1 /////////////////////////////////////////////////////////////////////////////
2 // Name: samples/richtext/richtext.cpp
3 // Purpose: wxWidgets rich text editor sample
4 // Author: Julian Smart
7 // Copyright: (c) Julian Smart
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 // For compilers that support precompilation, includes "wx/wx.h".
20 #include "wx/wxprec.h"
26 // for all others, include the necessary headers (this file is usually all you
27 // need because it includes almost all "standard" wxWidgets headers)
32 #include "wx/fontdlg.h"
33 #include "wx/splitter.h"
34 #include "wx/sstream.h"
35 #include "wx/html/htmlwin.h"
36 #include "wx/stopwatch.h"
37 #include "wx/sysopt.h"
40 #include "wx/filesys.h"
41 #include "wx/fs_mem.h"
45 #include "wx/cshelp.h"
48 #ifndef wxHAS_IMAGES_IN_RESOURCES
49 #include "../sample.xpm"
52 #include "bitmaps/smiley.xpm"
53 // #include "bitmaps/idea.xpm"
54 #include "bitmaps/zebra.xpm"
56 #include "bitmaps/open.xpm"
57 #include "bitmaps/save.xpm"
58 #include "bitmaps/copy.xpm"
59 #include "bitmaps/cut.xpm"
60 #include "bitmaps/paste.xpm"
61 #include "bitmaps/undo.xpm"
62 #include "bitmaps/redo.xpm"
63 #include "bitmaps/bold.xpm"
64 #include "bitmaps/italic.xpm"
65 #include "bitmaps/underline.xpm"
67 #include "bitmaps/alignleft.xpm"
68 #include "bitmaps/alignright.xpm"
69 #include "bitmaps/centre.xpm"
70 #include "bitmaps/font.xpm"
71 #include "bitmaps/indentless.xpm"
72 #include "bitmaps/indentmore.xpm"
74 #include "wx/richtext/richtextctrl.h"
75 #include "wx/richtext/richtextstyles.h"
76 #include "wx/richtext/richtextxml.h"
77 #include "wx/richtext/richtexthtml.h"
78 #include "wx/richtext/richtextformatdlg.h"
79 #include "wx/richtext/richtextsymboldlg.h"
80 #include "wx/richtext/richtextstyledlg.h"
81 #include "wx/richtext/richtextprint.h"
82 #include "wx/richtext/richtextimagedlg.h"
84 // A custom field type
85 class wxRichTextFieldTypePropertiesTest
: public wxRichTextFieldTypeStandard
88 wxRichTextFieldTypePropertiesTest(const wxString
& name
, const wxString
& label
, int displayStyle
= wxRICHTEXT_FIELD_STYLE_RECTANGLE
):
89 wxRichTextFieldTypeStandard(name
, label
, displayStyle
)
92 wxRichTextFieldTypePropertiesTest(const wxString
& name
, const wxBitmap
& bitmap
, int displayStyle
= wxRICHTEXT_FIELD_STYLE_RECTANGLE
):
93 wxRichTextFieldTypeStandard(name
, bitmap
, displayStyle
)
97 virtual bool CanEditProperties(wxRichTextField
* WXUNUSED(obj
)) const { return true; }
98 virtual bool EditProperties(wxRichTextField
* WXUNUSED(obj
), wxWindow
* WXUNUSED(parent
), wxRichTextBuffer
* WXUNUSED(buffer
))
100 wxString label
= GetLabel();
101 wxMessageBox(wxString::Format(wxT("Editing %s"), label
.c_str()));
105 virtual wxString
GetPropertiesMenuLabel(wxRichTextField
* WXUNUSED(obj
)) const
111 // A custom composite field type
112 class wxRichTextFieldTypeCompositeTest
: public wxRichTextFieldTypePropertiesTest
115 wxRichTextFieldTypeCompositeTest(const wxString
& name
, const wxString
& label
):
116 wxRichTextFieldTypePropertiesTest(name
, label
, wxRICHTEXT_FIELD_STYLE_COMPOSITE
)
120 virtual bool UpdateField(wxRichTextBuffer
* buffer
, wxRichTextField
* obj
)
124 wxRichTextAttr
attr(buffer
->GetAttributes());
125 attr
.GetTextBoxAttr().Reset();
126 attr
.SetParagraphSpacingAfter(0);
127 attr
.SetLineSpacing(10);
128 obj
->SetAttributes(attr
);
130 obj
->GetChildren().Clear();
131 wxRichTextParagraph
* para
= new wxRichTextParagraph
;
132 wxRichTextPlainText
* text
= new wxRichTextPlainText(GetLabel());
133 para
->AppendChild(text
);
134 obj
->AppendChild(para
);
139 // ----------------------------------------------------------------------------
141 // ----------------------------------------------------------------------------
143 // ----------------------------------------------------------------------------
145 // ----------------------------------------------------------------------------
147 // Define a new application type, each program should derive a class from wxApp
148 class MyRichTextCtrl
: public wxRichTextCtrl
151 MyRichTextCtrl( wxWindow
* parent
, wxWindowID id
= -1, const wxString
& value
= wxEmptyString
, const wxPoint
& pos
= wxDefaultPosition
, const wxSize
& size
= wxDefaultSize
,
152 long style
= wxRE_MULTILINE
, const wxValidator
& validator
= wxDefaultValidator
, const wxString
& name
= wxTextCtrlNameStr
):
153 wxRichTextCtrl(parent
, id
, value
, pos
, size
, style
, validator
, name
)
159 void SetLockId(long id
) { m_lockId
= id
; }
160 long GetLockId() const { return m_lockId
; }
162 void BeginLock() { m_lockId
++; m_locked
= true; }
163 void EndLock() { m_locked
= false; }
164 bool IsLocked() const { return m_locked
; }
166 static void SetEnhancedDrawingHandler();
169 Prepares the content just before insertion (or after buffer reset). Called by the same function in wxRichTextBuffer.
170 Currently is only called if undo mode is on.
172 virtual void PrepareContent(wxRichTextParagraphLayoutBox
& container
);
175 Can we delete this range?
176 Sends an event to the control.
178 virtual bool CanDeleteRange(wxRichTextParagraphLayoutBox
& container
, const wxRichTextRange
& range
) const;
181 Can we insert content at this position?
182 Sends an event to the control.
184 virtual bool CanInsertContent(wxRichTextParagraphLayoutBox
& container
, long pos
) const;
187 Finds a table, either selected or near the cursor
189 wxRichTextTable
* FindTable() const;
192 Helper for FindTable()
194 wxRichTextObject
* FindCurrentPosition() const;
200 // Define a new application type, each program should derive a class from wxApp
201 class MyApp
: public wxApp
204 // override base class virtuals
205 // ----------------------------
207 // this one is called on application startup and is a good place for the app
208 // initialization (doing it here and not in the ctor allows to have an error
209 // return: if OnInit() returns false, the application terminates)
210 virtual bool OnInit();
211 virtual int OnExit();
215 wxRichTextStyleSheet
* GetStyleSheet() const { return m_styleSheet
; }
216 wxRichTextPrinting
* GetPrinting() const { return m_printing
; }
218 wxRichTextStyleSheet
* m_styleSheet
;
219 wxRichTextPrinting
* m_printing
;
222 // Define a new frame type: this is going to be our main frame
223 class MyFrame
: public wxFrame
227 MyFrame(const wxString
& title
, wxWindowID id
, const wxPoint
& pos
= wxDefaultPosition
,
228 const wxSize
& size
= wxDefaultSize
, long style
= wxDEFAULT_FRAME_STYLE
);
230 // event handlers (these functions should _not_ be virtual)
231 void OnQuit(wxCommandEvent
& event
);
232 void OnAbout(wxCommandEvent
& event
);
234 void OnOpen(wxCommandEvent
& event
);
235 void OnSave(wxCommandEvent
& event
);
236 void OnSaveAs(wxCommandEvent
& event
);
238 void OnBold(wxCommandEvent
& event
);
239 void OnItalic(wxCommandEvent
& event
);
240 void OnUnderline(wxCommandEvent
& event
);
242 void OnStrikethrough(wxCommandEvent
& event
);
243 void OnSuperscript(wxCommandEvent
& event
);
244 void OnSubscript(wxCommandEvent
& event
);
246 void OnUpdateBold(wxUpdateUIEvent
& event
);
247 void OnUpdateItalic(wxUpdateUIEvent
& event
);
248 void OnUpdateUnderline(wxUpdateUIEvent
& event
);
249 void OnUpdateStrikethrough(wxUpdateUIEvent
& event
);
250 void OnUpdateSuperscript(wxUpdateUIEvent
& event
);
251 void OnUpdateSubscript(wxUpdateUIEvent
& event
);
253 void OnAlignLeft(wxCommandEvent
& event
);
254 void OnAlignCentre(wxCommandEvent
& event
);
255 void OnAlignRight(wxCommandEvent
& event
);
257 void OnUpdateAlignLeft(wxUpdateUIEvent
& event
);
258 void OnUpdateAlignCentre(wxUpdateUIEvent
& event
);
259 void OnUpdateAlignRight(wxUpdateUIEvent
& event
);
261 void OnIndentMore(wxCommandEvent
& event
);
262 void OnIndentLess(wxCommandEvent
& event
);
264 void OnFont(wxCommandEvent
& event
);
265 void OnImage(wxCommandEvent
& event
);
266 void OnUpdateImage(wxUpdateUIEvent
& event
);
267 void OnParagraph(wxCommandEvent
& event
);
268 void OnFormat(wxCommandEvent
& event
);
269 void OnUpdateFormat(wxUpdateUIEvent
& event
);
271 void OnInsertSymbol(wxCommandEvent
& event
);
273 void OnLineSpacingHalf(wxCommandEvent
& event
);
274 void OnLineSpacingDouble(wxCommandEvent
& event
);
275 void OnLineSpacingSingle(wxCommandEvent
& event
);
277 void OnParagraphSpacingMore(wxCommandEvent
& event
);
278 void OnParagraphSpacingLess(wxCommandEvent
& event
);
280 void OnNumberList(wxCommandEvent
& event
);
281 void OnBulletsAndNumbering(wxCommandEvent
& event
);
282 void OnItemizeList(wxCommandEvent
& event
);
283 void OnRenumberList(wxCommandEvent
& event
);
284 void OnPromoteList(wxCommandEvent
& event
);
285 void OnDemoteList(wxCommandEvent
& event
);
286 void OnClearList(wxCommandEvent
& event
);
288 void OnTableAddColumn(wxCommandEvent
& event
);
289 void OnTableAddRow(wxCommandEvent
& event
);
290 void OnTableDeleteColumn(wxCommandEvent
& event
);
291 void OnTableDeleteRow(wxCommandEvent
& event
);
292 void OnTableFocusedUpdateUI(wxUpdateUIEvent
& event
);
293 void OnTableHasCellsUpdateUI(wxUpdateUIEvent
& event
);
295 void OnReload(wxCommandEvent
& event
);
297 void OnViewHTML(wxCommandEvent
& event
);
299 void OnSwitchStyleSheets(wxCommandEvent
& event
);
300 void OnManageStyles(wxCommandEvent
& event
);
302 void OnInsertURL(wxCommandEvent
& event
);
303 void OnURL(wxTextUrlEvent
& event
);
304 void OnStyleSheetReplacing(wxRichTextEvent
& event
);
306 void OnPrint(wxCommandEvent
& event
);
307 void OnPreview(wxCommandEvent
& event
);
308 void OnPageSetup(wxCommandEvent
& event
);
310 void OnInsertImage(wxCommandEvent
& event
);
312 void OnSetFontScale(wxCommandEvent
& event
);
313 void OnSetDimensionScale(wxCommandEvent
& event
);
316 // Forward command events to the current rich text control, if any
317 bool ProcessEvent(wxEvent
& event
);
320 void WriteInitialText();
323 // any class wishing to process wxWidgets events must use this macro
324 DECLARE_EVENT_TABLE()
326 MyRichTextCtrl
* m_richTextCtrl
;
329 // ----------------------------------------------------------------------------
331 // ----------------------------------------------------------------------------
333 // IDs for the controls and the menu commands
338 ID_About
= wxID_ABOUT
,
340 ID_FORMAT_BOLD
= 100,
343 ID_FORMAT_STRIKETHROUGH
,
344 ID_FORMAT_SUPERSCRIPT
,
357 ID_FORMAT_ALIGN_LEFT
,
358 ID_FORMAT_ALIGN_CENTRE
,
359 ID_FORMAT_ALIGN_RIGHT
,
361 ID_FORMAT_INDENT_MORE
,
362 ID_FORMAT_INDENT_LESS
,
364 ID_FORMAT_PARAGRAPH_SPACING_MORE
,
365 ID_FORMAT_PARAGRAPH_SPACING_LESS
,
367 ID_FORMAT_LINE_SPACING_HALF
,
368 ID_FORMAT_LINE_SPACING_DOUBLE
,
369 ID_FORMAT_LINE_SPACING_SINGLE
,
371 ID_FORMAT_NUMBER_LIST
,
372 ID_FORMAT_BULLETS_AND_NUMBERING
,
373 ID_FORMAT_ITEMIZE_LIST
,
374 ID_FORMAT_RENUMBER_LIST
,
375 ID_FORMAT_PROMOTE_LIST
,
376 ID_FORMAT_DEMOTE_LIST
,
377 ID_FORMAT_CLEAR_LIST
,
381 ID_TABLE_DELETE_COLUMN
,
385 ID_SET_DIMENSION_SCALE
,
388 ID_SWITCH_STYLE_SHEETS
,
396 ID_RICHTEXT_STYLE_LIST
,
397 ID_RICHTEXT_STYLE_COMBO
400 // ----------------------------------------------------------------------------
401 // event tables and other macros for wxWidgets
402 // ----------------------------------------------------------------------------
404 // the event tables connect the wxWidgets events with the functions (event
405 // handlers) which process them. It can be also done at run-time, but for the
406 // simple menu events like this the static method is much simpler.
407 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
408 EVT_MENU(ID_Quit
, MyFrame::OnQuit
)
409 EVT_MENU(ID_About
, MyFrame::OnAbout
)
411 EVT_MENU(wxID_OPEN
, MyFrame::OnOpen
)
412 EVT_MENU(wxID_SAVE
, MyFrame::OnSave
)
413 EVT_MENU(wxID_SAVEAS
, MyFrame::OnSaveAs
)
415 EVT_MENU(ID_FORMAT_BOLD
, MyFrame::OnBold
)
416 EVT_MENU(ID_FORMAT_ITALIC
, MyFrame::OnItalic
)
417 EVT_MENU(ID_FORMAT_UNDERLINE
, MyFrame::OnUnderline
)
419 EVT_MENU(ID_FORMAT_STRIKETHROUGH
, MyFrame::OnStrikethrough
)
420 EVT_MENU(ID_FORMAT_SUPERSCRIPT
, MyFrame::OnSuperscript
)
421 EVT_MENU(ID_FORMAT_SUBSCRIPT
, MyFrame::OnSubscript
)
423 EVT_UPDATE_UI(ID_FORMAT_BOLD
, MyFrame::OnUpdateBold
)
424 EVT_UPDATE_UI(ID_FORMAT_ITALIC
, MyFrame::OnUpdateItalic
)
425 EVT_UPDATE_UI(ID_FORMAT_UNDERLINE
, MyFrame::OnUpdateUnderline
)
427 EVT_UPDATE_UI(ID_FORMAT_STRIKETHROUGH
, MyFrame::OnUpdateStrikethrough
)
428 EVT_UPDATE_UI(ID_FORMAT_SUPERSCRIPT
, MyFrame::OnUpdateSuperscript
)
429 EVT_UPDATE_UI(ID_FORMAT_SUBSCRIPT
, MyFrame::OnUpdateSubscript
)
431 EVT_MENU(ID_FORMAT_ALIGN_LEFT
, MyFrame::OnAlignLeft
)
432 EVT_MENU(ID_FORMAT_ALIGN_CENTRE
, MyFrame::OnAlignCentre
)
433 EVT_MENU(ID_FORMAT_ALIGN_RIGHT
, MyFrame::OnAlignRight
)
435 EVT_UPDATE_UI(ID_FORMAT_ALIGN_LEFT
, MyFrame::OnUpdateAlignLeft
)
436 EVT_UPDATE_UI(ID_FORMAT_ALIGN_CENTRE
, MyFrame::OnUpdateAlignCentre
)
437 EVT_UPDATE_UI(ID_FORMAT_ALIGN_RIGHT
, MyFrame::OnUpdateAlignRight
)
439 EVT_MENU(ID_FORMAT_FONT
, MyFrame::OnFont
)
440 EVT_MENU(ID_FORMAT_IMAGE
, MyFrame::OnImage
)
441 EVT_MENU(ID_FORMAT_PARAGRAPH
, MyFrame::OnParagraph
)
442 EVT_MENU(ID_FORMAT_CONTENT
, MyFrame::OnFormat
)
443 EVT_UPDATE_UI(ID_FORMAT_CONTENT
, MyFrame::OnUpdateFormat
)
444 EVT_UPDATE_UI(ID_FORMAT_FONT
, MyFrame::OnUpdateFormat
)
445 EVT_UPDATE_UI(ID_FORMAT_IMAGE
, MyFrame::OnUpdateImage
)
446 EVT_UPDATE_UI(ID_FORMAT_PARAGRAPH
, MyFrame::OnUpdateFormat
)
447 EVT_MENU(ID_FORMAT_INDENT_MORE
, MyFrame::OnIndentMore
)
448 EVT_MENU(ID_FORMAT_INDENT_LESS
, MyFrame::OnIndentLess
)
450 EVT_MENU(ID_FORMAT_LINE_SPACING_HALF
, MyFrame::OnLineSpacingHalf
)
451 EVT_MENU(ID_FORMAT_LINE_SPACING_SINGLE
, MyFrame::OnLineSpacingSingle
)
452 EVT_MENU(ID_FORMAT_LINE_SPACING_DOUBLE
, MyFrame::OnLineSpacingDouble
)
454 EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_MORE
, MyFrame::OnParagraphSpacingMore
)
455 EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_LESS
, MyFrame::OnParagraphSpacingLess
)
457 EVT_MENU(ID_RELOAD
, MyFrame::OnReload
)
459 EVT_MENU(ID_INSERT_SYMBOL
, MyFrame::OnInsertSymbol
)
460 EVT_MENU(ID_INSERT_URL
, MyFrame::OnInsertURL
)
461 EVT_MENU(ID_INSERT_IMAGE
, MyFrame::OnInsertImage
)
463 EVT_MENU(ID_FORMAT_NUMBER_LIST
, MyFrame::OnNumberList
)
464 EVT_MENU(ID_FORMAT_BULLETS_AND_NUMBERING
, MyFrame::OnBulletsAndNumbering
)
465 EVT_MENU(ID_FORMAT_ITEMIZE_LIST
, MyFrame::OnItemizeList
)
466 EVT_MENU(ID_FORMAT_RENUMBER_LIST
, MyFrame::OnRenumberList
)
467 EVT_MENU(ID_FORMAT_PROMOTE_LIST
, MyFrame::OnPromoteList
)
468 EVT_MENU(ID_FORMAT_DEMOTE_LIST
, MyFrame::OnDemoteList
)
469 EVT_MENU(ID_FORMAT_CLEAR_LIST
, MyFrame::OnClearList
)
471 EVT_MENU(ID_TABLE_ADD_COLUMN
, MyFrame::OnTableAddColumn
)
472 EVT_MENU(ID_TABLE_ADD_ROW
, MyFrame::OnTableAddRow
)
473 EVT_MENU(ID_TABLE_DELETE_COLUMN
, MyFrame::OnTableDeleteColumn
)
474 EVT_MENU(ID_TABLE_DELETE_ROW
, MyFrame::OnTableDeleteRow
)
475 EVT_UPDATE_UI_RANGE(ID_TABLE_ADD_COLUMN
, ID_TABLE_ADD_ROW
, MyFrame::OnTableFocusedUpdateUI
)
476 EVT_UPDATE_UI_RANGE(ID_TABLE_DELETE_COLUMN
, ID_TABLE_DELETE_ROW
, MyFrame::OnTableHasCellsUpdateUI
)
478 EVT_MENU(ID_VIEW_HTML
, MyFrame::OnViewHTML
)
479 EVT_MENU(ID_SWITCH_STYLE_SHEETS
, MyFrame::OnSwitchStyleSheets
)
480 EVT_MENU(ID_MANAGE_STYLES
, MyFrame::OnManageStyles
)
482 EVT_MENU(ID_PRINT
, MyFrame::OnPrint
)
483 EVT_MENU(ID_PREVIEW
, MyFrame::OnPreview
)
484 EVT_MENU(ID_PAGE_SETUP
, MyFrame::OnPageSetup
)
486 EVT_TEXT_URL(wxID_ANY
, MyFrame::OnURL
)
487 EVT_RICHTEXT_STYLESHEET_REPLACING(wxID_ANY
, MyFrame::OnStyleSheetReplacing
)
489 EVT_MENU(ID_SET_FONT_SCALE
, MyFrame::OnSetFontScale
)
490 EVT_MENU(ID_SET_DIMENSION_SCALE
, MyFrame::OnSetDimensionScale
)
493 // Create a new application object: this macro will allow wxWidgets to create
494 // the application object during program execution (it's better than using a
495 // static object for many reasons) and also implements the accessor function
496 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
500 // ============================================================================
502 // ============================================================================
504 // ----------------------------------------------------------------------------
505 // the application class
506 // ----------------------------------------------------------------------------
508 // 'Main program' equivalent: the program execution "starts" here
511 if ( !wxApp::OnInit() )
515 wxHelpProvider::Set(new wxSimpleHelpProvider
);
518 m_styleSheet
= new wxRichTextStyleSheet
;
519 m_printing
= new wxRichTextPrinting(wxT("Test Document"));
521 m_printing
->SetFooterText(wxT("@TITLE@"), wxRICHTEXT_PAGE_ALL
, wxRICHTEXT_PAGE_CENTRE
);
522 m_printing
->SetFooterText(wxT("Page @PAGENUM@"), wxRICHTEXT_PAGE_ALL
, wxRICHTEXT_PAGE_RIGHT
);
526 MyRichTextCtrl::SetEnhancedDrawingHandler();
528 // Add extra handlers (plain text is automatically added)
529 wxRichTextBuffer::AddHandler(new wxRichTextXMLHandler
);
530 wxRichTextBuffer::AddHandler(new wxRichTextHTMLHandler
);
534 wxRichTextBuffer::AddFieldType(new wxRichTextFieldTypePropertiesTest(wxT("rectangle"), wxT("RECTANGLE"), wxRichTextFieldTypeStandard::wxRICHTEXT_FIELD_STYLE_RECTANGLE
));
536 wxRichTextFieldTypeStandard
* s1
= new wxRichTextFieldTypeStandard(wxT("begin-section"), wxT("SECTION"), wxRichTextFieldTypeStandard::wxRICHTEXT_FIELD_STYLE_START_TAG
);
537 s1
->SetBackgroundColour(*wxBLUE
);
539 wxRichTextFieldTypeStandard
* s2
= new wxRichTextFieldTypeStandard(wxT("end-section"), wxT("SECTION"), wxRichTextFieldTypeStandard::wxRICHTEXT_FIELD_STYLE_END_TAG
);
540 s2
->SetBackgroundColour(*wxBLUE
);
542 wxRichTextFieldTypeStandard
* s3
= new wxRichTextFieldTypeStandard(wxT("bitmap"), wxBitmap(paste_xpm
), wxRichTextFieldTypeStandard::wxRICHTEXT_FIELD_STYLE_NO_BORDER
);
544 wxRichTextBuffer::AddFieldType(s1
);
545 wxRichTextBuffer::AddFieldType(s2
);
546 wxRichTextBuffer::AddFieldType(s3
);
548 wxRichTextFieldTypeCompositeTest
* s4
= new wxRichTextFieldTypeCompositeTest(wxT("composite"), wxT("This is a field value"));
549 wxRichTextBuffer::AddFieldType(s4
);
551 // Add image handlers
553 wxImage::AddHandler( new wxPNGHandler
);
557 wxImage::AddHandler( new wxJPEGHandler
);
561 wxImage::AddHandler( new wxGIFHandler
);
565 wxFileSystem::AddHandler( new wxMemoryFSHandler
);
568 // create the main application window
569 wxSize size
= wxGetDisplaySize();
570 size
.Scale(0.75, 0.75);
571 MyFrame
*frame
= new MyFrame(wxT("wxRichTextCtrl Sample"), wxID_ANY
, wxDefaultPosition
, size
);
573 m_printing
->SetParentWindow(frame
);
575 // and show it (the frames, unlike simple controls, are not shown when
576 // created initially)
579 // success: wxApp::OnRun() will be called which will enter the main message
580 // loop and the application will run. If we returned false here, the
581 // application would exit immediately.
593 void MyApp::CreateStyles()
597 wxFont
romanFont(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
598 wxFont
swissFont(12, wxSWISS
, wxNORMAL
, wxNORMAL
);
600 wxRichTextParagraphStyleDefinition
* normalPara
= new wxRichTextParagraphStyleDefinition(wxT("Normal"));
601 wxRichTextAttr normalAttr
;
602 normalAttr
.SetFontFaceName(romanFont
.GetFaceName());
603 normalAttr
.SetFontSize(12);
604 // Let's set all attributes for this style
605 normalAttr
.SetFlags(wxTEXT_ATTR_FONT
| wxTEXT_ATTR_BACKGROUND_COLOUR
| wxTEXT_ATTR_TEXT_COLOUR
|wxTEXT_ATTR_ALIGNMENT
|wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
|wxTEXT_ATTR_TABS
|
606 wxTEXT_ATTR_PARA_SPACING_BEFORE
|wxTEXT_ATTR_PARA_SPACING_AFTER
|wxTEXT_ATTR_LINE_SPACING
|
607 wxTEXT_ATTR_BULLET_STYLE
|wxTEXT_ATTR_BULLET_NUMBER
);
608 normalPara
->SetStyle(normalAttr
);
610 m_styleSheet
->AddParagraphStyle(normalPara
);
612 wxRichTextParagraphStyleDefinition
* indentedPara
= new wxRichTextParagraphStyleDefinition(wxT("Indented"));
613 wxRichTextAttr indentedAttr
;
614 indentedAttr
.SetFontFaceName(romanFont
.GetFaceName());
615 indentedAttr
.SetFontSize(12);
616 indentedAttr
.SetLeftIndent(100, 0);
617 // We only want to affect indentation
618 indentedAttr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
);
619 indentedPara
->SetStyle(indentedAttr
);
621 m_styleSheet
->AddParagraphStyle(indentedPara
);
623 wxRichTextParagraphStyleDefinition
* indentedPara2
= new wxRichTextParagraphStyleDefinition(wxT("Red Bold Indented"));
624 wxRichTextAttr indentedAttr2
;
625 indentedAttr2
.SetFontFaceName(romanFont
.GetFaceName());
626 indentedAttr2
.SetFontSize(12);
627 indentedAttr2
.SetFontWeight(wxFONTWEIGHT_BOLD
);
628 indentedAttr2
.SetTextColour(*wxRED
);
629 indentedAttr2
.SetFontSize(12);
630 indentedAttr2
.SetLeftIndent(100, 0);
631 // We want to affect indentation, font and text colour
632 indentedAttr2
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
|wxTEXT_ATTR_FONT
|wxTEXT_ATTR_TEXT_COLOUR
);
633 indentedPara2
->SetStyle(indentedAttr2
);
635 m_styleSheet
->AddParagraphStyle(indentedPara2
);
637 wxRichTextParagraphStyleDefinition
* flIndentedPara
= new wxRichTextParagraphStyleDefinition(wxT("First Line Indented"));
638 wxRichTextAttr flIndentedAttr
;
639 flIndentedAttr
.SetFontFaceName(swissFont
.GetFaceName());
640 flIndentedAttr
.SetFontSize(12);
641 flIndentedAttr
.SetLeftIndent(100, -100);
642 // We only want to affect indentation
643 flIndentedAttr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
);
644 flIndentedPara
->SetStyle(flIndentedAttr
);
646 m_styleSheet
->AddParagraphStyle(flIndentedPara
);
650 wxRichTextCharacterStyleDefinition
* boldDef
= new wxRichTextCharacterStyleDefinition(wxT("Bold"));
651 wxRichTextAttr boldAttr
;
652 boldAttr
.SetFontFaceName(romanFont
.GetFaceName());
653 boldAttr
.SetFontSize(12);
654 boldAttr
.SetFontWeight(wxFONTWEIGHT_BOLD
);
655 // We only want to affect boldness
656 boldAttr
.SetFlags(wxTEXT_ATTR_FONT_WEIGHT
);
657 boldDef
->SetStyle(boldAttr
);
659 m_styleSheet
->AddCharacterStyle(boldDef
);
661 wxRichTextCharacterStyleDefinition
* italicDef
= new wxRichTextCharacterStyleDefinition(wxT("Italic"));
662 wxRichTextAttr italicAttr
;
663 italicAttr
.SetFontFaceName(romanFont
.GetFaceName());
664 italicAttr
.SetFontSize(12);
665 italicAttr
.SetFontStyle(wxFONTSTYLE_ITALIC
);
666 // We only want to affect italics
667 italicAttr
.SetFlags(wxTEXT_ATTR_FONT_ITALIC
);
668 italicDef
->SetStyle(italicAttr
);
670 m_styleSheet
->AddCharacterStyle(italicDef
);
672 wxRichTextCharacterStyleDefinition
* redDef
= new wxRichTextCharacterStyleDefinition(wxT("Red Bold"));
673 wxRichTextAttr redAttr
;
674 redAttr
.SetFontFaceName(romanFont
.GetFaceName());
675 redAttr
.SetFontSize(12);
676 redAttr
.SetFontWeight(wxFONTWEIGHT_BOLD
);
677 redAttr
.SetTextColour(*wxRED
);
678 // We only want to affect colour, weight and face
679 redAttr
.SetFlags(wxTEXT_ATTR_FONT_FACE
|wxTEXT_ATTR_FONT_WEIGHT
|wxTEXT_ATTR_TEXT_COLOUR
);
680 redDef
->SetStyle(redAttr
);
682 m_styleSheet
->AddCharacterStyle(redDef
);
684 wxRichTextListStyleDefinition
* bulletList
= new wxRichTextListStyleDefinition(wxT("Bullet List 1"));
686 for (i
= 0; i
< 10; i
++)
690 bulletText
= wxT("standard/circle");
692 bulletText
= wxT("standard/square");
694 bulletText
= wxT("standard/circle");
696 bulletText
= wxT("standard/square");
698 bulletText
= wxT("standard/circle");
700 bulletList
->SetAttributes(i
, (i
+1)*60, 60, wxTEXT_ATTR_BULLET_STYLE_STANDARD
, bulletText
);
703 m_styleSheet
->AddListStyle(bulletList
);
705 wxRichTextListStyleDefinition
* numberedList
= new wxRichTextListStyleDefinition(wxT("Numbered List 1"));
706 for (i
= 0; i
< 10; i
++)
710 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
712 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_LETTERS_LOWER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
714 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ROMAN_LOWER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
716 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ROMAN_UPPER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
718 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
720 numberStyle
|= wxTEXT_ATTR_BULLET_STYLE_ALIGN_RIGHT
;
722 numberedList
->SetAttributes(i
, (i
+1)*60, 60, numberStyle
);
725 m_styleSheet
->AddListStyle(numberedList
);
727 wxRichTextListStyleDefinition
* outlineList
= new wxRichTextListStyleDefinition(wxT("Outline List 1"));
728 for (i
= 0; i
< 10; i
++)
732 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_OUTLINE
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
734 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
736 outlineList
->SetAttributes(i
, (i
+1)*120, 120, numberStyle
);
739 m_styleSheet
->AddListStyle(outlineList
);
742 // ----------------------------------------------------------------------------
744 // ----------------------------------------------------------------------------
747 MyFrame::MyFrame(const wxString
& title
, wxWindowID id
, const wxPoint
& pos
,
748 const wxSize
& size
, long style
)
749 : wxFrame(NULL
, id
, title
, pos
, size
, style
)
752 SetWindowVariant(wxWINDOW_VARIANT_SMALL
);
755 // set the frame icon
756 SetIcon(wxICON(sample
));
759 wxMenu
*fileMenu
= new wxMenu
;
761 // the "About" item should be in the help menu
762 wxMenu
*helpMenu
= new wxMenu
;
763 helpMenu
->Append(ID_About
, wxT("&About\tF1"), wxT("Show about dialog"));
765 fileMenu
->Append(wxID_OPEN
, wxT("&Open\tCtrl+O"), wxT("Open a file"));
766 fileMenu
->Append(wxID_SAVE
, wxT("&Save\tCtrl+S"), wxT("Save a file"));
767 fileMenu
->Append(wxID_SAVEAS
, wxT("&Save As...\tF12"), wxT("Save to a new file"));
768 fileMenu
->AppendSeparator();
769 fileMenu
->Append(ID_RELOAD
, wxT("&Reload Text\tF2"), wxT("Reload the initial text"));
770 fileMenu
->AppendSeparator();
771 fileMenu
->Append(ID_PAGE_SETUP
, wxT("Page Set&up..."), wxT("Page setup"));
772 fileMenu
->Append(ID_PRINT
, wxT("&Print...\tCtrl+P"), wxT("Print"));
773 fileMenu
->Append(ID_PREVIEW
, wxT("Print Pre&view"), wxT("Print preview"));
774 fileMenu
->AppendSeparator();
775 fileMenu
->Append(ID_VIEW_HTML
, wxT("&View as HTML"), wxT("View HTML"));
776 fileMenu
->AppendSeparator();
777 fileMenu
->Append(ID_Quit
, wxT("E&xit\tAlt+X"), wxT("Quit this program"));
779 wxMenu
* editMenu
= new wxMenu
;
780 editMenu
->Append(wxID_UNDO
, _("&Undo\tCtrl+Z"));
781 editMenu
->Append(wxID_REDO
, _("&Redo\tCtrl+Y"));
782 editMenu
->AppendSeparator();
783 editMenu
->Append(wxID_CUT
, _("Cu&t\tCtrl+X"));
784 editMenu
->Append(wxID_COPY
, _("&Copy\tCtrl+C"));
785 editMenu
->Append(wxID_PASTE
, _("&Paste\tCtrl+V"));
787 editMenu
->AppendSeparator();
788 editMenu
->Append(wxID_SELECTALL
, _("Select A&ll\tCtrl+A"));
789 editMenu
->AppendSeparator();
790 editMenu
->Append(ID_SET_FONT_SCALE
, _("Set &Text Scale..."));
791 editMenu
->Append(ID_SET_DIMENSION_SCALE
, _("Set &Dimension Scale..."));
793 wxMenu
* formatMenu
= new wxMenu
;
794 formatMenu
->AppendCheckItem(ID_FORMAT_BOLD
, _("&Bold\tCtrl+B"));
795 formatMenu
->AppendCheckItem(ID_FORMAT_ITALIC
, _("&Italic\tCtrl+I"));
796 formatMenu
->AppendCheckItem(ID_FORMAT_UNDERLINE
, _("&Underline\tCtrl+U"));
797 formatMenu
->AppendSeparator();
798 formatMenu
->AppendCheckItem(ID_FORMAT_STRIKETHROUGH
, _("Stri&kethrough"));
799 formatMenu
->AppendCheckItem(ID_FORMAT_SUPERSCRIPT
, _("Superscrip&t"));
800 formatMenu
->AppendCheckItem(ID_FORMAT_SUBSCRIPT
, _("Subscrip&t"));
801 formatMenu
->AppendSeparator();
802 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_LEFT
, _("L&eft Align"));
803 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_RIGHT
, _("&Right Align"));
804 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_CENTRE
, _("&Centre"));
805 formatMenu
->AppendSeparator();
806 formatMenu
->Append(ID_FORMAT_INDENT_MORE
, _("Indent &More"));
807 formatMenu
->Append(ID_FORMAT_INDENT_LESS
, _("Indent &Less"));
808 formatMenu
->AppendSeparator();
809 formatMenu
->Append(ID_FORMAT_PARAGRAPH_SPACING_MORE
, _("Increase Paragraph &Spacing"));
810 formatMenu
->Append(ID_FORMAT_PARAGRAPH_SPACING_LESS
, _("Decrease &Paragraph Spacing"));
811 formatMenu
->AppendSeparator();
812 formatMenu
->Append(ID_FORMAT_LINE_SPACING_SINGLE
, _("Normal Line Spacing"));
813 formatMenu
->Append(ID_FORMAT_LINE_SPACING_HALF
, _("1.5 Line Spacing"));
814 formatMenu
->Append(ID_FORMAT_LINE_SPACING_DOUBLE
, _("Double Line Spacing"));
815 formatMenu
->AppendSeparator();
816 formatMenu
->Append(ID_FORMAT_FONT
, _("&Font..."));
817 formatMenu
->Append(ID_FORMAT_IMAGE
, _("Image Property"));
818 formatMenu
->Append(ID_FORMAT_PARAGRAPH
, _("&Paragraph..."));
819 formatMenu
->Append(ID_FORMAT_CONTENT
, _("Font and Pa&ragraph...\tShift+Ctrl+F"));
820 formatMenu
->AppendSeparator();
821 formatMenu
->Append(ID_SWITCH_STYLE_SHEETS
, _("&Switch Style Sheets"));
822 formatMenu
->Append(ID_MANAGE_STYLES
, _("&Manage Styles"));
824 wxMenu
* listsMenu
= new wxMenu
;
825 listsMenu
->Append(ID_FORMAT_BULLETS_AND_NUMBERING
, _("Bullets and &Numbering..."));
826 listsMenu
->AppendSeparator();
827 listsMenu
->Append(ID_FORMAT_NUMBER_LIST
, _("Number List"));
828 listsMenu
->Append(ID_FORMAT_ITEMIZE_LIST
, _("Itemize List"));
829 listsMenu
->Append(ID_FORMAT_RENUMBER_LIST
, _("Renumber List"));
830 listsMenu
->Append(ID_FORMAT_PROMOTE_LIST
, _("Promote List Items"));
831 listsMenu
->Append(ID_FORMAT_DEMOTE_LIST
, _("Demote List Items"));
832 listsMenu
->Append(ID_FORMAT_CLEAR_LIST
, _("Clear List Formatting"));
834 wxMenu
* tableMenu
= new wxMenu
;
835 tableMenu
->Append(ID_TABLE_ADD_COLUMN
, _("&Add Column"));
836 tableMenu
->Append(ID_TABLE_ADD_ROW
, _("Add &Row"));
837 tableMenu
->Append(ID_TABLE_DELETE_COLUMN
, _("Delete &Column"));
838 tableMenu
->Append(ID_TABLE_DELETE_ROW
, _("&Delete Row"));
840 wxMenu
* insertMenu
= new wxMenu
;
841 insertMenu
->Append(ID_INSERT_SYMBOL
, _("&Symbol...\tCtrl+I"));
842 insertMenu
->Append(ID_INSERT_URL
, _("&URL..."));
843 insertMenu
->Append(ID_INSERT_IMAGE
, _("&Image..."));
845 // now append the freshly created menu to the menu bar...
846 wxMenuBar
*menuBar
= new wxMenuBar();
847 menuBar
->Append(fileMenu
, wxT("&File"));
848 menuBar
->Append(editMenu
, wxT("&Edit"));
849 menuBar
->Append(formatMenu
, wxT("F&ormat"));
850 menuBar
->Append(listsMenu
, wxT("&Lists"));
851 menuBar
->Append(tableMenu
, wxT("&Tables"));
852 menuBar
->Append(insertMenu
, wxT("&Insert"));
853 menuBar
->Append(helpMenu
, wxT("&Help"));
855 // ... and attach this menu bar to the frame
858 // create a status bar just for fun (by default with 1 pane only)
859 // but don't create it on limited screen space (WinCE)
860 bool is_pda
= wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA
;
866 SetStatusText(wxT("Welcome to wxRichTextCtrl!"));
870 wxBoxSizer
* sizer
= new wxBoxSizer(wxVERTICAL
);
873 // On Mac, don't create a 'native' wxToolBar because small bitmaps are not supported by native
874 // toolbars. On Mac, a non-native, small-bitmap toolbar doesn't show unless it is explicitly
875 // managed, hence the use of sizers. In a real application, use larger icons for the main
876 // toolbar to avoid the need for this workaround. Or, use the toolbar in a container window
877 // as part of a more complex hierarchy, and the toolbar will automatically be non-native.
879 wxSystemOptions::SetOption(wxT("mac.toolbar.no-native"), 1);
881 wxToolBar
* toolBar
= new wxToolBar(this, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
,
882 wxNO_BORDER
|wxTB_FLAT
|wxTB_NODIVIDER
|wxTB_NOALIGN
);
884 sizer
->Add(toolBar
, 0, wxEXPAND
);
886 toolBar
->AddTool(wxID_OPEN
, wxEmptyString
, wxBitmap(open_xpm
), _("Open"));
887 toolBar
->AddTool(wxID_SAVEAS
, wxEmptyString
, wxBitmap(save_xpm
), _("Save"));
888 toolBar
->AddSeparator();
889 toolBar
->AddTool(wxID_CUT
, wxEmptyString
, wxBitmap(cut_xpm
), _("Cut"));
890 toolBar
->AddTool(wxID_COPY
, wxEmptyString
, wxBitmap(copy_xpm
), _("Copy"));
891 toolBar
->AddTool(wxID_PASTE
, wxEmptyString
, wxBitmap(paste_xpm
), _("Paste"));
892 toolBar
->AddSeparator();
893 toolBar
->AddTool(wxID_UNDO
, wxEmptyString
, wxBitmap(undo_xpm
), _("Undo"));
894 toolBar
->AddTool(wxID_REDO
, wxEmptyString
, wxBitmap(redo_xpm
), _("Redo"));
895 toolBar
->AddSeparator();
896 toolBar
->AddCheckTool(ID_FORMAT_BOLD
, wxEmptyString
, wxBitmap(bold_xpm
), wxNullBitmap
, _("Bold"));
897 toolBar
->AddCheckTool(ID_FORMAT_ITALIC
, wxEmptyString
, wxBitmap(italic_xpm
), wxNullBitmap
, _("Italic"));
898 toolBar
->AddCheckTool(ID_FORMAT_UNDERLINE
, wxEmptyString
, wxBitmap(underline_xpm
), wxNullBitmap
, _("Underline"));
899 toolBar
->AddSeparator();
900 toolBar
->AddCheckTool(ID_FORMAT_ALIGN_LEFT
, wxEmptyString
, wxBitmap(alignleft_xpm
), wxNullBitmap
, _("Align Left"));
901 toolBar
->AddCheckTool(ID_FORMAT_ALIGN_CENTRE
, wxEmptyString
, wxBitmap(centre_xpm
), wxNullBitmap
, _("Centre"));
902 toolBar
->AddCheckTool(ID_FORMAT_ALIGN_RIGHT
, wxEmptyString
, wxBitmap(alignright_xpm
), wxNullBitmap
, _("Align Right"));
903 toolBar
->AddSeparator();
904 toolBar
->AddTool(ID_FORMAT_INDENT_LESS
, wxEmptyString
, wxBitmap(indentless_xpm
), _("Indent Less"));
905 toolBar
->AddTool(ID_FORMAT_INDENT_MORE
, wxEmptyString
, wxBitmap(indentmore_xpm
), _("Indent More"));
906 toolBar
->AddSeparator();
907 toolBar
->AddTool(ID_FORMAT_FONT
, wxEmptyString
, wxBitmap(font_xpm
), _("Font"));
908 toolBar
->AddSeparator();
910 wxRichTextStyleComboCtrl
* combo
= new wxRichTextStyleComboCtrl(toolBar
, ID_RICHTEXT_STYLE_COMBO
, wxDefaultPosition
, wxSize(160, -1), wxCB_READONLY
);
911 toolBar
->AddControl(combo
);
915 wxSplitterWindow
* splitter
= new wxSplitterWindow(this, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
, wxSP_LIVE_UPDATE
);
916 sizer
->Add(splitter
, 1, wxEXPAND
);
918 wxFont textFont
= wxFont(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
919 wxFont boldFont
= wxFont(12, wxROMAN
, wxNORMAL
, wxBOLD
);
920 wxFont italicFont
= wxFont(12, wxROMAN
, wxITALIC
, wxNORMAL
);
922 m_richTextCtrl
= new MyRichTextCtrl(splitter
, ID_RICHTEXT_CTRL
, wxEmptyString
, wxDefaultPosition
, wxDefaultSize
, wxVSCROLL
|wxHSCROLL
|wxWANTS_CHARS
);
923 wxASSERT(!m_richTextCtrl
->GetBuffer().GetAttributes().HasFontPixelSize());
925 wxFont
font(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
927 m_richTextCtrl
->SetFont(font
);
929 wxASSERT(!m_richTextCtrl
->GetBuffer().GetAttributes().HasFontPixelSize());
931 m_richTextCtrl
->SetMargins(10, 10);
933 m_richTextCtrl
->SetStyleSheet(wxGetApp().GetStyleSheet());
935 combo
->SetStyleSheet(wxGetApp().GetStyleSheet());
936 combo
->SetRichTextCtrl(m_richTextCtrl
);
937 combo
->UpdateStyles();
939 wxRichTextStyleListCtrl
* styleListCtrl
= new wxRichTextStyleListCtrl(splitter
, ID_RICHTEXT_STYLE_LIST
);
941 wxSize display
= wxGetDisplaySize();
942 if ( is_pda
&& ( display
.GetWidth() < display
.GetHeight() ) )
944 splitter
->SplitHorizontally(m_richTextCtrl
, styleListCtrl
);
948 int width
= GetClientSize().GetWidth() * 0.8;
949 splitter
->SplitVertically(m_richTextCtrl
, styleListCtrl
, width
);
950 splitter
->SetSashGravity(0.8);
955 splitter
->UpdateSize();
957 styleListCtrl
->SetStyleSheet(wxGetApp().GetStyleSheet());
958 styleListCtrl
->SetRichTextCtrl(m_richTextCtrl
);
959 styleListCtrl
->UpdateStyles();
965 void MyFrame::WriteInitialText()
967 MyRichTextCtrl
& r
= *m_richTextCtrl
;
969 r
.SetDefaultStyle(wxRichTextAttr());
973 r
.BeginSuppressUndo();
975 r
.BeginParagraphSpacing(0, 20);
977 r
.BeginAlignment(wxTEXT_ALIGNMENT_CENTRE
);
982 wxString lineBreak
= (wxChar
) 29;
984 r
.WriteText(wxString(wxT("Welcome to wxRichTextCtrl, a wxWidgets control")) + lineBreak
+ wxT("for editing and presenting styled text and images\n"));
988 r
.WriteText(wxT("by Julian Smart"));
994 r
.WriteImage(wxBitmap(zebra_xpm
));
1002 r
.BeginAlignment(wxTEXT_ALIGNMENT_CENTRE
);
1003 r
.WriteText(wxString(wxT("This is a simple test for a floating left image test. The zebra image should be placed at the left side of the current buffer and all the text should flow around it at the right side. This is a simple test for a floating left image test. The zebra image should be placed at the left side of the current buffer and all the text should flow around it at the right side. This is a simple test for a floating left image test. The zebra image should be placed at the left side of the current buffer and all the text should flow around it at the right side.")));
1008 r
.BeginAlignment(wxTEXT_ALIGNMENT_LEFT
);
1009 wxRichTextAttr imageAttr
;
1010 imageAttr
.GetTextBoxAttr().SetFloatMode(wxTEXT_BOX_ATTR_FLOAT_LEFT
);
1011 r
.WriteText(wxString(wxT("This is a simple test for a floating left image test. The zebra image should be placed at the left side of the current buffer and all the text should flow around it at the right side. This is a simple test for a floating left image test. The zebra image should be placed at the left side of the current buffer and all the text should flow around it at the right side. This is a simple test for a floating left image test. The zebra image should be placed at the left side of the current buffer and all the text should flow around it at the right side.")));
1012 r
.WriteImage(wxBitmap(zebra_xpm
), wxBITMAP_TYPE_PNG
, imageAttr
);
1014 imageAttr
.GetTextBoxAttr().GetTop().SetValue(200);
1015 imageAttr
.GetTextBoxAttr().GetTop().SetUnits(wxTEXT_ATTR_UNITS_PIXELS
);
1016 imageAttr
.GetTextBoxAttr().SetFloatMode(wxTEXT_BOX_ATTR_FLOAT_RIGHT
);
1017 r
.WriteImage(wxBitmap(zebra_xpm
), wxBITMAP_TYPE_PNG
, imageAttr
);
1018 r
.WriteText(wxString(wxT("This is a simple test for a floating right image test. The zebra image should be placed at the right side of the current buffer and all the text should flow around it at the left side. This is a simple test for a floating left image test. The zebra image should be placed at the right side of the current buffer and all the text should flow around it at the left side. This is a simple test for a floating left image test. The zebra image should be placed at the right side of the current buffer and all the text should flow around it at the left side.")));
1022 r
.WriteText(wxT("What can you do with this thing? "));
1024 r
.WriteImage(wxBitmap(smiley_xpm
));
1025 r
.WriteText(wxT(" Well, you can change text "));
1027 r
.BeginTextColour(*wxRED
);
1028 r
.WriteText(wxT("colour, like this red bit."));
1031 wxRichTextAttr backgroundColourAttr
;
1032 backgroundColourAttr
.SetBackgroundColour(*wxGREEN
);
1033 backgroundColourAttr
.SetTextColour(*wxBLUE
);
1034 r
.BeginStyle(backgroundColourAttr
);
1035 r
.WriteText(wxT(" And this blue on green bit."));
1038 r
.WriteText(wxT(" Naturally you can make things "));
1040 r
.WriteText(wxT("bold "));
1043 r
.WriteText(wxT("or italic "));
1046 r
.WriteText(wxT("or underlined."));
1049 r
.BeginFontSize(14);
1050 r
.WriteText(wxT(" Different font sizes on the same line is allowed, too."));
1053 r
.WriteText(wxT(" Next we'll show an indented paragraph."));
1057 r
.BeginLeftIndent(60);
1058 r
.WriteText(wxT("It was in January, the most down-trodden month of an Edinburgh winter. An attractive woman came into the cafe, which is nothing remarkable."));
1063 r
.WriteText(wxT("Next, we'll show a first-line indent, achieved using BeginLeftIndent(100, -40)."));
1067 r
.BeginLeftIndent(100, -40);
1069 r
.WriteText(wxT("It was in January, the most down-trodden month of an Edinburgh winter. An attractive woman came into the cafe, which is nothing remarkable."));
1074 r
.WriteText(wxT("Numbered bullets are possible, again using subindents:"));
1077 r
.BeginNumberedBullet(1, 100, 60);
1078 r
.WriteText(wxT("This is my first item. Note that wxRichTextCtrl can apply numbering and bullets automatically based on list styles, but this list is formatted explicitly by setting indents."));
1080 r
.EndNumberedBullet();
1082 r
.BeginNumberedBullet(2, 100, 60);
1083 r
.WriteText(wxT("This is my second item."));
1085 r
.EndNumberedBullet();
1087 r
.WriteText(wxT("The following paragraph is right-indented:"));
1090 r
.BeginRightIndent(200);
1092 r
.WriteText(wxT("It was in January, the most down-trodden month of an Edinburgh winter. An attractive woman came into the cafe, which is nothing remarkable."));
1097 r
.WriteText(wxT("The following paragraph is right-aligned with 1.5 line spacing:"));
1100 r
.BeginAlignment(wxTEXT_ALIGNMENT_RIGHT
);
1101 r
.BeginLineSpacing(wxTEXT_ATTR_LINE_SPACING_HALF
);
1102 r
.WriteText(wxT("It was in January, the most down-trodden month of an Edinburgh winter. An attractive woman came into the cafe, which is nothing remarkable."));
1112 wxRichTextAttr attr
;
1113 attr
.SetFlags(wxTEXT_ATTR_TABS
);
1115 r
.SetDefaultStyle(attr
);
1117 r
.WriteText(wxT("This line contains tabs:\tFirst tab\tSecond tab\tThird tab"));
1120 r
.WriteText(wxT("Other notable features of wxRichTextCtrl include:"));
1123 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1124 r
.WriteText(wxT("Compatibility with wxTextCtrl API"));
1126 r
.EndSymbolBullet();
1128 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1129 r
.WriteText(wxT("Easy stack-based BeginXXX()...EndXXX() style setting in addition to SetStyle()"));
1131 r
.EndSymbolBullet();
1133 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1134 r
.WriteText(wxT("XML loading and saving"));
1136 r
.EndSymbolBullet();
1138 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1139 r
.WriteText(wxT("Undo/Redo, with batching option and Undo suppressing"));
1141 r
.EndSymbolBullet();
1143 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1144 r
.WriteText(wxT("Clipboard copy and paste"));
1146 r
.EndSymbolBullet();
1148 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1149 r
.WriteText(wxT("wxRichTextStyleSheet with named character and paragraph styles, and control for applying named styles"));
1151 r
.EndSymbolBullet();
1153 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1154 r
.WriteText(wxT("A design that can easily be extended to other content types, ultimately with text boxes, tables, controls, and so on"));
1156 r
.EndSymbolBullet();
1158 // Make a style suitable for showing a URL
1159 wxRichTextAttr urlStyle
;
1160 urlStyle
.SetTextColour(*wxBLUE
);
1161 urlStyle
.SetFontUnderlined(true);
1163 r
.WriteText(wxT("wxRichTextCtrl can also display URLs, such as this one: "));
1164 r
.BeginStyle(urlStyle
);
1165 r
.BeginURL(wxT("http://www.wxwidgets.org"));
1166 r
.WriteText(wxT("The wxWidgets Web Site"));
1169 r
.WriteText(wxT(". Click on the URL to generate an event."));
1173 r
.WriteText(wxT("Note: this sample content was generated programmatically from within the MyFrame constructor in the demo. The images were loaded from inline XPMs. Enjoy wxRichTextCtrl!\n"));
1175 r
.EndParagraphSpacing();
1183 wxRichTextAttr attr
;
1184 attr
.GetTextBoxAttr().GetMargins().GetLeft().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS
);
1185 attr
.GetTextBoxAttr().GetMargins().GetTop().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS
);
1186 attr
.GetTextBoxAttr().GetMargins().GetRight().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS
);
1187 attr
.GetTextBoxAttr().GetMargins().GetBottom().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS
);
1189 attr
.GetTextBoxAttr().GetBorder().SetColour(*wxBLACK
);
1190 attr
.GetTextBoxAttr().GetBorder().SetWidth(1, wxTEXT_ATTR_UNITS_PIXELS
);
1191 attr
.GetTextBoxAttr().GetBorder().SetStyle(wxTEXT_BOX_ATTR_BORDER_SOLID
);
1193 wxRichTextBox
* textBox
= r
.WriteTextBox(attr
);
1194 r
.SetFocusObject(textBox
);
1196 r
.WriteText(wxT("This is a text box. Just testing! Once more unto the breach, dear friends, once more..."));
1198 r
.SetFocusObject(NULL
); // Set the focus back to the main buffer
1199 r
.SetInsertionPointEnd();
1209 wxRichTextAttr attr
;
1210 attr
.GetTextBoxAttr().GetMargins().GetLeft().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS
);
1211 attr
.GetTextBoxAttr().GetMargins().GetTop().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS
);
1212 attr
.GetTextBoxAttr().GetMargins().GetRight().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS
);
1213 attr
.GetTextBoxAttr().GetMargins().GetBottom().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS
);
1214 attr
.GetTextBoxAttr().GetPadding() = attr
.GetTextBoxAttr().GetMargins();
1216 attr
.GetTextBoxAttr().GetBorder().SetColour(*wxBLACK
);
1217 attr
.GetTextBoxAttr().GetBorder().SetWidth(1, wxTEXT_ATTR_UNITS_PIXELS
);
1218 attr
.GetTextBoxAttr().GetBorder().SetStyle(wxTEXT_BOX_ATTR_BORDER_SOLID
);
1220 wxRichTextAttr cellAttr
= attr
;
1221 cellAttr
.GetTextBoxAttr().GetWidth().SetValue(200, wxTEXT_ATTR_UNITS_PIXELS
);
1222 cellAttr
.GetTextBoxAttr().GetHeight().SetValue(150, wxTEXT_ATTR_UNITS_PIXELS
);
1224 wxRichTextTable
* table
= r
.WriteTable(6, 4, attr
, cellAttr
);
1227 for (j
= 0; j
< table
->GetRowCount(); j
++)
1229 for (i
= 0; i
< table
->GetColumnCount(); i
++)
1231 wxString msg
= wxString::Format(wxT("This is cell %d, %d"), (j
+1), (i
+1));
1232 r
.SetFocusObject(table
->GetCell(j
, i
));
1237 // Demonstrate colspan and rowspan
1238 wxRichTextCell
* cell
= table
->GetCell(1, 0);
1239 cell
->SetColspan(2);
1240 r
.SetFocusObject(cell
);
1242 r
.WriteText("This cell spans 2 columns");
1244 cell
= table
->GetCell(1, 3);
1245 cell
->SetRowspan(2);
1246 r
.SetFocusObject(cell
);
1248 r
.WriteText("This cell spans 2 rows");
1250 cell
= table
->GetCell(2, 1);
1251 cell
->SetColspan(2);
1252 cell
->SetRowspan(3);
1253 r
.SetFocusObject(cell
);
1255 r
.WriteText("This cell spans 2 columns and 3 rows");
1257 r
.SetFocusObject(NULL
); // Set the focus back to the main buffer
1258 r
.SetInsertionPointEnd();
1262 r
.Newline(); r
.Newline();
1264 wxRichTextProperties properties
;
1265 r
.WriteText(wxT("This is a rectangle field: "));
1266 r
.WriteField(wxT("rectangle"), properties
);
1267 r
.WriteText(wxT(" and a begin section field: "));
1268 r
.WriteField(wxT("begin-section"), properties
);
1269 r
.WriteText(wxT("This is text between the two tags."));
1270 r
.WriteField(wxT("end-section"), properties
);
1271 r
.WriteText(wxT(" Now a bitmap. "));
1272 r
.WriteField(wxT("bitmap"), properties
);
1273 r
.WriteText(wxT(" Before we go, here's a composite field: ***"));
1274 wxRichTextField
* field
= r
.WriteField(wxT("composite"), properties
);
1275 field
->UpdateField(& r
.GetBuffer()); // Creates the composite value (sort of a text box)
1276 r
.WriteText(wxT("*** End of composite field."));
1279 r
.EndSuppressUndo();
1281 // Add some locked content first - needs Undo to be enabled
1284 r
.WriteText(wxString(wxT("This is a locked object.")));
1287 r
.WriteText(wxString(wxT(" This is unlocked text. ")));
1290 r
.WriteText(wxString(wxT("More locked content.")));
1294 // Flush the Undo buffer
1295 r
.GetCommandProcessor()->ClearCommands();
1303 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
1305 // true is to force the frame to close
1309 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
1312 msg
.Printf( wxT("This is a demo for wxRichTextCtrl, a control for editing styled text.\n(c) Julian Smart, 2005"));
1313 wxMessageBox(msg
, wxT("About wxRichTextCtrl Sample"), wxOK
| wxICON_INFORMATION
, this);
1316 // Forward command events to the current rich text control, if any
1317 bool MyFrame::ProcessEvent(wxEvent
& event
)
1319 if (event
.IsCommandEvent() && !event
.IsKindOf(CLASSINFO(wxChildFocusEvent
)))
1321 // Problem: we can get infinite recursion because the events
1322 // climb back up to this frame, and repeat.
1323 // Assume that command events don't cause another command event
1324 // to be called, so we can rely on inCommand not being overwritten
1326 static int s_eventType
= 0;
1327 static wxWindowID s_id
= 0;
1329 if (s_id
!= event
.GetId() && s_eventType
!= event
.GetEventType())
1331 s_eventType
= event
.GetEventType();
1332 s_id
= event
.GetId();
1334 wxWindow
* focusWin
= wxFindFocusDescendant(this);
1335 if (focusWin
&& focusWin
->GetEventHandler()->ProcessEvent(event
))
1352 return wxFrame::ProcessEvent(event
);
1355 void MyFrame::OnOpen(wxCommandEvent
& WXUNUSED(event
))
1359 wxArrayInt fileTypes
;
1361 wxString filter
= wxRichTextBuffer::GetExtWildcard(false, false, & fileTypes
);
1362 if (!filter
.empty())
1364 filter
+= wxT("All files (*.*)|*.*");
1366 wxFileDialog
dialog(this,
1367 _("Choose a filename"),
1373 if (dialog
.ShowModal() == wxID_OK
)
1375 wxString path
= dialog
.GetPath();
1379 int filterIndex
= dialog
.GetFilterIndex();
1380 int fileType
= (filterIndex
< (int) fileTypes
.GetCount())
1381 ? fileTypes
[filterIndex
]
1382 : wxRICHTEXT_TYPE_TEXT
;
1383 m_richTextCtrl
->LoadFile(path
, fileType
);
1388 void MyFrame::OnSave(wxCommandEvent
& event
)
1390 if (m_richTextCtrl
->GetFilename().empty())
1395 m_richTextCtrl
->SaveFile();
1398 void MyFrame::OnSaveAs(wxCommandEvent
& WXUNUSED(event
))
1400 wxString filter
= wxRichTextBuffer::GetExtWildcard(false, true);
1404 wxFileDialog
dialog(this,
1405 _("Choose a filename"),
1411 if (dialog
.ShowModal() == wxID_OK
)
1413 wxString path
= dialog
.GetPath();
1418 wxStopWatch stopwatch
;
1420 m_richTextCtrl
->SaveFile(path
);
1422 long t
= stopwatch
.Time();
1423 wxLogDebug(wxT("Saving took %ldms"), t
);
1424 wxMessageBox(wxString::Format(wxT("Saving took %ldms"), t
));
1429 void MyFrame::OnBold(wxCommandEvent
& WXUNUSED(event
))
1431 m_richTextCtrl
->ApplyBoldToSelection();
1434 void MyFrame::OnItalic(wxCommandEvent
& WXUNUSED(event
))
1436 m_richTextCtrl
->ApplyItalicToSelection();
1439 void MyFrame::OnUnderline(wxCommandEvent
& WXUNUSED(event
))
1441 m_richTextCtrl
->ApplyUnderlineToSelection();
1444 void MyFrame::OnStrikethrough(wxCommandEvent
& WXUNUSED(event
))
1446 m_richTextCtrl
->ApplyTextEffectToSelection(wxTEXT_ATTR_EFFECT_STRIKETHROUGH
);
1449 void MyFrame::OnSuperscript(wxCommandEvent
& WXUNUSED(event
))
1451 m_richTextCtrl
->ApplyTextEffectToSelection(wxTEXT_ATTR_EFFECT_SUPERSCRIPT
);
1454 void MyFrame::OnSubscript(wxCommandEvent
& WXUNUSED(event
))
1456 m_richTextCtrl
->ApplyTextEffectToSelection(wxTEXT_ATTR_EFFECT_SUBSCRIPT
);
1460 void MyFrame::OnUpdateBold(wxUpdateUIEvent
& event
)
1462 event
.Check(m_richTextCtrl
->IsSelectionBold());
1465 void MyFrame::OnUpdateItalic(wxUpdateUIEvent
& event
)
1467 event
.Check(m_richTextCtrl
->IsSelectionItalics());
1470 void MyFrame::OnUpdateUnderline(wxUpdateUIEvent
& event
)
1472 event
.Check(m_richTextCtrl
->IsSelectionUnderlined());
1475 void MyFrame::OnUpdateStrikethrough(wxUpdateUIEvent
& event
)
1477 event
.Check(m_richTextCtrl
->DoesSelectionHaveTextEffectFlag(wxTEXT_ATTR_EFFECT_STRIKETHROUGH
));
1480 void MyFrame::OnUpdateSuperscript(wxUpdateUIEvent
& event
)
1482 event
.Check(m_richTextCtrl
->DoesSelectionHaveTextEffectFlag(wxTEXT_ATTR_EFFECT_SUPERSCRIPT
));
1485 void MyFrame::OnUpdateSubscript(wxUpdateUIEvent
& event
)
1487 event
.Check(m_richTextCtrl
->DoesSelectionHaveTextEffectFlag(wxTEXT_ATTR_EFFECT_SUBSCRIPT
));
1490 void MyFrame::OnAlignLeft(wxCommandEvent
& WXUNUSED(event
))
1492 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_LEFT
);
1495 void MyFrame::OnAlignCentre(wxCommandEvent
& WXUNUSED(event
))
1497 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_CENTRE
);
1500 void MyFrame::OnAlignRight(wxCommandEvent
& WXUNUSED(event
))
1502 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_RIGHT
);
1505 void MyFrame::OnUpdateAlignLeft(wxUpdateUIEvent
& event
)
1507 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_LEFT
));
1510 void MyFrame::OnUpdateAlignCentre(wxUpdateUIEvent
& event
)
1512 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_CENTRE
));
1515 void MyFrame::OnUpdateAlignRight(wxUpdateUIEvent
& event
)
1517 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_RIGHT
));
1520 void MyFrame::OnFont(wxCommandEvent
& WXUNUSED(event
))
1522 wxRichTextRange range
;
1523 if (m_richTextCtrl
->HasSelection())
1524 range
= m_richTextCtrl
->GetSelectionRange();
1526 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1528 int pages
= wxRICHTEXT_FORMAT_FONT
;
1530 wxRichTextFormattingDialog
formatDlg(pages
, this);
1531 formatDlg
.SetOptions(wxRichTextFormattingDialog::Option_AllowPixelFontSize
);
1532 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1534 if (formatDlg
.ShowModal() == wxID_OK
)
1536 formatDlg
.ApplyStyle(m_richTextCtrl
, range
, wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_OPTIMIZE
|wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY
);
1540 void MyFrame::OnImage(wxCommandEvent
& WXUNUSED(event
))
1542 wxRichTextRange range
;
1543 wxASSERT(m_richTextCtrl
->HasSelection());
1545 range
= m_richTextCtrl
->GetSelectionRange();
1546 wxASSERT(range
.ToInternal().GetLength() == 1);
1548 wxRichTextImage
* image
= wxDynamicCast(m_richTextCtrl
->GetFocusObject()->GetLeafObjectAtPosition(range
.GetStart()), wxRichTextImage
);
1551 wxRichTextObjectPropertiesDialog
imageDlg(image
, this);
1553 if (imageDlg
.ShowModal() == wxID_OK
)
1555 imageDlg
.ApplyStyle(m_richTextCtrl
);
1560 void MyFrame::OnParagraph(wxCommandEvent
& WXUNUSED(event
))
1562 wxRichTextRange range
;
1563 if (m_richTextCtrl
->HasSelection())
1564 range
= m_richTextCtrl
->GetSelectionRange();
1566 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1568 int pages
= wxRICHTEXT_FORMAT_INDENTS_SPACING
|wxRICHTEXT_FORMAT_TABS
|wxRICHTEXT_FORMAT_BULLETS
;
1570 wxRichTextFormattingDialog
formatDlg(pages
, this);
1571 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1573 if (formatDlg
.ShowModal() == wxID_OK
)
1575 formatDlg
.ApplyStyle(m_richTextCtrl
, range
);
1579 void MyFrame::OnFormat(wxCommandEvent
& WXUNUSED(event
))
1581 wxRichTextRange range
;
1582 if (m_richTextCtrl
->HasSelection())
1583 range
= m_richTextCtrl
->GetSelectionRange();
1585 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1587 int pages
= wxRICHTEXT_FORMAT_FONT
|wxRICHTEXT_FORMAT_INDENTS_SPACING
|wxRICHTEXT_FORMAT_TABS
|wxRICHTEXT_FORMAT_BULLETS
;
1589 wxRichTextFormattingDialog
formatDlg(pages
, this);
1590 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1592 if (formatDlg
.ShowModal() == wxID_OK
)
1594 formatDlg
.ApplyStyle(m_richTextCtrl
, range
);
1598 void MyFrame::OnUpdateFormat(wxUpdateUIEvent
& event
)
1600 event
.Enable(m_richTextCtrl
->HasSelection());
1603 void MyFrame::OnUpdateImage(wxUpdateUIEvent
& event
)
1605 wxRichTextRange range
;
1606 wxRichTextObject
*obj
;
1608 range
= m_richTextCtrl
->GetSelectionRange();
1609 if (range
.ToInternal().GetLength() == 1)
1611 obj
= m_richTextCtrl
->GetFocusObject()->GetLeafObjectAtPosition(range
.GetStart());
1612 if (obj
&& obj
->IsKindOf(CLASSINFO(wxRichTextImage
)))
1619 event
.Enable(false);
1622 void MyFrame::OnIndentMore(wxCommandEvent
& WXUNUSED(event
))
1624 wxRichTextAttr attr
;
1625 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1627 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1629 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1630 if (m_richTextCtrl
->HasSelection())
1631 range
= m_richTextCtrl
->GetSelectionRange();
1633 attr
.SetLeftIndent(attr
.GetLeftIndent() + 100);
1635 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1636 m_richTextCtrl
->SetStyle(range
, attr
);
1640 void MyFrame::OnIndentLess(wxCommandEvent
& WXUNUSED(event
))
1642 wxRichTextAttr attr
;
1643 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1645 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1647 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1648 if (m_richTextCtrl
->HasSelection())
1649 range
= m_richTextCtrl
->GetSelectionRange();
1651 if (attr
.GetLeftIndent() > 0)
1653 attr
.SetLeftIndent(wxMax(0, attr
.GetLeftIndent() - 100));
1655 m_richTextCtrl
->SetStyle(range
, attr
);
1660 void MyFrame::OnLineSpacingHalf(wxCommandEvent
& WXUNUSED(event
))
1662 wxRichTextAttr attr
;
1663 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1665 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1667 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1668 if (m_richTextCtrl
->HasSelection())
1669 range
= m_richTextCtrl
->GetSelectionRange();
1671 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1672 attr
.SetLineSpacing(15);
1674 m_richTextCtrl
->SetStyle(range
, attr
);
1678 void MyFrame::OnLineSpacingDouble(wxCommandEvent
& WXUNUSED(event
))
1680 wxRichTextAttr attr
;
1681 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1683 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1685 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1686 if (m_richTextCtrl
->HasSelection())
1687 range
= m_richTextCtrl
->GetSelectionRange();
1689 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1690 attr
.SetLineSpacing(20);
1692 m_richTextCtrl
->SetStyle(range
, attr
);
1696 void MyFrame::OnLineSpacingSingle(wxCommandEvent
& WXUNUSED(event
))
1698 wxRichTextAttr attr
;
1699 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1701 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1703 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1704 if (m_richTextCtrl
->HasSelection())
1705 range
= m_richTextCtrl
->GetSelectionRange();
1707 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1708 attr
.SetLineSpacing(0); // Can also use 10
1710 m_richTextCtrl
->SetStyle(range
, attr
);
1714 void MyFrame::OnParagraphSpacingMore(wxCommandEvent
& WXUNUSED(event
))
1716 wxRichTextAttr attr
;
1717 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1719 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1721 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1722 if (m_richTextCtrl
->HasSelection())
1723 range
= m_richTextCtrl
->GetSelectionRange();
1725 attr
.SetParagraphSpacingAfter(attr
.GetParagraphSpacingAfter() + 20);
1727 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1728 m_richTextCtrl
->SetStyle(range
, attr
);
1732 void MyFrame::OnParagraphSpacingLess(wxCommandEvent
& WXUNUSED(event
))
1734 wxRichTextAttr attr
;
1735 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1737 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1739 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1740 if (m_richTextCtrl
->HasSelection())
1741 range
= m_richTextCtrl
->GetSelectionRange();
1743 if (attr
.GetParagraphSpacingAfter() >= 20)
1745 attr
.SetParagraphSpacingAfter(attr
.GetParagraphSpacingAfter() - 20);
1747 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1748 m_richTextCtrl
->SetStyle(range
, attr
);
1753 void MyFrame::OnReload(wxCommandEvent
& WXUNUSED(event
))
1755 m_richTextCtrl
->Clear();
1759 void MyFrame::OnViewHTML(wxCommandEvent
& WXUNUSED(event
))
1761 wxDialog
dialog(this, wxID_ANY
, _("HTML"), wxDefaultPosition
, wxSize(500, 400), wxDEFAULT_DIALOG_STYLE
);
1763 wxBoxSizer
* boxSizer
= new wxBoxSizer(wxVERTICAL
);
1764 dialog
.SetSizer(boxSizer
);
1766 wxHtmlWindow
* win
= new wxHtmlWindow(& dialog
, wxID_ANY
, wxDefaultPosition
, wxSize(500, 400), wxSUNKEN_BORDER
);
1767 boxSizer
->Add(win
, 1, wxALL
, 5);
1769 wxButton
* cancelButton
= new wxButton(& dialog
, wxID_CANCEL
, wxT("&Close"));
1770 boxSizer
->Add(cancelButton
, 0, wxALL
|wxCENTRE
, 5);
1773 wxStringOutputStream
strStream(& text
);
1775 wxRichTextHTMLHandler htmlHandler
;
1776 htmlHandler
.SetFlags(wxRICHTEXT_HANDLER_SAVE_IMAGES_TO_MEMORY
);
1778 wxArrayInt fontSizeMapping
;
1779 fontSizeMapping
.Add(7);
1780 fontSizeMapping
.Add(9);
1781 fontSizeMapping
.Add(11);
1782 fontSizeMapping
.Add(12);
1783 fontSizeMapping
.Add(14);
1784 fontSizeMapping
.Add(22);
1785 fontSizeMapping
.Add(100);
1787 htmlHandler
.SetFontSizeMapping(fontSizeMapping
);
1789 if (htmlHandler
.SaveFile(& m_richTextCtrl
->GetBuffer(), strStream
))
1794 boxSizer
->Fit(& dialog
);
1798 // Now delete the temporary in-memory images
1799 htmlHandler
.DeleteTemporaryImages();
1802 // Demonstrates how you can change the style sheets and have the changes
1803 // reflected in the control content without wiping out character formatting.
1805 void MyFrame::OnSwitchStyleSheets(wxCommandEvent
& WXUNUSED(event
))
1807 static wxRichTextStyleSheet
* gs_AlternateStyleSheet
= NULL
;
1809 wxRichTextStyleListCtrl
*styleList
= (wxRichTextStyleListCtrl
*) FindWindow(ID_RICHTEXT_STYLE_LIST
);
1810 wxRichTextStyleComboCtrl
* styleCombo
= (wxRichTextStyleComboCtrl
*) FindWindow(ID_RICHTEXT_STYLE_COMBO
);
1812 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1814 // One-time creation of an alternate style sheet
1815 if (!gs_AlternateStyleSheet
)
1817 gs_AlternateStyleSheet
= new wxRichTextStyleSheet(*sheet
);
1819 // Make some modifications
1820 for (int i
= 0; i
< (int) gs_AlternateStyleSheet
->GetParagraphStyleCount(); i
++)
1822 wxRichTextParagraphStyleDefinition
* def
= gs_AlternateStyleSheet
->GetParagraphStyle(i
);
1824 if (def
->GetStyle().HasTextColour())
1825 def
->GetStyle().SetTextColour(*wxBLUE
);
1827 if (def
->GetStyle().HasAlignment())
1829 if (def
->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_CENTRE
)
1830 def
->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_RIGHT
);
1831 else if (def
->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_LEFT
)
1832 def
->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_CENTRE
);
1834 if (def
->GetStyle().HasLeftIndent())
1836 def
->GetStyle().SetLeftIndent(def
->GetStyle().GetLeftIndent() * 2);
1842 wxRichTextStyleSheet
* tmp
= gs_AlternateStyleSheet
;
1843 gs_AlternateStyleSheet
= sheet
;
1846 m_richTextCtrl
->SetStyleSheet(sheet
);
1847 m_richTextCtrl
->ApplyStyleSheet(sheet
); // Makes the control reflect the new style definitions
1849 styleList
->SetStyleSheet(sheet
);
1850 styleList
->UpdateStyles();
1852 styleCombo
->SetStyleSheet(sheet
);
1853 styleCombo
->UpdateStyles();
1856 void MyFrame::OnManageStyles(wxCommandEvent
& WXUNUSED(event
))
1858 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1860 int flags
= wxRICHTEXT_ORGANISER_CREATE_STYLES
|wxRICHTEXT_ORGANISER_EDIT_STYLES
;
1862 wxRichTextStyleOrganiserDialog
dlg(flags
, sheet
, NULL
, this, wxID_ANY
, _("Style Manager"));
1866 void MyFrame::OnInsertSymbol(wxCommandEvent
& WXUNUSED(event
))
1868 wxRichTextAttr attr
;
1869 attr
.SetFlags(wxTEXT_ATTR_FONT
);
1870 m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
);
1872 wxString currentFontName
;
1873 if (attr
.HasFont() && attr
.GetFont().IsOk())
1874 currentFontName
= attr
.GetFont().GetFaceName();
1876 // Don't set the initial font in the dialog (so the user is choosing
1877 // 'normal text', i.e. the current font) but do tell the dialog
1878 // what 'normal text' is.
1880 wxSymbolPickerDialog
dlg(wxT("*"), wxEmptyString
, currentFontName
, this);
1882 if (dlg
.ShowModal() == wxID_OK
)
1884 if (dlg
.HasSelection())
1886 long insertionPoint
= m_richTextCtrl
->GetInsertionPoint();
1888 m_richTextCtrl
->WriteText(dlg
.GetSymbol());
1890 if (!dlg
.UseNormalFont())
1892 wxFont
font(attr
.GetFont());
1893 font
.SetFaceName(dlg
.GetFontName());
1895 m_richTextCtrl
->SetStyle(insertionPoint
, insertionPoint
+1, attr
);
1901 void MyFrame::OnNumberList(wxCommandEvent
& WXUNUSED(event
))
1903 if (m_richTextCtrl
->HasSelection())
1905 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1906 m_richTextCtrl
->SetListStyle(range
, wxT("Numbered List 1"), wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_RENUMBER
);
1910 void MyFrame::OnBulletsAndNumbering(wxCommandEvent
& WXUNUSED(event
))
1912 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1914 int flags
= wxRICHTEXT_ORGANISER_BROWSE_NUMBERING
;
1916 wxRichTextStyleOrganiserDialog
dlg(flags
, sheet
, m_richTextCtrl
, this, wxID_ANY
, _("Bullets and Numbering"));
1917 if (dlg
.ShowModal() == wxID_OK
)
1919 if (dlg
.GetSelectedStyleDefinition())
1924 void MyFrame::OnItemizeList(wxCommandEvent
& WXUNUSED(event
))
1926 if (m_richTextCtrl
->HasSelection())
1928 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1929 m_richTextCtrl
->SetListStyle(range
, wxT("Bullet List 1"));
1933 void MyFrame::OnRenumberList(wxCommandEvent
& WXUNUSED(event
))
1935 if (m_richTextCtrl
->HasSelection())
1937 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1938 m_richTextCtrl
->NumberList(range
, NULL
, wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_RENUMBER
);
1942 void MyFrame::OnPromoteList(wxCommandEvent
& WXUNUSED(event
))
1944 if (m_richTextCtrl
->HasSelection())
1946 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1947 m_richTextCtrl
->PromoteList(1, range
, NULL
);
1951 void MyFrame::OnDemoteList(wxCommandEvent
& WXUNUSED(event
))
1953 if (m_richTextCtrl
->HasSelection())
1955 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1956 m_richTextCtrl
->PromoteList(-1, range
, NULL
);
1960 void MyFrame::OnClearList(wxCommandEvent
& WXUNUSED(event
))
1962 if (m_richTextCtrl
->HasSelection())
1964 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1965 m_richTextCtrl
->ClearListStyle(range
);
1969 void MyFrame::OnTableAddColumn(wxCommandEvent
& WXUNUSED(event
))
1971 wxRichTextTable
* table
= wxDynamicCast(m_richTextCtrl
->FindTable(), wxRichTextTable
);
1974 wxRichTextAttr cellAttr
= table
->GetCell(0, 0)->GetAttributes();
1975 table
->AddColumns(table
->GetColumnCount(), 1, cellAttr
);
1979 void MyFrame::OnTableAddRow(wxCommandEvent
& WXUNUSED(event
))
1981 wxRichTextTable
* table
= wxDynamicCast(m_richTextCtrl
->FindTable(), wxRichTextTable
);
1984 wxRichTextAttr cellAttr
= table
->GetCell(0, 0)->GetAttributes();
1985 table
->AddRows(table
->GetRowCount(), 1, cellAttr
);
1989 void MyFrame::OnTableDeleteColumn(wxCommandEvent
& WXUNUSED(event
))
1991 wxRichTextTable
* table
= wxDynamicCast(m_richTextCtrl
->FindTable(), wxRichTextTable
);
1994 int col
= table
->GetFocusedCell().GetCol();
1997 col
= table
->GetColumnCount() - 1;
2000 table
->DeleteColumns(col
, 1);
2004 void MyFrame::OnTableDeleteRow(wxCommandEvent
& WXUNUSED(event
))
2006 wxRichTextTable
* table
= wxDynamicCast(m_richTextCtrl
->FindTable(), wxRichTextTable
);
2009 int row
= table
->GetFocusedCell().GetRow();
2012 row
= table
->GetRowCount() - 1;
2015 table
->DeleteRows(row
, 1);
2019 void MyFrame::OnTableFocusedUpdateUI(wxUpdateUIEvent
& event
)
2021 event
.Enable(m_richTextCtrl
->FindTable() != NULL
);
2024 void MyFrame::OnTableHasCellsUpdateUI(wxUpdateUIEvent
& event
)
2027 wxRichTextTable
* table
= wxDynamicCast(m_richTextCtrl
->FindTable(), wxRichTextTable
);
2030 if (event
.GetId() == ID_TABLE_DELETE_COLUMN
)
2032 enable
= table
->GetColumnCount() > 1;
2036 enable
= table
->GetRowCount() > 1;
2040 event
.Enable(enable
);
2043 void MyFrame::OnInsertURL(wxCommandEvent
& WXUNUSED(event
))
2045 wxString url
= wxGetTextFromUser(_("URL:"), _("Insert URL"));
2048 // Make a style suitable for showing a URL
2049 wxRichTextAttr urlStyle
;
2050 urlStyle
.SetTextColour(*wxBLUE
);
2051 urlStyle
.SetFontUnderlined(true);
2053 m_richTextCtrl
->BeginStyle(urlStyle
);
2054 m_richTextCtrl
->BeginURL(url
);
2055 m_richTextCtrl
->WriteText(url
);
2056 m_richTextCtrl
->EndURL();
2057 m_richTextCtrl
->EndStyle();
2061 void MyFrame::OnInsertImage(wxCommandEvent
& WXUNUSED(event
))
2063 wxFileDialog
dialog(this, _("Choose an image"), "", "", "BMP and GIF files (*.bmp;*.gif)|*.bmp;*.gif|PNG files (*.png)|*.png");
2064 if (dialog
.ShowModal() == wxID_OK
)
2066 wxString path
= dialog
.GetPath();
2067 m_richTextCtrl
->WriteImage(path
, wxBITMAP_TYPE_ANY
);
2071 void MyFrame::OnURL(wxTextUrlEvent
& event
)
2073 wxMessageBox(event
.GetString());
2076 // Veto style sheet replace events when loading from XML, since we want
2077 // to keep the original style sheet.
2078 void MyFrame::OnStyleSheetReplacing(wxRichTextEvent
& event
)
2083 void MyFrame::OnPrint(wxCommandEvent
& WXUNUSED(event
))
2085 wxGetApp().GetPrinting()->PrintBuffer(m_richTextCtrl
->GetBuffer());
2088 void MyFrame::OnPreview(wxCommandEvent
& WXUNUSED(event
))
2090 wxGetApp().GetPrinting()->PreviewBuffer(m_richTextCtrl
->GetBuffer());
2093 void MyFrame::OnPageSetup(wxCommandEvent
& WXUNUSED(event
))
2095 wxDialog
dialog(this, wxID_ANY
, wxT("Testing"), wxPoint(10, 10), wxSize(400, 300), wxDEFAULT_DIALOG_STYLE
);
2097 wxNotebook
* nb
= new wxNotebook(& dialog
, wxID_ANY
, wxPoint(5, 5), wxSize(300, 250));
2098 wxPanel
* panel
= new wxPanel(nb
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
);
2099 wxPanel
* panel2
= new wxPanel(nb
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
);
2101 new wxRichTextCtrl(panel
, wxID_ANY
, wxEmptyString
, wxPoint(5, 5), wxSize(200, 150), wxVSCROLL
|wxTE_READONLY
);
2102 nb
->AddPage(panel
, wxT("Page 1"));
2104 new wxRichTextCtrl(panel2
, wxID_ANY
, wxEmptyString
, wxPoint(5, 5), wxSize(200, 150), wxVSCROLL
|wxTE_READONLY
);
2105 nb
->AddPage(panel2
, wxT("Page 2"));
2107 new wxButton(& dialog
, wxID_OK
, wxT("OK"), wxPoint(5, 180));
2111 // wxGetApp().GetPrinting()->PageSetup();
2114 void MyFrame::OnSetFontScale(wxCommandEvent
& WXUNUSED(event
))
2116 wxString value
= wxString::Format(wxT("%g"), m_richTextCtrl
->GetFontScale());
2117 wxString text
= wxGetTextFromUser(wxT("Enter a text scale factor:"), wxT("Text Scale Factor"), value
, wxGetTopLevelParent(this));
2118 if (!text
.IsEmpty() && value
!= text
)
2121 wxSscanf(text
, wxT("%lf"), & scale
);
2122 m_richTextCtrl
->SetFontScale(scale
, true);
2126 void MyFrame::OnSetDimensionScale(wxCommandEvent
& WXUNUSED(event
))
2128 wxString value
= wxString::Format(wxT("%g"), m_richTextCtrl
->GetDimensionScale());
2129 wxString text
= wxGetTextFromUser(wxT("Enter a dimension scale factor:"), wxT("Dimension Scale Factor"), value
, wxGetTopLevelParent(this));
2130 if (!text
.IsEmpty() && value
!= text
)
2133 wxSscanf(text
, wxT("%lf"), & scale
);
2134 m_richTextCtrl
->SetDimensionScale(scale
, true);
2138 void MyRichTextCtrl::PrepareContent(wxRichTextParagraphLayoutBox
& container
)
2142 // Lock all content that's about to be added to the control
2143 wxRichTextObjectList::compatibility_iterator node
= container
.GetChildren().GetFirst();
2146 wxRichTextParagraph
* para
= wxDynamicCast(node
->GetData(), wxRichTextParagraph
);
2149 wxRichTextObjectList::compatibility_iterator childNode
= para
->GetChildren().GetFirst();
2152 wxRichTextObject
* obj
= childNode
->GetData();
2153 obj
->GetProperties().SetProperty(wxT("Lock"), m_lockId
);
2155 childNode
= childNode
->GetNext();
2158 node
= node
->GetNext();
2163 bool MyRichTextCtrl::CanDeleteRange(wxRichTextParagraphLayoutBox
& container
, const wxRichTextRange
& range
) const
2166 for (i
= range
.GetStart(); i
< range
.GetEnd(); i
++)
2168 wxRichTextObject
* obj
= container
.GetLeafObjectAtPosition(i
);
2169 if (obj
&& obj
->GetProperties().HasProperty(wxT("Lock")))
2177 bool MyRichTextCtrl::CanInsertContent(wxRichTextParagraphLayoutBox
& container
, long pos
) const
2179 wxRichTextObject
* child1
= container
.GetLeafObjectAtPosition(pos
);
2180 wxRichTextObject
* child2
= container
.GetLeafObjectAtPosition(pos
-1);
2182 long lock1
= -1, lock2
= -1;
2184 if (child1
&& child1
->GetProperties().HasProperty(wxT("Lock")))
2185 lock1
= child1
->GetProperties().GetPropertyLong(wxT("Lock"));
2186 if (child2
&& child2
->GetProperties().HasProperty(wxT("Lock")))
2187 lock2
= child2
->GetProperties().GetPropertyLong(wxT("Lock"));
2189 if (lock1
!= -1 && lock1
== lock2
)
2192 // Don't allow insertion before a locked object if it's at the beginning of the buffer.
2193 if (pos
== 0 && lock1
!= -1)
2200 class wxRichTextEnhancedDrawingHandler
: public wxRichTextDrawingHandler
2203 wxRichTextEnhancedDrawingHandler()
2205 SetName(wxT("enhanceddrawing"));
2206 m_lockBackgroundColour
= wxColour(220, 220, 220);
2210 Returns @true if this object has virtual attributes that we can provide.
2212 virtual bool HasVirtualAttributes(wxRichTextObject
* obj
) const;
2215 Provides virtual attributes that we can provide.
2217 virtual bool GetVirtualAttributes(wxRichTextAttr
& attr
, wxRichTextObject
* obj
) const;
2220 Gets the count for mixed virtual attributes for individual positions within the object.
2221 For example, individual characters within a text object may require special highlighting.
2223 virtual int GetVirtualSubobjectAttributesCount(wxRichTextObject
* WXUNUSED(obj
)) const { return 0; }
2226 Gets the mixed virtual attributes for individual positions within the object.
2227 For example, individual characters within a text object may require special highlighting.
2228 Returns the number of virtual attributes found.
2230 virtual int GetVirtualSubobjectAttributes(wxRichTextObject
* WXUNUSED(obj
), wxArrayInt
& WXUNUSED(positions
), wxRichTextAttrArray
& WXUNUSED(attributes
)) const { return 0; }
2233 Do we have virtual text for this object? Virtual text allows an application
2234 to replace characters in an object for editing and display purposes, for example
2235 for highlighting special characters.
2237 virtual bool HasVirtualText(const wxRichTextPlainText
* WXUNUSED(obj
)) const { return false; }
2240 Gets the virtual text for this object.
2242 virtual bool GetVirtualText(const wxRichTextPlainText
* WXUNUSED(obj
), wxString
& WXUNUSED(text
)) const { return false; }
2244 wxColour m_lockBackgroundColour
;
2247 bool wxRichTextEnhancedDrawingHandler::HasVirtualAttributes(wxRichTextObject
* obj
) const
2249 return obj
->GetProperties().HasProperty(wxT("Lock"));
2252 bool wxRichTextEnhancedDrawingHandler::GetVirtualAttributes(wxRichTextAttr
& attr
, wxRichTextObject
* obj
) const
2254 if (obj
->GetProperties().HasProperty(wxT("Lock")))
2256 attr
.SetBackgroundColour(m_lockBackgroundColour
);
2262 void MyRichTextCtrl::SetEnhancedDrawingHandler()
2264 wxRichTextBuffer::AddDrawingHandler(new wxRichTextEnhancedDrawingHandler
);
2267 wxRichTextObject
* MyRichTextCtrl::FindCurrentPosition() const
2271 if (HasSelection()) // First see if there's a selection
2273 wxRichTextRange range
= GetSelectionRange();
2274 if (range
.ToInternal().GetLength() == 1)
2276 position
= range
.GetStart();
2279 if (position
== -1) // Failing that, near cursor
2281 position
= GetAdjustedCaretPosition(GetCaretPosition());
2285 wxRichTextObject
* obj
= GetFocusObject()->GetLeafObjectAtPosition(position
);
2290 wxRichTextTable
* MyRichTextCtrl::FindTable() const
2292 wxRichTextObject
* obj
= FindCurrentPosition();
2294 // It could be a table or a cell (or neither)
2295 wxRichTextTable
* table
= wxDynamicCast(obj
, wxRichTextTable
);
2303 obj
= obj
->GetParent();
2304 wxRichTextTable
* table
= wxDynamicCast(obj
, wxRichTextTable
);