diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/VariablesPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/VariablesPanel.java index ead97cba1c63..4201713a863e 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/VariablesPanel.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/VariablesPanel.java @@ -29,6 +29,7 @@ import com.intellij.openapi.project.Project; import com.intellij.ui.AppUIUtil; import com.intellij.ui.ScrollPaneFactory; import com.intellij.util.SystemProperties; +import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.XSourcePosition; import com.intellij.xdebugger.evaluation.EvaluationMode; import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; @@ -149,11 +150,11 @@ public class VariablesPanel extends DebuggerTreePanel implements DataProvider { } @Override - protected void clear() { + protected void clear(@Nullable XDebugSession session) { } @Override - public void processSessionEvent(@NotNull SessionEvent event) { + public void processSessionEvent(@NotNull SessionEvent event, @NotNull XDebugSession session) { } } } diff --git a/java/execution/impl/src/com/intellij/execution/impl/DefaultJavaProgramRunner.java b/java/execution/impl/src/com/intellij/execution/impl/DefaultJavaProgramRunner.java index 6da3ea91e37c..dff628c8df50 100644 --- a/java/execution/impl/src/com/intellij/execution/impl/DefaultJavaProgramRunner.java +++ b/java/execution/impl/src/com/intellij/execution/impl/DefaultJavaProgramRunner.java @@ -106,13 +106,9 @@ public class DefaultJavaProgramRunner extends JavaPatchableProgramRunner { } RunContentDescriptor runContent = contentBuilder.showRunContent(contentToReuse); - - AnAction[] actions = createActions(contentBuilder.getExecutionResult()); - - for (AnAction action : actions) { + for (AnAction action : createActions(contentBuilder.getExecutionResult())) { contentBuilder.addAction(action); } - return runContent; } diff --git a/platform/lang-impl/src/com/intellij/diagnostic/logging/LogFilesManager.java b/platform/lang-impl/src/com/intellij/diagnostic/logging/LogFilesManager.java index b45eb787d697..a581a15ed6b8 100644 --- a/platform/lang-impl/src/com/intellij/diagnostic/logging/LogFilesManager.java +++ b/platform/lang-impl/src/com/intellij/diagnostic/logging/LogFilesManager.java @@ -27,6 +27,7 @@ import com.intellij.openapi.util.Conditions; import com.intellij.openapi.util.Disposer; import com.intellij.util.Alarm; import gnu.trove.THashSet; +import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.io.File; @@ -37,18 +38,17 @@ import java.util.*; * Date: 01-Feb-2006 */ public class LogFilesManager implements Disposable { - public static final Logger LOG = Logger.getInstance("#" + LogFilesManager.class.getName()); + public static final Logger LOG = Logger.getInstance(LogFilesManager.class); private static final int UPDATE_INTERVAL = 500; private final Map> myLogFileManagerMap = new LinkedHashMap>(); - private final Map myLogFileToConfiguration = new HashMap(); private final Runnable myUpdateRequest; private final LogConsoleManager myManager; private final Alarm myUpdateAlarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, this); private boolean myDisposed; - public LogFilesManager(final Project project, LogConsoleManager manager, Disposable parentDisposable) { + public LogFilesManager(@NotNull final Project project, LogConsoleManager manager, Disposable parentDisposable) { myManager = manager; Disposer.register(parentDisposable, this); @@ -87,12 +87,11 @@ public class LogFilesManager implements Disposable { }; } - public void registerFileMatcher(final RunConfigurationBase runConfiguration) { + public void registerFileMatcher(@NotNull RunConfigurationBase runConfiguration) { final ArrayList logFiles = runConfiguration.getAllLogFiles(); for (LogFileOptions logFile : logFiles) { if (logFile.isEnabled()) { myLogFileManagerMap.put(logFile, logFile.getPaths()); - myLogFileToConfiguration.put(logFile, runConfiguration); } } Alarm updateAlarm = myUpdateAlarm; @@ -109,8 +108,8 @@ public class LogFilesManager implements Disposable { } } - public void initLogConsoles(RunConfigurationBase base, ProcessHandler startedProcess) { - final ArrayList logFiles = base.getAllLogFiles(); + public void initLogConsoles(@NotNull RunConfigurationBase base, ProcessHandler startedProcess) { + List logFiles = base.getAllLogFiles(); for (LogFileOptions logFile : logFiles) { if (logFile.isEnabled()) { addConfigurationConsoles(logFile, Conditions.alwaysTrue(), logFile.getPaths()); diff --git a/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java b/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java index 21f6ef1a5e49..07bb2184e1e4 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java @@ -66,7 +66,6 @@ public class RunContentManagerImpl implements RunContentManager, Disposable { private static final Key DESCRIPTOR_KEY = new Key("Descriptor"); private final Project myProject; - private DockableGridContainerFactory myContentFactory; private final Map myToolwindowIdToContentManagerMap = new HashMap(); private final Map myListeners = new HashMap(); @@ -74,9 +73,9 @@ public class RunContentManagerImpl implements RunContentManager, Disposable { public RunContentManagerImpl(Project project, DockManager dockManager) { myProject = project; - myContentFactory = new DockableGridContainerFactory(); - dockManager.register(DockableGridContainerFactory.TYPE, myContentFactory); - Disposer.register(myProject, myContentFactory); + DockableGridContainerFactory containerFactory = new DockableGridContainerFactory(); + dockManager.register(DockableGridContainerFactory.TYPE, containerFactory); + Disposer.register(myProject, containerFactory); } public void init() { @@ -202,8 +201,7 @@ public class RunContentManagerImpl implements RunContentManager, Disposable { final ContentManager contentManager = getContentManagerForRunner(requestor); final Content content = getRunContentByDescriptor(contentManager, descriptor); - - if (contentManager != null && content != null) { + if (content != null) { contentManager.setSelectedContent(content); final ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(requestor.getToolWindowId()); @@ -232,17 +230,8 @@ public class RunContentManagerImpl implements RunContentManager, Disposable { @Override @Nullable public RunContentDescriptor getSelectedContent(final Executor executor) { - final ContentManager contentManager = getContentManagerForRunner(executor); - if (contentManager != null) { - final Content selectedContent = contentManager.getSelectedContent(); - if (selectedContent != null) { - final RunContentDescriptor runContentDescriptorByContent = getRunContentDescriptorByContent(selectedContent); - if (runContentDescriptorByContent != null) { - return runContentDescriptorByContent; - } - } - } - return null; + final Content selectedContent = getContentManagerForRunner(executor).getSelectedContent(); + return selectedContent != null ? getRunContentDescriptorByContent(selectedContent) : null; } @Override @@ -293,7 +282,7 @@ public class RunContentManagerImpl implements RunContentManager, Disposable { final Content content; - Content oldAttachedContent = oldDescriptor != null ? oldDescriptor.getAttachedContent() : null; + Content oldAttachedContent = oldDescriptor == null ? null : oldDescriptor.getAttachedContent(); if (oldDescriptor != null) { content = oldAttachedContent; getSyncPublisher().contentRemoved(oldDescriptor, executor); @@ -382,11 +371,13 @@ public class RunContentManagerImpl implements RunContentManager, Disposable { @Nullable @Deprecated public RunContentDescriptor getReuseContent(Executor requestor, @Nullable RunContentDescriptor contentToReuse) { - if (ApplicationManager.getApplication().isUnitTestMode()) return null; - if (contentToReuse != null) return contentToReuse; - - final ContentManager contentManager = getContentManagerForRunner(requestor); - return chooseReuseContentForDescriptor(contentManager, contentToReuse, 0L, null); + if (ApplicationManager.getApplication().isUnitTestMode()) { + return null; + } + if (contentToReuse != null) { + return contentToReuse; + } + return chooseReuseContentForDescriptor(getContentManagerForRunner(requestor), null, 0L, null); } @Nullable @@ -400,10 +391,12 @@ public class RunContentManagerImpl implements RunContentManager, Disposable { public RunContentDescriptor getReuseContent(@NotNull ExecutionEnvironment executionEnvironment) { if (ApplicationManager.getApplication().isUnitTestMode()) return null; RunContentDescriptor contentToReuse = executionEnvironment.getContentToReuse(); - if (contentToReuse != null) return contentToReuse; + if (contentToReuse != null) { + return contentToReuse; + } final ContentManager contentManager = getContentManagerForRunner(executionEnvironment.getExecutor()); - return chooseReuseContentForDescriptor(contentManager, contentToReuse, executionEnvironment.getExecutionId(), + return chooseReuseContentForDescriptor(contentManager, null, executionEnvironment.getExecutionId(), executionEnvironment.toString()); } diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java index dc610943063f..179216fa6d21 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java @@ -636,8 +636,9 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac myManager.addContentManagerListener(new ContentManagerListener() { @Override public void contentAdded(final ContentManagerEvent event) { - final GridImpl grid = getGridFor(event.getContent(), true); + initUi(); + GridImpl grid = getGridFor(event.getContent(), true); if (grid == null) { return; } diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerLayoutUiImpl.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerLayoutUiImpl.java index 70d6a3f92819..7475adbcab21 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerLayoutUiImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerLayoutUiImpl.java @@ -21,7 +21,6 @@ import com.intellij.execution.ui.layout.LayoutAttractionPolicy; import com.intellij.execution.ui.layout.LayoutStateDefaults; import com.intellij.execution.ui.layout.LayoutViewOptions; import com.intellij.execution.ui.layout.PlaceInGrid; -import com.intellij.ide.DataManager; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.ActionGroup; import com.intellij.openapi.actionSystem.ActionManager; @@ -46,9 +45,8 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; -public class RunnerLayoutUiImpl implements Disposable.Parent, RunnerLayoutUi, LayoutStateDefaults, LayoutViewOptions { +public class RunnerLayoutUiImpl implements Disposable.Parent, RunnerLayoutUi, LayoutStateDefaults, LayoutViewOptions, DataProvider { private final RunnerLayout myLayout; - private final JPanel myContentPanel; private final RunnerContentUi myContentUI; private final ContentManager myViewsContentManager; @@ -63,14 +61,12 @@ public class RunnerLayoutUiImpl implements Disposable.Parent, RunnerLayoutUi, La Disposer.register(parent, this); myContentUI = new RunnerContentUi(project, this, ActionManager.getInstance(), IdeFocusManager.getInstance(project), myLayout, - runnerTitle + " - " + sessionName); + runnerTitle + " - " + sessionName); Disposer.register(this, myContentUI); - myContentPanel = new MyContent(); myViewsContentManager = getContentFactory().createContentManager(myContentUI.getContentUI(), false, project); + myViewsContentManager.addDataProvider(this); Disposer.register(this, myViewsContentManager); - - myContentPanel.add(myViewsContentManager.getComponent(), BorderLayout.CENTER); } @Override @@ -80,7 +76,6 @@ public class RunnerLayoutUiImpl implements Disposable.Parent, RunnerLayoutUi, La return this; } - @NotNull @Override public LayoutStateDefaults initTabDefaults(int id, String text, Icon icon) { @@ -156,7 +151,7 @@ public class RunnerLayoutUiImpl implements Disposable.Parent, RunnerLayoutUi, La @Override @NotNull public JComponent getComponent() { - return myContentPanel; + return myViewsContentManager.getComponent(); } private static ContentFactory getContentFactory() { @@ -380,28 +375,12 @@ public class RunnerLayoutUiImpl implements Disposable.Parent, RunnerLayoutUi, La return contents; } - private class MyContent extends JPanel implements DataProvider { - public MyContent() { - super(new BorderLayout()); - } - - @Override - public Object getData(@NonNls String dataId) { - if (SwitchProvider.KEY.getName().equals(dataId)) { - return myContentUI; - } - - if (QuickActionProvider.KEY.getName().equals(dataId)) { - return myContentUI; - } - - if (RunnerContentUi.KEY.getName().equals(dataId)) { - return myContentUI; - } - - final DataProvider provider = DataManager.getDataProvider(this); - return provider != null ? provider.getData(dataId) : null; + @Nullable + @Override + public Object getData(@NonNls String dataId) { + if (SwitchProvider.KEY.is(dataId) || QuickActionProvider.KEY.is(dataId) || RunnerContentUi.KEY.is(dataId)) { + return myContentUI; } + return null; } - } diff --git a/platform/platform-impl/src/com/intellij/ui/content/impl/ContentManagerImpl.java b/platform/platform-impl/src/com/intellij/ui/content/impl/ContentManagerImpl.java index 7aa6500ed16a..d7a0e72825be 100644 --- a/platform/platform-impl/src/com/intellij/ui/content/impl/ContentManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/content/impl/ContentManagerImpl.java @@ -15,6 +15,7 @@ */ package com.intellij.ui.content.impl; +import com.intellij.ide.DataManager; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.DataProvider; @@ -62,15 +63,16 @@ public class ContentManagerImpl implements ContentManager, PropertyChangeListene private final List mySelection = new ArrayList(); private final boolean myCanCloseContents; - private MyContentComponent myContentComponent; - private MyFocusProxy myFocusProxy; - private JPanel myComponent; + private Wrapper.FocusHolder myFocusProxy; + private MyNonOpaquePanel myComponent; private final Set myContentWithChangedComponent = new HashSet(); private boolean myDisposed; private final Project myProject; + private final List dataProviders = new SmartList(); + /** * WARNING: as this class adds listener to the ProjectManager which is removed on projectClosed event, all instances of this class * must be created on already OPENED projects, otherwise there will be memory leak! @@ -94,15 +96,18 @@ public class ContentManagerImpl implements ContentManager, PropertyChangeListene @Override public JComponent getComponent() { if (myComponent == null) { - myComponent = new NonOpaquePanel(new BorderLayout()); + myComponent = new MyNonOpaquePanel(); - myFocusProxy = new MyFocusProxy(); - myContentComponent = new MyContentComponent(); - myContentComponent.setContent(myUI.getComponent()); - myContentComponent.setFocusCycleRoot(true); + myFocusProxy = new Wrapper.FocusHolder(); + myFocusProxy.setOpaque(false); + myFocusProxy.setPreferredSize(new Dimension(0, 0)); + + MyContentComponent contentComponent = new MyContentComponent(); + contentComponent.setContent(myUI.getComponent()); + contentComponent.setFocusCycleRoot(true); myComponent.add(myFocusProxy, BorderLayout.NORTH); - myComponent.add(myContentComponent, BorderLayout.CENTER); + myComponent.add(contentComponent, BorderLayout.CENTER); } return myComponent; } @@ -116,57 +121,51 @@ public class ContentManagerImpl implements ContentManager, PropertyChangeListene return busyObject != null ? busyObject.getReady(requestor) : new ActionCallback.Done(); } - private class MyContentComponent extends NonOpaquePanel implements DataProvider, SwitchProvider { - private final List myProviders = new SmartList(); - - public void addProvider(final DataProvider provider) { - myProviders.add(provider); + private class MyNonOpaquePanel extends NonOpaquePanel implements DataProvider { + public MyNonOpaquePanel() { + super(new BorderLayout()); } @Override @Nullable - public Object getData(@NonNls final String dataId) { - if (PlatformDataKeys.CONTENT_MANAGER.is(dataId)) return ContentManagerImpl.this; - if (PlatformDataKeys.NONEMPTY_CONTENT_MANAGER.is(dataId) && getContentCount() > 1) { + public Object getData(@NonNls String dataId) { + if (PlatformDataKeys.CONTENT_MANAGER.is(dataId) || PlatformDataKeys.NONEMPTY_CONTENT_MANAGER.is(dataId) && getContentCount() > 1) { return ContentManagerImpl.this; } - for (DataProvider each : myProviders) { - final Object data = each.getData(dataId); - if (data != null) return data; + for (DataProvider dataProvider : dataProviders) { + Object data = dataProvider.getData(dataId); + if (data != null) { + return data; + } } if (myUI instanceof DataProvider) { return ((DataProvider)myUI).getData(dataId); } - return null; + DataProvider provider = DataManager.getDataProvider(this); + return provider == null ? null : provider.getData(dataId); } + } + private class MyContentComponent extends NonOpaquePanel implements SwitchProvider { @Override public List getTargets(boolean onlyVisible, boolean originalProvider) { if (myUI instanceof SwitchProvider) { return ((SwitchProvider)myUI).getTargets(onlyVisible, false); } - return new ArrayList(); + return new SmartList(); } @Override public SwitchTarget getCurrentTarget() { - if (myUI instanceof SwitchProvider) { - return ((SwitchProvider)myUI).getCurrentTarget(); - } - - return null; + return myUI instanceof SwitchProvider ? ((SwitchProvider)myUI).getCurrentTarget() : null; } @Override public JComponent getComponent() { - if (myUI instanceof SwitchProvider) { - return myUI.getComponent(); - } - - return this; + return myUI instanceof SwitchProvider ? myUI.getComponent() : this; } @Override @@ -175,19 +174,6 @@ public class ContentManagerImpl implements ContentManager, PropertyChangeListene } } - private class MyFocusProxy extends Wrapper.FocusHolder implements DataProvider { - private MyFocusProxy() { - setOpaque(false); - setPreferredSize(new Dimension(0, 0)); - } - - @Override - @Nullable - public Object getData(@NonNls final String dataId) { - return myContentComponent.getData(dataId); - } - } - @Override public void addContent(@NotNull Content content, final int order) { doAddContent(content, order); @@ -687,7 +673,7 @@ public class ContentManagerImpl implements ContentManager, PropertyChangeListene @Override public void addDataProvider(@NotNull final DataProvider provider) { - myContentComponent.addProvider(provider); + dataProviders.add(provider); } @Override diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java index fe18d14fd5a1..7d73fc54b004 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java @@ -314,7 +314,7 @@ public class XDebugSessionImpl implements XDebugSession { } private void initSessionTab(@Nullable RunContentDescriptor contentToReuse) { - mySessionTab = new XDebugSessionTab(myProject, this, myIcon, myEnvironment, contentToReuse); + mySessionTab = XDebugSessionTab.create(this, myIcon, myEnvironment, contentToReuse); myDebugProcess.sessionInitialized(); } @@ -851,6 +851,10 @@ public class XDebugSessionImpl implements XDebugSession { myProject.getMessageBus().syncPublisher(XDebuggerManager.TOPIC).processStopped(myDebugProcess); } + if (mySessionTab != null) { + mySessionTab.detachFromSession(); + } + adjustMouseTrackingCounter(myCurrentPosition, -1); myCurrentPosition = null; myCurrentExecutionStack = null; diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java index bee9b3d91fd7..37da856156ea 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java @@ -129,6 +129,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper { evaluate(); } + @Override protected void createDefaultActions() { super.createDefaultActions(); myOKAction = new OkAction(){ diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugView.java index 345f91170075..3d330d7084b8 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugView.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugView.java @@ -15,9 +15,16 @@ */ package com.intellij.xdebugger.impl.frame; +import com.intellij.ide.DataManager; import com.intellij.openapi.Disposable; import com.intellij.util.SingleAlarm; +import com.intellij.xdebugger.XDebugSession; +import com.intellij.xdebugger.impl.ui.XDebugSessionTab; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.awt.*; +import java.util.EventObject; /** * @author nik @@ -28,24 +35,41 @@ public abstract class XDebugView implements Disposable { private final SingleAlarm myClearAlarm; private static final int VIEW_CLEAR_DELAY = 100; //ms + // used only to implement "clear" + private volatile XDebugSession session; + public XDebugView() { myClearAlarm = new SingleAlarm(new Runnable() { @Override public void run() { - clear(); + clear(session); + session = null; } }, VIEW_CLEAR_DELAY, this); } - protected final void requestClear() { + protected final void requestClear(@NotNull XDebugSession session) { + this.session = session; myClearAlarm.cancelAndRequest(); } protected final void cancelClear() { + session = null; myClearAlarm.cancel(); } - protected abstract void clear(); + protected abstract void clear(@Nullable XDebugSession session); - public abstract void processSessionEvent(@NotNull SessionEvent event); + public abstract void processSessionEvent(@NotNull SessionEvent event, @NotNull XDebugSession session); + + @Nullable + protected static XDebugSession getSession(@NotNull EventObject e) { + Component component = e.getSource() instanceof Component ? (Component)e.getSource() : null; + return component == null ? null : getSession(component); + } + + @Nullable + public static XDebugSession getSession(@NotNull Component component) { + return XDebugSessionTab.SESSION_KEY.getData(DataManager.getInstance().getDataContext(component)); + } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugViewSessionListener.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugViewSessionListener.java index d265005d3a34..3a4869ad3e75 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugViewSessionListener.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugViewSessionListener.java @@ -15,8 +15,8 @@ */ package com.intellij.xdebugger.impl.frame; -import com.intellij.openapi.project.Project; import com.intellij.ui.AppUIUtil; +import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.XDebugSessionAdapter; import org.jetbrains.annotations.NotNull; @@ -25,18 +25,18 @@ import org.jetbrains.annotations.NotNull; */ public class XDebugViewSessionListener extends XDebugSessionAdapter { private final XDebugView myDebugView; - private final Project myProject; + private final XDebugSession session; - public XDebugViewSessionListener(@NotNull XDebugView debugView, @NotNull Project project) { + public XDebugViewSessionListener(@NotNull XDebugView debugView, @NotNull XDebugSession session) { myDebugView = debugView; - myProject = project; + this.session = session; } private void onSessionEvent(final @NotNull XDebugView.SessionEvent event) { - AppUIUtil.invokeLaterIfProjectAlive(myProject, new Runnable() { + AppUIUtil.invokeLaterIfProjectAlive(session.getProject(), new Runnable() { @Override public void run() { - myDebugView.processSessionEvent(event); + myDebugView.processSessionEvent(event, session); } }); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebuggerFramesList.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebuggerFramesList.java index f4b6c2caee8e..9b39ad63deb8 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebuggerFramesList.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebuggerFramesList.java @@ -27,6 +27,7 @@ import com.intellij.util.ui.UIUtil; import com.intellij.xdebugger.XDebuggerBundle; import com.intellij.xdebugger.XSourcePosition; import com.intellij.xdebugger.frame.XStackFrame; +import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; @@ -84,7 +85,7 @@ public class XDebuggerFramesList extends DebuggerFramesList { private XStackFrame mySelectedFrame; - public XDebuggerFramesList(Project project) { + public XDebuggerFramesList(@NotNull Project project) { super(project); doInit(); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java index 42023fc34baf..bf30dac2f95d 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java @@ -22,6 +22,7 @@ import com.intellij.openapi.actionSystem.ActionPlaces; import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.openapi.actionSystem.impl.ActionToolbarImpl; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.ComboBox; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.*; @@ -36,6 +37,7 @@ import com.intellij.xdebugger.frame.XStackFrame; import com.intellij.xdebugger.frame.XSuspendContext; import com.intellij.xdebugger.impl.actions.XDebuggerActions; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.border.EmptyBorder; @@ -59,7 +61,6 @@ public class XFramesView extends XDebugView { private final XDebuggerFramesList myFramesList; private final ComboBox myThreadComboBox; private final Set myExecutionStacks = ContainerUtil.newHashSet(); - @NotNull private final XDebugSession mySession; private XExecutionStack mySelectedStack; private boolean myListenersEnabled; private final Map myBuilders = new HashMap(); @@ -68,33 +69,34 @@ public class XFramesView extends XDebugView { private boolean myThreadsCalculated = false; private final TransferToEDTQueue myLaterInvocator = TransferToEDTQueue.createRunnableMerger("XFramesView later invocator", 50); - public XFramesView(@NotNull final XDebugSession session) { - mySession = session; - + public XFramesView(@NotNull Project project) { myMainPanel = new JPanel(new BorderLayout()); - myFramesList = new XDebuggerFramesList(session.getProject()); + myFramesList = new XDebuggerFramesList(project); myFramesList.addListSelectionListener(new ListSelectionListener() { @Override - public void valueChanged(final ListSelectionEvent e) { - if (e.getValueIsAdjusting()) return; - processFrameSelection(); + public void valueChanged(ListSelectionEvent e) { + if (myListenersEnabled && !e.getValueIsAdjusting()) { + processFrameSelection(e); + } } }); myFramesList.addMouseListener(new MouseAdapter() { @Override public void mousePressed(final MouseEvent e) { - int i = myFramesList.locationToIndex(e.getPoint()); - if (i != -1 && myFramesList.isSelectedIndex(i)) { - processFrameSelection(); + if (myListenersEnabled) { + int i = myFramesList.locationToIndex(e.getPoint()); + if (i != -1 && myFramesList.isSelectedIndex(i)) { + processFrameSelection(e); + } } } }); - final ActionManager actionManager = ActionManager.getInstance(); myFramesList.addMouseListener(new PopupHandler() { @Override public void invokePopup(final Component comp, final int x, final int y) { + ActionManager actionManager = ActionManager.getInstance(); ActionGroup group = (ActionGroup)actionManager.getAction(XDebuggerActions.FRAMES_TREE_POPUP_GROUP); actionManager.createActionPopupMenu(ActionPlaces.UNKNOWN, group).getComponent().show(comp, x, y); } @@ -105,11 +107,29 @@ public class XFramesView extends XDebugView { myThreadComboBox = new ComboBox(); //noinspection unchecked myThreadComboBox.setRenderer(new ThreadComboBoxRenderer(myThreadComboBox)); - myThreadComboBox.addItemListener(new MyItemListener()); + myThreadComboBox.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(final ItemEvent e) { + if (!myListenersEnabled) { + return; + } + + if (e.getStateChange() == ItemEvent.SELECTED) { + Object item = e.getItem(); + if (item instanceof XExecutionStack) { + XDebugSession session = getSession(e); + if (session != null) { + updateFrames((XExecutionStack)item, session); + } + } + } + } + }); myThreadComboBox.addPopupMenuListener(new PopupMenuListenerAdapter() { @Override public void popupMenuWillBecomeVisible(PopupMenuEvent e) { - XSuspendContext context = mySession.getSuspendContext(); + XDebugSession session = getSession(e); + XSuspendContext context = session == null ? null : session.getSuspendContext(); if (context != null && !myThreadsCalculated) { myThreadsCalculated = true; //noinspection unchecked @@ -133,7 +153,6 @@ public class XFramesView extends XDebugView { @Override public void errorOccurred(@NotNull String errorMessage) { - } }); } @@ -148,12 +167,9 @@ public class XFramesView extends XDebugView { myToolbar = createToolbar(); myThreadsPanel = new Wrapper(); - CustomLineBorder border = new CustomLineBorder(CaptionPanel.CNT_ACTIVE_BORDER_COLOR, 0, 0, 1, 0); - myThreadsPanel.setBorder(border); + myThreadsPanel.setBorder(new CustomLineBorder(CaptionPanel.CNT_ACTIVE_BORDER_COLOR, 0, 0, 1, 0)); myThreadsPanel.add(myToolbar.getComponent(), BorderLayout.EAST); myMainPanel.add(myThreadsPanel, BorderLayout.NORTH); - - processSessionEvent(SessionEvent.RESUMED); } private ActionToolbarImpl createToolbar() { @@ -183,10 +199,12 @@ public class XFramesView extends XDebugView { } @Override - public void processSessionEvent(@NotNull final SessionEvent event) { - if (event == SessionEvent.BEFORE_RESUME) return; + public void processSessionEvent(@NotNull final SessionEvent event, @NotNull XDebugSession session) { + if (event == SessionEvent.BEFORE_RESUME) { + return; + } if (event == SessionEvent.FRAME_CHANGED) { - XStackFrame currentStackFrame = mySession.getCurrentStackFrame(); + XStackFrame currentStackFrame = session.getCurrentStackFrame(); if (currentStackFrame != null) { myFramesList.setSelectedValue(currentStackFrame, true); } @@ -199,15 +217,16 @@ public class XFramesView extends XDebugView { } myBuilders.clear(); mySelectedStack = null; - XSuspendContext suspendContext = mySession.getSuspendContext(); + XSuspendContext suspendContext = session.getSuspendContext(); if (suspendContext == null) { - requestClear(); + requestClear(session); return; } + if (event == SessionEvent.PAUSED) { // clear immediately cancelClear(); - clear(); + clear(session); } XExecutionStack[] executionStacks = suspendContext.getExecutionStacks(); @@ -222,12 +241,12 @@ public class XFramesView extends XDebugView { myThreadsPanel.add(myThreadComboBox, BorderLayout.CENTER); } myToolbar.setAddSeparatorFirst(!invisible); - updateFrames(activeExecutionStack); + updateFrames(activeExecutionStack, session); myListenersEnabled = true; } @Override - protected void clear() { + protected void clear(@Nullable XDebugSession session) { myThreadComboBox.removeAllItems(); myFramesList.clear(); myThreadsCalculated = false; @@ -244,7 +263,7 @@ public class XFramesView extends XDebugView { } } - private void updateFrames(final XExecutionStack executionStack) { + private void updateFrames(final XExecutionStack executionStack, @NotNull XDebugSession session) { if (mySelectedStack == executionStack) { return; } @@ -260,7 +279,7 @@ public class XFramesView extends XDebugView { XStackFrame topFrame = executionStack.getTopFrame(); if (topFrame != null) { myFramesList.setSelectedValue(topFrame, true); - onFrameSelected(executionStack, topFrame); + session.setCurrentStackFrame(executionStack, topFrame); } } } @@ -273,32 +292,16 @@ public class XFramesView extends XDebugView { return myFramesList; } - private void onFrameSelected(XExecutionStack executionStack, final @NotNull XStackFrame stackFrame) { - mySession.setCurrentStackFrame(executionStack, stackFrame); - } - public JPanel getMainPanel() { return myMainPanel; } - private void processFrameSelection() { - if (!myListenersEnabled) return; + private void processFrameSelection(@NotNull EventObject e) { Object selected = myFramesList.getSelectedValue(); if (selected instanceof XStackFrame) { - onFrameSelected(mySelectedStack, (XStackFrame)selected); - } - } - - private class MyItemListener implements ItemListener { - @Override - public void itemStateChanged(final ItemEvent e) { - if (!myListenersEnabled) return; - - if (e.getStateChange() == ItemEvent.SELECTED) { - Object item = e.getItem(); - if (item instanceof XExecutionStack) { - updateFrames((XExecutionStack)item); - } + XDebugSession session = getSession(e); + if (session != null) { + session.setCurrentStackFrame(mySelectedStack, (XStackFrame)selected); } } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XStandaloneVariablesView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XStandaloneVariablesView.java index f91146426878..962494a4c3cd 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XStandaloneVariablesView.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XStandaloneVariablesView.java @@ -17,9 +17,11 @@ package com.intellij.xdebugger.impl.frame; import com.intellij.openapi.project.Project; import com.intellij.ui.AppUIUtil; +import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; import com.intellij.xdebugger.frame.XStackFrame; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author nik @@ -44,10 +46,10 @@ public class XStandaloneVariablesView extends XVariablesViewBase { } @Override - public void processSessionEvent(@NotNull SessionEvent event) { + public void processSessionEvent(@NotNull SessionEvent event, @NotNull XDebugSession session) { } @Override - protected void clear() { + protected void clear(@Nullable XDebugSession session) { } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java index f5393f31cd85..295d5b622def 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java @@ -22,6 +22,7 @@ import com.intellij.xdebugger.impl.XDebugSessionImpl; import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree; import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import static com.intellij.xdebugger.impl.ui.tree.nodes.MessageTreeNode.createInfoMessage; @@ -29,16 +30,13 @@ import static com.intellij.xdebugger.impl.ui.tree.nodes.MessageTreeNode.createIn * @author nik */ public class XVariablesView extends XVariablesViewBase { - @NotNull private final XDebugSession mySession; - - public XVariablesView(@NotNull XDebugSession session) { - super(session.getProject(), session.getDebugProcess().getEditorsProvider(), ((XDebugSessionImpl)session).getValueMarkers()); - mySession = session; + public XVariablesView(@NotNull XDebugSessionImpl session) { + super(session.getProject(), session.getDebugProcess().getEditorsProvider(), session.getValueMarkers()); } @Override - public void processSessionEvent(@NotNull final SessionEvent event) { - XStackFrame stackFrame = mySession.getCurrentStackFrame(); + public void processSessionEvent(@NotNull final SessionEvent event, @NotNull XDebugSession session) { + XStackFrame stackFrame = session.getCurrentStackFrame(); XDebuggerTree tree = getTree(); if (event == SessionEvent.BEFORE_RESUME || event == SessionEvent.SETTINGS_CHANGED) { @@ -54,20 +52,21 @@ public class XVariablesView extends XVariablesViewBase { buildTreeAndRestoreState(stackFrame); } else { - requestClear(); + requestClear(session); } } - protected void clear() { + @Override + protected void clear(@Nullable XDebugSession session) { XDebuggerTree tree = getTree(); tree.setSourcePosition(null); XDebuggerTreeNode node; - if (!mySession.isStopped() && mySession.isPaused()) { + if (session == null || (!session.isStopped() && session.isPaused())) { node = createInfoMessage(tree, "Frame is not available"); } else { - XDebugProcess debugProcess = mySession.getDebugProcess(); + XDebugProcess debugProcess = session.getDebugProcess(); node = createInfoMessage(tree, debugProcess.getCurrentStateMessage(), debugProcess.getCurrentStateHyperlinkListener()); } tree.setRoot(node, true); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java index 2510cb1a89d2..6e00714b0cba 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.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. @@ -33,6 +33,7 @@ import com.intellij.ui.border.CustomLineBorder; import com.intellij.util.Alarm; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.tree.TreeUtil; +import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.XDebuggerBundle; import com.intellij.xdebugger.XExpression; import com.intellij.xdebugger.frame.XStackFrame; @@ -69,15 +70,13 @@ public class XWatchesViewImpl extends XDebugView implements DnDNativeTarget, XWa private XDebuggerTreeState myTreeState; private XDebuggerTreeRestorer myTreeRestorer; private final WatchesRootNode myRootNode; - @NotNull private final XDebugSessionImpl mySession; private final JPanel myDecoratedPanel; private final CompositeDisposable myDisposables = new CompositeDisposable(); private boolean myRebuildNeeded; - public XWatchesViewImpl(@NotNull final XDebugSessionImpl session) { - mySession = session; + public XWatchesViewImpl(@NotNull XDebugSessionImpl session) { myTreePanel = new XDebuggerTreePanel(session.getProject(), session.getDebugProcess().getEditorsProvider(), this, null, - XDebuggerActions.WATCHES_TREE_POPUP_GROUP, ((XDebugSessionImpl)session).getValueMarkers()); + XDebuggerActions.WATCHES_TREE_POPUP_GROUP, session.getValueMarkers()); ActionManager actionManager = ActionManager.getInstance(); @@ -89,7 +88,7 @@ public class XWatchesViewImpl extends XDebugView implements DnDNativeTarget, XWa actionManager.getAction(XDebuggerActions.XEDIT_WATCH).registerCustomShortcutSet(f2Shortcut, tree); DnDManager.getInstance().registerTarget(this, tree); - myRootNode = new WatchesRootNode(tree, session, this, session.getSessionData().getWatchExpressions()); + myRootNode = new WatchesRootNode(tree, this, session.getSessionData().getWatchExpressions()); tree.setRoot(myRootNode, false); final ToolbarDecorator decorator = ToolbarDecorator.createDecorator(myTreePanel.getTree()).disableUpDownActions(); @@ -134,6 +133,7 @@ public class XWatchesViewImpl extends XDebugView implements DnDNativeTarget, XWa DataContext context = DataManager.getInstance().getDataContext(watchTree); final AnActionEvent actionEvent = new AnActionEvent(null, context, "WATCH_TREE", presentation, ActionManager.getInstance(), 0); Runnable runnable = new Runnable() { + @Override public void run() { editWatchAction.actionPerformed(actionEvent); } @@ -219,15 +219,20 @@ public class XWatchesViewImpl extends XDebugView implements DnDNativeTarget, XWa @Override public void addWatchExpression(@NotNull XExpression expression, int index, final boolean navigateToWatchNode) { - myRootNode.addWatchExpression(mySession.getDebugProcess().getEvaluator(), expression, index, navigateToWatchNode); + XDebugSession session = getSession(getTree()); + if (session == null) { + return; + } + + myRootNode.addWatchExpression(session.getDebugProcess().getEvaluator(), expression, index, navigateToWatchNode); updateSessionData(); if (navigateToWatchNode) { - showWatchesTab(); + showWatchesTab((XDebugSessionImpl)session); } } - private void showWatchesTab() { - XDebugSessionTab tab = mySession.getSessionTab(); + private static void showWatchesTab(@NotNull XDebugSessionImpl session) { + XDebugSessionTab tab = session.getSessionTab(); if (tab != null) { tab.toFront(false); // restore watches tab if minimized @@ -246,7 +251,7 @@ public class XWatchesViewImpl extends XDebugView implements DnDNativeTarget, XWa } @Override - public void processSessionEvent(@NotNull final SessionEvent event) { + public void processSessionEvent(@NotNull final SessionEvent event, @NotNull XDebugSession session) { if (getMainPanel().isShowing() || ApplicationManager.getApplication().isUnitTestMode()) { myRebuildNeeded = false; } @@ -255,7 +260,7 @@ public class XWatchesViewImpl extends XDebugView implements DnDNativeTarget, XWa return; } - XStackFrame stackFrame = mySession.getCurrentStackFrame(); + XStackFrame stackFrame = session.getCurrentStackFrame(); XDebuggerTree tree = myTreePanel.getTree(); if (event == SessionEvent.BEFORE_RESUME || event == SessionEvent.SETTINGS_CHANGED) { @@ -277,11 +282,12 @@ public class XWatchesViewImpl extends XDebugView implements DnDNativeTarget, XWa } } else { - requestClear(); + requestClear(session); } } - protected void clear() { + @Override + protected void clear(@Nullable XDebugSession session) { getTree().setSourcePosition(null); myRootNode.updateWatches(null); } @@ -295,7 +301,7 @@ public class XWatchesViewImpl extends XDebugView implements DnDNativeTarget, XWa } @Override - public void removeWatches(final List nodes) { + public void removeWatches(List nodes) { List children = myRootNode.getAllChildren(); int minIndex = Integer.MAX_VALUE; List toRemove = new ArrayList(); @@ -333,7 +339,11 @@ public class XWatchesViewImpl extends XDebugView implements DnDNativeTarget, XWa watchExpressions.add(child.getExpression()); } } - mySession.setWatchExpressions(watchExpressions.toArray(new XExpression[watchExpressions.size()])); + + XDebugSession session = getSession(getTree()); + if (session != null) { + ((XDebugSessionImpl)session).setWatchExpressions(watchExpressions.toArray(new XExpression[watchExpressions.size()])); + } } @Override @@ -353,13 +363,14 @@ public class XWatchesViewImpl extends XDebugView implements DnDNativeTarget, XWa } @Override - public void drop(final DnDEvent aEvent) { + public void drop(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) { + //noinspection ConstantConditions addWatchExpression(XExpressionImpl.fromText(expression), -1, false); } } @@ -367,6 +378,7 @@ public class XWatchesViewImpl extends XDebugView implements DnDNativeTarget, XWa else if (object instanceof EventInfo) { String text = ((EventInfo)object).getTextForFlavor(DataFlavor.stringFlavor); if (text != null) { + //noinspection ConstantConditions addWatchExpression(XExpressionImpl.fromText(text), -1, false); } } 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 7c817f2e7317..71657c03d051 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 @@ -100,13 +100,13 @@ public abstract class DebuggerSessionTabBase extends LogConsoleManagerBase imple return myUi; } - protected void registerFileMatcher(final RunProfile runConfiguration) { + protected void registerFileMatcher(@NotNull RunProfile runConfiguration) { if (runConfiguration instanceof RunConfigurationBase) { myManager.registerFileMatcher((RunConfigurationBase)runConfiguration); } } - protected void initLogConsoles(final RunProfile runConfiguration, final ProcessHandler processHandler, ExecutionConsole console) { + protected void initLogConsoles(@NotNull RunProfile runConfiguration, final ProcessHandler processHandler, ExecutionConsole console) { if (runConfiguration instanceof RunConfigurationBase) { myManager.initLogConsoles((RunConfigurationBase)runConfiguration, processHandler); OutputFileUtil.attachDumpListener((RunConfigurationBase)runConfiguration, processHandler, console); 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 d831ae5fd9eb..a6191984beb4 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. @@ -28,11 +28,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; @@ -40,7 +40,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; @@ -59,30 +59,113 @@ import java.util.List; /** * @author spleaner */ -public class XDebugSessionTab extends DebuggerSessionTabBase { +public class XDebugSessionTab extends DebuggerSessionTabBase implements DataProvider { + private static final DataKey TAB_KEY = DataKey.create("XDebugSessionTab"); + public static final DataKey SESSION_KEY = DataKey.create("XDebugSessionTab.XDebugSession"); + private XWatchesViewImpl myWatchesView; private final List myViews = new ArrayList(); - public XDebugSessionTab(@NotNull Project project, - @NotNull XDebugSessionImpl session, + private XDebugSessionImpl session; + + @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, contentToReuse, icon); + oldTab.attachToSession(); + return oldTab; + } + } + } + return new XDebugSessionTab(session, icon, environment, contentToReuse); + } + + private XDebugSessionTab(@NotNull XDebugSessionImpl session, @Nullable Icon icon, @Nullable ExecutionEnvironment environment, @Nullable RunContentDescriptor contentToReuse) { - super(project, "Debug", session.getSessionName(), GlobalSearchScope.allScope(project)); + super(session.getProject(), "Debug", session.getSessionName(), GlobalSearchScope.allScope(session.getProject())); + setSession(session, environment, contentToReuse, icon); + + myUi.addContent(createFramesContent(), 0, PlaceInGrid.left, false); + myUi.addContent(createVariablesContent(), 0, PlaceInGrid.center, false); + myUi.addContent(createWatchesContent(), 0, PlaceInGrid.right, false); + + for (XDebugView view : myViews) { + Disposer.register(this, view); + } + + attachToSession(); + + myUi.getContentManager().addDataProvider(this); + + 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 = XDebugSessionTab.this.session; + if (session != null && content.isSelected() && DebuggerContentInfo.WATCHES_CONTENT.equals(ViewImpl.ID.get(content))) { + if (myWatchesView.rebuildNeeded()) { + myWatchesView.processSessionEvent(XDebugView.SessionEvent.SETTINGS_CHANGED, session); + } + } + } + }, this); + + rebuildViews(); + } + + private void setSession(@NotNull XDebugSessionImpl session, @Nullable ExecutionEnvironment environment, @Nullable RunContentDescriptor contentToReuse, @Nullable Icon icon) { if (environment != null) { setEnvironment(environment); } + + this.session = session; myConsole = session.getConsoleView(); - XDebugProcess debugProcess = session.getDebugProcess(); - myRunContentDescriptor = new RunContentDescriptor(myConsole, debugProcess.getProcessHandler(), myUi.getComponent(), session.getSessionName(), icon); + myRunContentDescriptor = new RunContentDescriptor(myConsole, session.getDebugProcess().getProcessHandler(), myUi.getComponent(), session.getSessionName(), icon); if (contentToReuse != null && contentToReuse.isReuseToolWindowActivation()) { myRunContentDescriptor.setActivateToolWindowWhenAdded(contentToReuse.isActivateToolWindowWhenAdded()); } - attachToSession(session, environment, session.getSessionData(), debugProcess); } - 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 (SESSION_KEY.is(dataId)) { + return session; + } + + if (session != null) { + if (LangDataKeys.CONSOLE_VIEW.is(dataId)) { + return session.getConsoleView(); + } + else if (XDebugSessionData.DATA_KEY.is(dataId)) { + return session.getSessionData(); + } + } + + return null; + } + + private Content createVariablesContent() { final XVariablesView variablesView = new XVariablesView(session); myViews.add(variablesView); Content result = myUi.createContent(DebuggerContentInfo.VARIABLES_CONTENT, variablesView.getPanel(), @@ -92,26 +175,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) { + private Content createWatchesContent() { 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; } @@ -124,7 +206,9 @@ public class XDebugSessionTab extends DebuggerSessionTabBase { @Override public void run() { for (XDebugView view : myViews) { - view.processSessionEvent(XDebugView.SessionEvent.SETTINGS_CHANGED); + if (session != null) { + view.processSessionEvent(XDebugView.SessionEvent.SETTINGS_CHANGED, session); + } } } }); @@ -134,35 +218,12 @@ public class XDebugSessionTab extends DebuggerSessionTabBase { return myWatchesView; } - private void attachToSession(final @NotNull XDebugSessionImpl session, - @Nullable ExecutionEnvironment environment, - final @NotNull XDebugSessionData sessionData, - @NotNull XDebugProcess debugProcess) { - myUi.addContent(createFramesContent(session), 0, PlaceInGrid.left, false); - myUi.addContent(createVariablesContent(session), 0, PlaceInGrid.center, false); - myUi.addContent(createWatchesContent(session), 0, PlaceInGrid.right, false); + private void attachToSession() { 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); @@ -175,6 +236,7 @@ public class XDebugSessionTab extends DebuggerSessionTabBase { DefaultActionGroup leftToolbar = new DefaultActionGroup(); final Executor debugExecutor = DefaultDebugExecutor.getDebugExecutorInstance(); + ExecutionEnvironment environment = getEnvironment(); final Executor executor = environment != null ? environment.getExecutor() : debugExecutor; if (environment != null) { RestartAction restartAction = new RestartAction(executor, myRunContentDescriptor, environment); @@ -219,7 +281,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)); } @@ -234,35 +296,21 @@ public class XDebugSessionTab extends DebuggerSessionTabBase { 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(); + RunProfile runConfiguration = environment.getRunProfile(); registerFileMatcher(runConfiguration); initLogConsoles(runConfiguration, 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 session != null; + session = null; + } @Override @Nullable 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/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 myChildren; private List 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(); 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 {