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