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
++) {
88 characterSet
= characterSet_
;
89 rectangular
= rectangular_
;
92 void Copy(const SelectionText
&other
) {
93 Copy(other
.s
, other
.len
, other
.codePage
, other
.characterSet
, other
.rectangular
, other
.lineCopy
);
99 class Editor
: public DocWatcher
{
100 // Private so Editor objects can not be copied
101 Editor(const Editor
&);
102 Editor
&operator=(const Editor
&);
104 protected: // ScintillaBase subclass needs access to much of Editor
106 /** On GTK+, Scintilla is a container widget holding two scroll bars
107 * whereas on Windows there is just one window with both scroll bars turned on. */
108 Window wMain
; ///< The Scintilla parent window
110 /** Style resources may be expensive to allocate so are cached between uses.
111 * When a style attribute is changed, this cache is flushed. */
116 int printMagnification
;
120 int controlCharSymbol
;
125 bool mouseDownCaptures
;
127 /** In bufferedDraw mode, graphics operations are drawn to a pixmap and then copied to
128 * the screen. This avoids flashing but is about 30% slower. */
130 /** In twoPhaseDraw mode, drawing is performed in two phases, first the background
131 * and then the foreground. This avoids chopping off characters that overlap the next run. */
134 int xOffset
; ///< Horizontal scrolled amount in pixels
135 int xCaretMargin
; ///< Ensure this many pixels visible on both sides of caret
136 bool horizontalScrollBarVisible
;
139 int lineWidthMaxSeen
;
140 bool verticalScrollBarVisible
;
143 bool multipleSelection
;
144 bool additionalSelectionTyping
;
146 bool additionalCaretsBlink
;
147 bool additionalCaretsVisible
;
149 int virtualSpaceOptions
;
152 Surface
*pixmapSelMargin
;
153 Surface
*pixmapSelPattern
;
154 Surface
*pixmapIndentGuide
;
155 Surface
*pixmapIndentGuideHighlight
;
158 PositionCache posCache
;
164 Timer autoScrollTimer
;
165 enum { autoScrollDelay
= 200 };
170 unsigned int lastClickTime
;
174 enum { selChar
, selWord
, selLine
} selectionType
;
176 enum { ddNone
, ddInitial
, ddDragging
} inDragDrop
;
177 bool dropWentOutside
;
178 SelectionPosition posDrag
;
179 SelectionPosition posDrop
;
182 int originalAnchorPos
;
192 int bracesMatchStyle
;
193 int highlightGuideColumn
;
197 enum { notPainting
, painting
, paintAbandoned
} paintState
;
199 bool paintingAllText
;
205 bool primarySelection
;
208 int caretXSlop
; ///< Ensure this many pixels visible on both sides of caret
211 int caretYSlop
; ///< Ensure this many lines visible on both sides of caret
228 enum { eWrapNone
, eWrapWord
, eWrapChar
} wrapState
;
229 enum { wrapLineLarge
= 0x7ffffff };
234 int wrapVisualFlagsLocation
;
235 int wrapVisualStartIndent
;
236 int wrapAddIndent
; // This will be added to initial indent of line
237 int wrapIndentMode
; // SC_WRAPINDENT_FIXED, _SAME, _INDENT
245 virtual void Initialise() = 0;
246 virtual void Finalise();
248 void InvalidateStyleData();
249 void InvalidateStyleRedraw();
250 virtual void RefreshColourPalette(Palette
&pal
, bool want
);
251 void RefreshStyleData();
254 virtual PRectangle
GetClientRectangle();
255 PRectangle
GetTextRectangle();
260 SelectionPosition
ClampPositionIntoDocument(SelectionPosition sp
) const;
261 Point
LocationFromPosition(SelectionPosition pos
);
262 Point
LocationFromPosition(int pos
);
263 int XFromPosition(int pos
);
264 int XFromPosition(SelectionPosition sp
);
265 SelectionPosition
SPositionFromLocation(Point pt
, bool canReturnInvalid
=false, bool charPosition
=false, bool virtualSpace
=true);
266 int PositionFromLocation(Point pt
, bool canReturnInvalid
=false, bool charPosition
=false);
267 SelectionPosition
SPositionFromLineX(int lineDoc
, int x
);
268 int PositionFromLineX(int line
, int x
);
269 int LineFromLocation(Point pt
);
270 void SetTopLine(int topLineNew
);
273 void RedrawRect(PRectangle rc
);
275 void RedrawSelMargin(int line
=-1);
276 PRectangle
RectangleFromRange(int start
, int end
);
277 void InvalidateRange(int start
, int end
);
279 bool UserVirtualSpace() const {
280 return ((virtualSpaceOptions
& SCVS_USERACCESSIBLE
) != 0);
282 int CurrentPosition();
283 bool SelectionEmpty();
284 SelectionPosition
SelectionStart();
285 SelectionPosition
SelectionEnd();
286 void SetRectangularRange();
287 void ThinRectangularRange();
288 void InvalidateSelection(SelectionRange newMain
, bool invalidateWholeSelection
=false);
289 void SetSelection(SelectionPosition currentPos_
, SelectionPosition anchor_
);
290 void SetSelection(int currentPos_
, int anchor_
);
291 void SetSelection(SelectionPosition currentPos_
);
292 void SetSelection(int currentPos_
);
293 void SetEmptySelection(SelectionPosition currentPos_
);
294 void SetEmptySelection(int currentPos_
);
295 bool RangeContainsProtected(int start
, int end
) const;
296 bool SelectionContainsProtected();
297 int MovePositionOutsideChar(int pos
, int moveDir
, bool checkLineEnd
=true) const;
298 SelectionPosition
MovePositionOutsideChar(SelectionPosition pos
, int moveDir
, bool checkLineEnd
=true) const;
299 int MovePositionTo(SelectionPosition newPos
, Selection::selTypes sel
=Selection::noSel
, bool ensureVisible
=true);
300 int MovePositionTo(int newPos
, Selection::selTypes sel
=Selection::noSel
, bool ensureVisible
=true);
301 SelectionPosition
MovePositionSoVisible(SelectionPosition pos
, int moveDir
);
302 SelectionPosition
MovePositionSoVisible(int pos
, int moveDir
);
303 Point
PointMainCaret();
304 void SetLastXChosen();
306 void ScrollTo(int line
, bool moveThumb
=true);
307 virtual void ScrollText(int linesToMove
);
308 void HorizontalScrollTo(int xPos
);
309 void MoveCaretInsideView(bool ensureVisible
=true);
310 int DisplayFromPosition(int pos
);
311 void EnsureCaretVisible(bool useMargin
=true, bool vert
=true, bool horiz
=true);
312 void ShowCaretAtCurrentPosition();
314 void InvalidateCaret();
315 virtual void UpdateSystemCaret();
317 void NeedWrapping(int docLineStart
= 0, int docLineEnd
= wrapLineLarge
);
318 bool WrapOneLine(Surface
*surface
, int lineToWrap
);
319 bool WrapLines(bool fullWrap
, int priorityWrapLineStart
);
321 void LinesSplit(int pixelWidth
);
323 int SubstituteMarkerIfEmpty(int markerCheck
, int markerDefault
);
324 void PaintSelMargin(Surface
*surface
, PRectangle
&rc
);
325 LineLayout
*RetrieveLineLayout(int lineNumber
);
326 void LayoutLine(int line
, Surface
*surface
, ViewStyle
&vstyle
, LineLayout
*ll
,
327 int width
=LineLayout::wrapWidthInfinite
);
328 ColourAllocated
SelectionBackground(ViewStyle
&vsDraw
, bool main
);
329 ColourAllocated
TextBackground(ViewStyle
&vsDraw
, bool overrideBackground
, ColourAllocated background
, int inSelection
, bool inHotspot
, int styleMain
, int i
, LineLayout
*ll
);
330 void DrawIndentGuide(Surface
*surface
, int lineVisible
, int lineHeight
, int start
, PRectangle rcSegment
, bool highlight
);
331 void DrawWrapMarker(Surface
*surface
, PRectangle rcPlace
, bool isEndMarker
, ColourAllocated wrapColour
);
332 void DrawEOL(Surface
*surface
, ViewStyle
&vsDraw
, PRectangle rcLine
, LineLayout
*ll
,
333 int line
, int lineEnd
, int xStart
, int subLine
, int subLineStart
,
334 bool overrideBackground
, ColourAllocated background
,
335 bool drawWrapMark
, ColourAllocated wrapColour
);
336 void DrawIndicators(Surface
*surface
, ViewStyle
&vsDraw
, int line
, int xStart
,
337 PRectangle rcLine
, LineLayout
*ll
, int subLine
, int lineEnd
, bool under
);
338 void DrawAnnotation(Surface
*surface
, ViewStyle
&vsDraw
, int line
, int xStart
,
339 PRectangle rcLine
, LineLayout
*ll
, int subLine
);
340 void DrawLine(Surface
*surface
, ViewStyle
&vsDraw
, int line
, int lineVisible
, int xStart
,
341 PRectangle rcLine
, LineLayout
*ll
, int subLine
);
342 void DrawBlockCaret(Surface
*surface
, ViewStyle
&vsDraw
, LineLayout
*ll
, int subLine
,
343 int xStart
, int offset
, int posCaret
, PRectangle rcCaret
, ColourAllocated caretColour
);
344 void DrawCarets(Surface
*surface
, ViewStyle
&vsDraw
, int line
, int xStart
,
345 PRectangle rcLine
, LineLayout
*ll
, int subLine
);
346 void RefreshPixMaps(Surface
*surfaceWindow
);
347 void Paint(Surface
*surfaceWindow
, PRectangle rcArea
);
348 long FormatRange(bool draw
, Sci_RangeToFormat
*pfr
);
349 int TextWidth(int style
, const char *text
);
351 virtual void SetVerticalScrollPos() = 0;
352 virtual void SetHorizontalScrollPos() = 0;
353 virtual bool ModifyScrollBars(int nMax
, int nPage
) = 0;
354 virtual void ReconfigureScrollBars();
355 void SetScrollBars();
358 void FilterSelections();
359 int InsertSpace(int position
, unsigned int spaces
);
360 void AddChar(char ch
);
361 virtual void AddCharUTF(char *s
, unsigned int len
, bool treatAsDBCS
=false);
362 void InsertPaste(SelectionPosition selStart
, const char *text
, int len
);
363 void ClearSelection();
365 void ClearDocumentStyle();
367 void PasteRectangular(SelectionPosition pos
, const char *ptr
, int len
);
368 virtual void Copy() = 0;
369 virtual void CopyAllowLine();
370 virtual bool CanPaste();
371 virtual void Paste() = 0;
377 void DelCharBack(bool allowLineStartDeletion
);
378 virtual void ClaimSelection() = 0;
380 virtual void NotifyChange() = 0;
381 virtual void NotifyFocus(bool focus
);
382 virtual int GetCtrlID() { return ctrlID
; }
383 virtual void NotifyParent(SCNotification scn
) = 0;
384 virtual void NotifyStyleToNeeded(int endStyleNeeded
);
385 void NotifyChar(int ch
);
386 void NotifySavePoint(bool isSavePoint
);
387 void NotifyModifyAttempt();
388 virtual void NotifyDoubleClick(Point pt
, bool shift
, bool ctrl
, bool alt
);
389 void NotifyHotSpotClicked(int position
, bool shift
, bool ctrl
, bool alt
);
390 void NotifyHotSpotDoubleClicked(int position
, bool shift
, bool ctrl
, bool alt
);
391 void NotifyUpdateUI();
392 void NotifyPainted();
393 void NotifyIndicatorClick(bool click
, int position
, bool shift
, bool ctrl
, bool alt
);
394 bool NotifyMarginClick(Point pt
, bool shift
, bool ctrl
, bool alt
);
395 void NotifyNeedShown(int pos
, int len
);
396 void NotifyDwelling(Point pt
, bool state
);
399 void NotifyModifyAttempt(Document
*document
, void *userData
);
400 void NotifySavePoint(Document
*document
, void *userData
, bool atSavePoint
);
401 void CheckModificationForWrap(DocModification mh
);
402 void NotifyModified(Document
*document
, DocModification mh
, void *userData
);
403 void NotifyDeleted(Document
*document
, void *userData
);
404 void NotifyStyleNeeded(Document
*doc
, void *userData
, int endPos
);
405 void NotifyMacroRecord(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
407 void PageMove(int direction
, Selection::selTypes sel
=Selection::noSel
, bool stuttered
= false);
408 enum { cmSame
, cmUpper
, cmLower
} caseMap
;
409 virtual std::string
CaseMapString(const std::string
&s
, int caseMapping
);
410 void ChangeCaseOfSelection(int caseMapping
);
411 void LineTranspose();
412 void Duplicate(bool forLine
);
413 virtual void CancelModes();
415 void CursorUpOrDown(int direction
, Selection::selTypes sel
=Selection::noSel
);
416 void ParaUpOrDown(int direction
, Selection::selTypes sel
=Selection::noSel
);
417 int StartEndDisplayLine(int pos
, bool start
);
418 virtual int KeyCommand(unsigned int iMessage
);
419 virtual int KeyDefault(int /* key */, int /*modifiers*/);
420 int KeyDown(int key
, bool shift
, bool ctrl
, bool alt
, bool *consumed
=0);
422 int GetWhitespaceVisible();
423 void SetWhitespaceVisible(int view
);
425 void Indent(bool forwards
);
427 virtual CaseFolder
*CaseFolderForEncoding();
428 long FindText(uptr_t wParam
, sptr_t lParam
);
430 long SearchText(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
431 long SearchInTarget(const char *text
, int length
);
432 void GoToLine(int lineNo
);
434 virtual void CopyToClipboard(const SelectionText
&selectedText
) = 0;
435 char *CopyRange(int start
, int end
);
436 void CopySelectionRange(SelectionText
*ss
, bool allowLineCopy
=false);
437 void CopyRangeToClipboard(int start
, int end
);
438 void CopyText(int length
, const char *text
);
439 void SetDragPosition(SelectionPosition newPos
);
440 virtual void DisplayCursor(Window::Cursor c
);
441 virtual bool DragThreshold(Point ptStart
, Point ptNow
);
442 virtual void StartDrag();
443 void DropAt(SelectionPosition position
, const char *value
, bool moving
, bool rectangular
);
444 /** PositionInSelection returns true if position in selection. */
445 bool PositionInSelection(int pos
);
446 bool PointInSelection(Point pt
);
447 bool PointInSelMargin(Point pt
);
448 void LineSelection(int lineCurrent_
, int lineAnchor_
);
449 void DwellEnd(bool mouseMoved
);
451 virtual void ButtonDown(Point pt
, unsigned int curTime
, bool shift
, bool ctrl
, bool alt
);
452 void ButtonMove(Point pt
);
453 void ButtonUp(Point pt
, unsigned int curTime
, bool ctrl
);
457 virtual void SetTicking(bool on
) = 0;
458 virtual bool SetIdle(bool) { return false; }
459 virtual void SetMouseCapture(bool on
) = 0;
460 virtual bool HaveMouseCapture() = 0;
461 void SetFocusState(bool focusState
);
463 virtual bool PaintContains(PRectangle rc
);
464 bool PaintContainsMargin();
465 void CheckForChangeOutsidePaint(Range r
);
466 void SetBraceHighlight(Position pos0
, Position pos1
, int matchStyle
);
468 void SetAnnotationHeights(int start
, int end
);
469 void SetDocPointer(Document
*document
);
471 void SetAnnotationVisible(int visible
);
473 void Expand(int &line
, bool doExpand
);
474 void ToggleContraction(int line
);
475 void EnsureLineVisible(int lineDoc
, bool enforcePolicy
);
476 int GetTag(char *tagValue
, int tagNumber
);
477 int ReplaceTarget(bool replacePatterns
, const char *text
, int length
=-1);
479 bool PositionIsHotspot(int position
);
480 bool PointIsHotspot(Point pt
);
481 void SetHotSpotRange(Point
*pt
);
482 void GetHotSpotRange(int &hsStart
, int &hsEnd
);
484 int CodePage() const;
485 virtual bool ValidCodePage(int /* codePage */) const { return true; }
486 int WrapCount(int line
);
487 void AddStyledText(char *buffer
, int appendLength
);
489 virtual sptr_t
DefWndProc(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
) = 0;
490 void StyleSetMessage(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
491 sptr_t
StyleGetMessage(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
493 static const char *StringFromEOLMode(int eolMode
);
495 static sptr_t
StringResult(sptr_t lParam
, const char *val
);
498 // Public so the COM thunks can access it.
499 bool IsUnicodeMode() const;
500 // Public so scintilla_send_message can use it.
501 virtual sptr_t
WndProc(unsigned int iMessage
, uptr_t wParam
, sptr_t lParam
);
502 // Public so scintilla_set_id can use it.
504 // Public so COM methods for drag and drop can set it.
506 friend class AutoSurface
;
507 friend class SelectionLineIterator
;
511 * A smart pointer class to ensure Surfaces are set up and deleted correctly.
517 AutoSurface(Editor
*ed
) : surf(0) {
518 if (ed
->wMain
.GetID()) {
519 surf
= Surface::Allocate();
521 surf
->Init(ed
->wMain
.GetID());
522 surf
->SetUnicodeMode(SC_CP_UTF8
== ed
->CodePage());
523 surf
->SetDBCSMode(ed
->CodePage());
527 AutoSurface(SurfaceID sid
, Editor
*ed
) : surf(0) {
528 if (ed
->wMain
.GetID()) {
529 surf
= Surface::Allocate();
531 surf
->Init(sid
, ed
->wMain
.GetID());
532 surf
->SetUnicodeMode(SC_CP_UTF8
== ed
->CodePage());
533 surf
->SetDBCSMode(ed
->CodePage());
540 Surface
*operator->() const {
543 operator Surface
*() const {