]> git.saurik.com Git - wxWidgets.git/blob - include/wx/richtext/richtextbuffer.h
30db130e42208b2dd42c22289e21bfcc5f9d68a8
[wxWidgets.git] / include / wx / richtext / richtextbuffer.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/richtext/richtextbuffer.h
3 // Purpose: Buffer for wxRichTextCtrl
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 2005-09-30
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 /*
13
14 Data structures
15 ===============
16
17 Data is represented by a hierarchy of objects, all derived from
18 wxRichTextObject.
19
20 The top of the hierarchy is the buffer, a kind of wxRichTextParagraphLayoutBox.
21 These boxes will allow flexible placement of text boxes on a page, but
22 for now there will be a single box representing the document,
23 and this box will a wxRichTextParagraphLayoutBox which contains further
24 wxRichTextParagraph objects, each of which can include text and images.
25
26 Each object maintains a range (start and end position) measured
27 from the start of the main parent box.
28 A paragraph object knows its range, and a text fragment knows its range
29 too. So, a character or image in a page has a position relative to the
30 start of the document, and a character in an embedded text box has
31 a position relative to that text box. For now, we will not be dealing with
32 embedded objects but it's something to bear in mind for later.
33
34 Layout
35 ======
36
37 When Layout is called on an object, it is given a size which the object
38 must limit itself to, or one or more flexible directions (vertical
39 or horizontal). So for example a centered paragraph is given the page
40 width to play with (minus any margins), but can extend indefinitely
41 in the vertical direction. The implementation of Layout can then
42 cache the calculated size and position within the parent.
43
44 Note that position and size should be calculated separately, because
45 for example inserting a paragraph may result in the following paragraphs
46 moving down, but not changing in size.
47
48 Need to determine how objects specify their position. Absolute coordinates,
49 or relative to last object? May be hard to determine that. So should probably
50 be in absolute coordinates, in which case we'll need a Move virtual function
51 that allows quick movement of all elements without layout.
52
53 Let's work through a simple example of layout. Say we're laying out
54 a document with the buffer as the top box, with a wxRichTextParagraphLayoutBox
55 inside that that consists of wxRichTextParagraph objects.
56
57 We're in a mode whereby changes of window size change the width of the
58 page (useful for text editors, as opposed to word processors). The
59 window width is 600.
60
61 We pass (600, -1) to the top-level Layout (i.e. restrict size in horizontal
62 direction only). The wxRichTextBuffer box doesn't currently have
63 well-defined layout behaviour so we simply assume it has one child
64 that fills its parent (later we can define sizer-like box layout behaviour).
65 So it passes the same dimensions to the child, which is a wxRichTextParagraphLayoutBox.
66 This then looks at each child in turn (wxRichTextParagraph) and determines
67 the size the paragraph will take up, setting the cached size, and
68 splitting the paragraph into lines.
69
70 When the layout for one paragraph returns, the next paragraph is
71 fed the position of the previous, so it can position itself.
72
73 Each time Layout is called, the cached list of lines for each paragraph
74 is recreated, since it can change for example if the parent object width
75 changes.
76
77 Reporting size
78 ==============
79
80 Each object can report its size for a given range. It's important that
81 it can report a partial size, so that wrapping can be implemented,
82 hit test calculations performed, etc. So GetRangeSize must be implemented
83 for each object.
84
85 */
86
87 #ifndef _WX_RICHTEXTBUFFER_H_
88 #define _WX_RICHTEXTBUFFER_H_
89
90 /*!
91 * Includes
92 */
93
94 #include "wx/list.h"
95
96 #if wxUSE_RICHTEXT
97
98 #include "wx/image.h"
99 #include "wx/cmdproc.h"
100 #include "wx/txtstrm.h"
101
102 /*!
103 * File types
104 */
105
106 #define wxRICHTEXT_TYPE_ANY 0
107 #define wxRICHTEXT_TYPE_TEXT 1
108 #define wxRICHTEXT_TYPE_XML 2
109 #define wxRICHTEXT_TYPE_HTML 3
110 #define wxRICHTEXT_TYPE_RTF 4
111 #define wxRICHTEXT_TYPE_PDF 5
112
113 /*!
114 * Forward declarations
115 */
116
117 class WXDLLIMPEXP_ADV wxRichTextCtrl;
118 class WXDLLIMPEXP_ADV wxRichTextObject;
119 class WXDLLIMPEXP_ADV wxRichTextCacheObject;
120 class WXDLLIMPEXP_ADV wxRichTextObjectList;
121 class WXDLLIMPEXP_ADV wxRichTextLine;
122 class WXDLLIMPEXP_ADV wxRichTextParagraph;
123 class WXDLLIMPEXP_ADV wxRichTextFragment;
124 class WXDLLIMPEXP_ADV wxRichTextFileHandler;
125 class WXDLLIMPEXP_ADV wxRichTextStyleSheet;
126 class WXDLLIMPEXP_ADV wxTextAttrEx;
127
128 /*!
129 * Flags determining the available space, passed to Layout
130 */
131
132 #define wxRICHTEXT_FIXED_WIDTH 0x01
133 #define wxRICHTEXT_FIXED_HEIGHT 0x02
134 #define wxRICHTEXT_VARIABLE_WIDTH 0x04
135 #define wxRICHTEXT_VARIABLE_HEIGHT 0x08
136
137 /*!
138 * Flags returned from hit-testing
139 */
140
141 // The point was not on this object
142 #define wxRICHTEXT_HITTEST_NONE 0x01
143 // The point was before the position returned from HitTest
144 #define wxRICHTEXT_HITTEST_BEFORE 0x02
145 // The point was after the position returned from HitTest
146 #define wxRICHTEXT_HITTEST_AFTER 0x04
147 // The point was on the position returned from HitTest
148 #define wxRICHTEXT_HITTEST_ON 0x08
149
150 /*!
151 * Flags for GetRangeSize
152 */
153
154 #define wxRICHTEXT_FORMATTED 0x01
155 #define wxRICHTEXT_UNFORMATTED 0x02
156
157 /*!
158 * Extra formatting flags not in wxTextAttr
159 */
160
161 #define wxTEXT_ATTR_PARA_SPACING_AFTER 0x00000800
162 #define wxTEXT_ATTR_PARA_SPACING_BEFORE 0x00001000
163 #define wxTEXT_ATTR_LINE_SPACING 0x00002000
164 #define wxTEXT_ATTR_CHARACTER_STYLE_NAME 0x00004000
165 #define wxTEXT_ATTR_PARAGRAPH_STYLE_NAME 0x00008000
166 #define wxTEXT_ATTR_BULLET_STYLE 0x00010000
167 #define wxTEXT_ATTR_BULLET_NUMBER 0x00020000
168 #define wxTEXT_ATTR_BULLET_SYMBOL 0x00040000
169
170 /*!
171 * Styles for wxTextAttrEx::SetBulletStyle
172 */
173
174 #define wxTEXT_ATTR_BULLET_STYLE_NONE 0x0000
175 #define wxTEXT_ATTR_BULLET_STYLE_ARABIC 0x0001
176 #define wxTEXT_ATTR_BULLET_STYLE_LETTERS_UPPER 0x0002
177 #define wxTEXT_ATTR_BULLET_STYLE_LETTERS_LOWER 0x0004
178 #define wxTEXT_ATTR_BULLET_STYLE_ROMAN_UPPER 0x0008
179 #define wxTEXT_ATTR_BULLET_STYLE_ROMAN_LOWER 0x0010
180 #define wxTEXT_ATTR_BULLET_STYLE_SYMBOL 0x0020
181 #define wxTEXT_ATTR_BULLET_STYLE_BITMAP 0x0040
182 #define wxTEXT_ATTR_BULLET_STYLE_PARENTHESES 0x0080
183 #define wxTEXT_ATTR_BULLET_STYLE_PERIOD 0x0100
184
185 /*!
186 * Line spacing values
187 */
188
189 #define wxTEXT_ATTR_LINE_SPACING_NORMAL 10
190 #define wxTEXT_ATTR_LINE_SPACING_HALF 15
191 #define wxTEXT_ATTR_LINE_SPACING_TWICE 20
192
193 /*!
194 * wxRichTextRange class declaration
195 * This stores beginning and end positions for a range of data.
196 */
197
198 class WXDLLIMPEXP_ADV wxRichTextRange
199 {
200 public:
201 // Constructors
202
203 wxRichTextRange() { m_start = 0; m_end = 0; }
204 wxRichTextRange(long start, long end) { m_start = start; m_end = end; }
205 wxRichTextRange(const wxRichTextRange& range) { m_start = range.m_start; m_end = range.m_end; }
206 ~wxRichTextRange() {}
207
208 void operator =(const wxRichTextRange& range) { m_start = range.m_start; m_end = range.m_end; }
209 wxRichTextRange operator -(const wxRichTextRange& range) const { return wxRichTextRange(m_start - range.m_start, m_end - range.m_end); }
210 wxRichTextRange operator +(const wxRichTextRange& range) const { return wxRichTextRange(m_start + range.m_start, m_end + range.m_end); }
211
212 void SetRange(long start, long end) { m_start = start; m_end = end; }
213
214 void SetStart(long start) { m_start = start; }
215 long GetStart() const { return m_start; }
216
217 void SetEnd(long end) { m_end = end; }
218 long GetEnd() const { return m_end; }
219
220 /// Returns true if this range is completely outside 'range'
221 bool IsOutside(const wxRichTextRange& range) const { return range.m_start > m_end || range.m_end < m_start; }
222
223 /// Returns true if this range is completely within 'range'
224 bool IsWithin(const wxRichTextRange& range) const { return m_start >= range.m_start && m_end <= range.m_end; }
225
226 /// Returns true if the given position is within this range. Allow
227 /// for the possibility of an empty range - assume the position
228 /// is within this empty range. NO, I think we should not match with an empty range.
229 // bool Contains(long pos) const { return pos >= m_start && (pos <= m_end || GetLength() == 0); }
230 bool Contains(long pos) const { return pos >= m_start && pos <= m_end ; }
231
232 /// Limit this range to be within 'range'
233 bool LimitTo(const wxRichTextRange& range) ;
234
235 /// Gets the length of the range
236 long GetLength() const { return m_end - m_start + 1; }
237
238 /// Swaps the start and end
239 void Swap() { long tmp = m_start; m_start = m_end; m_end = tmp; }
240
241 protected:
242 long m_start;
243 long m_end;
244 };
245
246 /*!
247 * wxTextAttrEx is an extended version of wxTextAttr with more paragraph attributes.
248 */
249
250 class WXDLLIMPEXP_ADV wxTextAttrEx: public wxTextAttr
251 {
252 public:
253 // ctors
254 wxTextAttrEx(const wxTextAttrEx& attr);
255 wxTextAttrEx() { Init(); }
256
257 // Initialise this object.
258 void Init();
259
260 // Assignment from a wxTextAttrEx object
261 void operator= (const wxTextAttrEx& attr);
262
263 // Assignment from a wxTextAttr object.
264 void operator= (const wxTextAttr& attr);
265
266 // setters
267 void SetCharacterStyleName(const wxString& name) { m_characterStyleName = name; }
268 void SetParagraphStyleName(const wxString& name) { m_paragraphStyleName = name; }
269 void SetParagraphSpacingAfter(int spacing) { m_paragraphSpacingAfter = spacing; }
270 void SetParagraphSpacingBefore(int spacing) { m_paragraphSpacingBefore = spacing; }
271 void SetLineSpacing(int spacing) { m_lineSpacing = spacing; }
272 void SetBulletStyle(int style) { m_bulletStyle = style; }
273 void SetBulletNumber(int n) { m_bulletNumber = n; }
274 void SetBulletSymbol(wxChar symbol) { m_bulletSymbol = symbol; }
275
276 const wxString& GetCharacterStyleName() const { return m_characterStyleName; }
277 const wxString& GetParagraphStyleName() const { return m_paragraphStyleName; }
278 int GetParagraphSpacingAfter() const { return m_paragraphSpacingAfter; }
279 int GetParagraphSpacingBefore() const { return m_paragraphSpacingBefore; }
280 int GetLineSpacing() const { return m_lineSpacing; }
281 int GetBulletStyle() const { return m_bulletStyle; }
282 int GetBulletNumber() const { return m_bulletNumber; }
283 wxChar GetBulletSymbol() const { return m_bulletSymbol; }
284
285 bool HasParagraphSpacingAfter() const { return HasFlag(wxTEXT_ATTR_PARA_SPACING_AFTER); }
286 bool HasParagraphSpacingBefore() const { return HasFlag(wxTEXT_ATTR_PARA_SPACING_BEFORE); }
287 bool HasLineSpacing() const { return HasFlag(wxTEXT_ATTR_LINE_SPACING); }
288 bool HasCharacterStyleName() const { return HasFlag(wxTEXT_ATTR_CHARACTER_STYLE_NAME); }
289 bool HasParagraphStyleName() const { return HasFlag(wxTEXT_ATTR_PARAGRAPH_STYLE_NAME); }
290 bool HasBulletStyle() const { return HasFlag(wxTEXT_ATTR_BULLET_STYLE); }
291 bool HasBulletNumber() const { return HasFlag(wxTEXT_ATTR_BULLET_NUMBER); }
292 bool HasBulletSymbol() const { return HasFlag(wxTEXT_ATTR_BULLET_SYMBOL); }
293
294 // Is this a character style?
295 bool IsCharacterStyle() const { return (0 != (GetFlags() & (wxTEXT_ATTR_FONT | wxTEXT_ATTR_BACKGROUND_COLOUR | wxTEXT_ATTR_TEXT_COLOUR))); }
296 bool IsParagraphStyle() const { return (0 != (GetFlags() & (wxTEXT_ATTR_ALIGNMENT|wxTEXT_ATTR_LEFT_INDENT|wxTEXT_ATTR_RIGHT_INDENT|wxTEXT_ATTR_TABS|
297 wxTEXT_ATTR_PARA_SPACING_BEFORE|wxTEXT_ATTR_PARA_SPACING_AFTER|wxTEXT_ATTR_LINE_SPACING|
298 wxTEXT_ATTR_BULLET_STYLE|wxTEXT_ATTR_BULLET_NUMBER))); }
299
300 // returns false if we have any attributes set, true otherwise
301 bool IsDefault() const
302 {
303 return !HasTextColour() && !HasBackgroundColour() && !HasFont() && !HasAlignment() &&
304 !HasTabs() && !HasLeftIndent() && !HasRightIndent() &&
305 !HasParagraphSpacingAfter() && !HasParagraphSpacingBefore() && !HasLineSpacing() &&
306 !HasCharacterStyleName() && !HasParagraphStyleName() && !HasBulletNumber() && !HasBulletStyle() && !HasBulletSymbol();
307 }
308 private:
309 // Paragraph styles
310 int m_paragraphSpacingAfter;
311 int m_paragraphSpacingBefore;
312 int m_lineSpacing;
313 int m_bulletStyle;
314 int m_bulletNumber;
315 wxChar m_bulletSymbol;
316
317 // Character style
318 wxString m_characterStyleName;
319
320 // Paragraph style
321 wxString m_paragraphStyleName;
322 };
323
324 /*!
325 * wxRichTextAttr stores attributes without a wxFont object, so is a much more
326 * efficient way to query styles.
327 */
328
329 class WXDLLIMPEXP_ADV wxRichTextAttr
330 {
331 public:
332 // ctors
333 wxRichTextAttr(const wxTextAttrEx& attr);
334 wxRichTextAttr() { Init(); }
335 wxRichTextAttr(const wxColour& colText,
336 const wxColour& colBack = wxNullColour,
337 wxTextAttrAlignment alignment = wxTEXT_ALIGNMENT_DEFAULT);
338
339 // Initialise this object.
340 void Init();
341
342 // Assignment from a wxRichTextAttr object.
343 void operator= (const wxRichTextAttr& attr);
344
345 // Assignment from a wxTextAttrEx object.
346 void operator= (const wxTextAttrEx& attr);
347
348 // Making a wxTextAttrEx object.
349 operator wxTextAttrEx () const ;
350
351 // Copy to a wxTextAttr
352 void CopyTo(wxTextAttrEx& attr) const;
353
354 // Create font from font attributes.
355 wxFont CreateFont() const;
356
357 // Get attributes from font.
358 bool GetFontAttributes(const wxFont& font);
359
360 // setters
361 void SetTextColour(const wxColour& colText) { m_colText = colText; m_flags |= wxTEXT_ATTR_TEXT_COLOUR; }
362 void SetBackgroundColour(const wxColour& colBack) { m_colBack = colBack; m_flags |= wxTEXT_ATTR_BACKGROUND_COLOUR; }
363 void SetAlignment(wxTextAttrAlignment alignment) { m_textAlignment = alignment; m_flags |= wxTEXT_ATTR_ALIGNMENT; }
364 void SetTabs(const wxArrayInt& tabs) { m_tabs = tabs; m_flags |= wxTEXT_ATTR_TABS; }
365 void SetLeftIndent(int indent, int subIndent = 0) { m_leftIndent = indent; m_leftSubIndent = subIndent; m_flags |= wxTEXT_ATTR_LEFT_INDENT; }
366 void SetRightIndent(int indent) { m_rightIndent = indent; m_flags |= wxTEXT_ATTR_RIGHT_INDENT; }
367
368 void SetFontSize(int pointSize) { m_fontSize = pointSize; m_flags |= wxTEXT_ATTR_FONT_SIZE; }
369 void SetFontStyle(int fontStyle) { m_fontStyle = fontStyle; m_flags |= wxTEXT_ATTR_FONT_ITALIC; }
370 void SetFontWeight(int fontWeight) { m_fontWeight = fontWeight; m_flags |= wxTEXT_ATTR_FONT_WEIGHT; }
371 void SetFontFaceName(const wxString& faceName) { m_fontFaceName = faceName; m_flags |= wxTEXT_ATTR_FONT_FACE; }
372 void SetFontUnderlined(bool underlined) { m_fontUnderlined = underlined; m_flags |= wxTEXT_ATTR_FONT_UNDERLINE; }
373
374 void SetFlags(long flags) { m_flags = flags; }
375
376 void SetCharacterStyleName(const wxString& name) { m_characterStyleName = name; }
377 void SetParagraphStyleName(const wxString& name) { m_paragraphStyleName = name; }
378 void SetParagraphSpacingAfter(int spacing) { m_paragraphSpacingAfter = spacing; }
379 void SetParagraphSpacingBefore(int spacing) { m_paragraphSpacingBefore = spacing; }
380 void SetLineSpacing(int spacing) { m_lineSpacing = spacing; }
381 void SetBulletStyle(int style) { m_bulletStyle = style; }
382 void SetBulletNumber(int n) { m_bulletNumber = n; }
383 void SetBulletSymbol(wxChar symbol) { m_bulletSymbol = symbol; }
384
385 const wxColour& GetTextColour() const { return m_colText; }
386 const wxColour& GetBackgroundColour() const { return m_colBack; }
387 wxTextAttrAlignment GetAlignment() const { return m_textAlignment; }
388 const wxArrayInt& GetTabs() const { return m_tabs; }
389 long GetLeftIndent() const { return m_leftIndent; }
390 long GetLeftSubIndent() const { return m_leftSubIndent; }
391 long GetRightIndent() const { return m_rightIndent; }
392 long GetFlags() const { return m_flags; }
393
394 int GetFontSize() const { return m_fontSize; }
395 int GetFontStyle() const { return m_fontStyle; }
396 int GetFontWeight() const { return m_fontWeight; }
397 bool GetFontUnderlined() const { return m_fontUnderlined; }
398 const wxString& GetFontFaceName() const { return m_fontFaceName; }
399
400 const wxString& GetCharacterStyleName() const { return m_characterStyleName; }
401 const wxString& GetParagraphStyleName() const { return m_paragraphStyleName; }
402 int GetParagraphSpacingAfter() const { return m_paragraphSpacingAfter; }
403 int GetParagraphSpacingBefore() const { return m_paragraphSpacingBefore; }
404 int GetLineSpacing() const { return m_lineSpacing; }
405 int GetBulletStyle() const { return m_bulletStyle; }
406 int GetBulletNumber() const { return m_bulletNumber; }
407 wxChar GetBulletSymbol() const { return m_bulletSymbol; }
408
409 // accessors
410 bool HasTextColour() const { return m_colText.Ok() && HasFlag(wxTEXT_ATTR_TEXT_COLOUR) ; }
411 bool HasBackgroundColour() const { return m_colBack.Ok() && HasFlag(wxTEXT_ATTR_BACKGROUND_COLOUR) ; }
412 bool HasAlignment() const { return (m_textAlignment != wxTEXT_ALIGNMENT_DEFAULT) || ((m_flags & wxTEXT_ATTR_ALIGNMENT) != 0) ; }
413 bool HasTabs() const { return (m_flags & wxTEXT_ATTR_TABS) != 0 ; }
414 bool HasLeftIndent() const { return (m_flags & wxTEXT_ATTR_LEFT_INDENT) != 0 ; }
415 bool HasRightIndent() const { return (m_flags & wxTEXT_ATTR_RIGHT_INDENT) != 0 ; }
416 bool HasWeight() const { return (m_flags & wxTEXT_ATTR_FONT_WEIGHT) != 0; }
417 bool HasSize() const { return (m_flags & wxTEXT_ATTR_FONT_SIZE) != 0; }
418 bool HasItalic() const { return (m_flags & wxTEXT_ATTR_FONT_ITALIC) != 0; }
419 bool HasUnderlined() const { return (m_flags & wxTEXT_ATTR_FONT_UNDERLINE) != 0; }
420 bool HasFaceName() const { return (m_flags & wxTEXT_ATTR_FONT_FACE) != 0; }
421 bool HasFont() const { return (m_flags & (wxTEXT_ATTR_FONT)) != 0; }
422
423 bool HasParagraphSpacingAfter() const { return (m_flags & wxTEXT_ATTR_PARA_SPACING_AFTER) != 0; }
424 bool HasParagraphSpacingBefore() const { return (m_flags & wxTEXT_ATTR_PARA_SPACING_BEFORE) != 0; }
425 bool HasLineSpacing() const { return (m_flags & wxTEXT_ATTR_LINE_SPACING) != 0; }
426 bool HasCharacterStyleName() const { return (m_flags & wxTEXT_ATTR_CHARACTER_STYLE_NAME) != 0; }
427 bool HasParagraphStyleName() const { return (m_flags & wxTEXT_ATTR_PARAGRAPH_STYLE_NAME) != 0; }
428 bool HasBulletStyle() const { return (m_flags & wxTEXT_ATTR_BULLET_STYLE) != 0; }
429 bool HasBulletNumber() const { return (m_flags & wxTEXT_ATTR_BULLET_NUMBER) != 0; }
430 bool HasBulletSymbol() const { return (m_flags & wxTEXT_ATTR_BULLET_SYMBOL) != 0; }
431
432 bool HasFlag(long flag) const { return (m_flags & flag) != 0; }
433
434 // Is this a character style?
435 bool IsCharacterStyle() const { return (0 != (GetFlags() & (wxTEXT_ATTR_FONT | wxTEXT_ATTR_BACKGROUND_COLOUR | wxTEXT_ATTR_TEXT_COLOUR))); }
436 bool IsParagraphStyle() const { return (0 != (GetFlags() & (wxTEXT_ATTR_ALIGNMENT|wxTEXT_ATTR_LEFT_INDENT|wxTEXT_ATTR_RIGHT_INDENT|wxTEXT_ATTR_TABS|
437 wxTEXT_ATTR_PARA_SPACING_BEFORE|wxTEXT_ATTR_PARA_SPACING_AFTER|wxTEXT_ATTR_LINE_SPACING|
438 wxTEXT_ATTR_BULLET_STYLE|wxTEXT_ATTR_BULLET_NUMBER))); }
439
440 // returns false if we have any attributes set, true otherwise
441 bool IsDefault() const
442 {
443 return !HasTextColour() && !HasBackgroundColour() && !HasFont() && !HasAlignment() &&
444 !HasTabs() && !HasLeftIndent() && !HasRightIndent() &&
445 !HasParagraphSpacingAfter() && !HasParagraphSpacingBefore() && !HasLineSpacing() &&
446 !HasCharacterStyleName() && !HasParagraphStyleName() && !HasBulletNumber() && !HasBulletStyle() && !HasBulletSymbol();
447 }
448
449 private:
450 long m_flags;
451
452 // Paragraph styles
453 wxArrayInt m_tabs; // array of int: tab stops in 1/10 mm
454 int m_leftIndent; // left indent in 1/10 mm
455 int m_leftSubIndent; // left indent for all but the first
456 // line in a paragraph relative to the
457 // first line, in 1/10 mm
458 int m_rightIndent; // right indent in 1/10 mm
459 wxTextAttrAlignment m_textAlignment;
460
461 int m_paragraphSpacingAfter;
462 int m_paragraphSpacingBefore;
463 int m_lineSpacing;
464 int m_bulletStyle;
465 int m_bulletNumber;
466 wxChar m_bulletSymbol;
467
468 // Character styles
469 wxColour m_colText,
470 m_colBack;
471 int m_fontSize;
472 int m_fontStyle;
473 int m_fontWeight;
474 bool m_fontUnderlined;
475 wxString m_fontFaceName;
476
477 // Character style
478 wxString m_characterStyleName;
479
480 // Paragraph style
481 wxString m_paragraphStyleName;
482 };
483
484 #define wxTEXT_ATTR_CHARACTER (wxTEXT_ATTR_FONT) | wxTEXT_ATTR_BACKGROUND_COLOUR | wxTEXT_ATTR_TEXT_COLOUR
485
486 #define wxTEXT_ATTR_PARAGRAPH wxTEXT_ATTR_ALIGNMENT|wxTEXT_ATTR_LEFT_INDENT|wxTEXT_ATTR_RIGHT_INDENT|wxTEXT_ATTR_TABS|\
487 wxTEXT_ATTR_PARA_SPACING_BEFORE|wxTEXT_ATTR_PARA_SPACING_AFTER|wxTEXT_ATTR_LINE_SPACING|\
488 wxTEXT_ATTR_BULLET_STYLE|wxTEXT_ATTR_BULLET_NUMBER|wxTEXT_ATTR_BULLET_SYMBOL
489
490 #define wxTEXT_ATTR_ALL wxTEXT_ATTR_CHARACTER|wxTEXT_ATTR_PARAGRAPH
491
492 /*!
493 * wxRichTextObject class declaration
494 * This is the base for drawable objects.
495 */
496
497 class WXDLLIMPEXP_ADV wxRichTextObject: public wxObject
498 {
499 DECLARE_CLASS(wxRichTextObject)
500 public:
501 // Constructors
502
503 wxRichTextObject(wxRichTextObject* parent = NULL);
504 ~wxRichTextObject();
505
506 // Overrideables
507
508 /// Draw the item, within the given range. Some objects may ignore the range (for
509 /// example paragraphs) while others must obey it (lines, to implement wrapping)
510 virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style) = 0;
511
512 /// Lay the item out at the specified position with the given size constraint.
513 /// Layout must set the cached size.
514 virtual bool Layout(wxDC& dc, const wxRect& rect, const wxRichTextRange& affected, int style) = 0;
515
516 /// Hit-testing: returns a flag indicating hit test details, plus
517 /// information about position
518 virtual int HitTest(wxDC& WXUNUSED(dc), const wxPoint& WXUNUSED(pt), long& WXUNUSED(textPosition)) { return false; }
519
520 /// Finds the absolute position and row height for the given character position
521 virtual bool FindPosition(wxDC& WXUNUSED(dc), long WXUNUSED(index), wxPoint& WXUNUSED(pt), int* WXUNUSED(height), bool WXUNUSED(forceLineStart)) { return false; }
522
523 /// Get the best size, i.e. the ideal starting size for this object irrespective
524 /// of available space. For a short text string, it will be the size that exactly encloses
525 /// the text. For a longer string, it might use the parent width for example.
526 virtual wxSize GetBestSize() const { return m_size; }
527
528 /// Get the object size for the given range. Returns false if the range
529 /// is invalid for this object.
530 virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags) const = 0;
531
532 /// Do a split, returning an object containing the second part, and setting
533 /// the first part in 'this'.
534 virtual wxRichTextObject* DoSplit(long WXUNUSED(pos)) { return NULL; }
535
536 /// Calculate range. By default, guess that the object is 1 unit long.
537 virtual void CalculateRange(long start, long& end) { end = start ; m_range.SetRange(start, end); }
538
539 /// Delete range
540 virtual bool DeleteRange(const wxRichTextRange& WXUNUSED(range)) { return false; }
541
542 /// Returns true if the object is empty
543 virtual bool IsEmpty() const { return false; }
544
545 /// Get any text in this object for the given range
546 virtual wxString GetTextForRange(const wxRichTextRange& WXUNUSED(range)) const { return wxEmptyString; }
547
548 /// Returns true if this object can merge itself with the given one.
549 virtual bool CanMerge(wxRichTextObject* WXUNUSED(object)) const { return false; }
550
551 /// Returns true if this object merged itself with the given one.
552 /// The calling code will then delete the given object.
553 virtual bool Merge(wxRichTextObject* WXUNUSED(object)) { return false; }
554
555 /// Dump to output stream for debugging
556 virtual void Dump(wxTextOutputStream& stream);
557
558 // Accessors
559
560 /// Get/set the cached object size as calculated by Layout.
561 virtual wxSize GetCachedSize() const { return m_size; }
562 virtual void SetCachedSize(const wxSize& sz) { m_size = sz; }
563
564 /// Get/set the object position
565 virtual wxPoint GetPosition() const { return m_pos; }
566 virtual void SetPosition(const wxPoint& pos) { m_pos = pos; }
567
568 /// Get the rectangle enclosing the object
569 virtual wxRect GetRect() const { return wxRect(GetPosition(), GetCachedSize()); }
570
571 /// Set the range
572 void SetRange(const wxRichTextRange& range) { m_range = range; }
573
574 /// Get the range
575 const wxRichTextRange& GetRange() const { return m_range; }
576 wxRichTextRange& GetRange() { return m_range; }
577
578 /// Get/set dirty flag (whether the object needs Layout to be called)
579 virtual bool GetDirty() const { return m_dirty; }
580 virtual void SetDirty(bool dirty) { m_dirty = dirty; }
581
582 /// Is this composite?
583 virtual bool IsComposite() const { return false; }
584
585 /// Get/set the parent.
586 virtual wxRichTextObject* GetParent() const { return m_parent; }
587 virtual void SetParent(wxRichTextObject* parent) { m_parent = parent; }
588
589 /// Set the margin around the object
590 virtual void SetMargins(int margin);
591 virtual void SetMargins(int leftMargin, int rightMargin, int topMargin, int bottomMargin);
592 virtual int GetLeftMargin() const { return m_leftMargin; }
593 virtual int GetRightMargin() const { return m_rightMargin; }
594 virtual int GetTopMargin() const { return m_topMargin; }
595 virtual int GetBottomMargin() const { return m_bottomMargin; }
596
597 /// Set attributes object
598 void SetAttributes(const wxTextAttrEx& attr) { m_attributes = attr; }
599 const wxTextAttrEx& GetAttributes() const { return m_attributes; }
600 wxTextAttrEx& GetAttributes() { return m_attributes; }
601
602 /// Set/get stored descent
603 void SetDescent(int descent) { m_descent = descent; }
604 int GetDescent() const { return m_descent; }
605
606 // Operations
607
608 /// Clone the object
609 virtual wxRichTextObject* Clone() const { return NULL; }
610
611 /// Copy
612 void Copy(const wxRichTextObject& obj);
613
614 /// Reference-counting allows us to use the same object in multiple
615 /// lists (not yet used)
616 void Reference() { m_refCount ++; }
617 void Dereference();
618
619 /// Convert units in tends of a millimetre to device units
620 int ConvertTenthsMMToPixels(wxDC& dc, int units);
621
622 protected:
623 wxSize m_size;
624 wxPoint m_pos;
625 int m_descent; // Descent for this object (if any)
626 bool m_dirty;
627 int m_refCount;
628 wxRichTextObject* m_parent;
629
630 /// The range of this object (start position to end position)
631 wxRichTextRange m_range;
632
633 /// Margins
634 int m_leftMargin;
635 int m_rightMargin;
636 int m_topMargin;
637 int m_bottomMargin;
638
639 /// Attributes
640 wxTextAttrEx m_attributes;
641 };
642
643 WX_DECLARE_EXPORTED_LIST( wxRichTextObject, wxRichTextObjectList );
644
645 /*!
646 * wxRichTextCompositeObject class declaration
647 * Objects of this class can contain other objects.
648 */
649
650 class WXDLLIMPEXP_ADV wxRichTextCompositeObject: public wxRichTextObject
651 {
652 DECLARE_CLASS(wxRichTextCompositeObject)
653 public:
654 // Constructors
655
656 wxRichTextCompositeObject(wxRichTextObject* parent = NULL);
657 ~wxRichTextCompositeObject();
658
659 // Overrideables
660
661 /// Hit-testing: returns a flag indicating hit test details, plus
662 /// information about position
663 virtual int HitTest(wxDC& dc, const wxPoint& pt, long& textPosition);
664
665 /// Finds the absolute position and row height for the given character position
666 virtual bool FindPosition(wxDC& dc, long index, wxPoint& pt, int* height, bool forceLineStart);
667
668 /// Calculate range
669 virtual void CalculateRange(long start, long& end);
670
671 /// Delete range
672 virtual bool DeleteRange(const wxRichTextRange& range);
673
674 /// Get any text in this object for the given range
675 virtual wxString GetTextForRange(const wxRichTextRange& range) const;
676
677 /// Dump to output stream for debugging
678 virtual void Dump(wxTextOutputStream& stream);
679
680 // Accessors
681
682 /// Get the children
683 wxRichTextObjectList& GetChildren() { return m_children; }
684 const wxRichTextObjectList& GetChildren() const { return m_children; }
685
686 /// Get the child count
687 size_t GetChildCount() const ;
688
689 /// Get the nth child
690 wxRichTextObject* GetChild(size_t n) const ;
691
692 /// Get/set dirty flag
693 virtual bool GetDirty() const { return m_dirty; }
694 virtual void SetDirty(bool dirty) { m_dirty = dirty; }
695
696 /// Is this composite?
697 virtual bool IsComposite() const { return true; }
698
699 /// Returns true if the buffer is empty
700 virtual bool IsEmpty() const { return GetChildCount() == 0; }
701
702 // Operations
703
704 /// Copy
705 void Copy(const wxRichTextCompositeObject& obj);
706
707 /// Append a child, returning the position
708 size_t AppendChild(wxRichTextObject* child) ;
709
710 /// Insert the child in front of the given object, or at the beginning
711 bool InsertChild(wxRichTextObject* child, wxRichTextObject* inFrontOf) ;
712
713 /// Delete the child
714 bool RemoveChild(wxRichTextObject* child, bool deleteChild = false) ;
715
716 /// Delete all children
717 bool DeleteChildren() ;
718
719 /// Recursively merge all pieces that can be merged.
720 bool Defragment();
721
722 protected:
723 wxRichTextObjectList m_children;
724 };
725
726 /*!
727 * wxRichTextBox class declaration
728 * This defines a 2D space to lay out objects
729 */
730
731 class WXDLLIMPEXP_ADV wxRichTextBox: public wxRichTextCompositeObject
732 {
733 DECLARE_DYNAMIC_CLASS(wxRichTextBox)
734 public:
735 // Constructors
736
737 wxRichTextBox(wxRichTextObject* parent = NULL);
738 wxRichTextBox(const wxRichTextBox& obj): wxRichTextCompositeObject() { Copy(obj); }
739
740 // Overrideables
741
742 /// Draw the item
743 virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style);
744
745 /// Lay the item out
746 virtual bool Layout(wxDC& dc, const wxRect& rect, const wxRichTextRange& affected, int style);
747
748 /// Get/set the object size for the given range. Returns false if the range
749 /// is invalid for this object.
750 virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags) const;
751
752 // Accessors
753
754 // Operations
755
756 /// Clone
757 virtual wxRichTextObject* Clone() const { return new wxRichTextBox(*this); }
758
759 /// Copy
760 void Copy(const wxRichTextBox& obj);
761
762 protected:
763 };
764
765 /*!
766 * wxRichTextParagraphBox class declaration
767 * This box knows how to lay out paragraphs.
768 */
769
770 class WXDLLIMPEXP_ADV wxRichTextParagraphLayoutBox: public wxRichTextBox
771 {
772 DECLARE_DYNAMIC_CLASS(wxRichTextParagraphLayoutBox)
773 public:
774 // Constructors
775
776 wxRichTextParagraphLayoutBox(wxRichTextObject* parent = NULL);
777 wxRichTextParagraphLayoutBox(const wxRichTextParagraphLayoutBox& obj):wxRichTextBox() { Init(); Copy(obj); }
778
779 // Overrideables
780
781 /// Draw the item
782 virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style);
783
784 /// Lay the item out
785 virtual bool Layout(wxDC& dc, const wxRect& rect, const wxRichTextRange& affected, int style);
786
787 /// Get/set the object size for the given range. Returns false if the range
788 /// is invalid for this object.
789 virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags) const;
790
791 /// Delete range
792 virtual bool DeleteRange(const wxRichTextRange& range);
793
794 /// Get any text in this object for the given range
795 virtual wxString GetTextForRange(const wxRichTextRange& range) const;
796
797 // Accessors
798
799 /// Associate a control with the buffer, for operations that for example require refreshing the window.
800 void SetRichTextCtrl(wxRichTextCtrl* ctrl) { m_ctrl = ctrl; }
801
802 /// Get the associated control.
803 wxRichTextCtrl* GetRichTextCtrl() const { return m_ctrl; }
804
805 // Operations
806
807 /// Initialize the object.
808 void Init();
809
810 /// Clear all children
811 virtual void Clear();
812
813 /// Clear and initialize with one blank paragraph
814 virtual void Reset();
815
816 /// Convenience function to add a paragraph of text
817 virtual wxRichTextRange AddParagraph(const wxString& text);
818
819 /// Convenience function to add an image
820 virtual wxRichTextRange AddImage(const wxImage& image);
821
822 /// Adds multiple paragraphs, based on newlines.
823 virtual wxRichTextRange AddParagraphs(const wxString& text);
824
825 /// Get the line at the given position. If caretPosition is true, the position is
826 /// a caret position, which is normally a smaller number.
827 virtual wxRichTextLine* GetLineAtPosition(long pos, bool caretPosition = false) const;
828
829 /// Get the line at the given y pixel position, or the last line.
830 virtual wxRichTextLine* GetLineAtYPosition(int y) const;
831
832 /// Get the paragraph at the given character or caret position
833 virtual wxRichTextParagraph* GetParagraphAtPosition(long pos, bool caretPosition = false) const;
834
835 /// Get the line size at the given position
836 virtual wxSize GetLineSizeAtPosition(long pos, bool caretPosition = false) const;
837
838 /// Given a position, get the number of the visible line (potentially many to a paragraph),
839 /// starting from zero at the start of the buffer. We also have to pass a bool (startOfLine)
840 /// that indicates whether the caret is being shown at the end of the previous line or at the start
841 /// of the next, since the caret can be shown at 2 visible positions for the same underlying
842 /// position.
843 virtual long GetVisibleLineNumber(long pos, bool caretPosition = false, bool startOfLine = false) const;
844
845 /// Given a line number, get the corresponding wxRichTextLine object.
846 virtual wxRichTextLine* GetLineForVisibleLineNumber(long lineNumber) const;
847
848 /// Get the leaf object in a paragraph at this position.
849 /// Given a line number, get the corresponding wxRichTextLine object.
850 virtual wxRichTextObject* GetLeafObjectAtPosition(long position) const;
851
852 /// Get the paragraph by number
853 virtual wxRichTextParagraph* GetParagraphAtLine(long paragraphNumber) const;
854
855 /// Get the paragraph for a given line
856 virtual wxRichTextParagraph* GetParagraphForLine(wxRichTextLine* line) const;
857
858 /// Get the length of the paragraph
859 virtual int GetParagraphLength(long paragraphNumber) const;
860
861 /// Get the number of paragraphs
862 virtual int GetParagraphCount() const { return GetChildCount(); }
863
864 /// Get the number of visible lines
865 virtual int GetLineCount() const;
866
867 /// Get the text of the paragraph
868 virtual wxString GetParagraphText(long paragraphNumber) const;
869
870 /// Convert zero-based line column and paragraph number to a position.
871 virtual long XYToPosition(long x, long y) const;
872
873 /// Convert zero-based position to line column and paragraph number
874 virtual bool PositionToXY(long pos, long* x, long* y) const;
875
876 /// Set text attributes: character and/or paragraph styles.
877 virtual bool SetStyle(const wxRichTextRange& range, const wxRichTextAttr& style, bool withUndo = true);
878 virtual bool SetStyle(const wxRichTextRange& range, const wxTextAttrEx& style, bool withUndo = true);
879
880 /// Get the text attributes for this position.
881 virtual bool GetStyle(long position, wxTextAttrEx& style) const;
882 virtual bool GetStyle(long position, wxRichTextAttr& style) const;
883
884 /// Test if this whole range has character attributes of the specified kind. If any
885 /// of the attributes are different within the range, the test fails. You
886 /// can use this to implement, for example, bold button updating. style must have
887 /// flags indicating which attributes are of interest.
888 virtual bool HasCharacterAttributes(const wxRichTextRange& range, const wxTextAttrEx& style) const;
889 virtual bool HasCharacterAttributes(const wxRichTextRange& range, const wxRichTextAttr& style) const;
890
891 /// Test if this whole range has paragraph attributes of the specified kind. If any
892 /// of the attributes are different within the range, the test fails. You
893 /// can use this to implement, for example, centering button updating. style must have
894 /// flags indicating which attributes are of interest.
895 virtual bool HasParagraphAttributes(const wxRichTextRange& range, const wxTextAttrEx& style) const;
896 virtual bool HasParagraphAttributes(const wxRichTextRange& range, const wxRichTextAttr& style) const;
897
898 /// Clone
899 virtual wxRichTextObject* Clone() const { return new wxRichTextParagraphLayoutBox(*this); }
900
901 /// Insert fragment into this box at the given position. If partialParagraph is true,
902 /// it is assumed that the last (or only) paragraph is just a piece of data with no paragraph
903 /// marker.
904 virtual bool InsertFragment(long position, wxRichTextFragment& fragment);
905
906 /// Make a copy of the fragment corresponding to the given range, putting it in 'fragment'.
907 virtual bool CopyFragment(const wxRichTextRange& range, wxRichTextFragment& fragment);
908
909 /// Copy
910 void Copy(const wxRichTextParagraphLayoutBox& obj);
911
912 /// Calculate ranges
913 virtual void UpdateRanges() { long end; CalculateRange(0, end); }
914
915 /// Get all the text
916 virtual wxString GetText() const;
917
918 /// Set default style for new content. Setting it to a default attribute
919 /// makes new content take on the 'basic' style.
920 virtual bool SetDefaultStyle(const wxTextAttrEx& style);
921
922 /// Get default style
923 virtual const wxTextAttrEx& GetDefaultStyle() const { return m_defaultAttributes; }
924
925 /// Set basic (overall) style
926 virtual void SetBasicStyle(const wxTextAttrEx& style) { m_attributes = style; }
927 virtual void SetBasicStyle(const wxRichTextAttr& style) { style.CopyTo(m_attributes); }
928
929 /// Get basic (overall) style
930 virtual const wxTextAttrEx& GetBasicStyle() const { return m_attributes; }
931
932 protected:
933 wxRichTextCtrl* m_ctrl;
934 wxTextAttrEx m_defaultAttributes;
935 };
936
937 /*!
938 * wxRichTextFragment class declaration
939 * This is a lind of paragraph layout box used for storing
940 * paragraphs for Undo/Redo, for example.
941 */
942
943 class WXDLLIMPEXP_ADV wxRichTextFragment: public wxRichTextParagraphLayoutBox
944 {
945 DECLARE_DYNAMIC_CLASS(wxRichTextFragment)
946 public:
947 // Constructors
948
949 wxRichTextFragment() { Init(); }
950 wxRichTextFragment(const wxRichTextFragment& obj):wxRichTextParagraphLayoutBox() { Init(); Copy(obj); }
951
952 // Accessors
953
954 /// Get/set whether the last paragraph is partial or complete
955 void SetPartialParagraph(bool partialPara) { m_partialParagraph = partialPara; }
956 bool GetPartialParagraph() const { return m_partialParagraph; }
957
958 // Overrideables
959
960 // Operations
961
962 /// Initialise
963 void Init();
964
965 /// Copy
966 void Copy(const wxRichTextFragment& obj);
967
968 /// Clone
969 virtual wxRichTextObject* Clone() const { return new wxRichTextFragment(*this); }
970
971 protected:
972
973 // Is the last paragraph partial or complete?
974 bool m_partialParagraph;
975 };
976
977 /*!
978 * wxRichTextLine class declaration
979 * This object represents a line in a paragraph, and stores
980 * offsets from the start of the paragraph representing the
981 * start and end positions of the line.
982 */
983
984 class WXDLLIMPEXP_ADV wxRichTextLine
985 {
986 public:
987 // Constructors
988
989 wxRichTextLine(wxRichTextParagraph* parent);
990 wxRichTextLine(const wxRichTextLine& obj) { Init(); Copy(obj); }
991 virtual ~wxRichTextLine() {}
992
993 // Overrideables
994
995 // Accessors
996
997 /// Set the range
998 void SetRange(const wxRichTextRange& range) { m_range = range; }
999 void SetRange(long from, long to) { m_range = wxRichTextRange(from, to); }
1000
1001 /// Get the parent paragraph
1002 wxRichTextParagraph* GetParent() { return m_parent; }
1003
1004 /// Get the range
1005 const wxRichTextRange& GetRange() const { return m_range; }
1006 wxRichTextRange& GetRange() { return m_range; }
1007
1008 /// Get/set the line size as calculated by Layout.
1009 virtual wxSize GetSize() const { return m_size; }
1010 virtual void SetSize(const wxSize& sz) { m_size = sz; }
1011
1012 /// Get/set the object position relative to the parent
1013 virtual wxPoint GetPosition() const { return m_pos; }
1014 virtual void SetPosition(const wxPoint& pos) { m_pos = pos; }
1015
1016 /// Get the absolute object position
1017 virtual wxPoint GetAbsolutePosition() const;
1018
1019 /// Get the rectangle enclosing the line
1020 virtual wxRect GetRect() const { return wxRect(GetAbsolutePosition(), GetSize()); }
1021
1022 /// Set/get stored descent
1023 void SetDescent(int descent) { m_descent = descent; }
1024 int GetDescent() const { return m_descent; }
1025
1026 // Operations
1027
1028 /// Initialisation
1029 void Init();
1030
1031 /// Copy
1032 void Copy(const wxRichTextLine& obj);
1033
1034 /// Clone
1035 virtual wxRichTextLine* Clone() const { return new wxRichTextLine(*this); }
1036
1037 protected:
1038
1039 /// The range of the line (start position to end position)
1040 wxRichTextRange m_range;
1041
1042 /// Size and position measured relative to top of paragraph
1043 wxPoint m_pos;
1044 wxSize m_size;
1045
1046 /// Maximum descent for this line (location of text baseline)
1047 int m_descent;
1048
1049 // The parent object
1050 wxRichTextParagraph* m_parent;
1051 };
1052
1053 WX_DECLARE_EXPORTED_LIST( wxRichTextLine, wxRichTextLineList );
1054
1055 /*!
1056 * wxRichTextParagraph class declaration
1057 * This object represents a single paragraph (or in a straight text editor, a line).
1058 */
1059
1060 class WXDLLIMPEXP_ADV wxRichTextParagraph: public wxRichTextBox
1061 {
1062 DECLARE_DYNAMIC_CLASS(wxRichTextParagraph)
1063 public:
1064 // Constructors
1065
1066 wxRichTextParagraph(wxRichTextObject* parent = NULL, wxTextAttrEx* style = NULL);
1067 wxRichTextParagraph(const wxString& text, wxRichTextObject* parent = NULL, wxTextAttrEx* style = NULL);
1068 ~wxRichTextParagraph();
1069 wxRichTextParagraph(const wxRichTextParagraph& obj):wxRichTextBox() { Copy(obj); }
1070
1071 // Overrideables
1072
1073 /// Draw the item
1074 virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style);
1075
1076 /// Lay the item out
1077 virtual bool Layout(wxDC& dc, const wxRect& rect, const wxRichTextRange& affected, int style);
1078
1079 /// Get/set the object size for the given range. Returns false if the range
1080 /// is invalid for this object.
1081 virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags) const;
1082
1083 /// Finds the absolute position and row height for the given character position
1084 virtual bool FindPosition(wxDC& dc, long index, wxPoint& pt, int* height, bool forceLineStart);
1085
1086 /// Hit-testing: returns a flag indicating hit test details, plus
1087 /// information about position
1088 virtual int HitTest(wxDC& dc, const wxPoint& pt, long& textPosition);
1089
1090 /// Calculate range
1091 virtual void CalculateRange(long start, long& end);
1092
1093 // Accessors
1094
1095 /// Get the cached lines
1096 wxRichTextLineList& GetLines() { return m_cachedLines; }
1097
1098 // Operations
1099
1100 /// Copy
1101 void Copy(const wxRichTextParagraph& obj);
1102
1103 /// Clone
1104 virtual wxRichTextObject* Clone() const { return new wxRichTextParagraph(*this); }
1105
1106 /// Clear the cached lines
1107 void ClearLines();
1108
1109 // Implementation
1110
1111 /// Apply paragraph styles such as centering to the wrapped lines
1112 virtual void ApplyParagraphStyle(const wxRect& rect);
1113
1114 /// Insert text at the given position
1115 virtual bool InsertText(long pos, const wxString& text);
1116
1117 /// Split an object at this position if necessary, and return
1118 /// the previous object, or NULL if inserting at beginning.
1119 virtual wxRichTextObject* SplitAt(long pos, wxRichTextObject** previousObject = NULL);
1120
1121 /// Move content to a list from this point
1122 virtual void MoveToList(wxRichTextObject* obj, wxList& list);
1123
1124 /// Add content back from list
1125 virtual void MoveFromList(wxList& list);
1126
1127 /// Get the plain text searching from the start or end of the range.
1128 /// The resulting string may be shorter than the range given.
1129 bool GetContiguousPlainText(wxString& text, const wxRichTextRange& range, bool fromStart = true);
1130
1131 /// Find a suitable wrap position. wrapPosition is the last position in the line to the left
1132 /// of the split.
1133 bool FindWrapPosition(const wxRichTextRange& range, wxDC& dc, int availableSpace, long& wrapPosition);
1134
1135 /// Find the object at the given position
1136 wxRichTextObject* FindObjectAtPosition(long position);
1137
1138 /// Get the bullet text for this paragraph.
1139 wxString GetBulletText();
1140
1141 protected:
1142 /// The lines that make up the wrapped paragraph
1143 wxRichTextLineList m_cachedLines;
1144 };
1145
1146 /*!
1147 * wxRichTextPlainText class declaration
1148 * This object represents a single piece of text.
1149 */
1150
1151 class WXDLLIMPEXP_ADV wxRichTextPlainText: public wxRichTextObject
1152 {
1153 DECLARE_DYNAMIC_CLASS(wxRichTextPlainText)
1154 public:
1155 // Constructors
1156
1157 wxRichTextPlainText(const wxString& text = wxEmptyString, wxRichTextObject* parent = NULL, wxTextAttrEx* style = NULL);
1158 wxRichTextPlainText(const wxRichTextPlainText& obj):wxRichTextObject() { Copy(obj); }
1159
1160 // Overrideables
1161
1162 /// Draw the item
1163 virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style);
1164
1165 /// Lay the item out
1166 virtual bool Layout(wxDC& dc, const wxRect& rect, const wxRichTextRange& affected, int style);
1167
1168 /// Get/set the object size for the given range. Returns false if the range
1169 /// is invalid for this object.
1170 virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags) const;
1171
1172 /// Get any text in this object for the given range
1173 virtual wxString GetTextForRange(const wxRichTextRange& range) const;
1174
1175 /// Do a split, returning an object containing the second part, and setting
1176 /// the first part in 'this'.
1177 virtual wxRichTextObject* DoSplit(long pos);
1178
1179 /// Calculate range
1180 virtual void CalculateRange(long start, long& end);
1181
1182 /// Delete range
1183 virtual bool DeleteRange(const wxRichTextRange& range);
1184
1185 /// Returns true if the object is empty
1186 virtual bool IsEmpty() const { return m_text.empty(); }
1187
1188 /// Returns true if this object can merge itself with the given one.
1189 virtual bool CanMerge(wxRichTextObject* object) const;
1190
1191 /// Returns true if this object merged itself with the given one.
1192 /// The calling code will then delete the given object.
1193 virtual bool Merge(wxRichTextObject* object);
1194
1195 /// Dump to output stream for debugging
1196 virtual void Dump(wxTextOutputStream& stream);
1197
1198 // Accessors
1199
1200 /// Get the text
1201 const wxString& GetText() const { return m_text; }
1202
1203 /// Set the text
1204 void SetText(const wxString& text) { m_text = text; }
1205
1206 // Operations
1207
1208 /// Copy
1209 void Copy(const wxRichTextPlainText& obj);
1210
1211 /// Clone
1212 virtual wxRichTextObject* Clone() const { return new wxRichTextPlainText(*this); }
1213
1214 protected:
1215 wxString m_text;
1216 };
1217
1218 /*!
1219 * wxRichTextImageBlock stores information about an image, in binary in-memory form
1220 */
1221
1222 class WXDLLIMPEXP_BASE wxDataInputStream;
1223 class WXDLLIMPEXP_BASE wxDataOutputStream;
1224
1225 class WXDLLIMPEXP_ADV wxRichTextImageBlock: public wxObject
1226 {
1227 public:
1228 wxRichTextImageBlock();
1229 wxRichTextImageBlock(const wxRichTextImageBlock& block);
1230 ~wxRichTextImageBlock();
1231
1232 void Init();
1233 void Clear();
1234
1235 // Load the original image into a memory block.
1236 // If the image is not a JPEG, we must convert it into a JPEG
1237 // to conserve space.
1238 // If it's not a JPEG we can make use of 'image', already scaled, so we don't have to
1239 // load the image a 2nd time.
1240 virtual bool MakeImageBlock(const wxString& filename, int imageType, wxImage& image, bool convertToJPEG = true);
1241
1242 // Make an image block from the wxImage in the given
1243 // format.
1244 virtual bool MakeImageBlock(wxImage& image, int imageType, int quality = 80);
1245
1246 // Write to a file
1247 bool Write(const wxString& filename);
1248
1249 // Write data in hex to a stream
1250 bool WriteHex(wxOutputStream& stream);
1251
1252 // Read data in hex from a stream
1253 bool ReadHex(wxInputStream& stream, int length, int imageType);
1254
1255 // Copy from 'block'
1256 void Copy(const wxRichTextImageBlock& block);
1257
1258 // Load a wxImage from the block
1259 bool Load(wxImage& image);
1260
1261 //// Operators
1262 void operator=(const wxRichTextImageBlock& block);
1263
1264 //// Accessors
1265
1266 unsigned char* GetData() const { return m_data; }
1267 size_t GetDataSize() const { return m_dataSize; }
1268 int GetImageType() const { return m_imageType; }
1269
1270 void SetData(unsigned char* image) { m_data = image; }
1271 void SetDataSize(size_t size) { m_dataSize = size; }
1272 void SetImageType(int imageType) { m_imageType = imageType; }
1273
1274 bool Ok() const { return GetData() != NULL; }
1275
1276 /// Implementation
1277
1278 /// Allocate and read from stream as a block of memory
1279 static unsigned char* ReadBlock(wxInputStream& stream, size_t size);
1280 static unsigned char* ReadBlock(const wxString& filename, size_t size);
1281
1282 // Write memory block to stream
1283 static bool WriteBlock(wxOutputStream& stream, unsigned char* block, size_t size);
1284
1285 // Write memory block to file
1286 static bool WriteBlock(const wxString& filename, unsigned char* block, size_t size);
1287
1288 protected:
1289 // Size in bytes of the image stored.
1290 // This is in the raw, original form such as a JPEG file.
1291 unsigned char* m_data;
1292 size_t m_dataSize;
1293 int m_imageType; // wxWin type id
1294 };
1295
1296
1297 /*!
1298 * wxRichTextImage class declaration
1299 * This object represents an image.
1300 */
1301
1302 class WXDLLIMPEXP_ADV wxRichTextImage: public wxRichTextObject
1303 {
1304 DECLARE_DYNAMIC_CLASS(wxRichTextImage)
1305 public:
1306 // Constructors
1307
1308 wxRichTextImage(wxRichTextObject* parent = NULL):wxRichTextObject(parent) { }
1309 wxRichTextImage(const wxImage& image, wxRichTextObject* parent = NULL);
1310 wxRichTextImage(const wxRichTextImageBlock& imageBlock, wxRichTextObject* parent = NULL);
1311 wxRichTextImage(const wxRichTextImage& obj):wxRichTextObject() { Copy(obj); }
1312
1313 // Overrideables
1314
1315 /// Draw the item
1316 virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style);
1317
1318 /// Lay the item out
1319 virtual bool Layout(wxDC& dc, const wxRect& rect, const wxRichTextRange& affected, int style);
1320
1321 /// Get the object size for the given range. Returns false if the range
1322 /// is invalid for this object.
1323 virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags) const;
1324
1325 /// Returns true if the object is empty
1326 virtual bool IsEmpty() const { return !m_image.Ok(); }
1327
1328 // Accessors
1329
1330 /// Get the image
1331 const wxImage& GetImage() const { return m_image; }
1332
1333 /// Set the image
1334 void SetImage(const wxImage& image) { m_image = image; }
1335
1336 /// Get the image block containing the raw data
1337 wxRichTextImageBlock& GetImageBlock() { return m_imageBlock; }
1338
1339 // Operations
1340
1341 /// Copy
1342 void Copy(const wxRichTextImage& obj);
1343
1344 /// Clone
1345 virtual wxRichTextObject* Clone() const { return new wxRichTextImage(*this); }
1346
1347 /// Load wxImage from the block
1348 virtual bool LoadFromBlock();
1349
1350 /// Make block from the wxImage
1351 virtual bool MakeBlock();
1352
1353 protected:
1354 // TODO: reduce the multiple representations of data
1355 wxImage m_image;
1356 wxBitmap m_bitmap;
1357 wxRichTextImageBlock m_imageBlock;
1358 };
1359
1360
1361 /*!
1362 * wxRichTextBuffer class declaration
1363 * This is a kind of box, used to represent the whole buffer
1364 */
1365
1366 class WXDLLIMPEXP_ADV wxRichTextCommand;
1367 class WXDLLIMPEXP_ADV wxRichTextAction;
1368
1369 class WXDLLIMPEXP_ADV wxRichTextBuffer: public wxRichTextParagraphLayoutBox
1370 {
1371 DECLARE_DYNAMIC_CLASS(wxRichTextBuffer)
1372 public:
1373 // Constructors
1374
1375 wxRichTextBuffer() { Init(); }
1376 wxRichTextBuffer(const wxRichTextBuffer& obj):wxRichTextParagraphLayoutBox() { Init(); Copy(obj); }
1377 ~wxRichTextBuffer() ;
1378
1379 // Accessors
1380
1381 /// Gets the command processor
1382 wxCommandProcessor* GetCommandProcessor() const { return m_commandProcessor; }
1383
1384 /// Set style sheet, if any.
1385 void SetStyleSheet(wxRichTextStyleSheet* styleSheet) { m_styleSheet = styleSheet; }
1386 wxRichTextStyleSheet* GetStyleSheet() const { return m_styleSheet; }
1387
1388 // Operations
1389
1390 /// Initialisation
1391 void Init();
1392
1393 /// Clears the buffer and resets the command processor
1394 virtual void Clear();
1395
1396 /// The same as Clear, and adds an empty paragraph.
1397 virtual void Reset();
1398
1399 /// Load a file
1400 virtual bool LoadFile(const wxString& filename, int type = wxRICHTEXT_TYPE_ANY);
1401
1402 /// Save a file
1403 virtual bool SaveFile(const wxString& filename, int type = wxRICHTEXT_TYPE_ANY);
1404
1405 /// Load from a stream
1406 virtual bool LoadFile(wxInputStream& stream, int type = wxRICHTEXT_TYPE_ANY);
1407
1408 /// Save to a stream
1409 virtual bool SaveFile(wxOutputStream& stream, int type = wxRICHTEXT_TYPE_ANY);
1410
1411 /// Convenience function to add a paragraph of text
1412 virtual wxRichTextRange AddParagraph(const wxString& text) { Modify(); return wxRichTextParagraphLayoutBox::AddParagraph(text); }
1413
1414 /// Begin collapsing undo/redo commands. Note that this may not work properly
1415 /// if combining commands that delete or insert content, changing ranges for
1416 /// subsequent actions.
1417 virtual bool BeginBatchUndo(const wxString& cmdName);
1418
1419 /// End collapsing undo/redo commands
1420 virtual bool EndBatchUndo();
1421
1422 /// Collapsing commands?
1423 virtual bool BatchingUndo() const { return m_batchedCommandDepth > 0; }
1424
1425 /// Submit immediately, or delay according to whether collapsing is on
1426 virtual bool SubmitAction(wxRichTextAction* action);
1427
1428 /// Get collapsed command
1429 virtual wxRichTextCommand* GetBatchedCommand() const { return m_batchedCommand; }
1430
1431 /// Begin suppressing undo/redo commands. The way undo is suppressed may be implemented
1432 /// differently by each command. If not dealt with by a command implementation, then
1433 /// it will be implemented automatically by not storing the command in the undo history
1434 /// when the action is submitted to the command processor.
1435 virtual bool BeginSuppressUndo();
1436
1437 /// End suppressing undo/redo commands.
1438 virtual bool EndSuppressUndo();
1439
1440 /// Collapsing commands?
1441 virtual bool SuppressingUndo() const { return m_suppressUndo > 0; }
1442
1443 /// Copy the range to the clipboard
1444 virtual bool CopyToClipboard(const wxRichTextRange& range);
1445
1446 /// Paste the clipboard content to the buffer
1447 virtual bool PasteFromClipboard(long position);
1448
1449 /// Can we paste from the clipboard?
1450 virtual bool CanPasteFromClipboard() const;
1451
1452 /// Begin using a style
1453 virtual bool BeginStyle(const wxTextAttrEx& style);
1454
1455 /// End the style
1456 virtual bool EndStyle();
1457
1458 /// End all styles
1459 virtual bool EndAllStyles();
1460
1461 /// Clear the style stack
1462 virtual void ClearStyleStack();
1463
1464 /// Get the size of the style stack, for example to check correct nesting
1465 virtual int GetStyleStackSize() const { return m_attributeStack.GetCount(); }
1466
1467 /// Begin using bold
1468 bool BeginBold();
1469
1470 /// End using bold
1471 bool EndBold() { return EndStyle(); }
1472
1473 /// Begin using italic
1474 bool BeginItalic();
1475
1476 /// End using italic
1477 bool EndItalic() { return EndStyle(); }
1478
1479 /// Begin using underline
1480 bool BeginUnderline();
1481
1482 /// End using underline
1483 bool EndUnderline() { return EndStyle(); }
1484
1485 /// Begin using point size
1486 bool BeginFontSize(int pointSize);
1487
1488 /// End using point size
1489 bool EndFontSize() { return EndStyle(); }
1490
1491 /// Begin using this font
1492 bool BeginFont(const wxFont& font);
1493
1494 /// End using a font
1495 bool EndFont() { return EndStyle(); }
1496
1497 /// Begin using this colour
1498 bool BeginTextColour(const wxColour& colour);
1499
1500 /// End using a colour
1501 bool EndTextColour() { return EndStyle(); }
1502
1503 /// Begin using alignment
1504 bool BeginAlignment(wxTextAttrAlignment alignment);
1505
1506 /// End alignment
1507 bool EndAlignment() { return EndStyle(); }
1508
1509 /// Begin left indent
1510 bool BeginLeftIndent(int leftIndent, int leftSubIndent = 0);
1511
1512 /// End left indent
1513 bool EndLeftIndent() { return EndStyle(); }
1514
1515 /// Begin right indent
1516 bool BeginRightIndent(int rightIndent);
1517
1518 /// End right indent
1519 bool EndRightIndent() { return EndStyle(); }
1520
1521 /// Begin paragraph spacing
1522 bool BeginParagraphSpacing(int before, int after);
1523
1524 /// End paragraph spacing
1525 bool EndParagraphSpacing() { return EndStyle(); }
1526
1527 /// Begin line spacing
1528 bool BeginLineSpacing(int lineSpacing);
1529
1530 /// End line spacing
1531 bool EndLineSpacing() { return EndStyle(); }
1532
1533 /// Begin numbered bullet
1534 bool BeginNumberedBullet(int bulletNumber, int leftIndent, int leftSubIndent, int bulletStyle = wxTEXT_ATTR_BULLET_STYLE_ARABIC|wxTEXT_ATTR_BULLET_STYLE_PERIOD);
1535
1536 /// End numbered bullet
1537 bool EndNumberedBullet() { return EndStyle(); }
1538
1539 /// Begin symbol bullet
1540 bool BeginSymbolBullet(wxChar symbol, int leftIndent, int leftSubIndent, int bulletStyle = wxTEXT_ATTR_BULLET_STYLE_SYMBOL);
1541
1542 /// End symbol bullet
1543 bool EndSymbolBullet() { return EndStyle(); }
1544
1545 /// Begin named character style
1546 bool BeginCharacterStyle(const wxString& characterStyle);
1547
1548 /// End named character style
1549 bool EndCharacterStyle() { return EndStyle(); }
1550
1551 /// Begin named paragraph style
1552 bool BeginParagraphStyle(const wxString& paragraphStyle);
1553
1554 /// End named character style
1555 bool EndParagraphStyle() { return EndStyle(); }
1556
1557 // Implementation
1558
1559 /// Copy
1560 void Copy(const wxRichTextBuffer& obj) { wxRichTextBox::Copy(obj); }
1561
1562 /// Clone
1563 virtual wxRichTextObject* Clone() const { return new wxRichTextBuffer(*this); }
1564
1565 /// Submit command to insert the given text
1566 bool InsertTextWithUndo(long pos, const wxString& text, wxRichTextCtrl* ctrl);
1567
1568 /// Submit command to insert a newline
1569 bool InsertNewlineWithUndo(long pos, wxRichTextCtrl* ctrl);
1570
1571 /// Submit command to insert the given image
1572 bool InsertImageWithUndo(long pos, const wxRichTextImageBlock& imageBlock, wxRichTextCtrl* ctrl);
1573
1574 /// Submit command to delete this range
1575 bool DeleteRangeWithUndo(const wxRichTextRange& range, long initialCaretPosition, long newCaretPositon, wxRichTextCtrl* ctrl);
1576
1577 /// Mark modified
1578 void Modify(bool modify = true) { m_modified = modify; }
1579 bool IsModified() const { return m_modified; }
1580
1581 /// Dumps contents of buffer for debugging purposes
1582 virtual void Dump();
1583 virtual void Dump(wxTextOutputStream& stream) { wxRichTextParagraphLayoutBox::Dump(stream); }
1584
1585 /// Returns the file handlers
1586 static wxList& GetHandlers() { return sm_handlers; }
1587
1588 /// Adds a handler to the end
1589 static void AddHandler(wxRichTextFileHandler *handler);
1590
1591 /// Inserts a handler at the front
1592 static void InsertHandler(wxRichTextFileHandler *handler);
1593
1594 /// Removes a handler
1595 static bool RemoveHandler(const wxString& name);
1596
1597 /// Finds a handler by name
1598 static wxRichTextFileHandler *FindHandler(const wxString& name);
1599
1600 /// Finds a handler by extension and type
1601 static wxRichTextFileHandler *FindHandler(const wxString& extension, int imageType);
1602
1603 /// Finds a handler by filename or, if supplied, type
1604 static wxRichTextFileHandler *FindHandlerFilenameOrType(const wxString& filename, int imageType);
1605
1606 /// Finds a handler by type
1607 static wxRichTextFileHandler *FindHandler(int imageType);
1608
1609 /// Gets a wildcard incorporating all visible handlers
1610 static wxString GetExtWildcard(bool combine = false, bool save = false);
1611
1612 /// Clean up handlers
1613 static void CleanUpHandlers();
1614
1615 /// Initialise the standard handlers
1616 static void InitStandardHandlers();
1617
1618 protected:
1619
1620 /// Command processor
1621 wxCommandProcessor* m_commandProcessor;
1622
1623 /// Has been modified?
1624 bool m_modified;
1625
1626 /// Collapsed command stack
1627 int m_batchedCommandDepth;
1628
1629 /// Name for collapsed command
1630 wxString m_batchedCommandsName;
1631
1632 /// Current collapsed command accumulating actions
1633 wxRichTextCommand* m_batchedCommand;
1634
1635 /// Whether to suppress undo
1636 int m_suppressUndo;
1637
1638 /// Style sheet, if any
1639 wxRichTextStyleSheet* m_styleSheet;
1640
1641 /// Stack of attributes for convenience functions
1642 wxList m_attributeStack;
1643
1644 /// File handlers
1645 static wxList sm_handlers;
1646 };
1647
1648 /*!
1649 * The command identifiers
1650 *
1651 */
1652
1653 enum wxRichTextCommandId
1654 {
1655 wxRICHTEXT_INSERT,
1656 wxRICHTEXT_DELETE,
1657 wxRICHTEXT_CHANGE_STYLE
1658 };
1659
1660 /*!
1661 * Command classes for undo/redo
1662 *
1663 */
1664
1665 class WXDLLIMPEXP_ADV wxRichTextAction;
1666 class WXDLLIMPEXP_ADV wxRichTextCommand: public wxCommand
1667 {
1668 public:
1669 // Ctor for one action
1670 wxRichTextCommand(const wxString& name, wxRichTextCommandId id, wxRichTextBuffer* buffer,
1671 wxRichTextCtrl* ctrl, bool ignoreFirstTime = false);
1672
1673 // Ctor for multiple actions
1674 wxRichTextCommand(const wxString& name);
1675
1676 ~wxRichTextCommand();
1677
1678 bool Do();
1679 bool Undo();
1680
1681 void AddAction(wxRichTextAction* action);
1682 void ClearActions();
1683
1684 wxList& GetActions() { return m_actions; }
1685
1686 protected:
1687
1688 wxList m_actions;
1689 };
1690
1691 /*!
1692 * wxRichTextAction class declaration
1693 * There can be more than one action in a command.
1694 */
1695
1696 class WXDLLIMPEXP_ADV wxRichTextAction: public wxObject
1697 {
1698 public:
1699 wxRichTextAction(wxRichTextCommand* cmd, const wxString& name, wxRichTextCommandId id, wxRichTextBuffer* buffer,
1700 wxRichTextCtrl* ctrl, bool ignoreFirstTime = false);
1701
1702 ~wxRichTextAction();
1703
1704 bool Do();
1705 bool Undo();
1706
1707 /// Update the control appearance
1708 void UpdateAppearance(long caretPosition, bool sendUpdateEvent = false);
1709
1710 /// Replace the buffer paragraphs with the given fragment.
1711 void ApplyParagraphs(const wxRichTextFragment& fragment);
1712
1713 /// Get the fragments
1714 wxRichTextFragment& GetNewParagraphs() { return m_newParagraphs; }
1715 wxRichTextFragment& GetOldParagraphs() { return m_oldParagraphs; }
1716
1717 /// Set/get the position used for e.g. insertion
1718 void SetPosition(long pos) { m_position = pos; }
1719 long GetPosition() const { return m_position; }
1720
1721 /// Set/get the range for e.g. deletion
1722 void SetRange(const wxRichTextRange& range) { m_range = range; }
1723 const wxRichTextRange& GetRange() const { return m_range; }
1724
1725 /// Get name
1726 const wxString& GetName() const { return m_name; }
1727
1728 protected:
1729 // Action name
1730 wxString m_name;
1731
1732 // Buffer
1733 wxRichTextBuffer* m_buffer;
1734
1735 // Control
1736 wxRichTextCtrl* m_ctrl;
1737
1738 // Stores the new paragraphs
1739 wxRichTextFragment m_newParagraphs;
1740
1741 // Stores the old paragraphs
1742 wxRichTextFragment m_oldParagraphs;
1743
1744 // The affected range
1745 wxRichTextRange m_range;
1746
1747 // The insertion point for this command
1748 long m_position;
1749
1750 // Ignore 1st 'Do' operation because we already did it
1751 bool m_ignoreThis;
1752
1753 // The command identifier
1754 wxRichTextCommandId m_cmdId;
1755 };
1756
1757 /*!
1758 * wxRichTextFileHandler
1759 * Base class for file handlers
1760 */
1761
1762 class WXDLLIMPEXP_ADV wxRichTextFileHandler: public wxObject
1763 {
1764 DECLARE_CLASS(wxRichTextFileHandler)
1765 public:
1766 wxRichTextFileHandler(const wxString& name = wxEmptyString, const wxString& ext = wxEmptyString, int type = 0)
1767 : m_name(name), m_extension(ext), m_type(type), m_visible(true)
1768 { }
1769
1770 #if wxUSE_STREAMS
1771 bool LoadFile(wxRichTextBuffer *buffer, wxInputStream& stream)
1772 { return DoLoadFile(buffer, stream); }
1773 bool SaveFile(wxRichTextBuffer *buffer, wxOutputStream& stream)
1774 { return DoSaveFile(buffer, stream); }
1775 #endif
1776
1777 bool LoadFile(wxRichTextBuffer *buffer, const wxString& filename);
1778 bool SaveFile(wxRichTextBuffer *buffer, const wxString& filename);
1779
1780 /// Can we handle this filename (if using files)? By default, checks the extension.
1781 virtual bool CanHandle(const wxString& filename) const;
1782
1783 /// Can we save using this handler?
1784 virtual bool CanSave() const { return false; }
1785
1786 /// Can we load using this handler?
1787 virtual bool CanLoad() const { return false; }
1788
1789 /// Should this handler be visible to the user?
1790 virtual bool IsVisible() const { return m_visible; }
1791 virtual void SetVisible(bool visible) { m_visible = visible; }
1792
1793 void SetName(const wxString& name) { m_name = name; }
1794 wxString GetName() const { return m_name; }
1795
1796 void SetExtension(const wxString& ext) { m_extension = ext; }
1797 wxString GetExtension() const { return m_extension; }
1798
1799 void SetType(int type) { m_type = type; }
1800 int GetType() const { return m_type; }
1801
1802 protected:
1803
1804 #if wxUSE_STREAMS
1805 virtual bool DoLoadFile(wxRichTextBuffer *buffer, wxInputStream& stream) = 0;
1806 virtual bool DoSaveFile(wxRichTextBuffer *buffer, wxOutputStream& stream) = 0;
1807 #endif
1808
1809 wxString m_name;
1810 wxString m_extension;
1811 int m_type;
1812 bool m_visible;
1813 };
1814
1815 /*!
1816 * wxRichTextPlainTextHandler
1817 * Plain text handler
1818 */
1819
1820 class WXDLLIMPEXP_ADV wxRichTextPlainTextHandler: public wxRichTextFileHandler
1821 {
1822 DECLARE_CLASS(wxRichTextPlainTextHandler)
1823 public:
1824 wxRichTextPlainTextHandler(const wxString& name = wxT("Text"), const wxString& ext = wxT("txt"), int type = wxRICHTEXT_TYPE_TEXT)
1825 : wxRichTextFileHandler(name, ext, type)
1826 { }
1827
1828 /// Can we save using this handler?
1829 virtual bool CanSave() const { return true; }
1830
1831 /// Can we load using this handler?
1832 virtual bool CanLoad() const { return true; }
1833
1834 protected:
1835
1836 #if wxUSE_STREAMS
1837 virtual bool DoLoadFile(wxRichTextBuffer *buffer, wxInputStream& stream);
1838 virtual bool DoSaveFile(wxRichTextBuffer *buffer, wxOutputStream& stream);
1839 #endif
1840
1841 };
1842
1843 /*!
1844 * Utilities
1845 *
1846 */
1847
1848 inline bool wxRichTextHasStyle(int flags, int style)
1849 {
1850 return ((flags & style) == style);
1851 }
1852
1853 /// Compare two attribute objects
1854 bool wxTextAttrEq(const wxTextAttrEx& attr1, const wxTextAttrEx& attr2);
1855 bool wxTextAttrEq(const wxTextAttr& attr1, const wxRichTextAttr& attr2);
1856
1857 /// Compare two attribute objects, but take into account the flags
1858 /// specifying attributes of interest.
1859 bool wxTextAttrEqPartial(const wxTextAttrEx& attr1, const wxTextAttrEx& attr2, int flags);
1860 bool wxTextAttrEqPartial(const wxTextAttrEx& attr1, const wxRichTextAttr& attr2, int flags);
1861
1862 /// Apply one style to another
1863 bool wxRichTextApplyStyle(wxTextAttrEx& destStyle, const wxTextAttrEx& style);
1864 bool wxRichTextApplyStyle(wxRichTextAttr& destStyle, const wxTextAttrEx& style);
1865 bool wxRichTextApplyStyle(wxTextAttrEx& destStyle, const wxRichTextAttr& style);
1866
1867 #endif
1868 // wxUSE_RICHTEXT
1869
1870 #endif
1871 // _WX_RICHTEXTBUFFER_H_