Don't check for -Wbad-function-cast, because g++ 3.3 doesn't like it.
[kdbg.git] / kdbg / dbgmainwnd.cpp
blob0f5b81b76710f14c93e310b9d41c3492fa25d7c2
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 "mydebug.h"
33 DebuggerMainWnd::DebuggerMainWnd(const char* name) :
34 KDockMainWindow(0, name),
35 DebuggerMainWndBase()
37 QPixmap p;
39 KDockWidget* dw0 = createDockWidget("Source", p, 0, i18n("Source"));
40 m_filesWindow = new WinStack(dw0, "files");
41 dw0->setWidget(m_filesWindow);
42 dw0->setDockSite(KDockWidget::DockCorner);
43 dw0->setEnableDocking(KDockWidget::DockNone);
44 setView(dw0);
45 setMainDockWidget(dw0);
47 KDockWidget* dw1 = createDockWidget("Stack", p, 0, i18n("Stack"));
48 m_btWindow = new QListBox(dw1, "backtrace");
49 dw1->setWidget(m_btWindow);
50 KDockWidget* dw2 = createDockWidget("Locals", p, 0, i18n("Locals"));
51 m_localVariables = new ExprWnd(dw2, "locals");
52 dw2->setWidget(m_localVariables);
53 KDockWidget* dw3 = createDockWidget("Watches", p, 0, i18n("Watches"));
54 m_watches = new WatchWindow(dw3, "watches");
55 dw3->setWidget(m_watches);
56 KDockWidget* dw4 = createDockWidget("Registers", p, 0, i18n("Registers"));
57 m_registers = new RegisterView(dw4, "registers");
58 dw4->setWidget(m_registers);
59 KDockWidget* dw5 = createDockWidget("Breakpoints", p, 0, i18n("Breakpoints"));
60 m_bpTable = new BreakpointTable(dw5, "breakpoints");
61 dw5->setWidget(m_bpTable);
62 KDockWidget* dw6 = createDockWidget("Output", p, 0, i18n("Output"));
63 m_ttyWindow = new TTYWindow(dw6, "output");
64 dw6->setWidget(m_ttyWindow);
65 KDockWidget* dw7 = createDockWidget("Threads", p, 0, i18n("Threads"));
66 m_threads = new ThreadList(dw7, "threads");
67 dw7->setWidget(m_threads);
68 KDockWidget* dw8 = createDockWidget("Memory", p, 0, i18n("Memory"));
69 m_memoryWindow = new MemoryWindow(dw8, "memory");
70 dw8->setWidget(m_memoryWindow);
72 setupDebugger(this, m_localVariables, m_watches->watchVariables(), m_btWindow);
73 m_bpTable->setDebugger(m_debugger);
74 m_memoryWindow->setDebugger(m_debugger);
76 initKAction();
77 initToolbar(); // kind of obsolete?
79 connect(m_watches, SIGNAL(addWatch()), SLOT(slotAddWatch()));
80 connect(m_watches, SIGNAL(deleteWatch()), m_debugger, SLOT(slotDeleteWatch()));
82 KAction* windowMenu = actionCollection()->action("window");
83 m_filesWindow->setWindowMenu(static_cast<KActionMenu*>(windowMenu)->popupMenu());
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 connect(m_filesWindow, SIGNAL(moveProgramCounter(const QString&,int,const DbgAddr&)),
108 m_debugger, SLOT(setProgramCounter(const QString&,int,const DbgAddr&)));
109 // program stopped
110 connect(m_debugger, SIGNAL(programStopped()), SLOT(slotProgramStopped()));
111 connect(&m_backTimer, SIGNAL(timeout()), SLOT(slotBackTimer()));
112 // tab width
113 connect(this, SIGNAL(setTabWidth(int)), m_filesWindow, SIGNAL(setTabWidth(int)));
115 // Establish communication when right clicked on file window.
116 connect(m_filesWindow, SIGNAL(filesRightClick(const QPoint &)),
117 SLOT(slotFileWndMenu(const QPoint &)));
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 &)));
124 // file/line updates
125 connect(m_filesWindow, SIGNAL(fileChanged()), SLOT(slotFileChanged()));
126 connect(m_filesWindow, SIGNAL(lineChanged()), SLOT(slotLineChanged()));
128 // connect breakpoint table
129 connect(m_bpTable, SIGNAL(activateFileLine(const QString&,int,const DbgAddr&)),
130 m_filesWindow, SLOT(activate(const QString&,int,const DbgAddr&)));
131 connect(m_debugger, SIGNAL(updateUI()), m_bpTable, SLOT(updateUI()));
132 connect(m_debugger, SIGNAL(breakpointsChanged()), m_bpTable, SLOT(updateBreakList()));
133 connect(m_debugger, SIGNAL(breakpointsChanged()), m_bpTable, SLOT(updateUI()));
135 connect(m_debugger, SIGNAL(registersChanged(QList<RegisterInfo>&)),
136 m_registers, SLOT(updateRegisters(QList<RegisterInfo>&)));
138 connect(m_debugger, SIGNAL(memoryDumpChanged(const QString&, QList<MemoryDump>&)),
139 m_memoryWindow, SLOT(slotNewMemoryDump(const QString&, QList<MemoryDump>&)));
140 connect(m_debugger, SIGNAL(saveProgramSpecific(KSimpleConfig*)),
141 m_memoryWindow, SLOT(saveProgramSpecific(KSimpleConfig*)));
142 connect(m_debugger, SIGNAL(restoreProgramSpecific(KSimpleConfig*)),
143 m_memoryWindow, SLOT(restoreProgramSpecific(KSimpleConfig*)));
145 // thread window
146 connect(m_debugger, SIGNAL(threadsChanged(QList<ThreadInfo>&)),
147 m_threads, SLOT(updateThreads(QList<ThreadInfo>&)));
148 connect(m_threads, SIGNAL(setThread(int)),
149 m_debugger, SLOT(setThread(int)));
151 // view menu changes when docking state changes
152 connect(dockManager, SIGNAL(change()), SLOT(updateUI()));
154 // popup menu of the local variables window
155 connect(m_localVariables, SIGNAL(rightPressed(int, const QPoint&)),
156 this, SLOT(slotLocalsPopup(int, const QPoint&)));
158 restoreSettings(kapp->config());
160 updateUI();
161 m_bpTable->updateUI();
162 slotFileChanged();
165 DebuggerMainWnd::~DebuggerMainWnd()
167 saveSettings(kapp->config());
168 // must delete m_debugger early since it references our windows
169 delete m_debugger;
170 m_debugger = 0;
172 delete m_memoryWindow;
173 delete m_threads;
174 delete m_ttyWindow;
175 delete m_bpTable;
176 delete m_registers;
177 delete m_watches;
178 delete m_localVariables;
179 delete m_btWindow;
180 delete m_filesWindow;
183 void DebuggerMainWnd::initKAction()
185 // file menu
186 KAction* open = KStdAction::open(this, SLOT(slotFileOpen()),
187 actionCollection());
188 open->setText(i18n("&Open Source..."));
189 (void)new KAction(i18n("&Reload Source"), "reload", 0, m_filesWindow,
190 SLOT(slotFileReload()), actionCollection(),
191 "file_reload");
192 (void)new KAction(i18n("&Executable..."), "execopen", 0, this,
193 SLOT(slotFileExe()), actionCollection(),
194 "file_executable");
195 m_recentExecAction = new KRecentFilesAction(i18n("Recent E&xecutables"), 0,
196 this, SLOT(slotRecentExec(const KURL&)),
197 actionCollection(), "file_executable_recent");
198 (void)new KAction(i18n("&Core dump..."), 0, this, SLOT(slotFileCore()),
199 actionCollection(), "file_core_dump");
200 KStdAction::quit(this, SLOT(slotFileQuit()), actionCollection());
202 // settings menu
203 (void)new KAction(i18n("This &Program..."), 0, this,
204 SLOT(slotFileProgSettings()), actionCollection(),
205 "settings_program");
206 (void)new KAction(i18n("&Global Options..."), 0, this,
207 SLOT(slotFileGlobalSettings()), actionCollection(),
208 "settings_global");
209 KStdAction::keyBindings(this, SLOT(slotConfigureKeys()), actionCollection());
210 KStdAction::showToolbar(this, SLOT(slotViewToolbar()), actionCollection());
211 KStdAction::showStatusbar(this, SLOT(slotViewStatusbar()), actionCollection());
213 // view menu
214 (void)new KToggleAction(i18n("&Find"), "find", 0, m_filesWindow,
215 SLOT(slotViewFind()), actionCollection(),
216 "view_find");
217 i18n("Source &code");
218 struct { QString text; QWidget* w; QString id; } dw[] = {
219 { i18n("Stac&k"), m_btWindow, "view_stack"},
220 { i18n("&Locals"), m_localVariables, "view_locals"},
221 { i18n("&Watched expressions"), m_watches, "view_watched_expressions"},
222 { i18n("&Registers"), m_registers, "view_registers"},
223 { i18n("&Breakpoints"), m_bpTable, "view_breakpoints"},
224 { i18n("T&hreads"), m_threads, "view_threads"},
225 { i18n("&Output"), m_ttyWindow, "view_output"},
226 { i18n("&Memory"), m_memoryWindow, "view_memory"}
228 for (unsigned i = 0; i < sizeof(dw)/sizeof(dw[0]); i++) {
229 KDockWidget* d = dockParent(dw[i].w);
230 (void)new KToggleAction(dw[i].text, 0, d, SLOT(changeHideShowState()),
231 actionCollection(), dw[i].id);
235 // execution menu
236 KAction* a = new KAction(i18n("&Run"), "pgmrun", Key_F5, m_debugger,
237 SLOT(programRun()), actionCollection(), "exec_run");
238 connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
239 a = new KAction(i18n("Step &into"), "pgmstep", Key_F8, m_debugger,
240 SLOT(programStep()), actionCollection(),
241 "exec_step_into");
242 connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
243 a = new KAction(i18n("Step &over"), "pgmnext", Key_F10, m_debugger,
244 SLOT(programNext()), actionCollection(),
245 "exec_step_over");
246 connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
247 a = new KAction(i18n("Step o&ut"), "pgmfinish", Key_F6, m_debugger,
248 SLOT(programFinish()), actionCollection(),
249 "exec_step_out");
250 connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
251 a = new KAction(i18n("Run to &cursor"), Key_F7, this,
252 SLOT(slotExecUntil()), actionCollection(),
253 "exec_run_to_cursor");
254 connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
255 a = new KAction(i18n("Step i&nto by instruction"), "pgmstepi",
256 SHIFT+Key_F8, m_debugger, SLOT(programStepi()),
257 actionCollection(), "exec_step_into_by_insn");
258 connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
259 a = new KAction(i18n("Step o&ver by instruction"), "pgmnexti",
260 SHIFT+Key_F10, m_debugger, SLOT(programNexti()),
261 actionCollection(), "exec_step_over_by_insn");
262 connect(a, SIGNAL(activated()), this, SLOT(intoBackground()));
263 (void)new KAction(i18n("&Program counter to current line"), 0,
264 m_filesWindow, SLOT(slotMoveProgramCounter()),
265 actionCollection(), "exec_movepc");
266 (void)new KAction(i18n("&Break"), 0, m_debugger,
267 SLOT(programBreak()), actionCollection(),
268 "exec_break");
269 (void)new KAction(i18n("&Kill"), 0, m_debugger,
270 SLOT(programKill()), actionCollection(),
271 "exec_kill");
272 (void)new KAction(i18n("Re&start"), 0, m_debugger,
273 SLOT(programRunAgain()), actionCollection(),
274 "exec_restart");
275 (void)new KAction(i18n("A&ttach..."), 0, this,
276 SLOT(slotExecAttach()), actionCollection(),
277 "exec_attach");
278 (void)new KAction(i18n("&Arguments..."), 0, this,
279 SLOT(slotExecArgs()), actionCollection(),
280 "exec_arguments");
282 // breakpoint menu
283 (void)new KAction(i18n("Set/Clear &breakpoint"), "brkpt", Key_F9,
284 m_filesWindow, SLOT(slotBrkptSet()), actionCollection(),
285 "breakpoint_set");
286 (void)new KAction(i18n("Set &temporary breakpoint"), SHIFT+Key_F9,
287 m_filesWindow, SLOT(slotBrkptSetTemp()), actionCollection(),
288 "breakpoint_set_temporary");
289 (void)new KAction(i18n("&Enable/Disable breakpoint"), CTRL+Key_F9,
290 m_filesWindow, SLOT(slotBrkptEnable()), actionCollection(),
291 "breakpoint_enable");
293 // only in popup menus
294 (void)new KAction(i18n("Watch Expression"), 0, this,
295 SLOT(slotLocalsToWatch()), actionCollection(),
296 "watch_expression");
298 (void)new KActionMenu(i18n("&Window"), actionCollection(), "window");
300 // all actions force an UI update
301 QValueList<KAction*> actions = actionCollection()->actions();
302 QValueList<KAction*>::Iterator it = actions.begin();
303 for (; it != actions.end(); ++it) {
304 connect(*it, SIGNAL(activated()), this, SLOT(updateUI()));
307 createGUI("kdbgui.rc");
310 void DebuggerMainWnd::initToolbar()
312 KToolBar* toolbar = toolBar("mainToolBar");
313 toolbar->setBarPos(KToolBar::Top);
314 //moveToolBar(toolbar);
316 initAnimation(toolbar);
318 KStatusBar* statusbar = statusBar();
319 statusbar->insertItem(m_statusActive, ID_STATUS_ACTIVE);
320 m_lastActiveStatusText = m_statusActive;
321 statusbar->insertItem(i18n("Line 00000"), ID_STATUS_LINENO);
322 statusbar->insertItem("", ID_STATUS_MSG); /* message pane */
324 // reserve some translations
325 i18n("Restart");
326 i18n("Core dump");
330 * We must override KTMainWindow's handling of close events since we have
331 * only one toplevel window, which lives on the stack (which KTMainWindow
332 * can't live with :-( )
334 void DebuggerMainWnd::closeEvent(QCloseEvent* e)
336 clearWFlags(WDestructiveClose);
338 if (m_debugger != 0) {
339 m_debugger->shutdown();
342 e->accept();
343 kapp->quit();
347 // instance properties
348 void DebuggerMainWnd::saveProperties(KConfig* config)
350 // session management
351 QString executable = "";
352 if (m_debugger != 0) {
353 executable = m_debugger->executable();
355 config->writeEntry("executable", executable);
358 void DebuggerMainWnd::readProperties(KConfig* config)
360 // session management
361 QString execName = config->readEntry("executable");
363 TRACE("readProperties: executable=" + execName);
364 if (!execName.isEmpty()) {
365 debugProgram(execName, "");
369 const char WindowGroup[] = "Windows";
370 const char RecentExecutables[] = "RecentExecutables";
372 void DebuggerMainWnd::saveSettings(KConfig* config)
374 KConfigGroupSaver g(config, WindowGroup);
376 writeDockConfig(config);
377 fixDockConfig(config, false); // downgrade
379 m_recentExecAction->saveEntries(config, RecentExecutables);
381 DebuggerMainWndBase::saveSettings(config);
384 void DebuggerMainWnd::restoreSettings(KConfig* config)
386 KConfigGroupSaver g(config, WindowGroup);
388 fixDockConfig(config, true); // upgrade
389 readDockConfig(config);
391 m_recentExecAction->loadEntries(config, RecentExecutables);
393 DebuggerMainWndBase::restoreSettings(config);
395 emit setTabWidth(m_tabWidth);
398 void DebuggerMainWnd::updateUI()
400 KToggleAction* viewFind =
401 static_cast<KToggleAction*>(actionCollection()->action("view_find"));
402 viewFind->setChecked(m_filesWindow->m_findDlg.isVisible());
403 viewFind->setEnabled(m_filesWindow->hasWindows());
404 actionCollection()->action("breakpoint_set")->setEnabled(m_debugger->canChangeBreakpoints());
405 actionCollection()->action("breakpoint_set_temporary")->setEnabled(m_debugger->canChangeBreakpoints());
406 actionCollection()->action("breakpoint_enable")->setEnabled(m_debugger->canChangeBreakpoints());
407 dockUpdateHelper("view_breakpoints", m_bpTable);
408 dockUpdateHelper("view_stack", m_btWindow);
409 dockUpdateHelper("view_locals", m_localVariables);
410 dockUpdateHelper("view_watched_expressions", m_watches);
411 dockUpdateHelper("view_registers", m_registers);
412 dockUpdateHelper("view_threads", m_threads);
413 dockUpdateHelper("view_memory", m_memoryWindow);
414 dockUpdateHelper("view_output", m_ttyWindow);
416 // AB: maybe in mainwndbase.cpp?
417 actionCollection()->action("file_executable")->setEnabled(m_debugger->isIdle());
418 actionCollection()->action("settings_program")->setEnabled(m_debugger->haveExecutable());
419 actionCollection()->action("file_core_dump")->setEnabled(m_debugger->canUseCoreFile());
420 actionCollection()->action("exec_step_into")->setEnabled(m_debugger->canSingleStep());
421 actionCollection()->action("exec_step_into_by_insn")->setEnabled(m_debugger->canSingleStep());
422 actionCollection()->action("exec_step_over")->setEnabled(m_debugger->canSingleStep());
423 actionCollection()->action("exec_step_over_by_insn")->setEnabled(m_debugger->canSingleStep());
424 actionCollection()->action("exec_step_out")->setEnabled(m_debugger->canSingleStep());
425 actionCollection()->action("exec_run_to_cursor")->setEnabled(m_debugger->canSingleStep());
426 actionCollection()->action("exec_movepc")->setEnabled(m_debugger->canSingleStep());
427 actionCollection()->action("exec_restart")->setEnabled(m_debugger->canSingleStep());
428 actionCollection()->action("exec_attach")->setEnabled(m_debugger->isReady());
429 actionCollection()->action("exec_run")->setEnabled(m_debugger->isReady());
430 actionCollection()->action("exec_kill")->setEnabled(m_debugger->haveExecutable() && m_debugger->isProgramActive());
431 actionCollection()->action("exec_break")->setEnabled(m_debugger->isProgramRunning());
432 actionCollection()->action("exec_arguments")->setEnabled(m_debugger->haveExecutable());
434 // update statusbar
435 QString newStatus;
436 if (m_debugger->isProgramActive())
437 newStatus = m_statusActive;
438 if (newStatus != m_lastActiveStatusText) {
439 statusBar()->changeItem(newStatus, ID_STATUS_ACTIVE);
440 m_lastActiveStatusText = newStatus;
442 // line number is updated in slotLineChanged
445 void DebuggerMainWnd::dockUpdateHelper(QString action, QWidget* w)
447 KToggleAction* item =
448 static_cast<KToggleAction*>(actionCollection()->action(action));
449 bool canChange = canChangeDockVisibility(w);
450 item->setEnabled(canChange);
451 item->setChecked(canChange && isDockVisible(w));
454 void DebuggerMainWnd::updateLineItems()
456 m_filesWindow->updateLineItems(m_debugger);
459 void DebuggerMainWnd::slotAddWatch()
461 if (m_debugger != 0) {
462 QString t = m_watches->watchText();
463 m_debugger->addWatch(t);
467 void DebuggerMainWnd::slotFileChanged()
469 // set caption
470 QString caption;
472 if (m_debugger->haveExecutable()) {
473 // basename part of executable
474 QString executable = m_debugger->executable();
475 const char* execBase = executable.data();
476 int lastSlash = executable.findRev('/');
477 if (lastSlash >= 0)
478 execBase += lastSlash + 1;
479 caption += execBase;
481 QString file;
482 int line;
483 bool anyWindows = m_filesWindow->activeLine(file, line);
484 updateLineStatus(anyWindows ? line : -1);
485 if (anyWindows) {
486 caption += " (";
487 caption += file;
488 caption += ")";
490 setCaption(caption);
493 void DebuggerMainWnd::slotLineChanged()
495 QString file;
496 int line;
497 bool anyWindows = m_filesWindow->activeLine(file, line);
498 updateLineStatus(anyWindows ? line : -1);
501 void DebuggerMainWnd::slotNewFileLoaded()
503 // updates program counter in the new file
504 if (m_debugger != 0)
505 m_filesWindow->updateLineItems(m_debugger);
508 void DebuggerMainWnd::updateLineStatus(int lineNo)
510 if (lineNo < 0) {
511 statusBar()->changeItem("", ID_STATUS_LINENO);
512 } else {
513 QString strLine;
514 strLine.sprintf(i18n("Line %d"), lineNo + 1);
515 statusBar()->changeItem(strLine, ID_STATUS_LINENO);
519 KDockWidget* DebuggerMainWnd::dockParent(QWidget* w)
521 while ((w = w->parentWidget()) != 0) {
522 if (w->isA("KDockWidget"))
523 return static_cast<KDockWidget*>(w);
525 return 0;
528 bool DebuggerMainWnd::isDockVisible(QWidget* w)
530 KDockWidget* d = dockParent(w);
531 return d != 0 && d->mayBeHide();
534 bool DebuggerMainWnd::canChangeDockVisibility(QWidget* w)
536 KDockWidget* d = dockParent(w);
537 return d != 0 && (d->mayBeHide() || d->mayBeShow());
540 // upgrades the entries from version 0.0.4 to 0.0.5 and back
541 void DebuggerMainWnd::fixDockConfig(KConfig* c, bool upgrade)
543 static const char dockGroup[] = "dock_setting_default";
544 if (!c->hasGroup(dockGroup))
545 return;
547 static const char oldVersion[] = "0.0.4";
548 static const char newVersion[] = "0.0.5";
549 const char* from = upgrade ? oldVersion : newVersion;
550 const char* to = upgrade ? newVersion : oldVersion;
551 QMap<QString,QString> e = c->entryMap(dockGroup);
552 if (e["Version"] != from)
553 return;
555 KConfigGroupSaver g(c, dockGroup);
556 c->writeEntry("Version", to);
557 TRACE(upgrade ? "upgrading dockconfig" : "downgrading dockconfig");
559 // turn all orientation entries from 0 to 1 and from 1 to 0
560 QMap<QString,QString>::Iterator i;
561 for (i = e.begin(); i != e.end(); ++i)
563 if (i.key().right(12) == ":orientation") {
564 TRACE("upgrading " + i.key() + " old value: " + *i);
565 int orientation = c->readNumEntry(i.key(), -1);
566 if (orientation >= 0) { // paranoia
567 c->writeEntry(i.key(), 1 - orientation);
573 TTYWindow* DebuggerMainWnd::ttyWindow()
575 return m_ttyWindow;
578 bool DebuggerMainWnd::debugProgram(const QString& exe, QCString lang)
580 // check the file name
581 QFileInfo fi(exe);
583 bool success = fi.isFile();
584 if (!success)
586 QString msg = i18n("`%1' is not a file or does not exist");
587 KMessageBox::sorry(this, msg.arg(exe));
589 else
591 success = DebuggerMainWndBase::debugProgram(fi.absFilePath(), lang, this);
594 if (success)
596 m_recentExecAction->addURL(KURL(fi.absFilePath()));
598 // keep the directory
599 m_lastDirectory = fi.dirPath(true);
600 m_filesWindow->setExtraDirectory(m_lastDirectory);
602 else
604 m_recentExecAction->removeURL(KURL(fi.absFilePath()));
607 return true;
610 void DebuggerMainWnd::slotNewStatusMsg()
612 newStatusMsg(statusBar());
615 void DebuggerMainWnd::slotAnimationTimeout()
617 nextAnimationFrame(toolBar("mainToolBar"));
620 void DebuggerMainWnd::slotFileGlobalSettings()
622 int oldTabWidth = m_tabWidth;
624 doGlobalOptions(this);
626 if (m_tabWidth != oldTabWidth) {
627 emit setTabWidth(m_tabWidth);
631 void DebuggerMainWnd::slotDebuggerStarting()
633 DebuggerMainWndBase::slotDebuggerStarting();
636 void DebuggerMainWnd::slotToggleBreak(const QString& fileName, int lineNo,
637 const DbgAddr& address, bool temp)
639 // lineNo is zero-based
640 if (m_debugger != 0) {
641 m_debugger->setBreakpoint(fileName, lineNo, address, temp);
645 void DebuggerMainWnd::slotEnaDisBreak(const QString& fileName, int lineNo,
646 const DbgAddr& address)
648 // lineNo is zero-based
649 if (m_debugger != 0) {
650 m_debugger->enableDisableBreakpoint(fileName, lineNo, address);
654 QString DebuggerMainWnd::createOutputWindow()
656 QString tty = DebuggerMainWndBase::createOutputWindow();
657 if (!tty.isEmpty()) {
658 connect(m_outputTermProc, SIGNAL(processExited(KProcess*)),
659 SLOT(slotTermEmuExited()));
661 return tty;
664 void DebuggerMainWnd::slotTermEmuExited()
666 shutdownTermWindow();
669 #include <X11/Xlib.h> /* XRaiseWindow, XLowerWindow */
671 void DebuggerMainWnd::slotProgramStopped()
673 // when the program stopped, move the window to the foreground
674 if (m_popForeground) {
675 ::XRaiseWindow(x11Display(), winId());
677 m_backTimer.stop();
680 void DebuggerMainWnd::intoBackground()
682 if (m_popForeground) {
683 m_backTimer.start(m_backTimeout, true); /* single-shot */
687 void DebuggerMainWnd::slotBackTimer()
689 ::XLowerWindow(x11Display(), winId());
692 void DebuggerMainWnd::slotRecentExec(const KURL& url)
694 QString exe = url.path();
695 debugProgram(exe, "");
698 QString DebuggerMainWnd::makeSourceFilter()
700 QString f;
701 f = m_sourceFilter + " " + m_headerFilter + i18n("|All source files\n");
702 f += m_sourceFilter + i18n("|Source files\n");
703 f += m_headerFilter + i18n("|Header files\n");
704 f += i18n("*|All files");
705 return f;
709 * Pop up the context menu in the locals window
711 void DebuggerMainWnd::slotLocalsPopup(int, const QPoint& pt)
713 QPopupMenu* popup =
714 static_cast<QPopupMenu*>(factory()->container("popup_locals", this));
715 if (popup == 0) {
716 return;
718 if (popup->isVisible()) {
719 popup->hide();
720 } else {
721 popup->popup(m_localVariables->mapToGlobal(pt));
726 * Copies the currently selected item to the watch window.
728 void DebuggerMainWnd::slotLocalsToWatch()
730 int idx = m_localVariables->currentItem();
732 if (idx >= 0 && m_debugger != 0) {
733 QString text = m_localVariables->exprStringAt(idx);
734 m_debugger->addWatch(text);
738 // Pop up the context menu of the files window (for loaded files)
739 void DebuggerMainWnd::slotFileWndMenu(const QPoint& pos)
741 QPopupMenu* popup =
742 static_cast<QPopupMenu*>(factory()->container("popup_files", this));
743 if (popup == 0) {
744 return;
746 if (popup->isVisible()) {
747 popup->hide();
748 } else {
749 // pos is still in widget coordinates of the sender
750 const QWidget* w = static_cast<const QWidget*>(sender());
751 popup->popup(w->mapToGlobal(pos));
755 // Pop up the context menu of the files window (while no file is loaded)
756 void DebuggerMainWnd::slotFileWndEmptyMenu(const QPoint& pos)
758 QPopupMenu* popup =
759 static_cast<QPopupMenu*>(factory()->container("popup_files_empty", this));
760 if (popup == 0) {
761 return;
763 if (popup->isVisible()) {
764 popup->hide();
765 } else {
766 // pos is still in widget coordinates of the sender
767 const QWidget* w = static_cast<const QWidget*>(sender());
768 popup->popup(w->mapToGlobal(pos));
772 void DebuggerMainWnd::slotFileOpen()
774 QString fileName = myGetFileName(i18n("Open"),
775 m_lastDirectory,
776 makeSourceFilter(), this);
778 if (!fileName.isEmpty())
780 QFileInfo fi(fileName);
781 m_lastDirectory = fi.dirPath();
782 m_filesWindow->setExtraDirectory(m_lastDirectory);
783 m_filesWindow->activateFile(fileName);
787 void DebuggerMainWnd::slotFileQuit()
789 if (m_debugger != 0) {
790 m_debugger->shutdown();
792 kapp->quit();
795 void DebuggerMainWnd::slotFileExe()
797 if (m_debugger->isIdle())
799 // open a new executable
800 QString executable = myGetFileName(i18n("Select the executable to debug"),
801 m_lastDirectory, 0, this);
802 if (executable.isEmpty())
803 return;
805 debugProgram(executable, "");
809 void DebuggerMainWnd::slotFileCore()
811 if (m_debugger->canUseCoreFile())
813 QString corefile = myGetFileName(i18n("Select core dump"),
814 m_lastDirectory, 0, this);
815 if (!corefile.isEmpty()) {
816 m_debugger->useCoreFile(corefile, false);
821 void DebuggerMainWnd::slotFileProgSettings()
823 if (m_debugger != 0) {
824 m_debugger->programSettings(this);
828 void DebuggerMainWnd::slotViewToolbar()
830 if (toolBar()->isVisible())
831 toolBar()->hide();
832 else
833 toolBar()->show();
836 void DebuggerMainWnd::slotViewStatusbar()
838 if (statusBar()->isVisible())
839 statusBar()->hide();
840 else
841 statusBar()->show();
844 void DebuggerMainWnd::slotExecUntil()
846 if (m_debugger != 0)
848 QString file;
849 int lineNo;
850 if (m_filesWindow->activeLine(file, lineNo))
851 m_debugger->runUntil(file, lineNo);
855 void DebuggerMainWnd::slotExecAttach()
857 ProcAttach dlg(this);
858 dlg.setText(m_debugger->attachedPid());
859 if (dlg.exec()) {
860 m_debugger->attachProgram(dlg.text());
864 void DebuggerMainWnd::slotExecArgs()
866 if (m_debugger != 0) {
867 m_debugger->programArgs(this);
871 void DebuggerMainWnd::slotConfigureKeys()
873 KKeyDialog::configure(actionCollection(), this);
876 #include "dbgmainwnd.moc"