diff --git a/community-main.iml b/community-main.iml
index 63ff7f1979aa..f26de9512bd7 100644
--- a/community-main.iml
+++ b/community-main.iml
@@ -84,7 +84,6 @@
-
diff --git a/community-tests/src/tests/testGroups.properties b/community-tests/src/tests/testGroups.properties
index 736f52634df3..e3d67d9d1c5c 100644
--- a/community-tests/src/tests/testGroups.properties
+++ b/community-tests/src/tests/testGroups.properties
@@ -31,6 +31,8 @@ com.android.tools.idea.rendering.RenderErrorPanelTest
com.android.tools.idea.sdk.VersionCheckTest
org.jetbrains.android.sdk.AndroidSdkUtilsTest
org.jetbrains.android.sdk.AndroidSdkDataTest
+com.android.tools.idea.gradle.AndroidGradleModelTest
+com.android.tools.idea.gradle.InternalAndroidModelViewTest
com.android.tools.idea.gradle.project.GradleProjectImporterTest
com.android.tools.idea.gradle.compiler.AndroidGradleBuildProcessParametersProviderTest
com.android.tools.idea.sdk.JdksTest
diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/ManualRangeMarker.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/ManualRangeMarker.java
index 2e4e11c88c46..ac40c1190d8a 100644
--- a/platform/core-impl/src/com/intellij/openapi/editor/impl/ManualRangeMarker.java
+++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/ManualRangeMarker.java
@@ -59,7 +59,8 @@ public class ManualRangeMarker {
if (mySurviveOnExternalChange && PersistentRangeMarkerUtil.shouldTranslateViaDiff(event, myRange)) {
PersistentRangeMarker.LinesCols linesCols = myLinesCols != null ? myLinesCols
: PersistentRangeMarker.storeLinesAndCols(myRange, documentBefore);
- Pair pair = PersistentRangeMarker.translateViaDiff((DocumentEventImpl)event, linesCols);
+ Pair pair =
+ linesCols == null ? null : PersistentRangeMarker.translateViaDiff((DocumentEventImpl)event, linesCols);
if (pair != null) {
return new ManualRangeMarker(pair.first, myGreedyLeft, myGreedyRight, true, pair.second);
}
diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/PersistentRangeMarker.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/PersistentRangeMarker.java
index c401dbd17e58..3fc8bb200653 100644
--- a/platform/core-impl/src/com/intellij/openapi/editor/impl/PersistentRangeMarker.java
+++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/PersistentRangeMarker.java
@@ -79,7 +79,7 @@ class PersistentRangeMarker extends RangeMarkerImpl {
}
@Nullable
- static Pair translateViaDiff(final DocumentEventImpl event, LinesCols linesCols) {
+ static Pair translateViaDiff(@NotNull final DocumentEventImpl event, @NotNull LinesCols linesCols) {
try {
int myStartLine = event.translateLineViaDiffStrict(linesCols.myStartLine);
Document document = event.getDocument();
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocOnMouseOverManager.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocOnMouseOverManager.java
index 9d76e1314bff..e306416ac366 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocOnMouseOverManager.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocOnMouseOverManager.java
@@ -24,6 +24,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.VisualPosition;
import com.intellij.openapi.editor.event.*;
+import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
import com.intellij.openapi.editor.impl.EditorImpl;
import com.intellij.openapi.project.Project;
@@ -202,7 +203,13 @@ public class QuickDocOnMouseOverManager {
return;
}
- VisualPosition visualPosition = editor.xyToVisualPosition(e.getMouseEvent().getPoint());
+ Point point = e.getMouseEvent().getPoint();
+ if (editor instanceof EditorEx && ((EditorEx)editor).getFoldingModel().getFoldingPlaceholderAt(point) != null) {
+ closeQuickDocIfPossible();
+ return;
+ }
+
+ VisualPosition visualPosition = editor.xyToVisualPosition(point);
if (editor.getSoftWrapModel().isInsideOrBeforeSoftWrap(visualPosition)) {
closeQuickDocIfPossible();
return;
diff --git a/platform/platform-api/src/com/intellij/openapi/vfs/local/PluggableFileWatcher.java b/platform/platform-api/src/com/intellij/openapi/vfs/local/PluggableFileWatcher.java
index 52a278609682..85ebc64055ba 100644
--- a/platform/platform-api/src/com/intellij/openapi/vfs/local/PluggableFileWatcher.java
+++ b/platform/platform-api/src/com/intellij/openapi/vfs/local/PluggableFileWatcher.java
@@ -28,7 +28,8 @@ import java.util.List;
* @author dslomov
*/
public abstract class PluggableFileWatcher {
- public static final ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.vfs.local.pluggableFileWatcher");
+ public static final ExtensionPointName EP_NAME =
+ ExtensionPointName.create("com.intellij.vfs.local.pluggableFileWatcher");
public abstract void initialize(@NotNull ManagingFS managingFS, @NotNull FileWatcherNotificationSink notificationSink);
@@ -45,11 +46,11 @@ public abstract class PluggableFileWatcher {
public abstract boolean isWatched(@NotNull VirtualFile file);
- public abstract void resetChangedPaths();
+ public void resetChangedPaths() { }
@TestOnly
public abstract void startup() throws IOException;
@TestOnly
public abstract void shutdown() throws InterruptedException;
-}
+}
\ No newline at end of file
diff --git a/platform/platform-impl/src/com/intellij/ide/startup/impl/StartupManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/startup/impl/StartupManagerImpl.java
index 429fb33deee9..ed23ea542d60 100644
--- a/platform/platform-impl/src/com/intellij/ide/startup/impl/StartupManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/ide/startup/impl/StartupManagerImpl.java
@@ -51,6 +51,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.TestOnly;
import java.io.FileNotFoundException;
+import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
@@ -277,7 +278,7 @@ public class StartupManagerImpl extends StartupManagerEx {
if (!(fs instanceof LocalFileSystemImpl)) return;
FileWatcher watcher = ((LocalFileSystemImpl)fs).getFileWatcher();
if (!watcher.isOperational()) return;
- List manualWatchRoots = watcher.getManualWatchRoots();
+ Collection manualWatchRoots = watcher.getManualWatchRoots();
if (manualWatchRoots.isEmpty()) return;
VirtualFile[] roots = ProjectRootManager.getInstance(myProject).getContentRoots();
if (roots.length == 0) return;
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java
index f22111b06427..4f482d18f045 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java
@@ -53,6 +53,7 @@ import com.intellij.openapi.util.ScalableIcon;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.wm.impl.IdeBackgroundUtil;
+import com.intellij.openapi.wm.impl.IdeGlassPaneImpl;
import com.intellij.ui.HintHint;
import com.intellij.ui.JBColor;
import com.intellij.ui.awt.RelativePoint;
@@ -1362,26 +1363,24 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
}
void validateMousePointer(@NotNull MouseEvent e) {
- Cursor cursor = getCursor();//Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
+ if (IdeGlassPaneImpl.hasPreProcessedCursor(this)) return;
+
+ Cursor cursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
FoldRegion foldingAtCursor = findFoldingAnchorAt(e.getX(), e.getY());
setActiveFoldRegion(foldingAtCursor);
- boolean updated = false;
if (foldingAtCursor != null) {
cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
- updated = true;
}
GutterIconRenderer renderer = getGutterRenderer(e);
if (renderer != null) {
if (renderer.isNavigateAction()) {
cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
- updated = true;
}
}
else {
ActiveGutterRenderer lineRenderer = getActiveRendererByMouseEvent(e);
if (lineRenderer != null) {
cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
- updated = true;
}
else {
TextAnnotationGutterProvider provider = getProviderAtPoint(e.getPoint());
@@ -1391,15 +1390,11 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
if (action != null) {
int line = getLineNumAtPoint(e.getPoint());
cursor = action.getCursor(line);
- updated = true;
}
}
}
}
}
- if (!updated && cursor == Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)) {
- cursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
- }
setCursor(cursor);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java
index 65419745df7e..894751db67e9 100644
--- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java
@@ -119,7 +119,7 @@ public final class UpdateChecker {
ProgressManager.getInstance().run(new Task.Backgroundable(project, IdeBundle.message("updates.checking.progress"), true) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
- doUpdateAndShowResult(getProject(), !fromSettings, true, settings, indicator, null);
+ doUpdateAndShowResult(getProject(), fromSettings, true, settings, indicator, null);
}
@Override
@@ -135,7 +135,7 @@ public final class UpdateChecker {
}
private static void doUpdateAndShowResult(@Nullable final Project project,
- final boolean enableLink,
+ final boolean fromSettings,
final boolean manualCheck,
@NotNull final UpdateSettings updateSettings,
@Nullable ProgressIndicator indicator,
@@ -186,7 +186,13 @@ public final class UpdateChecker {
}
incompatiblePlugins = buildNumber != null ? new HashSet() : null;
- updatedPlugins = checkPluginsUpdate(manualCheck, updateSettings, indicator, incompatiblePlugins, buildNumber);
+ try {
+ updatedPlugins = checkPluginsUpdate(updateSettings, indicator, incompatiblePlugins, buildNumber);
+ }
+ catch (IOException e) {
+ showErrorMessage(manualCheck, IdeBundle.message("updates.error.connection.failed", e.getMessage()));
+ return;
+ }
}
// show result
@@ -194,12 +200,12 @@ public final class UpdateChecker {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
- showUpdateResult(project, result, updateSettings, updatedPlugins, incompatiblePlugins, enableLink, manualCheck);
+ showUpdateResult(project, result, updateSettings, updatedPlugins, incompatiblePlugins, !fromSettings, manualCheck);
if (callback != null) {
callback.setDone();
}
}
- }, ModalityState.NON_MODAL);
+ }, fromSettings ? ModalityState.any() : ModalityState.NON_MODAL);
}
@NotNull
@@ -244,11 +250,10 @@ public final class UpdateChecker {
return strategy.checkForUpdates();
}
- private static Collection checkPluginsUpdate(boolean manualCheck,
- @NotNull UpdateSettings updateSettings,
+ private static Collection checkPluginsUpdate(@NotNull UpdateSettings updateSettings,
@Nullable ProgressIndicator indicator,
@Nullable Collection incompatiblePlugins,
- @Nullable BuildNumber buildNumber) {
+ @Nullable BuildNumber buildNumber) throws IOException {
// collect installed plugins and plugins imported from a previous installation
Map updateable = ContainerUtil.newTroveMap();
@@ -309,7 +314,7 @@ public final class UpdateChecker {
LOG.info("failed to load plugin descriptions from " + host + ": " + e.getMessage());
}
else {
- showErrorMessage(manualCheck, IdeBundle.message("updates.error.connection.failed", e.getMessage()));
+ throw e;
}
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java
index c3d21240c497..c800eae8bd7d 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java
@@ -35,9 +35,9 @@ import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
-import static com.intellij.util.containers.ContainerUtil.emptyList;
import static com.intellij.util.containers.ContainerUtil.newArrayList;
/**
@@ -54,9 +54,6 @@ public class FileWatcher {
}
};
- private final Object myLock = new Object();
- private final PluggableFileWatcher[] myWatchers;
-
public static class DirtyPaths {
public final List dirtyPaths = newArrayList();
public final List dirtyPathsRecursive = newArrayList();
@@ -69,14 +66,15 @@ public class FileWatcher {
}
}
- private DirtyPaths myDirtyPaths = new DirtyPaths();
- private final AtomicBoolean myFailureShownToTheUser = new AtomicBoolean(false);
+ private final MyFileWatcherNotificationSink myNotificationSink;
+ private final PluggableFileWatcher[] myWatchers;
+ private final AtomicBoolean myFailureShown = new AtomicBoolean(false);
FileWatcher(@NotNull ManagingFS managingFS) {
- MyFileWatcherNotificationSink notificationSink = new MyFileWatcherNotificationSink();
+ myNotificationSink = new MyFileWatcherNotificationSink();
myWatchers = PluggableFileWatcher.EP_NAME.getExtensions();
for (PluggableFileWatcher watcher : myWatchers) {
- watcher.initialize(managingFS, notificationSink);
+ watcher.initialize(managingFS, myNotificationSink);
}
}
@@ -102,37 +100,29 @@ public class FileWatcher {
@NotNull
public DirtyPaths getDirtyPaths() {
- synchronized (myLock) {
- if (!myDirtyPaths.isEmpty()) {
- DirtyPaths dirtyPaths = myDirtyPaths;
- myDirtyPaths = new DirtyPaths();
- for (PluggableFileWatcher watcher : myWatchers) {
- watcher.resetChangedPaths();
- }
- return dirtyPaths;
- }
- else {
- return DirtyPaths.EMPTY;
- }
- }
+ return myNotificationSink.getDirtyPaths();
}
@NotNull
- public List getManualWatchRoots() {
+ public Collection getManualWatchRoots() {
if (myWatchers.length == 1) {
return myWatchers[0].getManualWatchRoots();
}
- HashSet result = null;
+
+ Set result = null;
for (PluggableFileWatcher watcher : myWatchers) {
- List roots = watcher.getManualWatchRoots();
- if (result == null) {
- result = new HashSet(roots);
- } else {
- result.retainAll(roots);
+ Collection roots = watcher.getManualWatchRoots();
+ if (!roots.isEmpty()) {
+ if (result == null) {
+ result = new HashSet(roots);
+ }
+ else {
+ result.retainAll(roots);
+ }
}
}
- if (result == null) return emptyList();
- return Collections.list(Collections.enumeration(result));
+
+ return result != null ? result : Collections.emptyList();
}
public void setWatchRoots(@NotNull List recursive, @NotNull List flat) {
@@ -151,16 +141,37 @@ public class FileWatcher {
public void notifyOnFailure(final String cause, @Nullable final NotificationListener listener) {
LOG.warn(cause);
- if (myFailureShownToTheUser.compareAndSet(false, true)) ApplicationManager.getApplication().invokeLater(new Runnable() {
- @Override
- public void run() {
- String title = ApplicationBundle.message("watcher.slow.sync");
- Notifications.Bus.notify(NOTIFICATION_GROUP.getValue().createNotification(title, cause, NotificationType.WARNING, listener));
- }
- }, ModalityState.NON_MODAL);
+ if (myFailureShown.compareAndSet(false, true)) {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ String title = ApplicationBundle.message("watcher.slow.sync");
+ Notifications.Bus.notify(NOTIFICATION_GROUP.getValue().createNotification(title, cause, NotificationType.WARNING, listener));
+ }
+ }, ModalityState.NON_MODAL);
+ }
}
private class MyFileWatcherNotificationSink implements FileWatcherNotificationSink {
+ private final Object myLock = new Object();
+ private DirtyPaths myDirtyPaths = new DirtyPaths();
+
+ private DirtyPaths getDirtyPaths() {
+ synchronized (myLock) {
+ if (!myDirtyPaths.isEmpty()) {
+ DirtyPaths dirtyPaths = myDirtyPaths;
+ myDirtyPaths = new DirtyPaths();
+ for (PluggableFileWatcher watcher : myWatchers) {
+ watcher.resetChangedPaths();
+ }
+ return dirtyPaths;
+ }
+ else {
+ return DirtyPaths.EMPTY;
+ }
+ }
+ }
+
@Override
public void notifyDirtyPaths(Collection paths) {
synchronized (myLock) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/NativeFileWatcherImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/NativeFileWatcherImpl.java
index 0191311514eb..b9bc9e0d3f76 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/NativeFileWatcherImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/NativeFileWatcherImpl.java
@@ -32,6 +32,7 @@ import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.ShutDownTracker;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.local.FileWatcherNotificationSink;
@@ -66,13 +67,13 @@ public class NativeFileWatcherImpl extends PluggableFileWatcher {
private static final int MAX_PROCESS_LAUNCH_ATTEMPT_COUNT = 10;
private ManagingFS myManagingFS;
+ private FileWatcherNotificationSink myNotificationSink;
private File myExecutable;
+
private volatile MyProcessHandler myProcessHandler;
private volatile int myStartAttemptCount = 0;
private volatile boolean myIsShuttingDown = false;
private final AtomicInteger mySettingRoots = new AtomicInteger(0);
- private final Object myLock = new Object();
- private FileWatcherNotificationSink myNotificationSink;
private volatile List myRecursiveWatchRoots = emptyList();
private volatile List myFlatWatchRoots = emptyList();
@@ -280,7 +281,7 @@ public class NativeFileWatcherImpl extends PluggableFileWatcher {
@Override
public void resetChangedPaths() {
- synchronized (myLock) {
+ synchronized (myLastChangedPaths) {
myLastChangedPathIndex = 0;
for (int i = 0; i < myLastChangedPaths.length; ++i) myLastChangedPaths[i] = null;
}
@@ -375,7 +376,8 @@ public class NativeFileWatcherImpl extends PluggableFileWatcher {
@Override
public void processTerminated(ProcessEvent event) {
- LOG.warn("Watcher terminated with exit code " + event.getExitCode());
+ String message = "Watcher terminated with exit code " + event.getExitCode();
+ if (myIsShuttingDown) LOG.info(message); else LOG.warn(message);
myProcessHandler = null;
@@ -444,7 +446,7 @@ public class NativeFileWatcherImpl extends PluggableFileWatcher {
}
}
else {
- String path = line.replace('\0', '\n'); // unescape
+ String path = StringUtil.trimEnd(line.replace('\0', '\n'), File.separator); // unescape
processChange(path, myLastOp);
myLastOp = null;
}
@@ -482,7 +484,7 @@ public class NativeFileWatcherImpl extends PluggableFileWatcher {
}
private void processChange(String path, WatcherOp op) {
- if (SystemInfo.isWindows && op == WatcherOp.RECDIRTY && path.length() == 3 && Character.isLetter(path.charAt(0))) {
+ if (SystemInfo.isWindows && op == WatcherOp.RECDIRTY) {
VirtualFile root = LocalFileSystem.getInstance().findFileByPath(path);
if (root != null) {
myNotificationSink.notifyPathsRecursive(list(root.getPresentableUrl()));
@@ -491,25 +493,13 @@ public class NativeFileWatcherImpl extends PluggableFileWatcher {
return;
}
- if (op == WatcherOp.CHANGE) {
- // collapse subsequent change file change notifications that happen once we copy large file,
- // this allows reduction of path checks at least 20% for Windows
- synchronized (myLock) {
- for (int i = 0; i < myLastChangedPaths.length; ++i) {
- int last = myLastChangedPathIndex - i - 1;
- if (last < 0) last += myLastChangedPaths.length;
- String lastChangedPath = myLastChangedPaths[last];
- if (lastChangedPath != null && lastChangedPath.equals(path)) {
- return;
- }
- }
- myLastChangedPaths[myLastChangedPathIndex++] = path;
- if (myLastChangedPathIndex == myLastChangedPaths.length) myLastChangedPathIndex = 0;
+ if ((op == WatcherOp.CHANGE || op == WatcherOp.STATS) && isRepetition(path)) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Repetition: " + path);
}
+ return;
}
- int length = path.length();
- if (length > 1 && path.charAt(length - 1) == '/') path = path.substring(0, length - 1);
boolean exactPath = op != WatcherOp.DIRTY && op != WatcherOp.RECDIRTY;
Collection paths = checkWatchable(path, exactPath, false);
@@ -547,6 +537,26 @@ public class NativeFileWatcherImpl extends PluggableFileWatcher {
}
}
+ private boolean isRepetition(String path) {
+ // collapse subsequent change file change notifications that happen once we copy large file,
+ // this allows reduction of path checks at least 20% for Windows
+ synchronized (myLastChangedPaths) {
+ for (int i = 0; i < myLastChangedPaths.length; ++i) {
+ int last = myLastChangedPathIndex - i - 1;
+ if (last < 0) last += myLastChangedPaths.length;
+ String lastChangedPath = myLastChangedPaths[last];
+ if (lastChangedPath != null && lastChangedPath.equals(path)) {
+ return true;
+ }
+ }
+
+ myLastChangedPaths[myLastChangedPathIndex++] = path;
+ if (myLastChangedPathIndex == myLastChangedPaths.length) myLastChangedPathIndex = 0;
+ }
+
+ return false;
+ }
+
@SuppressWarnings("TestOnlyProblems")
private void notifyOnAnyEvent() {
myNotificationSink.notifyOnAnyEvent();
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java
index 19283895eeb9..4b0abde0f04d 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java
@@ -48,6 +48,7 @@ import java.util.List;
public class IdeGlassPaneImpl extends JPanel implements IdeGlassPaneEx, IdeEventQueue.EventDispatcher {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.wm.impl.IdeGlassPaneImpl");
+ private static final String PREPROCESSED_CURSOR_KEY = "SuperCursor";
private final List myMouseListeners = new ArrayList();
private final Set mySortedMouseListeners = new TreeSet(new Comparator() {
@@ -345,6 +346,9 @@ public class IdeGlassPaneImpl extends JPanel implements IdeGlassPaneEx, IdeEvent
}
if (cursor != null && !cursor.equals(target.getCursor())) {
+ if (target instanceof JComponent) {
+ ((JComponent)target).putClientProperty(PREPROCESSED_CURSOR_KEY, Boolean.TRUE);
+ }
target.setCursor(cursor);
}
}
@@ -393,9 +397,15 @@ public class IdeGlassPaneImpl extends JPanel implements IdeGlassPaneEx, IdeEvent
private void restoreLastComponent(Component newC) {
if (myLastCursorComponent != null && myLastCursorComponent != newC) {
myLastCursorComponent.setCursor(myLastOriginalCursor);
+ if (myLastCursorComponent instanceof JComponent) {
+ ((JComponent)myLastCursorComponent).putClientProperty(PREPROCESSED_CURSOR_KEY, null);
+ }
}
}
+ public static boolean hasPreProcessedCursor(@NotNull JComponent component) {
+ return component.getClientProperty(PREPROCESSED_CURSOR_KEY) != null;
+ }
public void setCursor(Cursor cursor, @NotNull Object requestor) {
if (cursor == null) {
diff --git a/platform/platform-resources-en/src/messages/CommonBundle.properties b/platform/platform-resources-en/src/messages/CommonBundle.properties
index bf8d5dbabedd..615445ea616a 100644
--- a/platform/platform-resources-en/src/messages/CommonBundle.properties
+++ b/platform/platform-resources-en/src/messages/CommonBundle.properties
@@ -123,6 +123,8 @@ format.file.size.bytes={0}b
format.file.size.kbytes={0}Kb
format.file.size.mbytes={0}Mb
+profiling.capture.snapshot.progress=Capturing Memory Snapshot
+profiling.compress.snapshot.progress=Compressing Memory Snapshot
profiling.capture.snapshot.success=Captured snapshot ''{0}'' is placed in user home directory. Show in {2}.
profiling.capture.snapshot.error=Failed to capture snapshot: {0}