]> git.saurik.com Git - wxWidgets.git/blame_incremental - include/wx/richtext/richtextbuffer.h
Use an enum for the colour/string conversion flags
[wxWidgets.git] / include / wx / richtext / richtextbuffer.h
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: wx/richtext/richtextbuffer.h
3// Purpose: Buffer for wxRichTextCtrl
4// Author: Julian Smart
5// Modified by:
6// Created: 2005-09-30
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifndef _WX_RICHTEXTBUFFER_H_
13#define _WX_RICHTEXTBUFFER_H_
14
15/*
16
17 Data structures
18 ===============
19
20 Data is represented by a hierarchy of objects, all derived from
21 wxRichTextObject.
22
23 The top of the hierarchy is the buffer, a kind of wxRichTextParagraphLayoutBox.
24 These boxes will allow flexible placement of text boxes on a page, but
25 for now there is a single box representing the document, and this box is
26 a wxRichTextParagraphLayoutBox which contains further wxRichTextParagraph
27 objects, each of which can include text and images.
28
29 Each object maintains a range (start and end position) measured
30 from the start of the main parent box.
31 A paragraph object knows its range, and a text fragment knows its range
32 too. So, a character or image in a page has a position relative to the
33 start of the document, and a character in an embedded text box has
34 a position relative to that text box. For now, we will not be dealing with
35 embedded objects but it's something to bear in mind for later.
36
37 Note that internally, a range (5,5) represents a range of one character.
38 In the public wx[Rich]TextCtrl API, this would be passed to e.g. SetSelection
39 as (5,6). A paragraph with one character might have an internal range of (0, 1)
40 since the end of the paragraph takes up one position.
41
42 Layout
43 ======
44
45 When Layout is called on an object, it is given a size which the object
46 must limit itself to, or one or more flexible directions (vertical
47 or horizontal). So for example a centered paragraph is given the page
48 width to play with (minus any margins), but can extend indefinitely
49 in the vertical direction. The implementation of Layout can then
50 cache the calculated size and position within the parent.
51
52 */
53
54/*!
55 * Includes
56 */
57
58#include "wx/defs.h"
59
60#if wxUSE_RICHTEXT
61
62#include "wx/list.h"
63#include "wx/textctrl.h"
64#include "wx/bitmap.h"
65#include "wx/image.h"
66#include "wx/cmdproc.h"
67#include "wx/txtstrm.h"
68#include "wx/variant.h"
69
70#if wxUSE_DATAOBJ
71#include "wx/dataobj.h"
72#endif
73
74// Compatibility
75//#define wxRichTextAttr wxTextAttr
76#define wxTextAttrEx wxTextAttr
77
78// Setting wxRICHTEXT_USE_OWN_CARET to 1 implements a
79// caret reliably without using wxClientDC in case there
80// are platform-specific problems with the generic caret.
81#if defined(__WXGTK__) || defined(__WXMAC__)
82#define wxRICHTEXT_USE_OWN_CARET 1
83#else
84#define wxRICHTEXT_USE_OWN_CARET 0
85#endif
86
87// Switch off for binary compatibility, on for faster drawing
88// Note: this seems to be buggy (overzealous use of extents) so
89// don't use for now
90#define wxRICHTEXT_USE_OPTIMIZED_LINE_DRAWING 0
91
92// The following two symbols determine whether an output implementation
93// is present. To switch the relevant one on, set wxRICHTEXT_USE_XMLDOCUMENT_OUTPUT in
94// richtextxml.cpp. By default, the faster direct output implementation is used.
95
96// Include the wxXmlDocument implementation for output
97#define wxRICHTEXT_HAVE_XMLDOCUMENT_OUTPUT 1
98
99// Include the faster, direct implementation for output
100#define wxRICHTEXT_HAVE_DIRECT_OUTPUT 1
101
102/*!
103 * Special characters
104 */
105
106extern WXDLLIMPEXP_RICHTEXT const wxChar wxRichTextLineBreakChar;
107
108/*!
109 * File types in wxRichText context.
110 */
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};
120
121/*!
122 * Forward declarations
123 */
124
125class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextCtrl;
126class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextObject;
127class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextImage;
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;
134class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextListStyleDefinition;
135class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextEvent;
136class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextRenderer;
137class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextBuffer;
138class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextXMLHandler;
139class WXDLLIMPEXP_FWD_XML wxXmlNode;
140class wxRichTextFloatCollector;
141
142/*!
143 * Flags determining the available space, passed to Layout
144 */
145
146#define wxRICHTEXT_FIXED_WIDTH 0x01
147#define wxRICHTEXT_FIXED_HEIGHT 0x02
148#define wxRICHTEXT_VARIABLE_WIDTH 0x04
149#define wxRICHTEXT_VARIABLE_HEIGHT 0x08
150
151// Only lay out the part of the buffer that lies within
152// the rect passed to Layout.
153#define wxRICHTEXT_LAYOUT_SPECIFIED_RECT 0x10
154
155/*!
156 * Flags to pass to Draw
157 */
158
159// Ignore paragraph cache optimization, e.g. for printing purposes
160// where one line may be drawn higher (on the next page) compared
161// with the previous line
162#define wxRICHTEXT_DRAW_IGNORE_CACHE 0x01
163
164/*!
165 * Flags returned from hit-testing
166 */
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,
177
178 // The point was on the position returned from HitTest
179 wxRICHTEXT_HITTEST_ON = 0x08,
180
181 // The point was on space outside content
182 wxRICHTEXT_HITTEST_OUTSIDE = 0x10
183};
184
185/*!
186 * Flags for GetRangeSize
187 */
188
189#define wxRICHTEXT_FORMATTED 0x01
190#define wxRICHTEXT_UNFORMATTED 0x02
191#define wxRICHTEXT_CACHE_SIZE 0x04
192#define wxRICHTEXT_HEIGHT_ONLY 0x08
193
194/*!
195 * Flags for SetStyle/SetListStyle
196 */
197
198#define wxRICHTEXT_SETSTYLE_NONE 0x00
199
200// Specifies that this operation should be undoable
201#define wxRICHTEXT_SETSTYLE_WITH_UNDO 0x01
202
203// Specifies that the style should not be applied if the
204// combined style at this point is already the style in question.
205#define wxRICHTEXT_SETSTYLE_OPTIMIZE 0x02
206
207// Specifies that the style should only be applied to paragraphs,
208// and not the content. This allows content styling to be
209// preserved independently from that of e.g. a named paragraph style.
210#define wxRICHTEXT_SETSTYLE_PARAGRAPHS_ONLY 0x04
211
212// Specifies that the style should only be applied to characters,
213// and not the paragraph. This allows content styling to be
214// preserved independently from that of e.g. a named paragraph style.
215#define wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY 0x08
216
217// For SetListStyle only: specifies starting from the given number, otherwise
218// deduces number from existing attributes
219#define wxRICHTEXT_SETSTYLE_RENUMBER 0x10
220
221// For SetListStyle only: specifies the list level for all paragraphs, otherwise
222// the current indentation will be used
223#define wxRICHTEXT_SETSTYLE_SPECIFY_LEVEL 0x20
224
225// Resets the existing style before applying the new style
226#define wxRICHTEXT_SETSTYLE_RESET 0x40
227
228// Removes the given style instead of applying it
229#define wxRICHTEXT_SETSTYLE_REMOVE 0x80
230
231/*!
232 * Flags for text insertion
233 */
234
235#define wxRICHTEXT_INSERT_NONE 0x00
236#define wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE 0x01
237#define wxRICHTEXT_INSERT_INTERACTIVE 0x02
238
239// A special flag telling the buffer to keep the first paragraph style
240// as-is, when deleting a paragraph marker. In future we might pass a
241// flag to InsertFragment and DeleteRange to indicate the appropriate mode.
242#define wxTEXT_ATTR_KEEP_FIRST_PARA_STYLE 0x10000000
243
244/*!
245 * Default superscript/subscript font multiplication factor
246 */
247
248#define wxSCRIPT_MUL_FACTOR 1.5
249
250typedef unsigned short wxTextAttrDimensionFlags;
251
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};
259
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};
266
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
289class WXDLLIMPEXP_RICHTEXT wxTextAttrDimension
290{
291public:
292 wxTextAttrDimension() { Reset(); }
293 wxTextAttrDimension(int value, wxTextAttrDimensionFlags flags = wxTEXT_ATTR_VALUE_PRESENT|wxTEXT_ATTR_UNITS_TENTHS_MM) { m_value = value; m_flags = flags; }
294
295 void Reset() { m_value = 0; m_flags = 0; }
296
297 // Partial equality test
298 bool EqPartial(const wxTextAttrDimension& dim) const;
299
300 // Apply
301 bool Apply(const wxTextAttrDimension& dim, const wxTextAttrDimension* compareWith = NULL);
302
303 // Collects the attributes that are common to a range of content, building up a note of
304 // which attributes are absent in some objects and which clash in some objects.
305 void CollectCommonAttributes(const wxTextAttrDimension& attr, wxTextAttrDimension& clashingAttr, wxTextAttrDimension& absentAttr);
306
307 bool operator==(const wxTextAttrDimension& dim) const { return m_value == dim.m_value && m_flags == dim.m_flags; }
308
309 int GetValue() const { return m_value; }
310 float GetValueMM() const { return float(m_value) / 10.0; }
311 void SetValueMM(float value) { m_value = (int) ((value * 10.0) + 0.5); m_flags |= wxTEXT_ATTR_VALUE_PRESENT; }
312 void SetValue(int value) { m_value = value; m_flags |= wxTEXT_ATTR_VALUE_PRESENT; }
313 void SetValue(int value, wxTextAttrDimensionFlags flags) { m_value = value; m_flags = flags; }
314 void SetValue(const wxTextAttrDimension& dim) { (*this) = dim; }
315
316 wxTextAttrUnits GetUnits() const { return (wxTextAttrUnits) (m_flags & wxTEXT_ATTR_UNITS_MASK); }
317 void SetUnits(wxTextAttrUnits units) { m_flags &= ~wxTEXT_ATTR_UNITS_MASK; m_flags |= units; }
318
319 wxTextBoxAttrPosition GetPosition() const { return (wxTextBoxAttrPosition) (m_flags & wxTEXT_BOX_ATTR_POSITION_MASK); }
320 void SetPosition(wxTextBoxAttrPosition pos) { m_flags &= ~wxTEXT_BOX_ATTR_POSITION_MASK; m_flags |= pos; }
321
322 bool IsPresent() const { return (m_flags & wxTEXT_ATTR_VALUE_PRESENT) != 0; }
323 void SetPresent(bool b) { m_flags &= ~wxTEXT_ATTR_VALUE_PRESENT_MASK; m_flags |= (b ? wxTEXT_ATTR_VALUE_PRESENT : 0); }
324
325 wxTextAttrDimensionFlags GetFlags() const { return m_flags; }
326 void SetFlags(wxTextAttrDimensionFlags flags) { m_flags = flags; }
327
328 int m_value;
329 wxTextAttrDimensionFlags m_flags;
330};
331
332// A class for left, right, top and bottom dimensions
333class WXDLLIMPEXP_RICHTEXT wxTextAttrDimensions
334{
335public:
336 void Reset() { m_left.Reset(); m_top.Reset(); m_right.Reset(); m_bottom.Reset(); }
337
338 bool operator==(const wxTextAttrDimensions& dims) const { return m_left == dims.m_left && m_top == dims.m_top && m_right == dims.m_right && m_bottom == dims.m_bottom; }
339
340 // Partial equality test
341 bool EqPartial(const wxTextAttrDimensions& dims) const;
342
343 // Apply border to 'this', but not if the same as compareWith
344 bool Apply(const wxTextAttrDimensions& dims, const wxTextAttrDimensions* compareWith = NULL);
345
346 // Collects the attributes that are common to a range of content, building up a note of
347 // which attributes are absent in some objects and which clash in some objects.
348 void CollectCommonAttributes(const wxTextAttrDimensions& attr, wxTextAttrDimensions& clashingAttr, wxTextAttrDimensions& absentAttr);
349
350 // Remove specified attributes from this object
351 bool RemoveStyle(const wxTextAttrDimensions& attr);
352
353 const wxTextAttrDimension& GetLeft() const { return m_left; }
354 wxTextAttrDimension& GetLeft() { return m_left; }
355
356 const wxTextAttrDimension& GetRight() const { return m_right; }
357 wxTextAttrDimension& GetRight() { return m_right; }
358
359 const wxTextAttrDimension& GetTop() const { return m_top; }
360 wxTextAttrDimension& GetTop() { return m_top; }
361
362 const wxTextAttrDimension& GetBottom() const { return m_bottom; }
363 wxTextAttrDimension& GetBottom() { return m_bottom; }
364
365 wxTextAttrDimension m_left;
366 wxTextAttrDimension m_top;
367 wxTextAttrDimension m_right;
368 wxTextAttrDimension m_bottom;
369};
370
371// A class to make it easier to convert dimensions
372class WXDLLIMPEXP_RICHTEXT wxTextAttrDimensionConverter
373{
374public:
375 wxTextAttrDimensionConverter(wxDC& dc, double scale = 1.0, const wxSize& parentSize = wxDefaultSize);
376 wxTextAttrDimensionConverter(int ppi, double scale = 1.0, const wxSize& parentSize = wxDefaultSize);
377
378 int GetPixels(const wxTextAttrDimension& dim, int direction = wxHORIZONTAL) const;
379 int GetTenthsMM(const wxTextAttrDimension& dim) const;
380
381 int ConvertTenthsMMToPixels(int units) const;
382 int ConvertPixelsToTenthsMM(int pixels) const;
383
384 int m_ppi;
385 double m_scale;
386 wxSize m_parentSize;
387};
388
389// Border styles
390enum wxTextAttrBorderStyle
391{
392 wxTEXT_BOX_ATTR_BORDER_NONE = 0,
393 wxTEXT_BOX_ATTR_BORDER_SOLID = 1,
394 wxTEXT_BOX_ATTR_BORDER_DOTTED = 2,
395 wxTEXT_BOX_ATTR_BORDER_DASHED = 3,
396 wxTEXT_BOX_ATTR_BORDER_DOUBLE = 4,
397 wxTEXT_BOX_ATTR_BORDER_GROOVE = 5,
398 wxTEXT_BOX_ATTR_BORDER_RIDGE = 6,
399 wxTEXT_BOX_ATTR_BORDER_INSET = 7,
400 wxTEXT_BOX_ATTR_BORDER_OUTSET = 8
401};
402
403// Border style presence flags
404enum wxTextAttrBorderFlags
405{
406 wxTEXT_BOX_ATTR_BORDER_STYLE = 0x0001,
407 wxTEXT_BOX_ATTR_BORDER_COLOUR = 0x0002
408};
409
410// Border width symbols for qualitative widths
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
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
443class WXDLLIMPEXP_RICHTEXT wxTextAttrBorder
444{
445public:
446 wxTextAttrBorder() { Reset(); }
447
448 bool operator==(const wxTextAttrBorder& border) const
449 {
450 return m_flags == border.m_flags && m_borderStyle == border.m_borderStyle &&
451 m_borderColour == border.m_borderColour && m_borderWidth == border.m_borderWidth;
452 }
453
454 void Reset() { m_borderStyle = 0; m_borderColour = 0; m_flags = 0; m_borderWidth.Reset(); }
455
456 // Partial equality test
457 bool EqPartial(const wxTextAttrBorder& border) const;
458
459 // Apply border to 'this', but not if the same as compareWith
460 bool Apply(const wxTextAttrBorder& border, const wxTextAttrBorder* compareWith = NULL);
461
462 // Remove specified attributes from this object
463 bool RemoveStyle(const wxTextAttrBorder& attr);
464
465 // Collects the attributes that are common to a range of content, building up a note of
466 // which attributes are absent in some objects and which clash in some objects.
467 void CollectCommonAttributes(const wxTextAttrBorder& attr, wxTextAttrBorder& clashingAttr, wxTextAttrBorder& absentAttr);
468
469 void SetStyle(int style) { m_borderStyle = style; m_flags |= wxTEXT_BOX_ATTR_BORDER_STYLE; }
470 int GetStyle() const { return m_borderStyle; }
471
472 void SetColour(unsigned long colour) { m_borderColour = colour; m_flags |= wxTEXT_BOX_ATTR_BORDER_COLOUR; }
473 void SetColour(const wxColour& colour) { m_borderColour = colour.GetRGB(); m_flags |= wxTEXT_BOX_ATTR_BORDER_COLOUR; }
474 unsigned long GetColourLong() const { return m_borderColour; }
475 wxColour GetColour() const { return wxColour(m_borderColour); }
476
477 wxTextAttrDimension& GetWidth() { return m_borderWidth; }
478 const wxTextAttrDimension& GetWidth() const { return m_borderWidth; }
479 void SetWidth(const wxTextAttrDimension& width) { m_borderWidth = width; }
480
481 bool HasStyle() const { return (m_flags & wxTEXT_BOX_ATTR_BORDER_STYLE) != 0; }
482 bool HasColour() const { return (m_flags & wxTEXT_BOX_ATTR_BORDER_COLOUR) != 0; }
483 bool HasWidth() const { return m_borderWidth.IsPresent(); }
484
485 bool IsValid() const { return HasStyle() && HasColour() && HasWidth(); }
486
487 int GetFlags() const { return m_flags; }
488 void SetFlags(int flags) { m_flags = flags; }
489 void AddFlag(int flag) { m_flags |= flag; }
490 void RemoveFlag(int flag) { m_flags &= ~flag; }
491
492 int m_borderStyle;
493 unsigned long m_borderColour;
494 wxTextAttrDimension m_borderWidth;
495 int m_flags;
496};
497
498// Borders
499class WXDLLIMPEXP_RICHTEXT wxTextAttrBorders
500{
501public:
502 wxTextAttrBorders() { }
503
504 bool operator==(const wxTextAttrBorders& borders) const
505 {
506 return m_left == borders.m_left && m_right == borders.m_right &&
507 m_top == borders.m_top && m_bottom == borders.m_bottom;
508 }
509
510 // Set style of all borders
511 void SetStyle(int style);
512
513 // Set colour of all borders
514 void SetColour(unsigned long colour);
515 void SetColour(const wxColour& colour);
516
517 // Set width of all borders
518 void SetWidth(const wxTextAttrDimension& width);
519
520 // Reset
521 void Reset() { m_left.Reset(); m_right.Reset(); m_top.Reset(); m_bottom.Reset(); }
522
523 // Partial equality test
524 bool EqPartial(const wxTextAttrBorders& borders) const;
525
526 // Apply border to 'this', but not if the same as compareWith
527 bool Apply(const wxTextAttrBorders& borders, const wxTextAttrBorders* compareWith = NULL);
528
529 // Remove specified attributes from this object
530 bool RemoveStyle(const wxTextAttrBorders& attr);
531
532 // Collects the attributes that are common to a range of content, building up a note of
533 // which attributes are absent in some objects and which clash in some objects.
534 void CollectCommonAttributes(const wxTextAttrBorders& attr, wxTextAttrBorders& clashingAttr, wxTextAttrBorders& absentAttr);
535
536 bool HasBorder() const { return m_left.IsValid() || m_right.IsValid() || m_top.IsValid() || m_bottom.IsValid(); }
537
538 const wxTextAttrBorder& GetLeft() const { return m_left; }
539 wxTextAttrBorder& GetLeft() { return m_left; }
540
541 const wxTextAttrBorder& GetRight() const { return m_right; }
542 wxTextAttrBorder& GetRight() { return m_right; }
543
544 const wxTextAttrBorder& GetTop() const { return m_top; }
545 wxTextAttrBorder& GetTop() { return m_top; }
546
547 const wxTextAttrBorder& GetBottom() const { return m_bottom; }
548 wxTextAttrBorder& GetBottom() { return m_bottom; }
549
550 wxTextAttrBorder m_left, m_right, m_top, m_bottom;
551
552};
553
554// ----------------------------------------------------------------------------
555// wxTextBoxAttr: a structure containing box attributes
556// ----------------------------------------------------------------------------
557
558class WXDLLIMPEXP_RICHTEXT wxTextBoxAttr
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
571 // Copy. Unnecessary since we let it do a binary copy
572 //void Copy(const wxTextBoxAttr& attr);
573
574 // Assignment
575 //void operator= (const wxTextBoxAttr& attr);
576
577 // Equality test
578 bool operator== (const wxTextBoxAttr& attr) const;
579
580 // Partial equality test
581 bool EqPartial(const wxTextBoxAttr& attr) const;
582
583 // Merges the given attributes. If compareWith
584 // is non-NULL, then it will be used to mask out those attributes that are the same in style
585 // and compareWith, for situations where we don't want to explicitly set inherited attributes.
586 bool Apply(const wxTextBoxAttr& style, const wxTextBoxAttr* compareWith = NULL);
587
588 // Collects the attributes that are common to a range of content, building up a note of
589 // which attributes are absent in some objects and which clash in some objects.
590 void CollectCommonAttributes(const wxTextBoxAttr& attr, wxTextBoxAttr& clashingAttr, wxTextBoxAttr& absentAttr);
591
592 // Remove specified attributes from this object
593 bool RemoveStyle(const wxTextBoxAttr& attr);
594
595 // Set flags
596 void SetFlags(int flags) { m_flags = flags; }
597
598 // Get flags
599 int GetFlags() const { return m_flags; }
600
601 // Is this flag present?
602 bool HasFlag(wxTextBoxAttrFlags flag) const { return (m_flags & flag) != 0; }
603
604 // Remove this flag
605 void RemoveFlag(wxTextBoxAttrFlags flag) { m_flags &= ~flag; }
606
607 // Add this flag
608 void AddFlag(wxTextBoxAttrFlags flag) { m_flags |= flag; }
609
610 // Is this default? I.e. no flags set
611 bool IsDefault() const;
612
613 // Float mode
614 short int GetFloatMode() const { return m_floatMode; }
615 void SetFloatMode(short int mode) { m_floatMode = mode; m_flags |= wxTEXT_BOX_ATTR_FLOAT; }
616 bool HasFloatMode() const { return HasFlag(wxTEXT_BOX_ATTR_FLOAT); }
617 bool IsFloating() const { return HasFloatMode() && GetFloatMode() != wxTEXT_BOX_ATTR_FLOAT_NONE; }
618
619 // Whether to wrap text after object
620 short int GetClearMode() const { return m_clearMode; }
621 void SetClearMode(short int mode) { m_clearMode = mode; m_flags |= wxTEXT_BOX_ATTR_CLEAR; }
622 bool HasClearMode() const { return HasFlag(wxTEXT_BOX_ATTR_CLEAR); }
623
624 // Whether to collapse borders
625 int GetCollapseBorders() const { return m_collapseMode ; }
626 void SetCollapseBorders(int collapse) { m_collapseMode = collapse; m_flags |= wxTEXT_BOX_ATTR_COLLAPSE_BORDERS; }
627 bool HasCollapseBorders() const { return HasFlag(wxTEXT_BOX_ATTR_COLLAPSE_BORDERS); }
628
629 // Margins
630
631 wxTextAttrDimensions& GetMargins() { return m_margins; }
632 const wxTextAttrDimensions& GetMargins() const { return m_margins; }
633
634 wxTextAttrDimension& GetLeftMargin() { return m_margins.m_left; }
635 const wxTextAttrDimension& GetLeftMargin() const { return m_margins.m_left; }
636
637 wxTextAttrDimension& GetRightMargin() { return m_margins.m_right; }
638 const wxTextAttrDimension& GetRightMargin() const { return m_margins.m_right; }
639
640 wxTextAttrDimension& GetTopMargin() { return m_margins.m_top; }
641 const wxTextAttrDimension& GetTopMargin() const { return m_margins.m_top; }
642
643 wxTextAttrDimension& GetBottomMargin() { return m_margins.m_bottom; }
644 const wxTextAttrDimension& GetBottomMargin() const { return m_margins.m_bottom; }
645
646 // Position
647
648 wxTextAttrDimensions& GetPosition() { return m_position; }
649 const wxTextAttrDimensions& GetPosition() const { return m_position; }
650
651 wxTextAttrDimension& GetLeft() { return m_position.m_left; }
652 const wxTextAttrDimension& GetLeft() const { return m_position.m_left; }
653
654 wxTextAttrDimension& GetRight() { return m_position.m_right; }
655 const wxTextAttrDimension& GetRight() const { return m_position.m_right; }
656
657 wxTextAttrDimension& GetTop() { return m_position.m_top; }
658 const wxTextAttrDimension& GetTop() const { return m_position.m_top; }
659
660 wxTextAttrDimension& GetBottom() { return m_position.m_bottom; }
661 const wxTextAttrDimension& GetBottom() const { return m_position.m_bottom; }
662
663 // Padding
664
665 wxTextAttrDimensions& GetPadding() { return m_padding; }
666 const wxTextAttrDimensions& GetPadding() const { return m_padding; }
667
668 wxTextAttrDimension& GetLeftPadding() { return m_padding.m_left; }
669 const wxTextAttrDimension& GetLeftPadding() const { return m_padding.m_left; }
670
671 wxTextAttrDimension& GetRightPadding() { return m_padding.m_right; }
672 const wxTextAttrDimension& GetRightPadding() const { return m_padding.m_right; }
673
674 wxTextAttrDimension& GetTopPadding() { return m_padding.m_top; }
675 const wxTextAttrDimension& GetTopPadding() const { return m_padding.m_top; }
676
677 wxTextAttrDimension& GetBottomPadding() { return m_padding.m_bottom; }
678 const wxTextAttrDimension& GetBottomPadding() const { return m_padding.m_bottom; }
679
680 // Border
681
682 wxTextAttrBorders& GetBorder() { return m_border; }
683 const wxTextAttrBorders& GetBorder() const { return m_border; }
684
685 wxTextAttrBorder& GetLeftBorder() { return m_border.m_left; }
686 const wxTextAttrBorder& GetLeftBorder() const { return m_border.m_left; }
687
688 wxTextAttrBorder& GetTopBorder() { return m_border.m_top; }
689 const wxTextAttrBorder& GetTopBorder() const { return m_border.m_top; }
690
691 wxTextAttrBorder& GetRightBorder() { return m_border.m_right; }
692 const wxTextAttrBorder& GetRightBorder() const { return m_border.m_right; }
693
694 wxTextAttrBorder& GetBottomBorder() { return m_border.m_bottom; }
695 const wxTextAttrBorder& GetBottomBorder() const { return m_border.m_bottom; }
696
697 // Outline
698
699 wxTextAttrBorders& GetOutline() { return m_outline; }
700 const wxTextAttrBorders& GetOutline() const { return m_outline; }
701
702 wxTextAttrBorder& GetLeftOutline() { return m_outline.m_left; }
703 const wxTextAttrBorder& GetLeftOutline() const { return m_outline.m_left; }
704
705 wxTextAttrBorder& GetTopOutline() { return m_outline.m_top; }
706 const wxTextAttrBorder& GetTopOutline() const { return m_outline.m_top; }
707
708 wxTextAttrBorder& GetRightOutline() { return m_outline.m_right; }
709 const wxTextAttrBorder& GetRightOutline() const { return m_outline.m_right; }
710
711 wxTextAttrBorder& GetBottomOutline() { return m_outline.m_bottom; }
712 const wxTextAttrBorder& GetBottomOutline() const { return m_outline.m_bottom; }
713
714
715 // Width and height
716
717 wxTextAttrDimension& GetWidth() { return m_width; }
718 const wxTextAttrDimension& GetWidth() const { return m_width; }
719
720 wxTextAttrDimension& GetHeight() { return m_height; }
721 const wxTextAttrDimension& GetHeight() const { return m_height; }
722
723public:
724
725 int m_flags;
726
727 wxTextAttrDimensions m_margins;
728 wxTextAttrDimensions m_padding;
729 wxTextAttrDimensions m_position;
730
731 wxTextAttrDimension m_width;
732 wxTextAttrDimension m_height;
733
734 wxTextAttrBorders m_border;
735 wxTextAttrBorders m_outline;
736
737 short int m_floatMode;
738 short int m_clearMode;
739 short int m_collapseMode;
740};
741
742// ----------------------------------------------------------------------------
743// wxRichTextAttr: an enhanced attribute
744// ----------------------------------------------------------------------------
745
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;
783};
784
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
836/*!
837 * wxRichTextFontTable
838 * Manages quick access to a pool of fonts for rendering rich text
839 */
840
841class WXDLLIMPEXP_RICHTEXT wxRichTextFontTable: public wxObject
842{
843public:
844 wxRichTextFontTable();
845
846 wxRichTextFontTable(const wxRichTextFontTable& table);
847 virtual ~wxRichTextFontTable();
848
849 bool IsOk() const { return m_refData != NULL; }
850
851 wxFont FindFont(const wxRichTextAttr& fontSpec);
852 void Clear();
853
854 void operator= (const wxRichTextFontTable& table);
855 bool operator == (const wxRichTextFontTable& table) const;
856 bool operator != (const wxRichTextFontTable& table) const { return !(*this == table); }
857
858protected:
859
860 DECLARE_DYNAMIC_CLASS(wxRichTextFontTable)
861};
862
863/*!
864 * wxRichTextRange class declaration
865 * This stores beginning and end positions for a range of data.
866 * TODO: consider renaming wxTextRange and using for all text controls.
867 */
868
869class WXDLLIMPEXP_RICHTEXT wxRichTextRange
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; }
880 bool operator ==(const wxRichTextRange& range) const { return (m_start == range.m_start && m_end == range.m_end); }
881 bool operator !=(const wxRichTextRange& range) const { return (m_start != range.m_start || m_end != range.m_end); }
882 wxRichTextRange operator -(const wxRichTextRange& range) const { return wxRichTextRange(m_start - range.m_start, m_end - range.m_end); }
883 wxRichTextRange operator +(const wxRichTextRange& range) const { return wxRichTextRange(m_start + range.m_start, m_end + range.m_end); }
884
885 void SetRange(long start, long end) { m_start = start; m_end = end; }
886
887 void SetStart(long start) { m_start = start; }
888 long GetStart() const { return m_start; }
889
890 void SetEnd(long end) { m_end = end; }
891 long GetEnd() const { return m_end; }
892
893 /// Returns true if this range is completely outside 'range'
894 bool IsOutside(const wxRichTextRange& range) const { return range.m_start > m_end || range.m_end < m_start; }
895
896 /// Returns true if this range is completely within 'range'
897 bool IsWithin(const wxRichTextRange& range) const { return m_start >= range.m_start && m_end <= range.m_end; }
898
899 /// Returns true if the given position is within this range. Allow
900 /// for the possibility of an empty range - assume the position
901 /// is within this empty range. NO, I think we should not match with an empty range.
902 // bool Contains(long pos) const { return pos >= m_start && (pos <= m_end || GetLength() == 0); }
903 bool Contains(long pos) const { return pos >= m_start && pos <= m_end ; }
904
905 /// Limit this range to be within 'range'
906 bool LimitTo(const wxRichTextRange& range) ;
907
908 /// Gets the length of the range
909 long GetLength() const { return m_end - m_start + 1; }
910
911 /// Swaps the start and end
912 void Swap() { long tmp = m_start; m_start = m_end; m_end = tmp; }
913
914 /// Convert to internal form: (n, n) is the range of a single character.
915 wxRichTextRange ToInternal() const { return wxRichTextRange(m_start, m_end-1); }
916
917 /// Convert from internal to public API form: (n, n+1) is the range of a single character.
918 wxRichTextRange FromInternal() const { return wxRichTextRange(m_start, m_end+1); }
919
920protected:
921 long m_start;
922 long m_end;
923};
924
925#define wxRICHTEXT_ALL wxRichTextRange(-2, -2)
926#define wxRICHTEXT_NONE wxRichTextRange(-1, -1)
927
928/*!
929 * wxRichTextObject class declaration
930 * This is the base for drawable objects.
931 */
932
933class WXDLLIMPEXP_RICHTEXT wxRichTextObject: public wxObject
934{
935 DECLARE_CLASS(wxRichTextObject)
936public:
937// Constructors
938
939 wxRichTextObject(wxRichTextObject* parent = NULL);
940 virtual ~wxRichTextObject();
941
942// Overrideables
943
944 /// Draw the item, within the given range. Some objects may ignore the range (for
945 /// example paragraphs) while others must obey it (lines, to implement wrapping)
946 virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style) = 0;
947
948 /// Lay the item out at the specified position with the given size constraint.
949 /// Layout must set the cached size.
950 virtual bool Layout(wxDC& dc, const wxRect& rect, int style) = 0;
951
952 /// Hit-testing: returns a flag indicating hit test details, plus
953 /// information about position
954 virtual int HitTest(wxDC& WXUNUSED(dc), const wxPoint& WXUNUSED(pt), long& WXUNUSED(textPosition)) { return false; }
955
956 /// Finds the absolute position and row height for the given character position
957 virtual bool FindPosition(wxDC& WXUNUSED(dc), long WXUNUSED(index), wxPoint& WXUNUSED(pt), int* WXUNUSED(height), bool WXUNUSED(forceLineStart)) { return false; }
958
959 /// Get the best size, i.e. the ideal starting size for this object irrespective
960 /// of available space. For a short text string, it will be the size that exactly encloses
961 /// the text. For a longer string, it might use the parent width for example.
962 virtual wxSize GetBestSize() const { return m_size; }
963
964 /// Get the object size for the given range. Returns false if the range
965 /// is invalid for this object.
966 virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const = 0;
967
968 /// Do a split, returning an object containing the second part, and setting
969 /// the first part in 'this'.
970 virtual wxRichTextObject* DoSplit(long WXUNUSED(pos)) { return NULL; }
971
972 /// Calculate range. By default, guess that the object is 1 unit long.
973 virtual void CalculateRange(long start, long& end) { end = start ; m_range.SetRange(start, end); }
974
975 /// Delete range
976 virtual bool DeleteRange(const wxRichTextRange& WXUNUSED(range)) { return false; }
977
978 /// Returns true if the object is empty
979 virtual bool IsEmpty() const { return false; }
980
981 /// Whether this object floatable
982 virtual bool IsFloatable() const { return false; }
983
984 /// Whether this object is currently floating
985 virtual bool IsFloating() const { return GetAttributes().GetTextBoxAttr().IsFloating(); }
986
987 /// Whether this object is a place holding one
988 // virtual bool IsPlaceHolding() const { return false; }
989
990 /// The floating direction
991 virtual int GetFloatDirection() const { return GetAttributes().GetTextBoxAttr().GetFloatMode(); }
992
993 /// Get any text in this object for the given range
994 virtual wxString GetTextForRange(const wxRichTextRange& WXUNUSED(range)) const { return wxEmptyString; }
995
996 /// Returns true if this object can merge itself with the given one.
997 virtual bool CanMerge(wxRichTextObject* WXUNUSED(object)) const { return false; }
998
999 /// Returns true if this object merged itself with the given one.
1000 /// The calling code will then delete the given object.
1001 virtual bool Merge(wxRichTextObject* WXUNUSED(object)) { return false; }
1002
1003 /// Dump to output stream for debugging
1004 virtual void Dump(wxTextOutputStream& stream);
1005
1006 /// Can we edit properties via a GUI?
1007 virtual bool CanEditProperties() const { return false; }
1008
1009 /// Edit properties via a GUI
1010 virtual bool EditProperties(wxWindow* WXUNUSED(parent), wxRichTextBuffer* WXUNUSED(buffer)) { return false; }
1011
1012#if wxUSE_XML
1013 /// Import this object from XML
1014 virtual bool ImportFromXML(wxRichTextBuffer* buffer, wxXmlNode* node, wxRichTextXMLHandler* handler);
1015#endif
1016
1017#if wxRICHTEXT_HAVE_DIRECT_OUTPUT
1018 /// Export this object directly to the given stream.
1019 virtual bool ExportXML(wxOutputStream& stream, int indent, wxRichTextXMLHandler* handler);
1020#endif
1021
1022#if wxRICHTEXT_HAVE_XMLDOCUMENT_OUTPUT
1023 /// Export this object to the given parent node, usually creating at least one child node.
1024 virtual bool ExportXML(wxXmlNode* parent, wxRichTextXMLHandler* handler);
1025#endif
1026
1027 /// Does this object take note of paragraph attributes? Text and image objects don't.
1028 virtual bool UsesParagraphAttributes() const { return true; }
1029
1030 /// What is the XML node name of this object?
1031 virtual wxString GetXMLNodeName() const { return wxT("unknown"); }
1032
1033// Accessors
1034
1035 /// Get/set the cached object size as calculated by Layout.
1036 virtual wxSize GetCachedSize() const { return m_size; }
1037 virtual void SetCachedSize(const wxSize& sz) { m_size = sz; }
1038
1039 /// Get/set the object position
1040 virtual wxPoint GetPosition() const { return m_pos; }
1041 virtual void SetPosition(const wxPoint& pos) { m_pos = pos; }
1042
1043 /// Get the rectangle enclosing the object
1044 virtual wxRect GetRect() const { return wxRect(GetPosition(), GetCachedSize()); }
1045
1046 /// Set the range
1047 void SetRange(const wxRichTextRange& range) { m_range = range; }
1048
1049 /// Get the range
1050 const wxRichTextRange& GetRange() const { return m_range; }
1051 wxRichTextRange& GetRange() { return m_range; }
1052
1053 /// Get/set dirty flag (whether the object needs Layout to be called)
1054 virtual bool GetDirty() const { return m_dirty; }
1055 virtual void SetDirty(bool dirty) { m_dirty = dirty; }
1056
1057 /// Is this composite?
1058 virtual bool IsComposite() const { return false; }
1059
1060 /// Get/set the parent.
1061 virtual wxRichTextObject* GetParent() const { return m_parent; }
1062 virtual void SetParent(wxRichTextObject* parent) { m_parent = parent; }
1063
1064 /// Set the margin around the object
1065 virtual void SetMargins(int margin);
1066 virtual void SetMargins(int leftMargin, int rightMargin, int topMargin, int bottomMargin);
1067 virtual int GetLeftMargin() const { return m_leftMargin; }
1068 virtual int GetRightMargin() const { return m_rightMargin; }
1069 virtual int GetTopMargin() const { return m_topMargin; }
1070 virtual int GetBottomMargin() const { return m_bottomMargin; }
1071
1072 /// Set/get attributes object
1073 void SetAttributes(const wxRichTextAttr& attr) { m_attributes = attr; }
1074 const wxRichTextAttr& GetAttributes() const { return m_attributes; }
1075 wxRichTextAttr& GetAttributes() { return m_attributes; }
1076
1077 /// Set/get properties
1078 wxRichTextProperties& GetProperties() { return m_properties; }
1079 const wxRichTextProperties& GetProperties() const { return m_properties; }
1080 void SetProperties(const wxRichTextProperties& props) { m_properties = props; }
1081
1082 /// Set/get stored descent
1083 void SetDescent(int descent) { m_descent = descent; }
1084 int GetDescent() const { return m_descent; }
1085
1086 /// Gets the containing buffer
1087 wxRichTextBuffer* GetBuffer() const;
1088
1089// Operations
1090
1091 /// Clone the object
1092 virtual wxRichTextObject* Clone() const { return NULL; }
1093
1094 /// Copy
1095 void Copy(const wxRichTextObject& obj);
1096
1097 /// Reference-counting allows us to use the same object in multiple
1098 /// lists (not yet used)
1099 void Reference() { m_refCount ++; }
1100 void Dereference();
1101
1102 /// Convert units in tenths of a millimetre to device units
1103 int ConvertTenthsMMToPixels(wxDC& dc, int units) const;
1104 static int ConvertTenthsMMToPixels(int ppi, int units, double scale = 1.0);
1105
1106 /// Convert units in pixels to tenths of a millimetre
1107 int ConvertPixelsToTenthsMM(wxDC& dc, int pixels) const;
1108 static int ConvertPixelsToTenthsMM(int ppi, int pixels, double scale = 1.0);
1109
1110 /// Draw the borders and background for the given rectangle and attributes.
1111 /// Width and height are taken to be the content size, so excluding any
1112 /// border, margin and padding.
1113 static bool DrawBoxAttributes(wxDC& dc, const wxRichTextAttr& attr, const wxRect& boxRect);
1114
1115 /// Draw a border
1116 static bool DrawBorder(wxDC& dc, const wxTextAttrBorders& attr, const wxRect& rect);
1117
1118 /// Get the various rectangles of the box model in pixels. You can either specify contentRect (inner)
1119 /// or marginRect (outer), and the other must be the default rectangle (no width or height).
1120 /// Note that the outline doesn't affect the position of the rectangle, it's drawn in whatever space
1121 /// is available.
1122 static bool GetBoxRects(wxDC& dc, const wxRichTextAttr& attr, wxRect& marginRect, wxRect& borderRect, wxRect& contentRect, wxRect& paddingRect, wxRect& outlineRect);
1123
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
1142 wxRichTextAttr m_attributes;
1143
1144 /// Properties
1145 wxRichTextProperties m_properties;
1146};
1147
1148WX_DECLARE_LIST_WITH_DECL( wxRichTextObject, wxRichTextObjectList, class WXDLLIMPEXP_RICHTEXT );
1149
1150/*!
1151 * wxRichTextCompositeObject class declaration
1152 * Objects of this class can contain other objects.
1153 */
1154
1155class WXDLLIMPEXP_RICHTEXT wxRichTextCompositeObject: public wxRichTextObject
1156{
1157 DECLARE_CLASS(wxRichTextCompositeObject)
1158public:
1159// Constructors
1160
1161 wxRichTextCompositeObject(wxRichTextObject* parent = NULL);
1162 virtual ~wxRichTextCompositeObject();
1163
1164// Overrideables
1165
1166 /// Hit-testing: returns a flag indicating hit test details, plus
1167 /// information about position
1168 virtual int HitTest(wxDC& dc, const wxPoint& pt, long& textPosition);
1169
1170 /// Finds the absolute position and row height for the given character position
1171 virtual bool FindPosition(wxDC& dc, long index, wxPoint& pt, int* height, bool forceLineStart);
1172
1173 /// Calculate range
1174 virtual void CalculateRange(long start, long& end);
1175
1176 /// Delete range
1177 virtual bool DeleteRange(const wxRichTextRange& range);
1178
1179 /// Get any text in this object for the given range
1180 virtual wxString GetTextForRange(const wxRichTextRange& range) const;
1181
1182 /// Dump to output stream for debugging
1183 virtual void Dump(wxTextOutputStream& stream);
1184
1185// Accessors
1186
1187 /// Get the children
1188 wxRichTextObjectList& GetChildren() { return m_children; }
1189 const wxRichTextObjectList& GetChildren() const { return m_children; }
1190
1191 /// Get the child count
1192 size_t GetChildCount() const ;
1193
1194 /// Get the nth child
1195 wxRichTextObject* GetChild(size_t n) const ;
1196
1197 /// Get/set dirty flag
1198 virtual bool GetDirty() const { return m_dirty; }
1199 virtual void SetDirty(bool dirty) { m_dirty = dirty; }
1200
1201 /// Is this composite?
1202 virtual bool IsComposite() const { return true; }
1203
1204 /// Returns true if the buffer is empty
1205 virtual bool IsEmpty() const { return GetChildCount() == 0; }
1206
1207// Operations
1208
1209 /// Copy
1210 void Copy(const wxRichTextCompositeObject& obj);
1211
1212 /// Assignment
1213 void operator= (const wxRichTextCompositeObject& obj) { Copy(obj); }
1214
1215 /// Append a child, returning the position
1216 size_t AppendChild(wxRichTextObject* child) ;
1217
1218 /// Insert the child in front of the given object, or at the beginning
1219 bool InsertChild(wxRichTextObject* child, wxRichTextObject* inFrontOf) ;
1220
1221 /// Delete the child
1222 bool RemoveChild(wxRichTextObject* child, bool deleteChild = false) ;
1223
1224 /// Delete all children
1225 bool DeleteChildren() ;
1226
1227 /// Recursively merge all pieces that can be merged.
1228 bool Defragment(const wxRichTextRange& range = wxRICHTEXT_ALL);
1229
1230protected:
1231 wxRichTextObjectList m_children;
1232};
1233
1234/*!
1235 * wxRichTextParagraphBox class declaration
1236 * This box knows how to lay out paragraphs.
1237 */
1238
1239class WXDLLIMPEXP_RICHTEXT wxRichTextParagraphLayoutBox: public wxRichTextCompositeObject
1240{
1241 DECLARE_DYNAMIC_CLASS(wxRichTextParagraphLayoutBox)
1242public:
1243// Constructors
1244
1245 wxRichTextParagraphLayoutBox(wxRichTextObject* parent = NULL);
1246 wxRichTextParagraphLayoutBox(const wxRichTextParagraphLayoutBox& obj): wxRichTextCompositeObject() { Init(); Copy(obj); }
1247 ~wxRichTextParagraphLayoutBox();
1248
1249// Overrideables
1250
1251 /// Hit-testing: returns a flag indicating hit test details, plus
1252 /// information about position
1253 virtual int HitTest(wxDC& dc, const wxPoint& pt, long& textPosition);
1254
1255 /// Draw the item
1256 virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style);
1257
1258 /// Lay the item out
1259 virtual bool Layout(wxDC& dc, const wxRect& rect, int style);
1260
1261 /// Get/set the object size for the given range. Returns false if the range
1262 /// is invalid for this object.
1263 virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const;
1264
1265 /// Delete range
1266 virtual bool DeleteRange(const wxRichTextRange& range);
1267
1268 /// Get any text in this object for the given range
1269 virtual wxString GetTextForRange(const wxRichTextRange& range) const;
1270
1271#if wxUSE_XML
1272 /// Import this object from XML
1273 virtual bool ImportFromXML(wxRichTextBuffer* buffer, wxXmlNode* node, wxRichTextXMLHandler* handler);
1274#endif
1275
1276#if wxRICHTEXT_HAVE_DIRECT_OUTPUT
1277 /// Export this object directly to the given stream.
1278 virtual bool ExportXML(wxOutputStream& stream, int indent, wxRichTextXMLHandler* handler);
1279#endif
1280
1281#if wxRICHTEXT_HAVE_XMLDOCUMENT_OUTPUT
1282 /// Export this object to the given parent node, usually creating at least one child node.
1283 virtual bool ExportXML(wxXmlNode* parent, wxRichTextXMLHandler* handler);
1284#endif
1285
1286 /// What is the XML node name of this object?
1287 virtual wxString GetXMLNodeName() const { return wxT("paragraphlayout"); }
1288
1289// Accessors
1290
1291 /// Associate a control with the buffer, for operations that for example require refreshing the window.
1292 void SetRichTextCtrl(wxRichTextCtrl* ctrl) { m_ctrl = ctrl; }
1293
1294 /// Get the associated control.
1295 wxRichTextCtrl* GetRichTextCtrl() const { return m_ctrl; }
1296
1297 /// Get/set whether the last paragraph is partial or complete
1298 void SetPartialParagraph(bool partialPara) { m_partialParagraph = partialPara; }
1299 bool GetPartialParagraph() const { return m_partialParagraph; }
1300
1301 /// If this is a buffer, returns the current style sheet. The base layout box
1302 /// class doesn't have an associated style sheet.
1303 virtual wxRichTextStyleSheet* GetStyleSheet() const { return NULL; }
1304
1305// Operations
1306 /// Draw the floats of this buffer
1307 void DrawFloats(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style);
1308
1309 /// Move an anchored object to another paragraph
1310 void MoveAnchoredObjectToParagraph(wxRichTextParagraph* from, wxRichTextParagraph* to, wxRichTextObject* obj);
1311
1312 /// Initialize the object.
1313 void Init();
1314
1315 /// Clear all children
1316 virtual void Clear();
1317
1318 /// Clear and initialize with one blank paragraph
1319 virtual void Reset();
1320
1321 /// Convenience function to add a paragraph of text
1322 virtual wxRichTextRange AddParagraph(const wxString& text, wxRichTextAttr* paraStyle = NULL);
1323
1324 /// Convenience function to add an image
1325 virtual wxRichTextRange AddImage(const wxImage& image, wxRichTextAttr* paraStyle = NULL);
1326
1327 /// Adds multiple paragraphs, based on newlines.
1328 virtual wxRichTextRange AddParagraphs(const wxString& text, wxRichTextAttr* paraStyle = NULL);
1329
1330 /// Get the line at the given position. If caretPosition is true, the position is
1331 /// a caret position, which is normally a smaller number.
1332 virtual wxRichTextLine* GetLineAtPosition(long pos, bool caretPosition = false) const;
1333
1334 /// Get the line at the given y pixel position, or the last line.
1335 virtual wxRichTextLine* GetLineAtYPosition(int y) const;
1336
1337 /// Get the paragraph at the given character or caret position
1338 virtual wxRichTextParagraph* GetParagraphAtPosition(long pos, bool caretPosition = false) const;
1339
1340 /// Get the line size at the given position
1341 virtual wxSize GetLineSizeAtPosition(long pos, bool caretPosition = false) const;
1342
1343 /// Given a position, get the number of the visible line (potentially many to a paragraph),
1344 /// starting from zero at the start of the buffer. We also have to pass a bool (startOfLine)
1345 /// that indicates whether the caret is being shown at the end of the previous line or at the start
1346 /// of the next, since the caret can be shown at 2 visible positions for the same underlying
1347 /// position.
1348 virtual long GetVisibleLineNumber(long pos, bool caretPosition = false, bool startOfLine = false) const;
1349
1350 /// Given a line number, get the corresponding wxRichTextLine object.
1351 virtual wxRichTextLine* GetLineForVisibleLineNumber(long lineNumber) const;
1352
1353 /// Get the leaf object in a paragraph at this position.
1354 /// Given a line number, get the corresponding wxRichTextLine object.
1355 virtual wxRichTextObject* GetLeafObjectAtPosition(long position) const;
1356
1357 /// Get the paragraph by number
1358 virtual wxRichTextParagraph* GetParagraphAtLine(long paragraphNumber) const;
1359
1360 /// Get the paragraph for a given line
1361 virtual wxRichTextParagraph* GetParagraphForLine(wxRichTextLine* line) const;
1362
1363 /// Get the length of the paragraph
1364 virtual int GetParagraphLength(long paragraphNumber) const;
1365
1366 /// Get the number of paragraphs
1367 virtual int GetParagraphCount() const { return static_cast<int>(GetChildCount()); }
1368
1369 /// Get the number of visible lines
1370 virtual int GetLineCount() const;
1371
1372 /// Get the text of the paragraph
1373 virtual wxString GetParagraphText(long paragraphNumber) const;
1374
1375 /// Convert zero-based line column and paragraph number to a position.
1376 virtual long XYToPosition(long x, long y) const;
1377
1378 /// Convert zero-based position to line column and paragraph number
1379 virtual bool PositionToXY(long pos, long* x, long* y) const;
1380
1381 /// Set text attributes: character and/or paragraph styles.
1382 virtual bool SetStyle(const wxRichTextRange& range, const wxRichTextAttr& style, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO);
1383
1384 /// Set image attribute
1385 void SetImageStyle(wxRichTextImage *image, const wxRichTextAttr& textAttr, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO);
1386
1387 /// Get the conbined text attributes for this position.
1388 virtual bool GetStyle(long position, wxRichTextAttr& style);
1389
1390 /// Get the content (uncombined) attributes for this position.
1391 virtual bool GetUncombinedStyle(long position, wxRichTextAttr& style);
1392
1393 /// Implementation helper for GetStyle. If combineStyles is true, combine base, paragraph and
1394 /// context attributes.
1395 virtual bool DoGetStyle(long position, wxRichTextAttr& style, bool combineStyles = true);
1396
1397 /// Get the combined style for a range - if any attribute is different within the range,
1398 /// that attribute is not present within the flags
1399 virtual bool GetStyleForRange(const wxRichTextRange& range, wxRichTextAttr& style);
1400
1401 /// Combines 'style' with 'currentStyle' for the purpose of summarising the attributes of a range of
1402 /// content.
1403 bool CollectStyle(wxRichTextAttr& currentStyle, const wxRichTextAttr& style, wxRichTextAttr& clashingAttr, wxRichTextAttr& absentAttr);
1404
1405 /// Set list style
1406 virtual bool SetListStyle(const wxRichTextRange& range, wxRichTextListStyleDefinition* def, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int startFrom = 1, int specifiedLevel = -1);
1407 virtual bool SetListStyle(const wxRichTextRange& range, const wxString& defName, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int startFrom = 1, int specifiedLevel = -1);
1408
1409 /// Clear list for given range
1410 virtual bool ClearListStyle(const wxRichTextRange& range, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO);
1411
1412 /// Number/renumber any list elements in the given range.
1413 /// def/defName can be NULL/empty to indicate that the existing list style should be used.
1414 virtual bool NumberList(const wxRichTextRange& range, wxRichTextListStyleDefinition* def = NULL, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int startFrom = 1, int specifiedLevel = -1);
1415 virtual bool NumberList(const wxRichTextRange& range, const wxString& defName, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int startFrom = 1, int specifiedLevel = -1);
1416
1417 /// Promote the list items within the given range. promoteBy can be a positive or negative number, e.g. 1 or -1
1418 /// def/defName can be NULL/empty to indicate that the existing list style should be used.
1419 virtual bool PromoteList(int promoteBy, const wxRichTextRange& range, wxRichTextListStyleDefinition* def = NULL, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int specifiedLevel = -1);
1420 virtual bool PromoteList(int promoteBy, const wxRichTextRange& range, const wxString& defName, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int specifiedLevel = -1);
1421
1422 /// Helper for NumberList and PromoteList, that does renumbering and promotion simultaneously
1423 /// def/defName can be NULL/empty to indicate that the existing list style should be used.
1424 virtual bool DoNumberList(const wxRichTextRange& range, const wxRichTextRange& promotionRange, int promoteBy, wxRichTextListStyleDefinition* def, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int startFrom = 1, int specifiedLevel = -1);
1425
1426 /// Fills in the attributes for numbering a paragraph after previousParagraph.
1427 virtual bool FindNextParagraphNumber(wxRichTextParagraph* previousParagraph, wxRichTextAttr& attr) const;
1428
1429 /// Test if this whole range has character attributes of the specified kind. If any
1430 /// of the attributes are different within the range, the test fails. You
1431 /// can use this to implement, for example, bold button updating. style must have
1432 /// flags indicating which attributes are of interest.
1433 virtual bool HasCharacterAttributes(const wxRichTextRange& range, const wxRichTextAttr& style) const;
1434
1435 /// Test if this whole range has paragraph attributes of the specified kind. If any
1436 /// of the attributes are different within the range, the test fails. You
1437 /// can use this to implement, for example, centering button updating. style must have
1438 /// flags indicating which attributes are of interest.
1439 virtual bool HasParagraphAttributes(const wxRichTextRange& range, const wxRichTextAttr& style) const;
1440
1441 /// Clone
1442 virtual wxRichTextObject* Clone() const { return new wxRichTextParagraphLayoutBox(*this); }
1443
1444 /// Insert fragment into this box at the given position. If partialParagraph is true,
1445 /// it is assumed that the last (or only) paragraph is just a piece of data with no paragraph
1446 /// marker.
1447 virtual bool InsertFragment(long position, wxRichTextParagraphLayoutBox& fragment);
1448
1449 /// Make a copy of the fragment corresponding to the given range, putting it in 'fragment'.
1450 virtual bool CopyFragment(const wxRichTextRange& range, wxRichTextParagraphLayoutBox& fragment);
1451
1452 /// Apply the style sheet to the buffer, for example if the styles have changed.
1453 virtual bool ApplyStyleSheet(wxRichTextStyleSheet* styleSheet);
1454
1455 /// Copy
1456 void Copy(const wxRichTextParagraphLayoutBox& obj);
1457
1458 /// Assignment
1459 void operator= (const wxRichTextParagraphLayoutBox& obj) { Copy(obj); }
1460
1461 /// Calculate ranges
1462 virtual void UpdateRanges() { long end; CalculateRange(0, end); }
1463
1464 /// Get all the text
1465 virtual wxString GetText() const;
1466
1467 /// Set default style for new content. Setting it to a default attribute
1468 /// makes new content take on the 'basic' style.
1469 virtual bool SetDefaultStyle(const wxRichTextAttr& style);
1470
1471 /// Get default style
1472 virtual const wxRichTextAttr& GetDefaultStyle() const { return m_defaultAttributes; }
1473
1474 /// Set basic (overall) style
1475 virtual void SetBasicStyle(const wxRichTextAttr& style) { m_attributes = style; }
1476
1477 /// Get basic (overall) style
1478 virtual const wxRichTextAttr& GetBasicStyle() const { return m_attributes; }
1479
1480 /// Invalidate the buffer. With no argument, invalidates whole buffer.
1481 void Invalidate(const wxRichTextRange& invalidRange = wxRICHTEXT_ALL);
1482
1483 /// Gather information about floating objects. If untilObj is non-NULL,
1484 /// will stop getting information if the current object is this, since we
1485 /// will collect the rest later.
1486 virtual bool UpdateFloatingObjects(int width, wxRichTextObject* untilObj = NULL);
1487
1488 /// Get invalid range, rounding to entire paragraphs if argument is true.
1489 wxRichTextRange GetInvalidRange(bool wholeParagraphs = false) const;
1490
1491 /// Get the wxRichTextFloatCollector of this object
1492 wxRichTextFloatCollector* GetFloatCollector() { return m_floatCollector; }
1493
1494protected:
1495 wxRichTextCtrl* m_ctrl;
1496 wxRichTextAttr m_defaultAttributes;
1497
1498 /// The invalidated range that will need full layout
1499 wxRichTextRange m_invalidRange;
1500
1501 // Is the last paragraph partial or complete?
1502 bool m_partialParagraph;
1503
1504 // The floating layout state
1505 wxRichTextFloatCollector* m_floatCollector;
1506};
1507
1508/*!
1509 * wxRichTextBox class declaration
1510 * TODO: a floating text box
1511 */
1512
1513class WXDLLIMPEXP_RICHTEXT wxRichTextBox: public wxRichTextCompositeObject
1514{
1515 DECLARE_DYNAMIC_CLASS(wxRichTextBox)
1516public:
1517// Constructors
1518
1519 wxRichTextBox(wxRichTextObject* parent = NULL);
1520 wxRichTextBox(const wxRichTextBox& obj): wxRichTextCompositeObject() { Copy(obj); }
1521
1522// Overrideables
1523
1524 /// Draw the item
1525 virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style);
1526
1527 /// Lay the item out
1528 virtual bool Layout(wxDC& dc, const wxRect& rect, int style);
1529
1530 /// 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
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
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
1554class WXDLLIMPEXP_RICHTEXT wxRichTextLine
1555{
1556public:
1557// Constructors
1558
1559 wxRichTextLine(wxRichTextParagraph* parent);
1560 wxRichTextLine(const wxRichTextLine& obj) { Init( NULL); Copy(obj); }
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
1578 /// Get the absolute range
1579 wxRichTextRange GetAbsoluteRange() const;
1580
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
1599#if wxRICHTEXT_USE_OPTIMIZED_LINE_DRAWING
1600 wxArrayInt& GetObjectSizes() { return m_objectSizes; }
1601 const wxArrayInt& GetObjectSizes() const { return m_objectSizes; }
1602#endif
1603
1604// Operations
1605
1606 /// Initialisation
1607 void Init(wxRichTextParagraph* parent);
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)
1618 /// This is relative to the parent paragraph.
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;
1630
1631#if wxRICHTEXT_USE_OPTIMIZED_LINE_DRAWING
1632 wxArrayInt m_objectSizes;
1633#endif
1634};
1635
1636WX_DECLARE_LIST_WITH_DECL( wxRichTextLine, wxRichTextLineList , class WXDLLIMPEXP_RICHTEXT );
1637
1638/*!
1639 * wxRichTextParagraph class declaration
1640 * This object represents a single paragraph (or in a straight text editor, a line).
1641 */
1642
1643class WXDLLIMPEXP_RICHTEXT wxRichTextParagraph: public wxRichTextBox
1644{
1645 DECLARE_DYNAMIC_CLASS(wxRichTextParagraph)
1646public:
1647// Constructors
1648
1649 wxRichTextParagraph(wxRichTextObject* parent = NULL, wxRichTextAttr* style = NULL);
1650 wxRichTextParagraph(const wxString& text, wxRichTextObject* parent = NULL, wxRichTextAttr* paraStyle = NULL, wxRichTextAttr* charStyle = NULL);
1651 virtual ~wxRichTextParagraph();
1652 wxRichTextParagraph(const wxRichTextParagraph& obj): wxRichTextBox() { Copy(obj); }
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
1660 virtual bool Layout(wxDC& dc, const wxRect& rect, int style);
1661
1662 /// Get/set the object size for the given range. Returns false if the range
1663 /// is invalid for this object.
1664 virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const;
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
1676 /// What is the XML node name of this object?
1677 virtual wxString GetXMLNodeName() const { return wxT("paragraph"); }
1678
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
1698 virtual void ApplyParagraphStyle(const wxRichTextAttr& attr, const wxRect& rect, wxDC& dc);
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.
1719 bool FindWrapPosition(const wxRichTextRange& range, wxDC& dc, int availableSpace, long& wrapPosition, wxArrayInt* partialExtents);
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
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
1733 /// Get combined attributes of the base style, paragraph style and character style. We use this to dynamically
1734 /// retrieve the actual style.
1735 wxRichTextAttr GetCombinedAttributes(const wxRichTextAttr& contentStyle) const;
1736
1737 /// Get combined attributes of the base style and paragraph style.
1738 wxRichTextAttr GetCombinedAttributes() const;
1739
1740 /// Get the first position from pos that has a line break character.
1741 long GetFirstLineBreakPosition(long pos);
1742
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
1752 /// Layout the floats object
1753 void LayoutFloat(wxDC& dc, const wxRect& rect, int style, wxRichTextFloatCollector* floatCollector);
1754
1755protected:
1756 /// The lines that make up the wrapped paragraph
1757 wxRichTextLineList m_cachedLines;
1758
1759 /// Default tabstops
1760 static wxArrayInt sm_defaultTabs;
1761
1762friend class wxRichTextFloatCollector;
1763};
1764
1765/*!
1766 * wxRichTextPlainText class declaration
1767 * This object represents a single piece of text.
1768 */
1769
1770class WXDLLIMPEXP_RICHTEXT wxRichTextPlainText: public wxRichTextObject
1771{
1772 DECLARE_DYNAMIC_CLASS(wxRichTextPlainText)
1773public:
1774// Constructors
1775
1776 wxRichTextPlainText(const wxString& text = wxEmptyString, wxRichTextObject* parent = NULL, wxRichTextAttr* style = NULL);
1777 wxRichTextPlainText(const wxRichTextPlainText& obj): wxRichTextObject() { Copy(obj); }
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
1785 virtual bool Layout(wxDC& dc, const wxRect& rect, int style);
1786
1787 /// Get/set the object size for the given range. Returns false if the range
1788 /// is invalid for this object.
1789 virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const;
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
1805 virtual bool IsEmpty() const { return m_text.empty(); }
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
1817 /// Get the first position from pos that has a line break character.
1818 long GetFirstLineBreakPosition(long pos);
1819
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
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); }
1856private:
1857 bool DrawTabbedString(wxDC& dc, const wxRichTextAttr& attr, const wxRect& rect, wxString& str, wxCoord& x, wxCoord& y, bool selected);
1858
1859protected:
1860 wxString m_text;
1861};
1862
1863/*!
1864 * wxRichTextImageBlock stores information about an image, in binary in-memory form
1865 */
1866
1867class WXDLLIMPEXP_FWD_BASE wxDataInputStream;
1868class WXDLLIMPEXP_FWD_BASE wxDataOutputStream;
1869
1870class WXDLLIMPEXP_RICHTEXT wxRichTextImageBlock: public wxObject
1871{
1872public:
1873 wxRichTextImageBlock();
1874 wxRichTextImageBlock(const wxRichTextImageBlock& block);
1875 virtual ~wxRichTextImageBlock();
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.
1885 virtual bool MakeImageBlock(const wxString& filename, wxBitmapType imageType,
1886 wxImage& image, bool convertToJPEG = true);
1887
1888 // Make an image block from the wxImage in the given
1889 // format.
1890 virtual bool MakeImageBlock(wxImage& image, wxBitmapType imageType, int quality = 80);
1891
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);
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
1905 bool ReadHex(wxInputStream& stream, int length, wxBitmapType imageType);
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; }
1920 wxBitmapType GetImageType() const { return m_imageType; }
1921
1922 void SetData(unsigned char* image) { m_data = image; }
1923 void SetDataSize(size_t size) { m_dataSize = size; }
1924 void SetImageType(wxBitmapType imageType) { m_imageType = imageType; }
1925
1926 bool Ok() const { return IsOk(); }
1927 bool IsOk() const { return GetData() != NULL; }
1928
1929 // Gets the extension for the block's type
1930 wxString GetExtension() const;
1931
1932/// Implementation
1933
1934 // Allocate and read from stream as a block of memory
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;
1949 wxBitmapType m_imageType;
1950};
1951
1952/*!
1953 * wxRichTextImage class declaration
1954 * This object represents an image.
1955 */
1956
1957class WXDLLIMPEXP_RICHTEXT wxRichTextImage: public wxRichTextObject
1958{
1959 DECLARE_DYNAMIC_CLASS(wxRichTextImage)
1960public:
1961// Constructors
1962
1963 wxRichTextImage(wxRichTextObject* parent = NULL): wxRichTextObject(parent) { }
1964 wxRichTextImage(const wxImage& image, wxRichTextObject* parent = NULL, wxRichTextAttr* charStyle = NULL);
1965 wxRichTextImage(const wxRichTextImageBlock& imageBlock, wxRichTextObject* parent = NULL, wxRichTextAttr* charStyle = NULL);
1966 wxRichTextImage(const wxRichTextImage& obj): wxRichTextObject(obj) { Copy(obj); }
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
1974 virtual bool Layout(wxDC& dc, const wxRect& rect, int style);
1975
1976 /// Get the object size for the given range. Returns false if the range
1977 /// is invalid for this object.
1978 virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const;
1979
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(); */ }
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);
1988
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
2013// Accessors
2014
2015 /// Get the image cache (scaled bitmap)
2016 const wxBitmap& GetImageCache() const { return m_imageCache; }
2017
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; }
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
2035 /// Create a cached image at the required size
2036 virtual bool LoadImageCache(wxDC& dc, bool resetCache = false);
2037
2038protected:
2039 wxRichTextImageBlock m_imageBlock;
2040 wxBitmap m_imageCache;
2041};
2042
2043
2044/*!
2045 * wxRichTextBuffer class declaration
2046 * This is a kind of box, used to represent the whole buffer
2047 */
2048
2049class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextCommand;
2050class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextAction;
2051
2052class WXDLLIMPEXP_RICHTEXT wxRichTextBuffer: public wxRichTextParagraphLayoutBox
2053{
2054 DECLARE_DYNAMIC_CLASS(wxRichTextBuffer)
2055public:
2056// Constructors
2057
2058 wxRichTextBuffer() { Init(); }
2059 wxRichTextBuffer(const wxRichTextBuffer& obj): wxRichTextParagraphLayoutBox() { Init(); Copy(obj); }
2060 virtual ~wxRichTextBuffer() ;
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; }
2069 virtual wxRichTextStyleSheet* GetStyleSheet() const { return m_styleSheet; }
2070
2071 /// Set style sheet and notify of the change
2072 bool SetStyleSheetAndNotify(wxRichTextStyleSheet* sheet);
2073
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();
2079
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
2085// Operations
2086
2087 /// Initialisation
2088 void Init();
2089
2090 /// Clears the buffer, adds an empty paragraph, and clears the command processor.
2091 virtual void ResetAndClearCommands();
2092
2093 /// Load a file
2094 virtual bool LoadFile(const wxString& filename, wxRichTextFileType type = wxRICHTEXT_TYPE_ANY);
2095
2096 /// Save a file
2097 virtual bool SaveFile(const wxString& filename, wxRichTextFileType type = wxRICHTEXT_TYPE_ANY);
2098
2099 /// Load from a stream
2100 virtual bool LoadFile(wxInputStream& stream, wxRichTextFileType type = wxRICHTEXT_TYPE_ANY);
2101
2102 /// Save to a stream
2103 virtual bool SaveFile(wxOutputStream& stream, wxRichTextFileType type = wxRICHTEXT_TYPE_ANY);
2104
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
2111 /// Convenience function to add a paragraph of text
2112 virtual wxRichTextRange AddParagraph(const wxString& text, wxRichTextAttr* paraStyle = NULL) { Modify(); return wxRichTextParagraphLayoutBox::AddParagraph(text, paraStyle); }
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
2153 virtual bool BeginStyle(const wxRichTextAttr& style);
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
2165 virtual size_t GetStyleStackSize() const { return m_attributeStack.GetCount(); }
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
2240 bool BeginSymbolBullet(const wxString& symbol, int leftIndent, int leftSubIndent, int bulletStyle = wxTEXT_ATTR_BULLET_STYLE_SYMBOL);
2241
2242 /// End symbol bullet
2243 bool EndSymbolBullet() { return EndStyle(); }
2244
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
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(); }
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(); }
2268
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
2290// Implementation
2291
2292 /// Copy
2293 void Copy(const wxRichTextBuffer& obj);
2294
2295 /// Assignment
2296 void operator= (const wxRichTextBuffer& obj) { Copy(obj); }
2297
2298 /// Clone
2299 virtual wxRichTextObject* Clone() const { return new wxRichTextBuffer(*this); }
2300
2301 /// Submit command to insert paragraphs
2302 bool InsertParagraphsWithUndo(long pos, const wxRichTextParagraphLayoutBox& paragraphs, wxRichTextCtrl* ctrl, int flags = 0);
2303
2304 /// Submit command to insert the given text
2305 bool InsertTextWithUndo(long pos, const wxString& text, wxRichTextCtrl* ctrl, int flags = 0);
2306
2307 /// Submit command to insert a newline
2308 bool InsertNewlineWithUndo(long pos, wxRichTextCtrl* ctrl, int flags = 0);
2309
2310 /// Submit command to insert the given image
2311 bool InsertImageWithUndo(long pos, const wxRichTextImageBlock& imageBlock, wxRichTextCtrl* ctrl, int flags = 0,
2312 const wxRichTextAttr& textAttr = wxRichTextAttr());
2313
2314 /// Submit command to insert an object
2315 bool InsertObjectWithUndo(long pos, wxRichTextObject *object, wxRichTextCtrl* ctrl, int flags);
2316
2317 /// Submit command to delete this range
2318 bool DeleteRangeWithUndo(const wxRichTextRange& range, wxRichTextCtrl* ctrl);
2319
2320 /// Mark modified
2321 void Modify(bool modify = true) { m_modified = modify; }
2322 bool IsModified() const { return m_modified; }
2323
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.
2327 wxRichTextAttr GetStyleForNewParagraph(long pos, bool caretPosition = false, bool lookUpNewParaStyle=false) const;
2328
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
2349 static wxRichTextFileHandler *FindHandler(const wxString& extension, wxRichTextFileType imageType);
2350
2351 /// Finds a handler by filename or, if supplied, type
2352 static wxRichTextFileHandler *FindHandlerFilenameOrType(const wxString& filename,
2353 wxRichTextFileType imageType);
2354
2355 /// Finds a handler by type
2356 static wxRichTextFileHandler *FindHandler(wxRichTextFileType imageType);
2357
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);
2362
2363 /// Clean up handlers
2364 static void CleanUpHandlers();
2365
2366 /// Initialise the standard handlers
2367 static void InitStandardHandlers();
2368
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; }
2382
2383 /// Scale factor for calculating dimensions
2384 double GetScale() const { return m_scale; }
2385 void SetScale(double scale) { m_scale = scale; }
2386
2387protected:
2388
2389 /// Command processor
2390 wxCommandProcessor* m_commandProcessor;
2391
2392 /// Table storing fonts
2393 wxRichTextFontTable m_fontTable;
2394
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
2413 /// List of event handlers that will be notified of events
2414 wxList m_eventHandlers;
2415
2416 /// Stack of attributes for convenience functions
2417 wxList m_attributeStack;
2418
2419 /// Flags to be passed to handlers
2420 int m_handlerFlags;
2421
2422 /// File handlers
2423 static wxList sm_handlers;
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;
2433
2434 /// Scaling factor in use: needed to calculate correct dimensions when printing
2435 double m_scale;
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
2455class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextAction;
2456class WXDLLIMPEXP_RICHTEXT wxRichTextCommand: public wxCommand
2457{
2458public:
2459 // Ctor for one action
2460 wxRichTextCommand(const wxString& name, wxRichTextCommandId id, wxRichTextBuffer* buffer,
2461 wxRichTextCtrl* ctrl, bool ignoreFirstTime = false);
2462
2463 // Ctor for multiple actions
2464 wxRichTextCommand(const wxString& name);
2465
2466 virtual ~wxRichTextCommand();
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
2486class WXDLLIMPEXP_RICHTEXT wxRichTextAction: public wxObject
2487{
2488public:
2489 wxRichTextAction(wxRichTextCommand* cmd, const wxString& name, wxRichTextCommandId id, wxRichTextBuffer* buffer,
2490 wxRichTextCtrl* ctrl, bool ignoreFirstTime = false);
2491
2492 virtual ~wxRichTextAction();
2493
2494 bool Do();
2495 bool Undo();
2496
2497 /// Update the control appearance
2498 void UpdateAppearance(long caretPosition, bool sendUpdateEvent = false,
2499 wxArrayInt* optimizationLineCharPositions = NULL, wxArrayInt* optimizationLineYPositions = NULL, bool isDoCmd = true);
2500
2501 /// Replace the buffer paragraphs with the given fragment.
2502 void ApplyParagraphs(const wxRichTextParagraphLayoutBox& fragment);
2503
2504 /// Get the fragments
2505 wxRichTextParagraphLayoutBox& GetNewParagraphs() { return m_newParagraphs; }
2506 wxRichTextParagraphLayoutBox& GetOldParagraphs() { return m_oldParagraphs; }
2507
2508 /// Calculate arrays for refresh optimization
2509 void CalculateRefreshOptimizations(wxArrayInt& optimizationLineCharPositions, wxArrayInt& optimizationLineYPositions);
2510
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
2533 wxRichTextParagraphLayoutBox m_newParagraphs;
2534
2535 // Stores the old paragraphs
2536 wxRichTextParagraphLayoutBox m_oldParagraphs;
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
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
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
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
2575/*!
2576 * wxRichTextFileHandler
2577 * Base class for file handlers
2578 */
2579
2580class WXDLLIMPEXP_RICHTEXT wxRichTextFileHandler: public wxObject
2581{
2582 DECLARE_CLASS(wxRichTextFileHandler)
2583public:
2584 wxRichTextFileHandler(const wxString& name = wxEmptyString, const wxString& ext = wxEmptyString, int type = 0)
2585 : m_name(name), m_extension(ext), m_type(type), m_flags(0), m_visible(true)
2586 { }
2587
2588#if wxUSE_STREAMS
2589 bool LoadFile(wxRichTextBuffer *buffer, wxInputStream& stream)
2590 { return DoLoadFile(buffer, stream); }
2591 bool SaveFile(wxRichTextBuffer *buffer, wxOutputStream& stream)
2592 { return DoSaveFile(buffer, stream); }
2593#endif
2594
2595#if wxUSE_FFILE && wxUSE_STREAMS
2596 virtual bool LoadFile(wxRichTextBuffer *buffer, const wxString& filename);
2597 virtual bool SaveFile(wxRichTextBuffer *buffer, const wxString& filename);
2598#endif // wxUSE_STREAMS && wxUSE_STREAMS
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
2613 /// The name of the nandler
2614 void SetName(const wxString& name) { m_name = name; }
2615 wxString GetName() const { return m_name; }
2616
2617 /// The default extension to recognise
2618 void SetExtension(const wxString& ext) { m_extension = ext; }
2619 wxString GetExtension() const { return m_extension; }
2620
2621 /// The handler type
2622 void SetType(int type) { m_type = type; }
2623 int GetType() const { return m_type; }
2624
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
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
2633protected:
2634
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
2640 wxString m_name;
2641 wxString m_encoding;
2642 wxString m_extension;
2643 int m_type;
2644 int m_flags;
2645 bool m_visible;
2646};
2647
2648/*!
2649 * wxRichTextPlainTextHandler
2650 * Plain text handler
2651 */
2652
2653class WXDLLIMPEXP_RICHTEXT wxRichTextPlainTextHandler: public wxRichTextFileHandler
2654{
2655 DECLARE_CLASS(wxRichTextPlainTextHandler)
2656public:
2657 wxRichTextPlainTextHandler(const wxString& name = wxT("Text"),
2658 const wxString& ext = wxT("txt"),
2659 wxRichTextFileType type = wxRICHTEXT_TYPE_TEXT)
2660 : wxRichTextFileHandler(name, ext, type)
2661 { }
2662
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
2671#if wxUSE_STREAMS
2672 virtual bool DoLoadFile(wxRichTextBuffer *buffer, wxInputStream& stream);
2673 virtual bool DoSaveFile(wxRichTextBuffer *buffer, wxOutputStream& stream);
2674#endif
2675
2676};
2677
2678#if wxUSE_DATAOBJ
2679
2680/*!
2681 * The data object for a wxRichTextBuffer
2682 */
2683
2684class WXDLLIMPEXP_RICHTEXT wxRichTextBufferDataObject: public wxDataObjectSimple
2685{
2686public:
2687 // ctor doesn't copy the pointer, so it shouldn't go away while this object
2688 // is alive
2689 wxRichTextBufferDataObject(wxRichTextBuffer* richTextBuffer = NULL);
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
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
2731 virtual bool DrawStandardBullet(wxRichTextParagraph* paragraph, wxDC& dc, const wxRichTextAttr& attr, const wxRect& rect) = 0;
2732
2733 /// Draw a bullet that can be described by text, such as numbered or symbol bullets
2734 virtual bool DrawTextBullet(wxRichTextParagraph* paragraph, wxDC& dc, const wxRichTextAttr& attr, const wxRect& rect, const wxString& text) = 0;
2735
2736 /// Draw a bitmap bullet, where the bullet bitmap is specified by the value of GetBulletName
2737 virtual bool DrawBitmapBullet(wxRichTextParagraph* paragraph, wxDC& dc, const wxRichTextAttr& attr, const wxRect& rect) = 0;
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
2753 virtual bool DrawStandardBullet(wxRichTextParagraph* paragraph, wxDC& dc, const wxRichTextAttr& attr, const wxRect& rect);
2754
2755 /// Draw a bullet that can be described by text, such as numbered or symbol bullets
2756 virtual bool DrawTextBullet(wxRichTextParagraph* paragraph, wxDC& dc, const wxRichTextAttr& attr, const wxRect& rect, const wxString& text);
2757
2758 /// Draw a bitmap bullet, where the bullet bitmap is specified by the value of GetBulletName
2759 virtual bool DrawBitmapBullet(wxRichTextParagraph* paragraph, wxDC& dc, const wxRichTextAttr& attr, const wxRect& rect);
2760
2761 /// Enumerate the standard bullet names currently supported
2762 virtual bool EnumerateStandardBulletNames(wxArrayString& bulletNames);
2763};
2764
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
2776WXDLLIMPEXP_RICHTEXT bool wxTextAttrEq(const wxRichTextAttr& attr1, const wxRichTextAttr& attr2);
2777WXDLLIMPEXP_RICHTEXT bool wxTextAttrEq(const wxRichTextAttr& attr1, const wxRichTextAttr& attr2);
2778
2779/// Compare two attribute objects, but take into account the flags
2780/// specifying attributes of interest.
2781WXDLLIMPEXP_RICHTEXT bool wxTextAttrEqPartial(const wxRichTextAttr& attr1, const wxRichTextAttr& attr2);
2782
2783/// Apply one style to another
2784WXDLLIMPEXP_RICHTEXT bool wxRichTextApplyStyle(wxRichTextAttr& destStyle, const wxRichTextAttr& style, wxRichTextAttr* compareWith = NULL);
2785
2786// Remove attributes
2787WXDLLIMPEXP_RICHTEXT bool wxRichTextRemoveStyle(wxRichTextAttr& destStyle, const wxRichTextAttr& style);
2788
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
2795/// Split into paragraph and character styles
2796WXDLLIMPEXP_RICHTEXT bool wxRichTextSplitParaCharStyles(const wxRichTextAttr& style, wxRichTextAttr& parStyle, wxRichTextAttr& charStyle);
2797
2798/// Compare tabs
2799WXDLLIMPEXP_RICHTEXT bool wxRichTextTabsEq(const wxArrayInt& tabs1, const wxArrayInt& tabs2);
2800
2801/// Convert a decimal to Roman numerals
2802WXDLLIMPEXP_RICHTEXT wxString wxRichTextDecimalToRoman(long n);
2803
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
2808WXDLLIMPEXP_RICHTEXT void wxRichTextModuleInit();
2809
2810#endif
2811 // wxUSE_RICHTEXT
2812
2813#endif
2814 // _WX_RICHTEXTBUFFER_H_
2815