KDevelop API Documentation

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