Add QTL classes to qt3.kdbgtt.
[kdbg.git] / kdbg / dbgmainwnd.cpp
blob48387a9feb2980f489dfffe96524b100d1576f91
1 /*
2 * Copyright Johannes Sixt
3 * This file is licensed under the GNU General Public License Version 2.
4 * See the file COPYING in the toplevel directory of the source directory.
5 */
7 #include <kapp.h>
8 #include <klocale.h> /* i18n */
9 #include <kmessagebox.h>
10 #include <kconfig.h>
11 #include <kstatusbar.h>
12 #include <kiconloader.h>
13 #include <kstdaccel.h>
14 #include <kstdaction.h>
15 #include <kaction.h>
16 #include <kpopupmenu.h>
17 #include <kfiledialog.h>
18 #include <kprocess.h>
19 #include <kkeydialog.h>
20 #include <kanimwidget.h>
21 #include <kwin.h>
22 #include <qlistbox.h>
23 #include <qfileinfo.h>
24 #include "dbgmainwnd.h"
25 #include "debugger.h"
26 #include "commandids.h"
27 #include "winstack.h"
28 #include "brkpt.h"
29 #include "threadlist.h"
30 #include "memwindow.h"
31 #include "ttywnd.h"
32 #include "procattach.h"
33 #include "dbgdriver.h"
34 #include "mydebug.h"
35 #ifdef HAVE_CONFIG_H
36 #include "config.h"
37 #endif
40 DebuggerMainWnd::DebuggerMainWnd(const char* name) :
41 KDockMainWindow(0, name),
42 DebuggerMainWndBase()
44 QPixmap p;
46 KDockWidget* dw0 = createDockWidget("Source", p, 0, i18n("Source"));
47 m_filesWindow = new WinStack(dw0, "files");
48 dw0->setWidget(m_filesWindow);
49 dw0->setDockSite(KDockWidget::DockCorner);
50 dw0->setEnableDocking(KDockWidget::DockNone);
51 setView(dw0);
52 setMainDockWidget(dw0);
54 KDockWidget* dw1 = createDockWidget("Stack", p, 0, i18n("Stack"));
55 m_btWindow = new QListBox(dw1, "backtrace");
56 dw1->setWidget(m_btWindow);
57 KDockWidget* dw2 = createDockWidget("Locals", p, 0, i18n("Locals"));
58 m_localVariables = new ExprWnd(dw2, i18n("Variable"), "locals");
59 dw2->setWidget(m_localVariables);
60 KDockWidget* dw3 = createDockWidget("Watches", p, 0, i18n("Watches"));
61 m_watches = new WatchWindow(dw3, "watches");
62 dw3->setWidget(m_watches);
63 KDockWidget* dw4 = createDockWidget("Registers", p, 0, i18n("Registers"));
64 m_registers = new RegisterView(dw4, "registers");
65 dw4->setWidget(m_registers);
66 KDockWidget* dw5 = createDockWidget("Breakpoints", p, 0, i18n("Breakpoints"));
67 m_bpTable = new BreakpointTable(dw5, "breakpoints");
68 dw5->setWidget(m_bpTable);
69 KDockWidget* dw6 = createDockWidget("Output", p, 0, i18n("Output"));
70 m_ttyWindow = new TTYWindow(dw6, "output");
71 dw6->setWidget(m_ttyWindow);
72 KDockWidget* dw7 = createDockWidget("Threads", p, 0, i18n("Threads"));
73 m_threads = new ThreadList(dw7, "threads");
74 dw7->setWidget(m_threads);
75 KDockWidget* dw8 = createDockWidget("Memory", p, 0, i18n("Memory"));
76 m_memoryWindow = new MemoryWindow(dw8, "memory");
77 dw8->setWidget(m_memoryWindow);
79 setupDebugger(this, m_localVariables, m_watches->watchVariables(), m_btWindow);
80 m_bpTable->setDebugger(m_debugger);
81 m_memoryWindow->setDebugger(m_debugger);
83 setStandardToolBarMenuEnabled(true);
84 initKAction();
85 initToolbar(); // kind of obsolete?
87 connect(m_watches, SIGNAL(addWatch()), SLOT(slotAddWatch()));
88 connect(m_watches, SIGNAL(deleteWatch()), m_debugger, SLOT(slotDeleteWatch()));
89 connect(m_watches, SIGNAL(textDropped(const QString&)), SLOT(slotAddWatch(const QString&)));
91 KAction* windowMenu = actionCollection()->action("window");
92 m_filesWindow->setWindowMenu(static_cast<KActionMenu*>(windowMenu)->popupMenu());
93 connect(&m_filesWindow->m_findDlg, SIGNAL(closed()), SLOT(updateUI()));
94 connect(m_filesWindow, SIGNAL(newFileLoaded()),
95 SLOT(slotNewFileLoaded()));
96 connect(m_filesWindow, SIGNAL(toggleBreak(const QString&,int,const DbgAddr&,bool)),
97 this, SLOT(slotToggleBreak(const QString&,int,const DbgAddr&,bool)));
98 connect(m_filesWindow, SIGNAL(enadisBreak(const QString&,int,const DbgAddr&)),
99 this, SLOT(slotEnaDisBreak(const QString&,int,const DbgAddr&)));
100 connect(m_debugger, SIGNAL(activateFileLine(const QString&,int,const DbgAddr&)),
101 m_filesWindow, SLOT(activate(const QString&,int,const DbgAddr&)));
102 connect(m_debugger, SIGNAL(executableUpdated()),
103 m_filesWindow, SLOT(reloadAllFiles()));
104 connect(m_debugger, SIGNAL(updatePC(const QString&,int,const DbgAddr&,int)),
105 m_filesWindow, SLOT(updatePC(const QString&,int,const DbgAddr&,int)));
106 // value popup communication
107 connect(m_filesWindow, SIGNAL(initiateValuePopup(const QString&)),
108 m_debugger, SLOT(slotValuePopup(const QString&)));
109 connect(m_debugger, SIGNAL(valuePopup(const QString&)),
110 m_filesWindow, SLOT(slotShowValueTip(const QString&)));
111 // disassembling
112 connect(m_filesWindow, SIGNAL(disassemble(const QString&, int)),
113 m_debugger, SLOT(slotDisassemble(const QString&, int)));
114 connect(m_debugger, SIGNAL(disassembled(const QString&,int,const QList<DisassembledCode>&)),
115 m_filesWindow, SLOT(slotDisassembled(const QString&,int,const QList<DisassembledCode>&)));
116 connect(m_filesWindow, SIGNAL(moveProgramCounter(const QString&,int,const DbgAddr&)),
117 m_debugger, SLOT(setProgramCounter(const QString&,int,const DbgAddr&)));
118 // program stopped
119 connect(m_debugger, SIGNAL(programStopped()), SLOT(slotProgramStopped()));
120 connect(&m_backTimer, SIGNAL(timeout()), SLOT(slotBackTimer()));
121 // tab width
122 connect(this, SIGNAL(setTabWidth(int)), m_filesWindow, SIGNAL(setTabWidth(int)));
124 // file/line updates
125 connect(m_filesWindow, SIGNAL(fileChanged()), SLOT(slotFileChanged()));
127 // connect breakpoint table
128 connect(m_bpTable, SIGNAL(activateFileLine(const QString&,int,const DbgAddr&)),
129 m_filesWindow, SLOT(activate(const QString&,int,const DbgAddr&)));
130 connect(m_debugger, SIGNAL(updateUI()), m_bpTable, SLOT(updateUI()));
131 connect(m_debugger, SIGNAL(breakpointsChanged()), m_bpTable, SLOT(updateBreakList()));
132 connect(m_debugger, SIGNAL(breakpointsChanged()), m_bpTable, SLOT(updateUI()));
134 connect(m_debugger, SIGNAL(registersChanged(QList<RegisterInfo>&)),
135 m_registers, SLOT(updateRegisters(QList<RegisterInfo>&)));
137 connect(m_debugger, SIGNAL(memoryDumpChanged(const QString&, QList<MemoryDump>&)),
138 m_memoryWindow, SLOT(slotNewMemoryDump(const QString&, QList<MemoryDump>&)));
139 connect(m_debugger, SIGNAL(saveProgramSpecific(KConfigBase*)),
140 m_memoryWindow, SLOT(saveProgramSpecific(KConfigBase*)));
141 connect(m_debugger, SIGNAL(restoreProgramSpecific(KConfigBase*)),
142 m_memoryWindow, SLOT(restoreProgramSpecific(KConfigBase*)));
144 // thread window
145 connect(m_debugger, SIGNAL(threadsChanged(QList<ThreadInfo>&)),
146 m_threads, SLOT(updateThreads(QList<ThreadInfo>&)));
147 connect(m_threads, SIGNAL(setThread(int)),
148 m_debugger, SLOT(setThread(int)));
150 // view menu changes when docking state changes
151 connect(dockManager, SIGNAL(change()), SLOT(updateUI()));
153 // popup menu of the local variables window
154 connect(m_localVariables, SIGNAL(contextMenuRequested(QListViewItem*, const QPoint&, int)),
155 this, SLOT(slotLocalsPopup(QListViewItem*, const QPoint&)));
157 restoreSettings(kapp->config());
159 updateUI();
160 m_bpTable->updateUI();
161 slotFileChanged();
164 DebuggerMainWnd::~DebuggerMainWnd()
166 saveSettings(kapp->config());
167 // must delete m_debugger early since it references our windows
168 delete m_debugger;
169 m_debugger = 0;
171 delete m_memoryWindow;
172 delete m_threads;
173 delete m_ttyWindow;
174 delete m_bpTable;
175 delete m_registers;
176 delete m_watches;
177 delete m_localVariables;
178 delete m_btWindow;
179 delete m_filesWindow;
182 void DebuggerMainWnd::initKAction()
184 // file menu
185 KAction* open = KStdAction::open(this, SLOT(slotFileOpen()),
186 actionCollection());
187 open->setText(i18n("&Open Source..."));
188 (void)new KAction(i18n("&Reload Source"), "reload", 0, m_filesWindow,
189 SLOT(slotFileReload()), actionCollection(),
190 "file_reload");
191 (void)new KAction(i18n("&Executable..."), "execopen", 0, this,
192 SLOT(slotFileExe()), actionCollection(),
193 "file_executable");
194 m_recentExecAction = new KRecentFilesAction(i18n("Recent E&xecutables"), 0,
195 this, SLOT(slotRecentExec(const KURL&)),
196 actionCollection(), "file_executable_recent");
197 (void)new KAction(i18n("&Core dump..."), 0, this, SLOT(slotFileCore()),
198 actionCollection(), "file_core_dump");
199 KStdAction::quit(this, SLOT(slotFileQuit()), actionCollection());
201 // settings menu
202 (void)new KAction(i18n("This &Program..."), 0, this,
203 SLOT(slotFileProgSettings()), actionCollection(),
204 "settings_program");
205 (void)new KAction(i18n("&Global Options..."), 0, this,
206 SLOT(slotFileGlobalSettings()), actionCollection(),
207 "settings_global");
208 KStdAction::keyBindings(this, SLOT(slotConfigureKeys()), actionCollection());
209 KStdAction::showStatusbar(this, SLOT(slotViewStatusbar()), actionCollection());
211 // view menu
212 (void)new KToggleAction(i18n("&Find"), "find", CTRL+Key_F, m_filesWindow,
213 SLOT(slotViewFind()), actionCollection(),
214 "view_find");
215 (void)KStdAction::findNext(m_filesWindow, SLOT(slotFindForward()), actionCollection(), "view_findnext");
216 (void)KStdAction::findPrev(m_filesWindow, SLOT(slotFindBackward()), actionCollection(), "view_findprev");
218 i18n("Source &code");
219 struct { QString text; QWidget* w; QString id; } dw[] = {
220 { i18n("Stac&k"), m_btWindow, "view_stack"},
221 { i18n("&Locals"), m_localVariables, "view_locals"},
222 { i18n("&Watched expressions"), m_watches, "view_watched_expressions"},
223 { i18n("&Registers"), m_registers, "view_registers"},
224 { i18n("&Breakpoints"), m_bpTable, "view_breakpoints"},
225 { i18n("T&hreads"), m_threads, "view_threads"},
226 { i18n("&Output"), m_ttyWindow, "view_output"},
227 { i18n("&Memory"), m_memoryWindow, "view_memory"}
229 for (unsigned i = 0; i < sizeof(dw)/sizeof(dw[0]); i++) {
230 KDockWidget* d = dockParent(dw[i].w);
231 (void)new KToggleAction(dw[i].text, 0, d, SLOT(changeHideShowState()),
232 actionCollection(), dw[i].id);
236 // execution menu
237 KAction* a = new KAction(i18n("&Run"), "pgmrun", Key_F5, m_debugger,
238 SLOT(programRun()), actionCollection(), "exec_run");
239 connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
240 a = new KAction(i18n("Step &into"), "pgmstep", Key_F8, m_debugger,
241 SLOT(programStep()), actionCollection(),
242 "exec_step_into");
243 connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
244 a = new KAction(i18n("Step &over"), "pgmnext", Key_F10, m_debugger,
245 SLOT(programNext()), actionCollection(),
246 "exec_step_over");
247 connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
248 a = new KAction(i18n("Step o&ut"), "pgmfinish", Key_F6, m_debugger,
249 SLOT(programFinish()), actionCollection(),
250 "exec_step_out");
251 connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
252 a = new KAction(i18n("Run to &cursor"), Key_F7, this,
253 SLOT(slotExecUntil()), actionCollection(),
254 "exec_run_to_cursor");
255 connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
256 a = new KAction(i18n("Step i&nto by instruction"), "pgmstepi",
257 SHIFT+Key_F8, m_debugger, SLOT(programStepi()),
258 actionCollection(), "exec_step_into_by_insn");
259 connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
260 a = new KAction(i18n("Step o&ver by instruction"), "pgmnexti",
261 SHIFT+Key_F10, m_debugger, SLOT(programNexti()),
262 actionCollection(), "exec_step_over_by_insn");
263 connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
264 (void)new KAction(i18n("&Program counter to current line"), 0,
265 m_filesWindow, SLOT(slotMoveProgramCounter()),
266 actionCollection(), "exec_movepc");
267 (void)new KAction(i18n("&Break"), 0, m_debugger,
268 SLOT(programBreak()), actionCollection(),
269 "exec_break");
270 (void)new KAction(i18n("&Kill"), 0, m_debugger,
271 SLOT(programKill()), actionCollection(),
272 "exec_kill");
273 (void)new KAction(i18n("Re&start"), 0, m_debugger,
274 SLOT(programRunAgain()), actionCollection(),
275 "exec_restart");
276 (void)new KAction(i18n("A&ttach..."), 0, this,
277 SLOT(slotExecAttach()), actionCollection(),
278 "exec_attach");
279 (void)new KAction(i18n("&Arguments..."), 0, this,
280 SLOT(slotExecArgs()), actionCollection(),
281 "exec_arguments");
283 // breakpoint menu
284 (void)new KAction(i18n("Set/Clear &breakpoint"), "brkpt", Key_F9,
285 m_filesWindow, SLOT(slotBrkptSet()), actionCollection(),
286 "breakpoint_set");
287 (void)new KAction(i18n("Set &temporary breakpoint"), SHIFT+Key_F9,
288 m_filesWindow, SLOT(slotBrkptSetTemp()), actionCollection(),
289 "breakpoint_set_temporary");
290 (void)new KAction(i18n("&Enable/Disable breakpoint"), CTRL+Key_F9,
291 m_filesWindow, SLOT(slotBrkptEnable()), actionCollection(),
292 "breakpoint_enable");
294 // only in popup menus
295 (void)new KAction(i18n("Watch Expression"), 0, this,
296 SLOT(slotLocalsToWatch()), actionCollection(),
297 "watch_expression");
298 (void)new KAction(i18n("Edit Value"), Key_F2, this,
299 SLOT(slotEditValue()), actionCollection(),
300 "edit_value");
302 (void)new KActionMenu(i18n("&Window"), actionCollection(), "window");
304 // all actions force an UI update
305 QValueList<KAction*> actions = actionCollection()->actions();
306 QValueList<KAction*>::Iterator it = actions.begin();
307 for (; it != actions.end(); ++it) {
308 connect(*it, SIGNAL(activated()), this, SLOT(updateUI()));
311 createGUI("kdbgui.rc");
314 void DebuggerMainWnd::initToolbar()
316 KToolBar* toolbar = toolBar("mainToolBar");
317 toolbar->insertAnimatedWidget(ID_STATUS_BUSY,
318 actionCollection()->action("exec_break"), SLOT(activate()),
319 "pulse", -1);
320 toolbar->alignItemRight(ID_STATUS_BUSY, true);
321 m_animRunning = false;
323 KStatusBar* statusbar = statusBar();
324 statusbar->insertItem(m_statusActive, ID_STATUS_ACTIVE);
325 m_lastActiveStatusText = m_statusActive;
326 statusbar->insertItem("", ID_STATUS_MSG); /* message pane */
328 // reserve some translations
329 i18n("Restart");
330 i18n("Core dump");
334 * We must override KTMainWindow's handling of close events since we have
335 * only one toplevel window, which lives on the stack (which KTMainWindow
336 * can't live with :-( )
338 void DebuggerMainWnd::closeEvent(QCloseEvent* e)
340 clearWFlags(WDestructiveClose);
342 if (m_debugger != 0) {
343 m_debugger->shutdown();
346 e->accept();
347 kapp->quit();
351 // instance properties
352 void DebuggerMainWnd::saveProperties(KConfig* config)
354 // session management
355 QString executable = "";
356 if (m_debugger != 0) {
357 executable = m_debugger->executable();
359 config->writeEntry("executable", executable);
362 void DebuggerMainWnd::readProperties(KConfig* config)
364 // session management
365 QString execName = config->readEntry("executable");
367 TRACE("readProperties: executable=" + execName);
368 if (!execName.isEmpty()) {
369 debugProgram(execName, "");
373 const char WindowGroup[] = "Windows";
374 const char RecentExecutables[] = "RecentExecutables";
375 const char LastSession[] = "LastSession";
377 void DebuggerMainWnd::saveSettings(KConfig* config)
379 KConfigGroupSaver g(config, WindowGroup);
381 writeDockConfig(config);
382 fixDockConfig(config, false); // downgrade
384 m_recentExecAction->saveEntries(config, RecentExecutables);
386 KConfigGroupSaver g2(config, LastSession);
387 config->writeEntry("Width0Locals", m_localVariables->columnWidth(0));
388 config->writeEntry("Width0Watches", m_watches->columnWidth(0));
390 DebuggerMainWndBase::saveSettings(config);
393 void DebuggerMainWnd::restoreSettings(KConfig* config)
395 KConfigGroupSaver g(config, WindowGroup);
397 fixDockConfig(config, true); // upgrade
398 readDockConfig(config);
400 // Workaround bug #87787: KDockManager stores the titles of the KDockWidgets
401 // in the config files, although they are localized:
402 // If the user changes the language, the titles remain in the previous language.
403 struct { QString text; QWidget* w; } dw[] = {
404 { i18n("Stack"), m_btWindow },
405 { i18n("Locals"), m_localVariables },
406 { i18n("Watches"), m_watches },
407 { i18n("Registers"), m_registers },
408 { i18n("Breakpoints"), m_bpTable },
409 { i18n("Threads"), m_threads },
410 { i18n("Output"), m_ttyWindow },
411 { i18n("Memory"), m_memoryWindow }
413 for (int i = 0; i < int(sizeof(dw)/sizeof(dw[0])); i++)
415 KDockWidget* w = dockParent(dw[i].w);
416 w->setTabPageLabel(dw[i].text);
417 // this actually changes the captions in the tabs:
418 QEvent ev(QEvent::CaptionChange);
419 w->event(&ev);
422 m_recentExecAction->loadEntries(config, RecentExecutables);
424 KConfigGroupSaver g2(config, LastSession);
425 int w;
426 w = config->readNumEntry("Width0Locals", -1);
427 if (w >= 0 && w < 30000)
428 m_localVariables->setColumnWidth(0, w);
429 w = config->readNumEntry("Width0Watches", -1);
430 if (w >= 0 && w < 30000)
431 m_watches->setColumnWidth(0, w);
433 DebuggerMainWndBase::restoreSettings(config);
435 emit setTabWidth(m_tabWidth);
438 void DebuggerMainWnd::updateUI()
440 KToggleAction* viewFind =
441 static_cast<KToggleAction*>(actionCollection()->action("view_find"));
442 viewFind->setChecked(m_filesWindow->m_findDlg.isVisible());
443 viewFind->setEnabled(m_filesWindow->hasWindows());
444 actionCollection()->action("breakpoint_set")->setEnabled(m_debugger->canChangeBreakpoints());
445 actionCollection()->action("breakpoint_set_temporary")->setEnabled(m_debugger->canChangeBreakpoints());
446 actionCollection()->action("breakpoint_enable")->setEnabled(m_debugger->canChangeBreakpoints());
447 dockUpdateHelper("view_breakpoints", m_bpTable);
448 dockUpdateHelper("view_stack", m_btWindow);
449 dockUpdateHelper("view_locals", m_localVariables);
450 dockUpdateHelper("view_watched_expressions", m_watches);
451 dockUpdateHelper("view_registers", m_registers);
452 dockUpdateHelper("view_threads", m_threads);
453 dockUpdateHelper("view_memory", m_memoryWindow);
454 dockUpdateHelper("view_output", m_ttyWindow);
456 // AB: maybe in mainwndbase.cpp?
457 actionCollection()->action("file_executable")->setEnabled(m_debugger->isIdle());
458 actionCollection()->action("settings_program")->setEnabled(m_debugger->haveExecutable());
459 actionCollection()->action("file_core_dump")->setEnabled(m_debugger->canStart());
460 actionCollection()->action("exec_step_into")->setEnabled(m_debugger->canSingleStep());
461 actionCollection()->action("exec_step_into_by_insn")->setEnabled(m_debugger->canSingleStep());
462 actionCollection()->action("exec_step_over")->setEnabled(m_debugger->canSingleStep());
463 actionCollection()->action("exec_step_over_by_insn")->setEnabled(m_debugger->canSingleStep());
464 actionCollection()->action("exec_step_out")->setEnabled(m_debugger->canSingleStep());
465 actionCollection()->action("exec_run_to_cursor")->setEnabled(m_debugger->canSingleStep());
466 actionCollection()->action("exec_movepc")->setEnabled(m_debugger->canSingleStep());
467 actionCollection()->action("exec_restart")->setEnabled(m_debugger->canSingleStep());
468 actionCollection()->action("exec_attach")->setEnabled(m_debugger->isReady());
469 actionCollection()->action("exec_run")->setEnabled(m_debugger->canStart() || m_debugger->canSingleStep());
470 actionCollection()->action("exec_kill")->setEnabled(m_debugger->haveExecutable() && m_debugger->isProgramActive());
471 actionCollection()->action("exec_break")->setEnabled(m_debugger->isProgramRunning());
472 actionCollection()->action("exec_arguments")->setEnabled(m_debugger->haveExecutable());
473 actionCollection()->action("edit_value")->setEnabled(m_debugger->canSingleStep());
475 // animation
476 KAnimWidget* w = toolBar("mainToolBar")->animatedWidget(ID_STATUS_BUSY);
477 if (m_debugger->isIdle()) {
478 if (m_animRunning) {
479 w->stop();
480 m_animRunning = false;
482 } else {
483 if (!m_animRunning) {
484 w->start();
485 m_animRunning = true;
489 // update statusbar
490 QString newStatus;
491 if (m_debugger->isProgramActive())
492 newStatus = m_statusActive;
493 if (newStatus != m_lastActiveStatusText) {
494 statusBar()->changeItem(newStatus, ID_STATUS_ACTIVE);
495 m_lastActiveStatusText = newStatus;
499 void DebuggerMainWnd::dockUpdateHelper(QString action, QWidget* w)
501 KToggleAction* item =
502 static_cast<KToggleAction*>(actionCollection()->action(action));
503 bool canChange = canChangeDockVisibility(w);
504 item->setEnabled(canChange);
505 item->setChecked(canChange && isDockVisible(w));
508 void DebuggerMainWnd::updateLineItems()
510 m_filesWindow->updateLineItems(m_debugger);
513 void DebuggerMainWnd::slotAddWatch()
515 if (m_debugger != 0) {
516 QString t = m_watches->watchText();
517 m_debugger->addWatch(t);
521 void DebuggerMainWnd::slotAddWatch(const QString& text)
523 if (m_debugger != 0) {
524 m_debugger->addWatch(text);
528 void DebuggerMainWnd::slotFileChanged()
530 // set caption
531 QString caption;
533 if (m_debugger->haveExecutable()) {
534 // basename part of executable
535 QString executable = m_debugger->executable();
536 const char* execBase = executable.data();
537 int lastSlash = executable.findRev('/');
538 if (lastSlash >= 0)
539 execBase += lastSlash + 1;
540 caption += execBase;
542 QString file;
543 int line;
544 bool anyWindows = m_filesWindow->activeLine(file, line);
545 if (anyWindows) {
546 caption += " (";
547 caption += file;
548 caption += ")";
550 setCaption(caption);
553 void DebuggerMainWnd::slotNewFileLoaded()
555 // updates program counter in the new file
556 if (m_debugger != 0)
557 m_filesWindow->updateLineItems(m_debugger);
560 KDockWidget* DebuggerMainWnd::dockParent(QWidget* w)
562 while ((w = w->parentWidget()) != 0) {
563 if (w->isA("KDockWidget"))
564 return static_cast<KDockWidget*>(w);
566 return 0;
569 bool DebuggerMainWnd::isDockVisible(QWidget* w)
571 KDockWidget* d = dockParent(w);
572 return d != 0 && d->mayBeHide();
575 bool DebuggerMainWnd::canChangeDockVisibility(QWidget* w)
577 KDockWidget* d = dockParent(w);
578 return d != 0 && (d->mayBeHide() || d->mayBeShow());
581 // upgrades the entries from version 0.0.4 to 0.0.5 and back
582 void DebuggerMainWnd::fixDockConfig(KConfig* c, bool upgrade)
584 static const char dockGroup[] = "dock_setting_default";
585 if (!c->hasGroup(dockGroup))
586 return;
588 static const char oldVersion[] = "0.0.4";
589 static const char newVersion[] = "0.0.5";
590 const char* from = upgrade ? oldVersion : newVersion;
591 const char* to = upgrade ? newVersion : oldVersion;
592 QMap<QString,QString> e = c->entryMap(dockGroup);
593 if (e["Version"] != from)
594 return;
596 KConfigGroupSaver g(c, dockGroup);
597 c->writeEntry("Version", to);
598 TRACE(upgrade ? "upgrading dockconfig" : "downgrading dockconfig");
600 // turn all orientation entries from 0 to 1 and from 1 to 0
601 QMap<QString,QString>::Iterator i;
602 for (i = e.begin(); i != e.end(); ++i)
604 if (i.key().right(12) == ":orientation") {
605 TRACE("upgrading " + i.key() + " old value: " + *i);
606 int orientation = c->readNumEntry(i.key(), -1);
607 if (orientation >= 0) { // paranoia
608 c->writeEntry(i.key(), 1 - orientation);
614 TTYWindow* DebuggerMainWnd::ttyWindow()
616 return m_ttyWindow;
619 bool DebuggerMainWnd::debugProgram(const QString& exe, QCString lang)
621 // check the file name
622 QFileInfo fi(exe);
624 bool success = fi.isFile();
625 if (!success)
627 QString msg = i18n("`%1' is not a file or does not exist");
628 KMessageBox::sorry(this, msg.arg(exe));
630 else
632 success = DebuggerMainWndBase::debugProgram(fi.absFilePath(), lang, this);
635 if (success)
637 m_recentExecAction->addURL(KURL(fi.absFilePath()));
639 // keep the directory
640 m_lastDirectory = fi.dirPath(true);
641 m_filesWindow->setExtraDirectory(m_lastDirectory);
643 else
645 m_recentExecAction->removeURL(KURL(fi.absFilePath()));
648 return true;
651 void DebuggerMainWnd::slotNewStatusMsg()
653 newStatusMsg(statusBar());
656 void DebuggerMainWnd::slotFileGlobalSettings()
658 int oldTabWidth = m_tabWidth;
660 doGlobalOptions(this);
662 if (m_tabWidth != oldTabWidth) {
663 emit setTabWidth(m_tabWidth);
667 void DebuggerMainWnd::slotDebuggerStarting()
669 DebuggerMainWndBase::slotDebuggerStarting();
672 void DebuggerMainWnd::slotToggleBreak(const QString& fileName, int lineNo,
673 const DbgAddr& address, bool temp)
675 // lineNo is zero-based
676 if (m_debugger != 0) {
677 m_debugger->setBreakpoint(fileName, lineNo, address, temp);
681 void DebuggerMainWnd::slotEnaDisBreak(const QString& fileName, int lineNo,
682 const DbgAddr& address)
684 // lineNo is zero-based
685 if (m_debugger != 0) {
686 m_debugger->enableDisableBreakpoint(fileName, lineNo, address);
690 QString DebuggerMainWnd::createOutputWindow()
692 QString tty = DebuggerMainWndBase::createOutputWindow();
693 if (!tty.isEmpty()) {
694 connect(m_outputTermProc, SIGNAL(processExited(KProcess*)),
695 SLOT(slotTermEmuExited()));
697 return tty;
700 void DebuggerMainWnd::slotTermEmuExited()
702 shutdownTermWindow();
705 void DebuggerMainWnd::slotProgramStopped()
707 // when the program stopped, move the window to the foreground
708 if (m_popForeground) {
709 // unfortunately, this requires quite some force to work :-(
710 KWin::raiseWindow(winId());
711 KWin::forceActiveWindow(winId());
713 m_backTimer.stop();
716 void DebuggerMainWnd::intoBackground()
718 if (m_popForeground) {
719 m_backTimer.start(m_backTimeout, true); /* single-shot */
723 void DebuggerMainWnd::slotBackTimer()
725 lower();
728 void DebuggerMainWnd::slotRecentExec(const KURL& url)
730 QString exe = url.path();
731 debugProgram(exe, "");
734 QString DebuggerMainWnd::makeSourceFilter()
736 QString f;
737 f = m_sourceFilter + " " + m_headerFilter + i18n("|All source files\n");
738 f += m_sourceFilter + i18n("|Source files\n");
739 f += m_headerFilter + i18n("|Header files\n");
740 f += i18n("*|All files");
741 return f;
745 * Pop up the context menu in the locals window
747 void DebuggerMainWnd::slotLocalsPopup(QListViewItem*, const QPoint& pt)
749 QPopupMenu* popup =
750 static_cast<QPopupMenu*>(factory()->container("popup_locals", this));
751 if (popup == 0) {
752 return;
754 if (popup->isVisible()) {
755 popup->hide();
756 } else {
757 popup->popup(pt);
762 * Copies the currently selected item to the watch window.
764 void DebuggerMainWnd::slotLocalsToWatch()
766 VarTree* item = m_localVariables->selectedItem();
768 if (item != 0 && m_debugger != 0) {
769 QString text = item->computeExpr();
770 m_debugger->addWatch(text);
775 * Starts editing a value in a value display
777 void DebuggerMainWnd::slotEditValue()
779 // does one of the value trees have the focus
780 QWidget* f = kapp->focusWidget();
781 ExprWnd* wnd;
782 if (f == m_localVariables) {
783 wnd = m_localVariables;
784 } else if (f == m_watches->watchVariables()) {
785 wnd = m_watches->watchVariables();
786 } else {
787 return;
790 if (m_localVariables->isEditing() ||
791 m_watches->watchVariables()->isEditing())
793 return; /* don't edit twice */
796 VarTree* expr = wnd->currentItem();
797 if (expr != 0 && m_debugger != 0 && m_debugger->canSingleStep())
799 TRACE("edit value");
800 // determine the text to edit
801 QString text = m_debugger->driver()->editableValue(expr);
802 wnd->editValue(expr, text);
806 void DebuggerMainWnd::slotFileOpen()
808 // start browsing in the active file's directory
809 // fall back to last used directory (executable)
810 QString dir = m_lastDirectory;
811 QString fileName = m_filesWindow->activeFileName();
812 if (!fileName.isEmpty()) {
813 QFileInfo fi(fileName);
814 dir = fi.dirPath();
817 fileName = myGetFileName(i18n("Open"),
818 dir,
819 makeSourceFilter(), this);
821 if (!fileName.isEmpty())
823 QFileInfo fi(fileName);
824 m_lastDirectory = fi.dirPath();
825 m_filesWindow->setExtraDirectory(m_lastDirectory);
826 m_filesWindow->activateFile(fileName);
830 void DebuggerMainWnd::slotFileQuit()
832 if (m_debugger != 0) {
833 m_debugger->shutdown();
835 kapp->quit();
838 void DebuggerMainWnd::slotFileExe()
840 if (m_debugger->isIdle())
842 // open a new executable
843 QString executable = myGetFileName(i18n("Select the executable to debug"),
844 m_lastDirectory, 0, this);
845 if (executable.isEmpty())
846 return;
848 debugProgram(executable, "");
852 void DebuggerMainWnd::slotFileCore()
854 if (m_debugger->canStart())
856 QString corefile = myGetFileName(i18n("Select core dump"),
857 m_lastDirectory, 0, this);
858 if (!corefile.isEmpty()) {
859 m_debugger->useCoreFile(corefile, false);
864 void DebuggerMainWnd::slotFileProgSettings()
866 if (m_debugger != 0) {
867 m_debugger->programSettings(this);
871 void DebuggerMainWnd::slotViewStatusbar()
873 if (statusBar()->isVisible())
874 statusBar()->hide();
875 else
876 statusBar()->show();
877 setSettingsDirty();
880 void DebuggerMainWnd::slotExecUntil()
882 if (m_debugger != 0)
884 QString file;
885 int lineNo;
886 if (m_filesWindow->activeLine(file, lineNo))
887 m_debugger->runUntil(file, lineNo);
891 void DebuggerMainWnd::slotExecAttach()
893 #ifdef PS_COMMAND
894 ProcAttachPS dlg(this);
895 // seed filter with executable name
896 QFileInfo fi = m_debugger->executable();
897 dlg.filterEdit->setText(fi.fileName());
898 #else
899 ProcAttach dlg(this);
900 dlg.setText(m_debugger->attachedPid());
901 #endif
902 if (dlg.exec()) {
903 m_debugger->attachProgram(dlg.text());
907 void DebuggerMainWnd::slotExecArgs()
909 if (m_debugger != 0) {
910 m_debugger->programArgs(this);
914 void DebuggerMainWnd::slotConfigureKeys()
916 KKeyDialog::configure(actionCollection(), this);
919 #include "dbgmainwnd.moc"