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