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};
38 friend class LineLayoutCache
;
41 /// Drawing is only performed for @a maxLineLength characters on each line.
45 enum { wrapWidthInfinite
= 0x7ffffff };
48 enum validLevel
{ llInvalid
, llCheckTextAndStyle
, llPositions
, llLines
} validity
;
59 char bracePreviousStyles
[2];
65 // Wrapped line support
69 LineLayout(int maxLineLength_
);
70 virtual ~LineLayout();
71 void Resize(int maxLineLength_
);
73 void Invalidate(validLevel validity_
);
74 int LineStart(int line
) {
77 } else if ((line
>= lines
) || !lineStarts
) {
78 return numCharsInLine
;
80 return lineStarts
[line
];
83 void SetLineStart(int line
, int start
);
84 void SetBracesHighlight(Range rangeLine
, Position braces
[],
85 char bracesMatchStyle
, int xHighlight
);
86 void RestoreBracesHighlight(Range rangeLine
, Position braces
[]);
91 class LineLayoutCache
{
98 void Allocate(int length_
);
99 void AllocateForLevel(int linesOnScreen
, int linesInDoc
);
102 virtual ~LineLayoutCache();
105 llcNone
=SC_CACHE_NONE
,
106 llcCaret
=SC_CACHE_CARET
,
107 llcPage
=SC_CACHE_PAGE
,
108 llcDocument
=SC_CACHE_DOCUMENT
110 void Invalidate(LineLayout::validLevel validity_
);
111 void SetLevel(int level_
);
112 int GetLevel() { return level
; }
113 LineLayout
*Retrieve(int lineNumber
, int lineCaret
, int maxChars
, int styleClock_
,
114 int linesOnScreen
, int linesInDoc
);
115 void Dispose(LineLayout
*ll
);
118 class SelectionText
{
123 SelectionText() : s(0), len(0), rectangular(false) {}
127 void Set(char *s_
, int len_
, bool rectangular_
=false) {
134 rectangular
= rectangular_
;
140 class Editor
: public DocWatcher
{
141 // Private so Editor objects can not be copied
142 Editor(const Editor
&) : DocWatcher() {}
143 Editor
&operator=(const Editor
&) { return *this; }
145 protected: // ScintillaBase subclass needs access to much of Editor
147 /** On GTK+, Scintilla is a container widget holding two scroll bars
148 * whereas on Windows there is just one window with both scroll bars turned on. */
149 Window wMain
; ///< The Scintilla parent window
151 /** Style resources may be expensive to allocate so are cached between uses.
152 * When a style attribute is changed, this cache is flushed. */
157 int printMagnification
;
161 int controlCharSymbol
;
167 bool mouseDownCaptures
;
169 /** In bufferedDraw mode, graphics operations are drawn to a pixmap and then copied to
170 * the screen. This avoids flashing but is about 30% slower. */
172 /** In twoPhaseDraw mode, drawing is performed in two phases, first the background
173 * and then the foreground. This avoids chopping off characters that overlap the next run. */
176 int xOffset
; ///< Horizontal scrolled amount in pixels
177 int xCaretMargin
; ///< Ensure this many pixels visible on both sides of caret
178 bool horizontalScrollBarVisible
;
180 bool verticalScrollBarVisible
;
184 Surface
*pixmapSelMargin
;
185 Surface
*pixmapSelPattern
;
186 Surface
*pixmapIndentGuide
;
187 Surface
*pixmapIndentGuideHighlight
;
195 Timer autoScrollTimer
;
196 enum { autoScrollDelay
= 200 };
199 unsigned int lastClickTime
;
203 enum { selChar
, selWord
, selLine
} selectionType
;
206 bool dropWentOutside
;
211 int originalAnchorPos
;
222 int bracesMatchStyle
;
223 int highlightGuideColumn
;
227 enum { notPainting
, painting
, paintAbandoned
} paintState
;
229 bool paintingAllText
;
234 enum { selStream
, selRectangle
, selRectangleFixed
} selType
;
237 bool primarySelection
;
240 int caretXSlop
; ///< Ensure this many pixels visible on both sides of caret
243 int caretYSlop
; ///< Ensure this many lines visible on both sides of caret
260 enum { eWrapNone
, eWrapWord
} wrapState
;
262 int docLineLastWrapped
;
268 virtual void Initialise() = 0;
269 virtual void Finalise();
271 void InvalidateStyleData();
272 void InvalidateStyleRedraw();
273 virtual void RefreshColourPalette(Palette
&pal
, bool want
);
274 void RefreshStyleData();
277 virtual PRectangle
GetClientRectangle();
278 PRectangle
GetTextRectangle();
283 Point
LocationFromPosition(int pos
);
284 int XFromPosition(int pos
);
285 int PositionFromLocation(Point pt
);
286 int PositionFromLocationClose(Point pt
);
287 int PositionFromLineX(int line
, int x
);
288 int LineFromLocation(Point pt
);
289 void SetTopLine(int topLineNew
);
292 void RedrawRect(PRectangle rc
);
294 void RedrawSelMargin();
295 PRectangle
RectangleFromRange(int start
, int end
);
296 void InvalidateRange(int start
, int end
);
298 int CurrentPosition();
299 bool SelectionEmpty();
300 int SelectionStart(int line
=-1);
301 int SelectionEnd(int line
=-1);
302 void SetSelection(int currentPos_
, int anchor_
);
303 void SetSelection(int currentPos_
);
304 void SetEmptySelection(int currentPos_
);
305 bool RangeContainsProtected(int start
, int end
) const;
306 bool SelectionContainsProtected() const;
307 int MovePositionOutsideChar(int pos
, int moveDir
, bool checkLineEnd
=true);
308 int MovePositionTo(int newPos
, bool extend
=false, bool ensureVisible
=true);
309 int MovePositionSoVisible(int pos
, int moveDir
);
310 void SetLastXChosen();
312 void ScrollTo(int line
, bool moveThumb
=true);
313 virtual void ScrollText(int linesToMove
);
314 void HorizontalScrollTo(int xPos
);
315 void MoveCaretInsideView(bool ensureVisible
=true);
316 int DisplayFromPosition(int pos
);
317 void EnsureCaretVisible(bool useMargin
=true, bool vert
=true, bool horiz
=true);
318 void ShowCaretAtCurrentPosition();
320 void InvalidateCaret();
322 void NeedWrapping(int docLineStartWrapping
=0);
325 void LinesSplit(int pixelWidth
);
327 int SubstituteMarkerIfEmpty(int markerCheck
, int markerDefault
);
328 void PaintSelMargin(Surface
*surface
, PRectangle
&rc
);
329 LineLayout
*RetrieveLineLayout(int lineNumber
);
330 void LayoutLine(int line
, Surface
*surface
, ViewStyle
&vstyle
, LineLayout
*ll
,
331 int width
=LineLayout::wrapWidthInfinite
);
332 ColourAllocated
TextBackground(ViewStyle
&vsDraw
, bool overrideBackground
, ColourAllocated background
, bool inSelection
, bool inHotspot
, int styleMain
, int i
, LineLayout
*ll
);
333 void DrawIndentGuide(Surface
*surface
, int lineVisible
, int lineHeight
, int start
, PRectangle rcSegment
, bool highlight
);
334 void DrawEOL(Surface
*surface
, ViewStyle
&vsDraw
, PRectangle rcLine
, LineLayout
*ll
,
335 int line
, int lineEnd
, int xStart
, int subLine
, int subLineStart
,
336 bool overrideBackground
, ColourAllocated background
);
337 void DrawLine(Surface
*surface
, ViewStyle
&vsDraw
, int line
, int lineVisible
, int xStart
,
338 PRectangle rcLine
, LineLayout
*ll
, int subLine
=0);
339 void RefreshPixMaps(Surface
*surfaceWindow
);
340 void Paint(Surface
*surfaceWindow
, PRectangle rcArea
);
341 long FormatRange(bool draw
, RangeToFormat
*pfr
);
342 int TextWidth(int style
, const char *text
);
344 virtual void SetVerticalScrollPos() = 0;
345 virtual void SetHorizontalScrollPos() = 0;
346 virtual bool ModifyScrollBars(int nMax
, int nPage
) = 0;
347 virtual void ReconfigureScrollBars();
348 void SetScrollBars();
351 void AddChar(char ch
);
352 virtual void AddCharUTF(char *s
, unsigned int len
, bool treatAsDBCS
=false);
353 void ClearSelection();
355 void ClearDocumentStyle();
357 void PasteRectangular(int pos
, const char *ptr
, int len
);
358 virtual void Copy() = 0;
359 virtual bool CanPaste();
360 virtual void Paste() = 0;
366 void DelCharBack(bool allowLineStartDeletion
);
367 virtual void ClaimSelection() = 0;
369 virtual void NotifyChange() = 0;
370 virtual void NotifyFocus(bool focus
);
371 virtual int GetCtrlID() { return ctrlID
; }
372 virtual void NotifyParent(SCNotification scn
) = 0;
373 virtual void NotifyStyleToNeeded(int endStyleNeeded
);
374 void NotifyChar(int ch
);
375 void NotifyMove(int position
);
376 void NotifySavePoint(bool isSavePoint
);
377 void NotifyModifyAttempt();
378 virtual void NotifyDoubleClick(Point pt
, bool shift
);
379 void NotifyHotSpotClicked(int position
, bool shift
, bool ctrl
, bool alt
);
380 void NotifyHotSpotDoubleClicked(int position
, bool shift
, bool ctrl
, bool alt
);
381 void NotifyUpdateUI();
382 void NotifyPainted();
383 bool NotifyMarginClick(Point pt
, bool shift
, bool ctrl
, bool alt
);
384 void NotifyNeedShown(int pos
, int len
);
385 void NotifyDwelling(Point pt
, bool state
);
388 void NotifyModifyAttempt(Document
*document
, void *userData
);
389 void NotifySavePoint(Document
*document
, void *userData
, bool atSavePoint
);
390 void CheckModificationForWrap(DocModification mh
);
391 void NotifyModified(Document
*document
, DocModification mh
, void *userData
);
392 void NotifyDeleted(Document
*document
, void *userData
);
393 void NotifyStyleNeeded(Document
*doc
, void *userData
, int endPos
);
394 void NotifyMacroRecord(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
396 void PageMove(int direction
, bool extend
=false);
397 void ChangeCaseOfSelection(bool makeUpperCase
);
398 void LineTranspose();
399 void LineDuplicate();
400 virtual void CancelModes();
402 void CursorUpOrDown(int direction
, bool extend
=false);
403 int StartEndDisplayLine(int pos
, bool start
);
404 virtual int KeyCommand(unsigned int iMessage
);
405 virtual int KeyDefault(int /* key */, int /*modifiers*/);
406 int KeyDown(int key
, bool shift
, bool ctrl
, bool alt
, bool *consumed
=0);
408 int GetWhitespaceVisible();
409 void SetWhitespaceVisible(int view
);
411 void Indent(bool forwards
);
413 long FindText(uptr_t wParam
, sptr_t lParam
);
415 long SearchText(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
416 long SearchInTarget(const char *text
, int length
);
417 void GoToLine(int lineNo
);
419 char *CopyRange(int start
, int end
);
420 void CopySelectionRange(SelectionText
*ss
);
421 void SetDragPosition(int newPos
);
422 void DisplayCursor(Window::Cursor c
);
423 virtual void StartDrag();
424 void DropAt(int position
, const char *value
, bool moving
, bool rectangular
);
425 /** PositionInSelection returns 0 if position in selection, -1 if position before selection, and 1 if after.
426 * Before means either before any line of selection or before selection on its line, with a similar meaning to after. */
427 int PositionInSelection(int pos
);
428 bool PointInSelection(Point pt
);
429 bool PointInSelMargin(Point pt
);
430 void LineSelection(int lineCurrent_
, int lineAnchor_
);
431 void DwellEnd(bool mouseMoved
);
432 virtual void ButtonDown(Point pt
, unsigned int curTime
, bool shift
, bool ctrl
, bool alt
);
433 void ButtonMove(Point pt
);
434 void ButtonUp(Point pt
, unsigned int curTime
, bool ctrl
);
437 virtual void SetTicking(bool on
) = 0;
438 virtual void SetMouseCapture(bool on
) = 0;
439 virtual bool HaveMouseCapture() = 0;
440 void SetFocusState(bool focusState
);
442 void CheckForChangeOutsidePaint(Range r
);
443 int BraceMatch(int position
, int maxReStyle
);
444 void SetBraceHighlight(Position pos0
, Position pos1
, int matchStyle
);
446 void SetDocPointer(Document
*document
);
448 void Expand(int &line
, bool doExpand
);
449 void ToggleContraction(int line
);
450 void EnsureLineVisible(int lineDoc
, bool enforcePolicy
);
451 int ReplaceTarget(bool replacePatterns
, const char *text
, int length
=-1);
453 bool PositionIsHotspot(int position
);
454 bool PointIsHotspot(Point pt
);
455 void SetHotSpotRange(Point
*pt
);
456 void GetHotSpotRange(int& hsStart
, int& hsEnd
);
458 int CodePage() const;
460 virtual sptr_t
DefWndProc(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
) = 0;
463 // Public so the COM thunks can access it.
464 bool IsUnicodeMode() const;
465 // Public so scintilla_send_message can use it.
466 virtual sptr_t
WndProc(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
467 // Public so scintilla_set_id can use it.
469 friend class AutoSurface
;
473 * A smart pointer class to ensure Surfaces are set up and deleted correctly.
479 AutoSurface(Editor
*ed
) : surf(0) {
480 if (ed
->wMain
.GetID()) {
481 surf
= Surface::Allocate();
483 surf
->Init(ed
->wMain
.GetID());
484 surf
->SetUnicodeMode(SC_CP_UTF8
== ed
->CodePage());
485 surf
->SetDBCSMode(ed
->CodePage());
489 AutoSurface(SurfaceID sid
, Editor
*ed
) : surf(0) {
490 if (ed
->wMain
.GetID()) {
491 surf
= Surface::Allocate();
493 surf
->Init(sid
, ed
->wMain
.GetID());
494 surf
->SetUnicodeMode(SC_CP_UTF8
== ed
->CodePage());
495 surf
->SetDBCSMode(ed
->CodePage());
502 Surface
*operator->() const {
505 operator Surface
*() const {