File indexing completed on 2024-04-21 03:57:45

0001 /*
0002     SPDX-FileCopyrightText: 2009-2010 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #ifndef KATEUNDOMANAGER_H
0008 #define KATEUNDOMANAGER_H
0009 
0010 #include "kateundo.h"
0011 #include <QObject>
0012 
0013 #include <ktexteditor_export.h>
0014 
0015 #include <QList>
0016 
0017 #include <optional>
0018 
0019 namespace KTextEditor
0020 {
0021 class DocumentPrivate;
0022 }
0023 class KateUndo;
0024 class KateUndoGroup;
0025 
0026 namespace KTextEditor
0027 {
0028 class Document;
0029 class View;
0030 class ViewPrivate;
0031 class Cursor;
0032 }
0033 
0034 /**
0035  * KateUndoManager implements a document's history. It is in either of the two states:
0036  * @li the default state, which allows rolling back and forth the history of a document, and
0037  * @li a state in which a new element is being added to the history.
0038  *
0039  * The state of the KateUndomanager can be switched using editStart() and editEnd().
0040  */
0041 class KateUndoManager : public QObject
0042 {
0043     Q_OBJECT
0044 
0045 public:
0046     /**
0047      * Creates a clean undo history.
0048      *
0049      * @param doc the document the KateUndoManager will belong to
0050      */
0051     explicit KateUndoManager(KTextEditor::DocumentPrivate *doc);
0052 
0053     ~KateUndoManager() override;
0054 
0055     KTextEditor::DocumentPrivate *document()
0056     {
0057         return m_document;
0058     }
0059 
0060     /**
0061      * Returns how many undo() actions can be performed.
0062      *
0063      * @return the number of undo groups which can be undone
0064      */
0065     uint undoCount() const;
0066 
0067     /**
0068      * Returns how many redo() actions can be performed.
0069      *
0070      * @return the number of undo groups which can be redone
0071      */
0072     uint redoCount() const;
0073 
0074     /**
0075      * Prevent latest KateUndoGroup from being merged with the next one.
0076      */
0077     KTEXTEDITOR_EXPORT void undoSafePoint();
0078 
0079     /**
0080      * Allows or disallows merging of "complex" undo groups.
0081      *
0082      * When an undo group contains different types of undo items, it is considered
0083      * a "complex" group.
0084      *
0085      * @param allow whether complex merging is allowed
0086      */
0087     void setAllowComplexMerge(bool allow);
0088 
0089     bool isActive() const
0090     {
0091         return m_isActive;
0092     }
0093 
0094     void setModified(bool modified);
0095     void updateConfig();
0096     KTEXTEDITOR_EXPORT void updateLineModifications();
0097 
0098     /**
0099      * Used by the swap file recovery, this function afterwards manipulates
0100      * the undo/redo cursors of the last KateUndoGroup.
0101      * This function should not be used other than by Kate::SwapFile.
0102      * @param undoCursor the undo cursor
0103      * @param redoCursor the redo cursor
0104      */
0105     void setUndoRedoCursorsOfLastGroup(const KTextEditor::Cursor undoCursor, const KTextEditor::Cursor redoCursor);
0106 
0107     /**
0108      * Returns the redo cursor of the last undo group.
0109      * Needed for the swap file recovery.
0110      */
0111     KTextEditor::Cursor lastRedoCursor() const;
0112 
0113 public Q_SLOTS:
0114     /**
0115      * Undo the latest undo group.
0116      *
0117      * Make sure isDefaultState() is true when calling this method.
0118      */
0119     void undo();
0120 
0121     /**
0122      * Redo the latest undo group.
0123      *
0124      * Make sure isDefaultState() is true when calling this method.
0125      */
0126     void redo();
0127 
0128     KTEXTEDITOR_EXPORT void clearUndo();
0129     KTEXTEDITOR_EXPORT void clearRedo();
0130 
0131     /**
0132      * Notify KateUndoManager about the beginning of an edit.
0133      */
0134     void editStart();
0135 
0136     /**
0137      * Notify KateUndoManager about the end of an edit.
0138      */
0139     void editEnd();
0140 
0141     void startUndo();
0142     void endUndo();
0143 
0144     void inputMethodStart();
0145     void inputMethodEnd();
0146 
0147     /**
0148      * Notify KateUndoManager that text was inserted.
0149      */
0150     void slotTextInserted(int line, int col, const QString &s, const Kate::TextLine &tl);
0151 
0152     /**
0153      * Notify KateUndoManager that text was removed.
0154      */
0155     void slotTextRemoved(int line, int col, const QString &s, const Kate::TextLine &tl);
0156 
0157     /**
0158      * Notify KateUndoManager that a line was marked as autowrapped.
0159      */
0160     void slotMarkLineAutoWrapped(int line, bool autowrapped);
0161 
0162     /**
0163      * Notify KateUndoManager that a line was wrapped.
0164      */
0165     void slotLineWrapped(int line, int col, int length, bool newLine, const Kate::TextLine &tl);
0166 
0167     /**
0168      * Notify KateUndoManager that a line was un-wrapped.
0169      */
0170     void slotLineUnWrapped(int line, int col, int length, bool lineRemoved, const Kate::TextLine &tl, const Kate::TextLine &nextLine);
0171 
0172     /**
0173      * Notify KateUndoManager that a line was inserted.
0174      */
0175     void slotLineInserted(int line, const QString &s);
0176 
0177     /**
0178      * Notify KateUndoManager that a line was removed.
0179      */
0180     void slotLineRemoved(int line, const QString &s, const Kate::TextLine &tl);
0181 
0182 Q_SIGNALS:
0183     void undoChanged();
0184     void undoStart(KTextEditor::Document *);
0185     void undoEnd(KTextEditor::Document *);
0186     void redoStart(KTextEditor::Document *);
0187     void redoEnd(KTextEditor::Document *);
0188     void isActiveChanged(bool enabled);
0189 
0190 private Q_SLOTS:
0191     /**
0192      * @short Add an undo item to the current undo group.
0193      *
0194      * @param undo undo item to be added, must be non-null
0195      */
0196     void addUndoItem(UndoItem undo);
0197 
0198     void setActive(bool active);
0199 
0200     void updateModified();
0201 
0202     void undoCancel();
0203     void viewCreated(KTextEditor::Document *, KTextEditor::View *newView) const;
0204 
0205 private:
0206     KTEXTEDITOR_NO_EXPORT
0207     KTextEditor::ViewPrivate *activeView();
0208 
0209 private:
0210     KTextEditor::DocumentPrivate *m_document = nullptr;
0211     bool m_undoComplexMerge = false;
0212     bool m_isActive = true;
0213     std::optional<KateUndoGroup> m_editCurrentUndo;
0214     std::vector<KateUndoGroup> undoItems;
0215     std::vector<KateUndoGroup> redoItems;
0216     // these two variables are for resetting the document to
0217     // non-modified if all changes have been undone...
0218     KateUndoGroup *lastUndoGroupWhenSaved = nullptr;
0219     KateUndoGroup *lastRedoGroupWhenSaved = nullptr;
0220     bool docWasSavedWhenUndoWasEmpty = true;
0221     bool docWasSavedWhenRedoWasEmpty = true;
0222 
0223     // saved undo items that are used to restore state on doc reload
0224     std::vector<KateUndoGroup> savedUndoItems;
0225     std::vector<KateUndoGroup> savedRedoItems;
0226     QByteArray docChecksumBeforeReload;
0227 };
0228 
0229 #endif