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.
32 enum {tickSize
= 100};
49 * When platform has a way to generate an event before painting,
50 * accumulate needed styling range and other work items in
51 * WorkNeeded to avoid unnecessary work inside paint handler
64 WorkNeeded() : active(false), items(workNone
), upTo(0) {}
70 void Need(workItems items_
, Position pos
) {
71 if ((items_
& workStyle
) && (upTo
< pos
))
73 items
= static_cast<workItems
>(items
| items_
);
78 * Hold a piece of text selected for copying or dragging.
79 * The text is expected to hold a terminating '\0' and this is counted in len.
89 SelectionText() : s(0), len(0), rectangular(false), lineCopy(false), codePage(0), characterSet(0) {}
94 Set(0, 0, 0, 0, false, false);
96 void Set(char *s_
, int len_
, int codePage_
, int characterSet_
, bool rectangular_
, bool lineCopy_
) {
103 codePage
= codePage_
;
104 characterSet
= characterSet_
;
105 rectangular
= rectangular_
;
106 lineCopy
= lineCopy_
;
107 FixSelectionForClipboard();
109 void Copy(const char *s_
, int len_
, int codePage_
, int characterSet_
, bool rectangular_
, bool lineCopy_
) {
114 for (int i
= 0; i
< len_
; i
++) {
117 codePage
= codePage_
;
118 characterSet
= characterSet_
;
119 rectangular
= rectangular_
;
120 lineCopy
= lineCopy_
;
121 FixSelectionForClipboard();
123 void Copy(const SelectionText
&other
) {
124 Copy(other
.s
, other
.len
, other
.codePage
, other
.characterSet
, other
.rectangular
, other
.lineCopy
);
128 void FixSelectionForClipboard() {
129 // Replace null characters by spaces.
130 // To avoid that the content of the clipboard is truncated in the paste operation
131 // when the clipboard contains null characters.
132 for (int i
= 0; i
< len
- 1; ++i
) {
141 class Editor
: public DocWatcher
{
142 // Private so Editor objects can not be copied
143 Editor(const Editor
&);
144 Editor
&operator=(const Editor
&);
146 protected: // ScintillaBase subclass needs access to much of Editor
148 /** On GTK+, Scintilla is a container widget holding two scroll bars
149 * whereas on Windows there is just one window with both scroll bars turned on. */
150 Window wMain
; ///< The Scintilla parent window
151 Window wMargin
; ///< May be separate when using a scroll view for wMain
153 /** Style resources may be expensive to allocate so are cached between uses.
154 * When a style attribute is changed, this cache is flushed. */
159 float scaleRGBAImage
;
161 int printMagnification
;
165 int controlCharSymbol
;
167 // Highlight current folding block
168 HighlightDelimiter highlightDelimiter
;
173 bool mouseDownCaptures
;
175 /** In bufferedDraw mode, graphics operations are drawn to a pixmap and then copied to
176 * the screen. This avoids flashing but is about 30% slower. */
178 /** In twoPhaseDraw mode, drawing is performed in two phases, first the background
179 * and then the foreground. This avoids chopping off characters that overlap the next run. */
182 int xOffset
; ///< Horizontal scrolled amount in pixels
183 int xCaretMargin
; ///< Ensure this many pixels visible on both sides of caret
184 bool horizontalScrollBarVisible
;
187 int lineWidthMaxSeen
;
188 bool verticalScrollBarVisible
;
192 bool multipleSelection
;
193 bool additionalSelectionTyping
;
195 bool additionalCaretsBlink
;
196 bool additionalCaretsVisible
;
198 int virtualSpaceOptions
;
201 Surface
*pixmapSelMargin
;
202 Surface
*pixmapSelPattern
;
203 Surface
*pixmapSelPatternOffset1
;
204 Surface
*pixmapIndentGuide
;
205 Surface
*pixmapIndentGuideHighlight
;
208 PositionCache posCache
;
214 Timer autoScrollTimer
;
215 enum { autoScrollDelay
= 200 };
220 unsigned int lastClickTime
;
224 enum { selChar
, selWord
, selSubLine
, selWholeLine
} selectionType
;
226 enum { ddNone
, ddInitial
, ddDragging
} inDragDrop
;
227 bool dropWentOutside
;
228 SelectionPosition posDrag
;
229 SelectionPosition posDrop
;
233 int originalAnchorPos
;
234 int wordSelectAnchorStartPos
;
235 int wordSelectAnchorEndPos
;
236 int wordSelectInitialCaretPos
;
246 int bracesMatchStyle
;
247 int highlightGuideColumn
;
251 enum { notPainting
, painting
, paintAbandoned
} paintState
;
253 bool paintingAllText
;
255 WorkNeeded workNeeded
;
261 bool primarySelection
;
264 int caretXSlop
; ///< Ensure this many pixels visible on both sides of caret
267 int caretYSlop
; ///< Ensure this many lines visible on both sides of caret
284 enum { eWrapNone
, eWrapWord
, eWrapChar
} wrapState
;
285 enum { wrapLineLarge
= 0x7ffffff };
290 int wrapVisualFlagsLocation
;
291 int wrapVisualStartIndent
;
292 int wrapIndentMode
; // SC_WRAPINDENT_FIXED, _SAME, _INDENT
296 int marginNumberPadding
; // the right-side padding of the number margin
297 int ctrlCharPadding
; // the padding around control character text blobs
298 int lastSegItalicsOffset
; // the offset so as not to clip italic characters at EOLs
304 virtual void Initialise() = 0;
305 virtual void Finalise();
307 void InvalidateStyleData();
308 void InvalidateStyleRedraw();
309 void RefreshStyleData();
310 void DropGraphics(bool freeObjects
);
311 void AllocateGraphics();
313 // The top left visible point in main window coordinates. Will be 0,0 except for
314 // scroll views where it will be equivalent to the current scroll position.
315 virtual Point
GetVisibleOriginInMain();
316 Point
DocumentPointFromView(Point ptView
); // Convert a point from view space to document
317 int TopLineOfMain(); // Return the line at Main's y coordinate 0
318 virtual PRectangle
GetClientRectangle();
319 PRectangle
GetTextRectangle();
324 SelectionPosition
ClampPositionIntoDocument(SelectionPosition sp
) const;
325 Point
LocationFromPosition(SelectionPosition pos
);
326 Point
LocationFromPosition(int pos
);
327 int XFromPosition(int pos
);
328 int XFromPosition(SelectionPosition sp
);
329 SelectionPosition
SPositionFromLocation(Point pt
, bool canReturnInvalid
=false, bool charPosition
=false, bool virtualSpace
=true);
330 int PositionFromLocation(Point pt
, bool canReturnInvalid
=false, bool charPosition
=false);
331 SelectionPosition
SPositionFromLineX(int lineDoc
, int x
);
332 int PositionFromLineX(int line
, int x
);
333 int LineFromLocation(Point pt
);
334 void SetTopLine(int topLineNew
);
337 void RedrawRect(PRectangle rc
);
339 void RedrawSelMargin(int line
=-1, bool allAfter
=false);
340 PRectangle
RectangleFromRange(int start
, int end
);
341 void InvalidateRange(int start
, int end
);
343 bool UserVirtualSpace() const {
344 return ((virtualSpaceOptions
& SCVS_USERACCESSIBLE
) != 0);
346 int CurrentPosition();
347 bool SelectionEmpty();
348 SelectionPosition
SelectionStart();
349 SelectionPosition
SelectionEnd();
350 void SetRectangularRange();
351 void ThinRectangularRange();
352 void InvalidateSelection(SelectionRange newMain
, bool invalidateWholeSelection
=false);
353 void SetSelection(SelectionPosition currentPos_
, SelectionPosition anchor_
);
354 void SetSelection(int currentPos_
, int anchor_
);
355 void SetSelection(SelectionPosition currentPos_
);
356 void SetSelection(int currentPos_
);
357 void SetEmptySelection(SelectionPosition currentPos_
);
358 void SetEmptySelection(int currentPos_
);
359 bool RangeContainsProtected(int start
, int end
) const;
360 bool SelectionContainsProtected();
361 int MovePositionOutsideChar(int pos
, int moveDir
, bool checkLineEnd
=true) const;
362 SelectionPosition
MovePositionOutsideChar(SelectionPosition pos
, int moveDir
, bool checkLineEnd
=true) const;
363 int MovePositionTo(SelectionPosition newPos
, Selection::selTypes sel
=Selection::noSel
, bool ensureVisible
=true);
364 int MovePositionTo(int newPos
, Selection::selTypes sel
=Selection::noSel
, bool ensureVisible
=true);
365 SelectionPosition
MovePositionSoVisible(SelectionPosition pos
, int moveDir
);
366 SelectionPosition
MovePositionSoVisible(int pos
, int moveDir
);
367 Point
PointMainCaret();
368 void SetLastXChosen();
370 void ScrollTo(int line
, bool moveThumb
=true);
371 virtual void ScrollText(int linesToMove
);
372 void HorizontalScrollTo(int xPos
);
373 void VerticalCentreCaret();
374 void MoveSelectedLines(int lineDelta
);
375 void MoveSelectedLinesUp();
376 void MoveSelectedLinesDown();
377 void MoveCaretInsideView(bool ensureVisible
=true);
378 int DisplayFromPosition(int pos
);
380 struct XYScrollPosition
{
383 XYScrollPosition(int xOffset_
, int topLine_
) : xOffset(xOffset_
), topLine(topLine_
) {}
384 bool operator==(const XYScrollPosition
&other
) const {
385 return (xOffset
== other
.xOffset
) && (topLine
== other
.topLine
);
388 enum XYScrollOptions
{
392 xysDefault
=xysUseMargin
|xysVertical
|xysHorizontal
};
393 XYScrollPosition
XYScrollToMakeVisible(const SelectionRange range
, const XYScrollOptions options
);
394 void SetXYScroll(XYScrollPosition newXY
);
395 void EnsureCaretVisible(bool useMargin
=true, bool vert
=true, bool horiz
=true);
396 void ScrollRange(SelectionRange range
);
397 void ShowCaretAtCurrentPosition();
399 void InvalidateCaret();
400 virtual void UpdateSystemCaret();
402 void NeedWrapping(int docLineStart
= 0, int docLineEnd
= wrapLineLarge
);
403 bool WrapOneLine(Surface
*surface
, int lineToWrap
);
404 bool WrapLines(bool fullWrap
, int priorityWrapLineStart
);
406 void LinesSplit(int pixelWidth
);
408 int SubstituteMarkerIfEmpty(int markerCheck
, int markerDefault
);
409 void PaintSelMargin(Surface
*surface
, PRectangle
&rc
);
410 LineLayout
*RetrieveLineLayout(int lineNumber
);
411 void LayoutLine(int line
, Surface
*surface
, ViewStyle
&vstyle
, LineLayout
*ll
,
412 int width
=LineLayout::wrapWidthInfinite
);
413 ColourDesired
SelectionBackground(ViewStyle
&vsDraw
, bool main
);
414 ColourDesired
TextBackground(ViewStyle
&vsDraw
, bool overrideBackground
, ColourDesired background
, int inSelection
, bool inHotspot
, int styleMain
, int i
, LineLayout
*ll
);
415 void DrawIndentGuide(Surface
*surface
, int lineVisible
, int lineHeight
, int start
, PRectangle rcSegment
, bool highlight
);
416 void DrawWrapMarker(Surface
*surface
, PRectangle rcPlace
, bool isEndMarker
, ColourDesired wrapColour
);
417 void DrawEOL(Surface
*surface
, ViewStyle
&vsDraw
, PRectangle rcLine
, LineLayout
*ll
,
418 int line
, int lineEnd
, int xStart
, int subLine
, XYACCUMULATOR subLineStart
,
419 bool overrideBackground
, ColourDesired background
,
420 bool drawWrapMark
, ColourDesired wrapColour
);
421 void DrawIndicator(int indicNum
, int startPos
, int endPos
, Surface
*surface
, ViewStyle
&vsDraw
,
422 int xStart
, PRectangle rcLine
, LineLayout
*ll
, int subLine
);
423 void DrawIndicators(Surface
*surface
, ViewStyle
&vsDraw
, int line
, int xStart
,
424 PRectangle rcLine
, LineLayout
*ll
, int subLine
, int lineEnd
, bool under
);
425 void DrawAnnotation(Surface
*surface
, ViewStyle
&vsDraw
, int line
, int xStart
,
426 PRectangle rcLine
, LineLayout
*ll
, int subLine
);
427 void DrawLine(Surface
*surface
, ViewStyle
&vsDraw
, int line
, int lineVisible
, int xStart
,
428 PRectangle rcLine
, LineLayout
*ll
, int subLine
);
429 void DrawBlockCaret(Surface
*surface
, ViewStyle
&vsDraw
, LineLayout
*ll
, int subLine
,
430 int xStart
, int offset
, int posCaret
, PRectangle rcCaret
, ColourDesired caretColour
);
431 void DrawCarets(Surface
*surface
, ViewStyle
&vsDraw
, int line
, int xStart
,
432 PRectangle rcLine
, LineLayout
*ll
, int subLine
);
433 void RefreshPixMaps(Surface
*surfaceWindow
);
434 void Paint(Surface
*surfaceWindow
, PRectangle rcArea
);
435 long FormatRange(bool draw
, Sci_RangeToFormat
*pfr
);
436 int TextWidth(int style
, const char *text
);
438 virtual void SetVerticalScrollPos() = 0;
439 virtual void SetHorizontalScrollPos() = 0;
440 virtual bool ModifyScrollBars(int nMax
, int nPage
) = 0;
441 virtual void ReconfigureScrollBars();
442 void SetScrollBars();
445 void FilterSelections();
446 int InsertSpace(int position
, unsigned int spaces
);
447 void AddChar(char ch
);
448 virtual void AddCharUTF(char *s
, unsigned int len
, bool treatAsDBCS
=false);
449 void InsertPaste(SelectionPosition selStart
, const char *text
, int len
);
450 void ClearSelection(bool retainMultipleSelections
=false);
452 void ClearDocumentStyle();
454 void PasteRectangular(SelectionPosition pos
, const char *ptr
, int len
);
455 virtual void Copy() = 0;
456 virtual void CopyAllowLine();
457 virtual bool CanPaste();
458 virtual void Paste() = 0;
464 void DelCharBack(bool allowLineStartDeletion
);
465 virtual void ClaimSelection() = 0;
467 virtual void NotifyChange() = 0;
468 virtual void NotifyFocus(bool focus
);
469 virtual void SetCtrlID(int identifier
);
470 virtual int GetCtrlID() { return ctrlID
; }
471 virtual void NotifyParent(SCNotification scn
) = 0;
472 virtual void NotifyParent(SCNotification
* scn
) = 0;
473 virtual void NotifyStyleToNeeded(int endStyleNeeded
);
474 void NotifyChar(int ch
);
475 void NotifySavePoint(bool isSavePoint
);
476 void NotifyModifyAttempt();
477 virtual void NotifyDoubleClick(Point pt
, bool shift
, bool ctrl
, bool alt
);
478 void NotifyHotSpotClicked(int position
, bool shift
, bool ctrl
, bool alt
);
479 void NotifyHotSpotDoubleClicked(int position
, bool shift
, bool ctrl
, bool alt
);
480 void NotifyHotSpotReleaseClick(int position
, bool shift
, bool ctrl
, bool alt
);
481 bool NotifyUpdateUI();
482 void NotifyPainted();
483 void NotifyIndicatorClick(bool click
, int position
, bool shift
, bool ctrl
, bool alt
);
484 bool NotifyMarginClick(Point pt
, bool shift
, bool ctrl
, bool alt
);
485 void NotifyNeedShown(int pos
, int len
);
486 void NotifyDwelling(Point pt
, bool state
);
489 void NotifyModifyAttempt(Document
*document
, void *userData
);
490 void NotifySavePoint(Document
*document
, void *userData
, bool atSavePoint
);
491 void CheckModificationForWrap(DocModification mh
);
492 void NotifyModified(Document
*document
, DocModification mh
, void *userData
);
493 void NotifyDeleted(Document
*document
, void *userData
);
494 void NotifyStyleNeeded(Document
*doc
, void *userData
, int endPos
);
495 void NotifyLexerChanged(Document
*doc
, void *userData
);
496 void NotifyErrorOccurred(Document
*doc
, void *userData
, int status
);
497 void NotifyMacroRecord(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
499 void ContainerNeedsUpdate(int flags
);
500 void PageMove(int direction
, Selection::selTypes sel
=Selection::noSel
, bool stuttered
= false);
501 enum { cmSame
, cmUpper
, cmLower
} caseMap
;
502 virtual std::string
CaseMapString(const std::string
&s
, int caseMapping
);
503 void ChangeCaseOfSelection(int caseMapping
);
504 void LineTranspose();
505 void Duplicate(bool forLine
);
506 virtual void CancelModes();
508 void CursorUpOrDown(int direction
, Selection::selTypes sel
=Selection::noSel
);
509 void ParaUpOrDown(int direction
, Selection::selTypes sel
=Selection::noSel
);
510 int StartEndDisplayLine(int pos
, bool start
);
511 virtual int KeyCommand(unsigned int iMessage
);
512 virtual int KeyDefault(int /* key */, int /*modifiers*/);
513 int KeyDownWithModifiers(int key
, int modifiers
, bool *consumed
);
514 int KeyDown(int key
, bool shift
, bool ctrl
, bool alt
, bool *consumed
=0);
516 void Indent(bool forwards
);
518 virtual CaseFolder
*CaseFolderForEncoding();
519 long FindText(uptr_t wParam
, sptr_t lParam
);
521 long SearchText(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
522 long SearchInTarget(const char *text
, int length
);
523 void GoToLine(int lineNo
);
525 virtual void CopyToClipboard(const SelectionText
&selectedText
) = 0;
526 char *CopyRange(int start
, int end
);
527 std::string
RangeText(int start
, int end
) const;
528 void CopySelectionRange(SelectionText
*ss
, bool allowLineCopy
=false);
529 void CopyRangeToClipboard(int start
, int end
);
530 void CopyText(int length
, const char *text
);
531 void SetDragPosition(SelectionPosition newPos
);
532 virtual void DisplayCursor(Window::Cursor c
);
533 virtual bool DragThreshold(Point ptStart
, Point ptNow
);
534 virtual void StartDrag();
535 void DropAt(SelectionPosition position
, const char *value
, bool moving
, bool rectangular
);
536 /** PositionInSelection returns true if position in selection. */
537 bool PositionInSelection(int pos
);
538 bool PointInSelection(Point pt
);
539 bool PointInSelMargin(Point pt
);
540 Window::Cursor
GetMarginCursor(Point pt
);
541 void TrimAndSetSelection(int currentPos_
, int anchor_
);
542 void LineSelection(int lineCurrentPos_
, int lineAnchorPos_
, bool wholeLine
);
543 void WordSelection(int pos
);
544 void DwellEnd(bool mouseMoved
);
546 virtual void ButtonDown(Point pt
, unsigned int curTime
, bool shift
, bool ctrl
, bool alt
);
547 void ButtonMove(Point pt
);
548 void ButtonUp(Point pt
, unsigned int curTime
, bool ctrl
);
552 virtual void SetTicking(bool on
) = 0;
553 virtual bool SetIdle(bool) { return false; }
554 virtual void SetMouseCapture(bool on
) = 0;
555 virtual bool HaveMouseCapture() = 0;
556 void SetFocusState(bool focusState
);
558 int PositionAfterArea(PRectangle rcArea
);
559 void StyleToPositionInView(Position pos
);
560 virtual void IdleWork();
561 virtual void QueueIdleWork(WorkNeeded::workItems items
, int upTo
=0);
563 virtual bool PaintContains(PRectangle rc
);
564 bool PaintContainsMargin();
565 void CheckForChangeOutsidePaint(Range r
);
566 void SetBraceHighlight(Position pos0
, Position pos1
, int matchStyle
);
568 void SetAnnotationHeights(int start
, int end
);
569 void SetDocPointer(Document
*document
);
571 void SetAnnotationVisible(int visible
);
573 void Expand(int &line
, bool doExpand
);
574 void ToggleContraction(int line
);
575 int ContractedFoldNext(int lineStart
);
576 void EnsureLineVisible(int lineDoc
, bool enforcePolicy
);
577 int GetTag(char *tagValue
, int tagNumber
);
578 int ReplaceTarget(bool replacePatterns
, const char *text
, int length
=-1);
580 bool PositionIsHotspot(int position
);
581 bool PointIsHotspot(Point pt
);
582 void SetHotSpotRange(Point
*pt
);
583 void GetHotSpotRange(int &hsStart
, int &hsEnd
);
585 int CodePage() const;
586 virtual bool ValidCodePage(int /* codePage */) const { return true; }
587 int WrapCount(int line
);
588 void AddStyledText(char *buffer
, int appendLength
);
590 virtual sptr_t
DefWndProc(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
) = 0;
591 void StyleSetMessage(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
592 sptr_t
StyleGetMessage(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
594 static const char *StringFromEOLMode(int eolMode
);
596 static sptr_t
StringResult(sptr_t lParam
, const char *val
);
599 // Public so the COM thunks can access it.
600 bool IsUnicodeMode() const;
601 // Public so scintilla_send_message can use it.
602 virtual sptr_t
WndProc(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
603 // Public so scintilla_set_id can use it.
605 // Public so COM methods for drag and drop can set it.
607 friend class AutoSurface
;
608 friend class SelectionLineIterator
;
612 * A smart pointer class to ensure Surfaces are set up and deleted correctly.
618 AutoSurface(Editor
*ed
, int technology
= -1) : surf(0) {
619 if (ed
->wMain
.GetID()) {
620 surf
= Surface::Allocate(technology
!= -1 ? technology
: ed
->technology
);
622 surf
->Init(ed
->wMain
.GetID());
623 surf
->SetUnicodeMode(SC_CP_UTF8
== ed
->CodePage());
624 surf
->SetDBCSMode(ed
->CodePage());
628 AutoSurface(SurfaceID sid
, Editor
*ed
, int technology
= -1) : surf(0) {
629 if (ed
->wMain
.GetID()) {
630 surf
= Surface::Allocate(technology
!= -1 ? technology
: ed
->technology
);
632 surf
->Init(sid
, ed
->wMain
.GetID());
633 surf
->SetUnicodeMode(SC_CP_UTF8
== ed
->CodePage());
634 surf
->SetDBCSMode(ed
->CodePage());
641 Surface
*operator->() const {
644 operator Surface
*() const {