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