File indexing completed on 2024-05-12 15:45:40

0001 /*
0002     SPDX-FileCopyrightText: 2001 Christoph Cullmann <cullmann@kde.org>
0003 
0004     Documentation:
0005     SPDX-FileCopyrightText: 2005 Dominik Haumann <dhdev@gmx.de>
0006 
0007     SPDX-License-Identifier: LGPL-2.0-or-later
0008 */
0009 
0010 #ifndef KTEXTEDITOR_MARKINTERFACE_H
0011 #define KTEXTEDITOR_MARKINTERFACE_H
0012 
0013 #include <ktexteditor_export.h>
0014 
0015 #include <QHash>
0016 #include <QObject>
0017 
0018 class QIcon;
0019 class QPixmap;
0020 class QPoint;
0021 class QMenu;
0022 
0023 namespace KTextEditor
0024 {
0025 class Document;
0026 
0027 /**
0028  * \class Mark markinterface.h <KTextEditor/MarkInterface>
0029  *
0030  * \brief Mark class containing line and mark types.
0031  *
0032  * \section mark_intro Introduction
0033  *
0034  * The class Mark represents a mark in a Document. It contains the \e line
0035  * and \e type. A line can have multiple marks, like a \e bookmark and a
0036  * \e breakpoint, i.e. the \e type contains all marks combined with a logical
0037  * \e OR (<tt>|</tt>). There are several predefined mark types, look into the
0038  * MarkInterface for further details.
0039  *
0040  * \see KTextEditor::MarkInterface, KTextEditor::Document
0041  */
0042 class Mark
0043 {
0044 public:
0045     /** The line that contains the mark. */
0046     int line;
0047 
0048     /** The mark types in the line, combined with logical OR. */
0049     uint type;
0050 };
0051 
0052 /**
0053  * \class MarkInterface markinterface.h <KTextEditor/MarkInterface>
0054  *
0055  * \brief Mark extension interface for the Document.
0056  *
0057  * \ingroup kte_group_doc_extensions
0058  *
0059  * \section markext_intro Introduction
0060  *
0061  * The MarkInterface provides methods to enable and disable marks in a
0062  * Document, a marked line can be visualized for example with a shaded
0063  * background color and/or a pixmap in the iconborder of the Document's View.
0064  * There are a number of predefined mark types, specified in
0065  * reservedMarkersCount(). Additionally it is possible to add custom marks
0066  * and set custom pixmaps.
0067  *
0068  * \section markext_access Accessing the Interface
0069  *
0070  * The MarkInterface is supposed to be an extension interface for a Document,
0071  * i.e. the Document inherits the interface \e provided that the
0072  * KTextEditor library in use implements the interface. Use qobject_cast to access
0073  * the interface:
0074  * \code
0075  * // doc is of type KTextEditor::Document*
0076  * auto iface = qobject_cast<KTextEditor::MarkInterface*>(doc);
0077  *
0078  * if (iface) {
0079  *     // the implementation supports the interface
0080  *     // do stuff
0081  * } else {
0082  *     // the implementation does not support the interface
0083  * }
0084  * \endcode
0085  *
0086  * \section markext_handling Handling Marks
0087  *
0088  * Get all marks in the document by calling marks(). Use clearMarks() to
0089  * remove all marks in the entire document. A single mark can be retrieved
0090  * with mark(). To remove all marks from a line call clearMark(). To add
0091  * and remove marks from a given line use addMark() and removeMark(). It is
0092  * also possible to replace all marks with setMark(), i.e. setMark() is the
0093  * same as a call of clearMark() followed by addMark(). The signals
0094  * marksChanged() and markChanged() are emitted whenever a line's marks
0095  * changed.
0096  *
0097  * \attention A mark type is represented as an \e uint. An \e uint can have
0098  *     several mark types combined (see above: logical OR). That means for
0099  *     all functions/signals with an \e uint parameter, e.g. setMark(),
0100  *     removeMark(), etc, the \e uint may contain \e multiple marks, i.e.
0101  *     you can add and remove multiple marks \e simultaneously.
0102  *
0103  * \section markext_userdefined User Defined Marks
0104  *
0105  * All marks that should be editable by the user can be specified with a mark
0106  * mask via setEditableMarks(). To set a description and pixmap of a mark type
0107  * call setMarkDescription() and setMarkPixmap().
0108  *
0109  * \see KTextEditor::Document, KTextEditor::Mark
0110  * \author Christoph Cullmann \<cullmann@kde.org\>
0111  */
0112 class KTEXTEDITOR_EXPORT MarkInterface
0113 {
0114 public:
0115     MarkInterface();
0116 
0117     /**
0118      * Virtual destructor.
0119      */
0120     virtual ~MarkInterface();
0121 
0122     //
0123     // slots !!!
0124     //
0125 public:
0126     /**
0127      * Get all marks set on the \p line.
0128      * \param line requested line
0129      * \return a \e uint representing of the marks set in \p line concatenated
0130      *         by logical OR
0131      * \see addMark(), removeMark()
0132      */
0133     virtual uint mark(int line) = 0;
0134 
0135     /**
0136      * Set the \p line's mark types to \p markType.
0137      * If \p line already contains a mark of the given type it has no effect.
0138      * All other marks are deleted before the mark is set. You can achieve
0139      * the same by calling
0140      * \code
0141      * clearMark(line);
0142      * addMark(line, markType);
0143      * \endcode
0144      * \param line line to set the mark
0145      * \param markType mark type
0146      * \see clearMark(), addMark(), mark()
0147      */
0148     virtual void setMark(int line, uint markType) = 0;
0149 
0150     /**
0151      * Clear all marks set in the \p line.
0152      * \param line line to clear marks
0153      * \see clearMarks(), removeMark(), addMark()
0154      */
0155     virtual void clearMark(int line) = 0;
0156 
0157     /**
0158      * Add marks of type \p markType to \p line. Existing marks on this line
0159      * are preserved. If the mark \p markType already is set, nothing
0160      * happens.
0161      * \param line line to set the mark
0162      * \param markType mark type
0163      * \see removeMark(), setMark()
0164      */
0165     virtual void addMark(int line, uint markType) = 0;
0166 
0167     /**
0168      * Remove the mark mask of type \p markType from \p line.
0169      * \param line line to remove the mark
0170      * \param markType mark type to be removed
0171      * \see clearMark()
0172      */
0173     virtual void removeMark(int line, uint markType) = 0;
0174 
0175     /**
0176      * Get a hash holding all marks in the document.
0177      * The hash key for a mark is its line.
0178      * \return a hash holding all marks in the document
0179      *
0180      * KF6 TODO: Change Mark* to Mark. No need for pointer here.
0181      */
0182     virtual const QHash<int, KTextEditor::Mark *> &marks() = 0;
0183 
0184     /**
0185      * Clear all marks in the entire document.
0186      * \see clearMark(), removeMark()
0187      */
0188     /// TODO: dominik: add argument unit mask = 0
0189     virtual void clearMarks() = 0;
0190 
0191     /**
0192      * Get the number of predefined mark types we have so far.
0193      * \note FIXME: If you change this you have to make sure katepart
0194      *              supports the new size!
0195      * \return number of reserved marker types
0196      */
0197     static int reservedMarkersCount()
0198     {
0199         return 7;
0200     }
0201 
0202     /**
0203      * Predefined mark types.
0204      *
0205      * To add a new standard mark type, edit this interface and document
0206      * the type.
0207      */
0208     enum MarkTypes {
0209         /** Bookmark */
0210         markType01 = 0x1,
0211         /** Breakpoint active */
0212         markType02 = 0x2,
0213         /** Breakpoint reached */
0214         markType03 = 0x4,
0215         /** Breakpoint disabled */
0216         markType04 = 0x8,
0217         /** Execution mark */
0218         markType05 = 0x10,
0219         /** Warning */
0220         markType06 = 0x20,
0221         /** Error */
0222         markType07 = 0x40,
0223 
0224         markType08 = 0x80,
0225         markType09 = 0x100,
0226         markType10 = 0x200,
0227         markType11 = 0x400,
0228         markType12 = 0x800,
0229         markType13 = 0x1000,
0230         markType14 = 0x2000,
0231         markType15 = 0x4000,
0232         markType16 = 0x8000,
0233         markType17 = 0x10000,
0234         markType18 = 0x20000,
0235         markType19 = 0x40000,
0236         markType20 = 0x80000,
0237         markType21 = 0x100000,
0238         markType22 = 0x200000,
0239         markType23 = 0x400000,
0240         markType24 = 0x800000,
0241         markType25 = 0x1000000,
0242         markType26 = 0x2000000,
0243         markType27 = 0x4000000,
0244         markType28 = 0x8000000,
0245         markType29 = 0x10000000,
0246         markType30 = 0x20000000,
0247         markType31 = 0x40000000,
0248         markType32 = 0x80000000,
0249         /* reserved marks */
0250         Bookmark = markType01,
0251         BreakpointActive = markType02,
0252         BreakpointReached = markType03,
0253         BreakpointDisabled = markType04,
0254         Execution = markType05,
0255         Warning = markType06,
0256         Error = markType07,
0257         SearchMatch = markType32,
0258     };
0259 
0260     //
0261     // signals !!!
0262     //
0263 public:
0264     /**
0265      * The \p document emits this signal whenever a mark mask changed.
0266      * \param document document which emitted this signal
0267      * \see markChanged()
0268      */
0269     virtual void marksChanged(KTextEditor::Document *document) = 0;
0270 
0271     /*
0272      * Methods to modify mark properties.
0273      */
0274 public:
0275     /**
0276      * Set the \p mark's pixmap to \p pixmap.
0277      * \param mark mark to which the pixmap will be attached
0278      * \param pixmap new pixmap
0279      * \see setMarkDescription()
0280      */
0281     virtual void setMarkPixmap(MarkTypes mark, const QPixmap &pixmap) = 0;
0282 
0283     /**
0284      * Get the \p mark's pixmap.
0285      * \param mark mark type. If the pixmap does not exist the resulting is null
0286      *        (check with QPixmap::isNull()).
0287      * \see setMarkDescription()
0288      */
0289     virtual QPixmap markPixmap(MarkTypes mark) const = 0;
0290 
0291     /**
0292      * Set the \p mark's description to \p text.
0293      * \param mark mark to set the description
0294      * \param text new descriptive text
0295      * \see markDescription(), setMarkPixmap()
0296      */
0297     virtual void setMarkDescription(MarkTypes mark, const QString &text) = 0;
0298 
0299     /**
0300      * Get the \p mark's description to text.
0301      * \param mark mark to set the description
0302      * \return text of the given \p mark or QString(), if the entry does not
0303      *         exist
0304      * \see setMarkDescription(), setMarkPixmap()
0305      */
0306     virtual QString markDescription(MarkTypes mark) const = 0;
0307 
0308     /**
0309      * Set the mark mask the user is allowed to toggle to \p markMask.
0310      * I.e. concatenate all editable marks with a logical OR. If the user should
0311      * be able to add a bookmark and set a breakpoint with the context menu in
0312      * the icon pane, you have to call
0313      * \code
0314      * // iface is of Type KTextEditor::MarkInterface*
0315      * // only make bookmark and breakpoint editable
0316      * iface->setEditableMarks( MarkInterface::Bookmark |
0317      *                          MarkInterface::BreakpointActive );
0318      *
0319      * // or preserve last settings, and add bookmark and breakpoint
0320      * iface->setEditableMarks( iface->editableMarks() |
0321      *                          MarkInterface::Bookmark |
0322      *                          MarkInterface::BreakpointActive );
0323      * \endcode
0324      * \param markMask bitmap pattern
0325      * \see editableMarks(), setMarkPixmap(), setMarkDescription()
0326      */
0327     virtual void setEditableMarks(uint markMask) = 0;
0328 
0329     /**
0330      * Get, which marks can be toggled by the user.
0331      * The returned value is a mark mask containing all editable marks combined
0332      * with a logical OR.
0333      * \return mark mask containing all editable marks
0334      * \see setEditableMarks()
0335      */
0336     virtual uint editableMarks() const = 0;
0337 
0338     /**
0339      * Possible actions on a mark.
0340      * \see markChanged()
0341      */
0342     enum MarkChangeAction {
0343         MarkAdded = 0, /**< action: a mark was added.  */
0344         MarkRemoved = 1 /**< action: a mark was removed. */
0345     };
0346 
0347     //
0348     // signals !!!
0349     //
0350 public:
0351     /**
0352      * The \p document emits this signal whenever the \p mark changes.
0353      * \param document the document which emitted the signal
0354      * \param mark changed mark
0355      * \param action action, either removed or added
0356      * \see marksChanged()
0357      */
0358     virtual void markChanged(KTextEditor::Document *document, KTextEditor::Mark mark, KTextEditor::MarkInterface::MarkChangeAction action) = 0;
0359 
0360 Q_SIGNALS:
0361 
0362     /**
0363      * The \p document emits this signal whenever the \p mark is hovered using the mouse,
0364      * and the receiver may show a tooltip.
0365      * \param document the document which emitted the signal
0366      * \param mark mark that was hovered
0367      * \param position mouse position during the hovering
0368      * \param handled set this to 'true' if this event was handled externally
0369      */
0370     void markToolTipRequested(KTextEditor::Document *document, KTextEditor::Mark mark, QPoint position, bool &handled);
0371 
0372     /**
0373      * The \p document emits this signal whenever the \p mark is right-clicked to show a context menu.
0374      * The receiver may show an own context menu instead of the kate internal one.
0375      * \param document the document which emitted the signal
0376      * \param mark mark that was right-clicked
0377      * \param pos position where the menu should be started
0378      * \param handled set this to 'true' if this event was handled externally, and kate should not create an own context menu.
0379      */
0380     void markContextMenuRequested(KTextEditor::Document *document, KTextEditor::Mark mark, QPoint pos, bool &handled);
0381 
0382     /**
0383      * The \p document emits this signal whenever the \p mark is left-clicked.
0384      * \param document the document which emitted the signal
0385      * \param mark mark that was right-clicked
0386      * \param handled set this to 'true' if this event was handled externally, and kate should not do own handling of the left click.
0387      */
0388     void markClicked(KTextEditor::Document *document, KTextEditor::Mark mark, bool &handled);
0389 
0390 private:
0391     class MarkInterfacePrivate *const d = nullptr;
0392 };
0393 
0394 /**
0395  * \brief Mark extension interface for the Document, version 2
0396  *
0397  * \ingroup kte_group_doc_extensions
0398  *
0399  * \section markextv2_intro Introduction
0400  *
0401  * The MarkInterfaceV2 allows to do the same as MarkInterface
0402  * and additionally
0403  * - (1) set an icon for a mark type instead of just a pixmap
0404  *
0405  * \section markextv2_access Accessing the Interface
0406  *
0407  * The MarkInterfaceV2 is supposed to be an extension interface for a Document,
0408  * i.e. the Document inherits the interface \e provided that the
0409  * KTextEditor library in use implements the interface. Use qobject_cast to access
0410  * the interface:
0411  * \code
0412  * // doc is of type KTextEditor::Document*
0413  * auto iface = qobject_cast<KTextEditor::MarkInterfaceV2*>(doc);
0414  *
0415  * if (iface) {
0416  *     // the implementation supports the interface
0417  *     // do stuff
0418  * } else {
0419  *     // the implementation does not support the interface
0420  * }
0421  * \endcode
0422  *
0423  * \since 5.69
0424  */
0425 class KTEXTEDITOR_EXPORT MarkInterfaceV2 : public MarkInterface
0426 {
0427     // KF6: Merge KTextEditor::MarkInterfaceV2 into KTextEditor::MarkInterface, drop QPixmap API (kossebau)
0428 public:
0429     ~MarkInterfaceV2() override
0430     {
0431     }
0432 
0433     /**
0434      * Set the \p mark's icon to \p icon.
0435      * \param markType mark type to which the icon will be attached
0436      * \param icon new icon
0437      * \see setMarkDescription()
0438      */
0439     virtual void setMarkIcon(MarkTypes markType, const QIcon &icon) = 0;
0440 
0441     /**
0442      * Get the \p mark's icon.
0443      * \param markType mark type. If the icon does not exist the resulting is null
0444      *        (check with QIcon::isNull()).
0445      * \see setMarkDescription()
0446      */
0447     virtual QIcon markIcon(MarkTypes markType) const = 0;
0448 };
0449 
0450 }
0451 
0452 Q_DECLARE_INTERFACE(KTextEditor::MarkInterface, "org.kde.KTextEditor.MarkInterface")
0453 Q_DECLARE_INTERFACE(KTextEditor::MarkInterfaceV2, "org.kde.KTextEditor.MarkInterfaceV2")
0454 
0455 #endif