3 // Copyright by Johannes Sixt
4 // This file is under GPL, the GNU General Public Licence
8 #include <klocale.h> /* i18n */
11 #include <kstatusbar.h>
13 #include <kiconloader.h>
14 #include <kstdaccel.h>
15 #include <kfiledialog.h>
18 #include <qfileinfo.h>
19 #include "dbgmainwnd.h"
22 #include "commandids.h"
25 #include "threadlist.h"
26 #include "memwindow.h"
28 #include "procattach.h"
32 DebuggerMainWnd::DebuggerMainWnd(const char* name
) :
36 setDockManager(new DockManager( this, QString(name
)+"_DockManager"));
40 DockWidget
* dw0
= createDockWidget("Source", p
);
41 dw0
->setCaption(i18n("Source"));
42 m_filesWindow
= new WinStack(dw0
, "files");
45 DockWidget
* dw1
= createDockWidget("Stack", p
);
46 dw1
->setCaption(i18n("Stack"));
47 m_btWindow
= new QListBox(dw1
, "backtrace");
48 DockWidget
* dw2
= createDockWidget("Locals", p
);
49 dw2
->setCaption(i18n("Locals"));
50 m_localVariables
= new ExprWnd(dw2
, "locals");
51 DockWidget
* dw3
= createDockWidget("Watches", p
);
52 dw3
->setCaption(i18n("Watches"));
53 m_watches
= new WatchWindow(dw3
, "watches");
54 DockWidget
* dw4
= createDockWidget("Registers", p
);
55 dw4
->setCaption(i18n("Registers"));
56 m_registers
= new RegisterView(dw4
, "registers");
57 DockWidget
* dw5
= createDockWidget("Breakpoints", p
);
58 dw5
->setCaption(i18n("Breakpoints"));
59 m_bpTable
= new BreakpointTable(dw5
, "breakpoints");
60 DockWidget
* dw6
= createDockWidget("Output", p
);
61 dw6
->setCaption(i18n("Output"));
62 m_ttyWindow
= new TTYWindow(dw6
, "output");
63 DockWidget
* dw7
= createDockWidget("Threads", p
);
64 dw7
->setCaption(i18n("Threads"));
65 m_threads
= new ThreadList(dw7
, "threads");
66 DockWidget
* dw8
= createDockWidget("Memory", p
);
67 dw8
->setCaption(i18n("Memory"));
68 m_memoryWindow
= new MemoryWindow(dw8
, "memory");
70 m_menuRecentExecutables
= new QPopupMenu();
72 setupDebugger(this, m_localVariables
, m_watches
->watchVariables(), m_btWindow
);
73 m_bpTable
->setDebugger(m_debugger
);
74 m_memoryWindow
->setDebugger(m_debugger
);
80 connect(m_watches
, SIGNAL(addWatch()), SLOT(slotAddWatch()));
81 connect(m_watches
, SIGNAL(deleteWatch()), m_debugger
, SLOT(slotDeleteWatch()));
83 m_filesWindow
->setWindowMenu(m_menuWindow
);
84 connect(&m_filesWindow
->m_findDlg
, SIGNAL(closed()), SLOT(updateUI()));
85 connect(m_filesWindow
, SIGNAL(newFileLoaded()),
86 SLOT(slotNewFileLoaded()));
87 connect(m_filesWindow
, SIGNAL(toggleBreak(const QString
&,int,const DbgAddr
&,bool)),
88 this, SLOT(slotToggleBreak(const QString
&,int,const DbgAddr
&,bool)));
89 connect(m_filesWindow
, SIGNAL(enadisBreak(const QString
&,int,const DbgAddr
&)),
90 this, SLOT(slotEnaDisBreak(const QString
&,int,const DbgAddr
&)));
91 connect(m_debugger
, SIGNAL(activateFileLine(const QString
&,int,const DbgAddr
&)),
92 m_filesWindow
, SLOT(activate(const QString
&,int,const DbgAddr
&)));
93 connect(m_debugger
, SIGNAL(executableUpdated()),
94 m_filesWindow
, SLOT(reloadAllFiles()));
95 connect(m_debugger
, SIGNAL(updatePC(const QString
&,int,const DbgAddr
&,int)),
96 m_filesWindow
, SLOT(updatePC(const QString
&,int,const DbgAddr
&,int)));
97 // value popup communication
98 connect(m_filesWindow
, SIGNAL(initiateValuePopup(const QString
&)),
99 m_debugger
, SLOT(slotValuePopup(const QString
&)));
100 connect(m_debugger
, SIGNAL(valuePopup(const QString
&)),
101 m_filesWindow
, SLOT(slotShowValueTip(const QString
&)));
103 connect(m_filesWindow
, SIGNAL(disassemble(const QString
&, int)),
104 m_debugger
, SLOT(slotDisassemble(const QString
&, int)));
105 connect(m_debugger
, SIGNAL(disassembled(const QString
&,int,const QList
<DisassembledCode
>&)),
106 m_filesWindow
, SLOT(slotDisassembled(const QString
&,int,const QList
<DisassembledCode
>&)));
108 connect(m_debugger
, SIGNAL(programStopped()), SLOT(slotProgramStopped()));
109 connect(&m_backTimer
, SIGNAL(timeout()), SLOT(slotBackTimer()));
111 connect(this, SIGNAL(setTabWidth(int)), m_filesWindow
, SIGNAL(setTabWidth(int)));
113 // Establish communication when right clicked on file window.
114 connect(m_filesWindow
, SIGNAL(filesRightClick(const QPoint
&)),
115 SLOT(slotFileWndMenu(const QPoint
&)));
116 connect(m_popupFiles
, SIGNAL(activated(int)),
117 SLOT(menuCallback(int)));
119 // Connection when right clicked on file window before any file is
121 connect(m_filesWindow
, SIGNAL(clickedRight(const QPoint
&)),
122 SLOT(slotFileWndEmptyMenu(const QPoint
&)));
123 connect(m_popupFilesEmpty
, SIGNAL(activated(int)),
124 SLOT(menuCallback(int)));
127 connect(m_filesWindow
, SIGNAL(fileChanged()), SLOT(slotFileChanged()));
128 connect(m_filesWindow
, SIGNAL(lineChanged()), SLOT(slotLineChanged()));
130 // connect breakpoint table
131 connect(m_bpTable
, SIGNAL(activateFileLine(const QString
&,int,const DbgAddr
&)),
132 m_filesWindow
, SLOT(activate(const QString
&,int,const DbgAddr
&)));
133 connect(m_debugger
, SIGNAL(updateUI()), m_bpTable
, SLOT(updateUI()));
134 connect(m_debugger
, SIGNAL(breakpointsChanged()), m_bpTable
, SLOT(updateBreakList()));
136 connect(m_debugger
, SIGNAL(registersChanged(QList
<RegisterInfo
>&)),
137 m_registers
, SLOT(updateRegisters(QList
<RegisterInfo
>&)));
139 connect(m_debugger
, SIGNAL(memoryDumpChanged(const QString
&, QList
<MemoryDump
>&)),
140 m_memoryWindow
, SLOT(slotNewMemoryDump(const QString
&, QList
<MemoryDump
>&)));
141 connect(m_debugger
, SIGNAL(saveProgramSpecific(KSimpleConfig
*)),
142 m_memoryWindow
, SLOT(saveProgramSpecific(KSimpleConfig
*)));
143 connect(m_debugger
, SIGNAL(restoreProgramSpecific(KSimpleConfig
*)),
144 m_memoryWindow
, SLOT(restoreProgramSpecific(KSimpleConfig
*)));
147 connect(m_debugger
, SIGNAL(threadsChanged(QList
<ThreadInfo
>&)),
148 m_threads
, SLOT(updateThreads(QList
<ThreadInfo
>&)));
149 connect(m_threads
, SIGNAL(setThread(int)),
150 m_debugger
, SLOT(setThread(int)));
152 // view menu changes when docking state changes
153 connect(dockManager
, SIGNAL(change()), SLOT(updateUI()));
155 // popup menu of the local variables window
156 m_popupLocals
= new QPopupMenu
;
157 m_popupLocals
->insertItem(i18n("Watch Expression"),
158 this, SLOT(slotLocalsToWatch()));
159 connect(m_localVariables
, SIGNAL(rightPressed(int, const QPoint
&)),
160 this, SLOT(slotLocalsPopup(int, const QPoint
&)));
162 restoreSettings(kapp
->getConfig());
164 connect(m_menuRecentExecutables
, SIGNAL(activated(int)), SLOT(slotRecentExec(int)));
165 fillRecentExecMenu();
168 m_bpTable
->updateUI();
172 DebuggerMainWnd::~DebuggerMainWnd()
174 saveSettings(kapp
->getConfig());
175 // must delete m_debugger early since it references our windows
178 // must disconnect from dockManager since it keeps emitting signals
179 dockManager
->disconnect(this);
181 delete m_memoryWindow
;
187 delete m_localVariables
;
189 delete m_filesWindow
;
193 delete m_menuProgram
;
198 void DebuggerMainWnd::initMenu()
200 m_menuFile
= new QPopupMenu
;
201 m_menuFile
->insertItem(i18n("&Open Source..."), this, SLOT(slotFileOpen()),
202 keys
->open(), ID_FILE_OPEN
);
203 m_menuFile
->insertItem(i18n("&Reload Source"), m_filesWindow
, SLOT(slotFileReload()),
205 m_menuFile
->insertSeparator();
206 m_menuFile
->insertItem(i18n("&Executable..."), this, SLOT(slotFileExe()),
207 0, ID_FILE_EXECUTABLE
);
208 m_menuFile
->insertItem(i18n("Recent E&xecutables"), m_menuRecentExecutables
);
209 m_menuFile
->insertItem(i18n("&Settings..."), this, SLOT(slotFileProgSettings()),
210 0, ID_FILE_PROG_SETTINGS
);
211 m_menuFile
->insertItem(i18n("&Core dump..."), this, SLOT(slotFileCore()),
212 0, ID_FILE_COREFILE
);
213 m_menuFile
->insertSeparator();
214 m_menuFile
->insertItem(i18n("&Global Options..."), this, SLOT(slotFileGlobalSettings()),
215 0, ID_FILE_GLOBAL_OPTIONS
);
216 m_menuFile
->insertSeparator();
217 m_menuFile
->insertItem(i18n("&Quit"), this, SLOT(slotFileQuit()),
218 keys
->quit(), ID_FILE_QUIT
);
220 m_menuView
= new QPopupMenu
;
221 m_menuView
->setCheckable(true);
222 m_menuView
->insertItem(i18n("&Find..."), m_filesWindow
, SLOT(slotViewFind()),
223 keys
->find(), ID_VIEW_FINDDLG
);
224 m_menuView
->insertSeparator();
225 i18n("Source &code");
226 struct { QString text
; QWidget
* w
; int id
; } dw
[] = {
227 { i18n("Stac&k"), m_btWindow
, ID_VIEW_STACK
},
228 { i18n("&Locals"), m_localVariables
, ID_VIEW_LOCALS
},
229 { i18n("&Watched expressions"), m_watches
, ID_VIEW_WATCHES
},
230 { i18n("&Registers"), m_registers
, ID_VIEW_REGISTERS
},
231 { i18n("&Breakpoints"), m_bpTable
, ID_BRKPT_LIST
},
232 { i18n("T&hreads"), m_threads
, ID_VIEW_THREADS
},
233 { i18n("&Output"), m_ttyWindow
, ID_VIEW_OUTPUT
},
234 { i18n("&Memory"), m_memoryWindow
, ID_VIEW_MEMORY
}
236 for (unsigned i
= 0; i
< sizeof(dw
)/sizeof(dw
[0]); i
++) {
237 DockWidget
* d
= dockParent(dw
[i
].w
);
238 m_menuView
->insertItem(dw
[i
].text
, d
, SLOT(changeHideShowState()),
241 m_menuView
->insertSeparator();
242 m_menuView
->insertItem(i18n("Toggle &Toolbar"), this, SLOT(slotViewToolbar()),
244 m_menuView
->insertItem(i18n("Toggle &Statusbar"), this, SLOT(slotViewStatusbar()),
245 0, ID_VIEW_STATUSBAR
);
247 m_menuProgram
= new QPopupMenu
;
248 m_menuProgram
->insertItem(i18n("&Run"), m_debugger
, SLOT(programRun()),
249 Key_F5
, ID_PROGRAM_RUN
);
250 m_menuProgram
->insertItem(i18n("Step &into"), m_debugger
, SLOT(programStep()),
251 Key_F8
, ID_PROGRAM_STEP
);
252 m_menuProgram
->insertItem(i18n("Step &over"), m_debugger
, SLOT(programNext()),
253 Key_F10
, ID_PROGRAM_NEXT
);
254 m_menuProgram
->insertItem(i18n("Step o&ut"), m_debugger
, SLOT(programFinish()),
255 Key_F6
, ID_PROGRAM_FINISH
);
256 m_menuProgram
->insertItem(i18n("Run to &cursor"), this, SLOT(slotExecUntil()),
257 Key_F7
, ID_PROGRAM_UNTIL
);
258 m_menuProgram
->insertItem(i18n("Step i&nto by instruction"), m_debugger
, SLOT(programStepi()),
259 SHIFT
+Key_F8
, ID_PROGRAM_STEPI
);
260 m_menuProgram
->insertItem(i18n("Step o&ver by instruction"), m_debugger
, SLOT(programNexti()),
261 SHIFT
+Key_F10
, ID_PROGRAM_NEXTI
);
262 m_menuProgram
->insertSeparator();
263 m_menuProgram
->insertItem(i18n("&Break"), m_debugger
, SLOT(programBreak()),
264 0, ID_PROGRAM_BREAK
);
265 m_menuProgram
->insertItem(i18n("&Kill"), m_debugger
, SLOT(programKill()),
267 m_menuProgram
->insertItem(i18n("Re&start"), m_debugger
, SLOT(programRunAgain()),
268 0, ID_PROGRAM_RUN_AGAIN
);
269 m_menuProgram
->insertItem(i18n("A&ttach..."), this, SLOT(slotExecAttach()),
270 0, ID_PROGRAM_ATTACH
);
271 m_menuProgram
->insertSeparator();
272 m_menuProgram
->insertItem(i18n("&Arguments..."), this, SLOT(slotExecArgs()),
275 m_menuBrkpt
= new QPopupMenu
;
276 m_menuBrkpt
->insertItem(i18n("Set/Clear &breakpoint"), m_filesWindow
, SLOT(slotBrkptSet()),
277 Key_F9
, ID_BRKPT_SET
);
278 m_menuBrkpt
->insertItem(i18n("Set &temporary breakpoint"),
279 m_filesWindow
, SLOT(slotBrkptSetTemp()),
280 SHIFT
+Key_F9
, ID_BRKPT_TEMP
);
281 m_menuBrkpt
->insertItem(i18n("&Enable/Disable breakpoint"),
282 m_filesWindow
, SLOT(slotBrkptEnable()),
283 CTRL
+Key_F9
, ID_BRKPT_ENABLE
);
285 m_menuWindow
= new QPopupMenu
;
286 m_menuWindow
->insertItem(i18n("&More..."), WinStack::WindowMore
);
288 connect(m_menuFile
, SIGNAL(activated(int)), SLOT(menuCallback(int)));
289 connect(m_menuView
, SIGNAL(activated(int)), SLOT(menuCallback(int)));
290 connect(m_menuProgram
, SIGNAL(activated(int)), SLOT(menuCallback(int)));
291 connect(m_menuBrkpt
, SIGNAL(activated(int)), SLOT(menuCallback(int)));
292 connect(m_menuWindow
, SIGNAL(activated(int)), SLOT(menuCallback(int)));
294 KMenuBar
* menu
= menuBar();
295 menu
->insertItem(i18n("&File"), m_menuFile
);
296 menu
->insertItem(i18n("&View"), m_menuView
);
297 menu
->insertItem(i18n("E&xecution"), m_menuProgram
);
298 menu
->insertItem(i18n("&Breakpoint"), m_menuBrkpt
);
299 menu
->insertItem(i18n("&Window"), m_menuWindow
);
302 void DebuggerMainWnd::initFileWndMenus()
304 // popup menu for file windows
305 m_popupFiles
= new QPopupMenu(this);
306 m_popupFiles
->insertItem(i18n("&Open Source..."), this, SLOT(slotFileOpen()),
307 keys
->open(), ID_FILE_OPEN
);
308 m_popupFiles
->insertSeparator();
309 m_popupFiles
->insertItem(i18n("Step &into"), m_debugger
, SLOT(programStep()),
310 Key_F8
, ID_PROGRAM_STEP
);
311 m_popupFiles
->insertItem(i18n("Step &over"), m_debugger
, SLOT(programNext()),
312 Key_F10
, ID_PROGRAM_NEXT
);
313 m_popupFiles
->insertItem(i18n("Step o&ut"), m_debugger
, SLOT(programFinish()),
314 Key_F6
, ID_PROGRAM_FINISH
);
315 m_popupFiles
->insertItem(i18n("Run to &cursor"), this, SLOT(slotExecUntil()),
316 Key_F7
, ID_PROGRAM_UNTIL
);
317 m_popupFiles
->insertSeparator();
318 m_popupFiles
->insertItem(i18n("Set/Clear &breakpoint"), m_filesWindow
, SLOT(slotBrkptSet()),
319 Key_F9
, ID_BRKPT_SET
);
321 // popup menu for when no files are loaded
322 m_popupFilesEmpty
= new QPopupMenu(this);
323 m_popupFilesEmpty
->insertItem(i18n("&Open Source..."), this, SLOT(slotFileOpen()),
324 keys
->open(), ID_FILE_OPEN
);
325 m_popupFilesEmpty
->insertSeparator();
326 m_popupFilesEmpty
->insertItem(i18n("&Executable..."), this, SLOT(slotFileExe()),
327 0, ID_FILE_EXECUTABLE
);
328 m_popupFilesEmpty
->insertItem(i18n("&Core dump..."), this, SLOT(slotFileCore()),
329 0, ID_FILE_COREFILE
);
333 static QPixmap
BarIcon(const char* name
)
335 return kapp
->getIconLoader()->loadIcon(name
);
339 void DebuggerMainWnd::initToolbar()
341 KToolBar
* toolbar
= toolBar();
342 toolbar
->insertButton(BarIcon("execopen.xpm"),ID_FILE_EXECUTABLE
,
343 SIGNAL(clicked()), this, SLOT(slotFileExe()),
344 true, i18n("Executable"));
345 toolbar
->insertButton(BarIcon("fileopen.xpm"),ID_FILE_OPEN
,
346 SIGNAL(clicked()), this, SLOT(slotFileOpen()),
347 true, i18n("Open a source file"));
348 toolbar
->insertButton(BarIcon("reload.xpm"),ID_FILE_RELOAD
,
349 SIGNAL(clicked()), m_filesWindow
, SLOT(slotFileReload()),
350 true, i18n("Reload source file"));
351 toolbar
->insertSeparator();
352 toolbar
->insertButton(BarIcon("pgmrun.xpm"),ID_PROGRAM_RUN
,
353 SIGNAL(clicked()), m_debugger
, SLOT(programRun()),
354 true, i18n("Run/Continue"));
355 toolbar
->insertButton(BarIcon("pgmstep.xpm"),ID_PROGRAM_STEP
,
356 SIGNAL(clicked()), m_debugger
, SLOT(programStep()),
357 true, i18n("Step into"));
358 toolbar
->insertButton(BarIcon("pgmnext.xpm"),ID_PROGRAM_NEXT
,
359 SIGNAL(clicked()), m_debugger
, SLOT(programNext()),
360 true, i18n("Step over"));
361 toolbar
->insertButton(BarIcon("pgmfinish.xpm"),ID_PROGRAM_FINISH
,
362 SIGNAL(clicked()), m_debugger
, SLOT(programFinish()),
363 true, i18n("Step out"));
364 toolbar
->insertButton(BarIcon("pgmstepi.xpm"),ID_PROGRAM_STEPI
,
365 SIGNAL(clicked()), m_debugger
, SLOT(programStepi()),
366 true, i18n("Step into by instruction"));
367 toolbar
->insertButton(BarIcon("pgmnexti.xpm"),ID_PROGRAM_NEXTI
,
368 SIGNAL(clicked()), m_debugger
, SLOT(programNexti()),
369 true, i18n("Step over by instruction"));
370 toolbar
->insertSeparator();
371 toolbar
->insertButton(BarIcon("brkpt.xpm"),ID_BRKPT_SET
, true,
373 toolbar
->insertSeparator();
374 toolbar
->insertButton(BarIcon("search.xpm"),ID_VIEW_FINDDLG
,
375 SIGNAL(clicked()), m_filesWindow
, SLOT(slotViewFind()),
376 true, i18n("Search"));
378 connect(toolbar
, SIGNAL(clicked(int)), SLOT(menuCallback(int)));
379 toolbar
->setBarPos(KToolBar::Top
);
380 //moveToolBar(toolbar);
384 KStatusBar
* statusbar
= statusBar();
385 statusbar
->insertItem(m_statusActive
, ID_STATUS_ACTIVE
);
386 m_lastActiveStatusText
= m_statusActive
;
387 statusbar
->insertItem(i18n("Line 00000"), ID_STATUS_LINENO
);
388 statusbar
->insertItem("", ID_STATUS_MSG
); /* message pane */
390 // reserve some translations
396 * We must override KTMainWindow's handling of close events since we have
397 * only one toplevel window, which lives on the stack (which KTMainWindow
398 * can't live with :-( )
400 void DebuggerMainWnd::closeEvent(QCloseEvent
* e
)
402 #if QT_VERSION >= 200
403 clearWFlags(WDestructiveClose
);
406 if (m_debugger
!= 0) {
407 m_debugger
->shutdown();
415 // instance properties
416 void DebuggerMainWnd::saveProperties(KConfig
* config
)
418 // session management
419 QString executable
= "";
420 if (m_debugger
!= 0) {
421 executable
= m_debugger
->executable();
423 config
->writeEntry("executable", executable
);
426 void DebuggerMainWnd::readProperties(KConfig
* config
)
428 // session management
429 QString execName
= config
->readEntry("executable");
431 TRACE("readProperties: executable=" + execName
);
432 if (!execName
.isEmpty()) {
433 debugProgram(execName
);
437 const char WindowGroup
[] = "Windows";
439 void DebuggerMainWnd::saveSettings(KConfig
* config
)
441 KConfigGroupSaver
g(config
, WindowGroup
);
443 writeDockConfig(config
);
445 DebuggerMainWndBase::saveSettings(config
);
448 void DebuggerMainWnd::restoreSettings(KConfig
* config
)
450 KConfigGroupSaver
g(config
, WindowGroup
);
452 readDockConfig(config
);
454 DebuggerMainWndBase::restoreSettings(config
);
456 emit
setTabWidth(m_tabWidth
);
459 void DebuggerMainWnd::menuCallback(int item
)
463 // start timer to move window into background
465 case ID_PROGRAM_STEP
:
466 case ID_PROGRAM_STEPI
:
467 case ID_PROGRAM_NEXT
:
468 case ID_PROGRAM_NEXTI
:
469 case ID_PROGRAM_FINISH
:
470 case ID_PROGRAM_UNTIL
:
479 void DebuggerMainWnd::updateUI()
481 // enumerate all menus
483 UpdateMenuUI
updateMenu(m_menuFile
, this, SLOT(updateUIItem(UpdateUI
*)));
484 updateMenu
.iterateMenu();
487 UpdateMenuUI
updateMenu(m_menuView
, this, SLOT(updateUIItem(UpdateUI
*)));
488 updateMenu
.iterateMenu();
491 UpdateMenuUI
updateMenu(m_menuProgram
, this, SLOT(updateUIItem(UpdateUI
*)));
492 updateMenu
.iterateMenu();
495 UpdateMenuUI
updateMenu(m_menuBrkpt
, this, SLOT(updateUIItem(UpdateUI
*)));
496 updateMenu
.iterateMenu();
499 // Update winstack float popup items
501 UpdateMenuUI
updateMenu(m_popupFilesEmpty
, this,
502 SLOT(updateUIItem(UpdateUI
*)));
503 updateMenu
.iterateMenu();
506 // Update winstack float file popup items
508 UpdateMenuUI
updateMenu(m_popupFiles
, this,
509 SLOT(updateUIItem(UpdateUI
*)));
510 updateMenu
.iterateMenu();
514 static const int toolIds
[] = {
515 ID_PROGRAM_RUN
, ID_PROGRAM_STEP
, ID_PROGRAM_NEXT
, ID_PROGRAM_FINISH
,
516 ID_PROGRAM_STEPI
, ID_PROGRAM_NEXTI
,
519 UpdateToolbarUI
updateToolbar(toolBar(), this, SLOT(updateUIItem(UpdateUI
*)),
520 toolIds
, sizeof(toolIds
)/sizeof(toolIds
[0]));
521 updateToolbar
.iterateToolbar();
525 if (m_debugger
->isProgramActive())
526 newStatus
= m_statusActive
;
527 if (newStatus
!= m_lastActiveStatusText
) {
528 statusBar()->changeItem(newStatus
, ID_STATUS_ACTIVE
);
529 m_lastActiveStatusText
= newStatus
;
531 // line number is updated in slotLineChanged
534 void DebuggerMainWnd::dockUpdateHelper(UpdateUI
* item
, QWidget
* w
)
536 if (canChangeDockVisibility(w
)) {
538 item
->setCheck(isDockVisible(w
));
541 item
->setCheck(false);
545 void DebuggerMainWnd::updateUIItem(UpdateUI
* item
)
548 case ID_VIEW_FINDDLG
:
549 item
->setCheck(m_filesWindow
->m_findDlg
.isVisible());
553 item
->enable(m_debugger
->canChangeBreakpoints());
555 case ID_BRKPT_ENABLE
:
556 item
->enable(m_debugger
->canChangeBreakpoints());
559 dockUpdateHelper(item
, m_bpTable
);
562 dockUpdateHelper(item
, m_filesWindow
);
565 dockUpdateHelper(item
, m_btWindow
);
568 dockUpdateHelper(item
, m_localVariables
);
570 case ID_VIEW_WATCHES
:
571 dockUpdateHelper(item
, m_watches
);
573 case ID_VIEW_REGISTERS
:
574 dockUpdateHelper(item
, m_registers
);
576 case ID_VIEW_THREADS
:
577 dockUpdateHelper(item
, m_threads
);
580 dockUpdateHelper(item
, m_memoryWindow
);
583 dockUpdateHelper(item
, m_ttyWindow
);
586 DebuggerMainWndBase::updateUIItem(item
);
591 void DebuggerMainWnd::updateLineItems()
593 m_filesWindow
->updateLineItems(m_debugger
);
596 void DebuggerMainWnd::slotAddWatch()
598 if (m_debugger
!= 0) {
599 QString t
= m_watches
->watchText();
600 m_debugger
->addWatch(t
);
604 void DebuggerMainWnd::slotFileChanged()
608 QString caption
= kapp
->getCaption();
612 if (m_debugger
->haveExecutable()) {
613 // basename part of executable
614 QString executable
= m_debugger
->executable();
615 const char* execBase
= executable
.data();
616 int lastSlash
= executable
.findRev('/');
618 execBase
+= lastSlash
+ 1;
626 bool anyWindows
= m_filesWindow
->activeLine(file
, line
);
627 updateLineStatus(anyWindows
? line
: -1);
636 void DebuggerMainWnd::slotLineChanged()
640 bool anyWindows
= m_filesWindow
->activeLine(file
, line
);
641 updateLineStatus(anyWindows
? line
: -1);
644 void DebuggerMainWnd::slotNewFileLoaded()
646 // updates program counter in the new file
648 m_filesWindow
->updateLineItems(m_debugger
);
651 void DebuggerMainWnd::updateLineStatus(int lineNo
)
654 statusBar()->changeItem("", ID_STATUS_LINENO
);
657 strLine
.sprintf(i18n("Line %d"), lineNo
+ 1);
658 statusBar()->changeItem(strLine
, ID_STATUS_LINENO
);
662 DockWidget
* DebuggerMainWnd::dockParent(QWidget
* w
)
664 while ((w
= w
->parentWidget()) != 0) {
665 if (w
->isA("DockWidget"))
666 return static_cast<DockWidget
*>(w
);
671 bool DebuggerMainWnd::isDockVisible(QWidget
* w
)
673 DockWidget
* d
= dockParent(w
);
674 return d
!= 0 && d
->mayBeHide();
677 bool DebuggerMainWnd::canChangeDockVisibility(QWidget
* w
)
679 DockWidget
* d
= dockParent(w
);
680 return d
!= 0 && (d
->mayBeHide() || d
->mayBeShow());
683 KToolBar
* DebuggerMainWnd::dbgToolBar()
688 KStatusBar
* DebuggerMainWnd::dbgStatusBar()
693 TTYWindow
* DebuggerMainWnd::ttyWindow()
698 void DebuggerMainWnd::slotNewStatusMsg()
700 DebuggerMainWndBase::slotNewStatusMsg();
703 void DebuggerMainWnd::slotAnimationTimeout()
705 DebuggerMainWndBase::slotAnimationTimeout();
708 void DebuggerMainWnd::slotFileGlobalSettings()
710 int oldTabWidth
= m_tabWidth
;
712 doGlobalOptions(this);
714 if (m_tabWidth
!= oldTabWidth
) {
715 emit
setTabWidth(m_tabWidth
);
719 void DebuggerMainWnd::slotDebuggerStarting()
721 DebuggerMainWndBase::slotDebuggerStarting();
724 void DebuggerMainWnd::slotToggleBreak(const QString
& fileName
, int lineNo
,
725 const DbgAddr
& address
, bool temp
)
727 // lineNo is zero-based
728 if (m_debugger
!= 0) {
729 m_debugger
->setBreakpoint(fileName
, lineNo
, address
, temp
);
733 void DebuggerMainWnd::slotEnaDisBreak(const QString
& fileName
, int lineNo
,
734 const DbgAddr
& address
)
736 // lineNo is zero-based
737 if (m_debugger
!= 0) {
738 m_debugger
->enableDisableBreakpoint(fileName
, lineNo
, address
);
742 QString
DebuggerMainWnd::createOutputWindow()
744 QString tty
= DebuggerMainWndBase::createOutputWindow();
745 if (!tty
.isEmpty()) {
746 connect(m_outputTermProc
, SIGNAL(processExited(KProcess
*)),
747 SLOT(slotTermEmuExited()));
752 void DebuggerMainWnd::slotTermEmuExited()
754 shutdownTermWindow();
757 #include <X11/Xlib.h> /* XRaiseWindow, XLowerWindow */
759 void DebuggerMainWnd::slotProgramStopped()
761 // when the program stopped, move the window to the foreground
762 if (m_popForeground
) {
763 ::XRaiseWindow(x11Display(), winId());
768 void DebuggerMainWnd::intoBackground()
770 m_backTimer
.start(m_backTimeout
, true); /* single-shot */
773 void DebuggerMainWnd::slotBackTimer()
775 ::XLowerWindow(x11Display(), winId());
778 void DebuggerMainWnd::slotRecentExec(int item
)
780 if (item
>= 0 && item
< int(m_recentExecList
.count())) {
781 QString exe
= m_recentExecList
.at(item
);
782 if (debugProgramInteractive(exe
, this)) {
785 removeRecentExec(exe
);
787 fillRecentExecMenu();
791 void DebuggerMainWnd::fillRecentExecMenu()
793 m_menuRecentExecutables
->clear();
794 for (uint i
= 0; i
< m_recentExecList
.count(); i
++) {
795 m_menuRecentExecutables
->insertItem(m_recentExecList
.at(i
), i
);
799 QString
DebuggerMainWnd::makeSourceFilter()
802 f
= m_sourceFilter
+ " " + m_headerFilter
+ i18n("|All source files\n");
803 f
+= m_sourceFilter
+ i18n("|Source files\n");
804 f
+= m_headerFilter
+ i18n("|Header files\n");
805 f
+= i18n("*|All files");
810 * Pop up the context menu in the locals window
812 void DebuggerMainWnd::slotLocalsPopup(int, const QPoint
& pt
)
814 if (m_popupLocals
->isVisible()) {
815 m_popupLocals
->hide();
817 m_popupLocals
->popup(m_localVariables
->mapToGlobal(pt
));
822 * Copies the currently selected item to the watch window.
824 void DebuggerMainWnd::slotLocalsToWatch()
826 int idx
= m_localVariables
->currentItem();
828 if (idx
>= 0 && m_debugger
!= 0) {
829 QString text
= m_localVariables
->exprStringAt(idx
);
830 m_debugger
->addWatch(text
);
834 // Pop up the context menu of the files window (for loaded files)
835 void DebuggerMainWnd::slotFileWndMenu(const QPoint
& pos
)
837 if (m_popupFiles
->isVisible()) {
838 m_popupFiles
->hide();
840 // pos is still in widget coordinates of the sender
841 const QWidget
* w
= static_cast<const QWidget
*>(sender());
842 m_popupFiles
->popup(w
->mapToGlobal(pos
));
846 // Pop up the context menu of the files window (while no file is loaded)
847 void DebuggerMainWnd::slotFileWndEmptyMenu(const QPoint
& pos
)
849 if (m_popupFilesEmpty
->isVisible()) {
850 m_popupFilesEmpty
->hide();
852 // pos is still in widget coordinates of the sender
853 const QWidget
* w
= static_cast<const QWidget
*>(sender());
854 m_popupFilesEmpty
->popup(w
->mapToGlobal(pos
));
858 void DebuggerMainWnd::slotFileOpen()
860 QString fileName
= myGetFileName(i18n("Open"),
862 makeSourceFilter(), this);
864 if (!fileName
.isEmpty())
866 QFileInfo
fi(fileName
);
867 m_lastDirectory
= fi
.dirPath();
868 m_filesWindow
->setExtraDirectory(m_lastDirectory
);
869 m_filesWindow
->activateFile(fileName
);
873 void DebuggerMainWnd::slotFileQuit()
875 if (m_debugger
!= 0) {
876 m_debugger
->shutdown();
881 void DebuggerMainWnd::slotFileExe()
883 if (m_debugger
->isIdle())
885 // open a new executable
886 QString executable
= myGetFileName(i18n("Select the executable to debug"),
887 m_lastDirectory
, 0, this);
888 if (executable
.isEmpty())
891 if (debugProgramInteractive(executable
, this)) {
892 addRecentExec(executable
);
894 // this may have changed m_lastDirectory
895 m_filesWindow
->setExtraDirectory(m_lastDirectory
);
896 fillRecentExecMenu();
900 void DebuggerMainWnd::slotFileCore()
902 if (m_debugger
->canUseCoreFile())
904 QString corefile
= myGetFileName(i18n("Select core dump"),
905 m_lastDirectory
, 0, this);
906 if (!corefile
.isEmpty()) {
907 m_debugger
->useCoreFile(corefile
, false);
912 void DebuggerMainWnd::slotFileProgSettings()
914 if (m_debugger
!= 0) {
915 m_debugger
->programSettings(this);
919 void DebuggerMainWnd::slotViewToolbar()
921 if (toolBar()->isVisible())
927 void DebuggerMainWnd::slotViewStatusbar()
929 if (statusBar()->isVisible())
935 void DebuggerMainWnd::slotExecUntil()
941 if (m_filesWindow
->activeLine(file
, lineNo
))
942 m_debugger
->runUntil(file
, lineNo
);
946 void DebuggerMainWnd::slotExecAttach()
948 ProcAttach
dlg(this);
949 dlg
.setText(m_debugger
->attachedPid());
951 m_debugger
->attachProgram(dlg
.text());
955 void DebuggerMainWnd::slotExecArgs()
957 if (m_debugger
!= 0) {
958 m_debugger
->programArgs(this);
962 #include "dbgmainwnd.moc"