xdebugger: debugger trees decoupled from XDebugSession

This commit is contained in:
nik
2013-09-18 11:36:58 +04:00
parent 7469f4b4c2
commit 93a2c9ef22
24 changed files with 405 additions and 348 deletions
@@ -29,6 +29,7 @@ import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.evaluation.EvaluationMode;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.ui.XDebuggerEditorBase;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
@@ -84,7 +85,8 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
};
mySession.addSessionListener(mySessionListener);
myTreePanel = new XDebuggerTreePanel(session, editorsProvider, myDisposable, sourcePosition, XDebuggerActions.EVALUATE_DIALOG_TREE_POPUP_GROUP);
myTreePanel = new XDebuggerTreePanel(session.getProject(), editorsProvider, myDisposable, sourcePosition, XDebuggerActions.EVALUATE_DIALOG_TREE_POPUP_GROUP,
((XDebugSessionImpl)session).getValueMarkers());
myResultPanel = new JPanel(new BorderLayout());
myResultPanel.add(new JLabel(XDebuggerBundle.message("xdebugger.evaluate.label.result")), BorderLayout.NORTH);
myResultPanel.add(myTreePanel.getMainPanel(), BorderLayout.CENTER);
@@ -32,10 +32,12 @@ import com.intellij.xdebugger.frame.XFullValueEvaluator;
import com.intellij.xdebugger.frame.XValue;
import com.intellij.xdebugger.frame.XValuePlace;
import com.intellij.xdebugger.frame.presentation.XValuePresentation;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.actions.handlers.XDebuggerEvaluateActionHandler;
import com.intellij.xdebugger.impl.evaluate.quick.common.AbstractValueHint;
import com.intellij.xdebugger.impl.evaluate.quick.common.ValueHintType;
import com.intellij.xdebugger.impl.frame.XValueMarkers;
import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import com.intellij.xdebugger.impl.ui.tree.nodes.XEvaluationCallbackBase;
@@ -128,8 +130,9 @@ public class XValueHint extends AbstractValueHint {
}
private void showTree(final XValue value, final String name) {
XDebuggerTree tree = new XDebuggerTree(myDebugSession, myDebugSession.getDebugProcess().getEditorsProvider(),
myDebugSession.getCurrentPosition(), XDebuggerActions.INSPECT_TREE_POPUP_GROUP);
XValueMarkers<?,?> valueMarkers = ((XDebugSessionImpl)myDebugSession).getValueMarkers();
XDebuggerTree tree = new XDebuggerTree(myDebugSession.getProject(), myDebugSession.getDebugProcess().getEditorsProvider(),
myDebugSession.getCurrentPosition(), XDebuggerActions.INSPECT_TREE_POPUP_GROUP, valueMarkers);
tree.getModel().addTreeModelListener(createTreeListener(tree));
XValueHintTreeComponent component = new XValueHintTreeComponent(this, tree, Pair.create(value, name));
showTreePopup(component, tree, name);
@@ -17,16 +17,14 @@ package com.intellij.xdebugger.impl.frame;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.AppUIUtil;
import com.intellij.xdebugger.XStackFrameAwareSession;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebugSessionAdapter;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.intellij.xdebugger.impl.ui.XDebugSessionTab;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeInplaceEditor;
import com.intellij.xdebugger.impl.ui.tree.nodes.WatchNode;
import com.intellij.xdebugger.impl.ui.tree.nodes.WatchesRootNode;
import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -36,20 +34,19 @@ import javax.swing.*;
*/
public class WatchInplaceEditor extends XDebuggerTreeInplaceEditor {
private final WatchesRootNode myRootNode;
private final XWatchesView myWatchesView;
@Nullable private final WatchNode myOldNode;
public WatchInplaceEditor(WatchesRootNode rootNode,
final WatchNode node,
public WatchInplaceEditor(@NotNull WatchesRootNode rootNode,
@NotNull XDebugSession session, XWatchesView watchesView, final WatchNode node,
@NonNls final String historyId,
final @Nullable WatchNode oldNode) {
super((XDebuggerTreeNode)node, historyId);
myRootNode = rootNode;
myWatchesView = watchesView;
myOldNode = oldNode;
myExpressionEditor.setText(oldNode != null ? oldNode.getExpression() : "");
final XStackFrameAwareSession session = rootNode.getTree().getSession();
if (session instanceof XDebugSession) {
new WatchEditorSessionListener((XDebugSession)session).install();
}
new WatchEditorSessionListener(session).install();
}
protected JComponent createInplaceEditorComponent() {
@@ -61,7 +58,7 @@ public class WatchInplaceEditor extends XDebuggerTreeInplaceEditor {
super.cancelEditing();
int index = myRootNode.removeChildNode(getNode());
if (myOldNode != null && index != -1) {
getWatchesView().addWatchExpression(myOldNode.getExpression(), index, false);
myWatchesView.addWatchExpression(myOldNode.getExpression(), index, false);
}
}
@@ -71,24 +68,14 @@ public class WatchInplaceEditor extends XDebuggerTreeInplaceEditor {
super.doOKAction();
int index = myRootNode.removeChildNode(getNode());
if (!StringUtil.isEmpty(expression) && index != -1) {
getWatchesView().addWatchExpression(expression, index, false);
}
}
private XWatchesView getWatchesView() {
if (myRootNode.getTree().getSession() instanceof XDebugSessionImpl) {
XDebugSessionTab tab = ((XDebugSessionImpl)myRootNode.getTree().getSession()).getSessionTab();
return tab.getWatchesView();
}
else {
return null;
myWatchesView.addWatchExpression(expression, index, false);
}
}
private class WatchEditorSessionListener extends XDebugSessionAdapter {
private final XDebugSession mySession;
public WatchEditorSessionListener(XDebugSession session) {
public WatchEditorSessionListener(@NotNull XDebugSession session) {
mySession = session;
}
@@ -17,12 +17,13 @@ package com.intellij.xdebugger.impl.frame;
import com.intellij.ide.dnd.DnDManager;
import com.intellij.openapi.Disposable;
import com.intellij.xdebugger.XStackFrameAwareSession;
import com.intellij.xdebugger.XDebugProcess;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebuggerBundle;
import com.intellij.xdebugger.XStackFrameAwareSession;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.frame.XStackFrame;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreePanel;
@@ -49,7 +50,8 @@ public class XVariablesView extends XDebugViewBase {
public XVariablesView(@NotNull XStackFrameAwareSession session, @Nullable final Disposable parentDisposable) {
super(session, parentDisposable);
XDebuggerEditorsProvider editorsProvider = session.getEditorsProvider();
myDebuggerTreePanel = new XDebuggerTreePanel(session, editorsProvider, this, null, XDebuggerActions.VARIABLES_TREE_POPUP_GROUP);
XValueMarkers<?,?> markers = session instanceof XDebugSessionImpl ? ((XDebugSessionImpl)session).getValueMarkers() : null;
myDebuggerTreePanel = new XDebuggerTreePanel(session.getProject(), editorsProvider, this, null, XDebuggerActions.VARIABLES_TREE_POPUP_GROUP, markers);
myDebuggerTreePanel.getTree().getEmptyText().setText(XDebuggerBundle.message("debugger.variables.not.available"));
DnDManager.getInstance().registerSource(myDebuggerTreePanel, myDebuggerTreePanel.getTree());
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,236 +15,21 @@
*/
package com.intellij.xdebugger.impl.frame;
import com.intellij.ide.DataManager;
import com.intellij.ide.dnd.DnDEvent;
import com.intellij.ide.dnd.DnDManager;
import com.intellij.ide.dnd.DnDNativeTarget;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.ui.AnActionButton;
import com.intellij.ui.AnActionButtonRunnable;
import com.intellij.ui.CaptionPanel;
import com.intellij.ui.ToolbarDecorator;
import com.intellij.ui.border.CustomLineBorder;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ui.tree.TreeUtil;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebuggerBundle;
import com.intellij.xdebugger.frame.XStackFrame;
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.ui.XDebugSessionData;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreePanel;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeRestorer;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeState;
import com.intellij.xdebugger.impl.ui.tree.nodes.WatchNode;
import com.intellij.xdebugger.impl.ui.tree.nodes.WatchesRootNode;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
/**
* @author nik
*/
public class XWatchesView extends XDebugViewBase implements DnDNativeTarget {
private final XDebuggerTreePanel myTreePanel;
private XDebuggerTreeState myTreeState;
private XDebuggerTreeRestorer myTreeRestorer;
private final WatchesRootNode myRootNode;
private final XDebugSessionData mySessionData;
private final JPanel myDecoratedPanel;
public interface XWatchesView {
DataKey<XWatchesView> DATA_KEY = DataKey.create("XDEBUGGER_WATCHES_VIEW");
public XWatchesView(@NotNull final XDebugSession session, @Nullable final Disposable parentDisposable, final XDebugSessionData sessionData) {
super(session, parentDisposable);
mySessionData = sessionData;
myTreePanel = new XDebuggerTreePanel(session, session.getDebugProcess().getEditorsProvider(), this, null,
XDebuggerActions.WATCHES_TREE_POPUP_GROUP);
void addWatchExpression(@NotNull String expression, int index, boolean navigateToWatchNode);
ActionManager actionManager = ActionManager.getInstance();
void removeWatches(List<? extends XDebuggerTreeNode> nodes);
XDebuggerTree tree = myTreePanel.getTree();
actionManager.getAction(XDebuggerActions.XNEW_WATCH).registerCustomShortcutSet(CommonShortcuts.INSERT, tree);
actionManager.getAction(XDebuggerActions.XREMOVE_WATCH).registerCustomShortcutSet(CommonShortcuts.DELETE, tree);
CustomShortcutSet f2Shortcut = new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0));
actionManager.getAction(XDebuggerActions.XEDIT_WATCH).registerCustomShortcutSet(f2Shortcut, tree);
DnDManager.getInstance().registerTarget(this, tree);
myRootNode = new WatchesRootNode(tree, sessionData.getWatchExpressions());
tree.setRoot(myRootNode, false);
final ToolbarDecorator decorator = ToolbarDecorator.createDecorator(myTreePanel.getTree()).disableUpDownActions();
decorator.setAddAction(new AnActionButtonRunnable() {
@Override
public void run(AnActionButton button) {
executeAction(XDebuggerActions.XNEW_WATCH);
}
});
decorator.setRemoveAction(new AnActionButtonRunnable() {
@Override
public void run(AnActionButton button) {
executeAction(XDebuggerActions.XREMOVE_WATCH);
}
});
CustomLineBorder border = new CustomLineBorder(CaptionPanel.CNT_ACTIVE_BORDER_COLOR,
SystemInfo.isMac ? 1 : 0, 0,
SystemInfo.isMac ? 0 : 1, 0);
decorator.setToolbarBorder(border);
myDecoratedPanel = decorator.createPanel();
myDecoratedPanel.setBorder(null);
myTreePanel.getTree().getEmptyText().setText(XDebuggerBundle.message("debugger.no.watches"));
}
private void executeAction(final String watch) {
AnAction action = ActionManager.getInstance().getAction(watch);
Presentation presentation = action.getTemplatePresentation().clone();
DataContext context = DataManager.getInstance().getDataContext(myTreePanel.getTree());
AnActionEvent actionEvent =
new AnActionEvent(null, context, ActionPlaces.DEBUGGER_TOOLBAR, presentation, ActionManager.getInstance(), 0);
action.actionPerformed(actionEvent);
}
public void addWatchExpression(@NotNull String expression, int index, final boolean navigateToWatchNode) {
XStackFrame stackFrame = mySession.getCurrentStackFrame();
myRootNode.addWatchExpression(stackFrame == null ? null : stackFrame.getEvaluator(), expression, index, navigateToWatchNode);
updateSessionData();
}
@Override
protected void rebuildView(final SessionEvent event) {
XStackFrame stackFrame = mySession.getCurrentStackFrame();
XDebuggerTree tree = myTreePanel.getTree();
if (event == SessionEvent.BEFORE_RESUME || event == SessionEvent.SETTINGS_CHANGED) {
if (myTreeRestorer != null) {
myTreeRestorer.dispose();
}
myTreeState = XDebuggerTreeState.saveState(tree);
if (event == SessionEvent.BEFORE_RESUME) {
return;
}
}
if (stackFrame != null) {
tree.setSourcePosition(stackFrame.getSourcePosition());
myRootNode.updateWatches(stackFrame.getEvaluator());
if (myTreeState != null) {
myTreeRestorer = myTreeState.restoreState(tree);
}
}
else {
tree.setSourcePosition(null);
myRootNode.updateWatches(null);
}
}
@Override
public void dispose() {
DnDManager.getInstance().unregisterTarget(this, myTreePanel.getTree());
super.dispose();
}
public XDebuggerTree getTree() {
return myTreePanel.getTree();
}
public JPanel getMainPanel() {
return myDecoratedPanel;
}
public void removeWatches(final List<? extends XDebuggerTreeNode> nodes) {
List<? extends WatchNode> children = myRootNode.getAllChildren();
int minIndex = Integer.MAX_VALUE;
List<XDebuggerTreeNode> toRemove = new ArrayList<XDebuggerTreeNode>();
if (children != null) {
for (XDebuggerTreeNode node : nodes) {
@SuppressWarnings("SuspiciousMethodCalls")
int index = children.indexOf(node);
if (index != -1) {
toRemove.add(node);
minIndex = Math.min(minIndex, index);
}
}
}
myRootNode.removeChildren(toRemove);
List<? extends WatchNode> newChildren = myRootNode.getAllChildren();
if (newChildren != null && !newChildren.isEmpty()) {
WatchNode node = minIndex < newChildren.size() ? newChildren.get(minIndex) : newChildren.get(newChildren.size() - 1);
TreeUtil.selectNode(myTreePanel.getTree(), node);
}
updateSessionData();
}
public void removeAllWatches() {
myRootNode.removeAllChildren();
updateSessionData();
}
private void updateSessionData() {
List<String> watchExpressions = new ArrayList<String>();
final List<? extends WatchNode> children = myRootNode.getAllChildren();
if (children != null) {
for (WatchNode child : children) {
watchExpressions.add(child.getExpression());
}
}
mySessionData.setWatchExpressions(ArrayUtil.toStringArray(watchExpressions));
}
@Override
public boolean update(final DnDEvent aEvent) {
Object object = aEvent.getAttachedObject();
boolean possible = false;
if (object instanceof XValueNodeImpl[]) {
possible = true;
}
else if (object instanceof EventInfo) {
possible = ((EventInfo)object).getTextForFlavor(DataFlavor.stringFlavor) != null;
}
aEvent.setDropPossible(possible, XDebuggerBundle.message("xdebugger.drop.text.add.to.watches"));
return true;
}
@Override
public void drop(final DnDEvent aEvent) {
Object object = aEvent.getAttachedObject();
if (object instanceof XValueNodeImpl[]) {
final XValueNodeImpl[] nodes = (XValueNodeImpl[])object;
for (XValueNodeImpl node : nodes) {
String expression = node.getValueContainer().getEvaluationExpression();
if (expression != null) {
addWatchExpression(expression, -1, false);
}
}
}
else if (object instanceof EventInfo) {
String text = ((EventInfo)object).getTextForFlavor(DataFlavor.stringFlavor);
if (text != null) {
addWatchExpression(text, -1, false);
}
}
}
@Override
public void cleanUpOnLeave() {
}
@Override
public void updateDraggedImage(final Image image, final Point dropPoint, final Point imageOffset) {
}
void removeAllWatches();
}
@@ -0,0 +1,256 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.xdebugger.impl.frame;
import com.intellij.ide.DataManager;
import com.intellij.ide.dnd.DnDEvent;
import com.intellij.ide.dnd.DnDManager;
import com.intellij.ide.dnd.DnDNativeTarget;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.ui.AnActionButton;
import com.intellij.ui.AnActionButtonRunnable;
import com.intellij.ui.CaptionPanel;
import com.intellij.ui.ToolbarDecorator;
import com.intellij.ui.border.CustomLineBorder;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ui.tree.TreeUtil;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebuggerBundle;
import com.intellij.xdebugger.frame.XStackFrame;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.ui.XDebugSessionData;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreePanel;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeRestorer;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeState;
import com.intellij.xdebugger.impl.ui.tree.nodes.WatchNode;
import com.intellij.xdebugger.impl.ui.tree.nodes.WatchesRootNode;
import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
/**
* @author nik
*/
public class XWatchesViewImpl extends XDebugViewBase implements DnDNativeTarget, XWatchesView {
private final XDebuggerTreePanel myTreePanel;
private XDebuggerTreeState myTreeState;
private XDebuggerTreeRestorer myTreeRestorer;
private final WatchesRootNode myRootNode;
private final XDebugSessionData mySessionData;
private final JPanel myDecoratedPanel;
public XWatchesViewImpl(@NotNull final XDebugSession session,
@NotNull final Disposable parentDisposable,
final XDebugSessionData sessionData) {
super(session, parentDisposable);
mySessionData = sessionData;
myTreePanel = new XDebuggerTreePanel(session.getProject(), session.getDebugProcess().getEditorsProvider(), this, null,
XDebuggerActions.WATCHES_TREE_POPUP_GROUP, ((XDebugSessionImpl)session).getValueMarkers());
ActionManager actionManager = ActionManager.getInstance();
XDebuggerTree tree = myTreePanel.getTree();
actionManager.getAction(XDebuggerActions.XNEW_WATCH).registerCustomShortcutSet(CommonShortcuts.INSERT, tree);
actionManager.getAction(XDebuggerActions.XREMOVE_WATCH).registerCustomShortcutSet(CommonShortcuts.DELETE, tree);
CustomShortcutSet f2Shortcut = new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0));
actionManager.getAction(XDebuggerActions.XEDIT_WATCH).registerCustomShortcutSet(f2Shortcut, tree);
DnDManager.getInstance().registerTarget(this, tree);
Disposer.register(parentDisposable, new Disposable() {
@Override
public void dispose() {
DnDManager.getInstance().unregisterTarget(XWatchesViewImpl.this, myTreePanel.getTree());
}
});
myRootNode = new WatchesRootNode(tree, session, this, sessionData.getWatchExpressions());
tree.setRoot(myRootNode, false);
final ToolbarDecorator decorator = ToolbarDecorator.createDecorator(myTreePanel.getTree()).disableUpDownActions();
decorator.setAddAction(new AnActionButtonRunnable() {
@Override
public void run(AnActionButton button) {
executeAction(XDebuggerActions.XNEW_WATCH);
}
});
decorator.setRemoveAction(new AnActionButtonRunnable() {
@Override
public void run(AnActionButton button) {
executeAction(XDebuggerActions.XREMOVE_WATCH);
}
});
CustomLineBorder border = new CustomLineBorder(CaptionPanel.CNT_ACTIVE_BORDER_COLOR,
SystemInfo.isMac ? 1 : 0, 0,
SystemInfo.isMac ? 0 : 1, 0);
decorator.setToolbarBorder(border);
myDecoratedPanel = decorator.createPanel();
myDecoratedPanel.setBorder(null);
myTreePanel.getTree().getEmptyText().setText(XDebuggerBundle.message("debugger.no.watches"));
}
private void executeAction(final String watch) {
AnAction action = ActionManager.getInstance().getAction(watch);
Presentation presentation = action.getTemplatePresentation().clone();
DataContext context = DataManager.getInstance().getDataContext(myTreePanel.getTree());
AnActionEvent actionEvent =
new AnActionEvent(null, context, ActionPlaces.DEBUGGER_TOOLBAR, presentation, ActionManager.getInstance(), 0);
action.actionPerformed(actionEvent);
}
@Override
public void addWatchExpression(@NotNull String expression, int index, final boolean navigateToWatchNode) {
XStackFrame stackFrame = mySession.getCurrentStackFrame();
myRootNode.addWatchExpression(stackFrame == null ? null : stackFrame.getEvaluator(), expression, index, navigateToWatchNode);
updateSessionData();
}
@Override
protected void rebuildView(final SessionEvent event) {
XStackFrame stackFrame = mySession.getCurrentStackFrame();
XDebuggerTree tree = myTreePanel.getTree();
if (event == SessionEvent.BEFORE_RESUME || event == SessionEvent.SETTINGS_CHANGED) {
if (myTreeRestorer != null) {
myTreeRestorer.dispose();
}
myTreeState = XDebuggerTreeState.saveState(tree);
if (event == SessionEvent.BEFORE_RESUME) {
return;
}
}
if (stackFrame != null) {
tree.setSourcePosition(stackFrame.getSourcePosition());
myRootNode.updateWatches(stackFrame.getEvaluator());
if (myTreeState != null) {
myTreeRestorer = myTreeState.restoreState(tree);
}
}
else {
tree.setSourcePosition(null);
myRootNode.updateWatches(null);
}
}
public XDebuggerTree getTree() {
return myTreePanel.getTree();
}
public JPanel getMainPanel() {
return myDecoratedPanel;
}
@Override
public void removeWatches(final List<? extends XDebuggerTreeNode> nodes) {
List<? extends WatchNode> children = myRootNode.getAllChildren();
int minIndex = Integer.MAX_VALUE;
List<XDebuggerTreeNode> toRemove = new ArrayList<XDebuggerTreeNode>();
if (children != null) {
for (XDebuggerTreeNode node : nodes) {
@SuppressWarnings("SuspiciousMethodCalls")
int index = children.indexOf(node);
if (index != -1) {
toRemove.add(node);
minIndex = Math.min(minIndex, index);
}
}
}
myRootNode.removeChildren(toRemove);
List<? extends WatchNode> newChildren = myRootNode.getAllChildren();
if (newChildren != null && !newChildren.isEmpty()) {
WatchNode node = minIndex < newChildren.size() ? newChildren.get(minIndex) : newChildren.get(newChildren.size() - 1);
TreeUtil.selectNode(myTreePanel.getTree(), node);
}
updateSessionData();
}
@Override
public void removeAllWatches() {
myRootNode.removeAllChildren();
updateSessionData();
}
private void updateSessionData() {
List<String> watchExpressions = new ArrayList<String>();
final List<? extends WatchNode> children = myRootNode.getAllChildren();
if (children != null) {
for (WatchNode child : children) {
watchExpressions.add(child.getExpression());
}
}
mySessionData.setWatchExpressions(ArrayUtil.toStringArray(watchExpressions));
}
@Override
public boolean update(final DnDEvent aEvent) {
Object object = aEvent.getAttachedObject();
boolean possible = false;
if (object instanceof XValueNodeImpl[]) {
possible = true;
}
else if (object instanceof EventInfo) {
possible = ((EventInfo)object).getTextForFlavor(DataFlavor.stringFlavor) != null;
}
aEvent.setDropPossible(possible, XDebuggerBundle.message("xdebugger.drop.text.add.to.watches"));
return true;
}
@Override
public void drop(final DnDEvent aEvent) {
Object object = aEvent.getAttachedObject();
if (object instanceof XValueNodeImpl[]) {
final XValueNodeImpl[] nodes = (XValueNodeImpl[])object;
for (XValueNodeImpl node : nodes) {
String expression = node.getValueContainer().getEvaluationExpression();
if (expression != null) {
addWatchExpression(expression, -1, false);
}
}
}
else if (object instanceof EventInfo) {
String text = ((EventInfo)object).getTextForFlavor(DataFlavor.stringFlavor);
if (text != null) {
addWatchExpression(text, -1, false);
}
}
}
@Override
public void cleanUpOnLeave() {
}
@Override
public void updateDraggedImage(final Image image, final Point dropPoint, final Point imageOffset) {
}
}
@@ -16,10 +16,12 @@
package com.intellij.xdebugger.impl.frame.actions;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.xdebugger.impl.frame.XWatchesView;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import com.intellij.xdebugger.impl.ui.tree.nodes.WatchNode;
import com.intellij.xdebugger.impl.ui.tree.nodes.WatchesRootNode;
import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -35,7 +37,7 @@ public class XEditWatchAction extends XWatchesTreeActionBase {
}
@Override
protected void perform(AnActionEvent e, XDebuggerTree tree) {
protected void perform(@NotNull AnActionEvent e, @NotNull XDebuggerTree tree, @NotNull XWatchesView watchesView) {
List<? extends WatchNode> watchNodes = getSelectedNodes(tree, WatchNode.class);
if (watchNodes.size() != 1) return;
@@ -16,16 +16,18 @@
package com.intellij.xdebugger.impl.frame.actions;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.xdebugger.impl.frame.XWatchesView;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import com.intellij.xdebugger.impl.ui.tree.nodes.WatchesRootNode;
import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode;
import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
public class XNewWatchAction extends XWatchesTreeActionBase {
@Override
protected void perform(AnActionEvent e, XDebuggerTree tree) {
protected void perform(@NotNull AnActionEvent e, @NotNull XDebuggerTree tree, @NotNull XWatchesView watchesView) {
XDebuggerTreeNode root = tree.getRoot();
if (root instanceof WatchesRootNode) {
final WatchesRootNode watchesRoot = (WatchesRootNode)root;
@@ -16,8 +16,7 @@
package com.intellij.xdebugger.impl.frame.actions;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.intellij.xdebugger.impl.ui.XDebugSessionTab;
import com.intellij.xdebugger.impl.frame.XWatchesView;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import org.jetbrains.annotations.NotNull;
@@ -26,15 +25,12 @@ import org.jetbrains.annotations.NotNull;
*/
public class XRemoveAllWatchesAction extends XWatchesTreeActionBase {
@Override
protected boolean isEnabled(AnActionEvent e, @NotNull XDebuggerTree tree) {
return tree.getRoot().getChildCount() > 0 && (tree.getSession() instanceof XDebugSessionImpl);
protected boolean isEnabled(@NotNull AnActionEvent e, @NotNull XDebuggerTree tree) {
return tree.getRoot().getChildCount() > 0;
}
@Override
protected void perform(AnActionEvent e, XDebuggerTree tree) {
if (tree.getSession() instanceof XDebugSessionImpl) {
XDebugSessionTab tab = ((XDebugSessionImpl)tree.getSession()).getSessionTab();
tab.getWatchesView().removeAllWatches();
}
protected void perform(@NotNull AnActionEvent e, @NotNull XDebuggerTree tree, @NotNull XWatchesView watchesView) {
watchesView.removeAllWatches();
}
}
@@ -16,8 +16,7 @@
package com.intellij.xdebugger.impl.frame.actions;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.intellij.xdebugger.impl.ui.XDebugSessionTab;
import com.intellij.xdebugger.impl.frame.XWatchesView;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode;
import org.jetbrains.annotations.NotNull;
@@ -28,16 +27,13 @@ import java.util.List;
* @author nik
*/
public class XRemoveWatchAction extends XWatchesTreeActionBase {
protected boolean isEnabled(final AnActionEvent e, @NotNull XDebuggerTree tree) {
return !getSelectedNodes(tree, XDebuggerTreeNode.class).isEmpty() && (tree.getSession() instanceof XDebugSessionImpl);
protected boolean isEnabled(@NotNull final AnActionEvent e, @NotNull XDebuggerTree tree) {
return !getSelectedNodes(tree, XDebuggerTreeNode.class).isEmpty();
}
@Override
protected void perform(AnActionEvent e, XDebuggerTree tree) {
protected void perform(@NotNull AnActionEvent e, @NotNull XDebuggerTree tree, @NotNull XWatchesView watchesView) {
List<? extends XDebuggerTreeNode> nodes = getSelectedNodes(tree, XDebuggerTreeNode.class);
if (tree.getSession() instanceof XDebugSessionImpl) {
XDebugSessionTab tab = ((XDebugSessionImpl)tree.getSession()).getSessionTab();
tab.getWatchesView().removeWatches(nodes);
}
watchesView.removeWatches(nodes);
}
}
@@ -17,6 +17,7 @@ package com.intellij.xdebugger.impl.frame.actions;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.xdebugger.impl.frame.XWatchesView;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import org.jetbrains.annotations.NotNull;
@@ -45,21 +46,23 @@ public abstract class XWatchesTreeActionBase extends AnAction {
public void update(final AnActionEvent e) {
final XDebuggerTree tree = XDebuggerTree.getTree(e);
boolean enabled = tree != null && isEnabled(e, tree);
XWatchesView watchesView = e.getData(XWatchesView.DATA_KEY);
boolean enabled = tree != null && watchesView != null && isEnabled(e, tree);
e.getPresentation().setEnabled(enabled);
}
@Override
public void actionPerformed(AnActionEvent e) {
final XDebuggerTree tree = XDebuggerTree.getTree(e);
if (tree != null) {
perform(e, tree);
XWatchesView watchesView = e.getData(XWatchesView.DATA_KEY);
if (tree != null && watchesView != null) {
perform(e, tree, watchesView);
}
}
protected abstract void perform(AnActionEvent e, XDebuggerTree tree);
protected abstract void perform(@NotNull AnActionEvent e, @NotNull XDebuggerTree tree, @NotNull XWatchesView watchesView);
protected boolean isEnabled(AnActionEvent e, @NotNull XDebuggerTree tree) {
protected boolean isEnabled(@NotNull AnActionEvent e, @NotNull XDebuggerTree tree) {
return true;
}
}
@@ -41,12 +41,10 @@ import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebuggerBundle;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.frame.XDebugViewBase;
import com.intellij.xdebugger.impl.frame.XFramesView;
import com.intellij.xdebugger.impl.frame.XVariablesView;
import com.intellij.xdebugger.impl.frame.XWatchesView;
import com.intellij.xdebugger.impl.frame.*;
import com.intellij.xdebugger.impl.ui.tree.actions.SortValuesToggleAction;
import com.intellij.xdebugger.ui.XDebugTabLayouter;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -58,7 +56,7 @@ import java.util.List;
* @author spleaner
*/
public class XDebugSessionTab extends DebuggerSessionTabBase {
private XWatchesView myWatchesView;
private XWatchesViewImpl myWatchesView;
private final List<XDebugViewBase> myViews = new ArrayList<XDebugViewBase>();
public XDebugSessionTab(@NotNull final Project project, @NotNull final XDebugSessionImpl session, final @Nullable Icon icon,
@@ -88,7 +86,7 @@ public class XDebugSessionTab extends DebuggerSessionTabBase {
}
private Content createWatchesContent(final XDebugSession session, final XDebugSessionData sessionData) {
myWatchesView = new XWatchesView(session, this, sessionData);
myWatchesView = new XWatchesViewImpl(session, this, sessionData);
myViews.add(myWatchesView);
Content watchesContent = myUi.createContent(DebuggerContentInfo.WATCHES_CONTENT, myWatchesView.getMainPanel(),
XDebuggerBundle.message("debugger.session.tab.watches.title"), AllIcons.Debugger.Watches, null);
@@ -127,6 +125,16 @@ public class XDebugSessionTab extends DebuggerSessionTabBase {
myUi.addContent(createFramesContent(session), 0, PlaceInGrid.left, false);
myUi.addContent(createVariablesContent(session), 0, PlaceInGrid.center, false);
myUi.addContent(createWatchesContent(session, sessionData), 0, PlaceInGrid.right, false);
myUi.getContentManager().addDataProvider(new DataProvider() {
@Nullable
@Override
public Object getData(@NonNls String dataId) {
if (XWatchesView.DATA_KEY.is(dataId)) {
return myWatchesView;
}
return null;
}
});
XDebugTabLayouter layouter = debugProcess.createTabLayouter();
Content consoleContent = layouter.registerConsoleContent(myUi, myConsole);
attachNotificationTo(consoleContent);
@@ -28,10 +28,10 @@ import com.intellij.ui.TreeSpeedSearch;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.Convertor;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.XStackFrameAwareSession;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.frame.XDebuggerTreeNodeHyperlink;
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.frame.XValueMarkers;
import com.intellij.xdebugger.impl.ui.tree.nodes.*;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -73,14 +73,14 @@ public class XDebuggerTree extends DnDAwareTree implements DataProvider, Disposa
private final XDebuggerEditorsProvider myEditorsProvider;
private XSourcePosition mySourcePosition;
private final List<XDebuggerTreeListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
private final XStackFrameAwareSession mySession;
private final XValueMarkers<?,?> myValueMarkers;
public XDebuggerTree(final @NotNull XStackFrameAwareSession session,
public XDebuggerTree(final @NotNull Project project,
final @NotNull XDebuggerEditorsProvider editorsProvider,
final @Nullable XSourcePosition sourcePosition,
final @NotNull String popupActionGroupId) {
mySession = session;
myProject = session.getProject();
final @NotNull String popupActionGroupId, @Nullable XValueMarkers<?, ?> valueMarkers) {
myValueMarkers = valueMarkers;
myProject = project;
myEditorsProvider = editorsProvider;
mySourcePosition = sourcePosition;
myTreeModel = new DefaultTreeModel(null);
@@ -176,9 +176,9 @@ public class XDebuggerTree extends DnDAwareTree implements DataProvider, Disposa
return myProject;
}
@NotNull
public XStackFrameAwareSession getSession() {
return mySession;
@Nullable
public XValueMarkers<?, ?> getValueMarkers() {
return myValueMarkers;
}
public DefaultTreeModel getTreeModel() {
@@ -20,14 +20,15 @@ import com.intellij.ide.dnd.DnDDragStartBean;
import com.intellij.ide.dnd.DnDSource;
import com.intellij.ide.dnd.aware.DnDAwareTree;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.xdebugger.XDebuggerBundle;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.XStackFrameAwareSession;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.impl.frame.XValueMarkers;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -43,10 +44,10 @@ public class XDebuggerTreePanel implements DnDSource {
private final XDebuggerTree myTree;
private final JPanel myMainPanel;
public XDebuggerTreePanel(final @NotNull XStackFrameAwareSession session, final @NotNull XDebuggerEditorsProvider editorsProvider,
public XDebuggerTreePanel(final @NotNull Project project, final @NotNull XDebuggerEditorsProvider editorsProvider,
@NotNull Disposable parentDisposable, final @Nullable XSourcePosition sourcePosition,
@NotNull @NonNls final String popupActionGroupId) {
myTree = new XDebuggerTree(session, editorsProvider, sourcePosition, popupActionGroupId);
@NotNull @NonNls final String popupActionGroupId, @Nullable XValueMarkers<?, ?> markers) {
myTree = new XDebuggerTree(project, editorsProvider, sourcePosition, popupActionGroupId, markers);
myMainPanel = new JPanel(new BorderLayout());
myMainPanel.add(ScrollPaneFactory.createScrollPane(myTree), BorderLayout.CENTER);
Disposer.register(parentDisposable, myTree);
@@ -15,15 +15,16 @@
*/
package com.intellij.xdebugger.impl.ui.tree;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Pair;
import com.intellij.xdebugger.XStackFrameAwareSession;
import com.intellij.xdebugger.XDebuggerBundle;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.frame.XValue;
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.evaluate.quick.XValueHintTreeComponent;
import com.intellij.xdebugger.impl.frame.XValueMarkers;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -36,13 +37,18 @@ import javax.swing.*;
public class XInspectDialog extends DialogWrapper {
private final XValueHintTreeComponent myTreePanel;
public XInspectDialog(XStackFrameAwareSession session, XDebuggerEditorsProvider editorsProvider, XSourcePosition sourcePosition, @NotNull String name, @NotNull XValue value) {
super(session.getProject(), false);
public XInspectDialog(@NotNull Project project,
XDebuggerEditorsProvider editorsProvider,
XSourcePosition sourcePosition,
@NotNull String name,
@NotNull XValue value,
XValueMarkers<?, ?> markers) {
super(project, false);
setTitle(XDebuggerBundle.message("inspect.value.dialog.title", name));
setModal(false);
XDebuggerTree tree = new XDebuggerTree(session, editorsProvider, sourcePosition, XDebuggerActions.INSPECT_TREE_POPUP_GROUP);
XDebuggerTree tree = new XDebuggerTree(project, editorsProvider, sourcePosition, XDebuggerActions.INSPECT_TREE_POPUP_GROUP, markers);
myTreePanel = new XValueHintTreeComponent(null, tree, Pair.create(value, name));
init();
}
@@ -16,9 +16,7 @@
package com.intellij.xdebugger.impl.ui.tree.actions;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.xdebugger.XStackFrameAwareSession;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.intellij.xdebugger.impl.ui.XDebugSessionTab;
import com.intellij.xdebugger.impl.frame.XWatchesView;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import org.jetbrains.annotations.NotNull;
@@ -27,19 +25,16 @@ import org.jetbrains.annotations.NotNull;
*/
public class XAddToWatchesAction extends XDebuggerTreeActionBase {
@Override
protected boolean isEnabled(final XValueNodeImpl node) {
return super.isEnabled(node) && node.getValueContainer().getEvaluationExpression() != null && (node.getTree().getSession() instanceof XDebugSessionImpl);
protected boolean isEnabled(@NotNull final XValueNodeImpl node, @NotNull AnActionEvent e) {
return super.isEnabled(node, e) && node.getValueContainer().getEvaluationExpression() != null && e.getData(XWatchesView.DATA_KEY) != null;
}
@Override
protected void perform(final XValueNodeImpl node, @NotNull final String nodeName, final AnActionEvent e) {
XStackFrameAwareSession session = node.getTree().getSession();
if (session instanceof XDebugSessionImpl) {
XDebugSessionTab sessionTab = ((XDebugSessionImpl)session).getSessionTab();
String expression = node.getValueContainer().getEvaluationExpression();
if (expression != null) {
sessionTab.getWatchesView().addWatchExpression(expression, -1, true);
}
XWatchesView watchesView = e.getData(XWatchesView.DATA_KEY);
String expression = node.getValueContainer().getEvaluationExpression();
if (watchesView != null && expression != null) {
watchesView.addWatchExpression(expression, -1, true);
}
}
}
@@ -46,10 +46,10 @@ public abstract class XDebuggerTreeActionBase extends AnAction {
@Override
public void update(final AnActionEvent e) {
XValueNodeImpl node = getSelectedNode(e.getDataContext());
e.getPresentation().setEnabled(node != null && isEnabled(node));
e.getPresentation().setEnabled(node != null && isEnabled(node, e));
}
protected boolean isEnabled(final XValueNodeImpl node) {
protected boolean isEnabled(final @NotNull XValueNodeImpl node, @NotNull AnActionEvent e) {
return node.getName() != null;
}
@@ -15,6 +15,7 @@
*/
package com.intellij.xdebugger.impl.ui.tree.actions;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataContext;
@@ -26,8 +27,8 @@ import com.intellij.util.Alarm;
import com.intellij.util.SmartList;
import com.intellij.util.concurrency.Semaphore;
import com.intellij.xdebugger.XDebuggerBundle;
import com.intellij.xdebugger.XStackFrameAwareSession;
import com.intellij.xdebugger.frame.XFullValueEvaluator;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import com.intellij.xdebugger.impl.ui.tree.nodes.WatchMessageNode;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
@@ -83,7 +84,7 @@ public abstract class XFetchValueActionBase extends AnAction {
valueCollector.add(StringUtil.notNullize(valueNode.getRawValue()));
}
else {
startFetchingValue(fullValueEvaluator, new CopyValueEvaluationCallback(valueNode.getTree().getSession(), valueCollector));
startFetchingValue(fullValueEvaluator, new CopyValueEvaluationCallback(valueNode, valueCollector));
}
}
else if (node instanceof WatchMessageNode) {
@@ -133,21 +134,21 @@ public abstract class XFetchValueActionBase extends AnAction {
}
private static final class CopyValueEvaluationCallback implements XFullValueEvaluator.XFullValueEvaluationCallback {
private final XStackFrameAwareSession session;
private final XValueNodeImpl myNode;
private final int valueIndex;
private final ValueCollector valueCollector;
private final int myValueIndex;
private final ValueCollector myValueCollector;
private volatile boolean evaluated;
private volatile boolean canceled;
private final Semaphore semaphore;
private volatile boolean myEvaluated;
private volatile boolean myCanceled;
private final Semaphore mySemaphore;
public CopyValueEvaluationCallback(XStackFrameAwareSession session, ValueCollector valueCollector) {
this.session = session;
this.valueCollector = valueCollector;
valueIndex = valueCollector.acquire();
semaphore = new Semaphore();
semaphore.down();
public CopyValueEvaluationCallback(@NotNull XValueNodeImpl node, ValueCollector valueCollector) {
myNode = node;
myValueCollector = valueCollector;
myValueIndex = valueCollector.acquire();
mySemaphore = new Semaphore();
mySemaphore.down();
}
@Override
@@ -163,7 +164,8 @@ public abstract class XFetchValueActionBase extends AnAction {
@Override
public void errorOccurred(@NotNull String errorMessage) {
try {
session.reportError(XDebuggerBundle.message("load.value.task.error", errorMessage));
String message = XDebuggerBundle.message("load.value.task.error", errorMessage);
XDebugSessionImpl.NOTIFICATION_GROUP.createNotification(message, NotificationType.ERROR).notify(myNode.getTree().getProject());
}
finally {
evaluationComplete(errorMessage);
@@ -172,31 +174,31 @@ public abstract class XFetchValueActionBase extends AnAction {
private void evaluationComplete(String value) {
try {
evaluated = true;
semaphore.up();
myEvaluated = true;
mySemaphore.up();
}
finally {
valueCollector.evaluationComplete(valueIndex, value, session.getProject());
myValueCollector.evaluationComplete(myValueIndex, value, myNode.getTree().getProject());
}
}
@Override
public boolean isObsolete() {
return canceled;
return myCanceled;
}
public void showProgress() {
if (evaluated || session.isStopped()) return;
if (myEvaluated || myNode.isObsolete()) return;
new Task.Backgroundable(session.getProject(), XDebuggerBundle.message("load.value.task.text")) {
new Task.Backgroundable(myNode.getTree().getProject(), XDebuggerBundle.message("load.value.task.text")) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
indicator.setIndeterminate(true);
int i = 0;
while (!canceled && !evaluated) {
while (!myCanceled && !myEvaluated) {
indicator.checkCanceled();
indicator.setFraction(((i++) % 100) * 0.01);
semaphore.waitFor(300);
mySemaphore.waitFor(300);
}
}
@@ -207,7 +209,7 @@ public abstract class XFetchValueActionBase extends AnAction {
@Override
public void onCancel() {
canceled = true;
myCanceled = true;
}
}.queue();
}
@@ -30,7 +30,8 @@ public class XInspectAction extends XDebuggerTreeActionBase {
protected void perform(XValueNodeImpl node, @NotNull final String nodeName, AnActionEvent e) {
XDebuggerTree tree = node.getTree();
XValue value = node.getValueContainer();
XInspectDialog dialog = new XInspectDialog(tree.getSession(), tree.getEditorsProvider(), tree.getSourcePosition(), nodeName, value);
XInspectDialog dialog = new XInspectDialog(tree.getProject(), tree.getEditorsProvider(), tree.getSourcePosition(), nodeName, value,
tree.getValueMarkers());
dialog.show();
}
}
@@ -15,9 +15,11 @@
*/
package com.intellij.xdebugger.impl.ui.tree.actions;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.xdebugger.frame.XNavigatable;
import com.intellij.xdebugger.frame.XValue;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import org.jetbrains.annotations.NotNull;
/**
* @author nik
@@ -29,7 +31,7 @@ public class XJumpToSourceAction extends XJumpToSourceActionBase {
}
@Override
protected boolean isEnabled(XValueNodeImpl node) {
return super.isEnabled(node) && node.getValueContainer().canNavigateToSource();
protected boolean isEnabled(@NotNull XValueNodeImpl node, @NotNull AnActionEvent e) {
return super.isEnabled(node, e) && node.getValueContainer().canNavigateToSource();
}
}
@@ -15,9 +15,11 @@
*/
package com.intellij.xdebugger.impl.ui.tree.actions;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.xdebugger.frame.XNavigatable;
import com.intellij.xdebugger.frame.XValue;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import org.jetbrains.annotations.NotNull;
/**
* @author nik
@@ -29,7 +31,7 @@ public class XJumpToTypeSourceAction extends XJumpToSourceActionBase {
}
@Override
protected boolean isEnabled(XValueNodeImpl node) {
return super.isEnabled(node) && node.getValueContainer().canNavigateToTypeSource();
protected boolean isEnabled(@NotNull XValueNodeImpl node, @NotNull AnActionEvent e) {
return super.isEnabled(node, e) && node.getValueContainer().canNavigateToTypeSource();
}
}
@@ -42,8 +42,8 @@ public class XSetValueAction extends XDebuggerTreeActionBase {
}
@Override
protected boolean isEnabled(XValueNodeImpl node) {
return super.isEnabled(node) && node.getValueContainer().getModifier() != null;
protected boolean isEnabled(@NotNull XValueNodeImpl node, @NotNull AnActionEvent e) {
return super.isEnabled(node, e) && node.getValueContainer().getModifier() != null;
}
protected void perform(final XValueNodeImpl node, @NotNull final String nodeName, final AnActionEvent e) {
@@ -15,9 +15,11 @@
*/
package com.intellij.xdebugger.impl.ui.tree.nodes;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
import com.intellij.xdebugger.frame.XValue;
import com.intellij.xdebugger.impl.frame.WatchInplaceEditor;
import com.intellij.xdebugger.impl.frame.XWatchesView;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import org.jetbrains.annotations.NotNull;
@@ -33,12 +35,19 @@ import java.util.List;
* @author nik
*/
public class WatchesRootNode extends XDebuggerTreeNode {
private final XDebugSession mySession;
private final XWatchesView myWatchesView;
private List<WatchNode> myChildren;
private List<XDebuggerTreeNode> myLoadedChildren;
private XDebuggerEvaluator myCurrentEvaluator;
public WatchesRootNode(final XDebuggerTree tree, String[] watchExpressions) {
public WatchesRootNode(final @NotNull XDebuggerTree tree,
@NotNull XDebugSession session,
@NotNull XWatchesView watchesView,
@NotNull String[] watchExpressions) {
super(tree, null, false);
mySession = session;
myWatchesView = watchesView;
myChildren = new ArrayList<WatchNode>();
for (String watchExpression : watchExpressions) {
myChildren.add(WatchMessageNode.createMessageNode(tree, this, watchExpression));
@@ -177,7 +186,7 @@ public class WatchesRootNode extends XDebuggerTreeNode {
myChildren.set(index, messageNode);
fireNodeStructureChanged(messageNode);
}
WatchInplaceEditor editor = new WatchInplaceEditor(this, messageNode, "watch", node);
WatchInplaceEditor editor = new WatchInplaceEditor(this, mySession, myWatchesView, messageNode, "watch", node);
editor.show();
}
@@ -23,7 +23,6 @@ import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.NotNullFunction;
import com.intellij.xdebugger.frame.*;
import com.intellij.xdebugger.frame.presentation.XValuePresentation;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.intellij.xdebugger.impl.frame.XValueMarkers;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
@@ -133,15 +132,13 @@ public class XValueNodeImpl extends XValueContainerNode<XValue> implements XValu
private void updateText() {
myText.clear();
if (myTree.getSession() instanceof XDebugSessionImpl) {
XValueMarkers<?,?> markers = ((XDebugSessionImpl)myTree.getSession()).getValueMarkers();
XValueMarkers<?, ?> markers = myTree.getValueMarkers();
if (markers != null) {
ValueMarkup markup = markers.getMarkup(myValueContainer);
if (markup != null) {
myText.append("[" + markup.getText() + "] ", new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, markup.getColor()));
}
}
}
appendName();
buildText(myValuePresentation, myText);
}