Factor a loop into findByFileName().
[kdbg.git] / kdbg / winstack.cpp
blobbe20761b4fb1b0374b83f8fad349cde49f28c049
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 = 0; i < m_fileList.size(); i++) {
58 m_fileList[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 = 0; i < m_fileList.size(); i++) {
99 if (m_fileList[i]->fileName() == pathName) {
100 fw = m_fileList[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 m_fileList.insertAt(0, fw);
117 connect(fw, SIGNAL(clickedLeft(const QString&,int,const DbgAddr&,bool)),
118 SIGNAL(toggleBreak(const QString&,int,const DbgAddr&,bool)));
119 connect(fw, SIGNAL(clickedMid(const QString&,int,const DbgAddr&)),
120 SIGNAL(enadisBreak(const QString&,int,const DbgAddr&)));
122 // disassemble code
123 connect(fw, SIGNAL(disassemble(const QString&, int)),
124 SIGNAL(disassemble(const QString&, int)));
125 connect(fw, SIGNAL(expanded(int)), SLOT(slotExpandCollapse(int)));
126 connect(fw, SIGNAL(collapsed(int)), SLOT(slotExpandCollapse(int)));
128 // tab width
129 connect(this, SIGNAL(setTabWidth(int)), fw, SLOT(setTabWidth(int)));
130 fw->setTabWidth(m_tabWidth);
131 fw->setFocusPolicy(QWidget::WheelFocus);
133 // set PC if there is one
134 emit newFileLoaded();
135 if (m_pcLine >= 0) {
136 setPC(true, m_pcFile, m_pcLine, DbgAddr(m_pcAddress), m_pcFrame);
139 return activateWindow(fw, lineNo, address);
142 bool WinStack::activateWindow(SourceWindow* fw, int lineNo, const DbgAddr& address)
144 // lookup fw
145 int index = m_fileList.size()-1;
146 while (index >= 0 && m_fileList[index] != fw)
147 --index;
148 ASSERT(index >= 0);
149 if (index < 0) {
150 return false;
153 * If the file is not in the list of those that would appear in the
154 * window menu, move it to the first position.
156 if (index >= 9) {
157 m_fileList.removeAt(index);
158 m_fileList.insertAt(0, fw);
161 // make the line visible
162 if (lineNo >= 0) {
163 fw->scrollTo(lineNo, address);
166 showPage(fw);
167 fw->setFocus();
169 emit fileChanged();
171 return true;
174 bool WinStack::activeLine(QString& fileName, int& lineNo)
176 DbgAddr dummy;
177 return activeLine(fileName, lineNo, dummy);
180 bool WinStack::activeLine(QString& fileName, int& lineNo, DbgAddr& address)
182 if (activeWindow() == 0) {
183 return false;
186 fileName = activeFileName();
187 activeWindow()->activeLine(lineNo, address);
188 return true;
191 void WinStack::updateLineItems(const KDebugger* dbg)
193 for (int i = 0; i < m_fileList.size(); i++) {
194 m_fileList[i]->updateLineItems(dbg);
198 void WinStack::updatePC(const QString& fileName, int lineNo, const DbgAddr& address, int frameNo)
200 if (m_pcLine >= 0) {
201 setPC(false, m_pcFile, m_pcLine, DbgAddr(m_pcAddress), m_pcFrame);
203 m_pcFile = fileName;
204 m_pcLine = lineNo;
205 m_pcAddress = address.asString();
206 m_pcFrame = frameNo;
207 if (lineNo >= 0) {
208 setPC(true, fileName, lineNo, address, frameNo);
212 SourceWindow* WinStack::findByFileName(const QString& fileName) const
214 for (int i = 0; i < m_fileList.size(); i++) {
215 if (m_fileList[i]->fileNameMatches(fileName)) {
216 return m_fileList[i];
219 return 0;
222 void WinStack::setPC(bool set, const QString& fileName, int lineNo,
223 const DbgAddr& address, int frameNo)
225 TRACE((set ? "set PC: " : "clear PC: ") + fileName +
226 QString().sprintf(":%d#%d ", lineNo, frameNo) + address.asString());
227 SourceWindow* fw = findByFileName(fileName);
228 if (fw)
229 fw->setPC(set, lineNo, address, frameNo);
232 SourceWindow* WinStack::activeWindow() const
234 return static_cast<SourceWindow*>(currentPage());
237 QString WinStack::activeFileName() const
239 QString f;
240 if (activeWindow() != 0)
241 f = activeWindow()->fileName();
242 return f;
245 void WinStack::slotFindForward()
247 if (activeWindow() != 0)
248 activeWindow()->find(m_findDlg.searchText(), m_findDlg.caseSensitive(),
249 SourceWindow::findForward);
252 void WinStack::slotFindBackward()
254 if (activeWindow() != 0)
255 activeWindow()->find(m_findDlg.searchText(), m_findDlg.caseSensitive(),
256 SourceWindow::findBackward);
259 void WinStack::maybeTip(const QPoint& p)
261 if (activeWindow() == 0)
262 return;
264 // get the word at the point
265 QString word;
266 QRect r;
267 if (!activeWindow()->wordAtPoint(p, word, r))
268 return;
270 // must be valid
271 assert(!word.isEmpty());
272 assert(r.isValid());
274 // remember the location
275 m_tipLocation = r;
277 emit initiateValuePopup(word);
280 void WinStack::slotShowValueTip(const QString& tipText)
282 m_valueTip.tip(m_tipLocation, tipText);
285 void WinStack::slotDisassembled(const QString& fileName, int lineNo,
286 const QList<DisassembledCode>& disass)
288 SourceWindow* fw = findByFileName(fileName);
289 if (fw == 0) {
290 // not found: ignore
291 return;
294 fw->disassembled(lineNo, disass);
297 void WinStack::slotExpandCollapse(int)
299 // update line items after expanding or collapsing disassembled code
301 // HACK: we know that this will result in updateLineItems
302 // should be done more cleanly with a separate signal
303 emit newFileLoaded();
305 if (m_pcLine >= 0) {
306 setPC(true, m_pcFile, m_pcLine, DbgAddr(m_pcAddress), m_pcFrame);
311 void WinStack::slotSetTabWidth(int numChars)
313 m_tabWidth = numChars;
316 void WinStack::slotFileReload()
318 if (activeWindow() != 0) {
319 TRACE("reloading one file");
320 activeWindow()->reloadFile();
324 void WinStack::slotViewFind()
326 if (m_findDlg.isVisible()) {
327 m_findDlg.done(0);
328 } else {
329 m_findDlg.show();
333 void WinStack::slotBrkptSet()
335 QString file;
336 int lineNo;
337 DbgAddr address;
338 if (activeLine(file, lineNo, address))
339 emit toggleBreak(file, lineNo, address, false);
342 void WinStack::slotBrkptSetTemp()
344 QString file;
345 int lineNo;
346 DbgAddr address;
347 if (activeLine(file, lineNo, address))
348 emit toggleBreak(file, lineNo, address, true);
351 void WinStack::slotBrkptEnable()
353 QString file;
354 int lineNo;
355 DbgAddr address;
356 if (activeLine(file, lineNo, address))
357 emit enadisBreak(file, lineNo, address);
360 void WinStack::slotMoveProgramCounter()
362 QString file;
363 int lineNo;
364 DbgAddr address;
365 if (activeLine(file, lineNo, address))
366 emit moveProgramCounter(file, lineNo, address);
370 ValueTip::ValueTip(WinStack* parent) :
371 QToolTip(parent)
375 void ValueTip::maybeTip(const QPoint& p)
377 WinStack* w = static_cast<WinStack*>(parentWidget());
378 w->maybeTip(p);
382 FindDialog::FindDialog() :
383 QDialog(0, "find", false),
384 m_searchText(this, "text"),
385 m_caseCheck(this, "case"),
386 m_buttonForward(this, "forward"),
387 m_buttonBackward(this, "backward"),
388 m_buttonClose(this, "close"),
389 m_layout(this, 8),
390 m_buttons(4)
392 setCaption(QString(kapp->caption()) + i18n(": Search"));
394 m_searchText.setMinimumSize(330, 24);
395 m_searchText.setMaxLength(10000);
396 m_searchText.setFrame(true);
398 m_caseCheck.setText(i18n("&Case sensitive"));
399 m_caseCheck.setChecked(true);
400 m_buttonForward.setText(i18n("&Forward"));
401 m_buttonForward.setDefault(true);
402 m_buttonBackward.setText(i18n("&Backward"));
403 m_buttonClose.setText(i18n("Close"));
405 m_caseCheck.setMinimumSize(330, 24);
407 // get maximum size of buttons
408 QSize maxSize(80,30);
409 maxSize.expandedTo(m_buttonForward.sizeHint());
410 maxSize.expandedTo(m_buttonBackward.sizeHint());
411 maxSize.expandedTo(m_buttonClose.sizeHint());
413 m_buttonForward.setMinimumSize(maxSize);
414 m_buttonBackward.setMinimumSize(maxSize);
415 m_buttonClose.setMinimumSize(maxSize);
417 connect(&m_buttonClose, SIGNAL(clicked()), SLOT(reject()));
419 m_layout.addWidget(&m_searchText);
420 m_layout.addWidget(&m_caseCheck);
421 m_layout.addLayout(&m_buttons);
422 m_layout.addStretch(10);
423 m_buttons.addWidget(&m_buttonForward);
424 m_buttons.addStretch(10);
425 m_buttons.addWidget(&m_buttonBackward);
426 m_buttons.addStretch(10);
427 m_buttons.addWidget(&m_buttonClose);
429 m_layout.activate();
431 m_searchText.setFocus();
432 resize( 350, 120 );
435 FindDialog::~FindDialog()
439 void FindDialog::closeEvent(QCloseEvent* ev)
441 QDialog::closeEvent(ev);
442 emit closed();
445 void FindDialog::done(int result)
447 QDialog::done(result);
448 emit closed();
451 #include "winstack.moc"