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