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