[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kdevelop-devel
Subject:    possible split to breakpoints framework
From:       Aleix <aleixpol () gmail ! com>
Date:       2008-11-19 22:19:00
Message-ID: 757d9a550811191419g16329abxc93f32d5f6d18ed7 () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


hi list (and in special vladimir),

I spent some time trying to split this breakpoints code from the gdb support
to the platform so that we can take advantage from it for new future
debuggers. I don't really know if it is the best approach (i'm not really
familiar with this code) but i think it is not breaking the code logic and
could be useful enough.

some more code would be able to be ported to the platform like specially the
widget but i prefer to go step by step.

obviously here the files that would go to the platform would be the i* ones.

Thanks!
Aleix

[Attachment #5 (text/html)]

hi list (and in special vladimir),<br><br>I spent some time trying to split this \
breakpoints code from the gdb support to the platform so that we can take advantage \
from it for new future debuggers. I don&#39;t really know if it is the best approach \
(i&#39;m not really familiar with this code) but i think it is not breaking the code \
logic and could be useful enough.<br> <br>some more code would be able to be ported \
to the platform like specially the widget but i prefer to go step by \
step.<br><br>obviously here the files that would go to the platform would be the i* \
ones.<br><br>Thanks!<br> Aleix<br>


["breakpoints.kdevelop.patch" (text/x-diff)]

Index: breakpointcontroller.cpp
===================================================================
--- breakpointcontroller.cpp	(revision 886619)
+++ breakpointcontroller.cpp	(working copy)
@@ -24,486 +24,48 @@
 
 #include "newbreakpoint.h"
 #include "breakpoints.h"
-#include <QPixmap>
-#include <KIcon>
-#include <KParts/PartManager>
+#include "gdbcontroller.h"
+#include "gdbcommand.h"
+#include "breakpoint.h"
 
-#include <kdebug.h>
-#include <klocale.h>
-#include <ktexteditor/document.h>
-
 #include <interfaces/icore.h>
 #include <interfaces/idocumentcontroller.h>
 #include <interfaces/idocument.h>
+#include <ktexteditor/markinterface.h>
+#include <ktexteditor/document.h>
+#include <KParts/PartManager>
+#include <KDebug>
 
-#include "gdbcontroller.h"
-#include "gdbcommand.h"
-#include "breakpoint.h"
-
 #include "util/treeitem.h"
 #include "util/treemodel.h"
 
 // #include "modeltest.h"
 
-using namespace KTextEditor;
 using namespace GDBDebugger;
 using namespace GDBMI;
+using namespace KTextEditor;
 
 static int m_activeFlag = 0;
 
 BreakpointController::BreakpointController(GDBController* parent)
-: TreeModel(QVector<QString>() << "" << "" << "Type" << "Location" << "Condition",
-            parent)
+    : IBreakpointController(parent, new Breakpoints(this, parent))
 {
-    universe_ = new Breakpoints(this, parent);
-    setRootItem(universe_);
-    universe_->load();
-    universe_->createHelperBreakpoint();
-
-    connect(this, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
-            universe_, SLOT(save()));
-    connect(this, SIGNAL(rowsRemoved(const QModelIndex &, int, int)),
-            universe_, SLOT(save()));
-    connect(this, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)),
-            universe_, SLOT(save()));
-
-    //new ModelTest(this, this);
-
-    foreach(KParts::Part* p, KDevelop::ICore::self()->partController()->parts())
-        slotPartAdded(p);
     connect(KDevelop::ICore::self()->partController(),
             SIGNAL(partAdded(KParts::Part*)),
             this,
-            SLOT(slotPartAdded(KParts::Part*)));
-
+            SLOT(slotUpdateBreakpointMarks(KParts::Part*)));
+    
     // FIXME: maybe, all debugger components should derive from
     // a base class that does this connect.
     connect(parent,     SIGNAL(event(event_t)),
             this,       SLOT(slotEvent(event_t)));
 }
 
-void BreakpointController::slotPartAdded(KParts::Part* part)
-{
-    if (KTextEditor::Document* doc = dynamic_cast<KTextEditor::Document*>(part))
-    {
-        MarkInterface *iface = dynamic_cast<MarkInterface*>(doc);
-        if( !iface )
-            return;
-        
-        iface->setMarkDescription((MarkInterface::MarkTypes)BreakpointMark, \
                i18n("Breakpoint"));
-        iface->setMarkPixmap((MarkInterface::MarkTypes)BreakpointMark, \
                *inactiveBreakpointPixmap());
-        iface->setMarkPixmap((MarkInterface::MarkTypes)ActiveBreakpointMark, \
                *activeBreakpointPixmap());
-        iface->setMarkPixmap((MarkInterface::MarkTypes)ReachedBreakpointMark, \
                *reachedBreakpointPixmap());
-        iface->setMarkPixmap((MarkInterface::MarkTypes)DisabledBreakpointMark, \
                *disabledBreakpointPixmap());
-        iface->setMarkPixmap((MarkInterface::MarkTypes)ExecutionPointMark, \
                *executionPointPixmap());
-        iface->setEditableMarks( BookmarkMark | BreakpointMark );
-        
-        // When a file is loaded then we need to tell the editor (display window)
-        // which lines contain a breakpoint.
-        foreach (Breakpoint* breakpoint, breakpoints())
-            adjustMark(breakpoint, true);
-        
-#if 0
-        connect( doc, 
-                 SIGNAL(markChanged(KTextEditor::Document*, KTextEditor::Mark, \
KTextEditor::MarkInterface::MarkChangeAction)), this, \
SLOT(markChanged(KTextEditor::Document*, KTextEditor::Mark, \
                KTextEditor::MarkInterface::MarkChangeAction)) );
-#endif
-    }
-}
-
-BreakpointController::~BreakpointController()
-{
-}
-
-Breakpoints* BreakpointController::breakpointsItem()
-{
-    return universe_;
-}
-
-QVariant 
-BreakpointController::headerData(int section, Qt::Orientation orientation,
-                                 int role) const
-{ 
-    if (orientation == Qt::Horizontal && role == Qt::DecorationRole
-        && section == 0)
-        return KIcon("dialog-ok-apply");
-    else if (orientation == Qt::Horizontal && role == Qt::DecorationRole
-             && section == 1)
-        return KIcon("system-switch-user");
-
-    return TreeModel::headerData(section, orientation, role);
-}
-
-Qt::ItemFlags BreakpointController::flags(const QModelIndex &index) const
-{
-    /* FIXME: all this logic must be in item */
-    if (!index.isValid())
-        return 0;
-
-    if (index.column() == 0)
-        return static_cast<Qt::ItemFlags>(
-            Qt::ItemIsEnabled | Qt::ItemIsSelectable 
-            | Qt::ItemIsEditable | Qt::ItemIsUserCheckable);
-
-    if (index.column() == NewBreakpoint::location_column 
-        || index.column() == NewBreakpoint::condition_column)
-        return static_cast<Qt::ItemFlags>(
-            Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable);
-
-    return static_cast<Qt::ItemFlags>(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
-}
-
-void BreakpointController::clearExecutionPoint()
-{
-    kDebug(9012) << "clearExecutionPoint";
-    foreach (KDevelop::IDocument* document, \
                KDevelop::ICore::self()->documentController()->openDocuments())
-    {
-        MarkInterface *iface = \
                dynamic_cast<MarkInterface*>(document->textDocument());
-        if (!iface)
-            continue;
-
-        QHashIterator<int, KTextEditor::Mark*> it = iface->marks();
-        while (it.hasNext())
-        {
-            Mark* mark = it.next().value();
-            if( mark->type & ExecutionPointMark )
-                iface->removeMark( mark->line, ExecutionPointMark );
-        }
-    }
-}
-
-
-void BreakpointController::gotoExecutionPoint(const KUrl &url, int lineNum)
-{
-    clearExecutionPoint();
-    kDebug(9012) << "gotoExecutionPoint";
-    KDevelop::IDocument* document = KDevelop::ICore::self()
-        ->documentController()
-        ->openDocument(url, KTextEditor::Cursor(lineNum, 0));
-
-    if( !document )
-        return;
-
-    MarkInterface *iface = dynamic_cast<MarkInterface*>(document->textDocument());
-    if( !iface )
-        return;
-
-    document->textDocument()->blockSignals(true);
-    iface->addMark( lineNum, ExecutionPointMark );
-    document->textDocument()->blockSignals(false);
-}
-
-void BreakpointController::markChanged(
-    KTextEditor::Document *document, 
-    KTextEditor::Mark mark, 
-    KTextEditor::MarkInterface::MarkChangeAction action)
-{
-#if 0
-    int type = mark.type;
-    /* Is this a breakpoint mark, to begin with? */
-    if (type != (MarkInterface::MarkTypes)BreakpointMark
-        && type != (MarkInterface::MarkTypes)ActiveBreakpointMark
-        && type != (MarkInterface::MarkTypes)ReachedBreakpointMark
-        && type != (MarkInterface::MarkTypes)DisabledBreakpointMark)
-        return;
-
-    switch (action) {
-        case KTextEditor::MarkInterface::MarkAdded: {
-            FilePosBreakpoint* fileBreakpoint = new FilePosBreakpoint(this, \
                document->url().path(), mark.line);
-            addBreakpoint(fileBreakpoint);
-        }
-            break;
-
-        case KTextEditor::MarkInterface::MarkRemoved:
-            // Find this breakpoint and delete it
-            foreach (Breakpoint* breakpoint, m_breakpoints)
-                if (FilePosBreakpoint* fileBreakpoint = \
                qobject_cast<FilePosBreakpoint*>(breakpoint))
-                    if (mark.line == fileBreakpoint->lineNum())
-                        if (document->url().path() == fileBreakpoint->fileName()) {
-                            fileBreakpoint->remove();
-                            removeBreakpoint(fileBreakpoint);
-                        }
-            break;
-    }
-
-    if ( KDevelop::ICore::self()->documentController()->activeDocument() && \
KDevelop::ICore::self()->documentController()->activeDocument()->textDocument() == \
                document )
-    {
-        //bring focus back to the editor
-        // TODO probably want a different command here
-        KDevelop::ICore::self()->documentController()->activateDocument(KDevelop::ICore::self()->documentController()->activeDocument());
                
-    }
-#endif
-}
-
-const QPixmap* BreakpointController::inactiveBreakpointPixmap()
-{
-  static QPixmap pixmap=KIcon("script-error").pixmap(QSize(22,22), QIcon::Normal, \
                QIcon::Off);
-  return &pixmap;
-}
-
-const QPixmap* BreakpointController::activeBreakpointPixmap()
-{
-  static QPixmap pixmap=KIcon("script-error").pixmap(QSize(22,22), QIcon::Active, \
                QIcon::Off);
-  return &pixmap;
-}
-
-const QPixmap* BreakpointController::reachedBreakpointPixmap()
-{
-  static QPixmap pixmap=KIcon("script-error").pixmap(QSize(22,22), QIcon::Selected, \
                QIcon::Off);
-  return &pixmap;
-}
-
-const QPixmap* BreakpointController::disabledBreakpointPixmap()
-{
-  static QPixmap pixmap=KIcon("script-error").pixmap(QSize(22,22), QIcon::Disabled, \
                QIcon::Off);
-  return &pixmap;
-}
-
-const QPixmap* BreakpointController::executionPointPixmap()
-{
-  static QPixmap pixmap=KIcon("go-next").pixmap(QSize(22,22), QIcon::Normal, \
                QIcon::Off);
-  return &pixmap;
-}
-
-#if 0
-int BreakpointController::columnCount(const QModelIndex & parent) const
-{
-    Q_UNUSED(parent);
-    return Last + 1;
-}
-
-QVariant BreakpointController::data(const QModelIndex & index, int role) const
-{
-    Breakpoint* breakpoint = breakpointForIndex(index);
-    if (!breakpoint)
-        return QVariant();
-
-    switch (index.column()) {
-        case Enable:
-            switch (role) {
-                case Qt::CheckStateRole:
-                case Qt::EditRole:
-                    return breakpoint->isEnabled();
-            }
-            break;
-
-        case Type:
-            switch (role) {
-                case Qt::DisplayRole: {
-                    QString displayType = breakpoint->displayType();
-                    if (breakpoint->isTemporary())
-                        displayType = i18n(" temporary");
-                    if (breakpoint->isHardwareBP())
-                        displayType += i18n(" hw");
-                    return displayType;
-                }
-            }
-            break;
-
-        case Status:
-            switch (role) {
-                case Qt::DisplayRole:
-                    return breakpoint->statusDisplay(m_activeFlag);
-            }
-            break;
-
-        case Location:
-            switch (role) {
-                case Qt::DisplayRole:
-                case Qt::EditRole:
-                    return breakpoint->location();
-            }
-            break;
-
-        case Condition:
-            switch (role) {
-                case Qt::DisplayRole:
-                case Qt::EditRole:
-                    return breakpoint->conditional();
-            }
-            break;
-
-        case IgnoreCount:
-            switch (role) {
-                case Qt::DisplayRole:
-                case Qt::EditRole:
-                    return breakpoint->ignoreCount();
-            }
-            break;
-
-        case Hits:
-            switch (role) {
-                case Qt::DisplayRole:
-                    return breakpoint->hits();
-            }
-            break;
-
-        case Tracing:
-            switch (role) {
-                case Qt::DisplayRole:
-                    return breakpoint->tracingEnabled() ? i18n("Enabled") : \
                i18n("Disabled");
-            }
-            break;
-    }
-
-    return QVariant();
-}
-
-Qt::ItemFlags BreakpointController::flags(const QModelIndex & index) const
-{
-    Qt::ItemFlags flags = Qt::ItemIsSelectable;
-
-    flags |= Qt::ItemIsEnabled;
-
-    if (index.column() == Enable ||
-        index.column() == Location ||
-        index.column() == Condition ||
-        index.column() == IgnoreCount)
-        flags |= Qt::ItemIsEditable;
-
-    return flags;
-}
-
-QVariant BreakpointController::headerData(int section, Qt::Orientation orientation, \
                int role) const
-{
-    switch (section) {
-        case Enable:
-            break;//return i18n("Enabled");
-        case Type:
-            return i18n("Type");
-        case Status:
-            return i18n("Status");
-        case Location:
-            return i18n("Location");
-        case Condition:
-            return i18n("Condition");
-        case IgnoreCount:
-            return i18n("Ignore Count");
-        case Hits:
-            return i18n("Hits");
-        case Tracing:
-            return i18n("Tracing");
-    }
-
-    return QVariant();
-}
-
-QModelIndex BreakpointController::index(int row, int column, const QModelIndex & \
                parent) const
-{
-    if (row < 0 || column < 0 || column > Last)
-        return QModelIndex();
-
-    if (row >= m_breakpoints.count())
-        return QModelIndex();
-
-    return createIndex(row, column, m_breakpoints.at(row));
-}
-
-QModelIndex BreakpointController::parent(const QModelIndex & index) const
-{
-    Q_UNUSED(index);
-
-    return QModelIndex();
-}
-
-int BreakpointController::rowCount(const QModelIndex & parent) const
-{
-    if (!parent.isValid())
-        return m_breakpoints.count();
-
-    return 0;
-}
-
-bool BreakpointController::setData(const QModelIndex & index, const QVariant & \
                value, int role)
-{
-    Breakpoint* bp = breakpointForIndex(index);
-    if (!bp)
-        return false;
-
-    bool changed = false;
-
-    switch (role) {
-        case Qt::EditRole:
-            switch (index.column()) {
-                case Location:
-                    if (bp->location() != value.toString())
-                    {
-                        // GDB does not allow to change location of
-                        // an existing breakpoint. So, need to remove old
-                        // breakpoint and add another.
-
-                        // Announce to editor that breakpoit at its
-                        // current location is dying.
-                        bp->setActionDie();
-                        adjustMark(bp, false);
-
-                        // However, we don't want the line in breakpoint
-                        // widget to disappear and appear again.
-
-                        // Emit delete command. This won't resync breakpoint
-                        // table (unlike clearBreakpoint), so we won't have
-                        // nasty effect where line in the table first disappears
-                        // and then appears again, and won't have internal issues
-                        // as well.
-                        if (!controller()->stateIsOn(s_dbgNotStarted))
-                            controller()->addCommand(BreakDelete, \
                bp->dbgRemoveCommand().toLatin1());
-
-                        // Now add new breakpoint in gdb. It will correspond to
-                        // the same 'Breakpoint' and 'BreakpointRow' objects in
-                        // KDevelop is the previous, deleted, breakpoint.
-
-                        // Note: clears 'actionDie' implicitly.
-                        bp->setActionAdd(true);
-                        bp->setLocation(value.toString());
-                        adjustMark(bp, true);
-                        changed = true;
-                    }
-                    break;
-
-                case Condition:
-                    bp->setConditional(value.toString());
-                    changed = true;
-                    break;
-
-                case IgnoreCount:
-                    bp->setIgnoreCount(value.toInt());
-                    changed = true;
-                    break;
-
-                case Enable:
-                    bp->setEnabled(value.toBool());
-                    changed = true;
-                    break;
-            }
-            break;
-    }
-
-    if (changed) {
-        bp->setActionModify(true);
-        bp->sendToGdb();
-
-        emit dataChanged(index, index);
-    }
-
-    return changed;
-}
-
-Breakpoint * BreakpointController::breakpointForIndex(const QModelIndex & index) \
                const
-{
-    if (!index.isValid())
-        return 0;
-
-    return static_cast<Breakpoint*>(index.internalPointer());
-}
-
-#endif
-
 GDBController * BreakpointController::controller() const
 {
     return static_cast<GDBController*>(const_cast<QObject*>(QObject::parent()));
 }
 
-
-
 void BreakpointController::slotEvent(event_t e)
 {
     if (e == program_running ||
@@ -517,13 +79,13 @@
     {
     case program_state_changed:
         {
-            universe_->update();
+            breakpointsItem()->update();
         }
 
     case connected_to_program:
         {
             kDebug(9012) << "connected to program";
-            universe_->sendToGDB();
+            dynamic_cast<Breakpoints*>(breakpointsItem())->sendToGDB();
             #if 0
             foreach (Breakpoint* bp, breakpoints())
             {
@@ -547,19 +109,13 @@
             #endif
         }
     case debugger_exited:
-        universe_->markOut();
+        breakpointsItem()->markOut();
         break;
     default:
         ;
     }
 }
 
-
-const QList< Breakpoint * > & BreakpointController::breakpoints() const
-{
-    return m_breakpoints;
-}
-
 void BreakpointController::handleBreakpointList(const GDBMI::ResultRecord& r)
 {
 #if 0
@@ -627,35 +183,6 @@
 #endif
 }
 
-FilePosBreakpoint * BreakpointController::findBreakpoint(const QString & file, int \
                line) const
-{
-    foreach (Breakpoint* bp, breakpoints())
-        if (FilePosBreakpoint* fbp = qobject_cast<FilePosBreakpoint*>(bp))
-            if (fbp->fileName() == file && fbp->lineNum() == line)
-                return fbp;
-
-    return 0;
-}
-
-Watchpoint * BreakpointController::findWatchpoint(const QString & variableName) \
                const
-{
-    foreach (Breakpoint* bp, breakpoints())
-        if (Watchpoint* wp = qobject_cast<Watchpoint*>(bp))
-            if (wp->varName() == variableName)
-                return wp;
-
-    return 0;
-}
-
-Breakpoint* BreakpointController::findBreakpointById(int id) const
-{
-    foreach (Breakpoint* bp, breakpoints())
-        if (bp->dbgId() == id)
-            return bp;
-
-    return 0;
-}
-
 #if 0
 void BreakpointController::savePartialProjectSession(QDomElement* el)
 {
@@ -796,6 +323,35 @@
 }
 #endif
 
+FilePosBreakpoint * BreakpointController::findBreakpoint(const QString & file, int \
line) const +{
+    foreach (Breakpoint* bp, breakpoints())
+        if (FilePosBreakpoint* fbp = qobject_cast<FilePosBreakpoint*>(bp))
+            if (fbp->fileName() == file && fbp->lineNum() == line)
+                return fbp;
+
+    return 0;
+}
+
+Watchpoint * BreakpointController::findWatchpoint(const QString & variableName) \
const +{
+    foreach (Breakpoint* bp, breakpoints())
+        if (Watchpoint* wp = qobject_cast<Watchpoint*>(bp))
+            if (wp->varName() == variableName)
+                return wp;
+
+    return 0;
+}
+
+Breakpoint* BreakpointController::findBreakpointById(int id) const
+{
+    foreach (Breakpoint* bp, breakpoints())
+        if (bp->dbgId() == id)
+            return bp;
+
+    return 0;
+}
+
 Watchpoint* BreakpointController::findWatchpointByAddress(quint64 address) const
 {
     foreach (Breakpoint* breakpoint, breakpoints())
@@ -806,26 +362,34 @@
     return false;
 }
 
-Breakpoint* BreakpointController::addBreakpoint(Breakpoint *bp)
-{
-    beginInsertRows(QModelIndex(), m_breakpoints.count(), m_breakpoints.count());
 
-    m_breakpoints.append(bp);
 
-    endInsertRows();
+void BreakpointController::slotBreakpointModified(Breakpoint* b)
+{
+    if (b->isActionDie())
+    {
+        // Breakpoint was deleted, kill the table row.
+        removeBreakpoint(b);
+    }
+    else
+    {
+#if 0
+        emit dataChanged(indexForBreakpoint(b, 0), indexForBreakpoint(b, Last));
+#endif
+    }
+}
 
-    connect(bp, SIGNAL(modified(Breakpoint*)),
-            this, SLOT(slotBreakpointModified(Breakpoint*)));
-    connect(bp, SIGNAL(enabledChanged(Breakpoint*)),
-            this, SLOT(slotBreakpointEnabledChanged(Breakpoint*)));
 
-    bp->sendToGdb();
+void BreakpointController::removeAllBreakpoints()
+{
+    foreach (Breakpoint* breakpoint, breakpoints())
+        breakpoint->remove();
 
-    adjustMark(bp, true);
-
-    return bp;
+    m_breakpoints.clear();
+    reset();
 }
 
+
 void BreakpointController::adjustMark(Breakpoint* bp, bool add)
 {
     if (FilePosBreakpoint* fbp = qobject_cast<FilePosBreakpoint*>(bp)) {
@@ -852,7 +416,6 @@
     }
 }
 
-
 void BreakpointController::removeBreakpoint(Breakpoint* bp)
 {
     if (!bp)
@@ -872,42 +435,38 @@
     bp->remove();
 }
 
-#if 0
-QModelIndex BreakpointController::indexForBreakpoint(Breakpoint * breakpoint, int \
column) const +Breakpoint* BreakpointController::addBreakpoint(Breakpoint *bp)
 {
-    if (!breakpoint)
-        return QModelIndex();
+    beginInsertRows(QModelIndex(), m_breakpoints.count(), m_breakpoints.count());
 
-    int row = m_breakpoints.indexOf(breakpoint);
-    if (row == -1)
-        return QModelIndex();
+    m_breakpoints.append(bp);
 
-    return createIndex(row, column, breakpoint);
-}
-#endif
+    endInsertRows();
 
-void BreakpointController::removeAllBreakpoints()
-{
-    foreach (Breakpoint* breakpoint, breakpoints())
-        breakpoint->remove();
+    connect(bp, SIGNAL(modified(Breakpoint*)),
+            this, SLOT(slotBreakpointModified(Breakpoint*)));
+    connect(bp, SIGNAL(enabledChanged(Breakpoint*)),
+            this, SLOT(slotBreakpointEnabledChanged(Breakpoint*)));
 
-    m_breakpoints.clear();
-    reset();
+    bp->sendToGdb();
+
+    adjustMark(bp, true);
+
+    return bp;
 }
 
-void BreakpointController::slotBreakpointModified(Breakpoint* b)
+void BreakpointController::slotUpdateBreakpointMarks(KParts::Part* part)
 {
-    if (b->isActionDie())
+    if (KTextEditor::Document* doc = dynamic_cast<KTextEditor::Document*>(part))
     {
-        // Breakpoint was deleted, kill the table row.
-        removeBreakpoint(b);
+        if( !dynamic_cast<MarkInterface*>(doc))
+            return;
+
+        // When a file is loaded then we need to tell the editor (display window)
+        // which lines contain a breakpoint.
+        foreach (Breakpoint* breakpoint, breakpoints())
+            adjustMark(breakpoint, true);
     }
-    else
-    {
-#if 0
-        emit dataChanged(indexForBreakpoint(b, 0), indexForBreakpoint(b, Last));
-#endif
-    }
 }
 
 void BreakpointController::slotBreakpointEnabledChanged(Breakpoint * b)
@@ -915,18 +474,4 @@
     adjustMark(b, true);
 }
 
-const int NewBreakpoint::enable_column;
-const int NewBreakpoint::state_column;
-const int NewBreakpoint::type_column;
-const int NewBreakpoint::location_column;
-const int NewBreakpoint::condition_column;
-
-const char *NewBreakpoint::string_kinds[last_breakpoint_kind] = {
-    "Code",
-    "Write",
-    "Read",
-    "Access"
-};
-
-
 #include "breakpointcontroller.moc"
Index: stackmanager.h
===================================================================
--- stackmanager.h	(revision 886619)
+++ stackmanager.h	(working copy)
@@ -29,11 +29,11 @@
 #include "gdbglobal.h"
 #include "util/treeitem.h"
 
+class TreeModel;
+
 namespace GDBDebugger
 {
 class GDBController;
-class TreeItem;
-class TreeModel;
 
 class Thread : public TreeItem
 {
Index: newbreakpoint.h
===================================================================
--- newbreakpoint.h	(revision 886619)
+++ newbreakpoint.h	(working copy)
@@ -22,7 +22,7 @@
 #ifndef NEWBREAKPOINT_H
 #define NEWBREAKPOINT_H
 
-#include "util/treeitem.h"
+#include "inewbreakpoint.h"
 #include <QSet>
 
 class KConfigGroup;
@@ -32,48 +32,26 @@
     
 class GDBController;
 
-class NewBreakpoint : public TreeItem
+class NewBreakpoint : public KDevelop::INewBreakpoint
 {
 public:
-    enum kind_t { code_breakpoint = 0, write_breakpoint, read_breakpoint,
-                  access_breakpoint, last_breakpoint_kind };
+    NewBreakpoint(TreeModel *model, TreeItem *parent, GDBController* controller, \
kind_t kind); +    NewBreakpoint(TreeModel *model, TreeItem *parent, GDBController* \
controller, const KConfigGroup& config);  
-    NewBreakpoint(TreeModel *model, TreeItem *parent, GDBController* controller,
-                  kind_t kind);
-    NewBreakpoint(TreeModel *model, TreeItem *parent, GDBController* controller,
-                  const KConfigGroup& config);
-
     /* This constructor creates a "please enter location" item, that will
        turn into real breakpoint when user types something.  */
     NewBreakpoint(TreeModel *model, TreeItem *parent,
                   GDBController* controller);
 
-    int id() const { return id_; }
     void update(const GDBMI::Value &b);
-    void fetchMoreChildren() {}
 
     /* Mark this breakpoint as no longer inserted, due to GDB
        no longer running.  */
     void markOut();
 
-    void setColumn(int index, const QVariant& value);
-    void setDeleted();
+    virtual void sendMaybe();
 
-    void sendToGDBMaybe();
-    int hitCount() const;
-
-    QVariant data(int column, int role) const;
-
-    bool pending() const { return pending_; }
-    bool dirty() const { return !dirty_.empty(); }
-    
     void save(KConfigGroup& config);
-
-    static const int enable_column = 0;
-    static const int state_column = 1;
-    static const int type_column = 2;
-    static const int location_column = 3;
-    static const int condition_column = 4;
         
 private:
     void handleDeleted(const GDBMI::ResultRecord &v);
@@ -83,23 +61,9 @@
     void handleAddressComputed(const GDBMI::ResultRecord &r);
 
     friend class Breakpoints;
-    void setLocation(const QString& location);
 
-    int id_;
-    bool enabled_;
-    QSet<int> dirty_;
-    QSet<int> errors_;
-    GDBController* controller_;
-    bool deleted_;
-    int hitCount_;
-    kind_t kind_;
-    /* The GDB 'pending' flag.  */
-    bool pending_;
-    /* For watchpoints, the address it is set at.  */
-    QString address_;
-    bool pleaseEnterLocation_;
-
     static const char *string_kinds[last_breakpoint_kind];
+    GDBController* controller_;
 };
 
 }
Index: ibreakpoints.cpp
===================================================================
--- ibreakpoints.cpp	(revision 0)
+++ ibreakpoints.cpp	(revision 0)
@@ -0,0 +1,78 @@
+/* This file is part of the KDE project
+   Copyright (C) 2002 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
+   Copyright (C) 2002 John Firebaugh <jfirebaugh@kde.org>
+   Copyright (C) 2006, 2008 Vladimir Prus <ghost@cs.msu.su>
+   Copyright (C) 2007 Hamish Rodda <rodda@kde.org>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+*/
+
+#include "ibreakpoints.h"
+#include "inewbreakpoint.h"
+
+#include <KConfigGroup>
+#include <KGlobal>
+#include <KSharedConfig>
+
+using namespace KDevelop;
+
+IBreakpoints::IBreakpoints(IBreakpointController *model)
+ : TreeItem(model)
+{}
+
+void IBreakpoints::markOut()
+{
+    for (int i = 0; i < childItems.size(); ++i)
+    {
+        INewBreakpoint *b = dynamic_cast<INewBreakpoint *>(child(i));
+        Q_ASSERT(b);
+        b->markOut();
+    }
+}
+
+void IBreakpoints::save()
+{
+    KConfigGroup breakpoints = KGlobal::config()->group("breakpoints");
+    // Note that the last item is always "click to create" item, which
+    // we don't want to save.
+    breakpoints.writeEntry("number", childItems.size()-1);
+    for (int i = 0; i < childItems.size()-1; ++i)
+    {
+        INewBreakpoint *b = dynamic_cast<INewBreakpoint *>(child(i));
+        KConfigGroup g = breakpoints.group(QString::number(i));
+        b->save(g);
+    }
+}
+
+INewBreakpoint *IBreakpoints::breakpointById(int id)
+{
+    for (int i = 0; i < childItems.size(); ++i)
+    {
+        INewBreakpoint *b = static_cast<INewBreakpoint *>(child(i));
+        if (b->id() == id)
+            return b;
+    }
+    return NULL;
+}
+
+void IBreakpoints::remove(const QModelIndex &index)
+{
+    INewBreakpoint *b = static_cast<INewBreakpoint *>(model()->itemForIndex(index));
+    b->setDeleted();
+    b->sendMaybe();
+}
+
+#include "ibreakpoints.moc"
\ No newline at end of file
Index: tooltipwidget.h
===================================================================
--- tooltipwidget.h	(revision 886619)
+++ tooltipwidget.h	(working copy)
@@ -12,10 +12,11 @@
 class QString;
 class QResizeEvent;
 
+class TreeModel;
+class TreeItem;
+
 namespace GDBDebugger
 {
-    class TreeModel;
-    class TreeItem;
     class GDBController;
     class Variable;
 
Index: breakpointwidget.h
===================================================================
--- breakpointwidget.h	(revision 886619)
+++ breakpointwidget.h	(working copy)
@@ -360,7 +360,7 @@
         }
 
     private:
-        void edit(NewBreakpoint *n)
+        void edit(KDevelop::INewBreakpoint *n)
         {
             QModelIndex index = controller_->breakpoints()
                 ->indexForItem(n, NewBreakpoint::location_column);
@@ -414,7 +414,7 @@
                that is added in GDB outside kdevelop.  In this case we'll
                first try to find the breakpoint, and fail, and only then
                update the breakpoint table and notice the new one.  */
-            NewBreakpoint *b = controller_->breakpoints()->breakpointsItem()
+            KDevelop::INewBreakpoint *b = \
                controller_->breakpoints()->breakpointsItem()
                 ->breakpointById(id);
             if (b)
             {
Index: breakpointcontroller.h
===================================================================
--- breakpointcontroller.h	(revision 886619)
+++ breakpointcontroller.h	(working copy)
@@ -23,7 +23,6 @@
 #define BREAKPOINTCONTROLLER_H
 
 #include <QAbstractItemModel>
-#include <Qt>
 #include <QSet>
 
 #include <KUrl>
@@ -31,13 +30,11 @@
 #include <KConfigGroup>
 #include <KParts/Part>
 
-#include <ktexteditor/markinterface.h>
-
 #include "mi/gdbmi.h"
 #include "gdbglobal.h"
-#include "util/treemodel.h"
-#include "util/treeitem.h"
 
+#include "ibreakpointcontroller.h"
+
 namespace KDevelop { class IDocument; }
 
 namespace GDBDebugger
@@ -54,50 +51,14 @@
 * point of the debugger.
 * We may change, add or remove breakpoints in this class.
 */
-class BreakpointController : public TreeModel
+class BreakpointController : public KDevelop::IBreakpointController
 {
     Q_OBJECT
 
 public:
     BreakpointController(GDBController* parent);
-    ~BreakpointController();
-
     GDBController* controller() const;
 
-    Breakpoints* breakpointsItem();
-
-    const QList<Breakpoint*>& breakpoints() const;
-
-    QVariant headerData(int section, Qt::Orientation orientation,
-                        int role) const;
-
-    Qt::ItemFlags flags(const QModelIndex &index) const;
-
-    /**
-    * Displays an icon in the file at the line that the debugger has stoped
-    * at.
-    * @param url        The file the debugger has stopped at.
-    * @param lineNum    The line number to display. Note: We may not know it.
-    */
-    void gotoExecutionPoint(const KUrl &url, int lineNum=-1);
-
-    /**
-    * Remove the executution point being displayed.
-    */
-    void clearExecutionPoint();
-
-    enum Columns {
-        Enable,
-        Type,
-        Status,
-        Location,
-        Condition,
-        IgnoreCount,
-        Hits,
-        Tracing,
-        Last = Tracing
-    };
-
     FilePosBreakpoint* findBreakpoint(const QString& file, int line) const;
     Watchpoint* findWatchpoint(const QString& variableName) const;
     Watchpoint* findWatchpointByAddress(quint64 address) const;
@@ -105,65 +66,20 @@
 
     Breakpoint* addBreakpoint(Breakpoint *bp);
     void removeBreakpoint(Breakpoint *bp);
-    void removeAllBreakpoints();
 
-signals:
-
-    /**
-    * The user has toggled a breakpoint.
-    */
-    void toggledBreakpoint(const QString &fileName, int lineNum);
-
-    /**
-    * The user wants to edit the properties of a breakpoint.
-    */
-    void editedBreakpoint(const QString &fileName, int lineNum);
-
-    /**
-    * The user wants to enable/disable a breakpoint.
-    */
-    void toggledBreakpointEnabled(const QString &fileName, int lineNum);
-
-private slots:
-
-    void slotPartAdded(KParts::Part* part);
-
-    /**
-    * Called by the TextEditor interface when the marks have changed position
-    * because the user has added or removed source.
-    * In here we figure out if we need to reset the breakpoints due to
-    * these source changes.
-    */
-    void markChanged(KTextEditor::Document *document, KTextEditor::Mark mark, \
                KTextEditor::MarkInterface::MarkChangeAction action);
-
+    QList<Breakpoint*> breakpoints() const { return m_breakpoints; }
+    
+    void removeAllBreakpoints();
+    
+public slots:
     void slotEvent(event_t);
-
     void slotBreakpointModified(Breakpoint* b);
     void slotBreakpointEnabledChanged(Breakpoint* b);
-
+    void slotUpdateBreakpointMarks(KParts::Part* part);
+    
 private:
-    Breakpoints* universe_;
-
-
-    void handleBreakpointList(const GDBMI::ResultRecord& r);
-
     void adjustMark(Breakpoint* bp, bool add);
-
-    static const QPixmap* inactiveBreakpointPixmap();
-    static const QPixmap* activeBreakpointPixmap();
-    static const QPixmap* reachedBreakpointPixmap();
-    static const QPixmap* disabledBreakpointPixmap();
-    static const QPixmap* executionPointPixmap();
-
-    enum MarkType {
-        BookmarkMark           = KTextEditor::MarkInterface::markType01,
-        BreakpointMark         = KTextEditor::MarkInterface::markType02,
-        ActiveBreakpointMark   = KTextEditor::MarkInterface::markType03,
-        ReachedBreakpointMark  = KTextEditor::MarkInterface::markType04,
-        DisabledBreakpointMark = KTextEditor::MarkInterface::markType05,
-        ExecutionPointMark     = KTextEditor::MarkInterface::markType06
-    };
-
+    void handleBreakpointList(const GDBMI::ResultRecord& r);
     QList<Breakpoint*> m_breakpoints;
 };
 
Index: breakpoints.h
===================================================================
--- breakpoints.h	(revision 886619)
+++ breakpoints.h	(working copy)
@@ -22,7 +22,7 @@
 #ifndef BREAKPOINTS_H
 #define BREAKPOINTS_H
 
-#include "util/treeitem.h"
+#include "ibreakpoints.h"
 
 class QModelIndex;
 
@@ -33,35 +33,25 @@
 class GDBController;
 class NewBreakpoint;
 
-class Breakpoints : public TreeItem
+class Breakpoints : public KDevelop::IBreakpoints
 {
     Q_OBJECT
 public:
-    Breakpoints(TreeModel *model, GDBController *controller);
+    Breakpoints(KDevelop::IBreakpointController *model, GDBController *controller);
 
     void sendToGDB();
     void markOut();
 
     void update();
-
     void fetchMoreChildren() {}
+    virtual void createHelperBreakpoint();
+    
+    KDevelop::INewBreakpoint* addCodeBreakpoint();
+    KDevelop::INewBreakpoint* addWatchpoint();
+    KDevelop::INewBreakpoint* addWatchpoint(const QString& expression);
+    KDevelop::INewBreakpoint* addReadWatchpoint();
 
-    NewBreakpoint* addCodeBreakpoint();
-    NewBreakpoint* addWatchpoint();
-    NewBreakpoint* addWatchpoint(const QString& expression);
-    NewBreakpoint* addReadWatchpoint();
-    void remove(const QModelIndex &index);
-
-    NewBreakpoint *breakpointById(int id);
-
-    void createHelperBreakpoint();
-
-Q_SIGNALS:
-    void error(NewBreakpoint *b, const QString& message, int column);
-    friend class NewBreakpoint;                                                      \
                
-
 public slots:
-    void save();
     void load();
 
 private:
Index: util/treeitem.cpp
===================================================================
--- util/treeitem.cpp	(revision 886619)
+++ util/treeitem.cpp	(working copy)
@@ -7,8 +7,6 @@
 
 #include "kdebug.h"
 
-using namespace GDBDebugger;
-
 TreeItem::TreeItem(TreeModel* model, TreeItem *parent)
 : model_(model), more_(false), ellipsis_(0), expanded_(false)
 {
Index: util/treeview.h
===================================================================
--- util/treeview.h	(revision 886619)
+++ util/treeview.h	(working copy)
@@ -4,10 +4,10 @@
 
 #include <QTreeView>
 
+class TreeModel;
+
 namespace GDBDebugger
 {
-    class TreeModel;
-
     class AsyncTreeView : public QTreeView
     {
         Q_OBJECT
Index: util/treemodel.cpp
===================================================================
--- util/treemodel.cpp	(revision 886619)
+++ util/treemodel.cpp	(working copy)
@@ -8,8 +8,6 @@
 
 #include "kdebug.h"
 
-using namespace GDBDebugger;
-
 TreeModel::TreeModel(const QVector<QString>& headers,
                      QObject *parent)
   : QAbstractItemModel(parent), headers_(headers), root_(NULL)
Index: util/treeitem.h
===================================================================
--- util/treeitem.h	(revision 886619)
+++ util/treeitem.h	(working copy)
@@ -9,8 +9,6 @@
 
 #include <iostream>
 
-namespace GDBDebugger {
-
 class TreeModel;
 
 class TreeItem: public QObject
@@ -90,6 +88,4 @@
     bool expanded_;
 };
 
-}
-
 #endif
Index: util/treemodel.h
===================================================================
--- util/treemodel.h	(revision 886619)
+++ util/treemodel.h	(working copy)
@@ -7,8 +7,6 @@
 #include <QVector>
 #include <QString>
 
-namespace GDBDebugger {
-
 class TreeItem;
 
 class TreeModel : public QAbstractItemModel
@@ -55,6 +53,4 @@
     bool editable_;
 };
 
-}
-
 #endif
Index: ibreakpoints.h
===================================================================
--- ibreakpoints.h	(revision 0)
+++ ibreakpoints.h	(revision 0)
@@ -0,0 +1,64 @@
+/* This file is part of the KDE project
+   Copyright (C) 2002 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
+   Copyright (C) 2002 John Firebaugh <jfirebaugh@kde.org>
+   Copyright (C) 2007 Hamish Rodda <rodda@kde.org>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+*/
+
+#ifndef IBREAKPOINTS_H
+#define IBREAKPOINTS_H
+
+#include "util/treeitem.h"
+#include "ibreakpointcontroller.h"
+
+class QModelIndex;
+
+namespace KDevelop
+{
+class INewBreakpoint;
+class IBreakpointController;
+    
+class IBreakpoints : public TreeItem
+{
+    Q_OBJECT
+public:
+    IBreakpoints(IBreakpointController *model);
+
+    void markOut();
+
+    void remove(const QModelIndex &index);
+    virtual void update() =0;
+    
+    virtual INewBreakpoint* addCodeBreakpoint()=0;
+    virtual INewBreakpoint* addWatchpoint()=0;
+    virtual INewBreakpoint* addWatchpoint(const QString& expression)=0;
+    virtual INewBreakpoint* addReadWatchpoint()=0;
+    virtual void createHelperBreakpoint()=0;
+    INewBreakpoint *breakpointById(int id);
+
+    void errorEmit(INewBreakpoint *b, const QString& message, int column) { emit \
error(b, message, column); } +Q_SIGNALS:
+    void error(INewBreakpoint *b, const QString& message, int column);
+
+public slots:
+    void save();
+    virtual void load()=0;
+};
+
+}
+
+#endif
Index: debuggerplugin.cpp
===================================================================
--- debuggerplugin.cpp	(revision 886619)
+++ debuggerplugin.cpp	(working copy)
@@ -124,6 +124,7 @@
      work, but they don't need any toolbar.  So, suppress toolbar action.  */
   virtual QList<QAction*> toolBarActions( QWidget* viewWidget ) const
   {
+      Q_UNUSED(viewWidget);
       return QList<QAction*>();
   }
   
Index: ibreakpointcontroller.h
===================================================================
--- ibreakpointcontroller.h	(revision 0)
+++ ibreakpointcontroller.h	(revision 0)
@@ -0,0 +1,130 @@
+/* This file is part of the KDE project
+   Copyright (C) 2002 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
+   Copyright (C) 2002 John Firebaugh <jfirebaugh@kde.org>
+   Copyright (C) 2007 Hamish Rodda <rodda@kde.org>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+*/
+
+#ifndef IBREAKPOINTCONTROLLER_H
+#define IBREAKPOINTCONTROLLER_H
+
+#include "util/treemodel.h"
+#include "util/treeitem.h"
+#include "ibreakpoints.h"
+
+#include <ktexteditor/markinterface.h>
+
+class KUrl;
+
+namespace KParts { class Part; }
+
+namespace KDevelop
+{
+class IBreakpoints;
+
+class IBreakpointController : public TreeModel
+{
+    Q_OBJECT
+
+public:
+    IBreakpointController(QObject* parent, IBreakpoints* universe);
+    virtual ~IBreakpointController() {}
+
+    IBreakpoints* breakpointsItem();
+
+    QVariant headerData(int section, Qt::Orientation orientation, int role) const;
+
+    Qt::ItemFlags flags(const QModelIndex &index) const;
+
+    /**
+    * Displays an icon in the file at the line that the debugger has stoped
+    * at.
+    * @param url        The file the debugger has stopped at.
+    * @param lineNum    The line number to display. Note: We may not know it.
+    */
+    void gotoExecutionPoint(const KUrl &url, int lineNum=-1);
+
+    /**
+    * Remove the executution point being displayed.
+    */
+    void clearExecutionPoint();
+
+    enum Columns {
+        Enable,
+        Type,
+        Status,
+        Location,
+        Condition,
+        IgnoreCount,
+        Hits,
+        Tracing,
+        Last = Tracing
+    };
+    
+protected:
+    enum MarkType {
+        BookmarkMark           = KTextEditor::MarkInterface::markType01,
+        BreakpointMark         = KTextEditor::MarkInterface::markType02,
+        ActiveBreakpointMark   = KTextEditor::MarkInterface::markType03,
+        ReachedBreakpointMark  = KTextEditor::MarkInterface::markType04,
+        DisabledBreakpointMark = KTextEditor::MarkInterface::markType05,
+        ExecutionPointMark     = KTextEditor::MarkInterface::markType06
+    };
+
+signals:
+
+    /**
+    * The user has toggled a breakpoint.
+    */
+    void toggledBreakpoint(const QString &fileName, int lineNum);
+
+    /**
+    * The user wants to edit the properties of a breakpoint.
+    */
+    void editedBreakpoint(const QString &fileName, int lineNum);
+
+    /**
+    * The user wants to enable/disable a breakpoint.
+    */
+    void toggledBreakpointEnabled(const QString &fileName, int lineNum);
+
+private slots:
+
+    void slotPartAdded(KParts::Part* part);
+
+    /**
+    * Called by the TextEditor interface when the marks have changed position
+    * because the user has added or removed source.
+    * In here we figure out if we need to reset the breakpoints due to
+    * these source changes.
+    */
+    void markChanged(KTextEditor::Document *document, KTextEditor::Mark mark, \
KTextEditor::MarkInterface::MarkChangeAction action); +
+private:
+    IBreakpoints* universe_;
+
+    static const QPixmap* inactiveBreakpointPixmap();
+    static const QPixmap* activeBreakpointPixmap();
+    static const QPixmap* reachedBreakpointPixmap();
+    static const QPixmap* disabledBreakpointPixmap();
+    static const QPixmap* executionPointPixmap();
+};
+
+
+}
+
+#endif
\ No newline at end of file
Index: breakpoints.cpp
===================================================================
--- breakpoints.cpp	(revision 886619)
+++ breakpoints.cpp	(working copy)
@@ -34,8 +34,8 @@
 namespace GDBDebugger
 {
 
-Breakpoints::Breakpoints(TreeModel *model, GDBController *controller)
-: TreeItem(model), controller_(controller)
+Breakpoints::Breakpoints(KDevelop::IBreakpointController *model, GDBController \
*controller) +    : IBreakpoints(model), controller_(controller)
 {
 }
 
@@ -54,7 +54,7 @@
     appendChild(n);
 }
 
-NewBreakpoint* Breakpoints::addCodeBreakpoint()
+KDevelop::INewBreakpoint* Breakpoints::addCodeBreakpoint()
 {
     NewBreakpoint* n = new NewBreakpoint(model(), this, controller_,
                                          NewBreakpoint::code_breakpoint);
@@ -62,7 +62,7 @@
     return n;
 }
 
-NewBreakpoint* Breakpoints::addWatchpoint()
+KDevelop::INewBreakpoint* Breakpoints::addWatchpoint()
 {
     NewBreakpoint* n = new NewBreakpoint(model(), this, controller_,
                                          NewBreakpoint::write_breakpoint);
@@ -70,7 +70,7 @@
     return n;
 }
 
-NewBreakpoint* Breakpoints::addWatchpoint(const QString& expression)
+KDevelop::INewBreakpoint* Breakpoints::addWatchpoint(const QString& expression)
 {
     NewBreakpoint* n = new NewBreakpoint(model(), this, controller_,
                                          NewBreakpoint::write_breakpoint);
@@ -79,7 +79,7 @@
     return n;
 }
 
-NewBreakpoint* Breakpoints::addReadWatchpoint()
+KDevelop::INewBreakpoint* Breakpoints::addReadWatchpoint()
 {
     NewBreakpoint* n = new NewBreakpoint(model(), this, controller_,
                                          NewBreakpoint::read_breakpoint);
@@ -88,25 +88,6 @@
     return n;
 }
 
-void Breakpoints::remove(const QModelIndex &index)
-{
-    NewBreakpoint *b = static_cast<NewBreakpoint *>(
-        model()->itemForIndex(index));
-    b->setDeleted();
-    b->sendToGDBMaybe();
-}
-
-NewBreakpoint *Breakpoints::breakpointById(int id)
-{
-    for (int i = 0; i < childItems.size(); ++i)
-    {
-        NewBreakpoint *b = static_cast<NewBreakpoint *>(child(i));
-        if (b->id() == id)
-            return b;
-    }
-    return NULL;
-}
-
 void Breakpoints::handleBreakpointList(const GDBMI::ResultRecord &r)
 {
     const GDBMI::Value& blist = r["BreakpointTable"]["body"];
@@ -131,7 +112,7 @@
         const GDBMI::Value& mi_b = blist[i];            
         int id = mi_b["number"].toInt();
         
-        NewBreakpoint *b = breakpointById(id);
+        NewBreakpoint *b = dynamic_cast<NewBreakpoint*>(breakpointById(id));
         if (!b)
         {
             NewBreakpoint::kind_t kind = NewBreakpoint::code_breakpoint;
@@ -157,34 +138,10 @@
     {
         NewBreakpoint *b = dynamic_cast<NewBreakpoint *>(child(i));
         Q_ASSERT(b);
-        b->sendToGDBMaybe();
+        b->sendMaybe();
     }
 }
 
-void Breakpoints::markOut()
-{
-    for (int i = 0; i < childItems.size(); ++i)
-    {
-        NewBreakpoint *b = dynamic_cast<NewBreakpoint *>(child(i));
-        Q_ASSERT(b);
-        b->markOut();
-    }
-}
-
-void Breakpoints::save()
-{
-    KConfigGroup breakpoints = KGlobal::config()->group("breakpoints");
-    // Note that the last item is always "click to create" item, which
-    // we don't want to save.
-    breakpoints.writeEntry("number", childItems.size()-1);
-    for (int i = 0; i < childItems.size()-1; ++i)
-    {
-        NewBreakpoint *b = dynamic_cast<NewBreakpoint *>(child(i));
-        KConfigGroup g = breakpoints.group(QString::number(i));
-        b->save(g);
-    }
-}
-
 void Breakpoints::load()
 {
     KConfigGroup breakpoints = KGlobal::config()->group("breakpoints");
Index: inewbreakpoint.h
===================================================================
--- inewbreakpoint.h	(revision 0)
+++ inewbreakpoint.h	(revision 0)
@@ -0,0 +1,93 @@
+/* This file is part of the KDE project
+   Copyright (C) 2002 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
+   Copyright (C) 2002 John Firebaugh <jfirebaugh@kde.org>
+   Copyright (C) 2007 Hamish Rodda <rodda@kde.org>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+*/
+
+#ifndef INEWBREAKPOINT_H
+#define INEWBREAKPOINT_H
+
+#include "util/treeitem.h"
+#include <QSet>
+
+class KConfigGroup;
+
+namespace KDevelop
+{
+    
+class INewBreakpoint : public TreeItem
+{
+public:
+    enum kind_t { code_breakpoint = 0, write_breakpoint, read_breakpoint,
+                  access_breakpoint, last_breakpoint_kind };
+
+    INewBreakpoint(TreeModel *model, TreeItem *parent, kind_t kind);
+    INewBreakpoint(TreeModel *model, TreeItem *parent, const KConfigGroup& config);
+
+    /** This constructor creates a "please enter location" item, that will
+       turn into real breakpoint when user types something.  */
+    INewBreakpoint(TreeModel *model, TreeItem *parent);
+
+    int id() const { return id_; }
+    void fetchMoreChildren() {}
+
+    /** Mark this breakpoint as no longer inserted, due to GDB
+       no longer running.  */
+    void markOut();
+
+    void setColumn(int index, const QVariant& value);
+    void setDeleted();
+
+    int hitCount() const { return hitCount_; }
+
+    QVariant data(int column, int role) const;
+
+    bool pending() const { return pending_; }
+    bool dirty() const { return !dirty_.empty(); }
+    
+    void save(KConfigGroup& config);
+
+    static const int enable_column = 0;
+    static const int state_column = 1;
+    static const int type_column = 2;
+    static const int location_column = 3;
+    static const int condition_column = 4;
+    virtual void sendMaybe()=0;
+    
+protected:
+    friend class IBreakpoints;
+    void setLocation(const QString& location);
+
+    int id_;
+    bool enabled_;
+    QSet<int> dirty_;
+    QSet<int> errors_;
+    bool deleted_;
+    int hitCount_;
+    kind_t kind_;
+    /* The GDB 'pending' flag.  */
+    bool pending_;
+    /* For watchpoints, the address it is set at.  */
+    QString address_;
+    bool pleaseEnterLocation_;
+
+    static const char *string_kinds[last_breakpoint_kind];
+};
+
+}
+#endif
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt	(revision 886619)
+++ CMakeLists.txt	(working copy)
@@ -52,6 +52,9 @@
     gdboutputwidget.cpp
     debuggertracingdialog.cpp
     breakpointcontroller.cpp
+    ibreakpointcontroller.cpp
+    ibreakpoints.cpp
+    inewbreakpoint.cpp
     breakpoints.cpp
     newbreakpoint.cpp
     stackmanager.cpp
Index: newbreakpoint.cpp
===================================================================
--- newbreakpoint.cpp	(revision 886619)
+++ newbreakpoint.cpp	(working copy)
@@ -38,9 +38,7 @@
 
 NewBreakpoint::NewBreakpoint(TreeModel *model, TreeItem *parent, 
                              GDBController* controller, kind_t kind)
-: TreeItem(model, parent), id_(-1), enabled_(true), 
-  controller_(controller), deleted_(false), hitCount_(0), kind_(kind),
-  pending_(false), pleaseEnterLocation_(false)
+: KDevelop::INewBreakpoint(model, parent, kind), controller_(controller)
 {
     setData(QVector<QString>() << "" << "" << "" << "" << "");
 }
@@ -48,37 +46,14 @@
 NewBreakpoint::NewBreakpoint(TreeModel *model, TreeItem *parent, 
                              GDBController* controller,
                              const KConfigGroup& config)
-: TreeItem(model, parent), id_(-1), enabled_(true), 
-  controller_(controller), deleted_(false), hitCount_(0),
-  pending_(false), pleaseEnterLocation_(false)
+: KDevelop::INewBreakpoint(model, parent, config), controller_(controller)
 {
-    QString kindString = config.readEntry("kind", "");
-    int i;
-    for (i = 0; i < last_breakpoint_kind; ++i)
-        if (string_kinds[i] == kindString)
-        {
-            kind_ = (kind_t)i;
-            break;
-        }
-    /* FIXME: maybe, should silently ignore this breakpoint.  */
-    Q_ASSERT(i < last_breakpoint_kind);
-    enabled_ = config.readEntry("enabled", false);
-
-    QString location = config.readEntry("location", "");
-    QString condition = config.readEntry("condition", "");
-
-    dirty_.insert(location_column);
-
-    setData(QVector<QString>() << "" << "" << "" << location << condition);
 }
 
 NewBreakpoint::NewBreakpoint(TreeModel *model, TreeItem *parent,
                              GDBController* controller)
-: TreeItem(model, parent), id_(-1), enabled_(true), 
-  controller_(controller), deleted_(false), hitCount_(0), 
-  kind_(code_breakpoint), pending_(false), pleaseEnterLocation_(true)
+: KDevelop::INewBreakpoint(model, parent), controller_(controller)
 {   
-    setData(QVector<QString>() << "" << "" << "" << "" << "");
 }
 
 void NewBreakpoint::update(const GDBMI::Value &b)
@@ -173,130 +148,9 @@
 #endif        
 }
 
-void NewBreakpoint::setColumn(int index, const QVariant& value)
+void NewBreakpoint::sendMaybe()
 {
-    if (index == enable_column)
-    {
-        enabled_ = static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked;
-    }
-
-    /* Helper breakpoint becomes a real breakpoint only if user types
-       some real location.  */
-    if (pleaseEnterLocation_ && value.toString().isEmpty())
-        return;
-
-    if (index == location_column || index == condition_column)
-    {
-        itemData[index] = value;
-        if (pleaseEnterLocation_)
-        {
-            pleaseEnterLocation_ = false;
-            static_cast<Breakpoints*>(parentItem)->createHelperBreakpoint();
-        }
-    }
-
-    dirty_.insert(index);
-    errors_.remove(index);
-    reportChange();
-    sendToGDBMaybe();
-}
-
-void NewBreakpoint::markOut()
-{
-    id_ = -1;
-    dirty_.insert(location_column);
-    dirty_.insert(condition_column);
-}
-
-QVariant NewBreakpoint::data(int column, int role) const
-{
     if (pleaseEnterLocation_)
-    {
-        if (column != location_column)
-        {
-            if (role == Qt::DisplayRole)
-                return QString();
-            else
-                return QVariant();
-        }
-        
-        if (role == Qt::DisplayRole)
-            return i18n("Double-click to create new code breakpoint");
-        if (role == Qt::ForegroundRole)
-            // FIXME: returning hardcoded gray is bad,
-            // but we don't have access to any widget, or pallette
-            // thereof, at this point.
-            return QColor(128, 128, 128);
-        if (role == Qt::EditRole)
-            return QString();
-    }
-
-    if (column == enable_column)
-    {
-        if (role == Qt::CheckStateRole)
-            return enabled_ ? Qt::Checked : Qt::Unchecked;
-        else if (role == Qt::DisplayRole)
-            return "";
-        else
-            return QVariant();
-    }
-
-    if (column == state_column)
-    {
-        if (role == Qt::DecorationRole)
-        {
-            if (dirty_.empty())
-            {
-                if (pending_)
-                    return KIcon("help-contents");            
-                return KIcon("dialog-apply");
-            }
-            else
-                return KIcon("system-switch-user");
-        }
-        else if (role == Qt::DisplayRole)
-            return "";
-        else
-            return QVariant();
-    }
-
-    if (column == type_column && role == Qt::DisplayRole)
-    {
-        return string_kinds[kind_];
-    }
-
-    if (role == Qt::DecorationRole)
-    {
-        if ((column == location_column && errors_.contains(location_column))
-            || (column == condition_column && errors_.contains(condition_column)))
-        {
-            /* FIXME: does this leak? Is this efficient? */
-            return KIcon("dialog-warning");
-        }
-        return QVariant();
-    }
-
-    if (column == location_column && role == Qt::DisplayRole
-        && !address_.isEmpty())
-        return QString("%1 (%2)").arg(itemData[location_column].toString())
-            .arg(address_);
-
-    return TreeItem::data(column, role);
-}
-
-void NewBreakpoint::setDeleted()
-{
-    deleted_ = true;
-}
-
-int NewBreakpoint::hitCount() const
-{
-    return hitCount_;
-}
-
-void NewBreakpoint::sendToGDBMaybe()
-{
-    if (pleaseEnterLocation_)
         return;
 
     if (controller_->stateIsOn(s_dbgNotStarted))
@@ -386,7 +240,7 @@
     else
     {
         id_ = -1;
-        sendToGDBMaybe();
+        sendMaybe();
     }
 }
 
@@ -397,8 +251,8 @@
         errors_.insert(location_column);
         dirty_.remove(location_column);
         reportChange();        
-        emit static_cast<Breakpoints*>(parentItem)
-            ->error(this, r["msg"].literal(), location_column);
+        static_cast<Breakpoints*>(parentItem)
+            ->errorEmit(this, r["msg"].literal(), location_column);
     }
     else
     {
@@ -412,7 +266,7 @@
             id_ = r["wpt"]["number"].toInt();
         }
         reportChange();
-        sendToGDBMaybe();
+        sendMaybe();
     }
 }
 
@@ -423,7 +277,7 @@
     // breakpoint itself cannot be inserted in the target.
     dirty_.remove(enable_column);
     reportChange();
-    sendToGDBMaybe();
+    sendMaybe();
 }
 
 void NewBreakpoint::handleConditionChanged(const GDBMI::ResultRecord &r)
@@ -433,8 +287,8 @@
         errors_.insert(condition_column);
         dirty_.remove(condition_column);
         reportChange();
-        emit static_cast<Breakpoints*>(parentItem)
-            ->error(this, r["msg"].literal(), condition_column);
+        static_cast<Breakpoints*>(parentItem)
+            ->errorEmit(this, r["msg"].literal(), condition_column);
     }
     else
     {
@@ -442,7 +296,7 @@
            Presumably, it means that the condition is always what we want.  */
         dirty_.remove(condition_column);
         reportChange();
-        sendToGDBMaybe();
+        sendMaybe();
     }
 }
 
@@ -453,8 +307,8 @@
         errors_.insert(location_column);
         dirty_.remove(location_column);
         reportChange();
-        emit static_cast<Breakpoints*>(parentItem)
-            ->error(this, r["msg"].literal(), location_column);
+        static_cast<Breakpoints*>(parentItem)
+            ->errorEmit(this, r["msg"].literal(), location_column);
     }
     else
     {
@@ -474,20 +328,4 @@
     }
 }
 
-void NewBreakpoint::setLocation(const QString& location)
-{
-    itemData[location_column] = location;
-    dirty_.insert(location_column);
-    reportChange();
-    sendToGDBMaybe();
 }
-
-void NewBreakpoint::save(KConfigGroup& config)
-{
-    config.writeEntry("kind", string_kinds[kind_]);
-    config.writeEntry("enabled", enabled_);
-    config.writeEntry("location", itemData[location_column]);
-    config.writeEntry("condition", itemData[condition_column]);
-}
-
-}
Index: ibreakpointcontroller.cpp
===================================================================
--- ibreakpointcontroller.cpp	(revision 0)
+++ ibreakpointcontroller.cpp	(revision 0)
@@ -0,0 +1,484 @@
+/* This file is part of the KDE project
+   Copyright (C) 2002 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
+   Copyright (C) 2002 John Firebaugh <jfirebaugh@kde.org>
+   Copyright (C) 2006, 2008 Vladimir Prus <ghost@cs.msu.su>
+   Copyright (C) 2007 Hamish Rodda <rodda@kde.org>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+*/
+
+#include "ibreakpointcontroller.h"
+#include "inewbreakpoint.h"
+#include "ibreakpoints.h"
+
+#include <interfaces/icore.h>
+#include <interfaces/idocumentcontroller.h>
+#include <interfaces/idocument.h>
+#include <ktexteditor/markinterface.h>
+
+#include <QPixmap>
+#include <KIcon>
+#include <KParts/PartManager>
+#include <KDebug>
+#include <KLocale>
+
+#include <ktexteditor/document.h>
+
+using namespace KDevelop;
+using namespace KTextEditor;
+
+IBreakpointController::IBreakpointController(QObject* parent, IBreakpoints* \
universe) +    : TreeModel(QVector<QString>() << "" << "" << "Type" << "Location" << \
"Condition", parent), universe_(universe) +{
+    setRootItem(universe_);
+    universe_->load();
+    universe_->createHelperBreakpoint();
+
+    connect(this, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
+            universe_, SLOT(save()));
+    connect(this, SIGNAL(rowsRemoved(const QModelIndex &, int, int)),
+            universe_, SLOT(save()));
+    connect(this, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)),
+            universe_, SLOT(save()));
+
+    //new ModelTest(this, this);
+
+    foreach(KParts::Part* p, KDevelop::ICore::self()->partController()->parts())
+        slotPartAdded(p);
+    connect(KDevelop::ICore::self()->partController(),
+            SIGNAL(partAdded(KParts::Part*)),
+            this,
+            SLOT(slotPartAdded(KParts::Part*)));
+}
+
+void IBreakpointController::slotPartAdded(KParts::Part* part)
+{
+    if (KTextEditor::Document* doc = dynamic_cast<KTextEditor::Document*>(part))
+    {
+        MarkInterface *iface = dynamic_cast<MarkInterface*>(doc);
+        if( !iface )
+            return;
+        
+        iface->setMarkDescription((MarkInterface::MarkTypes)BreakpointMark, \
i18n("Breakpoint")); +        \
iface->setMarkPixmap((MarkInterface::MarkTypes)BreakpointMark, \
*inactiveBreakpointPixmap()); +        \
iface->setMarkPixmap((MarkInterface::MarkTypes)ActiveBreakpointMark, \
*activeBreakpointPixmap()); +        \
iface->setMarkPixmap((MarkInterface::MarkTypes)ReachedBreakpointMark, \
*reachedBreakpointPixmap()); +        \
iface->setMarkPixmap((MarkInterface::MarkTypes)DisabledBreakpointMark, \
*disabledBreakpointPixmap()); +        \
iface->setMarkPixmap((MarkInterface::MarkTypes)ExecutionPointMark, \
*executionPointPixmap()); +        iface->setEditableMarks( BookmarkMark | \
BreakpointMark ); +#if 0
+        connect( doc, 
+                 SIGNAL(markChanged(KTextEditor::Document*, KTextEditor::Mark, \
KTextEditor::MarkInterface::MarkChangeAction)), this, \
SLOT(markChanged(KTextEditor::Document*, KTextEditor::Mark, \
KTextEditor::MarkInterface::MarkChangeAction)) ); +#endif
+    }
+}
+
+QVariant 
+IBreakpointController::headerData(int section, Qt::Orientation orientation,
+                                 int role) const
+{ 
+    if (orientation == Qt::Horizontal && role == Qt::DecorationRole
+        && section == 0)
+        return KIcon("dialog-ok-apply");
+    else if (orientation == Qt::Horizontal && role == Qt::DecorationRole
+             && section == 1)
+        return KIcon("system-switch-user");
+
+    return TreeModel::headerData(section, orientation, role);
+}
+
+Qt::ItemFlags IBreakpointController::flags(const QModelIndex &index) const
+{
+    /* FIXME: all this logic must be in item */
+    if (!index.isValid())
+        return 0;
+
+    if (index.column() == 0)
+        return static_cast<Qt::ItemFlags>(
+            Qt::ItemIsEnabled | Qt::ItemIsSelectable 
+            | Qt::ItemIsEditable | Qt::ItemIsUserCheckable);
+
+    if (index.column() == INewBreakpoint::location_column 
+        || index.column() == INewBreakpoint::condition_column)
+        return static_cast<Qt::ItemFlags>(
+            Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable);
+
+    return static_cast<Qt::ItemFlags>(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
+}
+
+void IBreakpointController::clearExecutionPoint()
+{
+    kDebug(9012) << "clearExecutionPoint";
+    foreach (KDevelop::IDocument* document, \
KDevelop::ICore::self()->documentController()->openDocuments()) +    {
+        MarkInterface *iface = \
dynamic_cast<MarkInterface*>(document->textDocument()); +        if (!iface)
+            continue;
+
+        QHashIterator<int, KTextEditor::Mark*> it = iface->marks();
+        while (it.hasNext())
+        {
+            Mark* mark = it.next().value();
+            if( mark->type & ExecutionPointMark )
+                iface->removeMark( mark->line, ExecutionPointMark );
+        }
+    }
+}
+
+void IBreakpointController::gotoExecutionPoint(const KUrl &url, int lineNum)
+{
+    clearExecutionPoint();
+    kDebug(9012) << "gotoExecutionPoint";
+    KDevelop::IDocument* document = KDevelop::ICore::self()
+        ->documentController()
+        ->openDocument(url, KTextEditor::Cursor(lineNum, 0));
+
+    if( !document )
+        return;
+
+    MarkInterface *iface = dynamic_cast<MarkInterface*>(document->textDocument());
+    if( !iface )
+        return;
+
+    document->textDocument()->blockSignals(true);
+    iface->addMark( lineNum, ExecutionPointMark );
+    document->textDocument()->blockSignals(false);
+}
+
+void IBreakpointController::markChanged(
+    KTextEditor::Document *document, 
+    KTextEditor::Mark mark, 
+    KTextEditor::MarkInterface::MarkChangeAction action)
+{
+#if 0
+    int type = mark.type;
+    /* Is this a breakpoint mark, to begin with? */
+    if (type != (MarkInterface::MarkTypes)BreakpointMark
+        && type != (MarkInterface::MarkTypes)ActiveBreakpointMark
+        && type != (MarkInterface::MarkTypes)ReachedBreakpointMark
+        && type != (MarkInterface::MarkTypes)DisabledBreakpointMark)
+        return;
+
+    switch (action) {
+        case KTextEditor::MarkInterface::MarkAdded: {
+            IFilePosBreakpoint* fileBreakpoint = new IFilePosBreakpoint(this, \
document->url().path(), mark.line); +            addBreakpoint(fileBreakpoint);
+        }
+            break;
+
+        case KTextEditor::MarkInterface::MarkRemoved:
+            // Find this breakpoint and delete it
+            foreach (IBreakpoint* breakpoint, m_breakpoints)
+                if (IFilePosBreakpoint* fileBreakpoint = \
qobject_cast<IFilePosBreakpoint*>(breakpoint)) +                    if (mark.line == \
fileBreakpoint->lineNum()) +                        if (document->url().path() == \
fileBreakpoint->fileName()) { +                            fileBreakpoint->remove();
+                            removeBreakpoint(fileBreakpoint);
+                        }
+            break;
+    }
+
+    if ( KDevelop::ICore::self()->documentController()->activeDocument() && \
KDevelop::ICore::self()->documentController()->activeDocument()->textDocument() == \
document ) +    {
+        //bring focus back to the editor
+        // TODO probably want a different command here
+        KDevelop::ICore::self()->documentController()->activateDocument(KDevelop::ICore::self()->documentController()->activeDocument());
 +    }
+#endif
+}
+
+const QPixmap* IBreakpointController::inactiveBreakpointPixmap()
+{
+  static QPixmap pixmap=KIcon("script-error").pixmap(QSize(22,22), QIcon::Normal, \
QIcon::Off); +  return &pixmap;
+}
+
+const QPixmap* IBreakpointController::activeBreakpointPixmap()
+{
+  static QPixmap pixmap=KIcon("script-error").pixmap(QSize(22,22), QIcon::Active, \
QIcon::Off); +  return &pixmap;
+}
+
+const QPixmap* IBreakpointController::reachedBreakpointPixmap()
+{
+  static QPixmap pixmap=KIcon("script-error").pixmap(QSize(22,22), QIcon::Selected, \
QIcon::Off); +  return &pixmap;
+}
+
+const QPixmap* IBreakpointController::disabledBreakpointPixmap()
+{
+  static QPixmap pixmap=KIcon("script-error").pixmap(QSize(22,22), QIcon::Disabled, \
QIcon::Off); +  return &pixmap;
+}
+
+const QPixmap* IBreakpointController::executionPointPixmap()
+{
+  static QPixmap pixmap=KIcon("go-next").pixmap(QSize(22,22), QIcon::Normal, \
QIcon::Off); +  return &pixmap;
+}
+
+
+//NOTE: Isn't that done by TreeModel? why don't we remove this?
+#if 0
+int IBreakpointController::columnCount(const QModelIndex & parent) const
+{
+    Q_UNUSED(parent);
+    return Last + 1;
+}
+
+QVariant IBreakpointController::data(const QModelIndex & index, int role) const
+{
+    Breakpoint* breakpoint = breakpointForIndex(index);
+    if (!breakpoint)
+        return QVariant();
+
+    switch (index.column()) {
+        case Enable:
+            switch (role) {
+                case Qt::CheckStateRole:
+                case Qt::EditRole:
+                    return breakpoint->isEnabled();
+            }
+            break;
+
+        case Type:
+            switch (role) {
+                case Qt::DisplayRole: {
+                    QString displayType = breakpoint->displayType();
+                    if (breakpoint->isTemporary())
+                        displayType = i18n(" temporary");
+                    if (breakpoint->isHardwareBP())
+                        displayType += i18n(" hw");
+                    return displayType;
+                }
+            }
+            break;
+
+        case Status:
+            switch (role) {
+                case Qt::DisplayRole:
+                    return breakpoint->statusDisplay(m_activeFlag);
+            }
+            break;
+
+        case Location:
+            switch (role) {
+                case Qt::DisplayRole:
+                case Qt::EditRole:
+                    return breakpoint->location();
+            }
+            break;
+
+        case Condition:
+            switch (role) {
+                case Qt::DisplayRole:
+                case Qt::EditRole:
+                    return breakpoint->conditional();
+            }
+            break;
+
+        case IgnoreCount:
+            switch (role) {
+                case Qt::DisplayRole:
+                case Qt::EditRole:
+                    return breakpoint->ignoreCount();
+            }
+            break;
+
+        case Hits:
+            switch (role) {
+                case Qt::DisplayRole:
+                    return breakpoint->hits();
+            }
+            break;
+
+        case Tracing:
+            switch (role) {
+                case Qt::DisplayRole:
+                    return breakpoint->tracingEnabled() ? i18n("Enabled") : \
i18n("Disabled"); +            }
+            break;
+    }
+
+    return QVariant();
+}
+
+Qt::ItemFlags IBreakpointController::flags(const QModelIndex & index) const
+{
+    Qt::ItemFlags flags = Qt::ItemIsSelectable;
+
+    flags |= Qt::ItemIsEnabled;
+
+    if (index.column() == Enable ||
+        index.column() == Location ||
+        index.column() == Condition ||
+        index.column() == IgnoreCount)
+        flags |= Qt::ItemIsEditable;
+
+    return flags;
+}
+
+QVariant IBreakpointController::headerData(int section, Qt::Orientation orientation, \
int role) const +{
+    switch (section) {
+        case Enable:
+            break;//return i18n("Enabled");
+        case Type:
+            return i18n("Type");
+        case Status:
+            return i18n("Status");
+        case Location:
+            return i18n("Location");
+        case Condition:
+            return i18n("Condition");
+        case IgnoreCount:
+            return i18n("Ignore Count");
+        case Hits:
+            return i18n("Hits");
+        case Tracing:
+            return i18n("Tracing");
+    }
+
+    return QVariant();
+}
+
+QModelIndex IBreakpointController::index(int row, int column, const QModelIndex & \
parent) const +{
+    if (row < 0 || column < 0 || column > Last)
+        return QModelIndex();
+
+    if (row >= m_breakpoints.count())
+        return QModelIndex();
+
+    return createIndex(row, column, m_breakpoints.at(row));
+}
+
+QModelIndex IBreakpointController::parent(const QModelIndex & index) const
+{
+    Q_UNUSED(index);
+
+    return QModelIndex();
+}
+
+int IBreakpointController::rowCount(const QModelIndex & parent) const
+{
+    if (!parent.isValid())
+        return m_breakpoints.count();
+
+    return 0;
+}
+
+bool IBreakpointController::setData(const QModelIndex & index, const QVariant & \
value, int role) +{
+    Breakpoint* bp = breakpointForIndex(index);
+    if (!bp)
+        return false;
+
+    bool changed = false;
+
+    switch (role) {
+        case Qt::EditRole:
+            switch (index.column()) {
+                case Location:
+                    if (bp->location() != value.toString())
+                    {
+                        // GDB does not allow to change location of
+                        // an existing breakpoint. So, need to remove old
+                        // breakpoint and add another.
+
+                        // Announce to editor that breakpoit at its
+                        // current location is dying.
+                        bp->setActionDie();
+                        adjustMark(bp, false);
+
+                        // However, we don't want the line in breakpoint
+                        // widget to disappear and appear again.
+
+                        // Emit delete command. This won't resync breakpoint
+                        // table (unlike clearBreakpoint), so we won't have
+                        // nasty effect where line in the table first disappears
+                        // and then appears again, and won't have internal issues
+                        // as well.
+                        if (!controller()->stateIsOn(s_dbgNotStarted))
+                            controller()->addCommand(BreakDelete, \
bp->dbgRemoveCommand().toLatin1()); +
+                        // Now add new breakpoint in gdb. It will correspond to
+                        // the same 'Breakpoint' and 'BreakpointRow' objects in
+                        // KDevelop is the previous, deleted, breakpoint.
+
+                        // Note: clears 'actionDie' implicitly.
+                        bp->setActionAdd(true);
+                        bp->setLocation(value.toString());
+                        adjustMark(bp, true);
+                        changed = true;
+                    }
+                    break;
+
+                case Condition:
+                    bp->setConditional(value.toString());
+                    changed = true;
+                    break;
+
+                case IgnoreCount:
+                    bp->setIgnoreCount(value.toInt());
+                    changed = true;
+                    break;
+
+                case Enable:
+                    bp->setEnabled(value.toBool());
+                    changed = true;
+                    break;
+            }
+            break;
+    }
+
+    if (changed) {
+        bp->setActionModify(true);
+        bp->sendToGdb();
+
+        emit dataChanged(index, index);
+    }
+
+    return changed;
+}
+
+Breakpoint * IBreakpointController::breakpointForIndex(const QModelIndex & index) \
const +{
+    if (!index.isValid())
+        return 0;
+
+    return static_cast<Breakpoint*>(index.internalPointer());
+}
+
+#endif
+
+IBreakpoints* IBreakpointController::breakpointsItem() { return universe_; }
+
+#if 0
+QModelIndex IBreakpointController::indexForBreakpoint(IBreakpoint * breakpoint, int \
column) const +{
+    if (!breakpoint)
+        return QModelIndex();
+
+    int row = m_breakpoints.indexOf(breakpoint);
+    if (row == -1)
+        return QModelIndex();
+
+    return createIndex(row, column, breakpoint);
+}
+#endif
+
+#include "ibreakpointcontroller.moc"
Index: inewbreakpoint.cpp
===================================================================
--- inewbreakpoint.cpp	(revision 0)
+++ inewbreakpoint.cpp	(revision 0)
@@ -0,0 +1,216 @@
+/* This file is part of the KDE project
+   Copyright (C) 2002 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
+   Copyright (C) 2002 John Firebaugh <jfirebaugh@kde.org>
+   Copyright (C) 2006, 2008 Vladimir Prus <ghost@cs.msu.su>
+   Copyright (C) 2007 Hamish Rodda <rodda@kde.org>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+*/
+
+#include "inewbreakpoint.h"
+#include "ibreakpoints.h"
+#include <KLocale>
+#include <KIcon>
+#include <KConfigGroup>
+
+using namespace KDevelop;
+
+INewBreakpoint::INewBreakpoint(TreeModel *model, TreeItem *parent, kind_t kind)
+: TreeItem(model, parent), id_(-1), enabled_(true), 
+  deleted_(false), hitCount_(0), kind_(kind),
+  pending_(false), pleaseEnterLocation_(false)
+{
+    setData(QVector<QString>() << "" << "" << "" << "" << "");
+}
+
+INewBreakpoint::INewBreakpoint(TreeModel *model, TreeItem *parent,
+                             const KConfigGroup& config)
+: TreeItem(model, parent), id_(-1), enabled_(true),
+  deleted_(false), hitCount_(0),
+  pending_(false), pleaseEnterLocation_(false)
+{
+    QString kindString = config.readEntry("kind", "");
+    int i;
+    for (i = 0; i < last_breakpoint_kind; ++i)
+        if (string_kinds[i] == kindString)
+        {
+            kind_ = (kind_t)i;
+            break;
+        }
+    /* FIXME: maybe, should silently ignore this breakpoint.  */
+    Q_ASSERT(i < last_breakpoint_kind);
+    enabled_ = config.readEntry("enabled", false);
+
+    QString location = config.readEntry("location", "");
+    QString condition = config.readEntry("condition", "");
+
+    dirty_.insert(location_column);
+
+    setData(QVector<QString>() << "" << "" << "" << location << condition);
+}
+
+INewBreakpoint::INewBreakpoint(TreeModel *model, TreeItem *parent)
+: TreeItem(model, parent), id_(-1), enabled_(true), 
+  deleted_(false), hitCount_(0), 
+  kind_(code_breakpoint), pending_(false), pleaseEnterLocation_(true)
+{   
+    setData(QVector<QString>() << "" << "" << "" << "" << "");
+}
+
+void INewBreakpoint::setColumn(int index, const QVariant& value)
+{
+    if (index == enable_column)
+    {
+        enabled_ = static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked;
+    }
+
+    /* Helper breakpoint becomes a real breakpoint only if user types
+       some real location.  */
+    if (pleaseEnterLocation_ && value.toString().isEmpty())
+        return;
+
+    if (index == location_column || index == condition_column)
+    {
+        itemData[index] = value;
+        if (pleaseEnterLocation_)
+        {
+            pleaseEnterLocation_ = false;
+            static_cast<IBreakpoints*>(parentItem)->createHelperBreakpoint();
+        }
+    }
+
+    dirty_.insert(index);
+    errors_.remove(index);
+    reportChange();
+    sendMaybe();
+}
+
+void INewBreakpoint::markOut()
+{
+    id_ = -1;
+    dirty_.insert(location_column);
+    dirty_.insert(condition_column);
+}
+
+QVariant INewBreakpoint::data(int column, int role) const
+{
+    if (pleaseEnterLocation_)
+    {
+        if (column != location_column)
+        {
+            if (role == Qt::DisplayRole)
+                return QString();
+            else
+                return QVariant();
+        }
+        
+        if (role == Qt::DisplayRole)
+            return i18n("Double-click to create new code breakpoint");
+        if (role == Qt::ForegroundRole)
+            // FIXME: returning hardcoded gray is bad,
+            // but we don't have access to any widget, or pallette
+            // thereof, at this point.
+            return QColor(128, 128, 128);
+        if (role == Qt::EditRole)
+            return QString();
+    }
+
+    if (column == enable_column)
+    {
+        if (role == Qt::CheckStateRole)
+            return enabled_ ? Qt::Checked : Qt::Unchecked;
+        else if (role == Qt::DisplayRole)
+            return "";
+        else
+            return QVariant();
+    }
+
+    if (column == state_column)
+    {
+        if (role == Qt::DecorationRole)
+        {
+            if (dirty_.empty())
+            {
+                if (pending_)
+                    return KIcon("help-contents");            
+                return KIcon("dialog-apply");
+            }
+            else
+                return KIcon("system-switch-user");
+        }
+        else if (role == Qt::DisplayRole)
+            return "";
+        else
+            return QVariant();
+    }
+
+    if (column == type_column && role == Qt::DisplayRole)
+    {
+        return string_kinds[kind_];
+    }
+
+    if (role == Qt::DecorationRole)
+    {
+        if ((column == location_column && errors_.contains(location_column))
+            || (column == condition_column && errors_.contains(condition_column)))
+        {
+            /* FIXME: does this leak? Is this efficient? */
+            return KIcon("dialog-warning");
+        }
+        return QVariant();
+    }
+
+    if (column == location_column && role == Qt::DisplayRole
+        && !address_.isEmpty())
+        return QString("%1 (%2)").arg(itemData[location_column].toString())
+            .arg(address_);
+
+    return TreeItem::data(column, role);
+}
+
+void INewBreakpoint::setDeleted()
+{
+    deleted_ = true;
+}
+
+void INewBreakpoint::setLocation(const QString& location)
+{
+    itemData[location_column] = location;
+    dirty_.insert(location_column);
+    reportChange();
+    sendMaybe();
+}
+
+void INewBreakpoint::save(KConfigGroup& config)
+{
+    config.writeEntry("kind", string_kinds[kind_]);
+    config.writeEntry("enabled", enabled_);
+    config.writeEntry("location", itemData[location_column]);
+    config.writeEntry("condition", itemData[condition_column]);
+}
+
+const int INewBreakpoint::enable_column;
+const int INewBreakpoint::state_column;
+const int INewBreakpoint::type_column;
+const int INewBreakpoint::location_column;
+const int INewBreakpoint::condition_column;
+
+const char *INewBreakpoint::string_kinds[last_breakpoint_kind] = {
+    "Code",
+    "Write",
+    "Read",
+    "Access"
+};



_______________________________________________
KDevelop-devel mailing list
KDevelop-devel@kdevelop.org
https://barney.cs.uni-potsdam.de/mailman/listinfo/kdevelop-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic