KDevelop API Documentation

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 #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 //    watchVarEntry_ = new KLineEdit(this);
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 //    QBoxLayout *watchEntry = new QHBoxLayout();
00066 //    watchEntry->addWidget(label);
00067 //    watchEntry->addWidget(watchVarEntry_);
00068 //    watchEntry->addWidget(watchVarEditor_);
00069 //    watchEntry->setStretchFactor(watchVarEditor_, 1);
00070 //    watchEntry->addWidget(addButton);
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 //    connect( watchVarEntry_, SIGNAL(returnPressed()), SLOT(slotAddWatchVariable()) );
00082 
00083 }
00084 
00085 // **************************************************************************
00086 
00087 void VariableWidget::clear()
00088 {
00089 //  varTree_->clear();
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 //    QString watchVar(watchVarEntry_->text());
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 */*e*/)
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     work in progress - disabled for now
00171 
00172     // jw
00173     connect( this, SIGNAL(doubleClicked(QListViewItem *item, const QPoint &pos, int c)),
00174              SLOT(slotDoubleClicked(QListViewItem *item, const QPoint &pos, int c)) );
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);    // Need to select this item.
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 ) + "\", " + // name
00213                             "\"" + item->text( 2 ) + "\", " + // type
00214                             "\"" + item->text( 1 ) + "\" }";  // value
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 // jw
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     // When they want to _close_ a frame then we need to check the state of
00263     // all other frames to determine whether we still need the locals.
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     // frames only exist on th top level so we only need to
00299     // check the siblings
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         // don't trim the watch root
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 /* rgruber:
00396  * this it the slot which is connected to the toggleRadix() signal
00397  * it removes the given watch variable an replaces it by another
00398  * watch that includes a format modifier
00399  */
00400 void VariableTree::slotToggleRadix(QListViewItem * item)
00401 {
00402   if (item==NULL)  //no item->nothing to do
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 ")   //is there a wrong format modifier...
00413           strName = "/x "+strName.right(strName.length()-3);  //...replace the modifier
00414       else if (strTmp == "/x ")
00415           strName = strName.right(strName.length()-3);  //stripe the modifier
00416       else
00417           strName = QString("/x ")+strName;  //add the hex-formater
00418   } else
00419   if (iOutRadix == 16) {
00420       if (strTmp == "/x ")   //is there a wrong format modifier...
00421           strName = "/d "+strName.right(strName.length()-3);  //...replace the modifier
00422       else if (strTmp == "/d ")   //is there a format modifier?
00423           strName = strName.right(strName.length()-3);  //stripe the modifier
00424       else
00425           strName = QString("/d ")+strName;  //add the dec-formater
00426   }
00427 
00428   pNewItem = new VarItem((TrimmableItem *) item->parent(), strName, typeUnknown);
00429   emit expandItem(pNewItem);
00430 
00431   pNewItem->moveItem(pOldItem);  //move the new item up right under the old one
00432 
00433   delete item;  //remove the old one so that is seam as if it was replaced by the new 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     // make toplevel item (watch and frame items) names bold
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;  //this indicates if the current item needs to be replaced by a new one.
00513             //the problem is, that the debugger always replaces already
00514             //format-modified local item with non-mofified ones. So with every
00515             //run we need to newly modify the outcome of the debugger
00516 
00517     int iOutRad = ((VariableTree*)listView())->iOutRadix; //local copy of the output radix
00518 
00519     // Check the siblings on this branch
00520     while (child) {
00521         QString strMatch = child->text(VarNameCol);
00522         bRenew=false;
00523     if (strMatch.left(3) == "/x " || strMatch.left(3) == "/d ") {  //is the current item format modified?
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)) { //do we need to replace?
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             // Never trim a branch if we are waiting on data to arrive.
00561             if (isTrimmable()) {
00562                 if (item->isActive())
00563                     item->trim();      // recurse
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* /* buf */)
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     setRenameEnabled(VarTypeCol, true);
00622     setRenameEnabled(VarNameCol, true);
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     // This stops at the root item (FrameRoot or WatchRoot)
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())                   // Don't highlight new items
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     // Hack due to my bad QString implementation - this just tidies up the display
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 &&  //only if it is a pointer...
00708         ((VariableTree*)listView())->iOutRadix == 16) { //...and only do if outputradix is set to hex
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         // Try fixing a format string here by overriding the dataType calculated
00725         // from this data
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 &/*pos*/, 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     // This shouldn't be needed to keep it from blowing up, but sometimes is.
00810     // On the other hand, if it's empty, there is no reason to go on...
00811     if ( cache_.isEmpty() ) return;
00812 
00814 
00815     // Signature for a QT1.44 QString
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     // Signature for a QT1.44 QDir
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     // Signature for a QT2.x QT3.x QString
00831     // at the moment to leave it here, and it won't cause bad things to happen.
00832     if (strncmp(cache_, "d = 0x", 6) == 0) {     // Eeeek - too small
00833         waitingForData();
00834         emit ((VariableTree*)listView())->expandUserItem(this,
00835                                                          // QCString().sprintf("(($len=($data=%s.d).len)?$data.unicode.rw@($len>100?200:$len*2):\"\")",
00836                                                          QCString().sprintf("(($len=($data=%s.d).len)?*((char*)&$data.unicode[0])@($len>100?200:$len*2):\"\")",
00837                                                                             fullName().latin1()));
00838     }
00839 
00840     // Signature for a QT2.0.x QT2.1 QCString
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     // Signature for a QT2.0.x QT2.1 QDir
00848     if (strncmp(cache_, "dPath = {d = 0x", 15) == 0) {
00849         waitingForData();
00850         ((VariableTree*)listView())->expandUserItem(this,
00851                                                     // QCString().sprintf("(($len=($data=%s.dPath.d).len)?$data.unicode.rw@($len>100?200:$len*2):\"\")",
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 // Overridden to highlight the changed items
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     // "No symbol table info available" or "No locals."
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;      // clobber the new line
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 // Override setOpen so that we can decide what to do when we do change
00953 // state. This
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 
KDE Logo
This file is part of the documentation for KDevelop Version 3.1.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Mar 23 00:03:46 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003