diff options
Diffstat (limited to 'platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui')
12 files changed, 257 insertions, 146 deletions
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/BreakpointEditor.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/BreakpointEditor.java index f51ce77d3fee..79c8dc49c398 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/BreakpointEditor.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/BreakpointEditor.java @@ -19,6 +19,7 @@ import com.intellij.codeInsight.lookup.LookupManager; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.keymap.KeymapUtil; +import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.components.labels.LinkLabel; import com.intellij.ui.components.labels.LinkListener; @@ -79,7 +80,7 @@ public class BreakpointEditor { } }); - final AnAction doneAction = new AnAction() { + final AnAction doneAction = new DumbAwareAction() { @Override public void update(AnActionEvent e) { super.update(e); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerSessionTabBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerSessionTabBase.java index 2134c0c8d4e1..053f18dd14bf 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerSessionTabBase.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerSessionTabBase.java @@ -16,7 +16,8 @@ package com.intellij.xdebugger.impl.ui; import com.intellij.debugger.ui.DebuggerContentInfo; -import com.intellij.diagnostic.logging.*; +import com.intellij.diagnostic.logging.AdditionalTabComponent; +import com.intellij.diagnostic.logging.DebuggerLogConsoleManager; import com.intellij.execution.ExecutionManager; import com.intellij.execution.configurations.RunConfigurationBase; import com.intellij.execution.configurations.RunProfile; @@ -24,6 +25,7 @@ import com.intellij.execution.executors.DefaultDebugExecutor; import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.RunContentBuilder; +import com.intellij.execution.runners.RunTab; import com.intellij.execution.ui.*; import com.intellij.execution.ui.layout.LayoutAttractionPolicy; import com.intellij.execution.ui.layout.LayoutViewOptions; @@ -48,25 +50,13 @@ import java.util.Collection; /** * @author nik */ -public abstract class DebuggerSessionTabBase extends LogConsoleManagerBase implements DebuggerLogConsoleManager { - @NotNull private final LogFilesManager myManager; - - @NotNull final String mySessionName; - @NotNull protected final RunnerLayoutUi myUi; - +public abstract class DebuggerSessionTabBase extends RunTab implements DebuggerLogConsoleManager { protected ExecutionConsole myConsole; - protected RunContentDescriptor myRunContentDescriptor; - - public DebuggerSessionTabBase(@NotNull Project project, @NotNull String runnerId, @NotNull final String sessionName, - @NotNull GlobalSearchScope searchScope) { - super(project, searchScope); - Disposer.register(project, this); - myManager = new LogFilesManager(project, this, this); - mySessionName = sessionName; + public DebuggerSessionTabBase(@NotNull Project project, @NotNull String runnerId, @NotNull String sessionName, @NotNull GlobalSearchScope searchScope) { + super(project, searchScope, runnerId, XDebuggerBundle.message("xdebugger.default.content.title"), sessionName); - myUi = RunnerLayoutUi.Factory.getInstance(project).create( - runnerId, XDebuggerBundle.message("xdebugger.default.content.title"), sessionName, this); + Disposer.register(project, this); myUi.getDefaults() .initTabDefaults(0, XDebuggerBundle.message("xdebugger.debugger.tab.title"), null) @@ -104,23 +94,6 @@ public abstract class DebuggerSessionTabBase extends LogConsoleManagerBase imple return myUi; } - protected void registerFileMatcher(final RunProfile runConfiguration) { - if (runConfiguration instanceof RunConfigurationBase) { - myManager.registerFileMatcher((RunConfigurationBase)runConfiguration); - } - } - - protected void initLogConsoles(final RunProfile runConfiguration, final ProcessHandler processHandler, ExecutionConsole console) { - if (runConfiguration instanceof RunConfigurationBase) { - myManager.initLogConsoles((RunConfigurationBase)runConfiguration, processHandler); - OutputFileUtil.attachDumpListener((RunConfigurationBase)runConfiguration, processHandler, console); - } - } - - protected LogFilesManager getLogManager() { - return myManager; - } - protected void attachNotificationTo(final Content content) { if (myConsole instanceof ObservableConsoleView) { ObservableConsoleView observable = (ObservableConsoleView)myConsole; diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java index 4b6bea217c54..4c3766f23f5d 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -17,11 +17,8 @@ package com.intellij.xdebugger.impl.ui; import com.intellij.debugger.ui.DebuggerContentInfo; import com.intellij.execution.Executor; -import com.intellij.execution.configurations.RunProfile; import com.intellij.execution.executors.DefaultDebugExecutor; import com.intellij.execution.runners.ExecutionEnvironment; -import com.intellij.execution.runners.ProgramRunner; -import com.intellij.execution.runners.RestartAction; import com.intellij.execution.runners.RunContentBuilder; import com.intellij.execution.ui.ExecutionConsole; import com.intellij.execution.ui.RunContentDescriptor; @@ -29,11 +26,11 @@ import com.intellij.execution.ui.actions.CloseAction; import com.intellij.execution.ui.layout.PlaceInGrid; import com.intellij.execution.ui.layout.impl.ViewImpl; import com.intellij.icons.AllIcons; +import com.intellij.ide.DataManager; import com.intellij.ide.actions.ContextHelpAction; import com.intellij.idea.ActionsBundle; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.ui.AppUIUtil; @@ -41,7 +38,7 @@ import com.intellij.ui.content.Content; import com.intellij.ui.content.ContentManagerAdapter; import com.intellij.ui.content.ContentManagerEvent; import com.intellij.ui.content.tabs.PinToolwindowTabAction; -import com.intellij.xdebugger.XDebugProcess; +import com.intellij.util.SystemProperties; import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.XDebuggerBundle; import com.intellij.xdebugger.impl.XDebugSessionImpl; @@ -57,29 +54,109 @@ import javax.swing.*; import java.util.ArrayList; import java.util.List; -/** - * @author spleaner - */ public class XDebugSessionTab extends DebuggerSessionTabBase { + private static final DataKey<XDebugSessionTab> TAB_KEY = DataKey.create("XDebugSessionTab"); + private XWatchesViewImpl myWatchesView; private final List<XDebugView> myViews = new ArrayList<XDebugView>(); - public XDebugSessionTab(@NotNull Project project, - @NotNull XDebugSessionImpl session, - @Nullable Icon icon, - @Nullable ExecutionEnvironment environment, - @Nullable ProgramRunner runner) { - super(project, "Debug", session.getSessionName(), GlobalSearchScope.allScope(project)); + @Nullable + private XDebugSessionImpl mySession; + private XDebugSessionData mySessionData; + + @NotNull + public static XDebugSessionTab create(@NotNull XDebugSessionImpl session, + @Nullable Icon icon, + @Nullable ExecutionEnvironment environment, + @Nullable RunContentDescriptor contentToReuse) { + if (contentToReuse != null && SystemProperties.getBooleanProperty("xdebugger.reuse.session.tab", false)) { + JComponent component = contentToReuse.getComponent(); + if (component != null) { + XDebugSessionTab oldTab = TAB_KEY.getData(DataManager.getInstance().getDataContext(component)); + if (oldTab != null) { + oldTab.setSession(session, environment, icon); + oldTab.attachToSession(session); + return oldTab; + } + } + } + return new XDebugSessionTab(session, icon, environment); + } + + private XDebugSessionTab(@NotNull XDebugSessionImpl session, + @Nullable Icon icon, + @Nullable ExecutionEnvironment environment) { + super(session.getProject(), "Debug", session.getSessionName(), GlobalSearchScope.allScope(session.getProject())); + + setSession(session, environment, icon); + + myUi.addContent(createFramesContent(), 0, PlaceInGrid.left, false); + myUi.addContent(createVariablesContent(session), 0, PlaceInGrid.center, false); + myUi.addContent(createWatchesContent(session), 0, PlaceInGrid.right, false); + + for (XDebugView view : myViews) { + Disposer.register(this, view); + } + + attachToSession(session); + + DefaultActionGroup focus = new DefaultActionGroup(); + focus.add(ActionManager.getInstance().getAction(XDebuggerActions.FOCUS_ON_BREAKPOINT)); + myUi.getOptions().setAdditionalFocusActions(focus); + + myUi.addListener(new ContentManagerAdapter() { + @Override + public void selectionChanged(ContentManagerEvent event) { + Content content = event.getContent(); + XDebugSessionImpl session = mySession; + if (session != null && content.isSelected() && DebuggerContentInfo.WATCHES_CONTENT.equals(ViewImpl.ID.get(content))) { + if (myWatchesView.rebuildNeeded()) { + myWatchesView.processSessionEvent(XDebugView.SessionEvent.SETTINGS_CHANGED); + } + } + } + }, this); + + rebuildViews(); + } + + private void setSession(@NotNull XDebugSessionImpl session, @Nullable ExecutionEnvironment environment, @Nullable Icon icon) { if (environment != null) { setEnvironment(environment); } + + mySession = session; + mySessionData = session.getSessionData(); myConsole = session.getConsoleView(); - XDebugProcess debugProcess = session.getDebugProcess(); - myRunContentDescriptor = new RunContentDescriptor(myConsole, debugProcess.getProcessHandler(), myUi.getComponent(), mySessionName, icon); - attachToSession(session, runner, environment, session.getSessionData(), debugProcess); + myRunContentDescriptor = new RunContentDescriptor(myConsole, session.getDebugProcess().getProcessHandler(), myUi.getComponent(), session.getSessionName(), icon); } - private Content createVariablesContent(final XDebugSession session) { + @Nullable + @Override + public Object getData(@NonNls String dataId) { + if (XWatchesView.DATA_KEY.is(dataId)) { + return myWatchesView; + } + else if (TAB_KEY.is(dataId)) { + return this; + } + else if (XDebugSessionData.DATA_KEY.is(dataId)) { + return mySessionData; + } + + if (mySession != null) { + if (XDebugSession.DATA_KEY.is(dataId)) { + return mySession; + } + else if (LangDataKeys.CONSOLE_VIEW.is(dataId)) { + return mySession.getConsoleView(); + } + } + + return super.getData(dataId); + } + + private Content createVariablesContent(@NotNull XDebugSessionImpl session) { final XVariablesView variablesView = new XVariablesView(session); myViews.add(variablesView); Content result = myUi.createContent(DebuggerContentInfo.VARIABLES_CONTENT, variablesView.getPanel(), @@ -89,27 +166,25 @@ public class XDebugSessionTab extends DebuggerSessionTabBase { ActionGroup group = getCustomizedActionGroup(XDebuggerActions.VARIABLES_TREE_TOOLBAR_GROUP); result.setActions(group, ActionPlaces.DEBUGGER_TOOLBAR, variablesView.getTree()); - return result; } - private Content createWatchesContent(final XDebugSessionImpl session, final XDebugSessionData sessionData) { + private Content createWatchesContent(@NotNull XDebugSessionImpl session) { myWatchesView = new XWatchesViewImpl(session); myViews.add(myWatchesView); Content watchesContent = myUi.createContent(DebuggerContentInfo.WATCHES_CONTENT, myWatchesView.getMainPanel(), - XDebuggerBundle.message("debugger.session.tab.watches.title"), AllIcons.Debugger.Watches, null); + XDebuggerBundle.message("debugger.session.tab.watches.title"), AllIcons.Debugger.Watches, null); watchesContent.setCloseable(false); - return watchesContent; } - private Content createFramesContent(final XDebugSession session) { - final XFramesView framesView = new XFramesView(session); + @NotNull + private Content createFramesContent() { + XFramesView framesView = new XFramesView(getProject()); myViews.add(framesView); Content framesContent = myUi.createContent(DebuggerContentInfo.FRAME_CONTENT, framesView.getMainPanel(), XDebuggerBundle.message("debugger.session.tab.frames.title"), AllIcons.Debugger.Frame, null); framesContent.setCloseable(false); - return framesContent; } @@ -132,34 +207,12 @@ public class XDebugSessionTab extends DebuggerSessionTabBase { return myWatchesView; } - private void attachToSession(final @NotNull XDebugSessionImpl session, final @Nullable ProgramRunner runner, - final @Nullable ExecutionEnvironment environment, final @NotNull XDebugSessionData sessionData, - final @NotNull XDebugProcess debugProcess) { - 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); + private void attachToSession(@NotNull XDebugSessionImpl session) { for (XDebugView view : myViews) { - Disposer.register(this, view); - session.addSessionListener(new XDebugViewSessionListener(view, getProject()), this); + session.addSessionListener(new XDebugViewSessionListener(view, session), this); } - myUi.getContentManager().addDataProvider(new DataProvider() { - @Nullable - @Override - public Object getData(@NonNls String dataId) { - if (XWatchesView.DATA_KEY.is(dataId)) { - return myWatchesView; - } - if (LangDataKeys.CONSOLE_VIEW.is(dataId)) { - return session.getConsoleView(); - } - if (XDebugSessionData.DATA_KEY.is(dataId)) { - return sessionData; - } - return null; - } - }); - XDebugTabLayouter layouter = debugProcess.createTabLayouter(); + XDebugTabLayouter layouter = session.getDebugProcess().createTabLayouter(); Content consoleContent = layouter.registerConsoleContent(myUi, myConsole); attachNotificationTo(consoleContent); @@ -172,18 +225,15 @@ public class XDebugSessionTab extends DebuggerSessionTabBase { DefaultActionGroup leftToolbar = new DefaultActionGroup(); final Executor debugExecutor = DefaultDebugExecutor.getDebugExecutorInstance(); - final Executor executor = environment != null ? environment.getExecutor() : debugExecutor; - if (runner != null && environment != null) { - RestartAction restartAction = new RestartAction(executor, runner, myRunContentDescriptor, environment); - leftToolbar.add(restartAction); - restartAction.registerShortcut(myUi.getComponent()); - + ExecutionEnvironment environment = getEnvironment(); + if (environment != null) { List<AnAction> additionalRestartActions = session.getRestartActions(); - leftToolbar.addAll(additionalRestartActions); - if (!additionalRestartActions.isEmpty()) leftToolbar.addSeparator(); + if (!additionalRestartActions.isEmpty()) { + leftToolbar.addAll(additionalRestartActions); + leftToolbar.addSeparator(); + } leftToolbar.addAll(session.getExtraActions()); } - leftToolbar.addAll(getCustomizedActionGroup(XDebuggerActions.TOOL_WINDOW_LEFT_TOOLBAR_GROUP)); for (AnAction action : session.getExtraStopActions()) { @@ -216,7 +266,7 @@ public class XDebugSessionTab extends DebuggerSessionTabBase { if (commonSettings.length > 0) { settings.addSeparator(); } - if (!debugProcess.isValuesCustomSorted()) { + if (!session.getDebugProcess().isValuesCustomSorted()) { settings.add(new ToggleSortValuesAction(commonSettings.length == 0)); } @@ -225,41 +275,25 @@ public class XDebugSessionTab extends DebuggerSessionTabBase { leftToolbar.addSeparator(); leftToolbar.add(PinToolwindowTabAction.getPinAction()); - leftToolbar.add(new CloseAction(executor, myRunContentDescriptor, getProject())); + leftToolbar.add(new CloseAction(environment != null ? environment.getExecutor() : debugExecutor, myRunContentDescriptor, getProject())); leftToolbar.add(new ContextHelpAction(debugExecutor.getHelpId())); DefaultActionGroup topToolbar = new DefaultActionGroup(); topToolbar.addAll(getCustomizedActionGroup(XDebuggerActions.TOOL_WINDOW_TOP_TOOLBAR_GROUP)); - debugProcess.registerAdditionalActions(leftToolbar, topToolbar); + session.getDebugProcess().registerAdditionalActions(leftToolbar, topToolbar); myUi.getOptions().setLeftToolbar(leftToolbar, ActionPlaces.DEBUGGER_TOOLBAR); myUi.getOptions().setTopToolbar(topToolbar, ActionPlaces.DEBUGGER_TOOLBAR); if (environment != null) { - final RunProfile runConfiguration = environment.getRunProfile(); - registerFileMatcher(runConfiguration); - initLogConsoles(runConfiguration, myRunContentDescriptor.getProcessHandler(), myConsole); + initLogConsoles(environment.getRunProfile(), myRunContentDescriptor.getProcessHandler(), myConsole); } - - final DefaultActionGroup focus = new DefaultActionGroup(); - focus.add(ActionManager.getInstance().getAction(XDebuggerActions.FOCUS_ON_BREAKPOINT)); - myUi.getOptions().setAdditionalFocusActions(focus); - - myUi.addListener(new ContentManagerAdapter() { - @Override - public void selectionChanged(ContentManagerEvent event) { - Content content = event.getContent(); - if (content.isSelected() && DebuggerContentInfo.WATCHES_CONTENT.equals(content.getUserData(ViewImpl.ID))) { - if (myWatchesView.rebuildNeeded()) { - myWatchesView.processSessionEvent(XDebugView.SessionEvent.SETTINGS_CHANGED); - } - } - } - }, this); - - rebuildViews(); } + public void detachFromSession() { + assert mySession != null; + mySession = null; + } @Override @Nullable @@ -283,4 +317,4 @@ public class XDebugSessionTab extends DebuggerSessionTabBase { } } } -}
\ No newline at end of file +} diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XValueTextProvider.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XValueTextProvider.java new file mode 100644 index 000000000000..54ae63776e75 --- /dev/null +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XValueTextProvider.java @@ -0,0 +1,23 @@ +/* + * Copyright 2000-2014 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.ui; + +/** + * @author egor + */ +public interface XValueTextProvider { + String getValueText(); +} diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/TreeInplaceEditor.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/TreeInplaceEditor.java index 629385c9ad20..13fe7802481c 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/TreeInplaceEditor.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/TreeInplaceEditor.java @@ -17,16 +17,19 @@ package com.intellij.xdebugger.impl.ui.tree; import com.intellij.codeInsight.lookup.LookupManager; import com.intellij.codeInsight.lookup.impl.LookupImpl; -import com.intellij.execution.ExecutionManager; +import com.intellij.execution.Executor; import com.intellij.execution.ui.RunContentDescriptor; -import com.intellij.execution.ui.RunContentListener; import com.intellij.execution.ui.RunContentManager; +import com.intellij.execution.ui.RunContentWithExecutorListener; +import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.util.Disposer; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -176,23 +179,22 @@ public abstract class TreeInplaceEditor implements AWTEventListener { } }); - final RunContentManager contentManager = ExecutionManager.getInstance(getProject()).getContentManager(); - final RunContentListener runContentListener = new RunContentListener() { + final Disposable disposable = Disposer.newDisposable(); + getProject().getMessageBus().connect(disposable).subscribe(RunContentManager.TOPIC, new RunContentWithExecutorListener() { @Override - public void contentSelected(RunContentDescriptor descriptor) { + public void contentSelected(@Nullable RunContentDescriptor descriptor, @NotNull Executor executor) { cancelEditing(); } @Override - public void contentRemoved(RunContentDescriptor descriptor) { + public void contentRemoved(@Nullable RunContentDescriptor descriptor, @NotNull Executor executor) { cancelEditing(); } - }; - contentManager.addRunContentListener(runContentListener); + }); myRemoveActions.add(new Runnable() { @Override public void run() { - contentManager.removeRunContentListener(runContentListener); + disposable.dispose(); } }); @@ -246,13 +248,13 @@ public abstract class TreeInplaceEditor implements AWTEventListener { if (id != MouseEvent.MOUSE_PRESSED && id != MouseEvent.MOUSE_RELEASED && id != MouseEvent.MOUSE_CLICKED && id != MouseEvent.MOUSE_WHEEL) { return; } - + final Component sourceComponent = mouseEvent.getComponent(); final Point originalPoint = mouseEvent.getPoint(); final Editor editor = getEditor(); if (editor == null) return; - + final LookupImpl activeLookup = (LookupImpl)LookupManager.getInstance(editor.getProject()).getActiveLookup(); if (activeLookup != null){ final Point lookupPoint = SwingUtilities.convertPoint(sourceComponent, originalPoint, activeLookup.getComponent()); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java index fe32920a7ac6..9e4f471b047d 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -18,6 +18,8 @@ package com.intellij.xdebugger.impl.ui.tree; import com.intellij.ide.dnd.aware.DnDAwareTree; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.keymap.KeymapManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; @@ -26,10 +28,12 @@ import com.intellij.openapi.vcs.changes.issueLinks.TreeLinkMouseListener; import com.intellij.ui.DoubleClickListener; import com.intellij.ui.PopupHandler; import com.intellij.ui.TreeSpeedSearch; +import com.intellij.util.SingleAlarm; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.Convertor; import com.intellij.util.containers.TransferToEDTQueue; import com.intellij.util.ui.TextTransferable; +import com.intellij.util.ui.tree.TreeModelAdapter; import com.intellij.xdebugger.XSourcePosition; import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; import com.intellij.xdebugger.frame.XDebuggerTreeNodeHyperlink; @@ -41,6 +45,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import javax.swing.event.TreeModelEvent; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; @@ -58,6 +63,17 @@ public class XDebuggerTree extends DnDAwareTree implements DataProvider, Disposa private final TransferToEDTQueue<Runnable> myLaterInvocator = TransferToEDTQueue.createRunnableMerger("XDebuggerTree later invocator", 100); private static final DataKey<XDebuggerTree> XDEBUGGER_TREE_KEY = DataKey.create("xdebugger.tree"); + private final SingleAlarm myAlarm = new SingleAlarm(new Runnable() { + @Override + public void run() { + final Editor editor = FileEditorManager.getInstance(myProject).getSelectedTextEditor(); + if (editor != null) { + editor.getComponent().revalidate(); + editor.getComponent().repaint(); + } + } + }, 100, this); + private static final Convertor<TreePath, String> SPEED_SEARCH_CONVERTER = new Convertor<TreePath, String>() { @Override public String convert(TreePath o) { @@ -135,6 +151,27 @@ public class XDebuggerTree extends DnDAwareTree implements DataProvider, Disposa myEditorsProvider = editorsProvider; mySourcePosition = sourcePosition; myTreeModel = new DefaultTreeModel(null); + myTreeModel.addTreeModelListener(new TreeModelAdapter() { + @Override + public void treeNodesChanged(TreeModelEvent e) { + updateEditor(); + } + + @Override + public void treeNodesInserted(TreeModelEvent e) { + updateEditor(); + } + + @Override + public void treeNodesRemoved(TreeModelEvent e) { + updateEditor(); + } + + @Override + public void treeStructureChanged(TreeModelEvent e) { + updateEditor(); + } + }); setModel(myTreeModel); setCellRenderer(new XDebuggerTreeRenderer()); new TreeLinkMouseListener(new XDebuggerTreeRenderer()) { @@ -185,6 +222,10 @@ public class XDebuggerTree extends DnDAwareTree implements DataProvider, Disposa setTransferHandler(DEFAULT_TRANSFER_HANDLER); } + private void updateEditor() { + myAlarm.cancelAndRequest(); + } + private boolean expandIfEllipsis() { MessageTreeNode[] treeNodes = getSelectedNodes(MessageTreeNode.class, null); if (treeNodes.length == 1) { diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java index 66f22bbfd4f1..7c77bafc6553 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java @@ -55,7 +55,7 @@ class XAddToWatchesAction extends XDebuggerTreeActionBase { if (view == null && project != null) { XDebugSession session = XDebuggerManager.getInstance(project).getCurrentSession(); if (session != null) { - view = ((XDebugSessionImpl)session).getSessionTab().getWatchesView(); + return ((XDebugSessionImpl)session).getSessionTab().getWatchesView(); } } return view; diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XFetchValueActionBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XFetchValueActionBase.java index 3926e89ecd4c..13121c7fda16 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XFetchValueActionBase.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XFetchValueActionBase.java @@ -22,6 +22,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.SmartList; import com.intellij.xdebugger.frame.XFullValueEvaluator; +import com.intellij.xdebugger.impl.ui.XValueTextProvider; import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree; import com.intellij.xdebugger.impl.ui.tree.nodes.HeadlessValueEvaluationCallback; import com.intellij.xdebugger.impl.ui.tree.nodes.WatchMessageNode; @@ -74,7 +75,14 @@ public abstract class XFetchValueActionBase extends AnAction { XValueNodeImpl valueNode = (XValueNodeImpl)node; XFullValueEvaluator fullValueEvaluator = valueNode.getFullValueEvaluator(); if (fullValueEvaluator == null) { - valueCollector.add(StringUtil.notNullize(valueNode.getRawValue())); + String rawValue; + if (valueNode.getValueContainer() instanceof XValueTextProvider) { + rawValue = ((XValueTextProvider)valueNode.getValueContainer()).getValueText(); + } + else { + rawValue = valueNode.getRawValue(); + } + valueCollector.add(StringUtil.notNullize(rawValue)); } else { new CopyValueEvaluationCallback(valueNode, valueCollector).startFetchingValue(fullValueEvaluator); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchesRootNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchesRootNode.java index 204f45a4a02d..cf67f7d5fdb5 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchesRootNode.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchesRootNode.java @@ -21,6 +21,7 @@ import com.intellij.xdebugger.evaluation.XDebuggerEvaluator; import com.intellij.xdebugger.frame.XValue; import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl; import com.intellij.xdebugger.impl.frame.WatchInplaceEditor; +import com.intellij.xdebugger.impl.frame.XDebugView; import com.intellij.xdebugger.impl.frame.XWatchesView; import com.intellij.xdebugger.impl.ui.DebuggerUIUtil; import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree; @@ -37,18 +38,15 @@ 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 @NotNull XDebuggerTree tree, - @NotNull XDebugSession session, + public WatchesRootNode(@NotNull XDebuggerTree tree, @NotNull XWatchesView watchesView, @NotNull XExpression[] watchExpressions) { super(tree, null, false); - mySession = session; myWatchesView = watchesView; myChildren = new ArrayList<WatchNode>(); for (XExpression watchExpression : watchExpressions) { @@ -189,7 +187,10 @@ public class WatchesRootNode extends XDebuggerTreeNode { myChildren.set(index, messageNode); fireNodeStructureChanged(messageNode); } - new WatchInplaceEditor(this, mySession, myWatchesView, messageNode, "watch", node).show(); + XDebugSession session = XDebugView.getSession(myTree); + if (session != null) { + new WatchInplaceEditor(this, session, myWatchesView, messageNode, "watch", node).show(); + } } private class MyEvaluationCallback extends XEvaluationCallbackBase { diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java index e01d0ad7ce79..5e3101bff21a 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XDebuggerTreeNode.java @@ -49,8 +49,7 @@ public abstract class XDebuggerTreeNode implements TreeNode, TreeSpeedSearch.Pat @Override public TreeNode getChildAt(final int childIndex) { - if (isLeaf()) return null; - return getChildren().get(childIndex); + return isLeaf() ? null : getChildren().get(childIndex); } @Override @@ -64,7 +63,7 @@ public abstract class XDebuggerTreeNode implements TreeNode, TreeSpeedSearch.Pat } @Override - public int getIndex(final TreeNode node) { + public int getIndex(@NotNull TreeNode node) { if (isLeaf()) return -1; return getChildren().indexOf(node); } 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 b808c3ca96d8..1f3d4c77e84f 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 @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -16,14 +16,19 @@ package com.intellij.xdebugger.impl.ui.tree.nodes; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.AppUIUtil; import com.intellij.ui.ColoredTextContainer; import com.intellij.ui.SimpleTextAttributes; import com.intellij.util.NotNullFunction; +import com.intellij.xdebugger.XSourcePosition; import com.intellij.xdebugger.frame.*; import com.intellij.xdebugger.frame.presentation.XValuePresentation; import com.intellij.xdebugger.impl.frame.XValueMarkers; +import com.intellij.xdebugger.impl.frame.XVariablesView; import com.intellij.xdebugger.impl.ui.DebuggerUIUtil; import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants; import com.intellij.xdebugger.impl.ui.tree.ValueMarkup; @@ -35,6 +40,9 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.event.MouseEvent; import java.util.Comparator; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; /** * @author nik @@ -111,7 +119,28 @@ public class XValueNodeImpl extends XValueContainerNode<XValue> implements XValu setIcon(icon); 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) { + } + } updateText(); setLeaf(!hasChildren); fireNodeChanged(); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueTextRendererImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueTextRendererImpl.java index e8b8616e6b69..98410cf62552 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueTextRendererImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueTextRendererImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -27,7 +27,7 @@ import org.jetbrains.annotations.Nullable; /** * @author nik */ -class XValueTextRendererImpl extends XValueTextRendererBase { +public class XValueTextRendererImpl extends XValueTextRendererBase { private final ColoredTextContainer myText; public XValueTextRendererImpl(@NotNull ColoredTextContainer text) { |