]> git.saurik.com Git - wxWidgets.git/blob - include/wx/richtext/richtextbuffer.h
6f79ca90d3258612095245558fd400246559f435
[wxWidgets.git] / include / wx / richtext / richtextbuffer.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/richtext/richtextbuffer.h
3 // Purpose: Buffer for wxRichTextCtrl
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 2005-09-30
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _WX_RICHTEXTBUFFER_H_
13 #define _WX_RICHTEXTBUFFER_H_
14
15 /*
16
17 Data structures
18 ===============
19
20 Data is represented by a hierarchy of objects, all derived from
21 wxRichTextObject.
22
23 The top of the hierarchy is the buffer, a kind of wxRichTextParagraphLayoutBox.
24 These boxes will allow flexible placement of text boxes on a page, but
25 for now there is a single box representing the document, and this box is
26 a wxRichTextParagraphLayoutBox which contains further wxRichTextParagraph
27 objects, each of which can include text and images.
28
29 Each object maintains a range (start and end position) measured
30 from the start of the main parent box.
31 A paragraph object knows its range, and a text fragment knows its range
32 too. So, a character or image in a page has a position relative to the
33 start of the document, and a character in an embedded text box has
34 a position relative to that text box. For now, we will not be dealing with
35 embedded objects but it's something to bear in mind for later.
36
37 Note that internally, a range (5,5) represents a range of one character.
38 In the public wx[Rich]TextCtrl API, this would be passed to e.g. SetSelection
39 as (5,6). A paragraph with one character might have an internal range of (0, 1)
40 since the end of the paragraph takes up one position.
41
42 Layout
43 ======
44
45 When Layout is called on an object, it is given a size which the object
46 must limit itself to, or one or more flexible directions (vertical
47 or horizontal). So for example a centered paragraph is given the page
48 width to play with (minus any margins), but can extend indefinitely
49 in the vertical direction. The implementation of Layout can then
50 cache the calculated size and position within the parent.
51
52 */
53
54 /*!
55 * Includes
56 */
57
58 #include "wx/defs.h"
59
60 #if wxUSE_RICHTEXT
61
62 #include "wx/list.h"
63 #include "wx/textctrl.h"
64 #include "wx/bitmap.h"
65 #include "wx/image.h"
66 #include "wx/cmdproc.h"
67 #include "wx/txtstrm.h"
68 #include "wx/variant.h"
69
70 #if wxUSE_DATAOBJ
71 #include "wx/dataobj.h"
72 #endif
73
74 // Compatibility
75 //#define wxRichTextAttr wxTextAttr
76 #define wxTextAttrEx wxTextAttr
77
78 // Setting wxRICHTEXT_USE_OWN_CARET to 1 implements a
79 // caret reliably without using wxClientDC in case there
80 // are platform-specific problems with the generic caret.
81 #if defined(__WXGTK__) || defined(__WXMAC__)
82 #define wxRICHTEXT_USE_OWN_CARET 1
83 #else
84 #define wxRICHTEXT_USE_OWN_CARET 0
85 #endif
86
87 // Switch off for binary compatibility, on for faster drawing
88 // Note: this seems to be buggy (overzealous use of extents) so
89 // don't use for now
90 #define wxRICHTEXT_USE_OPTIMIZED_LINE_DRAWING 0
91
92 // The following two symbols determine whether an output implementation
93 // is present. To switch the relevant one on, set wxRICHTEXT_USE_XMLDOCUMENT_OUTPUT in
94 // richtextxml.cpp. By default, the faster direct output implementation is used.
95
96 // Include the wxXmlDocument implementation for output
97 #define wxRICHTEXT_HAVE_XMLDOCUMENT_OUTPUT 1
98
99 // Include the faster, direct implementation for output
100 #define wxRICHTEXT_HAVE_DIRECT_OUTPUT 1
101
102 /*!
103 * Special characters
104 */
105
106 extern WXDLLIMPEXP_RICHTEXT const wxChar wxRichTextLineBreakChar;
107
108 /*!
109 * File types in wxRichText context.
110 */
111 enum wxRichTextFileType
112 {
113 wxRICHTEXT_TYPE_ANY = 0,
114 wxRICHTEXT_TYPE_TEXT,
115 wxRICHTEXT_TYPE_XML,
116 wxRICHTEXT_TYPE_HTML,
117 wxRICHTEXT_TYPE_RTF,
118 wxRICHTEXT_TYPE_PDF
119 };
120
121 /*!
122 * Forward declarations
123 */
124
125 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextCtrl;
126 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextObject;
127 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextImage;
128 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextCacheObject;
129 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextObjectList;
130 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextLine;
131 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextParagraph;
132 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextFileHandler;
133 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextStyleSheet;
134 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextListStyleDefinition;
135 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextEvent;
136 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextRenderer;
137 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextBuffer;
138 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextXMLHandler;
139 class WXDLLIMPEXP_FWD_XML wxXmlNode;
140 class wxRichTextFloatCollector;
141
142 /*!
143 * Flags determining the available space, passed to Layout
144 */
145
146 #define wxRICHTEXT_FIXED_WIDTH 0x01
147 #define wxRICHTEXT_FIXED_HEIGHT 0x02
148 #define wxRICHTEXT_VARIABLE_WIDTH 0x04
149 #define wxRICHTEXT_VARIABLE_HEIGHT 0x08
150
151 // Only lay out the part of the buffer that lies within
152 // the rect passed to Layout.
153 #define wxRICHTEXT_LAYOUT_SPECIFIED_RECT 0x10
154
155 /*!
156 * Flags to pass to Draw
157 */
158
159 // Ignore paragraph cache optimization, e.g. for printing purposes
160 // where one line may be drawn higher (on the next page) compared
161 // with the previous line
162 #define wxRICHTEXT_DRAW_IGNORE_CACHE 0x01
163
164 /*!
165 * Flags returned from hit-testing
166 */
167 enum wxRichTextHitTestFlags
168 {
169 // The point was not on this object
170 wxRICHTEXT_HITTEST_NONE = 0x01,
171
172 // The point was before the position returned from HitTest
173 wxRICHTEXT_HITTEST_BEFORE = 0x02,
174
175 // The point was after the position returned from HitTest
176 wxRICHTEXT_HITTEST_AFTER = 0x04,
177
178 // The point was on the position returned from HitTest
179 wxRICHTEXT_HITTEST_ON = 0x08,
180
181 // The point was on space outside content
182 wxRICHTEXT_HITTEST_OUTSIDE = 0x10
183 };
184
185 /*!
186 * Flags for GetRangeSize
187 */
188
189 #define wxRICHTEXT_FORMATTED 0x01
190 #define wxRICHTEXT_UNFORMATTED 0x02
191 #define wxRICHTEXT_CACHE_SIZE 0x04
192 #define wxRICHTEXT_HEIGHT_ONLY 0x08
193
194 /*!
195 * Flags for SetStyle/SetListStyle
196 */
197
198 #define wxRICHTEXT_SETSTYLE_NONE 0x00
199
200 // Specifies that this operation should be undoable
201 #define wxRICHTEXT_SETSTYLE_WITH_UNDO 0x01
202
203 // Specifies that the style should not be applied if the
204 // combined style at this point is already the style in question.
205 #define wxRICHTEXT_SETSTYLE_OPTIMIZE 0x02
206
207 // Specifies that the style should only be applied to paragraphs,
208 // and not the content. This allows content styling to be
209 // preserved independently from that of e.g. a named paragraph style.
210 #define wxRICHTEXT_SETSTYLE_PARAGRAPHS_ONLY 0x04
211
212 // Specifies that the style should only be applied to characters,
213 // and not the paragraph. This allows content styling to be
214 // preserved independently from that of e.g. a named paragraph style.
215 #define wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY 0x08
216
217 // For SetListStyle only: specifies starting from the given number, otherwise
218 // deduces number from existing attributes
219 #define wxRICHTEXT_SETSTYLE_RENUMBER 0x10
220
221 // For SetListStyle only: specifies the list level for all paragraphs, otherwise
222 // the current indentation will be used
223 #define wxRICHTEXT_SETSTYLE_SPECIFY_LEVEL 0x20
224
225 // Resets the existing style before applying the new style
226 #define wxRICHTEXT_SETSTYLE_RESET 0x40
227
228 // Removes the given style instead of applying it
229 #define wxRICHTEXT_SETSTYLE_REMOVE 0x80
230
231 /*!
232 * Flags for text insertion
233 */
234
235 #define wxRICHTEXT_INSERT_NONE 0x00
236 #define wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE 0x01
237 #define wxRICHTEXT_INSERT_INTERACTIVE 0x02
238
239 // A special flag telling the buffer to keep the first paragraph style
240 // as-is, when deleting a paragraph marker. In future we might pass a
241 // flag to InsertFragment and DeleteRange to indicate the appropriate mode.
242 #define wxTEXT_ATTR_KEEP_FIRST_PARA_STYLE 0x10000000
243
244 /*!
245 * Default superscript/subscript font multiplication factor
246 */
247
248 #define wxSCRIPT_MUL_FACTOR 1.5
249
250 typedef unsigned short wxTextAttrDimensionFlags;
251
252 // Miscelaneous text box flags
253 enum wxTextBoxAttrFlags
254 {
255 wxTEXT_BOX_ATTR_FLOAT = 0x00000001,
256 wxTEXT_BOX_ATTR_CLEAR = 0x00000002,
257 wxTEXT_BOX_ATTR_COLLAPSE_BORDERS = 0x00000004
258 };
259
260 // Whether a value is present, used in dimension flags
261 enum wxTextAttrValueFlags
262 {
263 wxTEXT_ATTR_VALUE_PRESENT = 0x1000,
264 wxTEXT_ATTR_VALUE_PRESENT_MASK = 0x1000
265 };
266
267 // Units - included in the dimension value
268 enum wxTextAttrUnits
269 {
270 wxTEXT_ATTR_UNITS_TENTHS_MM = 0x0001,
271 wxTEXT_ATTR_UNITS_PIXELS = 0x0002,
272 wxTEXT_ATTR_UNITS_PERCENTAGE = 0x0004,
273 wxTEXT_ATTR_UNITS_POINTS = 0x0008,
274
275 wxTEXT_ATTR_UNITS_MASK = 0x000F
276 };
277
278 // Position - included in the dimension flags
279 enum wxTextBoxAttrPosition
280 {
281 wxTEXT_BOX_ATTR_POSITION_STATIC = 0x0000, // Default is static, i.e. as per normal layout
282 wxTEXT_BOX_ATTR_POSITION_RELATIVE = 0x0010,
283 wxTEXT_BOX_ATTR_POSITION_ABSOLUTE = 0x0020,
284
285 wxTEXT_BOX_ATTR_POSITION_MASK = 0x00F0
286 };
287
288 // Dimension, including units and position
289 class WXDLLIMPEXP_RICHTEXT wxTextAttrDimension
290 {
291 public:
292 wxTextAttrDimension() { Reset(); }
293 wxTextAttrDimension(int value, wxTextAttrDimensionFlags flags = wxTEXT_ATTR_VALUE_PRESENT|wxTEXT_ATTR_UNITS_TENTHS_MM) { m_value = value; m_flags = flags; }
294
295 void Reset() { m_value = 0; m_flags = 0; }
296
297 // Partial equality test
298 bool EqPartial(const wxTextAttrDimension& dim) const;
299
300 // Apply
301 bool Apply(const wxTextAttrDimension& dim, const wxTextAttrDimension* compareWith = NULL);
302
303 // Collects the attributes that are common to a range of content, building up a note of
304 // which attributes are absent in some objects and which clash in some objects.
305 void CollectCommonAttributes(const wxTextAttrDimension& attr, wxTextAttrDimension& clashingAttr, wxTextAttrDimension& absentAttr);
306
307 bool operator==(const wxTextAttrDimension& dim) const { return m_value == dim.m_value && m_flags == dim.m_flags; }
308
309 int GetValue() const { return m_value; }
310 float GetValueMM() const { return float(m_value) / 10.0; }
311 void SetValueMM(float value) { m_value = (int) ((value * 10.0) + 0.5); m_flags |= wxTEXT_ATTR_VALUE_PRESENT; }
312 void SetValue(int value) { m_value = value; m_flags |= wxTEXT_ATTR_VALUE_PRESENT; }
313 void SetValue(int value, wxTextAttrDimensionFlags flags) { m_value = value; m_flags = flags; }
314 void SetValue(const wxTextAttrDimension& dim) { (*this) = dim; }
315
316 wxTextAttrUnits GetUnits() const { return (wxTextAttrUnits) (m_flags & wxTEXT_ATTR_UNITS_MASK); }
317 void SetUnits(wxTextAttrUnits units) { m_flags &= ~wxTEXT_ATTR_UNITS_MASK; m_flags |= units; }
318
319 wxTextBoxAttrPosition GetPosition() const { return (wxTextBoxAttrPosition) (m_flags & wxTEXT_BOX_ATTR_POSITION_MASK); }
320 void SetPosition(wxTextBoxAttrPosition pos) { m_flags &= ~wxTEXT_BOX_ATTR_POSITION_MASK; m_flags |= pos; }
321
322 bool IsPresent() const { return (m_flags & wxTEXT_ATTR_VALUE_PRESENT) != 0; }
323 void SetPresent(bool b) { m_flags &= ~wxTEXT_ATTR_VALUE_PRESENT_MASK; m_flags |= (b ? wxTEXT_ATTR_VALUE_PRESENT : 0); }
324
325 wxTextAttrDimensionFlags GetFlags() const { return m_flags; }
326 void SetFlags(wxTextAttrDimensionFlags flags) { m_flags = flags; }
327
328 int m_value;
329 wxTextAttrDimensionFlags m_flags;
330 };
331
332 // A class for left, right, top and bottom dimensions
333 class WXDLLIMPEXP_RICHTEXT wxTextAttrDimensions
334 {
335 public:
336 void Reset() { m_left.Reset(); m_top.Reset(); m_right.Reset(); m_bottom.Reset(); }
337
338 bool operator==(const wxTextAttrDimensions& dims) const { return m_left == dims.m_left && m_top == dims.m_top && m_right == dims.m_right && m_bottom == dims.m_bottom; }
339
340 // Partial equality test
341 bool EqPartial(const wxTextAttrDimensions& dims) const;
342
343 // Apply border to 'this', but not if the same as compareWith
344 bool Apply(const wxTextAttrDimensions& dims, const wxTextAttrDimensions* compareWith = NULL);
345
346 // Collects the attributes that are common to a range of content, building up a note of
347 // which attributes are absent in some objects and which clash in some objects.
348 void CollectCommonAttributes(const wxTextAttrDimensions& attr, wxTextAttrDimensions& clashingAttr, wxTextAttrDimensions& absentAttr);
349
350 // Remove specified attributes from this object
351 bool RemoveStyle(const wxTextAttrDimensions& attr);
352
353 const wxTextAttrDimension& GetLeft() const { return m_left; }
354 wxTextAttrDimension& GetLeft() { return m_left; }
355
356 const wxTextAttrDimension& GetRight() const { return m_right; }
357 wxTextAttrDimension& GetRight() { return m_right; }
358
359 const wxTextAttrDimension& GetTop() const { return m_top; }
360 wxTextAttrDimension& GetTop() { return m_top; }
361
362 const wxTextAttrDimension& GetBottom() const { return m_bottom; }
363 wxTextAttrDimension& GetBottom() { return m_bottom; }
364
365 wxTextAttrDimension m_left;
366 wxTextAttrDimension m_top;
367 wxTextAttrDimension m_right;
368 wxTextAttrDimension m_bottom;
369 };
370
371 // A class to make it easier to convert dimensions
372 class WXDLLIMPEXP_RICHTEXT wxTextAttrDimensionConverter
373 {
374 public:
375 wxTextAttrDimensionConverter(wxDC& dc, double scale = 1.0, const wxSize& parentSize = wxDefaultSize);
376 wxTextAttrDimensionConverter(int ppi, double scale = 1.0, const wxSize& parentSize = wxDefaultSize);
377
378 int GetPixels(const wxTextAttrDimension& dim, int direction = wxHORIZONTAL) const;
379 int GetTenthsMM(const wxTextAttrDimension& dim) const;
380
381 int ConvertTenthsMMToPixels(int units) const;
382 int ConvertPixelsToTenthsMM(int pixels) const;
383
384 int m_ppi;
385 double m_scale;
386 wxSize m_parentSize;
387 };
388
389 // Border styles
390 enum wxTextAttrBorderStyle
391 {
392 wxTEXT_BOX_ATTR_BORDER_NONE = 0,
393 wxTEXT_BOX_ATTR_BORDER_SOLID = 1,
394 wxTEXT_BOX_ATTR_BORDER_DOTTED = 2,
395 wxTEXT_BOX_ATTR_BORDER_DASHED = 3,
396 wxTEXT_BOX_ATTR_BORDER_DOUBLE = 4,
397 wxTEXT_BOX_ATTR_BORDER_GROOVE = 5,
398 wxTEXT_BOX_ATTR_BORDER_RIDGE = 6,
399 wxTEXT_BOX_ATTR_BORDER_INSET = 7,
400 wxTEXT_BOX_ATTR_BORDER_OUTSET = 8
401 };
402
403 // Border style presence flags
404 enum wxTextAttrBorderFlags
405 {
406 wxTEXT_BOX_ATTR_BORDER_STYLE = 0x0001,
407 wxTEXT_BOX_ATTR_BORDER_COLOUR = 0x0002
408 };
409
410 // Border width symbols for qualitative widths
411 enum wxTextAttrBorderWidth
412 {
413 wxTEXT_BOX_ATTR_BORDER_THIN = -1,
414 wxTEXT_BOX_ATTR_BORDER_MEDIUM = -2,
415 wxTEXT_BOX_ATTR_BORDER_THICK = -3
416 };
417
418 // Float styles
419 enum wxTextBoxAttrFloatStyle
420 {
421 wxTEXT_BOX_ATTR_FLOAT_NONE = 0,
422 wxTEXT_BOX_ATTR_FLOAT_LEFT = 1,
423 wxTEXT_BOX_ATTR_FLOAT_RIGHT = 2
424 };
425
426 // Clear styles
427 enum wxTextBoxAttrClearStyle
428 {
429 wxTEXT_BOX_ATTR_CLEAR_NONE = 0,
430 wxTEXT_BOX_ATTR_CLEAR_LEFT = 1,
431 wxTEXT_BOX_ATTR_CLEAR_RIGHT = 2,
432 wxTEXT_BOX_ATTR_CLEAR_BOTH = 3
433 };
434
435 // Collapse mode styles. TODO: can they be switched on per side?
436 enum wxTextBoxAttrCollapseMode
437 {
438 wxTEXT_BOX_ATTR_COLLAPSE_NONE = 0,
439 wxTEXT_BOX_ATTR_COLLAPSE_FULL = 1
440 };
441
442 // Border
443 class WXDLLIMPEXP_RICHTEXT wxTextAttrBorder
444 {
445 public:
446 wxTextAttrBorder() { Reset(); }
447
448 bool operator==(const wxTextAttrBorder& border) const
449 {
450 return m_flags == border.m_flags && m_borderStyle == border.m_borderStyle &&
451 m_borderColour == border.m_borderColour && m_borderWidth == border.m_borderWidth;
452 }
453
454 void Reset() { m_borderStyle = 0; m_borderColour = 0; m_flags = 0; m_borderWidth.Reset(); }
455
456 // Partial equality test
457 bool EqPartial(const wxTextAttrBorder& border) const;
458
459 // Apply border to 'this', but not if the same as compareWith
460 bool Apply(const wxTextAttrBorder& border, const wxTextAttrBorder* compareWith = NULL);
461
462 // Remove specified attributes from this object
463 bool RemoveStyle(const wxTextAttrBorder& attr);
464
465 // Collects the attributes that are common to a range of content, building up a note of
466 // which attributes are absent in some objects and which clash in some objects.
467 void CollectCommonAttributes(const wxTextAttrBorder& attr, wxTextAttrBorder& clashingAttr, wxTextAttrBorder& absentAttr);
468
469 void SetStyle(int style) { m_borderStyle = style; m_flags |= wxTEXT_BOX_ATTR_BORDER_STYLE; }
470 int GetStyle() const { return m_borderStyle; }
471
472 void SetColour(unsigned long colour) { m_borderColour = colour; m_flags |= wxTEXT_BOX_ATTR_BORDER_COLOUR; }
473 void SetColour(const wxColour& colour) { m_borderColour = colour.GetRGB(); m_flags |= wxTEXT_BOX_ATTR_BORDER_COLOUR; }
474 unsigned long GetColourLong() const { return m_borderColour; }
475 wxColour GetColour() const { return wxColour(m_borderColour); }
476
477 wxTextAttrDimension& GetWidth() { return m_borderWidth; }
478 const wxTextAttrDimension& GetWidth() const { return m_borderWidth; }
479 void SetWidth(const wxTextAttrDimension& width) { m_borderWidth = width; }
480
481 bool HasStyle() const { return (m_flags & wxTEXT_BOX_ATTR_BORDER_STYLE) != 0; }
482 bool HasColour() const { return (m_flags & wxTEXT_BOX_ATTR_BORDER_COLOUR) != 0; }
483 bool HasWidth() const { return m_borderWidth.IsPresent(); }
484
485 bool IsValid() const { return HasStyle() && HasColour() && HasWidth(); }
486
487 int GetFlags() const { return m_flags; }
488 void SetFlags(int flags) { m_flags = flags; }
489 void AddFlag(int flag) { m_flags |= flag; }
490 void RemoveFlag(int flag) { m_flags &= ~flag; }
491
492 int m_borderStyle;
493 unsigned long m_borderColour;
494 wxTextAttrDimension m_borderWidth;
495 int m_flags;
496 };
497
498 // Borders
499 class WXDLLIMPEXP_RICHTEXT wxTextAttrBorders
500 {
501 public:
502 wxTextAttrBorders() { }
503
504 bool operator==(const wxTextAttrBorders& borders) const
505 {
506 return m_left == borders.m_left && m_right == borders.m_right &&
507 m_top == borders.m_top && m_bottom == borders.m_bottom;
508 }
509
510 // Set style of all borders
511 void SetStyle(int style);
512
513 // Set colour of all borders
514 void SetColour(unsigned long colour);
515 void SetColour(const wxColour& colour);
516
517 // Set width of all borders
518 void SetWidth(const wxTextAttrDimension& width);
519
520 // Reset
521 void Reset() { m_left.Reset(); m_right.Reset(); m_top.Reset(); m_bottom.Reset(); }
522
523 // Partial equality test
524 bool EqPartial(const wxTextAttrBorders& borders) const;
525
526 // Apply border to 'this', but not if the same as compareWith
527 bool Apply(const wxTextAttrBorders& borders, const wxTextAttrBorders* compareWith = NULL);
528
529 // Remove specified attributes from this object
530 bool RemoveStyle(const wxTextAttrBorders& attr);
531
532 // Collects the attributes that are common to a range of content, building up a note of
533 // which attributes are absent in some objects and which clash in some objects.
534 void CollectCommonAttributes(const wxTextAttrBorders& attr, wxTextAttrBorders& clashingAttr, wxTextAttrBorders& absentAttr);
535
536 bool HasBorder() const { return m_left.IsValid() || m_right.IsValid() || m_top.IsValid() || m_bottom.IsValid(); }
537
538 const wxTextAttrBorder& GetLeft() const { return m_left; }
539 wxTextAttrBorder& GetLeft() { return m_left; }
540
541 const wxTextAttrBorder& GetRight() const { return m_right; }
542 wxTextAttrBorder& GetRight() { return m_right; }
543
544 const wxTextAttrBorder& GetTop() const { return m_top; }
545 wxTextAttrBorder& GetTop() { return m_top; }
546
547 const wxTextAttrBorder& GetBottom() const { return m_bottom; }
548 wxTextAttrBorder& GetBottom() { return m_bottom; }
549
550 wxTextAttrBorder m_left, m_right, m_top, m_bottom;
551
552 };
553
554 // ----------------------------------------------------------------------------
555 // wxTextBoxAttr: a structure containing box attributes
556 // ----------------------------------------------------------------------------
557
558 class WXDLLIMPEXP_RICHTEXT wxTextBoxAttr
559 {
560 public:
561 // ctors
562 wxTextBoxAttr() { Init(); }
563 wxTextBoxAttr(const wxTextBoxAttr& attr) { Init(); (*this) = attr; }
564
565 // Initialise this object.
566 void Init() { Reset(); }
567
568 // Reset this object.
569 void Reset();
570
571 // Copy. Unnecessary since we let it do a binary copy
572 //void Copy(const wxTextBoxAttr& attr);
573
574 // Assignment
575 //void operator= (const wxTextBoxAttr& attr);
576
577 // Equality test
578 bool operator== (const wxTextBoxAttr& attr) const;
579
580 // Partial equality test
581 bool EqPartial(const wxTextBoxAttr& attr) const;
582
583 // Merges the given attributes. If compareWith
584 // is non-NULL, then it will be used to mask out those attributes that are the same in style
585 // and compareWith, for situations where we don't want to explicitly set inherited attributes.
586 bool Apply(const wxTextBoxAttr& style, const wxTextBoxAttr* compareWith = NULL);
587
588 // Collects the attributes that are common to a range of content, building up a note of
589 // which attributes are absent in some objects and which clash in some objects.
590 void CollectCommonAttributes(const wxTextBoxAttr& attr, wxTextBoxAttr& clashingAttr, wxTextBoxAttr& absentAttr);
591
592 // Remove specified attributes from this object
593 bool RemoveStyle(const wxTextBoxAttr& attr);
594
595 // Set flags
596 void SetFlags(int flags) { m_flags = flags; }
597
598 // Get flags
599 int GetFlags() const { return m_flags; }
600
601 // Is this flag present?
602 bool HasFlag(wxTextBoxAttrFlags flag) const { return (m_flags & flag) != 0; }
603
604 // Remove this flag
605 void RemoveFlag(wxTextBoxAttrFlags flag) { m_flags &= ~flag; }
606
607 // Add this flag
608 void AddFlag(wxTextBoxAttrFlags flag) { m_flags |= flag; }
609
610 // Is this default? I.e. no flags set
611 bool IsDefault() const;
612
613 // Float mode
614 short int GetFloatMode() const { return m_floatMode; }
615 void SetFloatMode(short int mode) { m_floatMode = mode; m_flags |= wxTEXT_BOX_ATTR_FLOAT; }
616 bool HasFloatMode() const { return HasFlag(wxTEXT_BOX_ATTR_FLOAT); }
617 bool IsFloating() const { return HasFloatMode() && GetFloatMode() != wxTEXT_BOX_ATTR_FLOAT_NONE; }
618
619 // Whether to wrap text after object
620 short int GetClearMode() const { return m_clearMode; }
621 void SetClearMode(short int mode) { m_clearMode = mode; m_flags |= wxTEXT_BOX_ATTR_CLEAR; }
622 bool HasClearMode() const { return HasFlag(wxTEXT_BOX_ATTR_CLEAR); }
623
624 // Whether to collapse borders
625 int GetCollapseBorders() const { return m_collapseMode ; }
626 void SetCollapseBorders(int collapse) { m_collapseMode = collapse; m_flags |= wxTEXT_BOX_ATTR_COLLAPSE_BORDERS; }
627 bool HasCollapseBorders() const { return HasFlag(wxTEXT_BOX_ATTR_COLLAPSE_BORDERS); }
628
629 // Margins
630
631 wxTextAttrDimensions& GetMargins() { return m_margins; }
632 const wxTextAttrDimensions& GetMargins() const { return m_margins; }
633
634 wxTextAttrDimension& GetLeftMargin() { return m_margins.m_left; }
635 const wxTextAttrDimension& GetLeftMargin() const { return m_margins.m_left; }
636
637 wxTextAttrDimension& GetRightMargin() { return m_margins.m_right; }
638 const wxTextAttrDimension& GetRightMargin() const { return m_margins.m_right; }
639
640 wxTextAttrDimension& GetTopMargin() { return m_margins.m_top; }
641 const wxTextAttrDimension& GetTopMargin() const { return m_margins.m_top; }
642
643 wxTextAttrDimension& GetBottomMargin() { return m_margins.m_bottom; }
644 const wxTextAttrDimension& GetBottomMargin() const { return m_margins.m_bottom; }
645
646 // Position
647
648 wxTextAttrDimensions& GetPosition() { return m_position; }
649 const wxTextAttrDimensions& GetPosition() const { return m_position; }
650
651 wxTextAttrDimension& GetLeft() { return m_position.m_left; }
652 const wxTextAttrDimension& GetLeft() const { return m_position.m_left; }
653
654 wxTextAttrDimension& GetRight() { return m_position.m_right; }
655 const wxTextAttrDimension& GetRight() const { return m_position.m_right; }
656
657 wxTextAttrDimension& GetTop() { return m_position.m_top; }
658 const wxTextAttrDimension& GetTop() const { return m_position.m_top; }
659
660 wxTextAttrDimension& GetBottom() { return m_position.m_bottom; }
661 const wxTextAttrDimension& GetBottom() const { return m_position.m_bottom; }
662
663 // Padding
664
665 wxTextAttrDimensions& GetPadding() { return m_padding; }
666 const wxTextAttrDimensions& GetPadding() const { return m_padding; }
667
668 wxTextAttrDimension& GetLeftPadding() { return m_padding.m_left; }
669 const wxTextAttrDimension& GetLeftPadding() const { return m_padding.m_left; }
670
671 wxTextAttrDimension& GetRightPadding() { return m_padding.m_right; }
672 const wxTextAttrDimension& GetRightPadding() const { return m_padding.m_right; }
673
674 wxTextAttrDimension& GetTopPadding() { return m_padding.m_top; }
675 const wxTextAttrDimension& GetTopPadding() const { return m_padding.m_top; }
676
677 wxTextAttrDimension& GetBottomPadding() { return m_padding.m_bottom; }
678 const wxTextAttrDimension& GetBottomPadding() const { return m_padding.m_bottom; }
679
680 // Border
681
682 wxTextAttrBorders& GetBorder() { return m_border; }
683 const wxTextAttrBorders& GetBorder() const { return m_border; }
684
685 wxTextAttrBorder& GetLeftBorder() { return m_border.m_left; }
686 const wxTextAttrBorder& GetLeftBorder() const { return m_border.m_left; }
687
688 wxTextAttrBorder& GetTopBorder() { return m_border.m_top; }
689 const wxTextAttrBorder& GetTopBorder() const { return m_border.m_top; }
690
691 wxTextAttrBorder& GetRightBorder() { return m_border.m_right; }
692 const wxTextAttrBorder& GetRightBorder() const { return m_border.m_right; }
693
694 wxTextAttrBorder& GetBottomBorder() { return m_border.m_bottom; }
695 const wxTextAttrBorder& GetBottomBorder() const { return m_border.m_bottom; }
696
697 // Outline
698
699 wxTextAttrBorders& GetOutline() { return m_outline; }
700 const wxTextAttrBorders& GetOutline() const { return m_outline; }
701
702 wxTextAttrBorder& GetLeftOutline() { return m_outline.m_left; }
703 const wxTextAttrBorder& GetLeftOutline() const { return m_outline.m_left; }
704
705 wxTextAttrBorder& GetTopOutline() { return m_outline.m_top; }
706 const wxTextAttrBorder& GetTopOutline() const { return m_outline.m_top; }
707
708 wxTextAttrBorder& GetRightOutline() { return m_outline.m_right; }
709 const wxTextAttrBorder& GetRightOutline() const { return m_outline.m_right; }
710
711 wxTextAttrBorder& GetBottomOutline() { return m_outline.m_bottom; }
712 const wxTextAttrBorder& GetBottomOutline() const { return m_outline.m_bottom; }
713
714
715 // Width and height
716
717 wxTextAttrDimension& GetWidth() { return m_width; }
718 const wxTextAttrDimension& GetWidth() const { return m_width; }
719
720 wxTextAttrDimension& GetHeight() { return m_height; }
721 const wxTextAttrDimension& GetHeight() const { return m_height; }
722
723 public:
724
725 int m_flags;
726
727 wxTextAttrDimensions m_margins;
728 wxTextAttrDimensions m_padding;
729 wxTextAttrDimensions m_position;
730
731 wxTextAttrDimension m_width;
732 wxTextAttrDimension m_height;
733
734 wxTextAttrBorders m_border;
735 wxTextAttrBorders m_outline;
736
737 short int m_floatMode;
738 short int m_clearMode;
739 short int m_collapseMode;
740 };
741
742 // ----------------------------------------------------------------------------
743 // wxRichTextAttr: an enhanced attribute
744 // ----------------------------------------------------------------------------
745
746 class WXDLLIMPEXP_RICHTEXT wxRichTextAttr: public wxTextAttr
747 {
748 public:
749 wxRichTextAttr(const wxTextAttr& attr) { wxTextAttr::Copy(attr); }
750 wxRichTextAttr(const wxRichTextAttr& attr) { Copy(attr); }
751 wxRichTextAttr() {}
752
753 // Copy
754 void Copy(const wxRichTextAttr& attr);
755
756 // Assignment
757 void operator=(const wxRichTextAttr& attr) { Copy(attr); }
758 void operator=(const wxTextAttr& attr) { wxTextAttr::Copy(attr); }
759
760 // Equality test
761 bool operator==(const wxRichTextAttr& attr) const;
762
763 // Partial equality test taking comparison object into account
764 bool EqPartial(const wxRichTextAttr& attr) const;
765
766 // Merges the given attributes. If compareWith
767 // is non-NULL, then it will be used to mask out those attributes that are the same in style
768 // and compareWith, for situations where we don't want to explicitly set inherited attributes.
769 bool Apply(const wxRichTextAttr& style, const wxRichTextAttr* compareWith = NULL);
770
771 // Collects the attributes that are common to a range of content, building up a note of
772 // which attributes are absent in some objects and which clash in some objects.
773 void CollectCommonAttributes(const wxRichTextAttr& attr, wxRichTextAttr& clashingAttr, wxRichTextAttr& absentAttr);
774
775 // Remove specified attributes from this object
776 bool RemoveStyle(const wxRichTextAttr& attr);
777
778 wxTextBoxAttr& GetTextBoxAttr() { return m_textBoxAttr; }
779 const wxTextBoxAttr& GetTextBoxAttr() const { return m_textBoxAttr; }
780 void SetTextBoxAttr(const wxTextBoxAttr& attr) { m_textBoxAttr = attr; }
781
782 wxTextBoxAttr m_textBoxAttr;
783 };
784
785 WX_DECLARE_USER_EXPORTED_OBJARRAY(wxVariant, wxRichTextVariantArray, WXDLLIMPEXP_RICHTEXT);
786
787 // ----------------------------------------------------------------------------
788 // wxRichTextProperties - A simple property class using wxVariants
789 // ----------------------------------------------------------------------------
790
791 class WXDLLIMPEXP_RICHTEXT wxRichTextProperties: public wxObject
792 {
793 DECLARE_DYNAMIC_CLASS(wxRichTextProperties)
794 public:
795 wxRichTextProperties() {}
796 wxRichTextProperties(const wxRichTextProperties& props) { Copy(props); }
797
798 void operator=(const wxRichTextProperties& props) { Copy(props); }
799 bool operator==(const wxRichTextProperties& props) const;
800 void Copy(const wxRichTextProperties& props) { m_properties = props.m_properties; }
801 const wxVariant& operator[](size_t idx) const { return m_properties[idx]; }
802 wxVariant& operator[](size_t idx) { return m_properties[idx]; }
803 void Clear() { m_properties.Clear(); }
804
805 const wxRichTextVariantArray& GetProperties() const { return m_properties; }
806 wxRichTextVariantArray& GetProperties() { return m_properties; }
807 void SetProperties(const wxRichTextVariantArray& props) { m_properties = props; }
808
809 wxArrayString GetPropertyNames() const;
810
811 size_t GetCount() const { return m_properties.GetCount(); }
812
813 int HasProperty(const wxString& name) const { return Find(name) != -1; }
814
815 int Find(const wxString& name) const;
816 const wxVariant& GetProperty(const wxString& name) const;
817 wxVariant* FindOrCreateProperty(const wxString& name);
818
819 wxString GetPropertyString(const wxString& name) const;
820 long GetPropertyLong(const wxString& name) const;
821 bool GetPropertyBool(const wxString& name) const;
822 double GetPropertyDouble(const wxString& name) const;
823
824 void SetProperty(const wxVariant& variant);
825 void SetProperty(const wxString& name, const wxVariant& variant);
826 void SetProperty(const wxString& name, const wxString& value);
827 void SetProperty(const wxString& name, long value);
828 void SetProperty(const wxString& name, double value);
829 void SetProperty(const wxString& name, bool value);
830
831 protected:
832 wxRichTextVariantArray m_properties;
833 };
834
835
836 /*!
837 * wxRichTextFontTable
838 * Manages quick access to a pool of fonts for rendering rich text
839 */
840
841 class WXDLLIMPEXP_RICHTEXT wxRichTextFontTable: public wxObject
842 {
843 public:
844 wxRichTextFontTable();
845
846 wxRichTextFontTable(const wxRichTextFontTable& table);
847 virtual ~wxRichTextFontTable();
848
849 bool IsOk() const { return m_refData != NULL; }
850
851 wxFont FindFont(const wxRichTextAttr& fontSpec);
852 void Clear();
853
854 void operator= (const wxRichTextFontTable& table);
855 bool operator == (const wxRichTextFontTable& table) const;
856 bool operator != (const wxRichTextFontTable& table) const { return !(*this == table); }
857
858 protected:
859
860 DECLARE_DYNAMIC_CLASS(wxRichTextFontTable)
861 };
862
863 /*!
864 * wxRichTextRange class declaration
865 * This stores beginning and end positions for a range of data.
866 * TODO: consider renaming wxTextRange and using for all text controls.
867 */
868
869 class WXDLLIMPEXP_RICHTEXT wxRichTextRange
870 {
871 public:
872 // Constructors
873
874 wxRichTextRange() { m_start = 0; m_end = 0; }
875 wxRichTextRange(long start, long end) { m_start = start; m_end = end; }
876 wxRichTextRange(const wxRichTextRange& range) { m_start = range.m_start; m_end = range.m_end; }
877 ~wxRichTextRange() {}
878
879 void operator =(const wxRichTextRange& range) { m_start = range.m_start; m_end = range.m_end; }
880 bool operator ==(const wxRichTextRange& range) const { return (m_start == range.m_start && m_end == range.m_end); }
881 bool operator !=(const wxRichTextRange& range) const { return (m_start != range.m_start || m_end != range.m_end); }
882 wxRichTextRange operator -(const wxRichTextRange& range) const { return wxRichTextRange(m_start - range.m_start, m_end - range.m_end); }
883 wxRichTextRange operator +(const wxRichTextRange& range) const { return wxRichTextRange(m_start + range.m_start, m_end + range.m_end); }
884
885 void SetRange(long start, long end) { m_start = start; m_end = end; }
886
887 void SetStart(long start) { m_start = start; }
888 long GetStart() const { return m_start; }
889
890 void SetEnd(long end) { m_end = end; }
891 long GetEnd() const { return m_end; }
892
893 /// Returns true if this range is completely outside 'range'
894 bool IsOutside(const wxRichTextRange& range) const { return range.m_start > m_end || range.m_end < m_start; }
895
896 /// Returns true if this range is completely within 'range'
897 bool IsWithin(const wxRichTextRange& range) const { return m_start >= range.m_start && m_end <= range.m_end; }
898
899 /// Returns true if the given position is within this range. Allow
900 /// for the possibility of an empty range - assume the position
901 /// is within this empty range. NO, I think we should not match with an empty range.
902 // bool Contains(long pos) const { return pos >= m_start && (pos <= m_end || GetLength() == 0); }
903 bool Contains(long pos) const { return pos >= m_start && pos <= m_end ; }
904
905 /// Limit this range to be within 'range'
906 bool LimitTo(const wxRichTextRange& range) ;
907
908 /// Gets the length of the range
909 long GetLength() const { return m_end - m_start + 1; }
910
911 /// Swaps the start and end
912 void Swap() { long tmp = m_start; m_start = m_end; m_end = tmp; }
913
914 /// Convert to internal form: (n, n) is the range of a single character.
915 wxRichTextRange ToInternal() const { return wxRichTextRange(m_start, m_end-1); }
916
917 /// Convert from internal to public API form: (n, n+1) is the range of a single character.
918 wxRichTextRange FromInternal() const { return wxRichTextRange(m_start, m_end+1); }
919
920 protected:
921 long m_start;
922 long m_end;
923 };
924
925 #define wxRICHTEXT_ALL wxRichTextRange(-2, -2)
926 #define wxRICHTEXT_NONE wxRichTextRange(-1, -1)
927
928 /*!
929 * wxRichTextObject class declaration
930 * This is the base for drawable objects.
931 */
932
933 class WXDLLIMPEXP_RICHTEXT wxRichTextObject: public wxObject
934 {
935 DECLARE_CLASS(wxRichTextObject)
936 public:
937 // Constructors
938
939 wxRichTextObject(wxRichTextObject* parent = NULL);
940 virtual ~wxRichTextObject();
941
942 // Overrideables
943
944 /// Draw the item, within the given range. Some objects may ignore the range (for
945 /// example paragraphs) while others must obey it (lines, to implement wrapping)
946 virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style) = 0;
947
948 /// Lay the item out at the specified position with the given size constraint.
949 /// Layout must set the cached size.
950 virtual bool Layout(wxDC& dc, const wxRect& rect, int style) = 0;
951
952 /// Hit-testing: returns a flag indicating hit test details, plus
953 /// information about position
954 virtual int HitTest(wxDC& WXUNUSED(dc), const wxPoint& WXUNUSED(pt), long& WXUNUSED(textPosition)) { return false; }
955
956 /// Finds the absolute position and row height for the given character position
957 virtual bool FindPosition(wxDC& WXUNUSED(dc), long WXUNUSED(index), wxPoint& WXUNUSED(pt), int* WXUNUSED(height), bool WXUNUSED(forceLineStart)) { return false; }
958
959 /// Get the best size, i.e. the ideal starting size for this object irrespective
960 /// of available space. For a short text string, it will be the size that exactly encloses
961 /// the text. For a longer string, it might use the parent width for example.
962 virtual wxSize GetBestSize() const { return m_size; }
963
964 /// Get the object size for the given range. Returns false if the range
965 /// is invalid for this object.
966 virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const = 0;
967
968 /// Do a split, returning an object containing the second part, and setting
969 /// the first part in 'this'.
970 virtual wxRichTextObject* DoSplit(long WXUNUSED(pos)) { return NULL; }
971
972 /// Calculate range. By default, guess that the object is 1 unit long.
973 virtual void CalculateRange(long start, long& end) { end = start ; m_range.SetRange(start, end); }
974
975 /// Delete range
976 virtual bool DeleteRange(const wxRichTextRange& WXUNUSED(range)) { return false; }
977
978 /// Returns true if the object is empty
979 virtual bool IsEmpty() const { return false; }
980
981 /// Whether this object floatable
982 virtual bool IsFloatable() const { return false; }
983
984 /// Whether this object is currently floating
985 virtual bool IsFloating() const { return GetAttributes().GetTextBoxAttr().IsFloating(); }
986
987 /// Whether this object is a place holding one
988 // virtual bool IsPlaceHolding() const { return false; }
989
990 /// The floating direction
991 virtual int GetFloatDirection() const { return GetAttributes().GetTextBoxAttr().GetFloatMode(); }
992
993 /// Get any text in this object for the given range
994 virtual wxString GetTextForRange(const wxRichTextRange& WXUNUSED(range)) const { return wxEmptyString; }
995
996 /// Returns true if this object can merge itself with the given one.
997 virtual bool CanMerge(wxRichTextObject* WXUNUSED(object)) const { return false; }
998
999 /// Returns true if this object merged itself with the given one.
1000 /// The calling code will then delete the given object.
1001 virtual bool Merge(wxRichTextObject* WXUNUSED(object)) { return false; }
1002
1003 /// Dump to output stream for debugging
1004 virtual void Dump(wxTextOutputStream& stream);
1005
1006 /// Can we edit properties via a GUI?
1007 virtual bool CanEditProperties() const { return false; }
1008
1009 /// Edit properties via a GUI
1010 virtual bool EditProperties(wxWindow* WXUNUSED(parent), wxRichTextBuffer* WXUNUSED(buffer)) { return false; }
1011
1012 #if wxUSE_XML
1013 /// Import this object from XML
1014 virtual bool ImportFromXML(wxRichTextBuffer* buffer, wxXmlNode* node, wxRichTextXMLHandler* handler);
1015 #endif
1016
1017 #if wxRICHTEXT_HAVE_DIRECT_OUTPUT
1018 /// Export this object directly to the given stream.
1019 virtual bool ExportXML(wxOutputStream& stream, int indent, wxRichTextXMLHandler* handler);
1020 #endif
1021
1022 #if wxRICHTEXT_HAVE_XMLDOCUMENT_OUTPUT
1023 /// Export this object to the given parent node, usually creating at least one child node.
1024 virtual bool ExportXML(wxXmlNode* parent, wxRichTextXMLHandler* handler);
1025 #endif
1026
1027 /// Does this object take note of paragraph attributes? Text and image objects don't.
1028 virtual bool UsesParagraphAttributes() const { return true; }
1029
1030 /// What is the XML node name of this object?
1031 virtual wxString GetXMLNodeName() const { return wxT("unknown"); }
1032
1033 // Accessors
1034
1035 /// Get/set the cached object size as calculated by Layout.
1036 virtual wxSize GetCachedSize() const { return m_size; }
1037 virtual void SetCachedSize(const wxSize& sz) { m_size = sz; }
1038
1039 /// Get/set the object position
1040 virtual wxPoint GetPosition() const { return m_pos; }
1041 virtual void SetPosition(const wxPoint& pos) { m_pos = pos; }
1042
1043 /// Get the rectangle enclosing the object
1044 virtual wxRect GetRect() const { return wxRect(GetPosition(), GetCachedSize()); }
1045
1046 /// Set the range
1047 void SetRange(const wxRichTextRange& range) { m_range = range; }
1048
1049 /// Get the range
1050 const wxRichTextRange& GetRange() const { return m_range; }
1051 wxRichTextRange& GetRange() { return m_range; }
1052
1053 /// Get/set dirty flag (whether the object needs Layout to be called)
1054 virtual bool GetDirty() const { return m_dirty; }
1055 virtual void SetDirty(bool dirty) { m_dirty = dirty; }
1056
1057 /// Is this composite?
1058 virtual bool IsComposite() const { return false; }
1059
1060 /// Get/set the parent.
1061 virtual wxRichTextObject* GetParent() const { return m_parent; }
1062 virtual void SetParent(wxRichTextObject* parent) { m_parent = parent; }
1063
1064 /// Set the margin around the object
1065 virtual void SetMargins(int margin);
1066 virtual void SetMargins(int leftMargin, int rightMargin, int topMargin, int bottomMargin);
1067 virtual int GetLeftMargin() const { return m_leftMargin; }
1068 virtual int GetRightMargin() const { return m_rightMargin; }
1069 virtual int GetTopMargin() const { return m_topMargin; }
1070 virtual int GetBottomMargin() const { return m_bottomMargin; }
1071
1072 /// Set/get attributes object
1073 void SetAttributes(const wxRichTextAttr& attr) { m_attributes = attr; }
1074 const wxRichTextAttr& GetAttributes() const { return m_attributes; }
1075 wxRichTextAttr& GetAttributes() { return m_attributes; }
1076
1077 /// Set/get properties
1078 wxRichTextProperties& GetProperties() { return m_properties; }
1079 const wxRichTextProperties& GetProperties() const { return m_properties; }
1080 void SetProperties(const wxRichTextProperties& props) { m_properties = props; }
1081
1082 /// Set/get stored descent
1083 void SetDescent(int descent) { m_descent = descent; }
1084 int GetDescent() const { return m_descent; }
1085
1086 /// Gets the containing buffer
1087 wxRichTextBuffer* GetBuffer() const;
1088
1089 // Operations
1090
1091 /// Clone the object
1092 virtual wxRichTextObject* Clone() const { return NULL; }
1093
1094 /// Copy
1095 void Copy(const wxRichTextObject& obj);
1096
1097 /// Reference-counting allows us to use the same object in multiple
1098 /// lists (not yet used)
1099 void Reference() { m_refCount ++; }
1100 void Dereference();
1101
1102 /// Convert units in tenths of a millimetre to device units
1103 int ConvertTenthsMMToPixels(wxDC& dc, int units) const;
1104 static int ConvertTenthsMMToPixels(int ppi, int units, double scale = 1.0);
1105
1106 /// Convert units in pixels to tenths of a millimetre
1107 int ConvertPixelsToTenthsMM(wxDC& dc, int pixels) const;
1108 static int ConvertPixelsToTenthsMM(int ppi, int pixels, double scale = 1.0);
1109
1110 /// Draw the borders and background for the given rectangle and attributes.
1111 /// Width and height are taken to be the content size, so excluding any
1112 /// border, margin and padding.
1113 static bool DrawBoxAttributes(wxDC& dc, const wxRichTextAttr& attr, const wxRect& boxRect);
1114
1115 /// Draw a border
1116 static bool DrawBorder(wxDC& dc, const wxTextAttrBorders& attr, const wxRect& rect);
1117
1118 /// Get the various rectangles of the box model in pixels. You can either specify contentRect (inner)
1119 /// or marginRect (outer), and the other must be the default rectangle (no width or height).
1120 /// Note that the outline doesn't affect the position of the rectangle, it's drawn in whatever space
1121 /// is available.
1122 static bool GetBoxRects(wxDC& dc, const wxRichTextAttr& attr, wxRect& marginRect, wxRect& borderRect, wxRect& contentRect, wxRect& paddingRect, wxRect& outlineRect);
1123
1124 protected:
1125 wxSize m_size;
1126 wxPoint m_pos;
1127 int m_descent; // Descent for this object (if any)
1128 bool m_dirty;
1129 int m_refCount;
1130 wxRichTextObject* m_parent;
1131
1132 /// The range of this object (start position to end position)
1133 wxRichTextRange m_range;
1134
1135 /// Margins
1136 int m_leftMargin;
1137 int m_rightMargin;
1138 int m_topMargin;
1139 int m_bottomMargin;
1140
1141 /// Attributes
1142 wxRichTextAttr m_attributes;
1143
1144 /// Properties
1145 wxRichTextProperties m_properties;
1146 };
1147
1148 WX_DECLARE_LIST_WITH_DECL( wxRichTextObject, wxRichTextObjectList, class WXDLLIMPEXP_RICHTEXT );
1149
1150 /*!
1151 * wxRichTextCompositeObject class declaration
1152 * Objects of this class can contain other objects.
1153 */
1154
1155 class WXDLLIMPEXP_RICHTEXT wxRichTextCompositeObject: public wxRichTextObject
1156 {
1157 DECLARE_CLASS(wxRichTextCompositeObject)
1158 public:
1159 // Constructors
1160
1161 wxRichTextCompositeObject(wxRichTextObject* parent = NULL);
1162 virtual ~wxRichTextCompositeObject();
1163
1164 // Overrideables
1165
1166 /// Hit-testing: returns a flag indicating hit test details, plus
1167 /// information about position
1168 virtual int HitTest(wxDC& dc, const wxPoint& pt, long& textPosition);
1169
1170 /// Finds the absolute position and row height for the given character position
1171 virtual bool FindPosition(wxDC& dc, long index, wxPoint& pt, int* height, bool forceLineStart);
1172
1173 /// Calculate range
1174 virtual void CalculateRange(long start, long& end);
1175
1176 /// Delete range
1177 virtual bool DeleteRange(const wxRichTextRange& range);
1178
1179 /// Get any text in this object for the given range
1180 virtual wxString GetTextForRange(const wxRichTextRange& range) const;
1181
1182 /// Dump to output stream for debugging
1183 virtual void Dump(wxTextOutputStream& stream);
1184
1185 // Accessors
1186
1187 /// Get the children
1188 wxRichTextObjectList& GetChildren() { return m_children; }
1189 const wxRichTextObjectList& GetChildren() const { return m_children; }
1190
1191 /// Get the child count
1192 size_t GetChildCount() const ;
1193
1194 /// Get the nth child
1195 wxRichTextObject* GetChild(size_t n) const ;
1196
1197 /// Get/set dirty flag
1198 virtual bool GetDirty() const { return m_dirty; }
1199 virtual void SetDirty(bool dirty) { m_dirty = dirty; }
1200
1201 /// Is this composite?
1202 virtual bool IsComposite() const { return true; }
1203
1204 /// Returns true if the buffer is empty
1205 virtual bool IsEmpty() const { return GetChildCount() == 0; }
1206
1207 // Operations
1208
1209 /// Copy
1210 void Copy(const wxRichTextCompositeObject& obj);
1211
1212 /// Assignment
1213 void operator= (const wxRichTextCompositeObject& obj) { Copy(obj); }
1214
1215 /// Append a child, returning the position
1216 size_t AppendChild(wxRichTextObject* child) ;
1217
1218 /// Insert the child in front of the given object, or at the beginning
1219 bool InsertChild(wxRichTextObject* child, wxRichTextObject* inFrontOf) ;
1220
1221 /// Delete the child
1222 bool RemoveChild(wxRichTextObject* child, bool deleteChild = false) ;
1223
1224 /// Delete all children
1225 bool DeleteChildren() ;
1226
1227 /// Recursively merge all pieces that can be merged.
1228 bool Defragment(const wxRichTextRange& range = wxRICHTEXT_ALL);
1229
1230 protected:
1231 wxRichTextObjectList m_children;
1232 };
1233
1234 /*!
1235 * wxRichTextParagraphBox class declaration
1236 * This box knows how to lay out paragraphs.
1237 */
1238
1239 class WXDLLIMPEXP_RICHTEXT wxRichTextParagraphLayoutBox: public wxRichTextCompositeObject
1240 {
1241 DECLARE_DYNAMIC_CLASS(wxRichTextParagraphLayoutBox)
1242 public:
1243 // Constructors
1244
1245 wxRichTextParagraphLayoutBox(wxRichTextObject* parent = NULL);
1246 wxRichTextParagraphLayoutBox(const wxRichTextParagraphLayoutBox& obj): wxRichTextCompositeObject() { Init(); Copy(obj); }
1247 ~wxRichTextParagraphLayoutBox();
1248
1249 // Overrideables
1250
1251 /// Hit-testing: returns a flag indicating hit test details, plus
1252 /// information about position
1253 virtual int HitTest(wxDC& dc, const wxPoint& pt, long& textPosition);
1254
1255 /// Draw the item
1256 virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style);
1257
1258 /// Lay the item out
1259 virtual bool Layout(wxDC& dc, const wxRect& rect, int style);
1260
1261 /// Get/set the object size for the given range. Returns false if the range
1262 /// is invalid for this object.
1263 virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const;
1264
1265 /// Delete range
1266 virtual bool DeleteRange(const wxRichTextRange& range);
1267
1268 /// Get any text in this object for the given range
1269 virtual wxString GetTextForRange(const wxRichTextRange& range) const;
1270
1271 #if wxUSE_XML
1272 /// Import this object from XML
1273 virtual bool ImportFromXML(wxRichTextBuffer* buffer, wxXmlNode* node, wxRichTextXMLHandler* handler);
1274 #endif
1275
1276 #if wxRICHTEXT_HAVE_DIRECT_OUTPUT
1277 /// Export this object directly to the given stream.
1278 virtual bool ExportXML(wxOutputStream& stream, int indent, wxRichTextXMLHandler* handler);
1279 #endif
1280
1281 #if wxRICHTEXT_HAVE_XMLDOCUMENT_OUTPUT
1282 /// Export this object to the given parent node, usually creating at least one child node.
1283 virtual bool ExportXML(wxXmlNode* parent, wxRichTextXMLHandler* handler);
1284 #endif
1285
1286 /// What is the XML node name of this object?
1287 virtual wxString GetXMLNodeName() const { return wxT("paragraphlayout"); }
1288
1289 // Accessors
1290
1291 /// Associate a control with the buffer, for operations that for example require refreshing the window.
1292 void SetRichTextCtrl(wxRichTextCtrl* ctrl) { m_ctrl = ctrl; }
1293
1294 /// Get the associated control.
1295 wxRichTextCtrl* GetRichTextCtrl() const { return m_ctrl; }
1296
1297 /// Get/set whether the last paragraph is partial or complete
1298 void SetPartialParagraph(bool partialPara) { m_partialParagraph = partialPara; }
1299 bool GetPartialParagraph() const { return m_partialParagraph; }
1300
1301 /// If this is a buffer, returns the current style sheet. The base layout box
1302 /// class doesn't have an associated style sheet.
1303 virtual wxRichTextStyleSheet* GetStyleSheet() const { return NULL; }
1304
1305 // Operations
1306 /// Draw the floats of this buffer
1307 void DrawFloats(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style);
1308
1309 /// Move an anchored object to another paragraph
1310 void MoveAnchoredObjectToParagraph(wxRichTextParagraph* from, wxRichTextParagraph* to, wxRichTextObject* obj);
1311
1312 /// Initialize the object.
1313 void Init();
1314
1315 /// Clear all children
1316 virtual void Clear();
1317
1318 /// Clear and initialize with one blank paragraph
1319 virtual void Reset();
1320
1321 /// Convenience function to add a paragraph of text
1322 virtual wxRichTextRange AddParagraph(const wxString& text, wxRichTextAttr* paraStyle = NULL);
1323
1324 /// Convenience function to add an image
1325 virtual wxRichTextRange AddImage(const wxImage& image, wxRichTextAttr* paraStyle = NULL);
1326
1327 /// Adds multiple paragraphs, based on newlines.
1328 virtual wxRichTextRange AddParagraphs(const wxString& text, wxRichTextAttr* paraStyle = NULL);
1329
1330 /// Get the line at the given position. If caretPosition is true, the position is
1331 /// a caret position, which is normally a smaller number.
1332 virtual wxRichTextLine* GetLineAtPosition(long pos, bool caretPosition = false) const;
1333
1334 /// Get the line at the given y pixel position, or the last line.
1335 virtual wxRichTextLine* GetLineAtYPosition(int y) const;
1336
1337 /// Get the paragraph at the given character or caret position
1338 virtual wxRichTextParagraph* GetParagraphAtPosition(long pos, bool caretPosition = false) const;
1339
1340 /// Get the line size at the given position
1341 virtual wxSize GetLineSizeAtPosition(long pos, bool caretPosition = false) const;
1342
1343 /// Given a position, get the number of the visible line (potentially many to a paragraph),
1344 /// starting from zero at the start of the buffer. We also have to pass a bool (startOfLine)
1345 /// that indicates whether the caret is being shown at the end of the previous line or at the start
1346 /// of the next, since the caret can be shown at 2 visible positions for the same underlying
1347 /// position.
1348 virtual long GetVisibleLineNumber(long pos, bool caretPosition = false, bool startOfLine = false) const;
1349
1350 /// Given a line number, get the corresponding wxRichTextLine object.
1351 virtual wxRichTextLine* GetLineForVisibleLineNumber(long lineNumber) const;
1352
1353 /// Get the leaf object in a paragraph at this position.
1354 /// Given a line number, get the corresponding wxRichTextLine object.
1355 virtual wxRichTextObject* GetLeafObjectAtPosition(long position) const;
1356
1357 /// Get the paragraph by number
1358 virtual wxRichTextParagraph* GetParagraphAtLine(long paragraphNumber) const;
1359
1360 /// Get the paragraph for a given line
1361 virtual wxRichTextParagraph* GetParagraphForLine(wxRichTextLine* line) const;
1362
1363 /// Get the length of the paragraph
1364 virtual int GetParagraphLength(long paragraphNumber) const;
1365
1366 /// Get the number of paragraphs
1367 virtual int GetParagraphCount() const { return static_cast<int>(GetChildCount()); }
1368
1369 /// Get the number of visible lines
1370 virtual int GetLineCount() const;
1371
1372 /// Get the text of the paragraph
1373 virtual wxString GetParagraphText(long paragraphNumber) const;
1374
1375 /// Convert zero-based line column and paragraph number to a position.
1376 virtual long XYToPosition(long x, long y) const;
1377
1378 /// Convert zero-based position to line column and paragraph number
1379 virtual bool PositionToXY(long pos, long* x, long* y) const;
1380
1381 /// Set text attributes: character and/or paragraph styles.
1382 virtual bool SetStyle(const wxRichTextRange& range, const wxRichTextAttr& style, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO);
1383
1384 /// Set image attribute
1385 void SetImageStyle(wxRichTextImage *image, const wxRichTextAttr& textAttr, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO);
1386
1387 /// Get the conbined text attributes for this position.
1388 virtual bool GetStyle(long position, wxRichTextAttr& style);
1389
1390 /// Get the content (uncombined) attributes for this position.
1391 virtual bool GetUncombinedStyle(long position, wxRichTextAttr& style);
1392
1393 /// Implementation helper for GetStyle. If combineStyles is true, combine base, paragraph and
1394 /// context attributes.
1395 virtual bool DoGetStyle(long position, wxRichTextAttr& style, bool combineStyles = true);
1396
1397 /// Get the combined style for a range - if any attribute is different within the range,
1398 /// that attribute is not present within the flags
1399 virtual bool GetStyleForRange(const wxRichTextRange& range, wxRichTextAttr& style);
1400
1401 /// Combines 'style' with 'currentStyle' for the purpose of summarising the attributes of a range of
1402 /// content.
1403 bool CollectStyle(wxRichTextAttr& currentStyle, const wxRichTextAttr& style, wxRichTextAttr& clashingAttr, wxRichTextAttr& absentAttr);
1404
1405 /// Set list style
1406 virtual bool SetListStyle(const wxRichTextRange& range, wxRichTextListStyleDefinition* def, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int startFrom = 1, int specifiedLevel = -1);
1407 virtual bool SetListStyle(const wxRichTextRange& range, const wxString& defName, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int startFrom = 1, int specifiedLevel = -1);
1408
1409 /// Clear list for given range
1410 virtual bool ClearListStyle(const wxRichTextRange& range, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO);
1411
1412 /// Number/renumber any list elements in the given range.
1413 /// def/defName can be NULL/empty to indicate that the existing list style should be used.
1414 virtual bool NumberList(const wxRichTextRange& range, wxRichTextListStyleDefinition* def = NULL, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int startFrom = 1, int specifiedLevel = -1);
1415 virtual bool NumberList(const wxRichTextRange& range, const wxString& defName, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int startFrom = 1, int specifiedLevel = -1);
1416
1417 /// Promote the list items within the given range. promoteBy can be a positive or negative number, e.g. 1 or -1
1418 /// def/defName can be NULL/empty to indicate that the existing list style should be used.
1419 virtual bool PromoteList(int promoteBy, const wxRichTextRange& range, wxRichTextListStyleDefinition* def = NULL, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int specifiedLevel = -1);
1420 virtual bool PromoteList(int promoteBy, const wxRichTextRange& range, const wxString& defName, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int specifiedLevel = -1);
1421
1422 /// Helper for NumberList and PromoteList, that does renumbering and promotion simultaneously
1423 /// def/defName can be NULL/empty to indicate that the existing list style should be used.
1424 virtual bool DoNumberList(const wxRichTextRange& range, const wxRichTextRange& promotionRange, int promoteBy, wxRichTextListStyleDefinition* def, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int startFrom = 1, int specifiedLevel = -1);
1425
1426 /// Fills in the attributes for numbering a paragraph after previousParagraph.
1427 virtual bool FindNextParagraphNumber(wxRichTextParagraph* previousParagraph, wxRichTextAttr& attr) const;
1428
1429 /// Test if this whole range has character attributes of the specified kind. If any
1430 /// of the attributes are different within the range, the test fails. You
1431 /// can use this to implement, for example, bold button updating. style must have
1432 /// flags indicating which attributes are of interest.
1433 virtual bool HasCharacterAttributes(const wxRichTextRange& range, const wxRichTextAttr& style) const;
1434
1435 /// Test if this whole range has paragraph attributes of the specified kind. If any
1436 /// of the attributes are different within the range, the test fails. You
1437 /// can use this to implement, for example, centering button updating. style must have
1438 /// flags indicating which attributes are of interest.
1439 virtual bool HasParagraphAttributes(const wxRichTextRange& range, const wxRichTextAttr& style) const;
1440
1441 /// Clone
1442 virtual wxRichTextObject* Clone() const { return new wxRichTextParagraphLayoutBox(*this); }
1443
1444 /// Insert fragment into this box at the given position. If partialParagraph is true,
1445 /// it is assumed that the last (or only) paragraph is just a piece of data with no paragraph
1446 /// marker.
1447 virtual bool InsertFragment(long position, wxRichTextParagraphLayoutBox& fragment);
1448
1449 /// Make a copy of the fragment corresponding to the given range, putting it in 'fragment'.
1450 virtual bool CopyFragment(const wxRichTextRange& range, wxRichTextParagraphLayoutBox& fragment);
1451
1452 /// Apply the style sheet to the buffer, for example if the styles have changed.
1453 virtual bool ApplyStyleSheet(wxRichTextStyleSheet* styleSheet);
1454
1455 /// Copy
1456 void Copy(const wxRichTextParagraphLayoutBox& obj);
1457
1458 /// Assignment
1459 void operator= (const wxRichTextParagraphLayoutBox& obj) { Copy(obj); }
1460
1461 /// Calculate ranges
1462 virtual void UpdateRanges() { long end; CalculateRange(0, end); }
1463
1464 /// Get all the text
1465 virtual wxString GetText() const;
1466
1467 /// Set default style for new content. Setting it to a default attribute
1468 /// makes new content take on the 'basic' style.
1469 virtual bool SetDefaultStyle(const wxRichTextAttr& style);
1470
1471 /// Get default style
1472 virtual const wxRichTextAttr& GetDefaultStyle() const { return m_defaultAttributes; }
1473
1474 /// Set basic (overall) style
1475 virtual void SetBasicStyle(const wxRichTextAttr& style) { m_attributes = style; }
1476
1477 /// Get basic (overall) style
1478 virtual const wxRichTextAttr& GetBasicStyle() const { return m_attributes; }
1479
1480 /// Invalidate the buffer. With no argument, invalidates whole buffer.
1481 void Invalidate(const wxRichTextRange& invalidRange = wxRICHTEXT_ALL);
1482
1483 /// Gather information about floating objects. If untilObj is non-NULL,
1484 /// will stop getting information if the current object is this, since we
1485 /// will collect the rest later.
1486 virtual bool UpdateFloatingObjects(int width, wxRichTextObject* untilObj = NULL);
1487
1488 /// Get invalid range, rounding to entire paragraphs if argument is true.
1489 wxRichTextRange GetInvalidRange(bool wholeParagraphs = false) const;
1490
1491 /// Get the wxRichTextFloatCollector of this object
1492 wxRichTextFloatCollector* GetFloatCollector() { return m_floatCollector; }
1493
1494 protected:
1495 wxRichTextCtrl* m_ctrl;
1496 wxRichTextAttr m_defaultAttributes;
1497
1498 /// The invalidated range that will need full layout
1499 wxRichTextRange m_invalidRange;
1500
1501 // Is the last paragraph partial or complete?
1502 bool m_partialParagraph;
1503
1504 // The floating layout state
1505 wxRichTextFloatCollector* m_floatCollector;
1506 };
1507
1508 /*!
1509 * wxRichTextBox class declaration
1510 * TODO: a floating text box
1511 */
1512
1513 class WXDLLIMPEXP_RICHTEXT wxRichTextBox: public wxRichTextParagraphLayoutBox
1514 {
1515 DECLARE_DYNAMIC_CLASS(wxRichTextBox)
1516 public:
1517 // Constructors
1518
1519 wxRichTextBox(wxRichTextObject* parent = NULL);
1520 wxRichTextBox(const wxRichTextBox& obj): wxRichTextParagraphLayoutBox() { Copy(obj); }
1521
1522 // Overrideables
1523
1524 /// Draw the item
1525 virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style);
1526
1527 /// Lay the item out
1528 virtual bool Layout(wxDC& dc, const wxRect& rect, int style);
1529
1530 // Accessors
1531
1532 // Operations
1533
1534 /// Clone
1535 virtual wxRichTextObject* Clone() const { return new wxRichTextBox(*this); }
1536
1537 /// Copy
1538 void Copy(const wxRichTextBox& obj);
1539
1540 protected:
1541 };
1542
1543 /*!
1544 * wxRichTextLine class declaration
1545 * This object represents a line in a paragraph, and stores
1546 * offsets from the start of the paragraph representing the
1547 * start and end positions of the line.
1548 */
1549
1550 class WXDLLIMPEXP_RICHTEXT wxRichTextLine
1551 {
1552 public:
1553 // Constructors
1554
1555 wxRichTextLine(wxRichTextParagraph* parent);
1556 wxRichTextLine(const wxRichTextLine& obj) { Init( NULL); Copy(obj); }
1557 virtual ~wxRichTextLine() {}
1558
1559 // Overrideables
1560
1561 // Accessors
1562
1563 /// Set the range
1564 void SetRange(const wxRichTextRange& range) { m_range = range; }
1565 void SetRange(long from, long to) { m_range = wxRichTextRange(from, to); }
1566
1567 /// Get the parent paragraph
1568 wxRichTextParagraph* GetParent() { return m_parent; }
1569
1570 /// Get the range
1571 const wxRichTextRange& GetRange() const { return m_range; }
1572 wxRichTextRange& GetRange() { return m_range; }
1573
1574 /// Get the absolute range
1575 wxRichTextRange GetAbsoluteRange() const;
1576
1577 /// Get/set the line size as calculated by Layout.
1578 virtual wxSize GetSize() const { return m_size; }
1579 virtual void SetSize(const wxSize& sz) { m_size = sz; }
1580
1581 /// Get/set the object position relative to the parent
1582 virtual wxPoint GetPosition() const { return m_pos; }
1583 virtual void SetPosition(const wxPoint& pos) { m_pos = pos; }
1584
1585 /// Get the absolute object position
1586 virtual wxPoint GetAbsolutePosition() const;
1587
1588 /// Get the rectangle enclosing the line
1589 virtual wxRect GetRect() const { return wxRect(GetAbsolutePosition(), GetSize()); }
1590
1591 /// Set/get stored descent
1592 void SetDescent(int descent) { m_descent = descent; }
1593 int GetDescent() const { return m_descent; }
1594
1595 #if wxRICHTEXT_USE_OPTIMIZED_LINE_DRAWING
1596 wxArrayInt& GetObjectSizes() { return m_objectSizes; }
1597 const wxArrayInt& GetObjectSizes() const { return m_objectSizes; }
1598 #endif
1599
1600 // Operations
1601
1602 /// Initialisation
1603 void Init(wxRichTextParagraph* parent);
1604
1605 /// Copy
1606 void Copy(const wxRichTextLine& obj);
1607
1608 /// Clone
1609 virtual wxRichTextLine* Clone() const { return new wxRichTextLine(*this); }
1610
1611 protected:
1612
1613 /// The range of the line (start position to end position)
1614 /// This is relative to the parent paragraph.
1615 wxRichTextRange m_range;
1616
1617 /// Size and position measured relative to top of paragraph
1618 wxPoint m_pos;
1619 wxSize m_size;
1620
1621 /// Maximum descent for this line (location of text baseline)
1622 int m_descent;
1623
1624 // The parent object
1625 wxRichTextParagraph* m_parent;
1626
1627 #if wxRICHTEXT_USE_OPTIMIZED_LINE_DRAWING
1628 wxArrayInt m_objectSizes;
1629 #endif
1630 };
1631
1632 WX_DECLARE_LIST_WITH_DECL( wxRichTextLine, wxRichTextLineList , class WXDLLIMPEXP_RICHTEXT );
1633
1634 /*!
1635 * wxRichTextParagraph class declaration
1636 * This object represents a single paragraph (or in a straight text editor, a line).
1637 */
1638
1639 class WXDLLIMPEXP_RICHTEXT wxRichTextParagraph: public wxRichTextBox
1640 {
1641 DECLARE_DYNAMIC_CLASS(wxRichTextParagraph)
1642 public:
1643 // Constructors
1644
1645 wxRichTextParagraph(wxRichTextObject* parent = NULL, wxRichTextAttr* style = NULL);
1646 wxRichTextParagraph(const wxString& text, wxRichTextObject* parent = NULL, wxRichTextAttr* paraStyle = NULL, wxRichTextAttr* charStyle = NULL);
1647 virtual ~wxRichTextParagraph();
1648 wxRichTextParagraph(const wxRichTextParagraph& obj): wxRichTextBox() { Copy(obj); }
1649
1650 // Overrideables
1651
1652 /// Draw the item
1653 virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style);
1654
1655 /// Lay the item out
1656 virtual bool Layout(wxDC& dc, const wxRect& rect, int style);
1657
1658 /// Get/set the object size for the given range. Returns false if the range
1659 /// is invalid for this object.
1660 virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const;
1661
1662 /// Finds the absolute position and row height for the given character position
1663 virtual bool FindPosition(wxDC& dc, long index, wxPoint& pt, int* height, bool forceLineStart);
1664
1665 /// Hit-testing: returns a flag indicating hit test details, plus
1666 /// information about position
1667 virtual int HitTest(wxDC& dc, const wxPoint& pt, long& textPosition);
1668
1669 /// Calculate range
1670 virtual void CalculateRange(long start, long& end);
1671
1672 /// What is the XML node name of this object?
1673 virtual wxString GetXMLNodeName() const { return wxT("paragraph"); }
1674
1675 // Accessors
1676
1677 /// Get the cached lines
1678 wxRichTextLineList& GetLines() { return m_cachedLines; }
1679
1680 // Operations
1681
1682 /// Copy
1683 void Copy(const wxRichTextParagraph& obj);
1684
1685 /// Clone
1686 virtual wxRichTextObject* Clone() const { return new wxRichTextParagraph(*this); }
1687
1688 /// Clear the cached lines
1689 void ClearLines();
1690
1691 // Implementation
1692
1693 /// Apply paragraph styles such as centering to the wrapped lines
1694 virtual void ApplyParagraphStyle(const wxRichTextAttr& attr, const wxRect& rect, wxDC& dc);
1695
1696 /// Insert text at the given position
1697 virtual bool InsertText(long pos, const wxString& text);
1698
1699 /// Split an object at this position if necessary, and return
1700 /// the previous object, or NULL if inserting at beginning.
1701 virtual wxRichTextObject* SplitAt(long pos, wxRichTextObject** previousObject = NULL);
1702
1703 /// Move content to a list from this point
1704 virtual void MoveToList(wxRichTextObject* obj, wxList& list);
1705
1706 /// Add content back from list
1707 virtual void MoveFromList(wxList& list);
1708
1709 /// Get the plain text searching from the start or end of the range.
1710 /// The resulting string may be shorter than the range given.
1711 bool GetContiguousPlainText(wxString& text, const wxRichTextRange& range, bool fromStart = true);
1712
1713 /// Find a suitable wrap position. wrapPosition is the last position in the line to the left
1714 /// of the split.
1715 bool FindWrapPosition(const wxRichTextRange& range, wxDC& dc, int availableSpace, long& wrapPosition, wxArrayInt* partialExtents);
1716
1717 /// Find the object at the given position
1718 wxRichTextObject* FindObjectAtPosition(long position);
1719
1720 /// Get the bullet text for this paragraph.
1721 wxString GetBulletText();
1722
1723 /// Allocate or reuse a line object
1724 wxRichTextLine* AllocateLine(int pos);
1725
1726 /// Clear remaining unused line objects, if any
1727 bool ClearUnusedLines(int lineCount);
1728
1729 /// Get combined attributes of the base style, paragraph style and character style. We use this to dynamically
1730 /// retrieve the actual style.
1731 wxRichTextAttr GetCombinedAttributes(const wxRichTextAttr& contentStyle) const;
1732
1733 /// Get combined attributes of the base style and paragraph style.
1734 wxRichTextAttr GetCombinedAttributes() const;
1735
1736 /// Get the first position from pos that has a line break character.
1737 long GetFirstLineBreakPosition(long pos);
1738
1739 /// Create default tabstop array
1740 static void InitDefaultTabs();
1741
1742 /// Clear default tabstop array
1743 static void ClearDefaultTabs();
1744
1745 /// Get default tabstop array
1746 static const wxArrayInt& GetDefaultTabs() { return sm_defaultTabs; }
1747
1748 /// Layout the floats object
1749 void LayoutFloat(wxDC& dc, const wxRect& rect, int style, wxRichTextFloatCollector* floatCollector);
1750
1751 protected:
1752 /// The lines that make up the wrapped paragraph
1753 wxRichTextLineList m_cachedLines;
1754
1755 /// Default tabstops
1756 static wxArrayInt sm_defaultTabs;
1757
1758 friend class wxRichTextFloatCollector;
1759 };
1760
1761 /*!
1762 * wxRichTextPlainText class declaration
1763 * This object represents a single piece of text.
1764 */
1765
1766 class WXDLLIMPEXP_RICHTEXT wxRichTextPlainText: public wxRichTextObject
1767 {
1768 DECLARE_DYNAMIC_CLASS(wxRichTextPlainText)
1769 public:
1770 // Constructors
1771
1772 wxRichTextPlainText(const wxString& text = wxEmptyString, wxRichTextObject* parent = NULL, wxRichTextAttr* style = NULL);
1773 wxRichTextPlainText(const wxRichTextPlainText& obj): wxRichTextObject() { Copy(obj); }
1774
1775 // Overrideables
1776
1777 /// Draw the item
1778 virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style);
1779
1780 /// Lay the item out
1781 virtual bool Layout(wxDC& dc, const wxRect& rect, int style);
1782
1783 /// Get/set the object size for the given range. Returns false if the range
1784 /// is invalid for this object.
1785 virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const;
1786
1787 /// Get any text in this object for the given range
1788 virtual wxString GetTextForRange(const wxRichTextRange& range) const;
1789
1790 /// Do a split, returning an object containing the second part, and setting
1791 /// the first part in 'this'.
1792 virtual wxRichTextObject* DoSplit(long pos);
1793
1794 /// Calculate range
1795 virtual void CalculateRange(long start, long& end);
1796
1797 /// Delete range
1798 virtual bool DeleteRange(const wxRichTextRange& range);
1799
1800 /// Returns true if the object is empty
1801 virtual bool IsEmpty() const { return m_text.empty(); }
1802
1803 /// Returns true if this object can merge itself with the given one.
1804 virtual bool CanMerge(wxRichTextObject* object) const;
1805
1806 /// Returns true if this object merged itself with the given one.
1807 /// The calling code will then delete the given object.
1808 virtual bool Merge(wxRichTextObject* object);
1809
1810 /// Dump to output stream for debugging
1811 virtual void Dump(wxTextOutputStream& stream);
1812
1813 /// Get the first position from pos that has a line break character.
1814 long GetFirstLineBreakPosition(long pos);
1815
1816 /// Does this object take note of paragraph attributes? Text and image objects don't.
1817 virtual bool UsesParagraphAttributes() const { return false; }
1818
1819 #if wxUSE_XML
1820 /// Import this object from XML
1821 virtual bool ImportFromXML(wxRichTextBuffer* buffer, wxXmlNode* node, wxRichTextXMLHandler* handler);
1822 #endif
1823
1824 #if wxRICHTEXT_HAVE_DIRECT_OUTPUT
1825 /// Export this object directly to the given stream.
1826 virtual bool ExportXML(wxOutputStream& stream, int indent, wxRichTextXMLHandler* handler);
1827 #endif
1828
1829 #if wxRICHTEXT_HAVE_XMLDOCUMENT_OUTPUT
1830 /// Export this object to the given parent node, usually creating at least one child node.
1831 virtual bool ExportXML(wxXmlNode* parent, wxRichTextXMLHandler* handler);
1832 #endif
1833
1834 /// What is the XML node name of this object?
1835 virtual wxString GetXMLNodeName() const { return wxT("text"); }
1836
1837 // Accessors
1838
1839 /// Get the text
1840 const wxString& GetText() const { return m_text; }
1841
1842 /// Set the text
1843 void SetText(const wxString& text) { m_text = text; }
1844
1845 // Operations
1846
1847 /// Copy
1848 void Copy(const wxRichTextPlainText& obj);
1849
1850 /// Clone
1851 virtual wxRichTextObject* Clone() const { return new wxRichTextPlainText(*this); }
1852 private:
1853 bool DrawTabbedString(wxDC& dc, const wxRichTextAttr& attr, const wxRect& rect, wxString& str, wxCoord& x, wxCoord& y, bool selected);
1854
1855 protected:
1856 wxString m_text;
1857 };
1858
1859 /*!
1860 * wxRichTextImageBlock stores information about an image, in binary in-memory form
1861 */
1862
1863 class WXDLLIMPEXP_FWD_BASE wxDataInputStream;
1864 class WXDLLIMPEXP_FWD_BASE wxDataOutputStream;
1865
1866 class WXDLLIMPEXP_RICHTEXT wxRichTextImageBlock: public wxObject
1867 {
1868 public:
1869 wxRichTextImageBlock();
1870 wxRichTextImageBlock(const wxRichTextImageBlock& block);
1871 virtual ~wxRichTextImageBlock();
1872
1873 void Init();
1874 void Clear();
1875
1876 // Load the original image into a memory block.
1877 // If the image is not a JPEG, we must convert it into a JPEG
1878 // to conserve space.
1879 // If it's not a JPEG we can make use of 'image', already scaled, so we don't have to
1880 // load the image a 2nd time.
1881 virtual bool MakeImageBlock(const wxString& filename, wxBitmapType imageType,
1882 wxImage& image, bool convertToJPEG = true);
1883
1884 // Make an image block from the wxImage in the given
1885 // format.
1886 virtual bool MakeImageBlock(wxImage& image, wxBitmapType imageType, int quality = 80);
1887
1888 // Uses a const wxImage for efficiency, but can't set quality (only relevant for JPEG)
1889 virtual bool MakeImageBlockDefaultQuality(const wxImage& image, wxBitmapType imageType);
1890
1891 // Makes the image block
1892 virtual bool DoMakeImageBlock(const wxImage& image, wxBitmapType imageType);
1893
1894 // Write to a file
1895 bool Write(const wxString& filename);
1896
1897 // Write data in hex to a stream
1898 bool WriteHex(wxOutputStream& stream);
1899
1900 // Read data in hex from a stream
1901 bool ReadHex(wxInputStream& stream, int length, wxBitmapType imageType);
1902
1903 // Copy from 'block'
1904 void Copy(const wxRichTextImageBlock& block);
1905
1906 // Load a wxImage from the block
1907 bool Load(wxImage& image);
1908
1909 //// Operators
1910 void operator=(const wxRichTextImageBlock& block);
1911
1912 //// Accessors
1913
1914 unsigned char* GetData() const { return m_data; }
1915 size_t GetDataSize() const { return m_dataSize; }
1916 wxBitmapType GetImageType() const { return m_imageType; }
1917
1918 void SetData(unsigned char* image) { m_data = image; }
1919 void SetDataSize(size_t size) { m_dataSize = size; }
1920 void SetImageType(wxBitmapType imageType) { m_imageType = imageType; }
1921
1922 bool Ok() const { return IsOk(); }
1923 bool IsOk() const { return GetData() != NULL; }
1924
1925 // Gets the extension for the block's type
1926 wxString GetExtension() const;
1927
1928 /// Implementation
1929
1930 // Allocate and read from stream as a block of memory
1931 static unsigned char* ReadBlock(wxInputStream& stream, size_t size);
1932 static unsigned char* ReadBlock(const wxString& filename, size_t size);
1933
1934 // Write memory block to stream
1935 static bool WriteBlock(wxOutputStream& stream, unsigned char* block, size_t size);
1936
1937 // Write memory block to file
1938 static bool WriteBlock(const wxString& filename, unsigned char* block, size_t size);
1939
1940 protected:
1941 // Size in bytes of the image stored.
1942 // This is in the raw, original form such as a JPEG file.
1943 unsigned char* m_data;
1944 size_t m_dataSize;
1945 wxBitmapType m_imageType;
1946 };
1947
1948 /*!
1949 * wxRichTextImage class declaration
1950 * This object represents an image.
1951 */
1952
1953 class WXDLLIMPEXP_RICHTEXT wxRichTextImage: public wxRichTextObject
1954 {
1955 DECLARE_DYNAMIC_CLASS(wxRichTextImage)
1956 public:
1957 // Constructors
1958
1959 wxRichTextImage(wxRichTextObject* parent = NULL): wxRichTextObject(parent) { }
1960 wxRichTextImage(const wxImage& image, wxRichTextObject* parent = NULL, wxRichTextAttr* charStyle = NULL);
1961 wxRichTextImage(const wxRichTextImageBlock& imageBlock, wxRichTextObject* parent = NULL, wxRichTextAttr* charStyle = NULL);
1962 wxRichTextImage(const wxRichTextImage& obj): wxRichTextObject(obj) { Copy(obj); }
1963
1964 // Overrideables
1965
1966 /// Draw the item
1967 virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style);
1968
1969 /// Lay the item out
1970 virtual bool Layout(wxDC& dc, const wxRect& rect, int style);
1971
1972 /// Get the object size for the given range. Returns false if the range
1973 /// is invalid for this object.
1974 virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const;
1975
1976 /// Returns true if the object is empty. An image is never empty; if the image is broken, that's not the same thing as empty.
1977 virtual bool IsEmpty() const { return false; /* !m_imageBlock.Ok(); */ }
1978
1979 /// Can we edit properties via a GUI?
1980 virtual bool CanEditProperties() const { return true; }
1981
1982 /// Edit properties via a GUI
1983 virtual bool EditProperties(wxWindow* parent, wxRichTextBuffer* buffer);
1984
1985 /// Does this object take note of paragraph attributes? Text and image objects don't.
1986 virtual bool UsesParagraphAttributes() const { return false; }
1987
1988 #if wxUSE_XML
1989 /// Import this object from XML
1990 virtual bool ImportFromXML(wxRichTextBuffer* buffer, wxXmlNode* node, wxRichTextXMLHandler* handler);
1991 #endif
1992
1993 #if wxRICHTEXT_HAVE_DIRECT_OUTPUT
1994 /// Export this object directly to the given stream.
1995 virtual bool ExportXML(wxOutputStream& stream, int indent, wxRichTextXMLHandler* handler);
1996 #endif
1997
1998 #if wxRICHTEXT_HAVE_XMLDOCUMENT_OUTPUT
1999 /// Export this object to the given parent node, usually creating at least one child node.
2000 virtual bool ExportXML(wxXmlNode* parent, wxRichTextXMLHandler* handler);
2001 #endif
2002
2003 // Images can be floatable (optionally).
2004 virtual bool IsFloatable() const { return true; }
2005
2006 /// What is the XML node name of this object?
2007 virtual wxString GetXMLNodeName() const { return wxT("image"); }
2008
2009 // Accessors
2010
2011 /// Get the image cache (scaled bitmap)
2012 const wxBitmap& GetImageCache() const { return m_imageCache; }
2013
2014 /// Set the image cache
2015 void SetImageCache(const wxBitmap& bitmap) { m_imageCache = bitmap; }
2016
2017 /// Reset the image cache
2018 void ResetImageCache() { m_imageCache = wxNullBitmap; }
2019
2020 /// Get the image block containing the raw data
2021 wxRichTextImageBlock& GetImageBlock() { return m_imageBlock; }
2022
2023 // Operations
2024
2025 /// Copy
2026 void Copy(const wxRichTextImage& obj);
2027
2028 /// Clone
2029 virtual wxRichTextObject* Clone() const { return new wxRichTextImage(*this); }
2030
2031 /// Create a cached image at the required size
2032 virtual bool LoadImageCache(wxDC& dc, bool resetCache = false);
2033
2034 protected:
2035 wxRichTextImageBlock m_imageBlock;
2036 wxBitmap m_imageCache;
2037 };
2038
2039
2040 /*!
2041 * wxRichTextBuffer class declaration
2042 * This is a kind of box, used to represent the whole buffer
2043 */
2044
2045 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextCommand;
2046 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextAction;
2047
2048 class WXDLLIMPEXP_RICHTEXT wxRichTextBuffer: public wxRichTextParagraphLayoutBox
2049 {
2050 DECLARE_DYNAMIC_CLASS(wxRichTextBuffer)
2051 public:
2052 // Constructors
2053
2054 wxRichTextBuffer() { Init(); }
2055 wxRichTextBuffer(const wxRichTextBuffer& obj): wxRichTextParagraphLayoutBox() { Init(); Copy(obj); }
2056 virtual ~wxRichTextBuffer() ;
2057
2058 // Accessors
2059
2060 /// Gets the command processor
2061 wxCommandProcessor* GetCommandProcessor() const { return m_commandProcessor; }
2062
2063 /// Set style sheet, if any.
2064 void SetStyleSheet(wxRichTextStyleSheet* styleSheet) { m_styleSheet = styleSheet; }
2065 virtual wxRichTextStyleSheet* GetStyleSheet() const { return m_styleSheet; }
2066
2067 /// Set style sheet and notify of the change
2068 bool SetStyleSheetAndNotify(wxRichTextStyleSheet* sheet);
2069
2070 /// Push style sheet to top of stack
2071 bool PushStyleSheet(wxRichTextStyleSheet* styleSheet);
2072
2073 /// Pop style sheet from top of stack
2074 wxRichTextStyleSheet* PopStyleSheet();
2075
2076 /// Set/get table storing fonts
2077 wxRichTextFontTable& GetFontTable() { return m_fontTable; }
2078 const wxRichTextFontTable& GetFontTable() const { return m_fontTable; }
2079 void SetFontTable(const wxRichTextFontTable& table) { m_fontTable = table; }
2080
2081 // Operations
2082
2083 /// Initialisation
2084 void Init();
2085
2086 /// Clears the buffer, adds an empty paragraph, and clears the command processor.
2087 virtual void ResetAndClearCommands();
2088
2089 /// Load a file
2090 virtual bool LoadFile(const wxString& filename, wxRichTextFileType type = wxRICHTEXT_TYPE_ANY);
2091
2092 /// Save a file
2093 virtual bool SaveFile(const wxString& filename, wxRichTextFileType type = wxRICHTEXT_TYPE_ANY);
2094
2095 /// Load from a stream
2096 virtual bool LoadFile(wxInputStream& stream, wxRichTextFileType type = wxRICHTEXT_TYPE_ANY);
2097
2098 /// Save to a stream
2099 virtual bool SaveFile(wxOutputStream& stream, wxRichTextFileType type = wxRICHTEXT_TYPE_ANY);
2100
2101 /// Set the handler flags, controlling loading and saving
2102 void SetHandlerFlags(int flags) { m_handlerFlags = flags; }
2103
2104 /// Get the handler flags, controlling loading and saving
2105 int GetHandlerFlags() const { return m_handlerFlags; }
2106
2107 /// Convenience function to add a paragraph of text
2108 virtual wxRichTextRange AddParagraph(const wxString& text, wxRichTextAttr* paraStyle = NULL) { Modify(); return wxRichTextParagraphLayoutBox::AddParagraph(text, paraStyle); }
2109
2110 /// Begin collapsing undo/redo commands. Note that this may not work properly
2111 /// if combining commands that delete or insert content, changing ranges for
2112 /// subsequent actions.
2113 virtual bool BeginBatchUndo(const wxString& cmdName);
2114
2115 /// End collapsing undo/redo commands
2116 virtual bool EndBatchUndo();
2117
2118 /// Collapsing commands?
2119 virtual bool BatchingUndo() const { return m_batchedCommandDepth > 0; }
2120
2121 /// Submit immediately, or delay according to whether collapsing is on
2122 virtual bool SubmitAction(wxRichTextAction* action);
2123
2124 /// Get collapsed command
2125 virtual wxRichTextCommand* GetBatchedCommand() const { return m_batchedCommand; }
2126
2127 /// Begin suppressing undo/redo commands. The way undo is suppressed may be implemented
2128 /// differently by each command. If not dealt with by a command implementation, then
2129 /// it will be implemented automatically by not storing the command in the undo history
2130 /// when the action is submitted to the command processor.
2131 virtual bool BeginSuppressUndo();
2132
2133 /// End suppressing undo/redo commands.
2134 virtual bool EndSuppressUndo();
2135
2136 /// Collapsing commands?
2137 virtual bool SuppressingUndo() const { return m_suppressUndo > 0; }
2138
2139 /// Copy the range to the clipboard
2140 virtual bool CopyToClipboard(const wxRichTextRange& range);
2141
2142 /// Paste the clipboard content to the buffer
2143 virtual bool PasteFromClipboard(long position);
2144
2145 /// Can we paste from the clipboard?
2146 virtual bool CanPasteFromClipboard() const;
2147
2148 /// Begin using a style
2149 virtual bool BeginStyle(const wxRichTextAttr& style);
2150
2151 /// End the style
2152 virtual bool EndStyle();
2153
2154 /// End all styles
2155 virtual bool EndAllStyles();
2156
2157 /// Clear the style stack
2158 virtual void ClearStyleStack();
2159
2160 /// Get the size of the style stack, for example to check correct nesting
2161 virtual size_t GetStyleStackSize() const { return m_attributeStack.GetCount(); }
2162
2163 /// Begin using bold
2164 bool BeginBold();
2165
2166 /// End using bold
2167 bool EndBold() { return EndStyle(); }
2168
2169 /// Begin using italic
2170 bool BeginItalic();
2171
2172 /// End using italic
2173 bool EndItalic() { return EndStyle(); }
2174
2175 /// Begin using underline
2176 bool BeginUnderline();
2177
2178 /// End using underline
2179 bool EndUnderline() { return EndStyle(); }
2180
2181 /// Begin using point size
2182 bool BeginFontSize(int pointSize);
2183
2184 /// End using point size
2185 bool EndFontSize() { return EndStyle(); }
2186
2187 /// Begin using this font
2188 bool BeginFont(const wxFont& font);
2189
2190 /// End using a font
2191 bool EndFont() { return EndStyle(); }
2192
2193 /// Begin using this colour
2194 bool BeginTextColour(const wxColour& colour);
2195
2196 /// End using a colour
2197 bool EndTextColour() { return EndStyle(); }
2198
2199 /// Begin using alignment
2200 bool BeginAlignment(wxTextAttrAlignment alignment);
2201
2202 /// End alignment
2203 bool EndAlignment() { return EndStyle(); }
2204
2205 /// Begin left indent
2206 bool BeginLeftIndent(int leftIndent, int leftSubIndent = 0);
2207
2208 /// End left indent
2209 bool EndLeftIndent() { return EndStyle(); }
2210
2211 /// Begin right indent
2212 bool BeginRightIndent(int rightIndent);
2213
2214 /// End right indent
2215 bool EndRightIndent() { return EndStyle(); }
2216
2217 /// Begin paragraph spacing
2218 bool BeginParagraphSpacing(int before, int after);
2219
2220 /// End paragraph spacing
2221 bool EndParagraphSpacing() { return EndStyle(); }
2222
2223 /// Begin line spacing
2224 bool BeginLineSpacing(int lineSpacing);
2225
2226 /// End line spacing
2227 bool EndLineSpacing() { return EndStyle(); }
2228
2229 /// Begin numbered bullet
2230 bool BeginNumberedBullet(int bulletNumber, int leftIndent, int leftSubIndent, int bulletStyle = wxTEXT_ATTR_BULLET_STYLE_ARABIC|wxTEXT_ATTR_BULLET_STYLE_PERIOD);
2231
2232 /// End numbered bullet
2233 bool EndNumberedBullet() { return EndStyle(); }
2234
2235 /// Begin symbol bullet
2236 bool BeginSymbolBullet(const wxString& symbol, int leftIndent, int leftSubIndent, int bulletStyle = wxTEXT_ATTR_BULLET_STYLE_SYMBOL);
2237
2238 /// End symbol bullet
2239 bool EndSymbolBullet() { return EndStyle(); }
2240
2241 /// Begin standard bullet
2242 bool BeginStandardBullet(const wxString& bulletName, int leftIndent, int leftSubIndent, int bulletStyle = wxTEXT_ATTR_BULLET_STYLE_STANDARD);
2243
2244 /// End standard bullet
2245 bool EndStandardBullet() { return EndStyle(); }
2246
2247 /// Begin named character style
2248 bool BeginCharacterStyle(const wxString& characterStyle);
2249
2250 /// End named character style
2251 bool EndCharacterStyle() { return EndStyle(); }
2252
2253 /// Begin named paragraph style
2254 bool BeginParagraphStyle(const wxString& paragraphStyle);
2255
2256 /// End named character style
2257 bool EndParagraphStyle() { return EndStyle(); }
2258
2259 /// Begin named list style
2260 bool BeginListStyle(const wxString& listStyle, int level = 1, int number = 1);
2261
2262 /// End named character style
2263 bool EndListStyle() { return EndStyle(); }
2264
2265 /// Begin URL
2266 bool BeginURL(const wxString& url, const wxString& characterStyle = wxEmptyString);
2267
2268 /// End URL
2269 bool EndURL() { return EndStyle(); }
2270
2271 // Event handling
2272
2273 /// Add an event handler
2274 bool AddEventHandler(wxEvtHandler* handler);
2275
2276 /// Remove an event handler
2277 bool RemoveEventHandler(wxEvtHandler* handler, bool deleteHandler = false);
2278
2279 /// Clear event handlers
2280 void ClearEventHandlers();
2281
2282 /// Send event to event handlers. If sendToAll is true, will send to all event handlers,
2283 /// otherwise will stop at the first successful one.
2284 bool SendEvent(wxEvent& event, bool sendToAll = true);
2285
2286 // Implementation
2287
2288 /// Copy
2289 void Copy(const wxRichTextBuffer& obj);
2290
2291 /// Assignment
2292 void operator= (const wxRichTextBuffer& obj) { Copy(obj); }
2293
2294 /// Clone
2295 virtual wxRichTextObject* Clone() const { return new wxRichTextBuffer(*this); }
2296
2297 /// Submit command to insert paragraphs
2298 bool InsertParagraphsWithUndo(long pos, const wxRichTextParagraphLayoutBox& paragraphs, wxRichTextCtrl* ctrl, int flags = 0);
2299
2300 /// Submit command to insert the given text
2301 bool InsertTextWithUndo(long pos, const wxString& text, wxRichTextCtrl* ctrl, int flags = 0);
2302
2303 /// Submit command to insert a newline
2304 bool InsertNewlineWithUndo(long pos, wxRichTextCtrl* ctrl, int flags = 0);
2305
2306 /// Submit command to insert the given image
2307 bool InsertImageWithUndo(long pos, const wxRichTextImageBlock& imageBlock, wxRichTextCtrl* ctrl, int flags = 0,
2308 const wxRichTextAttr& textAttr = wxRichTextAttr());
2309
2310 /// Submit command to insert an object
2311 bool InsertObjectWithUndo(long pos, wxRichTextObject *object, wxRichTextCtrl* ctrl, int flags);
2312
2313 /// Submit command to delete this range
2314 bool DeleteRangeWithUndo(const wxRichTextRange& range, wxRichTextCtrl* ctrl);
2315
2316 /// Mark modified
2317 void Modify(bool modify = true) { m_modified = modify; }
2318 bool IsModified() const { return m_modified; }
2319
2320 /// Get the style that is appropriate for a new paragraph at this position.
2321 /// If the previous paragraph has a paragraph style name, look up the next-paragraph
2322 /// style.
2323 wxRichTextAttr GetStyleForNewParagraph(long pos, bool caretPosition = false, bool lookUpNewParaStyle=false) const;
2324
2325 /// Dumps contents of buffer for debugging purposes
2326 virtual void Dump();
2327 virtual void Dump(wxTextOutputStream& stream) { wxRichTextParagraphLayoutBox::Dump(stream); }
2328
2329 /// Returns the file handlers
2330 static wxList& GetHandlers() { return sm_handlers; }
2331
2332 /// Adds a handler to the end
2333 static void AddHandler(wxRichTextFileHandler *handler);
2334
2335 /// Inserts a handler at the front
2336 static void InsertHandler(wxRichTextFileHandler *handler);
2337
2338 /// Removes a handler
2339 static bool RemoveHandler(const wxString& name);
2340
2341 /// Finds a handler by name
2342 static wxRichTextFileHandler *FindHandler(const wxString& name);
2343
2344 /// Finds a handler by extension and type
2345 static wxRichTextFileHandler *FindHandler(const wxString& extension, wxRichTextFileType imageType);
2346
2347 /// Finds a handler by filename or, if supplied, type
2348 static wxRichTextFileHandler *FindHandlerFilenameOrType(const wxString& filename,
2349 wxRichTextFileType imageType);
2350
2351 /// Finds a handler by type
2352 static wxRichTextFileHandler *FindHandler(wxRichTextFileType imageType);
2353
2354 /// Gets a wildcard incorporating all visible handlers. If 'types' is present,
2355 /// will be filled with the file type corresponding to each filter. This can be
2356 /// used to determine the type to pass to LoadFile given a selected filter.
2357 static wxString GetExtWildcard(bool combine = false, bool save = false, wxArrayInt* types = NULL);
2358
2359 /// Clean up handlers
2360 static void CleanUpHandlers();
2361
2362 /// Initialise the standard handlers
2363 static void InitStandardHandlers();
2364
2365 /// Get renderer
2366 static wxRichTextRenderer* GetRenderer() { return sm_renderer; }
2367
2368 /// Set renderer, deleting old one
2369 static void SetRenderer(wxRichTextRenderer* renderer);
2370
2371 /// Minimum margin between bullet and paragraph in 10ths of a mm
2372 static int GetBulletRightMargin() { return sm_bulletRightMargin; }
2373 static void SetBulletRightMargin(int margin) { sm_bulletRightMargin = margin; }
2374
2375 /// Factor to multiply by character height to get a reasonable bullet size
2376 static float GetBulletProportion() { return sm_bulletProportion; }
2377 static void SetBulletProportion(float prop) { sm_bulletProportion = prop; }
2378
2379 /// Scale factor for calculating dimensions
2380 double GetScale() const { return m_scale; }
2381 void SetScale(double scale) { m_scale = scale; }
2382
2383 protected:
2384
2385 /// Command processor
2386 wxCommandProcessor* m_commandProcessor;
2387
2388 /// Table storing fonts
2389 wxRichTextFontTable m_fontTable;
2390
2391 /// Has been modified?
2392 bool m_modified;
2393
2394 /// Collapsed command stack
2395 int m_batchedCommandDepth;
2396
2397 /// Name for collapsed command
2398 wxString m_batchedCommandsName;
2399
2400 /// Current collapsed command accumulating actions
2401 wxRichTextCommand* m_batchedCommand;
2402
2403 /// Whether to suppress undo
2404 int m_suppressUndo;
2405
2406 /// Style sheet, if any
2407 wxRichTextStyleSheet* m_styleSheet;
2408
2409 /// List of event handlers that will be notified of events
2410 wxList m_eventHandlers;
2411
2412 /// Stack of attributes for convenience functions
2413 wxList m_attributeStack;
2414
2415 /// Flags to be passed to handlers
2416 int m_handlerFlags;
2417
2418 /// File handlers
2419 static wxList sm_handlers;
2420
2421 /// Renderer
2422 static wxRichTextRenderer* sm_renderer;
2423
2424 /// Minimum margin between bullet and paragraph in 10ths of a mm
2425 static int sm_bulletRightMargin;
2426
2427 /// Factor to multiply by character height to get a reasonable bullet size
2428 static float sm_bulletProportion;
2429
2430 /// Scaling factor in use: needed to calculate correct dimensions when printing
2431 double m_scale;
2432 };
2433
2434 /*!
2435 * The command identifiers
2436 *
2437 */
2438
2439 enum wxRichTextCommandId
2440 {
2441 wxRICHTEXT_INSERT,
2442 wxRICHTEXT_DELETE,
2443 wxRICHTEXT_CHANGE_STYLE
2444 };
2445
2446 /*!
2447 * Command classes for undo/redo
2448 *
2449 */
2450
2451 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextAction;
2452 class WXDLLIMPEXP_RICHTEXT wxRichTextCommand: public wxCommand
2453 {
2454 public:
2455 // Ctor for one action
2456 wxRichTextCommand(const wxString& name, wxRichTextCommandId id, wxRichTextBuffer* buffer,
2457 wxRichTextCtrl* ctrl, bool ignoreFirstTime = false);
2458
2459 // Ctor for multiple actions
2460 wxRichTextCommand(const wxString& name);
2461
2462 virtual ~wxRichTextCommand();
2463
2464 bool Do();
2465 bool Undo();
2466
2467 void AddAction(wxRichTextAction* action);
2468 void ClearActions();
2469
2470 wxList& GetActions() { return m_actions; }
2471
2472 protected:
2473
2474 wxList m_actions;
2475 };
2476
2477 /*!
2478 * wxRichTextAction class declaration
2479 * There can be more than one action in a command.
2480 */
2481
2482 class WXDLLIMPEXP_RICHTEXT wxRichTextAction: public wxObject
2483 {
2484 public:
2485 wxRichTextAction(wxRichTextCommand* cmd, const wxString& name, wxRichTextCommandId id, wxRichTextBuffer* buffer,
2486 wxRichTextCtrl* ctrl, bool ignoreFirstTime = false);
2487
2488 virtual ~wxRichTextAction();
2489
2490 bool Do();
2491 bool Undo();
2492
2493 /// Update the control appearance
2494 void UpdateAppearance(long caretPosition, bool sendUpdateEvent = false,
2495 wxArrayInt* optimizationLineCharPositions = NULL, wxArrayInt* optimizationLineYPositions = NULL, bool isDoCmd = true);
2496
2497 /// Replace the buffer paragraphs with the given fragment.
2498 void ApplyParagraphs(const wxRichTextParagraphLayoutBox& fragment);
2499
2500 /// Get the fragments
2501 wxRichTextParagraphLayoutBox& GetNewParagraphs() { return m_newParagraphs; }
2502 wxRichTextParagraphLayoutBox& GetOldParagraphs() { return m_oldParagraphs; }
2503
2504 /// Calculate arrays for refresh optimization
2505 void CalculateRefreshOptimizations(wxArrayInt& optimizationLineCharPositions, wxArrayInt& optimizationLineYPositions);
2506
2507 /// Set/get the position used for e.g. insertion
2508 void SetPosition(long pos) { m_position = pos; }
2509 long GetPosition() const { return m_position; }
2510
2511 /// Set/get the range for e.g. deletion
2512 void SetRange(const wxRichTextRange& range) { m_range = range; }
2513 const wxRichTextRange& GetRange() const { return m_range; }
2514
2515 /// Get name
2516 const wxString& GetName() const { return m_name; }
2517
2518 protected:
2519 // Action name
2520 wxString m_name;
2521
2522 // Buffer
2523 wxRichTextBuffer* m_buffer;
2524
2525 // Control
2526 wxRichTextCtrl* m_ctrl;
2527
2528 // Stores the new paragraphs
2529 wxRichTextParagraphLayoutBox m_newParagraphs;
2530
2531 // Stores the old paragraphs
2532 wxRichTextParagraphLayoutBox m_oldParagraphs;
2533
2534 // The affected range
2535 wxRichTextRange m_range;
2536
2537 // The insertion point for this command
2538 long m_position;
2539
2540 // Ignore 1st 'Do' operation because we already did it
2541 bool m_ignoreThis;
2542
2543 // The command identifier
2544 wxRichTextCommandId m_cmdId;
2545 };
2546
2547 /*!
2548 * Handler flags
2549 */
2550
2551 // Include style sheet when loading and saving
2552 #define wxRICHTEXT_HANDLER_INCLUDE_STYLESHEET 0x0001
2553
2554 // Save images to memory file system in HTML handler
2555 #define wxRICHTEXT_HANDLER_SAVE_IMAGES_TO_MEMORY 0x0010
2556
2557 // Save images to files in HTML handler
2558 #define wxRICHTEXT_HANDLER_SAVE_IMAGES_TO_FILES 0x0020
2559
2560 // Save images as inline base64 data in HTML handler
2561 #define wxRICHTEXT_HANDLER_SAVE_IMAGES_TO_BASE64 0x0040
2562
2563 // Don't write header and footer (or BODY), so we can include the fragment
2564 // in a larger document
2565 #define wxRICHTEXT_HANDLER_NO_HEADER_FOOTER 0x0080
2566
2567 // Convert the more common face names to names that will work on the current platform
2568 // in a larger document
2569 #define wxRICHTEXT_HANDLER_CONVERT_FACENAMES 0x0100
2570
2571 /*!
2572 * wxRichTextFileHandler
2573 * Base class for file handlers
2574 */
2575
2576 class WXDLLIMPEXP_RICHTEXT wxRichTextFileHandler: public wxObject
2577 {
2578 DECLARE_CLASS(wxRichTextFileHandler)
2579 public:
2580 wxRichTextFileHandler(const wxString& name = wxEmptyString, const wxString& ext = wxEmptyString, int type = 0)
2581 : m_name(name), m_extension(ext), m_type(type), m_flags(0), m_visible(true)
2582 { }
2583
2584 #if wxUSE_STREAMS
2585 bool LoadFile(wxRichTextBuffer *buffer, wxInputStream& stream)
2586 { return DoLoadFile(buffer, stream); }
2587 bool SaveFile(wxRichTextBuffer *buffer, wxOutputStream& stream)
2588 { return DoSaveFile(buffer, stream); }
2589 #endif
2590
2591 #if wxUSE_FFILE && wxUSE_STREAMS
2592 virtual bool LoadFile(wxRichTextBuffer *buffer, const wxString& filename);
2593 virtual bool SaveFile(wxRichTextBuffer *buffer, const wxString& filename);
2594 #endif // wxUSE_STREAMS && wxUSE_STREAMS
2595
2596 /// Can we handle this filename (if using files)? By default, checks the extension.
2597 virtual bool CanHandle(const wxString& filename) const;
2598
2599 /// Can we save using this handler?
2600 virtual bool CanSave() const { return false; }
2601
2602 /// Can we load using this handler?
2603 virtual bool CanLoad() const { return false; }
2604
2605 /// Should this handler be visible to the user?
2606 virtual bool IsVisible() const { return m_visible; }
2607 virtual void SetVisible(bool visible) { m_visible = visible; }
2608
2609 /// The name of the nandler
2610 void SetName(const wxString& name) { m_name = name; }
2611 wxString GetName() const { return m_name; }
2612
2613 /// The default extension to recognise
2614 void SetExtension(const wxString& ext) { m_extension = ext; }
2615 wxString GetExtension() const { return m_extension; }
2616
2617 /// The handler type
2618 void SetType(int type) { m_type = type; }
2619 int GetType() const { return m_type; }
2620
2621 /// Flags controlling how loading and saving is done
2622 void SetFlags(int flags) { m_flags = flags; }
2623 int GetFlags() const { return m_flags; }
2624
2625 /// Encoding to use when saving a file. If empty, a suitable encoding is chosen
2626 void SetEncoding(const wxString& encoding) { m_encoding = encoding; }
2627 const wxString& GetEncoding() const { return m_encoding; }
2628
2629 protected:
2630
2631 #if wxUSE_STREAMS
2632 virtual bool DoLoadFile(wxRichTextBuffer *buffer, wxInputStream& stream) = 0;
2633 virtual bool DoSaveFile(wxRichTextBuffer *buffer, wxOutputStream& stream) = 0;
2634 #endif
2635
2636 wxString m_name;
2637 wxString m_encoding;
2638 wxString m_extension;
2639 int m_type;
2640 int m_flags;
2641 bool m_visible;
2642 };
2643
2644 /*!
2645 * wxRichTextPlainTextHandler
2646 * Plain text handler
2647 */
2648
2649 class WXDLLIMPEXP_RICHTEXT wxRichTextPlainTextHandler: public wxRichTextFileHandler
2650 {
2651 DECLARE_CLASS(wxRichTextPlainTextHandler)
2652 public:
2653 wxRichTextPlainTextHandler(const wxString& name = wxT("Text"),
2654 const wxString& ext = wxT("txt"),
2655 wxRichTextFileType type = wxRICHTEXT_TYPE_TEXT)
2656 : wxRichTextFileHandler(name, ext, type)
2657 { }
2658
2659 /// Can we save using this handler?
2660 virtual bool CanSave() const { return true; }
2661
2662 /// Can we load using this handler?
2663 virtual bool CanLoad() const { return true; }
2664
2665 protected:
2666
2667 #if wxUSE_STREAMS
2668 virtual bool DoLoadFile(wxRichTextBuffer *buffer, wxInputStream& stream);
2669 virtual bool DoSaveFile(wxRichTextBuffer *buffer, wxOutputStream& stream);
2670 #endif
2671
2672 };
2673
2674 #if wxUSE_DATAOBJ
2675
2676 /*!
2677 * The data object for a wxRichTextBuffer
2678 */
2679
2680 class WXDLLIMPEXP_RICHTEXT wxRichTextBufferDataObject: public wxDataObjectSimple
2681 {
2682 public:
2683 // ctor doesn't copy the pointer, so it shouldn't go away while this object
2684 // is alive
2685 wxRichTextBufferDataObject(wxRichTextBuffer* richTextBuffer = NULL);
2686 virtual ~wxRichTextBufferDataObject();
2687
2688 // after a call to this function, the buffer is owned by the caller and it
2689 // is responsible for deleting it
2690 wxRichTextBuffer* GetRichTextBuffer();
2691
2692 // Returns the id for the new data format
2693 static const wxChar* GetRichTextBufferFormatId() { return ms_richTextBufferFormatId; }
2694
2695 // base class pure virtuals
2696
2697 virtual wxDataFormat GetPreferredFormat(Direction dir) const;
2698 virtual size_t GetDataSize() const;
2699 virtual bool GetDataHere(void *pBuf) const;
2700 virtual bool SetData(size_t len, const void *buf);
2701
2702 // prevent warnings
2703
2704 virtual size_t GetDataSize(const wxDataFormat&) const { return GetDataSize(); }
2705 virtual bool GetDataHere(const wxDataFormat&, void *buf) const { return GetDataHere(buf); }
2706 virtual bool SetData(const wxDataFormat&, size_t len, const void *buf) { return SetData(len, buf); }
2707
2708 private:
2709 wxDataFormat m_formatRichTextBuffer; // our custom format
2710 wxRichTextBuffer* m_richTextBuffer; // our data
2711 static const wxChar* ms_richTextBufferFormatId; // our format id
2712 };
2713
2714 #endif
2715
2716 /*!
2717 * wxRichTextRenderer isolates common drawing functionality
2718 */
2719
2720 class WXDLLIMPEXP_RICHTEXT wxRichTextRenderer: public wxObject
2721 {
2722 public:
2723 wxRichTextRenderer() {}
2724 virtual ~wxRichTextRenderer() {}
2725
2726 /// Draw a standard bullet, as specified by the value of GetBulletName
2727 virtual bool DrawStandardBullet(wxRichTextParagraph* paragraph, wxDC& dc, const wxRichTextAttr& attr, const wxRect& rect) = 0;
2728
2729 /// Draw a bullet that can be described by text, such as numbered or symbol bullets
2730 virtual bool DrawTextBullet(wxRichTextParagraph* paragraph, wxDC& dc, const wxRichTextAttr& attr, const wxRect& rect, const wxString& text) = 0;
2731
2732 /// Draw a bitmap bullet, where the bullet bitmap is specified by the value of GetBulletName
2733 virtual bool DrawBitmapBullet(wxRichTextParagraph* paragraph, wxDC& dc, const wxRichTextAttr& attr, const wxRect& rect) = 0;
2734
2735 /// Enumerate the standard bullet names currently supported
2736 virtual bool EnumerateStandardBulletNames(wxArrayString& bulletNames) = 0;
2737 };
2738
2739 /*!
2740 * wxRichTextStdRenderer: standard renderer
2741 */
2742
2743 class WXDLLIMPEXP_RICHTEXT wxRichTextStdRenderer: public wxRichTextRenderer
2744 {
2745 public:
2746 wxRichTextStdRenderer() {}
2747
2748 /// Draw a standard bullet, as specified by the value of GetBulletName
2749 virtual bool DrawStandardBullet(wxRichTextParagraph* paragraph, wxDC& dc, const wxRichTextAttr& attr, const wxRect& rect);
2750
2751 /// Draw a bullet that can be described by text, such as numbered or symbol bullets
2752 virtual bool DrawTextBullet(wxRichTextParagraph* paragraph, wxDC& dc, const wxRichTextAttr& attr, const wxRect& rect, const wxString& text);
2753
2754 /// Draw a bitmap bullet, where the bullet bitmap is specified by the value of GetBulletName
2755 virtual bool DrawBitmapBullet(wxRichTextParagraph* paragraph, wxDC& dc, const wxRichTextAttr& attr, const wxRect& rect);
2756
2757 /// Enumerate the standard bullet names currently supported
2758 virtual bool EnumerateStandardBulletNames(wxArrayString& bulletNames);
2759 };
2760
2761 /*!
2762 * Utilities
2763 *
2764 */
2765
2766 inline bool wxRichTextHasStyle(int flags, int style)
2767 {
2768 return ((flags & style) == style);
2769 }
2770
2771 /// Compare two attribute objects
2772 WXDLLIMPEXP_RICHTEXT bool wxTextAttrEq(const wxRichTextAttr& attr1, const wxRichTextAttr& attr2);
2773 WXDLLIMPEXP_RICHTEXT bool wxTextAttrEq(const wxRichTextAttr& attr1, const wxRichTextAttr& attr2);
2774
2775 /// Compare two attribute objects, but take into account the flags
2776 /// specifying attributes of interest.
2777 WXDLLIMPEXP_RICHTEXT bool wxTextAttrEqPartial(const wxRichTextAttr& attr1, const wxRichTextAttr& attr2);
2778
2779 /// Apply one style to another
2780 WXDLLIMPEXP_RICHTEXT bool wxRichTextApplyStyle(wxRichTextAttr& destStyle, const wxRichTextAttr& style, wxRichTextAttr* compareWith = NULL);
2781
2782 // Remove attributes
2783 WXDLLIMPEXP_RICHTEXT bool wxRichTextRemoveStyle(wxRichTextAttr& destStyle, const wxRichTextAttr& style);
2784
2785 /// Combine two bitlists
2786 WXDLLIMPEXP_RICHTEXT bool wxRichTextCombineBitlists(int& valueA, int valueB, int& flagsA, int flagsB);
2787
2788 /// Compare two bitlists
2789 WXDLLIMPEXP_RICHTEXT bool wxRichTextBitlistsEqPartial(int valueA, int valueB, int flags);
2790
2791 /// Split into paragraph and character styles
2792 WXDLLIMPEXP_RICHTEXT bool wxRichTextSplitParaCharStyles(const wxRichTextAttr& style, wxRichTextAttr& parStyle, wxRichTextAttr& charStyle);
2793
2794 /// Compare tabs
2795 WXDLLIMPEXP_RICHTEXT bool wxRichTextTabsEq(const wxArrayInt& tabs1, const wxArrayInt& tabs2);
2796
2797 /// Convert a decimal to Roman numerals
2798 WXDLLIMPEXP_RICHTEXT wxString wxRichTextDecimalToRoman(long n);
2799
2800 // Collects the attributes that are common to a range of content, building up a note of
2801 // which attributes are absent in some objects and which clash in some objects.
2802 WXDLLIMPEXP_RICHTEXT void wxTextAttrCollectCommonAttributes(wxTextAttr& currentStyle, const wxTextAttr& attr, wxTextAttr& clashingAttr, wxTextAttr& absentAttr);
2803
2804 WXDLLIMPEXP_RICHTEXT void wxRichTextModuleInit();
2805
2806 #endif
2807 // wxUSE_RICHTEXT
2808
2809 #endif
2810 // _WX_RICHTEXTBUFFER_H_
2811