]>
Commit | Line | Data |
---|---|---|
9ce192d4 RD |
1 | // Scintilla source code edit control |
2 | // Document.h - text document that handles notifications, DBCS, styling, words and end of line | |
3 | // Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org> | |
4 | // The License.txt file describes the conditions under which this software may be distributed. | |
5 | ||
6 | #ifndef DOCUMENT_H | |
7 | #define DOCUMENT_H | |
8 | ||
9 | // A Position is a position within a document between two characters or at the beginning or end. | |
10 | // Sometimes used as a character index where it identifies the character after the position. | |
11 | typedef int Position; | |
12 | const Position invalidPosition = -1; | |
13 | ||
14 | // The range class represents a range of text in a document. | |
15 | // The two values are not sorted as one end may be more significant than the other | |
16 | // as is the case for the selection where the end position is the position of the caret. | |
17 | // If either position is invalidPosition then the range is invalid and most operations will fail. | |
18 | class Range { | |
19 | public: | |
20 | Position start; | |
21 | Position end; | |
22 | ||
23 | Range(Position pos=0) : | |
24 | start(pos), end(pos) { | |
25 | }; | |
26 | Range(Position start_, Position end_) : | |
27 | start(start_), end(end_) { | |
28 | }; | |
29 | ||
30 | bool Valid() const { | |
31 | return (start != invalidPosition) && (end != invalidPosition); | |
32 | } | |
33 | ||
34 | bool Contains(Position pos) const { | |
35 | if (start < end) { | |
36 | return (pos >= start && pos <= end); | |
37 | } else { | |
38 | return (pos <= start && pos >= end); | |
39 | } | |
40 | } | |
41 | ||
42 | bool Contains(Range other) const { | |
43 | return Contains(other.start) && Contains(other.end); | |
44 | } | |
45 | ||
46 | bool Overlaps(Range other) const { | |
47 | return | |
48 | Contains(other.start) || | |
49 | Contains(other.end) || | |
50 | other.Contains(start) || | |
51 | other.Contains(end); | |
52 | } | |
53 | }; | |
54 | ||
55 | class DocWatcher; | |
56 | class DocModification; | |
57 | ||
58 | class Document { | |
59 | ||
60 | public: | |
61 | // Used to pair watcher pointer with user data | |
62 | class WatcherWithUserData { | |
63 | public: | |
64 | DocWatcher *watcher; | |
65 | void *userData; | |
66 | WatcherWithUserData() { | |
67 | watcher = 0; | |
68 | userData = 0; | |
69 | } | |
70 | }; | |
71 | ||
72 | private: | |
73 | int refCount; | |
74 | CellBuffer cb; | |
75 | bool wordchars[256]; | |
76 | int stylingPos; | |
f6bcfd97 | 77 | char stylingMask; |
9ce192d4 RD |
78 | int endStyled; |
79 | int enteredCount; | |
f6bcfd97 | 80 | int enteredReadOnlyCount; |
9ce192d4 RD |
81 | |
82 | WatcherWithUserData *watchers; | |
83 | int lenWatchers; | |
84 | ||
85 | public: | |
86 | int stylingBits; | |
87 | int stylingBitsMask; | |
88 | ||
89 | int eolMode; | |
f6bcfd97 | 90 | // dbcsCodePage can also be SC_CP_UTF8 to enable UTF-8 mode |
9ce192d4 RD |
91 | int dbcsCodePage; |
92 | int tabInChars; | |
f6bcfd97 BP |
93 | int indentInChars; |
94 | bool useTabs; | |
9ce192d4 RD |
95 | |
96 | Document(); | |
97 | virtual ~Document(); | |
98 | ||
99 | int AddRef(); | |
100 | int Release(); | |
101 | ||
102 | int LineFromPosition(int pos); | |
103 | int ClampPositionIntoDocument(int pos); | |
104 | bool IsCrLf(int pos); | |
f6bcfd97 | 105 | int LenChar(int pos); |
9ce192d4 RD |
106 | int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true); |
107 | ||
108 | // Gateways to modifying document | |
109 | void DeleteChars(int pos, int len); | |
110 | void InsertStyledString(int position, char *s, int insertLength); | |
111 | int Undo(); | |
112 | int Redo(); | |
113 | bool CanUndo() { return cb.CanUndo(); } | |
114 | bool CanRedo() { return cb.CanRedo(); } | |
115 | void DeleteUndoHistory() { cb.DeleteUndoHistory(); } | |
116 | undoCollectionType SetUndoCollection(undoCollectionType collectUndo) { | |
117 | return cb.SetUndoCollection(collectUndo); | |
118 | } | |
9ce192d4 RD |
119 | void BeginUndoAction() { cb.BeginUndoAction(); } |
120 | void EndUndoAction() { cb.EndUndoAction(); } | |
121 | void SetSavePoint(); | |
122 | bool IsSavePoint() { return cb.IsSavePoint(); } | |
f6bcfd97 BP |
123 | |
124 | int GetLineIndentation(int line); | |
125 | void SetLineIndentation(int line, int indent); | |
126 | int GetLineIndentPosition(int line); | |
9ce192d4 RD |
127 | void Indent(bool forwards, int lineBottom, int lineTop); |
128 | void ConvertLineEnds(int eolModeSet); | |
129 | void SetReadOnly(bool set) { cb.SetReadOnly(set); } | |
130 | ||
131 | void InsertChar(int pos, char ch); | |
132 | void InsertString(int position, const char *s); | |
133 | void InsertString(int position, const char *s, int insertLength); | |
f6bcfd97 | 134 | void ChangeChar(int pos, char ch); |
9ce192d4 RD |
135 | void DelChar(int pos); |
136 | int DelCharBack(int pos); | |
137 | ||
138 | char CharAt(int position) { return cb.CharAt(position); } | |
139 | void GetCharRange(char *buffer, int position, int lengthRetrieve) { | |
140 | cb.GetCharRange(buffer, position, lengthRetrieve); | |
141 | } | |
142 | char StyleAt(int position) { return cb.StyleAt(position); } | |
143 | int GetMark(int line) { return cb.GetMark(line); } | |
f6bcfd97 BP |
144 | int AddMark(int line, int markerNum); |
145 | void DeleteMark(int line, int markerNum); | |
146 | void DeleteMarkFromHandle(int markerHandle); | |
147 | void DeleteAllMarks(int markerNum); | |
9ce192d4 RD |
148 | int LineFromHandle(int markerHandle) { return cb.LineFromHandle(markerHandle); } |
149 | int LineStart(int line); | |
f6bcfd97 | 150 | int LineEnd(int line); |
9ce192d4 RD |
151 | int LineEndPosition(int position); |
152 | int VCHomePosition(int position); | |
153 | ||
154 | int SetLevel(int line, int level); | |
155 | int GetLevel(int line) { return cb.GetLevel(line); } | |
156 | int GetLastChild(int lineParent, int level=-1); | |
157 | int GetFoldParent(int line); | |
158 | ||
159 | void Indent(bool forwards); | |
160 | int ExtendWordSelect(int pos, int delta); | |
161 | int NextWordStart(int pos, int delta); | |
162 | int Length() { return cb.Length(); } | |
163 | long FindText(int minPos, int maxPos, const char *s, bool caseSensitive, bool word); | |
164 | long FindText(WORD iMessage,WPARAM wParam,LPARAM lParam); | |
165 | int LinesTotal(); | |
166 | ||
f6bcfd97 BP |
167 | void ChangeCase(Range r, bool makeUpperCase); |
168 | ||
9ce192d4 RD |
169 | void SetWordChars(unsigned char *chars); |
170 | void SetStylingBits(int bits); | |
171 | void StartStyling(int position, char mask); | |
172 | void SetStyleFor(int length, char style); | |
173 | void SetStyles(int length, char *styles); | |
174 | int GetEndStyled() { return endStyled; } | |
f6bcfd97 | 175 | bool EnsureStyledTo(int pos); |
9ce192d4 RD |
176 | |
177 | int SetLineState(int line, int state) { return cb.SetLineState(line, state); } | |
178 | int GetLineState(int line) { return cb.GetLineState(line); } | |
179 | int GetMaxLineState() { return cb.GetMaxLineState(); } | |
180 | ||
181 | bool AddWatcher(DocWatcher *watcher, void *userData); | |
182 | bool RemoveWatcher(DocWatcher *watcher, void *userData); | |
183 | const WatcherWithUserData *GetWatchers() const { return watchers; } | |
184 | int GetLenWatchers() const { return lenWatchers; } | |
185 | ||
186 | private: | |
187 | bool IsDBCS(int pos); | |
188 | bool IsWordChar(unsigned char ch); | |
189 | bool IsWordAt(int start, int end); | |
190 | void ModifiedAt(int pos); | |
f6bcfd97 | 191 | |
9ce192d4 RD |
192 | void NotifyModifyAttempt(); |
193 | void NotifySavePoint(bool atSavePoint); | |
194 | void NotifyModified(DocModification mh); | |
f6bcfd97 BP |
195 | |
196 | int IndentSize() { return indentInChars ? indentInChars : tabInChars; } | |
9ce192d4 RD |
197 | }; |
198 | ||
199 | // To optimise processing of document modifications by DocWatchers, a hint is passed indicating the | |
200 | // scope of the change. | |
201 | // If the DocWatcher is a document view then this can be used to optimise screen updating. | |
202 | class DocModification { | |
203 | public: | |
204 | int modificationType; | |
205 | int position; | |
206 | int length; | |
207 | int linesAdded; // Negative if lines deleted | |
208 | const char *text; // Only valid for changes to text, not for changes to style | |
209 | int line; | |
210 | int foldLevelNow; | |
211 | int foldLevelPrev; | |
212 | ||
213 | DocModification(int modificationType_, int position_=0, int length_=0, | |
214 | int linesAdded_=0, const char *text_=0) : | |
215 | modificationType(modificationType_), | |
216 | position(position_), | |
217 | length(length_), | |
218 | linesAdded(linesAdded_), | |
219 | text(text_), | |
220 | line(0), | |
221 | foldLevelNow(0), | |
222 | foldLevelPrev(0) {} | |
f6bcfd97 BP |
223 | |
224 | DocModification(int modificationType_, const Action &act, int linesAdded_=0) : | |
225 | modificationType(modificationType_), | |
226 | position(act.position / 2), | |
227 | length(act.lenData), | |
228 | linesAdded(linesAdded_), | |
229 | text(act.data), | |
230 | line(0), | |
231 | foldLevelNow(0), | |
232 | foldLevelPrev(0) {} | |
9ce192d4 RD |
233 | }; |
234 | ||
235 | // A class that wants to receive notifications from a Document must be derived from DocWatcher | |
236 | // and implement the notification methods. It can then be added to the watcher list with AddWatcher. | |
237 | class DocWatcher { | |
238 | public: | |
239 | virtual ~DocWatcher() {} | |
240 | ||
241 | virtual void NotifyModifyAttempt(Document *doc, void *userData) = 0; | |
242 | virtual void NotifySavePoint(Document *doc, void *userData, bool atSavePoint) = 0; | |
243 | virtual void NotifyModified(Document *doc, DocModification mh, void *userData) = 0; | |
244 | virtual void NotifyDeleted(Document *doc, void *userData) = 0; | |
f6bcfd97 | 245 | virtual void NotifyStyleNeeded(Document *doc, void *userData, int endPos) = 0; |
9ce192d4 RD |
246 | }; |
247 | ||
248 | #endif |