1// Scintilla source code edit control
2/** @file Editor.h
3 ** Defines the main editor class.
4 **/
5// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
6// The License.txt file describes the conditions under which this software may be distributed.
7
8#ifndef EDITOR_H
9#define EDITOR_H
10
11namespace Scintilla::Internal {
12
13/**
14 */
15class Timer {
16public:
17 bool ticking;
18 int ticksToWait;
19 enum {tickSize = 100};
20 TickerID tickerID;
21
22 Timer() noexcept;
23};
24
25/**
26 */
27class Idler {
28public:
29 bool state;
30 IdlerID idlerID;
31
32 Idler() noexcept;
33};
34
35/**
36 * When platform has a way to generate an event before painting,
37 * accumulate needed styling range and other work items in
38 * WorkNeeded to avoid unnecessary work inside paint handler
39 */
40
41enum class WorkItems {
42 none = 0,
43 style = 1,
44 updateUI = 2
45};
46
47class WorkNeeded {
48public:
49 enum WorkItems items;
50 Sci::Position upTo;
51
52 WorkNeeded() noexcept : items(WorkItems::none), upTo(0) {}
53 void Reset() noexcept {
54 items = WorkItems::none;
55 upTo = 0;
56 }
57 void Need(WorkItems items_, Sci::Position pos) noexcept {
58 if (Scintilla::FlagSet(items_, WorkItems::style) && (upTo < pos))
59 upTo = pos;
60 items = static_cast<WorkItems>(static_cast<int>(items) | static_cast<int>(items_));
61 }
62};
63
64/**
65 * Hold a piece of text selected for copying or dragging, along with encoding and selection format information.
66 */
67class SelectionText {
68 std::string s;
69public:
70 bool rectangular;
71 bool lineCopy;
72 int codePage;
73 Scintilla::CharacterSet characterSet;
74 SelectionText() noexcept : rectangular(false), lineCopy(false), codePage(0), characterSet(Scintilla::CharacterSet::Ansi) {}
75 void Clear() noexcept {
76 s.clear();
77 rectangular = false;
78 lineCopy = false;
79 codePage = 0;
80 characterSet = Scintilla::CharacterSet::Ansi;
81 }
82 void Copy(const std::string &s_, int codePage_, Scintilla::CharacterSet characterSet_, bool rectangular_, bool lineCopy_) {
83 s = s_;
84 codePage = codePage_;
85 characterSet = characterSet_;
86 rectangular = rectangular_;
87 lineCopy = lineCopy_;
88 FixSelectionForClipboard();
89 }
90 void Copy(const SelectionText &other) {
91 Copy(other.s, other.codePage, other.characterSet, other.rectangular, other.lineCopy);
92 }
93 const char *Data() const noexcept {
94 return s.c_str();
95 }
96 size_t Length() const noexcept {
97 return s.length();
98 }
99 size_t LengthWithTerminator() const noexcept {
100 return s.length() + 1;
101 }
102 bool Empty() const noexcept {
103 return s.empty();
104 }
105private:
106 void FixSelectionForClipboard() {
107 // To avoid truncating the contents of the clipboard when pasted where the
108 // clipboard contains NUL characters, replace NUL characters by spaces.
109 std::replace(s.begin(), s.end(), '\0', ' ');
110 }
111};
112
113struct WrapPending {
114 // The range of lines that need to be wrapped
115 enum { lineLarge = 0x7ffffff };
116 Sci::Line start; // When there are wraps pending, will be in document range
117 Sci::Line end; // May be lineLarge to indicate all of document after start
118 WrapPending() noexcept {
119 start = lineLarge;
120 end = lineLarge;
121 }
122 void Reset() noexcept {
123 start = lineLarge;
124 end = lineLarge;
125 }
126 void Wrapped(Sci::Line line) noexcept {
127 if (start == line)
128 start++;
129 }
130 bool NeedsWrap() const noexcept {
131 return start < end;
132 }
133 bool AddRange(Sci::Line lineStart, Sci::Line lineEnd) noexcept {
134 const bool neededWrap = NeedsWrap();
135 bool changed = false;
136 if (start > lineStart) {
137 start = lineStart;
138 changed = true;
139 }
140 if ((end < lineEnd) || !neededWrap) {
141 end = lineEnd;
142 changed = true;
143 }
144 return changed;
145 }
146};
147
148struct CaretPolicySlop {
149 Scintilla::CaretPolicy policy; // Combination from CaretPolicy::Slop, CaretPolicy::Strict, CaretPolicy::Jumps, CaretPolicy::Even
150 int slop; // Pixels for X, lines for Y
151 CaretPolicySlop(Scintilla::CaretPolicy policy_, intptr_t slop_) noexcept :
152 policy(policy_), slop(static_cast<int>(slop_)) {}
153 CaretPolicySlop(uintptr_t policy_=0, intptr_t slop_=0) noexcept :
154 policy(static_cast<Scintilla::CaretPolicy>(policy_)), slop(static_cast<int>(slop_)) {}
155};
156
157struct CaretPolicies {
158 CaretPolicySlop x;
159 CaretPolicySlop y;
160};
161
162struct VisiblePolicySlop {
163 Scintilla::VisiblePolicy policy; // Combination from VisiblePolicy::Slop, VisiblePolicy::Strict
164 int slop; // Pixels for X, lines for Y
165 VisiblePolicySlop(uintptr_t policy_ = 0, intptr_t slop_ = 0) noexcept :
166 policy(static_cast<Scintilla::VisiblePolicy>(policy_)), slop(static_cast<int>(slop_)) {}
167};
168
169enum class XYScrollOptions {
170 none = 0x0,
171 useMargin = 0x1,
172 vertical = 0x2,
173 horizontal = 0x4,
174 all = useMargin | vertical | horizontal
175};
176
177constexpr XYScrollOptions operator|(XYScrollOptions a, XYScrollOptions b) noexcept {
178 return static_cast<XYScrollOptions>(static_cast<int>(a) | static_cast<int>(b));
179}
180
181/**
182 */
183class Editor : public EditModel, public DocWatcher {
184protected: // ScintillaBase subclass needs access to much of Editor
185
186 /** On GTK+, Scintilla is a container widget holding two scroll bars
187 * whereas on Windows there is just one window with both scroll bars turned on. */
188 Window wMain; ///< The Scintilla parent window
189 Window wMargin; ///< May be separate when using a scroll view for wMain
190
191 // Optimization that avoids superfluous invalidations
192 bool redrawPendingText = false;
193 bool redrawPendingMargin = false;
194
195 /** Style resources may be expensive to allocate so are cached between uses.
196 * When a style attribute is changed, this cache is flushed. */
197 bool stylesValid;
198 ViewStyle vs;
199 Scintilla::Technology technology;
200 Point sizeRGBAImage;
201 float scaleRGBAImage;
202
203 MarginView marginView;
204 EditView view;
205
206 Scintilla::CursorShape cursorMode;
207
208 bool mouseDownCaptures;
209 bool mouseWheelCaptures;
210
211 int xCaretMargin; ///< Ensure this many pixels visible on both sides of caret
212 bool horizontalScrollBarVisible;
213 int scrollWidth;
214 bool verticalScrollBarVisible;
215 bool endAtLastLine;
216 Scintilla::CaretSticky caretSticky;
217 Scintilla::MarginOption marginOptions;
218 bool mouseSelectionRectangularSwitch;
219 bool multipleSelection;
220 bool additionalSelectionTyping;
221 Scintilla::MultiPaste multiPasteMode;
222
223 Scintilla::VirtualSpace virtualSpaceOptions;
224
225 KeyMap kmap;
226
227 Timer timer;
228 Timer autoScrollTimer;
229 enum { autoScrollDelay = 200 };
230
231 Idler idler;
232
233 Point lastClick;
234 unsigned int lastClickTime;
235 Point doubleClickCloseThreshold;
236 int dwellDelay;
237 int ticksToDwell;
238 bool dwelling;
239 enum class TextUnit { character, word, subLine, wholeLine } selectionUnit;
240 Point ptMouseLast;
241 enum class DragDrop { none, initial, dragging } inDragDrop;
242 bool dropWentOutside;
243 SelectionPosition posDrop;
244 Sci::Position hotSpotClickPos;
245 int lastXChosen;
246 Sci::Position lineAnchorPos;
247 Sci::Position originalAnchorPos;
248 Sci::Position wordSelectAnchorStartPos;
249 Sci::Position wordSelectAnchorEndPos;
250 Sci::Position wordSelectInitialCaretPos;
251 SelectionSegment targetRange;
252 Scintilla::FindOption searchFlags;
253 Sci::Line topLine;
254 Sci::Position posTopLine;
255 Sci::Position lengthForEncode;
256
257 Scintilla::Update needUpdateUI;
258
259 enum class PaintState { notPainting, painting, abandoned } paintState;
260 bool paintAbandonedByStyling;
261 PRectangle rcPaint;
262 bool paintingAllText;
263 bool willRedrawAll;
264 WorkNeeded workNeeded;
265 Scintilla::IdleStyling idleStyling;
266 bool needIdleStyling;
267
268 Scintilla::ModificationFlags modEventMask;
269 bool commandEvents;
270
271 SelectionText drag;
272
273 CaretPolicies caretPolicies;
274
275 VisiblePolicySlop visiblePolicy;
276
277 Sci::Position searchAnchor;
278
279 bool recordingMacro;
280
281 Scintilla::AutomaticFold foldAutomatic;
282
283 // Wrapping support
284 WrapPending wrapPending;
285 ActionDuration durationWrapOneByte;
286
287 bool convertPastes;
288
289 Editor();
290 // Deleted so Editor objects can not be copied.
291 Editor(const Editor &) = delete;
292 Editor(Editor &&) = delete;
293 Editor &operator=(const Editor &) = delete;
294 Editor &operator=(Editor &&) = delete;
295 // ~Editor() in public section
296 virtual void Initialise() = 0;
297 virtual void Finalise();
298
299 void InvalidateStyleData();
300 void InvalidateStyleRedraw();
301 void RefreshStyleData();
302 void SetRepresentations();
303 void DropGraphics() noexcept;
304
305 // The top left visible point in main window coordinates. Will be 0,0 except for
306 // scroll views where it will be equivalent to the current scroll position.
307 Point GetVisibleOriginInMain() const override;
308 PointDocument DocumentPointFromView(Point ptView) const; // Convert a point from view space to document
309 Sci::Line TopLineOfMain() const override; // Return the line at Main's y coordinate 0
310 virtual PRectangle GetClientRectangle() const;
311 virtual PRectangle GetClientDrawingRectangle();
312 PRectangle GetTextRectangle() const;
313
314 Sci::Line LinesOnScreen() const override;
315 Sci::Line LinesToScroll() const;
316 Sci::Line MaxScrollPos() const;
317 SelectionPosition ClampPositionIntoDocument(SelectionPosition sp) const;
318 Point LocationFromPosition(SelectionPosition pos, PointEnd pe=PointEnd::start);
319 Point LocationFromPosition(Sci::Position pos, PointEnd pe=PointEnd::start);
320 int XFromPosition(SelectionPosition sp);
321 SelectionPosition SPositionFromLocation(Point pt, bool canReturnInvalid=false, bool charPosition=false, bool virtualSpace=true);
322 Sci::Position PositionFromLocation(Point pt, bool canReturnInvalid = false, bool charPosition = false);
323 SelectionPosition SPositionFromLineX(Sci::Line lineDoc, int x);
324 Sci::Position PositionFromLineX(Sci::Line lineDoc, int x);
325 Sci::Line LineFromLocation(Point pt) const;
326 void SetTopLine(Sci::Line topLineNew);
327
328 virtual bool AbandonPaint();
329 virtual void RedrawRect(PRectangle rc);
330 virtual void DiscardOverdraw();
331 virtual void Redraw();
332 void RedrawSelMargin(Sci::Line line=-1, bool allAfter=false);
333 PRectangle RectangleFromRange(Range r, int overlap);
334 void InvalidateRange(Sci::Position start, Sci::Position end);
335
336 bool UserVirtualSpace() const noexcept {
337 return (FlagSet(virtualSpaceOptions, Scintilla::VirtualSpace::UserAccessible));
338 }
339 Sci::Position CurrentPosition() const;
340 bool SelectionEmpty() const noexcept;
341 SelectionPosition SelectionStart();
342 SelectionPosition SelectionEnd();
343 void SetRectangularRange();
344 void ThinRectangularRange();
345 void InvalidateSelection(SelectionRange newMain, bool invalidateWholeSelection=false);
346 void InvalidateWholeSelection();
347 SelectionRange LineSelectionRange(SelectionPosition currentPos_, SelectionPosition anchor_) const;
348 void SetSelection(SelectionPosition currentPos_, SelectionPosition anchor_);
349 void SetSelection(Sci::Position currentPos_, Sci::Position anchor_);
350 void SetSelection(SelectionPosition currentPos_);
351 void SetEmptySelection(SelectionPosition currentPos_);
352 void SetEmptySelection(Sci::Position currentPos_);
353 enum class AddNumber { one, each };
354 void MultipleSelectAdd(AddNumber addNumber);
355 bool RangeContainsProtected(Sci::Position start, Sci::Position end) const noexcept;
356 bool SelectionContainsProtected() const;
357 Sci::Position MovePositionOutsideChar(Sci::Position pos, Sci::Position moveDir, bool checkLineEnd=true) const;
358 SelectionPosition MovePositionOutsideChar(SelectionPosition pos, Sci::Position moveDir, bool checkLineEnd=true) const;
359 void MovedCaret(SelectionPosition newPos, SelectionPosition previousPos,
360 bool ensureVisible, CaretPolicies policies);
361 void MovePositionTo(SelectionPosition newPos, Selection::SelTypes selt=Selection::SelTypes::none, bool ensureVisible=true);
362 void MovePositionTo(Sci::Position newPos, Selection::SelTypes selt=Selection::SelTypes::none, bool ensureVisible=true);
363 SelectionPosition MovePositionSoVisible(SelectionPosition pos, int moveDir);
364 SelectionPosition MovePositionSoVisible(Sci::Position pos, int moveDir);
365 Point PointMainCaret();
366 void SetLastXChosen();
367
368 void ScrollTo(Sci::Line line, bool moveThumb=true);
369 virtual void ScrollText(Sci::Line linesToMove);
370 void HorizontalScrollTo(int xPos);
371 void VerticalCentreCaret();
372 void MoveSelectedLines(int lineDelta);
373 void MoveSelectedLinesUp();
374 void MoveSelectedLinesDown();
375 void MoveCaretInsideView(bool ensureVisible=true);
376 Sci::Line DisplayFromPosition(Sci::Position pos);
377
378 struct XYScrollPosition {
379 int xOffset;
380 Sci::Line topLine;
381 XYScrollPosition(int xOffset_, Sci::Line topLine_) noexcept : xOffset(xOffset_), topLine(topLine_) {}
382 bool operator==(const XYScrollPosition &other) const noexcept {
383 return (xOffset == other.xOffset) && (topLine == other.topLine);
384 }
385 };
386 XYScrollPosition XYScrollToMakeVisible(const SelectionRange &range,
387 const XYScrollOptions options, CaretPolicies policies);
388 void SetXYScroll(XYScrollPosition newXY);
389 void EnsureCaretVisible(bool useMargin=true, bool vert=true, bool horiz=true);
390 void ScrollRange(SelectionRange range);
391 void ShowCaretAtCurrentPosition();
392 void DropCaret();
393 void CaretSetPeriod(int period);
394 void InvalidateCaret();
395 virtual void NotifyCaretMove();
396 virtual void UpdateSystemCaret();
397
398 bool Wrapping() const noexcept;
399 void NeedWrapping(Sci::Line docLineStart=0, Sci::Line docLineEnd=WrapPending::lineLarge);
400 bool WrapOneLine(Surface *surface, Sci::Line lineToWrap);
401 enum class WrapScope {wsAll, wsVisible, wsIdle};
402 bool WrapLines(WrapScope ws);
403 void LinesJoin();
404 void LinesSplit(int pixelWidth);
405
406 void PaintSelMargin(Surface *surfaceWindow, const PRectangle &rc);
407 void RefreshPixMaps(Surface *surfaceWindow);
408 void Paint(Surface *surfaceWindow, PRectangle rcArea);
409 Sci::Position FormatRange(bool draw, const Scintilla::RangeToFormat *pfr);
410 long TextWidth(Scintilla::uptr_t style, const char *text);
411
412 virtual void SetVerticalScrollPos() = 0;
413 virtual void SetHorizontalScrollPos() = 0;
414 virtual bool ModifyScrollBars(Sci::Line nMax, Sci::Line nPage) = 0;
415 virtual void ReconfigureScrollBars();
416 void SetScrollBars();
417 void ChangeSize();
418
419 void FilterSelections();
420 Sci::Position RealizeVirtualSpace(Sci::Position position, Sci::Position virtualSpace);
421 SelectionPosition RealizeVirtualSpace(const SelectionPosition &position);
422 void AddChar(char ch);
423 virtual void InsertCharacter(std::string_view sv, Scintilla::CharacterSource charSource);
424 void ClearBeforeTentativeStart();
425 void InsertPaste(const char *text, Sci::Position len);
426 enum class PasteShape { stream=0, rectangular = 1, line = 2 };
427 void InsertPasteShape(const char *text, Sci::Position len, PasteShape shape);
428 void ClearSelection(bool retainMultipleSelections = false);
429 void ClearAll();
430 void ClearDocumentStyle();
431 virtual void Cut();
432 void PasteRectangular(SelectionPosition pos, const char *ptr, Sci::Position len);
433 virtual void Copy() = 0;
434 void CopyAllowLine();
435 virtual bool CanPaste();
436 virtual void Paste() = 0;
437 void Clear();
438 virtual void SelectAll();
439 virtual void Undo();
440 virtual void Redo();
441 void DelCharBack(bool allowLineStartDeletion);
442 virtual void ClaimSelection() = 0;
443
444 static Scintilla::KeyMod ModifierFlags(bool shift, bool ctrl, bool alt, bool meta=false, bool super=false) noexcept;
445 virtual void NotifyChange() = 0;
446 virtual void NotifyFocus(bool focus);
447 virtual void SetCtrlID(int identifier);
448 virtual int GetCtrlID() { return ctrlID; }
449 virtual void NotifyParent(Scintilla::NotificationData scn) = 0;
450 virtual void NotifyStyleToNeeded(Sci::Position endStyleNeeded);
451 void NotifyChar(int ch, Scintilla::CharacterSource charSource);
452 void NotifySavePoint(bool isSavePoint);
453 void NotifyModifyAttempt();
454 virtual void NotifyDoubleClick(Point pt, Scintilla::KeyMod modifiers);
455 void NotifyHotSpotClicked(Sci::Position position, Scintilla::KeyMod modifiers);
456 void NotifyHotSpotDoubleClicked(Sci::Position position, Scintilla::KeyMod modifiers);
457 void NotifyHotSpotReleaseClick(Sci::Position position, Scintilla::KeyMod modifiers);
458 bool NotifyUpdateUI();
459 void NotifyPainted();
460 void NotifyIndicatorClick(bool click, Sci::Position position, Scintilla::KeyMod modifiers);
461 bool NotifyMarginClick(Point pt, Scintilla::KeyMod modifiers);
462 bool NotifyMarginRightClick(Point pt, Scintilla::KeyMod modifiers);
463 void NotifyNeedShown(Sci::Position pos, Sci::Position len);
464 void NotifyDwelling(Point pt, bool state);
465 void NotifyZoom();
466
467 void NotifyModifyAttempt(Document *document, void *userData) override;
468 void NotifySavePoint(Document *document, void *userData, bool atSavePoint) override;
469 void CheckModificationForWrap(DocModification mh);
470 void NotifyModified(Document *document, DocModification mh, void *userData) override;
471 void NotifyDeleted(Document *document, void *userData) noexcept override;
472 void NotifyStyleNeeded(Document *doc, void *userData, Sci::Position endStyleNeeded) override;
473 void NotifyLexerChanged(Document *doc, void *userData) override;
474 void NotifyErrorOccurred(Document *doc, void *userData, Scintilla::Status status) override;
475 void NotifyMacroRecord(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam);
476
477 void ContainerNeedsUpdate(Scintilla::Update flags) noexcept;
478 void PageMove(int direction, Selection::SelTypes selt=Selection::SelTypes::none, bool stuttered = false);
479 enum class CaseMapping { same, upper, lower };
480 virtual std::string CaseMapString(const std::string &s, CaseMapping caseMapping);
481 void ChangeCaseOfSelection(CaseMapping caseMapping);
482 void LineTranspose();
483 void LineReverse();
484 void Duplicate(bool forLine);
485 virtual void CancelModes();
486 void NewLine();
487 SelectionPosition PositionUpOrDown(SelectionPosition spStart, int direction, int lastX);
488 void CursorUpOrDown(int direction, Selection::SelTypes selt);
489 void ParaUpOrDown(int direction, Selection::SelTypes selt);
490 Range RangeDisplayLine(Sci::Line lineVisible);
491 Sci::Position StartEndDisplayLine(Sci::Position pos, bool start);
492 Sci::Position VCHomeDisplayPosition(Sci::Position position);
493 Sci::Position VCHomeWrapPosition(Sci::Position position);
494 Sci::Position LineEndWrapPosition(Sci::Position position);
495 int HorizontalMove(Scintilla::Message iMessage);
496 int DelWordOrLine(Scintilla::Message iMessage);
497 virtual int KeyCommand(Scintilla::Message iMessage);
498 virtual int KeyDefault(Scintilla::Keys /* key */, Scintilla::KeyMod /*modifiers*/);
499 int KeyDownWithModifiers(Scintilla::Keys key, Scintilla::KeyMod modifiers, bool *consumed);
500
501 void Indent(bool forwards);
502
503 virtual std::unique_ptr<CaseFolder> CaseFolderForEncoding();
504 Sci::Position FindText(Scintilla::uptr_t wParam, Scintilla::sptr_t lParam);
505 void SearchAnchor();
506 Sci::Position SearchText(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam);
507 Sci::Position SearchInTarget(const char *text, Sci::Position length);
508 void GoToLine(Sci::Line lineNo);
509
510 virtual void CopyToClipboard(const SelectionText &selectedText) = 0;
511 std::string RangeText(Sci::Position start, Sci::Position end) const;
512 void CopySelectionRange(SelectionText *ss, bool allowLineCopy=false);
513 void CopyRangeToClipboard(Sci::Position start, Sci::Position end);
514 void CopyText(size_t length, const char *text);
515 void SetDragPosition(SelectionPosition newPos);
516 virtual void DisplayCursor(Window::Cursor c);
517 virtual bool DragThreshold(Point ptStart, Point ptNow);
518 virtual void StartDrag();
519 void DropAt(SelectionPosition position, const char *value, size_t lengthValue, bool moving, bool rectangular);
520 void DropAt(SelectionPosition position, const char *value, bool moving, bool rectangular);
521 /** PositionInSelection returns true if position in selection. */
522 bool PositionInSelection(Sci::Position pos);
523 bool PointInSelection(Point pt);
524 bool PointInSelMargin(Point pt) const;
525 Window::Cursor GetMarginCursor(Point pt) const noexcept;
526 void TrimAndSetSelection(Sci::Position currentPos_, Sci::Position anchor_);
527 void LineSelection(Sci::Position lineCurrentPos_, Sci::Position lineAnchorPos_, bool wholeLine);
528 void WordSelection(Sci::Position pos);
529 void DwellEnd(bool mouseMoved);
530 void MouseLeave();
531 virtual void ButtonDownWithModifiers(Point pt, unsigned int curTime, Scintilla::KeyMod modifiers);
532 virtual void RightButtonDownWithModifiers(Point pt, unsigned int curTime, Scintilla::KeyMod modifiers);
533 void ButtonMoveWithModifiers(Point pt, unsigned int curTime, Scintilla::KeyMod modifiers);
534 void ButtonUpWithModifiers(Point pt, unsigned int curTime, Scintilla::KeyMod modifiers);
535
536 bool Idle();
537 enum class TickReason { caret, scroll, widen, dwell, platform };
538 virtual void TickFor(TickReason reason);
539 virtual bool FineTickerRunning(TickReason reason);
540 virtual void FineTickerStart(TickReason reason, int millis, int tolerance);
541 virtual void FineTickerCancel(TickReason reason);
542 virtual bool SetIdle(bool) { return false; }
543 virtual void SetMouseCapture(bool on) = 0;
544 virtual bool HaveMouseCapture() = 0;
545 void SetFocusState(bool focusState);
546 virtual void UpdateBaseElements();
547
548 Sci::Position PositionAfterArea(PRectangle rcArea) const;
549 void StyleToPositionInView(Sci::Position pos);
550 Sci::Position PositionAfterMaxStyling(Sci::Position posMax, bool scrolling) const;
551 void StartIdleStyling(bool truncatedLastStyling);
552 void StyleAreaBounded(PRectangle rcArea, bool scrolling);
553 constexpr bool SynchronousStylingToVisible() const noexcept {
554 return (idleStyling == Scintilla::IdleStyling::None) || (idleStyling == Scintilla::IdleStyling::AfterVisible);
555 }
556 void IdleStyle();
557 virtual void IdleWork();
558 virtual void QueueIdleWork(WorkItems items, Sci::Position upTo=0);
559
560 virtual int SupportsFeature(Scintilla::Supports feature);
561 virtual bool PaintContains(PRectangle rc);
562 bool PaintContainsMargin();
563 void CheckForChangeOutsidePaint(Range r);
564 void SetBraceHighlight(Sci::Position pos0, Sci::Position pos1, int matchStyle);
565
566 void SetAnnotationHeights(Sci::Line start, Sci::Line end);
567 virtual void SetDocPointer(Document *document);
568
569 void SetAnnotationVisible(Scintilla::AnnotationVisible visible);
570 void SetEOLAnnotationVisible(Scintilla::EOLAnnotationVisible visible);
571
572 Sci::Line ExpandLine(Sci::Line line);
573 void SetFoldExpanded(Sci::Line lineDoc, bool expanded);
574 void FoldLine(Sci::Line line, Scintilla::FoldAction action);
575 void FoldExpand(Sci::Line line, Scintilla::FoldAction action, Scintilla::FoldLevel level);
576 Sci::Line ContractedFoldNext(Sci::Line lineStart) const;
577 void EnsureLineVisible(Sci::Line lineDoc, bool enforcePolicy);
578 void FoldChanged(Sci::Line line, Scintilla::FoldLevel levelNow, Scintilla::FoldLevel levelPrev);
579 void NeedShown(Sci::Position pos, Sci::Position len);
580 void FoldAll(Scintilla::FoldAction action);
581
582 Sci::Position GetTag(char *tagValue, int tagNumber);
583 Sci::Position ReplaceTarget(bool replacePatterns, const char *text, Sci::Position length=-1);
584
585 bool PositionIsHotspot(Sci::Position position) const;
586 bool PointIsHotspot(Point pt);
587 void SetHotSpotRange(const Point *pt);
588 void SetHoverIndicatorPosition(Sci::Position position);
589 void SetHoverIndicatorPoint(Point pt);
590
591 int CodePage() const noexcept;
592 virtual bool ValidCodePage(int /* codePage */) const { return true; }
593 virtual std::string UTF8FromEncoded(std::string_view encoded) const = 0;
594 virtual std::string EncodedFromUTF8(std::string_view utf8) const = 0;
595
596 Sci::Line WrapCount(Sci::Line line);
597 void AddStyledText(const char *buffer, Sci::Position appendLength);
598
599 virtual Scintilla::sptr_t DefWndProc(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam) = 0;
600 bool ValidMargin(Scintilla::uptr_t wParam) const noexcept;
601 void StyleSetMessage(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam);
602 Scintilla::sptr_t StyleGetMessage(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam);
603 void SetSelectionNMessage(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam);
604
605 static const char *StringFromEOLMode(Scintilla::EndOfLine eolMode) noexcept;
606
607 // Coercion functions for transforming WndProc parameters into pointers
608 static void *PtrFromSPtr(Scintilla::sptr_t lParam) noexcept {
609 return reinterpret_cast<void *>(lParam);
610 }
611 static const char *ConstCharPtrFromSPtr(Scintilla::sptr_t lParam) noexcept {
612 return static_cast<const char *>(PtrFromSPtr(lParam));
613 }
614 static const unsigned char *ConstUCharPtrFromSPtr(Scintilla::sptr_t lParam) noexcept {
615 return static_cast<const unsigned char *>(PtrFromSPtr(lParam));
616 }
617 static char *CharPtrFromSPtr(Scintilla::sptr_t lParam) noexcept {
618 return static_cast<char *>(PtrFromSPtr(lParam));
619 }
620 static unsigned char *UCharPtrFromSPtr(Scintilla::sptr_t lParam) noexcept {
621 return static_cast<unsigned char *>(PtrFromSPtr(lParam));
622 }
623 static void *PtrFromUPtr(Scintilla::uptr_t wParam) noexcept {
624 return reinterpret_cast<void *>(wParam);
625 }
626 static const char *ConstCharPtrFromUPtr(Scintilla::uptr_t wParam) noexcept {
627 return static_cast<const char *>(PtrFromUPtr(wParam));
628 }
629
630 static constexpr Scintilla::sptr_t SPtrFromUPtr(Scintilla::uptr_t wParam) noexcept {
631 return static_cast<Scintilla::sptr_t>(wParam);
632 }
633 static constexpr Sci::Position PositionFromUPtr(Scintilla::uptr_t wParam) noexcept {
634 return SPtrFromUPtr(wParam);
635 }
636 static constexpr Sci::Line LineFromUPtr(Scintilla::uptr_t wParam) noexcept {
637 return SPtrFromUPtr(wParam);
638 }
639 Point PointFromParameters(Scintilla::uptr_t wParam, Scintilla::sptr_t lParam) const noexcept {
640 return Point(static_cast<XYPOSITION>(wParam) - vs.ExternalMarginWidth(), static_cast<XYPOSITION>(lParam));
641 }
642
643 static constexpr std::optional<FoldLevel> OptionalFoldLevel(Scintilla::sptr_t lParam) {
644 if (lParam >= 0) {
645 return static_cast<FoldLevel>(lParam);
646 }
647 return std::nullopt;
648 }
649
650 static Scintilla::sptr_t StringResult(Scintilla::sptr_t lParam, const char *val) noexcept;
651 static Scintilla::sptr_t BytesResult(Scintilla::sptr_t lParam, const unsigned char *val, size_t len) noexcept;
652
653 // Set a variable controlling appearance to a value and invalidates the display
654 // if a change was made. Avoids extra text and the possibility of mistyping.
655 template <typename T>
656 bool SetAppearance(T &variable, T value) {
657 // Using ! and == as more types have == defined than !=.
658 const bool changed = !(variable == value);
659 if (changed) {
660 variable = value;
661 InvalidateStyleRedraw();
662 }
663 return changed;
664 }
665
666public:
667 ~Editor() override;
668
669 // Public so the COM thunks can access it.
670 bool IsUnicodeMode() const noexcept;
671 // Public so scintilla_send_message can use it.
672 virtual Scintilla::sptr_t WndProc(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam);
673 // Public so scintilla_set_id can use it.
674 int ctrlID;
675 // Public so COM methods for drag and drop can set it.
676 Scintilla::Status errorStatus;
677 friend class AutoSurface;
678};
679
680/**
681 * A smart pointer class to ensure Surfaces are set up and deleted correctly.
682 */
683class AutoSurface {
684private:
685 std::unique_ptr<Surface> surf;
686public:
687 AutoSurface(const Editor *ed) {
688 if (ed->wMain.GetID()) {
689 surf = Surface::Allocate(ed->technology);
690 surf->Init(ed->wMain.GetID());
691 surf->SetMode(SurfaceMode(ed->CodePage(), ed->BidirectionalR2L()));
692 }
693 }
694 AutoSurface(SurfaceID sid, Editor *ed, std::optional<Scintilla::Technology> technology = {}) {
695 if (ed->wMain.GetID()) {
696 surf = Surface::Allocate(technology ? *technology : ed->technology);
697 surf->Init(sid, ed->wMain.GetID());
698 surf->SetMode(SurfaceMode(ed->CodePage(), ed->BidirectionalR2L()));
699 }
700 }
701 // Deleted so AutoSurface objects can not be copied.
702 AutoSurface(const AutoSurface &) = delete;
703 AutoSurface(AutoSurface &&) = delete;
704 void operator=(const AutoSurface &) = delete;
705 void operator=(AutoSurface &&) = delete;
706 ~AutoSurface() {
707 }
708 Surface *operator->() const noexcept {
709 return surf.get();
710 }
711 operator Surface *() const noexcept {
712 return surf.get();
713 }
714};
715
716}
717
718#endif
719