File indexing completed on 2024-10-13 06:37:59

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