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 in StyleNeeded to avoid unnecessary work.
57 StyleNeeded() : active(false), upTo(0) {}
62 void NeedUpTo(Position pos
) {
69 * Hold a piece of text selected for copying or dragging.
70 * The text is expected to hold a terminating '\0' and this is counted in len.
80 SelectionText() : s(0), len(0), rectangular(false), lineCopy(false), codePage(0), characterSet(0) {}
85 Set(0, 0, 0, 0, false, false);
87 void Set(char *s_
, int len_
, int codePage_
, int characterSet_
, bool rectangular_
, bool lineCopy_
) {
95 characterSet
= characterSet_
;
96 rectangular
= rectangular_
;
99 void Copy(const char *s_
, int len_
, int codePage_
, int characterSet_
, bool rectangular_
, bool lineCopy_
) {
104 for (int i
= 0; i
< len_
; i
++) {
107 codePage
= codePage_
;
108 characterSet
= characterSet_
;
109 rectangular
= rectangular_
;
110 lineCopy
= lineCopy_
;
112 void Copy(const SelectionText
&other
) {
113 Copy(other
.s
, other
.len
, other
.codePage
, other
.characterSet
, other
.rectangular
, other
.lineCopy
);
119 class Editor
: public DocWatcher
{
120 // Private so Editor objects can not be copied
121 Editor(const Editor
&);
122 Editor
&operator=(const Editor
&);
124 protected: // ScintillaBase subclass needs access to much of Editor
126 /** On GTK+, Scintilla is a container widget holding two scroll bars
127 * whereas on Windows there is just one window with both scroll bars turned on. */
128 Window wMain
; ///< The Scintilla parent window
130 /** Style resources may be expensive to allocate so are cached between uses.
131 * When a style attribute is changed, this cache is flushed. */
137 int printMagnification
;
141 int controlCharSymbol
;
143 // Highlight current folding block
144 HighlightDelimiter highlightDelimiter
;
149 bool mouseDownCaptures
;
151 /** In bufferedDraw mode, graphics operations are drawn to a pixmap and then copied to
152 * the screen. This avoids flashing but is about 30% slower. */
154 /** In twoPhaseDraw mode, drawing is performed in two phases, first the background
155 * and then the foreground. This avoids chopping off characters that overlap the next run. */
158 int xOffset
; ///< Horizontal scrolled amount in pixels
159 int xCaretMargin
; ///< Ensure this many pixels visible on both sides of caret
160 bool horizontalScrollBarVisible
;
163 int lineWidthMaxSeen
;
164 bool verticalScrollBarVisible
;
168 bool multipleSelection
;
169 bool additionalSelectionTyping
;
171 bool additionalCaretsBlink
;
172 bool additionalCaretsVisible
;
174 int virtualSpaceOptions
;
177 Surface
*pixmapSelMargin
;
178 Surface
*pixmapSelPattern
;
179 Surface
*pixmapIndentGuide
;
180 Surface
*pixmapIndentGuideHighlight
;
183 PositionCache posCache
;
189 Timer autoScrollTimer
;
190 enum { autoScrollDelay
= 200 };
195 unsigned int lastClickTime
;
199 enum { selChar
, selWord
, selSubLine
, selWholeLine
} selectionType
;
201 enum { ddNone
, ddInitial
, ddDragging
} inDragDrop
;
202 bool dropWentOutside
;
203 SelectionPosition posDrag
;
204 SelectionPosition posDrop
;
208 int originalAnchorPos
;
209 int wordSelectAnchorStartPos
;
210 int wordSelectAnchorEndPos
;
211 int wordSelectInitialCaretPos
;
221 int bracesMatchStyle
;
222 int highlightGuideColumn
;
226 enum { notPainting
, painting
, paintAbandoned
} paintState
;
228 bool paintingAllText
;
230 StyleNeeded styleNeeded
;
236 bool primarySelection
;
239 int caretXSlop
; ///< Ensure this many pixels visible on both sides of caret
242 int caretYSlop
; ///< Ensure this many lines visible on both sides of caret
259 enum { eWrapNone
, eWrapWord
, eWrapChar
} wrapState
;
260 enum { wrapLineLarge
= 0x7ffffff };
265 int wrapVisualFlagsLocation
;
266 int wrapVisualStartIndent
;
267 XYPOSITION wrapAddIndent
; // This will be added to initial indent of line
268 int wrapIndentMode
; // SC_WRAPINDENT_FIXED, _SAME, _INDENT
276 virtual void Initialise() = 0;
277 virtual void Finalise();
279 void InvalidateStyleData();
280 void InvalidateStyleRedraw();
281 void RefreshStyleData();
282 void DropGraphics(bool freeObjects
);
283 void AllocateGraphics();
285 virtual PRectangle
GetClientRectangle();
286 PRectangle
GetTextRectangle();
291 SelectionPosition
ClampPositionIntoDocument(SelectionPosition sp
) const;
292 Point
LocationFromPosition(SelectionPosition pos
);
293 Point
LocationFromPosition(int pos
);
294 int XFromPosition(int pos
);
295 int XFromPosition(SelectionPosition sp
);
296 SelectionPosition
SPositionFromLocation(Point pt
, bool canReturnInvalid
=false, bool charPosition
=false, bool virtualSpace
=true);
297 int PositionFromLocation(Point pt
, bool canReturnInvalid
=false, bool charPosition
=false);
298 SelectionPosition
SPositionFromLineX(int lineDoc
, int x
);
299 int PositionFromLineX(int line
, int x
);
300 int LineFromLocation(Point pt
);
301 void SetTopLine(int topLineNew
);
304 void RedrawRect(PRectangle rc
);
306 void RedrawSelMargin(int line
=-1, bool allAfter
=false);
307 PRectangle
RectangleFromRange(int start
, int end
);
308 void InvalidateRange(int start
, int end
);
310 bool UserVirtualSpace() const {
311 return ((virtualSpaceOptions
& SCVS_USERACCESSIBLE
) != 0);
313 int CurrentPosition();
314 bool SelectionEmpty();
315 SelectionPosition
SelectionStart();
316 SelectionPosition
SelectionEnd();
317 void SetRectangularRange();
318 void ThinRectangularRange();
319 void InvalidateSelection(SelectionRange newMain
, bool invalidateWholeSelection
=false);
320 void SetSelection(SelectionPosition currentPos_
, SelectionPosition anchor_
);
321 void SetSelection(int currentPos_
, int anchor_
);
322 void SetSelection(SelectionPosition currentPos_
);
323 void SetSelection(int currentPos_
);
324 void SetEmptySelection(SelectionPosition currentPos_
);
325 void SetEmptySelection(int currentPos_
);
326 bool RangeContainsProtected(int start
, int end
) const;
327 bool SelectionContainsProtected();
328 int MovePositionOutsideChar(int pos
, int moveDir
, bool checkLineEnd
=true) const;
329 SelectionPosition
MovePositionOutsideChar(SelectionPosition pos
, int moveDir
, bool checkLineEnd
=true) const;
330 int MovePositionTo(SelectionPosition newPos
, Selection::selTypes sel
=Selection::noSel
, bool ensureVisible
=true);
331 int MovePositionTo(int newPos
, Selection::selTypes sel
=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_
) {}
352 XYScrollPosition
XYScrollToMakeVisible(const bool useMargin
, const bool vert
, const bool horiz
);
353 void SetXYScroll(XYScrollPosition newXY
);
354 void EnsureCaretVisible(bool useMargin
=true, bool vert
=true, bool horiz
=true);
355 void ShowCaretAtCurrentPosition();
357 void InvalidateCaret();
358 virtual void UpdateSystemCaret();
360 void NeedWrapping(int docLineStart
= 0, int docLineEnd
= wrapLineLarge
);
361 bool WrapOneLine(Surface
*surface
, int lineToWrap
);
362 bool WrapLines(bool fullWrap
, int priorityWrapLineStart
);
364 void LinesSplit(int pixelWidth
);
366 int SubstituteMarkerIfEmpty(int markerCheck
, int markerDefault
);
367 void PaintSelMargin(Surface
*surface
, PRectangle
&rc
);
368 LineLayout
*RetrieveLineLayout(int lineNumber
);
369 void LayoutLine(int line
, Surface
*surface
, ViewStyle
&vstyle
, LineLayout
*ll
,
370 int width
=LineLayout::wrapWidthInfinite
);
371 ColourDesired
SelectionBackground(ViewStyle
&vsDraw
, bool main
);
372 ColourDesired
TextBackground(ViewStyle
&vsDraw
, bool overrideBackground
, ColourDesired background
, int inSelection
, bool inHotspot
, int styleMain
, int i
, LineLayout
*ll
);
373 void DrawIndentGuide(Surface
*surface
, int lineVisible
, int lineHeight
, int start
, PRectangle rcSegment
, bool highlight
);
374 void DrawWrapMarker(Surface
*surface
, PRectangle rcPlace
, bool isEndMarker
, ColourDesired wrapColour
);
375 void DrawEOL(Surface
*surface
, ViewStyle
&vsDraw
, PRectangle rcLine
, LineLayout
*ll
,
376 int line
, int lineEnd
, int xStart
, int subLine
, XYACCUMULATOR subLineStart
,
377 bool overrideBackground
, ColourDesired background
,
378 bool drawWrapMark
, ColourDesired wrapColour
);
379 void DrawIndicator(int indicNum
, int startPos
, int endPos
, Surface
*surface
, ViewStyle
&vsDraw
,
380 int xStart
, PRectangle rcLine
, LineLayout
*ll
, int subLine
);
381 void DrawIndicators(Surface
*surface
, ViewStyle
&vsDraw
, int line
, int xStart
,
382 PRectangle rcLine
, LineLayout
*ll
, int subLine
, int lineEnd
, bool under
);
383 void DrawAnnotation(Surface
*surface
, ViewStyle
&vsDraw
, int line
, int xStart
,
384 PRectangle rcLine
, LineLayout
*ll
, int subLine
);
385 void DrawLine(Surface
*surface
, ViewStyle
&vsDraw
, int line
, int lineVisible
, int xStart
,
386 PRectangle rcLine
, LineLayout
*ll
, int subLine
);
387 void DrawBlockCaret(Surface
*surface
, ViewStyle
&vsDraw
, LineLayout
*ll
, int subLine
,
388 int xStart
, int offset
, int posCaret
, PRectangle rcCaret
, ColourDesired caretColour
);
389 void DrawCarets(Surface
*surface
, ViewStyle
&vsDraw
, int line
, int xStart
,
390 PRectangle rcLine
, LineLayout
*ll
, int subLine
);
391 void RefreshPixMaps(Surface
*surfaceWindow
);
392 void Paint(Surface
*surfaceWindow
, PRectangle rcArea
);
393 long FormatRange(bool draw
, Sci_RangeToFormat
*pfr
);
394 int TextWidth(int style
, const char *text
);
396 virtual void SetVerticalScrollPos() = 0;
397 virtual void SetHorizontalScrollPos() = 0;
398 virtual bool ModifyScrollBars(int nMax
, int nPage
) = 0;
399 virtual void ReconfigureScrollBars();
400 void SetScrollBars();
403 void FilterSelections();
404 int InsertSpace(int position
, unsigned int spaces
);
405 void AddChar(char ch
);
406 virtual void AddCharUTF(char *s
, unsigned int len
, bool treatAsDBCS
=false);
407 void InsertPaste(SelectionPosition selStart
, const char *text
, int len
);
408 void ClearSelection(bool retainMultipleSelections
=false);
410 void ClearDocumentStyle();
412 void PasteRectangular(SelectionPosition pos
, const char *ptr
, int len
);
413 virtual void Copy() = 0;
414 virtual void CopyAllowLine();
415 virtual bool CanPaste();
416 virtual void Paste() = 0;
422 void DelCharBack(bool allowLineStartDeletion
);
423 virtual void ClaimSelection() = 0;
425 virtual void NotifyChange() = 0;
426 virtual void NotifyFocus(bool focus
);
427 virtual void SetCtrlID(int identifier
);
428 virtual int GetCtrlID() { return ctrlID
; }
429 virtual void NotifyParent(SCNotification scn
) = 0;
430 virtual void NotifyParent(SCNotification
* scn
) = 0;
431 virtual void NotifyStyleToNeeded(int endStyleNeeded
);
432 void NotifyChar(int ch
);
433 void NotifySavePoint(bool isSavePoint
);
434 void NotifyModifyAttempt();
435 virtual void NotifyDoubleClick(Point pt
, bool shift
, bool ctrl
, bool alt
);
436 void NotifyHotSpotClicked(int position
, bool shift
, bool ctrl
, bool alt
);
437 void NotifyHotSpotDoubleClicked(int position
, bool shift
, bool ctrl
, bool alt
);
438 void NotifyHotSpotReleaseClick(int position
, bool shift
, bool ctrl
, bool alt
);
439 void NotifyUpdateUI();
440 void NotifyPainted();
441 void NotifyIndicatorClick(bool click
, int position
, bool shift
, bool ctrl
, bool alt
);
442 bool NotifyMarginClick(Point pt
, bool shift
, bool ctrl
, bool alt
);
443 void NotifyNeedShown(int pos
, int len
);
444 void NotifyDwelling(Point pt
, bool state
);
447 void NotifyModifyAttempt(Document
*document
, void *userData
);
448 void NotifySavePoint(Document
*document
, void *userData
, bool atSavePoint
);
449 void CheckModificationForWrap(DocModification mh
);
450 void NotifyModified(Document
*document
, DocModification mh
, void *userData
);
451 void NotifyDeleted(Document
*document
, void *userData
);
452 void NotifyStyleNeeded(Document
*doc
, void *userData
, int endPos
);
453 void NotifyLexerChanged(Document
*doc
, void *userData
);
454 void NotifyErrorOccurred(Document
*doc
, void *userData
, int status
);
455 void NotifyMacroRecord(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
457 void ContainerNeedsUpdate(int flags
);
458 void PageMove(int direction
, Selection::selTypes sel
=Selection::noSel
, bool stuttered
= false);
459 enum { cmSame
, cmUpper
, cmLower
} caseMap
;
460 virtual std::string
CaseMapString(const std::string
&s
, int caseMapping
);
461 void ChangeCaseOfSelection(int caseMapping
);
462 void LineTranspose();
463 void Duplicate(bool forLine
);
464 virtual void CancelModes();
466 void CursorUpOrDown(int direction
, Selection::selTypes sel
=Selection::noSel
);
467 void ParaUpOrDown(int direction
, Selection::selTypes sel
=Selection::noSel
);
468 int StartEndDisplayLine(int pos
, bool start
);
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 int KeyDown(int key
, bool shift
, bool ctrl
, bool alt
, bool *consumed
=0);
474 int GetWhitespaceVisible();
475 void SetWhitespaceVisible(int view
);
477 void Indent(bool forwards
);
479 virtual CaseFolder
*CaseFolderForEncoding();
480 long FindText(uptr_t wParam
, sptr_t lParam
);
482 long SearchText(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
483 long SearchInTarget(const char *text
, int length
);
484 void GoToLine(int lineNo
);
486 virtual void CopyToClipboard(const SelectionText
&selectedText
) = 0;
487 char *CopyRange(int start
, int end
);
488 void CopySelectionRange(SelectionText
*ss
, bool allowLineCopy
=false);
489 void CopyRangeToClipboard(int start
, int end
);
490 void CopyText(int length
, const char *text
);
491 void SetDragPosition(SelectionPosition newPos
);
492 virtual void DisplayCursor(Window::Cursor c
);
493 virtual bool DragThreshold(Point ptStart
, Point ptNow
);
494 virtual void StartDrag();
495 void DropAt(SelectionPosition position
, const char *value
, bool moving
, bool rectangular
);
496 /** PositionInSelection returns true if position in selection. */
497 bool PositionInSelection(int pos
);
498 bool PointInSelection(Point pt
);
499 bool PointInSelMargin(Point pt
);
500 Window::Cursor
GetMarginCursor(Point pt
);
501 void LineSelection(int lineCurrentPos_
, int lineAnchorPos_
, bool wholeLine
);
502 void WordSelection(int pos
);
503 void DwellEnd(bool mouseMoved
);
505 virtual void ButtonDown(Point pt
, unsigned int curTime
, bool shift
, bool ctrl
, bool alt
);
506 void ButtonMove(Point pt
);
507 void ButtonUp(Point pt
, unsigned int curTime
, bool ctrl
);
511 virtual void SetTicking(bool on
) = 0;
512 virtual bool SetIdle(bool) { return false; }
513 virtual void SetMouseCapture(bool on
) = 0;
514 virtual bool HaveMouseCapture() = 0;
515 void SetFocusState(bool focusState
);
517 int PositionAfterArea(PRectangle rcArea
);
518 void StyleToPositionInView(Position pos
);
520 virtual void QueueStyling(int upTo
);
522 virtual bool PaintContains(PRectangle rc
);
523 bool PaintContainsMargin();
524 void CheckForChangeOutsidePaint(Range r
);
525 void SetBraceHighlight(Position pos0
, Position pos1
, int matchStyle
);
527 void SetAnnotationHeights(int start
, int end
);
528 void SetDocPointer(Document
*document
);
530 void SetAnnotationVisible(int visible
);
532 void Expand(int &line
, bool doExpand
);
533 void ToggleContraction(int line
);
534 int ContractedFoldNext(int lineStart
);
535 void EnsureLineVisible(int lineDoc
, bool enforcePolicy
);
536 int GetTag(char *tagValue
, int tagNumber
);
537 int ReplaceTarget(bool replacePatterns
, const char *text
, int length
=-1);
539 bool PositionIsHotspot(int position
);
540 bool PointIsHotspot(Point pt
);
541 void SetHotSpotRange(Point
*pt
);
542 void GetHotSpotRange(int &hsStart
, int &hsEnd
);
544 int CodePage() const;
545 virtual bool ValidCodePage(int /* codePage */) const { return true; }
546 int WrapCount(int line
);
547 void AddStyledText(char *buffer
, int appendLength
);
549 virtual sptr_t
DefWndProc(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
) = 0;
550 void StyleSetMessage(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
551 sptr_t
StyleGetMessage(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
553 static const char *StringFromEOLMode(int eolMode
);
555 static sptr_t
StringResult(sptr_t lParam
, const char *val
);
558 // Public so the COM thunks can access it.
559 bool IsUnicodeMode() const;
560 // Public so scintilla_send_message can use it.
561 virtual sptr_t
WndProc(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
562 // Public so scintilla_set_id can use it.
564 // Public so COM methods for drag and drop can set it.
566 friend class AutoSurface
;
567 friend class SelectionLineIterator
;
571 * A smart pointer class to ensure Surfaces are set up and deleted correctly.
577 AutoSurface(Editor
*ed
) : surf(0) {
578 if (ed
->wMain
.GetID()) {
579 surf
= Surface::Allocate(ed
->technology
);
581 surf
->Init(ed
->wMain
.GetID());
582 surf
->SetUnicodeMode(SC_CP_UTF8
== ed
->CodePage());
583 surf
->SetDBCSMode(ed
->CodePage());
587 AutoSurface(SurfaceID sid
, Editor
*ed
) : surf(0) {
588 if (ed
->wMain
.GetID()) {
589 surf
= Surface::Allocate(ed
->technology
);
591 surf
->Init(sid
, ed
->wMain
.GetID());
592 surf
->SetUnicodeMode(SC_CP_UTF8
== ed
->CodePage());
593 surf
->SetDBCSMode(ed
->CodePage());
600 Surface
*operator->() const {
603 operator Surface
*() const {