Generate and install scalable icons.
[kdbg.git] / kdbg / winstack.cpp
blob819b1bbcb23308886299a3abfdaa8e7d8a4b7f4e
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 <kxmlguiwindow.h>
15 #include <kxmlguifactory.h>
16 #include <klocale.h> /* i18n */
17 #include "mydebug.h"
21 WinStack::WinStack(QWidget* parent) :
22 QTabWidget(parent),
23 m_pcLine(-1),
24 m_tabWidth(0)
26 connect(&m_findDlg.m_buttonForward,
27 SIGNAL(clicked()), SLOT(slotFindForward()));
28 connect(&m_findDlg.m_buttonBackward,
29 SIGNAL(clicked()), SLOT(slotFindBackward()));
31 connect(this, SIGNAL(setTabWidth(int)), this, SLOT(slotSetTabWidth(int)));
34 WinStack::~WinStack()
38 void WinStack::contextMenuEvent(QContextMenuEvent* e)
40 // get the context menu from the GUI factory
41 QWidget* top = this;
43 top = top->parentWidget();
44 while (!top->isTopLevel());
45 KXmlGuiWindow* mw = static_cast<KXmlGuiWindow*>(top);
46 QMenu* m =
47 static_cast<QMenu*>(mw->factory()->container("popup_files_empty", mw));
48 m->exec(e->globalPos());
52 void WinStack::reloadAllFiles()
54 for (int i = count()-1; i >= 0; i--) {
55 windowAt(i)->reloadFile();
59 QSize WinStack::sizeHint() const
61 return QSize(640, 480);
64 void WinStack::activate(const QString& fileName, int lineNo, const DbgAddr& address)
66 QFileInfo fi(fileName);
68 if (!fi.isFile()) {
70 * We didn't find that file. Now check if it is a relative path and
71 * try m_lastOpenDir as prefix.
73 TRACE(fi.filePath() + (" not found, looking in " + m_lastOpenDir));
74 if (!fi.isRelative() || m_lastOpenDir.isEmpty()) {
75 return;
77 fi.setFile(m_lastOpenDir + "/" + fi.filePath());
78 if (!fi.isFile()) {
79 return;
82 // if this is not an absolute path name, make it one
83 activatePath(fi.absoluteFilePath(), lineNo, address);
86 void WinStack::activateFile(const QString& fileName)
88 activatePath(fileName, 0, DbgAddr());
91 bool WinStack::activatePath(QString pathName, int lineNo, const DbgAddr& address)
93 // check whether the file is already open
94 SourceWindow* fw = 0;
95 for (int i = count()-1; i >= 0; i--) {
96 if (windowAt(i)->fileName() == pathName) {
97 fw = windowAt(i);
98 break;
101 if (fw == 0) {
102 // not found, load it
103 fw = new SourceWindow(pathName, this);
105 // slurp the file in
106 if (!fw->loadFile()) {
107 // read failed
108 delete fw;
109 return false;
112 int idx = addTab(fw, QFileInfo(pathName).fileName());
113 setTabToolTip(idx, pathName);
115 connect(fw, SIGNAL(clickedLeft(const QString&,int,const DbgAddr&,bool)),
116 SIGNAL(toggleBreak(const QString&,int,const DbgAddr&,bool)));
117 connect(fw, SIGNAL(clickedMid(const QString&,int,const DbgAddr&)),
118 SIGNAL(enadisBreak(const QString&,int,const DbgAddr&)));
120 // disassemble code
121 connect(fw, SIGNAL(disassemble(const QString&, int)),
122 SIGNAL(disassemble(const QString&, int)));
123 connect(fw, SIGNAL(expanded(int)), SLOT(slotExpandCollapse(int)));
124 connect(fw, SIGNAL(collapsed(int)), SLOT(slotExpandCollapse(int)));
126 // tab width
127 connect(this, SIGNAL(setTabWidth(int)), fw, SLOT(setTabWidth(int)));
128 fw->setTabWidth(m_tabWidth);
129 fw->setFocusPolicy(Qt::WheelFocus);
131 // set PC if there is one
132 emit newFileLoaded();
133 if (m_pcLine >= 0) {
134 setPC(true, m_pcFile, m_pcLine, DbgAddr(m_pcAddress), m_pcFrame);
137 return activateWindow(fw, lineNo, address);
140 bool WinStack::activateWindow(SourceWindow* fw, int lineNo, const DbgAddr& address)
142 // make the line visible
143 if (lineNo >= 0) {
144 fw->scrollTo(lineNo, address);
147 setCurrentWidget(fw);
148 fw->setFocus();
150 return true;
153 bool WinStack::activeLine(QString& fileName, int& lineNo)
155 DbgAddr dummy;
156 return activeLine(fileName, lineNo, dummy);
159 bool WinStack::activeLine(QString& fileName, int& lineNo, DbgAddr& address)
161 if (activeWindow() == 0) {
162 return false;
165 fileName = activeFileName();
166 activeWindow()->activeLine(lineNo, address);
167 return true;
170 void WinStack::updateLineItems(const KDebugger* dbg)
172 for (int i = count()-1; i >= 0; i--) {
173 windowAt(i)->updateLineItems(dbg);
177 void WinStack::updatePC(const QString& fileName, int lineNo, const DbgAddr& address, int frameNo)
179 if (m_pcLine >= 0) {
180 setPC(false, m_pcFile, m_pcLine, DbgAddr(m_pcAddress), m_pcFrame);
182 m_pcFile = fileName;
183 m_pcLine = lineNo;
184 m_pcAddress = address.asString();
185 m_pcFrame = frameNo;
186 if (lineNo >= 0) {
187 setPC(true, fileName, lineNo, address, frameNo);
191 SourceWindow* WinStack::findByFileName(const QString& fileName) const
193 for (int i = count()-1; i >= 0; i--) {
194 if (windowAt(i)->fileNameMatches(fileName)) {
195 return windowAt(i);
198 return 0;
201 void WinStack::setPC(bool set, const QString& fileName, int lineNo,
202 const DbgAddr& address, int frameNo)
204 TRACE((set ? "set PC: " : "clear PC: ") + fileName +
205 QString().sprintf(":%d#%d ", lineNo, frameNo) + address.asString());
206 SourceWindow* fw = findByFileName(fileName);
207 if (fw)
208 fw->setPC(set, lineNo, address, frameNo);
211 SourceWindow* WinStack::windowAt(int i) const
213 return static_cast<SourceWindow*>(widget(i));
216 SourceWindow* WinStack::activeWindow() const
218 return static_cast<SourceWindow*>(currentWidget());
221 QString WinStack::activeFileName() const
223 QString f;
224 if (activeWindow() != 0)
225 f = activeWindow()->fileName();
226 return f;
229 void WinStack::slotFindForward()
231 if (activeWindow() != 0)
232 activeWindow()->find(m_findDlg.searchText(), m_findDlg.caseSensitive(),
233 SourceWindow::findForward);
236 void WinStack::slotFindBackward()
238 if (activeWindow() != 0)
239 activeWindow()->find(m_findDlg.searchText(), m_findDlg.caseSensitive(),
240 SourceWindow::findBackward);
243 bool WinStack::event(QEvent* evt)
245 if (evt->type() != QEvent::ToolTip)
246 return QTabWidget::event(evt);
248 SourceWindow* w = activeWindow();
249 if (w == 0)
250 return true;
252 QPoint p = static_cast<QHelpEvent*>(evt)->globalPos();
253 // get the word at the point
254 QString word;
255 QRect r;
256 if (!w->wordAtPoint(w->mapFromGlobal(p), word, r)) {
257 QToolTip::hideText();
258 return true;
261 // must be valid
262 assert(!word.isEmpty());
263 assert(r.isValid());
265 // remember the location
266 m_tipLocation = p;
267 m_tipRegion = QRect(w->mapTo(this, r.topLeft()), r.size());
269 emit initiateValuePopup(word);
270 return true;
273 void WinStack::slotShowValueTip(const QString& tipText)
275 QToolTip::showText(m_tipLocation, tipText, this, m_tipRegion);
278 void WinStack::slotDisassembled(const QString& fileName, int lineNo,
279 const std::list<DisassembledCode>& disass)
281 SourceWindow* fw = findByFileName(fileName);
282 if (fw == 0) {
283 // not found: ignore
284 return;
287 fw->disassembled(lineNo, disass);
290 void WinStack::slotExpandCollapse(int)
292 // update line items after expanding or collapsing disassembled code
294 // HACK: we know that this will result in updateLineItems
295 // should be done more cleanly with a separate signal
296 emit newFileLoaded();
298 if (m_pcLine >= 0) {
299 setPC(true, m_pcFile, m_pcLine, DbgAddr(m_pcAddress), m_pcFrame);
304 void WinStack::slotSetTabWidth(int numChars)
306 m_tabWidth = numChars;
309 void WinStack::slotFileReload()
311 if (activeWindow() != 0) {
312 TRACE("reloading one file");
313 activeWindow()->reloadFile();
317 void WinStack::slotViewFind()
319 if (m_findDlg.isVisible()) {
320 m_findDlg.done(0);
321 } else {
322 m_findDlg.show();
326 void WinStack::slotBrkptSet()
328 QString file;
329 int lineNo;
330 DbgAddr address;
331 if (activeLine(file, lineNo, address))
332 emit toggleBreak(file, lineNo, address, false);
335 void WinStack::slotBrkptSetTemp()
337 QString file;
338 int lineNo;
339 DbgAddr address;
340 if (activeLine(file, lineNo, address))
341 emit toggleBreak(file, lineNo, address, true);
344 void WinStack::slotBrkptEnable()
346 QString file;
347 int lineNo;
348 DbgAddr address;
349 if (activeLine(file, lineNo, address))
350 emit enadisBreak(file, lineNo, address);
353 void WinStack::slotMoveProgramCounter()
355 QString file;
356 int lineNo;
357 DbgAddr address;
358 if (activeLine(file, lineNo, address))
359 emit moveProgramCounter(file, lineNo, address);
362 void WinStack::slotClose()
364 QWidget* w = activeWindow();
365 if (!w)
366 return;
368 removeTab(currentIndex());
369 delete w;
373 FindDialog::FindDialog() :
374 QDialog(),
375 m_searchText(this),
376 m_caseCheck(this),
377 m_buttonForward(this),
378 m_buttonBackward(this),
379 m_buttonClose(this)
381 setWindowTitle(i18n("Search"));
383 m_searchText.setMinimumSize(330, 24);
384 m_searchText.setMaxLength(10000);
385 m_searchText.setFrame(true);
386 m_searchText.setFocus();
388 m_caseCheck.setText(i18n("&Case sensitive"));
389 m_caseCheck.setChecked(true);
390 m_buttonForward.setText(i18n("&Forward"));
391 m_buttonForward.setDefault(true);
392 m_buttonBackward.setText(i18n("&Backward"));
393 m_buttonClose.setText(i18n("Close"));
395 connect(&m_buttonClose, SIGNAL(clicked()), SLOT(reject()));
397 m_layout.addWidget(&m_searchText);
398 m_layout.addWidget(&m_caseCheck);
399 m_layout.addLayout(&m_buttons);
401 m_buttons.addWidget(&m_buttonForward);
402 m_buttons.addWidget(&m_buttonBackward);
403 m_buttons.addWidget(&m_buttonClose);
405 setLayout(&m_layout);
408 FindDialog::~FindDialog()
412 void FindDialog::closeEvent(QCloseEvent* ev)
414 QDialog::closeEvent(ev);
415 emit closed();
418 void FindDialog::done(int result)
420 QDialog::done(result);
421 emit closed();
424 #include "winstack.moc"