diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index 81d1f1190702..21d527b1fff5 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -743,12 +743,9 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi myGutterComponent.repaint(0, y, myGutterComponent.getWidth(), myGutterComponent.getHeight() - y); } // make sure carets won't appear at invalid positions (e.g. on Tab width change) - getCaretModel().runForEachCaret(new CaretAction() { - @Override - public void perform(Caret caret) { - caret.moveToOffset(caret.getOffset()); - } - }); + for (Caret caret : getCaretModel().getAllCarets()) { + caret.moveToOffset(caret.getOffset()); + } } private void initTabPainter() { diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java index ec5c50db6e9d..390e61b8b53b 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java @@ -15,8 +15,10 @@ */ package com.intellij.xdebugger.impl.evaluate; +import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.EditorLinePainter; import com.intellij.openapi.editor.LineExtensionInfo; +import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; @@ -39,63 +41,72 @@ import java.util.List; * @author Konstantin Bulenkov */ public class XDebuggerEditorLinePainter extends EditorLinePainter { - public static final Key> CACHE = Key.create("debug.frame"); + public static final Key> CACHE = Key.create("debug.inline.variables.cache"); @Override public Collection getLineExtensions(@NotNull Project project, @NotNull VirtualFile file, int lineNumber) { if (!Registry.is("ide.debugger.inline")) { return null; } - Map, Set> map = project.getUserData(XVariablesView.DEBUG_VARIABLES); + final Map, Set> map = project.getUserData(XVariablesView.DEBUG_VARIABLES); + final Map timestamps = project.getUserData(XVariablesView.DEBUG_VARIABLES_TIMESTAMPS); + final Document doc = FileDocumentManager.getInstance().getDocument(file); + + if (map == null || timestamps == null || doc == null) { + return null; + } + Map oldValues = project.getUserData(CACHE); if (oldValues == null) { oldValues = new HashMap(); project.putUserData(CACHE, oldValues); } - if (map != null) { - Set values = map.get(Pair.create(file, lineNumber)); - if (values != null && !values.isEmpty()) { - ArrayList result = new ArrayList(); - for (XValueNodeImpl value : values) { - SimpleColoredText text = new SimpleColoredText(); - XValueTextRendererImpl renderer = new XValueTextRendererImpl(text); - final XValuePresentation presentation = value.getValuePresentation(); - if (presentation == null) continue; - try { - if (presentation instanceof XValueCompactPresentation) { - ((XValueCompactPresentation)presentation).renderValue(renderer, value); - } else { - presentation.renderValue(renderer); - } - } catch (Exception e) { - continue; - } - final Color color = getForeground(); - final String name = value.getName(); - result.add(new LineExtensionInfo(" " + name + ": ", color, null, null, Font.PLAIN)); - - Variable var = new Variable(name, lineNumber); - VariableValue variableValue = oldValues.get(var); - if (variableValue == null) { - variableValue = new VariableValue(text.toString(), null, value.hashCode()); - oldValues.put(var, variableValue); - } - if (variableValue.valueNodeHashCode != value.hashCode()) { - variableValue.old = variableValue.actual; - variableValue.actual = text.toString(); - variableValue.valueNodeHashCode = value.hashCode(); - } - - if (!variableValue.isChanged()) { - for (String s : text.getTexts()) { - result.add(new LineExtensionInfo(s, color, null, null, Font.PLAIN)); - } + final Long timestamp = timestamps.get(file); + if (timestamp == null || timestamp < doc.getModificationStamp()) { + return null; + } + Set values = map.get(Pair.create(file, lineNumber)); + if (values != null && !values.isEmpty()) { + ArrayList result = new ArrayList(); + for (XValueNodeImpl value : values) { + SimpleColoredText text = new SimpleColoredText(); + XValueTextRendererImpl renderer = new XValueTextRendererImpl(text); + final XValuePresentation presentation = value.getValuePresentation(); + if (presentation == null) continue; + try { + if (presentation instanceof XValueCompactPresentation) { + ((XValueCompactPresentation)presentation).renderValue(renderer, value); } else { - variableValue.produceChangedParts(result); + presentation.renderValue(renderer); } + } catch (Exception e) { + continue; + } + final Color color = getForeground(); + final String name = value.getName(); + result.add(new LineExtensionInfo(" " + name + ": ", color, null, null, Font.PLAIN)); + + Variable var = new Variable(name, lineNumber); + VariableValue variableValue = oldValues.get(var); + if (variableValue == null) { + variableValue = new VariableValue(text.toString(), null, value.hashCode()); + oldValues.put(var, variableValue); + } + if (variableValue.valueNodeHashCode != value.hashCode()) { + variableValue.old = variableValue.actual; + variableValue.actual = text.toString(); + variableValue.valueNodeHashCode = value.hashCode(); + } + + if (!variableValue.isChanged()) { + for (String s : text.getTexts()) { + result.add(new LineExtensionInfo(s, color, null, null, Font.PLAIN)); + } + } else { + variableValue.produceChangedParts(result); } - return result; } + return result; } return null; diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java index df43b1147419..ea53645b57e5 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java @@ -36,7 +36,8 @@ import static com.intellij.xdebugger.impl.ui.tree.nodes.MessageTreeNode.createIn * @author nik */ public class XVariablesView extends XVariablesViewBase { - public static final Key, Set>> DEBUG_VARIABLES = Key.create("debug.frame"); + public static final Key, Set>> DEBUG_VARIABLES = Key.create("debug.variables"); + public static final Key> DEBUG_VARIABLES_TIMESTAMPS = Key.create("debug.variables.timestamps"); public XVariablesView(@NotNull XDebugSessionImpl session) { super(session.getProject(), session.getDebugProcess().getEditorsProvider(), session.getValueMarkers()); @@ -69,6 +70,7 @@ public class XVariablesView extends XVariablesViewBase { protected void clear() { XDebuggerTree tree = getTree(); tree.getProject().putUserData(DEBUG_VARIABLES, null); + tree.getProject().putUserData(DEBUG_VARIABLES_TIMESTAMPS, null); tree.setSourcePosition(null); XDebuggerTreeNode node; diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java index ace9938318df..ab4483cd75d9 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java @@ -56,6 +56,7 @@ public abstract class XVariablesViewBase extends XDebugView { tree.setSourcePosition(stackFrame.getSourcePosition()); tree.setRoot(new XStackFrameNode(tree, stackFrame), false); tree.getProject().putUserData(XVariablesView.DEBUG_VARIABLES, new HashMap, Set>()); + tree.getProject().putUserData(XVariablesView.DEBUG_VARIABLES_TIMESTAMPS, new HashMap()); Object newEqualityObject = stackFrame.getEqualityObject(); if (myFrameEqualityObject != null && newEqualityObject != null && myFrameEqualityObject.equals(newEqualityObject) && myTreeState != null) { diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java index 1f3d4c77e84f..4b10c1a28b09 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java @@ -16,6 +16,8 @@ package com.intellij.xdebugger.impl.ui.tree.nodes; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; @@ -120,26 +122,7 @@ public class XValueNodeImpl extends XValueContainerNode implements XValu myValuePresentation = valuePresentation; myRawValue = XValuePresentationUtil.computeValueText(valuePresentation); if (Registry.is("ide.debugger.inline")) { - try { - getValueContainer().computeSourcePosition(new XNavigatable() { - @Override - public void setSourcePosition(@Nullable XSourcePosition sourcePosition) { - Map, Set> map = myTree.getProject().getUserData(XVariablesView.DEBUG_VARIABLES); - if (map == null || sourcePosition == null) return; - VirtualFile file = sourcePosition.getFile(); - int line = sourcePosition.getLine(); - Pair key = Pair.create(file, line); - Set presentations = map.get(key); - if (presentations == null) { - presentations = new LinkedHashSet(); - map.put(key, presentations); - } - presentations.add(XValueNodeImpl.this); - } - }); - } - catch (Exception ignore) { - } + updateInlineDebuggerData(); } updateText(); setLeaf(!hasChildren); @@ -147,6 +130,33 @@ public class XValueNodeImpl extends XValueContainerNode implements XValu myTree.nodeLoaded(this, myName); } + public void updateInlineDebuggerData() { + try { + getValueContainer().computeSourcePosition(new XNavigatable() { + @Override + public void setSourcePosition(@Nullable XSourcePosition sourcePosition) { + final Map, Set> map = myTree.getProject().getUserData(XVariablesView.DEBUG_VARIABLES); + final Map timestamps = myTree.getProject().getUserData(XVariablesView.DEBUG_VARIABLES_TIMESTAMPS); + if (map == null || timestamps == null || sourcePosition == null) return; + VirtualFile file = sourcePosition.getFile(); + final Document doc = FileDocumentManager.getInstance().getDocument(file); + if (doc == null) return; + int line = sourcePosition.getLine(); + Pair key = Pair.create(file, line); + Set presentations = map.get(key); + if (presentations == null) { + presentations = new LinkedHashSet(); + map.put(key, presentations); + timestamps.put(file, doc.getModificationStamp()); + } + presentations.add(XValueNodeImpl.this); + } + }); + } + catch (Exception ignore) { + } + } + @Override public void setFullValueEvaluator(@NotNull final XFullValueEvaluator fullValueEvaluator) { AppUIUtil.invokeOnEdt(new Runnable() { diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyCheckAction.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyCheckAction.java index eef2d00237b5..79e7325f5320 100644 --- a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyCheckAction.java +++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyCheckAction.java @@ -15,9 +15,7 @@ import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; -import com.intellij.openapi.ui.popup.Balloon; -import com.intellij.openapi.ui.popup.BalloonBuilder; -import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.ui.popup.*; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.IdeFocusManager; @@ -185,7 +183,6 @@ public class StudyCheckAction extends DumbAwareAction { IdeFocusManager.getInstance(project).requestFocus(editorToNavigate.getContentComponent(), true); } }); - taskFileToNavigate.navigateToFirstFailedTaskWindow(editor); } @@ -253,12 +250,17 @@ public class StudyCheckAction extends DumbAwareAction { private static void createTestResultPopUp(final String text, Color color, @NotNull final Project project) { BalloonBuilder balloonBuilder = JBPopupFactory.getInstance().createHtmlTextBalloonBuilder(text, null, color, null); - Balloon balloon = balloonBuilder.createBalloon(); + final Balloon balloon = balloonBuilder.createBalloon(); StudyEditor studyEditor = StudyEditor.getSelectedStudyEditor(project); assert studyEditor != null; JButton checkButton = studyEditor.getCheckButton(); balloon.showInCenterOf(checkButton); - Disposer.dispose(balloon); + balloon.addListener(new JBPopupAdapter() { + @Override + public void onClosed(LightweightWindowEvent event) { + Disposer.dispose(balloon); + } + }); } @Override diff --git a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyRefreshTaskAction.java b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyRefreshTaskAction.java index e7d1bf3855ad..11beed226757 100644 --- a/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyRefreshTaskAction.java +++ b/python/edu/learn-python/src/com/jetbrains/python/edu/actions/StudyRefreshTaskAction.java @@ -11,9 +11,8 @@ import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; -import com.intellij.openapi.ui.popup.Balloon; -import com.intellij.openapi.ui.popup.BalloonBuilder; -import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.ui.popup.*; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.IdeFocusManager; import com.jetbrains.python.edu.StudyDocumentListener; @@ -101,10 +100,16 @@ public class StudyRefreshTaskAction extends DumbAwareAction { selectedTaskFile.navigateToFirstTaskWindow(editor); BalloonBuilder balloonBuilder = JBPopupFactory.getInstance().createHtmlTextBalloonBuilder("You can now start again", MessageType.INFO, null); - Balloon balloon = balloonBuilder.createBalloon(); + final Balloon balloon = balloonBuilder.createBalloon(); StudyEditor selectedStudyEditor = StudyEditor.getSelectedStudyEditor(project); assert selectedStudyEditor != null; balloon.showInCenterOf(selectedStudyEditor.getRefreshButton()); + balloon.addListener(new JBPopupAdapter() { + @Override + public void onClosed(LightweightWindowEvent event) { + Disposer.dispose(balloon); + } + }); } catch (FileNotFoundException e1) { LOG.error(e1); diff --git a/python/src/com/jetbrains/python/sdk/PySdkListCellRenderer.java b/python/src/com/jetbrains/python/sdk/PySdkListCellRenderer.java index 1a42621dde3d..e165e59656f4 100644 --- a/python/src/com/jetbrains/python/sdk/PySdkListCellRenderer.java +++ b/python/src/com/jetbrains/python/sdk/PySdkListCellRenderer.java @@ -20,6 +20,7 @@ import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.SdkModificator; import com.intellij.openapi.projectRoots.SdkType; import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.ui.LayeredIcon; import com.intellij.ui.ListCellRendererWrapper; import com.jetbrains.python.sdk.flavors.PythonSdkFlavor; @@ -113,7 +114,7 @@ public class PySdkListCellRenderer extends ListCellRendererWrapper { } } else if (new File(name).exists()) { - name = "..." + File.separator + new File(name).getParentFile().getParentFile().getName(); + name = FileUtil.getLocationRelativeToUserHome(name); } return name; } diff --git a/xml/xml-psi-impl/src/com/intellij/psi/xml/XmlElementType.java b/xml/xml-psi-impl/src/com/intellij/psi/xml/XmlElementType.java index 04f5d67d3694..cd2625b33117 100644 --- a/xml/xml-psi-impl/src/com/intellij/psi/xml/XmlElementType.java +++ b/xml/xml-psi-impl/src/com/intellij/psi/xml/XmlElementType.java @@ -55,7 +55,7 @@ public interface XmlElementType extends XmlTokenType { //todo: move to html IElementType HTML_DOCUMENT = new IXmlElementType("HTML_DOCUMENT"); IElementType HTML_TAG = new IXmlElementType("HTML_TAG"); - IFileElementType HTML_FILE = new IFileElementType(HTMLLanguage.INSTANCE); + IFileElementType HTML_FILE = new IStubFileElementType(HTMLLanguage.INSTANCE); IElementType HTML_EMBEDDED_CONTENT = new EmbeddedHtmlContentElementType(); IElementType XML_TEXT = new XmlTextElementType();