Refine "View Code" command.
[kdbg.git] / kdbg / winstack.cpp
blobdde80e9d3db30cb74addeec3d85c48ce9b0dbc67
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 <qbrush.h>
10 #include <qfileinfo.h>
11 #include <qpopupmenu.h>
12 #include <kapplication.h>
13 #include <kmainwindow.h>
14 #include <klocale.h> /* i18n */
15 #ifdef HAVE_CONFIG_H
16 #include "config.h"
17 #endif
18 #include "mydebug.h"
22 WinStack::WinStack(QWidget* parent, const char* name) :
23 KTabWidget(parent, name),
24 m_pcLine(-1),
25 m_valueTip(this),
26 m_tipLocation(1,1,10,10),
27 m_tabWidth(0)
29 connect(&m_findDlg.m_buttonForward,
30 SIGNAL(clicked()), SLOT(slotFindForward()));
31 connect(&m_findDlg.m_buttonBackward,
32 SIGNAL(clicked()), SLOT(slotFindBackward()));
34 connect(this, SIGNAL(setTabWidth(int)), this, SLOT(slotSetTabWidth(int)));
37 WinStack::~WinStack()
41 void WinStack::contextMenuEvent(QContextMenuEvent* e)
43 // get the context menu from the GUI factory
44 QWidget* top = this;
46 top = top->parentWidget();
47 while (!top->isTopLevel());
48 KMainWindow* mw = static_cast<KMainWindow*>(top);
49 QPopupMenu* m =
50 static_cast<QPopupMenu*>(mw->factory()->container("popup_files_empty", mw));
51 m->exec(e->globalPos());
55 void WinStack::reloadAllFiles()
57 for (int i = count()-1; i >= 0; i--) {
58 windowAt(i)->reloadFile();
62 QSize WinStack::sizeHint() const
64 return QSize(640, 480);
67 void WinStack::activate(const QString& fileName, int lineNo, const DbgAddr& address)
69 QFileInfo fi(fileName);
71 if (!fi.isFile()) {
73 * We didn't find that file. Now check if it is a relative path and
74 * try m_lastOpenDir as prefix.
76 TRACE(fi.filePath() + (" not found, looking in " + m_lastOpenDir));
77 if (!fi.isRelative() || m_lastOpenDir.isEmpty()) {
78 return;
80 fi.setFile(m_lastOpenDir + "/" + fi.filePath());
81 if (!fi.isFile()) {
82 return;
85 // if this is not an absolute path name, make it one
86 activatePath(fi.absFilePath(), lineNo, address);
89 void WinStack::activateFile(const QString& fileName)
91 activatePath(fileName, 0, DbgAddr());
94 bool WinStack::activatePath(QString pathName, int lineNo, const DbgAddr& address)
96 // check whether the file is already open
97 SourceWindow* fw = 0;
98 for (int i = count()-1; i >= 0; i--) {
99 if (windowAt(i)->fileName() == pathName) {
100 fw = windowAt(i);
101 break;
104 if (fw == 0) {
105 // not found, load it
106 fw = new SourceWindow(pathName, this, "fileWindow");
108 // slurp the file in
109 if (!fw->loadFile()) {
110 // read failed
111 delete fw;
112 return false;
115 addTab(fw, QFileInfo(pathName).fileName());
116 setTabToolTip(fw, pathName);
118 connect(fw, SIGNAL(clickedLeft(const QString&,int,const DbgAddr&,bool)),
119 SIGNAL(toggleBreak(const QString&,int,const DbgAddr&,bool)));
120 connect(fw, SIGNAL(clickedMid(const QString&,int,const DbgAddr&)),
121 SIGNAL(enadisBreak(const QString&,int,const DbgAddr&)));
123 // disassemble code
124 connect(fw, SIGNAL(disassemble(const QString&, int)),
125 SIGNAL(disassemble(const QString&, int)));
126 connect(fw, SIGNAL(expanded(int)), SLOT(slotExpandCollapse(int)));
127 connect(fw, SIGNAL(collapsed(int)), SLOT(slotExpandCollapse(int)));
129 // tab width
130 connect(this, SIGNAL(setTabWidth(int)), fw, SLOT(setTabWidth(int)));
131 fw->setTabWidth(m_tabWidth);
132 fw->setFocusPolicy(QWidget::WheelFocus);
134 // set PC if there is one
135 emit newFileLoaded();
136 if (m_pcLine >= 0) {
137 setPC(true, m_pcFile, m_pcLine, DbgAddr(m_pcAddress), m_pcFrame);
140 return activateWindow(fw, lineNo, address);
143 bool WinStack::activateWindow(SourceWindow* fw, int lineNo, const DbgAddr& address)
145 // make the line visible
146 if (lineNo >= 0) {
147 fw->scrollTo(lineNo, address);
150 showPage(fw);
151 fw->setFocus();
153 return true;
156 bool WinStack::activeLine(QString& fileName, int& lineNo)
158 DbgAddr dummy;
159 return activeLine(fileName, lineNo, dummy);
162 bool WinStack::activeLine(QString& fileName, int& lineNo, DbgAddr& address)
164 if (activeWindow() == 0) {
165 return false;
168 fileName = activeFileName();
169 activeWindow()->activeLine(lineNo, address);
170 return true;
173 void WinStack::updateLineItems(const KDebugger* dbg)
175 for (int i = count()-1; i >= 0; i--) {
176 windowAt(i)->updateLineItems(dbg);
180 void WinStack::updatePC(const QString& fileName, int lineNo, const DbgAddr& address, int frameNo)
182 if (m_pcLine >= 0) {
183 setPC(false, m_pcFile, m_pcLine, DbgAddr(m_pcAddress), m_pcFrame);
185 m_pcFile = fileName;
186 m_pcLine = lineNo;
187 m_pcAddress = address.asString();
188 m_pcFrame = frameNo;
189 if (lineNo >= 0) {
190 setPC(true, fileName, lineNo, address, frameNo);
194 SourceWindow* WinStack::findByFileName(const QString& fileName) const
196 for (int i = count()-1; i >= 0; i--) {
197 if (windowAt(i)->fileNameMatches(fileName)) {
198 return windowAt(i);
201 return 0;
204 void WinStack::setPC(bool set, const QString& fileName, int lineNo,
205 const DbgAddr& address, int frameNo)
207 TRACE((set ? "set PC: " : "clear PC: ") + fileName +
208 QString().sprintf(":%d#%d ", lineNo, frameNo) + address.asString());
209 SourceWindow* fw = findByFileName(fileName);
210 if (fw)
211 fw->setPC(set, lineNo, address, frameNo);
214 SourceWindow* WinStack::windowAt(int i) const
216 return static_cast<SourceWindow*>(page(i));
219 SourceWindow* WinStack::activeWindow() const
221 return static_cast<SourceWindow*>(currentPage());
224 QString WinStack::activeFileName() const
226 QString f;
227 if (activeWindow() != 0)
228 f = activeWindow()->fileName();
229 return f;
232 void WinStack::slotFindForward()
234 if (activeWindow() != 0)
235 activeWindow()->find(m_findDlg.searchText(), m_findDlg.caseSensitive(),
236 SourceWindow::findForward);
239 void WinStack::slotFindBackward()
241 if (activeWindow() != 0)
242 activeWindow()->find(m_findDlg.searchText(), m_findDlg.caseSensitive(),
243 SourceWindow::findBackward);
246 void WinStack::maybeTip(const QPoint& p)
248 SourceWindow* w = activeWindow();
249 if (w == 0)
250 return;
252 // get the word at the point
253 QString word;
254 QRect r;
255 if (!w->wordAtPoint(w->mapFrom(this, p), word, r))
256 return;
258 // must be valid
259 assert(!word.isEmpty());
260 assert(r.isValid());
262 // remember the location
263 m_tipLocation = QRect(w->mapTo(this, r.topLeft()), r.size());
265 emit initiateValuePopup(word);
268 void WinStack::slotShowValueTip(const QString& tipText)
270 m_valueTip.tip(m_tipLocation, tipText);
273 void WinStack::slotDisassembled(const QString& fileName, int lineNo,
274 const std::list<DisassembledCode>& disass)
276 SourceWindow* fw = findByFileName(fileName);
277 if (fw == 0) {
278 // not found: ignore
279 return;
282 fw->disassembled(lineNo, disass);
285 void WinStack::slotExpandCollapse(int)
287 // update line items after expanding or collapsing disassembled code
289 // HACK: we know that this will result in updateLineItems
290 // should be done more cleanly with a separate signal
291 emit newFileLoaded();
293 if (m_pcLine >= 0) {
294 setPC(true, m_pcFile, m_pcLine, DbgAddr(m_pcAddress), m_pcFrame);
299 void WinStack::slotSetTabWidth(int numChars)
301 m_tabWidth = numChars;
304 void WinStack::slotFileReload()
306 if (activeWindow() != 0) {
307 TRACE("reloading one file");
308 activeWindow()->reloadFile();
312 void WinStack::slotViewFind()
314 if (m_findDlg.isVisible()) {
315 m_findDlg.done(0);
316 } else {
317 m_findDlg.show();
321 void WinStack::slotBrkptSet()
323 QString file;
324 int lineNo;
325 DbgAddr address;
326 if (activeLine(file, lineNo, address))
327 emit toggleBreak(file, lineNo, address, false);
330 void WinStack::slotBrkptSetTemp()
332 QString file;
333 int lineNo;
334 DbgAddr address;
335 if (activeLine(file, lineNo, address))
336 emit toggleBreak(file, lineNo, address, true);
339 void WinStack::slotBrkptEnable()
341 QString file;
342 int lineNo;
343 DbgAddr address;
344 if (activeLine(file, lineNo, address))
345 emit enadisBreak(file, lineNo, address);
348 void WinStack::slotMoveProgramCounter()
350 QString file;
351 int lineNo;
352 DbgAddr address;
353 if (activeLine(file, lineNo, address))
354 emit moveProgramCounter(file, lineNo, address);
357 void WinStack::slotClose()
359 QWidget* w = activeWindow();
360 if (!w)
361 return;
363 removePage(w);
364 delete w;
368 ValueTip::ValueTip(WinStack* parent) :
369 QToolTip(parent)
373 void ValueTip::maybeTip(const QPoint& p)
375 WinStack* w = static_cast<WinStack*>(parentWidget());
376 w->maybeTip(p);
380 FindDialog::FindDialog() :
381 QDialog(0, "find", false),
382 m_searchText(this, "text"),
383 m_caseCheck(this, "case"),
384 m_buttonForward(this, "forward"),
385 m_buttonBackward(this, "backward"),
386 m_buttonClose(this, "close"),
387 m_layout(this, 8),
388 m_buttons(4)
390 setCaption(QString(kapp->caption()) + i18n(": Search"));
392 m_searchText.setMinimumSize(330, 24);
393 m_searchText.setMaxLength(10000);
394 m_searchText.setFrame(true);
396 m_caseCheck.setText(i18n("&Case sensitive"));
397 m_caseCheck.setChecked(true);
398 m_buttonForward.setText(i18n("&Forward"));
399 m_buttonForward.setDefault(true);
400 m_buttonBackward.setText(i18n("&Backward"));
401 m_buttonClose.setText(i18n("Close"));
403 m_caseCheck.setMinimumSize(330, 24);
405 // get maximum size of buttons
406 QSize maxSize(80,30);
407 maxSize.expandedTo(m_buttonForward.sizeHint());
408 maxSize.expandedTo(m_buttonBackward.sizeHint());
409 maxSize.expandedTo(m_buttonClose.sizeHint());
411 m_buttonForward.setMinimumSize(maxSize);
412 m_buttonBackward.setMinimumSize(maxSize);
413 m_buttonClose.setMinimumSize(maxSize);
415 connect(&m_buttonClose, SIGNAL(clicked()), SLOT(reject()));
417 m_layout.addWidget(&m_searchText);
418 m_layout.addWidget(&m_caseCheck);
419 m_layout.addLayout(&m_buttons);
420 m_layout.addStretch(10);
421 m_buttons.addWidget(&m_buttonForward);
422 m_buttons.addStretch(10);
423 m_buttons.addWidget(&m_buttonBackward);
424 m_buttons.addStretch(10);
425 m_buttons.addWidget(&m_buttonClose);
427 m_layout.activate();
429 m_searchText.setFocus();
430 resize( 350, 120 );
433 FindDialog::~FindDialog()
437 void FindDialog::closeEvent(QCloseEvent* ev)
439 QDialog::closeEvent(ev);
440 emit closed();
443 void FindDialog::done(int result)
445 QDialog::done(result);
446 emit closed();
449 #include "winstack.moc"