Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Trofimov
2014-08-21 14:06:59 +02:00
9 changed files with 110 additions and 81 deletions
@@ -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() {
@@ -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<Map<Variable, VariableValue>> CACHE = Key.create("debug.frame");
public static final Key<Map<Variable, VariableValue>> CACHE = Key.create("debug.inline.variables.cache");
@Override
public Collection<LineExtensionInfo> getLineExtensions(@NotNull Project project, @NotNull VirtualFile file, int lineNumber) {
if (!Registry.is("ide.debugger.inline")) {
return null;
}
Map<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>> map = project.getUserData(XVariablesView.DEBUG_VARIABLES);
final Map<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>> map = project.getUserData(XVariablesView.DEBUG_VARIABLES);
final Map<VirtualFile, Long> timestamps = project.getUserData(XVariablesView.DEBUG_VARIABLES_TIMESTAMPS);
final Document doc = FileDocumentManager.getInstance().getDocument(file);
if (map == null || timestamps == null || doc == null) {
return null;
}
Map<Variable, VariableValue> oldValues = project.getUserData(CACHE);
if (oldValues == null) {
oldValues = new HashMap<Variable, VariableValue>();
project.putUserData(CACHE, oldValues);
}
if (map != null) {
Set<XValueNodeImpl> values = map.get(Pair.create(file, lineNumber));
if (values != null && !values.isEmpty()) {
ArrayList<LineExtensionInfo> result = new ArrayList<LineExtensionInfo>();
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<XValueNodeImpl> values = map.get(Pair.create(file, lineNumber));
if (values != null && !values.isEmpty()) {
ArrayList<LineExtensionInfo> result = new ArrayList<LineExtensionInfo>();
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;
@@ -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<Map<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>>> DEBUG_VARIABLES = Key.create("debug.frame");
public static final Key<Map<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>>> DEBUG_VARIABLES = Key.create("debug.variables");
public static final Key<Map<VirtualFile, Long>> 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;
@@ -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<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>>());
tree.getProject().putUserData(XVariablesView.DEBUG_VARIABLES_TIMESTAMPS, new HashMap<VirtualFile, Long>());
Object newEqualityObject = stackFrame.getEqualityObject();
if (myFrameEqualityObject != null && newEqualityObject != null && myFrameEqualityObject.equals(newEqualityObject)
&& myTreeState != null) {
@@ -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<XValue> 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<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>> map = myTree.getProject().getUserData(XVariablesView.DEBUG_VARIABLES);
if (map == null || sourcePosition == null) return;
VirtualFile file = sourcePosition.getFile();
int line = sourcePosition.getLine();
Pair<VirtualFile, Integer> key = Pair.create(file, line);
Set<XValueNodeImpl> presentations = map.get(key);
if (presentations == null) {
presentations = new LinkedHashSet<XValueNodeImpl>();
map.put(key, presentations);
}
presentations.add(XValueNodeImpl.this);
}
});
}
catch (Exception ignore) {
}
updateInlineDebuggerData();
}
updateText();
setLeaf(!hasChildren);
@@ -147,6 +130,33 @@ public class XValueNodeImpl extends XValueContainerNode<XValue> implements XValu
myTree.nodeLoaded(this, myName);
}
public void updateInlineDebuggerData() {
try {
getValueContainer().computeSourcePosition(new XNavigatable() {
@Override
public void setSourcePosition(@Nullable XSourcePosition sourcePosition) {
final Map<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>> map = myTree.getProject().getUserData(XVariablesView.DEBUG_VARIABLES);
final Map<VirtualFile, Long> 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<VirtualFile, Integer> key = Pair.create(file, line);
Set<XValueNodeImpl> presentations = map.get(key);
if (presentations == null) {
presentations = new LinkedHashSet<XValueNodeImpl>();
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() {
@@ -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
@@ -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);
@@ -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<Object> {
}
}
else if (new File(name).exists()) {
name = "..." + File.separator + new File(name).getParentFile().getParentFile().getName();
name = FileUtil.getLocationRelativeToUserHome(name);
}
return name;
}
@@ -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();