Switched off some buggy optimisation that caused caret positioning/drawn text mismatch.
[wxWidgets.git] / include / wx / richtext / richtextbuffer.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/richtext/richtextbuffer.h
3 // Purpose: Buffer for wxRichTextCtrl
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 2005-09-30
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _WX_RICHTEXTBUFFER_H_
13 #define _WX_RICHTEXTBUFFER_H_
14
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 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.
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 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
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
52 */
53
54 /*!
55 * Includes
56 */
57
58 #include "wx/defs.h"
59
60 #if wxUSE_RICHTEXT
61
62 #include "wx/list.h"
63 #include "wx/textctrl.h"
64 #include "wx/bitmap.h"
65 #include "wx/image.h"
66 #include "wx/cmdproc.h"
67 #include "wx/txtstrm.h"
68
69 #if wxUSE_DATAOBJ
70 #include "wx/dataobj.h"
71 #endif
72
73 // Compatibility
74 #define wxRichTextAttr wxTextAttr
75 #define wxTextAttrEx wxTextAttr
76
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
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
86
87 /*!
88 * Special characters
89 */
90
91 extern WXDLLIMPEXP_RICHTEXT const wxChar wxRichTextLineBreakChar;
92
93 /*!
94 * File types
95 */
96 enum 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 };
105
106 /*!
107 * Forward declarations
108 */
109
110 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextCtrl;
111 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextObject;
112 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextCacheObject;
113 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextObjectList;
114 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextLine;
115 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextParagraph;
116 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextFileHandler;
117 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextStyleSheet;
118 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextListStyleDefinition;
119 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextEvent;
120 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextRenderer;
121 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextBuffer;
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
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
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
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
157 // The point was on space outside content
158 #define wxRICHTEXT_HITTEST_OUTSIDE 0x10
159
160 /*!
161 * Flags for GetRangeSize
162 */
163
164 #define wxRICHTEXT_FORMATTED 0x01
165 #define wxRICHTEXT_UNFORMATTED 0x02
166 #define wxRICHTEXT_CACHE_SIZE 0x04
167 #define wxRICHTEXT_HEIGHT_ONLY 0x08
168
169 /*!
170 * Flags for SetStyle/SetListStyle
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
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
200 // Resets the existing style before applying the new style
201 #define wxRICHTEXT_SETSTYLE_RESET 0x40
202
203 // Removes the given style instead of applying it
204 #define wxRICHTEXT_SETSTYLE_REMOVE 0x80
205
206 /*!
207 * Flags for text insertion
208 */
209
210 #define wxRICHTEXT_INSERT_NONE 0x00
211 #define wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE 0x01
212 #define wxRICHTEXT_INSERT_INTERACTIVE 0x02
213
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
219 /*!
220 * Default superscript/subscript font multiplication factor
221 */
222
223 #define wxSCRIPT_MUL_FACTOR 1.5
224
225 /*!
226 * wxRichTextFontTable
227 * Manages quick access to a pool of fonts for rendering rich text
228 */
229
230 class WXDLLIMPEXP_RICHTEXT wxRichTextFontTable: public wxObject
231 {
232 public:
233 wxRichTextFontTable();
234
235 wxRichTextFontTable(const wxRichTextFontTable& table);
236 virtual ~wxRichTextFontTable();
237
238 bool IsOk() const { return m_refData != NULL; }
239
240 wxFont FindFont(const wxTextAttr& fontSpec);
241 void Clear();
242
243 void operator= (const wxRichTextFontTable& table);
244 bool operator == (const wxRichTextFontTable& table) const;
245 bool operator != (const wxRichTextFontTable& table) const { return !(*this == table); }
246
247 protected:
248
249 DECLARE_DYNAMIC_CLASS(wxRichTextFontTable)
250 };
251
252 /*!
253 * wxRichTextRange class declaration
254 * This stores beginning and end positions for a range of data.
255 * TODO: consider renaming wxTextRange and using for all text controls.
256 */
257
258 class WXDLLIMPEXP_RICHTEXT wxRichTextRange
259 {
260 public:
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; }
269 bool operator ==(const wxRichTextRange& range) const { return (m_start == range.m_start && m_end == range.m_end); }
270 bool operator !=(const wxRichTextRange& range) const { return (m_start != range.m_start && m_end != range.m_end); }
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
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
309 protected:
310 long m_start;
311 long m_end;
312 };
313
314 #define wxRICHTEXT_ALL wxRichTextRange(-2, -2)
315 #define wxRICHTEXT_NONE wxRichTextRange(-1, -1)
316
317 /*!
318 * wxRichTextObject class declaration
319 * This is the base for drawable objects.
320 */
321
322 class WXDLLIMPEXP_RICHTEXT wxRichTextObject: public wxObject
323 {
324 DECLARE_CLASS(wxRichTextObject)
325 public:
326 // Constructors
327
328 wxRichTextObject(wxRichTextObject* parent = NULL);
329 virtual ~wxRichTextObject();
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.
339 virtual bool Layout(wxDC& dc, const wxRect& rect, int style) = 0;
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.
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;
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
423 void SetAttributes(const wxTextAttr& attr) { m_attributes = attr; }
424 const wxTextAttr& GetAttributes() const { return m_attributes; }
425 wxTextAttr& GetAttributes() { return m_attributes; }
426
427 /// Set/get stored descent
428 void SetDescent(int descent) { m_descent = descent; }
429 int GetDescent() const { return m_descent; }
430
431 /// Gets the containing buffer
432 wxRichTextBuffer* GetBuffer() const;
433
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
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);
450
451 protected:
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
469 wxTextAttr m_attributes;
470 };
471
472 WX_DECLARE_LIST_WITH_DECL( wxRichTextObject, wxRichTextObjectList, class WXDLLIMPEXP_RICHTEXT );
473
474 /*!
475 * wxRichTextCompositeObject class declaration
476 * Objects of this class can contain other objects.
477 */
478
479 class WXDLLIMPEXP_RICHTEXT wxRichTextCompositeObject: public wxRichTextObject
480 {
481 DECLARE_CLASS(wxRichTextCompositeObject)
482 public:
483 // Constructors
484
485 wxRichTextCompositeObject(wxRichTextObject* parent = NULL);
486 virtual ~wxRichTextCompositeObject();
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
536 /// Assignment
537 void operator= (const wxRichTextCompositeObject& obj) { Copy(obj); }
538
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.
552 bool Defragment(const wxRichTextRange& range = wxRICHTEXT_ALL);
553
554 protected:
555 wxRichTextObjectList m_children;
556 };
557
558 /*!
559 * wxRichTextBox class declaration
560 * This defines a 2D space to lay out objects
561 */
562
563 class WXDLLIMPEXP_RICHTEXT wxRichTextBox: public wxRichTextCompositeObject
564 {
565 DECLARE_DYNAMIC_CLASS(wxRichTextBox)
566 public:
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
578 virtual bool Layout(wxDC& dc, const wxRect& rect, int style);
579
580 /// Get/set the object size for the given range. Returns false if the range
581 /// is invalid for this object.
582 virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const;
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
594 protected:
595 };
596
597 /*!
598 * wxRichTextParagraphBox class declaration
599 * This box knows how to lay out paragraphs.
600 */
601
602 class WXDLLIMPEXP_RICHTEXT wxRichTextParagraphLayoutBox: public wxRichTextBox
603 {
604 DECLARE_DYNAMIC_CLASS(wxRichTextParagraphLayoutBox)
605 public:
606 // Constructors
607
608 wxRichTextParagraphLayoutBox(wxRichTextObject* parent = NULL);
609 wxRichTextParagraphLayoutBox(const wxRichTextParagraphLayoutBox& obj): wxRichTextBox() { Init(); Copy(obj); }
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
617 virtual bool Layout(wxDC& dc, const wxRect& rect, int style);
618
619 /// Get/set the object size for the given range. Returns false if the range
620 /// is invalid for this object.
621 virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const;
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
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
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
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
657 virtual wxRichTextRange AddParagraph(const wxString& text, wxTextAttr* paraStyle = NULL);
658
659 /// Convenience function to add an image
660 virtual wxRichTextRange AddImage(const wxImage& image, wxTextAttr* paraStyle = NULL);
661
662 /// Adds multiple paragraphs, based on newlines.
663 virtual wxRichTextRange AddParagraphs(const wxString& text, wxTextAttr* paraStyle = NULL);
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
693 virtual wxRichTextParagraph* GetParagraphAtLine(long paragraphNumber) const;
694
695 /// Get the paragraph for a given line
696 virtual wxRichTextParagraph* GetParagraphForLine(wxRichTextLine* line) const;
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.
717 virtual bool SetStyle(const wxRichTextRange& range, const wxTextAttr& style, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO);
718
719 /// Get the conbined text attributes for this position.
720 virtual bool GetStyle(long position, wxTextAttr& style);
721
722 /// Get the content (uncombined) attributes for this position.
723 virtual bool GetUncombinedStyle(long position, wxTextAttr& style);
724
725 /// Implementation helper for GetStyle. If combineStyles is true, combine base, paragraph and
726 /// context attributes.
727 virtual bool DoGetStyle(long position, wxTextAttr& style, bool combineStyles = true);
728
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
731 virtual bool GetStyleForRange(const wxRichTextRange& range, wxTextAttr& style);
732
733 /// Combines 'style' with 'currentStyle' for the purpose of summarising the attributes of a range of
734 /// content.
735 bool CollectStyle(wxTextAttr& currentStyle, const wxTextAttr& style, long& multipleStyleAttributes, int& multipleTextEffectAttributes, int& absentStyleAttributes, int& absentTextEffectAttributes);
736
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.
746 virtual bool NumberList(const wxRichTextRange& range, wxRichTextListStyleDefinition* def = NULL, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int startFrom = 1, int specifiedLevel = -1);
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.
751 virtual bool PromoteList(int promoteBy, const wxRichTextRange& range, wxRichTextListStyleDefinition* def = NULL, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int specifiedLevel = -1);
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
758 /// Fills in the attributes for numbering a paragraph after previousParagraph.
759 virtual bool FindNextParagraphNumber(wxRichTextParagraph* previousParagraph, wxTextAttr& attr) const;
760
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.
765 virtual bool HasCharacterAttributes(const wxRichTextRange& range, const wxTextAttr& style) const;
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.
771 virtual bool HasParagraphAttributes(const wxRichTextRange& range, const wxTextAttr& style) const;
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.
779 virtual bool InsertFragment(long position, wxRichTextParagraphLayoutBox& fragment);
780
781 /// Make a copy of the fragment corresponding to the given range, putting it in 'fragment'.
782 virtual bool CopyFragment(const wxRichTextRange& range, wxRichTextParagraphLayoutBox& fragment);
783
784 /// Apply the style sheet to the buffer, for example if the styles have changed.
785 virtual bool ApplyStyleSheet(wxRichTextStyleSheet* styleSheet);
786
787 /// Copy
788 void Copy(const wxRichTextParagraphLayoutBox& obj);
789
790 /// Assignment
791 void operator= (const wxRichTextParagraphLayoutBox& obj) { Copy(obj); }
792
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.
801 virtual bool SetDefaultStyle(const wxTextAttr& style);
802
803 /// Get default style
804 virtual const wxTextAttr& GetDefaultStyle() const { return m_defaultAttributes; }
805
806 /// Set basic (overall) style
807 virtual void SetBasicStyle(const wxTextAttr& style) { m_attributes = style; }
808
809 /// Get basic (overall) style
810 virtual const wxTextAttr& GetBasicStyle() const { return m_attributes; }
811
812 /// Invalidate the buffer. With no argument, invalidates whole buffer.
813 void Invalidate(const wxRichTextRange& invalidRange = wxRICHTEXT_ALL);
814
815 /// Get invalid range, rounding to entire paragraphs if argument is true.
816 wxRichTextRange GetInvalidRange(bool wholeParagraphs = false) const;
817
818 protected:
819 wxRichTextCtrl* m_ctrl;
820 wxTextAttr m_defaultAttributes;
821
822 /// The invalidated range that will need full layout
823 wxRichTextRange m_invalidRange;
824
825 // Is the last paragraph partial or complete?
826 bool m_partialParagraph;
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
836 class WXDLLIMPEXP_RICHTEXT wxRichTextLine
837 {
838 public:
839 // Constructors
840
841 wxRichTextLine(wxRichTextParagraph* parent);
842 wxRichTextLine(const wxRichTextLine& obj) { Init( NULL); Copy(obj); }
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
860 /// Get the absolute range
861 wxRichTextRange GetAbsoluteRange() const;
862
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
881 #if wxRICHTEXT_USE_OPTIMIZED_LINE_DRAWING
882 wxArrayInt& GetObjectSizes() { return m_objectSizes; }
883 const wxArrayInt& GetObjectSizes() const { return m_objectSizes; }
884 #endif
885
886 // Operations
887
888 /// Initialisation
889 void Init(wxRichTextParagraph* parent);
890
891 /// Copy
892 void Copy(const wxRichTextLine& obj);
893
894 /// Clone
895 virtual wxRichTextLine* Clone() const { return new wxRichTextLine(*this); }
896
897 protected:
898
899 /// The range of the line (start position to end position)
900 /// This is relative to the parent paragraph.
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;
912
913 #if wxRICHTEXT_USE_OPTIMIZED_LINE_DRAWING
914 wxArrayInt m_objectSizes;
915 #endif
916 };
917
918 WX_DECLARE_LIST_WITH_DECL( wxRichTextLine, wxRichTextLineList , class WXDLLIMPEXP_RICHTEXT );
919
920 /*!
921 * wxRichTextParagraph class declaration
922 * This object represents a single paragraph (or in a straight text editor, a line).
923 */
924
925 class WXDLLIMPEXP_RICHTEXT wxRichTextParagraph: public wxRichTextBox
926 {
927 DECLARE_DYNAMIC_CLASS(wxRichTextParagraph)
928 public:
929 // Constructors
930
931 wxRichTextParagraph(wxRichTextObject* parent = NULL, wxTextAttr* style = NULL);
932 wxRichTextParagraph(const wxString& text, wxRichTextObject* parent = NULL, wxTextAttr* paraStyle = NULL, wxTextAttr* charStyle = NULL);
933 virtual ~wxRichTextParagraph();
934 wxRichTextParagraph(const wxRichTextParagraph& obj): wxRichTextBox() { Copy(obj); }
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
942 virtual bool Layout(wxDC& dc, const wxRect& rect, int style);
943
944 /// Get/set the object size for the given range. Returns false if the range
945 /// is invalid for this object.
946 virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const;
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
977 virtual void ApplyParagraphStyle(const wxTextAttr& attr, const wxRect& rect);
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.
998 bool FindWrapPosition(const wxRichTextRange& range, wxDC& dc, int availableSpace, long& wrapPosition, wxArrayInt* partialExtents);
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
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
1012 /// Get combined attributes of the base style, paragraph style and character style. We use this to dynamically
1013 /// retrieve the actual style.
1014 wxTextAttr GetCombinedAttributes(const wxTextAttr& contentStyle) const;
1015
1016 /// Get combined attributes of the base style and paragraph style.
1017 wxTextAttr GetCombinedAttributes() const;
1018
1019 /// Get the first position from pos that has a line break character.
1020 long GetFirstLineBreakPosition(long pos);
1021
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
1031 protected:
1032 /// The lines that make up the wrapped paragraph
1033 wxRichTextLineList m_cachedLines;
1034
1035 /// Default tabstops
1036 static wxArrayInt sm_defaultTabs;
1037 };
1038
1039 /*!
1040 * wxRichTextPlainText class declaration
1041 * This object represents a single piece of text.
1042 */
1043
1044 class WXDLLIMPEXP_RICHTEXT wxRichTextPlainText: public wxRichTextObject
1045 {
1046 DECLARE_DYNAMIC_CLASS(wxRichTextPlainText)
1047 public:
1048 // Constructors
1049
1050 wxRichTextPlainText(const wxString& text = wxEmptyString, wxRichTextObject* parent = NULL, wxTextAttr* style = NULL);
1051 wxRichTextPlainText(const wxRichTextPlainText& obj): wxRichTextObject() { Copy(obj); }
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
1059 virtual bool Layout(wxDC& dc, const wxRect& rect, int style);
1060
1061 /// Get/set the object size for the given range. Returns false if the range
1062 /// is invalid for this object.
1063 virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const;
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
1079 virtual bool IsEmpty() const { return m_text.empty(); }
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
1091 /// Get the first position from pos that has a line break character.
1092 long GetFirstLineBreakPosition(long pos);
1093
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); }
1109 private:
1110 bool DrawTabbedString(wxDC& dc, const wxTextAttr& attr, const wxRect& rect, wxString& str, wxCoord& x, wxCoord& y, bool selected);
1111
1112 protected:
1113 wxString m_text;
1114 };
1115
1116 /*!
1117 * wxRichTextImageBlock stores information about an image, in binary in-memory form
1118 */
1119
1120 class WXDLLIMPEXP_FWD_BASE wxDataInputStream;
1121 class WXDLLIMPEXP_FWD_BASE wxDataOutputStream;
1122
1123 class WXDLLIMPEXP_RICHTEXT wxRichTextImageBlock: public wxObject
1124 {
1125 public:
1126 wxRichTextImageBlock();
1127 wxRichTextImageBlock(const wxRichTextImageBlock& block);
1128 virtual ~wxRichTextImageBlock();
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.
1138 virtual bool MakeImageBlock(const wxString& filename, wxBitmapType imageType,
1139 wxImage& image, bool convertToJPEG = true);
1140
1141 // Make an image block from the wxImage in the given
1142 // format.
1143 virtual bool MakeImageBlock(wxImage& image, wxBitmapType imageType, int quality = 80);
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
1152 bool ReadHex(wxInputStream& stream, int length, wxBitmapType imageType);
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; }
1167 wxBitmapType GetImageType() const { return m_imageType; }
1168
1169 void SetData(unsigned char* image) { m_data = image; }
1170 void SetDataSize(size_t size) { m_dataSize = size; }
1171 void SetImageType(wxBitmapType imageType) { m_imageType = imageType; }
1172
1173 bool Ok() const { return IsOk(); }
1174 bool IsOk() const { return GetData() != NULL; }
1175
1176 // Gets the extension for the block's type
1177 wxString GetExtension() const;
1178
1179 /// Implementation
1180
1181 // Allocate and read from stream as a block of memory
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
1191 protected:
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;
1196 wxBitmapType m_imageType;
1197 };
1198
1199
1200 /*!
1201 * wxRichTextImage class declaration
1202 * This object represents an image.
1203 */
1204
1205 class WXDLLIMPEXP_RICHTEXT wxRichTextImage: public wxRichTextObject
1206 {
1207 DECLARE_DYNAMIC_CLASS(wxRichTextImage)
1208 public:
1209 // Constructors
1210
1211 wxRichTextImage(wxRichTextObject* parent = NULL): wxRichTextObject(parent) { }
1212 wxRichTextImage(const wxImage& image, wxRichTextObject* parent = NULL, wxTextAttr* charStyle = NULL);
1213 wxRichTextImage(const wxRichTextImageBlock& imageBlock, wxRichTextObject* parent = NULL, wxTextAttr* charStyle = NULL);
1214 wxRichTextImage(const wxRichTextImage& obj): wxRichTextObject() { Copy(obj); }
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
1222 virtual bool Layout(wxDC& dc, const wxRect& rect, int style);
1223
1224 /// Get the object size for the given range. Returns false if the range
1225 /// is invalid for this object.
1226 virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const;
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
1256 protected:
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
1269 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextCommand;
1270 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextAction;
1271
1272 class WXDLLIMPEXP_RICHTEXT wxRichTextBuffer: public wxRichTextParagraphLayoutBox
1273 {
1274 DECLARE_DYNAMIC_CLASS(wxRichTextBuffer)
1275 public:
1276 // Constructors
1277
1278 wxRichTextBuffer() { Init(); }
1279 wxRichTextBuffer(const wxRichTextBuffer& obj): wxRichTextParagraphLayoutBox() { Init(); Copy(obj); }
1280 virtual ~wxRichTextBuffer() ;
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; }
1289 virtual wxRichTextStyleSheet* GetStyleSheet() const { return m_styleSheet; }
1290
1291 /// Set style sheet and notify of the change
1292 bool SetStyleSheetAndNotify(wxRichTextStyleSheet* sheet);
1293
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();
1299
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
1305 // Operations
1306
1307 /// Initialisation
1308 void Init();
1309
1310 /// Clears the buffer, adds an empty paragraph, and clears the command processor.
1311 virtual void ResetAndClearCommands();
1312
1313 /// Load a file
1314 virtual bool LoadFile(const wxString& filename, wxRichTextFileType type = wxRICHTEXT_TYPE_ANY);
1315
1316 /// Save a file
1317 virtual bool SaveFile(const wxString& filename, wxRichTextFileType type = wxRICHTEXT_TYPE_ANY);
1318
1319 /// Load from a stream
1320 virtual bool LoadFile(wxInputStream& stream, wxRichTextFileType type = wxRICHTEXT_TYPE_ANY);
1321
1322 /// Save to a stream
1323 virtual bool SaveFile(wxOutputStream& stream, wxRichTextFileType type = wxRICHTEXT_TYPE_ANY);
1324
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
1331 /// Convenience function to add a paragraph of text
1332 virtual wxRichTextRange AddParagraph(const wxString& text, wxTextAttr* paraStyle = NULL) { Modify(); return wxRichTextParagraphLayoutBox::AddParagraph(text, paraStyle); }
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
1373 virtual bool BeginStyle(const wxTextAttr& style);
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
1385 virtual size_t GetStyleStackSize() const { return m_attributeStack.GetCount(); }
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
1460 bool BeginSymbolBullet(const wxString& symbol, int leftIndent, int leftSubIndent, int bulletStyle = wxTEXT_ATTR_BULLET_STYLE_SYMBOL);
1461
1462 /// End symbol bullet
1463 bool EndSymbolBullet() { return EndStyle(); }
1464
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
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(); }
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(); }
1488
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
1510 // Implementation
1511
1512 /// Copy
1513 void Copy(const wxRichTextBuffer& obj);
1514
1515 /// Clone
1516 virtual wxRichTextObject* Clone() const { return new wxRichTextBuffer(*this); }
1517
1518 /// Submit command to insert paragraphs
1519 bool InsertParagraphsWithUndo(long pos, const wxRichTextParagraphLayoutBox& paragraphs, wxRichTextCtrl* ctrl, int flags = 0);
1520
1521 /// Submit command to insert the given text
1522 bool InsertTextWithUndo(long pos, const wxString& text, wxRichTextCtrl* ctrl, int flags = 0);
1523
1524 /// Submit command to insert a newline
1525 bool InsertNewlineWithUndo(long pos, wxRichTextCtrl* ctrl, int flags = 0);
1526
1527 /// Submit command to insert the given image
1528 bool InsertImageWithUndo(long pos, const wxRichTextImageBlock& imageBlock, wxRichTextCtrl* ctrl, int flags = 0);
1529
1530 /// Submit command to delete this range
1531 bool DeleteRangeWithUndo(const wxRichTextRange& range, wxRichTextCtrl* ctrl);
1532
1533 /// Mark modified
1534 void Modify(bool modify = true) { m_modified = modify; }
1535 bool IsModified() const { return m_modified; }
1536
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.
1540 wxTextAttr GetStyleForNewParagraph(long pos, bool caretPosition = false, bool lookUpNewParaStyle=false) const;
1541
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
1562 static wxRichTextFileHandler *FindHandler(const wxString& extension, wxRichTextFileType imageType);
1563
1564 /// Finds a handler by filename or, if supplied, type
1565 static wxRichTextFileHandler *FindHandlerFilenameOrType(const wxString& filename,
1566 wxRichTextFileType imageType);
1567
1568 /// Finds a handler by type
1569 static wxRichTextFileHandler *FindHandler(wxRichTextFileType imageType);
1570
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);
1575
1576 /// Clean up handlers
1577 static void CleanUpHandlers();
1578
1579 /// Initialise the standard handlers
1580 static void InitStandardHandlers();
1581
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; }
1595
1596 /// Scale factor for calculating dimensions
1597 double GetScale() const { return m_scale; }
1598 void SetScale(double scale) { m_scale = scale; }
1599
1600 protected:
1601
1602 /// Command processor
1603 wxCommandProcessor* m_commandProcessor;
1604
1605 /// Table storing fonts
1606 wxRichTextFontTable m_fontTable;
1607
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
1626 /// List of event handlers that will be notified of events
1627 wxList m_eventHandlers;
1628
1629 /// Stack of attributes for convenience functions
1630 wxList m_attributeStack;
1631
1632 /// Flags to be passed to handlers
1633 int m_handlerFlags;
1634
1635 /// File handlers
1636 static wxList sm_handlers;
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;
1646
1647 /// Scaling factor in use: needed to calculate correct dimensions when printing
1648 double m_scale;
1649 };
1650
1651 /*!
1652 * The command identifiers
1653 *
1654 */
1655
1656 enum wxRichTextCommandId
1657 {
1658 wxRICHTEXT_INSERT,
1659 wxRICHTEXT_DELETE,
1660 wxRICHTEXT_CHANGE_STYLE
1661 };
1662
1663 /*!
1664 * Command classes for undo/redo
1665 *
1666 */
1667
1668 class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextAction;
1669 class WXDLLIMPEXP_RICHTEXT wxRichTextCommand: public wxCommand
1670 {
1671 public:
1672 // Ctor for one action
1673 wxRichTextCommand(const wxString& name, wxRichTextCommandId id, wxRichTextBuffer* buffer,
1674 wxRichTextCtrl* ctrl, bool ignoreFirstTime = false);
1675
1676 // Ctor for multiple actions
1677 wxRichTextCommand(const wxString& name);
1678
1679 virtual ~wxRichTextCommand();
1680
1681 bool Do();
1682 bool Undo();
1683
1684 void AddAction(wxRichTextAction* action);
1685 void ClearActions();
1686
1687 wxList& GetActions() { return m_actions; }
1688
1689 protected:
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
1699 class WXDLLIMPEXP_RICHTEXT wxRichTextAction: public wxObject
1700 {
1701 public:
1702 wxRichTextAction(wxRichTextCommand* cmd, const wxString& name, wxRichTextCommandId id, wxRichTextBuffer* buffer,
1703 wxRichTextCtrl* ctrl, bool ignoreFirstTime = false);
1704
1705 virtual ~wxRichTextAction();
1706
1707 bool Do();
1708 bool Undo();
1709
1710 /// Update the control appearance
1711 void UpdateAppearance(long caretPosition, bool sendUpdateEvent = false,
1712 wxArrayInt* optimizationLineCharPositions = NULL, wxArrayInt* optimizationLineYPositions = NULL, bool isDoCmd = true);
1713
1714 /// Replace the buffer paragraphs with the given fragment.
1715 void ApplyParagraphs(const wxRichTextParagraphLayoutBox& fragment);
1716
1717 /// Get the fragments
1718 wxRichTextParagraphLayoutBox& GetNewParagraphs() { return m_newParagraphs; }
1719 wxRichTextParagraphLayoutBox& GetOldParagraphs() { return m_oldParagraphs; }
1720
1721 /// Calculate arrays for refresh optimization
1722 void CalculateRefreshOptimizations(wxArrayInt& optimizationLineCharPositions, wxArrayInt& optimizationLineYPositions);
1723
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
1735 protected:
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
1746 wxRichTextParagraphLayoutBox m_newParagraphs;
1747
1748 // Stores the old paragraphs
1749 wxRichTextParagraphLayoutBox m_oldParagraphs;
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
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
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
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
1788 /*!
1789 * wxRichTextFileHandler
1790 * Base class for file handlers
1791 */
1792
1793 class WXDLLIMPEXP_RICHTEXT wxRichTextFileHandler: public wxObject
1794 {
1795 DECLARE_CLASS(wxRichTextFileHandler)
1796 public:
1797 wxRichTextFileHandler(const wxString& name = wxEmptyString, const wxString& ext = wxEmptyString, int type = 0)
1798 : m_name(name), m_extension(ext), m_type(type), m_flags(0), m_visible(true)
1799 { }
1800
1801 #if wxUSE_STREAMS
1802 bool LoadFile(wxRichTextBuffer *buffer, wxInputStream& stream)
1803 { return DoLoadFile(buffer, stream); }
1804 bool SaveFile(wxRichTextBuffer *buffer, wxOutputStream& stream)
1805 { return DoSaveFile(buffer, stream); }
1806 #endif
1807
1808 #if wxUSE_FFILE && wxUSE_STREAMS
1809 virtual bool LoadFile(wxRichTextBuffer *buffer, const wxString& filename);
1810 virtual bool SaveFile(wxRichTextBuffer *buffer, const wxString& filename);
1811 #endif // wxUSE_STREAMS && wxUSE_STREAMS
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
1826 /// The name of the nandler
1827 void SetName(const wxString& name) { m_name = name; }
1828 wxString GetName() const { return m_name; }
1829
1830 /// The default extension to recognise
1831 void SetExtension(const wxString& ext) { m_extension = ext; }
1832 wxString GetExtension() const { return m_extension; }
1833
1834 /// The handler type
1835 void SetType(int type) { m_type = type; }
1836 int GetType() const { return m_type; }
1837
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
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
1846 protected:
1847
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
1853 wxString m_name;
1854 wxString m_encoding;
1855 wxString m_extension;
1856 int m_type;
1857 int m_flags;
1858 bool m_visible;
1859 };
1860
1861 /*!
1862 * wxRichTextPlainTextHandler
1863 * Plain text handler
1864 */
1865
1866 class WXDLLIMPEXP_RICHTEXT wxRichTextPlainTextHandler: public wxRichTextFileHandler
1867 {
1868 DECLARE_CLASS(wxRichTextPlainTextHandler)
1869 public:
1870 wxRichTextPlainTextHandler(const wxString& name = wxT("Text"),
1871 const wxString& ext = wxT("txt"),
1872 wxRichTextFileType type = wxRICHTEXT_TYPE_TEXT)
1873 : wxRichTextFileHandler(name, ext, type)
1874 { }
1875
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
1882 protected:
1883
1884 #if wxUSE_STREAMS
1885 virtual bool DoLoadFile(wxRichTextBuffer *buffer, wxInputStream& stream);
1886 virtual bool DoSaveFile(wxRichTextBuffer *buffer, wxOutputStream& stream);
1887 #endif
1888
1889 };
1890
1891 #if wxUSE_DATAOBJ
1892
1893 /*!
1894 * The data object for a wxRichTextBuffer
1895 */
1896
1897 class WXDLLIMPEXP_RICHTEXT wxRichTextBufferDataObject: public wxDataObjectSimple
1898 {
1899 public:
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
1925 private:
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
1933 /*!
1934 * wxRichTextRenderer isolates common drawing functionality
1935 */
1936
1937 class WXDLLIMPEXP_RICHTEXT wxRichTextRenderer: public wxObject
1938 {
1939 public:
1940 wxRichTextRenderer() {}
1941 virtual ~wxRichTextRenderer() {}
1942
1943 /// Draw a standard bullet, as specified by the value of GetBulletName
1944 virtual bool DrawStandardBullet(wxRichTextParagraph* paragraph, wxDC& dc, const wxTextAttr& attr, const wxRect& rect) = 0;
1945
1946 /// Draw a bullet that can be described by text, such as numbered or symbol bullets
1947 virtual bool DrawTextBullet(wxRichTextParagraph* paragraph, wxDC& dc, const wxTextAttr& attr, const wxRect& rect, const wxString& text) = 0;
1948
1949 /// Draw a bitmap bullet, where the bullet bitmap is specified by the value of GetBulletName
1950 virtual bool DrawBitmapBullet(wxRichTextParagraph* paragraph, wxDC& dc, const wxTextAttr& attr, const wxRect& rect) = 0;
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
1960 class WXDLLIMPEXP_RICHTEXT wxRichTextStdRenderer: public wxRichTextRenderer
1961 {
1962 public:
1963 wxRichTextStdRenderer() {}
1964
1965 /// Draw a standard bullet, as specified by the value of GetBulletName
1966 virtual bool DrawStandardBullet(wxRichTextParagraph* paragraph, wxDC& dc, const wxTextAttr& attr, const wxRect& rect);
1967
1968 /// Draw a bullet that can be described by text, such as numbered or symbol bullets
1969 virtual bool DrawTextBullet(wxRichTextParagraph* paragraph, wxDC& dc, const wxTextAttr& attr, const wxRect& rect, const wxString& text);
1970
1971 /// Draw a bitmap bullet, where the bullet bitmap is specified by the value of GetBulletName
1972 virtual bool DrawBitmapBullet(wxRichTextParagraph* paragraph, wxDC& dc, const wxTextAttr& attr, const wxRect& rect);
1973
1974 /// Enumerate the standard bullet names currently supported
1975 virtual bool EnumerateStandardBulletNames(wxArrayString& bulletNames);
1976 };
1977
1978 /*!
1979 * Utilities
1980 *
1981 */
1982
1983 inline bool wxRichTextHasStyle(int flags, int style)
1984 {
1985 return ((flags & style) == style);
1986 }
1987
1988 /// Compare two attribute objects
1989 WXDLLIMPEXP_RICHTEXT bool wxTextAttrEq(const wxTextAttr& attr1, const wxTextAttr& attr2);
1990 WXDLLIMPEXP_RICHTEXT bool wxTextAttrEq(const wxTextAttr& attr1, const wxTextAttr& attr2);
1991
1992 /// Compare two attribute objects, but take into account the flags
1993 /// specifying attributes of interest.
1994 WXDLLIMPEXP_RICHTEXT bool wxTextAttrEqPartial(const wxTextAttr& attr1, const wxTextAttr& attr2, int flags);
1995
1996 /// Apply one style to another
1997 WXDLLIMPEXP_RICHTEXT bool wxRichTextApplyStyle(wxTextAttr& destStyle, const wxTextAttr& style, wxTextAttr* compareWith = NULL);
1998
1999 // Remove attributes
2000 WXDLLIMPEXP_RICHTEXT bool wxRichTextRemoveStyle(wxTextAttr& destStyle, const wxTextAttr& style);
2001
2002 /// Combine two bitlists
2003 WXDLLIMPEXP_RICHTEXT bool wxRichTextCombineBitlists(int& valueA, int valueB, int& flagsA, int flagsB);
2004
2005 /// Compare two bitlists
2006 WXDLLIMPEXP_RICHTEXT bool wxRichTextBitlistsEqPartial(int valueA, int valueB, int flags);
2007
2008 /// Split into paragraph and character styles
2009 WXDLLIMPEXP_RICHTEXT bool wxRichTextSplitParaCharStyles(const wxTextAttr& style, wxTextAttr& parStyle, wxTextAttr& charStyle);
2010
2011 /// Compare tabs
2012 WXDLLIMPEXP_RICHTEXT bool wxRichTextTabsEq(const wxArrayInt& tabs1, const wxArrayInt& tabs2);
2013
2014 /// Convert a decimal to Roman numerals
2015 WXDLLIMPEXP_RICHTEXT wxString wxRichTextDecimalToRoman(long n);
2016
2017 WXDLLIMPEXP_RICHTEXT void wxRichTextModuleInit();
2018
2019 #endif
2020 // wxUSE_RICHTEXT
2021
2022 #endif
2023 // _WX_RICHTEXTBUFFER_H_
2024