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