3 // Copyright by Johannes Sixt
4 // This file is under GPL, the GNU General Public Licence
7 #include <klocale.h> /* i18n */
8 #include <kmessagebox.h>
10 #include <kstatusbar.h>
11 #include <kiconloader.h>
12 #include <kstdaccel.h>
13 #include <kstdaction.h>
15 #include <kpopupmenu.h>
16 #include <kfiledialog.h>
18 #include <kkeydialog.h>
20 #include <qfileinfo.h>
21 #include "dbgmainwnd.h"
23 #include "commandids.h"
26 #include "threadlist.h"
27 #include "memwindow.h"
29 #include "procattach.h"
33 DebuggerMainWnd::DebuggerMainWnd(const char* name
) :
34 KDockMainWindow(0, name
),
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
);
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
);
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
&)));
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
&)));
110 connect(m_debugger
, SIGNAL(programStopped()), SLOT(slotProgramStopped()));
111 connect(&m_backTimer
, SIGNAL(timeout()), SLOT(slotBackTimer()));
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
121 connect(m_filesWindow
, SIGNAL(clickedRight(const QPoint
&)),
122 SLOT(slotFileWndEmptyMenu(const QPoint
&)));
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(KConfigBase
*)),
141 m_memoryWindow
, SLOT(saveProgramSpecific(KConfigBase
*)));
142 connect(m_debugger
, SIGNAL(restoreProgramSpecific(KConfigBase
*)),
143 m_memoryWindow
, SLOT(restoreProgramSpecific(KConfigBase
*)));
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());
161 m_bpTable
->updateUI();
165 DebuggerMainWnd::~DebuggerMainWnd()
167 saveSettings(kapp
->config());
168 // must delete m_debugger early since it references our windows
172 delete m_memoryWindow
;
178 delete m_localVariables
;
180 delete m_filesWindow
;
183 void DebuggerMainWnd::initKAction()
186 KAction
* open
= KStdAction::open(this, SLOT(slotFileOpen()),
188 open
->setText(i18n("&Open Source..."));
189 (void)new KAction(i18n("&Reload Source"), "reload", 0, m_filesWindow
,
190 SLOT(slotFileReload()), actionCollection(),
192 (void)new KAction(i18n("&Executable..."), "execopen", 0, this,
193 SLOT(slotFileExe()), actionCollection(),
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());
203 (void)new KAction(i18n("This &Program..."), 0, this,
204 SLOT(slotFileProgSettings()), actionCollection(),
206 (void)new KAction(i18n("&Global Options..."), 0, this,
207 SLOT(slotFileGlobalSettings()), actionCollection(),
209 KStdAction::keyBindings(this, SLOT(slotConfigureKeys()), actionCollection());
210 KStdAction::showToolbar(this, SLOT(slotViewToolbar()), actionCollection());
211 KStdAction::showStatusbar(this, SLOT(slotViewStatusbar()), actionCollection());
214 (void)new KToggleAction(i18n("&Find"), "find", 0, m_filesWindow
,
215 SLOT(slotViewFind()), actionCollection(),
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
);
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(),
242 connect(a
, SIGNAL(activated()), this, SLOT(intoBackground()));
243 a
= new KAction(i18n("Step &over"), "pgmnext", Key_F10
, m_debugger
,
244 SLOT(programNext()), actionCollection(),
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(),
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(),
269 (void)new KAction(i18n("&Kill"), 0, m_debugger
,
270 SLOT(programKill()), actionCollection(),
272 (void)new KAction(i18n("Re&start"), 0, m_debugger
,
273 SLOT(programRunAgain()), actionCollection(),
275 (void)new KAction(i18n("A&ttach..."), 0, this,
276 SLOT(slotExecAttach()), actionCollection(),
278 (void)new KAction(i18n("&Arguments..."), 0, this,
279 SLOT(slotExecArgs()), actionCollection(),
283 (void)new KAction(i18n("Set/Clear &breakpoint"), "brkpt", Key_F9
,
284 m_filesWindow
, SLOT(slotBrkptSet()), actionCollection(),
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(),
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
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();
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());
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()
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('/');
478 execBase
+= lastSlash
+ 1;
483 bool anyWindows
= m_filesWindow
->activeLine(file
, line
);
484 updateLineStatus(anyWindows
? line
: -1);
493 void DebuggerMainWnd::slotLineChanged()
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
505 m_filesWindow
->updateLineItems(m_debugger
);
508 void DebuggerMainWnd::updateLineStatus(int lineNo
)
511 statusBar()->changeItem("", ID_STATUS_LINENO
);
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
);
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
))
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
)
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()
578 bool DebuggerMainWnd::debugProgram(const QString
& exe
, QCString lang
)
580 // check the file name
583 bool success
= fi
.isFile();
586 QString msg
= i18n("`%1' is not a file or does not exist");
587 KMessageBox::sorry(this, msg
.arg(exe
));
591 success
= DebuggerMainWndBase::debugProgram(fi
.absFilePath(), lang
, this);
596 m_recentExecAction
->addURL(KURL(fi
.absFilePath()));
598 // keep the directory
599 m_lastDirectory
= fi
.dirPath(true);
600 m_filesWindow
->setExtraDirectory(m_lastDirectory
);
604 m_recentExecAction
->removeURL(KURL(fi
.absFilePath()));
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()));
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());
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()
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");
709 * Pop up the context menu in the locals window
711 void DebuggerMainWnd::slotLocalsPopup(int, const QPoint
& pt
)
714 static_cast<QPopupMenu
*>(factory()->container("popup_locals", this));
718 if (popup
->isVisible()) {
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
)
742 static_cast<QPopupMenu
*>(factory()->container("popup_files", this));
746 if (popup
->isVisible()) {
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
)
759 static_cast<QPopupMenu
*>(factory()->container("popup_files_empty", this));
763 if (popup
->isVisible()) {
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"),
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();
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())
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())
836 void DebuggerMainWnd::slotViewStatusbar()
838 if (statusBar()->isVisible())
844 void DebuggerMainWnd::slotExecUntil()
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());
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"