1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/richtext/richtextbuffer.h
3 // Purpose: Buffer for wxRichTextCtrl
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #ifndef _WX_RICHTEXTBUFFER_H_
13 #define _WX_RICHTEXTBUFFER_H_
20 Data is represented by a hierarchy of objects, all derived from
23 The top of the hierarchy is the buffer, a kind of wxRichTextParagraphLayoutBox.
24 These boxes will allow flexible placement of text boxes on a page, but
25 for now there is a single box representing the document, and this box is
26 a wxRichTextParagraphLayoutBox which contains further wxRichTextParagraph
27 objects, each of which can include text and images.
29 Each object maintains a range (start and end position) measured
30 from the start of the main parent box.
31 A paragraph object knows its range, and a text fragment knows its range
32 too. So, a character or image in a page has a position relative to the
33 start of the document, and a character in an embedded text box has
34 a position relative to that text box. For now, we will not be dealing with
35 embedded objects but it's something to bear in mind for later.
37 Note that internally, a range (5,5) represents a range of one character.
38 In the public wx[Rich]TextCtrl API, this would be passed to e.g. SetSelection
39 as (5,6). A paragraph with one character might have an internal range of (0, 1)
40 since the end of the paragraph takes up one position.
45 When Layout is called on an object, it is given a size which the object
46 must limit itself to, or one or more flexible directions (vertical
47 or horizontal). So for example a centered paragraph is given the page
48 width to play with (minus any margins), but can extend indefinitely
49 in the vertical direction. The implementation of Layout can then
50 cache the calculated size and position within the parent.
63 #include "wx/textctrl.h"
64 #include "wx/bitmap.h"
66 #include "wx/cmdproc.h"
67 #include "wx/txtstrm.h"
70 #include "wx/dataobj.h"
73 // Experimental dynamic styles to avoid user-specific character styles from being
74 // overwritten by paragraph styles.
75 #define wxRICHTEXT_USE_DYNAMIC_STYLES 1
81 #define wxRICHTEXT_TYPE_ANY 0
82 #define wxRICHTEXT_TYPE_TEXT 1
83 #define wxRICHTEXT_TYPE_XML 2
84 #define wxRICHTEXT_TYPE_HTML 3
85 #define wxRICHTEXT_TYPE_RTF 4
86 #define wxRICHTEXT_TYPE_PDF 5
89 * Forward declarations
92 class WXDLLIMPEXP_RICHTEXT wxRichTextCtrl
;
93 class WXDLLIMPEXP_RICHTEXT wxRichTextObject
;
94 class WXDLLIMPEXP_RICHTEXT wxRichTextCacheObject
;
95 class WXDLLIMPEXP_RICHTEXT wxRichTextObjectList
;
96 class WXDLLIMPEXP_RICHTEXT wxRichTextLine
;
97 class WXDLLIMPEXP_RICHTEXT wxRichTextParagraph
;
98 class WXDLLIMPEXP_RICHTEXT wxRichTextFileHandler
;
99 class WXDLLIMPEXP_RICHTEXT wxRichTextStyleSheet
;
100 class WXDLLIMPEXP_RICHTEXT wxTextAttrEx
;
101 class WXDLLIMPEXP_RICHTEXT wxRichTextListStyleDefinition
;
102 class WXDLLIMPEXP_RICHTEXT wxRichTextEvent
;
103 class WXDLLIMPEXP_RICHTEXT wxRichTextRenderer
;
106 * Flags determining the available space, passed to Layout
109 #define wxRICHTEXT_FIXED_WIDTH 0x01
110 #define wxRICHTEXT_FIXED_HEIGHT 0x02
111 #define wxRICHTEXT_VARIABLE_WIDTH 0x04
112 #define wxRICHTEXT_VARIABLE_HEIGHT 0x08
114 // Only lay out the part of the buffer that lies within
115 // the rect passed to Layout.
116 #define wxRICHTEXT_LAYOUT_SPECIFIED_RECT 0x10
119 * Flags returned from hit-testing
122 // The point was not on this object
123 #define wxRICHTEXT_HITTEST_NONE 0x01
124 // The point was before the position returned from HitTest
125 #define wxRICHTEXT_HITTEST_BEFORE 0x02
126 // The point was after the position returned from HitTest
127 #define wxRICHTEXT_HITTEST_AFTER 0x04
128 // The point was on the position returned from HitTest
129 #define wxRICHTEXT_HITTEST_ON 0x08
132 * Flags for GetRangeSize
135 #define wxRICHTEXT_FORMATTED 0x01
136 #define wxRICHTEXT_UNFORMATTED 0x02
139 * Flags for SetStyle/SetListStyle
142 #define wxRICHTEXT_SETSTYLE_NONE 0x00
144 // Specifies that this operation should be undoable
145 #define wxRICHTEXT_SETSTYLE_WITH_UNDO 0x01
147 // Specifies that the style should not be applied if the
148 // combined style at this point is already the style in question.
149 #define wxRICHTEXT_SETSTYLE_OPTIMIZE 0x02
151 // Specifies that the style should only be applied to paragraphs,
152 // and not the content. This allows content styling to be
153 // preserved independently from that of e.g. a named paragraph style.
154 #define wxRICHTEXT_SETSTYLE_PARAGRAPHS_ONLY 0x04
156 // Specifies that the style should only be applied to characters,
157 // and not the paragraph. This allows content styling to be
158 // preserved independently from that of e.g. a named paragraph style.
159 #define wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY 0x08
161 // For SetListStyle only: specifies starting from the given number, otherwise
162 // deduces number from existing attributes
163 #define wxRICHTEXT_SETSTYLE_RENUMBER 0x10
165 // For SetListStyle only: specifies the list level for all paragraphs, otherwise
166 // the current indentation will be used
167 #define wxRICHTEXT_SETSTYLE_SPECIFY_LEVEL 0x20
170 * Flags for text insertion
173 #define wxRICHTEXT_INSERT_NONE 0x00
174 #define wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE 0x01
177 * Extra formatting flags not in wxTextAttr
180 #define wxTEXT_ATTR_PARA_SPACING_AFTER 0x00000800
181 #define wxTEXT_ATTR_PARA_SPACING_BEFORE 0x00001000
182 #define wxTEXT_ATTR_LINE_SPACING 0x00002000
183 #define wxTEXT_ATTR_CHARACTER_STYLE_NAME 0x00004000
184 #define wxTEXT_ATTR_PARAGRAPH_STYLE_NAME 0x00008000
185 #define wxTEXT_ATTR_LIST_STYLE_NAME 0x00010000
186 #define wxTEXT_ATTR_BULLET_STYLE 0x00020000
187 #define wxTEXT_ATTR_BULLET_NUMBER 0x00040000
188 #define wxTEXT_ATTR_BULLET_TEXT 0x00080000
189 #define wxTEXT_ATTR_BULLET_NAME 0x00100000
190 #define wxTEXT_ATTR_URL 0x00200000
193 * Styles for wxTextAttrEx::SetBulletStyle
196 #define wxTEXT_ATTR_BULLET_STYLE_NONE 0x00000000
197 #define wxTEXT_ATTR_BULLET_STYLE_ARABIC 0x00000001
198 #define wxTEXT_ATTR_BULLET_STYLE_LETTERS_UPPER 0x00000002
199 #define wxTEXT_ATTR_BULLET_STYLE_LETTERS_LOWER 0x00000004
200 #define wxTEXT_ATTR_BULLET_STYLE_ROMAN_UPPER 0x00000008
201 #define wxTEXT_ATTR_BULLET_STYLE_ROMAN_LOWER 0x00000010
202 #define wxTEXT_ATTR_BULLET_STYLE_SYMBOL 0x00000020
203 #define wxTEXT_ATTR_BULLET_STYLE_BITMAP 0x00000040
204 #define wxTEXT_ATTR_BULLET_STYLE_PARENTHESES 0x00000080
205 #define wxTEXT_ATTR_BULLET_STYLE_PERIOD 0x00000100
206 #define wxTEXT_ATTR_BULLET_STYLE_STANDARD 0x00000200
207 #define wxTEXT_ATTR_BULLET_STYLE_RIGHT_PARENTHESIS 0x00000400
208 #define wxTEXT_ATTR_BULLET_STYLE_OUTLINE 0x00000800
210 #define wxTEXT_ATTR_BULLET_STYLE_ALIGN_LEFT 0x00000000
211 #define wxTEXT_ATTR_BULLET_STYLE_ALIGN_RIGHT 0x00001000
212 #define wxTEXT_ATTR_BULLET_STYLE_ALIGN_CENTRE 0x00002000
215 * Line spacing values
218 #define wxTEXT_ATTR_LINE_SPACING_NORMAL 10
219 #define wxTEXT_ATTR_LINE_SPACING_HALF 15
220 #define wxTEXT_ATTR_LINE_SPACING_TWICE 20
223 * Character and paragraph combined styles
226 #define wxTEXT_ATTR_CHARACTER (wxTEXT_ATTR_FONT | wxTEXT_ATTR_BACKGROUND_COLOUR | wxTEXT_ATTR_TEXT_COLOUR | wxTEXT_ATTR_CHARACTER_STYLE_NAME | wxTEXT_ATTR_URL)
228 #define wxTEXT_ATTR_PARAGRAPH (wxTEXT_ATTR_ALIGNMENT|wxTEXT_ATTR_LEFT_INDENT|wxTEXT_ATTR_RIGHT_INDENT|wxTEXT_ATTR_TABS|\
229 wxTEXT_ATTR_PARA_SPACING_BEFORE|wxTEXT_ATTR_PARA_SPACING_AFTER|wxTEXT_ATTR_LINE_SPACING|\
230 wxTEXT_ATTR_BULLET_STYLE|wxTEXT_ATTR_BULLET_NUMBER|wxTEXT_ATTR_BULLET_TEXT|wxTEXT_ATTR_BULLET_NAME|\
231 wxTEXT_ATTR_PARAGRAPH_STYLE_NAME|wxTEXT_ATTR_LIST_STYLE_NAME)
233 #define wxTEXT_ATTR_ALL (wxTEXT_ATTR_CHARACTER|wxTEXT_ATTR_PARAGRAPH)
236 * wxRichTextRange class declaration
237 * This stores beginning and end positions for a range of data.
240 class WXDLLIMPEXP_RICHTEXT wxRichTextRange
245 wxRichTextRange() { m_start
= 0; m_end
= 0; }
246 wxRichTextRange(long start
, long end
) { m_start
= start
; m_end
= end
; }
247 wxRichTextRange(const wxRichTextRange
& range
) { m_start
= range
.m_start
; m_end
= range
.m_end
; }
248 ~wxRichTextRange() {}
250 void operator =(const wxRichTextRange
& range
) { m_start
= range
.m_start
; m_end
= range
.m_end
; }
251 bool operator ==(const wxRichTextRange
& range
) const { return (m_start
== range
.m_start
&& m_end
== range
.m_end
); }
252 bool operator !=(const wxRichTextRange
& range
) const { return (m_start
!= range
.m_start
&& m_end
!= range
.m_end
); }
253 wxRichTextRange
operator -(const wxRichTextRange
& range
) const { return wxRichTextRange(m_start
- range
.m_start
, m_end
- range
.m_end
); }
254 wxRichTextRange
operator +(const wxRichTextRange
& range
) const { return wxRichTextRange(m_start
+ range
.m_start
, m_end
+ range
.m_end
); }
256 void SetRange(long start
, long end
) { m_start
= start
; m_end
= end
; }
258 void SetStart(long start
) { m_start
= start
; }
259 long GetStart() const { return m_start
; }
261 void SetEnd(long end
) { m_end
= end
; }
262 long GetEnd() const { return m_end
; }
264 /// Returns true if this range is completely outside 'range'
265 bool IsOutside(const wxRichTextRange
& range
) const { return range
.m_start
> m_end
|| range
.m_end
< m_start
; }
267 /// Returns true if this range is completely within 'range'
268 bool IsWithin(const wxRichTextRange
& range
) const { return m_start
>= range
.m_start
&& m_end
<= range
.m_end
; }
270 /// Returns true if the given position is within this range. Allow
271 /// for the possibility of an empty range - assume the position
272 /// is within this empty range. NO, I think we should not match with an empty range.
273 // bool Contains(long pos) const { return pos >= m_start && (pos <= m_end || GetLength() == 0); }
274 bool Contains(long pos
) const { return pos
>= m_start
&& pos
<= m_end
; }
276 /// Limit this range to be within 'range'
277 bool LimitTo(const wxRichTextRange
& range
) ;
279 /// Gets the length of the range
280 long GetLength() const { return m_end
- m_start
+ 1; }
282 /// Swaps the start and end
283 void Swap() { long tmp
= m_start
; m_start
= m_end
; m_end
= tmp
; }
285 /// Convert to internal form: (n, n) is the range of a single character.
286 wxRichTextRange
ToInternal() const { return wxRichTextRange(m_start
, m_end
-1); }
288 /// Convert from internal to public API form: (n, n+1) is the range of a single character.
289 wxRichTextRange
FromInternal() const { return wxRichTextRange(m_start
, m_end
+1); }
296 #define wxRICHTEXT_ALL wxRichTextRange(-2, -2)
297 #define wxRICHTEXT_NONE wxRichTextRange(-1, -1)
300 * wxTextAttrEx is an extended version of wxTextAttr with more paragraph attributes.
303 class WXDLLIMPEXP_RICHTEXT wxTextAttrEx
: public wxTextAttr
307 wxTextAttrEx(const wxTextAttrEx
& attr
);
308 wxTextAttrEx(const wxTextAttr
& attr
) { Init(); (*this) = attr
; }
309 wxTextAttrEx() { Init(); }
311 // Initialise this object
315 void Copy(const wxTextAttrEx
& attr
);
317 // Assignment from a wxTextAttrEx object
318 void operator= (const wxTextAttrEx
& attr
);
320 // Assignment from a wxTextAttr object
321 void operator= (const wxTextAttr
& attr
);
324 bool operator== (const wxTextAttrEx
& attr
) const;
327 void SetCharacterStyleName(const wxString
& name
) { m_characterStyleName
= name
; SetFlags(GetFlags() | wxTEXT_ATTR_CHARACTER_STYLE_NAME
); }
328 void SetParagraphStyleName(const wxString
& name
) { m_paragraphStyleName
= name
; SetFlags(GetFlags() | wxTEXT_ATTR_PARAGRAPH_STYLE_NAME
); }
329 void SetListStyleName(const wxString
& name
) { m_listStyleName
= name
; SetFlags(GetFlags() | wxTEXT_ATTR_LIST_STYLE_NAME
); }
330 void SetParagraphSpacingAfter(int spacing
) { m_paragraphSpacingAfter
= spacing
; SetFlags(GetFlags() | wxTEXT_ATTR_PARA_SPACING_AFTER
); }
331 void SetParagraphSpacingBefore(int spacing
) { m_paragraphSpacingBefore
= spacing
; SetFlags(GetFlags() | wxTEXT_ATTR_PARA_SPACING_BEFORE
); }
332 void SetLineSpacing(int spacing
) { m_lineSpacing
= spacing
; SetFlags(GetFlags() | wxTEXT_ATTR_LINE_SPACING
); }
333 void SetBulletStyle(int style
) { m_bulletStyle
= style
; SetFlags(GetFlags() | wxTEXT_ATTR_BULLET_STYLE
); }
334 void SetBulletNumber(int n
) { m_bulletNumber
= n
; SetFlags(GetFlags() | wxTEXT_ATTR_BULLET_NUMBER
); }
335 void SetBulletText(const wxString
& text
) { m_bulletText
= text
; SetFlags(GetFlags() | wxTEXT_ATTR_BULLET_TEXT
); }
336 void SetBulletName(const wxString
& name
) { m_bulletName
= name
; SetFlags(GetFlags() | wxTEXT_ATTR_BULLET_NAME
); }
337 void SetBulletFont(const wxString
& bulletFont
) { m_bulletFont
= bulletFont
; }
338 void SetURL(const wxString
& url
) { m_urlTarget
= url
; SetFlags(GetFlags() | wxTEXT_ATTR_URL
); }
340 const wxString
& GetCharacterStyleName() const { return m_characterStyleName
; }
341 const wxString
& GetParagraphStyleName() const { return m_paragraphStyleName
; }
342 const wxString
& GetListStyleName() const { return m_listStyleName
; }
343 int GetParagraphSpacingAfter() const { return m_paragraphSpacingAfter
; }
344 int GetParagraphSpacingBefore() const { return m_paragraphSpacingBefore
; }
345 int GetLineSpacing() const { return m_lineSpacing
; }
346 int GetBulletStyle() const { return m_bulletStyle
; }
347 int GetBulletNumber() const { return m_bulletNumber
; }
348 const wxString
& GetBulletText() const { return m_bulletText
; }
349 const wxString
& GetBulletName() const { return m_bulletName
; }
350 const wxString
& GetBulletFont() const { return m_bulletFont
; }
351 const wxString
& GetURL() const { return m_urlTarget
; }
353 bool HasWeight() const { return (GetFlags() & wxTEXT_ATTR_FONT_WEIGHT
) != 0; }
354 bool HasSize() const { return (GetFlags() & wxTEXT_ATTR_FONT_SIZE
) != 0; }
355 bool HasItalic() const { return (GetFlags() & wxTEXT_ATTR_FONT_ITALIC
) != 0; }
356 bool HasUnderlined() const { return (GetFlags() & wxTEXT_ATTR_FONT_UNDERLINE
) != 0; }
357 bool HasFaceName() const { return (GetFlags() & wxTEXT_ATTR_FONT_FACE
) != 0; }
359 bool HasParagraphSpacingAfter() const { return HasFlag(wxTEXT_ATTR_PARA_SPACING_AFTER
); }
360 bool HasParagraphSpacingBefore() const { return HasFlag(wxTEXT_ATTR_PARA_SPACING_BEFORE
); }
361 bool HasLineSpacing() const { return HasFlag(wxTEXT_ATTR_LINE_SPACING
); }
362 bool HasCharacterStyleName() const { return HasFlag(wxTEXT_ATTR_CHARACTER_STYLE_NAME
) || !m_characterStyleName
.IsEmpty(); }
363 bool HasParagraphStyleName() const { return HasFlag(wxTEXT_ATTR_PARAGRAPH_STYLE_NAME
) || !m_paragraphStyleName
.IsEmpty(); }
364 bool HasListStyleName() const { return HasFlag(wxTEXT_ATTR_LIST_STYLE_NAME
) || !m_listStyleName
.IsEmpty(); }
365 bool HasBulletStyle() const { return HasFlag(wxTEXT_ATTR_BULLET_STYLE
); }
366 bool HasBulletNumber() const { return HasFlag(wxTEXT_ATTR_BULLET_NUMBER
); }
367 bool HasBulletText() const { return HasFlag(wxTEXT_ATTR_BULLET_TEXT
); }
368 bool HasBulletName() const { return HasFlag(wxTEXT_ATTR_BULLET_NAME
); }
369 bool HasURL() const { return HasFlag(wxTEXT_ATTR_URL
); }
371 // Is this a character style?
372 bool IsCharacterStyle() const { return (0 != (GetFlags() & wxTEXT_ATTR_CHARACTER
)); }
373 bool IsParagraphStyle() const { return (0 != (GetFlags() & wxTEXT_ATTR_PARAGRAPH
)); }
375 // returns false if we have any attributes set, true otherwise
376 bool IsDefault() const
378 return !HasTextColour() && !HasBackgroundColour() && !HasFont() && !HasAlignment() &&
379 !HasTabs() && !HasLeftIndent() && !HasRightIndent() &&
380 !HasParagraphSpacingAfter() && !HasParagraphSpacingBefore() && !HasLineSpacing() &&
381 !HasCharacterStyleName() && !HasParagraphStyleName() && !HasListStyleName() &&
382 !HasBulletNumber() && !HasBulletStyle() && !HasBulletText() && !HasBulletName() && !HasURL();
385 // return the attribute having the valid font and colours: it uses the
386 // attributes set in attr and falls back first to attrDefault and then to
387 // the text control font/colours for those attributes which are not set
388 static wxTextAttrEx
CombineEx(const wxTextAttrEx
& attr
,
389 const wxTextAttrEx
& attrDef
,
390 const wxTextCtrlBase
*text
);
394 int m_paragraphSpacingAfter
;
395 int m_paragraphSpacingBefore
;
399 wxString m_bulletText
;
400 wxString m_bulletFont
;
401 wxString m_bulletName
;
402 wxString m_urlTarget
;
405 wxString m_characterStyleName
;
408 wxString m_paragraphStyleName
;
411 wxString m_listStyleName
;
415 * wxRichTextAttr stores attributes without a wxFont object, so is a much more
416 * efficient way to query styles.
419 class WXDLLIMPEXP_RICHTEXT wxRichTextAttr
423 wxRichTextAttr(const wxTextAttrEx
& attr
);
424 wxRichTextAttr(const wxRichTextAttr
& attr
);
425 wxRichTextAttr() { Init(); }
426 wxRichTextAttr(const wxColour
& colText
,
427 const wxColour
& colBack
= wxNullColour
,
428 wxTextAttrAlignment alignment
= wxTEXT_ALIGNMENT_DEFAULT
);
430 // Initialise this object.
434 void Copy(const wxRichTextAttr
& attr
);
436 // Assignment from a wxRichTextAttr object.
437 void operator= (const wxRichTextAttr
& attr
);
439 // Assignment from a wxTextAttrEx object.
440 void operator= (const wxTextAttrEx
& attr
);
443 bool operator== (const wxRichTextAttr
& attr
) const;
445 // Making a wxTextAttrEx object.
446 operator wxTextAttrEx () const ;
448 // Copy to a wxTextAttr
449 void CopyTo(wxTextAttrEx
& attr
) const;
451 // Create font from font attributes.
452 wxFont
CreateFont() const;
454 // Get attributes from font.
455 bool GetFontAttributes(const wxFont
& font
);
458 void SetTextColour(const wxColour
& colText
) { m_colText
= colText
; m_flags
|= wxTEXT_ATTR_TEXT_COLOUR
; }
459 void SetBackgroundColour(const wxColour
& colBack
) { m_colBack
= colBack
; m_flags
|= wxTEXT_ATTR_BACKGROUND_COLOUR
; }
460 void SetAlignment(wxTextAttrAlignment alignment
) { m_textAlignment
= alignment
; m_flags
|= wxTEXT_ATTR_ALIGNMENT
; }
461 void SetTabs(const wxArrayInt
& tabs
) { m_tabs
= tabs
; m_flags
|= wxTEXT_ATTR_TABS
; }
462 void SetLeftIndent(int indent
, int subIndent
= 0) { m_leftIndent
= indent
; m_leftSubIndent
= subIndent
; m_flags
|= wxTEXT_ATTR_LEFT_INDENT
; }
463 void SetRightIndent(int indent
) { m_rightIndent
= indent
; m_flags
|= wxTEXT_ATTR_RIGHT_INDENT
; }
465 void SetFontSize(int pointSize
) { m_fontSize
= pointSize
; m_flags
|= wxTEXT_ATTR_FONT_SIZE
; }
466 void SetFontStyle(int fontStyle
) { m_fontStyle
= fontStyle
; m_flags
|= wxTEXT_ATTR_FONT_ITALIC
; }
467 void SetFontWeight(int fontWeight
) { m_fontWeight
= fontWeight
; m_flags
|= wxTEXT_ATTR_FONT_WEIGHT
; }
468 void SetFontFaceName(const wxString
& faceName
) { m_fontFaceName
= faceName
; m_flags
|= wxTEXT_ATTR_FONT_FACE
; }
469 void SetFontUnderlined(bool underlined
) { m_fontUnderlined
= underlined
; m_flags
|= wxTEXT_ATTR_FONT_UNDERLINE
; }
471 void SetFlags(long flags
) { m_flags
= flags
; }
473 void SetCharacterStyleName(const wxString
& name
) { m_characterStyleName
= name
; m_flags
|= wxTEXT_ATTR_CHARACTER_STYLE_NAME
; }
474 void SetParagraphStyleName(const wxString
& name
) { m_paragraphStyleName
= name
; m_flags
|= wxTEXT_ATTR_PARAGRAPH_STYLE_NAME
; }
475 void SetListStyleName(const wxString
& name
) { m_listStyleName
= name
; SetFlags(GetFlags() | wxTEXT_ATTR_LIST_STYLE_NAME
); }
476 void SetParagraphSpacingAfter(int spacing
) { m_paragraphSpacingAfter
= spacing
; m_flags
|= wxTEXT_ATTR_PARA_SPACING_AFTER
; }
477 void SetParagraphSpacingBefore(int spacing
) { m_paragraphSpacingBefore
= spacing
; m_flags
|= wxTEXT_ATTR_PARA_SPACING_BEFORE
; }
478 void SetLineSpacing(int spacing
) { m_lineSpacing
= spacing
; m_flags
|= wxTEXT_ATTR_LINE_SPACING
; }
479 void SetBulletStyle(int style
) { m_bulletStyle
= style
; m_flags
|= wxTEXT_ATTR_BULLET_STYLE
; }
480 void SetBulletNumber(int n
) { m_bulletNumber
= n
; m_flags
|= wxTEXT_ATTR_BULLET_NUMBER
; }
481 void SetBulletText(const wxString
& text
) { m_bulletText
= text
; m_flags
|= wxTEXT_ATTR_BULLET_TEXT
; }
482 void SetBulletFont(const wxString
& bulletFont
) { m_bulletFont
= bulletFont
; }
483 void SetBulletName(const wxString
& name
) { m_bulletName
= name
; m_flags
|= wxTEXT_ATTR_BULLET_NAME
; }
484 void SetURL(const wxString
& url
) { m_urlTarget
= url
; m_flags
|= wxTEXT_ATTR_URL
; }
486 const wxColour
& GetTextColour() const { return m_colText
; }
487 const wxColour
& GetBackgroundColour() const { return m_colBack
; }
488 wxTextAttrAlignment
GetAlignment() const { return m_textAlignment
; }
489 const wxArrayInt
& GetTabs() const { return m_tabs
; }
490 long GetLeftIndent() const { return m_leftIndent
; }
491 long GetLeftSubIndent() const { return m_leftSubIndent
; }
492 long GetRightIndent() const { return m_rightIndent
; }
493 long GetFlags() const { return m_flags
; }
495 int GetFontSize() const { return m_fontSize
; }
496 int GetFontStyle() const { return m_fontStyle
; }
497 int GetFontWeight() const { return m_fontWeight
; }
498 bool GetFontUnderlined() const { return m_fontUnderlined
; }
499 const wxString
& GetFontFaceName() const { return m_fontFaceName
; }
501 const wxString
& GetCharacterStyleName() const { return m_characterStyleName
; }
502 const wxString
& GetParagraphStyleName() const { return m_paragraphStyleName
; }
503 const wxString
& GetListStyleName() const { return m_listStyleName
; }
504 int GetParagraphSpacingAfter() const { return m_paragraphSpacingAfter
; }
505 int GetParagraphSpacingBefore() const { return m_paragraphSpacingBefore
; }
506 int GetLineSpacing() const { return m_lineSpacing
; }
507 int GetBulletStyle() const { return m_bulletStyle
; }
508 int GetBulletNumber() const { return m_bulletNumber
; }
509 const wxString
& GetBulletText() const { return m_bulletText
; }
510 const wxString
& GetBulletFont() const { return m_bulletFont
; }
511 const wxString
& GetBulletName() const { return m_bulletName
; }
512 const wxString
& GetURL() const { return m_urlTarget
; }
515 bool HasTextColour() const { return m_colText
.Ok() && HasFlag(wxTEXT_ATTR_TEXT_COLOUR
) ; }
516 bool HasBackgroundColour() const { return m_colBack
.Ok() && HasFlag(wxTEXT_ATTR_BACKGROUND_COLOUR
) ; }
517 bool HasAlignment() const { return (m_textAlignment
!= wxTEXT_ALIGNMENT_DEFAULT
) || ((m_flags
& wxTEXT_ATTR_ALIGNMENT
) != 0) ; }
518 bool HasTabs() const { return (m_flags
& wxTEXT_ATTR_TABS
) != 0 ; }
519 bool HasLeftIndent() const { return (m_flags
& wxTEXT_ATTR_LEFT_INDENT
) != 0 ; }
520 bool HasRightIndent() const { return (m_flags
& wxTEXT_ATTR_RIGHT_INDENT
) != 0 ; }
521 bool HasWeight() const { return (m_flags
& wxTEXT_ATTR_FONT_WEIGHT
) != 0; }
522 bool HasSize() const { return (m_flags
& wxTEXT_ATTR_FONT_SIZE
) != 0; }
523 bool HasItalic() const { return (m_flags
& wxTEXT_ATTR_FONT_ITALIC
) != 0; }
524 bool HasUnderlined() const { return (m_flags
& wxTEXT_ATTR_FONT_UNDERLINE
) != 0; }
525 bool HasFaceName() const { return (m_flags
& wxTEXT_ATTR_FONT_FACE
) != 0; }
526 bool HasFont() const { return (m_flags
& (wxTEXT_ATTR_FONT
)) != 0; }
528 bool HasParagraphSpacingAfter() const { return (m_flags
& wxTEXT_ATTR_PARA_SPACING_AFTER
) != 0; }
529 bool HasParagraphSpacingBefore() const { return (m_flags
& wxTEXT_ATTR_PARA_SPACING_BEFORE
) != 0; }
530 bool HasLineSpacing() const { return (m_flags
& wxTEXT_ATTR_LINE_SPACING
) != 0; }
531 bool HasCharacterStyleName() const { return (m_flags
& wxTEXT_ATTR_CHARACTER_STYLE_NAME
) != 0 || !m_characterStyleName
.IsEmpty(); }
532 bool HasParagraphStyleName() const { return (m_flags
& wxTEXT_ATTR_PARAGRAPH_STYLE_NAME
) != 0 || !m_paragraphStyleName
.IsEmpty(); }
533 bool HasListStyleName() const { return HasFlag(wxTEXT_ATTR_LIST_STYLE_NAME
) || !m_listStyleName
.IsEmpty(); }
534 bool HasBulletStyle() const { return (m_flags
& wxTEXT_ATTR_BULLET_STYLE
) != 0; }
535 bool HasBulletNumber() const { return (m_flags
& wxTEXT_ATTR_BULLET_NUMBER
) != 0; }
536 bool HasBulletText() const { return (m_flags
& wxTEXT_ATTR_BULLET_TEXT
) != 0; }
537 bool HasBulletName() const { return (m_flags
& wxTEXT_ATTR_BULLET_NAME
) != 0; }
538 bool HasURL() const { return HasFlag(wxTEXT_ATTR_URL
); }
540 bool HasFlag(long flag
) const { return (m_flags
& flag
) != 0; }
542 // Is this a character style?
543 bool IsCharacterStyle() const { return (0 != (GetFlags() & wxTEXT_ATTR_CHARACTER
)); }
544 bool IsParagraphStyle() const { return (0 != (GetFlags() & wxTEXT_ATTR_PARAGRAPH
)); }
546 // returns false if we have any attributes set, true otherwise
547 bool IsDefault() const
549 return !HasTextColour() && !HasBackgroundColour() && !HasFont() && !HasAlignment() &&
550 !HasTabs() && !HasLeftIndent() && !HasRightIndent() &&
551 !HasParagraphSpacingAfter() && !HasParagraphSpacingBefore() && !HasLineSpacing() &&
552 !HasCharacterStyleName() && !HasParagraphStyleName() && !HasListStyleName() &&
553 !HasBulletNumber() && !HasBulletStyle() && !HasBulletText() && !HasBulletName() && !HasURL();
556 // return the attribute having the valid font and colours: it uses the
557 // attributes set in attr and falls back first to attrDefault and then to
558 // the text control font/colours for those attributes which are not set
559 static wxRichTextAttr
Combine(const wxRichTextAttr
& attr
,
560 const wxRichTextAttr
& attrDef
,
561 const wxTextCtrlBase
*text
);
566 wxArrayInt m_tabs
; // array of int: tab stops in 1/10 mm
567 int m_leftIndent
; // left indent in 1/10 mm
568 int m_leftSubIndent
; // left indent for all but the first
569 // line in a paragraph relative to the
570 // first line, in 1/10 mm
571 int m_rightIndent
; // right indent in 1/10 mm
572 wxTextAttrAlignment m_textAlignment
;
574 int m_paragraphSpacingAfter
;
575 int m_paragraphSpacingBefore
;
579 wxString m_bulletText
;
580 wxString m_bulletFont
;
581 wxString m_bulletName
;
582 wxString m_urlTarget
;
590 bool m_fontUnderlined
;
591 wxString m_fontFaceName
;
594 wxString m_characterStyleName
;
597 wxString m_paragraphStyleName
;
600 wxString m_listStyleName
;
604 * wxRichTextObject class declaration
605 * This is the base for drawable objects.
608 class WXDLLIMPEXP_RICHTEXT wxRichTextObject
: public wxObject
610 DECLARE_CLASS(wxRichTextObject
)
614 wxRichTextObject(wxRichTextObject
* parent
= NULL
);
615 virtual ~wxRichTextObject();
619 /// Draw the item, within the given range. Some objects may ignore the range (for
620 /// example paragraphs) while others must obey it (lines, to implement wrapping)
621 virtual bool Draw(wxDC
& dc
, const wxRichTextRange
& range
, const wxRichTextRange
& selectionRange
, const wxRect
& rect
, int descent
, int style
) = 0;
623 /// Lay the item out at the specified position with the given size constraint.
624 /// Layout must set the cached size.
625 virtual bool Layout(wxDC
& dc
, const wxRect
& rect
, int style
) = 0;
627 /// Hit-testing: returns a flag indicating hit test details, plus
628 /// information about position
629 virtual int HitTest(wxDC
& WXUNUSED(dc
), const wxPoint
& WXUNUSED(pt
), long& WXUNUSED(textPosition
)) { return false; }
631 /// Finds the absolute position and row height for the given character position
632 virtual bool FindPosition(wxDC
& WXUNUSED(dc
), long WXUNUSED(index
), wxPoint
& WXUNUSED(pt
), int* WXUNUSED(height
), bool WXUNUSED(forceLineStart
)) { return false; }
634 /// Get the best size, i.e. the ideal starting size for this object irrespective
635 /// of available space. For a short text string, it will be the size that exactly encloses
636 /// the text. For a longer string, it might use the parent width for example.
637 virtual wxSize
GetBestSize() const { return m_size
; }
639 /// Get the object size for the given range. Returns false if the range
640 /// is invalid for this object.
641 virtual bool GetRangeSize(const wxRichTextRange
& range
, wxSize
& size
, int& descent
, wxDC
& dc
, int flags
, wxPoint position
= wxPoint(0,0)) const = 0;
643 /// Do a split, returning an object containing the second part, and setting
644 /// the first part in 'this'.
645 virtual wxRichTextObject
* DoSplit(long WXUNUSED(pos
)) { return NULL
; }
647 /// Calculate range. By default, guess that the object is 1 unit long.
648 virtual void CalculateRange(long start
, long& end
) { end
= start
; m_range
.SetRange(start
, end
); }
651 virtual bool DeleteRange(const wxRichTextRange
& WXUNUSED(range
)) { return false; }
653 /// Returns true if the object is empty
654 virtual bool IsEmpty() const { return false; }
656 /// Get any text in this object for the given range
657 virtual wxString
GetTextForRange(const wxRichTextRange
& WXUNUSED(range
)) const { return wxEmptyString
; }
659 /// Returns true if this object can merge itself with the given one.
660 virtual bool CanMerge(wxRichTextObject
* WXUNUSED(object
)) const { return false; }
662 /// Returns true if this object merged itself with the given one.
663 /// The calling code will then delete the given object.
664 virtual bool Merge(wxRichTextObject
* WXUNUSED(object
)) { return false; }
666 /// Dump to output stream for debugging
667 virtual void Dump(wxTextOutputStream
& stream
);
671 /// Get/set the cached object size as calculated by Layout.
672 virtual wxSize
GetCachedSize() const { return m_size
; }
673 virtual void SetCachedSize(const wxSize
& sz
) { m_size
= sz
; }
675 /// Get/set the object position
676 virtual wxPoint
GetPosition() const { return m_pos
; }
677 virtual void SetPosition(const wxPoint
& pos
) { m_pos
= pos
; }
679 /// Get the rectangle enclosing the object
680 virtual wxRect
GetRect() const { return wxRect(GetPosition(), GetCachedSize()); }
683 void SetRange(const wxRichTextRange
& range
) { m_range
= range
; }
686 const wxRichTextRange
& GetRange() const { return m_range
; }
687 wxRichTextRange
& GetRange() { return m_range
; }
689 /// Get/set dirty flag (whether the object needs Layout to be called)
690 virtual bool GetDirty() const { return m_dirty
; }
691 virtual void SetDirty(bool dirty
) { m_dirty
= dirty
; }
693 /// Is this composite?
694 virtual bool IsComposite() const { return false; }
696 /// Get/set the parent.
697 virtual wxRichTextObject
* GetParent() const { return m_parent
; }
698 virtual void SetParent(wxRichTextObject
* parent
) { m_parent
= parent
; }
700 /// Set the margin around the object
701 virtual void SetMargins(int margin
);
702 virtual void SetMargins(int leftMargin
, int rightMargin
, int topMargin
, int bottomMargin
);
703 virtual int GetLeftMargin() const { return m_leftMargin
; }
704 virtual int GetRightMargin() const { return m_rightMargin
; }
705 virtual int GetTopMargin() const { return m_topMargin
; }
706 virtual int GetBottomMargin() const { return m_bottomMargin
; }
708 /// Set attributes object
709 void SetAttributes(const wxTextAttrEx
& attr
) { m_attributes
= attr
; }
710 const wxTextAttrEx
& GetAttributes() const { return m_attributes
; }
711 wxTextAttrEx
& GetAttributes() { return m_attributes
; }
713 /// Set/get stored descent
714 void SetDescent(int descent
) { m_descent
= descent
; }
715 int GetDescent() const { return m_descent
; }
720 virtual wxRichTextObject
* Clone() const { return NULL
; }
723 void Copy(const wxRichTextObject
& obj
);
725 /// Reference-counting allows us to use the same object in multiple
726 /// lists (not yet used)
727 void Reference() { m_refCount
++; }
730 /// Convert units in tends of a millimetre to device units
731 static int ConvertTenthsMMToPixels(wxDC
& dc
, int units
);
736 int m_descent
; // Descent for this object (if any)
739 wxRichTextObject
* m_parent
;
741 /// The range of this object (start position to end position)
742 wxRichTextRange m_range
;
751 wxTextAttrEx m_attributes
;
754 WX_DECLARE_LIST_WITH_DECL( wxRichTextObject
, wxRichTextObjectList
, class WXDLLIMPEXP_RICHTEXT
);
757 * wxRichTextCompositeObject class declaration
758 * Objects of this class can contain other objects.
761 class WXDLLIMPEXP_RICHTEXT wxRichTextCompositeObject
: public wxRichTextObject
763 DECLARE_CLASS(wxRichTextCompositeObject
)
767 wxRichTextCompositeObject(wxRichTextObject
* parent
= NULL
);
768 virtual ~wxRichTextCompositeObject();
772 /// Hit-testing: returns a flag indicating hit test details, plus
773 /// information about position
774 virtual int HitTest(wxDC
& dc
, const wxPoint
& pt
, long& textPosition
);
776 /// Finds the absolute position and row height for the given character position
777 virtual bool FindPosition(wxDC
& dc
, long index
, wxPoint
& pt
, int* height
, bool forceLineStart
);
780 virtual void CalculateRange(long start
, long& end
);
783 virtual bool DeleteRange(const wxRichTextRange
& range
);
785 /// Get any text in this object for the given range
786 virtual wxString
GetTextForRange(const wxRichTextRange
& range
) const;
788 /// Dump to output stream for debugging
789 virtual void Dump(wxTextOutputStream
& stream
);
794 wxRichTextObjectList
& GetChildren() { return m_children
; }
795 const wxRichTextObjectList
& GetChildren() const { return m_children
; }
797 /// Get the child count
798 size_t GetChildCount() const ;
800 /// Get the nth child
801 wxRichTextObject
* GetChild(size_t n
) const ;
803 /// Get/set dirty flag
804 virtual bool GetDirty() const { return m_dirty
; }
805 virtual void SetDirty(bool dirty
) { m_dirty
= dirty
; }
807 /// Is this composite?
808 virtual bool IsComposite() const { return true; }
810 /// Returns true if the buffer is empty
811 virtual bool IsEmpty() const { return GetChildCount() == 0; }
816 void Copy(const wxRichTextCompositeObject
& obj
);
819 void operator= (const wxRichTextCompositeObject
& obj
) { Copy(obj
); }
821 /// Append a child, returning the position
822 size_t AppendChild(wxRichTextObject
* child
) ;
824 /// Insert the child in front of the given object, or at the beginning
825 bool InsertChild(wxRichTextObject
* child
, wxRichTextObject
* inFrontOf
) ;
828 bool RemoveChild(wxRichTextObject
* child
, bool deleteChild
= false) ;
830 /// Delete all children
831 bool DeleteChildren() ;
833 /// Recursively merge all pieces that can be merged.
837 wxRichTextObjectList m_children
;
841 * wxRichTextBox class declaration
842 * This defines a 2D space to lay out objects
845 class WXDLLIMPEXP_RICHTEXT wxRichTextBox
: public wxRichTextCompositeObject
847 DECLARE_DYNAMIC_CLASS(wxRichTextBox
)
851 wxRichTextBox(wxRichTextObject
* parent
= NULL
);
852 wxRichTextBox(const wxRichTextBox
& obj
): wxRichTextCompositeObject() { Copy(obj
); }
857 virtual bool Draw(wxDC
& dc
, const wxRichTextRange
& range
, const wxRichTextRange
& selectionRange
, const wxRect
& rect
, int descent
, int style
);
860 virtual bool Layout(wxDC
& dc
, const wxRect
& rect
, int style
);
862 /// Get/set the object size for the given range. Returns false if the range
863 /// is invalid for this object.
864 virtual bool GetRangeSize(const wxRichTextRange
& range
, wxSize
& size
, int& descent
, wxDC
& dc
, int flags
, wxPoint position
= wxPoint(0,0)) const;
871 virtual wxRichTextObject
* Clone() const { return new wxRichTextBox(*this); }
874 void Copy(const wxRichTextBox
& obj
);
880 * wxRichTextParagraphBox class declaration
881 * This box knows how to lay out paragraphs.
884 class WXDLLIMPEXP_RICHTEXT wxRichTextParagraphLayoutBox
: public wxRichTextBox
886 DECLARE_DYNAMIC_CLASS(wxRichTextParagraphLayoutBox
)
890 wxRichTextParagraphLayoutBox(wxRichTextObject
* parent
= NULL
);
891 wxRichTextParagraphLayoutBox(const wxRichTextParagraphLayoutBox
& obj
): wxRichTextBox() { Init(); Copy(obj
); }
896 virtual bool Draw(wxDC
& dc
, const wxRichTextRange
& range
, const wxRichTextRange
& selectionRange
, const wxRect
& rect
, int descent
, int style
);
899 virtual bool Layout(wxDC
& dc
, const wxRect
& rect
, int style
);
901 /// Get/set the object size for the given range. Returns false if the range
902 /// is invalid for this object.
903 virtual bool GetRangeSize(const wxRichTextRange
& range
, wxSize
& size
, int& descent
, wxDC
& dc
, int flags
, wxPoint position
= wxPoint(0,0)) const;
906 virtual bool DeleteRange(const wxRichTextRange
& range
);
908 /// Get any text in this object for the given range
909 virtual wxString
GetTextForRange(const wxRichTextRange
& range
) const;
913 /// Associate a control with the buffer, for operations that for example require refreshing the window.
914 void SetRichTextCtrl(wxRichTextCtrl
* ctrl
) { m_ctrl
= ctrl
; }
916 /// Get the associated control.
917 wxRichTextCtrl
* GetRichTextCtrl() const { return m_ctrl
; }
919 /// Get/set whether the last paragraph is partial or complete
920 void SetPartialParagraph(bool partialPara
) { m_partialParagraph
= partialPara
; }
921 bool GetPartialParagraph() const { return m_partialParagraph
; }
923 /// If this is a buffer, returns the current style sheet. The base layout box
924 /// class doesn't have an associated style sheet.
925 virtual wxRichTextStyleSheet
* GetStyleSheet() const { return NULL
; }
929 /// Initialize the object.
932 /// Clear all children
933 virtual void Clear();
935 /// Clear and initialize with one blank paragraph
936 virtual void Reset();
938 /// Convenience function to add a paragraph of text
939 virtual wxRichTextRange
AddParagraph(const wxString
& text
, wxTextAttrEx
* paraStyle
= NULL
);
941 /// Convenience function to add an image
942 virtual wxRichTextRange
AddImage(const wxImage
& image
, wxTextAttrEx
* paraStyle
= NULL
);
944 /// Adds multiple paragraphs, based on newlines.
945 virtual wxRichTextRange
AddParagraphs(const wxString
& text
, wxTextAttrEx
* paraStyle
= NULL
);
947 /// Get the line at the given position. If caretPosition is true, the position is
948 /// a caret position, which is normally a smaller number.
949 virtual wxRichTextLine
* GetLineAtPosition(long pos
, bool caretPosition
= false) const;
951 /// Get the line at the given y pixel position, or the last line.
952 virtual wxRichTextLine
* GetLineAtYPosition(int y
) const;
954 /// Get the paragraph at the given character or caret position
955 virtual wxRichTextParagraph
* GetParagraphAtPosition(long pos
, bool caretPosition
= false) const;
957 /// Get the line size at the given position
958 virtual wxSize
GetLineSizeAtPosition(long pos
, bool caretPosition
= false) const;
960 /// Given a position, get the number of the visible line (potentially many to a paragraph),
961 /// starting from zero at the start of the buffer. We also have to pass a bool (startOfLine)
962 /// that indicates whether the caret is being shown at the end of the previous line or at the start
963 /// of the next, since the caret can be shown at 2 visible positions for the same underlying
965 virtual long GetVisibleLineNumber(long pos
, bool caretPosition
= false, bool startOfLine
= false) const;
967 /// Given a line number, get the corresponding wxRichTextLine object.
968 virtual wxRichTextLine
* GetLineForVisibleLineNumber(long lineNumber
) const;
970 /// Get the leaf object in a paragraph at this position.
971 /// Given a line number, get the corresponding wxRichTextLine object.
972 virtual wxRichTextObject
* GetLeafObjectAtPosition(long position
) const;
974 /// Get the paragraph by number
975 virtual wxRichTextParagraph
* GetParagraphAtLine(long paragraphNumber
) const;
977 /// Get the paragraph for a given line
978 virtual wxRichTextParagraph
* GetParagraphForLine(wxRichTextLine
* line
) const;
980 /// Get the length of the paragraph
981 virtual int GetParagraphLength(long paragraphNumber
) const;
983 /// Get the number of paragraphs
984 virtual int GetParagraphCount() const { return GetChildCount(); }
986 /// Get the number of visible lines
987 virtual int GetLineCount() const;
989 /// Get the text of the paragraph
990 virtual wxString
GetParagraphText(long paragraphNumber
) const;
992 /// Convert zero-based line column and paragraph number to a position.
993 virtual long XYToPosition(long x
, long y
) const;
995 /// Convert zero-based position to line column and paragraph number
996 virtual bool PositionToXY(long pos
, long* x
, long* y
) const;
998 /// Set text attributes: character and/or paragraph styles.
999 virtual bool SetStyle(const wxRichTextRange
& range
, const wxRichTextAttr
& style
, int flags
= wxRICHTEXT_SETSTYLE_WITH_UNDO
);
1000 virtual bool SetStyle(const wxRichTextRange
& range
, const wxTextAttrEx
& style
, int flags
= wxRICHTEXT_SETSTYLE_WITH_UNDO
);
1002 /// Get the conbined text attributes for this position.
1003 virtual bool GetStyle(long position
, wxTextAttrEx
& style
);
1004 virtual bool GetStyle(long position
, wxRichTextAttr
& style
);
1006 /// Get the content (uncombined) attributes for this position.
1007 virtual bool GetUncombinedStyle(long position
, wxTextAttrEx
& style
);
1008 virtual bool GetUncombinedStyle(long position
, wxRichTextAttr
& style
);
1010 /// Implementation helper for GetStyle. If combineStyles is true, combine base, paragraph and
1011 /// context attributes.
1012 virtual bool DoGetStyle(long position
, wxTextAttrEx
& style
, bool combineStyles
= true);
1014 /// Get the combined style for a range - if any attribute is different within the range,
1015 /// that attribute is not present within the flags
1016 virtual bool GetStyleForRange(const wxRichTextRange
& range
, wxTextAttrEx
& style
);
1018 /// Combines 'style' with 'currentStyle' for the purpose of summarising the attributes of a range of
1020 bool CollectStyle(wxTextAttrEx
& currentStyle
, const wxTextAttrEx
& style
, long& multipleStyleAttributes
);
1023 virtual bool SetListStyle(const wxRichTextRange
& range
, wxRichTextListStyleDefinition
* def
, int flags
= wxRICHTEXT_SETSTYLE_WITH_UNDO
, int startFrom
= 1, int specifiedLevel
= -1);
1024 virtual bool SetListStyle(const wxRichTextRange
& range
, const wxString
& defName
, int flags
= wxRICHTEXT_SETSTYLE_WITH_UNDO
, int startFrom
= 1, int specifiedLevel
= -1);
1026 /// Clear list for given range
1027 virtual bool ClearListStyle(const wxRichTextRange
& range
, int flags
= wxRICHTEXT_SETSTYLE_WITH_UNDO
);
1029 /// Number/renumber any list elements in the given range.
1030 /// def/defName can be NULL/empty to indicate that the existing list style should be used.
1031 virtual bool NumberList(const wxRichTextRange
& range
, wxRichTextListStyleDefinition
* def
= NULL
, int flags
= wxRICHTEXT_SETSTYLE_WITH_UNDO
, int startFrom
= 1, int specifiedLevel
= -1);
1032 virtual bool NumberList(const wxRichTextRange
& range
, const wxString
& defName
, int flags
= wxRICHTEXT_SETSTYLE_WITH_UNDO
, int startFrom
= 1, int specifiedLevel
= -1);
1034 /// Promote the list items within the given range. promoteBy can be a positive or negative number, e.g. 1 or -1
1035 /// def/defName can be NULL/empty to indicate that the existing list style should be used.
1036 virtual bool PromoteList(int promoteBy
, const wxRichTextRange
& range
, wxRichTextListStyleDefinition
* def
= NULL
, int flags
= wxRICHTEXT_SETSTYLE_WITH_UNDO
, int specifiedLevel
= -1);
1037 virtual bool PromoteList(int promoteBy
, const wxRichTextRange
& range
, const wxString
& defName
, int flags
= wxRICHTEXT_SETSTYLE_WITH_UNDO
, int specifiedLevel
= -1);
1039 /// Helper for NumberList and PromoteList, that does renumbering and promotion simultaneously
1040 /// def/defName can be NULL/empty to indicate that the existing list style should be used.
1041 virtual bool DoNumberList(const wxRichTextRange
& range
, const wxRichTextRange
& promotionRange
, int promoteBy
, wxRichTextListStyleDefinition
* def
, int flags
= wxRICHTEXT_SETSTYLE_WITH_UNDO
, int startFrom
= 1, int specifiedLevel
= -1);
1043 /// Fills in the attributes for numbering a paragraph after previousParagraph.
1044 virtual bool FindNextParagraphNumber(wxRichTextParagraph
* previousParagraph
, wxRichTextAttr
& attr
) const;
1046 /// Test if this whole range has character attributes of the specified kind. If any
1047 /// of the attributes are different within the range, the test fails. You
1048 /// can use this to implement, for example, bold button updating. style must have
1049 /// flags indicating which attributes are of interest.
1050 virtual bool HasCharacterAttributes(const wxRichTextRange
& range
, const wxTextAttrEx
& style
) const;
1051 virtual bool HasCharacterAttributes(const wxRichTextRange
& range
, const wxRichTextAttr
& style
) const;
1053 /// Test if this whole range has paragraph attributes of the specified kind. If any
1054 /// of the attributes are different within the range, the test fails. You
1055 /// can use this to implement, for example, centering button updating. style must have
1056 /// flags indicating which attributes are of interest.
1057 virtual bool HasParagraphAttributes(const wxRichTextRange
& range
, const wxTextAttrEx
& style
) const;
1058 virtual bool HasParagraphAttributes(const wxRichTextRange
& range
, const wxRichTextAttr
& style
) const;
1061 virtual wxRichTextObject
* Clone() const { return new wxRichTextParagraphLayoutBox(*this); }
1063 /// Insert fragment into this box at the given position. If partialParagraph is true,
1064 /// it is assumed that the last (or only) paragraph is just a piece of data with no paragraph
1066 virtual bool InsertFragment(long position
, wxRichTextParagraphLayoutBox
& fragment
);
1068 /// Make a copy of the fragment corresponding to the given range, putting it in 'fragment'.
1069 virtual bool CopyFragment(const wxRichTextRange
& range
, wxRichTextParagraphLayoutBox
& fragment
);
1071 /// Apply the style sheet to the buffer, for example if the styles have changed.
1072 virtual bool ApplyStyleSheet(wxRichTextStyleSheet
* styleSheet
);
1075 void Copy(const wxRichTextParagraphLayoutBox
& obj
);
1078 void operator= (const wxRichTextParagraphLayoutBox
& obj
) { Copy(obj
); }
1080 /// Calculate ranges
1081 virtual void UpdateRanges() { long end
; CalculateRange(0, end
); }
1083 /// Get all the text
1084 virtual wxString
GetText() const;
1086 /// Set default style for new content. Setting it to a default attribute
1087 /// makes new content take on the 'basic' style.
1088 virtual bool SetDefaultStyle(const wxTextAttrEx
& style
);
1090 /// Get default style
1091 virtual const wxTextAttrEx
& GetDefaultStyle() const { return m_defaultAttributes
; }
1093 /// Set basic (overall) style
1094 virtual void SetBasicStyle(const wxTextAttrEx
& style
) { m_attributes
= style
; }
1095 virtual void SetBasicStyle(const wxRichTextAttr
& style
) { style
.CopyTo(m_attributes
); }
1097 /// Get basic (overall) style
1098 virtual const wxTextAttrEx
& GetBasicStyle() const { return m_attributes
; }
1100 /// Invalidate the buffer. With no argument, invalidates whole buffer.
1101 void Invalidate(const wxRichTextRange
& invalidRange
= wxRICHTEXT_ALL
);
1103 /// Get invalid range, rounding to entire paragraphs if argument is true.
1104 wxRichTextRange
GetInvalidRange(bool wholeParagraphs
= false) const;
1107 wxRichTextCtrl
* m_ctrl
;
1108 wxTextAttrEx m_defaultAttributes
;
1110 /// The invalidated range that will need full layout
1111 wxRichTextRange m_invalidRange
;
1113 // Is the last paragraph partial or complete?
1114 bool m_partialParagraph
;
1118 * wxRichTextLine class declaration
1119 * This object represents a line in a paragraph, and stores
1120 * offsets from the start of the paragraph representing the
1121 * start and end positions of the line.
1124 class WXDLLIMPEXP_RICHTEXT wxRichTextLine
1129 wxRichTextLine(wxRichTextParagraph
* parent
);
1130 wxRichTextLine(const wxRichTextLine
& obj
) { Init( NULL
); Copy(obj
); }
1131 virtual ~wxRichTextLine() {}
1138 void SetRange(const wxRichTextRange
& range
) { m_range
= range
; }
1139 void SetRange(long from
, long to
) { m_range
= wxRichTextRange(from
, to
); }
1141 /// Get the parent paragraph
1142 wxRichTextParagraph
* GetParent() { return m_parent
; }
1145 const wxRichTextRange
& GetRange() const { return m_range
; }
1146 wxRichTextRange
& GetRange() { return m_range
; }
1148 /// Get the absolute range
1149 wxRichTextRange
GetAbsoluteRange() const;
1151 /// Get/set the line size as calculated by Layout.
1152 virtual wxSize
GetSize() const { return m_size
; }
1153 virtual void SetSize(const wxSize
& sz
) { m_size
= sz
; }
1155 /// Get/set the object position relative to the parent
1156 virtual wxPoint
GetPosition() const { return m_pos
; }
1157 virtual void SetPosition(const wxPoint
& pos
) { m_pos
= pos
; }
1159 /// Get the absolute object position
1160 virtual wxPoint
GetAbsolutePosition() const;
1162 /// Get the rectangle enclosing the line
1163 virtual wxRect
GetRect() const { return wxRect(GetAbsolutePosition(), GetSize()); }
1165 /// Set/get stored descent
1166 void SetDescent(int descent
) { m_descent
= descent
; }
1167 int GetDescent() const { return m_descent
; }
1172 void Init(wxRichTextParagraph
* parent
);
1175 void Copy(const wxRichTextLine
& obj
);
1178 virtual wxRichTextLine
* Clone() const { return new wxRichTextLine(*this); }
1182 /// The range of the line (start position to end position)
1183 /// This is relative to the parent paragraph.
1184 wxRichTextRange m_range
;
1186 /// Size and position measured relative to top of paragraph
1190 /// Maximum descent for this line (location of text baseline)
1193 // The parent object
1194 wxRichTextParagraph
* m_parent
;
1197 WX_DECLARE_LIST_WITH_DECL( wxRichTextLine
, wxRichTextLineList
, class WXDLLIMPEXP_RICHTEXT
);
1200 * wxRichTextParagraph class declaration
1201 * This object represents a single paragraph (or in a straight text editor, a line).
1204 class WXDLLIMPEXP_RICHTEXT wxRichTextParagraph
: public wxRichTextBox
1206 DECLARE_DYNAMIC_CLASS(wxRichTextParagraph
)
1210 wxRichTextParagraph(wxRichTextObject
* parent
= NULL
, wxTextAttrEx
* style
= NULL
);
1211 wxRichTextParagraph(const wxString
& text
, wxRichTextObject
* parent
= NULL
, wxTextAttrEx
* style
= NULL
);
1212 virtual ~wxRichTextParagraph();
1213 wxRichTextParagraph(const wxRichTextParagraph
& obj
): wxRichTextBox() { Copy(obj
); }
1218 virtual bool Draw(wxDC
& dc
, const wxRichTextRange
& range
, const wxRichTextRange
& selectionRange
, const wxRect
& rect
, int descent
, int style
);
1220 /// Lay the item out
1221 virtual bool Layout(wxDC
& dc
, const wxRect
& rect
, int style
);
1223 /// Get/set the object size for the given range. Returns false if the range
1224 /// is invalid for this object.
1225 virtual bool GetRangeSize(const wxRichTextRange
& range
, wxSize
& size
, int& descent
, wxDC
& dc
, int flags
, wxPoint position
= wxPoint(0,0)) const;
1227 /// Finds the absolute position and row height for the given character position
1228 virtual bool FindPosition(wxDC
& dc
, long index
, wxPoint
& pt
, int* height
, bool forceLineStart
);
1230 /// Hit-testing: returns a flag indicating hit test details, plus
1231 /// information about position
1232 virtual int HitTest(wxDC
& dc
, const wxPoint
& pt
, long& textPosition
);
1235 virtual void CalculateRange(long start
, long& end
);
1239 /// Get the cached lines
1240 wxRichTextLineList
& GetLines() { return m_cachedLines
; }
1245 void Copy(const wxRichTextParagraph
& obj
);
1248 virtual wxRichTextObject
* Clone() const { return new wxRichTextParagraph(*this); }
1250 /// Clear the cached lines
1255 /// Apply paragraph styles such as centering to the wrapped lines
1256 virtual void ApplyParagraphStyle(const wxTextAttrEx
& attr
, const wxRect
& rect
);
1258 /// Insert text at the given position
1259 virtual bool InsertText(long pos
, const wxString
& text
);
1261 /// Split an object at this position if necessary, and return
1262 /// the previous object, or NULL if inserting at beginning.
1263 virtual wxRichTextObject
* SplitAt(long pos
, wxRichTextObject
** previousObject
= NULL
);
1265 /// Move content to a list from this point
1266 virtual void MoveToList(wxRichTextObject
* obj
, wxList
& list
);
1268 /// Add content back from list
1269 virtual void MoveFromList(wxList
& list
);
1271 /// Get the plain text searching from the start or end of the range.
1272 /// The resulting string may be shorter than the range given.
1273 bool GetContiguousPlainText(wxString
& text
, const wxRichTextRange
& range
, bool fromStart
= true);
1275 /// Find a suitable wrap position. wrapPosition is the last position in the line to the left
1277 bool FindWrapPosition(const wxRichTextRange
& range
, wxDC
& dc
, int availableSpace
, long& wrapPosition
);
1279 /// Find the object at the given position
1280 wxRichTextObject
* FindObjectAtPosition(long position
);
1282 /// Get the bullet text for this paragraph.
1283 wxString
GetBulletText();
1285 /// Allocate or reuse a line object
1286 wxRichTextLine
* AllocateLine(int pos
);
1288 /// Clear remaining unused line objects, if any
1289 bool ClearUnusedLines(int lineCount
);
1291 /// Get combined attributes of the base style, paragraph style and character style. We use this to dynamically
1292 /// retrieve the actual style.
1293 wxTextAttrEx
GetCombinedAttributes(const wxTextAttrEx
& contentStyle
) const;
1295 /// Get combined attributes of the base style and paragraph style.
1296 wxTextAttrEx
GetCombinedAttributes() const;
1298 /// Create default tabstop array
1299 static void InitDefaultTabs();
1301 /// Clear default tabstop array
1302 static void ClearDefaultTabs();
1304 /// Get default tabstop array
1305 static const wxArrayInt
& GetDefaultTabs() { return sm_defaultTabs
; }
1308 /// The lines that make up the wrapped paragraph
1309 wxRichTextLineList m_cachedLines
;
1311 /// Default tabstops
1312 static wxArrayInt sm_defaultTabs
;
1316 * wxRichTextPlainText class declaration
1317 * This object represents a single piece of text.
1320 class WXDLLIMPEXP_RICHTEXT wxRichTextPlainText
: public wxRichTextObject
1322 DECLARE_DYNAMIC_CLASS(wxRichTextPlainText
)
1326 wxRichTextPlainText(const wxString
& text
= wxEmptyString
, wxRichTextObject
* parent
= NULL
, wxTextAttrEx
* style
= NULL
);
1327 wxRichTextPlainText(const wxRichTextPlainText
& obj
): wxRichTextObject() { Copy(obj
); }
1332 virtual bool Draw(wxDC
& dc
, const wxRichTextRange
& range
, const wxRichTextRange
& selectionRange
, const wxRect
& rect
, int descent
, int style
);
1334 /// Lay the item out
1335 virtual bool Layout(wxDC
& dc
, const wxRect
& rect
, int style
);
1337 /// Get/set the object size for the given range. Returns false if the range
1338 /// is invalid for this object.
1339 virtual bool GetRangeSize(const wxRichTextRange
& range
, wxSize
& size
, int& descent
, wxDC
& dc
, int flags
, wxPoint position
/* = wxPoint(0,0)*/) const;
1341 /// Get any text in this object for the given range
1342 virtual wxString
GetTextForRange(const wxRichTextRange
& range
) const;
1344 /// Do a split, returning an object containing the second part, and setting
1345 /// the first part in 'this'.
1346 virtual wxRichTextObject
* DoSplit(long pos
);
1349 virtual void CalculateRange(long start
, long& end
);
1352 virtual bool DeleteRange(const wxRichTextRange
& range
);
1354 /// Returns true if the object is empty
1355 virtual bool IsEmpty() const { return m_text
.empty(); }
1357 /// Returns true if this object can merge itself with the given one.
1358 virtual bool CanMerge(wxRichTextObject
* object
) const;
1360 /// Returns true if this object merged itself with the given one.
1361 /// The calling code will then delete the given object.
1362 virtual bool Merge(wxRichTextObject
* object
);
1364 /// Dump to output stream for debugging
1365 virtual void Dump(wxTextOutputStream
& stream
);
1370 const wxString
& GetText() const { return m_text
; }
1373 void SetText(const wxString
& text
) { m_text
= text
; }
1378 void Copy(const wxRichTextPlainText
& obj
);
1381 virtual wxRichTextObject
* Clone() const { return new wxRichTextPlainText(*this); }
1383 bool DrawTabbedString(wxDC
& dc
, const wxTextAttrEx
& attr
, const wxRect
& rect
, wxString
& str
, wxCoord
& x
, wxCoord
& y
, bool selected
);
1390 * wxRichTextImageBlock stores information about an image, in binary in-memory form
1393 class WXDLLIMPEXP_BASE wxDataInputStream
;
1394 class WXDLLIMPEXP_BASE wxDataOutputStream
;
1396 class WXDLLIMPEXP_RICHTEXT wxRichTextImageBlock
: public wxObject
1399 wxRichTextImageBlock();
1400 wxRichTextImageBlock(const wxRichTextImageBlock
& block
);
1401 virtual ~wxRichTextImageBlock();
1406 // Load the original image into a memory block.
1407 // If the image is not a JPEG, we must convert it into a JPEG
1408 // to conserve space.
1409 // If it's not a JPEG we can make use of 'image', already scaled, so we don't have to
1410 // load the image a 2nd time.
1411 virtual bool MakeImageBlock(const wxString
& filename
, int imageType
, wxImage
& image
, bool convertToJPEG
= true);
1413 // Make an image block from the wxImage in the given
1415 virtual bool MakeImageBlock(wxImage
& image
, int imageType
, int quality
= 80);
1418 bool Write(const wxString
& filename
);
1420 // Write data in hex to a stream
1421 bool WriteHex(wxOutputStream
& stream
);
1423 // Read data in hex from a stream
1424 bool ReadHex(wxInputStream
& stream
, int length
, int imageType
);
1426 // Copy from 'block'
1427 void Copy(const wxRichTextImageBlock
& block
);
1429 // Load a wxImage from the block
1430 bool Load(wxImage
& image
);
1433 void operator=(const wxRichTextImageBlock
& block
);
1437 unsigned char* GetData() const { return m_data
; }
1438 size_t GetDataSize() const { return m_dataSize
; }
1439 int GetImageType() const { return m_imageType
; }
1441 void SetData(unsigned char* image
) { m_data
= image
; }
1442 void SetDataSize(size_t size
) { m_dataSize
= size
; }
1443 void SetImageType(int imageType
) { m_imageType
= imageType
; }
1445 bool Ok() const { return IsOk(); }
1446 bool IsOk() const { return GetData() != NULL
; }
1448 // Gets the extension for the block's type
1449 wxString
GetExtension() const;
1453 // Allocate and read from stream as a block of memory
1454 static unsigned char* ReadBlock(wxInputStream
& stream
, size_t size
);
1455 static unsigned char* ReadBlock(const wxString
& filename
, size_t size
);
1457 // Write memory block to stream
1458 static bool WriteBlock(wxOutputStream
& stream
, unsigned char* block
, size_t size
);
1460 // Write memory block to file
1461 static bool WriteBlock(const wxString
& filename
, unsigned char* block
, size_t size
);
1464 // Size in bytes of the image stored.
1465 // This is in the raw, original form such as a JPEG file.
1466 unsigned char* m_data
;
1468 int m_imageType
; // wxWin type id
1473 * wxRichTextImage class declaration
1474 * This object represents an image.
1477 class WXDLLIMPEXP_RICHTEXT wxRichTextImage
: public wxRichTextObject
1479 DECLARE_DYNAMIC_CLASS(wxRichTextImage
)
1483 wxRichTextImage(wxRichTextObject
* parent
= NULL
): wxRichTextObject(parent
) { }
1484 wxRichTextImage(const wxImage
& image
, wxRichTextObject
* parent
= NULL
);
1485 wxRichTextImage(const wxRichTextImageBlock
& imageBlock
, wxRichTextObject
* parent
= NULL
);
1486 wxRichTextImage(const wxRichTextImage
& obj
): wxRichTextObject() { Copy(obj
); }
1491 virtual bool Draw(wxDC
& dc
, const wxRichTextRange
& range
, const wxRichTextRange
& selectionRange
, const wxRect
& rect
, int descent
, int style
);
1493 /// Lay the item out
1494 virtual bool Layout(wxDC
& dc
, const wxRect
& rect
, int style
);
1496 /// Get the object size for the given range. Returns false if the range
1497 /// is invalid for this object.
1498 virtual bool GetRangeSize(const wxRichTextRange
& range
, wxSize
& size
, int& descent
, wxDC
& dc
, int flags
, wxPoint position
= wxPoint(0,0)) const;
1500 /// Returns true if the object is empty
1501 virtual bool IsEmpty() const { return !m_image
.Ok(); }
1506 const wxImage
& GetImage() const { return m_image
; }
1509 void SetImage(const wxImage
& image
) { m_image
= image
; }
1511 /// Get the image block containing the raw data
1512 wxRichTextImageBlock
& GetImageBlock() { return m_imageBlock
; }
1517 void Copy(const wxRichTextImage
& obj
);
1520 virtual wxRichTextObject
* Clone() const { return new wxRichTextImage(*this); }
1522 /// Load wxImage from the block
1523 virtual bool LoadFromBlock();
1525 /// Make block from the wxImage
1526 virtual bool MakeBlock();
1529 // TODO: reduce the multiple representations of data
1532 wxRichTextImageBlock m_imageBlock
;
1537 * wxRichTextBuffer class declaration
1538 * This is a kind of box, used to represent the whole buffer
1541 class WXDLLIMPEXP_RICHTEXT wxRichTextCommand
;
1542 class WXDLLIMPEXP_RICHTEXT wxRichTextAction
;
1544 class WXDLLIMPEXP_RICHTEXT wxRichTextBuffer
: public wxRichTextParagraphLayoutBox
1546 DECLARE_DYNAMIC_CLASS(wxRichTextBuffer
)
1550 wxRichTextBuffer() { Init(); }
1551 wxRichTextBuffer(const wxRichTextBuffer
& obj
): wxRichTextParagraphLayoutBox() { Init(); Copy(obj
); }
1552 virtual ~wxRichTextBuffer() ;
1556 /// Gets the command processor
1557 wxCommandProcessor
* GetCommandProcessor() const { return m_commandProcessor
; }
1559 /// Set style sheet, if any.
1560 void SetStyleSheet(wxRichTextStyleSheet
* styleSheet
) { m_styleSheet
= styleSheet
; }
1561 virtual wxRichTextStyleSheet
* GetStyleSheet() const { return m_styleSheet
; }
1563 /// Set style sheet and notify of the change
1564 bool SetStyleSheetAndNotify(wxRichTextStyleSheet
* sheet
);
1566 /// Push style sheet to top of stack
1567 bool PushStyleSheet(wxRichTextStyleSheet
* styleSheet
);
1569 /// Pop style sheet from top of stack
1570 wxRichTextStyleSheet
* PopStyleSheet();
1577 /// Clears the buffer and resets the command processor
1578 virtual void Clear();
1580 /// The same as Clear, and adds an empty paragraph.
1581 virtual void Reset();
1584 virtual bool LoadFile(const wxString
& filename
, int type
= wxRICHTEXT_TYPE_ANY
);
1587 virtual bool SaveFile(const wxString
& filename
, int type
= wxRICHTEXT_TYPE_ANY
);
1589 /// Load from a stream
1590 virtual bool LoadFile(wxInputStream
& stream
, int type
= wxRICHTEXT_TYPE_ANY
);
1592 /// Save to a stream
1593 virtual bool SaveFile(wxOutputStream
& stream
, int type
= wxRICHTEXT_TYPE_ANY
);
1595 /// Set the handler flags, controlling loading and saving
1596 void SetHandlerFlags(int flags
) { m_handlerFlags
= flags
; }
1598 /// Get the handler flags, controlling loading and saving
1599 int GetHandlerFlags() const { return m_handlerFlags
; }
1601 /// Convenience function to add a paragraph of text
1602 virtual wxRichTextRange
AddParagraph(const wxString
& text
, wxTextAttrEx
* paraStyle
= NULL
) { Modify(); return wxRichTextParagraphLayoutBox::AddParagraph(text
, paraStyle
); }
1604 /// Begin collapsing undo/redo commands. Note that this may not work properly
1605 /// if combining commands that delete or insert content, changing ranges for
1606 /// subsequent actions.
1607 virtual bool BeginBatchUndo(const wxString
& cmdName
);
1609 /// End collapsing undo/redo commands
1610 virtual bool EndBatchUndo();
1612 /// Collapsing commands?
1613 virtual bool BatchingUndo() const { return m_batchedCommandDepth
> 0; }
1615 /// Submit immediately, or delay according to whether collapsing is on
1616 virtual bool SubmitAction(wxRichTextAction
* action
);
1618 /// Get collapsed command
1619 virtual wxRichTextCommand
* GetBatchedCommand() const { return m_batchedCommand
; }
1621 /// Begin suppressing undo/redo commands. The way undo is suppressed may be implemented
1622 /// differently by each command. If not dealt with by a command implementation, then
1623 /// it will be implemented automatically by not storing the command in the undo history
1624 /// when the action is submitted to the command processor.
1625 virtual bool BeginSuppressUndo();
1627 /// End suppressing undo/redo commands.
1628 virtual bool EndSuppressUndo();
1630 /// Collapsing commands?
1631 virtual bool SuppressingUndo() const { return m_suppressUndo
> 0; }
1633 /// Copy the range to the clipboard
1634 virtual bool CopyToClipboard(const wxRichTextRange
& range
);
1636 /// Paste the clipboard content to the buffer
1637 virtual bool PasteFromClipboard(long position
);
1639 /// Can we paste from the clipboard?
1640 virtual bool CanPasteFromClipboard() const;
1642 /// Begin using a style
1643 virtual bool BeginStyle(const wxTextAttrEx
& style
);
1646 virtual bool EndStyle();
1649 virtual bool EndAllStyles();
1651 /// Clear the style stack
1652 virtual void ClearStyleStack();
1654 /// Get the size of the style stack, for example to check correct nesting
1655 virtual size_t GetStyleStackSize() const { return m_attributeStack
.GetCount(); }
1657 /// Begin using bold
1661 bool EndBold() { return EndStyle(); }
1663 /// Begin using italic
1666 /// End using italic
1667 bool EndItalic() { return EndStyle(); }
1669 /// Begin using underline
1670 bool BeginUnderline();
1672 /// End using underline
1673 bool EndUnderline() { return EndStyle(); }
1675 /// Begin using point size
1676 bool BeginFontSize(int pointSize
);
1678 /// End using point size
1679 bool EndFontSize() { return EndStyle(); }
1681 /// Begin using this font
1682 bool BeginFont(const wxFont
& font
);
1684 /// End using a font
1685 bool EndFont() { return EndStyle(); }
1687 /// Begin using this colour
1688 bool BeginTextColour(const wxColour
& colour
);
1690 /// End using a colour
1691 bool EndTextColour() { return EndStyle(); }
1693 /// Begin using alignment
1694 bool BeginAlignment(wxTextAttrAlignment alignment
);
1697 bool EndAlignment() { return EndStyle(); }
1699 /// Begin left indent
1700 bool BeginLeftIndent(int leftIndent
, int leftSubIndent
= 0);
1703 bool EndLeftIndent() { return EndStyle(); }
1705 /// Begin right indent
1706 bool BeginRightIndent(int rightIndent
);
1708 /// End right indent
1709 bool EndRightIndent() { return EndStyle(); }
1711 /// Begin paragraph spacing
1712 bool BeginParagraphSpacing(int before
, int after
);
1714 /// End paragraph spacing
1715 bool EndParagraphSpacing() { return EndStyle(); }
1717 /// Begin line spacing
1718 bool BeginLineSpacing(int lineSpacing
);
1720 /// End line spacing
1721 bool EndLineSpacing() { return EndStyle(); }
1723 /// Begin numbered bullet
1724 bool BeginNumberedBullet(int bulletNumber
, int leftIndent
, int leftSubIndent
, int bulletStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
);
1726 /// End numbered bullet
1727 bool EndNumberedBullet() { return EndStyle(); }
1729 /// Begin symbol bullet
1730 bool BeginSymbolBullet(const wxString
& symbol
, int leftIndent
, int leftSubIndent
, int bulletStyle
= wxTEXT_ATTR_BULLET_STYLE_SYMBOL
);
1732 /// End symbol bullet
1733 bool EndSymbolBullet() { return EndStyle(); }
1735 /// Begin standard bullet
1736 bool BeginStandardBullet(const wxString
& bulletName
, int leftIndent
, int leftSubIndent
, int bulletStyle
= wxTEXT_ATTR_BULLET_STYLE_STANDARD
);
1738 /// End standard bullet
1739 bool EndStandardBullet() { return EndStyle(); }
1741 /// Begin named character style
1742 bool BeginCharacterStyle(const wxString
& characterStyle
);
1744 /// End named character style
1745 bool EndCharacterStyle() { return EndStyle(); }
1747 /// Begin named paragraph style
1748 bool BeginParagraphStyle(const wxString
& paragraphStyle
);
1750 /// End named character style
1751 bool EndParagraphStyle() { return EndStyle(); }
1753 /// Begin named list style
1754 bool BeginListStyle(const wxString
& listStyle
, int level
= 1, int number
= 1);
1756 /// End named character style
1757 bool EndListStyle() { return EndStyle(); }
1760 bool BeginURL(const wxString
& url
, const wxString
& characterStyle
= wxEmptyString
);
1763 bool EndURL() { return EndStyle(); }
1767 /// Add an event handler
1768 bool AddEventHandler(wxEvtHandler
* handler
);
1770 /// Remove an event handler
1771 bool RemoveEventHandler(wxEvtHandler
* handler
, bool deleteHandler
= false);
1773 /// Clear event handlers
1774 void ClearEventHandlers();
1776 /// Send event to event handlers. If sendToAll is true, will send to all event handlers,
1777 /// otherwise will stop at the first successful one.
1778 bool SendEvent(wxEvent
& event
, bool sendToAll
= true);
1783 void Copy(const wxRichTextBuffer
& obj
);
1786 virtual wxRichTextObject
* Clone() const { return new wxRichTextBuffer(*this); }
1788 /// Submit command to insert paragraphs
1789 bool InsertParagraphsWithUndo(long pos
, const wxRichTextParagraphLayoutBox
& paragraphs
, wxRichTextCtrl
* ctrl
, int flags
= 0);
1791 /// Submit command to insert the given text
1792 bool InsertTextWithUndo(long pos
, const wxString
& text
, wxRichTextCtrl
* ctrl
, int flags
= 0);
1794 /// Submit command to insert a newline
1795 bool InsertNewlineWithUndo(long pos
, wxRichTextCtrl
* ctrl
, int flags
= 0);
1797 /// Submit command to insert the given image
1798 bool InsertImageWithUndo(long pos
, const wxRichTextImageBlock
& imageBlock
, wxRichTextCtrl
* ctrl
, int flags
= 0);
1800 /// Submit command to delete this range
1801 bool DeleteRangeWithUndo(const wxRichTextRange
& range
, long initialCaretPosition
, long newCaretPositon
, wxRichTextCtrl
* ctrl
);
1804 void Modify(bool modify
= true) { m_modified
= modify
; }
1805 bool IsModified() const { return m_modified
; }
1807 /// Get the style that is appropriate for a new paragraph at this position.
1808 /// If the previous paragraph has a paragraph style name, look up the next-paragraph
1810 wxRichTextAttr
GetStyleForNewParagraph(long pos
, bool caretPosition
= false) const;
1812 /// Dumps contents of buffer for debugging purposes
1813 virtual void Dump();
1814 virtual void Dump(wxTextOutputStream
& stream
) { wxRichTextParagraphLayoutBox::Dump(stream
); }
1816 /// Returns the file handlers
1817 static wxList
& GetHandlers() { return sm_handlers
; }
1819 /// Adds a handler to the end
1820 static void AddHandler(wxRichTextFileHandler
*handler
);
1822 /// Inserts a handler at the front
1823 static void InsertHandler(wxRichTextFileHandler
*handler
);
1825 /// Removes a handler
1826 static bool RemoveHandler(const wxString
& name
);
1828 /// Finds a handler by name
1829 static wxRichTextFileHandler
*FindHandler(const wxString
& name
);
1831 /// Finds a handler by extension and type
1832 static wxRichTextFileHandler
*FindHandler(const wxString
& extension
, int imageType
);
1834 /// Finds a handler by filename or, if supplied, type
1835 static wxRichTextFileHandler
*FindHandlerFilenameOrType(const wxString
& filename
, int imageType
);
1837 /// Finds a handler by type
1838 static wxRichTextFileHandler
*FindHandler(int imageType
);
1840 /// Gets a wildcard incorporating all visible handlers. If 'types' is present,
1841 /// will be filled with the file type corresponding to each filter. This can be
1842 /// used to determine the type to pass to LoadFile given a selected filter.
1843 static wxString
GetExtWildcard(bool combine
= false, bool save
= false, wxArrayInt
* types
= NULL
);
1845 /// Clean up handlers
1846 static void CleanUpHandlers();
1848 /// Initialise the standard handlers
1849 static void InitStandardHandlers();
1852 static wxRichTextRenderer
* GetRenderer() { return sm_renderer
; }
1854 /// Set renderer, deleting old one
1855 static void SetRenderer(wxRichTextRenderer
* renderer
);
1857 /// Minimum margin between bullet and paragraph in 10ths of a mm
1858 static int GetBulletRightMargin() { return sm_bulletRightMargin
; }
1859 static void SetBulletRightMargin(int margin
) { sm_bulletRightMargin
= margin
; }
1861 /// Factor to multiply by character height to get a reasonable bullet size
1862 static float GetBulletProportion() { return sm_bulletProportion
; }
1863 static void SetBulletProportion(float prop
) { sm_bulletProportion
= prop
; }
1866 /// Command processor
1867 wxCommandProcessor
* m_commandProcessor
;
1869 /// Has been modified?
1872 /// Collapsed command stack
1873 int m_batchedCommandDepth
;
1875 /// Name for collapsed command
1876 wxString m_batchedCommandsName
;
1878 /// Current collapsed command accumulating actions
1879 wxRichTextCommand
* m_batchedCommand
;
1881 /// Whether to suppress undo
1884 /// Style sheet, if any
1885 wxRichTextStyleSheet
* m_styleSheet
;
1887 /// List of event handlers that will be notified of events
1888 wxList m_eventHandlers
;
1890 /// Stack of attributes for convenience functions
1891 wxList m_attributeStack
;
1893 /// Flags to be passed to handlers
1897 static wxList sm_handlers
;
1900 static wxRichTextRenderer
* sm_renderer
;
1902 /// Minimum margin between bullet and paragraph in 10ths of a mm
1903 static int sm_bulletRightMargin
;
1905 /// Factor to multiply by character height to get a reasonable bullet size
1906 static float sm_bulletProportion
;
1910 * The command identifiers
1914 enum wxRichTextCommandId
1918 wxRICHTEXT_CHANGE_STYLE
1922 * Command classes for undo/redo
1926 class WXDLLIMPEXP_RICHTEXT wxRichTextAction
;
1927 class WXDLLIMPEXP_RICHTEXT wxRichTextCommand
: public wxCommand
1930 // Ctor for one action
1931 wxRichTextCommand(const wxString
& name
, wxRichTextCommandId id
, wxRichTextBuffer
* buffer
,
1932 wxRichTextCtrl
* ctrl
, bool ignoreFirstTime
= false);
1934 // Ctor for multiple actions
1935 wxRichTextCommand(const wxString
& name
);
1937 virtual ~wxRichTextCommand();
1942 void AddAction(wxRichTextAction
* action
);
1943 void ClearActions();
1945 wxList
& GetActions() { return m_actions
; }
1953 * wxRichTextAction class declaration
1954 * There can be more than one action in a command.
1957 class WXDLLIMPEXP_RICHTEXT wxRichTextAction
: public wxObject
1960 wxRichTextAction(wxRichTextCommand
* cmd
, const wxString
& name
, wxRichTextCommandId id
, wxRichTextBuffer
* buffer
,
1961 wxRichTextCtrl
* ctrl
, bool ignoreFirstTime
= false);
1963 virtual ~wxRichTextAction();
1968 /// Update the control appearance
1969 void UpdateAppearance(long caretPosition
, bool sendUpdateEvent
= false);
1971 /// Replace the buffer paragraphs with the given fragment.
1972 void ApplyParagraphs(const wxRichTextParagraphLayoutBox
& fragment
);
1974 /// Get the fragments
1975 wxRichTextParagraphLayoutBox
& GetNewParagraphs() { return m_newParagraphs
; }
1976 wxRichTextParagraphLayoutBox
& GetOldParagraphs() { return m_oldParagraphs
; }
1978 /// Set/get the position used for e.g. insertion
1979 void SetPosition(long pos
) { m_position
= pos
; }
1980 long GetPosition() const { return m_position
; }
1982 /// Set/get the range for e.g. deletion
1983 void SetRange(const wxRichTextRange
& range
) { m_range
= range
; }
1984 const wxRichTextRange
& GetRange() const { return m_range
; }
1987 const wxString
& GetName() const { return m_name
; }
1994 wxRichTextBuffer
* m_buffer
;
1997 wxRichTextCtrl
* m_ctrl
;
1999 // Stores the new paragraphs
2000 wxRichTextParagraphLayoutBox m_newParagraphs
;
2002 // Stores the old paragraphs
2003 wxRichTextParagraphLayoutBox m_oldParagraphs
;
2005 // The affected range
2006 wxRichTextRange m_range
;
2008 // The insertion point for this command
2011 // Ignore 1st 'Do' operation because we already did it
2014 // The command identifier
2015 wxRichTextCommandId m_cmdId
;
2022 // Include style sheet when loading and saving
2023 #define wxRICHTEXT_HANDLER_INCLUDE_STYLESHEET 0x0001
2025 // Save images to memory file system in HTML handler
2026 #define wxRICHTEXT_HANDLER_SAVE_IMAGES_TO_MEMORY 0x0010
2028 // Save images to files in HTML handler
2029 #define wxRICHTEXT_HANDLER_SAVE_IMAGES_TO_FILES 0x0020
2031 // Save images as inline base64 data in HTML handler
2032 #define wxRICHTEXT_HANDLER_SAVE_IMAGES_TO_BASE64 0x0040
2035 * wxRichTextFileHandler
2036 * Base class for file handlers
2039 class WXDLLIMPEXP_RICHTEXT wxRichTextFileHandler
: public wxObject
2041 DECLARE_CLASS(wxRichTextFileHandler
)
2043 wxRichTextFileHandler(const wxString
& name
= wxEmptyString
, const wxString
& ext
= wxEmptyString
, int type
= 0)
2044 : m_name(name
), m_extension(ext
), m_type(type
), m_flags(0), m_visible(true)
2048 bool LoadFile(wxRichTextBuffer
*buffer
, wxInputStream
& stream
)
2049 { return DoLoadFile(buffer
, stream
); }
2050 bool SaveFile(wxRichTextBuffer
*buffer
, wxOutputStream
& stream
)
2051 { return DoSaveFile(buffer
, stream
); }
2054 bool LoadFile(wxRichTextBuffer
*buffer
, const wxString
& filename
);
2055 bool SaveFile(wxRichTextBuffer
*buffer
, const wxString
& filename
);
2057 /// Can we handle this filename (if using files)? By default, checks the extension.
2058 virtual bool CanHandle(const wxString
& filename
) const;
2060 /// Can we save using this handler?
2061 virtual bool CanSave() const { return false; }
2063 /// Can we load using this handler?
2064 virtual bool CanLoad() const { return false; }
2066 /// Should this handler be visible to the user?
2067 virtual bool IsVisible() const { return m_visible
; }
2068 virtual void SetVisible(bool visible
) { m_visible
= visible
; }
2070 /// The name of the nandler
2071 void SetName(const wxString
& name
) { m_name
= name
; }
2072 wxString
GetName() const { return m_name
; }
2074 /// The default extension to recognise
2075 void SetExtension(const wxString
& ext
) { m_extension
= ext
; }
2076 wxString
GetExtension() const { return m_extension
; }
2078 /// The handler type
2079 void SetType(int type
) { m_type
= type
; }
2080 int GetType() const { return m_type
; }
2082 /// Flags controlling how loading and saving is done
2083 void SetFlags(int flags
) { m_flags
= flags
; }
2084 int GetFlags() const { return m_flags
; }
2086 /// Encoding to use when saving a file. If empty, a suitable encoding is chosen
2087 void SetEncoding(const wxString
& encoding
) { m_encoding
= encoding
; }
2088 const wxString
& GetEncoding() const { return m_encoding
; }
2093 virtual bool DoLoadFile(wxRichTextBuffer
*buffer
, wxInputStream
& stream
) = 0;
2094 virtual bool DoSaveFile(wxRichTextBuffer
*buffer
, wxOutputStream
& stream
) = 0;
2098 wxString m_encoding
;
2099 wxString m_extension
;
2106 * wxRichTextPlainTextHandler
2107 * Plain text handler
2110 class WXDLLIMPEXP_RICHTEXT wxRichTextPlainTextHandler
: public wxRichTextFileHandler
2112 DECLARE_CLASS(wxRichTextPlainTextHandler
)
2114 wxRichTextPlainTextHandler(const wxString
& name
= wxT("Text"), const wxString
& ext
= wxT("txt"), int type
= wxRICHTEXT_TYPE_TEXT
)
2115 : wxRichTextFileHandler(name
, ext
, type
)
2118 /// Can we save using this handler?
2119 virtual bool CanSave() const { return true; }
2121 /// Can we load using this handler?
2122 virtual bool CanLoad() const { return true; }
2127 virtual bool DoLoadFile(wxRichTextBuffer
*buffer
, wxInputStream
& stream
);
2128 virtual bool DoSaveFile(wxRichTextBuffer
*buffer
, wxOutputStream
& stream
);
2136 * The data object for a wxRichTextBuffer
2139 class WXDLLIMPEXP_RICHTEXT wxRichTextBufferDataObject
: public wxDataObjectSimple
2142 // ctor doesn't copy the pointer, so it shouldn't go away while this object
2144 wxRichTextBufferDataObject(wxRichTextBuffer
* richTextBuffer
= (wxRichTextBuffer
*) NULL
);
2145 virtual ~wxRichTextBufferDataObject();
2147 // after a call to this function, the buffer is owned by the caller and it
2148 // is responsible for deleting it
2149 wxRichTextBuffer
* GetRichTextBuffer();
2151 // Returns the id for the new data format
2152 static const wxChar
* GetRichTextBufferFormatId() { return ms_richTextBufferFormatId
; }
2154 // base class pure virtuals
2156 virtual wxDataFormat
GetPreferredFormat(Direction dir
) const;
2157 virtual size_t GetDataSize() const;
2158 virtual bool GetDataHere(void *pBuf
) const;
2159 virtual bool SetData(size_t len
, const void *buf
);
2163 virtual size_t GetDataSize(const wxDataFormat
&) const { return GetDataSize(); }
2164 virtual bool GetDataHere(const wxDataFormat
&, void *buf
) const { return GetDataHere(buf
); }
2165 virtual bool SetData(const wxDataFormat
&, size_t len
, const void *buf
) { return SetData(len
, buf
); }
2168 wxDataFormat m_formatRichTextBuffer
; // our custom format
2169 wxRichTextBuffer
* m_richTextBuffer
; // our data
2170 static const wxChar
* ms_richTextBufferFormatId
; // our format id
2176 * wxRichTextRenderer isolates common drawing functionality
2179 class WXDLLIMPEXP_RICHTEXT wxRichTextRenderer
: public wxObject
2182 wxRichTextRenderer() {}
2183 virtual ~wxRichTextRenderer() {}
2185 /// Draw a standard bullet, as specified by the value of GetBulletName
2186 virtual bool DrawStandardBullet(wxRichTextParagraph
* paragraph
, wxDC
& dc
, const wxTextAttrEx
& attr
, const wxRect
& rect
) = 0;
2188 /// Draw a bullet that can be described by text, such as numbered or symbol bullets
2189 virtual bool DrawTextBullet(wxRichTextParagraph
* paragraph
, wxDC
& dc
, const wxTextAttrEx
& attr
, const wxRect
& rect
, const wxString
& text
) = 0;
2191 /// Draw a bitmap bullet, where the bullet bitmap is specified by the value of GetBulletName
2192 virtual bool DrawBitmapBullet(wxRichTextParagraph
* paragraph
, wxDC
& dc
, const wxTextAttrEx
& attr
, const wxRect
& rect
) = 0;
2194 /// Enumerate the standard bullet names currently supported
2195 virtual bool EnumerateStandardBulletNames(wxArrayString
& bulletNames
) = 0;
2199 * wxRichTextStdRenderer: standard renderer
2202 class WXDLLIMPEXP_RICHTEXT wxRichTextStdRenderer
: public wxRichTextRenderer
2205 wxRichTextStdRenderer() {}
2207 /// Draw a standard bullet, as specified by the value of GetBulletName
2208 virtual bool DrawStandardBullet(wxRichTextParagraph
* paragraph
, wxDC
& dc
, const wxTextAttrEx
& attr
, const wxRect
& rect
);
2210 /// Draw a bullet that can be described by text, such as numbered or symbol bullets
2211 virtual bool DrawTextBullet(wxRichTextParagraph
* paragraph
, wxDC
& dc
, const wxTextAttrEx
& attr
, const wxRect
& rect
, const wxString
& text
);
2213 /// Draw a bitmap bullet, where the bullet bitmap is specified by the value of GetBulletName
2214 virtual bool DrawBitmapBullet(wxRichTextParagraph
* paragraph
, wxDC
& dc
, const wxTextAttrEx
& attr
, const wxRect
& rect
);
2216 /// Enumerate the standard bullet names currently supported
2217 virtual bool EnumerateStandardBulletNames(wxArrayString
& bulletNames
);
2225 inline bool wxRichTextHasStyle(int flags
, int style
)
2227 return ((flags
& style
) == style
);
2230 /// Compare two attribute objects
2231 WXDLLIMPEXP_RICHTEXT
bool wxTextAttrEq(const wxTextAttrEx
& attr1
, const wxTextAttrEx
& attr2
);
2232 WXDLLIMPEXP_RICHTEXT
bool wxTextAttrEq(const wxTextAttr
& attr1
, const wxRichTextAttr
& attr2
);
2234 /// Compare two attribute objects, but take into account the flags
2235 /// specifying attributes of interest.
2236 WXDLLIMPEXP_RICHTEXT
bool wxTextAttrEqPartial(const wxTextAttrEx
& attr1
, const wxTextAttrEx
& attr2
, int flags
);
2237 WXDLLIMPEXP_RICHTEXT
bool wxTextAttrEqPartial(const wxTextAttrEx
& attr1
, const wxRichTextAttr
& attr2
, int flags
);
2239 /// Apply one style to another
2240 WXDLLIMPEXP_RICHTEXT
bool wxRichTextApplyStyle(wxTextAttrEx
& destStyle
, const wxTextAttrEx
& style
);
2241 WXDLLIMPEXP_RICHTEXT
bool wxRichTextApplyStyle(wxRichTextAttr
& destStyle
, const wxTextAttrEx
& style
);
2242 WXDLLIMPEXP_RICHTEXT
bool wxRichTextApplyStyle(wxTextAttrEx
& destStyle
, const wxRichTextAttr
& style
, wxRichTextAttr
* compareWith
= NULL
);
2245 WXDLLIMPEXP_RICHTEXT
bool wxRichTextTabsEq(const wxArrayInt
& tabs1
, const wxArrayInt
& tabs2
);
2247 /// Set the font without changing the font attributes
2248 WXDLLIMPEXP_RICHTEXT
void wxSetFontPreservingStyles(wxTextAttr
& attr
, const wxFont
& font
);
2250 /// Convert a decimal to Roman numerals
2251 WXDLLIMPEXP_RICHTEXT wxString
wxRichTextDecimalToRoman(long n
);
2253 WXDLLIMPEXP_RICHTEXT
void wxRichTextModuleInit();
2259 // _WX_RICHTEXTBUFFER_H_