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