1 // Scintilla source code edit control
3 ** Defines the main editor class.
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.
21 enum {tickSize
= 100};
38 * When platform has a way to generate an event before painting,
39 * accumulate needed styling range and other work items in
40 * WorkNeeded to avoid unnecessary work inside paint handler
52 WorkNeeded() : items(workNone
), upTo(0) {}
57 void Need(workItems items_
, Position pos
) {
58 if ((items_
& workStyle
) && (upTo
< pos
))
60 items
= static_cast<workItems
>(items
| items_
);
65 * Hold a piece of text selected for copying or dragging, along with encoding and selection format information.
74 SelectionText() : rectangular(false), lineCopy(false), codePage(0), characterSet(0) {}
84 void Copy(const std::string
&s_
, int codePage_
, int characterSet_
, bool rectangular_
, bool lineCopy_
) {
87 characterSet
= characterSet_
;
88 rectangular
= rectangular_
;
90 FixSelectionForClipboard();
92 void Copy(const SelectionText
&other
) {
93 Copy(other
.s
, other
.codePage
, other
.characterSet
, other
.rectangular
, other
.lineCopy
);
95 const char *Data() const {
98 size_t Length() const {
101 size_t LengthWithTerminator() const {
102 return s
.length() + 1;
108 void FixSelectionForClipboard() {
109 // To avoid truncating the contents of the clipboard when pasted where the
110 // clipboard contains NUL characters, replace NUL characters by spaces.
111 std::replace(s
.begin(), s
.end(), '\0', ' ');
116 // The range of lines that need to be wrapped
117 enum { lineLarge
= 0x7ffffff };
118 int start
; // When there are wraps pending, will be in document range
119 int end
; // May be lineLarge to indicate all of document after start
128 void Wrapped(int line
) {
132 bool NeedsWrap() const {
135 bool AddRange(int lineStart
, int lineEnd
) {
136 const bool neededWrap
= NeedsWrap();
137 bool changed
= false;
138 if (start
> lineStart
) {
142 if ((end
< lineEnd
) || !neededWrap
) {
152 class Editor
: public EditModel
, public DocWatcher
{
153 // Private so Editor objects can not be copied
154 explicit Editor(const Editor
&);
155 Editor
&operator=(const Editor
&);
157 protected: // ScintillaBase subclass needs access to much of Editor
159 /** On GTK+, Scintilla is a container widget holding two scroll bars
160 * whereas on Windows there is just one window with both scroll bars turned on. */
161 Window wMain
; ///< The Scintilla parent window
162 Window wMargin
; ///< May be separate when using a scroll view for wMain
164 /** Style resources may be expensive to allocate so are cached between uses.
165 * When a style attribute is changed, this cache is flushed. */
170 float scaleRGBAImage
;
172 MarginView marginView
;
178 bool mouseDownCaptures
;
180 int xCaretMargin
; ///< Ensure this many pixels visible on both sides of caret
181 bool horizontalScrollBarVisible
;
183 bool verticalScrollBarVisible
;
187 bool mouseSelectionRectangularSwitch
;
188 bool multipleSelection
;
189 bool additionalSelectionTyping
;
192 int virtualSpaceOptions
;
197 Timer autoScrollTimer
;
198 enum { autoScrollDelay
= 200 };
203 unsigned int lastClickTime
;
204 Point doubleClickCloseThreshold
;
208 enum { selChar
, selWord
, selSubLine
, selWholeLine
} selectionType
;
210 enum { ddNone
, ddInitial
, ddDragging
} inDragDrop
;
211 bool dropWentOutside
;
212 SelectionPosition posDrop
;
216 int originalAnchorPos
;
217 int wordSelectAnchorStartPos
;
218 int wordSelectAnchorEndPos
;
219 int wordSelectInitialCaretPos
;
229 enum { notPainting
, painting
, paintAbandoned
} paintState
;
230 bool paintAbandonedByStyling
;
232 bool paintingAllText
;
234 WorkNeeded workNeeded
;
236 bool needIdleStyling
;
243 int caretXSlop
; ///< Ensure this many pixels visible on both sides of caret
246 int caretYSlop
; ///< Ensure this many lines visible on both sides of caret
258 WrapPending wrapPending
;
264 virtual void Initialise() = 0;
265 virtual void Finalise();
267 void InvalidateStyleData();
268 void InvalidateStyleRedraw();
269 void RefreshStyleData();
270 void SetRepresentations();
271 void DropGraphics(bool freeObjects
);
272 void AllocateGraphics();
274 // The top left visible point in main window coordinates. Will be 0,0 except for
275 // scroll views where it will be equivalent to the current scroll position.
276 virtual Point
GetVisibleOriginInMain() const;
277 Point
DocumentPointFromView(Point ptView
) const; // Convert a point from view space to document
278 int TopLineOfMain() const; // Return the line at Main's y coordinate 0
279 virtual PRectangle
GetClientRectangle() const;
280 virtual PRectangle
GetClientDrawingRectangle();
281 PRectangle
GetTextRectangle() const;
283 virtual int LinesOnScreen() const;
284 int LinesToScroll() const;
285 int MaxScrollPos() const;
286 SelectionPosition
ClampPositionIntoDocument(SelectionPosition sp
) const;
287 Point
LocationFromPosition(SelectionPosition pos
);
288 Point
LocationFromPosition(int pos
);
289 int XFromPosition(int pos
);
290 int XFromPosition(SelectionPosition sp
);
291 SelectionPosition
SPositionFromLocation(Point pt
, bool canReturnInvalid
=false, bool charPosition
=false, bool virtualSpace
=true);
292 int PositionFromLocation(Point pt
, bool canReturnInvalid
= false, bool charPosition
= false);
293 SelectionPosition
SPositionFromLineX(int lineDoc
, int x
);
294 int PositionFromLineX(int line
, int x
);
295 int LineFromLocation(Point pt
) const;
296 void SetTopLine(int topLineNew
);
298 virtual bool AbandonPaint();
299 virtual void RedrawRect(PRectangle rc
);
300 virtual void DiscardOverdraw();
301 virtual void Redraw();
302 void RedrawSelMargin(int line
=-1, bool allAfter
=false);
303 PRectangle
RectangleFromRange(Range r
, int overlap
);
304 void InvalidateRange(int start
, int end
);
306 bool UserVirtualSpace() const {
307 return ((virtualSpaceOptions
& SCVS_USERACCESSIBLE
) != 0);
309 int CurrentPosition() const;
310 bool SelectionEmpty() const;
311 SelectionPosition
SelectionStart();
312 SelectionPosition
SelectionEnd();
313 void SetRectangularRange();
314 void ThinRectangularRange();
315 void InvalidateSelection(SelectionRange newMain
, bool invalidateWholeSelection
=false);
316 void InvalidateWholeSelection();
317 void SetSelection(SelectionPosition currentPos_
, SelectionPosition anchor_
);
318 void SetSelection(int currentPos_
, int anchor_
);
319 void SetSelection(SelectionPosition currentPos_
);
320 void SetSelection(int currentPos_
);
321 void SetEmptySelection(SelectionPosition currentPos_
);
322 void SetEmptySelection(int currentPos_
);
323 enum AddNumber
{ addOne
, addEach
};
324 void MultipleSelectAdd(AddNumber addNumber
);
325 bool RangeContainsProtected(int start
, int end
) const;
326 bool SelectionContainsProtected();
327 int MovePositionOutsideChar(int pos
, int moveDir
, bool checkLineEnd
=true) const;
328 SelectionPosition
MovePositionOutsideChar(SelectionPosition pos
, int moveDir
, bool checkLineEnd
=true) const;
329 void MovedCaret(SelectionPosition newPos
, SelectionPosition previousPos
, bool ensureVisible
);
330 void MovePositionTo(SelectionPosition newPos
, Selection::selTypes selt
=Selection::noSel
, bool ensureVisible
=true);
331 void MovePositionTo(int newPos
, Selection::selTypes selt
=Selection::noSel
, bool ensureVisible
=true);
332 SelectionPosition
MovePositionSoVisible(SelectionPosition pos
, int moveDir
);
333 SelectionPosition
MovePositionSoVisible(int pos
, int moveDir
);
334 Point
PointMainCaret();
335 void SetLastXChosen();
337 void ScrollTo(int line
, bool moveThumb
=true);
338 virtual void ScrollText(int linesToMove
);
339 void HorizontalScrollTo(int xPos
);
340 void VerticalCentreCaret();
341 void MoveSelectedLines(int lineDelta
);
342 void MoveSelectedLinesUp();
343 void MoveSelectedLinesDown();
344 void MoveCaretInsideView(bool ensureVisible
=true);
345 int DisplayFromPosition(int pos
);
347 struct XYScrollPosition
{
350 XYScrollPosition(int xOffset_
, int topLine_
) : xOffset(xOffset_
), topLine(topLine_
) {}
351 bool operator==(const XYScrollPosition
&other
) const {
352 return (xOffset
== other
.xOffset
) && (topLine
== other
.topLine
);
355 enum XYScrollOptions
{
359 xysDefault
=xysUseMargin
|xysVertical
|xysHorizontal
};
360 XYScrollPosition
XYScrollToMakeVisible(const SelectionRange
&range
, const XYScrollOptions options
);
361 void SetXYScroll(XYScrollPosition newXY
);
362 void EnsureCaretVisible(bool useMargin
=true, bool vert
=true, bool horiz
=true);
363 void ScrollRange(SelectionRange range
);
364 void ShowCaretAtCurrentPosition();
366 void CaretSetPeriod(int period
);
367 void InvalidateCaret();
368 virtual void NotifyCaretMove();
369 virtual void UpdateSystemCaret();
371 bool Wrapping() const;
372 void NeedWrapping(int docLineStart
=0, int docLineEnd
=WrapPending::lineLarge
);
373 bool WrapOneLine(Surface
*surface
, int lineToWrap
);
374 enum wrapScope
{wsAll
, wsVisible
, wsIdle
};
375 bool WrapLines(enum wrapScope ws
);
377 void LinesSplit(int pixelWidth
);
379 void PaintSelMargin(Surface
*surface
, PRectangle
&rc
);
380 void RefreshPixMaps(Surface
*surfaceWindow
);
381 void Paint(Surface
*surfaceWindow
, PRectangle rcArea
);
382 long FormatRange(bool draw
, Sci_RangeToFormat
*pfr
);
383 int TextWidth(int style
, const char *text
);
385 virtual void SetVerticalScrollPos() = 0;
386 virtual void SetHorizontalScrollPos() = 0;
387 virtual bool ModifyScrollBars(int nMax
, int nPage
) = 0;
388 virtual void ReconfigureScrollBars();
389 void SetScrollBars();
392 void FilterSelections();
393 int RealizeVirtualSpace(int position
, unsigned int virtualSpace
);
394 SelectionPosition
RealizeVirtualSpace(const SelectionPosition
&position
);
395 void AddChar(char ch
);
396 virtual void AddCharUTF(const char *s
, unsigned int len
, bool treatAsDBCS
=false);
397 void ClearBeforeTentativeStart();
398 void InsertPaste(const char *text
, int len
);
399 enum PasteShape
{ pasteStream
=0, pasteRectangular
= 1, pasteLine
= 2 };
400 void InsertPasteShape(const char *text
, int len
, PasteShape shape
);
401 void ClearSelection(bool retainMultipleSelections
= false);
403 void ClearDocumentStyle();
405 void PasteRectangular(SelectionPosition pos
, const char *ptr
, int len
);
406 virtual void Copy() = 0;
407 virtual void CopyAllowLine();
408 virtual bool CanPaste();
409 virtual void Paste() = 0;
414 void DelCharBack(bool allowLineStartDeletion
);
415 virtual void ClaimSelection() = 0;
417 static int ModifierFlags(bool shift
, bool ctrl
, bool alt
, bool meta
=false, bool super
=false);
418 virtual void NotifyChange() = 0;
419 virtual void NotifyFocus(bool focus
);
420 virtual void SetCtrlID(int identifier
);
421 virtual int GetCtrlID() { return ctrlID
; }
422 virtual void NotifyParent(SCNotification scn
) = 0;
423 virtual void NotifyStyleToNeeded(int endStyleNeeded
);
424 void NotifyChar(int ch
);
425 void NotifySavePoint(bool isSavePoint
);
426 void NotifyModifyAttempt();
427 virtual void NotifyDoubleClick(Point pt
, int modifiers
);
428 virtual void NotifyDoubleClick(Point pt
, bool shift
, bool ctrl
, bool alt
);
429 void NotifyHotSpotClicked(int position
, int modifiers
);
430 void NotifyHotSpotClicked(int position
, bool shift
, bool ctrl
, bool alt
);
431 void NotifyHotSpotDoubleClicked(int position
, int modifiers
);
432 void NotifyHotSpotDoubleClicked(int position
, bool shift
, bool ctrl
, bool alt
);
433 void NotifyHotSpotReleaseClick(int position
, int modifiers
);
434 void NotifyHotSpotReleaseClick(int position
, bool shift
, bool ctrl
, bool alt
);
435 bool NotifyUpdateUI();
436 void NotifyPainted();
437 void NotifyIndicatorClick(bool click
, int position
, int modifiers
);
438 void NotifyIndicatorClick(bool click
, int position
, bool shift
, bool ctrl
, bool alt
);
439 bool NotifyMarginClick(Point pt
, int modifiers
);
440 bool NotifyMarginClick(Point pt
, bool shift
, bool ctrl
, bool alt
);
441 void NotifyNeedShown(int pos
, int len
);
442 void NotifyDwelling(Point pt
, bool state
);
445 void NotifyModifyAttempt(Document
*document
, void *userData
);
446 void NotifySavePoint(Document
*document
, void *userData
, bool atSavePoint
);
447 void CheckModificationForWrap(DocModification mh
);
448 void NotifyModified(Document
*document
, DocModification mh
, void *userData
);
449 void NotifyDeleted(Document
*document
, void *userData
);
450 void NotifyStyleNeeded(Document
*doc
, void *userData
, int endPos
);
451 void NotifyLexerChanged(Document
*doc
, void *userData
);
452 void NotifyErrorOccurred(Document
*doc
, void *userData
, int status
);
453 void NotifyMacroRecord(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
455 void ContainerNeedsUpdate(int flags
);
456 void PageMove(int direction
, Selection::selTypes selt
=Selection::noSel
, bool stuttered
= false);
457 enum { cmSame
, cmUpper
, cmLower
};
458 virtual std::string
CaseMapString(const std::string
&s
, int caseMapping
);
459 void ChangeCaseOfSelection(int caseMapping
);
460 void LineTranspose();
461 void Duplicate(bool forLine
);
462 virtual void CancelModes();
464 SelectionPosition
PositionUpOrDown(SelectionPosition spStart
, int direction
, int lastX
);
465 void CursorUpOrDown(int direction
, Selection::selTypes selt
);
466 void ParaUpOrDown(int direction
, Selection::selTypes selt
);
467 int StartEndDisplayLine(int pos
, bool start
);
468 int VCHomeDisplayPosition(int position
);
469 int VCHomeWrapPosition(int position
);
470 int LineEndWrapPosition(int position
);
471 int HorizontalMove(unsigned int iMessage
);
472 int DelWordOrLine(unsigned int iMessage
);
473 virtual int KeyCommand(unsigned int iMessage
);
474 virtual int KeyDefault(int /* key */, int /*modifiers*/);
475 int KeyDownWithModifiers(int key
, int modifiers
, bool *consumed
);
476 int KeyDown(int key
, bool shift
, bool ctrl
, bool alt
, bool *consumed
=0);
478 void Indent(bool forwards
);
480 virtual CaseFolder
*CaseFolderForEncoding();
481 long FindText(uptr_t wParam
, sptr_t lParam
);
483 long SearchText(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
484 long SearchInTarget(const char *text
, int length
);
485 void GoToLine(int lineNo
);
487 virtual void CopyToClipboard(const SelectionText
&selectedText
) = 0;
488 std::string
RangeText(int start
, int end
) const;
489 void CopySelectionRange(SelectionText
*ss
, bool allowLineCopy
=false);
490 void CopyRangeToClipboard(int start
, int end
);
491 void CopyText(int length
, const char *text
);
492 void SetDragPosition(SelectionPosition newPos
);
493 virtual void DisplayCursor(Window::Cursor c
);
494 virtual bool DragThreshold(Point ptStart
, Point ptNow
);
495 virtual void StartDrag();
496 void DropAt(SelectionPosition position
, const char *value
, size_t lengthValue
, bool moving
, bool rectangular
);
497 void DropAt(SelectionPosition position
, const char *value
, bool moving
, bool rectangular
);
498 /** PositionInSelection returns true if position in selection. */
499 bool PositionInSelection(int pos
);
500 bool PointInSelection(Point pt
);
501 bool PointInSelMargin(Point pt
) const;
502 Window::Cursor
GetMarginCursor(Point pt
) const;
503 void TrimAndSetSelection(int currentPos_
, int anchor_
);
504 void LineSelection(int lineCurrentPos_
, int lineAnchorPos_
, bool wholeLine
);
505 void WordSelection(int pos
);
506 void DwellEnd(bool mouseMoved
);
508 virtual void ButtonDownWithModifiers(Point pt
, unsigned int curTime
, int modifiers
);
509 virtual void ButtonDown(Point pt
, unsigned int curTime
, bool shift
, bool ctrl
, bool alt
);
510 void ButtonMoveWithModifiers(Point pt
, int modifiers
);
511 void ButtonMove(Point pt
);
512 void ButtonUp(Point pt
, unsigned int curTime
, bool ctrl
);
516 virtual void SetTicking(bool on
);
517 enum TickReason
{ tickCaret
, tickScroll
, tickWiden
, tickDwell
, tickPlatform
};
518 virtual void TickFor(TickReason reason
);
519 virtual bool FineTickerAvailable();
520 virtual bool FineTickerRunning(TickReason reason
);
521 virtual void FineTickerStart(TickReason reason
, int millis
, int tolerance
);
522 virtual void FineTickerCancel(TickReason reason
);
523 virtual bool SetIdle(bool) { return false; }
524 virtual void SetMouseCapture(bool on
) = 0;
525 virtual bool HaveMouseCapture() = 0;
526 void SetFocusState(bool focusState
);
528 int PositionAfterArea(PRectangle rcArea
) const;
529 void StyleToPositionInView(Position pos
);
530 int PositionAfterMaxStyling(int posMax
, bool scrolling
) const;
531 void StartIdleStyling(bool truncatedLastStyling
);
532 void StyleAreaBounded(PRectangle rcArea
, bool scrolling
);
534 virtual void IdleWork();
535 virtual void QueueIdleWork(WorkNeeded::workItems items
, int upTo
=0);
537 virtual bool PaintContains(PRectangle rc
);
538 bool PaintContainsMargin();
539 void CheckForChangeOutsidePaint(Range r
);
540 void SetBraceHighlight(Position pos0
, Position pos1
, int matchStyle
);
542 void SetAnnotationHeights(int start
, int end
);
543 virtual void SetDocPointer(Document
*document
);
545 void SetAnnotationVisible(int visible
);
547 int ExpandLine(int line
);
548 void SetFoldExpanded(int lineDoc
, bool expanded
);
549 void FoldLine(int line
, int action
);
550 void FoldExpand(int line
, int action
, int level
);
551 int ContractedFoldNext(int lineStart
) const;
552 void EnsureLineVisible(int lineDoc
, bool enforcePolicy
);
553 void FoldChanged(int line
, int levelNow
, int levelPrev
);
554 void NeedShown(int pos
, int len
);
555 void FoldAll(int action
);
557 int GetTag(char *tagValue
, int tagNumber
);
558 int ReplaceTarget(bool replacePatterns
, const char *text
, int length
=-1);
560 bool PositionIsHotspot(int position
) const;
561 bool PointIsHotspot(Point pt
);
562 void SetHotSpotRange(Point
*pt
);
563 Range
GetHotSpotRange() const;
564 void SetHoverIndicatorPosition(int position
);
565 void SetHoverIndicatorPoint(Point pt
);
567 int CodePage() const;
568 virtual bool ValidCodePage(int /* codePage */) const { return true; }
569 int WrapCount(int line
);
570 void AddStyledText(char *buffer
, int appendLength
);
572 virtual sptr_t
DefWndProc(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
) = 0;
573 void StyleSetMessage(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
574 sptr_t
StyleGetMessage(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
576 static const char *StringFromEOLMode(int eolMode
);
578 static sptr_t
StringResult(sptr_t lParam
, const char *val
);
579 static sptr_t
BytesResult(sptr_t lParam
, const unsigned char *val
, size_t len
);
582 // Public so the COM thunks can access it.
583 bool IsUnicodeMode() const;
584 // Public so scintilla_send_message can use it.
585 virtual sptr_t
WndProc(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
586 // Public so scintilla_set_id can use it.
588 // Public so COM methods for drag and drop can set it.
590 friend class AutoSurface
;
591 friend class SelectionLineIterator
;
595 * A smart pointer class to ensure Surfaces are set up and deleted correctly.
601 AutoSurface(Editor
*ed
, int technology
= -1) : surf(0) {
602 if (ed
->wMain
.GetID()) {
603 surf
= Surface::Allocate(technology
!= -1 ? technology
: ed
->technology
);
605 surf
->Init(ed
->wMain
.GetID());
606 surf
->SetUnicodeMode(SC_CP_UTF8
== ed
->CodePage());
607 surf
->SetDBCSMode(ed
->CodePage());
611 AutoSurface(SurfaceID sid
, Editor
*ed
, int technology
= -1) : surf(0) {
612 if (ed
->wMain
.GetID()) {
613 surf
= Surface::Allocate(technology
!= -1 ? technology
: ed
->technology
);
615 surf
->Init(sid
, ed
->wMain
.GetID());
616 surf
->SetUnicodeMode(SC_CP_UTF8
== ed
->CodePage());
617 surf
->SetDBCSMode(ed
->CodePage());
624 Surface
*operator->() const {
627 operator Surface
*() const {