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 /////////////////////////////////////////////////////////////////////////////
17 Data is represented by a hierarchy of objects, all derived from
20 The top of the hierarchy is the buffer, a kind of wxRichTextParagraphLayoutBox.
21 These boxes will allow flexible placement of text boxes on a page, but
22 for now there will be a single box representing the document,
23 and this box will a wxRichTextParagraphLayoutBox which contains further
24 wxRichTextParagraph objects, each of which can include text and images.
26 Each object maintains a range (start and end position) measured
27 from the start of the main parent box.
28 A paragraph object knows its range, and a text fragment knows its range
29 too. So, a character or image in a page has a position relative to the
30 start of the document, and a character in an embedded text box has
31 a position relative to that text box. For now, we will not be dealing with
32 embedded objects but it's something to bear in mind for later.
37 When Layout is called on an object, it is given a size which the object
38 must limit itself to, or one or more flexible directions (vertical
39 or horizontal). So for example a centered paragraph is given the page
40 width to play with (minus any margins), but can extend indefinitely
41 in the vertical direction. The implementation of Layout can then
42 cache the calculated size and position within the parent.
44 Note that position and size should be calculated separately, because
45 for example inserting a paragraph may result in the following paragraphs
46 moving down, but not changing in size.
48 Need to determine how objects specify their position. Absolute coordinates,
49 or relative to last object? May be hard to determine that. So should probably
50 be in absolute coordinates, in which case we'll need a Move virtual function
51 that allows quick movement of all elements without layout.
53 Let's work through a simple example of layout. Say we're laying out
54 a document with the buffer as the top box, with a wxRichTextParagraphLayoutBox
55 inside that that consists of wxRichTextParagraph objects.
57 We're in a mode whereby changes of window size change the width of the
58 page (useful for text editors, as opposed to word processors). The
61 We pass (600, -1) to the top-level Layout (i.e. restrict size in horizontal
62 direction only). The wxRichTextBuffer box doesn't currently have
63 well-defined layout behaviour so we simply assume it has one child
64 that fills its parent (later we can define sizer-like box layout behaviour).
65 So it passes the same dimensions to the child, which is a wxRichTextParagraphLayoutBox.
66 This then looks at each child in turn (wxRichTextParagraph) and determines
67 the size the paragraph will take up, setting the cached size, and
68 splitting the paragraph into lines.
70 When the layout for one paragraph returns, the next paragraph is
71 fed the position of the previous, so it can position itself.
73 Each time Layout is called, the cached list of lines for each paragraph
74 is recreated, since it can change for example if the parent object width
80 Each object can report its size for a given range. It's important that
81 it can report a partial size, so that wrapping can be implemented,
82 hit test calculations performed, etc. So GetRangeSize must be implemented
87 #ifndef _WX_RICHTEXTBUFFER_H_
88 #define _WX_RICHTEXTBUFFER_H_
99 #include "wx/cmdproc.h"
100 #include "wx/txtstrm.h"
106 #define wxRICHTEXT_TYPE_ANY 0
107 #define wxRICHTEXT_TYPE_TEXT 1
108 #define wxRICHTEXT_TYPE_XML 2
109 #define wxRICHTEXT_TYPE_HTML 3
110 #define wxRICHTEXT_TYPE_RTF 4
111 #define wxRICHTEXT_TYPE_PDF 5
114 * Forward declarations
117 class WXDLLIMPEXP_ADV wxRichTextCtrl
;
118 class WXDLLIMPEXP_ADV wxRichTextObject
;
119 class WXDLLIMPEXP_ADV wxRichTextCacheObject
;
120 class WXDLLIMPEXP_ADV wxRichTextObjectList
;
121 class WXDLLIMPEXP_ADV wxRichTextLine
;
122 class WXDLLIMPEXP_ADV wxRichTextParagraph
;
123 class WXDLLIMPEXP_ADV wxRichTextFragment
;
124 class WXDLLIMPEXP_ADV wxRichTextFileHandler
;
125 class WXDLLIMPEXP_ADV wxRichTextStyleSheet
;
126 class WXDLLIMPEXP_ADV wxTextAttrEx
;
129 * Flags determining the available space, passed to Layout
132 #define wxRICHTEXT_FIXED_WIDTH 0x01
133 #define wxRICHTEXT_FIXED_HEIGHT 0x02
134 #define wxRICHTEXT_VARIABLE_WIDTH 0x04
135 #define wxRICHTEXT_VARIABLE_HEIGHT 0x08
138 * Flags returned from hit-testing
141 // The point was not on this object
142 #define wxRICHTEXT_HITTEST_NONE 0x01
143 // The point was before the position returned from HitTest
144 #define wxRICHTEXT_HITTEST_BEFORE 0x02
145 // The point was after the position returned from HitTest
146 #define wxRICHTEXT_HITTEST_AFTER 0x04
147 // The point was on the position returned from HitTest
148 #define wxRICHTEXT_HITTEST_ON 0x08
151 * Flags for GetRangeSize
154 #define wxRICHTEXT_FORMATTED 0x01
155 #define wxRICHTEXT_UNFORMATTED 0x02
158 * Extra formatting flags not in wxTextAttr
161 #define wxTEXT_ATTR_PARA_SPACING_AFTER 0x00000800
162 #define wxTEXT_ATTR_PARA_SPACING_BEFORE 0x00001000
163 #define wxTEXT_ATTR_LINE_SPACING 0x00002000
164 #define wxTEXT_ATTR_CHARACTER_STYLE_NAME 0x00004000
165 #define wxTEXT_ATTR_PARAGRAPH_STYLE_NAME 0x00008000
166 #define wxTEXT_ATTR_BULLET_STYLE 0x00010000
167 #define wxTEXT_ATTR_BULLET_NUMBER 0x00020000
168 #define wxTEXT_ATTR_BULLET_SYMBOL 0x00040000
171 * Styles for wxTextAttrEx::SetBulletStyle
174 #define wxTEXT_ATTR_BULLET_STYLE_NONE 0x0000
175 #define wxTEXT_ATTR_BULLET_STYLE_ARABIC 0x0001
176 #define wxTEXT_ATTR_BULLET_STYLE_LETTERS_UPPER 0x0002
177 #define wxTEXT_ATTR_BULLET_STYLE_LETTERS_LOWER 0x0004
178 #define wxTEXT_ATTR_BULLET_STYLE_ROMAN_UPPER 0x0008
179 #define wxTEXT_ATTR_BULLET_STYLE_ROMAN_LOWER 0x0010
180 #define wxTEXT_ATTR_BULLET_STYLE_SYMBOL 0x0020
181 #define wxTEXT_ATTR_BULLET_STYLE_BITMAP 0x0040
182 #define wxTEXT_ATTR_BULLET_STYLE_PARENTHESES 0x0080
183 #define wxTEXT_ATTR_BULLET_STYLE_PERIOD 0x0100
186 * Line spacing values
189 #define wxTEXT_ATTR_LINE_SPACING_NORMAL 10
190 #define wxTEXT_ATTR_LINE_SPACING_HALF 15
191 #define wxTEXT_ATTR_LINE_SPACING_TWICE 20
194 * wxRichTextRange class declaration
195 * This stores beginning and end positions for a range of data.
198 class WXDLLIMPEXP_ADV wxRichTextRange
203 wxRichTextRange() { m_start
= 0; m_end
= 0; }
204 wxRichTextRange(long start
, long end
) { m_start
= start
; m_end
= end
; }
205 wxRichTextRange(const wxRichTextRange
& range
) { m_start
= range
.m_start
; m_end
= range
.m_end
; }
206 ~wxRichTextRange() {}
208 void operator =(const wxRichTextRange
& range
) { m_start
= range
.m_start
; m_end
= range
.m_end
; }
209 bool operator ==(const wxRichTextRange
& range
) const { return (m_start
== range
.m_start
&& m_end
== range
.m_end
); }
210 wxRichTextRange
operator -(const wxRichTextRange
& range
) const { return wxRichTextRange(m_start
- range
.m_start
, m_end
- range
.m_end
); }
211 wxRichTextRange
operator +(const wxRichTextRange
& range
) const { return wxRichTextRange(m_start
+ range
.m_start
, m_end
+ range
.m_end
); }
213 void SetRange(long start
, long end
) { m_start
= start
; m_end
= end
; }
215 void SetStart(long start
) { m_start
= start
; }
216 long GetStart() const { return m_start
; }
218 void SetEnd(long end
) { m_end
= end
; }
219 long GetEnd() const { return m_end
; }
221 /// Returns true if this range is completely outside 'range'
222 bool IsOutside(const wxRichTextRange
& range
) const { return range
.m_start
> m_end
|| range
.m_end
< m_start
; }
224 /// Returns true if this range is completely within 'range'
225 bool IsWithin(const wxRichTextRange
& range
) const { return m_start
>= range
.m_start
&& m_end
<= range
.m_end
; }
227 /// Returns true if the given position is within this range. Allow
228 /// for the possibility of an empty range - assume the position
229 /// is within this empty range. NO, I think we should not match with an empty range.
230 // bool Contains(long pos) const { return pos >= m_start && (pos <= m_end || GetLength() == 0); }
231 bool Contains(long pos
) const { return pos
>= m_start
&& pos
<= m_end
; }
233 /// Limit this range to be within 'range'
234 bool LimitTo(const wxRichTextRange
& range
) ;
236 /// Gets the length of the range
237 long GetLength() const { return m_end
- m_start
+ 1; }
239 /// Swaps the start and end
240 void Swap() { long tmp
= m_start
; m_start
= m_end
; m_end
= tmp
; }
247 #define wxRICHTEXT_ALL wxRichTextRange(-2, -2)
248 #define wxRICHTEXT_NONE wxRichTextRange(-1, -1)
251 * wxTextAttrEx is an extended version of wxTextAttr with more paragraph attributes.
254 class WXDLLIMPEXP_ADV wxTextAttrEx
: public wxTextAttr
258 wxTextAttrEx(const wxTextAttrEx
& attr
);
259 wxTextAttrEx() { Init(); }
261 // Initialise this object.
264 // Assignment from a wxTextAttrEx object
265 void operator= (const wxTextAttrEx
& attr
);
267 // Assignment from a wxTextAttr object.
268 void operator= (const wxTextAttr
& attr
);
271 void SetCharacterStyleName(const wxString
& name
) { m_characterStyleName
= name
; }
272 void SetParagraphStyleName(const wxString
& name
) { m_paragraphStyleName
= name
; }
273 void SetParagraphSpacingAfter(int spacing
) { m_paragraphSpacingAfter
= spacing
; }
274 void SetParagraphSpacingBefore(int spacing
) { m_paragraphSpacingBefore
= spacing
; }
275 void SetLineSpacing(int spacing
) { m_lineSpacing
= spacing
; }
276 void SetBulletStyle(int style
) { m_bulletStyle
= style
; }
277 void SetBulletNumber(int n
) { m_bulletNumber
= n
; }
278 void SetBulletSymbol(wxChar symbol
) { m_bulletSymbol
= symbol
; }
280 const wxString
& GetCharacterStyleName() const { return m_characterStyleName
; }
281 const wxString
& GetParagraphStyleName() const { return m_paragraphStyleName
; }
282 int GetParagraphSpacingAfter() const { return m_paragraphSpacingAfter
; }
283 int GetParagraphSpacingBefore() const { return m_paragraphSpacingBefore
; }
284 int GetLineSpacing() const { return m_lineSpacing
; }
285 int GetBulletStyle() const { return m_bulletStyle
; }
286 int GetBulletNumber() const { return m_bulletNumber
; }
287 wxChar
GetBulletSymbol() const { return m_bulletSymbol
; }
289 bool HasParagraphSpacingAfter() const { return HasFlag(wxTEXT_ATTR_PARA_SPACING_AFTER
); }
290 bool HasParagraphSpacingBefore() const { return HasFlag(wxTEXT_ATTR_PARA_SPACING_BEFORE
); }
291 bool HasLineSpacing() const { return HasFlag(wxTEXT_ATTR_LINE_SPACING
); }
292 bool HasCharacterStyleName() const { return HasFlag(wxTEXT_ATTR_CHARACTER_STYLE_NAME
); }
293 bool HasParagraphStyleName() const { return HasFlag(wxTEXT_ATTR_PARAGRAPH_STYLE_NAME
); }
294 bool HasBulletStyle() const { return HasFlag(wxTEXT_ATTR_BULLET_STYLE
); }
295 bool HasBulletNumber() const { return HasFlag(wxTEXT_ATTR_BULLET_NUMBER
); }
296 bool HasBulletSymbol() const { return HasFlag(wxTEXT_ATTR_BULLET_SYMBOL
); }
298 // Is this a character style?
299 bool IsCharacterStyle() const { return (0 != (GetFlags() & (wxTEXT_ATTR_FONT
| wxTEXT_ATTR_BACKGROUND_COLOUR
| wxTEXT_ATTR_TEXT_COLOUR
))); }
300 bool IsParagraphStyle() const { return (0 != (GetFlags() & (wxTEXT_ATTR_ALIGNMENT
|wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
|wxTEXT_ATTR_TABS
|
301 wxTEXT_ATTR_PARA_SPACING_BEFORE
|wxTEXT_ATTR_PARA_SPACING_AFTER
|wxTEXT_ATTR_LINE_SPACING
|
302 wxTEXT_ATTR_BULLET_STYLE
|wxTEXT_ATTR_BULLET_NUMBER
))); }
304 // returns false if we have any attributes set, true otherwise
305 bool IsDefault() const
307 return !HasTextColour() && !HasBackgroundColour() && !HasFont() && !HasAlignment() &&
308 !HasTabs() && !HasLeftIndent() && !HasRightIndent() &&
309 !HasParagraphSpacingAfter() && !HasParagraphSpacingBefore() && !HasLineSpacing() &&
310 !HasCharacterStyleName() && !HasParagraphStyleName() && !HasBulletNumber() && !HasBulletStyle() && !HasBulletSymbol();
314 int m_paragraphSpacingAfter
;
315 int m_paragraphSpacingBefore
;
319 wxChar m_bulletSymbol
;
322 wxString m_characterStyleName
;
325 wxString m_paragraphStyleName
;
329 * wxRichTextAttr stores attributes without a wxFont object, so is a much more
330 * efficient way to query styles.
333 class WXDLLIMPEXP_ADV wxRichTextAttr
337 wxRichTextAttr(const wxTextAttrEx
& attr
);
338 wxRichTextAttr() { Init(); }
339 wxRichTextAttr(const wxColour
& colText
,
340 const wxColour
& colBack
= wxNullColour
,
341 wxTextAttrAlignment alignment
= wxTEXT_ALIGNMENT_DEFAULT
);
343 // Initialise this object.
346 // Assignment from a wxRichTextAttr object.
347 void operator= (const wxRichTextAttr
& attr
);
349 // Assignment from a wxTextAttrEx object.
350 void operator= (const wxTextAttrEx
& attr
);
352 // Making a wxTextAttrEx object.
353 operator wxTextAttrEx () const ;
355 // Copy to a wxTextAttr
356 void CopyTo(wxTextAttrEx
& attr
) const;
358 // Create font from font attributes.
359 wxFont
CreateFont() const;
361 // Get attributes from font.
362 bool GetFontAttributes(const wxFont
& font
);
365 void SetTextColour(const wxColour
& colText
) { m_colText
= colText
; m_flags
|= wxTEXT_ATTR_TEXT_COLOUR
; }
366 void SetBackgroundColour(const wxColour
& colBack
) { m_colBack
= colBack
; m_flags
|= wxTEXT_ATTR_BACKGROUND_COLOUR
; }
367 void SetAlignment(wxTextAttrAlignment alignment
) { m_textAlignment
= alignment
; m_flags
|= wxTEXT_ATTR_ALIGNMENT
; }
368 void SetTabs(const wxArrayInt
& tabs
) { m_tabs
= tabs
; m_flags
|= wxTEXT_ATTR_TABS
; }
369 void SetLeftIndent(int indent
, int subIndent
= 0) { m_leftIndent
= indent
; m_leftSubIndent
= subIndent
; m_flags
|= wxTEXT_ATTR_LEFT_INDENT
; }
370 void SetRightIndent(int indent
) { m_rightIndent
= indent
; m_flags
|= wxTEXT_ATTR_RIGHT_INDENT
; }
372 void SetFontSize(int pointSize
) { m_fontSize
= pointSize
; m_flags
|= wxTEXT_ATTR_FONT_SIZE
; }
373 void SetFontStyle(int fontStyle
) { m_fontStyle
= fontStyle
; m_flags
|= wxTEXT_ATTR_FONT_ITALIC
; }
374 void SetFontWeight(int fontWeight
) { m_fontWeight
= fontWeight
; m_flags
|= wxTEXT_ATTR_FONT_WEIGHT
; }
375 void SetFontFaceName(const wxString
& faceName
) { m_fontFaceName
= faceName
; m_flags
|= wxTEXT_ATTR_FONT_FACE
; }
376 void SetFontUnderlined(bool underlined
) { m_fontUnderlined
= underlined
; m_flags
|= wxTEXT_ATTR_FONT_UNDERLINE
; }
378 void SetFlags(long flags
) { m_flags
= flags
; }
380 void SetCharacterStyleName(const wxString
& name
) { m_characterStyleName
= name
; }
381 void SetParagraphStyleName(const wxString
& name
) { m_paragraphStyleName
= name
; }
382 void SetParagraphSpacingAfter(int spacing
) { m_paragraphSpacingAfter
= spacing
; }
383 void SetParagraphSpacingBefore(int spacing
) { m_paragraphSpacingBefore
= spacing
; }
384 void SetLineSpacing(int spacing
) { m_lineSpacing
= spacing
; }
385 void SetBulletStyle(int style
) { m_bulletStyle
= style
; }
386 void SetBulletNumber(int n
) { m_bulletNumber
= n
; }
387 void SetBulletSymbol(wxChar symbol
) { m_bulletSymbol
= symbol
; }
389 const wxColour
& GetTextColour() const { return m_colText
; }
390 const wxColour
& GetBackgroundColour() const { return m_colBack
; }
391 wxTextAttrAlignment
GetAlignment() const { return m_textAlignment
; }
392 const wxArrayInt
& GetTabs() const { return m_tabs
; }
393 long GetLeftIndent() const { return m_leftIndent
; }
394 long GetLeftSubIndent() const { return m_leftSubIndent
; }
395 long GetRightIndent() const { return m_rightIndent
; }
396 long GetFlags() const { return m_flags
; }
398 int GetFontSize() const { return m_fontSize
; }
399 int GetFontStyle() const { return m_fontStyle
; }
400 int GetFontWeight() const { return m_fontWeight
; }
401 bool GetFontUnderlined() const { return m_fontUnderlined
; }
402 const wxString
& GetFontFaceName() const { return m_fontFaceName
; }
404 const wxString
& GetCharacterStyleName() const { return m_characterStyleName
; }
405 const wxString
& GetParagraphStyleName() const { return m_paragraphStyleName
; }
406 int GetParagraphSpacingAfter() const { return m_paragraphSpacingAfter
; }
407 int GetParagraphSpacingBefore() const { return m_paragraphSpacingBefore
; }
408 int GetLineSpacing() const { return m_lineSpacing
; }
409 int GetBulletStyle() const { return m_bulletStyle
; }
410 int GetBulletNumber() const { return m_bulletNumber
; }
411 wxChar
GetBulletSymbol() const { return m_bulletSymbol
; }
414 bool HasTextColour() const { return m_colText
.Ok() && HasFlag(wxTEXT_ATTR_TEXT_COLOUR
) ; }
415 bool HasBackgroundColour() const { return m_colBack
.Ok() && HasFlag(wxTEXT_ATTR_BACKGROUND_COLOUR
) ; }
416 bool HasAlignment() const { return (m_textAlignment
!= wxTEXT_ALIGNMENT_DEFAULT
) || ((m_flags
& wxTEXT_ATTR_ALIGNMENT
) != 0) ; }
417 bool HasTabs() const { return (m_flags
& wxTEXT_ATTR_TABS
) != 0 ; }
418 bool HasLeftIndent() const { return (m_flags
& wxTEXT_ATTR_LEFT_INDENT
) != 0 ; }
419 bool HasRightIndent() const { return (m_flags
& wxTEXT_ATTR_RIGHT_INDENT
) != 0 ; }
420 bool HasWeight() const { return (m_flags
& wxTEXT_ATTR_FONT_WEIGHT
) != 0; }
421 bool HasSize() const { return (m_flags
& wxTEXT_ATTR_FONT_SIZE
) != 0; }
422 bool HasItalic() const { return (m_flags
& wxTEXT_ATTR_FONT_ITALIC
) != 0; }
423 bool HasUnderlined() const { return (m_flags
& wxTEXT_ATTR_FONT_UNDERLINE
) != 0; }
424 bool HasFaceName() const { return (m_flags
& wxTEXT_ATTR_FONT_FACE
) != 0; }
425 bool HasFont() const { return (m_flags
& (wxTEXT_ATTR_FONT
)) != 0; }
427 bool HasParagraphSpacingAfter() const { return (m_flags
& wxTEXT_ATTR_PARA_SPACING_AFTER
) != 0; }
428 bool HasParagraphSpacingBefore() const { return (m_flags
& wxTEXT_ATTR_PARA_SPACING_BEFORE
) != 0; }
429 bool HasLineSpacing() const { return (m_flags
& wxTEXT_ATTR_LINE_SPACING
) != 0; }
430 bool HasCharacterStyleName() const { return (m_flags
& wxTEXT_ATTR_CHARACTER_STYLE_NAME
) != 0; }
431 bool HasParagraphStyleName() const { return (m_flags
& wxTEXT_ATTR_PARAGRAPH_STYLE_NAME
) != 0; }
432 bool HasBulletStyle() const { return (m_flags
& wxTEXT_ATTR_BULLET_STYLE
) != 0; }
433 bool HasBulletNumber() const { return (m_flags
& wxTEXT_ATTR_BULLET_NUMBER
) != 0; }
434 bool HasBulletSymbol() const { return (m_flags
& wxTEXT_ATTR_BULLET_SYMBOL
) != 0; }
436 bool HasFlag(long flag
) const { return (m_flags
& flag
) != 0; }
438 // Is this a character style?
439 bool IsCharacterStyle() const { return (0 != (GetFlags() & (wxTEXT_ATTR_FONT
| wxTEXT_ATTR_BACKGROUND_COLOUR
| wxTEXT_ATTR_TEXT_COLOUR
))); }
440 bool IsParagraphStyle() const { return (0 != (GetFlags() & (wxTEXT_ATTR_ALIGNMENT
|wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
|wxTEXT_ATTR_TABS
|
441 wxTEXT_ATTR_PARA_SPACING_BEFORE
|wxTEXT_ATTR_PARA_SPACING_AFTER
|wxTEXT_ATTR_LINE_SPACING
|
442 wxTEXT_ATTR_BULLET_STYLE
|wxTEXT_ATTR_BULLET_NUMBER
))); }
444 // returns false if we have any attributes set, true otherwise
445 bool IsDefault() const
447 return !HasTextColour() && !HasBackgroundColour() && !HasFont() && !HasAlignment() &&
448 !HasTabs() && !HasLeftIndent() && !HasRightIndent() &&
449 !HasParagraphSpacingAfter() && !HasParagraphSpacingBefore() && !HasLineSpacing() &&
450 !HasCharacterStyleName() && !HasParagraphStyleName() && !HasBulletNumber() && !HasBulletStyle() && !HasBulletSymbol();
457 wxArrayInt m_tabs
; // array of int: tab stops in 1/10 mm
458 int m_leftIndent
; // left indent in 1/10 mm
459 int m_leftSubIndent
; // left indent for all but the first
460 // line in a paragraph relative to the
461 // first line, in 1/10 mm
462 int m_rightIndent
; // right indent in 1/10 mm
463 wxTextAttrAlignment m_textAlignment
;
465 int m_paragraphSpacingAfter
;
466 int m_paragraphSpacingBefore
;
470 wxChar m_bulletSymbol
;
478 bool m_fontUnderlined
;
479 wxString m_fontFaceName
;
482 wxString m_characterStyleName
;
485 wxString m_paragraphStyleName
;
488 #define wxTEXT_ATTR_CHARACTER (wxTEXT_ATTR_FONT) | wxTEXT_ATTR_BACKGROUND_COLOUR | wxTEXT_ATTR_TEXT_COLOUR
490 #define wxTEXT_ATTR_PARAGRAPH wxTEXT_ATTR_ALIGNMENT|wxTEXT_ATTR_LEFT_INDENT|wxTEXT_ATTR_RIGHT_INDENT|wxTEXT_ATTR_TABS|\
491 wxTEXT_ATTR_PARA_SPACING_BEFORE|wxTEXT_ATTR_PARA_SPACING_AFTER|wxTEXT_ATTR_LINE_SPACING|\
492 wxTEXT_ATTR_BULLET_STYLE|wxTEXT_ATTR_BULLET_NUMBER|wxTEXT_ATTR_BULLET_SYMBOL
494 #define wxTEXT_ATTR_ALL wxTEXT_ATTR_CHARACTER|wxTEXT_ATTR_PARAGRAPH
497 * wxRichTextObject class declaration
498 * This is the base for drawable objects.
501 class WXDLLIMPEXP_ADV wxRichTextObject
: public wxObject
503 DECLARE_CLASS(wxRichTextObject
)
507 wxRichTextObject(wxRichTextObject
* parent
= NULL
);
512 /// Draw the item, within the given range. Some objects may ignore the range (for
513 /// example paragraphs) while others must obey it (lines, to implement wrapping)
514 virtual bool Draw(wxDC
& dc
, const wxRichTextRange
& range
, const wxRichTextRange
& selectionRange
, const wxRect
& rect
, int descent
, int style
) = 0;
516 /// Lay the item out at the specified position with the given size constraint.
517 /// Layout must set the cached size.
518 virtual bool Layout(wxDC
& dc
, const wxRect
& rect
, int style
) = 0;
520 /// Hit-testing: returns a flag indicating hit test details, plus
521 /// information about position
522 virtual int HitTest(wxDC
& WXUNUSED(dc
), const wxPoint
& WXUNUSED(pt
), long& WXUNUSED(textPosition
)) { return false; }
524 /// Finds the absolute position and row height for the given character position
525 virtual bool FindPosition(wxDC
& WXUNUSED(dc
), long WXUNUSED(index
), wxPoint
& WXUNUSED(pt
), int* WXUNUSED(height
), bool WXUNUSED(forceLineStart
)) { return false; }
527 /// Get the best size, i.e. the ideal starting size for this object irrespective
528 /// of available space. For a short text string, it will be the size that exactly encloses
529 /// the text. For a longer string, it might use the parent width for example.
530 virtual wxSize
GetBestSize() const { return m_size
; }
532 /// Get the object size for the given range. Returns false if the range
533 /// is invalid for this object.
534 virtual bool GetRangeSize(const wxRichTextRange
& range
, wxSize
& size
, int& descent
, wxDC
& dc
, int flags
) const = 0;
536 /// Do a split, returning an object containing the second part, and setting
537 /// the first part in 'this'.
538 virtual wxRichTextObject
* DoSplit(long WXUNUSED(pos
)) { return NULL
; }
540 /// Calculate range. By default, guess that the object is 1 unit long.
541 virtual void CalculateRange(long start
, long& end
) { end
= start
; m_range
.SetRange(start
, end
); }
544 virtual bool DeleteRange(const wxRichTextRange
& WXUNUSED(range
)) { return false; }
546 /// Returns true if the object is empty
547 virtual bool IsEmpty() const { return false; }
549 /// Get any text in this object for the given range
550 virtual wxString
GetTextForRange(const wxRichTextRange
& WXUNUSED(range
)) const { return wxEmptyString
; }
552 /// Returns true if this object can merge itself with the given one.
553 virtual bool CanMerge(wxRichTextObject
* WXUNUSED(object
)) const { return false; }
555 /// Returns true if this object merged itself with the given one.
556 /// The calling code will then delete the given object.
557 virtual bool Merge(wxRichTextObject
* WXUNUSED(object
)) { return false; }
559 /// Dump to output stream for debugging
560 virtual void Dump(wxTextOutputStream
& stream
);
564 /// Get/set the cached object size as calculated by Layout.
565 virtual wxSize
GetCachedSize() const { return m_size
; }
566 virtual void SetCachedSize(const wxSize
& sz
) { m_size
= sz
; }
568 /// Get/set the object position
569 virtual wxPoint
GetPosition() const { return m_pos
; }
570 virtual void SetPosition(const wxPoint
& pos
) { m_pos
= pos
; }
572 /// Get the rectangle enclosing the object
573 virtual wxRect
GetRect() const { return wxRect(GetPosition(), GetCachedSize()); }
576 void SetRange(const wxRichTextRange
& range
) { m_range
= range
; }
579 const wxRichTextRange
& GetRange() const { return m_range
; }
580 wxRichTextRange
& GetRange() { return m_range
; }
582 /// Get/set dirty flag (whether the object needs Layout to be called)
583 virtual bool GetDirty() const { return m_dirty
; }
584 virtual void SetDirty(bool dirty
) { m_dirty
= dirty
; }
586 /// Is this composite?
587 virtual bool IsComposite() const { return false; }
589 /// Get/set the parent.
590 virtual wxRichTextObject
* GetParent() const { return m_parent
; }
591 virtual void SetParent(wxRichTextObject
* parent
) { m_parent
= parent
; }
593 /// Set the margin around the object
594 virtual void SetMargins(int margin
);
595 virtual void SetMargins(int leftMargin
, int rightMargin
, int topMargin
, int bottomMargin
);
596 virtual int GetLeftMargin() const { return m_leftMargin
; }
597 virtual int GetRightMargin() const { return m_rightMargin
; }
598 virtual int GetTopMargin() const { return m_topMargin
; }
599 virtual int GetBottomMargin() const { return m_bottomMargin
; }
601 /// Set attributes object
602 void SetAttributes(const wxTextAttrEx
& attr
) { m_attributes
= attr
; }
603 const wxTextAttrEx
& GetAttributes() const { return m_attributes
; }
604 wxTextAttrEx
& GetAttributes() { return m_attributes
; }
606 /// Set/get stored descent
607 void SetDescent(int descent
) { m_descent
= descent
; }
608 int GetDescent() const { return m_descent
; }
613 virtual wxRichTextObject
* Clone() const { return NULL
; }
616 void Copy(const wxRichTextObject
& obj
);
618 /// Reference-counting allows us to use the same object in multiple
619 /// lists (not yet used)
620 void Reference() { m_refCount
++; }
623 /// Convert units in tends of a millimetre to device units
624 int ConvertTenthsMMToPixels(wxDC
& dc
, int units
);
629 int m_descent
; // Descent for this object (if any)
632 wxRichTextObject
* m_parent
;
634 /// The range of this object (start position to end position)
635 wxRichTextRange m_range
;
644 wxTextAttrEx m_attributes
;
647 WX_DECLARE_EXPORTED_LIST( wxRichTextObject
, wxRichTextObjectList
);
650 * wxRichTextCompositeObject class declaration
651 * Objects of this class can contain other objects.
654 class WXDLLIMPEXP_ADV wxRichTextCompositeObject
: public wxRichTextObject
656 DECLARE_CLASS(wxRichTextCompositeObject
)
660 wxRichTextCompositeObject(wxRichTextObject
* parent
= NULL
);
661 ~wxRichTextCompositeObject();
665 /// Hit-testing: returns a flag indicating hit test details, plus
666 /// information about position
667 virtual int HitTest(wxDC
& dc
, const wxPoint
& pt
, long& textPosition
);
669 /// Finds the absolute position and row height for the given character position
670 virtual bool FindPosition(wxDC
& dc
, long index
, wxPoint
& pt
, int* height
, bool forceLineStart
);
673 virtual void CalculateRange(long start
, long& end
);
676 virtual bool DeleteRange(const wxRichTextRange
& range
);
678 /// Get any text in this object for the given range
679 virtual wxString
GetTextForRange(const wxRichTextRange
& range
) const;
681 /// Dump to output stream for debugging
682 virtual void Dump(wxTextOutputStream
& stream
);
687 wxRichTextObjectList
& GetChildren() { return m_children
; }
688 const wxRichTextObjectList
& GetChildren() const { return m_children
; }
690 /// Get the child count
691 size_t GetChildCount() const ;
693 /// Get the nth child
694 wxRichTextObject
* GetChild(size_t n
) const ;
696 /// Get/set dirty flag
697 virtual bool GetDirty() const { return m_dirty
; }
698 virtual void SetDirty(bool dirty
) { m_dirty
= dirty
; }
700 /// Is this composite?
701 virtual bool IsComposite() const { return true; }
703 /// Returns true if the buffer is empty
704 virtual bool IsEmpty() const { return GetChildCount() == 0; }
709 void Copy(const wxRichTextCompositeObject
& obj
);
711 /// Append a child, returning the position
712 size_t AppendChild(wxRichTextObject
* child
) ;
714 /// Insert the child in front of the given object, or at the beginning
715 bool InsertChild(wxRichTextObject
* child
, wxRichTextObject
* inFrontOf
) ;
718 bool RemoveChild(wxRichTextObject
* child
, bool deleteChild
= false) ;
720 /// Delete all children
721 bool DeleteChildren() ;
723 /// Recursively merge all pieces that can be merged.
727 wxRichTextObjectList m_children
;
731 * wxRichTextBox class declaration
732 * This defines a 2D space to lay out objects
735 class WXDLLIMPEXP_ADV wxRichTextBox
: public wxRichTextCompositeObject
737 DECLARE_DYNAMIC_CLASS(wxRichTextBox
)
741 wxRichTextBox(wxRichTextObject
* parent
= NULL
);
742 wxRichTextBox(const wxRichTextBox
& obj
): wxRichTextCompositeObject() { Copy(obj
); }
747 virtual bool Draw(wxDC
& dc
, const wxRichTextRange
& range
, const wxRichTextRange
& selectionRange
, const wxRect
& rect
, int descent
, int style
);
750 virtual bool Layout(wxDC
& dc
, const wxRect
& rect
, int style
);
752 /// Get/set the object size for the given range. Returns false if the range
753 /// is invalid for this object.
754 virtual bool GetRangeSize(const wxRichTextRange
& range
, wxSize
& size
, int& descent
, wxDC
& dc
, int flags
) const;
761 virtual wxRichTextObject
* Clone() const { return new wxRichTextBox(*this); }
764 void Copy(const wxRichTextBox
& obj
);
770 * wxRichTextParagraphBox class declaration
771 * This box knows how to lay out paragraphs.
774 class WXDLLIMPEXP_ADV wxRichTextParagraphLayoutBox
: public wxRichTextBox
776 DECLARE_DYNAMIC_CLASS(wxRichTextParagraphLayoutBox
)
780 wxRichTextParagraphLayoutBox(wxRichTextObject
* parent
= NULL
);
781 wxRichTextParagraphLayoutBox(const wxRichTextParagraphLayoutBox
& obj
):wxRichTextBox() { Init(); Copy(obj
); }
786 virtual bool Draw(wxDC
& dc
, const wxRichTextRange
& range
, const wxRichTextRange
& selectionRange
, const wxRect
& rect
, int descent
, int style
);
789 virtual bool Layout(wxDC
& dc
, const wxRect
& rect
, int style
);
791 /// Get/set the object size for the given range. Returns false if the range
792 /// is invalid for this object.
793 virtual bool GetRangeSize(const wxRichTextRange
& range
, wxSize
& size
, int& descent
, wxDC
& dc
, int flags
) const;
796 virtual bool DeleteRange(const wxRichTextRange
& range
);
798 /// Get any text in this object for the given range
799 virtual wxString
GetTextForRange(const wxRichTextRange
& range
) const;
803 /// Associate a control with the buffer, for operations that for example require refreshing the window.
804 void SetRichTextCtrl(wxRichTextCtrl
* ctrl
) { m_ctrl
= ctrl
; }
806 /// Get the associated control.
807 wxRichTextCtrl
* GetRichTextCtrl() const { return m_ctrl
; }
811 /// Initialize the object.
814 /// Clear all children
815 virtual void Clear();
817 /// Clear and initialize with one blank paragraph
818 virtual void Reset();
820 /// Convenience function to add a paragraph of text
821 virtual wxRichTextRange
AddParagraph(const wxString
& text
);
823 /// Convenience function to add an image
824 virtual wxRichTextRange
AddImage(const wxImage
& image
);
826 /// Adds multiple paragraphs, based on newlines.
827 virtual wxRichTextRange
AddParagraphs(const wxString
& text
);
829 /// Get the line at the given position. If caretPosition is true, the position is
830 /// a caret position, which is normally a smaller number.
831 virtual wxRichTextLine
* GetLineAtPosition(long pos
, bool caretPosition
= false) const;
833 /// Get the line at the given y pixel position, or the last line.
834 virtual wxRichTextLine
* GetLineAtYPosition(int y
) const;
836 /// Get the paragraph at the given character or caret position
837 virtual wxRichTextParagraph
* GetParagraphAtPosition(long pos
, bool caretPosition
= false) const;
839 /// Get the line size at the given position
840 virtual wxSize
GetLineSizeAtPosition(long pos
, bool caretPosition
= false) const;
842 /// Given a position, get the number of the visible line (potentially many to a paragraph),
843 /// starting from zero at the start of the buffer. We also have to pass a bool (startOfLine)
844 /// that indicates whether the caret is being shown at the end of the previous line or at the start
845 /// of the next, since the caret can be shown at 2 visible positions for the same underlying
847 virtual long GetVisibleLineNumber(long pos
, bool caretPosition
= false, bool startOfLine
= false) const;
849 /// Given a line number, get the corresponding wxRichTextLine object.
850 virtual wxRichTextLine
* GetLineForVisibleLineNumber(long lineNumber
) const;
852 /// Get the leaf object in a paragraph at this position.
853 /// Given a line number, get the corresponding wxRichTextLine object.
854 virtual wxRichTextObject
* GetLeafObjectAtPosition(long position
) const;
856 /// Get the paragraph by number
857 virtual wxRichTextParagraph
* GetParagraphAtLine(long paragraphNumber
) const;
859 /// Get the paragraph for a given line
860 virtual wxRichTextParagraph
* GetParagraphForLine(wxRichTextLine
* line
) const;
862 /// Get the length of the paragraph
863 virtual int GetParagraphLength(long paragraphNumber
) const;
865 /// Get the number of paragraphs
866 virtual int GetParagraphCount() const { return GetChildCount(); }
868 /// Get the number of visible lines
869 virtual int GetLineCount() const;
871 /// Get the text of the paragraph
872 virtual wxString
GetParagraphText(long paragraphNumber
) const;
874 /// Convert zero-based line column and paragraph number to a position.
875 virtual long XYToPosition(long x
, long y
) const;
877 /// Convert zero-based position to line column and paragraph number
878 virtual bool PositionToXY(long pos
, long* x
, long* y
) const;
880 /// Set text attributes: character and/or paragraph styles.
881 virtual bool SetStyle(const wxRichTextRange
& range
, const wxRichTextAttr
& style
, bool withUndo
= true);
882 virtual bool SetStyle(const wxRichTextRange
& range
, const wxTextAttrEx
& style
, bool withUndo
= true);
884 /// Get the text attributes for this position.
885 virtual bool GetStyle(long position
, wxTextAttrEx
& style
) const;
886 virtual bool GetStyle(long position
, wxRichTextAttr
& style
) const;
888 /// Test if this whole range has character attributes of the specified kind. If any
889 /// of the attributes are different within the range, the test fails. You
890 /// can use this to implement, for example, bold button updating. style must have
891 /// flags indicating which attributes are of interest.
892 virtual bool HasCharacterAttributes(const wxRichTextRange
& range
, const wxTextAttrEx
& style
) const;
893 virtual bool HasCharacterAttributes(const wxRichTextRange
& range
, const wxRichTextAttr
& style
) const;
895 /// Test if this whole range has paragraph attributes of the specified kind. If any
896 /// of the attributes are different within the range, the test fails. You
897 /// can use this to implement, for example, centering button updating. style must have
898 /// flags indicating which attributes are of interest.
899 virtual bool HasParagraphAttributes(const wxRichTextRange
& range
, const wxTextAttrEx
& style
) const;
900 virtual bool HasParagraphAttributes(const wxRichTextRange
& range
, const wxRichTextAttr
& style
) const;
903 virtual wxRichTextObject
* Clone() const { return new wxRichTextParagraphLayoutBox(*this); }
905 /// Insert fragment into this box at the given position. If partialParagraph is true,
906 /// it is assumed that the last (or only) paragraph is just a piece of data with no paragraph
908 virtual bool InsertFragment(long position
, wxRichTextFragment
& fragment
);
910 /// Make a copy of the fragment corresponding to the given range, putting it in 'fragment'.
911 virtual bool CopyFragment(const wxRichTextRange
& range
, wxRichTextFragment
& fragment
);
914 void Copy(const wxRichTextParagraphLayoutBox
& obj
);
917 virtual void UpdateRanges() { long end
; CalculateRange(0, end
); }
920 virtual wxString
GetText() const;
922 /// Set default style for new content. Setting it to a default attribute
923 /// makes new content take on the 'basic' style.
924 virtual bool SetDefaultStyle(const wxTextAttrEx
& style
);
926 /// Get default style
927 virtual const wxTextAttrEx
& GetDefaultStyle() const { return m_defaultAttributes
; }
929 /// Set basic (overall) style
930 virtual void SetBasicStyle(const wxTextAttrEx
& style
) { m_attributes
= style
; }
931 virtual void SetBasicStyle(const wxRichTextAttr
& style
) { style
.CopyTo(m_attributes
); }
933 /// Get basic (overall) style
934 virtual const wxTextAttrEx
& GetBasicStyle() const { return m_attributes
; }
936 /// Invalidate the buffer. With no argument, invalidates whole buffer.
937 void Invalidate(const wxRichTextRange
& invalidRange
= wxRICHTEXT_ALL
);
939 /// Get invalid range, rounding to entire paragraphs if argument is true.
940 wxRichTextRange
GetInvalidRange(bool wholeParagraphs
= false) const;
943 wxRichTextCtrl
* m_ctrl
;
944 wxTextAttrEx m_defaultAttributes
;
946 /// The invalidated range that will need full layout
947 wxRichTextRange m_invalidRange
;
951 * wxRichTextFragment class declaration
952 * This is a lind of paragraph layout box used for storing
953 * paragraphs for Undo/Redo, for example.
956 class WXDLLIMPEXP_ADV wxRichTextFragment
: public wxRichTextParagraphLayoutBox
958 DECLARE_DYNAMIC_CLASS(wxRichTextFragment
)
962 wxRichTextFragment() { Init(); }
963 wxRichTextFragment(const wxRichTextFragment
& obj
):wxRichTextParagraphLayoutBox() { Init(); Copy(obj
); }
967 /// Get/set whether the last paragraph is partial or complete
968 void SetPartialParagraph(bool partialPara
) { m_partialParagraph
= partialPara
; }
969 bool GetPartialParagraph() const { return m_partialParagraph
; }
979 void Copy(const wxRichTextFragment
& obj
);
982 virtual wxRichTextObject
* Clone() const { return new wxRichTextFragment(*this); }
986 // Is the last paragraph partial or complete?
987 bool m_partialParagraph
;
991 * wxRichTextLine class declaration
992 * This object represents a line in a paragraph, and stores
993 * offsets from the start of the paragraph representing the
994 * start and end positions of the line.
997 class WXDLLIMPEXP_ADV wxRichTextLine
1002 wxRichTextLine(wxRichTextParagraph
* parent
);
1003 wxRichTextLine(const wxRichTextLine
& obj
) { Init( NULL
); Copy(obj
); }
1004 virtual ~wxRichTextLine() {}
1011 void SetRange(const wxRichTextRange
& range
) { m_range
= range
; }
1012 void SetRange(long from
, long to
) { m_range
= wxRichTextRange(from
, to
); }
1014 /// Get the parent paragraph
1015 wxRichTextParagraph
* GetParent() { return m_parent
; }
1018 const wxRichTextRange
& GetRange() const { return m_range
; }
1019 wxRichTextRange
& GetRange() { return m_range
; }
1021 /// Get the absolute range
1022 wxRichTextRange
GetAbsoluteRange() const;
1024 /// Get/set the line size as calculated by Layout.
1025 virtual wxSize
GetSize() const { return m_size
; }
1026 virtual void SetSize(const wxSize
& sz
) { m_size
= sz
; }
1028 /// Get/set the object position relative to the parent
1029 virtual wxPoint
GetPosition() const { return m_pos
; }
1030 virtual void SetPosition(const wxPoint
& pos
) { m_pos
= pos
; }
1032 /// Get the absolute object position
1033 virtual wxPoint
GetAbsolutePosition() const;
1035 /// Get the rectangle enclosing the line
1036 virtual wxRect
GetRect() const { return wxRect(GetAbsolutePosition(), GetSize()); }
1038 /// Set/get stored descent
1039 void SetDescent(int descent
) { m_descent
= descent
; }
1040 int GetDescent() const { return m_descent
; }
1045 void Init(wxRichTextParagraph
* parent
);
1048 void Copy(const wxRichTextLine
& obj
);
1051 virtual wxRichTextLine
* Clone() const { return new wxRichTextLine(*this); }
1055 /// The range of the line (start position to end position)
1056 /// This is relative to the parent paragraph.
1057 wxRichTextRange m_range
;
1059 /// Size and position measured relative to top of paragraph
1063 /// Maximum descent for this line (location of text baseline)
1066 // The parent object
1067 wxRichTextParagraph
* m_parent
;
1070 WX_DECLARE_EXPORTED_LIST( wxRichTextLine
, wxRichTextLineList
);
1073 * wxRichTextParagraph class declaration
1074 * This object represents a single paragraph (or in a straight text editor, a line).
1077 class WXDLLIMPEXP_ADV wxRichTextParagraph
: public wxRichTextBox
1079 DECLARE_DYNAMIC_CLASS(wxRichTextParagraph
)
1083 wxRichTextParagraph(wxRichTextObject
* parent
= NULL
, wxTextAttrEx
* style
= NULL
);
1084 wxRichTextParagraph(const wxString
& text
, wxRichTextObject
* parent
= NULL
, wxTextAttrEx
* style
= NULL
);
1085 ~wxRichTextParagraph();
1086 wxRichTextParagraph(const wxRichTextParagraph
& obj
):wxRichTextBox() { Copy(obj
); }
1091 virtual bool Draw(wxDC
& dc
, const wxRichTextRange
& range
, const wxRichTextRange
& selectionRange
, const wxRect
& rect
, int descent
, int style
);
1093 /// Lay the item out
1094 virtual bool Layout(wxDC
& dc
, const wxRect
& rect
, int style
);
1096 /// Get/set the object size for the given range. Returns false if the range
1097 /// is invalid for this object.
1098 virtual bool GetRangeSize(const wxRichTextRange
& range
, wxSize
& size
, int& descent
, wxDC
& dc
, int flags
) const;
1100 /// Finds the absolute position and row height for the given character position
1101 virtual bool FindPosition(wxDC
& dc
, long index
, wxPoint
& pt
, int* height
, bool forceLineStart
);
1103 /// Hit-testing: returns a flag indicating hit test details, plus
1104 /// information about position
1105 virtual int HitTest(wxDC
& dc
, const wxPoint
& pt
, long& textPosition
);
1108 virtual void CalculateRange(long start
, long& end
);
1112 /// Get the cached lines
1113 wxRichTextLineList
& GetLines() { return m_cachedLines
; }
1118 void Copy(const wxRichTextParagraph
& obj
);
1121 virtual wxRichTextObject
* Clone() const { return new wxRichTextParagraph(*this); }
1123 /// Clear the cached lines
1128 /// Apply paragraph styles such as centering to the wrapped lines
1129 virtual void ApplyParagraphStyle(const wxRect
& rect
);
1131 /// Insert text at the given position
1132 virtual bool InsertText(long pos
, const wxString
& text
);
1134 /// Split an object at this position if necessary, and return
1135 /// the previous object, or NULL if inserting at beginning.
1136 virtual wxRichTextObject
* SplitAt(long pos
, wxRichTextObject
** previousObject
= NULL
);
1138 /// Move content to a list from this point
1139 virtual void MoveToList(wxRichTextObject
* obj
, wxList
& list
);
1141 /// Add content back from list
1142 virtual void MoveFromList(wxList
& list
);
1144 /// Get the plain text searching from the start or end of the range.
1145 /// The resulting string may be shorter than the range given.
1146 bool GetContiguousPlainText(wxString
& text
, const wxRichTextRange
& range
, bool fromStart
= true);
1148 /// Find a suitable wrap position. wrapPosition is the last position in the line to the left
1150 bool FindWrapPosition(const wxRichTextRange
& range
, wxDC
& dc
, int availableSpace
, long& wrapPosition
);
1152 /// Find the object at the given position
1153 wxRichTextObject
* FindObjectAtPosition(long position
);
1155 /// Get the bullet text for this paragraph.
1156 wxString
GetBulletText();
1158 /// Allocate or reuse a line object
1159 wxRichTextLine
* AllocateLine(int pos
);
1161 /// Clear remaining unused line objects, if any
1162 bool ClearUnusedLines(int lineCount
);
1165 /// The lines that make up the wrapped paragraph
1166 wxRichTextLineList m_cachedLines
;
1170 * wxRichTextPlainText class declaration
1171 * This object represents a single piece of text.
1174 class WXDLLIMPEXP_ADV wxRichTextPlainText
: public wxRichTextObject
1176 DECLARE_DYNAMIC_CLASS(wxRichTextPlainText
)
1180 wxRichTextPlainText(const wxString
& text
= wxEmptyString
, wxRichTextObject
* parent
= NULL
, wxTextAttrEx
* style
= NULL
);
1181 wxRichTextPlainText(const wxRichTextPlainText
& obj
):wxRichTextObject() { Copy(obj
); }
1186 virtual bool Draw(wxDC
& dc
, const wxRichTextRange
& range
, const wxRichTextRange
& selectionRange
, const wxRect
& rect
, int descent
, int style
);
1188 /// Lay the item out
1189 virtual bool Layout(wxDC
& dc
, const wxRect
& rect
, int style
);
1191 /// Get/set the object size for the given range. Returns false if the range
1192 /// is invalid for this object.
1193 virtual bool GetRangeSize(const wxRichTextRange
& range
, wxSize
& size
, int& descent
, wxDC
& dc
, int flags
) const;
1195 /// Get any text in this object for the given range
1196 virtual wxString
GetTextForRange(const wxRichTextRange
& range
) const;
1198 /// Do a split, returning an object containing the second part, and setting
1199 /// the first part in 'this'.
1200 virtual wxRichTextObject
* DoSplit(long pos
);
1203 virtual void CalculateRange(long start
, long& end
);
1206 virtual bool DeleteRange(const wxRichTextRange
& range
);
1208 /// Returns true if the object is empty
1209 virtual bool IsEmpty() const { return m_text
.empty(); }
1211 /// Returns true if this object can merge itself with the given one.
1212 virtual bool CanMerge(wxRichTextObject
* object
) const;
1214 /// Returns true if this object merged itself with the given one.
1215 /// The calling code will then delete the given object.
1216 virtual bool Merge(wxRichTextObject
* object
);
1218 /// Dump to output stream for debugging
1219 virtual void Dump(wxTextOutputStream
& stream
);
1224 const wxString
& GetText() const { return m_text
; }
1227 void SetText(const wxString
& text
) { m_text
= text
; }
1232 void Copy(const wxRichTextPlainText
& obj
);
1235 virtual wxRichTextObject
* Clone() const { return new wxRichTextPlainText(*this); }
1242 * wxRichTextImageBlock stores information about an image, in binary in-memory form
1245 class WXDLLIMPEXP_BASE wxDataInputStream
;
1246 class WXDLLIMPEXP_BASE wxDataOutputStream
;
1248 class WXDLLIMPEXP_ADV wxRichTextImageBlock
: public wxObject
1251 wxRichTextImageBlock();
1252 wxRichTextImageBlock(const wxRichTextImageBlock
& block
);
1253 ~wxRichTextImageBlock();
1258 // Load the original image into a memory block.
1259 // If the image is not a JPEG, we must convert it into a JPEG
1260 // to conserve space.
1261 // If it's not a JPEG we can make use of 'image', already scaled, so we don't have to
1262 // load the image a 2nd time.
1263 virtual bool MakeImageBlock(const wxString
& filename
, int imageType
, wxImage
& image
, bool convertToJPEG
= true);
1265 // Make an image block from the wxImage in the given
1267 virtual bool MakeImageBlock(wxImage
& image
, int imageType
, int quality
= 80);
1270 bool Write(const wxString
& filename
);
1272 // Write data in hex to a stream
1273 bool WriteHex(wxOutputStream
& stream
);
1275 // Read data in hex from a stream
1276 bool ReadHex(wxInputStream
& stream
, int length
, int imageType
);
1278 // Copy from 'block'
1279 void Copy(const wxRichTextImageBlock
& block
);
1281 // Load a wxImage from the block
1282 bool Load(wxImage
& image
);
1285 void operator=(const wxRichTextImageBlock
& block
);
1289 unsigned char* GetData() const { return m_data
; }
1290 size_t GetDataSize() const { return m_dataSize
; }
1291 int GetImageType() const { return m_imageType
; }
1293 void SetData(unsigned char* image
) { m_data
= image
; }
1294 void SetDataSize(size_t size
) { m_dataSize
= size
; }
1295 void SetImageType(int imageType
) { m_imageType
= imageType
; }
1297 bool Ok() const { return GetData() != NULL
; }
1301 /// Allocate and read from stream as a block of memory
1302 static unsigned char* ReadBlock(wxInputStream
& stream
, size_t size
);
1303 static unsigned char* ReadBlock(const wxString
& filename
, size_t size
);
1305 // Write memory block to stream
1306 static bool WriteBlock(wxOutputStream
& stream
, unsigned char* block
, size_t size
);
1308 // Write memory block to file
1309 static bool WriteBlock(const wxString
& filename
, unsigned char* block
, size_t size
);
1312 // Size in bytes of the image stored.
1313 // This is in the raw, original form such as a JPEG file.
1314 unsigned char* m_data
;
1316 int m_imageType
; // wxWin type id
1321 * wxRichTextImage class declaration
1322 * This object represents an image.
1325 class WXDLLIMPEXP_ADV wxRichTextImage
: public wxRichTextObject
1327 DECLARE_DYNAMIC_CLASS(wxRichTextImage
)
1331 wxRichTextImage(wxRichTextObject
* parent
= NULL
):wxRichTextObject(parent
) { }
1332 wxRichTextImage(const wxImage
& image
, wxRichTextObject
* parent
= NULL
);
1333 wxRichTextImage(const wxRichTextImageBlock
& imageBlock
, wxRichTextObject
* parent
= NULL
);
1334 wxRichTextImage(const wxRichTextImage
& obj
):wxRichTextObject() { Copy(obj
); }
1339 virtual bool Draw(wxDC
& dc
, const wxRichTextRange
& range
, const wxRichTextRange
& selectionRange
, const wxRect
& rect
, int descent
, int style
);
1341 /// Lay the item out
1342 virtual bool Layout(wxDC
& dc
, const wxRect
& rect
, int style
);
1344 /// Get the object size for the given range. Returns false if the range
1345 /// is invalid for this object.
1346 virtual bool GetRangeSize(const wxRichTextRange
& range
, wxSize
& size
, int& descent
, wxDC
& dc
, int flags
) const;
1348 /// Returns true if the object is empty
1349 virtual bool IsEmpty() const { return !m_image
.Ok(); }
1354 const wxImage
& GetImage() const { return m_image
; }
1357 void SetImage(const wxImage
& image
) { m_image
= image
; }
1359 /// Get the image block containing the raw data
1360 wxRichTextImageBlock
& GetImageBlock() { return m_imageBlock
; }
1365 void Copy(const wxRichTextImage
& obj
);
1368 virtual wxRichTextObject
* Clone() const { return new wxRichTextImage(*this); }
1370 /// Load wxImage from the block
1371 virtual bool LoadFromBlock();
1373 /// Make block from the wxImage
1374 virtual bool MakeBlock();
1377 // TODO: reduce the multiple representations of data
1380 wxRichTextImageBlock m_imageBlock
;
1385 * wxRichTextBuffer class declaration
1386 * This is a kind of box, used to represent the whole buffer
1389 class WXDLLIMPEXP_ADV wxRichTextCommand
;
1390 class WXDLLIMPEXP_ADV wxRichTextAction
;
1392 class WXDLLIMPEXP_ADV wxRichTextBuffer
: public wxRichTextParagraphLayoutBox
1394 DECLARE_DYNAMIC_CLASS(wxRichTextBuffer
)
1398 wxRichTextBuffer() { Init(); }
1399 wxRichTextBuffer(const wxRichTextBuffer
& obj
):wxRichTextParagraphLayoutBox() { Init(); Copy(obj
); }
1400 ~wxRichTextBuffer() ;
1404 /// Gets the command processor
1405 wxCommandProcessor
* GetCommandProcessor() const { return m_commandProcessor
; }
1407 /// Set style sheet, if any.
1408 void SetStyleSheet(wxRichTextStyleSheet
* styleSheet
) { m_styleSheet
= styleSheet
; }
1409 wxRichTextStyleSheet
* GetStyleSheet() const { return m_styleSheet
; }
1416 /// Clears the buffer and resets the command processor
1417 virtual void Clear();
1419 /// The same as Clear, and adds an empty paragraph.
1420 virtual void Reset();
1423 virtual bool LoadFile(const wxString
& filename
, int type
= wxRICHTEXT_TYPE_ANY
);
1426 virtual bool SaveFile(const wxString
& filename
, int type
= wxRICHTEXT_TYPE_ANY
);
1428 /// Load from a stream
1429 virtual bool LoadFile(wxInputStream
& stream
, int type
= wxRICHTEXT_TYPE_ANY
);
1431 /// Save to a stream
1432 virtual bool SaveFile(wxOutputStream
& stream
, int type
= wxRICHTEXT_TYPE_ANY
);
1434 /// Convenience function to add a paragraph of text
1435 virtual wxRichTextRange
AddParagraph(const wxString
& text
) { Modify(); return wxRichTextParagraphLayoutBox
::AddParagraph(text
); }
1437 /// Begin collapsing undo/redo commands. Note that this may not work properly
1438 /// if combining commands that delete or insert content, changing ranges for
1439 /// subsequent actions.
1440 virtual bool BeginBatchUndo(const wxString
& cmdName
);
1442 /// End collapsing undo/redo commands
1443 virtual bool EndBatchUndo();
1445 /// Collapsing commands?
1446 virtual bool BatchingUndo() const { return m_batchedCommandDepth
> 0; }
1448 /// Submit immediately, or delay according to whether collapsing is on
1449 virtual bool SubmitAction(wxRichTextAction
* action
);
1451 /// Get collapsed command
1452 virtual wxRichTextCommand
* GetBatchedCommand() const { return m_batchedCommand
; }
1454 /// Begin suppressing undo/redo commands. The way undo is suppressed may be implemented
1455 /// differently by each command. If not dealt with by a command implementation, then
1456 /// it will be implemented automatically by not storing the command in the undo history
1457 /// when the action is submitted to the command processor.
1458 virtual bool BeginSuppressUndo();
1460 /// End suppressing undo/redo commands.
1461 virtual bool EndSuppressUndo();
1463 /// Collapsing commands?
1464 virtual bool SuppressingUndo() const { return m_suppressUndo
> 0; }
1466 /// Copy the range to the clipboard
1467 virtual bool CopyToClipboard(const wxRichTextRange
& range
);
1469 /// Paste the clipboard content to the buffer
1470 virtual bool PasteFromClipboard(long position
);
1472 /// Can we paste from the clipboard?
1473 virtual bool CanPasteFromClipboard() const;
1475 /// Begin using a style
1476 virtual bool BeginStyle(const wxTextAttrEx
& style
);
1479 virtual bool EndStyle();
1482 virtual bool EndAllStyles();
1484 /// Clear the style stack
1485 virtual void ClearStyleStack();
1487 /// Get the size of the style stack, for example to check correct nesting
1488 virtual int GetStyleStackSize() const { return m_attributeStack
.GetCount(); }
1490 /// Begin using bold
1494 bool EndBold() { return EndStyle(); }
1496 /// Begin using italic
1499 /// End using italic
1500 bool EndItalic() { return EndStyle(); }
1502 /// Begin using underline
1503 bool BeginUnderline();
1505 /// End using underline
1506 bool EndUnderline() { return EndStyle(); }
1508 /// Begin using point size
1509 bool BeginFontSize(int pointSize
);
1511 /// End using point size
1512 bool EndFontSize() { return EndStyle(); }
1514 /// Begin using this font
1515 bool BeginFont(const wxFont
& font
);
1517 /// End using a font
1518 bool EndFont() { return EndStyle(); }
1520 /// Begin using this colour
1521 bool BeginTextColour(const wxColour
& colour
);
1523 /// End using a colour
1524 bool EndTextColour() { return EndStyle(); }
1526 /// Begin using alignment
1527 bool BeginAlignment(wxTextAttrAlignment alignment
);
1530 bool EndAlignment() { return EndStyle(); }
1532 /// Begin left indent
1533 bool BeginLeftIndent(int leftIndent
, int leftSubIndent
= 0);
1536 bool EndLeftIndent() { return EndStyle(); }
1538 /// Begin right indent
1539 bool BeginRightIndent(int rightIndent
);
1541 /// End right indent
1542 bool EndRightIndent() { return EndStyle(); }
1544 /// Begin paragraph spacing
1545 bool BeginParagraphSpacing(int before
, int after
);
1547 /// End paragraph spacing
1548 bool EndParagraphSpacing() { return EndStyle(); }
1550 /// Begin line spacing
1551 bool BeginLineSpacing(int lineSpacing
);
1553 /// End line spacing
1554 bool EndLineSpacing() { return EndStyle(); }
1556 /// Begin numbered bullet
1557 bool BeginNumberedBullet(int bulletNumber
, int leftIndent
, int leftSubIndent
, int bulletStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
);
1559 /// End numbered bullet
1560 bool EndNumberedBullet() { return EndStyle(); }
1562 /// Begin symbol bullet
1563 bool BeginSymbolBullet(wxChar symbol
, int leftIndent
, int leftSubIndent
, int bulletStyle
= wxTEXT_ATTR_BULLET_STYLE_SYMBOL
);
1565 /// End symbol bullet
1566 bool EndSymbolBullet() { return EndStyle(); }
1568 /// Begin named character style
1569 bool BeginCharacterStyle(const wxString
& characterStyle
);
1571 /// End named character style
1572 bool EndCharacterStyle() { return EndStyle(); }
1574 /// Begin named paragraph style
1575 bool BeginParagraphStyle(const wxString
& paragraphStyle
);
1577 /// End named character style
1578 bool EndParagraphStyle() { return EndStyle(); }
1583 void Copy(const wxRichTextBuffer
& obj
) { wxRichTextBox
::Copy(obj
); }
1586 virtual wxRichTextObject
* Clone() const { return new wxRichTextBuffer(*this); }
1588 /// Submit command to insert the given text
1589 bool InsertTextWithUndo(long pos
, const wxString
& text
, wxRichTextCtrl
* ctrl
);
1591 /// Submit command to insert a newline
1592 bool InsertNewlineWithUndo(long pos
, wxRichTextCtrl
* ctrl
);
1594 /// Submit command to insert the given image
1595 bool InsertImageWithUndo(long pos
, const wxRichTextImageBlock
& imageBlock
, wxRichTextCtrl
* ctrl
);
1597 /// Submit command to delete this range
1598 bool DeleteRangeWithUndo(const wxRichTextRange
& range
, long initialCaretPosition
, long newCaretPositon
, wxRichTextCtrl
* ctrl
);
1601 void Modify(bool modify
= true) { m_modified
= modify
; }
1602 bool IsModified() const { return m_modified
; }
1604 /// Dumps contents of buffer for debugging purposes
1605 virtual void Dump();
1606 virtual void Dump(wxTextOutputStream
& stream
) { wxRichTextParagraphLayoutBox
::Dump(stream
); }
1608 /// Returns the file handlers
1609 static wxList
& GetHandlers() { return sm_handlers
; }
1611 /// Adds a handler to the end
1612 static void AddHandler(wxRichTextFileHandler
*handler
);
1614 /// Inserts a handler at the front
1615 static void InsertHandler(wxRichTextFileHandler
*handler
);
1617 /// Removes a handler
1618 static bool RemoveHandler(const wxString
& name
);
1620 /// Finds a handler by name
1621 static wxRichTextFileHandler
*FindHandler(const wxString
& name
);
1623 /// Finds a handler by extension and type
1624 static wxRichTextFileHandler
*FindHandler(const wxString
& extension
, int imageType
);
1626 /// Finds a handler by filename or, if supplied, type
1627 static wxRichTextFileHandler
*FindHandlerFilenameOrType(const wxString
& filename
, int imageType
);
1629 /// Finds a handler by type
1630 static wxRichTextFileHandler
*FindHandler(int imageType
);
1632 /// Gets a wildcard incorporating all visible handlers. If 'types' is present,
1633 /// will be filled with the file type corresponding to each filter. This can be
1634 /// used to determine the type to pass to LoadFile given a selected filter.
1635 static wxString
GetExtWildcard(bool combine
= false, bool save
= false, wxArrayInt
* types
= NULL
);
1637 /// Clean up handlers
1638 static void CleanUpHandlers();
1640 /// Initialise the standard handlers
1641 static void InitStandardHandlers();
1645 /// Command processor
1646 wxCommandProcessor
* m_commandProcessor
;
1648 /// Has been modified?
1651 /// Collapsed command stack
1652 int m_batchedCommandDepth
;
1654 /// Name for collapsed command
1655 wxString m_batchedCommandsName
;
1657 /// Current collapsed command accumulating actions
1658 wxRichTextCommand
* m_batchedCommand
;
1660 /// Whether to suppress undo
1663 /// Style sheet, if any
1664 wxRichTextStyleSheet
* m_styleSheet
;
1666 /// Stack of attributes for convenience functions
1667 wxList m_attributeStack
;
1670 static wxList sm_handlers
;
1674 * The command identifiers
1678 enum wxRichTextCommandId
1682 wxRICHTEXT_CHANGE_STYLE
1686 * Command classes for undo/redo
1690 class WXDLLIMPEXP_ADV wxRichTextAction
;
1691 class WXDLLIMPEXP_ADV wxRichTextCommand
: public wxCommand
1694 // Ctor for one action
1695 wxRichTextCommand(const wxString
& name
, wxRichTextCommandId id
, wxRichTextBuffer
* buffer
,
1696 wxRichTextCtrl
* ctrl
, bool ignoreFirstTime
= false);
1698 // Ctor for multiple actions
1699 wxRichTextCommand(const wxString
& name
);
1701 ~wxRichTextCommand();
1706 void AddAction(wxRichTextAction
* action
);
1707 void ClearActions();
1709 wxList
& GetActions() { return m_actions
; }
1717 * wxRichTextAction class declaration
1718 * There can be more than one action in a command.
1721 class WXDLLIMPEXP_ADV wxRichTextAction
: public wxObject
1724 wxRichTextAction(wxRichTextCommand
* cmd
, const wxString
& name
, wxRichTextCommandId id
, wxRichTextBuffer
* buffer
,
1725 wxRichTextCtrl
* ctrl
, bool ignoreFirstTime
= false);
1727 ~wxRichTextAction();
1732 /// Update the control appearance
1733 void UpdateAppearance(long caretPosition
, bool sendUpdateEvent
= false);
1735 /// Replace the buffer paragraphs with the given fragment.
1736 void ApplyParagraphs(const wxRichTextFragment
& fragment
);
1738 /// Get the fragments
1739 wxRichTextFragment
& GetNewParagraphs() { return m_newParagraphs
; }
1740 wxRichTextFragment
& GetOldParagraphs() { return m_oldParagraphs
; }
1742 /// Set/get the position used for e.g. insertion
1743 void SetPosition(long pos
) { m_position
= pos
; }
1744 long GetPosition() const { return m_position
; }
1746 /// Set/get the range for e.g. deletion
1747 void SetRange(const wxRichTextRange
& range
) { m_range
= range
; }
1748 const wxRichTextRange
& GetRange() const { return m_range
; }
1751 const wxString
& GetName() const { return m_name
; }
1758 wxRichTextBuffer
* m_buffer
;
1761 wxRichTextCtrl
* m_ctrl
;
1763 // Stores the new paragraphs
1764 wxRichTextFragment m_newParagraphs
;
1766 // Stores the old paragraphs
1767 wxRichTextFragment m_oldParagraphs
;
1769 // The affected range
1770 wxRichTextRange m_range
;
1772 // The insertion point for this command
1775 // Ignore 1st 'Do' operation because we already did it
1778 // The command identifier
1779 wxRichTextCommandId m_cmdId
;
1783 * wxRichTextFileHandler
1784 * Base class for file handlers
1787 class WXDLLIMPEXP_ADV wxRichTextFileHandler
: public wxObject
1789 DECLARE_CLASS(wxRichTextFileHandler
)
1791 wxRichTextFileHandler(const wxString
& name
= wxEmptyString
, const wxString
& ext
= wxEmptyString
, int type
= 0)
1792 : m_name(name
), m_extension(ext
), m_type(type
), m_visible(true)
1796 bool LoadFile(wxRichTextBuffer
*buffer
, wxInputStream
& stream
)
1797 { return DoLoadFile(buffer
, stream
); }
1798 bool SaveFile(wxRichTextBuffer
*buffer
, wxOutputStream
& stream
)
1799 { return DoSaveFile(buffer
, stream
); }
1802 bool LoadFile(wxRichTextBuffer
*buffer
, const wxString
& filename
);
1803 bool SaveFile(wxRichTextBuffer
*buffer
, const wxString
& filename
);
1805 /// Can we handle this filename (if using files)? By default, checks the extension.
1806 virtual bool CanHandle(const wxString
& filename
) const;
1808 /// Can we save using this handler?
1809 virtual bool CanSave() const { return false; }
1811 /// Can we load using this handler?
1812 virtual bool CanLoad() const { return false; }
1814 /// Should this handler be visible to the user?
1815 virtual bool IsVisible() const { return m_visible
; }
1816 virtual void SetVisible(bool visible
) { m_visible
= visible
; }
1818 void SetName(const wxString
& name
) { m_name
= name
; }
1819 wxString
GetName() const { return m_name
; }
1821 void SetExtension(const wxString
& ext
) { m_extension
= ext
; }
1822 wxString
GetExtension() const { return m_extension
; }
1824 void SetType(int type
) { m_type
= type
; }
1825 int GetType() const { return m_type
; }
1830 virtual bool DoLoadFile(wxRichTextBuffer
*buffer
, wxInputStream
& stream
) = 0;
1831 virtual bool DoSaveFile(wxRichTextBuffer
*buffer
, wxOutputStream
& stream
) = 0;
1835 wxString m_extension
;
1841 * wxRichTextPlainTextHandler
1842 * Plain text handler
1845 class WXDLLIMPEXP_ADV wxRichTextPlainTextHandler
: public wxRichTextFileHandler
1847 DECLARE_CLASS(wxRichTextPlainTextHandler
)
1849 wxRichTextPlainTextHandler(const wxString
& name
= wxT("Text"), const wxString
& ext
= wxT("txt"), int type
= wxRICHTEXT_TYPE_TEXT
)
1850 : wxRichTextFileHandler(name
, ext
, type
)
1853 /// Can we save using this handler?
1854 virtual bool CanSave() const { return true; }
1856 /// Can we load using this handler?
1857 virtual bool CanLoad() const { return true; }
1862 virtual bool DoLoadFile(wxRichTextBuffer
*buffer
, wxInputStream
& stream
);
1863 virtual bool DoSaveFile(wxRichTextBuffer
*buffer
, wxOutputStream
& stream
);
1873 inline bool wxRichTextHasStyle(int flags
, int style
)
1875 return ((flags
& style
) == style
);
1878 /// Compare two attribute objects
1879 bool wxTextAttrEq(const wxTextAttrEx
& attr1
, const wxTextAttrEx
& attr2
);
1880 bool wxTextAttrEq(const wxTextAttr
& attr1
, const wxRichTextAttr
& attr2
);
1882 /// Compare two attribute objects, but take into account the flags
1883 /// specifying attributes of interest.
1884 bool wxTextAttrEqPartial(const wxTextAttrEx
& attr1
, const wxTextAttrEx
& attr2
, int flags
);
1885 bool wxTextAttrEqPartial(const wxTextAttrEx
& attr1
, const wxRichTextAttr
& attr2
, int flags
);
1887 /// Apply one style to another
1888 bool wxRichTextApplyStyle(wxTextAttrEx
& destStyle
, const wxTextAttrEx
& style
);
1889 bool wxRichTextApplyStyle(wxRichTextAttr
& destStyle
, const wxTextAttrEx
& style
);
1890 bool wxRichTextApplyStyle(wxTextAttrEx
& destStyle
, const wxRichTextAttr
& style
);
1896 // _WX_RICHTEXTBUFFER_H_