KDevelop API Documentation

languages/cpp/debugger/variablewidget.cpp

Go to the documentation of this file.
00001 // ************************************************************************** 00002 // begin : Sun Aug 8 1999 00003 // copyright : (C) 1999 by John Birch 00004 // email : jbb@kdevelop.org 00005 // ************************************************************************** 00006 00007 // ************************************************************************** 00008 // * * 00009 // * This program is free software; you can redistribute it and/or modify * 00010 // * it under the terms of the GNU General Public License as published by * 00011 // * the Free Software Foundation; either version 2 of the License, or * 00012 // * (at your option) any later version. * 00013 // * * 00014 // ************************************************************************** 00015 00016 #include "variablewidget.h" 00017 #include "gdbparser.h" 00018 00019 #include <kdebug.h> 00020 #include <kpopupmenu.h> 00021 #include <klineedit.h> 00022 #include <kdeversion.h> 00023 00024 #include <qheader.h> 00025 #include <qlabel.h> 00026 #include <qlayout.h> 00027 #include <qhbox.h> 00028 #include <qpainter.h> 00029 #include <qpushbutton.h> 00030 #include <qregexp.h> 00031 #include <qcursor.h> 00032 #include <klocale.h> 00033 00034 #include <qpoint.h> 00035 #include <qclipboard.h> 00036 #include <kapplication.h> 00037 00038 // ************************************************************************** 00039 // ************************************************************************** 00040 // ************************************************************************** 00041 00042 namespace GDBDebugger 00043 { 00044 00045 VariableWidget::VariableWidget(QWidget *parent, const char *name) 00046 : QWidget(parent, name) 00047 { 00048 varTree_ = new VariableTree(this); 00049 QLabel *label = new QLabel(i18n("E&xpression to watch:"), this); 00050 00051 QHBox *watchEntry = new QHBox( this ); 00052 00053 watchVarEditor_ = new KHistoryCombo( watchEntry, "var-to-watch editor"); 00054 label->setBuddy(watchVarEditor_); 00055 00056 // watchVarEntry_ = new KLineEdit(this); 00057 00058 QPushButton *addButton = new QPushButton(i18n("&Add"), watchEntry ); 00059 00060 QBoxLayout * vbox = new QVBoxLayout(); 00061 00062 // QBoxLayout *watchEntry = new QHBoxLayout(); 00063 // watchEntry->addWidget(label); 00064 // watchEntry->addWidget(watchVarEntry_); 00065 // watchEntry->addWidget(watchVarEditor_); 00066 // watchEntry->setStretchFactor(watchVarEditor_, 1); 00067 // watchEntry->addWidget(addButton); 00068 00069 vbox->addWidget( label ); 00070 vbox->addWidget( watchEntry ); 00071 00072 QVBoxLayout *topLayout = new QVBoxLayout(this, 2); 00073 topLayout->addWidget(varTree_, 10); 00074 topLayout->addLayout( vbox ); 00075 00076 connect( addButton, SIGNAL(clicked()), SLOT(slotAddWatchVariable()) ); 00077 connect( watchVarEditor_, SIGNAL(returnPressed()), SLOT(slotAddWatchVariable()) ); 00078 // connect( watchVarEntry_, SIGNAL(returnPressed()), SLOT(slotAddWatchVariable()) ); 00079 } 00080 00081 // ************************************************************************** 00082 00083 void VariableWidget::clear() 00084 { 00085 // varTree_->clear(); 00086 QListViewItemIterator it(varTree_); 00087 while (it.current()) 00088 { 00089 if (!dynamic_cast<WatchRoot*>(varTree_->findRoot(it.current()))) 00090 { 00091 QListViewItem *item = it.current(); 00092 delete item; 00093 } else 00094 { 00095 ++it; 00096 } 00097 } 00098 } 00099 00100 // ************************************************************************** 00101 00102 void VariableWidget::setEnabled(bool bEnabled) 00103 { 00104 QWidget::setEnabled(bEnabled); 00105 if (bEnabled && parentWidget()) { 00106 varTree_->setColumnWidth(0, parentWidget()->width()/2); 00107 } 00108 } 00109 // ************************************************************************** 00110 00111 void VariableWidget::slotAddWatchVariable() 00112 { 00113 // QString watchVar(watchVarEntry_->text()); 00114 QString watchVar(watchVarEditor_->currentText()); 00115 if (!watchVar.isEmpty()) 00116 { 00117 slotAddWatchVariable(watchVar); 00118 } 00119 } 00120 00121 // ************************************************************************** 00122 00123 void VariableWidget::slotAddWatchVariable(const QString &ident) 00124 { 00125 if (!ident.isEmpty()) 00126 { 00127 watchVarEditor_->addToHistory(ident); 00128 varTree_->slotAddWatchVariable(ident); 00129 watchVarEditor_->clearEdit(); 00130 } 00131 } 00132 00133 // ************************************************************************** 00134 // ************************************************************************** 00135 // ************************************************************************** 00136 00137 VariableTree::VariableTree(VariableWidget *parent, const char *name) 00138 : KListView(parent, name), 00139 QToolTip( viewport() ), 00140 activeFlag_(0), 00141 currentThread_(-1) 00142 { 00143 setRootIsDecorated(true); 00144 setAllColumnsShowFocus(true); 00145 setColumnWidthMode(0, Manual); 00146 setSorting(-1); 00147 QListView::setSelectionMode(QListView::Single); 00148 00149 addColumn(i18n("Variable")); 00150 addColumn(i18n("Value")); 00151 addColumn(i18n("Type")); 00152 00153 connect( this, SIGNAL(contextMenu(KListView*, QListViewItem*, const QPoint&)), 00154 SLOT(slotContextMenu(KListView*, QListViewItem*)) ); 00155 00156 /* 00157 work in progress - disabled for now 00158 00159 // jw 00160 connect( this, SIGNAL(doubleClicked(QListViewItem *item, const QPoint &pos, int c)), 00161 SLOT(slotDoubleClicked(QListViewItem *item, const QPoint &pos, int c)) ); 00162 */ 00163 } 00164 00165 // ************************************************************************** 00166 00167 VariableTree::~VariableTree() 00168 { 00169 } 00170 00171 // ************************************************************************** 00172 00173 void VariableTree::slotContextMenu(KListView *, QListViewItem *item) 00174 { 00175 if (!item) 00176 return; 00177 00178 setSelected(item, true); // Need to select this item. 00179 00180 if (item->parent()) 00181 { 00182 KPopupMenu popup(item->text(VarNameCol), this); 00183 int idRemoveWatch = -2; 00184 if (dynamic_cast<WatchRoot*>(findRoot(item))) 00185 idRemoveWatch = popup.insertItem( i18n("Remove Watch Variable") ); 00186 00187 int idToggleWatch = popup.insertItem( i18n("Toggle Watchpoint") ); 00188 int idCopyToClipboard = popup.insertItem( i18n("Copy to Clipboard") ); 00189 int res = popup.exec(QCursor::pos()); 00190 00191 if (res == idRemoveWatch) 00192 delete item; 00193 else if (res == idCopyToClipboard) 00194 { 00195 QClipboard *qb = KApplication::clipboard(); 00196 QString text = "{ \"" + item->text( 0 ) + "\", " + // name 00197 "\"" + item->text( 2 ) + "\", " + // type 00198 "\"" + item->text( 1 ) + "\" }"; // value 00199 00200 #if KDE_VERSION > 305 00201 qb->setText( text, QClipboard::Clipboard ); 00202 #else 00203 qb->setText( text ); 00204 #endif 00205 } 00206 else if (res == idToggleWatch) 00207 { 00208 if (VarItem *item = dynamic_cast<VarItem*>(currentItem())) 00209 emit toggleWatchpoint(item->fullName()); 00210 } 00211 } 00212 } 00213 00214 // ************************************************************************** 00215 00216 void VariableTree::slotAddWatchVariable(const QString &watchVar) 00217 { 00218 kdDebug(9012) << "Add watch variable: " << watchVar << endl; 00219 VarItem *varItem = new VarItem(findWatch(), watchVar, typeUnknown); 00220 emit expandItem(varItem); 00221 } 00222 00223 // ************************************************************************** 00224 00225 // jw 00226 void VariableTree::slotDoubleClicked(QListViewItem *item, const QPoint &pos, int c) 00227 { 00228 kdDebug(9012) << " ### VariableTree::slotDoubleClicked 1" << endl; 00229 00230 if (item) 00231 { 00232 kdDebug(9012) << " ### VariableTree::slotDoubleClicked 2" << endl; 00233 TrimmableItem *titem = dynamic_cast<TrimmableItem*>(item); 00234 if (titem) 00235 { 00236 kdDebug(9012) << " ### VariableTree::slotDoubleClicked 2" << endl; 00237 titem->handleDoubleClicked(pos, c); 00238 } 00239 } 00240 } 00241 00242 // ************************************************************************** 00243 00244 void VariableTree::setLocalViewState(bool localsOn, int frameNo, int threadNo) 00245 { 00246 // When they want to _close_ a frame then we need to check the state of 00247 // all other frames to determine whether we still need the locals. 00248 if (!localsOn) { 00249 QListViewItem *sibling = firstChild(); 00250 while (sibling) { 00251 VarFrameRoot *frame = dynamic_cast<VarFrameRoot*> (sibling); 00252 if (frame && frame->isOpen()) { 00253 localsOn = true; 00254 break; 00255 } 00256 00257 sibling = sibling->nextSibling(); 00258 } 00259 } 00260 00261 emit setLocalViewState(localsOn); 00262 emit selectFrame(frameNo, threadNo); 00263 } 00264 00265 00266 // ************************************************************************** 00267 00268 QListViewItem *VariableTree::findRoot(QListViewItem *item) const 00269 { 00270 while (item->parent()) 00271 item = item->parent(); 00272 00273 return item; 00274 } 00275 00276 // ************************************************************************** 00277 00278 VarFrameRoot *VariableTree::findFrame(int frameNo, int threadNo) const 00279 { 00280 QListViewItem *sibling = firstChild(); 00281 00282 // frames only exist on th top level so we only need to 00283 // check the siblings 00284 while (sibling) { 00285 VarFrameRoot *frame = dynamic_cast<VarFrameRoot*> (sibling); 00286 if (frame && frame->matchDetails(frameNo, threadNo)) 00287 return frame; 00288 00289 sibling = sibling->nextSibling(); 00290 } 00291 00292 return 0; 00293 } 00294 00295 // ************************************************************************** 00296 00297 WatchRoot *VariableTree::findWatch() 00298 { 00299 QListViewItem *sibling = firstChild(); 00300 00301 while (sibling) { 00302 if (WatchRoot *watch = dynamic_cast<WatchRoot*> (sibling)) 00303 return watch; 00304 00305 sibling = sibling->nextSibling(); 00306 } 00307 00308 return new WatchRoot(this); 00309 } 00310 00311 // ************************************************************************** 00312 00313 void VariableTree::trim() 00314 { 00315 QListViewItem *child = firstChild(); 00316 00317 while (child) { 00318 QListViewItem *nextChild = child->nextSibling(); 00319 00320 // don't trim the watch root 00321 if (!(dynamic_cast<WatchRoot*> (child))) { 00322 if (TrimmableItem *item = dynamic_cast<TrimmableItem*> (child)) { 00323 if (item->isActive()) 00324 item->trim(); 00325 else 00326 delete item; 00327 } 00328 } 00329 child = nextChild; 00330 } 00331 } 00332 00333 // ************************************************************************** 00334 00335 void VariableTree::trimExcessFrames() 00336 { 00337 viewport()->setUpdatesEnabled(false); 00338 QListViewItem *child = firstChild(); 00339 00340 while (child) { 00341 QListViewItem *nextChild = child->nextSibling(); 00342 if (VarFrameRoot *frame = dynamic_cast<VarFrameRoot*> (child)) { 00343 if (!frame->matchDetails(0, currentThread_)) 00344 delete frame; 00345 } 00346 child = nextChild; 00347 } 00348 viewport()->setUpdatesEnabled(true); 00349 repaint(); 00350 } 00351 00352 // ************************************************************************** 00353 00354 QListViewItem *VariableTree::lastChild() const 00355 { 00356 QListViewItem *child = firstChild(); 00357 if (child) 00358 while (QListViewItem *nextChild = child->nextSibling()) 00359 child = nextChild; 00360 00361 return child; 00362 } 00363 00364 // ************************************************************************** 00365 00366 void VariableTree::maybeTip(const QPoint &p) 00367 { 00368 kdDebug(9012) << "ToolTip::maybeTip()" << endl; 00369 00370 VarItem * item = dynamic_cast<VarItem*>( itemAt( p ) ); 00371 if ( item ) 00372 { 00373 QRect r = itemRect( item ); 00374 if ( r.isValid() ) 00375 tip( r, item->tipText() ); 00376 } 00377 } 00378 00379 // ************************************************************************** 00380 // ************************************************************************** 00381 // ************************************************************************** 00382 00383 TrimmableItem::TrimmableItem(VariableTree *parent) 00384 : KListViewItem (parent, parent->lastChild()), 00385 activeFlag_(0) 00386 { 00387 setActive(); 00388 } 00389 00390 // ************************************************************************** 00391 00392 TrimmableItem::TrimmableItem(TrimmableItem *parent) 00393 : KListViewItem (parent, parent->lastChild()), 00394 activeFlag_(0), 00395 waitingForData_(false) 00396 { 00397 setActive(); 00398 } 00399 00400 // ************************************************************************** 00401 00402 TrimmableItem::~TrimmableItem() 00403 { 00404 } 00405 00406 // ************************************************************************** 00407 00408 void TrimmableItem::paintCell(QPainter *p, const QColorGroup &cg, 00409 int column, int width, int align) 00410 { 00411 if ( !p ) 00412 return; 00413 // make toplevel item (watch and frame items) names bold 00414 if (column == 0 && !parent()) 00415 { 00416 QFont f = p->font(); 00417 f.setBold(true); 00418 p->setFont(f); 00419 } 00420 QListViewItem::paintCell( p, cg, column, width, align ); 00421 } 00422 00423 // ************************************************************************** 00424 00425 int TrimmableItem::rootActiveFlag() const 00426 { 00427 return ((VariableTree*)listView())->activeFlag(); 00428 } 00429 00430 // ************************************************************************** 00431 00432 bool TrimmableItem::isTrimmable() const 00433 { 00434 return !waitingForData_; 00435 } 00436 00437 // ************************************************************************** 00438 00439 QListViewItem *TrimmableItem::lastChild() const 00440 { 00441 QListViewItem *child = firstChild(); 00442 if (child) 00443 while (QListViewItem *nextChild = child->nextSibling()) 00444 child = nextChild; 00445 00446 return child; 00447 } 00448 00449 // ************************************************************************** 00450 00451 TrimmableItem *TrimmableItem::findMatch(const QString &match, DataType type) const 00452 { 00453 QListViewItem *child = firstChild(); 00454 00455 // Check the siblings on this branch 00456 while (child) { 00457 if (child->text(VarNameCol) == match) { 00458 if (TrimmableItem *item = dynamic_cast<TrimmableItem*> (child)) 00459 if (item->getDataType() == type) 00460 return item; 00461 } 00462 00463 child = child->nextSibling(); 00464 } 00465 00466 return 0; 00467 } 00468 00469 // ************************************************************************** 00470 00471 void TrimmableItem::trim() 00472 { 00473 QListViewItem *child = firstChild(); 00474 00475 while (child) { 00476 QListViewItem *nextChild = child->nextSibling(); 00477 if (TrimmableItem *item = dynamic_cast<TrimmableItem*>(child)) { 00478 // Never trim a branch if we are waiting on data to arrive. 00479 if (isTrimmable()) { 00480 if (item->isActive()) 00481 item->trim(); // recurse 00482 else 00483 delete item; 00484 } 00485 } 00486 child = nextChild; 00487 } 00488 } 00489 00490 // ************************************************************************** 00491 00492 DataType TrimmableItem::getDataType() const 00493 { 00494 return typeUnknown; 00495 } 00496 00497 // ************************************************************************** 00498 00499 void TrimmableItem::setCache(const QCString&) 00500 { 00501 Q_ASSERT(false); 00502 } 00503 00504 // ************************************************************************** 00505 00506 QCString TrimmableItem::getCache() 00507 { 00508 Q_ASSERT(false); 00509 return QCString(); 00510 } 00511 00512 // ************************************************************************** 00513 00514 void TrimmableItem::updateValue(char* /* buf */) 00515 { 00516 waitingForData_ = false; 00517 } 00518 00519 // ************************************************************************** 00520 00521 QString TrimmableItem::key (int, bool) const 00522 { 00523 return QString::null; 00524 } 00525 00526 // ************************************************************************** 00527 // ************************************************************************** 00528 // ************************************************************************** 00529 00530 VarItem::VarItem(TrimmableItem *parent, const QString &varName, DataType dataType) 00531 : TrimmableItem (parent), 00532 cache_(QCString()), 00533 dataType_(dataType), 00534 highlight_(false) 00535 { 00536 setText(VarNameCol, varName); 00537 00538 /* 00539 setRenameEnabled(VarTypeCol, true); 00540 setRenameEnabled(VarNameCol, true); 00541 */ 00542 00543 kdDebug(9012) << " ### VarItem::VarItem *CONSTR*" << endl; 00544 emit ((VariableTree*)listView())->varItemConstructed(this); 00545 } 00546 00547 // ************************************************************************** 00548 00549 VarItem::~VarItem() 00550 { 00551 } 00552 00553 // ************************************************************************** 00554 00555 QString VarItem::varPath() const 00556 { 00557 QString vPath(""); 00558 const VarItem *item = this; 00559 00560 // This stops at the root item (FrameRoot or WatchRoot) 00561 while ((item = dynamic_cast<const VarItem*> (item->parent()))) { 00562 if (item->getDataType() != typeArray) { 00563 if ((item->text(VarNameCol))[0] != '<') { 00564 QString itemName = item->text(VarNameCol); 00565 if (vPath.isEmpty()) 00566 vPath = itemName.replace(QRegExp("^static "), ""); 00567 else 00568 vPath = itemName.replace(QRegExp("^static "), "") + "." + vPath; 00569 } 00570 } 00571 } 00572 00573 return vPath; 00574 } 00575 00576 // ************************************************************************** 00577 00578 QString VarItem::fullName() const 00579 { 00580 QString itemName = getName(); 00581 QString vPath = varPath(); 00582 if (itemName[0] == '<') 00583 return vPath; 00584 00585 if (vPath.isEmpty()) 00586 return itemName.replace(QRegExp("^static "), ""); 00587 00588 return varPath() + "." + itemName.replace(QRegExp("^static "), ""); 00589 } 00590 00591 // ************************************************************************** 00592 00593 void VarItem::setText(int column, const QString &data) 00594 { 00595 if (!isActive() && isOpen() && dataType_ == typePointer) { 00596 waitingForData(); 00597 ((VariableTree*)listView())->expandItem(this); 00598 } 00599 00600 setActive(); 00601 if (column == ValueCol) { 00602 QString oldValue(text(column)); 00603 if (!oldValue.isEmpty()) // Don't highlight new items 00604 highlight_ = (oldValue != QString(data)); 00605 } 00606 00607 QListViewItem::setText(column, data); 00608 repaint(); 00609 } 00610 00611 // ************************************************************************** 00612 00613 void VarItem::updateValue(char *buf) 00614 { 00615 TrimmableItem::updateValue(buf); 00616 00617 // Hack due to my bad QString implementation - this just tidies up the display 00618 if ((strncmp(buf, "There is no member named len.", 29) == 0) || 00619 (strncmp(buf, "There is no member or method named len.", 39) == 0)) 00620 return; 00621 00622 if (*buf == '$') { 00623 if (char *end = strchr(buf, '=')) 00624 buf = end+2; 00625 } 00626 00627 if (dataType_ == typeUnknown) { 00628 dataType_ = GDBParser::getGDBParser()->determineType(buf); 00629 if (dataType_ == typeArray) 00630 buf++; 00631 00632 // Try fixing a format string here by overriding the dataType calculated 00633 // from this data 00634 QString varName = getName(); 00635 if (dataType_ == typePointer && varName[0] == '/') 00636 dataType_ = typeValue; 00637 } 00638 00639 GDBParser::getGDBParser()->parseData(this, buf, true, false); 00640 setActive(); 00641 } 00642 00643 // ************************************************************************** 00644 00645 void VarItem::updateType(char *buf) 00646 { 00647 kdDebug(9012) << " ### VarItem::updateType " << buf << endl; 00648 00649 QString str(buf); 00650 int eq = str.find('='); 00651 if (eq < 0) 00652 return; 00653 str.replace(QRegExp("[\n\r]"),""); 00654 str = str.mid(eq + 1, 0xffff).stripWhiteSpace(); 00655 00656 originalValueType_ = str.latin1(); 00657 00658 setText(VarTypeCol, str); 00659 } 00660 00661 // ************************************************************************** 00662 00663 void VarItem::handleDoubleClicked(const QPoint &/*pos*/, int c) 00664 { 00665 kdDebug(9012) << " ### VarItem::handleDoubleClicked 1" << endl; 00666 if (c == VarTypeCol || c == ValueCol) 00667 { 00668 kdDebug(9012) << " ### VarItem::handleDoubleClicked 2" << endl; 00669 static_cast<KListView*>(listView())->rename(this, c); 00670 } 00671 } 00672 00673 // ************************************************************************** 00674 00675 void VarItem::setCache(const QCString &value) 00676 { 00677 cache_ = value; 00678 setExpandable(true); 00679 checkForRequests(); 00680 if (isOpen()) 00681 setOpen(true); 00682 setActive(); 00683 } 00684 00685 // ************************************************************************** 00686 00687 void VarItem::setOpen(bool open) 00688 { 00689 if (open) { 00690 if (cache_) { 00691 QCString value = cache_; 00692 cache_ = QCString(); 00693 GDBParser::getGDBParser()->parseData(this, value.data(), false, false); 00694 trim(); 00695 } else { 00696 if (dataType_ == typePointer || dataType_ == typeReference) { 00697 waitingForData(); 00698 emit ((VariableTree*)listView())->expandItem(this); 00699 } 00700 } 00701 } 00702 00703 QListViewItem::setOpen(open); 00704 } 00705 00706 // ************************************************************************** 00707 00708 QCString VarItem::getCache() 00709 { 00710 return cache_; 00711 } 00712 00713 // ************************************************************************** 00714 00715 void VarItem::checkForRequests() 00716 { 00717 // This shouldn't be needed to keep it from blowing up, but sometimes is. 00718 // On the other hand, if it's empty, there is no reason to go on... 00719 if ( cache_.isEmpty() ) return; 00720 00722 00723 // Signature for a QT1.44 QString 00724 if (strncmp(cache_, "<QArrayT<char>> = {<QGArray> = {shd = ", 38) == 0) { 00725 waitingForData(); 00726 emit ((VariableTree*)listView())->expandUserItem(this, 00727 fullName().latin1()+QCString(".shd.data")); 00728 } 00729 00730 // Signature for a QT1.44 QDir 00731 if (strncmp(cache_, "dPath = {<QArrayT<char>> = {<QGArray> = {shd", 44) == 0) { 00732 waitingForData(); 00733 emit ((VariableTree*)listView())->expandUserItem(this, 00734 fullName().latin1()+QCString(".dPath.shd.data")); 00735 } 00736 00737 // Signature for a QT2.x QT3.x QString 00739 // at the moment to leave it here, and it won't cause bad things to happen. 00740 if (strncmp(cache_, "d = 0x", 6) == 0) { // Eeeek - too small 00741 waitingForData(); 00742 emit ((VariableTree*)listView())->expandUserItem(this, 00743 // QCString().sprintf("(($len=($data=%s.d).len)?$data.unicode.rw@($len>100?200:$len*2):\"\")", 00744 QCString().sprintf("(($len=($data=%s.d).len)?*((char*)&$data.unicode[0])@($len>100?200:$len*2):\"\")", 00745 fullName().latin1())); 00746 } 00747 00748 // Signature for a QT2.0.x QT2.1 QCString 00749 if (strncmp(cache_, "<QArray<char>> = {<QGArray> = {shd = ", 37) == 0) { 00750 waitingForData(); 00751 emit ((VariableTree*)listView())->expandUserItem(this, 00752 fullName().latin1()+QCString(".shd.data")); 00753 } 00754 00755 // Signature for a QT2.0.x QT2.1 QDir 00756 if (strncmp(cache_, "dPath = {d = 0x", 15) == 0) { 00757 waitingForData(); 00758 ((VariableTree*)listView())->expandUserItem(this, 00759 // QCString().sprintf("(($len=($data=%s.dPath.d).len)?$data.unicode.rw@($len>100?200:$len*2):\"\")", 00760 QCString().sprintf("(($len=($data=%s.dPath.d).len)?*((char*)&$data.unicode[0])@($len>100?200:$len*2):\"\")", 00761 fullName().latin1())); 00762 } 00763 } 00764 00765 // ************************************************************************** 00766 00767 DataType VarItem::getDataType() const 00768 { 00769 return dataType_; 00770 } 00771 00772 // ************************************************************************** 00773 00774 // Overridden to highlight the changed items 00775 void VarItem::paintCell(QPainter *p, const QColorGroup &cg, 00776 int column, int width, int align) 00777 { 00778 if ( !p ) 00779 return; 00780 00781 if (column == ValueCol && highlight_) { 00782 QColorGroup hl_cg( cg.foreground(), cg.background(), cg.light(), 00783 cg.dark(), cg.mid(), red, cg.base()); 00784 QListViewItem::paintCell( p, hl_cg, column, width, align ); 00785 } else 00786 QListViewItem::paintCell( p, cg, column, width, align ); 00787 } 00788 00789 // ************************************************************************** 00790 00791 QString VarItem::tipText() const 00792 { 00793 const unsigned int maxTooltipSize = 70; 00795 QString tip = text( 1 ); 00796 00797 if (tip.length() < maxTooltipSize ) 00798 return tip; 00799 else 00800 return tip.mid( 0, maxTooltipSize - 1 ) + " [...]"; 00801 } 00802 00803 // ************************************************************************** 00804 // ************************************************************************** 00805 // ************************************************************************** 00806 00807 VarFrameRoot::VarFrameRoot(VariableTree *parent, int frameNo, int threadNo) 00808 : TrimmableItem (parent), 00809 needLocals_(true), 00810 frameNo_(frameNo), 00811 threadNo_(threadNo), 00812 params_(QCString()), 00813 locals_(QCString()) 00814 { 00815 setExpandable(true); 00816 } 00817 00818 // ************************************************************************** 00819 00820 VarFrameRoot::~VarFrameRoot() 00821 { 00822 } 00823 00824 // ************************************************************************** 00825 00826 void VarFrameRoot::setParams(char *params) 00827 { 00828 setActive(); 00829 params_ = params; 00830 } 00831 00832 // ************************************************************************** 00833 00834 void VarFrameRoot::setLocals(char *locals) 00835 { 00836 setActive(); 00837 00838 // "No symbol table info available" or "No locals." 00839 bool noLocals = (locals && (strncmp(locals, "No ", 3) == 0)); 00840 setExpandable(!params_.isEmpty() || !noLocals); 00841 00842 if (noLocals) { 00843 locals_ = ""; 00844 if (locals) 00845 if (char *end = strchr(locals, '\n')) 00846 *end = 0; // clobber the new line 00847 } else 00848 locals_ = locals; 00849 00850 if (!isExpandable() && noLocals) 00851 setText( ValueCol, locals ); 00852 00853 needLocals_ = false; 00854 if (isOpen()) 00855 setOpen(true); 00856 } 00857 00858 // ************************************************************************** 00859 00860 // Override setOpen so that we can decide what to do when we do change 00861 // state. This 00862 void VarFrameRoot::setOpen(bool open) 00863 { 00864 bool localStateChange = (isOpen() != open); 00865 QListViewItem::setOpen(open); 00866 00867 if (localStateChange) 00868 ((VariableTree*)listView())->setLocalViewState(open, frameNo_, threadNo_); 00869 00870 if (!open) 00871 return; 00872 00873 GDBParser::getGDBParser()->parseData(this, params_.data(), false, true); 00874 GDBParser::getGDBParser()->parseData(this, locals_.data(), false, false); 00875 00876 locals_ = QCString(); 00877 params_ = QCString(); 00878 } 00879 00880 // ************************************************************************** 00881 00882 bool VarFrameRoot::matchDetails(int frameNo, int threadNo) 00883 { 00884 return frameNo == frameNo_ && threadNo == threadNo_; 00885 } 00886 00887 // ************************************************************************** 00888 // ************************************************************************** 00889 // ************************************************************************** 00890 // ************************************************************************** 00891 00892 WatchRoot::WatchRoot(VariableTree *parent) 00893 : TrimmableItem(parent) 00894 { 00895 setText(0, i18n("Watch")); 00896 setOpen(true); 00897 } 00898 00899 // ************************************************************************** 00900 00901 WatchRoot::~WatchRoot() 00902 { 00903 } 00904 00905 // ************************************************************************** 00906 00907 void WatchRoot::requestWatchVars() 00908 { 00909 for (QListViewItem *child = firstChild(); child; child = child->nextSibling()) 00910 if (VarItem *varItem = dynamic_cast<VarItem*>(child)) 00911 emit ((VariableTree*)listView())->expandItem(varItem); 00912 } 00913 00914 // ************************************************************************** 00915 // ************************************************************************** 00916 // ************************************************************************** 00917 00918 } 00919 00920 #include "variablewidget.moc"
KDE Logo
This file is part of the documentation for KDevelop Version 3.0.4.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Oct 19 08:01:43 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003