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