1 // Scintilla source code edit control
2 /** @file Editor.h
3  ** Defines the main editor class.
4  **/
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.
7 
8 #ifndef EDITOR_H
9 #define EDITOR_H
10 
11 #ifdef SCI_NAMESPACE
12 namespace Scintilla {
13 #endif
14 
15 /**
16  */
17 class Timer {
18 public:
19 	bool ticking;
20 	int ticksToWait;
21 	enum {tickSize = 100};
22 	TickerID tickerID;
23 
24 	Timer();
25 };
26 
27 /**
28  */
29 class Idler {
30 public:
31 	bool state;
32 	IdlerID idlerID;
33 
34 	Idler();
35 };
36 
37 /**
38  * When platform has a way to generate an event before painting,
39  * accumulate needed styling range and other work items in
40  * WorkNeeded to avoid unnecessary work inside paint handler
41  */
42 class WorkNeeded {
43 public:
44 	enum workItems {
45 		workNone=0,
46 		workStyle=1,
47 		workUpdateUI=2
48 	};
49 	bool active;
50 	enum workItems items;
51 	Position upTo;
52 
WorkNeeded()53 	WorkNeeded() : active(false), items(workNone), upTo(0) {}
Reset()54 	void Reset() {
55 		active = false;
56 		items = workNone;
57 		upTo = 0;
58 	}
Need(workItems items_,Position pos)59 	void Need(workItems items_, Position pos) {
60 		if ((items_ & workStyle) && (upTo < pos))
61 			upTo = pos;
62 		items = static_cast<workItems>(items | items_);
63 	}
64 };
65 
66 /**
67  * Hold a piece of text selected for copying or dragging, along with encoding and selection format information.
68  */
69 class SelectionText {
70 	std::string s;
71 public:
72 	bool rectangular;
73 	bool lineCopy;
74 	int codePage;
75 	int characterSet;
SelectionText()76 	SelectionText() : rectangular(false), lineCopy(false), codePage(0), characterSet(0) {}
~SelectionText()77 	~SelectionText() {
78 	}
Clear()79 	void Clear() {
80 		s.clear();
81 		rectangular = false;
82 		lineCopy = false;
83 		codePage = 0;
84 		characterSet = 0;
85 	}
Copy(const std::string & s_,int codePage_,int characterSet_,bool rectangular_,bool lineCopy_)86 	void Copy(const std::string &s_, int codePage_, int characterSet_, bool rectangular_, bool lineCopy_) {
87 		s = s_;
88 		codePage = codePage_;
89 		characterSet = characterSet_;
90 		rectangular = rectangular_;
91 		lineCopy = lineCopy_;
92 		FixSelectionForClipboard();
93 	}
Copy(const SelectionText & other)94 	void Copy(const SelectionText &other) {
95 		Copy(other.s, other.codePage, other.characterSet, other.rectangular, other.lineCopy);
96 	}
Data()97 	const char *Data() const {
98 		return s.c_str();
99 	}
Length()100 	size_t Length() const {
101 		return s.length();
102 	}
LengthWithTerminator()103 	size_t LengthWithTerminator() const {
104 		return s.length() + 1;
105 	}
Empty()106 	bool Empty() const {
107 		return s.empty();
108 	}
109 private:
FixSelectionForClipboard()110 	void FixSelectionForClipboard() {
111 		// To avoid truncating the contents of the clipboard when pasted where the
112 		// clipboard contains NUL characters, replace NUL characters by spaces.
113 		std::replace(s.begin(), s.end(), '\0', ' ');
114 	}
115 };
116 
117 struct WrapPending {
118 	// The range of lines that need to be wrapped
119 	enum { lineLarge = 0x7ffffff };
120 	int start;	// When there are wraps pending, will be in document range
121 	int end;	// May be lineLarge to indicate all of document after start
WrapPendingWrapPending122 	WrapPending() {
123 		start = lineLarge;
124 		end = lineLarge;
125 	}
ResetWrapPending126 	void Reset() {
127 		start = lineLarge;
128 		end = lineLarge;
129 	}
WrappedWrapPending130 	void Wrapped(int line) {
131 		if (start == line)
132 			start++;
133 	}
NeedsWrapWrapPending134 	bool NeedsWrap() const {
135 		return start < end;
136 	}
AddRangeWrapPending137 	bool AddRange(int lineStart, int lineEnd) {
138 		const bool neededWrap = NeedsWrap();
139 		bool changed = false;
140 		if (start > lineStart) {
141 			start = lineStart;
142 			changed = true;
143 		}
144 		if ((end < lineEnd) || !neededWrap) {
145 			end = lineEnd;
146 			changed = true;
147 		}
148 		return changed;
149 	}
150 };
151 
152 /**
153  */
154 class Editor : public EditModel, public DocWatcher {
155 	// Private so Editor objects can not be copied
156 	Editor(const Editor &);
157 	Editor &operator=(const Editor &);
158 
159 protected:	// ScintillaBase subclass needs access to much of Editor
160 
161 	/** On GTK+, Scintilla is a container widget holding two scroll bars
162 	 * whereas on Windows there is just one window with both scroll bars turned on. */
163 	Window wMain;	///< The Scintilla parent window
164 	Window wMargin;	///< May be separate when using a scroll view for wMain
165 
166 	/** Style resources may be expensive to allocate so are cached between uses.
167 	 * When a style attribute is changed, this cache is flushed. */
168 	bool stylesValid;
169 	ViewStyle vs;
170 	int technology;
171 	Point sizeRGBAImage;
172 	float scaleRGBAImage;
173 
174 	MarginView marginView;
175 	EditView view;
176 
177 	int cursorMode;
178 
179 	bool hasFocus;
180 	bool mouseDownCaptures;
181 
182 	int xCaretMargin;	///< Ensure this many pixels visible on both sides of caret
183 	bool horizontalScrollBarVisible;
184 	int scrollWidth;
185 	bool verticalScrollBarVisible;
186 	bool endAtLastLine;
187 	int caretSticky;
188 	int marginOptions;
189 	bool mouseSelectionRectangularSwitch;
190 	bool multipleSelection;
191 	bool additionalSelectionTyping;
192 	int multiPasteMode;
193 
194 	int virtualSpaceOptions;
195 
196 	KeyMap kmap;
197 
198 	Timer timer;
199 	Timer autoScrollTimer;
200 	enum { autoScrollDelay = 200 };
201 
202 	Idler idler;
203 
204 	Point lastClick;
205 	unsigned int lastClickTime;
206 	Point doubleClickCloseThreshold;
207 	int dwellDelay;
208 	int ticksToDwell;
209 	bool dwelling;
210 	enum { selChar, selWord, selSubLine, selWholeLine } selectionType;
211 	Point ptMouseLast;
212 	enum { ddNone, ddInitial, ddDragging } inDragDrop;
213 	bool dropWentOutside;
214 	SelectionPosition posDrop;
215 	int hotSpotClickPos;
216 	int lastXChosen;
217 	int lineAnchorPos;
218 	int originalAnchorPos;
219 	int wordSelectAnchorStartPos;
220 	int wordSelectAnchorEndPos;
221 	int wordSelectInitialCaretPos;
222 	int targetStart;
223 	int targetEnd;
224 	int searchFlags;
225 	int topLine;
226 	int posTopLine;
227 	int lengthForEncode;
228 
229 	int needUpdateUI;
230 
231 	enum { notPainting, painting, paintAbandoned } paintState;
232 	bool paintAbandonedByStyling;
233 	PRectangle rcPaint;
234 	bool paintingAllText;
235 	bool willRedrawAll;
236 	WorkNeeded workNeeded;
237 
238 	int modEventMask;
239 
240 	SelectionText drag;
241 
242 	int caretXPolicy;
243 	int caretXSlop;	///< Ensure this many pixels visible on both sides of caret
244 
245 	int caretYPolicy;
246 	int caretYSlop;	///< Ensure this many lines visible on both sides of caret
247 
248 	int visiblePolicy;
249 	int visibleSlop;
250 
251 	int searchAnchor;
252 
253 	bool recordingMacro;
254 
255 	int foldAutomatic;
256 
257 	// Wrapping support
258 	WrapPending wrapPending;
259 
260 	bool convertPastes;
261 
262 	Editor();
263 	virtual ~Editor();
264 	virtual void Initialise() = 0;
265 	virtual void Finalise();
266 
267 	void InvalidateStyleData();
268 	void InvalidateStyleRedraw();
269 	void RefreshStyleData();
270 	void SetRepresentations();
271 	void DropGraphics(bool freeObjects);
272 	void AllocateGraphics();
273 
274 	// The top left visible point in main window coordinates. Will be 0,0 except for
275 	// scroll views where it will be equivalent to the current scroll position.
276 	virtual Point GetVisibleOriginInMain() const;
277 	Point DocumentPointFromView(Point ptView) const;  // Convert a point from view space to document
278 	int TopLineOfMain() const;   // Return the line at Main's y coordinate 0
279 	virtual PRectangle GetClientRectangle() const;
280 	virtual PRectangle GetClientDrawingRectangle();
281 	PRectangle GetTextRectangle() const;
282 
283 	virtual int LinesOnScreen() const;
284 	int LinesToScroll() const;
285 	int MaxScrollPos() const;
286 	SelectionPosition ClampPositionIntoDocument(SelectionPosition sp) const;
287 	Point LocationFromPosition(SelectionPosition pos);
288 	Point LocationFromPosition(int pos);
289 	int XFromPosition(int pos);
290 	int XFromPosition(SelectionPosition sp);
291 	SelectionPosition SPositionFromLocation(Point pt, bool canReturnInvalid=false, bool charPosition=false, bool virtualSpace=true);
292 	int PositionFromLocation(Point pt, bool canReturnInvalid = false, bool charPosition = false);
293 	SelectionPosition SPositionFromLineX(int lineDoc, int x);
294 	int PositionFromLineX(int line, int x);
295 	int LineFromLocation(Point pt) const;
296 	void SetTopLine(int topLineNew);
297 
298 	virtual bool AbandonPaint();
299 	virtual void RedrawRect(PRectangle rc);
300 	virtual void DiscardOverdraw();
301 	virtual void Redraw();
302 	void RedrawSelMargin(int line=-1, bool allAfter=false);
303 	PRectangle RectangleFromRange(Range r, int overlap);
304 	void InvalidateRange(int start, int end);
305 
UserVirtualSpace()306 	bool UserVirtualSpace() const {
307 		return ((virtualSpaceOptions & SCVS_USERACCESSIBLE) != 0);
308 	}
309 	int CurrentPosition() const;
310 	bool SelectionEmpty() const;
311 	SelectionPosition SelectionStart();
312 	SelectionPosition SelectionEnd();
313 	void SetRectangularRange();
314 	void ThinRectangularRange();
315 	void InvalidateSelection(SelectionRange newMain, bool invalidateWholeSelection=false);
316 	void SetSelection(SelectionPosition currentPos_, SelectionPosition anchor_);
317 	void SetSelection(int currentPos_, int anchor_);
318 	void SetSelection(SelectionPosition currentPos_);
319 	void SetSelection(int currentPos_);
320 	void SetEmptySelection(SelectionPosition currentPos_);
321 	void SetEmptySelection(int currentPos_);
322 	bool RangeContainsProtected(int start, int end) const;
323 	bool SelectionContainsProtected();
324 	int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true) const;
325 	SelectionPosition MovePositionOutsideChar(SelectionPosition pos, int moveDir, bool checkLineEnd=true) const;
326 	int MovePositionTo(SelectionPosition newPos, Selection::selTypes selt=Selection::noSel, bool ensureVisible=true);
327 	int MovePositionTo(int newPos, Selection::selTypes selt=Selection::noSel, bool ensureVisible=true);
328 	SelectionPosition MovePositionSoVisible(SelectionPosition pos, int moveDir);
329 	SelectionPosition MovePositionSoVisible(int pos, int moveDir);
330 	Point PointMainCaret();
331 	void SetLastXChosen();
332 
333 	void ScrollTo(int line, bool moveThumb=true);
334 	virtual void ScrollText(int linesToMove);
335 	void HorizontalScrollTo(int xPos);
336 	void VerticalCentreCaret();
337 	void MoveSelectedLines(int lineDelta);
338 	void MoveSelectedLinesUp();
339 	void MoveSelectedLinesDown();
340 	void MoveCaretInsideView(bool ensureVisible=true);
341 	int DisplayFromPosition(int pos);
342 
343 	struct XYScrollPosition {
344 		int xOffset;
345 		int topLine;
XYScrollPositionXYScrollPosition346 		XYScrollPosition(int xOffset_, int topLine_) : xOffset(xOffset_), topLine(topLine_) {}
347 		bool operator==(const XYScrollPosition &other) const {
348 			return (xOffset == other.xOffset) && (topLine == other.topLine);
349 		}
350 	};
351 	enum XYScrollOptions {
352 		xysUseMargin=0x1,
353 		xysVertical=0x2,
354 		xysHorizontal=0x4,
355 		xysDefault=xysUseMargin|xysVertical|xysHorizontal};
356 	XYScrollPosition XYScrollToMakeVisible(const SelectionRange &range, const XYScrollOptions options);
357 	void SetXYScroll(XYScrollPosition newXY);
358 	void EnsureCaretVisible(bool useMargin=true, bool vert=true, bool horiz=true);
359 	void ScrollRange(SelectionRange range);
360 	void ShowCaretAtCurrentPosition();
361 	void DropCaret();
362 	void CaretSetPeriod(int period);
363 	void InvalidateCaret();
364 	virtual void UpdateSystemCaret();
365 
366 	bool Wrapping() const;
367 	void NeedWrapping(int docLineStart=0, int docLineEnd=WrapPending::lineLarge);
368 	bool WrapOneLine(Surface *surface, int lineToWrap);
369 	enum wrapScope {wsAll, wsVisible, wsIdle};
370 	bool WrapLines(enum wrapScope ws);
371 	void LinesJoin();
372 	void LinesSplit(int pixelWidth);
373 
374 	void PaintSelMargin(Surface *surface, PRectangle &rc);
375 	void RefreshPixMaps(Surface *surfaceWindow);
376 	void Paint(Surface *surfaceWindow, PRectangle rcArea);
377 	long FormatRange(bool draw, Sci_RangeToFormat *pfr);
378 	int TextWidth(int style, const char *text);
379 
380 	virtual void SetVerticalScrollPos() = 0;
381 	virtual void SetHorizontalScrollPos() = 0;
382 	virtual bool ModifyScrollBars(int nMax, int nPage) = 0;
383 	virtual void ReconfigureScrollBars();
384 	void SetScrollBars();
385 	void ChangeSize();
386 
387 	void FilterSelections();
388 	int InsertSpace(int position, unsigned int spaces);
389 	void AddChar(char ch);
390 	virtual void AddCharUTF(const char *s, unsigned int len, bool treatAsDBCS=false);
391 	void InsertPaste(const char *text, int len);
392 	enum PasteShape { pasteStream=0, pasteRectangular = 1, pasteLine = 2 };
393 	void InsertPasteShape(const char *text, int len, PasteShape shape);
394 	void ClearSelection(bool retainMultipleSelections = false);
395 	void ClearAll();
396 	void ClearDocumentStyle();
397 	void Cut();
398 	void PasteRectangular(SelectionPosition pos, const char *ptr, int len);
399 	virtual void Copy() = 0;
400 	virtual void CopyAllowLine();
401 	virtual bool CanPaste();
402 	virtual void Paste() = 0;
403 	void Clear();
404 	void SelectAll();
405 	void Undo();
406 	void Redo();
407 	void DelCharBack(bool allowLineStartDeletion);
408 	virtual void ClaimSelection() = 0;
409 
410 	static int ModifierFlags(bool shift, bool ctrl, bool alt, bool meta=false);
411 	virtual void NotifyChange() = 0;
412 	virtual void NotifyFocus(bool focus);
413 	virtual void SetCtrlID(int identifier);
GetCtrlID()414 	virtual int GetCtrlID() { return ctrlID; }
415 	virtual void NotifyParent(SCNotification scn) = 0;
416 	virtual void NotifyStyleToNeeded(int endStyleNeeded);
417 	void NotifyChar(int ch);
418 	void NotifySavePoint(bool isSavePoint);
419 	void NotifyModifyAttempt();
420 	virtual void NotifyDoubleClick(Point pt, int modifiers);
421 	virtual void NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt);
422 	void NotifyHotSpotClicked(int position, int modifiers);
423 	void NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt);
424 	void NotifyHotSpotDoubleClicked(int position, int modifiers);
425 	void NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt);
426 	void NotifyHotSpotReleaseClick(int position, int modifiers);
427 	void NotifyHotSpotReleaseClick(int position, bool shift, bool ctrl, bool alt);
428 	bool NotifyUpdateUI();
429 	void NotifyPainted();
430 	void NotifyIndicatorClick(bool click, int position, int modifiers);
431 	void NotifyIndicatorClick(bool click, int position, bool shift, bool ctrl, bool alt);
432 	bool NotifyMarginClick(Point pt, int modifiers);
433 	bool NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt);
434 	void NotifyNeedShown(int pos, int len);
435 	void NotifyDwelling(Point pt, bool state);
436 	void NotifyZoom();
437 
438 	void NotifyModifyAttempt(Document *document, void *userData);
439 	void NotifySavePoint(Document *document, void *userData, bool atSavePoint);
440 	void CheckModificationForWrap(DocModification mh);
441 	void NotifyModified(Document *document, DocModification mh, void *userData);
442 	void NotifyDeleted(Document *document, void *userData);
443 	void NotifyStyleNeeded(Document *doc, void *userData, int endPos);
444 	void NotifyLexerChanged(Document *doc, void *userData);
445 	void NotifyErrorOccurred(Document *doc, void *userData, int status);
446 	void NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
447 
448 	void ContainerNeedsUpdate(int flags);
449 	void PageMove(int direction, Selection::selTypes selt=Selection::noSel, bool stuttered = false);
450 	enum { cmSame, cmUpper, cmLower };
451 	virtual std::string CaseMapString(const std::string &s, int caseMapping);
452 	void ChangeCaseOfSelection(int caseMapping);
453 	void LineTranspose();
454 	void Duplicate(bool forLine);
455 	virtual void CancelModes();
456 	void NewLine();
457 	void CursorUpOrDown(int direction, Selection::selTypes selt=Selection::noSel);
458 	void ParaUpOrDown(int direction, Selection::selTypes selt=Selection::noSel);
459 	int StartEndDisplayLine(int pos, bool start);
460 	virtual int KeyCommand(unsigned int iMessage);
461 	virtual int KeyDefault(int /* key */, int /*modifiers*/);
462 	int KeyDownWithModifiers(int key, int modifiers, bool *consumed);
463 	int KeyDown(int key, bool shift, bool ctrl, bool alt, bool *consumed=0);
464 
465 	void Indent(bool forwards);
466 
467 	virtual CaseFolder *CaseFolderForEncoding();
468 	long FindText(uptr_t wParam, sptr_t lParam);
469 	void SearchAnchor();
470 	long SearchText(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
471 	long SearchInTarget(const char *text, int length);
472 	void GoToLine(int lineNo);
473 
474 	virtual void CopyToClipboard(const SelectionText &selectedText) = 0;
475 	std::string RangeText(int start, int end) const;
476 	void CopySelectionRange(SelectionText *ss, bool allowLineCopy=false);
477 	void CopyRangeToClipboard(int start, int end);
478 	void CopyText(int length, const char *text);
479 	void SetDragPosition(SelectionPosition newPos);
480 	virtual void DisplayCursor(Window::Cursor c);
481 	virtual bool DragThreshold(Point ptStart, Point ptNow);
482 	virtual void StartDrag();
483 	void DropAt(SelectionPosition position, const char *value, size_t lengthValue, bool moving, bool rectangular);
484 	void DropAt(SelectionPosition position, const char *value, bool moving, bool rectangular);
485 	/** PositionInSelection returns true if position in selection. */
486 	bool PositionInSelection(int pos);
487 	bool PointInSelection(Point pt);
488 	bool PointInSelMargin(Point pt) const;
489 	Window::Cursor GetMarginCursor(Point pt) const;
490 	void TrimAndSetSelection(int currentPos_, int anchor_);
491 	void LineSelection(int lineCurrentPos_, int lineAnchorPos_, bool wholeLine);
492 	void WordSelection(int pos);
493 	void DwellEnd(bool mouseMoved);
494 	void MouseLeave();
495 	virtual void ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers);
496 	virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt);
497 	void ButtonMoveWithModifiers(Point pt, int modifiers);
498 	void ButtonMove(Point pt);
499 	void ButtonUp(Point pt, unsigned int curTime, bool ctrl);
500 
501 	void Tick();
502 	bool Idle();
503 	virtual void SetTicking(bool on);
504 	enum TickReason { tickCaret, tickScroll, tickWiden, tickDwell, tickPlatform };
505 	virtual void TickFor(TickReason reason);
506 	virtual bool FineTickerAvailable();
507 	virtual bool FineTickerRunning(TickReason reason);
508 	virtual void FineTickerStart(TickReason reason, int millis, int tolerance);
509 	virtual void FineTickerCancel(TickReason reason);
SetIdle(bool)510 	virtual bool SetIdle(bool) { return false; }
511 	virtual void SetMouseCapture(bool on) = 0;
512 	virtual bool HaveMouseCapture() = 0;
513 	void SetFocusState(bool focusState);
514 
515 	int PositionAfterArea(PRectangle rcArea) const;
516 	void StyleToPositionInView(Position pos);
517 	virtual void IdleWork();
518 	virtual void QueueIdleWork(WorkNeeded::workItems items, int upTo=0);
519 
520 	virtual bool PaintContains(PRectangle rc);
521 	bool PaintContainsMargin();
522 	void CheckForChangeOutsidePaint(Range r);
523 	void SetBraceHighlight(Position pos0, Position pos1, int matchStyle);
524 
525 	void SetAnnotationHeights(int start, int end);
526 	virtual void SetDocPointer(Document *document);
527 
528 	void SetAnnotationVisible(int visible);
529 
530 	int ExpandLine(int line);
531 	void SetFoldExpanded(int lineDoc, bool expanded);
532 	void FoldLine(int line, int action);
533 	void FoldExpand(int line, int action, int level);
534 	int ContractedFoldNext(int lineStart) const;
535 	void EnsureLineVisible(int lineDoc, bool enforcePolicy);
536 	void FoldChanged(int line, int levelNow, int levelPrev);
537 	void NeedShown(int pos, int len);
538 	void FoldAll(int action);
539 
540 	int GetTag(char *tagValue, int tagNumber);
541 	int ReplaceTarget(bool replacePatterns, const char *text, int length=-1);
542 
543 	bool PositionIsHotspot(int position) const;
544 	bool PointIsHotspot(Point pt);
545 	void SetHotSpotRange(Point *pt);
546 	Range GetHotSpotRange() const;
547 
548 	int CodePage() const;
ValidCodePage(int)549 	virtual bool ValidCodePage(int /* codePage */) const { return true; }
550 	int WrapCount(int line);
551 	void AddStyledText(char *buffer, int appendLength);
552 
553 	virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) = 0;
554 	void StyleSetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
555 	sptr_t StyleGetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
556 
557 	static const char *StringFromEOLMode(int eolMode);
558 
559 	static sptr_t StringResult(sptr_t lParam, const char *val);
560 	static sptr_t BytesResult(sptr_t lParam, const unsigned char *val, size_t len);
561 
562 public:
563 	// Public so the COM thunks can access it.
564 	bool IsUnicodeMode() const;
565 	// Public so scintilla_send_message can use it.
566 	virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
567 	// Public so scintilla_set_id can use it.
568 	int ctrlID;
569 	// Public so COM methods for drag and drop can set it.
570 	int errorStatus;
571 	friend class AutoSurface;
572 	friend class SelectionLineIterator;
573 };
574 
575 /**
576  * A smart pointer class to ensure Surfaces are set up and deleted correctly.
577  */
578 class AutoSurface {
579 private:
580 	Surface *surf;
581 public:
582 	AutoSurface(Editor *ed, int technology = -1) : surf(0) {
583 		if (ed->wMain.GetID()) {
584 			surf = Surface::Allocate(technology != -1 ? technology : ed->technology);
585 			if (surf) {
586 				surf->Init(ed->wMain.GetID());
587 				surf->SetUnicodeMode(SC_CP_UTF8 == ed->CodePage());
588 				surf->SetDBCSMode(ed->CodePage());
589 			}
590 		}
591 	}
592 	AutoSurface(SurfaceID sid, Editor *ed, int technology = -1) : surf(0) {
593 		if (ed->wMain.GetID()) {
594 			surf = Surface::Allocate(technology != -1 ? technology : ed->technology);
595 			if (surf) {
596 				surf->Init(sid, ed->wMain.GetID());
597 				surf->SetUnicodeMode(SC_CP_UTF8 == ed->CodePage());
598 				surf->SetDBCSMode(ed->CodePage());
599 			}
600 		}
601 	}
~AutoSurface()602 	~AutoSurface() {
603 		delete surf;
604 	}
605 	Surface *operator->() const {
606 		return surf;
607 	}
608 	operator Surface *() const {
609 		return surf;
610 	}
611 };
612 
613 #ifdef SCI_NAMESPACE
614 }
615 #endif
616 
617 #endif
618