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