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