1 /////////////////////////////////////////////////////////////////////////////
2 // Name: 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 wxRichTextRange
operator -(const wxRichTextRange
& range
) const { return wxRichTextRange(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
); }
212 void SetRange(long start
, long end
) { m_start
= start
; m_end
= end
; }
214 void SetStart(long start
) { m_start
= start
; }
215 long GetStart() const { return m_start
; }
217 void SetEnd(long end
) { m_end
= end
; }
218 long GetEnd() const { return m_end
; }
220 /// Returns true if this range is completely outside 'range'
221 bool IsOutside(const wxRichTextRange
& range
) const { return range
.m_start
> m_end
|| range
.m_end
< m_start
; }
223 /// Returns true if this range is completely within 'range'
224 bool IsWithin(const wxRichTextRange
& range
) const { return m_start
>= range
.m_start
&& m_end
<= range
.m_end
; }
226 /// Returns true if the given position is within this range. Allow
227 /// for the possibility of an empty range - assume the position
228 /// is within this empty range. NO, I think we should not match with an empty range.
229 // bool Contains(long pos) const { return pos >= m_start && (pos <= m_end || GetLength() == 0); }
230 bool Contains(long pos
) const { return pos
>= m_start
&& pos
<= m_end
; }
232 /// Limit this range to be within 'range'
233 bool LimitTo(const wxRichTextRange
& range
) ;
235 /// Gets the length of the range
236 long GetLength() const { return m_end
- m_start
+ 1; }
238 /// Swaps the start and end
239 void Swap() { long tmp
= m_start
; m_start
= m_end
; m_end
= tmp
; }
247 * wxTextAttrEx is an extended version of wxTextAttr with more paragraph attributes.
250 class WXDLLIMPEXP_ADV wxTextAttrEx
: public wxTextAttr
254 wxTextAttrEx(const wxTextAttrEx
& attr
);
255 wxTextAttrEx() { Init(); }
257 // Initialise this object.
260 // Assignment from a wxTextAttrEx object
261 void operator= (const wxTextAttrEx
& attr
);
263 // Assignment from a wxTextAttr object.
264 void operator= (const wxTextAttr
& attr
);
267 void SetCharacterStyleName(const wxString
& name
) { m_characterStyleName
= name
; }
268 void SetParagraphStyleName(const wxString
& name
) { m_paragraphStyleName
= name
; }
269 void SetParagraphSpacingAfter(int spacing
) { m_paragraphSpacingAfter
= spacing
; }
270 void SetParagraphSpacingBefore(int spacing
) { m_paragraphSpacingBefore
= spacing
; }
271 void SetLineSpacing(int spacing
) { m_lineSpacing
= spacing
; }
272 void SetBulletStyle(int style
) { m_bulletStyle
= style
; }
273 void SetBulletNumber(int n
) { m_bulletNumber
= n
; }
274 void SetBulletSymbol(wxChar symbol
) { m_bulletSymbol
= symbol
; }
276 const wxString
& GetCharacterStyleName() const { return m_characterStyleName
; }
277 const wxString
& GetParagraphStyleName() const { return m_paragraphStyleName
; }
278 int GetParagraphSpacingAfter() const { return m_paragraphSpacingAfter
; }
279 int GetParagraphSpacingBefore() const { return m_paragraphSpacingBefore
; }
280 int GetLineSpacing() const { return m_lineSpacing
; }
281 int GetBulletStyle() const { return m_bulletStyle
; }
282 int GetBulletNumber() const { return m_bulletNumber
; }
283 wxChar
GetBulletSymbol() const { return m_bulletSymbol
; }
285 bool HasParagraphSpacingAfter() const { return HasFlag(wxTEXT_ATTR_PARA_SPACING_AFTER
); }
286 bool HasParagraphSpacingBefore() const { return HasFlag(wxTEXT_ATTR_PARA_SPACING_BEFORE
); }
287 bool HasLineSpacing() const { return HasFlag(wxTEXT_ATTR_LINE_SPACING
); }
288 bool HasCharacterStyleName() const { return HasFlag(wxTEXT_ATTR_CHARACTER_STYLE_NAME
); }
289 bool HasParagraphStyleName() const { return HasFlag(wxTEXT_ATTR_PARAGRAPH_STYLE_NAME
); }
290 bool HasBulletStyle() const { return HasFlag(wxTEXT_ATTR_BULLET_STYLE
); }
291 bool HasBulletNumber() const { return HasFlag(wxTEXT_ATTR_BULLET_NUMBER
); }
292 bool HasBulletSymbol() const { return HasFlag(wxTEXT_ATTR_BULLET_SYMBOL
); }
294 // Is this a character style?
295 bool IsCharacterStyle() const { return (0 != (GetFlags() & (wxTEXT_ATTR_FONT
| wxTEXT_ATTR_BACKGROUND_COLOUR
| wxTEXT_ATTR_TEXT_COLOUR
))); }
296 bool IsParagraphStyle() const { return (0 != (GetFlags() & (wxTEXT_ATTR_ALIGNMENT
|wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
|wxTEXT_ATTR_TABS
|
297 wxTEXT_ATTR_PARA_SPACING_BEFORE
|wxTEXT_ATTR_PARA_SPACING_AFTER
|wxTEXT_ATTR_LINE_SPACING
|
298 wxTEXT_ATTR_BULLET_STYLE
|wxTEXT_ATTR_BULLET_NUMBER
))); }
300 // returns false if we have any attributes set, true otherwise
301 bool IsDefault() const
303 return !HasTextColour() && !HasBackgroundColour() && !HasFont() && !HasAlignment() &&
304 !HasTabs() && !HasLeftIndent() && !HasRightIndent() &&
305 !HasParagraphSpacingAfter() && !HasParagraphSpacingBefore() && !HasLineSpacing() &&
306 !HasCharacterStyleName() && !HasParagraphStyleName() && !HasBulletNumber() && !HasBulletStyle() && !HasBulletSymbol();
310 int m_paragraphSpacingAfter
;
311 int m_paragraphSpacingBefore
;
315 wxChar m_bulletSymbol
;
318 wxString m_characterStyleName
;
321 wxString m_paragraphStyleName
;
325 * wxRichTextAttr stores attributes without a wxFont object, so is a much more
326 * efficient way to query styles.
329 class WXDLLIMPEXP_ADV wxRichTextAttr
333 wxRichTextAttr(const wxTextAttrEx
& attr
);
334 wxRichTextAttr() { Init(); }
335 wxRichTextAttr(const wxColour
& colText
,
336 const wxColour
& colBack
= wxNullColour
,
337 wxTextAttrAlignment alignment
= wxTEXT_ALIGNMENT_DEFAULT
);
339 // Initialise this object.
342 // Assignment from a wxRichTextAttr object.
343 void operator= (const wxRichTextAttr
& attr
);
345 // Assignment from a wxTextAttrEx object.
346 void operator= (const wxTextAttrEx
& attr
);
348 // Making a wxTextAttrEx object.
349 operator wxTextAttrEx () const ;
351 // Copy to a wxTextAttr
352 void CopyTo(wxTextAttrEx
& attr
) const;
354 // Create font from font attributes.
355 wxFont
CreateFont() const;
357 // Get attributes from font.
358 bool GetFontAttributes(const wxFont
& font
);
361 void SetTextColour(const wxColour
& colText
) { m_colText
= colText
; m_flags
|= wxTEXT_ATTR_TEXT_COLOUR
; }
362 void SetBackgroundColour(const wxColour
& colBack
) { m_colBack
= colBack
; m_flags
|= wxTEXT_ATTR_BACKGROUND_COLOUR
; }
363 void SetAlignment(wxTextAttrAlignment alignment
) { m_textAlignment
= alignment
; m_flags
|= wxTEXT_ATTR_ALIGNMENT
; }
364 void SetTabs(const wxArrayInt
& tabs
) { m_tabs
= tabs
; m_flags
|= wxTEXT_ATTR_TABS
; }
365 void SetLeftIndent(int indent
, int subIndent
= 0) { m_leftIndent
= indent
; m_leftSubIndent
= subIndent
; m_flags
|= wxTEXT_ATTR_LEFT_INDENT
; }
366 void SetRightIndent(int indent
) { m_rightIndent
= indent
; m_flags
|= wxTEXT_ATTR_RIGHT_INDENT
; }
368 void SetFontSize(int pointSize
) { m_fontSize
= pointSize
; m_flags
|= wxTEXT_ATTR_FONT_SIZE
; }
369 void SetFontStyle(int fontStyle
) { m_fontStyle
= fontStyle
; m_flags
|= wxTEXT_ATTR_FONT_ITALIC
; }
370 void SetFontWeight(int fontWeight
) { m_fontWeight
= fontWeight
; m_flags
|= wxTEXT_ATTR_FONT_WEIGHT
; }
371 void SetFontFaceName(const wxString
& faceName
) { m_fontFaceName
= faceName
; m_flags
|= wxTEXT_ATTR_FONT_FACE
; }
372 void SetFontUnderlined(bool underlined
) { m_fontUnderlined
= underlined
; m_flags
|= wxTEXT_ATTR_FONT_UNDERLINE
; }
374 void SetFlags(long flags
) { m_flags
= flags
; }
376 void SetCharacterStyleName(const wxString
& name
) { m_characterStyleName
= name
; }
377 void SetParagraphStyleName(const wxString
& name
) { m_paragraphStyleName
= name
; }
378 void SetParagraphSpacingAfter(int spacing
) { m_paragraphSpacingAfter
= spacing
; }
379 void SetParagraphSpacingBefore(int spacing
) { m_paragraphSpacingBefore
= spacing
; }
380 void SetLineSpacing(int spacing
) { m_lineSpacing
= spacing
; }
381 void SetBulletStyle(int style
) { m_bulletStyle
= style
; }
382 void SetBulletNumber(int n
) { m_bulletNumber
= n
; }
383 void SetBulletSymbol(wxChar symbol
) { m_bulletSymbol
= symbol
; }
385 const wxColour
& GetTextColour() const { return m_colText
; }
386 const wxColour
& GetBackgroundColour() const { return m_colBack
; }
387 wxTextAttrAlignment
GetAlignment() const { return m_textAlignment
; }
388 const wxArrayInt
& GetTabs() const { return m_tabs
; }
389 long GetLeftIndent() const { return m_leftIndent
; }
390 long GetLeftSubIndent() const { return m_leftSubIndent
; }
391 long GetRightIndent() const { return m_rightIndent
; }
392 long GetFlags() const { return m_flags
; }
394 int GetFontSize() const { return m_fontSize
; }
395 int GetFontStyle() const { return m_fontStyle
; }
396 int GetFontWeight() const { return m_fontWeight
; }
397 bool GetFontUnderlined() const { return m_fontUnderlined
; }
398 const wxString
& GetFontFaceName() const { return m_fontFaceName
; }
400 const wxString
& GetCharacterStyleName() const { return m_characterStyleName
; }
401 const wxString
& GetParagraphStyleName() const { return m_paragraphStyleName
; }
402 int GetParagraphSpacingAfter() const { return m_paragraphSpacingAfter
; }
403 int GetParagraphSpacingBefore() const { return m_paragraphSpacingBefore
; }
404 int GetLineSpacing() const { return m_lineSpacing
; }
405 int GetBulletStyle() const { return m_bulletStyle
; }
406 int GetBulletNumber() const { return m_bulletNumber
; }
407 wxChar
GetBulletSymbol() const { return m_bulletSymbol
; }
410 bool HasTextColour() const { return m_colText
.Ok() && HasFlag(wxTEXT_ATTR_TEXT_COLOUR
) ; }
411 bool HasBackgroundColour() const { return m_colBack
.Ok() && HasFlag(wxTEXT_ATTR_BACKGROUND_COLOUR
) ; }
412 bool HasAlignment() const { return (m_textAlignment
!= wxTEXT_ALIGNMENT_DEFAULT
) || ((m_flags
& wxTEXT_ATTR_ALIGNMENT
) != 0) ; }
413 bool HasTabs() const { return (m_flags
& wxTEXT_ATTR_TABS
) != 0 ; }
414 bool HasLeftIndent() const { return (m_flags
& wxTEXT_ATTR_LEFT_INDENT
) != 0 ; }
415 bool HasRightIndent() const { return (m_flags
& wxTEXT_ATTR_RIGHT_INDENT
) != 0 ; }
416 bool HasWeight() const { return (m_flags
& wxTEXT_ATTR_FONT_WEIGHT
) != 0; }
417 bool HasSize() const { return (m_flags
& wxTEXT_ATTR_FONT_SIZE
) != 0; }
418 bool HasItalic() const { return (m_flags
& wxTEXT_ATTR_FONT_ITALIC
) != 0; }
419 bool HasUnderlined() const { return (m_flags
& wxTEXT_ATTR_FONT_UNDERLINE
) != 0; }
420 bool HasFaceName() const { return (m_flags
& wxTEXT_ATTR_FONT_FACE
) != 0; }
421 bool HasFont() const { return (m_flags
& (wxTEXT_ATTR_FONT
)) != 0; }
423 bool HasParagraphSpacingAfter() const { return (m_flags
& wxTEXT_ATTR_PARA_SPACING_AFTER
) != 0; }
424 bool HasParagraphSpacingBefore() const { return (m_flags
& wxTEXT_ATTR_PARA_SPACING_BEFORE
) != 0; }
425 bool HasLineSpacing() const { return (m_flags
& wxTEXT_ATTR_LINE_SPACING
) != 0; }
426 bool HasCharacterStyleName() const { return (m_flags
& wxTEXT_ATTR_CHARACTER_STYLE_NAME
) != 0; }
427 bool HasParagraphStyleName() const { return (m_flags
& wxTEXT_ATTR_PARAGRAPH_STYLE_NAME
) != 0; }
428 bool HasBulletStyle() const { return (m_flags
& wxTEXT_ATTR_BULLET_STYLE
) != 0; }
429 bool HasBulletNumber() const { return (m_flags
& wxTEXT_ATTR_BULLET_NUMBER
) != 0; }
430 bool HasBulletSymbol() const { return (m_flags
& wxTEXT_ATTR_BULLET_SYMBOL
) != 0; }
432 bool HasFlag(long flag
) const { return (m_flags
& flag
) != 0; }
434 // Is this a character style?
435 bool IsCharacterStyle() const { return (0 != (GetFlags() & (wxTEXT_ATTR_FONT
| wxTEXT_ATTR_BACKGROUND_COLOUR
| wxTEXT_ATTR_TEXT_COLOUR
))); }
436 bool IsParagraphStyle() const { return (0 != (GetFlags() & (wxTEXT_ATTR_ALIGNMENT
|wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
|wxTEXT_ATTR_TABS
|
437 wxTEXT_ATTR_PARA_SPACING_BEFORE
|wxTEXT_ATTR_PARA_SPACING_AFTER
|wxTEXT_ATTR_LINE_SPACING
|
438 wxTEXT_ATTR_BULLET_STYLE
|wxTEXT_ATTR_BULLET_NUMBER
))); }
440 // returns false if we have any attributes set, true otherwise
441 bool IsDefault() const
443 return !HasTextColour() && !HasBackgroundColour() && !HasFont() && !HasAlignment() &&
444 !HasTabs() && !HasLeftIndent() && !HasRightIndent() &&
445 !HasParagraphSpacingAfter() && !HasParagraphSpacingBefore() && !HasLineSpacing() &&
446 !HasCharacterStyleName() && !HasParagraphStyleName() && !HasBulletNumber() && !HasBulletStyle() && !HasBulletSymbol();
453 wxArrayInt m_tabs
; // array of int: tab stops in 1/10 mm
454 int m_leftIndent
; // left indent in 1/10 mm
455 int m_leftSubIndent
; // left indent for all but the first
456 // line in a paragraph relative to the
457 // first line, in 1/10 mm
458 int m_rightIndent
; // right indent in 1/10 mm
459 wxTextAttrAlignment m_textAlignment
;
461 int m_paragraphSpacingAfter
;
462 int m_paragraphSpacingBefore
;
466 wxChar m_bulletSymbol
;
474 bool m_fontUnderlined
;
475 wxString m_fontFaceName
;
478 wxString m_characterStyleName
;
481 wxString m_paragraphStyleName
;
484 #define wxTEXT_ATTR_CHARACTER (wxTEXT_ATTR_FONT) | wxTEXT_ATTR_BACKGROUND_COLOUR | wxTEXT_ATTR_TEXT_COLOUR
486 #define wxTEXT_ATTR_PARAGRAPH wxTEXT_ATTR_ALIGNMENT|wxTEXT_ATTR_LEFT_INDENT|wxTEXT_ATTR_RIGHT_INDENT|wxTEXT_ATTR_TABS|\
487 wxTEXT_ATTR_PARA_SPACING_BEFORE|wxTEXT_ATTR_PARA_SPACING_AFTER|wxTEXT_ATTR_LINE_SPACING|\
488 wxTEXT_ATTR_BULLET_STYLE|wxTEXT_ATTR_BULLET_NUMBER|wxTEXT_ATTR_BULLET_SYMBOL
490 #define wxTEXT_ATTR_ALL wxTEXT_ATTR_CHARACTER|wxTEXT_ATTR_PARAGRAPH
493 * wxRichTextObject class declaration
494 * This is the base for drawable objects.
497 class WXDLLIMPEXP_ADV wxRichTextObject
: public wxObject
499 DECLARE_CLASS(wxRichTextObject
)
503 wxRichTextObject(wxRichTextObject
* parent
= NULL
);
508 /// Draw the item, within the given range. Some objects may ignore the range (for
509 /// example paragraphs) while others must obey it (lines, to implement wrapping)
510 virtual bool Draw(wxDC
& dc
, const wxRichTextRange
& range
, const wxRichTextRange
& selectionRange
, const wxRect
& rect
, int descent
, int style
) = 0;
512 /// Lay the item out at the specified position with the given size constraint.
513 /// Layout must set the cached size.
514 virtual bool Layout(wxDC
& dc
, const wxRect
& rect
, int style
) = 0;
516 /// Hit-testing: returns a flag indicating hit test details, plus
517 /// information about position
518 virtual int HitTest(wxDC
& WXUNUSED(dc
), const wxPoint
& WXUNUSED(pt
), long& WXUNUSED(textPosition
)) { return false; }
520 /// Finds the absolute position and row height for the given character position
521 virtual bool FindPosition(wxDC
& WXUNUSED(dc
), long WXUNUSED(index
), wxPoint
& WXUNUSED(pt
), int* WXUNUSED(height
), bool WXUNUSED(forceLineStart
)) { return false; }
523 /// Get the best size, i.e. the ideal starting size for this object irrespective
524 /// of available space. For a short text string, it will be the size that exactly encloses
525 /// the text. For a longer string, it might use the parent width for example.
526 virtual wxSize
GetBestSize() const { return m_size
; }
528 /// Get the object size for the given range. Returns false if the range
529 /// is invalid for this object.
530 virtual bool GetRangeSize(const wxRichTextRange
& range
, wxSize
& size
, int& descent
, wxDC
& dc
, int flags
) const = 0;
532 /// Do a split, returning an object containing the second part, and setting
533 /// the first part in 'this'.
534 virtual wxRichTextObject
* DoSplit(long WXUNUSED(pos
)) { return NULL
; }
536 /// Calculate range. By default, guess that the object is 1 unit long.
537 virtual void CalculateRange(long start
, long& end
) { end
= start
; m_range
.SetRange(start
, end
); }
540 virtual bool DeleteRange(const wxRichTextRange
& WXUNUSED(range
)) { return false; }
542 /// Returns true if the object is empty
543 virtual bool IsEmpty() const { return false; }
545 /// Get any text in this object for the given range
546 virtual wxString
GetTextForRange(const wxRichTextRange
& WXUNUSED(range
)) const { return wxEmptyString
; }
548 /// Returns true if this object can merge itself with the given one.
549 virtual bool CanMerge(wxRichTextObject
* WXUNUSED(object
)) const { return false; }
551 /// Returns true if this object merged itself with the given one.
552 /// The calling code will then delete the given object.
553 virtual bool Merge(wxRichTextObject
* WXUNUSED(object
)) { return false; }
555 /// Dump to output stream for debugging
556 virtual void Dump(wxTextOutputStream
& stream
);
560 /// Get/set the cached object size as calculated by Layout.
561 virtual wxSize
GetCachedSize() const { return m_size
; }
562 virtual void SetCachedSize(const wxSize
& sz
) { m_size
= sz
; }
564 /// Get/set the object position
565 virtual wxPoint
GetPosition() const { return m_pos
; }
566 virtual void SetPosition(const wxPoint
& pos
) { m_pos
= pos
; }
568 /// Get the rectangle enclosing the object
569 virtual wxRect
GetRect() const { return wxRect(GetPosition(), GetCachedSize()); }
572 void SetRange(const wxRichTextRange
& range
) { m_range
= range
; }
575 const wxRichTextRange
& GetRange() const { return m_range
; }
576 wxRichTextRange
& GetRange() { return m_range
; }
578 /// Get/set dirty flag (whether the object needs Layout to be called)
579 virtual bool GetDirty() const { return m_dirty
; }
580 virtual void SetDirty(bool dirty
) { m_dirty
= dirty
; }
582 /// Is this composite?
583 virtual bool IsComposite() const { return false; }
585 /// Get/set the parent.
586 virtual wxRichTextObject
* GetParent() const { return m_parent
; }
587 virtual void SetParent(wxRichTextObject
* parent
) { m_parent
= parent
; }
589 /// Set the margin around the object
590 virtual void SetMargins(int margin
);
591 virtual void SetMargins(int leftMargin
, int rightMargin
, int topMargin
, int bottomMargin
);
592 virtual int GetLeftMargin() const { return m_leftMargin
; }
593 virtual int GetRightMargin() const { return m_rightMargin
; }
594 virtual int GetTopMargin() const { return m_topMargin
; }
595 virtual int GetBottomMargin() const { return m_bottomMargin
; }
597 /// Set attributes object
598 void SetAttributes(const wxTextAttrEx
& attr
) { m_attributes
= attr
; }
599 const wxTextAttrEx
& GetAttributes() const { return m_attributes
; }
600 wxTextAttrEx
& GetAttributes() { return m_attributes
; }
602 /// Set/get stored descent
603 void SetDescent(int descent
) { m_descent
= descent
; }
604 int GetDescent() const { return m_descent
; }
609 virtual wxRichTextObject
* Clone() const { return NULL
; }
612 void Copy(const wxRichTextObject
& obj
);
614 /// Reference-counting allows us to use the same object in multiple
615 /// lists (not yet used)
616 void Reference() { m_refCount
++; }
619 /// Convert units in tends of a millimetre to device units
620 int ConvertTenthsMMToPixels(wxDC
& dc
, int units
);
625 int m_descent
; // Descent for this object (if any)
628 wxRichTextObject
* m_parent
;
630 /// The range of this object (start position to end position)
631 wxRichTextRange m_range
;
640 wxTextAttrEx m_attributes
;
643 WX_DECLARE_EXPORTED_LIST( wxRichTextObject
, wxRichTextObjectList
);
646 * wxRichTextCompositeObject class declaration
647 * Objects of this class can contain other objects.
650 class WXDLLIMPEXP_ADV wxRichTextCompositeObject
: public wxRichTextObject
652 DECLARE_CLASS(wxRichTextCompositeObject
)
656 wxRichTextCompositeObject(wxRichTextObject
* parent
= NULL
);
657 ~wxRichTextCompositeObject();
661 /// Hit-testing: returns a flag indicating hit test details, plus
662 /// information about position
663 virtual int HitTest(wxDC
& dc
, const wxPoint
& pt
, long& textPosition
);
665 /// Finds the absolute position and row height for the given character position
666 virtual bool FindPosition(wxDC
& dc
, long index
, wxPoint
& pt
, int* height
, bool forceLineStart
);
669 virtual void CalculateRange(long start
, long& end
);
672 virtual bool DeleteRange(const wxRichTextRange
& range
);
674 /// Get any text in this object for the given range
675 virtual wxString
GetTextForRange(const wxRichTextRange
& range
) const;
677 /// Dump to output stream for debugging
678 virtual void Dump(wxTextOutputStream
& stream
);
683 wxRichTextObjectList
& GetChildren() { return m_children
; }
684 const wxRichTextObjectList
& GetChildren() const { return m_children
; }
686 /// Get the child count
687 size_t GetChildCount() const ;
689 /// Get the nth child
690 wxRichTextObject
* GetChild(size_t n
) const ;
692 /// Get/set dirty flag
693 virtual bool GetDirty() const { return m_dirty
; }
694 virtual void SetDirty(bool dirty
) { m_dirty
= dirty
; }
696 /// Is this composite?
697 virtual bool IsComposite() const { return true; }
699 /// Returns true if the buffer is empty
700 virtual bool IsEmpty() const { return GetChildCount() == 0; }
705 void Copy(const wxRichTextCompositeObject
& obj
);
707 /// Append a child, returning the position
708 size_t AppendChild(wxRichTextObject
* child
) ;
710 /// Insert the child in front of the given object, or at the beginning
711 bool InsertChild(wxRichTextObject
* child
, wxRichTextObject
* inFrontOf
) ;
714 bool RemoveChild(wxRichTextObject
* child
, bool deleteChild
= false) ;
716 /// Delete all children
717 bool DeleteChildren() ;
719 /// Recursively merge all pieces that can be merged.
723 wxRichTextObjectList m_children
;
727 * wxRichTextBox class declaration
728 * This defines a 2D space to lay out objects
731 class WXDLLIMPEXP_ADV wxRichTextBox
: public wxRichTextCompositeObject
733 DECLARE_DYNAMIC_CLASS(wxRichTextBox
)
737 wxRichTextBox(wxRichTextObject
* parent
= NULL
);
738 wxRichTextBox(const wxRichTextBox
& obj
): wxRichTextCompositeObject() { Copy(obj
); }
743 virtual bool Draw(wxDC
& dc
, const wxRichTextRange
& range
, const wxRichTextRange
& selectionRange
, const wxRect
& rect
, int descent
, int style
);
746 virtual bool Layout(wxDC
& dc
, const wxRect
& rect
, int style
);
748 /// Get/set the object size for the given range. Returns false if the range
749 /// is invalid for this object.
750 virtual bool GetRangeSize(const wxRichTextRange
& range
, wxSize
& size
, int& descent
, wxDC
& dc
, int flags
) const;
757 virtual wxRichTextObject
* Clone() const { return new wxRichTextBox(*this); }
760 void Copy(const wxRichTextBox
& obj
);
766 * wxRichTextParagraphBox class declaration
767 * This box knows how to lay out paragraphs.
770 class WXDLLIMPEXP_ADV wxRichTextParagraphLayoutBox
: public wxRichTextBox
772 DECLARE_DYNAMIC_CLASS(wxRichTextParagraphLayoutBox
)
776 wxRichTextParagraphLayoutBox(wxRichTextObject
* parent
= NULL
);
777 wxRichTextParagraphLayoutBox(const wxRichTextParagraphLayoutBox
& obj
):wxRichTextBox() { Init(); Copy(obj
); }
782 virtual bool Draw(wxDC
& dc
, const wxRichTextRange
& range
, const wxRichTextRange
& selectionRange
, const wxRect
& rect
, int descent
, int style
);
785 virtual bool Layout(wxDC
& dc
, const wxRect
& rect
, int style
);
787 /// Get/set the object size for the given range. Returns false if the range
788 /// is invalid for this object.
789 virtual bool GetRangeSize(const wxRichTextRange
& range
, wxSize
& size
, int& descent
, wxDC
& dc
, int flags
) const;
792 virtual bool DeleteRange(const wxRichTextRange
& range
);
794 /// Get any text in this object for the given range
795 virtual wxString
GetTextForRange(const wxRichTextRange
& range
) const;
799 /// Associate a control with the buffer, for operations that for example require refreshing the window.
800 void SetRichTextCtrl(wxRichTextCtrl
* ctrl
) { m_ctrl
= ctrl
; }
802 /// Get the associated control.
803 wxRichTextCtrl
* GetRichTextCtrl() const { return m_ctrl
; }
807 /// Initialize the object.
810 /// Clear all children
811 virtual void Clear();
813 /// Clear and initialize with one blank paragraph
814 virtual void Reset();
816 /// Convenience function to add a paragraph of text
817 virtual wxRichTextRange
AddParagraph(const wxString
& text
);
819 /// Convenience function to add an image
820 virtual wxRichTextRange
AddImage(const wxImage
& image
);
822 /// Adds multiple paragraphs, based on newlines.
823 virtual wxRichTextRange
AddParagraphs(const wxString
& text
);
825 /// Get the line at the given position. If caretPosition is true, the position is
826 /// a caret position, which is normally a smaller number.
827 virtual wxRichTextLine
* GetLineAtPosition(long pos
, bool caretPosition
= false) const;
829 /// Get the line at the given y pixel position, or the last line.
830 virtual wxRichTextLine
* GetLineAtYPosition(int y
) const;
832 /// Get the paragraph at the given character or caret position
833 virtual wxRichTextParagraph
* GetParagraphAtPosition(long pos
, bool caretPosition
= false) const;
835 /// Get the line size at the given position
836 virtual wxSize
GetLineSizeAtPosition(long pos
, bool caretPosition
= false) const;
838 /// Given a position, get the number of the visible line (potentially many to a paragraph),
839 /// starting from zero at the start of the buffer. We also have to pass a bool (startOfLine)
840 /// that indicates whether the caret is being shown at the end of the previous line or at the start
841 /// of the next, since the caret can be shown at 2 visible positions for the same underlying
843 virtual long GetVisibleLineNumber(long pos
, bool caretPosition
= false, bool startOfLine
= false) const;
845 /// Given a line number, get the corresponding wxRichTextLine object.
846 virtual wxRichTextLine
* GetLineForVisibleLineNumber(long lineNumber
) const;
848 /// Get the leaf object in a paragraph at this position.
849 /// Given a line number, get the corresponding wxRichTextLine object.
850 virtual wxRichTextObject
* GetLeafObjectAtPosition(long position
) const;
852 /// Get the paragraph by number
853 virtual wxRichTextParagraph
* GetParagraphAtLine(long paragraphNumber
) const;
855 /// Get the paragraph for a given line
856 virtual wxRichTextParagraph
* GetParagraphForLine(wxRichTextLine
* line
) const;
858 /// Get the length of the paragraph
859 virtual int GetParagraphLength(long paragraphNumber
) const;
861 /// Get the number of paragraphs
862 virtual int GetParagraphCount() const { return GetChildCount(); }
864 /// Get the number of visible lines
865 virtual int GetLineCount() const;
867 /// Get the text of the paragraph
868 virtual wxString
GetParagraphText(long paragraphNumber
) const;
870 /// Convert zero-based line column and paragraph number to a position.
871 virtual long XYToPosition(long x
, long y
) const;
873 /// Convert zero-based position to line column and paragraph number
874 virtual bool PositionToXY(long pos
, long* x
, long* y
) const;
876 /// Set text attributes: character and/or paragraph styles.
877 virtual bool SetStyle(const wxRichTextRange
& range
, const wxRichTextAttr
& style
, bool withUndo
= true);
878 virtual bool SetStyle(const wxRichTextRange
& range
, const wxTextAttrEx
& style
, bool withUndo
= true);
880 /// Get the text attributes for this position.
881 virtual bool GetStyle(long position
, wxTextAttrEx
& style
) const;
882 virtual bool GetStyle(long position
, wxRichTextAttr
& style
) const;
884 /// Test if this whole range has character attributes of the specified kind. If any
885 /// of the attributes are different within the range, the test fails. You
886 /// can use this to implement, for example, bold button updating. style must have
887 /// flags indicating which attributes are of interest.
888 virtual bool HasCharacterAttributes(const wxRichTextRange
& range
, const wxTextAttrEx
& style
) const;
889 virtual bool HasCharacterAttributes(const wxRichTextRange
& range
, const wxRichTextAttr
& style
) const;
891 /// Test if this whole range has paragraph attributes of the specified kind. If any
892 /// of the attributes are different within the range, the test fails. You
893 /// can use this to implement, for example, centering button updating. style must have
894 /// flags indicating which attributes are of interest.
895 virtual bool HasParagraphAttributes(const wxRichTextRange
& range
, const wxTextAttrEx
& style
) const;
896 virtual bool HasParagraphAttributes(const wxRichTextRange
& range
, const wxRichTextAttr
& style
) const;
899 virtual wxRichTextObject
* Clone() const { return new wxRichTextParagraphLayoutBox(*this); }
901 /// Insert fragment into this box at the given position. If partialParagraph is true,
902 /// it is assumed that the last (or only) paragraph is just a piece of data with no paragraph
904 virtual bool InsertFragment(long position
, wxRichTextFragment
& fragment
);
906 /// Make a copy of the fragment corresponding to the given range, putting it in 'fragment'.
907 virtual bool CopyFragment(const wxRichTextRange
& range
, wxRichTextFragment
& fragment
);
910 void Copy(const wxRichTextParagraphLayoutBox
& obj
);
913 virtual wxRichTextObject
* Clone() { return new wxRichTextParagraphLayoutBox(*this); }
916 virtual void UpdateRanges() { long end
; CalculateRange(0, end
); }
919 virtual wxString
GetText() const;
921 /// Set default style for new content. Setting it to a default attribute
922 /// makes new content take on the 'basic' style.
923 virtual bool SetDefaultStyle(const wxTextAttrEx
& style
);
925 /// Get default style
926 virtual const wxTextAttrEx
& GetDefaultStyle() const { return m_defaultAttributes
; }
928 /// Set basic (overall) style
929 virtual void SetBasicStyle(const wxTextAttrEx
& style
) { m_attributes
= style
; }
930 virtual void SetBasicStyle(const wxRichTextAttr
& style
) { style
.CopyTo(m_attributes
); }
932 /// Get basic (overall) style
933 virtual const wxTextAttrEx
& GetBasicStyle() const { return m_attributes
; }
936 wxRichTextCtrl
* m_ctrl
;
937 wxTextAttrEx m_defaultAttributes
;
941 * wxRichTextFragment class declaration
942 * This is a lind of paragraph layout box used for storing
943 * paragraphs for Undo/Redo, for example.
946 class WXDLLIMPEXP_ADV wxRichTextFragment
: public wxRichTextParagraphLayoutBox
948 DECLARE_DYNAMIC_CLASS(wxRichTextFragment
)
952 wxRichTextFragment() { Init(); }
953 wxRichTextFragment(const wxRichTextFragment
& obj
):wxRichTextParagraphLayoutBox() { Init(); Copy(obj
); }
957 /// Get/set whether the last paragraph is partial or complete
958 void SetPartialParagraph(bool partialPara
) { m_partialParagraph
= partialPara
; }
959 bool GetPartialParagraph() const { return m_partialParagraph
; }
969 void Copy(const wxRichTextFragment
& obj
);
972 virtual wxRichTextObject
* Clone() { return new wxRichTextFragment(*this); }
976 // Is the last paragraph partial or complete?
977 bool m_partialParagraph
;
981 * wxRichTextLine class declaration
982 * This object represents a line in a paragraph, and stores
983 * offsets from the start of the paragraph representing the
984 * start and end positions of the line.
987 class WXDLLIMPEXP_ADV wxRichTextLine
992 wxRichTextLine(wxRichTextParagraph
* parent
);
993 wxRichTextLine(const wxRichTextLine
& obj
) { Init(); Copy(obj
); }
994 virtual ~wxRichTextLine() {}
1001 void SetRange(const wxRichTextRange
& range
) { m_range
= range
; }
1002 void SetRange(long from
, long to
) { m_range
= wxRichTextRange(from
, to
); }
1004 /// Get the parent paragraph
1005 wxRichTextParagraph
* GetParent() { return m_parent
; }
1008 const wxRichTextRange
& GetRange() const { return m_range
; }
1009 wxRichTextRange
& GetRange() { return m_range
; }
1011 /// Get/set the line size as calculated by Layout.
1012 virtual wxSize
GetSize() const { return m_size
; }
1013 virtual void SetSize(const wxSize
& sz
) { m_size
= sz
; }
1015 /// Get/set the object position relative to the parent
1016 virtual wxPoint
GetPosition() const { return m_pos
; }
1017 virtual void SetPosition(const wxPoint
& pos
) { m_pos
= pos
; }
1019 /// Get the absolute object position
1020 virtual wxPoint
GetAbsolutePosition() const;
1022 /// Get the rectangle enclosing the line
1023 virtual wxRect
GetRect() const { return wxRect(GetAbsolutePosition(), GetSize()); }
1025 /// Set/get stored descent
1026 void SetDescent(int descent
) { m_descent
= descent
; }
1027 int GetDescent() const { return m_descent
; }
1035 void Copy(const wxRichTextLine
& obj
);
1038 virtual wxRichTextLine
* Clone() const { return new wxRichTextLine(*this); }
1042 /// The range of the line (start position to end position)
1043 wxRichTextRange m_range
;
1045 /// Size and position measured relative to top of paragraph
1049 /// Maximum descent for this line (location of text baseline)
1052 // The parent object
1053 wxRichTextParagraph
* m_parent
;
1056 WX_DECLARE_EXPORTED_LIST( wxRichTextLine
, wxRichTextLineList
);
1059 * wxRichTextParagraph class declaration
1060 * This object represents a single paragraph (or in a straight text editor, a line).
1063 class WXDLLIMPEXP_ADV wxRichTextParagraph
: public wxRichTextBox
1065 DECLARE_DYNAMIC_CLASS(wxRichTextParagraph
)
1069 wxRichTextParagraph(wxRichTextObject
* parent
= NULL
, wxTextAttrEx
* style
= NULL
);
1070 wxRichTextParagraph(const wxString
& text
, wxRichTextObject
* parent
= NULL
, wxTextAttrEx
* style
= NULL
);
1071 ~wxRichTextParagraph();
1072 wxRichTextParagraph(const wxRichTextParagraph
& obj
):wxRichTextBox() { Copy(obj
); }
1077 virtual bool Draw(wxDC
& dc
, const wxRichTextRange
& range
, const wxRichTextRange
& selectionRange
, const wxRect
& rect
, int descent
, int style
);
1079 /// Lay the item out
1080 virtual bool Layout(wxDC
& dc
, const wxRect
& rect
, int style
);
1082 /// Get/set the object size for the given range. Returns false if the range
1083 /// is invalid for this object.
1084 virtual bool GetRangeSize(const wxRichTextRange
& range
, wxSize
& size
, int& descent
, wxDC
& dc
, int flags
) const;
1086 /// Finds the absolute position and row height for the given character position
1087 virtual bool FindPosition(wxDC
& dc
, long index
, wxPoint
& pt
, int* height
, bool forceLineStart
);
1089 /// Hit-testing: returns a flag indicating hit test details, plus
1090 /// information about position
1091 virtual int HitTest(wxDC
& dc
, const wxPoint
& pt
, long& textPosition
);
1094 virtual void CalculateRange(long start
, long& end
);
1098 /// Get the cached lines
1099 wxRichTextLineList
& GetLines() { return m_cachedLines
; }
1104 void Copy(const wxRichTextParagraph
& obj
);
1107 virtual wxRichTextObject
* Clone() const { return new wxRichTextParagraph(*this); }
1109 /// Clear the cached lines
1114 /// Apply paragraph styles such as centering to the wrapped lines
1115 virtual void ApplyParagraphStyle(const wxRect
& rect
);
1117 /// Insert text at the given position
1118 virtual bool InsertText(long pos
, const wxString
& text
);
1120 /// Split an object at this position if necessary, and return
1121 /// the previous object, or NULL if inserting at beginning.
1122 virtual wxRichTextObject
* SplitAt(long pos
, wxRichTextObject
** previousObject
= NULL
);
1124 /// Move content to a list from this point
1125 virtual void MoveToList(wxRichTextObject
* obj
, wxList
& list
);
1127 /// Add content back from list
1128 virtual void MoveFromList(wxList
& list
);
1130 /// Get the plain text searching from the start or end of the range.
1131 /// The resulting string may be shorter than the range given.
1132 bool GetContiguousPlainText(wxString
& text
, const wxRichTextRange
& range
, bool fromStart
= true);
1134 /// Find a suitable wrap position. wrapPosition is the last position in the line to the left
1136 bool FindWrapPosition(const wxRichTextRange
& range
, wxDC
& dc
, int availableSpace
, long& wrapPosition
);
1138 /// Find the object at the given position
1139 wxRichTextObject
* FindObjectAtPosition(long position
);
1141 /// Get the bullet text for this paragraph.
1142 wxString
GetBulletText();
1145 /// The lines that make up the wrapped paragraph
1146 wxRichTextLineList m_cachedLines
;
1150 * wxRichTextPlainText class declaration
1151 * This object represents a single piece of text.
1154 class WXDLLIMPEXP_ADV wxRichTextPlainText
: public wxRichTextObject
1156 DECLARE_DYNAMIC_CLASS(wxRichTextPlainText
)
1160 wxRichTextPlainText(const wxString
& text
= wxEmptyString
, wxRichTextObject
* parent
= NULL
, wxTextAttrEx
* style
= NULL
);
1161 wxRichTextPlainText(const wxRichTextPlainText
& obj
):wxRichTextObject() { Copy(obj
); }
1166 virtual bool Draw(wxDC
& dc
, const wxRichTextRange
& range
, const wxRichTextRange
& selectionRange
, const wxRect
& rect
, int descent
, int style
);
1168 /// Lay the item out
1169 virtual bool Layout(wxDC
& dc
, const wxRect
& rect
, int style
);
1171 /// Get/set the object size for the given range. Returns false if the range
1172 /// is invalid for this object.
1173 virtual bool GetRangeSize(const wxRichTextRange
& range
, wxSize
& size
, int& descent
, wxDC
& dc
, int flags
) const;
1175 /// Get any text in this object for the given range
1176 virtual wxString
GetTextForRange(const wxRichTextRange
& range
) const;
1178 /// Do a split, returning an object containing the second part, and setting
1179 /// the first part in 'this'.
1180 virtual wxRichTextObject
* DoSplit(long pos
);
1183 virtual void CalculateRange(long start
, long& end
);
1186 virtual bool DeleteRange(const wxRichTextRange
& range
);
1188 /// Returns true if the object is empty
1189 virtual bool IsEmpty() const { return m_text
.IsEmpty(); }
1191 /// Returns true if this object can merge itself with the given one.
1192 virtual bool CanMerge(wxRichTextObject
* object
) const;
1194 /// Returns true if this object merged itself with the given one.
1195 /// The calling code will then delete the given object.
1196 virtual bool Merge(wxRichTextObject
* object
);
1198 /// Dump to output stream for debugging
1199 virtual void Dump(wxTextOutputStream
& stream
);
1204 const wxString
& GetText() const { return m_text
; }
1207 void SetText(const wxString
& text
) { m_text
= text
; }
1212 void Copy(const wxRichTextPlainText
& obj
);
1215 virtual wxRichTextObject
* Clone() const { return new wxRichTextPlainText(*this); }
1222 * wxRichTextImageBlock stores information about an image, in binary in-memory form
1225 class WXDLLIMPEXP_BASE wxDataInputStream
;
1226 class WXDLLIMPEXP_BASE wxDataOutputStream
;
1228 class WXDLLIMPEXP_ADV wxRichTextImageBlock
: public wxObject
1231 wxRichTextImageBlock();
1232 wxRichTextImageBlock(const wxRichTextImageBlock
& block
);
1233 ~wxRichTextImageBlock();
1238 // Load the original image into a memory block.
1239 // If the image is not a JPEG, we must convert it into a JPEG
1240 // to conserve space.
1241 // If it's not a JPEG we can make use of 'image', already scaled, so we don't have to
1242 // load the image a 2nd time.
1243 virtual bool MakeImageBlock(const wxString
& filename
, int imageType
, wxImage
& image
, bool convertToJPEG
= TRUE
);
1245 // Make an image block from the wxImage in the given
1247 virtual bool MakeImageBlock(wxImage
& image
, int imageType
, int quality
= 80);
1250 bool Write(const wxString
& filename
);
1252 // Write data in hex to a stream
1253 bool WriteHex(wxOutputStream
& stream
);
1255 // Read data in hex from a stream
1256 bool ReadHex(wxInputStream
& stream
, int length
, int imageType
);
1258 // Copy from 'block'
1259 void Copy(const wxRichTextImageBlock
& block
);
1261 // Load a wxImage from the block
1262 bool Load(wxImage
& image
);
1265 void operator=(const wxRichTextImageBlock
& block
);
1269 unsigned char* GetData() const { return m_data
; }
1270 size_t GetDataSize() const { return m_dataSize
; }
1271 int GetImageType() const { return m_imageType
; }
1273 void SetData(unsigned char* image
) { m_data
= image
; }
1274 void SetDataSize(size_t size
) { m_dataSize
= size
; }
1275 void SetImageType(int imageType
) { m_imageType
= imageType
; }
1277 bool Ok() const { return GetData() != NULL
; }
1281 /// Allocate and read from stream as a block of memory
1282 static unsigned char* ReadBlock(wxInputStream
& stream
, size_t size
);
1283 static unsigned char* ReadBlock(const wxString
& filename
, size_t size
);
1285 // Write memory block to stream
1286 static bool WriteBlock(wxOutputStream
& stream
, unsigned char* block
, size_t size
);
1288 // Write memory block to file
1289 static bool WriteBlock(const wxString
& filename
, unsigned char* block
, size_t size
);
1292 // Size in bytes of the image stored.
1293 // This is in the raw, original form such as a JPEG file.
1294 unsigned char* m_data
;
1296 int m_imageType
; // wxWin type id
1301 * wxRichTextImage class declaration
1302 * This object represents an image.
1305 class WXDLLIMPEXP_ADV wxRichTextImage
: public wxRichTextObject
1307 DECLARE_DYNAMIC_CLASS(wxRichTextImage
)
1311 wxRichTextImage(wxRichTextObject
* parent
= NULL
):wxRichTextObject(parent
) { }
1312 wxRichTextImage(const wxImage
& image
, wxRichTextObject
* parent
= NULL
);
1313 wxRichTextImage(const wxRichTextImageBlock
& imageBlock
, wxRichTextObject
* parent
= NULL
);
1314 wxRichTextImage(const wxRichTextImage
& obj
):wxRichTextObject() { Copy(obj
); }
1319 virtual bool Draw(wxDC
& dc
, const wxRichTextRange
& range
, const wxRichTextRange
& selectionRange
, const wxRect
& rect
, int descent
, int style
);
1321 /// Lay the item out
1322 virtual bool Layout(wxDC
& dc
, const wxRect
& rect
, int style
);
1324 /// Get the object size for the given range. Returns false if the range
1325 /// is invalid for this object.
1326 virtual bool GetRangeSize(const wxRichTextRange
& range
, wxSize
& size
, int& descent
, wxDC
& dc
, int flags
) const;
1328 /// Returns true if the object is empty
1329 virtual bool IsEmpty() const { return !m_image
.Ok(); }
1334 const wxImage
& GetImage() const { return m_image
; }
1337 void SetImage(const wxImage
& image
) { m_image
= image
; }
1339 /// Get the image block containing the raw data
1340 wxRichTextImageBlock
& GetImageBlock() { return m_imageBlock
; }
1345 void Copy(const wxRichTextImage
& obj
);
1348 virtual wxRichTextObject
* Clone() const { return new wxRichTextImage(*this); }
1350 /// Load wxImage from the block
1351 virtual bool LoadFromBlock();
1353 /// Make block from the wxImage
1354 virtual bool MakeBlock();
1357 // TODO: reduce the multiple representations of data
1360 wxRichTextImageBlock m_imageBlock
;
1365 * wxRichTextBuffer class declaration
1366 * This is a kind of box, used to represent the whole buffer
1369 class WXDLLIMPEXP_ADV wxRichTextCommand
;
1370 class WXDLLIMPEXP_ADV wxRichTextAction
;
1372 class WXDLLIMPEXP_ADV wxRichTextBuffer
: public wxRichTextParagraphLayoutBox
1374 DECLARE_DYNAMIC_CLASS(wxRichTextBuffer
)
1378 wxRichTextBuffer() { Init(); }
1379 wxRichTextBuffer(const wxRichTextBuffer
& obj
):wxRichTextParagraphLayoutBox() { Init(); Copy(obj
); }
1380 ~wxRichTextBuffer() ;
1384 /// Gets the command processor
1385 wxCommandProcessor
* GetCommandProcessor() const { return m_commandProcessor
; }
1387 /// Set style sheet, if any.
1388 void SetStyleSheet(wxRichTextStyleSheet
* styleSheet
) { m_styleSheet
= styleSheet
; }
1389 wxRichTextStyleSheet
* GetStyleSheet() const { return m_styleSheet
; }
1396 /// Clears the buffer and resets the command processor
1397 virtual void Clear();
1399 /// The same as Clear, and adds an empty paragraph.
1400 virtual void Reset();
1403 virtual bool LoadFile(const wxString
& filename
, int type
= wxRICHTEXT_TYPE_ANY
);
1406 virtual bool SaveFile(const wxString
& filename
, int type
= wxRICHTEXT_TYPE_ANY
);
1408 /// Load from a stream
1409 virtual bool LoadFile(wxInputStream
& stream
, int type
= wxRICHTEXT_TYPE_ANY
);
1411 /// Save to a stream
1412 virtual bool SaveFile(wxOutputStream
& stream
, int type
= wxRICHTEXT_TYPE_ANY
);
1414 /// Convenience function to add a paragraph of text
1415 virtual wxRichTextRange
AddParagraph(const wxString
& text
) { Modify(); return wxRichTextParagraphLayoutBox::AddParagraph(text
); }
1417 /// Begin collapsing undo/redo commands. Note that this may not work properly
1418 /// if combining commands that delete or insert content, changing ranges for
1419 /// subsequent actions.
1420 virtual bool BeginBatchUndo(const wxString
& cmdName
);
1422 /// End collapsing undo/redo commands
1423 virtual bool EndBatchUndo();
1425 /// Collapsing commands?
1426 virtual bool BatchingUndo() const { return m_batchedCommandDepth
> 0; }
1428 /// Submit immediately, or delay according to whether collapsing is on
1429 virtual bool SubmitAction(wxRichTextAction
* action
);
1431 /// Get collapsed command
1432 virtual wxRichTextCommand
* GetBatchedCommand() const { return m_batchedCommand
; }
1434 /// Begin suppressing undo/redo commands. The way undo is suppressed may be implemented
1435 /// differently by each command. If not dealt with by a command implementation, then
1436 /// it will be implemented automatically by not storing the command in the undo history
1437 /// when the action is submitted to the command processor.
1438 virtual bool BeginSuppressUndo();
1440 /// End suppressing undo/redo commands.
1441 virtual bool EndSuppressUndo();
1443 /// Collapsing commands?
1444 virtual bool SuppressingUndo() const { return m_suppressUndo
> 0; }
1446 /// Copy the range to the clipboard
1447 virtual bool CopyToClipboard(const wxRichTextRange
& range
);
1449 /// Paste the clipboard content to the buffer
1450 virtual bool PasteFromClipboard(long position
);
1452 /// Can we paste from the clipboard?
1453 virtual bool CanPasteFromClipboard() const;
1455 /// Begin using a style
1456 virtual bool BeginStyle(const wxTextAttrEx
& style
);
1459 virtual bool EndStyle();
1462 virtual bool EndAllStyles();
1464 /// Clear the style stack
1465 virtual void ClearStyleStack();
1467 /// Get the size of the style stack, for example to check correct nesting
1468 virtual int GetStyleStackSize() const { return m_attributeStack
.GetCount(); }
1470 /// Begin using bold
1474 bool EndBold() { return EndStyle(); }
1476 /// Begin using italic
1479 /// End using italic
1480 bool EndItalic() { return EndStyle(); }
1482 /// Begin using underline
1483 bool BeginUnderline();
1485 /// End using underline
1486 bool EndUnderline() { return EndStyle(); }
1488 /// Begin using point size
1489 bool BeginFontSize(int pointSize
);
1491 /// End using point size
1492 bool EndFontSize() { return EndStyle(); }
1494 /// Begin using this font
1495 bool BeginFont(const wxFont
& font
);
1497 /// End using a font
1498 bool EndFont() { return EndStyle(); }
1500 /// Begin using this colour
1501 bool BeginTextColour(const wxColour
& colour
);
1503 /// End using a colour
1504 bool EndTextColour() { return EndStyle(); }
1506 /// Begin using alignment
1507 bool BeginAlignment(wxTextAttrAlignment alignment
);
1510 bool EndAlignment() { return EndStyle(); }
1512 /// Begin left indent
1513 bool BeginLeftIndent(int leftIndent
, int leftSubIndent
= 0);
1516 bool EndLeftIndent() { return EndStyle(); }
1518 /// Begin right indent
1519 bool BeginRightIndent(int rightIndent
);
1521 /// End right indent
1522 bool EndRightIndent() { return EndStyle(); }
1524 /// Begin paragraph spacing
1525 bool BeginParagraphSpacing(int before
, int after
);
1527 /// End paragraph spacing
1528 bool EndParagraphSpacing() { return EndStyle(); }
1530 /// Begin line spacing
1531 bool BeginLineSpacing(int lineSpacing
);
1533 /// End line spacing
1534 bool EndLineSpacing() { return EndStyle(); }
1536 /// Begin numbered bullet
1537 bool BeginNumberedBullet(int bulletNumber
, int leftIndent
, int leftSubIndent
, int bulletStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
);
1539 /// End numbered bullet
1540 bool EndNumberedBullet() { return EndStyle(); }
1542 /// Begin symbol bullet
1543 bool BeginSymbolBullet(wxChar symbol
, int leftIndent
, int leftSubIndent
, int bulletStyle
= wxTEXT_ATTR_BULLET_STYLE_SYMBOL
);
1545 /// End symbol bullet
1546 bool EndSymbolBullet() { return EndStyle(); }
1548 /// Begin named character style
1549 bool BeginCharacterStyle(const wxString
& characterStyle
);
1551 /// End named character style
1552 bool EndCharacterStyle() { return EndStyle(); }
1554 /// Begin named paragraph style
1555 bool BeginParagraphStyle(const wxString
& paragraphStyle
);
1557 /// End named character style
1558 bool EndParagraphStyle() { return EndStyle(); }
1563 void Copy(const wxRichTextBuffer
& obj
) { wxRichTextBox::Copy(obj
); }
1566 virtual wxRichTextObject
* Clone() const { return new wxRichTextBuffer(*this); }
1568 /// Submit command to insert the given text
1569 bool InsertTextWithUndo(long pos
, const wxString
& text
, wxRichTextCtrl
* ctrl
);
1571 /// Submit command to insert a newline
1572 bool InsertNewlineWithUndo(long pos
, wxRichTextCtrl
* ctrl
);
1574 /// Submit command to insert the given image
1575 bool InsertImageWithUndo(long pos
, const wxRichTextImageBlock
& imageBlock
, wxRichTextCtrl
* ctrl
);
1577 /// Submit command to delete this range
1578 bool DeleteRangeWithUndo(const wxRichTextRange
& range
, long initialCaretPosition
, long newCaretPositon
, wxRichTextCtrl
* ctrl
);
1581 void Modify(bool modify
= true) { m_modified
= modify
; }
1582 bool IsModified() const { return m_modified
; }
1584 /// Dumps contents of buffer for debugging purposes
1585 virtual void Dump();
1586 virtual void Dump(wxTextOutputStream
& stream
) { wxRichTextParagraphLayoutBox::Dump(stream
); }
1588 /// Returns the file handlers
1589 static wxList
& GetHandlers() { return sm_handlers
; }
1591 /// Adds a handler to the end
1592 static void AddHandler(wxRichTextFileHandler
*handler
);
1594 /// Inserts a handler at the front
1595 static void InsertHandler(wxRichTextFileHandler
*handler
);
1597 /// Removes a handler
1598 static bool RemoveHandler(const wxString
& name
);
1600 /// Finds a handler by name
1601 static wxRichTextFileHandler
*FindHandler(const wxString
& name
);
1603 /// Finds a handler by extension and type
1604 static wxRichTextFileHandler
*FindHandler(const wxString
& extension
, int imageType
);
1606 /// Finds a handler by filename or, if supplied, type
1607 static wxRichTextFileHandler
*FindHandlerFilenameOrType(const wxString
& filename
, int imageType
);
1609 /// Finds a handler by type
1610 static wxRichTextFileHandler
*FindHandler(int imageType
);
1612 /// Gets a wildcard incorporating all visible handlers
1613 static wxString
GetExtWildcard(bool combine
= false, bool save
= false);
1615 /// Clean up handlers
1616 static void CleanUpHandlers();
1618 /// Initialise the standard handlers
1619 static void InitStandardHandlers();
1623 /// Command processor
1624 wxCommandProcessor
* m_commandProcessor
;
1626 /// Has been modified?
1629 /// Collapsed command stack
1630 int m_batchedCommandDepth
;
1632 /// Name for collapsed command
1633 wxString m_batchedCommandsName
;
1635 /// Current collapsed command accumulating actions
1636 wxRichTextCommand
* m_batchedCommand
;
1638 /// Whether to suppress undo
1641 /// Style sheet, if any
1642 wxRichTextStyleSheet
* m_styleSheet
;
1644 /// Stack of attributes for convenience functions
1645 wxList m_attributeStack
;
1648 static wxList sm_handlers
;
1652 * The command identifiers
1656 enum wxRichTextCommandId
1660 wxRICHTEXT_CHANGE_STYLE
1664 * Command classes for undo/redo
1668 class WXDLLIMPEXP_ADV wxRichTextAction
;
1669 class WXDLLIMPEXP_ADV wxRichTextCommand
: public wxCommand
1672 // Ctor for one action
1673 wxRichTextCommand(const wxString
& name
, wxRichTextCommandId id
, wxRichTextBuffer
* buffer
,
1674 wxRichTextCtrl
* ctrl
, bool ignoreFirstTime
= FALSE
);
1676 // Ctor for multiple actions
1677 wxRichTextCommand(const wxString
& name
);
1679 ~wxRichTextCommand();
1684 void AddAction(wxRichTextAction
* action
);
1685 void ClearActions();
1687 wxList
& GetActions() { return m_actions
; }
1695 * wxRichTextAction class declaration
1696 * There can be more than one action in a command.
1699 class WXDLLIMPEXP_ADV wxRichTextAction
: public wxObject
1702 wxRichTextAction(wxRichTextCommand
* cmd
, const wxString
& name
, wxRichTextCommandId id
, wxRichTextBuffer
* buffer
,
1703 wxRichTextCtrl
* ctrl
, bool ignoreFirstTime
= FALSE
);
1705 ~wxRichTextAction();
1710 /// Update the control appearance
1711 void UpdateAppearance(long caretPosition
, bool sendUpdateEvent
= false);
1713 /// Replace the buffer paragraphs with the given fragment.
1714 void ApplyParagraphs(const wxRichTextFragment
& fragment
);
1716 /// Get the fragments
1717 wxRichTextFragment
& GetNewParagraphs() { return m_newParagraphs
; }
1718 wxRichTextFragment
& GetOldParagraphs() { return m_oldParagraphs
; }
1720 /// Set/get the position used for e.g. insertion
1721 void SetPosition(long pos
) { m_position
= pos
; }
1722 long GetPosition() const { return m_position
; }
1724 /// Set/get the range for e.g. deletion
1725 void SetRange(const wxRichTextRange
& range
) { m_range
= range
; }
1726 const wxRichTextRange
& GetRange() const { return m_range
; }
1729 const wxString
& GetName() const { return m_name
; }
1736 wxRichTextBuffer
* m_buffer
;
1739 wxRichTextCtrl
* m_ctrl
;
1741 // Stores the new paragraphs
1742 wxRichTextFragment m_newParagraphs
;
1744 // Stores the old paragraphs
1745 wxRichTextFragment m_oldParagraphs
;
1747 // The affected range
1748 wxRichTextRange m_range
;
1750 // The insertion point for this command
1753 // Ignore 1st 'Do' operation because we already did it
1756 // The command identifier
1757 wxRichTextCommandId m_cmdId
;
1761 * wxRichTextFileHandler
1762 * Base class for file handlers
1765 class WXDLLIMPEXP_ADV wxRichTextFileHandler
: public wxObject
1767 DECLARE_CLASS(wxRichTextFileHandler
)
1769 wxRichTextFileHandler(const wxString
& name
= wxEmptyString
, const wxString
& ext
= wxEmptyString
, int type
= 0)
1770 : m_name(name
), m_extension(ext
), m_type(type
), m_visible(true)
1774 virtual bool LoadFile(wxRichTextBuffer
*buffer
, wxInputStream
& stream
) = 0;
1775 virtual bool SaveFile(wxRichTextBuffer
*buffer
, wxOutputStream
& stream
) = 0;
1778 virtual bool LoadFile(wxRichTextBuffer
*buffer
, const wxString
& filename
);
1779 virtual bool SaveFile(wxRichTextBuffer
*buffer
, const wxString
& filename
);
1781 /// Can we handle this filename (if using files)? By default, checks the extension.
1782 virtual bool CanHandle(const wxString
& filename
) const;
1784 /// Can we save using this handler?
1785 virtual bool CanSave() const { return false; }
1787 /// Can we load using this handler?
1788 virtual bool CanLoad() const { return false; }
1790 /// Should this handler be visible to the user?
1791 virtual bool IsVisible() const { return m_visible
; }
1792 virtual void SetVisible(bool visible
) { m_visible
= visible
; }
1794 void SetName(const wxString
& name
) { m_name
= name
; }
1795 wxString
GetName() const { return m_name
; }
1797 void SetExtension(const wxString
& ext
) { m_extension
= ext
; }
1798 wxString
GetExtension() const { return m_extension
; }
1800 void SetType(int type
) { m_type
= type
; }
1801 int GetType() const { return m_type
; }
1806 wxString m_extension
;
1812 * wxRichTextPlainTextHandler
1813 * Plain text handler
1816 class WXDLLIMPEXP_ADV wxRichTextPlainTextHandler
: public wxRichTextFileHandler
1818 DECLARE_CLASS(wxRichTextPlainTextHandler
)
1820 wxRichTextPlainTextHandler(const wxString
& name
= wxT("Text"), const wxString
& ext
= wxT("txt"), int type
= wxRICHTEXT_TYPE_TEXT
)
1821 : wxRichTextFileHandler(name
, ext
, type
)
1825 virtual bool LoadFile(wxRichTextBuffer
*buffer
, wxInputStream
& stream
);
1826 virtual bool SaveFile(wxRichTextBuffer
*buffer
, wxOutputStream
& stream
);
1829 /// Can we save using this handler?
1830 virtual bool CanSave() const { return true; }
1832 /// Can we load using this handler?
1833 virtual bool CanLoad() const { return true; }
1844 inline bool wxRichTextHasStyle(int flags
, int style
)
1846 return ((flags
& style
) == style
);
1849 /// Compare two attribute objects
1850 bool wxTextAttrEq(const wxTextAttrEx
& attr1
, const wxTextAttrEx
& attr2
);
1851 bool wxTextAttrEq(const wxTextAttr
& attr1
, const wxRichTextAttr
& attr2
);
1853 /// Compare two attribute objects, but take into account the flags
1854 /// specifying attributes of interest.
1855 bool wxTextAttrEqPartial(const wxTextAttrEx
& attr1
, const wxTextAttrEx
& attr2
, int flags
);
1856 bool wxTextAttrEqPartial(const wxTextAttrEx
& attr1
, const wxRichTextAttr
& attr2
, int flags
);
1858 /// Apply one style to another
1859 bool wxRichTextApplyStyle(wxTextAttrEx
& destStyle
, const wxTextAttrEx
& style
);
1860 bool wxRichTextApplyStyle(wxRichTextAttr
& destStyle
, const wxTextAttrEx
& style
);
1861 bool wxRichTextApplyStyle(wxTextAttrEx
& destStyle
, const wxRichTextAttr
& style
);
1867 // _WX_RICHTEXTBUFFER_H_