2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com
.intellij
.xdebugger
.impl
.ui
;
18 import com
.intellij
.debugger
.ui
.DebuggerContentInfo
;
19 import com
.intellij
.execution
.DefaultExecutionResult
;
20 import com
.intellij
.execution
.ExecutionManager
;
21 import com
.intellij
.execution
.ExecutionResult
;
22 import com
.intellij
.execution
.Executor
;
23 import com
.intellij
.execution
.configurations
.RunProfile
;
24 import com
.intellij
.execution
.executors
.DefaultDebugExecutor
;
25 import com
.intellij
.execution
.process
.ProcessAdapter
;
26 import com
.intellij
.execution
.process
.ProcessEvent
;
27 import com
.intellij
.execution
.process
.ProcessHandler
;
28 import com
.intellij
.execution
.runners
.ExecutionEnvironment
;
29 import com
.intellij
.execution
.runners
.ProgramRunner
;
30 import com
.intellij
.execution
.runners
.RestartAction
;
31 import com
.intellij
.execution
.ui
.*;
32 import com
.intellij
.execution
.ui
.actions
.CloseAction
;
33 import com
.intellij
.execution
.ui
.layout
.PlaceInGrid
;
34 import com
.intellij
.ide
.CommonActionsManager
;
35 import com
.intellij
.ide
.actions
.ContextHelpAction
;
36 import com
.intellij
.ide
.impl
.ProjectUtil
;
37 import com
.intellij
.openapi
.actionSystem
.*;
38 import com
.intellij
.openapi
.application
.ApplicationManager
;
39 import com
.intellij
.openapi
.project
.Project
;
40 import com
.intellij
.openapi
.wm
.ex
.WindowManagerEx
;
41 import com
.intellij
.ui
.content
.Content
;
42 import com
.intellij
.ui
.content
.tabs
.PinToolwindowTabAction
;
43 import com
.intellij
.xdebugger
.XDebugProcess
;
44 import com
.intellij
.xdebugger
.XDebugSession
;
45 import com
.intellij
.xdebugger
.XDebuggerBundle
;
46 import com
.intellij
.xdebugger
.impl
.XDebugSessionImpl
;
47 import com
.intellij
.xdebugger
.impl
.actions
.XDebuggerActions
;
48 import com
.intellij
.xdebugger
.impl
.frame
.XDebugViewBase
;
49 import com
.intellij
.xdebugger
.impl
.frame
.XFramesView
;
50 import com
.intellij
.xdebugger
.impl
.frame
.XVariablesView
;
51 import com
.intellij
.xdebugger
.impl
.frame
.XWatchesView
;
52 import org
.jetbrains
.annotations
.NotNull
;
53 import org
.jetbrains
.annotations
.Nullable
;
55 import java
.util
.ArrayList
;
56 import java
.util
.Collection
;
57 import java
.util
.List
;
62 public class XDebugSessionTab
extends DebuggerLogConsoleManagerBase
{
63 private final String mySessionName
;
64 private final RunnerLayoutUi myUi
;
65 private RunContentDescriptor myRunContentDescriptor
;
66 private ExecutionConsole myConsole
;
67 private XWatchesView myWatchesView
;
68 private final List
<XDebugViewBase
> myViews
= new ArrayList
<XDebugViewBase
>();
70 public XDebugSessionTab(@NotNull final Project project
, @NotNull final String sessionName
) {
72 mySessionName
= sessionName
;
74 myUi
= RunnerLayoutUi
.Factory
.getInstance(project
).create("Debug", "unknown!", sessionName
, this);
75 myUi
.getDefaults().initTabDefaults(0, "Debug", null);
77 myUi
.getOptions().setTopToolbar(createTopToolbar(), ActionPlaces
.DEBUGGER_TOOLBAR
);
80 private Content
createConsoleContent() {
81 return myUi
.createContent(DebuggerContentInfo
.CONSOLE_CONTENT
, myConsole
.getComponent(),
82 XDebuggerBundle
.message("debugger.session.tab.console.content.name"), XDebuggerUIConstants
.CONSOLE_TAB_ICON
,
83 myConsole
.getPreferredFocusableComponent());
86 private Content
createVariablesContent(final XDebugSession session
) {
87 final XVariablesView variablesView
= new XVariablesView(session
, this);
88 myViews
.add(variablesView
);
89 return myUi
.createContent(DebuggerContentInfo
.VARIABLES_CONTENT
, variablesView
.getPanel(),
90 XDebuggerBundle
.message("debugger.session.tab.variables.title"), XDebuggerUIConstants
.VARIABLES_TAB_ICON
, null);
93 private Content
createWatchesContent(final XDebugSession session
, final XDebugSessionData sessionData
) {
94 myWatchesView
= new XWatchesView(session
, this, sessionData
);
95 myViews
.add(myWatchesView
);
96 Content watchesContent
= myUi
.createContent(DebuggerContentInfo
.WATCHES_CONTENT
, myWatchesView
.getMainPanel(),
97 XDebuggerBundle
.message("debugger.session.tab.watches.title"), XDebuggerUIConstants
.WATCHES_TAB_ICON
, null);
99 ActionGroup group
= (ActionGroup
)ActionManager
.getInstance().getAction(XDebuggerActions
.WATCHES_TREE_TOOLBAR_GROUP
);
100 watchesContent
.setActions(group
, ActionPlaces
.DEBUGGER_TOOLBAR
, myWatchesView
.getTree());
101 return watchesContent
;
104 private Content
createFramesContent(final XDebugSession session
) {
105 final XFramesView framesView
= new XFramesView(session
, this);
106 myViews
.add(framesView
);
107 Content framesContent
= myUi
.createContent(DebuggerContentInfo
.FRAME_CONTENT
, framesView
.getMainPanel(),
108 XDebuggerBundle
.message("debugger.session.tab.frames.title"), XDebuggerUIConstants
.FRAMES_TAB_ICON
, null);
109 final DefaultActionGroup framesGroup
= new DefaultActionGroup();
111 CommonActionsManager actionsManager
= CommonActionsManager
.getInstance();
112 framesGroup
.add(actionsManager
.createPrevOccurenceAction(framesView
.getFramesList()));
113 framesGroup
.add(actionsManager
.createNextOccurenceAction(framesView
.getFramesList()));
115 framesContent
.setActions(framesGroup
, ActionPlaces
.DEBUGGER_TOOLBAR
, framesView
.getFramesList());
116 return framesContent
;
119 private static DefaultActionGroup
createTopToolbar() {
120 DefaultActionGroup stepping
= new DefaultActionGroup();
121 ActionManager actionManager
= ActionManager
.getInstance();
122 stepping
.add(actionManager
.getAction(XDebuggerActions
.SHOW_EXECUTION_POINT
));
123 stepping
.addSeparator();
124 stepping
.add(actionManager
.getAction(XDebuggerActions
.STEP_OVER
));
125 stepping
.add(actionManager
.getAction(XDebuggerActions
.STEP_INTO
));
126 stepping
.add(actionManager
.getAction(XDebuggerActions
.FORCE_STEP_INTO
));
127 stepping
.add(actionManager
.getAction(XDebuggerActions
.STEP_OUT
));
128 stepping
.addSeparator();
129 stepping
.add(actionManager
.getAction(XDebuggerActions
.RUN_TO_CURSOR
));
133 public XDebugSessionData
saveData() {
134 final List
<String
> watchExpressions
= myWatchesView
.getWatchExpressions();
135 return new XDebugSessionData(watchExpressions
.toArray(new String
[watchExpressions
.size()]));
138 public ExecutionConsole
getConsole() {
142 public String
getSessionName() {
143 return mySessionName
;
146 public void rebuildViews() {
147 for (XDebugViewBase view
: myViews
) {
152 public RunContentDescriptor
attachToSession(final @NotNull XDebugSession session
, final @Nullable ProgramRunner runner
,
153 final @Nullable ExecutionEnvironment env
,
154 final @NotNull XDebugSessionData sessionData
) {
155 return initUI(session
, sessionData
, env
, runner
);
159 private static ExecutionResult
createExecutionResult(@NotNull final XDebugSession session
) {
160 final XDebugProcess debugProcess
= session
.getDebugProcess();
161 ProcessHandler processHandler
= debugProcess
.getProcessHandler();
162 processHandler
.addProcessListener(new ProcessAdapter() {
163 public void processTerminated(final ProcessEvent event
) {
164 ((XDebugSessionImpl
)session
).stopImpl();
167 return new DefaultExecutionResult(debugProcess
.createConsole(), processHandler
);
170 public XWatchesView
getWatchesView() {
171 return myWatchesView
;
174 private RunContentDescriptor
initUI(final @NotNull XDebugSession session
, final @NotNull XDebugSessionData sessionData
,
175 final @Nullable ExecutionEnvironment environment
, final @Nullable ProgramRunner runner
) {
176 ExecutionResult executionResult
= createExecutionResult(session
);
177 myConsole
= executionResult
.getExecutionConsole();
179 myUi
.addContent(createFramesContent(session
), 0, PlaceInGrid
.left
, false);
180 myUi
.addContent(createVariablesContent(session
), 0, PlaceInGrid
.center
, false);
181 myUi
.addContent(createWatchesContent(session
, sessionData
), 0, PlaceInGrid
.right
, false);
182 final Content consoleContent
= createConsoleContent();
183 myUi
.addContent(consoleContent
, 1, PlaceInGrid
.bottom
, false);
184 if (myConsole
instanceof ObservableConsoleView
) {
185 ObservableConsoleView observable
= (ObservableConsoleView
)myConsole
;
186 observable
.addChangeListener(new ObservableConsoleView
.ChangeListener() {
187 public void contentAdded(final Collection
<ConsoleViewContentType
> types
) {
188 if (types
.contains(ConsoleViewContentType
.ERROR_OUTPUT
) || types
.contains(ConsoleViewContentType
.SYSTEM_OUTPUT
)) {
189 consoleContent
.fireAlert();
196 myRunContentDescriptor
= new RunContentDescriptor(myConsole
, executionResult
.getProcessHandler(), myUi
.getComponent(), getSessionName());
198 if (ApplicationManager
.getApplication().isUnitTestMode()) {
199 return myRunContentDescriptor
;
202 DefaultActionGroup group
= new DefaultActionGroup();
203 final Executor executor
= DefaultDebugExecutor
.getDebugExecutorInstance();
204 if (runner
!= null && environment
!= null) {
205 RestartAction restarAction
= new RestartAction(executor
, runner
, myRunContentDescriptor
.getProcessHandler(), XDebuggerUIConstants
.DEBUG_AGAIN_ICON
,
206 myRunContentDescriptor
, environment
);
207 group
.add(restarAction
);
208 restarAction
.registerShortcut(myUi
.getComponent());
211 addActionToGroup(group
, XDebuggerActions
.RESUME
);
212 addActionToGroup(group
, XDebuggerActions
.PAUSE
);
213 addActionToGroup(group
, IdeActions
.ACTION_STOP_PROGRAM
);
215 group
.addSeparator();
217 addActionToGroup(group
, XDebuggerActions
.VIEW_BREAKPOINTS
);
218 addActionToGroup(group
, XDebuggerActions
.MUTE_BREAKPOINTS
);
220 group
.addSeparator();
221 //addAction(group, DebuggerActions.EXPORT_THREADS);
222 group
.addSeparator();
224 group
.add(myUi
.getOptions().getLayoutActions());
226 group
.addSeparator();
228 group
.add(PinToolwindowTabAction
.getPinAction());
229 group
.add(new CloseAction(executor
, myRunContentDescriptor
, getProject()));
230 group
.add(new ContextHelpAction(executor
.getHelpId()));
232 myUi
.getOptions().setLeftToolbar(group
, ActionPlaces
.DEBUGGER_TOOLBAR
);
234 if (environment
!= null) {
235 final RunProfile runConfiguration
= environment
.getRunProfile();
236 registerFileMatcher(runConfiguration
);
237 initLogConsoles(runConfiguration
, myRunContentDescriptor
.getProcessHandler());
242 return myRunContentDescriptor
;
245 private static void addActionToGroup(final DefaultActionGroup group
, final String actionId
) {
246 AnAction action
= ActionManager
.getInstance().getAction(actionId
);
247 if (action
!= null) group
.add(action
);
250 public RunnerLayoutUi
getUi() {
255 public RunContentDescriptor
getRunContentDescriptor() {
256 return myRunContentDescriptor
;
259 public void toFront() {
260 ApplicationManager
.getApplication().invokeLater(new Runnable() {
262 ProjectUtil
.focusProjectWindow(getProject());
263 ExecutionManager
.getInstance(getProject()).getContentManager().toFrontRunContent(DefaultDebugExecutor
.getDebugExecutorInstance(), myRunContentDescriptor
);