Warning, file /frameworks/ktexteditor/src/undo/kateundo.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002     SPDX-FileCopyrightText: 2011 Dominik Haumann <dhaumann@kde.org>
0003     SPDX-FileCopyrightText: 2009-2010 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
0004     SPDX-FileCopyrightText: 2002 John Firebaugh <jfirebaugh@kde.org>
0005     SPDX-FileCopyrightText: 2001 Christoph Cullmann <cullmann@kde.org>
0006     SPDX-FileCopyrightText: 2001 Joseph Wenninger <jowenn@kde.org>
0007 
0008     SPDX-License-Identifier: LGPL-2.0-or-later
0009 */
0010 
0011 #ifndef kate_undo_h
0012 #define kate_undo_h
0013 
0014 #include <QList>
0015 
0016 #include <QBitArray>
0017 #include <kateview.h>
0018 #include <ktexteditor/range.h>
0019 
0020 class KateUndoManager;
0021 namespace KTextEditor
0022 {
0023 class DocumentPrivate;
0024 }
0025 
0026 /**
0027  * Base class for Kate undo commands.
0028  */
0029 class KateUndo
0030 {
0031 public:
0032     /**
0033      * Constructor
0034      * @param document the document the undo item belongs to
0035      */
0036     explicit KateUndo(KTextEditor::DocumentPrivate *document);
0037 
0038     /**
0039      * Destructor
0040      */
0041     virtual ~KateUndo() = default;
0042 
0043 public:
0044     /**
0045      * Types for undo items
0046      */
0047     enum UndoType { editInsertText, editRemoveText, editWrapLine, editUnWrapLine, editInsertLine, editRemoveLine, editMarkLineAutoWrapped, editInvalid };
0048 
0049 public:
0050     /**
0051      * Check whether the item is empty.
0052      *
0053      * @return whether the item is empty
0054      */
0055     virtual bool isEmpty() const;
0056 
0057     /**
0058      * merge an undo item
0059      * Saves a bit of memory and potentially many calls when undo/redoing.
0060      * Only called for equal types of this object and the passed one.
0061      * @param undo undo item to merge
0062      * @return success
0063      */
0064     virtual bool mergeWith(const KateUndo *undo);
0065 
0066     /**
0067      * undo this item
0068      */
0069     virtual void undo() = 0;
0070 
0071     /**
0072      * redo this item
0073      */
0074     virtual void redo() = 0;
0075 
0076     /**
0077      * type of item
0078      * @return type
0079      */
0080     virtual KateUndo::UndoType type() const = 0;
0081 
0082 protected:
0083     /**
0084      * Return the document the undo item belongs to.
0085      * @return the document the undo item belongs to
0086      */
0087     inline KTextEditor::DocumentPrivate *document()
0088     {
0089         return m_document;
0090     }
0091 
0092 private:
0093     /**
0094      * the document the undo item belongs to
0095      */
0096     KTextEditor::DocumentPrivate *m_document;
0097 
0098     //
0099     // Line modification system
0100     //
0101 public:
0102     enum ModificationFlag {
0103         UndoLine1Modified = 1,
0104         UndoLine2Modified = 2,
0105         UndoLine1Saved = 4,
0106         UndoLine2Saved = 8,
0107         RedoLine1Modified = 16,
0108         RedoLine2Modified = 32,
0109         RedoLine1Saved = 64,
0110         RedoLine2Saved = 128
0111     };
0112 
0113     inline void setFlag(ModificationFlag flag)
0114     {
0115         m_lineModFlags |= flag;
0116     }
0117 
0118     inline void unsetFlag(ModificationFlag flag)
0119     {
0120         m_lineModFlags &= (~flag);
0121     }
0122 
0123     inline bool isFlagSet(ModificationFlag flag) const
0124     {
0125         return m_lineModFlags & flag;
0126     }
0127 
0128     virtual void updateUndoSavedOnDiskFlag(QBitArray &lines)
0129     {
0130         Q_UNUSED(lines)
0131     }
0132     virtual void updateRedoSavedOnDiskFlag(QBitArray &lines)
0133     {
0134         Q_UNUSED(lines)
0135     }
0136 
0137 private:
0138     uchar m_lineModFlags = 0x0;
0139 };
0140 
0141 class KateEditInsertTextUndo : public KateUndo
0142 {
0143 public:
0144     explicit KateEditInsertTextUndo(KTextEditor::DocumentPrivate *document, int line, int col, const QString &text);
0145 
0146     /**
0147      * @copydoc KateUndo::isEmpty()
0148      */
0149     bool isEmpty() const override;
0150 
0151     /**
0152      * @copydoc KateUndo::undo()
0153      */
0154     void undo() override;
0155 
0156     /**
0157      * @copydoc KateUndo::redo()
0158      */
0159     void redo() override;
0160 
0161     /**
0162      * @copydoc KateUndo::mergeWith(const KateUndo)
0163      */
0164     bool mergeWith(const KateUndo *undo) override;
0165 
0166     /**
0167      * @copydoc KateUndo::type()
0168      */
0169     KateUndo::UndoType type() const override
0170     {
0171         return KateUndo::editInsertText;
0172     }
0173 
0174 protected:
0175     inline int len() const
0176     {
0177         return m_text.length();
0178     }
0179     inline int line() const
0180     {
0181         return m_line;
0182     }
0183 
0184 private:
0185     const int m_line;
0186     const int m_col;
0187     QString m_text;
0188 };
0189 
0190 class KateEditRemoveTextUndo : public KateUndo
0191 {
0192 public:
0193     explicit KateEditRemoveTextUndo(KTextEditor::DocumentPrivate *document, int line, int col, const QString &text);
0194 
0195     /**
0196      * @copydoc KateUndo::isEmpty()
0197      */
0198     bool isEmpty() const override;
0199 
0200     /**
0201      * @copydoc KateUndo::undo()
0202      */
0203     void undo() override;
0204 
0205     /**
0206      * @copydoc KateUndo::redo()
0207      */
0208     void redo() override;
0209 
0210     /**
0211      * @copydoc KateUndo::mergeWith(const KateUndo)
0212      */
0213     bool mergeWith(const KateUndo *undo) override;
0214 
0215     /**
0216      * @copydoc KateUndo::type()
0217      */
0218     KateUndo::UndoType type() const override
0219     {
0220         return KateUndo::editRemoveText;
0221     }
0222 
0223 protected:
0224     inline int len() const
0225     {
0226         return m_text.length();
0227     }
0228     inline int line() const
0229     {
0230         return m_line;
0231     }
0232 
0233 private:
0234     const int m_line;
0235     int m_col;
0236     QString m_text;
0237 };
0238 
0239 class KateEditMarkLineAutoWrappedUndo : public KateUndo
0240 {
0241 public:
0242     explicit KateEditMarkLineAutoWrappedUndo(KTextEditor::DocumentPrivate *document, int line, bool autowrapped)
0243         : KateUndo(document)
0244         , m_line(line)
0245         , m_autowrapped(autowrapped)
0246     {
0247     }
0248 
0249     /**
0250      * @copydoc KateUndo::undo()
0251      */
0252     void undo() override;
0253 
0254     /**
0255      * @copydoc KateUndo::redo()
0256      */
0257     void redo() override;
0258 
0259     /**
0260      * @copydoc KateUndo::type()
0261      */
0262     KateUndo::UndoType type() const override
0263     {
0264         return KateUndo::editMarkLineAutoWrapped;
0265     }
0266 
0267 private:
0268     const int m_line;
0269     const bool m_autowrapped;
0270 };
0271 
0272 class KateEditWrapLineUndo : public KateUndo
0273 {
0274 public:
0275     explicit KateEditWrapLineUndo(KTextEditor::DocumentPrivate *document, int line, int col, int len, bool newLine);
0276 
0277     /**
0278      * @copydoc KateUndo::undo()
0279      */
0280     void undo() override;
0281 
0282     /**
0283      * @copydoc KateUndo::redo()
0284      */
0285     void redo() override;
0286 
0287     /**
0288      * @copydoc KateUndo::type()
0289      */
0290     KateUndo::UndoType type() const override
0291     {
0292         return KateUndo::editWrapLine;
0293     }
0294 
0295 protected:
0296     inline int line() const
0297     {
0298         return m_line;
0299     }
0300 
0301 private:
0302     const int m_line;
0303     const int m_col;
0304     const int m_len;
0305     const bool m_newLine;
0306 };
0307 
0308 class KateEditUnWrapLineUndo : public KateUndo
0309 {
0310 public:
0311     explicit KateEditUnWrapLineUndo(KTextEditor::DocumentPrivate *document, int line, int col, int len, bool removeLine);
0312 
0313     /**
0314      * @copydoc KateUndo::undo()
0315      */
0316     void undo() override;
0317 
0318     /**
0319      * @copydoc KateUndo::redo()
0320      */
0321     void redo() override;
0322 
0323     /**
0324      * @copydoc KateUndo::type()
0325      */
0326     KateUndo::UndoType type() const override
0327     {
0328         return KateUndo::editUnWrapLine;
0329     }
0330 
0331 protected:
0332     inline int line() const
0333     {
0334         return m_line;
0335     }
0336 
0337 private:
0338     const int m_line;
0339     const int m_col;
0340     const int m_len;
0341     const bool m_removeLine;
0342 };
0343 
0344 class KateEditInsertLineUndo : public KateUndo
0345 {
0346 public:
0347     explicit KateEditInsertLineUndo(KTextEditor::DocumentPrivate *document, int line, const QString &text);
0348 
0349     /**
0350      * @copydoc KateUndo::undo()
0351      */
0352     void undo() override;
0353 
0354     /**
0355      * @copydoc KateUndo::redo()
0356      */
0357     void redo() override;
0358 
0359     /**
0360      * @copydoc KateUndo::type()
0361      */
0362     KateUndo::UndoType type() const override
0363     {
0364         return KateUndo::editInsertLine;
0365     }
0366 
0367 protected:
0368     inline int line() const
0369     {
0370         return m_line;
0371     }
0372 
0373 private:
0374     const int m_line;
0375     const QString m_text;
0376 };
0377 
0378 class KateEditRemoveLineUndo : public KateUndo
0379 {
0380 public:
0381     explicit KateEditRemoveLineUndo(KTextEditor::DocumentPrivate *document, int line, const QString &text);
0382 
0383     /**
0384      * @copydoc KateUndo::undo()
0385      */
0386     void undo() override;
0387 
0388     /**
0389      * @copydoc KateUndo::redo()
0390      */
0391     void redo() override;
0392 
0393     /**
0394      * @copydoc KateUndo::type()
0395      */
0396     KateUndo::UndoType type() const override
0397     {
0398         return KateUndo::editRemoveLine;
0399     }
0400 
0401 protected:
0402     inline int line() const
0403     {
0404         return m_line;
0405     }
0406 
0407 private:
0408     const int m_line;
0409     const QString m_text;
0410 };
0411 
0412 /**
0413  * Class to manage a group of undo items
0414  */
0415 class KateUndoGroup
0416 {
0417 public:
0418     /**
0419      * Constructor
0420      * @param manager KateUndoManager this undo group will belong to
0421      */
0422     explicit KateUndoGroup(KateUndoManager *manager,
0423                            const KTextEditor::Cursor cursorPosition,
0424                            KTextEditor::Range selection,
0425                            const QVector<KTextEditor::ViewPrivate::PlainSecondaryCursor> &);
0426 
0427     /**
0428      * Destructor
0429      */
0430     ~KateUndoGroup();
0431 
0432     KateUndoGroup(const KateUndoGroup &) = delete;
0433     KateUndoGroup &operator=(const KateUndoGroup &) = delete;
0434 
0435 public:
0436     /**
0437      * Undo the contained undo items
0438      */
0439     void undo(KTextEditor::ViewPrivate *view);
0440 
0441     /**
0442      * Redo the contained undo items
0443      */
0444     void redo(KTextEditor::ViewPrivate *view);
0445 
0446     void editEnd(const KTextEditor::Cursor cursorPosition,
0447                  KTextEditor::Range selectionRange,
0448                  const QVector<KTextEditor::ViewPrivate::PlainSecondaryCursor> &secondaryCursors);
0449 
0450     /**
0451      * merge this group with an other
0452      * @param newGroup group to merge into this one
0453      * @param complex set if a complex undo
0454      * @return success
0455      */
0456     bool merge(KateUndoGroup *newGroup, bool complex);
0457 
0458     /**
0459      * set group as as savepoint. the next group will not merge with this one
0460      */
0461     void safePoint(bool safePoint = true);
0462 
0463     /**
0464      * is this undogroup empty?
0465      */
0466     bool isEmpty() const
0467     {
0468         return m_items.isEmpty();
0469     }
0470 
0471     /**
0472      * Change all LineSaved flags to LineModified of the line modification system.
0473      */
0474     void flagSavedAsModified();
0475 
0476     void markUndoAsSaved(QBitArray &lines);
0477     void markRedoAsSaved(QBitArray &lines);
0478 
0479     /**
0480      * Set the undo cursor to @p cursor.
0481      */
0482     inline void setUndoCursor(const KTextEditor::Cursor cursor)
0483     {
0484         m_undoCursor = cursor;
0485     }
0486 
0487     /**
0488      * Set the redo cursor to @p cursor.
0489      */
0490     inline void setRedoCursor(const KTextEditor::Cursor cursor)
0491     {
0492         m_redoCursor = cursor;
0493     }
0494 
0495     inline KTextEditor::Cursor redoCursor() const
0496     {
0497         return m_redoCursor;
0498     }
0499 
0500 private:
0501     KTextEditor::Document *document();
0502 
0503     /**
0504      * singleType
0505      * @return the type if it's only one type, or editInvalid if it contains multiple types.
0506      */
0507     KateUndo::UndoType singleType() const;
0508 
0509     /**
0510      * are we only of this type ?
0511      * @param type type to query
0512      * @return we contain only the given type
0513      */
0514     bool isOnlyType(KateUndo::UndoType type) const;
0515 
0516 public:
0517     /**
0518      * add an undo item
0519      * @param u item to add
0520      */
0521     void addItem(KateUndo *u);
0522 
0523 private:
0524     KateUndoManager *const m_manager;
0525 
0526     /**
0527      * list of items contained
0528      */
0529     QList<KateUndo *> m_items;
0530 
0531     /**
0532      * prohibit merging with the next group
0533      */
0534     bool m_safePoint = false;
0535     /*
0536      * Selection Range of primary cursor
0537      */
0538     const KTextEditor::Range m_undoSelection;
0539     /*
0540      * Selection Range of primary cursor
0541      */
0542     KTextEditor::Range m_redoSelection;
0543 
0544     /**
0545      * the cursor position of the active view before the edit step
0546      */
0547     KTextEditor::Cursor m_undoCursor;
0548     /**
0549      * the cursor positions of the active view before the edit step
0550      */
0551     QVector<KTextEditor::ViewPrivate::PlainSecondaryCursor> m_undoSecondaryCursors;
0552 
0553     /**
0554      * the cursor position of the active view after the edit step
0555      */
0556     KTextEditor::Cursor m_redoCursor;
0557     /**
0558      * the cursor positions of the active view before the edit step
0559      */
0560     QVector<KTextEditor::ViewPrivate::PlainSecondaryCursor> m_redoSecondaryCursors;
0561 };
0562 
0563 #endif