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.
10 #include <qfileinfo.h>
11 #include <q3popupmenu.h>
12 #include <QContextMenuEvent>
13 #include <QCloseEvent>
14 #include <kapplication.h>
15 #include <kmainwindow.h>
16 #include <klocale.h> /* i18n */
21 WinStack::WinStack(QWidget
* parent
) :
25 m_tipLocation(1,1,10,10),
28 connect(&m_findDlg
.m_buttonForward
,
29 SIGNAL(clicked()), SLOT(slotFindForward()));
30 connect(&m_findDlg
.m_buttonBackward
,
31 SIGNAL(clicked()), SLOT(slotFindBackward()));
33 connect(this, SIGNAL(setTabWidth(int)), this, SLOT(slotSetTabWidth(int)));
40 void WinStack::contextMenuEvent(QContextMenuEvent
* e
)
42 // get the context menu from the GUI factory
45 top
= top
->parentWidget();
46 while (!top
->isTopLevel());
47 KMainWindow
* mw
= static_cast<KMainWindow
*>(top
);
49 static_cast<Q3PopupMenu
*>(mw
->factory()->container("popup_files_empty", mw
));
50 m
->exec(e
->globalPos());
54 void WinStack::reloadAllFiles()
56 for (int i
= count()-1; i
>= 0; i
--) {
57 windowAt(i
)->reloadFile();
61 QSize
WinStack::sizeHint() const
63 return QSize(640, 480);
66 void WinStack::activate(const QString
& fileName
, int lineNo
, const DbgAddr
& address
)
68 QFileInfo
fi(fileName
);
72 * We didn't find that file. Now check if it is a relative path and
73 * try m_lastOpenDir as prefix.
75 TRACE(fi
.filePath() + (" not found, looking in " + m_lastOpenDir
));
76 if (!fi
.isRelative() || m_lastOpenDir
.isEmpty()) {
79 fi
.setFile(m_lastOpenDir
+ "/" + fi
.filePath());
84 // if this is not an absolute path name, make it one
85 activatePath(fi
.absFilePath(), lineNo
, address
);
88 void WinStack::activateFile(const QString
& fileName
)
90 activatePath(fileName
, 0, DbgAddr());
93 bool WinStack::activatePath(QString pathName
, int lineNo
, const DbgAddr
& address
)
95 // check whether the file is already open
97 for (int i
= count()-1; i
>= 0; i
--) {
98 if (windowAt(i
)->fileName() == pathName
) {
104 // not found, load it
105 fw
= new SourceWindow(pathName
, this);
108 if (!fw
->loadFile()) {
114 addTab(fw
, QFileInfo(pathName
).fileName());
115 setTabToolTip(fw
, pathName
);
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
&)));
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)));
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();
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 // make the line visible
146 fw
->scrollTo(lineNo
, address
);
155 bool WinStack::activeLine(QString
& fileName
, int& lineNo
)
158 return activeLine(fileName
, lineNo
, dummy
);
161 bool WinStack::activeLine(QString
& fileName
, int& lineNo
, DbgAddr
& address
)
163 if (activeWindow() == 0) {
167 fileName
= activeFileName();
168 activeWindow()->activeLine(lineNo
, address
);
172 void WinStack::updateLineItems(const KDebugger
* dbg
)
174 for (int i
= count()-1; i
>= 0; i
--) {
175 windowAt(i
)->updateLineItems(dbg
);
179 void WinStack::updatePC(const QString
& fileName
, int lineNo
, const DbgAddr
& address
, int frameNo
)
182 setPC(false, m_pcFile
, m_pcLine
, DbgAddr(m_pcAddress
), m_pcFrame
);
186 m_pcAddress
= address
.asString();
189 setPC(true, fileName
, lineNo
, address
, frameNo
);
193 SourceWindow
* WinStack::findByFileName(const QString
& fileName
) const
195 for (int i
= count()-1; i
>= 0; i
--) {
196 if (windowAt(i
)->fileNameMatches(fileName
)) {
203 void WinStack::setPC(bool set
, const QString
& fileName
, int lineNo
,
204 const DbgAddr
& address
, int frameNo
)
206 TRACE((set
? "set PC: " : "clear PC: ") + fileName
+
207 QString().sprintf(":%d#%d ", lineNo
, frameNo
) + address
.asString());
208 SourceWindow
* fw
= findByFileName(fileName
);
210 fw
->setPC(set
, lineNo
, address
, frameNo
);
213 SourceWindow
* WinStack::windowAt(int i
) const
215 return static_cast<SourceWindow
*>(page(i
));
218 SourceWindow
* WinStack::activeWindow() const
220 return static_cast<SourceWindow
*>(currentPage());
223 QString
WinStack::activeFileName() const
226 if (activeWindow() != 0)
227 f
= activeWindow()->fileName();
231 void WinStack::slotFindForward()
233 if (activeWindow() != 0)
234 activeWindow()->find(m_findDlg
.searchText(), m_findDlg
.caseSensitive(),
235 SourceWindow::findForward
);
238 void WinStack::slotFindBackward()
240 if (activeWindow() != 0)
241 activeWindow()->find(m_findDlg
.searchText(), m_findDlg
.caseSensitive(),
242 SourceWindow::findBackward
);
245 void WinStack::maybeTip(const QPoint
& p
)
247 SourceWindow
* w
= activeWindow();
251 // get the word at the point
254 if (!w
->wordAtPoint(w
->mapFrom(this, p
), word
, r
))
258 assert(!word
.isEmpty());
261 // remember the location
262 m_tipLocation
= QRect(w
->mapTo(this, r
.topLeft()), r
.size());
264 emit
initiateValuePopup(word
);
267 void WinStack::slotShowValueTip(const QString
& tipText
)
269 m_valueTip
.tip(m_tipLocation
, tipText
);
272 void WinStack::slotDisassembled(const QString
& fileName
, int lineNo
,
273 const std::list
<DisassembledCode
>& disass
)
275 SourceWindow
* fw
= findByFileName(fileName
);
281 fw
->disassembled(lineNo
, disass
);
284 void WinStack::slotExpandCollapse(int)
286 // update line items after expanding or collapsing disassembled code
288 // HACK: we know that this will result in updateLineItems
289 // should be done more cleanly with a separate signal
290 emit
newFileLoaded();
293 setPC(true, m_pcFile
, m_pcLine
, DbgAddr(m_pcAddress
), m_pcFrame
);
298 void WinStack::slotSetTabWidth(int numChars
)
300 m_tabWidth
= numChars
;
303 void WinStack::slotFileReload()
305 if (activeWindow() != 0) {
306 TRACE("reloading one file");
307 activeWindow()->reloadFile();
311 void WinStack::slotViewFind()
313 if (m_findDlg
.isVisible()) {
320 void WinStack::slotBrkptSet()
325 if (activeLine(file
, lineNo
, address
))
326 emit
toggleBreak(file
, lineNo
, address
, false);
329 void WinStack::slotBrkptSetTemp()
334 if (activeLine(file
, lineNo
, address
))
335 emit
toggleBreak(file
, lineNo
, address
, true);
338 void WinStack::slotBrkptEnable()
343 if (activeLine(file
, lineNo
, address
))
344 emit
enadisBreak(file
, lineNo
, address
);
347 void WinStack::slotMoveProgramCounter()
352 if (activeLine(file
, lineNo
, address
))
353 emit
moveProgramCounter(file
, lineNo
, address
);
356 void WinStack::slotClose()
358 QWidget
* w
= activeWindow();
367 ValueTip::ValueTip(WinStack
* parent
) :
372 void ValueTip::maybeTip(const QPoint
& p
)
374 WinStack
* w
= static_cast<WinStack
*>(parentWidget());
379 FindDialog::FindDialog() :
380 QDialog(0, "find", false),
381 m_searchText(this, "text"),
382 m_caseCheck(this, "case"),
383 m_buttonForward(this, "forward"),
384 m_buttonBackward(this, "backward"),
385 m_buttonClose(this, "close"),
389 setCaption(QString(kapp
->caption()) + i18n(": Search"));
391 m_searchText
.setMinimumSize(330, 24);
392 m_searchText
.setMaxLength(10000);
393 m_searchText
.setFrame(true);
395 m_caseCheck
.setText(i18n("&Case sensitive"));
396 m_caseCheck
.setChecked(true);
397 m_buttonForward
.setText(i18n("&Forward"));
398 m_buttonForward
.setDefault(true);
399 m_buttonBackward
.setText(i18n("&Backward"));
400 m_buttonClose
.setText(i18n("Close"));
402 m_caseCheck
.setMinimumSize(330, 24);
404 // get maximum size of buttons
405 QSize
maxSize(80,30);
406 maxSize
.expandedTo(m_buttonForward
.sizeHint());
407 maxSize
.expandedTo(m_buttonBackward
.sizeHint());
408 maxSize
.expandedTo(m_buttonClose
.sizeHint());
410 m_buttonForward
.setMinimumSize(maxSize
);
411 m_buttonBackward
.setMinimumSize(maxSize
);
412 m_buttonClose
.setMinimumSize(maxSize
);
414 connect(&m_buttonClose
, SIGNAL(clicked()), SLOT(reject()));
416 m_layout
.addWidget(&m_searchText
);
417 m_layout
.addWidget(&m_caseCheck
);
418 m_layout
.addLayout(&m_buttons
);
419 m_layout
.addStretch(10);
420 m_buttons
.addWidget(&m_buttonForward
);
421 m_buttons
.addStretch(10);
422 m_buttons
.addWidget(&m_buttonBackward
);
423 m_buttons
.addStretch(10);
424 m_buttons
.addWidget(&m_buttonClose
);
428 m_searchText
.setFocus();
432 FindDialog::~FindDialog()
436 void FindDialog::closeEvent(QCloseEvent
* ev
)
438 QDialog::closeEvent(ev
);
442 void FindDialog::done(int result
)
444 QDialog::done(result
);
448 #include "winstack.moc"