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