1 // Scintilla source code edit control
3 ** Defines the main editor class.
5 // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
6 // The License.txt file describes the conditions under which this software may be distributed.
28 enum {tickSize
= 100};
48 friend class LineLayoutCache
;
51 /// Drawing is only performed for @a maxLineLength characters on each line.
55 enum { wrapWidthInfinite
= 0x7ffffff };
58 enum validLevel
{ llInvalid
, llCheckTextAndStyle
, llPositions
, llLines
} validity
;
66 unsigned char *styles
;
70 char bracePreviousStyles
[2];
76 // Wrapped line support
80 LineLayout(int maxLineLength_
);
81 virtual ~LineLayout();
82 void Resize(int maxLineLength_
);
84 void Invalidate(validLevel validity_
);
85 int LineStart(int line
) {
88 } else if ((line
>= lines
) || !lineStarts
) {
89 return numCharsInLine
;
91 return lineStarts
[line
];
94 void SetLineStart(int line
, int start
);
95 void SetBracesHighlight(Range rangeLine
, Position braces
[],
96 char bracesMatchStyle
, int xHighlight
);
97 void RestoreBracesHighlight(Range rangeLine
, Position braces
[]);
102 class LineLayoutCache
{
110 void Allocate(int length_
);
111 void AllocateForLevel(int linesOnScreen
, int linesInDoc
);
114 virtual ~LineLayoutCache();
117 llcNone
=SC_CACHE_NONE
,
118 llcCaret
=SC_CACHE_CARET
,
119 llcPage
=SC_CACHE_PAGE
,
120 llcDocument
=SC_CACHE_DOCUMENT
122 void Invalidate(LineLayout::validLevel validity_
);
123 void SetLevel(int level_
);
124 int GetLevel() { return level
; }
125 LineLayout
*Retrieve(int lineNumber
, int lineCaret
, int maxChars
, int styleClock_
,
126 int linesOnScreen
, int linesInDoc
);
127 void Dispose(LineLayout
*ll
);
131 * Hold a piece of text selected for copying or dragging.
132 * The text is expected to hold a terminating '\0' and this is counted in len.
134 class SelectionText
{
141 SelectionText() : s(0), len(0), rectangular(false), codePage(0), characterSet(0) {}
146 Set(0, 0, 0, 0, false);
148 void Set(char *s_
, int len_
, int codePage_
, int characterSet_
, bool rectangular_
) {
155 codePage
= codePage_
;
156 characterSet
= characterSet_
;
157 rectangular
= rectangular_
;
159 void Copy(const char *s_
, int len_
, int codePage_
, int characterSet_
, bool rectangular_
) {
164 for (int i
= 0; i
< len_
; i
++) {
170 codePage
= codePage_
;
171 characterSet
= characterSet_
;
172 rectangular
= rectangular_
;
174 void Copy(const SelectionText
&other
) {
175 Copy(other
.s
, other
.len
, other
.codePage
, other
.characterSet
, other
.rectangular
);
181 class Editor
: public DocWatcher
{
182 // Private so Editor objects can not be copied
183 Editor(const Editor
&) : DocWatcher() {}
184 Editor
&operator=(const Editor
&) { return *this; }
186 protected: // ScintillaBase subclass needs access to much of Editor
188 /** On GTK+, Scintilla is a container widget holding two scroll bars
189 * whereas on Windows there is just one window with both scroll bars turned on. */
190 Window wMain
; ///< The Scintilla parent window
192 /** Style resources may be expensive to allocate so are cached between uses.
193 * When a style attribute is changed, this cache is flushed. */
198 int printMagnification
;
202 int controlCharSymbol
;
208 bool mouseDownCaptures
;
210 /** In bufferedDraw mode, graphics operations are drawn to a pixmap and then copied to
211 * the screen. This avoids flashing but is about 30% slower. */
213 /** In twoPhaseDraw mode, drawing is performed in two phases, first the background
214 * and then the foreground. This avoids chopping off characters that overlap the next run. */
217 int xOffset
; ///< Horizontal scrolled amount in pixels
218 int xCaretMargin
; ///< Ensure this many pixels visible on both sides of caret
219 bool horizontalScrollBarVisible
;
221 bool verticalScrollBarVisible
;
226 Surface
*pixmapSelMargin
;
227 Surface
*pixmapSelPattern
;
228 Surface
*pixmapIndentGuide
;
229 Surface
*pixmapIndentGuideHighlight
;
237 Timer autoScrollTimer
;
238 enum { autoScrollDelay
= 200 };
243 unsigned int lastClickTime
;
247 enum { selChar
, selWord
, selLine
} selectionType
;
250 bool dropWentOutside
;
255 int originalAnchorPos
;
267 int bracesMatchStyle
;
268 int highlightGuideColumn
;
272 enum { notPainting
, painting
, paintAbandoned
} paintState
;
274 bool paintingAllText
;
279 enum selTypes
{ noSel
, selStream
, selRectangle
, selLines
};
281 bool moveExtendsSelection
;
282 int xStartSelect
; ///< x position of start of rectangular selection
283 int xEndSelect
; ///< x position of end of rectangular selection
284 bool primarySelection
;
287 int caretXSlop
; ///< Ensure this many pixels visible on both sides of caret
290 int caretYSlop
; ///< Ensure this many lines visible on both sides of caret
307 enum { eWrapNone
, eWrapWord
, eWrapChar
} wrapState
;
308 enum { wrapLineLarge
= 0x7ffffff };
313 int wrapVisualFlagsLocation
;
314 int wrapVisualStartIndent
;
315 int actualWrapVisualStartIndent
;
323 virtual void Initialise() = 0;
324 virtual void Finalise();
326 void InvalidateStyleData();
327 void InvalidateStyleRedraw();
328 virtual void RefreshColourPalette(Palette
&pal
, bool want
);
329 void RefreshStyleData();
332 virtual PRectangle
GetClientRectangle();
333 PRectangle
GetTextRectangle();
338 Point
LocationFromPosition(int pos
);
339 int XFromPosition(int pos
);
340 int PositionFromLocation(Point pt
);
341 int PositionFromLocationClose(Point pt
);
342 int PositionFromLineX(int line
, int x
);
343 int LineFromLocation(Point pt
);
344 void SetTopLine(int topLineNew
);
347 void RedrawRect(PRectangle rc
);
349 void RedrawSelMargin(int line
=-1);
350 PRectangle
RectangleFromRange(int start
, int end
);
351 void InvalidateRange(int start
, int end
);
353 int CurrentPosition();
354 bool SelectionEmpty();
355 int SelectionStart();
357 void SetRectangularRange();
358 void InvalidateSelection(int currentPos_
, int anchor_
);
359 void SetSelection(int currentPos_
, int anchor_
);
360 void SetSelection(int currentPos_
);
361 void SetEmptySelection(int currentPos_
);
362 bool RangeContainsProtected(int start
, int end
) const;
363 bool SelectionContainsProtected();
364 int MovePositionOutsideChar(int pos
, int moveDir
, bool checkLineEnd
=true);
365 int MovePositionTo(int newPos
, selTypes sel
=noSel
, bool ensureVisible
=true);
366 int MovePositionSoVisible(int pos
, int moveDir
);
367 void SetLastXChosen();
369 void ScrollTo(int line
, bool moveThumb
=true);
370 virtual void ScrollText(int linesToMove
);
371 void HorizontalScrollTo(int xPos
);
372 void MoveCaretInsideView(bool ensureVisible
=true);
373 int DisplayFromPosition(int pos
);
374 void EnsureCaretVisible(bool useMargin
=true, bool vert
=true, bool horiz
=true);
375 void ShowCaretAtCurrentPosition();
377 void InvalidateCaret();
378 virtual void UpdateSystemCaret();
380 void NeedWrapping(int docLineStart
= 0, int docLineEnd
= wrapLineLarge
);
381 bool WrapLines(bool fullWrap
, int priorityWrapLineStart
);
383 void LinesSplit(int pixelWidth
);
385 int SubstituteMarkerIfEmpty(int markerCheck
, int markerDefault
);
386 void PaintSelMargin(Surface
*surface
, PRectangle
&rc
);
387 LineLayout
*RetrieveLineLayout(int lineNumber
);
388 void LayoutLine(int line
, Surface
*surface
, ViewStyle
&vstyle
, LineLayout
*ll
,
389 int width
=LineLayout::wrapWidthInfinite
);
390 ColourAllocated
SelectionBackground(ViewStyle
&vsDraw
);
391 ColourAllocated
TextBackground(ViewStyle
&vsDraw
, bool overrideBackground
, ColourAllocated background
, bool inSelection
, bool inHotspot
, int styleMain
, int i
, LineLayout
*ll
);
392 void DrawIndentGuide(Surface
*surface
, int lineVisible
, int lineHeight
, int start
, PRectangle rcSegment
, bool highlight
);
393 void DrawWrapMarker(Surface
*surface
, PRectangle rcPlace
, bool isEndMarker
, ColourAllocated wrapColour
);
394 void DrawEOL(Surface
*surface
, ViewStyle
&vsDraw
, PRectangle rcLine
, LineLayout
*ll
,
395 int line
, int lineEnd
, int xStart
, int subLine
, int subLineStart
,
396 bool overrideBackground
, ColourAllocated background
,
397 bool drawWrapMark
, ColourAllocated wrapColour
);
398 void DrawLine(Surface
*surface
, ViewStyle
&vsDraw
, int line
, int lineVisible
, int xStart
,
399 PRectangle rcLine
, LineLayout
*ll
, int subLine
=0);
400 void RefreshPixMaps(Surface
*surfaceWindow
);
401 void Paint(Surface
*surfaceWindow
, PRectangle rcArea
);
402 long FormatRange(bool draw
, RangeToFormat
*pfr
);
403 int TextWidth(int style
, const char *text
);
405 virtual void SetVerticalScrollPos() = 0;
406 virtual void SetHorizontalScrollPos() = 0;
407 virtual bool ModifyScrollBars(int nMax
, int nPage
) = 0;
408 virtual void ReconfigureScrollBars();
409 void SetScrollBars();
412 void AddChar(char ch
);
413 virtual void AddCharUTF(char *s
, unsigned int len
, bool treatAsDBCS
=false);
414 void ClearSelection();
416 void ClearDocumentStyle();
418 void PasteRectangular(int pos
, const char *ptr
, int len
);
419 virtual void Copy() = 0;
420 virtual bool CanPaste();
421 virtual void Paste() = 0;
427 void DelCharBack(bool allowLineStartDeletion
);
428 virtual void ClaimSelection() = 0;
430 virtual void NotifyChange() = 0;
431 virtual void NotifyFocus(bool focus
);
432 virtual int GetCtrlID() { return ctrlID
; }
433 virtual void NotifyParent(SCNotification scn
) = 0;
434 virtual void NotifyStyleToNeeded(int endStyleNeeded
);
435 void NotifyChar(int ch
);
436 void NotifyMove(int position
);
437 void NotifySavePoint(bool isSavePoint
);
438 void NotifyModifyAttempt();
439 virtual void NotifyDoubleClick(Point pt
, bool shift
);
440 void NotifyHotSpotClicked(int position
, bool shift
, bool ctrl
, bool alt
);
441 void NotifyHotSpotDoubleClicked(int position
, bool shift
, bool ctrl
, bool alt
);
442 void NotifyUpdateUI();
443 void NotifyPainted();
444 bool NotifyMarginClick(Point pt
, bool shift
, bool ctrl
, bool alt
);
445 void NotifyNeedShown(int pos
, int len
);
446 void NotifyDwelling(Point pt
, bool state
);
449 void NotifyModifyAttempt(Document
*document
, void *userData
);
450 void NotifySavePoint(Document
*document
, void *userData
, bool atSavePoint
);
451 void CheckModificationForWrap(DocModification mh
);
452 void NotifyModified(Document
*document
, DocModification mh
, void *userData
);
453 void NotifyDeleted(Document
*document
, void *userData
);
454 void NotifyStyleNeeded(Document
*doc
, void *userData
, int endPos
);
455 void NotifyMacroRecord(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
457 void PageMove(int direction
, selTypes sel
=noSel
, bool stuttered
= false);
458 void ChangeCaseOfSelection(bool makeUpperCase
);
459 void LineTranspose();
460 void Duplicate(bool forLine
);
461 virtual void CancelModes();
463 void CursorUpOrDown(int direction
, selTypes sel
=noSel
);
464 void ParaUpOrDown(int direction
, selTypes sel
=noSel
);
465 int StartEndDisplayLine(int pos
, bool start
);
466 virtual int KeyCommand(unsigned int iMessage
);
467 virtual int KeyDefault(int /* key */, int /*modifiers*/);
468 int KeyDown(int key
, bool shift
, bool ctrl
, bool alt
, bool *consumed
=0);
470 int GetWhitespaceVisible();
471 void SetWhitespaceVisible(int view
);
473 void Indent(bool forwards
);
475 long FindText(uptr_t wParam
, sptr_t lParam
);
477 long SearchText(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
478 long SearchInTarget(const char *text
, int length
);
479 void GoToLine(int lineNo
);
481 virtual void CopyToClipboard(const SelectionText
&selectedText
) = 0;
482 char *CopyRange(int start
, int end
);
483 void CopySelectionFromRange(SelectionText
*ss
, int start
, int end
);
484 void CopySelectionRange(SelectionText
*ss
);
485 void CopyRangeToClipboard(int start
, int end
);
486 void CopyText(int length
, const char *text
);
487 void SetDragPosition(int newPos
);
488 virtual void DisplayCursor(Window::Cursor c
);
489 virtual void StartDrag();
490 void DropAt(int position
, const char *value
, bool moving
, bool rectangular
);
491 /** PositionInSelection returns 0 if position in selection, -1 if position before selection, and 1 if after.
492 * Before means either before any line of selection or before selection on its line, with a similar meaning to after. */
493 int PositionInSelection(int pos
);
494 bool PointInSelection(Point pt
);
495 bool PointInSelMargin(Point pt
);
496 void LineSelection(int lineCurrent_
, int lineAnchor_
);
497 void DwellEnd(bool mouseMoved
);
498 virtual void ButtonDown(Point pt
, unsigned int curTime
, bool shift
, bool ctrl
, bool alt
);
499 void ButtonMove(Point pt
);
500 void ButtonUp(Point pt
, unsigned int curTime
, bool ctrl
);
504 virtual void SetTicking(bool on
) = 0;
505 virtual bool SetIdle(bool) { return false; }
506 virtual void SetMouseCapture(bool on
) = 0;
507 virtual bool HaveMouseCapture() = 0;
508 void SetFocusState(bool focusState
);
510 virtual bool PaintContains(PRectangle rc
);
511 bool PaintContainsMargin();
512 void CheckForChangeOutsidePaint(Range r
);
513 void SetBraceHighlight(Position pos0
, Position pos1
, int matchStyle
);
515 void SetDocPointer(Document
*document
);
517 void Expand(int &line
, bool doExpand
);
518 void ToggleContraction(int line
);
519 void EnsureLineVisible(int lineDoc
, bool enforcePolicy
);
520 int ReplaceTarget(bool replacePatterns
, const char *text
, int length
=-1);
522 bool PositionIsHotspot(int position
);
523 bool PointIsHotspot(Point pt
);
524 void SetHotSpotRange(Point
*pt
);
525 void GetHotSpotRange(int& hsStart
, int& hsEnd
);
527 int CodePage() const;
528 virtual bool ValidCodePage(int /* codePage */) const { return true; }
529 int WrapCount(int line
);
531 virtual sptr_t
DefWndProc(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
) = 0;
534 // Public so the COM thunks can access it.
535 bool IsUnicodeMode() const;
536 // Public so scintilla_send_message can use it.
537 virtual sptr_t
WndProc(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
538 // Public so scintilla_set_id can use it.
540 friend class AutoSurface
;
541 friend class SelectionLineIterator
;
545 * A smart pointer class to ensure Surfaces are set up and deleted correctly.
551 AutoSurface(Editor
*ed
) : surf(0) {
552 if (ed
->wMain
.GetID()) {
553 surf
= Surface::Allocate();
555 surf
->Init(ed
->wMain
.GetID());
556 surf
->SetUnicodeMode(SC_CP_UTF8
== ed
->CodePage());
557 surf
->SetDBCSMode(ed
->CodePage());
561 AutoSurface(SurfaceID sid
, Editor
*ed
) : surf(0) {
562 if (ed
->wMain
.GetID()) {
563 surf
= Surface::Allocate();
565 surf
->Init(sid
, ed
->wMain
.GetID());
566 surf
->SetUnicodeMode(SC_CP_UTF8
== ed
->CodePage());
567 surf
->SetDBCSMode(ed
->CodePage());
574 Surface
*operator->() const {
577 operator Surface
*() const {