xref: /MusicPlayer2/scintilla/src/CellBuffer.h (revision 8af74909132ed5e696cb05b6689ae4baf14c1c96)
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