xdebugger: correctly dispose views and show popup tree for 'value hint' tree (IDEA-56249)

This commit is contained in:
nik
2010-11-19 15:19:31 +03:00
parent e0b50e3291
commit a548e34d3f
10 changed files with 59 additions and 49 deletions
@@ -698,6 +698,11 @@
<reference ref="XDebugger.CopyValue"/>
</group>
<group id="XDebugger.Value.Hint.Tree.Popup">
<reference ref="XDebugger.CopyValue"/>
<reference ref="XDebugger.AddToWatches"/>
</group>
<group id="RunnerLayoutActions">
<group id="Runner.Layout" icon="/debugger/restoreLayout.png" popup="true">
<action id="Runner.RestoreLayout" class="com.intellij.execution.ui.layout.actions.RestoreLayoutAction"/>
@@ -44,6 +44,7 @@ public interface XDebuggerActions {
@NonNls String VARIABLES_TREE_POPUP_GROUP = "XDebugger.Variables.Tree.Popup";
@NonNls String WATCHES_TREE_POPUP_GROUP = "XDebugger.Watches.Tree.Popup";
@NonNls String WATCHES_TREE_TOOLBAR_GROUP = "XDebugger.Watches.Tree.Toolbar";
@NonNls String VALUE_HINT_TREE_POPUP_GROUP = "XDebugger.Value.Hint.Tree.Popup";
@NonNls String ADD_TO_WATCH = "Debugger.AddToWatch";
@@ -63,7 +63,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
setOKButtonText(XDebuggerBundle.message("xdebugger.button.evaluate"));
setCancelButtonText(XDebuggerBundle.message("xdebugger.evaluate.dialog.close"));
myTreePanel = new XDebuggerTreePanel(session, editorsProvider, sourcePosition, XDebuggerActions.EVALUATE_DIALOG_TREE_POPUP_GROUP);
myTreePanel = new XDebuggerTreePanel(session, editorsProvider, myDisposable, sourcePosition, XDebuggerActions.EVALUATE_DIALOG_TREE_POPUP_GROUP);
myResultPanel = new JPanel(new BorderLayout());
myResultPanel.add(new JLabel(XDebuggerBundle.message("xdebugger.evaluate.label.result")), BorderLayout.NORTH);
myResultPanel.add(myTreePanel.getMainPanel(), BorderLayout.CENTER);
@@ -149,11 +149,6 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
myInputComponent.getInputEditor().selectAll();
}
protected void dispose() {
myTreePanel.dispose();
super.dispose();
}
protected String getDimensionServiceKey() {
return "#xdebugger.evaluate";
}
@@ -33,6 +33,7 @@ import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
import com.intellij.xdebugger.frame.XFullValueEvaluator;
import com.intellij.xdebugger.frame.XValue;
import com.intellij.xdebugger.frame.XValueNode;
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.evaluate.quick.common.AbstractValueHint;
import com.intellij.xdebugger.impl.evaluate.quick.common.ValueHintType;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
@@ -142,7 +143,7 @@ public class XValueHint extends AbstractValueHint {
private void showTree(final XValue value, final String name) {
XDebuggerTree tree = new XDebuggerTree(myDebugSession, myDebugSession.getDebugProcess().getEditorsProvider(),
myDebugSession.getCurrentPosition());
myDebugSession.getCurrentPosition(), XDebuggerActions.VALUE_HINT_TREE_POPUP_GROUP);
tree.getModel().addTreeModelListener(createTreeListener(tree));
XValueHintTreeComponent component = new XValueHintTreeComponent(this, tree, Pair.create(value, name));
showTreePopup(component, tree, name);
@@ -15,10 +15,11 @@
*/
package com.intellij.xdebugger.impl.frame;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.util.Disposer;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebugSessionAdapter;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import com.intellij.openapi.Disposable;
/**
* @author nik
@@ -32,6 +33,7 @@ public abstract class XDebugViewBase implements Disposable {
mySession = session;
mySessionListener = new MyDebugSessionListener();
mySession.addSessionListener(mySessionListener);
Disposer.register(parentDisposable, this);
}
public void rebuildView() {
@@ -43,7 +43,7 @@ public class XVariablesView extends XDebugViewBase {
public XVariablesView(@NotNull XDebugSession session, final Disposable parentDisposable) {
super(session, parentDisposable);
XDebuggerEditorsProvider editorsProvider = session.getDebugProcess().getEditorsProvider();
myDebuggerTreePanel = new XDebuggerTreePanel(session, editorsProvider, null, XDebuggerActions.VARIABLES_TREE_POPUP_GROUP);
myDebuggerTreePanel = new XDebuggerTreePanel(session, editorsProvider, this, null, XDebuggerActions.VARIABLES_TREE_POPUP_GROUP);
DnDManager.getInstance().registerSource(myDebuggerTreePanel, myDebuggerTreePanel.getTree());
}
@@ -56,7 +56,7 @@ public class XWatchesView extends XDebugViewBase implements DnDNativeTarget {
public XWatchesView(final XDebugSession session, final Disposable parentDisposable, final XDebugSessionData sessionData) {
super(session, parentDisposable);
myTreePanel = new XDebuggerTreePanel(session, session.getDebugProcess().getEditorsProvider(), null,
myTreePanel = new XDebuggerTreePanel(session, session.getDebugProcess().getEditorsProvider(), this, null,
XDebuggerActions.WATCHES_TREE_POPUP_GROUP);
ActionManager actionManager = ActionManager.getInstance();
@@ -16,12 +16,11 @@
package com.intellij.xdebugger.impl.ui.tree;
import com.intellij.ide.dnd.aware.DnDAwareTree;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.changes.issueLinks.TreeLinkMouseListener;
import com.intellij.ui.PopupHandler;
import com.intellij.ui.TreeSpeedSearch;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.Convertor;
@@ -29,14 +28,18 @@ import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.frame.XDebuggerTreeNodeHyperlink;
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.ui.tree.nodes.*;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
@@ -44,7 +47,7 @@ import java.util.List;
/**
* @author nik
*/
public class XDebuggerTree extends DnDAwareTree implements DataProvider {
public class XDebuggerTree extends DnDAwareTree implements DataProvider, Disposable {
private static final DataKey<XDebuggerTree> XDEBUGGER_TREE_KEY = DataKey.create("xdebugger.tree");
private static final Convertor<TreePath,String> SPEED_SEARCH_CONVERTER = new Convertor<TreePath, String>() {
public String convert(TreePath o) {
@@ -67,8 +70,12 @@ public class XDebuggerTree extends DnDAwareTree implements DataProvider {
private XSourcePosition mySourcePosition;
private final List<XDebuggerTreeListener> myListeners = ContainerUtil.createEmptyCOWList();
private final XDebugSession mySession;
private final PopupHandler myPopupHandler;
public XDebuggerTree(final @NotNull XDebugSession session, final @NotNull XDebuggerEditorsProvider editorsProvider, final @Nullable XSourcePosition sourcePosition) {
public XDebuggerTree(final @NotNull XDebugSession session,
final @NotNull XDebuggerEditorsProvider editorsProvider,
final @Nullable XSourcePosition sourcePosition,
final @NotNull String popupActionGroupId) {
mySession = session;
myProject = session.getProject();
myEditorsProvider = editorsProvider;
@@ -104,6 +111,17 @@ public class XDebuggerTree extends DnDAwareTree implements DataProvider {
}
});
new TreeSpeedSearch(this, SPEED_SEARCH_CONVERTER);
final ActionManager actionManager = ActionManager.getInstance();
myPopupHandler = new PopupHandler() {
public void invokePopup(final Component comp, final int x, final int y) {
final ActionGroup group = (ActionGroup)actionManager.getAction(popupActionGroupId);
ActionPopupMenu popupMenu = actionManager.createActionPopupMenu(ActionPlaces.UNKNOWN, group);
popupMenu.getComponent().show(comp, x, y);
}
};
addMouseListener(myPopupHandler);
registerShortcuts();
}
public void addTreeListener(@NotNull XDebuggerTreeListener listener) {
@@ -187,6 +205,20 @@ public class XDebuggerTree extends DnDAwareTree implements DataProvider {
}
}
public void dispose() {
ActionManager actionManager = ActionManager.getInstance();
actionManager.getAction(XDebuggerActions.SET_VALUE).unregisterCustomShortcutSet(this);
actionManager.getAction(XDebuggerActions.COPY_VALUE).unregisterCustomShortcutSet(this);
actionManager.getAction(XDebuggerActions.JUMP_TO_SOURCE).unregisterCustomShortcutSet(this);
}
private void registerShortcuts() {
ActionManager actionManager = ActionManager.getInstance();
actionManager.getAction(XDebuggerActions.SET_VALUE).registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0)), this);
actionManager.getAction(XDebuggerActions.COPY_VALUE).registerCustomShortcutSet(CommonShortcuts.getCopy(), this);
actionManager.getAction(XDebuggerActions.JUMP_TO_SOURCE).registerCustomShortcutSet(CommonShortcuts.getEditSource(), this);
}
private static void markNodesObsolete(final XValueContainerNode<?> node) {
node.setObsolete();
List<XValueContainerNode<?>> loadedChildren = node.getLoadedChildren();
@@ -19,16 +19,15 @@ import com.intellij.ide.dnd.DnDAction;
import com.intellij.ide.dnd.DnDDragStartBean;
import com.intellij.ide.dnd.DnDSource;
import com.intellij.ide.dnd.aware.DnDAwareTree;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.ui.PopupHandler;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebuggerBundle;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -36,7 +35,6 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
/**
* @author nik
@@ -44,33 +42,14 @@ import java.awt.event.KeyEvent;
public class XDebuggerTreePanel implements DnDSource {
private final XDebuggerTree myTree;
private final JPanel myMainPanel;
private final PopupHandler myPopupHandler;
public XDebuggerTreePanel(final @NotNull XDebugSession session, final @NotNull XDebuggerEditorsProvider editorsProvider, final @Nullable XSourcePosition sourcePosition,
public XDebuggerTreePanel(final @NotNull XDebugSession session, final @NotNull XDebuggerEditorsProvider editorsProvider,
@NotNull Disposable parentDisposable, final @Nullable XSourcePosition sourcePosition,
@NotNull @NonNls final String popupActionGroupId) {
myTree = new XDebuggerTree(session, editorsProvider, sourcePosition);
myTree = new XDebuggerTree(session, editorsProvider, sourcePosition, popupActionGroupId);
myMainPanel = new JPanel(new BorderLayout());
myMainPanel.add(ScrollPaneFactory.createScrollPane(myTree), BorderLayout.CENTER);
final ActionManager actionManager = ActionManager.getInstance();
myPopupHandler = new PopupHandler() {
public void invokePopup(final Component comp, final int x, final int y) {
final ActionGroup group = (ActionGroup)actionManager.getAction(popupActionGroupId);
ActionPopupMenu popupMenu = actionManager.createActionPopupMenu(ActionPlaces.UNKNOWN, group);
popupMenu.getComponent().show(comp, x, y);
}
};
actionManager.getAction(XDebuggerActions.SET_VALUE).registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0)), myTree);
actionManager.getAction(XDebuggerActions.COPY_VALUE).registerCustomShortcutSet(CommonShortcuts.getCopy(), myTree);
actionManager.getAction(XDebuggerActions.JUMP_TO_SOURCE).registerCustomShortcutSet(CommonShortcuts.getEditSource(), myTree);
myTree.addMouseListener(myPopupHandler);
}
public void dispose() {
ActionManager actionManager = ActionManager.getInstance();
actionManager.getAction(XDebuggerActions.SET_VALUE).unregisterCustomShortcutSet(myTree);
actionManager.getAction(XDebuggerActions.JUMP_TO_SOURCE).unregisterCustomShortcutSet(myTree);
myTree.removeMouseListener(myPopupHandler);
Disposer.register(parentDisposable, myTree);
}
public XDebuggerTree getTree() {
@@ -38,7 +38,7 @@ public class XInspectDialog extends DialogWrapper {
super(session.getProject(), false);
setTitle(XDebuggerBundle.message("inspect.value.dialog.title", nodeName));
setModal(false);
myTreePanel = new XDebuggerTreePanel(session, editorsProvider, sourcePosition, XDebuggerActions.INSPECT_TREE_POPUP_GROUP);
myTreePanel = new XDebuggerTreePanel(session, editorsProvider, myDisposable, sourcePosition, XDebuggerActions.INSPECT_TREE_POPUP_GROUP);
XDebuggerTree tree = myTreePanel.getTree();
tree.setRoot(new XValueNodeImpl(tree, null, value), true);
init();
@@ -58,9 +58,4 @@ public class XInspectDialog extends DialogWrapper {
protected String getDimensionServiceKey() {
return "#xdebugger.XInspectDialog";
}
protected void dispose() {
myTreePanel.dispose();
super.dispose();
}
}