1*8af74909SZhong Yang // Scintilla source code edit control 2*8af74909SZhong Yang /** @file CellBuffer.h 3*8af74909SZhong Yang ** Manages the text of the document. 4*8af74909SZhong Yang **/ 5*8af74909SZhong Yang // Copyright 1998-2004 by Neil Hodgson <[email protected]> 6*8af74909SZhong Yang // The License.txt file describes the conditions under which this software may be distributed. 7*8af74909SZhong Yang 8*8af74909SZhong Yang #ifndef CELLBUFFER_H 9*8af74909SZhong Yang #define CELLBUFFER_H 10*8af74909SZhong Yang 11*8af74909SZhong Yang namespace Scintilla { 12*8af74909SZhong Yang 13*8af74909SZhong Yang // Interface to per-line data that wants to see each line insertion and deletion 14*8af74909SZhong Yang class PerLine { 15*8af74909SZhong Yang public: ~PerLine()16*8af74909SZhong Yang virtual ~PerLine() {} 17*8af74909SZhong Yang virtual void Init()=0; 18*8af74909SZhong Yang virtual void InsertLine(Sci::Line line)=0; 19*8af74909SZhong Yang virtual void InsertLines(Sci::Line line, Sci::Line lines) = 0; 20*8af74909SZhong Yang virtual void RemoveLine(Sci::Line line)=0; 21*8af74909SZhong Yang }; 22*8af74909SZhong Yang 23*8af74909SZhong Yang /** 24*8af74909SZhong Yang * The line vector contains information about each of the lines in a cell buffer. 25*8af74909SZhong Yang */ 26*8af74909SZhong Yang class ILineVector; 27*8af74909SZhong Yang 28*8af74909SZhong Yang enum actionType { insertAction, removeAction, startAction, containerAction }; 29*8af74909SZhong Yang 30*8af74909SZhong Yang /** 31*8af74909SZhong Yang * Actions are used to store all the information required to perform one undo/redo step. 32*8af74909SZhong Yang */ 33*8af74909SZhong Yang class Action { 34*8af74909SZhong Yang public: 35*8af74909SZhong Yang actionType at; 36*8af74909SZhong Yang Sci::Position position; 37*8af74909SZhong Yang std::unique_ptr<char[]> data; 38*8af74909SZhong Yang Sci::Position lenData; 39*8af74909SZhong Yang bool mayCoalesce; 40*8af74909SZhong Yang 41*8af74909SZhong Yang Action() noexcept; 42*8af74909SZhong Yang // Deleted so Action objects can not be copied. 43*8af74909SZhong Yang Action(const Action &other) = delete; 44*8af74909SZhong Yang Action &operator=(const Action &other) = delete; 45*8af74909SZhong Yang Action &operator=(const Action &&other) = delete; 46*8af74909SZhong Yang // Move constructor allows vector to be resized without reallocating. 47*8af74909SZhong Yang Action(Action &&other) noexcept = default; 48*8af74909SZhong Yang ~Action(); 49*8af74909SZhong Yang void Create(actionType at_, Sci::Position position_=0, const char *data_=nullptr, Sci::Position lenData_=0, bool mayCoalesce_=true); 50*8af74909SZhong Yang void Clear() noexcept; 51*8af74909SZhong Yang }; 52*8af74909SZhong Yang 53*8af74909SZhong Yang /** 54*8af74909SZhong Yang * 55*8af74909SZhong Yang */ 56*8af74909SZhong Yang class UndoHistory { 57*8af74909SZhong Yang std::vector<Action> actions; 58*8af74909SZhong Yang int maxAction; 59*8af74909SZhong Yang int currentAction; 60*8af74909SZhong Yang int undoSequenceDepth; 61*8af74909SZhong Yang int savePoint; 62*8af74909SZhong Yang int tentativePoint; 63*8af74909SZhong Yang 64*8af74909SZhong Yang void EnsureUndoRoom(); 65*8af74909SZhong Yang 66*8af74909SZhong Yang public: 67*8af74909SZhong Yang UndoHistory(); 68*8af74909SZhong Yang // Deleted so UndoHistory objects can not be copied. 69*8af74909SZhong Yang UndoHistory(const UndoHistory &) = delete; 70*8af74909SZhong Yang UndoHistory(UndoHistory &&) = delete; 71*8af74909SZhong Yang void operator=(const UndoHistory &) = delete; 72*8af74909SZhong Yang void operator=(UndoHistory &&) = delete; 73*8af74909SZhong Yang ~UndoHistory(); 74*8af74909SZhong Yang 75*8af74909SZhong Yang const char *AppendAction(actionType at, Sci::Position position, const char *data, Sci::Position lengthData, bool &startSequence, bool mayCoalesce=true); 76*8af74909SZhong Yang 77*8af74909SZhong Yang void BeginUndoAction(); 78*8af74909SZhong Yang void EndUndoAction(); 79*8af74909SZhong Yang void DropUndoSequence(); 80*8af74909SZhong Yang void DeleteUndoHistory(); 81*8af74909SZhong Yang 82*8af74909SZhong Yang /// The save point is a marker in the undo stack where the container has stated that 83*8af74909SZhong Yang /// the buffer was saved. Undo and redo can move over the save point. 84*8af74909SZhong Yang void SetSavePoint() noexcept; 85*8af74909SZhong Yang bool IsSavePoint() const noexcept; 86*8af74909SZhong Yang 87*8af74909SZhong Yang // Tentative actions are used for input composition so that it can be undone cleanly 88*8af74909SZhong Yang void TentativeStart(); 89*8af74909SZhong Yang void TentativeCommit(); 90*8af74909SZhong Yang bool TentativeActive() const noexcept; 91*8af74909SZhong Yang int TentativeSteps() noexcept; 92*8af74909SZhong Yang 93*8af74909SZhong Yang /// To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is 94*8af74909SZhong Yang /// called that many times. Similarly for redo. 95*8af74909SZhong Yang bool CanUndo() const noexcept; 96*8af74909SZhong Yang int StartUndo(); 97*8af74909SZhong Yang const Action &GetUndoStep() const; 98*8af74909SZhong Yang void CompletedUndoStep(); 99*8af74909SZhong Yang bool CanRedo() const noexcept; 100*8af74909SZhong Yang int StartRedo(); 101*8af74909SZhong Yang const Action &GetRedoStep() const; 102*8af74909SZhong Yang void CompletedRedoStep(); 103*8af74909SZhong Yang }; 104*8af74909SZhong Yang 105*8af74909SZhong Yang /** 106*8af74909SZhong Yang * Holder for an expandable array of characters that supports undo and line markers. 107*8af74909SZhong Yang * Based on article "Data Structures in a Bit-Mapped Text Editor" 108*8af74909SZhong Yang * by Wilfred J. Hansen, Byte January 1987, page 183. 109*8af74909SZhong Yang */ 110*8af74909SZhong Yang class CellBuffer { 111*8af74909SZhong Yang private: 112*8af74909SZhong Yang bool hasStyles; 113*8af74909SZhong Yang bool largeDocument; 114*8af74909SZhong Yang SplitVector<char> substance; 115*8af74909SZhong Yang SplitVector<char> style; 116*8af74909SZhong Yang bool readOnly; 117*8af74909SZhong Yang bool utf8Substance; 118*8af74909SZhong Yang int utf8LineEnds; 119*8af74909SZhong Yang 120*8af74909SZhong Yang bool collectingUndo; 121*8af74909SZhong Yang UndoHistory uh; 122*8af74909SZhong Yang 123*8af74909SZhong Yang std::unique_ptr<ILineVector> plv; 124*8af74909SZhong Yang 125*8af74909SZhong Yang bool UTF8LineEndOverlaps(Sci::Position position) const noexcept; 126*8af74909SZhong Yang bool UTF8IsCharacterBoundary(Sci::Position position) const; 127*8af74909SZhong Yang void ResetLineEnds(); 128*8af74909SZhong Yang void RecalculateIndexLineStarts(Sci::Line lineFirst, Sci::Line lineLast); 129*8af74909SZhong Yang bool MaintainingLineCharacterIndex() const noexcept; 130*8af74909SZhong Yang /// Actions without undo 131*8af74909SZhong Yang void BasicInsertString(Sci::Position position, const char *s, Sci::Position insertLength); 132*8af74909SZhong Yang void BasicDeleteChars(Sci::Position position, Sci::Position deleteLength); 133*8af74909SZhong Yang 134*8af74909SZhong Yang public: 135*8af74909SZhong Yang 136*8af74909SZhong Yang CellBuffer(bool hasStyles_, bool largeDocument_); 137*8af74909SZhong Yang // Deleted so CellBuffer objects can not be copied. 138*8af74909SZhong Yang CellBuffer(const CellBuffer &) = delete; 139*8af74909SZhong Yang CellBuffer(CellBuffer &&) = delete; 140*8af74909SZhong Yang void operator=(const CellBuffer &) = delete; 141*8af74909SZhong Yang void operator=(CellBuffer &&) = delete; 142*8af74909SZhong Yang ~CellBuffer(); 143*8af74909SZhong Yang 144*8af74909SZhong Yang /// Retrieving positions outside the range of the buffer works and returns 0 145*8af74909SZhong Yang char CharAt(Sci::Position position) const noexcept; 146*8af74909SZhong Yang unsigned char UCharAt(Sci::Position position) const noexcept; 147*8af74909SZhong Yang void GetCharRange(char *buffer, Sci::Position position, Sci::Position lengthRetrieve) const; 148*8af74909SZhong Yang char StyleAt(Sci::Position position) const noexcept; 149*8af74909SZhong Yang void GetStyleRange(unsigned char *buffer, Sci::Position position, Sci::Position lengthRetrieve) const; 150*8af74909SZhong Yang const char *BufferPointer(); 151*8af74909SZhong Yang const char *RangePointer(Sci::Position position, Sci::Position rangeLength) noexcept; 152*8af74909SZhong Yang Sci::Position GapPosition() const noexcept; 153*8af74909SZhong Yang 154*8af74909SZhong Yang Sci::Position Length() const noexcept; 155*8af74909SZhong Yang void Allocate(Sci::Position newSize); 156*8af74909SZhong Yang void SetUTF8Substance(bool utf8Substance_) noexcept; GetLineEndTypes()157*8af74909SZhong Yang int GetLineEndTypes() const noexcept { return utf8LineEnds; } 158*8af74909SZhong Yang void SetLineEndTypes(int utf8LineEnds_); 159*8af74909SZhong Yang bool ContainsLineEnd(const char *s, Sci::Position length) const noexcept; 160*8af74909SZhong Yang void SetPerLine(PerLine *pl) noexcept; 161*8af74909SZhong Yang int LineCharacterIndex() const noexcept; 162*8af74909SZhong Yang void AllocateLineCharacterIndex(int lineCharacterIndex); 163*8af74909SZhong Yang void ReleaseLineCharacterIndex(int lineCharacterIndex); 164*8af74909SZhong Yang Sci::Line Lines() const noexcept; 165*8af74909SZhong Yang Sci::Position LineStart(Sci::Line line) const noexcept; 166*8af74909SZhong Yang Sci::Position IndexLineStart(Sci::Line line, int lineCharacterIndex) const noexcept; 167*8af74909SZhong Yang Sci::Line LineFromPosition(Sci::Position pos) const noexcept; 168*8af74909SZhong Yang Sci::Line LineFromPositionIndex(Sci::Position pos, int lineCharacterIndex) const noexcept; 169*8af74909SZhong Yang void InsertLine(Sci::Line line, Sci::Position position, bool lineStart); 170*8af74909SZhong Yang void RemoveLine(Sci::Line line); 171*8af74909SZhong Yang const char *InsertString(Sci::Position position, const char *s, Sci::Position insertLength, bool &startSequence); 172*8af74909SZhong Yang 173*8af74909SZhong Yang /// Setting styles for positions outside the range of the buffer is safe and has no effect. 174*8af74909SZhong Yang /// @return true if the style of a character is changed. 175*8af74909SZhong Yang bool SetStyleAt(Sci::Position position, char styleValue) noexcept; 176*8af74909SZhong Yang bool SetStyleFor(Sci::Position position, Sci::Position lengthStyle, char styleValue) noexcept; 177*8af74909SZhong Yang 178*8af74909SZhong Yang const char *DeleteChars(Sci::Position position, Sci::Position deleteLength, bool &startSequence); 179*8af74909SZhong Yang 180*8af74909SZhong Yang bool IsReadOnly() const noexcept; 181*8af74909SZhong Yang void SetReadOnly(bool set) noexcept; 182*8af74909SZhong Yang bool IsLarge() const noexcept; 183*8af74909SZhong Yang bool HasStyles() const noexcept; 184*8af74909SZhong Yang 185*8af74909SZhong Yang /// The save point is a marker in the undo stack where the container has stated that 186*8af74909SZhong Yang /// the buffer was saved. Undo and redo can move over the save point. 187*8af74909SZhong Yang void SetSavePoint(); 188*8af74909SZhong Yang bool IsSavePoint() const noexcept; 189*8af74909SZhong Yang 190*8af74909SZhong Yang void TentativeStart(); 191*8af74909SZhong Yang void TentativeCommit(); 192*8af74909SZhong Yang bool TentativeActive() const noexcept; 193*8af74909SZhong Yang int TentativeSteps() noexcept; 194*8af74909SZhong Yang 195*8af74909SZhong Yang bool SetUndoCollection(bool collectUndo); 196*8af74909SZhong Yang bool IsCollectingUndo() const noexcept; 197*8af74909SZhong Yang void BeginUndoAction(); 198*8af74909SZhong Yang void EndUndoAction(); 199*8af74909SZhong Yang void AddUndoAction(Sci::Position token, bool mayCoalesce); 200*8af74909SZhong Yang void DeleteUndoHistory(); 201*8af74909SZhong Yang 202*8af74909SZhong Yang /// To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is 203*8af74909SZhong Yang /// called that many times. Similarly for redo. 204*8af74909SZhong Yang bool CanUndo() const noexcept; 205*8af74909SZhong Yang int StartUndo(); 206*8af74909SZhong Yang const Action &GetUndoStep() const; 207*8af74909SZhong Yang void PerformUndoStep(); 208*8af74909SZhong Yang bool CanRedo() const noexcept; 209*8af74909SZhong Yang int StartRedo(); 210*8af74909SZhong Yang const Action &GetRedoStep() const; 211*8af74909SZhong Yang void PerformRedoStep(); 212*8af74909SZhong Yang }; 213*8af74909SZhong Yang 214*8af74909SZhong Yang } 215*8af74909SZhong Yang 216*8af74909SZhong Yang #endif 217