// Scintilla source code edit control /** @file Editor.h ** Defines the main editor class. **/ // Copyright 1998-2011 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. #ifndef EDITOR_H #define EDITOR_H namespace Scintilla { /** */ class Timer { public: bool ticking; int ticksToWait; enum {tickSize = 100}; TickerID tickerID; Timer(); }; /** */ class Idler { public: bool state; IdlerID idlerID; Idler(); }; /** * When platform has a way to generate an event before painting, * accumulate needed styling range and other work items in * WorkNeeded to avoid unnecessary work inside paint handler */ class WorkNeeded { public: enum workItems { workNone=0, workStyle=1, workUpdateUI=2 }; enum workItems items; Sci::Position upTo; WorkNeeded() : items(workNone), upTo(0) {} void Reset() { items = workNone; upTo = 0; } void Need(workItems items_, Sci::Position pos) { if ((items_ & workStyle) && (upTo < pos)) upTo = pos; items = static_cast(items | items_); } }; /** * Hold a piece of text selected for copying or dragging, along with encoding and selection format information. */ class SelectionText { std::string s; public: bool rectangular; bool lineCopy; int codePage; int characterSet; SelectionText() : rectangular(false), lineCopy(false), codePage(0), characterSet(0) {} ~SelectionText() { } void Clear() { s.clear(); rectangular = false; lineCopy = false; codePage = 0; characterSet = 0; } void Copy(const std::string &s_, int codePage_, int characterSet_, bool rectangular_, bool lineCopy_) { s = s_; codePage = codePage_; characterSet = characterSet_; rectangular = rectangular_; lineCopy = lineCopy_; FixSelectionForClipboard(); } void Copy(const SelectionText &other) { Copy(other.s, other.codePage, other.characterSet, other.rectangular, other.lineCopy); } const char *Data() const { return s.c_str(); } size_t Length() const { return s.length(); } size_t LengthWithTerminator() const { return s.length() + 1; } bool Empty() const { return s.empty(); } private: void FixSelectionForClipboard() { // To avoid truncating the contents of the clipboard when pasted where the // clipboard contains NUL characters, replace NUL characters by spaces. std::replace(s.begin(), s.end(), '\0', ' '); } }; struct WrapPending { // The range of lines that need to be wrapped enum { lineLarge = 0x7ffffff }; Sci::Line start; // When there are wraps pending, will be in document range Sci::Line end; // May be lineLarge to indicate all of document after start WrapPending() { start = lineLarge; end = lineLarge; } void Reset() { start = lineLarge; end = lineLarge; } void Wrapped(Sci::Line line) { if (start == line) start++; } bool NeedsWrap() const { return start < end; } bool AddRange(Sci::Line lineStart, Sci::Line lineEnd) { const bool neededWrap = NeedsWrap(); bool changed = false; if (start > lineStart) { start = lineStart; changed = true; } if ((end < lineEnd) || !neededWrap) { end = lineEnd; changed = true; } return changed; } }; /** */ class Editor : public EditModel, public DocWatcher { protected: // ScintillaBase subclass needs access to much of Editor /** On GTK+, Scintilla is a container widget holding two scroll bars * whereas on Windows there is just one window with both scroll bars turned on. */ Window wMain; ///< The Scintilla parent window Window wMargin; ///< May be separate when using a scroll view for wMain /** Style resources may be expensive to allocate so are cached between uses. * When a style attribute is changed, this cache is flushed. */ bool stylesValid; ViewStyle vs; int technology; Point sizeRGBAImage; float scaleRGBAImage; MarginView marginView; EditView view; int cursorMode; bool hasFocus; bool mouseDownCaptures; bool mouseWheelCaptures; int xCaretMargin; ///< Ensure this many pixels visible on both sides of caret bool horizontalScrollBarVisible; int scrollWidth; bool verticalScrollBarVisible; bool endAtLastLine; int caretSticky; int marginOptions; bool mouseSelectionRectangularSwitch; bool multipleSelection; bool additionalSelectionTyping; int multiPasteMode; int virtualSpaceOptions; KeyMap kmap; Timer timer; Timer autoScrollTimer; enum { autoScrollDelay = 200 }; Idler idler; Point lastClick; unsigned int lastClickTime; Point doubleClickCloseThreshold; int dwellDelay; int ticksToDwell; bool dwelling; enum { selChar, selWord, selSubLine, selWholeLine } selectionType; Point ptMouseLast; enum { ddNone, ddInitial, ddDragging } inDragDrop; bool dropWentOutside; SelectionPosition posDrop; Sci::Position hotSpotClickPos; int lastXChosen; Sci::Position lineAnchorPos; Sci::Position originalAnchorPos; Sci::Position wordSelectAnchorStartPos; Sci::Position wordSelectAnchorEndPos; Sci::Position wordSelectInitialCaretPos; Sci::Position targetStart; Sci::Position targetEnd; int searchFlags; Sci::Line topLine; Sci::Position posTopLine; Sci::Position lengthForEncode; int needUpdateUI; enum { notPainting, painting, paintAbandoned } paintState; bool paintAbandonedByStyling; PRectangle rcPaint; bool paintingAllText; bool willRedrawAll; WorkNeeded workNeeded; int idleStyling; bool needIdleStyling; int modEventMask; SelectionText drag; int caretXPolicy; int caretXSlop; ///< Ensure this many pixels visible on both sides of caret int caretYPolicy; int caretYSlop; ///< Ensure this many lines visible on both sides of caret int visiblePolicy; int visibleSlop; Sci::Position searchAnchor; bool recordingMacro; int foldAutomatic; // Wrapping support WrapPending wrapPending; bool convertPastes; Editor(); // Deleted so Editor objects can not be copied. explicit Editor(const Editor &) = delete; Editor &operator=(const Editor &) = delete; ~Editor() override; virtual void Initialise() = 0; virtual void Finalise(); void InvalidateStyleData(); void InvalidateStyleRedraw(); void RefreshStyleData(); void SetRepresentations(); void DropGraphics(bool freeObjects); void AllocateGraphics(); // The top left visible point in main window coordinates. Will be 0,0 except for // scroll views where it will be equivalent to the current scroll position. virtual Point GetVisibleOriginInMain() const override; PointDocument DocumentPointFromView(Point ptView) const; // Convert a point from view space to document Sci::Line TopLineOfMain() const override; // Return the line at Main's y coordinate 0 virtual PRectangle GetClientRectangle() const; virtual PRectangle GetClientDrawingRectangle(); PRectangle GetTextRectangle() const; virtual Sci::Line LinesOnScreen() const override; Sci::Line LinesToScroll() const; Sci::Line MaxScrollPos() const; SelectionPosition ClampPositionIntoDocument(SelectionPosition sp) const; Point LocationFromPosition(SelectionPosition pos, PointEnd pe=peDefault); Point LocationFromPosition(Sci::Position pos, PointEnd pe=peDefault); int XFromPosition(Sci::Position pos); int XFromPosition(SelectionPosition sp); SelectionPosition SPositionFromLocation(Point pt, bool canReturnInvalid=false, bool charPosition=false, bool virtualSpace=true); Sci::Position PositionFromLocation(Point pt, bool canReturnInvalid = false, bool charPosition = false); SelectionPosition SPositionFromLineX(Sci::Line lineDoc, int x); Sci::Position PositionFromLineX(Sci::Line lineDoc, int x); Sci::Line LineFromLocation(Point pt) const; void SetTopLine(Sci::Line topLineNew); virtual bool AbandonPaint(); virtual void RedrawRect(PRectangle rc); virtual void DiscardOverdraw(); virtual void Redraw(); void RedrawSelMargin(Sci::Line line=-1, bool allAfter=false); PRectangle RectangleFromRange(Range r, int overlap); void InvalidateRange(Sci::Position start, Sci::Position end); bool UserVirtualSpace() const { return ((virtualSpaceOptions & SCVS_USERACCESSIBLE) != 0); } Sci::Position CurrentPosition() const; bool SelectionEmpty() const; SelectionPosition SelectionStart(); SelectionPosition SelectionEnd(); void SetHTTP/1.1 200 OK Connection: keep-alive Connection: keep-alive Connection: keep-alive Content-Disposition: inline; filename="Editor.h" Content-Disposition: inline; filename="Editor.h" Content-Disposition: inline; filename="Editor.h" Content-Length: 21986 Content-Length: 21986 Content-Length: 21986 Content-Security-Policy: default-src 'none' Content-Security-Policy: default-src 'none' Content-Security-Policy: default-src 'none' Content-Type: text/plain; charset=UTF-8 Content-Type: text/plain; charset=UTF-8 Content-Type: text/plain; charset=UTF-8 Date: Sun, 28 Dec 2025 15:10:10 UTC ETag: "44255016a3993ff2fd0319fea2d7b5224e5a9857" ETag: "44255016a3993ff2fd0319fea2d7b5224e5a9857" ETag: "44255016a3993ff2fd0319fea2d7b5224e5a9857" Expires: Wed, 26 Dec 2035 15:10:10 GMT Expires: Wed, 26 Dec 2035 15:10:10 GMT Expires: Wed, 26 Dec 2035 15:10:10 GMT Last-Modified: Sun, 28 Dec 2025 15:10:10 GMT Last-Modified: Sun, 28 Dec 2025 15:10:10 GMT Last-Modified: Sun, 28 Dec 2025 15:10:10 GMT Server: OpenBSD httpd Server: OpenBSD httpd Server: OpenBSD httpd X-Content-Type-Options: nosniff X-Content-Type-Options: nosniff X-Content-Type-Options: nosniff // Scintilla source code edit control /** @file Editor.h ** Defines the main editor class. **/ // Copyright 1998-2011 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. #ifndef EDITOR_H #define EDITOR_H namespace Scintilla { /** */ class Timer { public: bool ticking; int ticksToWait; enum {tickSize = 100}; TickerID tickerID; Timer(); }; /** */ class Idler { public: bool state; IdlerID idlerID; Idler(); }; /** * When platform has a way to generate an event before painting, * accumulate needed styling range and other work items in * WorkNeeded to avoid unnecessary work inside paint handler */ class WorkNeeded { public: enum workItems { workNone=0, workStyle=1, workUpdateUI=2 }; enum workItems items; Sci::Position upTo; WorkNeeded() : items(workNone), upTo(0) {} void Reset() { items = workNone; upTo = 0; } void Need(workItems items_, Sci::Position pos) { if ((items_ & workStyle) && (upTo < pos)) upTo = pos; items = static_cast(items | items_); } }; /** * Hold a piece of text selected for copying or dragging, along with encoding and selection format information. */ class SelectionText { std::string s; public: bool rectangular; bool lineCopy; int codePage; int characterSet; SelectionText() : rectangular(false), lineCopy(false), codePage(0), characterSet(0) {} ~SelectionText() { } void Clear() { s.clear(); rectangular = false; lineCopy = false; codePage = 0; characterSet = 0; } void Copy(const std::string &s_, int codePage_, int characterSet_, bool rectangular_, bool lineCopy_) { s = s_; codePage = codePage_; characterSet = characterSet_; rectangular = rectangular_; lineCopy = lineCopy_; FixSelectionForClipboard(); } void Copy(const SelectionText &other) { Copy(other.s, other.codePage, other.characterSet, other.rectangular, other.lineCopy); } const char *Data() const { return s.c_str(); } size_t Length() const { return s.length(); } size_t LengthWithTerminator() const { return s.length() + 1; } bool Empty() const { return s.empty(); } private: void FixSelectionForClipboard() { // To avoid truncating the contents of the clipboard when pasted where the // clipboard contains NUL characters, replace NUL characters by spaces. std::replace(s.begin(), s.end(), '\0', ' '); } }; struct WrapPending { // The range of lines that need to be wrapped enum { lineLarge = 0x7ffffff }; Sci::Line start; // When there are wraps pending, will be in document range Sci::Line end; // May be lineLarge to indicate all of document after start WrapPending() { start = lineLarge; end = lineLarge; } void Reset() { start = lineLarge; end = lineLarge; } void Wrapped(Sci::Line line) { if (start == line) start++; } bool NeedsWrap() const { return start < end; } bool AddRange(Sci::Line lineStart, Sci::Line lineEnd) { const bool neededWrap = NeedsWrap(); bool changed = false; if (start > lineStart) { start = lineStart; changed = true; } if ((end < lineEnd) || !neededWrap) { end = lineEnd; changed = true; } return changed; } }; /** */ class Editor : public EditModel, public DocWatcher { protected: // ScintillaBase subclass needs access to much of Editor /** On GTK+, Scintilla is a container widget holding two scroll bars * whereas on Windows there is just one window with both scroll bars turned on. */ Window wMain; ///< The Scintilla parent window Window wMargin; ///< May be separate when using a scroll view for wMain /** Style resources may be expensive to allocate so are cached between uses. * When a style attribute is changed, this cache is flushed. */ bool stylesValid; ViewStyle vs; int technology; Point sizeRGBAImage; float scaleRGBAImage; MarginView marginView; EditView view; int cursorMode; bool hasFocus; bool mouseDownCaptures; bool mouseWheelCaptures; int xCaretMargin; ///< Ensure this many pixels visible on both sides of caret bool horizontalScrollBarVisible; int scrollWidth; bool verticalScrollBarVisible; bool endAtLastLine; int caretSticky; int marginOptions; bool mouseSelectionRectangularSwitch; bool multipleSelection; bool additionalSelectionTyping; int multiPasteMode; int virtualSpaceOptions; KeyMap kmap; Timer timer; Timer autoScrollTimer; enum { autoScrollDelay = 200 }; Idler idler; Point lastClick; unsigned int lastClickTime; Point doubleClickCloseThreshold; int dwellDelay; int ticksToDwell; bool dwelling; enum { selChar, selWord, selSubLine, selWholeLine } selectionType; Point ptMouseLast; enum { ddNone, ddInitial, ddDragging } inDragDrop; bool dropWentOutside; SelectionPosition posDrop; Sci::Position hotSpotClickPos; int lastXChosen; Sci::Position lineAnchorPos; Sci::Position originalAnchorPos; Sci::Position wordSelectAnchorStartPos; Sci::Position wordSelectAnchorEndPos; Sci::Position wordSelectInitialCaretPos; Sci::Position targetStart; Sci::Position targetEnd; int searchFlags; Sci::Line topLine; Sci::Position posTopLine; Sci::Position lengthForEncode; int needUpdateUI; enum { notPainting, painting, paintAbandoned } paintState; bool paintAbandonedByStyling; PRectangle rcPaint; bool paintingAllText; bool willRedrawAll; WorkNeeded workNeeded; int idleStyling; bool needIdleStyling; int modEventMask; SelectionText drag; int caretXPolicy; int caretXSlop; ///< Ensure this many pixels visible on both sides of caret int caretYPolicy; int caretYSlop; ///< Ensure this many lines visible on both sides of caret int visiblePolicy; int visibleSlop; Sci::Position searchAnchor; bool recordingMacro; int foldAutomatic; // Wrapping support WrapPending wrapPending; bool convertPastes; Editor(); // Deleted so Editor objects can not be copied. explicit Editor(const Editor &) = delete; Editor &operator=(const Editor &) = delete; ~Editor() override; virtual void Initialise() = 0; virtual void Finalise(); void InvalidateStyleData(); void InvalidateStyleRedraw(); void RefreshStyleData(); void SetRepresentations(); void DropGraphics(bool freeObjects); void AllocateGraphics(); // The top left visible point in main window coordinates. Will be 0,0 except for // scroll views where it will be equivalent to the current scroll position. virtual Point GetVisibleOriginInMain() const override; PointDocument DocumentPointFromView(Point ptView) const; // Convert a point from view space to document Sci::Line TopLineOfMain() const override; // Return the line at Main's y coordinate 0 virtual PRectangle GetClientRectangle() const; virtual PRectangle GetClientDrawingRectangle(); PRectangle GetTextRectangle() const; virtual Sci::Line LinesOnScreen() const override; Sci::Line LinesToScroll() const; Sci::Line MaxScrollPos() const; SelectionPosition ClampPositionIntoDocument(SelectionPosition sp) const; Point LocationFromPosition(SelectionPosition pos, PointEnd pe=peDefault); Point LocationFromPosition(Sci::Position pos, PointEnd pe=peDefault); int XFromPosition(Sci::Position pos); int XFromPosition(SelectionPosition sp); SelectionPosition SPositionFromLocation(Point pt, bool canReturnInvalid=false, bool charPosition=false, bool virtualSpace=true); Sci::Position PositionFromLocation(Point pt, bool canReturnInvalid = false, bool charPosition = false); SelectionPosition SPositionFromLineX(Sci::Line lineDoc, int x); Sci::Position PositionFromLineX(Sci::Line lineDoc, int x); Sci::Line LineFromLocation(Point pt) const; void SetTopLine(Sci::Line topLineNew); virtual bool AbandonPaint(); virtual void RedrawRect(PRectangle rc); virtual void DiscardOverdraw(); virtual void Redraw(); void RedrawSelMargin(Sci::Line line=-1, bool allAfter=false); PRectangle RectangleFromRange(Range r, int overlap); void InvalidateRange(Sci::Position start, Sci::Position end); bool UserVirtualSpace() const { return ((virtualSpaceOptions & SCVS_USERACCESSIBLE) != 0); } Sci::Position CurrentPosition() const; bool SelectionEmpty() const; SelectionPosition SelectionStart(); SelectionPosition SelectionEnd(); void SetRectangularRange(); void ThinRectangularRange(); void InvalidateSelection(SelectionRange newMain, bool invalidateWholeSelection=false); void InvalidateWholeSelection(); SelectionRange LineSelectionRange(SelectionPosition currentPos_, SelectionPosition anchor_) const; void SetSelection(SelectionPosition currentPos_, SelectionPosition anchor_); void SetSelection(Sci::Position currentPos_, Sci::Position anchor_); void SetSelection(SelectionPosition currentPos_); void SetSelection(int currentPos_); void SetEmptySelection(SelectionPosition currentPos_); void SetEmptySelection(Sci::Position currentPos_); enum AddNumber { addOne, addEach }; void MultipleSelectAdd(AddNumber addNumber); bool RangeContainsProtected(Sci::Position start, Sci::Position end) const; bool SelectionContainsProtected(); Sci::Position MovePositionOutsideChar(Sci::Position pos, Sci::Position moveDir, bool checkLineEnd=true) const; SelectionPosition MovePositionOutsideChar(SelectionPosition pos, Sci::Position moveDir, bool checkLineEnd=true) const; void MovedCaret(SelectionPosition newPos, SelectionPosition previousPos, bool ensureVisible); void MovePositionTo(SelectionPosition newPos, Selection::selTypes selt=Selection::noSel, bool ensureVisible=true); void MovePositionTo(Sci::Position newPos, Selection::selTypes selt=Selection::noSel, bool ensureVisible=true); SelectionPosition MovePositionSoVisible(SelectionPosition pos, int moveDir); SelectionPosition MovePositionSoVisible(Sci::Position pos, int moveDir); Point PointMainCaret(); void SetLastXChosen(); void ScrollTo(Sci::Line line, bool moveThumb=true); virtual void ScrollText(Sci::Line linesToMove); void HorizontalScrollTo(int xPos); void VerticalCentreCaret(); void MoveSelectedLines(int lineDelta); void MoveSelectedLinesUp(); void MoveSelectedLinesDown(); void MoveCaretInsideView(bool ensureVisible=true); Sci::Line DisplayFromPosition(Sci::Position pos); struct XYScrollPosition { int xOffset; Sci::Line topLine; XYScrollPosition(int xOffset_, Sci::Line topLine_) : xOffset(xOffset_), topLine(topLine_) {} bool operator==(const XYScrollPosition &other) const { return (xOffset == other.xOffset) && (topLine == other.topLine); } }; enum XYScrollOptions { xysUseMargin=0x1, xysVertical=0x2, xysHorizontal=0x4, xysDefault=xysUseMargin|xysVertical|xysHorizontal}; XYScrollPosition XYScrollToMakeVisible(const SelectionRange &range, const XYScrollOptions options); void SetXYScroll(XYScrollPosition newXY); void EnsureCaretVisible(bool useMargin=true, bool vert=true, bool horiz=true); void ScrollRange(SelectionRange range); void ShowCaretAtCurrentPosition(); void DropCaret(); void CaretSetPeriod(int period); void InvalidateCaret(); virtual void NotifyCaretMove(); virtual void UpdateSystemCaret(); bool Wrapping() const; void NeedWrapping(Sci::Line docLineStart=0, Sci::Line docLineEnd=WrapPending::lineLarge); bool WrapOneLine(Surface *surface, Sci::Line lineToWrap); enum class WrapScope {wsAll, wsVisible, wsIdle}; bool WrapLines(WrapScope ws); void LinesJoin(); void LinesSplit(int pixelWidth); void PaintSelMargin(Surface *surfaceWindow, PRectangle &rc); void RefreshPixMaps(Surface *surfaceWindow); void Paint(Surface *surfaceWindow, PRectangle rcArea); long FormatRange(bool draw, Sci_RangeToFormat *pfr); int TextWidth(int style, const char *text); virtual void SetVerticalScrollPos() = 0; virtual void SetHorizontalScrollPos() = 0; virtual bool ModifyScrollBars(Sci::Line nMax, Sci::Line nPage) = 0; virtual void ReconfigureScrollBars(); void SetScrollBars(); void ChangeSize(); void FilterSelections(); Sci::Position RealizeVirtualSpace(Sci::Position position, Sci::Position virtualSpace); SelectionPosition RealizeVirtualSpace(const SelectionPosition &position); void AddChar(char ch); virtual void AddCharUTF(const char *s, unsigned int len, bool treatAsDBCS=false); void ClearBeforeTentativeStart(); void InsertPaste(const char *text, int len); enum PasteShape { pasteStream=0, pasteRectangular = 1, pasteLine = 2 }; void InsertPasteShape(const char *text, int len, PasteShape shape); void ClearSelection(bool retainMultipleSelections = false); void ClearAll(); void ClearDocumentStyle(); virtual void Cut(); void PasteRectangular(SelectionPosition pos, const char *ptr, Sci::Position len); virtual void Copy() = 0; virtual void CopyAllowLine(); virtua