KDbg 2.5.5.
[kdbg.git] / kdbg / winstack.cpp
blobbffd45ccc3733bc7a310f597a09f8adc6b969edc
1 /*
2 * Copyright Johannes Sixt
3 * This file is licensed under the GNU General Public License Version 2.
4 * See the file COPYING in the toplevel directory of the source directory.
5 */
7 #include "winstack.h"
8 #include "sourcewnd.h"
9 #include "dbgdriver.h"
10 #include <QFileInfo>
11 #include <QMenu>
12 #include <QContextMenuEvent>
13 #include <QToolTip>
14 #include <kglobal.h>
15 #include <kxmlguiwindow.h>
16 #include <kxmlguifactory.h>
17 #include <klocale.h> /* i18n */
18 #include "mydebug.h"
22 WinStack::WinStack(QWidget* parent) :
23 KTabWidget(parent),
24 m_pcLine(-1),
25 m_tabWidth(0)
27 connect(&m_findDlg.m_buttonForward,
28 SIGNAL(clicked()), SLOT(slotFindForward()));
29 connect(&m_findDlg.m_buttonBackward,
30 SIGNAL(clicked()), SLOT(slotFindBackward()));
32 connect(this, SIGNAL(setTabWidth(int)), this, SLOT(slotSetTabWidth(int)));
35 WinStack::~WinStack()
39 void WinStack::contextMenuEvent(QContextMenuEvent* e)
41 // get the context menu from the GUI factory
42 QWidget* top = this;
44 top = top->parentWidget();
45 while (!top->isTopLevel());
46 KXmlGuiWindow* mw = static_cast<KXmlGuiWindow*>(top);
47 QMenu* m =
48 static_cast<QMenu*>(mw->factory()->container("popup_files_empty", mw));
49 m->exec(e->globalPos());
53 void WinStack::reloadAllFiles()
55 for (int i = count()-1; i >= 0; i--) {
56 windowAt(i)->reloadFile();
60 QSize WinStack::sizeHint() const
62 return QSize(640, 480);
65 void WinStack::activate(const QString& fileName, int lineNo, const DbgAddr& address)
67 QFileInfo fi(fileName);
69 if (!fi.isFile()) {
71 * We didn't find that file. Now check if it is a relative path and
72 * try m_lastOpenDir as prefix.
74 TRACE(fi.filePath() + (" not found, looking in " + m_lastOpenDir));
75 if (!fi.isRelative() || m_lastOpenDir.isEmpty()) {
76 return;
78 fi.setFile(m_lastOpenDir + "/" + fi.filePath());
79 if (!fi.isFile()) {
80 return;
83 // if this is not an absolute path name, make it one
84 activatePath(fi.absoluteFilePath(), lineNo, address);
87 void WinStack::activateFile(const QString& fileName)
89 activatePath(fileName, 0, DbgAddr());
92 bool WinStack::activatePath(QString pathName, int lineNo, const DbgAddr& address)
94 // check whether the file is already open
95 SourceWindow* fw = 0;
96 for (int i = count()-1; i >= 0; i--) {
97 if (windowAt(i)->fileName() == pathName) {
98 fw = windowAt(i);
99 break;
102 if (fw == 0) {
103 // not found, load it
104 fw = new SourceWindow(pathName, this);
106 // slurp the file in
107 if (!fw->loadFile()) {
108 // read failed
109 delete fw;
110 return false;
113 int idx = addTab(fw, QFileInfo(pathName).fileName());
114 setTabToolTip(idx, pathName);
116 connect(fw, SIGNAL(clickedLeft(const QString&,int,const DbgAddr&,bool)),
117 SIGNAL(toggleBreak(const QString&,int,const DbgAddr&,bool)));
118 connect(fw, SIGNAL(clickedMid(const QString&,int,const DbgAddr&)),
119 SIGNAL(enadisBreak(const QString&,int,const DbgAddr&)));
121 // disassemble code
122 connect(fw, SIGNAL(disassemble(const QString&, int)),
123 SIGNAL(disassemble(const QString&, int)));
124 connect(fw, SIGNAL(expanded(int)), SLOT(slotExpandCollapse(int)));
125 connect(fw, SIGNAL(collapsed(int)), SLOT(slotExpandCollapse(int)));
127 // tab width
128 connect(this, SIGNAL(setTabWidth(int)), fw, SLOT(setTabWidth(int)));
129 fw->setTabWidth(m_tabWidth);
130 fw->setFocusPolicy(Qt::WheelFocus);
132 // set PC if there is one
133 emit newFileLoaded();
134 if (m_pcLine >= 0) {
135 setPC(true, m_pcFile, m_pcLine, DbgAddr(m_pcAddress), m_pcFrame);
138 return activateWindow(fw, lineNo, address);
141 bool WinStack::activateWindow(SourceWindow* fw, int lineNo, const DbgAddr& address)
143 // make the line visible
144 if (lineNo >= 0) {
145 fw->scrollTo(lineNo, address);
148 setCurrentWidget(fw);
149 fw->setFocus();
151 return true;
154 bool WinStack::activeLine(QString& fileName, int& lineNo)
156 DbgAddr dummy;
157 return activeLine(fileName, lineNo, dummy);
160 bool WinStack::activeLine(QString& fileName, int& lineNo, DbgAddr& address)
162 if (activeWindow() == 0) {
163 return false;
166 fileName = activeFileName();
167 activeWindow()->activeLine(lineNo, address);
168 return true;
171 void WinStack::updateLineItems(const KDebugger* dbg)
173 for (int i = count()-1; i >= 0; i--) {
174 windowAt(i)->updateLineItems(dbg);
178 void WinStack::updatePC(const QString& fileName, int lineNo, const DbgAddr& address, int frameNo)
180 if (m_pcLine >= 0) {
181 setPC(false, m_pcFile, m_pcLine, DbgAddr(m_pcAddress), m_pcFrame);
183 m_pcFile = fileName;
184 m_pcLine = lineNo;
185 m_pcAddress = address.asString();
186 m_pcFrame = frameNo;
187 if (lineNo >= 0) {
188 setPC(true, fileName, lineNo, address, frameNo);
192 SourceWindow* WinStack::findByFileName(const QString& fileName) const
194 for (int i = count()-1; i >= 0; i--) {
195 if (windowAt(i)->fileNameMatches(fileName)) {
196 return windowAt(i);
199 return 0;
202 void WinStack::setPC(bool set, const QString& fileName, int lineNo,
203 const DbgAddr& address, int frameNo)
205 TRACE((set ? "set PC: " : "clear PC: ") + fileName +
206 QString().sprintf(":%d#%d ", lineNo, frameNo) + address.asString());
207 SourceWindow* fw = findByFileName(fileName);
208 if (fw)
209 fw->setPC(set, lineNo, address, frameNo);
212 SourceWindow* WinStack::windowAt(int i) const
214 return static_cast<SourceWindow*>(widget(i));
217 SourceWindow* WinStack::activeWindow() const
219 return static_cast<SourceWindow*>(currentWidget());
222 QString WinStack::activeFileName() const
224 QString f;
225 if (activeWindow() != 0)
226 f = activeWindow()->fileName();
227 return f;
230 void WinStack::slotFindForward()
232 if (activeWindow() != 0)
233 activeWindow()->find(m_findDlg.searchText(), m_findDlg.caseSensitive(),
234 SourceWindow::findForward);
237 void WinStack::slotFindBackward()
239 if (activeWindow() != 0)
240 activeWindow()->find(m_findDlg.searchText(), m_findDlg.caseSensitive(),
241 SourceWindow::findBackward);
244 bool WinStack::event(QEvent* evt)
246 if (evt->type() != QEvent::ToolTip)
247 return KTabWidget::event(evt);
249 SourceWindow* w = activeWindow();
250 if (w == 0)
251 return true;
253 QPoint p = static_cast<QHelpEvent*>(evt)->globalPos();
254 // get the word at the point
255 QString word;
256 QRect r;
257 if (!w->wordAtPoint(w->mapFromGlobal(p), word, r)) {
258 QToolTip::hideText();
259 return true;
262 // must be valid
263 assert(!word.isEmpty());
264 assert(r.isValid());
266 // remember the location
267 m_tipLocation = p;
268 m_tipRegion = QRect(w->mapTo(this, r.topLeft()), r.size());
270 emit initiateValuePopup(word);
271 return true;
274 void WinStack::slotShowValueTip(const QString& tipText)
276 QToolTip::showText(m_tipLocation, tipText, this, m_tipRegion);
279 void WinStack::slotDisassembled(const QString& fileName, int lineNo,
280 const std::list<DisassembledCode>& disass)
282 SourceWindow* fw = findByFileName(fileName);
283 if (fw == 0) {
284 // not found: ignore
285 return;
288 fw->disassembled(lineNo, disass);
291 void WinStack::slotExpandCollapse(int)
293 // update line items after expanding or collapsing disassembled code
295 // HACK: we know that this will result in updateLineItems
296 // should be done more cleanly with a separate signal
297 emit newFileLoaded();
299 if (m_pcLine >= 0) {
300 setPC(true, m_pcFile, m_pcLine, DbgAddr(m_pcAddress), m_pcFrame);
305 void WinStack::slotSetTabWidth(int numChars)
307 m_tabWidth = numChars;
310 void WinStack::slotFileReload()
312 if (activeWindow() != 0) {
313 TRACE("reloading one file");
314 activeWindow()->reloadFile();
318 void WinStack::slotViewFind()
320 if (m_findDlg.isVisible()) {
321 m_findDlg.done(0);
322 } else {
323 m_findDlg.show();
327 void WinStack::slotBrkptSet()
329 QString file;
330 int lineNo;
331 DbgAddr address;
332 if (activeLine(file, lineNo, address))
333 emit toggleBreak(file, lineNo, address, false);
336 void WinStack::slotBrkptSetTemp()
338 QString file;
339 int lineNo;
340 DbgAddr address;
341 if (activeLine(file, lineNo, address))
342 emit toggleBreak(file, lineNo, address, true);
345 void WinStack::slotBrkptEnable()
347 QString file;
348 int lineNo;
349 DbgAddr address;
350 if (activeLine(file, lineNo, address))
351 emit enadisBreak(file, lineNo, address);
354 void WinStack::slotMoveProgramCounter()
356 QString file;
357 int lineNo;
358 DbgAddr address;
359 if (activeLine(file, lineNo, address))
360 emit moveProgramCounter(file, lineNo, address);
363 void WinStack::slotClose()
365 QWidget* w = activeWindow();
366 if (!w)
367 return;
369 removePage(w);
370 delete w;
374 FindDialog::FindDialog() :
375 QDialog(),
376 m_searchText(this),
377 m_caseCheck(this),
378 m_buttonForward(this),
379 m_buttonBackward(this),
380 m_buttonClose(this)
382 setWindowTitle(KGlobal::caption() + i18n(": Search"));
384 m_searchText.setMinimumSize(330, 24);
385 m_searchText.setMaxLength(10000);
386 m_searchText.setFrame(true);
387 m_searchText.setFocus();
389 m_caseCheck.setText(i18n("&Case sensitive"));
390 m_caseCheck.setChecked(true);
391 m_buttonForward.setText(i18n("&Forward"));
392 m_buttonForward.setDefault(true);
393 m_buttonBackward.setText(i18n("&Backward"));
394 m_buttonClose.setText(i18n("Close"));
396 connect(&m_buttonClose, SIGNAL(clicked()), SLOT(reject()));
398 m_layout.addWidget(&m_searchText);
399 m_layout.addWidget(&m_caseCheck);
400 m_layout.addLayout(&m_buttons);
402 m_buttons.addWidget(&m_buttonForward);
403 m_buttons.addWidget(&m_buttonBackward);
404 m_buttons.addWidget(&m_buttonClose);
406 setLayout(&m_layout);
409 FindDialog::~FindDialog()
413 void FindDialog::closeEvent(QCloseEvent* ev)
415 QDialog::closeEvent(ev);
416 emit closed();
419 void FindDialog::done(int result)
421 QDialog::done(result);
422 emit closed();
425 #include "winstack.moc"