00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "variablewidget.h"
00017 #include "gdbparser.h"
00018 #include "gdbcommand.h"
00019
00020 #include <kdebug.h>
00021 #include <kpopupmenu.h>
00022 #include <klineedit.h>
00023 #include <kdeversion.h>
00024
00025 #include <qheader.h>
00026 #include <qlabel.h>
00027 #include <qlayout.h>
00028 #include <qhbox.h>
00029 #include <qpainter.h>
00030 #include <qpushbutton.h>
00031 #include <qregexp.h>
00032 #include <qcursor.h>
00033 #include <klocale.h>
00034
00035 #include <qpoint.h>
00036 #include <qclipboard.h>
00037 #include <kapplication.h>
00038
00039
00040
00041
00042
00043 namespace GDBDebugger
00044 {
00045
00046 VariableWidget::VariableWidget(QWidget *parent, const char *name)
00047 : QWidget(parent, name)
00048 {
00049 varTree_ = new VariableTree(this);
00050 QLabel *label = new QLabel(i18n("E&xpression to watch:"), this);
00051
00052 QHBox *watchEntry = new QHBox( this );
00053
00054 watchVarEditor_ = new KHistoryCombo( watchEntry, "var-to-watch editor");
00055 label->setBuddy(watchVarEditor_);
00056
00057
00058
00059 QPushButton *addButton = new QPushButton(i18n("&Add"), watchEntry );
00060 addButton->adjustSize();
00061 addButton->setFixedWidth(addButton->width());
00062
00063 QBoxLayout * vbox = new QVBoxLayout();
00064
00065
00066
00067
00068
00069
00070
00071
00072 vbox->addWidget( label );
00073 vbox->addWidget( watchEntry );
00074
00075 QVBoxLayout *topLayout = new QVBoxLayout(this, 2);
00076 topLayout->addWidget(varTree_, 10);
00077 topLayout->addLayout( vbox );
00078
00079 connect( addButton, SIGNAL(clicked()), SLOT(slotAddWatchVariable()) );
00080 connect( watchVarEditor_, SIGNAL(returnPressed()), SLOT(slotAddWatchVariable()) );
00081
00082
00083 }
00084
00085
00086
00087 void VariableWidget::clear()
00088 {
00089
00090 QListViewItemIterator it(varTree_);
00091 while (it.current())
00092 {
00093 if (!dynamic_cast<WatchRoot*>(varTree_->findRoot(it.current())))
00094 {
00095 QListViewItem *item = it.current();
00096 delete item;
00097 } else
00098 {
00099 ++it;
00100 }
00101 }
00102 }
00103
00104
00105
00106 void VariableWidget::setEnabled(bool bEnabled)
00107 {
00108 QWidget::setEnabled(bEnabled);
00109 if (bEnabled && parentWidget()) {
00110 varTree_->setColumnWidth(0, parentWidget()->width()/2);
00111 }
00112 }
00113
00114
00115 void VariableWidget::slotAddWatchVariable()
00116 {
00117
00118 QString watchVar(watchVarEditor_->currentText());
00119 if (!watchVar.isEmpty())
00120 {
00121 slotAddWatchVariable(watchVar);
00122 }
00123 }
00124
00125
00126
00127 void VariableWidget::slotAddWatchVariable(const QString &ident)
00128 {
00129 if (!ident.isEmpty())
00130 {
00131 watchVarEditor_->addToHistory(ident);
00132 varTree_->slotAddWatchVariable(ident);
00133 watchVarEditor_->clearEdit();
00134 }
00135 }
00136
00137
00138
00139 void VariableWidget::focusInEvent(QFocusEvent *)
00140 {
00141 varTree_->setFocus();
00142 }
00143
00144
00145
00146
00147
00148
00149 VariableTree::VariableTree(VariableWidget *parent, const char *name)
00150 : KListView(parent, name),
00151 QToolTip( viewport() ),
00152 activeFlag_(0),
00153 currentThread_(-1)
00154 {
00155 setRootIsDecorated(true);
00156 setAllColumnsShowFocus(true);
00157 setColumnWidthMode(0, Manual);
00158 setSorting(-1);
00159 QListView::setSelectionMode(QListView::Single);
00160
00161 addColumn(i18n("Variable"), 100 );
00162 addColumn(i18n("Value"), 100 );
00163 addColumn(i18n("Type"), 100 );
00164
00165 connect( this, SIGNAL(contextMenu(KListView*, QListViewItem*, const QPoint&)),
00166 SLOT(slotContextMenu(KListView*, QListViewItem*)) );
00167 connect( this, SIGNAL(toggleRadix(QListViewItem*)), SLOT(slotToggleRadix(QListViewItem*)) );
00168
00169
00170
00171
00172
00173
00174
00175
00176 }
00177
00178
00179
00180 VariableTree::~VariableTree()
00181 {
00182 }
00183
00184
00185
00186 void VariableTree::slotContextMenu(KListView *, QListViewItem *item)
00187 {
00188 if (!item)
00189 return;
00190
00191 setSelected(item, true);
00192
00193 if (item->parent())
00194 {
00195 KPopupMenu popup(item->text(VarNameCol), this);
00196 int idRemoveWatch = -2;
00197 if (dynamic_cast<WatchRoot*>(findRoot(item)))
00198 idRemoveWatch = popup.insertItem( i18n("Remove Watch Variable") );
00199
00200 int idToggleWatch = popup.insertItem( i18n("Toggle Watchpoint") );
00201 int idToggleRadix = popup.insertItem( i18n("Toggle Hex/Decimal") );
00202 int idCopyToClipboard = popup.insertItem( i18n("Copy to Clipboard") );
00203 int res = popup.exec(QCursor::pos());
00204
00205 if (res == idRemoveWatch)
00206 delete item;
00207 if (res == idToggleRadix)
00208 emit toggleRadix(item);
00209 else if (res == idCopyToClipboard)
00210 {
00211 QClipboard *qb = KApplication::clipboard();
00212 QString text = "{ \"" + item->text( 0 ) + "\", " +
00213 "\"" + item->text( 2 ) + "\", " +
00214 "\"" + item->text( 1 ) + "\" }";
00215
00216 #if KDE_VERSION > 305
00217 qb->setText( text, QClipboard::Clipboard );
00218 #else
00219 qb->setText( text );
00220 #endif
00221 }
00222 else if (res == idToggleWatch)
00223 {
00224 if (VarItem *item = dynamic_cast<VarItem*>(currentItem()))
00225 emit toggleWatchpoint(item->fullName());
00226 }
00227 }
00228 }
00229
00230
00231
00232 void VariableTree::slotAddWatchVariable(const QString &watchVar)
00233 {
00234 kdDebug(9012) << "Add watch variable: " << watchVar << endl;
00235 VarItem *varItem = new VarItem(findWatch(), watchVar, typeUnknown);
00236 emit expandItem(varItem);
00237 }
00238
00239
00240
00241
00242 void VariableTree::slotDoubleClicked(QListViewItem *item, const QPoint &pos, int c)
00243 {
00244 kdDebug(9012) << " ### VariableTree::slotDoubleClicked 1" << endl;
00245
00246 if (item)
00247 {
00248 kdDebug(9012) << " ### VariableTree::slotDoubleClicked 2" << endl;
00249 TrimmableItem *titem = dynamic_cast<TrimmableItem*>(item);
00250 if (titem)
00251 {
00252 kdDebug(9012) << " ### VariableTree::slotDoubleClicked 2" << endl;
00253 titem->handleDoubleClicked(pos, c);
00254 }
00255 }
00256 }
00257
00258
00259
00260 void VariableTree::setLocalViewState(bool localsOn, int frameNo, int threadNo)
00261 {
00262
00263
00264 if (!localsOn) {
00265 QListViewItem *sibling = firstChild();
00266 while (sibling) {
00267 VarFrameRoot *frame = dynamic_cast<VarFrameRoot*> (sibling);
00268 if (frame && frame->isOpen()) {
00269 localsOn = true;
00270 break;
00271 }
00272
00273 sibling = sibling->nextSibling();
00274 }
00275 }
00276
00277 emit setLocalViewState(localsOn);
00278 emit selectFrame(frameNo, threadNo);
00279 }
00280
00281
00282
00283
00284 QListViewItem *VariableTree::findRoot(QListViewItem *item) const
00285 {
00286 while (item->parent())
00287 item = item->parent();
00288
00289 return item;
00290 }
00291
00292
00293
00294 VarFrameRoot *VariableTree::findFrame(int frameNo, int threadNo) const
00295 {
00296 QListViewItem *sibling = firstChild();
00297
00298
00299
00300 while (sibling) {
00301 VarFrameRoot *frame = dynamic_cast<VarFrameRoot*> (sibling);
00302 if (frame && frame->matchDetails(frameNo, threadNo))
00303 return frame;
00304
00305 sibling = sibling->nextSibling();
00306 }
00307
00308 return 0;
00309 }
00310
00311
00312
00313 WatchRoot *VariableTree::findWatch()
00314 {
00315 QListViewItem *sibling = firstChild();
00316
00317 while (sibling) {
00318 if (WatchRoot *watch = dynamic_cast<WatchRoot*> (sibling))
00319 return watch;
00320
00321 sibling = sibling->nextSibling();
00322 }
00323
00324 return new WatchRoot(this);
00325 }
00326
00327
00328
00329 void VariableTree::trim()
00330 {
00331 QListViewItem *child = firstChild();
00332
00333 while (child) {
00334 QListViewItem *nextChild = child->nextSibling();
00335
00336
00337 if (!(dynamic_cast<WatchRoot*> (child))) {
00338 if (TrimmableItem *item = dynamic_cast<TrimmableItem*> (child)) {
00339 if (item->isActive())
00340 item->trim();
00341 else
00342 delete item;
00343 }
00344 }
00345 child = nextChild;
00346 }
00347 }
00348
00349
00350
00351 void VariableTree::trimExcessFrames()
00352 {
00353 viewport()->setUpdatesEnabled(false);
00354 QListViewItem *child = firstChild();
00355
00356 while (child) {
00357 QListViewItem *nextChild = child->nextSibling();
00358 if (VarFrameRoot *frame = dynamic_cast<VarFrameRoot*> (child)) {
00359 if (!frame->matchDetails(0, currentThread_))
00360 delete frame;
00361 }
00362 child = nextChild;
00363 }
00364 viewport()->setUpdatesEnabled(true);
00365 repaint();
00366 }
00367
00368
00369
00370 QListViewItem *VariableTree::lastChild() const
00371 {
00372 QListViewItem *child = firstChild();
00373 if (child)
00374 while (QListViewItem *nextChild = child->nextSibling())
00375 child = nextChild;
00376
00377 return child;
00378 }
00379
00380
00381
00382 void VariableTree::maybeTip(const QPoint &p)
00383 {
00384 kdDebug(9012) << "ToolTip::maybeTip()" << endl;
00385
00386 VarItem * item = dynamic_cast<VarItem*>( itemAt( p ) );
00387 if ( item )
00388 {
00389 QRect r = itemRect( item );
00390 if ( r.isValid() )
00391 tip( r, item->tipText() );
00392 }
00393 }
00394
00395
00396
00397
00398
00399
00400 void VariableTree::slotToggleRadix(QListViewItem * item)
00401 {
00402 if (item==NULL)
00403 return;
00404
00405 VarItem *pOldItem = dynamic_cast<VarItem*>(item);
00406 VarItem *pNewItem = NULL;
00407
00408 QString strName = pOldItem->text(VarNameCol);
00409
00410 QString strTmp = strName.left(3).lower();
00411 if (iOutRadix == 10) {
00412 if (strTmp == "/d ")
00413 strName = "/x "+strName.right(strName.length()-3);
00414 else if (strTmp == "/x ")
00415 strName = strName.right(strName.length()-3);
00416 else
00417 strName = QString("/x ")+strName;
00418 } else
00419 if (iOutRadix == 16) {
00420 if (strTmp == "/x ")
00421 strName = "/d "+strName.right(strName.length()-3);
00422 else if (strTmp == "/d ")
00423 strName = strName.right(strName.length()-3);
00424 else
00425 strName = QString("/d ")+strName;
00426 }
00427
00428 pNewItem = new VarItem((TrimmableItem *) item->parent(), strName, typeUnknown);
00429 emit expandItem(pNewItem);
00430
00431 pNewItem->moveItem(pOldItem);
00432
00433 delete item;
00434 pOldItem=NULL;
00435 }
00436
00437
00438
00439
00440
00441 TrimmableItem::TrimmableItem(VariableTree *parent)
00442 : KListViewItem (parent, parent->lastChild()),
00443 activeFlag_(0)
00444 {
00445 setActive();
00446 }
00447
00448
00449
00450 TrimmableItem::TrimmableItem(TrimmableItem *parent)
00451 : KListViewItem (parent, parent->lastChild()),
00452 activeFlag_(0),
00453 waitingForData_(false)
00454 {
00455 setActive();
00456 }
00457
00458
00459
00460 TrimmableItem::~TrimmableItem()
00461 {
00462 }
00463
00464
00465
00466 void TrimmableItem::paintCell(QPainter *p, const QColorGroup &cg,
00467 int column, int width, int align)
00468 {
00469 if ( !p )
00470 return;
00471
00472 if (column == 0 && !parent())
00473 {
00474 QFont f = p->font();
00475 f.setBold(true);
00476 p->setFont(f);
00477 }
00478 QListViewItem::paintCell( p, cg, column, width, align );
00479 }
00480
00481
00482
00483 int TrimmableItem::rootActiveFlag() const
00484 {
00485 return ((VariableTree*)listView())->activeFlag();
00486 }
00487
00488
00489
00490 bool TrimmableItem::isTrimmable() const
00491 {
00492 return !waitingForData_;
00493 }
00494
00495
00496
00497 QListViewItem *TrimmableItem::lastChild() const
00498 {
00499 QListViewItem *child = firstChild();
00500 if (child)
00501 while (QListViewItem *nextChild = child->nextSibling())
00502 child = nextChild;
00503
00504 return child;
00505 }
00506
00507
00508
00509 TrimmableItem *TrimmableItem::findMatch(const QString &match, DataType type) const
00510 {
00511 QListViewItem *child = firstChild();
00512 bool bRenew=false;
00513
00514
00515
00516
00517 int iOutRad = ((VariableTree*)listView())->iOutRadix;
00518
00519
00520 while (child) {
00521 QString strMatch = child->text(VarNameCol);
00522 bRenew=false;
00523 if (strMatch.left(3) == "/x " || strMatch.left(3) == "/d ") {
00524 strMatch = strMatch.right(strMatch.length()-3);
00525 bRenew=true;
00526 }
00527 if (strMatch == match) {
00528 if (TrimmableItem *item = dynamic_cast<TrimmableItem*> (child))
00529 if ( item->getDataType() == type ||
00530 ( iOutRad==16 && item->getDataType() == typeValue ) ||
00531 ( iOutRad==10 && item->getDataType() == typePointer ) ) {
00532 if (bRenew && dynamic_cast<VarItem*>(item)) {
00533 VarItem* pNewItem = new VarItem((TrimmableItem *) item->parent(),
00534 child->text(VarNameCol), typeUnknown);
00535 emit ((VariableTree*)pNewItem->listView())->expandItem(pNewItem);
00536 pNewItem->moveItem(item);
00537 delete item;
00538 item=NULL;
00539 item=pNewItem;
00540 }
00541 return item;
00542 }
00543 }
00544
00545 child = child->nextSibling();
00546 }
00547
00548 return 0;
00549 }
00550
00551
00552
00553 void TrimmableItem::trim()
00554 {
00555 QListViewItem *child = firstChild();
00556
00557 while (child) {
00558 QListViewItem *nextChild = child->nextSibling();
00559 if (TrimmableItem *item = dynamic_cast<TrimmableItem*>(child)) {
00560
00561 if (isTrimmable()) {
00562 if (item->isActive())
00563 item->trim();
00564 else
00565 delete item;
00566 }
00567 }
00568 child = nextChild;
00569 }
00570 }
00571
00572
00573
00574 DataType TrimmableItem::getDataType() const
00575 {
00576 return typeUnknown;
00577 }
00578
00579
00580
00581 void TrimmableItem::setCache(const QCString&)
00582 {
00583 Q_ASSERT(false);
00584 }
00585
00586
00587
00588 QCString TrimmableItem::getCache()
00589 {
00590 Q_ASSERT(false);
00591 return QCString();
00592 }
00593
00594
00595
00596 void TrimmableItem::updateValue(char* )
00597 {
00598 waitingForData_ = false;
00599 }
00600
00601
00602
00603 QString TrimmableItem::key (int, bool) const
00604 {
00605 return QString::null;
00606 }
00607
00608
00609
00610
00611
00612 VarItem::VarItem(TrimmableItem *parent, const QString &varName, DataType dataType)
00613 : TrimmableItem (parent),
00614 cache_(QCString()),
00615 dataType_(dataType),
00616 highlight_(false)
00617 {
00618 setText(VarNameCol, varName);
00619
00620
00621
00622
00623
00624
00625 kdDebug(9012) << " ### VarItem::VarItem *CONSTR*" << endl;
00626 emit ((VariableTree*)listView())->varItemConstructed(this);
00627 }
00628
00629
00630
00631 VarItem::~VarItem()
00632 {
00633 }
00634
00635
00636
00637 QString VarItem::varPath() const
00638 {
00639 QString vPath("");
00640 const VarItem *item = this;
00641
00642
00643 while ((item = dynamic_cast<const VarItem*> (item->parent()))) {
00644 if (item->getDataType() != typeArray) {
00645 if ((item->text(VarNameCol))[0] != '<') {
00646 QString itemName = item->text(VarNameCol);
00647 if (vPath.isEmpty())
00648 vPath = itemName.replace(QRegExp("^static "), "");
00649 else
00650 vPath = itemName.replace(QRegExp("^static "), "") + "." + vPath;
00651 }
00652 }
00653 }
00654
00655 return vPath;
00656 }
00657
00658
00659
00660 QString VarItem::fullName() const
00661 {
00662 QString itemName = getName();
00663 QString vPath = varPath();
00664 if (itemName[0] == '<')
00665 return vPath;
00666
00667 if (vPath.isEmpty())
00668 return itemName.replace(QRegExp("^static "), "");
00669
00670 return varPath() + "." + itemName.replace(QRegExp("^static "), "");
00671 }
00672
00673
00674
00675 void VarItem::setText(int column, const QString &data)
00676 {
00677 QString strData=data;
00678
00679 if (!isActive() && isOpen() && dataType_ == typePointer) {
00680 waitingForData();
00681 ((VariableTree*)listView())->expandItem(this);
00682 }
00683
00684 setActive();
00685 if (column == ValueCol) {
00686 QString oldValue(text(column));
00687 if (!oldValue.isEmpty())
00688 highlight_ = (oldValue != QString(data));
00689 }
00690
00691 QListViewItem::setText(column, strData);
00692 repaint();
00693 }
00694
00695
00696
00697 void VarItem::updateValue(char *buf)
00698 {
00699 TrimmableItem::updateValue(buf);
00700
00701
00702 if ((strncmp(buf, "There is no member named len.", 29) == 0) ||
00703 (strncmp(buf, "There is no member or method named len.", 39) == 0))
00704 return;
00705
00706 if (strncmp(buf, "Cannot access memory at address", 31) == 0 &&
00707 dataType_ == typePointer &&
00708 ((VariableTree*)listView())->iOutRadix == 16) {
00709 dataType_ = typeValue;
00710 ((VariableTree*)listView())->expandItem(this);
00711 return;
00712 }
00713
00714 if (*buf == '$') {
00715 if (char *end = strchr(buf, '='))
00716 buf = end+2;
00717 }
00718
00719 if (dataType_ == typeUnknown) {
00720 dataType_ = GDBParser::getGDBParser()->determineType(buf);
00721 if (dataType_ == typeArray)
00722 buf++;
00723
00724
00725
00726 QString varName = getName();
00727 if (dataType_ == typePointer && varName[0] == '/')
00728 dataType_ = typeValue;
00729 }
00730
00731 GDBParser::getGDBParser()->parseData(this, buf, true, false);
00732 setActive();
00733 }
00734
00735
00736
00737 void VarItem::updateType(char *buf)
00738 {
00739 kdDebug(9012) << " ### VarItem::updateType " << buf << endl;
00740
00741 QString str(buf);
00742 int eq = str.find('=');
00743 if (eq < 0)
00744 return;
00745 str.replace(QRegExp("[\n\r]"),"");
00746 str = str.mid(eq + 1, 0xffff).stripWhiteSpace();
00747
00748 originalValueType_ = str.latin1();
00749
00750 setText(VarTypeCol, str);
00751 }
00752
00753
00754
00755 void VarItem::handleDoubleClicked(const QPoint &, int c)
00756 {
00757 kdDebug(9012) << " ### VarItem::handleDoubleClicked 1" << endl;
00758 if (c == VarTypeCol || c == ValueCol)
00759 {
00760 kdDebug(9012) << " ### VarItem::handleDoubleClicked 2" << endl;
00761 static_cast<KListView*>(listView())->rename(this, c);
00762 }
00763 }
00764
00765
00766
00767 void VarItem::setCache(const QCString &value)
00768 {
00769 cache_ = value;
00770 setExpandable(true);
00771 checkForRequests();
00772 if (isOpen())
00773 setOpen(true);
00774 setActive();
00775 }
00776
00777
00778
00779 void VarItem::setOpen(bool open)
00780 {
00781 if (open) {
00782 if (cache_) {
00783 QCString value = cache_;
00784 cache_ = QCString();
00785 GDBParser::getGDBParser()->parseData(this, value.data(), false, false);
00786 trim();
00787 } else {
00788 if (dataType_ == typePointer || dataType_ == typeReference) {
00789 waitingForData();
00790 emit ((VariableTree*)listView())->expandItem(this);
00791 }
00792 }
00793 }
00794
00795 QListViewItem::setOpen(open);
00796 }
00797
00798
00799
00800 QCString VarItem::getCache()
00801 {
00802 return cache_;
00803 }
00804
00805
00806
00807 void VarItem::checkForRequests()
00808 {
00809
00810
00811 if ( cache_.isEmpty() ) return;
00812
00814
00815
00816 if (strncmp(cache_, "<QArrayT<char>> = {<QGArray> = {shd = ", 38) == 0) {
00817 waitingForData();
00818 emit ((VariableTree*)listView())->expandUserItem(this,
00819 fullName().latin1()+QCString(".shd.data"));
00820 }
00821
00822
00823 if (strncmp(cache_, "dPath = {<QArrayT<char>> = {<QGArray> = {shd", 44) == 0) {
00824 waitingForData();
00825 emit ((VariableTree*)listView())->expandUserItem(this,
00826 fullName().latin1()+QCString(".dPath.shd.data"));
00827 }
00828
00829
00831
00832 if (strncmp(cache_, "d = 0x", 6) == 0) {
00833 waitingForData();
00834 emit ((VariableTree*)listView())->expandUserItem(this,
00835
00836 QCString().sprintf("(($len=($data=%s.d).len)?*((char*)&$data.unicode[0])@($len>100?200:$len*2):\"\")",
00837 fullName().latin1()));
00838 }
00839
00840
00841 if (strncmp(cache_, "<QArray<char>> = {<QGArray> = {shd = ", 37) == 0) {
00842 waitingForData();
00843 emit ((VariableTree*)listView())->expandUserItem(this,
00844 fullName().latin1()+QCString(".shd.data"));
00845 }
00846
00847
00848 if (strncmp(cache_, "dPath = {d = 0x", 15) == 0) {
00849 waitingForData();
00850 ((VariableTree*)listView())->expandUserItem(this,
00851
00852 QCString().sprintf("(($len=($data=%s.dPath.d).len)?*((char*)&$data.unicode[0])@($len>100?200:$len*2):\"\")",
00853 fullName().latin1()));
00854 }
00855 }
00856
00857
00858
00859 DataType VarItem::getDataType() const
00860 {
00861 return dataType_;
00862 }
00863
00864
00865
00866
00867 void VarItem::paintCell(QPainter *p, const QColorGroup &cg,
00868 int column, int width, int align)
00869 {
00870 if ( !p )
00871 return;
00872
00873 if (column == ValueCol && highlight_) {
00874 QColorGroup hl_cg( cg.foreground(), cg.background(), cg.light(),
00875 cg.dark(), cg.mid(), red, cg.base());
00876 QListViewItem::paintCell( p, hl_cg, column, width, align );
00877 } else
00878 QListViewItem::paintCell( p, cg, column, width, align );
00879 }
00880
00881
00882
00883 QString VarItem::tipText() const
00884 {
00885 const unsigned int maxTooltipSize = 70;
00887 QString tip = text( 1 );
00888
00889 if (tip.length() < maxTooltipSize )
00890 return tip;
00891 else
00892 return tip.mid( 0, maxTooltipSize - 1 ) + " [...]";
00893 }
00894
00895
00896
00897
00898
00899 VarFrameRoot::VarFrameRoot(VariableTree *parent, int frameNo, int threadNo)
00900 : TrimmableItem (parent),
00901 needLocals_(true),
00902 frameNo_(frameNo),
00903 threadNo_(threadNo),
00904 params_(QCString()),
00905 locals_(QCString())
00906 {
00907 setExpandable(true);
00908 }
00909
00910
00911
00912 VarFrameRoot::~VarFrameRoot()
00913 {
00914 }
00915
00916
00917
00918 void VarFrameRoot::setParams(char *params)
00919 {
00920 setActive();
00921 params_ = params;
00922 }
00923
00924
00925
00926 void VarFrameRoot::setLocals(char *locals)
00927 {
00928 setActive();
00929
00930
00931 bool noLocals = (locals && (strncmp(locals, "No ", 3) == 0));
00932 setExpandable(!params_.isEmpty() || !noLocals);
00933
00934 if (noLocals) {
00935 locals_ = "";
00936 if (locals)
00937 if (char *end = strchr(locals, '\n'))
00938 *end = 0;
00939 } else
00940 locals_ = locals;
00941
00942 if (!isExpandable() && noLocals)
00943 setText( ValueCol, locals );
00944
00945 needLocals_ = false;
00946 if (isOpen())
00947 setOpen(true);
00948 }
00949
00950
00951
00952
00953
00954 void VarFrameRoot::setOpen(bool open)
00955 {
00956 bool localStateChange = (isOpen() != open);
00957 QListViewItem::setOpen(open);
00958
00959 if (localStateChange)
00960 ((VariableTree*)listView())->setLocalViewState(open, frameNo_, threadNo_);
00961
00962 if (!open)
00963 return;
00964
00965 GDBParser::getGDBParser()->parseData(this, params_.data(), false, true);
00966 GDBParser::getGDBParser()->parseData(this, locals_.data(), false, false);
00967
00968 locals_ = QCString();
00969 params_ = QCString();
00970 }
00971
00972
00973
00974 bool VarFrameRoot::matchDetails(int frameNo, int threadNo)
00975 {
00976 return frameNo == frameNo_ && threadNo == threadNo_;
00977 }
00978
00979
00980
00981
00982
00983
00984 WatchRoot::WatchRoot(VariableTree *parent)
00985 : TrimmableItem(parent)
00986 {
00987 setText(0, i18n("Watch"));
00988 setOpen(true);
00989 }
00990
00991
00992
00993 WatchRoot::~WatchRoot()
00994 {
00995 }
00996
00997
00998
00999 void WatchRoot::requestWatchVars()
01000 {
01001 for (QListViewItem *child = firstChild(); child; child = child->nextSibling())
01002 if (VarItem *varItem = dynamic_cast<VarItem*>(child))
01003 emit ((VariableTree*)listView())->expandItem(varItem);
01004 }
01005
01006
01007
01008
01009
01010 }
01011
01012
01013 #include "variablewidget.moc"
01014