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 <qpopupmenu.h>
12 #include <kapplication.h>
13 #include <kmainwindow.h>
14 #include <klocale.h> /* i18n */
22 WinStack::WinStack(QWidget
* parent
, const char* name
) :
23 KTabWidget(parent
, name
),
26 m_tipLocation(1,1,10,10),
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)));
41 void WinStack::contextMenuEvent(QContextMenuEvent
* e
)
43 // get the context menu from the GUI factory
46 top
= top
->parentWidget();
47 while (!top
->isTopLevel());
48 KMainWindow
* mw
= static_cast<KMainWindow
*>(top
);
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
);
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()) {
80 fi
.setFile(m_lastOpenDir
+ "/" + fi
.filePath());
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
98 for (int i
= 0; i
< m_fileList
.size(); i
++) {
99 if (m_fileList
[i
]->fileName() == pathName
) {
105 // not found, load it
106 fw
= new SourceWindow(pathName
, this, "fileWindow");
109 if (!fw
->loadFile()) {
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
&)));
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
)
145 int index
= m_fileList
.size()-1;
146 while (index
>= 0 && m_fileList
[index
] != fw
)
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.
157 m_fileList
.removeAt(index
);
158 m_fileList
.insertAt(0, fw
);
161 // make the line visible
163 fw
->scrollTo(lineNo
, address
);
174 bool WinStack::activeLine(QString
& fileName
, int& lineNo
)
177 return activeLine(fileName
, lineNo
, dummy
);
180 bool WinStack::activeLine(QString
& fileName
, int& lineNo
, DbgAddr
& address
)
182 if (activeWindow() == 0) {
186 fileName
= activeFileName();
187 activeWindow()->activeLine(lineNo
, address
);
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
)
201 setPC(false, m_pcFile
, m_pcLine
, DbgAddr(m_pcAddress
), m_pcFrame
);
205 m_pcAddress
= address
.asString();
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
];
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
);
229 fw
->setPC(set
, lineNo
, address
, frameNo
);
232 SourceWindow
* WinStack::activeWindow() const
234 return static_cast<SourceWindow
*>(currentPage());
237 QString
WinStack::activeFileName() const
240 if (activeWindow() != 0)
241 f
= activeWindow()->fileName();
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)
264 // get the word at the point
267 if (!activeWindow()->wordAtPoint(p
, word
, r
))
271 assert(!word
.isEmpty());
274 // remember the location
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
);
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();
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()) {
333 void WinStack::slotBrkptSet()
338 if (activeLine(file
, lineNo
, address
))
339 emit
toggleBreak(file
, lineNo
, address
, false);
342 void WinStack::slotBrkptSetTemp()
347 if (activeLine(file
, lineNo
, address
))
348 emit
toggleBreak(file
, lineNo
, address
, true);
351 void WinStack::slotBrkptEnable()
356 if (activeLine(file
, lineNo
, address
))
357 emit
enadisBreak(file
, lineNo
, address
);
360 void WinStack::slotMoveProgramCounter()
365 if (activeLine(file
, lineNo
, address
))
366 emit
moveProgramCounter(file
, lineNo
, address
);
370 ValueTip::ValueTip(WinStack
* parent
) :
375 void ValueTip::maybeTip(const QPoint
& p
)
377 WinStack
* w
= static_cast<WinStack
*>(parentWidget());
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"),
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
);
431 m_searchText
.setFocus();
435 FindDialog::~FindDialog()
439 void FindDialog::closeEvent(QCloseEvent
* ev
)
441 QDialog::closeEvent(ev
);
445 void FindDialog::done(int result
)
447 QDialog::done(result
);
451 #include "winstack.moc"