Make toolbar visible again.
[kdbg.git] / kdbg / mainwndbase.cpp
blob8bc39145b7992c44cc5815df318b62f05ffa428c
1 // $Id$
3 // Copyright by Johannes Sixt
4 // This file is under GPL, the GNU General Public Licence
6 #include <kapp.h>
7 #if QT_VERSION >= 200
8 #include <klocale.h> /* i18n */
9 #include <kconfig.h>
10 #include <kmessagebox.h>
11 #else
12 #include <kmsgbox.h>
13 #include <qkeycode.h>
14 #endif
15 #include <kiconloader.h>
16 #include <kstatusbar.h>
17 #include <ktoolbar.h>
18 #include <kfiledialog.h>
19 #include <qpainter.h>
20 #include <qtabdialog.h>
21 #include <qfileinfo.h>
22 #include "mainwndbase.h"
23 #include "debugger.h"
24 #include "gdbdriver.h"
25 #include "prefdebugger.h"
26 #include "prefmisc.h"
27 #include "procattach.h"
28 #include "ttywnd.h"
29 #include "updateui.h"
30 #include "commandids.h"
31 #include "valarray.h"
32 #ifdef HAVE_CONFIG
33 #include "config.h"
34 #endif
35 #include "mydebug.h"
36 #ifdef HAVE_SYS_STAT_H
37 #include <sys/stat.h> /* mknod(2) */
38 #endif
39 #ifdef HAVE_FCNTL_H
40 #include <fcntl.h> /* open(2) */
41 #endif
42 #ifdef HAVE_UNISTD_H
43 #include <unistd.h> /* getpid, unlink etc. */
44 #endif
46 #define MAX_RECENT_FILES 4
49 KStdAccel* keys = 0;
51 WatchWindow::WatchWindow(QWidget* parent, const char* name, WFlags f) :
52 QWidget(parent, name, f),
53 m_watchEdit(this, "watch_edit"),
54 m_watchAdd(i18n(" Add "), this, "watch_add"),
55 m_watchDelete(i18n(" Del "), this, "watch_delete"),
56 m_watchVariables(this, "watch_variables"),
57 m_watchV(this, 0),
58 m_watchH(0)
60 // setup the layout
61 m_watchAdd.setMinimumSize(m_watchAdd.sizeHint());
62 m_watchDelete.setMinimumSize(m_watchDelete.sizeHint());
63 m_watchV.addLayout(&m_watchH, 0);
64 m_watchV.addWidget(&m_watchVariables, 10);
65 m_watchH.addWidget(&m_watchEdit, 10);
66 m_watchH.addWidget(&m_watchAdd, 0);
67 m_watchH.addWidget(&m_watchDelete, 0);
69 connect(&m_watchEdit, SIGNAL(returnPressed()), SIGNAL(addWatch()));
70 connect(&m_watchAdd, SIGNAL(clicked()), SIGNAL(addWatch()));
71 connect(&m_watchDelete, SIGNAL(clicked()), SIGNAL(deleteWatch()));
72 connect(&m_watchVariables, SIGNAL(highlighted(int)), SLOT(slotWatchHighlighted(int)));
74 m_watchVariables.setMoveCurrentToSibling(true);
75 m_watchVariables.installEventFilter(this);
78 WatchWindow::~WatchWindow()
82 bool WatchWindow::eventFilter(QObject*, QEvent* ev)
84 if (ev->type() ==
85 #if QT_VERSION < 200
86 Event_KeyPress
87 #else
88 QEvent::KeyPress
89 #endif
92 QKeyEvent* kev = static_cast<QKeyEvent*>(ev);
93 if (kev->key() == Key_Delete) {
94 emit deleteWatch();
95 return true;
98 return false;
102 // place the text of the hightlighted watch expr in the edit field
103 void WatchWindow::slotWatchHighlighted(int idx)
105 QString text = m_watchVariables.exprStringAt(idx);
106 m_watchEdit.setText(text);
110 static void splitCmdStr(const QString& cmd, ValArray<QString>& parts)
112 QString str = cmd.simplifyWhiteSpace();
113 int start = 0;
114 int end;
115 while ((end = str.find(' ', start)) >= 0) {
116 parts.append(str.mid(start, end-start));
117 start = end+1;
119 parts.append(str.mid(start, str.length()-start));
123 const char defaultTermCmdStr[] = "xterm -name kdbgio -title %T -e sh -c %C";
124 const char defaultSourceFilter[] = "*.c *.cc *.cpp *.c++ *.C *.CC";
125 const char defaultHeaderFilter[] = "*.h *.hh *.hpp *.h++";
128 DebuggerMainWndBase::DebuggerMainWndBase() :
129 m_animationCounter(0),
130 m_outputTermCmdStr(defaultTermCmdStr),
131 m_outputTermProc(0),
132 m_ttyLevel(-1), /* no tty yet */
133 #ifdef GDB_TRANSCRIPT
134 m_transcriptFile(GDB_TRANSCRIPT),
135 #endif
136 m_popForeground(false),
137 m_backTimeout(1000),
138 m_tabWidth(0),
139 m_sourceFilter(defaultSourceFilter),
140 m_headerFilter(defaultHeaderFilter),
141 m_debugger(0)
143 m_statusActive = i18n("active");
144 m_recentExecList.setAutoDelete(true);
147 DebuggerMainWndBase::~DebuggerMainWndBase()
149 delete m_debugger;
151 // if the output window is open, close it
152 if (m_outputTermProc != 0) {
153 m_outputTermProc->disconnect(); /* ignore signals */
154 m_outputTermProc->kill();
155 shutdownTermWindow();
159 void DebuggerMainWndBase::setupDebugger(ExprWnd* localVars,
160 ExprWnd* watchVars,
161 QListBox* backtrace)
163 QWidget* parent = dbgMainWnd();
165 GdbDriver* driver = new GdbDriver;
166 driver->setLogFileName(m_transcriptFile);
168 m_debugger = new KDebugger(parent, localVars, watchVars, backtrace, driver);
170 QObject::connect(m_debugger, SIGNAL(updateStatusMessage()),
171 parent, SLOT(slotNewStatusMsg()));
172 QObject::connect(m_debugger, SIGNAL(updateUI()),
173 parent, SLOT(updateUI()));
175 QObject::connect(m_debugger, SIGNAL(lineItemsChanged()),
176 parent, SLOT(updateLineItems()));
178 QObject::connect(m_debugger, SIGNAL(animationTimeout()),
179 parent, SLOT(slotAnimationTimeout()));
180 QObject::connect(m_debugger, SIGNAL(debuggerStarting()),
181 parent, SLOT(slotDebuggerStarting()));
183 m_debugger->setDebuggerCmd(m_debuggerCmdStr);
187 void DebuggerMainWndBase::setCoreFile(const QString& corefile)
189 assert(m_debugger != 0);
190 m_debugger->useCoreFile(corefile, true);
193 void DebuggerMainWndBase::setRemoteDevice(const QString& remoteDevice)
195 if (m_debugger != 0) {
196 m_debugger->setRemoteDevice(remoteDevice);
200 void DebuggerMainWndBase::setTranscript(const char* name)
202 m_transcriptFile = name;
203 if (m_debugger != 0)
204 m_debugger->driver()->setLogFileName(m_transcriptFile);
207 const char OutputWindowGroup[] = "OutputWindow";
208 const char TermCmdStr[] = "TermCmdStr";
209 const char KeepScript[] = "KeepScript";
210 const char DebuggerGroup[] = "Debugger";
211 const char DebuggerCmdStr[] = "DebuggerCmdStr";
212 const char PreferencesGroup[] = "Preferences";
213 const char PopForeground[] = "PopForeground";
214 const char BackTimeout[] = "BackTimeout";
215 const char TabWidth[] = "TabWidth";
216 const char FilesGroup[] = "Files";
217 const char RecentExecutables[] = "RecentExecutables";
218 const char SourceFileFilter[] = "SourceFileFilter";
219 const char HeaderFileFilter[] = "HeaderFileFilter";
221 void DebuggerMainWndBase::saveSettings(KConfig* config)
223 if (m_debugger != 0) {
224 m_debugger->saveSettings(config);
227 KConfigGroupSaver g(config, OutputWindowGroup);
228 config->writeEntry(TermCmdStr, m_outputTermCmdStr);
230 config->setGroup(DebuggerGroup);
231 config->writeEntry(DebuggerCmdStr, m_debuggerCmdStr);
233 config->setGroup(PreferencesGroup);
234 config->writeEntry(PopForeground, m_popForeground);
235 config->writeEntry(BackTimeout, m_backTimeout);
236 config->writeEntry(TabWidth, m_tabWidth);
237 config->writeEntry(SourceFileFilter, m_sourceFilter);
238 config->writeEntry(HeaderFileFilter, m_headerFilter);
240 config->setGroup(FilesGroup);
241 config->writeEntry(RecentExecutables, m_recentExecList, ',');
244 void DebuggerMainWndBase::restoreSettings(KConfig* config)
246 if (m_debugger != 0) {
247 m_debugger->restoreSettings(config);
250 KConfigGroupSaver g(config, OutputWindowGroup);
252 * For debugging and emergency purposes, let the config file override
253 * the shell script that is used to keep the output window open. This
254 * string must have EXACTLY 1 %s sequence in it.
256 setTerminalCmd(config->readEntry(TermCmdStr, defaultTermCmdStr));
257 m_outputTermKeepScript = config->readEntry(KeepScript);
259 config->setGroup(DebuggerGroup);
260 setDebuggerCmdStr(config->readEntry(DebuggerCmdStr));
262 config->setGroup(PreferencesGroup);
263 m_popForeground = config->readBoolEntry(PopForeground, false);
264 m_backTimeout = config->readNumEntry(BackTimeout, 1000);
265 m_tabWidth = config->readNumEntry(TabWidth, 0);
266 m_sourceFilter = config->readEntry(SourceFileFilter, m_sourceFilter);
267 m_headerFilter = config->readEntry(HeaderFileFilter, m_headerFilter);
269 config->setGroup(FilesGroup);
270 config->readListEntry(RecentExecutables, m_recentExecList,',');
273 bool DebuggerMainWndBase::debugProgram(const QString& executable)
275 assert(m_debugger != 0);
276 return m_debugger->debugProgram(executable);
279 // helper that gets a file name (it only differs in the caption of the dialog)
280 QString DebuggerMainWndBase::myGetFileName(QString caption,
281 QString dir, QString filter,
282 QWidget* parent)
284 QString filename;
285 KFileDialog dlg(dir, filter, parent, "filedialog", true);
287 dlg.setCaption(caption);
289 if (dlg.exec() == QDialog::Accepted)
290 filename = dlg.selectedFile();
292 return filename;
295 bool DebuggerMainWndBase::handleCommand(int item)
297 /* first commands that don't require the debugger */
298 switch (item) {
299 case ID_FILE_GLOBAL_OPTIONS:
300 doGlobalOptions();
301 return true;
304 // now commands that do
305 if (m_debugger == 0)
306 return false;
308 switch (item) {
309 case ID_FILE_EXECUTABLE:
310 if (m_debugger->isIdle())
312 // open a new executable
313 QString executable = myGetFileName(i18n("Select the executable to debug"),
314 m_lastDirectory, 0, dbgMainWnd());
315 if (executable.isEmpty())
316 return true;
318 if (debugProgramInteractive(executable)) {
319 addRecentExec(executable);
322 return true;
323 case ID_FILE_PROG_SETTINGS:
324 m_debugger->programSettings(dbgMainWnd());
325 return true;
326 case ID_FILE_COREFILE:
327 if (m_debugger->canUseCoreFile())
329 QString corefile = myGetFileName(i18n("Select core dump"),
330 m_lastDirectory, 0, dbgMainWnd());
331 if (!corefile.isEmpty()) {
332 m_debugger->useCoreFile(corefile, false);
335 return true;
336 case ID_PROGRAM_RUN:
337 m_debugger->programRun();
338 return true;
339 case ID_PROGRAM_ATTACH:
341 ProcAttach dlg(dbgMainWnd());
342 dlg.setText(m_debugger->attachedPid());
343 if (dlg.exec()) {
344 m_debugger->attachProgram(dlg.text());
347 return true;
348 case ID_PROGRAM_RUN_AGAIN:
349 m_debugger->programRunAgain();
350 return true;
351 case ID_PROGRAM_STEP:
352 m_debugger->programStep(false);
353 return true;
354 case ID_PROGRAM_STEPI:
355 m_debugger->programStep(true);
356 return true;
357 case ID_PROGRAM_NEXT:
358 m_debugger->programNext(false);
359 return true;
360 case ID_PROGRAM_NEXTI:
361 m_debugger->programNext(true);
362 return true;
363 case ID_PROGRAM_FINISH:
364 m_debugger->programFinish();
365 return true;
366 case ID_PROGRAM_KILL:
367 m_debugger->programKill();
368 return true;
369 case ID_PROGRAM_BREAK:
370 m_debugger->programBreak();
371 return true;
372 case ID_PROGRAM_ARGS:
373 m_debugger->programArgs(dbgMainWnd());
374 return true;
376 return false;
379 void DebuggerMainWndBase::updateUIItem(UpdateUI* item)
381 switch (item->id) {
382 case ID_FILE_EXECUTABLE:
383 item->enable(m_debugger->isIdle());
384 break;
385 case ID_FILE_PROG_SETTINGS:
386 item->enable(m_debugger->haveExecutable());
387 break;
388 case ID_FILE_COREFILE:
389 item->enable(m_debugger->canUseCoreFile());
390 break;
391 case ID_PROGRAM_STEP:
392 case ID_PROGRAM_STEPI:
393 case ID_PROGRAM_NEXT:
394 case ID_PROGRAM_NEXTI:
395 case ID_PROGRAM_FINISH:
396 case ID_PROGRAM_UNTIL:
397 case ID_PROGRAM_RUN_AGAIN:
398 item->enable(m_debugger->canSingleStep());
399 break;
400 case ID_PROGRAM_ATTACH:
401 case ID_PROGRAM_RUN:
402 item->enable(m_debugger->isReady());
403 break;
404 case ID_PROGRAM_KILL:
405 item->enable(m_debugger->haveExecutable() && m_debugger->isProgramActive());
406 break;
407 case ID_PROGRAM_BREAK:
408 item->enable(m_debugger->isProgramRunning());
409 break;
410 case ID_PROGRAM_ARGS:
411 item->enable(m_debugger->haveExecutable());
412 break;
415 // update statusbar
416 dbgStatusBar()->changeItem(m_debugger->isProgramActive() ?
417 static_cast<const char*>(m_statusActive) : "",
418 ID_STATUS_ACTIVE);
421 void DebuggerMainWndBase::updateLineItems()
425 void DebuggerMainWndBase::initAnimation()
427 #if QT_VERSION < 200
428 QString path = kapp->kde_datadir() + "/kfm/pics/";
429 QPixmap pixmap;
430 pixmap.load(path + "/kde1.xpm");
431 int numPix = 9;
432 #else
433 QPixmap pixmap = BarIcon("kde1");
434 int numPix = 6;
435 #endif
437 KToolBar* toolbar = dbgToolBar();
438 toolbar->insertButton(pixmap, ID_STATUS_BUSY);
439 toolbar->alignItemRight(ID_STATUS_BUSY, true);
441 // Load animated logo
442 m_animation.setAutoDelete(true);
443 QString n;
444 for (int i = 1; i <= numPix; i++) {
445 #if QT_VERSION < 200
446 n.sprintf("/kde%d.xpm", i);
447 QPixmap* p = new QPixmap();
448 p->load(path + n);
449 #else
450 n.sprintf("kde%d", i);
451 QPixmap* p = new QPixmap(BarIcon(n));
452 #endif
453 if (!p->isNull()) {
454 m_animation.append(p);
455 } else {
456 delete p;
459 // safeguard: if we did not find a single icon, add a dummy
460 if (m_animation.count() == 0) {
461 QPixmap* pix = new QPixmap(2,2);
462 QPainter p(pix);
463 #if QT_VERSION < 200
464 p.fillRect(0,0,2,2,QBrush(white));
465 #else
466 p.fillRect(0,0,2,2,QBrush(Qt::white));
467 #endif
468 m_animation.append(pix);
472 void DebuggerMainWndBase::slotAnimationTimeout()
474 assert(m_animation.count() > 0); /* must have been initialized */
475 m_animationCounter++;
476 if (m_animationCounter == m_animation.count())
477 m_animationCounter = 0;
478 dbgToolBar()->setButtonPixmap(ID_STATUS_BUSY,
479 *m_animation.at(m_animationCounter));
482 void DebuggerMainWndBase::slotNewStatusMsg()
484 QString msg = m_debugger->statusMessage();
485 dbgStatusBar()->changeItem(msg, ID_STATUS_MSG);
488 void DebuggerMainWndBase::doGlobalOptions()
490 QTabDialog dlg(dbgMainWnd(), "global_options", true);
491 QString title = kapp->getCaption();
492 title += i18n(": Global options");
493 dlg.setCaption(title);
494 dlg.setCancelButton(i18n("Cancel"));
495 dlg.setOKButton(i18n("OK"));
497 PrefDebugger prefDebugger(&dlg);
498 prefDebugger.setDebuggerCmd(m_debuggerCmdStr.isEmpty() ?
499 GdbDriver::defaultGdb() : m_debuggerCmdStr);
500 prefDebugger.setTerminal(m_outputTermCmdStr);
502 PrefMisc prefMisc(&dlg);
503 prefMisc.setPopIntoForeground(m_popForeground);
504 prefMisc.setBackTimeout(m_backTimeout);
505 prefMisc.setTabWidth(m_tabWidth);
506 prefMisc.setSourceFilter(m_sourceFilter);
507 prefMisc.setHeaderFilter(m_headerFilter);
509 dlg.addTab(&prefDebugger, i18n("&Debugger"));
510 dlg.addTab(&prefMisc, i18n("&Miscellaneous"));
511 if (dlg.exec() == QDialog::Accepted)
513 setDebuggerCmdStr(prefDebugger.debuggerCmd());
514 setTerminalCmd(prefDebugger.terminal());
515 m_popForeground = prefMisc.popIntoForeground();
516 m_backTimeout = prefMisc.backTimeout();
517 m_tabWidth = prefMisc.tabWidth();
518 m_sourceFilter = prefMisc.sourceFilter();
519 if (m_sourceFilter.isEmpty())
520 m_sourceFilter = defaultSourceFilter;
521 m_headerFilter = prefMisc.headerFilter();
522 if (m_headerFilter.isEmpty())
523 m_headerFilter = defaultHeaderFilter;
527 const char fifoNameBase[] = "/tmp/kdbgttywin%05d";
530 * We use the scope operator :: in this function, so that we don't
531 * accidentally use the wrong close() function (I've been bitten ;-),
532 * outch!) (We use it for all the libc functions, to be consistent...)
534 QString DebuggerMainWndBase::createOutputWindow()
536 // create a name for a fifo
537 QString fifoName;
538 fifoName.sprintf(fifoNameBase, ::getpid());
540 // create a fifo that will pass in the tty name
541 ::unlink(fifoName); /* remove remnants */
542 #ifdef HAVE_MKFIFO
543 if (::mkfifo(fifoName, S_IRUSR|S_IWUSR) < 0) {
544 // failed
545 TRACE("mkfifo " + fifoName + " failed");
546 return QString();
548 #else
549 if (::mknod(fifoName, S_IFIFO | S_IRUSR|S_IWUSR, 0) < 0) {
550 // failed
551 TRACE("mknod " + fifoName + " failed");
552 return QString();
554 #endif
556 m_outputTermProc = new KProcess;
560 * Spawn an xterm that in turn runs a shell script that passes us
561 * back the terminal name and then only sits and waits.
563 static const char shellScriptFmt[] =
564 "tty>%s;"
565 "trap \"\" INT QUIT TSTP;" /* ignore various signals */
566 "exec<&-;exec>&-;" /* close stdin and stdout */
567 "while :;do sleep 3600;done";
568 // let config file override this script
569 const char* fmt = shellScriptFmt;
570 if (m_outputTermKeepScript.length() != 0) {
571 fmt = m_outputTermKeepScript.data();
573 #if QT_VERSION < 200
574 QString shellScript(strlen(fmt) + fifoName.length());
575 #else
576 QString shellScript;
577 #endif
578 shellScript.sprintf(fmt, fifoName.data());
579 TRACE("output window script is " + shellScript);
581 QString title = kapp->getCaption();
582 title += i18n(": Program output");
584 // parse the command line specified in the preferences
585 ValArray<QString> cmdParts;
586 splitCmdStr(m_outputTermCmdStr, cmdParts);
589 * Build the argv array. Thereby substitute special sequences:
591 struct {
592 char seq[4];
593 QString replace;
594 } substitute[] = {
595 { "%T", title },
596 { "%C", shellScript }
599 for (int i = 0; i < cmdParts.size(); i++) {
600 QString& str = cmdParts[i];
601 for (int j = sizeof(substitute)/sizeof(substitute[0])-1; j >= 0; j--) {
602 int pos = str.find(substitute[j].seq);
603 if (pos >= 0) {
604 str.replace(pos, 2, substitute[j].replace);
605 break; /* substitute only one sequence */
608 *m_outputTermProc << str;
613 if (m_outputTermProc->start())
615 // read the ttyname from the fifo
616 int f = ::open(fifoName, O_RDONLY);
617 if (f < 0) {
618 // error
619 ::unlink(fifoName);
620 return QString();
623 char ttyname[50];
624 int n = ::read(f, ttyname, sizeof(ttyname)-sizeof(char)); /* leave space for '\0' */
626 ::close(f);
627 ::unlink(fifoName);
629 if (n < 0) {
630 // error
631 return QString();
634 // remove whitespace
635 ttyname[n] = '\0';
636 QString tty = QString(ttyname).stripWhiteSpace();
637 TRACE("tty=" + tty);
638 return tty;
640 else
642 // error, could not start xterm
643 TRACE("fork failed for fifo " + fifoName);
644 ::unlink(fifoName);
645 shutdownTermWindow();
646 return QString();
650 void DebuggerMainWndBase::shutdownTermWindow()
652 delete m_outputTermProc;
653 m_outputTermProc = 0;
656 void DebuggerMainWndBase::setTerminalCmd(const QString& cmd)
658 m_outputTermCmdStr = cmd;
659 // revert to default if empty
660 if (m_outputTermCmdStr.isEmpty()) {
661 m_outputTermCmdStr = defaultTermCmdStr;
665 void DebuggerMainWndBase::slotDebuggerStarting()
667 if (m_debugger == 0) /* paranoia check */
668 return;
670 if (m_ttyLevel == m_debugger->ttyLevel())
673 else
675 // shut down terminal emulations we will not need
676 switch (m_ttyLevel) {
677 case KDebugger::ttySimpleOutputOnly:
678 ttyWindow()->deactivate();
679 break;
680 case KDebugger::ttyFull:
681 if (m_outputTermProc != 0) {
682 m_outputTermProc->kill();
683 // will be deleted in slot
685 break;
686 default: break;
689 m_ttyLevel = m_debugger->ttyLevel();
691 QString ttyName;
692 switch (m_ttyLevel) {
693 case KDebugger::ttySimpleOutputOnly:
694 ttyName = ttyWindow()->activate();
695 break;
696 case KDebugger::ttyFull:
697 if (m_outputTermProc == 0) {
698 // create an output window
699 ttyName = createOutputWindow();
700 TRACE(ttyName.isEmpty() ?
701 "createOuputWindow failed" : "successfully created output window");
703 break;
704 default: break;
707 m_debugger->setTerminal(ttyName);
711 void DebuggerMainWndBase::setDebuggerCmdStr(const QString& cmd)
713 m_debuggerCmdStr = cmd;
714 // make empty if it is the default
715 if (m_debuggerCmdStr == GdbDriver::defaultGdb()) {
716 m_debuggerCmdStr = QString();
718 if (m_debugger != 0) {
719 m_debugger->setDebuggerCmd(m_debuggerCmdStr);
723 void DebuggerMainWndBase::addRecentExec(const QString& executable)
725 int pos = m_recentExecList.find(executable);
726 if (pos != 0) {
727 // move to top
728 if (pos > 0)
729 m_recentExecList.remove(pos);
730 // else entry is new
732 // insert on top
733 m_recentExecList.insert(0, executable);
734 } // else pos == 0, which means we dont need to change the list
736 // shorten list
737 while (m_recentExecList.count() > MAX_RECENT_FILES) {
738 m_recentExecList.remove(MAX_RECENT_FILES);
742 void DebuggerMainWndBase::removeRecentExec(const QString& executable)
744 int pos = m_recentExecList.find(executable);
745 if (pos >= 0) {
746 m_recentExecList.remove(pos);
750 bool DebuggerMainWndBase::debugProgramInteractive(const QString& executable)
752 // check the file name
753 QFileInfo fi(executable);
754 m_lastDirectory = fi.dirPath(true);
756 if (!fi.isFile()) {
757 QString msgFmt = i18n("`%s' is not a file or does not exist");
758 SIZED_QString(msg, msgFmt.length() + executable.length() + 20);
759 #if QT_VERSION < 200
760 msg.sprintf(msgFmt, executable.data());
761 KMsgBox::message(dbgMainWnd(), kapp->appName(),
762 msg,
763 KMsgBox::STOP,
764 i18n("OK"));
765 #else
766 msg.sprintf(msgFmt, executable.latin1());
767 KMessageBox::sorry(dbgMainWnd(), msg);
768 #endif
769 return false;
772 if (!m_debugger->debugProgram(executable)) {
773 QString msg = i18n("Could not start the debugger process.\n"
774 "Please shut down KDbg and resolve the problem.");
775 #if QT_VERSION < 200
776 KMsgBox::message(dbgMainWnd(), kapp->appName(),
777 msg,
778 KMsgBox::STOP,
779 i18n("OK"));
780 #else
781 KMessageBox::sorry(dbgMainWnd(), msg);
782 #endif
784 return true;
788 #include "mainwndbase.moc"