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