1 // Scintilla source code edit control 
   3  ** Text document that handles notifications, DBCS, styling, words and end of line. 
   5 // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org> 
   6 // The License.txt file describes the conditions under which this software may be distributed. 
  12  * A Position is a position within a document between two characters or at the beginning or end. 
  13  * Sometimes used as a character index where it identifies the character after the position. 
  16 const Position invalidPosition 
= -1; 
  19  * The range class represents a range of text in a document. 
  20  * The two values are not sorted as one end may be more significant than the other 
  21  * as is the case for the selection where the end position is the position of the caret. 
  22  * If either position is invalidPosition then the range is invalid and most operations will fail. 
  29         Range(Position pos
=0) : 
  30                 start(pos
), end(pos
) { 
  32         Range(Position start_
, Position end_
) : 
  33                 start(start_
), end(end_
) { 
  37                 return (start 
!= invalidPosition
) && (end 
!= invalidPosition
); 
  40         // Is the position within the range? 
  41         bool Contains(Position pos
) const { 
  43                         return (pos 
>= start 
&& pos 
<= end
); 
  45                         return (pos 
<= start 
&& pos 
>= end
); 
  49         // Is the character after pos within the range? 
  50         bool ContainsCharacter(Position pos
) const { 
  52                         return (pos 
>= start 
&& pos 
< end
); 
  54                         return (pos 
< start 
&& pos 
>= end
); 
  58         bool Contains(Range other
) const { 
  59                 return Contains(other
.start
) && Contains(other
.end
); 
  62         bool Overlaps(Range other
) const { 
  64                 Contains(other
.start
) || 
  65                 Contains(other
.end
) || 
  66                 other
.Contains(start
) || 
  72 class DocModification
; 
  80         /** Used to pair watcher pointer with user data. */ 
  81         class WatcherWithUserData 
{ 
  85                 WatcherWithUserData() { 
  91         enum charClassification 
{ ccSpace
, ccNewLine
, ccWord
, ccPunctuation 
}; 
  96         charClassification charClass
[256]; 
 101         int enteredReadOnlyCount
; 
 103         WatcherWithUserData 
*watchers
; 
 115         /// Can also be SC_CP_UTF8 to enable UTF-8 mode 
 119         int actualIndentInChars
; 
 122         bool backspaceUnindents
; 
 130         int LineFromPosition(int pos
); 
 131         int ClampPositionIntoDocument(int pos
); 
 132         bool IsCrLf(int pos
); 
 133         int LenChar(int pos
); 
 134         int MovePositionOutsideChar(int pos
, int moveDir
, bool checkLineEnd
=true); 
 136         // Gateways to modifying document 
 137         void ModifiedAt(int pos
); 
 138         bool DeleteChars(int pos
, int len
); 
 139         bool InsertStyledString(int position
, char *s
, int insertLength
); 
 142         bool CanUndo() { return cb
.CanUndo(); } 
 143         bool CanRedo() { return cb
.CanRedo(); } 
 144         void DeleteUndoHistory() { cb
.DeleteUndoHistory(); } 
 145         bool SetUndoCollection(bool collectUndo
) { 
 146                 return cb
.SetUndoCollection(collectUndo
); 
 148         bool IsCollectingUndo() { return cb
.IsCollectingUndo(); } 
 149         void BeginUndoAction() { cb
.BeginUndoAction(); } 
 150         void EndUndoAction() { cb
.EndUndoAction(); } 
 152         bool IsSavePoint() { return cb
.IsSavePoint(); } 
 154         int GetLineIndentation(int line
); 
 155         void SetLineIndentation(int line
, int indent
); 
 156         int GetLineIndentPosition(int line
); 
 157         int GetColumn(int position
); 
 158         int FindColumn(int line
, int column
); 
 159         void Indent(bool forwards
, int lineBottom
, int lineTop
); 
 160         static char *TransformLineEnds(int *pLenOut
, const char *s
, size_t len
, int eolMode
); 
 161         void ConvertLineEnds(int eolModeSet
); 
 162         void SetReadOnly(bool set
) { cb
.SetReadOnly(set
); } 
 163         bool IsReadOnly() { return cb
.IsReadOnly(); } 
 165         bool InsertChar(int pos
, char ch
); 
 166         bool InsertString(int position
, const char *s
); 
 167         bool InsertString(int position
, const char *s
, size_t insertLength
); 
 168         void ChangeChar(int pos
, char ch
); 
 169         void DelChar(int pos
); 
 170         void DelCharBack(int pos
); 
 172         char CharAt(int position
) { return cb
.CharAt(position
); } 
 173         void GetCharRange(char *buffer
, int position
, int lengthRetrieve
) { 
 174                 cb
.GetCharRange(buffer
, position
, lengthRetrieve
); 
 176         char StyleAt(int position
) { return cb
.StyleAt(position
); } 
 177         int GetMark(int line
) { return cb
.GetMark(line
); } 
 178         int AddMark(int line
, int markerNum
); 
 179         void AddMarkSet(int line
, int valueSet
); 
 180         void DeleteMark(int line
, int markerNum
); 
 181         void DeleteMarkFromHandle(int markerHandle
); 
 182         void DeleteAllMarks(int markerNum
); 
 183         int LineFromHandle(int markerHandle
) { return cb
.LineFromHandle(markerHandle
); } 
 184         int LineStart(int line
); 
 185         int LineEnd(int line
); 
 186         int LineEndPosition(int position
); 
 187         int VCHomePosition(int position
); 
 189         int SetLevel(int line
, int level
); 
 190         int GetLevel(int line
) { return cb
.GetLevel(line
); } 
 191         void ClearLevels() { cb
.ClearLevels(); } 
 192         int GetLastChild(int lineParent
, int level
=-1); 
 193         int GetFoldParent(int line
); 
 195         void Indent(bool forwards
); 
 196         int ExtendWordSelect(int pos
, int delta
, bool onlyWordCharacters
=false); 
 197         int NextWordStart(int pos
, int delta
); 
 198         int NextWordEnd(int pos
, int delta
); 
 199         int Length() { return cb
.Length(); } 
 200         void Allocate(int newSize
) { cb
.Allocate(newSize
*2); } 
 201         long FindText(int minPos
, int maxPos
, const char *s
, 
 202                 bool caseSensitive
, bool word
, bool wordStart
, bool regExp
, bool posix
, int *length
); 
 203         long FindText(int iMessage
, unsigned long wParam
, long lParam
); 
 204         const char *SubstituteByPosition(const char *text
, int *length
); 
 207         void ChangeCase(Range r
, bool makeUpperCase
); 
 209         void SetDefaultCharClasses(bool includeWordClass
); 
 210         void SetCharClasses(const unsigned char *chars
, charClassification newCharClass
); 
 211         void SetStylingBits(int bits
); 
 212         void StartStyling(int position
, char mask
); 
 213         bool SetStyleFor(int length
, char style
); 
 214         bool SetStyles(int length
, char *styles
); 
 215         int GetEndStyled() { return endStyled
; } 
 216         bool EnsureStyledTo(int pos
); 
 217         int GetStyleClock() { return styleClock
; } 
 218         void IncrementStyleClock(); 
 220         int SetLineState(int line
, int state
) { return cb
.SetLineState(line
, state
); } 
 221         int GetLineState(int line
) { return cb
.GetLineState(line
); } 
 222         int GetMaxLineState() { return cb
.GetMaxLineState(); } 
 224         bool AddWatcher(DocWatcher 
*watcher
, void *userData
); 
 225         bool RemoveWatcher(DocWatcher 
*watcher
, void *userData
); 
 226         const WatcherWithUserData 
*GetWatchers() const { return watchers
; } 
 227         int GetLenWatchers() const { return lenWatchers
; } 
 229         bool IsWordPartSeparator(char ch
); 
 230         int WordPartLeft(int pos
); 
 231         int WordPartRight(int pos
); 
 232         int ExtendStyleRange(int pos
, int delta
, bool singleLine 
= false); 
 233         bool IsWhiteLine(int line
); 
 235         int ParaDown(int pos
); 
 236         int IndentSize() { return actualIndentInChars
; } 
 237         int BraceMatch(int position
, int maxReStyle
); 
 240         void CheckReadOnly(); 
 242         charClassification 
WordCharClass(unsigned char ch
); 
 243         bool IsWordStartAt(int pos
); 
 244         bool IsWordEndAt(int pos
); 
 245         bool IsWordAt(int start
, int end
); 
 247         void NotifyModifyAttempt(); 
 248         void NotifySavePoint(bool atSavePoint
); 
 249         void NotifyModified(DocModification mh
); 
 253  * To optimise processing of document modifications by DocWatchers, a hint is passed indicating the 
 254  * scope of the change. 
 255  * If the DocWatcher is a document view then this can be used to optimise screen updating. 
 257 class DocModification 
{ 
 259         int modificationType
; 
 262         int linesAdded
; /**< Negative if lines deleted. */ 
 263         const char *text
;       /**< Only valid for changes to text, not for changes to style. */ 
 268         DocModification(int modificationType_
, int position_
=0, int length_
=0, 
 269                 int linesAdded_
=0, const char *text_
=0, int line_
=0) : 
 270                 modificationType(modificationType_
), 
 273                 linesAdded(linesAdded_
), 
 279         DocModification(int modificationType_
, const Action 
&act
, int linesAdded_
=0) : 
 280                 modificationType(modificationType_
), 
 281                 position(act
.position
), 
 283                 linesAdded(linesAdded_
), 
 291  * A class that wants to receive notifications from a Document must be derived from DocWatcher 
 292  * and implement the notification methods. It can then be added to the watcher list with AddWatcher. 
 296         virtual ~DocWatcher() {} 
 298         virtual void NotifyModifyAttempt(Document 
*doc
, void *userData
) = 0; 
 299         virtual void NotifySavePoint(Document 
*doc
, void *userData
, bool atSavePoint
) = 0; 
 300         virtual void NotifyModified(Document 
*doc
, DocModification mh
, void *userData
) = 0; 
 301         virtual void NotifyDeleted(Document 
*doc
, void *userData
) = 0; 
 302         virtual void NotifyStyleNeeded(Document 
*doc
, void *userData
, int endPos
) = 0;