// Scintilla source code edit control /** @file CellBuffer.h ** Manages the text of the document. **/ // Copyright 1998-2004 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. #ifndef CELLBUFFER_H #define CELLBUFFER_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif // Interface to per-line data that wants to see each line insertion and deletion class PerLine { public: virtual ~PerLine() {} virtual void Init()=0; virtual void InsertLine(Sci::Line line)=0; virtual void RemoveLine(Sci::Line line)=0; }; /** * The line vector contains information about each of the lines in a cell buffer. */ class LineVector { Partitioning starts; PerLine *perLine; public: LineVector(); ~LineVector(); void Init(); void SetPerLine(PerLine *pl); void InsertText(Sci::Line line, Sci::Position delta); void InsertLine(Sci::Line line, Sci::Position position, bool lineStart); void SetLineStart(Sci::Line line, Sci::Position position); void RemoveLine(Sci::Line line); Sci::Line Lines() const { return starts.Partitions(); } Sci::Line LineFromPosition(Sci::Position pos) const; Sci::Position LineStart(Sci::Line line) const { return starts.PositionFromPartition(line); } }; enum actionType { insertAction, removeAction, startAction, containerAction }; /** * Actions are used to store all the information required to perform one undo/redo step. */ class Action { public: actionType at; Sci::Position position; char *data; Sci::Position lenData; bool mayCoalesce; Action(); ~Action(); void Create(actionType at_, Sci::Position position_=0, const char *data_=0, Sci::Position lenData_=0, bool mayCoalesce_=true); void Destroy(); void Grab(Action *source); }; /** * */ class UndoHistory { Action *actions; int lenActions; int maxAction; int currentAction; int undoSequenceDepth; int savePoint; int tentativePoint; void EnsureUndoRoom(); public: UndoHistory(); // Deleted so UndoHistory objects can not be copied UndoHistory(const UndoHistory &) = delete; ~UndoHistory(); const char *AppendAction(actionType at, Sci::Position position, const char *data, Sci::Position lengthData, bool &startSequence, bool mayCoalesce=true); void BeginUndoAction(); void EndUndoAction(); void DropUndoSequence(); void DeleteUndoHistory(); /// The save point is a marker in the undo stack where the container has stated that /// the buffer was saved. Undo and redo can move over the save point. void SetSavePoint(); bool IsSavePoint() const; // Tentative actions are used for input composition so that it can be undone cleanly void TentativeStart(); void TentativeCommit(); bool TentativeActive() const { return tentativePoint >= 0; } int TentativeSteps(); /// To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is /// called that many times. Similarly for redo. bool CanUndo() const; int StartUndo(); const Action &GetUndoStep() const; void CompletedUndoStep(); bool CanRedo() const; int StartRedo(); const Action &GetRedoStep() const; void CompletedRedoStep(); }; /** * Holder for an expandable array of characters that supports undo and line markers. * Based on article "Data Structures in a Bit-Mapped Text Editor" * by Wilfred J. Hansen, Byte January 1987, page 183. */ class CellBuffer { private: SplitVector substance; SplitVector style; bool readOnly; int utf8LineEnds; bool collectingUndo; UndoHistory uh; LineVector lv; bool UTF8LineEndOverlaps(Sci::Position position) const; void ResetLineEnds(); /// Actions without undo void BasicInsertString(Sci::Position position, const char *s, Sci::Position insertLength); void BasicDeleteChars(Sci::Position position, Sci::Position deleteLength); public: CellBuffer(); ~CellBuffer(); /// Retrieving positions outside the range of the buffer works and returns 0 char CharAt(Sci::Position position) const; void GetCharRange(char *buffer, Sci::Position position, Sci::Position lengthRetrieve) const; char StyleAt(Sci::Position position) const; void GetStyleRange(unsigned char *buffer, Sci::Position position, Sci::Position lengthRetrieve) const; const char *BufferPointer(); const char *RangePointer(Sci::Position position, Sci::Position rangeLength); Sci::Position GapPosition() const; Sci::Position Length() const; void Allocate(Sci::Position newSize); int GetLineEndTypes() const { return utf8LineEnds; } void SetLineEndTypes(int utf8LineEnds_); bool ContainsLineEnd(const char *s, Sci::Position length) const; void SetPerLine(PerLine *pl); Sci::Line Lines() const; Sci::Position LineStart(Sci::Line line) const; Sci::Line LineFromPosition(Sci::Position pos) const { return lv.LineFromPosition(pos); } void InsertLine(Sci::Line line, Sci::Position position, bool lineStart); void RemoveLine(Sci::Line line); const char *InsertString(Sci::Position position, const char *s, Sci::Position insertLength, bool &startSequence); /// Setting styles for positions outside the range of the buffer is safe and has no effect. /// @return true if the style of a character is changed. bool SetStyleAt(Sci::Position position, char styleValue); bool SetStyleFor(Sci::Position position, Sci::Position lengthStyle, char styleValue); const char *DeleteChars(Sci::Position position, Sci::Position deleteLength, bool &startSequence); bool IsReadOnly() const; void SetReadOnly(bool set); /// The save point is a marker in the undo stack where the container has stated that /// the buffer was saved. Undo and redo can move over the save point. void SetSavePoint(); bool IsSavePoint() const; void TentativeStart(); void TentativeCommit(); bool TentativeActive() const; int TentativeSteps(); bool SetUndoCollection(bool collectUndo); bool IsCollectingUndo() const; void BeginUndoAction(); void EndUndoAction(); void AddUndoAction(Sci::Position token, bool mayCoalesce); void DeleteUndoHistory(); /// To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is /// called that many times. Similarly for redo. bool CanUndo() const; int StartUndo(); const Action &GetUndoStep() const; void PerformUndoStep(); bool CanRedo() const; int StartRedo(); const Action &GetRedoStep() const; void PerformRedoStep(); }; #ifdef SCI_NAMESPACE } #endif #endif