KDevelop API Documentation

gdbbreakpointwidget.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002     begin                : Tue May 13 2003
00003     copyright            : (C) 2003 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 "gdbbreakpointwidget.h"
00017 #include "gdbtable.h"
00018 
00019 #include "breakpoint.h"
00020 #include "domutil.h"
00021 
00022 #include <kdebug.h>
00023 #include <kiconloader.h>
00024 #include <klocale.h>
00025 #include <kpopupmenu.h>
00026 #include <kurl.h>
00027 
00028 #include <qvbuttongroup.h>
00029 #include <qfileinfo.h>
00030 #include <qheader.h>
00031 #include <qtable.h>
00032 #include <qtoolbutton.h>
00033 #include <qtooltip.h>
00034 #include <qwhatsthis.h>
00035 #include <qvbox.h>
00036 #include <qlayout.h>
00037 
00038 #include <stdlib.h>
00039 #include <ctype.h>
00040 
00041 /***************************************************************************/
00042 /***************************************************************************/
00043 /***************************************************************************/
00044 
00045 namespace GDBDebugger
00046 {
00047 
00048 enum Column {
00049     Control     = 0,
00050     Enable      = 1,
00051     Type        = 2,
00052     Status      = 3,
00053     Location    = 4,
00054     Condition   = 5,
00055     IgnoreCount = 6,
00056     Hits        = 7
00057 };
00058 
00059 
00060 #define numCols 8
00061 
00062 static int m_activeFlag = 0;
00063 
00064 /***************************************************************************/
00065 /***************************************************************************/
00066 /***************************************************************************/
00067 
00068 class BreakpointTableRow : public QTableItem
00069 {
00070 public:
00071 
00072     BreakpointTableRow(QTable* table, EditType editType, Breakpoint* bp);
00073     ~BreakpointTableRow();
00074 
00075     bool match (Breakpoint* bp) const;
00076     void reset ();
00077     void setRow();
00078 
00079     Breakpoint* breakpoint()        { return m_breakpoint; }
00080 
00081 private:
00082     void appendEmptyRow();
00083 
00084 private:
00085     Breakpoint* m_breakpoint;
00086 };
00087 
00088 /***************************************************************************/
00089 /***************************************************************************/
00090 /***************************************************************************/
00091 
00092 BreakpointTableRow::BreakpointTableRow(QTable* parent, EditType editType,
00093                                        Breakpoint* bp) :
00094         QTableItem(parent, editType, ""),
00095         m_breakpoint(bp)
00096 {
00097     appendEmptyRow();
00098     setRow();
00099 }
00100 
00101 /***************************************************************************/
00102 
00103 BreakpointTableRow::~BreakpointTableRow()
00104 {
00105     delete m_breakpoint;
00106 }
00107 
00108 /***************************************************************************/
00109 
00110 bool BreakpointTableRow::match(Breakpoint* breakpoint) const
00111 {
00112     return m_breakpoint->match(breakpoint);
00113 }
00114 
00115 /***************************************************************************/
00116 
00117 void BreakpointTableRow::reset()
00118 {
00119     m_breakpoint->reset();
00120     setRow();
00121 }
00122 
00123 /***************************************************************************/
00124 
00125 void BreakpointTableRow::appendEmptyRow()
00126 {
00127     int row = table()->numRows();
00128     table()->setNumRows(row+1);
00129 
00130     table()->setItem(row, Control, this);
00131 
00132     QCheckTableItem* cti = new QCheckTableItem( table(), "");
00133     table()->setItem(row, Enable, cti);
00134 }
00135 
00136 /***************************************************************************/
00137 
00138 void BreakpointTableRow::setRow()
00139 {
00140     if ( m_breakpoint )
00141     {
00142         QTableItem *item =  table()->item ( row(), Enable );
00143         Q_ASSERT(item->rtti() == 2);
00144         ((QCheckTableItem*)item)->setChecked(m_breakpoint->isEnabled());
00145 
00146         QString status=m_breakpoint->statusDisplay(m_activeFlag);
00147 
00148         table()->setText(row(), Status, status);
00149         table()->setText(row(), Condition, m_breakpoint->conditional());
00150         table()->setText(row(), IgnoreCount, QString::number(m_breakpoint->ignoreCount() ));
00151         table()->setText(row(), Hits, QString::number(m_breakpoint->hits() ));
00152 
00153         QString displayType = m_breakpoint->displayType();
00154         table()->setText(row(), Location, m_breakpoint->location());
00155 
00156         if (m_breakpoint->isTemporary())
00157             displayType = i18n(" temporary");
00158         if (m_breakpoint->isHardwareBP())
00159             displayType += i18n(" hw");
00160 
00161         table()->setText(row(), Type, displayType);
00162         table()->adjustColumn(Type);
00163         table()->adjustColumn(Status);
00164         table()->adjustColumn(Location);
00165         table()->adjustColumn(Hits);
00166         table()->adjustColumn(IgnoreCount);
00167         table()->adjustColumn(Condition);
00168     }
00169 }
00170 
00171 /***************************************************************************/
00172 /***************************************************************************/
00173 /***************************************************************************/
00174 
00175 GDBBreakpointWidget::GDBBreakpointWidget(QWidget *parent, const char *name) :
00176     QHBox(parent, name)
00177 {
00178     QFrame* toolbar = new QFrame( this );
00179     QVBoxLayout *l = new QVBoxLayout(toolbar, 0, 0);
00180 
00181     toolbar->setFrameStyle( QFrame::ToolBarPanel | QFrame::Plain );
00182     toolbar->setLineWidth( 0 );
00183 
00184     m_add       = new QToolButton( toolbar, "add breakpoint" );
00185     m_add->setPixmap ( SmallIcon ( "breakpoint_add" ) );
00186     QToolTip::add ( m_add, i18n ( "Add empty breakpoint" ) + I18N_NOOP(" <Alt+A>"));
00187     QWhatsThis::add( m_add, i18n("<b>Add empty breakpoint</b><p>Shows a popup menu that allows you to choose "
00188         "the type of breakpoint, then adds a breakpoint of the selected type to the breakpoints list."));
00189 
00190     m_delete    = new QToolButton( toolbar, "delete breakpoint" );
00191     m_delete->setPixmap ( SmallIcon ( "breakpoint_delete" ) );
00192     QToolTip::add ( m_delete, i18n ( "Delete selected breakpoint" ) + I18N_NOOP(" <Delete>") );
00193     QWhatsThis::add( m_delete, i18n("<b>Delete selected breakpoint</b><p>Deletes the selected breakpoint in the breakpoints list."));
00194 
00195     m_edit      = new QToolButton( toolbar, "edit breakpoint" );
00196     m_edit->setPixmap ( SmallIcon ( "breakpoint_edit" ) );
00197     QToolTip::add ( m_edit, i18n ( "Edit selected breakpoint" ) + I18N_NOOP(" <Return>")  );
00198     QWhatsThis::add( m_edit, i18n("<b>Edit selected breakpoint</b><p>Allows to edit location, condition and ignore count properties of the selected breakpoint in the breakpoints list."));
00199 
00200     m_removeAll      = new QToolButton( toolbar, "Delete all breakppoints" );
00201     m_removeAll->setPixmap ( SmallIcon ( "breakpoint_delete_all" ) );
00202     QToolTip::add ( m_removeAll, i18n ( "Remove all breakpoints" ) );
00203     QWhatsThis::add( m_removeAll, i18n("<b>Remove all breakpoints</b><p>Removes all breakpoints in the project."));
00204 
00205     l->addWidget(m_add);
00206     l->addWidget(m_edit);
00207     l->addWidget(m_delete);
00208     l->addWidget(m_removeAll);
00209     QSpacerItem* spacer = new QSpacerItem( 5, 5, QSizePolicy::Minimum, QSizePolicy::Expanding );
00210     l->addItem(spacer);
00211 
00212     QPopupMenu *addMenu = new QPopupMenu( this );
00213     addMenu->insertItem( i18n( "File:line" ),   BP_TYPE_FilePos );
00214     addMenu->insertItem( i18n( "Watchpoint" ),  BP_TYPE_Watchpoint );
00215     addMenu->insertItem( i18n( "Address" ),     BP_TYPE_Address );
00216     addMenu->insertItem( i18n( "Method()" ),    BP_TYPE_Function );
00217     m_add->setPopup( addMenu );
00218     m_add->setPopupDelay(1);
00219 
00220     m_table = new GDBTable(0, numCols, this, name);
00221     m_table->setSelectionMode(QTable::SingleRow);
00222     m_table->setShowGrid (false);
00223     m_table->setLeftMargin(0);
00224     m_table->setFocusStyle(QTable::FollowStyle);
00225 
00226     m_table->hideColumn(Control);
00227     m_table->setColumnReadOnly(Type, true);
00228     m_table->setColumnReadOnly(Status, true);
00229     m_table->setColumnReadOnly(Hits, true);
00230     m_table->setColumnWidth( Enable, 20);
00231 
00232     QHeader *header = m_table->horizontalHeader();
00233 
00234     header->setLabel( Enable,       "" );
00235     header->setLabel( Type,         i18n("Type") );
00236     header->setLabel( Status,       i18n("Status") );
00237     header->setLabel( Location,     i18n("Location") );
00238     header->setLabel( Condition,    i18n("Condition") );
00239     header->setLabel( IgnoreCount,  i18n("Ignore Count") );
00240     header->setLabel( Hits,         i18n("Hits") );
00241 
00242     m_table->show();
00243 
00244     connect( addMenu,     SIGNAL(activated(int)),
00245              this,          SLOT(slotAddBlankBreakpoint(int)) );
00246     connect( m_delete,      SIGNAL(clicked()),
00247              this,          SLOT(slotRemoveBreakpoint()) );
00248     connect( m_edit,        SIGNAL(clicked()),
00249              this,          SLOT(slotEditBreakpoint()) );
00250     connect( m_removeAll,   SIGNAL(clicked()),
00251              this,          SLOT(slotRemoveAllBreakpoints()) );
00252 
00253 //    connect( m_table,       SIGNAL(contextMenuRequested(int, int, const QPoint &)),
00254 //             this,          SLOT(slotEditRow(int, int, const QPoint &)));
00255     connect( m_table,       SIGNAL(clicked(int, int, int, const QPoint &)),
00256              this,          SLOT(slotRowSelected(int, int, int, const QPoint &)));
00257     connect( m_table,       SIGNAL(valueChanged(int, int)),
00258              this,          SLOT(slotNewValue(int, int)));
00259 
00260     connect( m_table,       SIGNAL(returnPressed()),
00261              this,          SLOT(slotEditBreakpoint()));
00262 //    connect( m_table,       SIGNAL(f2Pressed()),
00263 //             this,          SLOT(slotEditBreakpoint()));
00264     connect( m_table,       SIGNAL(deletePressed()),
00265              this,          SLOT(slotRemoveBreakpoint()));
00266     connect( m_table,       SIGNAL(insertPressed()),
00267              this,          SLOT(slotAddBreakpoint()));
00268 }
00269 
00270 /***************************************************************************/
00271 
00272 GDBBreakpointWidget::~GDBBreakpointWidget()
00273 {
00274     delete m_table;
00275 }
00276 
00277 /***************************************************************************/
00278 
00279 void GDBBreakpointWidget::reset()
00280 {
00281     for ( int row = 0; row < m_table->numRows(); row++ )
00282     {
00283         BreakpointTableRow* btr = (BreakpointTableRow *) m_table->item(row, Control);
00284         if (btr)
00285         {
00286             btr->reset();
00287             emit publishBPState(*(btr->breakpoint()));
00288         }
00289     }
00290 }
00291 
00292 /***************************************************************************/
00293 
00294 // When a file is loaded then we need to tell the editor (display window)
00295 // which lines contain a breakpoint.
00296 void GDBBreakpointWidget::slotRefreshBP(const KURL &filename)
00297 {
00298     for ( int row = 0; row < m_table->numRows(); row++ )
00299     {
00300         BreakpointTableRow* btr = (BreakpointTableRow *) m_table->item(row, Control);
00301         if (btr)
00302         {
00303             FilePosBreakpoint* bp = dynamic_cast<FilePosBreakpoint*>(btr->breakpoint());
00304             if (bp && (bp->fileName() == filename.path()))
00305                 emit refreshBPState(*bp);
00306         }
00307     }
00308 }
00309 
00310 /***************************************************************************/
00311 
00312 BreakpointTableRow* GDBBreakpointWidget::find(Breakpoint *breakpoint)
00313 {
00314     // NOTE:- The match doesn't have to be equal. Each type of bp
00315     // must decide on the match criteria.
00316     Q_ASSERT (breakpoint);
00317 
00318     for ( int row = 0; row < m_table->numRows(); row++ )
00319     {
00320         BreakpointTableRow* btr = (BreakpointTableRow *) m_table->item(row, Control);
00321         if (btr && btr->match(breakpoint))
00322             return btr;
00323     }
00324 
00325     return 0;
00326 }
00327 
00328 /***************************************************************************/
00329 
00330 // The Id is supplied by the debugger
00331 BreakpointTableRow* GDBBreakpointWidget::findId(int dbgId)
00332 {
00333     for ( int row = 0; row < m_table->numRows(); row++ )
00334     {
00335         BreakpointTableRow* btr = (BreakpointTableRow *) m_table->item(row, Control);
00336         if (btr && btr->breakpoint()->dbgId() == dbgId)
00337             return btr;
00338     }
00339 
00340     return 0;
00341 }
00342 
00343 /***************************************************************************/
00344 
00345 // The key is a unique number supplied by us
00346 BreakpointTableRow* GDBBreakpointWidget::findKey(int BPKey)
00347 {
00348     for ( int row = 0; row < m_table->numRows(); row++ )
00349     {
00350         BreakpointTableRow* btr = (BreakpointTableRow *) m_table->item(row, Control);
00351         if (btr && btr->breakpoint()->key() == BPKey)
00352             return btr;
00353     }
00354 
00355     return 0;
00356 }
00357 
00358 /***************************************************************************/
00359 
00360 BreakpointTableRow* GDBBreakpointWidget::addBreakpoint(Breakpoint *bp)
00361 {
00362     BreakpointTableRow* btr =
00363         new BreakpointTableRow( m_table, QTableItem::WhenCurrent, bp );
00364     emit publishBPState(*bp);
00365     return btr;
00366 }
00367 
00368 /***************************************************************************/
00369 
00370 void GDBBreakpointWidget::removeBreakpoint(BreakpointTableRow* btr)
00371 {
00372     if (!btr)
00373         return;
00374 
00375     // Pending but the debugger hasn't started processing this bp so
00376     // we can just remove it.
00377     Breakpoint* bp = btr->breakpoint();
00378     if (bp->isPending() && !bp->isDbgProcessing())
00379     {
00380         bp->setActionDie();
00381         emit publishBPState(*bp);
00382         m_table->removeRow(btr->row());
00383     }
00384     else
00385     {
00386         bp->setPending(true);
00387         bp->setActionClear(true);
00388         emit publishBPState(*bp);
00389         btr->setRow();
00390     }
00391 }
00392 
00393 /***************************************************************************/
00394 
00395 void GDBBreakpointWidget::slotToggleBreakpoint(const QString &fileName, int lineNum)
00396 {
00397     FilePosBreakpoint *fpBP = new FilePosBreakpoint(fileName, lineNum+1);
00398 
00399     BreakpointTableRow* btr = find(fpBP);
00400     if (btr)
00401     {
00402         delete fpBP;
00403         removeBreakpoint(btr);
00404     }
00405     else
00406         addBreakpoint(fpBP);
00407 }
00408 
00409 /***************************************************************************/
00410 
00411 void GDBBreakpointWidget::slotToggleBreakpointEnabled(const QString &fileName, int lineNum)
00412 {
00413     FilePosBreakpoint *fpBP = new FilePosBreakpoint(fileName, lineNum+1);
00414 
00415     BreakpointTableRow* btr = find(fpBP);
00416     delete fpBP;
00417     if (btr)
00418     {
00419         Breakpoint* bp=btr->breakpoint();
00420         bp->setEnabled(!isEnabled());
00421         emit publishBPState(*bp);
00422     }
00423 }
00424 
00425 /***************************************************************************/
00426 
00427 void GDBBreakpointWidget::slotToggleWatchpoint(const QString &varName)
00428 {
00429     Watchpoint *watchpoint = new Watchpoint(varName, false, true);
00430     BreakpointTableRow* btr = find(watchpoint);
00431     if (btr)
00432     {
00433         removeBreakpoint(btr);
00434         delete watchpoint;
00435     }
00436     else
00437         addBreakpoint(watchpoint);
00438 }
00439 
00440 /***************************************************************************/
00441 
00442 // The debugger allows us to set pending breakpoints => do it
00443 void GDBBreakpointWidget::slotSetPendingBPs()
00444 {
00445     for ( int row = 0; row < m_table->numRows(); row++ )
00446     {
00447         BreakpointTableRow* btr = (BreakpointTableRow *) m_table->item(row, Control);
00448 
00449         if (btr)
00450         {
00451             Breakpoint* bp = btr->breakpoint();
00452             if (bp->isPending() && !bp->isDbgProcessing() && bp->isValid())
00453                 emit publishBPState(*bp);
00454         }
00455     }
00456 }
00457 
00458 /***************************************************************************/
00459 
00460 // The debugger is having trouble with this bp - probably because a library
00461 // was unloaded and invalidated a bp that was previously set in the library
00462 // code. Reset the bp so that we can try again later.
00463 void GDBBreakpointWidget::slotUnableToSetBPNow(int BPid)
00464 {
00465     if (BPid == -1)
00466         reset();
00467     else
00468         if (BreakpointTableRow *btr = findId(BPid))
00469             btr->reset();
00470 }
00471 
00472 /***************************************************************************/
00473 
00474 void GDBBreakpointWidget::slotParseGDBBrkptList(char *str)
00475 {
00476     // An example of a GDB breakpoint table
00477     // Num Type           Disp Enb Address    What
00478     // 1   breakpoint     del  y   0x0804a7fb in main at main.cpp:22
00479     // 2   hw watchpoint  keep y   thisIsAGlobal_int
00480     // 3   breakpoint     keep y   0x0804a847 in main at main.cpp:23
00481     //        stop only if thisIsAGlobal_int == 1
00482     //        breakpoint already hit 1 time
00483     // 4   breakpoint     keep y   0x0804a930 in main at main.cpp:28
00484     //        ignore next 6 hits
00485 
00486     // Another example of a not too uncommon occurance
00487     // No breakpoints or watchpoints.
00488 
00489     // Set the new active flag so that after we have read the
00490     // breakpoint list we can trim the breakpoints that have been
00491     // removed (temporary breakpoints do this)
00492     m_activeFlag++;
00493 
00494     // skip the first line which is the header
00495     while (str && (str = strchr(str, '\n')))
00496     {
00497         str++;
00498         int id = atoi(str);
00499         if (id)
00500         {
00501             // Inner loop handles lines of extra data for this breakpoint
00502             // eg
00503             //  3   breakpoint     keep y   0x0804a847 in main at main.cpp:23
00504             //         breakpoint already hit 1 time"
00505             int hits = 0;
00506             int ignore = 0;
00507             QString condition;
00508             while (str && (str = strchr(str, '\n')))
00509             {
00510                 str++;
00511 
00512                 // The char after a newline is a digit hence it's
00513                 // a new breakpt. Breakout to deal with this breakpoint.
00514                 if (isdigit(*str))
00515                 {
00516                     str--;
00517                     break;
00518                 }
00519 
00520                 // We're only interested in these fields here.
00521                 if (strncmp(str, "\tbreakpoint already hit ", 24) == 0)
00522                     hits = atoi(str+24);
00523 
00524                 if (strncmp(str, "\tignore next ", 13) == 0)
00525                     ignore = atoi(str+13);
00526 
00527                 if (strncmp(str, "\tstop only if ", 14) == 0)
00528                 {
00529                     char* EOL = strchr(str, '\n');
00530                     if (EOL)
00531                         condition = QCString(str+14, EOL-(str+13));
00532                 }
00533             }
00534 
00535             BreakpointTableRow* btr = findId(id);
00536             if (btr)
00537             {
00538                 Breakpoint *bp = btr->breakpoint();
00539                 bp->setActive(m_activeFlag, id);
00540                 bp->setHits(hits);
00541                 bp->setIgnoreCount(ignore);
00542                 bp->setConditional(condition);
00543                 btr->setRow();
00544                 emit publishBPState(*bp);
00545             }
00546         }
00547     }
00548 
00549     // Remove any inactive breakpoints.
00550     for ( int row = m_table->numRows()-1; row >= 0 ; row-- )
00551     {
00552         BreakpointTableRow* btr = (BreakpointTableRow *) m_table->item(row, Control);
00553         if (btr)
00554         {
00555             Breakpoint* bp = btr->breakpoint();
00556             if (!(bp->isActive(m_activeFlag)))
00557                 removeBreakpoint(btr);
00558         }
00559     }
00560 }
00561 
00562 /***************************************************************************/
00563 
00564 void GDBBreakpointWidget::slotParseGDBBreakpointSet(char *str, int BPKey)
00565 {
00566     char *startNo=0;
00567     bool hardware = false;
00568     BreakpointTableRow* btr = findKey(BPKey);
00569     if (!btr)
00570         return;
00571 
00572     Breakpoint *bp = btr->breakpoint();
00573     bp->setDbgProcessing(false);
00574 
00575     if ((strncmp(str, "Breakpoint ", 11) == 0))
00576         startNo = str+11;
00577     else
00578     {
00579         if ((strncmp(str, "Hardware watchpoint ", 20) == 0))
00580         {
00581             hardware = true;
00582             startNo = str+20;
00583         }
00584         else if ((strncmp(str, "Watchpoint ", 11) == 0))
00585             startNo = str+11;
00586     }
00587 
00588     if (startNo)
00589     {
00590         int id = atoi(startNo);
00591         if (id)
00592         {
00593             bp->setActive(m_activeFlag, id);
00594             bp->setHardwareBP(hardware);
00595             emit publishBPState(*bp);
00596             btr->setRow();
00597         }
00598     }
00599 }
00600 
00601 /***************************************************************************/
00602 
00603 void GDBBreakpointWidget::slotAddBlankBreakpoint(int idx)
00604 {
00605     BreakpointTableRow* btr = 0;
00606     switch (idx)
00607     {
00608       case BP_TYPE_FilePos:
00609           btr = addBreakpoint(new FilePosBreakpoint("", 0));
00610           break;
00611 
00612       case BP_TYPE_Watchpoint:
00613           btr = addBreakpoint(new Watchpoint(""));
00614           break;
00615 
00616       case BP_TYPE_Address:
00617           btr = addBreakpoint(new AddressBreakpoint(""));
00618           break;
00619 
00620       case BP_TYPE_Function:
00621           btr = addBreakpoint(new FunctionBreakpoint(""));
00622           break;
00623 
00624       default:
00625           break;
00626     }
00627 
00628     if (btr)
00629     {
00630         QTableSelection ts;
00631         ts.init(btr->row(), 0);
00632         ts.expandTo(btr->row(), numCols );
00633         m_table->addSelection(ts);
00634         m_table->editCell(btr->row(), Location, false);
00635     }
00636 }
00637 
00638 /***************************************************************************/
00639 
00640 void GDBBreakpointWidget::slotRemoveBreakpoint()
00641 {
00642     int row = m_table->currentRow();
00643     if ( row != -1)
00644     {
00645         BreakpointTableRow* btr = (BreakpointTableRow *) m_table->item(row, Control);
00646         removeBreakpoint(btr);
00647     }
00648 }
00649 
00650 /***************************************************************************/
00651 
00652 void GDBBreakpointWidget::slotRemoveAllBreakpoints()
00653 {
00654   while (m_table->numRows() > 0)
00655   {
00656     for ( int row = m_table->numRows()-1; row>=0; row-- )
00657     {
00658         BreakpointTableRow* btr = (BreakpointTableRow *) m_table->item(row, Control);
00659         removeBreakpoint(btr);
00660     }
00661   }
00662 }
00663 
00664 /***************************************************************************/
00665 
00666 void GDBBreakpointWidget::slotRowSelected(int row, int col, int btn, const QPoint &)
00667 {
00668     if ( btn == Qt::LeftButton )
00669     {
00670 //    kdDebug(9012) << "in slotRowSelected row=" << row << endl;
00671         BreakpointTableRow* btr = (BreakpointTableRow *) m_table->item(row, Control);
00672         if (btr)
00673         {
00674             FilePosBreakpoint* bp = dynamic_cast<FilePosBreakpoint*>(btr->breakpoint());
00675             if (bp)
00676                 emit gotoSourcePosition(bp->fileName(), bp->lineNum()-1);
00677 
00678             // put the focus back on the clicked item if appropriate
00679             if (col == Location || col ==  Condition || col == IgnoreCount)
00680                 m_table->editCell(row, col, false);
00681         }
00682     }
00683 }
00684 
00685 /***************************************************************************/
00686 
00687 void GDBBreakpointWidget::slotEditRow(int row, int col, const QPoint &)
00688 {
00689 //    kdDebug(9012) << "in slotEditRow row=" << row << endl;
00690     BreakpointTableRow* btr = (BreakpointTableRow *) m_table->item(row, Control);
00691     if (btr)
00692     {
00693         if (col == Location || col ==  Condition || col == IgnoreCount)
00694             m_table->editCell(row, col, false);
00695     }
00696 }
00697 
00698 /***************************************************************************/
00699 
00700 void GDBBreakpointWidget::slotNewValue(int row, int col)
00701 {
00702 //    kdDebug(9012) << "in slotNewValue row=" << row << endl;
00703     BreakpointTableRow* btr = (BreakpointTableRow *) m_table->item(row, Control);
00704 
00705     if (btr)
00706     {
00707         bool changed=false;
00708         Breakpoint* bp = btr->breakpoint();
00709         switch (col)
00710         {
00711 
00712         case Enable:
00713         {
00714             QCheckTableItem *item = (QCheckTableItem*)m_table->item ( row, Enable );
00715             if ( item->isChecked() != bp->isEnabled() )
00716             {
00717                 bp->setEnabled(item->isChecked());
00718                 bp->setPending(true);
00719                 bp->setActionModify(true);
00720                 changed = true;
00721             }
00722             break;
00723         }
00724 
00725         case Location:
00726         {
00727             if (bp->location() != m_table->text(btr->row(), Location))
00728             {
00729 //                kdDebug(9012) << "Old location [" << bp->location() << "]" << endl;
00730 //                kdDebug(9012) << "New location [" << m_table->text(btr->row(), Location) << "]" << endl;
00731                 bp->setActionDie();
00732                 emit publishBPState(*bp);
00733                 bp->setPending(true);
00734                 bp->setActionAdd(true);
00735                 bp->setLocation(m_table->text(btr->row(), Location));
00736                 changed = true;
00737             }
00738             break;
00739         }
00740 
00741         case Condition:
00742         {
00743             if (bp->conditional() != m_table->text(btr->row(), Condition))
00744             {
00745 //                kdDebug(9012) << "Old condition [" << bp->conditional() << "]" << endl;
00746 //                kdDebug(9012) << "New condition [" << m_table->text(btr->row(), Condition) << "]" << endl;
00747                 bp->setConditional(m_table->text(btr->row(), Condition));
00748                 bp->setPending(true);
00749                 bp->setActionModify(true);
00750                 changed = true;
00751             }
00752             break;
00753         }
00754 
00755         case IgnoreCount:
00756         {
00757             if (bp->ignoreCount() != m_table->text(btr->row(), IgnoreCount).toInt())
00758             {
00759 //                kdDebug(9012) << "Old ignoreCount [" << bp->ignoreCount() << "]" << endl;
00760 //                kdDebug(9012) << "New ignoreCount [" << m_table->text(btr->row(), IgnoreCount) << "]" << endl;
00761                 bp->setIgnoreCount(m_table->text(btr->row(), IgnoreCount).toInt());
00762                 bp->setPending(true);
00763                 bp->setActionModify(true);
00764                 changed = true;
00765             }
00766             break;
00767         }
00768 
00769         case Type:
00770         case Status:
00771         case Hits:
00772         default:
00773             break;
00774         }
00775 
00776         if (changed)
00777         {
00778             btr->setRow();
00779             emit publishBPState(*bp);
00780         }
00781     }
00782 }
00783 
00784 /***************************************************************************/
00785 
00786 void GDBBreakpointWidget::slotEditBreakpoint(const QString &fileName, int lineNum)
00787 {
00788     FilePosBreakpoint *fpBP = new FilePosBreakpoint(fileName, lineNum+1);
00789 
00790     BreakpointTableRow* btr = find(fpBP);
00791     delete fpBP;
00792 
00793     if (btr)
00794     {
00795         QTableSelection ts;
00796         ts.init(btr->row(), 0);
00797         ts.expandTo(btr->row(), numCols);
00798         m_table->addSelection(ts);
00799         m_table->editCell(btr->row(), Location, false);
00800     }
00801 
00802 }
00803 
00804 /***************************************************************************/
00805 
00806 void GDBBreakpointWidget::slotEditBreakpoint()
00807 {
00808     m_table->editCell(m_table->currentRow(), Location, false);
00809 }
00810 
00811 /***************************************************************************/
00812 
00813 void GDBBreakpointWidget::savePartialProjectSession(QDomElement* el)
00814 {
00815     QDomDocument domDoc = el->ownerDocument();
00816     if (domDoc.isNull())
00817         return;
00818 
00819     QDomElement breakpointListEl = domDoc.createElement("breakpointList");
00820     for ( int row = 0; row < m_table->numRows(); row++ )
00821     {
00822         BreakpointTableRow* btr =
00823             (BreakpointTableRow *) m_table->item(row, Control);
00824         Breakpoint* bp = btr->breakpoint();
00825 
00826         QDomElement breakpointEl =
00827             domDoc.createElement("breakpoint"+QString::number(row));
00828 
00829         breakpointEl.setAttribute("type", bp->type());
00830         breakpointEl.setAttribute("location", bp->location(false));
00831         breakpointEl.setAttribute("enabled", bp->isEnabled());
00832         breakpointEl.setAttribute("condition", bp->conditional());
00833 
00834         breakpointListEl.appendChild(breakpointEl);
00835     }
00836 
00837     if (!breakpointListEl.isNull())
00838         el->appendChild(breakpointListEl);
00839 }
00840 
00841 /***************************************************************************/
00842 
00843 void GDBBreakpointWidget::restorePartialProjectSession(const QDomElement* el)
00844 {
00845     QDomElement breakpointListEl = el->namedItem("breakpointList").toElement();
00846     if (!breakpointListEl.isNull())
00847     {
00848         QDomElement breakpointEl;
00849         for (breakpointEl = breakpointListEl.firstChild().toElement();
00850                 !breakpointEl.isNull();
00851                 breakpointEl = breakpointEl.nextSibling().toElement())
00852         {
00853             Breakpoint* bp=0;
00854             BP_TYPES type = (BP_TYPES) breakpointEl.attribute( "type", "0").toInt();
00855             switch (type)
00856             {
00857             case BP_TYPE_FilePos:
00858             {
00859                 bp = new FilePosBreakpoint("", 0);
00860                 break;
00861             }
00862             case BP_TYPE_Watchpoint:
00863             {
00864                 bp = new Watchpoint("");
00865                 break;
00866             }
00867             case BP_TYPE_Address:
00868             {
00869                 bp = new Watchpoint("");
00870                 break;
00871             }
00872             case BP_TYPE_Function:
00873             {
00874                 bp = new FunctionBreakpoint("");
00875                 break;
00876             }
00877             default:
00878                 break;
00879             }
00880 
00881             // Common settings for any type of breakpoint
00882             if (bp)
00883             {
00884                 bp->setLocation(breakpointEl.attribute( "location", ""));
00885                 bp->setEnabled(breakpointEl.attribute( "enabled", "1").toInt());
00886                 bp->setConditional(breakpointEl.attribute( "condition", ""));
00887 
00888                 // Add the bp if we don't already have it.
00889                 if (!find(bp))
00890                     addBreakpoint(bp);
00891                 else
00892                     delete bp;
00893             }
00894         }
00895     }
00896 }
00897 
00898 /***************************************************************************/
00899 
00900 void GDBBreakpointWidget::slotAddBreakpoint( )
00901 {
00902     if (m_add->popup())
00903     {
00904         m_add->popup()->popup(mapToGlobal(this->geometry().topLeft()));
00905     }
00906 }
00907 
00908 /***************************************************************************/
00909 
00910 void GDBBreakpointWidget::focusInEvent( QFocusEvent */* e*/ )
00911 {
00912     m_table->setFocus();
00913 }
00914 
00915 }
00916 
00917 
00918 #include "gdbbreakpointwidget.moc"
KDE Logo
This file is part of the documentation for KDevelop Version 3.1.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Feb 22 09:22:29 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003