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