3 // Copyright by Johannes Sixt
4 // This file is under GPL, the GNU General Public Licence
12 #include <klocale.h> /* i18n */
20 WinStack::WinStack(QWidget
* parent
, const char* name
) :
21 QWidget(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::setWindowMenu(QPopupMenu
* menu
)
48 // hook up for menu activations
49 connect(menu
, SIGNAL(activated(int)), this, SLOT(selectWindow(int)));
52 void WinStack::mousePressEvent(QMouseEvent
* mouseEvent
)
54 // Check if right button was clicked.
55 if (mouseEvent
->button() == RightButton
)
57 emit
clickedRight(mouseEvent
->pos());
59 QWidget::mousePressEvent(mouseEvent
);
64 void WinStack::reloadAllFiles()
66 for (int i
= 0; i
< m_fileList
.size(); i
++) {
67 m_fileList
[i
]->reloadFile();
71 QSize
WinStack::sizeHint() const
73 return QSize(640, 480);
76 void WinStack::activate(const QString
& fileName
, int lineNo
, const DbgAddr
& address
)
78 QFileInfo
fi(fileName
);
82 * We didn't find that file. Now check if it is a relative path and
83 * try m_lastOpenDir as prefix.
85 TRACE(fi
.filePath() + (" not found, looking in " + m_lastOpenDir
));
86 if (!fi
.isRelative() || m_lastOpenDir
.isEmpty()) {
89 fi
.setFile(m_lastOpenDir
+ "/" + fi
.filePath());
94 // if this is not an absolute path name, make it one
95 activatePath(fi
.absFilePath(), lineNo
, address
);
98 void WinStack::activateFile(const QString
& fileName
)
100 activatePath(fileName
, 0, DbgAddr());
103 bool WinStack::activatePath(QString pathName
, int lineNo
, const DbgAddr
& address
)
105 // check whether the file is already open
106 SourceWindow
* fw
= 0;
107 for (int i
= 0; i
< m_fileList
.size(); i
++) {
108 if (m_fileList
[i
]->fileName() == pathName
) {
114 // not found, load it
115 fw
= new SourceWindow(pathName
, this, "fileWindow");
118 if (!fw
->loadFile()) {
124 m_fileList
.insertAt(0, fw
);
125 connect(fw
, SIGNAL(lineChanged()),SIGNAL(lineChanged()));
126 connect(fw
, SIGNAL(clickedLeft(const QString
&,int,const DbgAddr
&,bool)),
127 SIGNAL(toggleBreak(const QString
&,int,const DbgAddr
&,bool)));
128 connect(fw
, SIGNAL(clickedMid(const QString
&,int,const DbgAddr
&)),
129 SIGNAL(enadisBreak(const QString
&,int,const DbgAddr
&)));
131 // Comunication when right button is clicked.
132 connect(fw
, SIGNAL(clickedRight(const QPoint
&)),
133 SIGNAL(filesRightClick(const QPoint
&)));
136 connect(fw
, SIGNAL(disassemble(const QString
&, int)),
137 SIGNAL(disassemble(const QString
&, int)));
138 connect(fw
, SIGNAL(expanded(int)), SLOT(slotExpandCollapse(int)));
139 connect(fw
, SIGNAL(collapsed(int)), SLOT(slotExpandCollapse(int)));
142 connect(this, SIGNAL(setTabWidth(int)), fw
, SLOT(setTabWidth(int)));
143 fw
->setTabWidth(m_tabWidth
);
147 // set PC if there is one
148 emit
newFileLoaded();
150 setPC(true, m_pcFile
, m_pcLine
, DbgAddr(m_pcAddress
), m_pcFrame
);
153 return activateWindow(fw
, lineNo
, address
);
156 bool WinStack::activateWindow(SourceWindow
* fw
, int lineNo
, const DbgAddr
& address
)
159 int index
= m_fileList
.size()-1;
160 while (index
>= 0 && m_fileList
[index
] != fw
)
167 * If the file is not in the list of those that would appear in the
168 * window menu, move it to the first position.
171 m_fileList
.removeAt(index
);
172 m_fileList
.insertAt(0, fw
);
176 // make the line visible
178 fw
->scrollTo(lineNo
, address
);
181 // first resize the window, then lift it to the top
182 fw
->setGeometry(0,0, width(),height());
186 // set the focus to the new active window
187 QWidget
* oldActive
= m_activeWindow
;
188 fw
->setFocusPolicy(QWidget::WheelFocus
);
190 if (oldActive
!= 0 && oldActive
!= fw
) {
191 // disable focus on non-active windows
192 oldActive
->setFocusPolicy(QWidget::NoFocus
);
201 bool WinStack::activeLine(QString
& fileName
, int& lineNo
)
204 return activeLine(fileName
, lineNo
, dummy
);
207 bool WinStack::activeLine(QString
& fileName
, int& lineNo
, DbgAddr
& address
)
209 if (m_activeWindow
== 0) {
213 fileName
= m_activeWindow
->fileName();
214 m_activeWindow
->activeLine(lineNo
, address
);
218 void WinStack::changeWindowMenu()
220 if (m_windowMenu
== 0) {
225 // Delete entries at most the N window entries that we insert below.
226 // When we get here if the More entry was selected, we must make sure
227 // that we don't delete it (or we crash).
228 bool haveMore
= m_windowMenu
->count() > uint(N
);
229 int k
= haveMore
? N
: m_windowMenu
->count();
231 for (int i
= 0; i
< k
; i
++) {
232 m_windowMenu
->removeItemAt(0);
235 // insert current windows
237 for (int i
= 0; i
< m_fileList
.size() && i
< N
; i
++) {
238 text
.sprintf("&%d ", i
+1);
239 text
+= m_fileList
[i
]->fileName();
240 m_windowMenu
->insertItem(text
, WindowMore
+i
+1, i
);
242 // add More entry if we have none yet
243 if (!haveMore
&& m_fileList
.size() > N
) {
244 m_windowMenu
->insertItem(i18n("&More..."), WindowMore
, N
);
248 void WinStack::updateLineItems(const KDebugger
* dbg
)
250 for (int i
= 0; i
< m_fileList
.size(); i
++) {
251 m_fileList
[i
]->updateLineItems(dbg
);
255 void WinStack::updatePC(const QString
& fileName
, int lineNo
, const DbgAddr
& address
, int frameNo
)
258 setPC(false, m_pcFile
, m_pcLine
, DbgAddr(m_pcAddress
), m_pcFrame
);
262 m_pcAddress
= address
.asString();
265 setPC(true, fileName
, lineNo
, address
, frameNo
);
269 void WinStack::setPC(bool set
, const QString
& fileName
, int lineNo
,
270 const DbgAddr
& address
, int frameNo
)
272 TRACE((set
? "set PC: " : "clear PC: ") + fileName
+
273 QString().sprintf(":%d#%d ", lineNo
, frameNo
) + address
.asString());
275 for (int i
= 0; i
< m_fileList
.size(); i
++) {
276 if (m_fileList
[i
]->fileNameMatches(fileName
)) {
277 m_fileList
[i
]->setPC(set
, lineNo
, address
, frameNo
);
283 void WinStack::resizeEvent(QResizeEvent
*)
285 if (m_activeWindow
!= 0) {
286 m_activeWindow
->resize(width(), height());
290 QString
WinStack::activeFileName() const
293 if (m_activeWindow
!= 0)
294 f
= m_activeWindow
->fileName();
298 void WinStack::slotFindForward()
300 if (m_activeWindow
!= 0)
301 m_activeWindow
->find(m_findDlg
.searchText(), m_findDlg
.caseSensitive(),
302 SourceWindow::findForward
);
305 void WinStack::slotFindBackward()
307 if (m_activeWindow
!= 0)
308 m_activeWindow
->find(m_findDlg
.searchText(), m_findDlg
.caseSensitive(),
309 SourceWindow::findBackward
);
312 void WinStack::maybeTip(const QPoint
& p
)
314 if (m_activeWindow
== 0)
317 // get the word at the point
320 if (!m_activeWindow
->wordAtPoint(p
, word
, r
))
324 assert(!word
.isEmpty());
327 // remember the location
330 emit
initiateValuePopup(word
);
333 void WinStack::slotShowValueTip(const QString
& tipText
)
335 m_valueTip
.tip(m_tipLocation
, tipText
);
338 void WinStack::slotDisassembled(const QString
& fileName
, int lineNo
,
339 const QList
<DisassembledCode
>& disass
)
342 SourceWindow
* fw
= 0;
343 for (int i
= 0; i
< m_fileList
.size(); i
++) {
344 if (m_fileList
[i
]->fileNameMatches(fileName
)) {
354 fw
->disassembled(lineNo
, disass
);
357 void WinStack::slotExpandCollapse(int)
359 // update line items after expanding or collapsing disassembled code
361 // HACK: we know that this will result in updateLineItems
362 // should be done more cleanly with a separate signal
363 emit
newFileLoaded();
366 setPC(true, m_pcFile
, m_pcLine
, DbgAddr(m_pcAddress
), m_pcFrame
);
371 void WinStack::slotSetTabWidth(int numChars
)
373 m_tabWidth
= numChars
;
376 void WinStack::slotFileReload()
378 if (m_activeWindow
!= 0) {
379 TRACE("reloading one file");
380 m_activeWindow
->reloadFile();
384 void WinStack::slotViewFind()
386 if (m_findDlg
.isVisible()) {
393 void WinStack::slotBrkptSet()
398 if (activeLine(file
, lineNo
, address
))
399 emit
toggleBreak(file
, lineNo
, address
, false);
402 void WinStack::slotBrkptSetTemp()
407 if (activeLine(file
, lineNo
, address
))
408 emit
toggleBreak(file
, lineNo
, address
, true);
411 void WinStack::slotBrkptEnable()
416 if (activeLine(file
, lineNo
, address
))
417 emit
enadisBreak(file
, lineNo
, address
);
420 void WinStack::slotMoveProgramCounter()
425 if (activeLine(file
, lineNo
, address
))
426 emit
moveProgramCounter(file
, lineNo
, address
);
430 ValueTip::ValueTip(WinStack
* parent
) :
435 void ValueTip::maybeTip(const QPoint
& p
)
437 WinStack
* w
= static_cast<WinStack
*>(parentWidget());
442 class MoreWindowsDialog
: public QDialog
445 MoreWindowsDialog(QWidget
* parent
);
446 virtual ~MoreWindowsDialog();
448 void insertString(const char* text
) { m_list
.insertItem(text
); }
449 void setListIndex(int i
) { m_list
.setCurrentItem(i
); }
450 int listIndex() const { return m_list
.currentItem(); }
454 QPushButton m_buttonOK
;
455 QPushButton m_buttonCancel
;
456 QVBoxLayout m_layout
;
457 QHBoxLayout m_buttons
;
460 MoreWindowsDialog::MoreWindowsDialog(QWidget
* parent
) :
461 QDialog(parent
, "morewindows", true),
462 m_list(this, "windows"),
463 m_buttonOK(this, "show"),
464 m_buttonCancel(this, "cancel"),
468 QString title
= kapp
->caption();
469 title
+= i18n(": Open Windows");
472 m_list
.setMinimumSize(250, 100);
473 connect(&m_list
, SIGNAL(selected(int)), SLOT(accept()));
475 m_buttonOK
.setMinimumSize(100, 30);
476 connect(&m_buttonOK
, SIGNAL(clicked()), SLOT(accept()));
477 m_buttonOK
.setText(i18n("Show"));
478 m_buttonOK
.setDefault(true);
480 m_buttonCancel
.setMinimumSize(100, 30);
481 connect(&m_buttonCancel
, SIGNAL(clicked()), SLOT(reject()));
482 m_buttonCancel
.setText(i18n("Cancel"));
484 m_layout
.addWidget(&m_list
, 10);
485 m_layout
.addLayout(&m_buttons
);
486 m_buttons
.addStretch(10);
487 m_buttons
.addWidget(&m_buttonOK
);
488 m_buttons
.addSpacing(40);
489 m_buttons
.addWidget(&m_buttonCancel
);
490 m_buttons
.addStretch(10);
498 MoreWindowsDialog::~MoreWindowsDialog()
502 void WinStack::selectWindow(int id
)
504 // react only on menu entries concerning windows
505 if ((id
& ~WindowMask
) != WindowMore
) {
514 // more windows selected: show windows in a list
515 MoreWindowsDialog
dlg(this);
516 for (int i
= 0; i
< m_fileList
.size(); i
++)
518 dlg
.insertString(m_fileList
[i
]->fileName());
519 if (m_activeWindow
== m_fileList
[i
]) {
523 dlg
.setListIndex(index
);
524 if (dlg
.exec() == QDialog::Rejected
)
526 index
= dlg
.listIndex();
528 index
= (id
& WindowMask
)-1;
531 SourceWindow
* fw
= m_fileList
[index
];
534 activateWindow(fw
, -1, DbgAddr());
538 FindDialog::FindDialog() :
539 QDialog(0, "find", false),
540 m_searchText(this, "text"),
541 m_caseCheck(this, "case"),
542 m_buttonForward(this, "forward"),
543 m_buttonBackward(this, "backward"),
544 m_buttonClose(this, "close"),
548 setCaption(QString(kapp
->caption()) + i18n(": Search"));
550 m_searchText
.setMinimumSize(330, 24);
551 m_searchText
.setMaxLength(10000);
552 m_searchText
.setFrame(true);
554 m_caseCheck
.setText(i18n("&Case sensitive"));
555 m_caseCheck
.setChecked(true);
556 m_buttonForward
.setText(i18n("&Forward"));
557 m_buttonForward
.setDefault(true);
558 m_buttonBackward
.setText(i18n("&Backward"));
559 m_buttonClose
.setText(i18n("Close"));
561 m_caseCheck
.setMinimumSize(330, 24);
563 // get maximum size of buttons
564 QSize
maxSize(80,30);
565 maxSize
.expandedTo(m_buttonForward
.sizeHint());
566 maxSize
.expandedTo(m_buttonBackward
.sizeHint());
567 maxSize
.expandedTo(m_buttonClose
.sizeHint());
569 m_buttonForward
.setMinimumSize(maxSize
);
570 m_buttonBackward
.setMinimumSize(maxSize
);
571 m_buttonClose
.setMinimumSize(maxSize
);
573 connect(&m_buttonClose
, SIGNAL(clicked()), SLOT(reject()));
575 m_layout
.addWidget(&m_searchText
);
576 m_layout
.addWidget(&m_caseCheck
);
577 m_layout
.addLayout(&m_buttons
);
578 m_layout
.addStretch(10);
579 m_buttons
.addWidget(&m_buttonForward
);
580 m_buttons
.addStretch(10);
581 m_buttons
.addWidget(&m_buttonBackward
);
582 m_buttons
.addStretch(10);
583 m_buttons
.addWidget(&m_buttonClose
);
587 m_searchText
.setFocus();
591 FindDialog::~FindDialog()
595 void FindDialog::closeEvent(QCloseEvent
* ev
)
597 QDialog::closeEvent(ev
);
601 void FindDialog::done(int result
)
603 QDialog::done(result
);
607 #include "winstack.moc"