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.
32 enum {tickSize
= 100};
49 * Hold a piece of text selected for copying or dragging.
50 * The text is expected to hold a terminating '\0' and this is counted in len.
60 SelectionText() : s(0), len(0), rectangular(false), lineCopy(false), codePage(0), characterSet(0) {}
65 Set(0, 0, 0, 0, false, false);
67 void Set(char *s_
, int len_
, int codePage_
, int characterSet_
, bool rectangular_
, bool lineCopy_
) {
75 characterSet
= characterSet_
;
76 rectangular
= rectangular_
;
79 void Copy(const char *s_
, int len_
, int codePage_
, int characterSet_
, bool rectangular_
, bool lineCopy_
) {
84 for (int i
= 0; i
< len_
; i
++) {
91 characterSet
= characterSet_
;
92 rectangular
= rectangular_
;
95 void Copy(const SelectionText
&other
) {
96 Copy(other
.s
, other
.len
, other
.codePage
, other
.characterSet
, other
.rectangular
, other
.lineCopy
);
102 class Editor
: public DocWatcher
{
103 // Private so Editor objects can not be copied
104 Editor(const Editor
&) : DocWatcher() {}
105 Editor
&operator=(const Editor
&) { return *this; }
107 protected: // ScintillaBase subclass needs access to much of Editor
109 /** On GTK+, Scintilla is a container widget holding two scroll bars
110 * whereas on Windows there is just one window with both scroll bars turned on. */
111 Window wMain
; ///< The Scintilla parent window
113 /** Style resources may be expensive to allocate so are cached between uses.
114 * When a style attribute is changed, this cache is flushed. */
119 int printMagnification
;
123 int controlCharSymbol
;
129 bool mouseDownCaptures
;
131 /** In bufferedDraw mode, graphics operations are drawn to a pixmap and then copied to
132 * the screen. This avoids flashing but is about 30% slower. */
134 /** In twoPhaseDraw mode, drawing is performed in two phases, first the background
135 * and then the foreground. This avoids chopping off characters that overlap the next run. */
138 int xOffset
; ///< Horizontal scrolled amount in pixels
139 int xCaretMargin
; ///< Ensure this many pixels visible on both sides of caret
140 bool horizontalScrollBarVisible
;
143 int lineWidthMaxSeen
;
144 bool verticalScrollBarVisible
;
149 Surface
*pixmapSelMargin
;
150 Surface
*pixmapSelPattern
;
151 Surface
*pixmapIndentGuide
;
152 Surface
*pixmapIndentGuideHighlight
;
155 PositionCache posCache
;
161 Timer autoScrollTimer
;
162 enum { autoScrollDelay
= 200 };
167 unsigned int lastClickTime
;
171 enum { selChar
, selWord
, selLine
} selectionType
;
173 enum { ddNone
, ddInitial
, ddDragging
} inDragDrop
;
174 bool dropWentOutside
;
179 int originalAnchorPos
;
191 int bracesMatchStyle
;
192 int highlightGuideColumn
;
196 enum { notPainting
, painting
, paintAbandoned
} paintState
;
198 bool paintingAllText
;
203 enum selTypes
{ noSel
, selStream
, selRectangle
, selLines
};
205 bool moveExtendsSelection
;
206 int xStartSelect
; ///< x position of start of rectangular selection
207 int xEndSelect
; ///< x position of end of rectangular selection
208 bool primarySelection
;
211 int caretXSlop
; ///< Ensure this many pixels visible on both sides of caret
214 int caretYSlop
; ///< Ensure this many lines visible on both sides of caret
231 enum { eWrapNone
, eWrapWord
, eWrapChar
} wrapState
;
232 enum { wrapLineLarge
= 0x7ffffff };
237 int wrapVisualFlagsLocation
;
238 int wrapVisualStartIndent
;
239 int actualWrapVisualStartIndent
;
247 virtual void Initialise() = 0;
248 virtual void Finalise();
250 void InvalidateStyleData();
251 void InvalidateStyleRedraw();
252 virtual void RefreshColourPalette(Palette
&pal
, bool want
);
253 void RefreshStyleData();
256 virtual PRectangle
GetClientRectangle();
257 PRectangle
GetTextRectangle();
262 Point
LocationFromPosition(int pos
);
263 int XFromPosition(int pos
);
264 int PositionFromLocation(Point pt
);
265 int PositionFromLocationClose(Point pt
);
266 int PositionFromLineX(int line
, int x
);
267 int LineFromLocation(Point pt
);
268 void SetTopLine(int topLineNew
);
271 void RedrawRect(PRectangle rc
);
273 void RedrawSelMargin(int line
=-1);
274 PRectangle
RectangleFromRange(int start
, int end
);
275 void InvalidateRange(int start
, int end
);
277 int CurrentPosition();
278 bool SelectionEmpty();
279 int SelectionStart();
281 void SetRectangularRange();
282 void InvalidateSelection(int currentPos_
, int anchor_
, bool invalidateWholeSelection
);
283 void SetSelection(int currentPos_
, int anchor_
);
284 void SetSelection(int currentPos_
);
285 void SetEmptySelection(int currentPos_
);
286 bool RangeContainsProtected(int start
, int end
) const;
287 bool SelectionContainsProtected();
288 int MovePositionOutsideChar(int pos
, int moveDir
, bool checkLineEnd
=true);
289 int MovePositionTo(int newPos
, selTypes sel
=noSel
, bool ensureVisible
=true);
290 int MovePositionSoVisible(int pos
, int moveDir
);
291 void SetLastXChosen();
293 void ScrollTo(int line
, bool moveThumb
=true);
294 virtual void ScrollText(int linesToMove
);
295 void HorizontalScrollTo(int xPos
);
296 void MoveCaretInsideView(bool ensureVisible
=true);
297 int DisplayFromPosition(int pos
);
298 void EnsureCaretVisible(bool useMargin
=true, bool vert
=true, bool horiz
=true);
299 void ShowCaretAtCurrentPosition();
301 void InvalidateCaret();
302 virtual void UpdateSystemCaret();
304 void NeedWrapping(int docLineStart
= 0, int docLineEnd
= wrapLineLarge
);
305 bool WrapOneLine(Surface
*surface
, int lineToWrap
);
306 bool WrapLines(bool fullWrap
, int priorityWrapLineStart
);
308 void LinesSplit(int pixelWidth
);
310 int SubstituteMarkerIfEmpty(int markerCheck
, int markerDefault
);
311 void PaintSelMargin(Surface
*surface
, PRectangle
&rc
);
312 LineLayout
*RetrieveLineLayout(int lineNumber
);
313 void LayoutLine(int line
, Surface
*surface
, ViewStyle
&vstyle
, LineLayout
*ll
,
314 int width
=LineLayout::wrapWidthInfinite
);
315 ColourAllocated
SelectionBackground(ViewStyle
&vsDraw
);
316 ColourAllocated
TextBackground(ViewStyle
&vsDraw
, bool overrideBackground
, ColourAllocated background
, bool inSelection
, bool inHotspot
, int styleMain
, int i
, LineLayout
*ll
);
317 void DrawIndentGuide(Surface
*surface
, int lineVisible
, int lineHeight
, int start
, PRectangle rcSegment
, bool highlight
);
318 void DrawWrapMarker(Surface
*surface
, PRectangle rcPlace
, bool isEndMarker
, ColourAllocated wrapColour
);
319 void DrawEOL(Surface
*surface
, ViewStyle
&vsDraw
, PRectangle rcLine
, LineLayout
*ll
,
320 int line
, int lineEnd
, int xStart
, int subLine
, int subLineStart
,
321 bool overrideBackground
, ColourAllocated background
,
322 bool drawWrapMark
, ColourAllocated wrapColour
);
323 void DrawIndicators(Surface
*surface
, ViewStyle
&vsDraw
, int line
, int xStart
,
324 PRectangle rcLine
, LineLayout
*ll
, int subLine
, int lineEnd
, bool under
);
325 void DrawLine(Surface
*surface
, ViewStyle
&vsDraw
, int line
, int lineVisible
, int xStart
,
326 PRectangle rcLine
, LineLayout
*ll
, int subLine
=0);
327 void DrawBlockCaret(Surface
*surface
, ViewStyle
&vsDraw
, LineLayout
*ll
, int subLine
, int xStart
, int offset
, int posCaret
, PRectangle rcCaret
);
328 void RefreshPixMaps(Surface
*surfaceWindow
);
329 void Paint(Surface
*surfaceWindow
, PRectangle rcArea
);
330 long FormatRange(bool draw
, RangeToFormat
*pfr
);
331 int TextWidth(int style
, const char *text
);
333 virtual void SetVerticalScrollPos() = 0;
334 virtual void SetHorizontalScrollPos() = 0;
335 virtual bool ModifyScrollBars(int nMax
, int nPage
) = 0;
336 virtual void ReconfigureScrollBars();
337 void SetScrollBars();
340 void AddChar(char ch
);
341 virtual void AddCharUTF(char *s
, unsigned int len
, bool treatAsDBCS
=false);
342 void ClearSelection();
344 void ClearDocumentStyle();
346 void PasteRectangular(int pos
, const char *ptr
, int len
);
347 virtual void Copy() = 0;
348 virtual void CopyAllowLine();
349 virtual bool CanPaste();
350 virtual void Paste() = 0;
356 void DelCharBack(bool allowLineStartDeletion
);
357 virtual void ClaimSelection() = 0;
359 virtual void NotifyChange() = 0;
360 virtual void NotifyFocus(bool focus
);
361 virtual int GetCtrlID() { return ctrlID
; }
362 virtual void NotifyParent(SCNotification scn
) = 0;
363 virtual void NotifyParent(SCNotification
* scn
) = 0;
364 virtual void NotifyStyleToNeeded(int endStyleNeeded
);
365 void NotifyChar(int ch
);
366 void NotifyMove(int position
);
367 void NotifySavePoint(bool isSavePoint
);
368 void NotifyModifyAttempt();
369 virtual void NotifyDoubleClick(Point pt
, bool shift
, bool ctrl
, bool alt
);
370 void NotifyHotSpotClicked(int position
, bool shift
, bool ctrl
, bool alt
);
371 void NotifyHotSpotDoubleClicked(int position
, bool shift
, bool ctrl
, bool alt
);
372 void NotifyUpdateUI();
373 void NotifyPainted();
374 void NotifyIndicatorClick(bool click
, int position
, bool shift
, bool ctrl
, bool alt
);
375 bool NotifyMarginClick(Point pt
, bool shift
, bool ctrl
, bool alt
);
376 void NotifyNeedShown(int pos
, int len
);
377 void NotifyDwelling(Point pt
, bool state
);
380 void NotifyModifyAttempt(Document
*document
, void *userData
);
381 void NotifySavePoint(Document
*document
, void *userData
, bool atSavePoint
);
382 void CheckModificationForWrap(DocModification mh
);
383 void NotifyModified(Document
*document
, DocModification mh
, void *userData
);
384 void NotifyDeleted(Document
*document
, void *userData
);
385 void NotifyStyleNeeded(Document
*doc
, void *userData
, int endPos
);
386 void NotifyMacroRecord(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
388 void PageMove(int direction
, selTypes sel
=noSel
, bool stuttered
= false);
389 void ChangeCaseOfSelection(bool makeUpperCase
);
390 void LineTranspose();
391 void Duplicate(bool forLine
);
392 virtual void CancelModes();
394 void CursorUpOrDown(int direction
, selTypes sel
=noSel
);
395 void ParaUpOrDown(int direction
, selTypes sel
=noSel
);
396 int StartEndDisplayLine(int pos
, bool start
);
397 virtual int KeyCommand(unsigned int iMessage
);
398 virtual int KeyDefault(int /* key */, int /*modifiers*/);
399 int KeyDown(int key
, bool shift
, bool ctrl
, bool alt
, bool *consumed
=0);
401 int GetWhitespaceVisible();
402 void SetWhitespaceVisible(int view
);
404 void Indent(bool forwards
);
406 long FindText(uptr_t wParam
, sptr_t lParam
);
408 long SearchText(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
409 long SearchInTarget(const char *text
, int length
);
410 void GoToLine(int lineNo
);
412 virtual void CopyToClipboard(const SelectionText
&selectedText
) = 0;
413 char *CopyRange(int start
, int end
);
414 void CopySelectionFromRange(SelectionText
*ss
, bool allowLineCopy
, int start
, int end
);
415 void CopySelectionRange(SelectionText
*ss
, bool allowLineCopy
=false);
416 void CopyRangeToClipboard(int start
, int end
);
417 void CopyText(int length
, const char *text
);
418 void SetDragPosition(int newPos
);
419 virtual void DisplayCursor(Window::Cursor c
);
420 virtual bool DragThreshold(Point ptStart
, Point ptNow
);
421 virtual void StartDrag();
422 void DropAt(int position
, const char *value
, bool moving
, bool rectangular
);
423 /** PositionInSelection returns 0 if position in selection, -1 if position before selection, and 1 if after.
424 * Before means either before any line of selection or before selection on its line, with a similar meaning to after. */
425 int PositionInSelection(int pos
);
426 bool PointInSelection(Point pt
);
427 bool PointInSelMargin(Point pt
);
428 void LineSelection(int lineCurrent_
, int lineAnchor_
);
429 void DwellEnd(bool mouseMoved
);
430 virtual void ButtonDown(Point pt
, unsigned int curTime
, bool shift
, bool ctrl
, bool alt
);
431 void ButtonMove(Point pt
);
432 void ButtonUp(Point pt
, unsigned int curTime
, bool ctrl
);
436 virtual void SetTicking(bool on
) = 0;
437 virtual bool SetIdle(bool) { return false; }
438 virtual void SetMouseCapture(bool on
) = 0;
439 virtual bool HaveMouseCapture() = 0;
440 void SetFocusState(bool focusState
);
442 virtual bool PaintContains(PRectangle rc
);
443 bool PaintContainsMargin();
444 void CheckForChangeOutsidePaint(Range r
);
445 void SetBraceHighlight(Position pos0
, Position pos1
, int matchStyle
);
447 void SetDocPointer(Document
*document
);
449 void Expand(int &line
, bool doExpand
);
450 void ToggleContraction(int line
);
451 void EnsureLineVisible(int lineDoc
, bool enforcePolicy
);
452 int ReplaceTarget(bool replacePatterns
, const char *text
, int length
=-1);
454 bool PositionIsHotspot(int position
);
455 bool PointIsHotspot(Point pt
);
456 void SetHotSpotRange(Point
*pt
);
457 void GetHotSpotRange(int& hsStart
, int& hsEnd
);
459 int CodePage() const;
460 virtual bool ValidCodePage(int /* codePage */) const { return true; }
461 int WrapCount(int line
);
462 void AddStyledText(char *buffer
, int appendLength
);
464 virtual sptr_t
DefWndProc(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
) = 0;
465 void StyleSetMessage(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
466 sptr_t
StyleGetMessage(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
468 static const char *StringFromEOLMode(int eolMode
);
471 // Public so the COM thunks can access it.
472 bool IsUnicodeMode() const;
473 // Public so scintilla_send_message can use it.
474 virtual sptr_t
WndProc(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
475 // Public so scintilla_set_id can use it.
477 friend class AutoSurface
;
478 friend class SelectionLineIterator
;
482 * A smart pointer class to ensure Surfaces are set up and deleted correctly.
488 AutoSurface(Editor
*ed
) : surf(0) {
489 if (ed
->wMain
.GetID()) {
490 surf
= Surface::Allocate();
492 surf
->Init(ed
->wMain
.GetID());
493 surf
->SetUnicodeMode(SC_CP_UTF8
== ed
->CodePage());
494 surf
->SetDBCSMode(ed
->CodePage());
498 AutoSurface(SurfaceID sid
, Editor
*ed
) : surf(0) {
499 if (ed
->wMain
.GetID()) {
500 surf
= Surface::Allocate();
502 surf
->Init(sid
, ed
->wMain
.GetID());
503 surf
->SetUnicodeMode(SC_CP_UTF8
== ed
->CodePage());
504 surf
->SetDBCSMode(ed
->CodePage());
511 Surface
*operator->() const {
514 operator Surface
*() const {