import com.intellij.debugger.ui.DebuggerContentInfo;
import com.intellij.execution.ui.layout.impl.RunnerContentUi;
+import com.intellij.icons.AllIcons;
import com.intellij.ide.DataManager;
import com.intellij.ide.dnd.DnDEvent;
import com.intellij.ide.dnd.DnDManager;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.EmptyRunnable;
import com.intellij.openapi.util.SystemInfo;
-import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.*;
import com.intellij.ui.border.CustomLineBorder;
import com.intellij.util.Alarm;
private final CompositeDisposable myDisposables = new CompositeDisposable();
private boolean myRebuildNeeded;
+ private final boolean myWatchesInVariables;
- public XWatchesViewImpl(@NotNull XDebugSessionImpl session) {
+ public XWatchesViewImpl(@NotNull XDebugSessionImpl session, boolean watchesInVariables) {
super(session);
+ myWatchesInVariables = watchesInVariables;
ActionManager actionManager = ActionManager.getInstance();
return e.getPresentation().isEnabled();
});
decorator.addExtraAction(AnActionButton.fromAction(copyAction));
+ decorator.addExtraAction(
+ new ToggleActionButton(XDebuggerBundle.message("debugger.session.tab.show.watches.in.variables"), AllIcons.Debugger.Watches) {
+ @Override
+ public boolean isSelected(AnActionEvent e) {
+ XDebugSessionTab tab = session.getSessionTab();
+ return tab == null || tab.isWatchesInVariables();
+ }
+
+ @Override
+ public void setSelected(AnActionEvent e, boolean state) {
+ XDebugSessionTab tab = session.getSessionTab();
+ if (tab != null) {
+ tab.setWatchesInVariables(!tab.isWatchesInVariables());
+ }
+ }
+ });
decorator.setMoveUpAction(button -> {
List<? extends WatchNode> nodes = XWatchesTreeActionBase.getSelectedNodes(getTree(), WatchNode.class);
assert nodes.size() == 1;
decorator.setToolbarBorder(border);
decorator.setPanelBorder(BorderFactory.createEmptyBorder());
getPanel().removeAll();
- if (Registry.is("debugger.watches.in.variables")) {
+ if (myWatchesInVariables) {
decorator.setToolbarPosition(ActionToolbarPosition.LEFT);
}
else {
public void dispose() {
Disposer.dispose(myDisposables);
DnDManager.getInstance().unregisterTarget(this, getTree());
+ super.dispose();
}
private static boolean isAboveSelectedItem(MouseEvent event, XDebuggerTree watchTree) {
@Override
public void processSessionEvent(@NotNull final SessionEvent event) {
- if (Registry.is("debugger.watches.in.variables") ||
+ if (myWatchesInVariables ||
getPanel().isShowing() ||
ApplicationManager.getApplication().isUnitTestMode()) {
myRebuildNeeded = false;
@Override
protected XValueContainerNode createNewRootNode(@Nullable XStackFrame stackFrame) {
- WatchesRootNode node = new WatchesRootNode(getTree(), this, getExpressions(), stackFrame);
+ WatchesRootNode node = new WatchesRootNode(getTree(), this, getExpressions(), stackFrame, myWatchesInVariables);
myRootNode = node;
getTree().setRoot(node, false);
return node;
@Override
protected void addEmptyMessage(XValueContainerNode root) {
- if (Registry.is("debugger.watches.in.variables")) {
+ if (myWatchesInVariables) {
super.addEmptyMessage(root);
}
}
import com.intellij.ui.content.tabs.PinToolwindowTabAction;
import com.intellij.util.SystemProperties;
import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.hash.LinkedHashMap;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebuggerBundle;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
public static final DataKey<XDebugSessionTab> TAB_KEY = DataKey.create("XDebugSessionTab");
private XWatchesViewImpl myWatchesView;
- private final List<XDebugView> myViews = ContainerUtil.newArrayList();
+ private boolean myWatchesInVariables = Registry.is("debugger.watches.in.variables");
+ private final LinkedHashMap<String, XDebugView> myViews = new LinkedHashMap<>();
@Nullable
private XDebugSessionImpl mySession;
setSession(session, environment, icon);
myUi.addContent(createFramesContent(), 0, PlaceInGrid.left, false);
- myUi.addContent(createVariablesContent(session), 0, PlaceInGrid.center, false);
- if (!Registry.is("debugger.watches.in.variables")) {
- myUi.addContent(createWatchesContent(session), 0, PlaceInGrid.right, false);
- }
-
- for (XDebugView view : myViews) {
- Disposer.register(myRunContentDescriptor, view);
- }
+ addVariablesAndWatches(session);
attachToSession(session);
rebuildViews();
}
+ private void addVariablesAndWatches(@NotNull XDebugSessionImpl session) {
+ myUi.addContent(createVariablesContent(session), 0, PlaceInGrid.center, false);
+ if (!myWatchesInVariables) {
+ myUi.addContent(createWatchesContent(session), 0, PlaceInGrid.right, false);
+ }
+ }
+
private void setSession(@NotNull XDebugSessionImpl session, @Nullable ExecutionEnvironment environment, @Nullable Icon icon) {
myEnvironment = environment;
mySession = session;
private Content createVariablesContent(@NotNull XDebugSessionImpl session) {
XVariablesView variablesView;
- if (Registry.is("debugger.watches.in.variables")) {
- variablesView = myWatchesView = new XWatchesViewImpl(session);
+ if (myWatchesInVariables) {
+ variablesView = myWatchesView = new XWatchesViewImpl(session, myWatchesInVariables);
}
else {
variablesView = new XVariablesView(session);
}
- myViews.add(variablesView);
+ registerView(DebuggerContentInfo.VARIABLES_CONTENT, variablesView);
Content result = myUi.createContent(DebuggerContentInfo.VARIABLES_CONTENT, variablesView.getPanel(),
XDebuggerBundle.message("debugger.session.tab.variables.title"),
AllIcons.Debugger.Value, null);
}
private Content createWatchesContent(@NotNull XDebugSessionImpl session) {
- myWatchesView = new XWatchesViewImpl(session);
- myViews.add(myWatchesView);
+ myWatchesView = new XWatchesViewImpl(session, myWatchesInVariables);
+ registerView(DebuggerContentInfo.WATCHES_CONTENT, myWatchesView);
Content watchesContent = myUi.createContent(DebuggerContentInfo.WATCHES_CONTENT, myWatchesView.getPanel(),
XDebuggerBundle.message("debugger.session.tab.watches.title"), AllIcons.Debugger.Watches, null);
watchesContent.setCloseable(false);
@NotNull
private Content createFramesContent() {
XFramesView framesView = new XFramesView(myProject);
- myViews.add(framesView);
+ registerView(DebuggerContentInfo.FRAME_CONTENT, framesView);
Content framesContent = myUi.createContent(DebuggerContentInfo.FRAME_CONTENT, framesView.getMainPanel(),
XDebuggerBundle.message("debugger.session.tab.frames.title"), AllIcons.Debugger.Frame, null);
framesContent.setCloseable(false);
public void rebuildViews() {
AppUIUtil.invokeLaterIfProjectAlive(myProject, () -> {
- for (XDebugView view : myViews) {
+ for (XDebugView view : myViews.values()) {
view.processSessionEvent(XDebugView.SessionEvent.SETTINGS_CHANGED);
}
});
}
private void attachToSession(@NotNull XDebugSessionImpl session) {
- for (XDebugView view : myViews) {
- session.addSessionListener(new XDebugViewSessionListener(view), myRunContentDescriptor);
+ for (XDebugView view : myViews.values()) {
+ attachViewToSession(session, view);
}
XDebugTabLayouter layouter = session.getDebugProcess().createTabLayouter();
}
}
+ private static void attachViewToSession(@NotNull XDebugSessionImpl session, @Nullable XDebugView view) {
+ if (view != null) {
+ session.addSessionListener(new XDebugViewSessionListener(view), view);
+ }
+ }
+
public void detachFromSession() {
assert mySession != null;
mySession = null;
return myRunContentDescriptor;
}
+ public boolean isWatchesInVariables() {
+ return myWatchesInVariables;
+ }
+
+ public void setWatchesInVariables(boolean watchesInVariables) {
+ if (myWatchesInVariables != watchesInVariables) {
+ myWatchesInVariables = watchesInVariables;
+ Registry.get("debugger.watches.in.variables").setValue(watchesInVariables);
+ if (mySession != null) {
+ removeContent(DebuggerContentInfo.VARIABLES_CONTENT);
+ removeContent(DebuggerContentInfo.WATCHES_CONTENT);
+ addVariablesAndWatches(mySession);
+ XDebugView variablesView = myViews.get(DebuggerContentInfo.VARIABLES_CONTENT);
+ if (variablesView != null) {
+ Disposer.register(myRunContentDescriptor, variablesView);
+ }
+ attachViewToSession(mySession, variablesView);
+ if (!myWatchesInVariables) {
+ XDebugView watchesView = myViews.get(DebuggerContentInfo.WATCHES_CONTENT);
+ if (watchesView != null) {
+ Disposer.register(myRunContentDescriptor, watchesView);
+ }
+ attachViewToSession(mySession, watchesView);
+ }
+ rebuildViews();
+ }
+ }
+ }
+
+ private void registerView(String contentId, @NotNull XDebugView view) {
+ myViews.put(contentId, view);
+ Disposer.register(myRunContentDescriptor, view);
+ }
+
+ private void removeContent(String contentId) {
+ myUi.removeContent(myUi.findContent(contentId), true);
+ XDebugView view = myViews.remove(contentId);
+ if (view != null) {
+ Disposer.dispose(view);
+ }
+ }
+
private static class ToggleSortValuesAction extends SortValuesToggleAction {
private final boolean myShowIcon;
*/
package com.intellij.xdebugger.impl.ui.tree.nodes;
-import com.intellij.openapi.util.registry.Registry;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.tree.TreeUtil;
public WatchesRootNode(@NotNull XDebuggerTree tree,
@NotNull XWatchesView watchesView,
@NotNull XExpression[] expressions) {
- this(tree, watchesView, expressions, null);
+ this(tree, watchesView, expressions, null, false);
}
public WatchesRootNode(@NotNull XDebuggerTree tree,
@NotNull XWatchesView watchesView,
@NotNull XExpression[] expressions,
- @Nullable XStackFrame stackFrame) {
+ @Nullable XStackFrame stackFrame,
+ boolean watchesInVariables) {
super(tree, null, new XValueContainer() {
@Override
public void computeChildren(@NotNull XCompositeNode node) {
- if (stackFrame != null && Registry.is("debugger.watches.in.variables")) {
+ if (stackFrame != null && watchesInVariables) {
stackFrame.computeChildren(node);
}
else {