KDevelop API Documentation

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.1.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Feb 22 09:22:30 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003