KDevelop API Documentation

languages/java/debugger/breakpointwidget.cpp

Go to the documentation of this file.
00001 /*************************************************************************** 00002 brkptmanager.cpp - description 00003 ------------------- 00004 begin : Sun Aug 8 1999 00005 copyright : (C) 1999 by John Birch 00006 email : jbb@kdevelop.org 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * * 00011 * This program is free software; you can redistribute it and/or modify * 00012 * it under the terms of the GNU General Public License as published by * 00013 * the Free Software Foundation; either version 2 of the License, or * 00014 * (at your option) any later version. * 00015 * * 00016 ***************************************************************************/ 00017 00018 #include "breakpointwidget.h" 00019 #include "breakpoint.h" 00020 00021 #include <qdict.h> 00022 #include <qheader.h> 00023 00024 #include <kpopupmenu.h> 00025 00026 #include <stdlib.h> 00027 #include <ctype.h> 00028 #include <klocale.h> 00029 #include <qcursor.h> 00030 00031 namespace JAVADebugger 00032 { 00033 00034 /***************************************************************************/ 00035 /***************************************************************************/ 00036 /***************************************************************************/ 00037 00038 BreakpointWidget::BreakpointWidget(QWidget *parent, const char *name) 00039 : KListBox(parent, name), 00040 activeFlag_(0) 00041 { 00042 connect( this, SIGNAL(rightButtonPressed(QListBoxItem*, const QPoint&)), 00043 SLOT(slotContextMenu(QListBoxItem*)) ); 00044 connect ( this, SIGNAL(executed(QListBoxItem*)), 00045 SLOT(slotExecuted(QListBoxItem*)) ); 00046 } 00047 00048 /***************************************************************************/ 00049 00050 BreakpointWidget::~BreakpointWidget() 00051 { 00052 } 00053 00054 /***************************************************************************/ 00055 00056 void BreakpointWidget::reset() 00057 { 00058 for (int index=0; index<(int)count(); index++) 00059 ((Breakpoint*)item(index))->reset(); 00060 repaint(); 00061 } 00062 00063 /***************************************************************************/ 00064 00065 // Essentially tells the editor (display window) what lines contain a 00066 // breakpoint. Used when a file is loaded 00067 void BreakpointWidget::refreshBP(const QString &filename) 00068 { 00069 for (int index=0; index<(int)count(); index++) { 00070 Breakpoint *BP = (Breakpoint*)item(index); 00071 if (BP->hasSourcePosition() && (BP->fileName() == filename)) 00072 emit refreshBPState(BP); 00073 } 00074 } 00075 00076 /***************************************************************************/ 00077 00078 int BreakpointWidget::findIndex(const Breakpoint *breakpoint) const 00079 { 00080 // NOTE:- The match doesn't have to be equal. Each type of BP 00081 // must decide on the match criteria. 00082 Q_ASSERT (breakpoint); 00083 00084 for (int index=0; index<(int)count(); index++) { 00085 Breakpoint *BP = (Breakpoint*)(item(index)); 00086 if (breakpoint->match(BP)) 00087 return index; 00088 } 00089 00090 return -1; 00091 } 00092 00093 /***************************************************************************/ 00094 00095 // The Id is supplied by the debugger 00096 Breakpoint *BreakpointWidget::findId(int dbgId) const 00097 { 00098 for (int index=0; index<(int)count(); index++) { 00099 Breakpoint *BP = (Breakpoint*)item(index); 00100 if (BP->dbgId() == dbgId) 00101 return BP; 00102 } 00103 00104 return 0; 00105 } 00106 00107 /***************************************************************************/ 00108 00109 // The key is a unique number supplied by us 00110 Breakpoint *BreakpointWidget::findKey(int BPKey) const 00111 { 00112 for (int index=0; index<(int)count(); index++) { 00113 Breakpoint *BP = (Breakpoint*)item(index); 00114 if (BP->key() == BPKey) 00115 return BP; 00116 } 00117 00118 return 0; 00119 } 00120 00121 00122 /***************************************************************************/ 00123 00124 void BreakpointWidget::addBreakpoint(Breakpoint *BP) 00125 { 00126 insertItem(BP); 00127 BP->setActionAdd(true); 00128 BP->setPending(true); 00129 emit publishBPState(BP); 00130 00131 BP->configureDisplay(); 00132 repaint(); 00133 } 00134 00135 /***************************************************************************/ 00136 00137 void BreakpointWidget::removeBreakpoint(Breakpoint *BP) 00138 { 00139 // Pending but the debugger hasn't started processing this BP so 00140 // we can just remove it. 00141 if (BP->isPending() && !BP->isDbgProcessing()) { 00142 BP->setActionDie(); 00143 emit publishBPState(BP); 00144 removeItem(findIndex(BP)); 00145 } else { 00146 BP->setPending(true); 00147 BP->setActionClear(true); 00148 emit publishBPState(BP); 00149 00150 BP->configureDisplay(); 00151 } 00152 00153 repaint(); 00154 } 00155 00156 /***************************************************************************/ 00157 00158 void BreakpointWidget::modifyBreakpoint(Breakpoint *BP) 00159 { 00160 if (BP->modifyDialog()) { 00161 BP->setPending(true); 00162 BP->setActionModify(true); 00163 emit publishBPState(BP); 00164 00165 BP->configureDisplay(); 00166 repaint(); 00167 } 00168 } 00169 00170 /***************************************************************************/ 00171 00172 void BreakpointWidget::toggleBPEnabled(Breakpoint *BP) 00173 { 00174 BP->setEnabled(!BP->isEnabled()); 00175 BP->setPending(true); 00176 BP->setActionModify(true); 00177 emit publishBPState(BP); 00178 00179 BP->configureDisplay(); 00180 repaint(); 00181 } 00182 00183 /***************************************************************************/ 00184 00185 void BreakpointWidget::removeAllBreakpoints() 00186 { 00187 for (int index=count()-1; index>=0; index--) { 00188 Breakpoint *BP = (Breakpoint*)item(index); 00189 if (BP->isPending() && !BP->isDbgProcessing()) 00190 removeBreakpoint(BP); 00191 } 00192 00193 if (count()) 00194 emit clearAllBreakpoints(); 00195 } 00196 00197 /***************************************************************************/ 00198 00199 void BreakpointWidget::slotExecuted(QListBoxItem *item) 00200 { 00201 if (item) { 00202 setCurrentItem(item); 00203 Breakpoint *BP = (Breakpoint*)item; 00204 if (BP->hasSourcePosition()) 00205 emit gotoSourcePosition(BP->fileName(), BP->lineNum()-1); 00206 } 00207 } 00208 00209 /***************************************************************************/ 00210 00211 void BreakpointWidget::slotContextMenu(QListBoxItem *item) 00212 { 00213 if (!item) 00214 return; 00215 00216 Breakpoint *BP = (Breakpoint*)item; 00217 KPopupMenu popup(i18n("Breakpoints"), this); 00218 int idRemoveBP = popup.insertItem( i18n("Remove Breakpoint") ); 00219 int idEditBP = popup.insertItem( i18n("Edit Breakpoint") ); 00220 int idToggleBPEnabled = popup.insertItem( BP->isEnabled()? 00221 i18n("Disable Breakpoint") : 00222 i18n("Enable Breakpoint") ); 00223 int idGotoSource = popup.insertItem( i18n("Display Source Code") ); 00224 popup.setItemEnabled(idGotoSource, BP->hasSourcePosition()); 00225 popup.insertSeparator(); 00226 int idClearAll = popup.insertItem( i18n("Clear All Breakpoints") ); 00227 00228 int res = popup.exec(QCursor::pos()); 00229 00230 if (res == idRemoveBP) 00231 removeBreakpoint(BP); 00232 else if (res == idEditBP) 00233 modifyBreakpoint(BP); 00234 else if (res == idToggleBPEnabled) 00235 toggleBPEnabled(BP); 00236 else if (res == idGotoSource && BP->hasSourcePosition()) 00237 emit gotoSourcePosition(BP->fileName(), BP->lineNum()-1); 00238 else if (res == idClearAll) 00239 removeAllBreakpoints(); 00240 } 00241 00242 /***************************************************************************/ 00243 00244 void BreakpointWidget::slotToggleBreakpoint(const QString &fileName, int lineNum) 00245 { 00246 FilePosBreakpoint *fpBP = new FilePosBreakpoint(fileName, lineNum+1); 00247 00248 int found = findIndex(fpBP); 00249 if (found >= 0) { 00250 delete fpBP; 00251 removeBreakpoint((Breakpoint*)item(found)); 00252 } else 00253 addBreakpoint(fpBP); 00254 } 00255 00256 /***************************************************************************/ 00257 00258 void BreakpointWidget::slotEditBreakpoint(const QString &fileName, int lineNum) 00259 { 00260 FilePosBreakpoint *fpBP = new FilePosBreakpoint(fileName, lineNum+1); 00261 00262 int found = findIndex(fpBP); 00263 delete fpBP; 00264 if (found >= 0) 00265 modifyBreakpoint((Breakpoint*)item(found)); 00266 } 00267 00268 /***************************************************************************/ 00269 00270 void BreakpointWidget::slotToggleBreakpointEnabled(const QString &fileName, int lineNum) 00271 { 00272 FilePosBreakpoint *fpBP = new FilePosBreakpoint(fileName, lineNum+1); 00273 00274 int found = findIndex(fpBP); 00275 delete fpBP; 00276 if (found >= 0) { 00277 setCurrentItem(found); 00278 toggleBPEnabled((Breakpoint*)item(found)); 00279 } 00280 } 00281 00282 /***************************************************************************/ 00283 00284 void BreakpointWidget::slotToggleWatchpoint(const QString &varName) 00285 { 00286 Watchpoint *watchpoint = new Watchpoint(varName, false, true); 00287 int found = findIndex(watchpoint); 00288 if (found >= 0) { 00289 removeBreakpoint((Breakpoint*)item(found)); 00290 delete watchpoint; 00291 } else 00292 addBreakpoint(watchpoint); 00293 } 00294 00295 /***************************************************************************/ 00296 00297 // The debugger allows us to set pending breakpoints => do it 00298 void BreakpointWidget::slotSetPendingBPs() 00299 { 00300 for (int index=0; index<(int)count(); index++) { 00301 Breakpoint *BP = (Breakpoint*)(item(index)); 00302 if (BP->isPending() && !BP->isDbgProcessing()) 00303 emit publishBPState(BP); 00304 } 00305 } 00306 00307 /***************************************************************************/ 00308 00309 // The debugger is having trouble with this BP - probably because a library 00310 // was unloaded and invalidated a BP that was previously set in the library 00311 // code. Reset the BP so that we can try again later. 00312 void BreakpointWidget::slotUnableToSetBPNow(int BPid) 00313 { 00314 if (BPid == -1) 00315 reset(); 00316 else if (Breakpoint *BP = findId(BPid)) 00317 BP->reset(); 00318 00319 repaint(); 00320 } 00321 00322 /***************************************************************************/ 00323 00324 void BreakpointWidget::slotParseJDBBrkptList(char *str) 00325 { 00326 // An example of a JDB breakpoint table 00327 // Num Type Disp Enb Address What 00328 // 1 breakpoint del y 0x0804a7fb in main at main.cpp:22 00329 // 2 hw watchpoint keep y thisIsAGlobal_int 00330 // 3 breakpoint keep y 0x0804a847 in main at main.cpp:23 00331 // stop only if thisIsAGlobal_int == 1 00332 // breakpoint already hit 1 time 00333 // 4 breakpoint keep y 0x0804a930 in main at main.cpp:28 00334 // ignore next 6 hits 00335 00336 // Another example of a not too uncommon occurance 00337 // No breakpoints or watchpoints. 00338 00339 // Set the new active flag so that after we have read the 00340 // breakpoint list we can trim the breakpoints that have been 00341 // removed (temporary breakpoints do this) 00342 activeFlag_++; 00343 00344 // skip the first line which is the header 00345 while (str && (str = strchr(str, '\n'))) { 00346 str++; 00347 int id = atoi(str); 00348 if (id) { 00349 // Inner loop handles lines of extra data for this breakpoint 00350 // eg 00351 // 3 breakpoint keep y 0x0804a847 in main at main.cpp:23 00352 // breakpoint already hit 1 time" 00353 int hits = 0; 00354 int ignore = 0; 00355 QString condition; 00356 while (str && (str = strchr(str, '\n'))) { 00357 str++; 00358 00359 // The char after a newline is a digit hence it's 00360 // a new breakpt. Breakout to deal with this breakpoint. 00361 if (isdigit(*str)) { 00362 str--; 00363 break; 00364 } 00365 00366 // We're only interested in these fields here. 00367 if (strncmp(str, "\tbreakpoint already hit ", 24) == 0) 00368 hits = atoi(str+24); 00369 00370 if (strncmp(str, "\tignore next ", 13) == 0) 00371 ignore = atoi(str+13); 00372 00373 if (strncmp(str, "\tstop only if ", 14) == 0) { 00374 char* EOL = strchr(str, '\n'); 00375 if (EOL) 00376 condition = QCString(str+14, EOL-(str+13)); 00377 } 00378 } 00379 00380 if (Breakpoint *BP = findId(id)) { 00381 BP->setActive(activeFlag_, id); 00382 BP->setHits(hits); 00383 BP->setIgnoreCount(ignore); 00384 BP->setConditional(condition); 00385 emit publishBPState(BP); 00386 00387 BP->configureDisplay(); 00388 } 00389 } 00390 } 00391 00392 // Remove any inactive breakpoints. 00393 for (int index=count()-1; index>=0; index--) { 00394 Breakpoint* BP = (Breakpoint*)(item(index)); 00395 if (!BP->isActive(activeFlag_)) { 00396 BP->setActionDie(); 00397 emit publishBPState(BP); 00398 00399 removeItem(index); 00400 } 00401 } 00402 00403 // setAutoUpdate(true); 00404 repaint(); 00405 } 00406 00407 /***************************************************************************/ 00408 00409 void BreakpointWidget::slotParseJDBBreakpointSet(char *str, int BPKey) 00410 { 00411 char *startNo=0; 00412 bool hardware = false; 00413 Breakpoint *BP = findKey(BPKey); 00414 if (!BP) 00415 return; // Why ?? Possibly internal dbgController BPs that shouldn't get here! 00416 00417 BP->setDbgProcessing(false); 00418 00419 if ((strncmp(str, "Breakpoint ", 11) == 0)) 00420 startNo = str+11; 00421 else { 00422 if ((strncmp(str, "Hardware watchpoint ", 20) == 0)) { 00423 hardware = true; 00424 startNo = str+20; 00425 } else if ((strncmp(str, "Watchpoint ", 11) == 0)) 00426 startNo = str+11; 00427 } 00428 00429 if (startNo) { 00430 int id = atoi(startNo); 00431 if (id) { 00432 BP->setActive(activeFlag_, id); 00433 BP->setHardwareBP(hardware); 00434 emit publishBPState(BP); 00435 00436 BP->configureDisplay(); 00437 repaint(); 00438 } 00439 } 00440 } 00441 00442 /***************************************************************************/ 00443 00444 } 00445 00446 #include "breakpointwidget.moc"
KDE Logo
This file is part of the documentation for KDevelop Version 3.0.4.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Oct 19 08:01:43 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003