File indexing completed on 2024-04-14 03:55:09

0001 /*
0002     SPDX-FileCopyrightText: 2013 Christoph Cullmann <cullmann@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #ifndef KTEXTEDITOR_FOLDINGINTERFACE_H
0008 #define KTEXTEDITOR_FOLDINGINTERFACE_H
0009 
0010 // #include <ktexteditor_export.h>
0011 
0012 #include <QFlags>
0013 
0014 namespace KTextEditor
0015 {
0016 class Range;
0017 
0018 /**
0019  * KTextEditor interface for code folding of a KTextEditor::View.
0020  * The interface allows to arbitrary fold given regions of a buffer as long
0021  * as they are well nested.
0022  * Multiple instances of this class can exist for the same buffer.
0023  */
0024 class KTEXTEDITOR_EXPORT FoldingInterface
0025 {
0026 public:
0027     /**
0028      * Create folding object for given buffer.
0029      * @param buffer text buffer we want to provide folding info for
0030      */
0031     FoldingInterface();
0032 
0033     /**
0034      * Cleanup
0035      */
0036     virtual ~FoldingInterface();
0037 
0038     /**
0039      * Folding state of a range
0040      */
0041     enum FoldingRangeFlag {
0042         /**
0043          * Range is persistent, e.g. it should not auto-delete after unfolding!
0044          */
0045         Persistent = 0x1,
0046 
0047         /**
0048          * Range is folded away
0049          */
0050         Folded = 0x2
0051     };
0052     Q_DECLARE_FLAGS(FoldingRangeFlags, FoldingRangeFlag)
0053 
0054     /**
0055      * \name Creation, Folding and Unfolding
0056      *
0057      * The following functions provide access and manipulation of the range's position.
0058      * \{
0059      */
0060 
0061     /**
0062      * Create a new folding range.
0063      * @param range folding range
0064      * @param flags initial flags for the new folding range
0065      * @return on success, id of new range >= 0, else -1, we return no pointer as folding ranges might be auto-deleted internally!
0066      *         the ids are stable for one KTextEditor::FoldingInterface, e.g. you can rely in unit tests that you get 0,1,.... for successfully created ranges!
0067      */
0068     qint64 newFoldingRange(KTextEditor::Range range, FoldingRangeFlags flags = FoldingRangeFlags());
0069 
0070     /**
0071      * Fold the given range.
0072      * @param id id of the range to fold
0073      * @return success
0074      */
0075     virtual bool foldRange(qint64 id) = 0;
0076 
0077     /**
0078      * Unfold the given range.
0079      * In addition it can be forced to remove the region, even if it is persistent.
0080      * @param id id of the range to unfold
0081      * @param remove should the range be removed from the folding after unfolding? ranges that are not persistent auto-remove themself on unfolding
0082      * @return success
0083      */
0084     virtual bool unfoldRange(qint64 id, bool remove = false) = 0;
0085 
0086     /**
0087      * Queries which folding ranges start at the given line and returns the id + flags for all
0088      * of them. Very fast if nothing is folded, else binary search.
0089      * @param line line to query starting folding ranges
0090      * @return vector of id's + flags
0091      */
0092     virtual QList<QPair<qint64, FoldingRangeFlags>> foldingRangesStartingOnLine(int line) const = 0;
0093 
0094     /**
0095      * Check whether on this line starts a folding range
0096      * @param line line to query starting folding ranges
0097      * @return true, if a folding range starts, otherwise false
0098      */
0099     virtual bool lineContainsStartFoldingRanges(int line) const = 0;
0100 
0101     /**
0102      * Fold the first folding range starting on this line, if applicable.
0103      * @param line line to fold
0104      * @return id of folded range (>= 0) or -1, if no folding range starts at line
0105      */
0106     virtual qint64 foldLine(int line) const = 0;
0107 
0108     /**
0109      * Unfolds all folding range starting on this line, if applicable.
0110      * @param line line to unfold
0111      * @return id of folded range (>= 0) or -1, if no folding range starts at line
0112      */
0113     virtual bool unfoldLine(int line) const = 0;
0114 
0115     /**
0116      * \}
0117      *
0118      * \name Line Visibility
0119      *
0120      * The following functions provide access and manipulation of the range's position.
0121      * \{
0122      */
0123 
0124     /**
0125      * Query if a given line is visible.
0126      * Very fast, if nothing is folded, else does binary search
0127      * log(n) for n == number of folded ranges
0128      * @param line line to query
0129      * @param foldedRangeId if the line is not visible and that pointer is not 0, will be filled with id of range hiding the line or -1
0130      * @return is that line visible?
0131      */
0132     virtual bool isLineVisible(int line, qint64 *foldedRangeId = 0) const = 0;
0133 
0134     /**
0135      * Ensure that a given line will be visible.
0136      * Potentially unfold recursively all folds hiding this line, else just returns.
0137      * @param line line to make visible
0138      */
0139     virtual void ensureLineIsVisible(int line) = 0;
0140 
0141     /**
0142      * Query number of visible lines.
0143      * Very fast, if nothing is folded, else walks over all folded regions
0144      * O(n) for n == number of folded ranges
0145      */
0146     virtual int visibleLines() const = 0;
0147 
0148     /**
0149      * Convert a text buffer line to a visible line number.
0150      * Very fast, if nothing is folded, else walks over all folded regions
0151      * O(n) for n == number of folded ranges
0152      * @param line line index in the text buffer
0153      * @return index in visible lines
0154      */
0155     virtual int lineToVisibleLine(int line) const = 0;
0156 
0157     /**
0158      * Convert a visible line number to a line number in the text buffer.
0159      * Very fast, if nothing is folded, else walks over all folded regions
0160      * O(n) for n == number of folded ranges
0161      * @param visibleLine visible line index
0162      * @return index in text buffer lines
0163      */
0164     virtual int visibleLineToLine(int visibleLine) const = 0;
0165 
0166     /**
0167      * \}
0168      */
0169 
0170 public Q_SLOTS:
0171     /**
0172      * Clear the complete folding.
0173      * This is automatically triggered if the buffer is cleared.
0174      */
0175     void clear();
0176 
0177 Q_SIGNALS:
0178     /**
0179      * If the folding state of existing ranges changes or
0180      * ranges are added/removed, this signal is emitted.
0181      */
0182     void foldingRangesChanged();
0183 };
0184 
0185 Q_DECLARE_OPERATORS_FOR_FLAGS(FoldingInterface::FoldingRangeFlags)
0186 
0187 }
0188 
0189 #endif