1 // Scintilla source code edit control 2 /** @file Editor.h 3 ** Defines the main editor class. 4 **/ 5 // Copyright 1998-2011 by Neil Hodgson <[email protected]> 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