File indexing completed on 2024-04-21 15:03:33

0001 /*
0002     SPDX-FileCopyrightText: 2013 Christoph Cullmann <cullmann@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #ifndef KATE_TEXTHISTORY_H
0008 #define KATE_TEXTHISTORY_H
0009 
0010 #include <vector>
0011 
0012 #include <ktexteditor/movingcursor.h>
0013 #include <ktexteditor/movingrange.h>
0014 #include <ktexteditor/range.h>
0015 
0016 #include <ktexteditor_export.h>
0017 
0018 namespace Kate
0019 {
0020 class TextBuffer;
0021 
0022 /**
0023  * Class representing the editing history of a TextBuffer
0024  */
0025 class KTEXTEDITOR_EXPORT TextHistory
0026 {
0027     friend class TextBuffer;
0028     friend class TextBlock;
0029 
0030 public:
0031     /**
0032      * Current revision, just relay the revision of the buffer
0033      * @return current revision
0034      */
0035     qint64 revision() const;
0036 
0037     /**
0038      * Last revision the buffer got successful saved
0039      * @return last revision buffer got saved, -1 if none
0040      */
0041     qint64 lastSavedRevision() const
0042     {
0043         return m_lastSavedRevision;
0044     }
0045 
0046     /**
0047      * Lock a revision, this will keep it around until released again.
0048      * But all revisions will always be cleared on buffer clear() (and therefor load())
0049      * @param revision revision to lock
0050      */
0051     void lockRevision(qint64 revision);
0052 
0053     /**
0054      * Release a revision.
0055      * @param revision revision to release
0056      */
0057     void unlockRevision(qint64 revision);
0058 
0059     /**
0060      * Transform a cursor from one revision to an other.
0061      * @param line line number of the cursor to transform
0062      * @param column column number of the cursor to transform
0063      * @param insertBehavior behavior of this cursor on insert of text at its position
0064      * @param fromRevision from this revision we want to transform
0065      * @param toRevision to this revision we want to transform, default of -1 is current revision
0066      */
0067     void transformCursor(int &line, int &column, KTextEditor::MovingCursor::InsertBehavior insertBehavior, qint64 fromRevision, qint64 toRevision = -1);
0068 
0069     /**
0070      * Transform a range from one revision to an other.
0071      * @param range range to transform
0072      * @param insertBehaviors behavior of this range on insert of text at its position
0073      * @param emptyBehavior behavior on becoming empty
0074      * @param fromRevision from this revision we want to transform
0075      * @param toRevision to this revision we want to transform, default of -1 is current revision
0076      */
0077     void transformRange(KTextEditor::Range &range,
0078                         KTextEditor::MovingRange::InsertBehaviors insertBehaviors,
0079                         KTextEditor::MovingRange::EmptyBehavior emptyBehavior,
0080                         qint64 fromRevision,
0081                         qint64 toRevision = -1);
0082 
0083 private:
0084     /**
0085      * Class representing one entry in the editing history.
0086      */
0087     class KTEXTEDITOR_NO_EXPORT Entry
0088     {
0089     public:
0090         /**
0091          * transform cursor for this history entry
0092          * @param line line number of the cursor to transform
0093          * @param column column number of the cursor to transform
0094          * @param moveOnInsert behavior of this cursor on insert of text at its position
0095          */
0096         void transformCursor(int &line, int &column, bool moveOnInsert) const;
0097 
0098         /**
0099          * reverse transform cursor for this history entry
0100          * @param line line number of the cursor to transform
0101          * @param column column number of the cursor to transform
0102          * @param moveOnInsert behavior of this cursor on insert of text at its position
0103          */
0104         void reverseTransformCursor(int &line, int &column, bool moveOnInsert) const;
0105 
0106         /**
0107          * Types of entries, matching editing primitives of buffer and placeholder
0108          */
0109         enum Type { NoChange, WrapLine, UnwrapLine, InsertText, RemoveText };
0110 
0111         /**
0112          * Default Constructor, invalidates all fields
0113          */
0114         Entry()
0115         {
0116         }
0117 
0118         /**
0119          * Reference counter, how often ist this entry referenced from the outside?
0120          */
0121         unsigned int referenceCounter = 0;
0122 
0123         /**
0124          * Type of change
0125          */
0126         Type type = NoChange;
0127 
0128         /**
0129          * line the change occurred
0130          */
0131         int line = -1;
0132 
0133         /**
0134          * column the change occurred
0135          */
0136         int column = -1;
0137 
0138         /**
0139          * length of change (length of insert or removed text)
0140          */
0141         int length = -1;
0142 
0143         /**
0144          * old line length (needed for unwrap and insert)
0145          */
0146         int oldLineLength = -1;
0147     };
0148 
0149     /**
0150      * Construct an empty text history.
0151      * @param buffer buffer this text history belongs to
0152      */
0153     KTEXTEDITOR_NO_EXPORT
0154     explicit TextHistory(TextBuffer &buffer);
0155 
0156     /**
0157      * Destruct the text history
0158      */
0159     KTEXTEDITOR_NO_EXPORT
0160     ~TextHistory();
0161 
0162     /**
0163      * Clear the edit history, this is done on clear() in buffer.
0164      */
0165     KTEXTEDITOR_NO_EXPORT
0166     void clear();
0167 
0168     /**
0169      * Set current revision as last saved revision
0170      */
0171     KTEXTEDITOR_NO_EXPORT
0172     void setLastSavedRevision();
0173 
0174     /**
0175      * Notify about wrap line at given cursor position.
0176      * @param position line/column as cursor where to wrap
0177      */
0178     KTEXTEDITOR_NO_EXPORT
0179     void wrapLine(const KTextEditor::Cursor position);
0180 
0181     /**
0182      * Notify about unwrap given line.
0183      * @param line line to unwrap
0184      * @param oldLineLength text length of the line in front of this one before this unwrap
0185      */
0186     KTEXTEDITOR_NO_EXPORT
0187     void unwrapLine(int line, int oldLineLength);
0188 
0189     /**
0190      * Notify about insert text at given cursor position.
0191      * @param position position where to insert text
0192      * @param length text length to be inserted
0193      * @param oldLineLength text length of the line before this insert
0194      */
0195     KTEXTEDITOR_NO_EXPORT
0196     void insertText(const KTextEditor::Cursor position, int length, int oldLineLength);
0197 
0198     /**
0199      * Notify about remove text at given range.
0200      * @param range range of text to remove, must be on one line only.
0201      * @param oldLineLength text length of the line before this remove
0202      */
0203     KTEXTEDITOR_NO_EXPORT
0204     void removeText(KTextEditor::Range range, int oldLineLength);
0205 
0206     /**
0207      * Generic function to add a entry to the history. Is used by the above functions for the different editing primitives.
0208      * @param entry new entry to add
0209      */
0210     KTEXTEDITOR_NO_EXPORT
0211     void addEntry(const Entry &entry);
0212 
0213 private:
0214     /**
0215      * TextBuffer this history belongs to
0216      */
0217     TextBuffer &m_buffer;
0218 
0219     /**
0220      * Last revision the buffer got saved
0221      */
0222     qint64 m_lastSavedRevision;
0223 
0224     /**
0225      * history of edits
0226      * needs no sharing, small entries
0227      */
0228     std::vector<Entry> m_historyEntries;
0229 
0230     /**
0231      * offset for the first entry in m_history, to which revision it really belongs?
0232      */
0233     qint64 m_firstHistoryEntryRevision;
0234 };
0235 
0236 }
0237 
0238 #endif