1/////////////////////////////////////////////////////////////////////////////
2// Name:        wx/richtext/richtextctrl.h
3// Purpose:     A rich edit control
4// Author:      Julian Smart
5// Modified by:
6// Created:     2005-09-30
7// RCS-ID:      $Id: richtextctrl.h 62194 2009-09-29 06:45:04Z JS $
8// Copyright:   (c) Julian Smart
9// Licence:     wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifndef _WX_RICHTEXTCTRL_H_
13#define _WX_RICHTEXTCTRL_H_
14
15#include "wx/richtext/richtextbuffer.h"
16
17#if wxUSE_RICHTEXT
18
19#include "wx/scrolwin.h"
20#include "wx/caret.h"
21
22#include "wx/textctrl.h"
23
24#if !defined(__WXGTK__) && !defined(__WXMAC__)
25#define wxRICHTEXT_BUFFERED_PAINTING 1
26#else
27#define wxRICHTEXT_BUFFERED_PAINTING 0
28#endif
29
30class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextStyleDefinition;
31
32/*!
33 * Styles and flags
34 */
35
36/* Styles
37 */
38
39#define wxRE_READONLY          0x0010
40#define wxRE_MULTILINE         0x0020
41#define wxRE_CENTRE_CARET      0x8000
42#define wxRE_CENTER_CARET      wxRE_CENTRE_CARET
43
44/* Flags
45 */
46
47#define wxRICHTEXT_SHIFT_DOWN  0x01
48#define wxRICHTEXT_CTRL_DOWN   0x02
49#define wxRICHTEXT_ALT_DOWN    0x04
50
51/* Defaults
52 */
53
54#define wxRICHTEXT_DEFAULT_OVERALL_SIZE wxSize(-1, -1)
55#define wxRICHTEXT_DEFAULT_IMAGE_SIZE wxSize(80, 80)
56#define wxRICHTEXT_DEFAULT_SPACING 3
57#define wxRICHTEXT_DEFAULT_MARGIN 3
58#define wxRICHTEXT_DEFAULT_UNFOCUSSED_BACKGROUND wxColour(175, 175, 175)
59#define wxRICHTEXT_DEFAULT_FOCUSSED_BACKGROUND wxColour(140, 140, 140)
60#define wxRICHTEXT_DEFAULT_UNSELECTED_BACKGROUND wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)
61#define wxRICHTEXT_DEFAULT_TYPE_COLOUR wxColour(0, 0, 200)
62#define wxRICHTEXT_DEFAULT_FOCUS_RECT_COLOUR wxColour(100, 80, 80)
63#define wxRICHTEXT_DEFAULT_CARET_WIDTH 2
64// Minimum buffer size before delayed layout kicks in
65#define wxRICHTEXT_DEFAULT_DELAYED_LAYOUT_THRESHOLD 20000
66// Milliseconds before layout occurs after resize
67#define wxRICHTEXT_DEFAULT_LAYOUT_INTERVAL 50
68
69/*!
70 * Forward declarations
71 */
72
73/*!
74 * wxRichTextItem class declaration
75 */
76
77// Drawing styles/states
78#define wxRICHTEXT_SELECTED    0x01
79#define wxRICHTEXT_TAGGED      0x02
80// The control is focussed
81#define wxRICHTEXT_FOCUSSED    0x04
82// The item itself has the focus
83#define wxRICHTEXT_IS_FOCUS    0x08
84
85/*!
86 * wxRichTextCtrl class declaration
87 */
88
89class WXDLLIMPEXP_RICHTEXT wxRichTextCtrl : public wxTextCtrlBase,
90                                            public wxScrollHelper
91{
92    DECLARE_CLASS( wxRichTextCtrl )
93    DECLARE_EVENT_TABLE()
94
95public:
96// Constructors
97
98    wxRichTextCtrl( );
99    wxRichTextCtrl( wxWindow* parent, wxWindowID id = -1, const wxString& value = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
100        long style = wxRE_MULTILINE, const wxValidator& validator = wxDefaultValidator, const wxString& name = wxTextCtrlNameStr);
101
102    virtual ~wxRichTextCtrl( );
103
104// Operations
105
106    /// Creation
107    bool Create( wxWindow* parent, wxWindowID id = -1, const wxString& value = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
108        long style = wxRE_MULTILINE, const wxValidator& validator = wxDefaultValidator, const wxString& name = wxTextCtrlNameStr );
109
110    /// Member initialisation
111    void Init();
112
113///// wxTextCtrl compatibility
114
115// Accessors
116
117    virtual wxString GetValue() const;
118
119    virtual wxString GetRange(long from, long to) const;
120
121    virtual int GetLineLength(long lineNo) const ;
122    virtual wxString GetLineText(long lineNo) const ;
123    virtual int GetNumberOfLines() const ;
124
125    virtual bool IsModified() const ;
126    virtual bool IsEditable() const ;
127
128    // more readable flag testing methods
129    bool IsSingleLine() const { return !HasFlag(wxRE_MULTILINE); }
130    bool IsMultiLine() const { return !IsSingleLine(); }
131
132    // If the return values from and to are the same, there is no selection.
133    virtual void GetSelection(long* from, long* to) const;
134
135    virtual wxString GetStringSelection() const;
136
137    /// Get filename
138    wxString GetFilename() const { return m_filename; }
139
140    /// Set filename
141    void SetFilename(const wxString& filename) { m_filename = filename; }
142
143    /// Set the threshold in character positions for doing layout optimization during sizing
144    void SetDelayedLayoutThreshold(long threshold) { m_delayedLayoutThreshold = threshold; }
145
146    /// Get the threshold in character positions for doing layout optimization during sizing
147    long GetDelayedLayoutThreshold() const { return m_delayedLayoutThreshold; }
148
149#if wxABI_VERSION >= 20808
150    /// Set text cursor
151    void SetTextCursor(const wxCursor& cursor ) { m_textCursor = cursor; }
152
153    /// Get text cursor
154    wxCursor GetTextCursor() const { return m_textCursor; }
155
156    /// Set URL cursor
157    void SetURLCursor(const wxCursor& cursor ) { m_urlCursor = cursor; }
158
159    /// Get URL cursor
160    wxCursor GetURLCursor() const { return m_urlCursor; }
161#endif
162
163#if wxABI_VERSION >= 20811
164    /// Get/set context menu
165    wxMenu* GetContextMenu() const { return m_contextMenu; }
166    void SetContextMenu(wxMenu* menu);
167#endif
168
169// Operations
170
171    // editing
172    virtual void Clear();
173    virtual void Replace(long from, long to, const wxString& value);
174    virtual void Remove(long from, long to);
175
176    // load/save the controls contents from/to the file
177    virtual bool DoLoadFile(const wxString& file, int fileType);
178    virtual bool DoSaveFile(const wxString& file = wxEmptyString, int fileType = wxRICHTEXT_TYPE_ANY);
179
180    /// Set the handler flags, controlling loading and saving
181    void SetHandlerFlags(int flags) { GetBuffer().SetHandlerFlags(flags); }
182
183    /// Get the handler flags, controlling loading and saving
184    int GetHandlerFlags() const { return GetBuffer().GetHandlerFlags(); }
185
186    // sets/clears the dirty flag
187    virtual void MarkDirty();
188    virtual void DiscardEdits();
189
190    // set the max number of characters which may be entered in a single line
191    // text control
192    virtual void SetMaxLength(unsigned long WXUNUSED(len)) { }
193
194    // writing text inserts it at the current position, appending always
195    // inserts it at the end
196    virtual void WriteText(const wxString& text);
197    virtual void AppendText(const wxString& text);
198
199    // text control under some platforms supports the text styles: these
200    // methods allow to apply the given text style to the given selection or to
201    // set/get the style which will be used for all appended text
202    virtual bool SetStyle(long start, long end, const wxTextAttr& style);
203    virtual bool SetStyle(long start, long end, const wxTextAttrEx& style);
204    virtual bool SetStyle(const wxRichTextRange& range, const wxRichTextAttr& style);
205    virtual bool GetStyle(long position, wxTextAttr& style);
206    virtual bool GetStyle(long position, wxTextAttrEx& style);
207    virtual bool GetStyle(long position, wxRichTextAttr& style);
208
209    // get the common set of styles for the range
210    virtual bool GetStyleForRange(const wxRichTextRange& range, wxRichTextAttr& style);
211    virtual bool GetStyleForRange(const wxRichTextRange& range, wxTextAttrEx& style);
212
213    // extended style setting operation with flags including:
214    // wxRICHTEXT_SETSTYLE_WITH_UNDO, wxRICHTEXT_SETSTYLE_OPTIMIZE, wxRICHTEXT_SETSTYLE_PARAGRAPHS_ONLY, wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY
215    // see richtextbuffer.h for more details.
216    virtual bool SetStyleEx(long start, long end, const wxTextAttrEx& style, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO);
217    virtual bool SetStyleEx(const wxRichTextRange& range, const wxTextAttrEx& style, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO);
218    virtual bool SetStyleEx(const wxRichTextRange& range, const wxRichTextAttr& style, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO);
219
220    /// Get the content (uncombined) attributes for this position.
221    virtual bool GetUncombinedStyle(long position, wxTextAttr& style);
222    virtual bool GetUncombinedStyle(long position, wxTextAttrEx& style);
223    virtual bool GetUncombinedStyle(long position, wxRichTextAttr& style);
224
225    virtual bool SetDefaultStyle(const wxTextAttrEx& style);
226    virtual bool SetDefaultStyle(const wxTextAttr& style);
227
228    // TODO: change to GetDefaultStyle if we merge wxTextAttr and wxTextAttrEx
229    virtual const wxTextAttrEx& GetDefaultStyleEx() const;
230    virtual const wxTextAttr& GetDefaultStyle() const;
231
232    /// Set list style
233    virtual bool SetListStyle(const wxRichTextRange& range, wxRichTextListStyleDefinition* def, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int startFrom = 1, int specifiedLevel = -1);
234    virtual bool SetListStyle(const wxRichTextRange& range, const wxString& defName, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int startFrom = 1, int specifiedLevel = -1);
235
236    /// Clear list for given range
237    virtual bool ClearListStyle(const wxRichTextRange& range, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO);
238
239    /// Number/renumber any list elements in the given range
240    /// def/defName can be NULL/empty to indicate that the existing list style should be used.
241    virtual bool NumberList(const wxRichTextRange& range, wxRichTextListStyleDefinition* def = NULL, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int startFrom = 1, int specifiedLevel = -1);
242    virtual bool NumberList(const wxRichTextRange& range, const wxString& defName, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int startFrom = 1, int specifiedLevel = -1);
243
244    /// Promote the list items within the given range. promoteBy can be a positive or negative number, e.g. 1 or -1
245    /// def/defName can be NULL/empty to indicate that the existing list style should be used.
246    virtual bool PromoteList(int promoteBy, const wxRichTextRange& range, wxRichTextListStyleDefinition* def = NULL, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int specifiedLevel = -1);
247    virtual bool PromoteList(int promoteBy, const wxRichTextRange& range, const wxString& defName, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int specifiedLevel = -1);
248
249    /// Deletes the content in the given range
250    virtual bool Delete(const wxRichTextRange& range);
251
252    // translate between the position (which is just an index in the text ctrl
253    // considering all its contents as a single strings) and (x, y) coordinates
254    // which represent column and line.
255    virtual long XYToPosition(long x, long y) const;
256    virtual bool PositionToXY(long pos, long *x, long *y) const;
257
258    virtual void ShowPosition(long pos);
259
260    // find the character at position given in pixels
261    //
262    // NB: pt is in device coords (not adjusted for the client area origin nor
263    //     scrolling)
264    virtual wxTextCtrlHitTestResult HitTest(const wxPoint& pt, long *pos) const;
265    virtual wxTextCtrlHitTestResult HitTest(const wxPoint& pt,
266                                            wxTextCoord *col,
267                                            wxTextCoord *row) const;
268
269    // Clipboard operations
270    virtual void Copy();
271    virtual void Cut();
272    virtual void Paste();
273    virtual void DeleteSelection();
274
275    virtual bool CanCopy() const;
276    virtual bool CanCut() const;
277    virtual bool CanPaste() const;
278    virtual bool CanDeleteSelection() const;
279
280    // Undo/redo
281    virtual void Undo();
282    virtual void Redo();
283
284    virtual bool CanUndo() const;
285    virtual bool CanRedo() const;
286
287    // Insertion point
288    virtual void SetInsertionPoint(long pos);
289    virtual void SetInsertionPointEnd();
290    virtual long GetInsertionPoint() const;
291    virtual wxTextPos GetLastPosition() const;
292
293    virtual void SetSelection(long from, long to);
294    virtual void SelectAll();
295    virtual void SetEditable(bool editable);
296
297    /// Call Freeze to prevent refresh
298    virtual void Freeze();
299
300    /// Call Thaw to refresh
301    virtual void Thaw();
302
303    /// Call Thaw to refresh
304    virtual bool IsFrozen() const { return m_freezeCount > 0; }
305
306    virtual bool HasSelection() const;
307
308///// Functionality specific to wxRichTextCtrl
309
310    /// Write an image at the current insertion point. Supply optional type to use
311    /// for internal and file storage of the raw data.
312    virtual bool WriteImage(const wxImage& image, int bitmapType = wxBITMAP_TYPE_PNG);
313
314    /// Write a bitmap at the current insertion point. Supply optional type to use
315    /// for internal and file storage of the raw data.
316    virtual bool WriteImage(const wxBitmap& bitmap, int bitmapType = wxBITMAP_TYPE_PNG);
317
318    /// Load an image from file and write at the current insertion point.
319    virtual bool WriteImage(const wxString& filename, int bitmapType);
320
321    /// Write an image block at the current insertion point.
322    virtual bool WriteImage(const wxRichTextImageBlock& imageBlock);
323
324    /// Insert a newline (actually paragraph) at the current insertion point.
325    virtual bool Newline();
326
327    /// Insert a line break at the current insertion point.
328    virtual bool LineBreak();
329
330    /// Set basic (overall) style
331    virtual void SetBasicStyle(const wxTextAttrEx& style) { GetBuffer().SetBasicStyle(style); }
332    virtual void SetBasicStyle(const wxRichTextAttr& style) { GetBuffer().SetBasicStyle(style); }
333
334    /// Get basic (overall) style
335    virtual const wxTextAttrEx& GetBasicStyle() const { return GetBuffer().GetBasicStyle(); }
336
337    /// Begin using a style
338    virtual bool BeginStyle(const wxTextAttrEx& style) { return GetBuffer().BeginStyle(style); }
339
340    /// End the style
341    virtual bool EndStyle() { return GetBuffer().EndStyle(); }
342
343    /// End all styles
344    virtual bool EndAllStyles() { return GetBuffer().EndAllStyles(); }
345
346    /// Begin using bold
347    bool BeginBold() { return GetBuffer().BeginBold(); }
348
349    /// End using bold
350    bool EndBold()  { return GetBuffer().EndBold(); }
351
352    /// Begin using italic
353    bool BeginItalic() { return GetBuffer().BeginItalic(); }
354
355    /// End using italic
356    bool EndItalic() { return GetBuffer().EndItalic(); }
357
358    /// Begin using underline
359    bool BeginUnderline() { return GetBuffer().BeginUnderline(); }
360
361    /// End using underline
362    bool EndUnderline() { return GetBuffer().EndUnderline(); }
363
364    /// Begin using point size
365    bool BeginFontSize(int pointSize) { return GetBuffer().BeginFontSize(pointSize); }
366
367    /// End using point size
368    bool EndFontSize() { return GetBuffer().EndFontSize(); }
369
370    /// Begin using this font
371    bool BeginFont(const wxFont& font) { return GetBuffer().BeginFont(font); }
372
373    /// End using a font
374    bool EndFont() { return GetBuffer().EndFont(); }
375
376    /// Begin using this colour
377    bool BeginTextColour(const wxColour& colour) { return GetBuffer().BeginTextColour(colour); }
378
379    /// End using a colour
380    bool EndTextColour() { return GetBuffer().EndTextColour(); }
381
382    /// Begin using alignment
383    bool BeginAlignment(wxTextAttrAlignment alignment) { return GetBuffer().BeginAlignment(alignment); }
384
385    /// End alignment
386    bool EndAlignment() { return GetBuffer().EndAlignment(); }
387
388    /// Begin left indent
389    bool BeginLeftIndent(int leftIndent, int leftSubIndent = 0) { return GetBuffer().BeginLeftIndent(leftIndent, leftSubIndent); }
390
391    /// End left indent
392    bool EndLeftIndent() { return GetBuffer().EndLeftIndent(); }
393
394    /// Begin right indent
395    bool BeginRightIndent(int rightIndent) { return GetBuffer().BeginRightIndent(rightIndent); }
396
397    /// End right indent
398    bool EndRightIndent() { return GetBuffer().EndRightIndent(); }
399
400    /// Begin paragraph spacing
401    bool BeginParagraphSpacing(int before, int after) { return GetBuffer().BeginParagraphSpacing(before, after); }
402
403    /// End paragraph spacing
404    bool EndParagraphSpacing() { return GetBuffer().EndParagraphSpacing(); }
405
406    /// Begin line spacing
407    bool BeginLineSpacing(int lineSpacing) { return GetBuffer().BeginLineSpacing(lineSpacing); }
408
409    /// End line spacing
410    bool EndLineSpacing() { return GetBuffer().EndLineSpacing(); }
411
412    /// Begin numbered bullet
413    bool BeginNumberedBullet(int bulletNumber, int leftIndent, int leftSubIndent, int bulletStyle = wxTEXT_ATTR_BULLET_STYLE_ARABIC|wxTEXT_ATTR_BULLET_STYLE_PERIOD)
414    { return GetBuffer().BeginNumberedBullet(bulletNumber, leftIndent, leftSubIndent, bulletStyle); }
415
416    /// End numbered bullet
417    bool EndNumberedBullet() { return GetBuffer().EndNumberedBullet(); }
418
419    /// Begin symbol bullet
420    bool BeginSymbolBullet(const wxString& symbol, int leftIndent, int leftSubIndent, int bulletStyle = wxTEXT_ATTR_BULLET_STYLE_SYMBOL)
421    { return GetBuffer().BeginSymbolBullet(symbol, leftIndent, leftSubIndent, bulletStyle); }
422
423    /// End symbol bullet
424    bool EndSymbolBullet() { return GetBuffer().EndSymbolBullet(); }
425
426    /// Begin standard bullet
427    bool BeginStandardBullet(const wxString& bulletName, int leftIndent, int leftSubIndent, int bulletStyle = wxTEXT_ATTR_BULLET_STYLE_STANDARD)
428    { return GetBuffer().BeginStandardBullet(bulletName, leftIndent, leftSubIndent, bulletStyle); }
429
430    /// End standard bullet
431    bool EndStandardBullet() { return GetBuffer().EndStandardBullet(); }
432
433    /// Begin named character style
434    bool BeginCharacterStyle(const wxString& characterStyle) { return GetBuffer().BeginCharacterStyle(characterStyle); }
435
436    /// End named character style
437    bool EndCharacterStyle() { return GetBuffer().EndCharacterStyle(); }
438
439    /// Begin named paragraph style
440    bool BeginParagraphStyle(const wxString& paragraphStyle) { return GetBuffer().BeginParagraphStyle(paragraphStyle); }
441
442    /// End named character style
443    bool EndParagraphStyle() { return GetBuffer().EndParagraphStyle(); }
444
445    /// Begin named list style
446    bool BeginListStyle(const wxString& listStyle, int level = 1, int number = 1) { return GetBuffer().BeginListStyle(listStyle, level, number); }
447
448    /// End named character style
449    bool EndListStyle() { return GetBuffer().EndListStyle(); }
450
451    /// Begin URL
452    bool BeginURL(const wxString& url, const wxString& characterStyle = wxEmptyString) { return GetBuffer().BeginURL(url, characterStyle); }
453
454    /// End URL
455    bool EndURL() { return GetBuffer().EndURL(); }
456
457    /// Sets the default style to the style under the cursor
458    bool SetDefaultStyleToCursorStyle();
459
460    /// Clear the selection
461    virtual void SelectNone();
462
463    /// Select the word at the given character position
464    virtual bool SelectWord(long position);
465
466    /// Get/set the selection range in character positions. -1, -1 means no selection.
467    /// The range is in API convention, i.e. a single character selection is denoted
468    /// by (n, n+1)
469    wxRichTextRange GetSelectionRange() const;
470    void SetSelectionRange(const wxRichTextRange& range);
471
472    /// Get/set the selection range in character positions. -1, -1 means no selection.
473    /// The range is in internal format, i.e. a single character selection is denoted
474    /// by (n, n)
475    const wxRichTextRange& GetInternalSelectionRange() const { return m_selectionRange; }
476    void SetInternalSelectionRange(const wxRichTextRange& range) { m_selectionRange = range; }
477
478    /// Add a new paragraph of text to the end of the buffer
479    virtual wxRichTextRange AddParagraph(const wxString& text);
480
481    /// Add an image
482    virtual wxRichTextRange AddImage(const wxImage& image);
483
484    /// Layout the buffer: which we must do before certain operations, such as
485    /// setting the caret position.
486    virtual bool LayoutContent(bool onlyVisibleRect = false);
487
488    /// Move the caret to the given character position
489    virtual bool MoveCaret(long pos, bool showAtLineStart = false);
490
491    /// Move right
492    virtual bool MoveRight(int noPositions = 1, int flags = 0);
493
494    /// Move left
495    virtual bool MoveLeft(int noPositions = 1, int flags = 0);
496
497    /// Move up
498    virtual bool MoveUp(int noLines = 1, int flags = 0);
499
500    /// Move up
501    virtual bool MoveDown(int noLines = 1, int flags = 0);
502
503    /// Move to the end of the line
504    virtual bool MoveToLineEnd(int flags = 0);
505
506    /// Move to the start of the line
507    virtual bool MoveToLineStart(int flags = 0);
508
509    /// Move to the end of the paragraph
510    virtual bool MoveToParagraphEnd(int flags = 0);
511
512    /// Move to the start of the paragraph
513    virtual bool MoveToParagraphStart(int flags = 0);
514
515    /// Move to the start of the buffer
516    virtual bool MoveHome(int flags = 0);
517
518    /// Move to the end of the buffer
519    virtual bool MoveEnd(int flags = 0);
520
521    /// Move n pages up
522    virtual bool PageUp(int noPages = 1, int flags = 0);
523
524    /// Move n pages down
525    virtual bool PageDown(int noPages = 1, int flags = 0);
526
527    /// Move n words left
528    virtual bool WordLeft(int noPages = 1, int flags = 0);
529
530    /// Move n words right
531    virtual bool WordRight(int noPages = 1, int flags = 0);
532
533    /// Returns the buffer associated with the control.
534    wxRichTextBuffer& GetBuffer() { return m_buffer; }
535    const wxRichTextBuffer& GetBuffer() const { return m_buffer; }
536
537    /// Start batching undo history for commands.
538    virtual bool BeginBatchUndo(const wxString& cmdName) { return m_buffer.BeginBatchUndo(cmdName); }
539
540    /// End batching undo history for commands.
541    virtual bool EndBatchUndo() { return m_buffer.EndBatchUndo(); }
542
543    /// Are we batching undo history for commands?
544    virtual bool BatchingUndo() const { return m_buffer.BatchingUndo(); }
545
546    /// Start suppressing undo history for commands.
547    virtual bool BeginSuppressUndo() { return m_buffer.BeginSuppressUndo(); }
548
549    /// End suppressing undo history for commands.
550    virtual bool EndSuppressUndo() { return m_buffer.EndSuppressUndo(); }
551
552    /// Are we suppressing undo history for commands?
553    virtual bool SuppressingUndo() const { return m_buffer.SuppressingUndo(); }
554
555    /// Test if this whole range has character attributes of the specified kind. If any
556    /// of the attributes are different within the range, the test fails. You
557    /// can use this to implement, for example, bold button updating. style must have
558    /// flags indicating which attributes are of interest.
559    virtual bool HasCharacterAttributes(const wxRichTextRange& range, const wxTextAttrEx& style) const
560    {
561        return GetBuffer().HasCharacterAttributes(range.ToInternal(), style);
562    }
563    virtual bool HasCharacterAttributes(const wxRichTextRange& range, const wxRichTextAttr& style) const
564    {
565        return GetBuffer().HasCharacterAttributes(range.ToInternal(), style);
566    }
567
568    /// Test if this whole range has paragraph attributes of the specified kind. If any
569    /// of the attributes are different within the range, the test fails. You
570    /// can use this to implement, for example, centering button updating. style must have
571    /// flags indicating which attributes are of interest.
572    virtual bool HasParagraphAttributes(const wxRichTextRange& range, const wxTextAttrEx& style) const
573    {
574        return GetBuffer().HasParagraphAttributes(range.ToInternal(), style);
575    }
576    virtual bool HasParagraphAttributes(const wxRichTextRange& range, const wxRichTextAttr& style) const
577    {
578        return GetBuffer().HasParagraphAttributes(range.ToInternal(), style);
579    }
580
581    /// Is all of the selection bold?
582    virtual bool IsSelectionBold();
583
584    /// Is all of the selection italics?
585    virtual bool IsSelectionItalics();
586
587    /// Is all of the selection underlined?
588    virtual bool IsSelectionUnderlined();
589
590    /// Is all of the selection aligned according to the specified flag?
591    virtual bool IsSelectionAligned(wxTextAttrAlignment alignment);
592
593    /// Apply bold to the selection
594    virtual bool ApplyBoldToSelection();
595
596    /// Apply italic to the selection
597    virtual bool ApplyItalicToSelection();
598
599    /// Apply underline to the selection
600    virtual bool ApplyUnderlineToSelection();
601
602    /// Apply alignment to the selection
603    virtual bool ApplyAlignmentToSelection(wxTextAttrAlignment alignment);
604
605    /// Apply a named style to the selection
606    virtual bool ApplyStyle(wxRichTextStyleDefinition* def);
607
608    /// Set style sheet, if any
609    void SetStyleSheet(wxRichTextStyleSheet* styleSheet) { GetBuffer().SetStyleSheet(styleSheet); }
610    wxRichTextStyleSheet* GetStyleSheet() const { return GetBuffer().GetStyleSheet(); }
611
612    /// Push style sheet to top of stack
613    bool PushStyleSheet(wxRichTextStyleSheet* styleSheet) { return GetBuffer().PushStyleSheet(styleSheet); }
614
615    /// Pop style sheet from top of stack
616    wxRichTextStyleSheet* PopStyleSheet() { return GetBuffer().PopStyleSheet(); }
617
618    /// Apply the style sheet to the buffer, for example if the styles have changed.
619    bool ApplyStyleSheet(wxRichTextStyleSheet* styleSheet = NULL);
620
621// Command handlers
622
623    void Command(wxCommandEvent& event);
624    void OnDropFiles(wxDropFilesEvent& event);
625    void OnCaptureLost(wxMouseCaptureLostEvent& event);
626
627    void OnCut(wxCommandEvent& event);
628    void OnCopy(wxCommandEvent& event);
629    void OnPaste(wxCommandEvent& event);
630    void OnUndo(wxCommandEvent& event);
631    void OnRedo(wxCommandEvent& event);
632    void OnSelectAll(wxCommandEvent& event);
633    void OnClear(wxCommandEvent& event);
634
635    void OnUpdateCut(wxUpdateUIEvent& event);
636    void OnUpdateCopy(wxUpdateUIEvent& event);
637    void OnUpdatePaste(wxUpdateUIEvent& event);
638    void OnUpdateUndo(wxUpdateUIEvent& event);
639    void OnUpdateRedo(wxUpdateUIEvent& event);
640    void OnUpdateSelectAll(wxUpdateUIEvent& event);
641    void OnUpdateClear(wxUpdateUIEvent& event);
642
643    // Show a context menu for Rich Edit controls (the standard
644    // EDIT control has one already)
645    void OnContextMenu(wxContextMenuEvent& event);
646
647// Event handlers
648
649    /// Painting
650    void OnPaint(wxPaintEvent& event);
651    void OnEraseBackground(wxEraseEvent& event);
652
653    /// Left-click
654    void OnLeftClick(wxMouseEvent& event);
655
656    /// Left-up
657    void OnLeftUp(wxMouseEvent& event);
658
659    /// Motion
660    void OnMoveMouse(wxMouseEvent& event);
661
662    /// Left-double-click
663    void OnLeftDClick(wxMouseEvent& event);
664
665    /// Middle-click
666    void OnMiddleClick(wxMouseEvent& event);
667
668    /// Right-click
669    void OnRightClick(wxMouseEvent& event);
670
671    /// Key press
672    void OnChar(wxKeyEvent& event);
673
674    /// Sizing
675    void OnSize(wxSizeEvent& event);
676
677    /// Setting/losing focus
678    void OnSetFocus(wxFocusEvent& event);
679    void OnKillFocus(wxFocusEvent& event);
680
681    /// Idle-time processing
682    void OnIdle(wxIdleEvent& event);
683
684    /// Scrolling
685    void OnScroll(wxScrollWinEvent& event);
686
687    /// Set font, and also default attributes
688    virtual bool SetFont(const wxFont& font);
689
690    /// Set up scrollbars, e.g. after a resize
691    virtual void SetupScrollbars(bool atTop = false);
692
693    /// Keyboard navigation
694    virtual bool KeyboardNavigate(int keyCode, int flags);
695
696    /// Paint the background
697    virtual void PaintBackground(wxDC& dc);
698
699#if wxRICHTEXT_BUFFERED_PAINTING
700    /// Recreate buffer bitmap if necessary
701    virtual bool RecreateBuffer(const wxSize& size = wxDefaultSize);
702#endif
703
704    /// Set the selection
705    virtual void DoSetSelection(long from, long to, bool scrollCaret = true);
706
707    /// Write text
708    virtual void DoWriteText(const wxString& value, int flags = 0);
709
710    /// Should we inherit colours?
711    virtual bool ShouldInheritColours() const { return false; }
712
713    /// Position the caret
714    virtual void PositionCaret();
715
716    /// Extend the selection, returning true if the selection was
717    /// changed. Selections are in caret positions.
718    virtual bool ExtendSelection(long oldPosition, long newPosition, int flags);
719
720    /// Scroll into view. This takes a _caret_ position.
721    virtual bool ScrollIntoView(long position, int keyCode);
722
723    /// The caret position is the character position just before the caret.
724    /// A value of -1 means the caret is at the start of the buffer.
725    void SetCaretPosition(long position, bool showAtLineStart = false) ;
726    long GetCaretPosition() const { return m_caretPosition; }
727
728    /// The adjusted caret position is the character position adjusted to take
729    /// into account whether we're at the start of a paragraph, in which case
730    /// style information should be taken from the next position, not current one.
731    long GetAdjustedCaretPosition(long caretPos) const;
732
733    /// Move caret one visual step forward: this may mean setting a flag
734    /// and keeping the same position if we're going from the end of one line
735    /// to the start of the next, which may be the exact same caret position.
736    void MoveCaretForward(long oldPosition) ;
737
738    /// Move caret one visual step forward: this may mean setting a flag
739    /// and keeping the same position if we're going from the end of one line
740    /// to the start of the next, which may be the exact same caret position.
741    void MoveCaretBack(long oldPosition) ;
742
743    /// Get the caret height and position for the given character position
744    bool GetCaretPositionForIndex(long position, wxRect& rect);
745
746    /// Gets the line for the visible caret position. If the caret is
747    /// shown at the very end of the line, it means the next character is actually
748    /// on the following line. So let's get the line we're expecting to find
749    /// if this is the case.
750    wxRichTextLine* GetVisibleLineForCaretPosition(long caretPosition) const;
751
752    /// Gets the command processor
753    wxCommandProcessor* GetCommandProcessor() const { return GetBuffer().GetCommandProcessor(); }
754
755    /// Delete content if there is a selection, e.g. when pressing a key.
756    /// Returns the new caret position in newPos, or leaves it if there
757    /// was no action.
758    bool DeleteSelectedContent(long* newPos= NULL);
759
760    /// Transform logical to physical
761    wxPoint GetPhysicalPoint(const wxPoint& ptLogical) const;
762
763    /// Transform physical to logical
764    wxPoint GetLogicalPoint(const wxPoint& ptPhysical) const;
765
766    /// Finds the caret position for the next word. Direction
767    /// is 1 (forward) or -1 (backwards).
768    virtual long FindNextWordPosition(int direction = 1) const;
769
770    /// Is the given position visible on the screen?
771    bool IsPositionVisible(long pos) const;
772
773    /// Returns the first visible position in the current view
774    long GetFirstVisiblePosition() const;
775
776    /// Returns the caret position since the default formatting was changed. As
777    /// soon as this position changes, we no longer reflect the default style
778    /// in the UI. A value of -2 means that we should only reflect the style of the
779    /// content under the caret.
780    long GetCaretPositionForDefaultStyle() const { return m_caretPositionForDefaultStyle; }
781
782    /// Set the caret position for the default style that the user is selecting.
783    void SetCaretPositionForDefaultStyle(long pos) { m_caretPositionForDefaultStyle = pos; }
784
785    /// Should the UI reflect the default style chosen by the user, rather than the style under
786    /// the caret?
787    bool IsDefaultStyleShowing() const { return m_caretPositionForDefaultStyle != -2; }
788
789    /// Convenience function that tells the control to start reflecting the default
790    /// style, since the user is changing it.
791    void SetAndShowDefaultStyle(const wxRichTextAttr& attr)
792    {
793        SetDefaultStyle(attr);
794        SetCaretPositionForDefaultStyle(GetCaretPosition());
795    }
796
797    /// Get the first visible point in the window
798    wxPoint GetFirstVisiblePoint() const;
799
800// Implementation
801
802     /// Font names take a long time to retrieve, so cache them (on demand)
803     static const wxArrayString& GetAvailableFontNames();
804     static void ClearAvailableFontNames();
805
806     WX_FORWARD_TO_SCROLL_HELPER()
807
808// Overrides
809protected:
810
811    virtual wxSize DoGetBestSize() const ;
812
813    virtual void DoSetValue(const wxString& value, int flags = 0);
814
815
816// Data members
817private:
818
819    /// Allows nested Freeze/Thaw
820    int                     m_freezeCount;
821
822#if wxRICHTEXT_BUFFERED_PAINTING
823    /// Buffer bitmap
824    wxBitmap                m_bufferBitmap;
825#endif
826
827    /// Text buffer
828    wxRichTextBuffer        m_buffer;
829
830    wxMenu*                 m_contextMenu;
831
832    /// Caret position (1 less than the character position, so -1 is the
833    /// first caret position).
834    long                    m_caretPosition;
835
836    /// Caret position when the default formatting has been changed. As
837    /// soon as this position changes, we no longer reflect the default style
838    /// in the UI.
839    long                    m_caretPositionForDefaultStyle;
840
841    /// Selection range in character positions. -2, -2 means no selection.
842    wxRichTextRange         m_selectionRange;
843
844    /// Anchor so we know how to extend the selection
845    /// It's a caret position since it's between two characters.
846    long                    m_selectionAnchor;
847
848    /// Are we editable?
849    bool                    m_editable;
850
851    /// Are we showing the caret position at the start of a line
852    /// instead of at the end of the previous one?
853    bool                    m_caretAtLineStart;
854
855    /// Are we dragging a selection?
856    bool                    m_dragging;
857
858    /// Start position for drag
859    wxPoint                 m_dragStart;
860
861    /// Do we need full layout in idle?
862    bool                    m_fullLayoutRequired;
863    wxLongLong              m_fullLayoutTime;
864    long                    m_fullLayoutSavedPosition;
865
866    /// Threshold for doing delayed layout
867    long                    m_delayedLayoutThreshold;
868
869    /// Cursors
870    wxCursor                m_textCursor;
871    wxCursor                m_urlCursor;
872
873    static wxArrayString    sm_availableFontNames;
874};
875
876/*!
877 * wxRichTextEvent - the event class for wxRichTextCtrl notifications
878 */
879
880class WXDLLIMPEXP_RICHTEXT wxRichTextEvent : public wxNotifyEvent
881{
882public:
883    wxRichTextEvent(wxEventType commandType = wxEVT_NULL, int winid = 0)
884        : wxNotifyEvent(commandType, winid),
885        m_flags(0), m_position(-1), m_oldStyleSheet(NULL), m_newStyleSheet(NULL),
886        m_char((wxChar) 0)
887        { }
888
889    wxRichTextEvent(const wxRichTextEvent& event)
890        : wxNotifyEvent(event),
891        m_flags(event.m_flags), m_position(-1),
892        m_oldStyleSheet(event.m_oldStyleSheet), m_newStyleSheet(event.m_newStyleSheet),
893        m_char((wxChar) 0)
894        { }
895
896    long GetPosition() const { return m_position; }
897    void SetPosition(long pos) { m_position = pos; }
898
899    int GetFlags() const { return m_flags; }
900    void SetFlags(int flags) { m_flags = flags; }
901
902    wxRichTextStyleSheet* GetOldStyleSheet() const { return m_oldStyleSheet; }
903    void SetOldStyleSheet(wxRichTextStyleSheet* sheet) { m_oldStyleSheet = sheet; }
904
905    wxRichTextStyleSheet* GetNewStyleSheet() const { return m_newStyleSheet; }
906    void SetNewStyleSheet(wxRichTextStyleSheet* sheet) { m_newStyleSheet = sheet; }
907
908    const wxRichTextRange& GetRange() const { return m_range; }
909    void SetRange(const wxRichTextRange& range) { m_range = range; }
910
911    wxChar GetCharacter() const { return m_char; }
912    void SetCharacter(wxChar ch) { m_char = ch; }
913
914    virtual wxEvent *Clone() const { return new wxRichTextEvent(*this); }
915
916protected:
917    int                     m_flags;
918    long                    m_position;
919    wxRichTextStyleSheet*   m_oldStyleSheet;
920    wxRichTextStyleSheet*   m_newStyleSheet;
921    wxRichTextRange         m_range;
922    wxChar                  m_char;
923
924private:
925    DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxRichTextEvent)
926};
927
928/*!
929 * wxRichTextCtrl event macros
930 */
931
932BEGIN_DECLARE_EVENT_TYPES()
933    DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_LEFT_CLICK, 2602)
934    DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_RIGHT_CLICK, 2603)
935    DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_MIDDLE_CLICK, 2604)
936    DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_LEFT_DCLICK, 2605)
937    DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_RETURN, 2606)
938    DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_CHARACTER, 2607)
939    DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_DELETE, 2608)
940
941    DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_STYLESHEET_CHANGING, 2609)
942    DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_STYLESHEET_CHANGED, 2610)
943    DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_STYLESHEET_REPLACING, 2611)
944    DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_STYLESHEET_REPLACED, 2612)
945
946    DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_CONTENT_INSERTED, 2613)
947    DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_CONTENT_DELETED, 2614)
948    DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_STYLE_CHANGED, 2615)
949    DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_SELECTION_CHANGED, 2616)
950
951#if wxABI_VERSION >= 20808
952    DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_BUFFER_RESET, 2617)
953#endif
954END_DECLARE_EVENT_TYPES()
955
956typedef void (wxEvtHandler::*wxRichTextEventFunction)(wxRichTextEvent&);
957
958#define wxRichTextEventHandler(func) \
959    (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxRichTextEventFunction, &func)
960
961#define EVT_RICHTEXT_LEFT_CLICK(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_RICHTEXT_LEFT_CLICK, id, -1, (wxObjectEventFunction) (wxEventFunction)  wxStaticCastEvent( wxRichTextEventFunction, & fn ), NULL ),
962#define EVT_RICHTEXT_RIGHT_CLICK(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_RICHTEXT_RIGHT_CLICK, id, -1, (wxObjectEventFunction) (wxEventFunction)  wxStaticCastEvent( wxRichTextEventFunction, & fn ), NULL ),
963#define EVT_RICHTEXT_MIDDLE_CLICK(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_RICHTEXT_MIDDLE_CLICK, id, -1, (wxObjectEventFunction) (wxEventFunction)  wxStaticCastEvent( wxRichTextEventFunction, & fn ), NULL ),
964#define EVT_RICHTEXT_LEFT_DCLICK(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_RICHTEXT_LEFT_DCLICK, id, -1, (wxObjectEventFunction) (wxEventFunction)  wxStaticCastEvent( wxRichTextEventFunction, & fn ), NULL ),
965#define EVT_RICHTEXT_RETURN(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_RICHTEXT_RETURN, id, -1, (wxObjectEventFunction) (wxEventFunction)  wxStaticCastEvent( wxRichTextEventFunction, & fn ), NULL ),
966#define EVT_RICHTEXT_CHARACTER(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_RICHTEXT_CHARACTER, id, -1, (wxObjectEventFunction) (wxEventFunction)  wxStaticCastEvent( wxRichTextEventFunction, & fn ), NULL ),
967#define EVT_RICHTEXT_DELETE(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_RICHTEXT_DELETE, id, -1, (wxObjectEventFunction) (wxEventFunction)  wxStaticCastEvent( wxRichTextEventFunction, & fn ), NULL ),
968
969#define EVT_RICHTEXT_STYLESHEET_CHANGING(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_RICHTEXT_STYLESHEET_CHANGING, id, -1, (wxObjectEventFunction) (wxEventFunction)  wxStaticCastEvent( wxRichTextEventFunction, & fn ), NULL ),
970#define EVT_RICHTEXT_STYLESHEET_CHANGED(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_RICHTEXT_STYLESHEET_CHANGED, id, -1, (wxObjectEventFunction) (wxEventFunction)  wxStaticCastEvent( wxRichTextEventFunction, & fn ), NULL ),
971#define EVT_RICHTEXT_STYLESHEET_REPLACING(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_RICHTEXT_STYLESHEET_REPLACING, id, -1, (wxObjectEventFunction) (wxEventFunction)  wxStaticCastEvent( wxRichTextEventFunction, & fn ), NULL ),
972#define EVT_RICHTEXT_STYLESHEET_REPLACED(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_RICHTEXT_STYLESHEET_REPLACED, id, -1, (wxObjectEventFunction) (wxEventFunction)  wxStaticCastEvent( wxRichTextEventFunction, & fn ), NULL ),
973
974#define EVT_RICHTEXT_CONTENT_INSERTED(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_RICHTEXT_CONTENT_INSERTED, id, -1, (wxObjectEventFunction) (wxEventFunction)  wxStaticCastEvent( wxRichTextEventFunction, & fn ), NULL ),
975#define EVT_RICHTEXT_CONTENT_DELETED(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_RICHTEXT_CONTENT_DELETED, id, -1, (wxObjectEventFunction) (wxEventFunction)  wxStaticCastEvent( wxRichTextEventFunction, & fn ), NULL ),
976#define EVT_RICHTEXT_STYLE_CHANGED(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_RICHTEXT_STYLE_CHANGED, id, -1, (wxObjectEventFunction) (wxEventFunction)  wxStaticCastEvent( wxRichTextEventFunction, & fn ), NULL ),
977#define EVT_RICHTEXT_SELECTION_CHANGED(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_RICHTEXT_SELECTION_CHANGED, id, -1, (wxObjectEventFunction) (wxEventFunction)  wxStaticCastEvent( wxRichTextEventFunction, & fn ), NULL ),
978#define EVT_RICHTEXT_BUFFER_RESET(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_RICHTEXT_BUFFER_RESET, id, -1, (wxObjectEventFunction) (wxEventFunction)  wxStaticCastEvent( wxRichTextEventFunction, & fn ), NULL ),
979
980#endif
981    // wxUSE_RICHTEXT
982
983#endif
984    // _WX_RICHTEXTCTRL_H_
985