When an executable is loaded be prepared for some messages from gdb,
[kdbg.git] / kdbg / dbgmainwnd.cpp
blob7a823529b1e8b5470852343080f358d76e293d3d
1 // $Id$
3 // Copyright by Johannes Sixt
4 // This file is under GPL, the GNU General Public Licence
6 #include <kapp.h>
7 #include <klocale.h> /* i18n */
8 #include <kmessagebox.h>
9 #include <kconfig.h>
10 #include <kstatusbar.h>
11 #include <kiconloader.h>
12 #include <kstdaccel.h>
13 #include <kstdaction.h>
14 #include <kaction.h>
15 #include <kpopupmenu.h>
16 #include <kfiledialog.h>
17 #include <kprocess.h>
18 #include <kkeydialog.h>
19 #include <qlistbox.h>
20 #include <qfileinfo.h>
21 #include "dbgmainwnd.h"
22 #include "debugger.h"
23 #include "commandids.h"
24 #include "winstack.h"
25 #include "brkpt.h"
26 #include "threadlist.h"
27 #include "memwindow.h"
28 #include "ttywnd.h"
29 #include "procattach.h"
30 #include "dbgdriver.h"
31 #include "mydebug.h"
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
37 DebuggerMainWnd::DebuggerMainWnd(const char* name) :
38 KDockMainWindow(0, name),
39 DebuggerMainWndBase()
41 QPixmap p;
43 KDockWidget* dw0 = createDockWidget("Source", p, 0, i18n("Source"));
44 m_filesWindow = new WinStack(dw0, "files");
45 dw0->setWidget(m_filesWindow);
46 dw0->setDockSite(KDockWidget::DockCorner);
47 dw0->setEnableDocking(KDockWidget::DockNone);
48 setView(dw0);
49 setMainDockWidget(dw0);
51 KDockWidget* dw1 = createDockWidget("Stack", p, 0, i18n("Stack"));
52 m_btWindow = new QListBox(dw1, "backtrace");
53 dw1->setWidget(m_btWindow);
54 KDockWidget* dw2 = createDockWidget("Locals", p, 0, i18n("Locals"));
55 m_localVariables = new ExprWnd(dw2, "locals");
56 dw2->setWidget(m_localVariables);
57 KDockWidget* dw3 = createDockWidget("Watches", p, 0, i18n("Watches"));
58 m_watches = new WatchWindow(dw3, "watches");
59 dw3->setWidget(m_watches);
60 KDockWidget* dw4 = createDockWidget("Registers", p, 0, i18n("Registers"));
61 m_registers = new RegisterView(dw4, "registers");
62 dw4->setWidget(m_registers);
63 KDockWidget* dw5 = createDockWidget("Breakpoints", p, 0, i18n("Breakpoints"));
64 m_bpTable = new BreakpointTable(dw5, "breakpoints");
65 dw5->setWidget(m_bpTable);
66 KDockWidget* dw6 = createDockWidget("Output", p, 0, i18n("Output"));
67 m_ttyWindow = new TTYWindow(dw6, "output");
68 dw6->setWidget(m_ttyWindow);
69 KDockWidget* dw7 = createDockWidget("Threads", p, 0, i18n("Threads"));
70 m_threads = new ThreadList(dw7, "threads");
71 dw7->setWidget(m_threads);
72 KDockWidget* dw8 = createDockWidget("Memory", p, 0, i18n("Memory"));
73 m_memoryWindow = new MemoryWindow(dw8, "memory");
74 dw8->setWidget(m_memoryWindow);
76 setupDebugger(this, m_localVariables, m_watches->watchVariables(), m_btWindow);
77 m_bpTable->setDebugger(m_debugger);
78 m_memoryWindow->setDebugger(m_debugger);
80 initKAction();
81 initToolbar(); // kind of obsolete?
83 connect(m_watches, SIGNAL(addWatch()), SLOT(slotAddWatch()));
84 connect(m_watches, SIGNAL(deleteWatch()), m_debugger, SLOT(slotDeleteWatch()));
86 KAction* windowMenu = actionCollection()->action("window");
87 m_filesWindow->setWindowMenu(static_cast<KActionMenu*>(windowMenu)->popupMenu());
88 connect(&m_filesWindow->m_findDlg, SIGNAL(closed()), SLOT(updateUI()));
89 connect(m_filesWindow, SIGNAL(newFileLoaded()),
90 SLOT(slotNewFileLoaded()));
91 connect(m_filesWindow, SIGNAL(toggleBreak(const QString&,int,const DbgAddr&,bool)),
92 this, SLOT(slotToggleBreak(const QString&,int,const DbgAddr&,bool)));
93 connect(m_filesWindow, SIGNAL(enadisBreak(const QString&,int,const DbgAddr&)),
94 this, SLOT(slotEnaDisBreak(const QString&,int,const DbgAddr&)));
95 connect(m_debugger, SIGNAL(activateFileLine(const QString&,int,const DbgAddr&)),
96 m_filesWindow, SLOT(activate(const QString&,int,const DbgAddr&)));
97 connect(m_debugger, SIGNAL(executableUpdated()),
98 m_filesWindow, SLOT(reloadAllFiles()));
99 connect(m_debugger, SIGNAL(updatePC(const QString&,int,const DbgAddr&,int)),
100 m_filesWindow, SLOT(updatePC(const QString&,int,const DbgAddr&,int)));
101 // value popup communication
102 connect(m_filesWindow, SIGNAL(initiateValuePopup(const QString&)),
103 m_debugger, SLOT(slotValuePopup(const QString&)));
104 connect(m_debugger, SIGNAL(valuePopup(const QString&)),
105 m_filesWindow, SLOT(slotShowValueTip(const QString&)));
106 // disassembling
107 connect(m_filesWindow, SIGNAL(disassemble(const QString&, int)),
108 m_debugger, SLOT(slotDisassemble(const QString&, int)));
109 connect(m_debugger, SIGNAL(disassembled(const QString&,int,const QList<DisassembledCode>&)),
110 m_filesWindow, SLOT(slotDisassembled(const QString&,int,const QList<DisassembledCode>&)));
111 connect(m_filesWindow, SIGNAL(moveProgramCounter(const QString&,int,const DbgAddr&)),
112 m_debugger, SLOT(setProgramCounter(const QString&,int,const DbgAddr&)));
113 // program stopped
114 connect(m_debugger, SIGNAL(programStopped()), SLOT(slotProgramStopped()));
115 connect(&m_backTimer, SIGNAL(timeout()), SLOT(slotBackTimer()));
116 // tab width
117 connect(this, SIGNAL(setTabWidth(int)), m_filesWindow, SIGNAL(setTabWidth(int)));
119 // Establish communication when right clicked on file window.
120 connect(m_filesWindow, SIGNAL(filesRightClick(const QPoint &)),
121 SLOT(slotFileWndMenu(const QPoint &)));
123 // Connection when right clicked on file window before any file is
124 // loaded.
125 connect(m_filesWindow, SIGNAL(clickedRight(const QPoint &)),
126 SLOT(slotFileWndEmptyMenu(const QPoint &)));
128 // file/line updates
129 connect(m_filesWindow, SIGNAL(fileChanged()), SLOT(slotFileChanged()));
130 connect(m_filesWindow, SIGNAL(lineChanged()), SLOT(slotLineChanged()));
132 // connect breakpoint table
133 connect(m_bpTable, SIGNAL(activateFileLine(const QString&,int,const DbgAddr&)),
134 m_filesWindow, SLOT(activate(const QString&,int,const DbgAddr&)));
135 connect(m_debugger, SIGNAL(updateUI()), m_bpTable, SLOT(updateUI()));
136 connect(m_debugger, SIGNAL(breakpointsChanged()), m_bpTable, SLOT(updateBreakList()));
137 connect(m_debugger, SIGNAL(breakpointsChanged()), m_bpTable, SLOT(updateUI()));
139 connect(m_debugger, SIGNAL(registersChanged(QList<RegisterInfo>&)),
140 m_registers, SLOT(updateRegisters(QList<RegisterInfo>&)));
142 connect(m_debugger, SIGNAL(memoryDumpChanged(const QString&, QList<MemoryDump>&)),
143 m_memoryWindow, SLOT(slotNewMemoryDump(const QString&, QList<MemoryDump>&)));
144 connect(m_debugger, SIGNAL(saveProgramSpecific(KConfigBase*)),
145 m_memoryWindow, SLOT(saveProgramSpecific(KConfigBase*)));
146 connect(m_debugger, SIGNAL(restoreProgramSpecific(KConfigBase*)),
147 m_memoryWindow, SLOT(restoreProgramSpecific(KConfigBase*)));
149 // thread window
150 connect(m_debugger, SIGNAL(threadsChanged(QList<ThreadInfo>&)),
151 m_threads, SLOT(updateThreads(QList<ThreadInfo>&)));
152 connect(m_threads, SIGNAL(setThread(int)),
153 m_debugger, SLOT(setThread(int)));
155 // view menu changes when docking state changes
156 connect(dockManager, SIGNAL(change()), SLOT(updateUI()));
158 // popup menu of the local variables window
159 connect(m_localVariables, SIGNAL(rightPressed(int, const QPoint&)),
160 this, SLOT(slotLocalsPopup(int, const QPoint&)));
162 restoreSettings(kapp->config());
164 updateUI();
165 m_bpTable->updateUI();
166 slotFileChanged();
169 DebuggerMainWnd::~DebuggerMainWnd()
171 saveSettings(kapp->config());
172 // must delete m_debugger early since it references our windows
173 delete m_debugger;
174 m_debugger = 0;
176 delete m_memoryWindow;
177 delete m_threads;
178 delete m_ttyWindow;
179 delete m_bpTable;
180 delete m_registers;
181 delete m_watches;
182 delete m_localVariables;
183 delete m_btWindow;
184 delete m_filesWindow;
187 void DebuggerMainWnd::initKAction()
189 // file menu
190 KAction* open = KStdAction::open(this, SLOT(slotFileOpen()),
191 actionCollection());
192 open->setText(i18n("&Open Source..."));
193 (void)new KAction(i18n("&Reload Source"), "reload", 0, m_filesWindow,
194 SLOT(slotFileReload()), actionCollection(),
195 "file_reload");
196 (void)new KAction(i18n("&Executable..."), "execopen", 0, this,
197 SLOT(slotFileExe()), actionCollection(),
198 "file_executable");
199 m_recentExecAction = new KRecentFilesAction(i18n("Recent E&xecutables"), 0,
200 this, SLOT(slotRecentExec(const KURL&)),
201 actionCollection(), "file_executable_recent");
202 (void)new KAction(i18n("&Core dump..."), 0, this, SLOT(slotFileCore()),
203 actionCollection(), "file_core_dump");
204 KStdAction::quit(this, SLOT(slotFileQuit()), actionCollection());
206 // settings menu
207 (void)new KAction(i18n("This &Program..."), 0, this,
208 SLOT(slotFileProgSettings()), actionCollection(),
209 "settings_program");
210 (void)new KAction(i18n("&Global Options..."), 0, this,
211 SLOT(slotFileGlobalSettings()), actionCollection(),
212 "settings_global");
213 KStdAction::keyBindings(this, SLOT(slotConfigureKeys()), actionCollection());
214 KStdAction::showToolbar(this, SLOT(slotViewToolbar()), actionCollection());
215 KStdAction::showStatusbar(this, SLOT(slotViewStatusbar()), actionCollection());
217 // view menu
218 (void)new KToggleAction(i18n("&Find"), "find", 0, m_filesWindow,
219 SLOT(slotViewFind()), actionCollection(),
220 "view_find");
221 i18n("Source &code");
222 struct { QString text; QWidget* w; QString id; } dw[] = {
223 { i18n("Stac&k"), m_btWindow, "view_stack"},
224 { i18n("&Locals"), m_localVariables, "view_locals"},
225 { i18n("&Watched expressions"), m_watches, "view_watched_expressions"},
226 { i18n("&Registers"), m_registers, "view_registers"},
227 { i18n("&Breakpoints"), m_bpTable, "view_breakpoints"},
228 { i18n("T&hreads"), m_threads, "view_threads"},
229 { i18n("&Output"), m_ttyWindow, "view_output"},
230 { i18n("&Memory"), m_memoryWindow, "view_memory"}
232 for (unsigned i = 0; i < sizeof(dw)/sizeof(dw[0]); i++) {
233 KDockWidget* d = dockParent(dw[i].w);
234 (void)new KToggleAction(dw[i].text, 0, d, SLOT(changeHideShowState()),
235 actionCollection(), dw[i].id);
239 // execution menu
240 KAction* a = new KAction(i18n("&Run"), "pgmrun", Key_F5, m_debugger,
241 SLOT(programRun()), actionCollection(), "exec_run");
242 connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
243 a = new KAction(i18n("Step &into"), "pgmstep", Key_F8, m_debugger,
244 SLOT(programStep()), actionCollection(),
245 "exec_step_into");
246 connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
247 a = new KAction(i18n("Step &over"), "pgmnext", Key_F10, m_debugger,
248 SLOT(programNext()), actionCollection(),
249 "exec_step_over");
250 connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
251 a = new KAction(i18n("Step o&ut"), "pgmfinish", Key_F6, m_debugger,
252 SLOT(programFinish()), actionCollection(),
253 "exec_step_out");
254 connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
255 a = new KAction(i18n("Run to &cursor"), Key_F7, this,
256 SLOT(slotExecUntil()), actionCollection(),
257 "exec_run_to_cursor");
258 connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
259 a = new KAction(i18n("Step i&nto by instruction"), "pgmstepi",
260 SHIFT+Key_F8, m_debugger, SLOT(programStepi()),
261 actionCollection(), "exec_step_into_by_insn");
262 connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
263 a = new KAction(i18n("Step o&ver by instruction"), "pgmnexti",
264 SHIFT+Key_F10, m_debugger, SLOT(programNexti()),
265 actionCollection(), "exec_step_over_by_insn");
266 connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
267 (void)new KAction(i18n("&Program counter to current line"), 0,
268 m_filesWindow, SLOT(slotMoveProgramCounter()),
269 actionCollection(), "exec_movepc");
270 (void)new KAction(i18n("&Break"), 0, m_debugger,
271 SLOT(programBreak()), actionCollection(),
272 "exec_break");
273 (void)new KAction(i18n("&Kill"), 0, m_debugger,
274 SLOT(programKill()), actionCollection(),
275 "exec_kill");
276 (void)new KAction(i18n("Re&start"), 0, m_debugger,
277 SLOT(programRunAgain()), actionCollection(),
278 "exec_restart");
279 (void)new KAction(i18n("A&ttach..."), 0, this,
280 SLOT(slotExecAttach()), actionCollection(),
281 "exec_attach");
282 (void)new KAction(i18n("&Arguments..."), 0, this,
283 SLOT(slotExecArgs()), actionCollection(),
284 "exec_arguments");
286 // breakpoint menu
287 (void)new KAction(i18n("Set/Clear &breakpoint"), "brkpt", Key_F9,
288 m_filesWindow, SLOT(slotBrkptSet()), actionCollection(),
289 "breakpoint_set");
290 (void)new KAction(i18n("Set &temporary breakpoint"), SHIFT+Key_F9,
291 m_filesWindow, SLOT(slotBrkptSetTemp()), actionCollection(),
292 "breakpoint_set_temporary");
293 (void)new KAction(i18n("&Enable/Disable breakpoint"), CTRL+Key_F9,
294 m_filesWindow, SLOT(slotBrkptEnable()), actionCollection(),
295 "breakpoint_enable");
297 // only in popup menus
298 (void)new KAction(i18n("Watch Expression"), 0, this,
299 SLOT(slotLocalsToWatch()), actionCollection(),
300 "watch_expression");
301 (void)new KAction(i18n("Edit Value"), Key_F2, this,
302 SLOT(slotEditValue()), actionCollection(),
303 "edit_value");
305 (void)new KActionMenu(i18n("&Window"), actionCollection(), "window");
307 // all actions force an UI update
308 QValueList<KAction*> actions = actionCollection()->actions();
309 QValueList<KAction*>::Iterator it = actions.begin();
310 for (; it != actions.end(); ++it) {
311 connect(*it, SIGNAL(activated()), this, SLOT(updateUI()));
314 createGUI("kdbgui.rc");
317 void DebuggerMainWnd::initToolbar()
319 KToolBar* toolbar = toolBar("mainToolBar");
320 toolbar->setBarPos(KToolBar::Top);
321 //moveToolBar(toolbar);
323 initAnimation(toolbar);
325 KStatusBar* statusbar = statusBar();
326 statusbar->insertItem(m_statusActive, ID_STATUS_ACTIVE);
327 m_lastActiveStatusText = m_statusActive;
328 statusbar->insertItem(i18n("Line 00000"), ID_STATUS_LINENO);
329 statusbar->insertItem("", ID_STATUS_MSG); /* message pane */
331 // reserve some translations
332 i18n("Restart");
333 i18n("Core dump");
337 * We must override KTMainWindow's handling of close events since we have
338 * only one toplevel window, which lives on the stack (which KTMainWindow
339 * can't live with :-( )
341 void DebuggerMainWnd::closeEvent(QCloseEvent* e)
343 clearWFlags(WDestructiveClose);
345 if (m_debugger != 0) {
346 m_debugger->shutdown();
349 e->accept();
350 kapp->quit();
354 // instance properties
355 void DebuggerMainWnd::saveProperties(KConfig* config)
357 // session management
358 QString executable = "";
359 if (m_debugger != 0) {
360 executable = m_debugger->executable();
362 config->writeEntry("executable", executable);
365 void DebuggerMainWnd::readProperties(KConfig* config)
367 // session management
368 QString execName = config->readEntry("executable");
370 TRACE("readProperties: executable=" + execName);
371 if (!execName.isEmpty()) {
372 debugProgram(execName, "");
376 const char WindowGroup[] = "Windows";
377 const char RecentExecutables[] = "RecentExecutables";
379 void DebuggerMainWnd::saveSettings(KConfig* config)
381 KConfigGroupSaver g(config, WindowGroup);
383 writeDockConfig(config);
384 fixDockConfig(config, false); // downgrade
386 m_recentExecAction->saveEntries(config, RecentExecutables);
388 DebuggerMainWndBase::saveSettings(config);
391 void DebuggerMainWnd::restoreSettings(KConfig* config)
393 KConfigGroupSaver g(config, WindowGroup);
395 fixDockConfig(config, true); // upgrade
396 readDockConfig(config);
398 m_recentExecAction->loadEntries(config, RecentExecutables);
400 DebuggerMainWndBase::restoreSettings(config);
402 emit setTabWidth(m_tabWidth);
405 void DebuggerMainWnd::updateUI()
407 KToggleAction* viewFind =
408 static_cast<KToggleAction*>(actionCollection()->action("view_find"));
409 viewFind->setChecked(m_filesWindow->m_findDlg.isVisible());
410 viewFind->setEnabled(m_filesWindow->hasWindows());
411 actionCollection()->action("breakpoint_set")->setEnabled(m_debugger->canChangeBreakpoints());
412 actionCollection()->action("breakpoint_set_temporary")->setEnabled(m_debugger->canChangeBreakpoints());
413 actionCollection()->action("breakpoint_enable")->setEnabled(m_debugger->canChangeBreakpoints());
414 dockUpdateHelper("view_breakpoints", m_bpTable);
415 dockUpdateHelper("view_stack", m_btWindow);
416 dockUpdateHelper("view_locals", m_localVariables);
417 dockUpdateHelper("view_watched_expressions", m_watches);
418 dockUpdateHelper("view_registers", m_registers);
419 dockUpdateHelper("view_threads", m_threads);
420 dockUpdateHelper("view_memory", m_memoryWindow);
421 dockUpdateHelper("view_output", m_ttyWindow);
423 // AB: maybe in mainwndbase.cpp?
424 actionCollection()->action("file_executable")->setEnabled(m_debugger->isIdle());
425 actionCollection()->action("settings_program")->setEnabled(m_debugger->haveExecutable());
426 actionCollection()->action("file_core_dump")->setEnabled(m_debugger->canUseCoreFile());
427 actionCollection()->action("exec_step_into")->setEnabled(m_debugger->canSingleStep());
428 actionCollection()->action("exec_step_into_by_insn")->setEnabled(m_debugger->canSingleStep());
429 actionCollection()->action("exec_step_over")->setEnabled(m_debugger->canSingleStep());
430 actionCollection()->action("exec_step_over_by_insn")->setEnabled(m_debugger->canSingleStep());
431 actionCollection()->action("exec_step_out")->setEnabled(m_debugger->canSingleStep());
432 actionCollection()->action("exec_run_to_cursor")->setEnabled(m_debugger->canSingleStep());
433 actionCollection()->action("exec_movepc")->setEnabled(m_debugger->canSingleStep());
434 actionCollection()->action("exec_restart")->setEnabled(m_debugger->canSingleStep());
435 actionCollection()->action("exec_attach")->setEnabled(m_debugger->isReady());
436 actionCollection()->action("exec_run")->setEnabled(m_debugger->isReady());
437 actionCollection()->action("exec_kill")->setEnabled(m_debugger->haveExecutable() && m_debugger->isProgramActive());
438 actionCollection()->action("exec_break")->setEnabled(m_debugger->isProgramRunning());
439 actionCollection()->action("exec_arguments")->setEnabled(m_debugger->haveExecutable());
440 actionCollection()->action("edit_value")->setEnabled(m_debugger->canSingleStep());
442 // update statusbar
443 QString newStatus;
444 if (m_debugger->isProgramActive())
445 newStatus = m_statusActive;
446 if (newStatus != m_lastActiveStatusText) {
447 statusBar()->changeItem(newStatus, ID_STATUS_ACTIVE);
448 m_lastActiveStatusText = newStatus;
450 // line number is updated in slotLineChanged
453 void DebuggerMainWnd::dockUpdateHelper(QString action, QWidget* w)
455 KToggleAction* item =
456 static_cast<KToggleAction*>(actionCollection()->action(action));
457 bool canChange = canChangeDockVisibility(w);
458 item->setEnabled(canChange);
459 item->setChecked(canChange && isDockVisible(w));
462 void DebuggerMainWnd::updateLineItems()
464 m_filesWindow->updateLineItems(m_debugger);
467 void DebuggerMainWnd::slotAddWatch()
469 if (m_debugger != 0) {
470 QString t = m_watches->watchText();
471 m_debugger->addWatch(t);
475 void DebuggerMainWnd::slotFileChanged()
477 // set caption
478 QString caption;
480 if (m_debugger->haveExecutable()) {
481 // basename part of executable
482 QString executable = m_debugger->executable();
483 const char* execBase = executable.data();
484 int lastSlash = executable.findRev('/');
485 if (lastSlash >= 0)
486 execBase += lastSlash + 1;
487 caption += execBase;
489 QString file;
490 int line;
491 bool anyWindows = m_filesWindow->activeLine(file, line);
492 updateLineStatus(anyWindows ? line : -1);
493 if (anyWindows) {
494 caption += " (";
495 caption += file;
496 caption += ")";
498 setCaption(caption);
501 void DebuggerMainWnd::slotLineChanged()
503 QString file;
504 int line;
505 bool anyWindows = m_filesWindow->activeLine(file, line);
506 updateLineStatus(anyWindows ? line : -1);
509 void DebuggerMainWnd::slotNewFileLoaded()
511 // updates program counter in the new file
512 if (m_debugger != 0)
513 m_filesWindow->updateLineItems(m_debugger);
516 void DebuggerMainWnd::updateLineStatus(int lineNo)
518 if (lineNo < 0) {
519 statusBar()->changeItem("", ID_STATUS_LINENO);
520 } else {
521 QString strLine;
522 strLine.sprintf(i18n("Line %d"), lineNo + 1);
523 statusBar()->changeItem(strLine, ID_STATUS_LINENO);
527 KDockWidget* DebuggerMainWnd::dockParent(QWidget* w)
529 while ((w = w->parentWidget()) != 0) {
530 if (w->isA("KDockWidget"))
531 return static_cast<KDockWidget*>(w);
533 return 0;
536 bool DebuggerMainWnd::isDockVisible(QWidget* w)
538 KDockWidget* d = dockParent(w);
539 return d != 0 && d->mayBeHide();
542 bool DebuggerMainWnd::canChangeDockVisibility(QWidget* w)
544 KDockWidget* d = dockParent(w);
545 return d != 0 && (d->mayBeHide() || d->mayBeShow());
548 // upgrades the entries from version 0.0.4 to 0.0.5 and back
549 void DebuggerMainWnd::fixDockConfig(KConfig* c, bool upgrade)
551 static const char dockGroup[] = "dock_setting_default";
552 if (!c->hasGroup(dockGroup))
553 return;
555 static const char oldVersion[] = "0.0.4";
556 static const char newVersion[] = "0.0.5";
557 const char* from = upgrade ? oldVersion : newVersion;
558 const char* to = upgrade ? newVersion : oldVersion;
559 QMap<QString,QString> e = c->entryMap(dockGroup);
560 if (e["Version"] != from)
561 return;
563 KConfigGroupSaver g(c, dockGroup);
564 c->writeEntry("Version", to);
565 TRACE(upgrade ? "upgrading dockconfig" : "downgrading dockconfig");
567 // turn all orientation entries from 0 to 1 and from 1 to 0
568 QMap<QString,QString>::Iterator i;
569 for (i = e.begin(); i != e.end(); ++i)
571 if (i.key().right(12) == ":orientation") {
572 TRACE("upgrading " + i.key() + " old value: " + *i);
573 int orientation = c->readNumEntry(i.key(), -1);
574 if (orientation >= 0) { // paranoia
575 c->writeEntry(i.key(), 1 - orientation);
581 TTYWindow* DebuggerMainWnd::ttyWindow()
583 return m_ttyWindow;
586 bool DebuggerMainWnd::debugProgram(const QString& exe, QCString lang)
588 // check the file name
589 QFileInfo fi(exe);
591 bool success = fi.isFile();
592 if (!success)
594 QString msg = i18n("`%1' is not a file or does not exist");
595 KMessageBox::sorry(this, msg.arg(exe));
597 else
599 success = DebuggerMainWndBase::debugProgram(fi.absFilePath(), lang, this);
602 if (success)
604 m_recentExecAction->addURL(KURL(fi.absFilePath()));
606 // keep the directory
607 m_lastDirectory = fi.dirPath(true);
608 m_filesWindow->setExtraDirectory(m_lastDirectory);
610 else
612 m_recentExecAction->removeURL(KURL(fi.absFilePath()));
615 return true;
618 void DebuggerMainWnd::slotNewStatusMsg()
620 newStatusMsg(statusBar());
623 void DebuggerMainWnd::slotAnimationTimeout()
625 nextAnimationFrame(toolBar("mainToolBar"));
628 void DebuggerMainWnd::slotFileGlobalSettings()
630 int oldTabWidth = m_tabWidth;
632 doGlobalOptions(this);
634 if (m_tabWidth != oldTabWidth) {
635 emit setTabWidth(m_tabWidth);
639 void DebuggerMainWnd::slotDebuggerStarting()
641 DebuggerMainWndBase::slotDebuggerStarting();
644 void DebuggerMainWnd::slotToggleBreak(const QString& fileName, int lineNo,
645 const DbgAddr& address, bool temp)
647 // lineNo is zero-based
648 if (m_debugger != 0) {
649 m_debugger->setBreakpoint(fileName, lineNo, address, temp);
653 void DebuggerMainWnd::slotEnaDisBreak(const QString& fileName, int lineNo,
654 const DbgAddr& address)
656 // lineNo is zero-based
657 if (m_debugger != 0) {
658 m_debugger->enableDisableBreakpoint(fileName, lineNo, address);
662 QString DebuggerMainWnd::createOutputWindow()
664 QString tty = DebuggerMainWndBase::createOutputWindow();
665 if (!tty.isEmpty()) {
666 connect(m_outputTermProc, SIGNAL(processExited(KProcess*)),
667 SLOT(slotTermEmuExited()));
669 return tty;
672 void DebuggerMainWnd::slotTermEmuExited()
674 shutdownTermWindow();
677 #include <X11/Xlib.h> /* XRaiseWindow, XLowerWindow */
679 void DebuggerMainWnd::slotProgramStopped()
681 // when the program stopped, move the window to the foreground
682 if (m_popForeground) {
683 ::XRaiseWindow(x11Display(), winId());
685 m_backTimer.stop();
688 void DebuggerMainWnd::intoBackground()
690 if (m_popForeground) {
691 m_backTimer.start(m_backTimeout, true); /* single-shot */
695 void DebuggerMainWnd::slotBackTimer()
697 ::XLowerWindow(x11Display(), winId());
700 void DebuggerMainWnd::slotRecentExec(const KURL& url)
702 QString exe = url.path();
703 debugProgram(exe, "");
706 QString DebuggerMainWnd::makeSourceFilter()
708 QString f;
709 f = m_sourceFilter + " " + m_headerFilter + i18n("|All source files\n");
710 f += m_sourceFilter + i18n("|Source files\n");
711 f += m_headerFilter + i18n("|Header files\n");
712 f += i18n("*|All files");
713 return f;
717 * Pop up the context menu in the locals window
719 void DebuggerMainWnd::slotLocalsPopup(int, const QPoint& pt)
721 QPopupMenu* popup =
722 static_cast<QPopupMenu*>(factory()->container("popup_locals", this));
723 if (popup == 0) {
724 return;
726 if (popup->isVisible()) {
727 popup->hide();
728 } else {
729 popup->popup(m_localVariables->mapToGlobal(pt));
734 * Copies the currently selected item to the watch window.
736 void DebuggerMainWnd::slotLocalsToWatch()
738 int idx = m_localVariables->currentItem();
740 if (idx >= 0 && m_debugger != 0) {
741 QString text = m_localVariables->exprStringAt(idx);
742 m_debugger->addWatch(text);
747 * Starts editing a value in a value display
749 void DebuggerMainWnd::slotEditValue()
751 // does one of the value trees have the focus
752 QWidget* f = kapp->focusWidget();
753 ExprWnd* wnd;
754 if (f == m_localVariables) {
755 wnd = m_localVariables;
756 } else if (f == m_watches->watchVariables()) {
757 wnd = m_watches->watchVariables();
758 } else {
759 return;
762 if (m_localVariables->isEditing() ||
763 m_watches->watchVariables()->isEditing())
765 return; /* don't edit twice */
768 int idx = wnd->currentItem();
769 if (idx >= 0 && m_debugger != 0 && m_debugger->canSingleStep())
771 TRACE("edit value");
772 // determine the text to edit
773 VarTree* expr = static_cast<VarTree*>(wnd->itemAt(idx));
774 QString text = m_debugger->driver()->editableValue(expr);
775 wnd->editValue(idx, text);
779 // Pop up the context menu of the files window (for loaded files)
780 void DebuggerMainWnd::slotFileWndMenu(const QPoint& pos)
782 QPopupMenu* popup =
783 static_cast<QPopupMenu*>(factory()->container("popup_files", this));
784 if (popup == 0) {
785 return;
787 if (popup->isVisible()) {
788 popup->hide();
789 } else {
790 // pos is still in widget coordinates of the sender
791 const QWidget* w = static_cast<const QWidget*>(sender());
792 popup->popup(w->mapToGlobal(pos));
796 // Pop up the context menu of the files window (while no file is loaded)
797 void DebuggerMainWnd::slotFileWndEmptyMenu(const QPoint& pos)
799 QPopupMenu* popup =
800 static_cast<QPopupMenu*>(factory()->container("popup_files_empty", this));
801 if (popup == 0) {
802 return;
804 if (popup->isVisible()) {
805 popup->hide();
806 } else {
807 // pos is still in widget coordinates of the sender
808 const QWidget* w = static_cast<const QWidget*>(sender());
809 popup->popup(w->mapToGlobal(pos));
813 void DebuggerMainWnd::slotFileOpen()
815 QString fileName = myGetFileName(i18n("Open"),
816 m_lastDirectory,
817 makeSourceFilter(), this);
819 if (!fileName.isEmpty())
821 QFileInfo fi(fileName);
822 m_lastDirectory = fi.dirPath();
823 m_filesWindow->setExtraDirectory(m_lastDirectory);
824 m_filesWindow->activateFile(fileName);
828 void DebuggerMainWnd::slotFileQuit()
830 if (m_debugger != 0) {
831 m_debugger->shutdown();
833 kapp->quit();
836 void DebuggerMainWnd::slotFileExe()
838 if (m_debugger->isIdle())
840 // open a new executable
841 QString executable = myGetFileName(i18n("Select the executable to debug"),
842 m_lastDirectory, 0, this);
843 if (executable.isEmpty())
844 return;
846 debugProgram(executable, "");
850 void DebuggerMainWnd::slotFileCore()
852 if (m_debugger->canUseCoreFile())
854 QString corefile = myGetFileName(i18n("Select core dump"),
855 m_lastDirectory, 0, this);
856 if (!corefile.isEmpty()) {
857 m_debugger->useCoreFile(corefile, false);
862 void DebuggerMainWnd::slotFileProgSettings()
864 if (m_debugger != 0) {
865 m_debugger->programSettings(this);
869 void DebuggerMainWnd::slotViewToolbar()
871 if (toolBar()->isVisible())
872 toolBar()->hide();
873 else
874 toolBar()->show();
877 void DebuggerMainWnd::slotViewStatusbar()
879 if (statusBar()->isVisible())
880 statusBar()->hide();
881 else
882 statusBar()->show();
885 void DebuggerMainWnd::slotExecUntil()
887 if (m_debugger != 0)
889 QString file;
890 int lineNo;
891 if (m_filesWindow->activeLine(file, lineNo))
892 m_debugger->runUntil(file, lineNo);
896 void DebuggerMainWnd::slotExecAttach()
898 #ifdef PS_COMMAND
899 ProcAttachPS dlg(this);
900 #else
901 ProcAttach dlg(this);
902 dlg.setText(m_debugger->attachedPid());
903 #endif
904 if (dlg.exec()) {
905 m_debugger->attachProgram(dlg.text());
909 void DebuggerMainWnd::slotExecArgs()
911 if (m_debugger != 0) {
912 m_debugger->programArgs(this);
916 void DebuggerMainWnd::slotConfigureKeys()
918 KKeyDialog::configure(actionCollection(), this);
921 #include "dbgmainwnd.moc"