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