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