Merged latest fixes and improvements from 1.2 branch.
[kdbg.git] / kdbg / dbgmainwnd.cpp
blob5961f3a8b13d71fb9cf93ed63f338c99fcd63079
1 // $Id$
3 // Copyright by Johannes Sixt
4 // This file is under GPL, the GNU General Public Licence
6 #include <kapp.h>
7 #if QT_VERSION >= 200
8 #include <klocale.h> /* i18n */
9 #include <kmenubar.h>
10 #include <kconfig.h>
11 #include <kstatusbar.h>
12 #endif
13 #include <kiconloader.h>
14 #include <kstdaccel.h>
15 #include <kfiledialog.h>
16 #include <kprocess.h>
17 #include <qlistbox.h>
18 #include <qfileinfo.h>
19 #include "dbgmainwnd.h"
20 #include "debugger.h"
21 #include "updateui.h"
22 #include "commandids.h"
23 #include "winstack.h"
24 #include "brkpt.h"
25 #include "threadlist.h"
26 #include "memwindow.h"
27 #include "ttywnd.h"
28 #include "procattach.h"
29 #include "mydebug.h"
32 DebuggerMainWnd::DebuggerMainWnd(const char* name) :
33 DockMainWindow(name),
34 DebuggerMainWndBase()
36 setDockManager(new DockManager( this, QString(name)+"_DockManager"));
38 QPixmap p;
40 DockWidget* dw0 = createDockWidget("Source", p);
41 dw0->setCaption(i18n("Source"));
42 m_filesWindow = new WinStack(dw0, "files");
43 setView(dw0);
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);
76 initMenu();
77 initFileWndMenus();
78 initToolbar();
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&)));
102 // disassembling
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>&)));
107 // program stopped
108 connect(m_debugger, SIGNAL(programStopped()), SLOT(slotProgramStopped()));
109 connect(&m_backTimer, SIGNAL(timeout()), SLOT(slotBackTimer()));
110 // tab width
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
120 // loaded.
121 connect(m_filesWindow, SIGNAL(clickedRight(const QPoint &)),
122 SLOT(slotFileWndEmptyMenu(const QPoint &)));
123 connect(m_popupFilesEmpty, SIGNAL(activated(int)),
124 SLOT(menuCallback(int)));
126 // file/line updates
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*)));
146 // thread window
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();
167 updateUI();
168 m_bpTable->updateUI();
169 slotFileChanged();
172 DebuggerMainWnd::~DebuggerMainWnd()
174 saveSettings(kapp->getConfig());
175 // must delete m_debugger early since it references our windows
176 delete m_debugger;
177 m_debugger = 0;
178 // must disconnect from dockManager since it keeps emitting signals
179 dockManager->disconnect(this);
181 delete m_memoryWindow;
182 delete m_threads;
183 delete m_ttyWindow;
184 delete m_bpTable;
185 delete m_registers;
186 delete m_watches;
187 delete m_localVariables;
188 delete m_btWindow;
189 delete m_filesWindow;
191 delete m_menuWindow;
192 delete m_menuBrkpt;
193 delete m_menuProgram;
194 delete m_menuView;
195 delete m_menuFile;
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()),
204 0, ID_FILE_RELOAD);
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()),
239 0, dw[i].id);
241 m_menuView->insertSeparator();
242 m_menuView->insertItem(i18n("Toggle &Toolbar"), this, SLOT(slotViewToolbar()),
243 0, ID_VIEW_TOOLBAR);
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()),
266 0, ID_PROGRAM_KILL);
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()),
273 0, ID_PROGRAM_ARGS);
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);
332 #if QT_VERSION < 200
333 static QPixmap BarIcon(const char* name)
335 return kapp->getIconLoader()->loadIcon(name);
337 #endif
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,
372 i18n("Breakpoint"));
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);
382 initAnimation();
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
391 i18n("Restart");
392 i18n("Core dump");
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);
404 #endif
406 if (m_debugger != 0) {
407 m_debugger->shutdown();
410 e->accept();
411 kapp->quit();
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)
461 if (m_popForeground)
463 // start timer to move window into background
464 switch (item) {
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:
471 case ID_PROGRAM_RUN:
472 intoBackground();
473 break;
476 updateUI();
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();
513 // toolbar
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,
517 ID_BRKPT_SET
519 UpdateToolbarUI updateToolbar(toolBar(), this, SLOT(updateUIItem(UpdateUI*)),
520 toolIds, sizeof(toolIds)/sizeof(toolIds[0]));
521 updateToolbar.iterateToolbar();
523 // update statusbar
524 QString newStatus;
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)) {
537 item->enable(true);
538 item->setCheck(isDockVisible(w));
539 } else {
540 item->enable(false);
541 item->setCheck(false);
545 void DebuggerMainWnd::updateUIItem(UpdateUI* item)
547 switch (item->id) {
548 case ID_VIEW_FINDDLG:
549 item->setCheck(m_filesWindow->m_findDlg.isVisible());
550 break;
551 case ID_BRKPT_SET:
552 case ID_BRKPT_TEMP:
553 item->enable(m_debugger->canChangeBreakpoints());
554 break;
555 case ID_BRKPT_ENABLE:
556 item->enable(m_debugger->canChangeBreakpoints());
557 break;
558 case ID_BRKPT_LIST:
559 dockUpdateHelper(item, m_bpTable);
560 break;
561 case ID_VIEW_SOURCE:
562 dockUpdateHelper(item, m_filesWindow);
563 break;
564 case ID_VIEW_STACK:
565 dockUpdateHelper(item, m_btWindow);
566 break;
567 case ID_VIEW_LOCALS:
568 dockUpdateHelper(item, m_localVariables);
569 break;
570 case ID_VIEW_WATCHES:
571 dockUpdateHelper(item, m_watches);
572 break;
573 case ID_VIEW_REGISTERS:
574 dockUpdateHelper(item, m_registers);
575 break;
576 case ID_VIEW_THREADS:
577 dockUpdateHelper(item, m_threads);
578 break;
579 case ID_VIEW_MEMORY:
580 dockUpdateHelper(item, m_memoryWindow);
581 break;
582 case ID_VIEW_OUTPUT:
583 dockUpdateHelper(item, m_ttyWindow);
584 break;
585 default:
586 DebuggerMainWndBase::updateUIItem(item);
587 break;
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()
606 // set caption
607 #if QT_VERSION < 200
608 QString caption = kapp->getCaption();
609 #else
610 QString caption;
611 #endif
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('/');
617 if (lastSlash >= 0)
618 execBase += lastSlash + 1;
619 #if QT_VERSION < 200
620 caption += ": ";
621 #endif
622 caption += execBase;
624 QString file;
625 int line;
626 bool anyWindows = m_filesWindow->activeLine(file, line);
627 updateLineStatus(anyWindows ? line : -1);
628 if (anyWindows) {
629 caption += " (";
630 caption += file;
631 caption += ")";
633 setCaption(caption);
636 void DebuggerMainWnd::slotLineChanged()
638 QString file;
639 int line;
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
647 if (m_debugger != 0)
648 m_filesWindow->updateLineItems(m_debugger);
651 void DebuggerMainWnd::updateLineStatus(int lineNo)
653 if (lineNo < 0) {
654 statusBar()->changeItem("", ID_STATUS_LINENO);
655 } else {
656 QString strLine;
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);
668 return 0;
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()
685 return toolBar();
688 KStatusBar* DebuggerMainWnd::dbgStatusBar()
690 return statusBar();
693 TTYWindow* DebuggerMainWnd::ttyWindow()
695 return m_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()));
749 return tty;
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());
765 m_backTimer.stop();
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)) {
783 addRecentExec(exe);
784 } else {
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()
801 QString f;
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");
806 return f;
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();
816 } else {
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();
839 } else {
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();
851 } else {
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"),
861 m_lastDirectory,
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();
878 kapp->quit();
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())
889 return;
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())
922 toolBar()->hide();
923 else
924 toolBar()->show();
927 void DebuggerMainWnd::slotViewStatusbar()
929 if (statusBar()->isVisible())
930 statusBar()->hide();
931 else
932 statusBar()->show();
935 void DebuggerMainWnd::slotExecUntil()
937 if (m_debugger != 0)
939 QString file;
940 int lineNo;
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());
950 if (dlg.exec()) {
951 m_debugger->attachProgram(dlg.text());
955 void DebuggerMainWnd::slotExecArgs()
957 if (m_debugger != 0) {
958 m_debugger->programArgs(this);
962 #include "dbgmainwnd.moc"