File indexing completed on 2024-05-12 04:37:35

0001 /*
0002     SPDX-FileCopyrightText: 2002 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
0003     SPDX-FileCopyrightText: 2002 John Firebaugh <jfirebaugh@kde.org>
0004     SPDX-FileCopyrightText: 2007 Hamish Rodda <rodda@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 
0010 #ifndef KDEVPLATFORM_BREAKPOINTMODEL_H
0011 #define KDEVPLATFORM_BREAKPOINTMODEL_H
0012 
0013 #include <QAbstractTableModel>
0014 
0015 #include <KTextEditor/MarkInterface>
0016 #include "breakpoint.h"
0017 
0018 class QUrl;
0019 class TestBreakpointModel;
0020 
0021 namespace KParts { class Part; }
0022 namespace KTextEditor {
0023 class Cursor;
0024 }
0025 
0026 namespace KDevelop
0027 {
0028 class IDocument;
0029 class Breakpoint;
0030 class BreakpointModelPrivate;
0031 
0032 class KDEVPLATFORMDEBUGGER_EXPORT BreakpointModel : public QAbstractTableModel
0033 {
0034     Q_OBJECT
0035 
0036 public:
0037     enum Column {
0038         /**
0039          * Whether the breakpoint is active or not (settable by user): value is Qt::Checked
0040          * or Qt::Unchecked.
0041          */
0042         EnableColumn,
0043 
0044         /**
0045          * Synchronization state of the breakpoint (not settable by user): value is one of the
0046          * BreakpointState enum values.
0047          */
0048         StateColumn,
0049 
0050         /**
0051          * Kind/type of breakpoint (never changes): value is one of the BreakpointKind
0052          * enum values.
0053          */
0054         KindColumn,
0055 
0056         /**
0057          * Location of the breakpoint (modifiable by user); value is a string describing the
0058          * location; note that the formatting of retrieved data can be affected by a custom
0059          * BreakpointRole.
0060          */
0061         LocationColumn,
0062 
0063         /**
0064          * Condition for conditional breakpoints (modifiable by user).
0065          */
0066         ConditionColumn,
0067 
0068         /**
0069          * The number of times this breakpoint has been hit (cannot be modified by the user).
0070          */
0071         HitCountColumn,
0072 
0073         /**
0074          * How many hits of the breakpoint will be ignored before the breakpoint actually stops
0075          * the program (can be modified by the user and is updated by the debugger backend).
0076          */
0077         IgnoreHitsColumn,
0078 
0079         NumColumns
0080     };
0081 
0082     enum ColumnFlag {
0083         EnableColumnFlag = 1 << EnableColumn,
0084         StateColumnFlag = 1 << StateColumn,
0085         KindColumnFlag = 1 << KindColumn,
0086         LocationColumnFlag = 1 << LocationColumn,
0087         ConditionColumnFlag = 1 << ConditionColumn,
0088         HitCountColumnFlag = 1 << HitCountColumn,
0089         IgnoreHitsColumnFlag = 1 << IgnoreHitsColumn
0090     };
0091     Q_DECLARE_FLAGS(ColumnFlags, ColumnFlag)
0092 
0093     explicit BreakpointModel(QObject* parent);
0094     ~BreakpointModel() override;
0095 
0096     QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
0097     Qt::ItemFlags flags(const QModelIndex &index) const override;
0098     QModelIndex breakpointIndex(Breakpoint *b, int column);
0099     bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex()) override;
0100     int rowCount(const QModelIndex& parent = QModelIndex()) const override;
0101     int columnCount(const QModelIndex& parent = QModelIndex()) const override;
0102 
0103      ///Note: to retrieve the full path use Breakpoint::LocationRole, Qt::DisplayRole returns only a file's name
0104     QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
0105     bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
0106 
0107     /**
0108      * Delete a given registered breakpoint.
0109      * @param breakpoint a non-null pointer
0110      */
0111     void removeBreakpoint(Breakpoint* breakpoint);
0112 
0113     void toggleBreakpoint(const QUrl &url, const KTextEditor::Cursor& cursor);
0114 
0115 
0116     KDevelop::Breakpoint* addCodeBreakpoint();
0117     KDevelop::Breakpoint* addCodeBreakpoint(const QUrl& location, int line);
0118     KDevelop::Breakpoint* addCodeBreakpoint(const QString& expression);
0119     KDevelop::Breakpoint* addWatchpoint();
0120     KDevelop::Breakpoint* addWatchpoint(const QString& expression);
0121     KDevelop::Breakpoint* addReadWatchpoint();
0122     KDevelop::Breakpoint* addReadWatchpoint(const QString& expression);
0123     KDevelop::Breakpoint* addAccessWatchpoint();
0124     KDevelop::Breakpoint* addAccessWatchpoint(const QString& expression);
0125 
0126     Breakpoint* breakpoint(int row) const;
0127     QList<Breakpoint*> breakpoints() const;
0128 
0129 Q_SIGNALS:
0130     void error(int row, const QString& errorText);
0131     void hit(int row);
0132 
0133 public Q_SLOTS:
0134     void save();
0135     void load();
0136 
0137 private:
0138     enum MarkType {
0139         BreakpointMark = KTextEditor::MarkInterface::BreakpointActive,
0140         ReachedBreakpointMark  = KTextEditor::MarkInterface::BreakpointReached,
0141         DisabledBreakpointMark = KTextEditor::MarkInterface::BreakpointDisabled,
0142         PendingBreakpointMark   = KTextEditor::MarkInterface::markType08,
0143 
0144         AllBreakpointMarks = BreakpointMark | ReachedBreakpointMark | DisabledBreakpointMark | PendingBreakpointMark
0145     };
0146 
0147 private Q_SLOTS:
0148 
0149     void updateMarks();
0150 
0151     void slotPartAdded(KParts::Part* part);
0152 
0153     /**
0154     * Called by the TextEditor interface when the marks have changed position
0155     * because the user has added or removed source.
0156     * In here we figure out if we need to reset the breakpoints due to
0157     * these source changes.
0158     */
0159     void markChanged(KTextEditor::Document *document, KTextEditor::Mark mark, KTextEditor::MarkInterface::MarkChangeAction action);
0160     void textDocumentCreated(KDevelop::IDocument*);
0161     void documentSaved(KDevelop::IDocument*);
0162     void aboutToDeleteMovingInterfaceContent(KTextEditor::Document *document);
0163 
0164     void markContextMenuRequested( KTextEditor::Document* document, KTextEditor::Mark mark,
0165                                const QPoint &pos, bool& handled );
0166 
0167 private:
0168     static const QPixmap* breakpointPixmap();
0169     static const QPixmap* pendingBreakpointPixmap();
0170     static const QPixmap* reachedBreakpointPixmap();
0171     static const QPixmap* disabledBreakpointPixmap();
0172 
0173 private:
0174     friend class Breakpoint;
0175     friend class IBreakpointController;
0176     friend class ::TestBreakpointModel;
0177 
0178     void updateState(int row, Breakpoint::BreakpointState state);
0179     void updateHitCount(int row, int hitCount);
0180     void updateErrorText(int row, const QString& errorText);
0181     void notifyHit(int row);
0182 
0183     void registerBreakpoint(Breakpoint* breakpoint);
0184     void scheduleSave();
0185 
0186     void reportChange(Breakpoint *breakpoint, Breakpoint::Column column);
0187     uint breakpointType(Breakpoint *breakpoint) const;
0188     Breakpoint *breakpoint(const QUrl& url, int line) const;
0189 
0190     void setupMovingCursor(KTextEditor::Document* document, Breakpoint* breakpoint) const;
0191 
0192 private:
0193     const QScopedPointer<class BreakpointModelPrivate> d_ptr;
0194     Q_DECLARE_PRIVATE(BreakpointModel)
0195 };
0196 
0197 Q_DECLARE_OPERATORS_FOR_FLAGS(BreakpointModel::ColumnFlags)
0198 }
0199 
0200 #endif