1 /////////////////////////////////////////////////////////////////////////////
2 // Name: samples/richtext/richtext.cpp
3 // Purpose: wxWidgets rich text editor sample
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx/wx.h".
21 #include "wx/wxprec.h"
27 // for all others, include the necessary headers (this file is usually all you
28 // need because it includes almost all "standard" wxWidgets headers)
33 #include "wx/fontdlg.h"
34 #include "wx/splitter.h"
35 #include "wx/sstream.h"
36 #include "wx/html/htmlwin.h"
39 #include "wx/filesys.h"
40 #include "wx/fs_mem.h"
44 #include "wx/cshelp.h"
48 #include "../sample.xpm"
51 #include "bitmaps/smiley.xpm"
52 // #include "bitmaps/idea.xpm"
53 #include "bitmaps/zebra.xpm"
55 #include "bitmaps/open.xpm"
56 #include "bitmaps/save.xpm"
57 #include "bitmaps/copy.xpm"
58 #include "bitmaps/cut.xpm"
59 #include "bitmaps/paste.xpm"
60 #include "bitmaps/undo.xpm"
61 #include "bitmaps/redo.xpm"
62 #include "bitmaps/bold.xpm"
63 #include "bitmaps/italic.xpm"
64 #include "bitmaps/underline.xpm"
66 #include "bitmaps/alignleft.xpm"
67 #include "bitmaps/alignright.xpm"
68 #include "bitmaps/centre.xpm"
69 #include "bitmaps/font.xpm"
70 #include "bitmaps/indentless.xpm"
71 #include "bitmaps/indentmore.xpm"
73 #include "wx/richtext/richtextctrl.h"
74 #include "wx/richtext/richtextstyles.h"
75 #include "wx/richtext/richtextxml.h"
76 #include "wx/richtext/richtexthtml.h"
77 #include "wx/richtext/richtextformatdlg.h"
78 #include "wx/richtext/richtextsymboldlg.h"
79 #include "wx/richtext/richtextstyledlg.h"
80 #include "wx/richtext/richtextprint.h"
81 #include "wx/richtext/richtextimagedlg.h"
83 // ----------------------------------------------------------------------------
85 // ----------------------------------------------------------------------------
87 // ----------------------------------------------------------------------------
89 // ----------------------------------------------------------------------------
91 // Define a new application type, each program should derive a class from wxApp
92 class MyApp
: public wxApp
95 // override base class virtuals
96 // ----------------------------
98 // this one is called on application startup and is a good place for the app
99 // initialization (doing it here and not in the ctor allows to have an error
100 // return: if OnInit() returns false, the application terminates)
101 virtual bool OnInit();
102 virtual int OnExit();
106 wxRichTextStyleSheet
* GetStyleSheet() const { return m_styleSheet
; }
107 wxRichTextPrinting
* GetPrinting() const { return m_printing
; }
109 wxRichTextStyleSheet
* m_styleSheet
;
110 wxRichTextPrinting
* m_printing
;
113 // Define a new frame type: this is going to be our main frame
114 class MyFrame
: public wxFrame
118 MyFrame(const wxString
& title
, wxWindowID id
, const wxPoint
& pos
= wxDefaultPosition
,
119 const wxSize
& size
= wxDefaultSize
, long style
= wxDEFAULT_FRAME_STYLE
);
121 // event handlers (these functions should _not_ be virtual)
122 void OnQuit(wxCommandEvent
& event
);
123 void OnAbout(wxCommandEvent
& event
);
125 void OnOpen(wxCommandEvent
& event
);
126 void OnSave(wxCommandEvent
& event
);
127 void OnSaveAs(wxCommandEvent
& event
);
129 void OnBold(wxCommandEvent
& event
);
130 void OnItalic(wxCommandEvent
& event
);
131 void OnUnderline(wxCommandEvent
& event
);
133 void OnUpdateBold(wxUpdateUIEvent
& event
);
134 void OnUpdateItalic(wxUpdateUIEvent
& event
);
135 void OnUpdateUnderline(wxUpdateUIEvent
& event
);
137 void OnAlignLeft(wxCommandEvent
& event
);
138 void OnAlignCentre(wxCommandEvent
& event
);
139 void OnAlignRight(wxCommandEvent
& event
);
141 void OnUpdateAlignLeft(wxUpdateUIEvent
& event
);
142 void OnUpdateAlignCentre(wxUpdateUIEvent
& event
);
143 void OnUpdateAlignRight(wxUpdateUIEvent
& event
);
145 void OnIndentMore(wxCommandEvent
& event
);
146 void OnIndentLess(wxCommandEvent
& event
);
148 void OnFont(wxCommandEvent
& event
);
149 void OnImage(wxCommandEvent
& event
);
150 void OnUpdateImage(wxUpdateUIEvent
& event
);
151 void OnParagraph(wxCommandEvent
& event
);
152 void OnFormat(wxCommandEvent
& event
);
153 void OnUpdateFormat(wxUpdateUIEvent
& event
);
155 void OnInsertSymbol(wxCommandEvent
& event
);
157 void OnLineSpacingHalf(wxCommandEvent
& event
);
158 void OnLineSpacingDouble(wxCommandEvent
& event
);
159 void OnLineSpacingSingle(wxCommandEvent
& event
);
161 void OnParagraphSpacingMore(wxCommandEvent
& event
);
162 void OnParagraphSpacingLess(wxCommandEvent
& event
);
164 void OnNumberList(wxCommandEvent
& event
);
165 void OnBulletsAndNumbering(wxCommandEvent
& event
);
166 void OnItemizeList(wxCommandEvent
& event
);
167 void OnRenumberList(wxCommandEvent
& event
);
168 void OnPromoteList(wxCommandEvent
& event
);
169 void OnDemoteList(wxCommandEvent
& event
);
170 void OnClearList(wxCommandEvent
& event
);
172 void OnReload(wxCommandEvent
& event
);
174 void OnViewHTML(wxCommandEvent
& event
);
176 void OnSwitchStyleSheets(wxCommandEvent
& event
);
177 void OnManageStyles(wxCommandEvent
& event
);
179 void OnInsertURL(wxCommandEvent
& event
);
180 void OnURL(wxTextUrlEvent
& event
);
181 void OnStyleSheetReplacing(wxRichTextEvent
& event
);
183 void OnPrint(wxCommandEvent
& event
);
184 void OnPreview(wxCommandEvent
& event
);
185 void OnPageSetup(wxCommandEvent
& event
);
187 void OnInsertImage(wxCommandEvent
& event
);
190 // Forward command events to the current rich text control, if any
191 bool ProcessEvent(wxEvent
& event
);
194 void WriteInitialText();
197 // any class wishing to process wxWidgets events must use this macro
198 DECLARE_EVENT_TABLE()
200 wxRichTextCtrl
* m_richTextCtrl
;
203 // ----------------------------------------------------------------------------
205 // ----------------------------------------------------------------------------
207 // IDs for the controls and the menu commands
212 ID_About
= wxID_ABOUT
,
214 ID_FORMAT_BOLD
= 100,
228 ID_FORMAT_ALIGN_LEFT
,
229 ID_FORMAT_ALIGN_CENTRE
,
230 ID_FORMAT_ALIGN_RIGHT
,
232 ID_FORMAT_INDENT_MORE
,
233 ID_FORMAT_INDENT_LESS
,
235 ID_FORMAT_PARAGRAPH_SPACING_MORE
,
236 ID_FORMAT_PARAGRAPH_SPACING_LESS
,
238 ID_FORMAT_LINE_SPACING_HALF
,
239 ID_FORMAT_LINE_SPACING_DOUBLE
,
240 ID_FORMAT_LINE_SPACING_SINGLE
,
242 ID_FORMAT_NUMBER_LIST
,
243 ID_FORMAT_BULLETS_AND_NUMBERING
,
244 ID_FORMAT_ITEMIZE_LIST
,
245 ID_FORMAT_RENUMBER_LIST
,
246 ID_FORMAT_PROMOTE_LIST
,
247 ID_FORMAT_DEMOTE_LIST
,
248 ID_FORMAT_CLEAR_LIST
,
251 ID_SWITCH_STYLE_SHEETS
,
259 ID_RICHTEXT_STYLE_LIST
,
260 ID_RICHTEXT_STYLE_COMBO
263 // ----------------------------------------------------------------------------
264 // event tables and other macros for wxWidgets
265 // ----------------------------------------------------------------------------
267 // the event tables connect the wxWidgets events with the functions (event
268 // handlers) which process them. It can be also done at run-time, but for the
269 // simple menu events like this the static method is much simpler.
270 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
271 EVT_MENU(ID_Quit
, MyFrame
::OnQuit
)
272 EVT_MENU(ID_About
, MyFrame
::OnAbout
)
274 EVT_MENU(wxID_OPEN
, MyFrame
::OnOpen
)
275 EVT_MENU(wxID_SAVE
, MyFrame
::OnSave
)
276 EVT_MENU(wxID_SAVEAS
, MyFrame
::OnSaveAs
)
278 EVT_MENU(ID_FORMAT_BOLD
, MyFrame
::OnBold
)
279 EVT_MENU(ID_FORMAT_ITALIC
, MyFrame
::OnItalic
)
280 EVT_MENU(ID_FORMAT_UNDERLINE
, MyFrame
::OnUnderline
)
282 EVT_UPDATE_UI(ID_FORMAT_BOLD
, MyFrame
::OnUpdateBold
)
283 EVT_UPDATE_UI(ID_FORMAT_ITALIC
, MyFrame
::OnUpdateItalic
)
284 EVT_UPDATE_UI(ID_FORMAT_UNDERLINE
, MyFrame
::OnUpdateUnderline
)
286 EVT_MENU(ID_FORMAT_ALIGN_LEFT
, MyFrame
::OnAlignLeft
)
287 EVT_MENU(ID_FORMAT_ALIGN_CENTRE
, MyFrame
::OnAlignCentre
)
288 EVT_MENU(ID_FORMAT_ALIGN_RIGHT
, MyFrame
::OnAlignRight
)
290 EVT_UPDATE_UI(ID_FORMAT_ALIGN_LEFT
, MyFrame
::OnUpdateAlignLeft
)
291 EVT_UPDATE_UI(ID_FORMAT_ALIGN_CENTRE
, MyFrame
::OnUpdateAlignCentre
)
292 EVT_UPDATE_UI(ID_FORMAT_ALIGN_RIGHT
, MyFrame
::OnUpdateAlignRight
)
294 EVT_MENU(ID_FORMAT_FONT
, MyFrame
::OnFont
)
295 EVT_MENU(ID_FORMAT_IMAGE
, MyFrame
::OnImage
)
296 EVT_MENU(ID_FORMAT_PARAGRAPH
, MyFrame
::OnParagraph
)
297 EVT_MENU(ID_FORMAT_CONTENT
, MyFrame
::OnFormat
)
298 EVT_UPDATE_UI(ID_FORMAT_CONTENT
, MyFrame
::OnUpdateFormat
)
299 EVT_UPDATE_UI(ID_FORMAT_FONT
, MyFrame
::OnUpdateFormat
)
300 EVT_UPDATE_UI(ID_FORMAT_IMAGE
, MyFrame
::OnUpdateImage
)
301 EVT_UPDATE_UI(ID_FORMAT_PARAGRAPH
, MyFrame
::OnUpdateFormat
)
302 EVT_MENU(ID_FORMAT_INDENT_MORE
, MyFrame
::OnIndentMore
)
303 EVT_MENU(ID_FORMAT_INDENT_LESS
, MyFrame
::OnIndentLess
)
305 EVT_MENU(ID_FORMAT_LINE_SPACING_HALF
, MyFrame
::OnLineSpacingHalf
)
306 EVT_MENU(ID_FORMAT_LINE_SPACING_SINGLE
, MyFrame
::OnLineSpacingSingle
)
307 EVT_MENU(ID_FORMAT_LINE_SPACING_DOUBLE
, MyFrame
::OnLineSpacingDouble
)
309 EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_MORE
, MyFrame
::OnParagraphSpacingMore
)
310 EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_LESS
, MyFrame
::OnParagraphSpacingLess
)
312 EVT_MENU(ID_RELOAD
, MyFrame
::OnReload
)
314 EVT_MENU(ID_INSERT_SYMBOL
, MyFrame
::OnInsertSymbol
)
315 EVT_MENU(ID_INSERT_URL
, MyFrame
::OnInsertURL
)
316 EVT_MENU(ID_INSERT_IMAGE
, MyFrame
::OnInsertImage
)
318 EVT_MENU(ID_FORMAT_NUMBER_LIST
, MyFrame
::OnNumberList
)
319 EVT_MENU(ID_FORMAT_BULLETS_AND_NUMBERING
, MyFrame
::OnBulletsAndNumbering
)
320 EVT_MENU(ID_FORMAT_ITEMIZE_LIST
, MyFrame
::OnItemizeList
)
321 EVT_MENU(ID_FORMAT_RENUMBER_LIST
, MyFrame
::OnRenumberList
)
322 EVT_MENU(ID_FORMAT_PROMOTE_LIST
, MyFrame
::OnPromoteList
)
323 EVT_MENU(ID_FORMAT_DEMOTE_LIST
, MyFrame
::OnDemoteList
)
324 EVT_MENU(ID_FORMAT_CLEAR_LIST
, MyFrame
::OnClearList
)
326 EVT_MENU(ID_VIEW_HTML
, MyFrame
::OnViewHTML
)
327 EVT_MENU(ID_SWITCH_STYLE_SHEETS
, MyFrame
::OnSwitchStyleSheets
)
328 EVT_MENU(ID_MANAGE_STYLES
, MyFrame
::OnManageStyles
)
330 EVT_MENU(ID_PRINT
, MyFrame
::OnPrint
)
331 EVT_MENU(ID_PREVIEW
, MyFrame
::OnPreview
)
332 EVT_MENU(ID_PAGE_SETUP
, MyFrame
::OnPageSetup
)
334 EVT_TEXT_URL(wxID_ANY
, MyFrame
::OnURL
)
335 EVT_RICHTEXT_STYLESHEET_REPLACING(wxID_ANY
, MyFrame
::OnStyleSheetReplacing
)
338 // Create a new application object: this macro will allow wxWidgets to create
339 // the application object during program execution (it's better than using a
340 // static object for many reasons) and also implements the accessor function
341 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
345 // ============================================================================
347 // ============================================================================
349 // ----------------------------------------------------------------------------
350 // the application class
351 // ----------------------------------------------------------------------------
353 // 'Main program' equivalent: the program execution "starts" here
356 if ( !wxApp
::OnInit() )
360 wxHelpProvider
::Set(new wxSimpleHelpProvider
);
363 m_styleSheet
= new wxRichTextStyleSheet
;
364 m_printing
= new wxRichTextPrinting(wxT("Test Document"));
366 m_printing
->SetFooterText(wxT("@TITLE@"), wxRICHTEXT_PAGE_ALL
, wxRICHTEXT_PAGE_CENTRE
);
367 m_printing
->SetFooterText(wxT("Page @PAGENUM@"), wxRICHTEXT_PAGE_ALL
, wxRICHTEXT_PAGE_RIGHT
);
371 // Add extra handlers (plain text is automatically added)
372 wxRichTextBuffer
::AddHandler(new wxRichTextXMLHandler
);
373 wxRichTextBuffer
::AddHandler(new wxRichTextHTMLHandler
);
375 // Add image handlers
377 wxImage
::AddHandler( new wxPNGHandler
);
381 wxImage
::AddHandler( new wxJPEGHandler
);
385 wxImage
::AddHandler( new wxGIFHandler
);
389 wxFileSystem
::AddHandler( new wxMemoryFSHandler
);
392 // create the main application window
393 MyFrame
*frame
= new MyFrame(wxT("wxRichTextCtrl Sample"), wxID_ANY
, wxDefaultPosition
, wxSize(700, 600));
395 m_printing
->SetParentWindow(frame
);
397 // and show it (the frames, unlike simple controls, are not shown when
398 // created initially)
401 // success: wxApp::OnRun() will be called which will enter the main message
402 // loop and the application will run. If we returned false here, the
403 // application would exit immediately.
415 void MyApp
::CreateStyles()
419 wxFont
romanFont(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
420 wxFont
swissFont(12, wxSWISS
, wxNORMAL
, wxNORMAL
);
422 wxRichTextParagraphStyleDefinition
* normalPara
= new wxRichTextParagraphStyleDefinition(wxT("Normal"));
423 wxRichTextAttr normalAttr
;
424 normalAttr
.SetFontFaceName(romanFont
.GetFaceName());
425 normalAttr
.SetFontSize(12);
426 // Let's set all attributes for this style
427 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
|
428 wxTEXT_ATTR_PARA_SPACING_BEFORE
|wxTEXT_ATTR_PARA_SPACING_AFTER
|wxTEXT_ATTR_LINE_SPACING
|
429 wxTEXT_ATTR_BULLET_STYLE
|wxTEXT_ATTR_BULLET_NUMBER
);
430 normalPara
->SetStyle(normalAttr
);
432 m_styleSheet
->AddParagraphStyle(normalPara
);
434 wxRichTextParagraphStyleDefinition
* indentedPara
= new wxRichTextParagraphStyleDefinition(wxT("Indented"));
435 wxRichTextAttr indentedAttr
;
436 indentedAttr
.SetFontFaceName(romanFont
.GetFaceName());
437 indentedAttr
.SetFontSize(12);
438 indentedAttr
.SetLeftIndent(100, 0);
439 // We only want to affect indentation
440 indentedAttr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
);
441 indentedPara
->SetStyle(indentedAttr
);
443 m_styleSheet
->AddParagraphStyle(indentedPara
);
445 wxRichTextParagraphStyleDefinition
* indentedPara2
= new wxRichTextParagraphStyleDefinition(wxT("Red Bold Indented"));
446 wxRichTextAttr indentedAttr2
;
447 indentedAttr2
.SetFontFaceName(romanFont
.GetFaceName());
448 indentedAttr2
.SetFontSize(12);
449 indentedAttr2
.SetFontWeight(wxFONTWEIGHT_BOLD
);
450 indentedAttr2
.SetTextColour(*wxRED
);
451 indentedAttr2
.SetFontSize(12);
452 indentedAttr2
.SetLeftIndent(100, 0);
453 // We want to affect indentation, font and text colour
454 indentedAttr2
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
|wxTEXT_ATTR_FONT
|wxTEXT_ATTR_TEXT_COLOUR
);
455 indentedPara2
->SetStyle(indentedAttr2
);
457 m_styleSheet
->AddParagraphStyle(indentedPara2
);
459 wxRichTextParagraphStyleDefinition
* flIndentedPara
= new wxRichTextParagraphStyleDefinition(wxT("First Line Indented"));
460 wxRichTextAttr flIndentedAttr
;
461 flIndentedAttr
.SetFontFaceName(swissFont
.GetFaceName());
462 flIndentedAttr
.SetFontSize(12);
463 flIndentedAttr
.SetLeftIndent(100, -100);
464 // We only want to affect indentation
465 flIndentedAttr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
);
466 flIndentedPara
->SetStyle(flIndentedAttr
);
468 m_styleSheet
->AddParagraphStyle(flIndentedPara
);
472 wxRichTextCharacterStyleDefinition
* boldDef
= new wxRichTextCharacterStyleDefinition(wxT("Bold"));
473 wxRichTextAttr boldAttr
;
474 boldAttr
.SetFontFaceName(romanFont
.GetFaceName());
475 boldAttr
.SetFontSize(12);
476 boldAttr
.SetFontWeight(wxFONTWEIGHT_BOLD
);
477 // We only want to affect boldness
478 boldAttr
.SetFlags(wxTEXT_ATTR_FONT_WEIGHT
);
479 boldDef
->SetStyle(boldAttr
);
481 m_styleSheet
->AddCharacterStyle(boldDef
);
483 wxRichTextCharacterStyleDefinition
* italicDef
= new wxRichTextCharacterStyleDefinition(wxT("Italic"));
484 wxRichTextAttr italicAttr
;
485 italicAttr
.SetFontFaceName(romanFont
.GetFaceName());
486 italicAttr
.SetFontSize(12);
487 italicAttr
.SetFontStyle(wxFONTSTYLE_ITALIC
);
488 // We only want to affect italics
489 italicAttr
.SetFlags(wxTEXT_ATTR_FONT_ITALIC
);
490 italicDef
->SetStyle(italicAttr
);
492 m_styleSheet
->AddCharacterStyle(italicDef
);
494 wxRichTextCharacterStyleDefinition
* redDef
= new wxRichTextCharacterStyleDefinition(wxT("Red Bold"));
495 wxRichTextAttr redAttr
;
496 redAttr
.SetFontFaceName(romanFont
.GetFaceName());
497 redAttr
.SetFontSize(12);
498 redAttr
.SetFontWeight(wxFONTWEIGHT_BOLD
);
499 redAttr
.SetTextColour(*wxRED
);
500 // We only want to affect colour, weight and face
501 redAttr
.SetFlags(wxTEXT_ATTR_FONT_FACE
|wxTEXT_ATTR_FONT_WEIGHT
|wxTEXT_ATTR_TEXT_COLOUR
);
502 redDef
->SetStyle(redAttr
);
504 m_styleSheet
->AddCharacterStyle(redDef
);
506 wxRichTextListStyleDefinition
* bulletList
= new wxRichTextListStyleDefinition(wxT("Bullet List 1"));
508 for (i
= 0; i
< 10; i
++)
512 bulletText
= wxT("standard/circle");
514 bulletText
= wxT("standard/square");
516 bulletText
= wxT("standard/circle");
518 bulletText
= wxT("standard/square");
520 bulletText
= wxT("standard/circle");
522 bulletList
->SetAttributes(i
, (i
+1)*60, 60, wxTEXT_ATTR_BULLET_STYLE_STANDARD
, bulletText
);
525 m_styleSheet
->AddListStyle(bulletList
);
527 wxRichTextListStyleDefinition
* numberedList
= new wxRichTextListStyleDefinition(wxT("Numbered List 1"));
528 for (i
= 0; i
< 10; i
++)
532 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
534 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_LETTERS_LOWER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
536 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ROMAN_LOWER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
538 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ROMAN_UPPER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
540 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
542 numberStyle
|= wxTEXT_ATTR_BULLET_STYLE_ALIGN_RIGHT
;
544 numberedList
->SetAttributes(i
, (i
+1)*60, 60, numberStyle
);
547 m_styleSheet
->AddListStyle(numberedList
);
549 wxRichTextListStyleDefinition
* outlineList
= new wxRichTextListStyleDefinition(wxT("Outline List 1"));
550 for (i
= 0; i
< 10; i
++)
554 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_OUTLINE
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
556 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
558 outlineList
->SetAttributes(i
, (i
+1)*120, 120, numberStyle
);
561 m_styleSheet
->AddListStyle(outlineList
);
564 // ----------------------------------------------------------------------------
566 // ----------------------------------------------------------------------------
569 MyFrame
::MyFrame(const wxString
& title
, wxWindowID id
, const wxPoint
& pos
,
570 const wxSize
& size
, long style
)
571 : wxFrame(NULL
, id
, title
, pos
, size
, style
)
573 // set the frame icon
574 SetIcon(wxICON(sample
));
577 wxMenu
*fileMenu
= new wxMenu
;
579 // the "About" item should be in the help menu
580 wxMenu
*helpMenu
= new wxMenu
;
581 helpMenu
->Append(ID_About
, wxT("&About...\tF1"), wxT("Show about dialog"));
583 fileMenu
->Append(wxID_OPEN
, wxT("&Open\tCtrl+O"), wxT("Open a file"));
584 fileMenu
->Append(wxID_SAVE
, wxT("&Save\tCtrl+S"), wxT("Save a file"));
585 fileMenu
->Append(wxID_SAVEAS
, wxT("&Save As...\tF12"), wxT("Save to a new file"));
586 fileMenu
->AppendSeparator();
587 fileMenu
->Append(ID_RELOAD
, wxT("&Reload Text\tF2"), wxT("Reload the initial text"));
588 fileMenu
->AppendSeparator();
589 fileMenu
->Append(ID_PAGE_SETUP
, wxT("Page Set&up..."), wxT("Page setup"));
590 fileMenu
->Append(ID_PRINT
, wxT("&Print...\tCtrl+P"), wxT("Print"));
591 fileMenu
->Append(ID_PREVIEW
, wxT("Print Pre&view"), wxT("Print preview"));
592 fileMenu
->AppendSeparator();
593 fileMenu
->Append(ID_VIEW_HTML
, wxT("&View as HTML"), wxT("View HTML"));
594 fileMenu
->AppendSeparator();
595 fileMenu
->Append(ID_Quit
, wxT("E&xit\tAlt+X"), wxT("Quit this program"));
597 wxMenu
* editMenu
= new wxMenu
;
598 editMenu
->Append(wxID_UNDO
, _("&Undo\tCtrl+Z"));
599 editMenu
->Append(wxID_REDO
, _("&Redo\tCtrl+Y"));
600 editMenu
->AppendSeparator();
601 editMenu
->Append(wxID_CUT
, _("Cu&t\tCtrl+X"));
602 editMenu
->Append(wxID_COPY
, _("&Copy\tCtrl+C"));
603 editMenu
->Append(wxID_PASTE
, _("&Paste\tCtrl+V"));
605 editMenu
->AppendSeparator();
606 editMenu
->Append(wxID_SELECTALL
, _("Select A&ll\tCtrl+A"));
608 editMenu
->AppendSeparator();
609 editMenu
->Append(wxID_FIND
, _("&Find...\tCtrl+F"));
610 editMenu
->Append(stID_FIND_REPLACE
, _("&Replace...\tCtrl+R"));
613 wxMenu
* formatMenu
= new wxMenu
;
614 formatMenu
->AppendCheckItem(ID_FORMAT_BOLD
, _("&Bold\tCtrl+B"));
615 formatMenu
->AppendCheckItem(ID_FORMAT_ITALIC
, _("&Italic\tCtrl+I"));
616 formatMenu
->AppendCheckItem(ID_FORMAT_UNDERLINE
, _("&Underline\tCtrl+U"));
617 formatMenu
->AppendSeparator();
618 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_LEFT
, _("L&eft Align"));
619 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_RIGHT
, _("&Right Align"));
620 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_CENTRE
, _("&Centre"));
621 formatMenu
->AppendSeparator();
622 formatMenu
->Append(ID_FORMAT_INDENT_MORE
, _("Indent &More"));
623 formatMenu
->Append(ID_FORMAT_INDENT_LESS
, _("Indent &Less"));
624 formatMenu
->AppendSeparator();
625 formatMenu
->Append(ID_FORMAT_PARAGRAPH_SPACING_MORE
, _("Increase Paragraph &Spacing"));
626 formatMenu
->Append(ID_FORMAT_PARAGRAPH_SPACING_LESS
, _("Decrease &Paragraph Spacing"));
627 formatMenu
->AppendSeparator();
628 formatMenu
->Append(ID_FORMAT_LINE_SPACING_SINGLE
, _("Normal Line Spacing"));
629 formatMenu
->Append(ID_FORMAT_LINE_SPACING_HALF
, _("1.5 Line Spacing"));
630 formatMenu
->Append(ID_FORMAT_LINE_SPACING_DOUBLE
, _("Double Line Spacing"));
631 formatMenu
->AppendSeparator();
632 formatMenu
->Append(ID_FORMAT_FONT
, _("&Font..."));
633 formatMenu
->Append(ID_FORMAT_IMAGE
, _("Image Property"));
634 formatMenu
->Append(ID_FORMAT_PARAGRAPH
, _("&Paragraph..."));
635 formatMenu
->Append(ID_FORMAT_CONTENT
, _("Font and Pa&ragraph...\tShift+Ctrl+F"));
636 formatMenu
->AppendSeparator();
637 formatMenu
->Append(ID_SWITCH_STYLE_SHEETS
, _("&Switch Style Sheets"));
638 formatMenu
->Append(ID_MANAGE_STYLES
, _("&Manage Styles"));
640 wxMenu
* listsMenu
= new wxMenu
;
641 listsMenu
->Append(ID_FORMAT_BULLETS_AND_NUMBERING
, _("Bullets and &Numbering..."));
642 listsMenu
->AppendSeparator();
643 listsMenu
->Append(ID_FORMAT_NUMBER_LIST
, _("Number List"));
644 listsMenu
->Append(ID_FORMAT_ITEMIZE_LIST
, _("Itemize List"));
645 listsMenu
->Append(ID_FORMAT_RENUMBER_LIST
, _("Renumber List"));
646 listsMenu
->Append(ID_FORMAT_PROMOTE_LIST
, _("Promote List Items"));
647 listsMenu
->Append(ID_FORMAT_DEMOTE_LIST
, _("Demote List Items"));
648 listsMenu
->Append(ID_FORMAT_CLEAR_LIST
, _("Clear List Formatting"));
650 wxMenu
* insertMenu
= new wxMenu
;
651 insertMenu
->Append(ID_INSERT_SYMBOL
, _("&Symbol...\tCtrl+I"));
652 insertMenu
->Append(ID_INSERT_URL
, _("&URL..."));
653 insertMenu
->Append(ID_INSERT_IMAGE
, _("&Image..."));
655 // now append the freshly created menu to the menu bar...
656 wxMenuBar
*menuBar
= new wxMenuBar();
657 menuBar
->Append(fileMenu
, wxT("&File"));
658 menuBar
->Append(editMenu
, wxT("&Edit"));
659 menuBar
->Append(formatMenu
, wxT("F&ormat"));
660 menuBar
->Append(listsMenu
, wxT("&Lists"));
661 menuBar
->Append(insertMenu
, wxT("&Insert"));
662 menuBar
->Append(helpMenu
, wxT("&Help"));
664 // ... and attach this menu bar to the frame
667 // create a status bar just for fun (by default with 1 pane only)
668 // but don't create it on limited screen space (WinCE)
669 bool is_pda
= wxSystemSettings
::GetScreenType() <= wxSYS_SCREEN_PDA
;
675 SetStatusText(wxT("Welcome to wxRichTextCtrl!"));
679 wxToolBar
* toolBar
= CreateToolBar();
681 toolBar
->AddTool(wxID_OPEN
, wxEmptyString
, wxBitmap(open_xpm
), _("Open"));
682 toolBar
->AddTool(wxID_SAVEAS
, wxEmptyString
, wxBitmap(save_xpm
), _("Save"));
683 toolBar
->AddSeparator();
684 toolBar
->AddTool(wxID_CUT
, wxEmptyString
, wxBitmap(cut_xpm
), _("Cut"));
685 toolBar
->AddTool(wxID_COPY
, wxEmptyString
, wxBitmap(copy_xpm
), _("Copy"));
686 toolBar
->AddTool(wxID_PASTE
, wxEmptyString
, wxBitmap(paste_xpm
), _("Paste"));
687 toolBar
->AddSeparator();
688 toolBar
->AddTool(wxID_UNDO
, wxEmptyString
, wxBitmap(undo_xpm
), _("Undo"));
689 toolBar
->AddTool(wxID_REDO
, wxEmptyString
, wxBitmap(redo_xpm
), _("Redo"));
690 toolBar
->AddSeparator();
691 toolBar
->AddCheckTool(ID_FORMAT_BOLD
, wxEmptyString
, wxBitmap(bold_xpm
), wxNullBitmap
, _("Bold"));
692 toolBar
->AddCheckTool(ID_FORMAT_ITALIC
, wxEmptyString
, wxBitmap(italic_xpm
), wxNullBitmap
, _("Italic"));
693 toolBar
->AddCheckTool(ID_FORMAT_UNDERLINE
, wxEmptyString
, wxBitmap(underline_xpm
), wxNullBitmap
, _("Underline"));
694 toolBar
->AddSeparator();
695 toolBar
->AddCheckTool(ID_FORMAT_ALIGN_LEFT
, wxEmptyString
, wxBitmap(alignleft_xpm
), wxNullBitmap
, _("Align Left"));
696 toolBar
->AddCheckTool(ID_FORMAT_ALIGN_CENTRE
, wxEmptyString
, wxBitmap(centre_xpm
), wxNullBitmap
, _("Centre"));
697 toolBar
->AddCheckTool(ID_FORMAT_ALIGN_RIGHT
, wxEmptyString
, wxBitmap(alignright_xpm
), wxNullBitmap
, _("Align Right"));
698 toolBar
->AddSeparator();
699 toolBar
->AddTool(ID_FORMAT_INDENT_LESS
, wxEmptyString
, wxBitmap(indentless_xpm
), _("Indent Less"));
700 toolBar
->AddTool(ID_FORMAT_INDENT_MORE
, wxEmptyString
, wxBitmap(indentmore_xpm
), _("Indent More"));
701 toolBar
->AddSeparator();
702 toolBar
->AddTool(ID_FORMAT_FONT
, wxEmptyString
, wxBitmap(font_xpm
), _("Font"));
703 toolBar
->AddTool(ID_FORMAT_IMAGE
, wxString("Im"), wxBitmap(font_xpm
), _("Image Property"));
705 wxRichTextStyleComboCtrl
* combo
= new wxRichTextStyleComboCtrl(toolBar
, ID_RICHTEXT_STYLE_COMBO
, wxDefaultPosition
, wxSize(200, -1));
706 toolBar
->AddControl(combo
);
710 wxSplitterWindow
* splitter
= new wxSplitterWindow(this, wxID_ANY
, wxDefaultPosition
, GetClientSize(), wxSP_LIVE_UPDATE
);
712 wxFont textFont
= wxFont(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
713 wxFont boldFont
= wxFont(12, wxROMAN
, wxNORMAL
, wxBOLD
);
714 wxFont italicFont
= wxFont(12, wxROMAN
, wxITALIC
, wxNORMAL
);
716 m_richTextCtrl
= new wxRichTextCtrl(splitter
, ID_RICHTEXT_CTRL
, wxEmptyString
, wxDefaultPosition
, wxSize(200, 200), wxVSCROLL
|wxHSCROLL
|wxWANTS_CHARS
);
717 wxFont
font(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
719 m_richTextCtrl
->SetFont(font
);
721 m_richTextCtrl
->SetStyleSheet(wxGetApp().GetStyleSheet());
723 combo
->SetStyleSheet(wxGetApp().GetStyleSheet());
724 combo
->SetRichTextCtrl(m_richTextCtrl
);
725 combo
->UpdateStyles();
727 wxRichTextStyleListCtrl
* styleListCtrl
= new wxRichTextStyleListCtrl(splitter
, ID_RICHTEXT_STYLE_LIST
);
729 wxSize display
= wxGetDisplaySize();
730 if ( is_pda
&& ( display
.GetWidth() < display
.GetHeight() ) )
732 splitter
->SplitHorizontally(m_richTextCtrl
, styleListCtrl
);
736 splitter
->SplitVertically(m_richTextCtrl
, styleListCtrl
, 500);
739 splitter
->UpdateSize();
741 styleListCtrl
->SetStyleSheet(wxGetApp().GetStyleSheet());
742 styleListCtrl
->SetRichTextCtrl(m_richTextCtrl
);
743 styleListCtrl
->UpdateStyles();
749 void MyFrame
::WriteInitialText()
751 wxRichTextCtrl
& r
= *m_richTextCtrl
;
753 r
.SetDefaultStyle(wxRichTextAttr());
755 r
.BeginSuppressUndo();
759 r
.BeginParagraphSpacing(0, 20);
761 r
.BeginAlignment(wxTEXT_ALIGNMENT_CENTRE
);
766 wxString lineBreak
= (wxChar
) 29;
768 r
.WriteText(wxString(wxT("Welcome to wxRichTextCtrl, a wxWidgets control")) + lineBreak
+ wxT("for editing and presenting styled text and images\n"));
772 r
.WriteText(wxT("by Julian Smart"));
778 r
.WriteImage(wxBitmap(zebra_xpm
));
785 r
.BeginAlignment(wxTEXT_ALIGNMENT_LEFT
);
786 wxRichTextAnchoredObjectAttr anchoredAttr
;
787 anchoredAttr
.m_floating
= wxRICHTEXT_FLOAT_LEFT
;
788 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.")));
789 r
.WriteImage(wxBitmap(zebra_xpm
), wxBITMAP_TYPE_PNG
, anchoredAttr
);
790 anchoredAttr
.m_floating
= wxRICHTEXT_FLOAT_RIGHT
;
791 anchoredAttr
.m_offset
= 200;
792 r
.WriteImage(wxBitmap(zebra_xpm
), wxBITMAP_TYPE_PNG
, anchoredAttr
);
793 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.")));
797 r
.WriteText(wxT("What can you do with this thing? "));
799 r
.WriteImage(wxBitmap(smiley_xpm
));
800 r
.WriteText(wxT(" Well, you can change text "));
802 r
.BeginTextColour(wxColour(255, 0, 0));
803 r
.WriteText(wxT("colour, like this red bit."));
806 wxRichTextAttr backgroundColourAttr
;
807 backgroundColourAttr
.SetBackgroundColour(*wxGREEN
);
808 backgroundColourAttr
.SetTextColour(wxColour(0, 0, 255));
809 r
.BeginStyle(backgroundColourAttr
);
810 r
.WriteText(wxT(" And this blue on green bit."));
813 r
.WriteText(wxT(" Naturally you can make things "));
815 r
.WriteText(wxT("bold "));
818 r
.WriteText(wxT("or italic "));
821 r
.WriteText(wxT("or underlined."));
825 r
.WriteText(wxT(" Different font sizes on the same line is allowed, too."));
828 r
.WriteText(wxT(" Next we'll show an indented paragraph."));
832 r
.BeginLeftIndent(60);
833 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."));
838 r
.WriteText(wxT("Next, we'll show a first-line indent, achieved using BeginLeftIndent(100, -40)."));
842 r
.BeginLeftIndent(100, -40);
844 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."));
849 r
.WriteText(wxT("Numbered bullets are possible, again using subindents:"));
852 r
.BeginNumberedBullet(1, 100, 60);
853 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."));
855 r
.EndNumberedBullet();
857 r
.BeginNumberedBullet(2, 100, 60);
858 r
.WriteText(wxT("This is my second item."));
860 r
.EndNumberedBullet();
862 r
.WriteText(wxT("The following paragraph is right-indented:"));
865 r
.BeginRightIndent(200);
867 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."));
872 r
.WriteText(wxT("The following paragraph is right-aligned with 1.5 line spacing:"));
875 r
.BeginAlignment(wxTEXT_ALIGNMENT_RIGHT
);
876 r
.BeginLineSpacing(wxTEXT_ATTR_LINE_SPACING_HALF
);
877 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."));
888 attr
.SetFlags(wxTEXT_ATTR_TABS
);
890 r
.SetDefaultStyle(attr
);
892 r
.WriteText(wxT("This line contains tabs:\tFirst tab\tSecond tab\tThird tab"));
895 r
.WriteText(wxT("Other notable features of wxRichTextCtrl include:"));
898 r
.BeginSymbolBullet(wxT('*'), 100, 60);
899 r
.WriteText(wxT("Compatibility with wxTextCtrl API"));
903 r
.BeginSymbolBullet(wxT('*'), 100, 60);
904 r
.WriteText(wxT("Easy stack-based BeginXXX()...EndXXX() style setting in addition to SetStyle()"));
908 r
.BeginSymbolBullet(wxT('*'), 100, 60);
909 r
.WriteText(wxT("XML loading and saving"));
913 r
.BeginSymbolBullet(wxT('*'), 100, 60);
914 r
.WriteText(wxT("Undo/Redo, with batching option and Undo suppressing"));
918 r
.BeginSymbolBullet(wxT('*'), 100, 60);
919 r
.WriteText(wxT("Clipboard copy and paste"));
923 r
.BeginSymbolBullet(wxT('*'), 100, 60);
924 r
.WriteText(wxT("wxRichTextStyleSheet with named character and paragraph styles, and control for applying named styles"));
928 r
.BeginSymbolBullet(wxT('*'), 100, 60);
929 r
.WriteText(wxT("A design that can easily be extended to other content types, ultimately with text boxes, tables, controls, and so on"));
933 // Make a style suitable for showing a URL
934 wxRichTextAttr urlStyle
;
935 urlStyle
.SetTextColour(*wxBLUE
);
936 urlStyle
.SetFontUnderlined(true);
938 r
.WriteText(wxT("wxRichTextCtrl can also display URLs, such as this one: "));
939 r
.BeginStyle(urlStyle
);
940 r
.BeginURL(wxT("http://www.wxwidgets.org"));
941 r
.WriteText(wxT("The wxWidgets Web Site"));
944 r
.WriteText(wxT(". Click on the URL to generate an event."));
948 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"));
950 r
.EndParagraphSpacing();
959 void MyFrame
::OnQuit(wxCommandEvent
& WXUNUSED(event
))
961 // true is to force the frame to close
965 void MyFrame
::OnAbout(wxCommandEvent
& WXUNUSED(event
))
968 msg
.Printf( wxT("This is a demo for wxRichTextCtrl, a control for editing styled text.\n(c) Julian Smart, 2005"));
969 wxMessageBox(msg
, wxT("About wxRichTextCtrl Sample"), wxOK
| wxICON_INFORMATION
, this);
972 // Forward command events to the current rich text control, if any
973 bool MyFrame
::ProcessEvent(wxEvent
& event
)
975 if (event
.IsCommandEvent() && !event
.IsKindOf(CLASSINFO(wxChildFocusEvent
)))
977 // Problem: we can get infinite recursion because the events
978 // climb back up to this frame, and repeat.
979 // Assume that command events don't cause another command event
980 // to be called, so we can rely on inCommand not being overwritten
982 static int s_eventType
= 0;
983 static wxWindowID s_id
= 0;
985 if (s_id
!= event
.GetId() && s_eventType
!= event
.GetEventType())
987 s_eventType
= event
.GetEventType();
988 s_id
= event
.GetId();
990 wxWindow
* focusWin
= wxFindFocusDescendant(this);
991 if (focusWin
&& focusWin
->GetEventHandler()->ProcessEvent(event
))
1008 return wxFrame
::ProcessEvent(event
);
1011 void MyFrame
::OnOpen(wxCommandEvent
& WXUNUSED(event
))
1015 wxArrayInt fileTypes
;
1017 wxString filter
= wxRichTextBuffer
::GetExtWildcard(false, false, & fileTypes
);
1018 if (!filter
.empty())
1020 filter
+= wxT("All files (*.*)|*.*");
1022 wxFileDialog
dialog(this,
1023 _("Choose a filename"),
1029 if (dialog
.ShowModal() == wxID_OK
)
1031 wxString path
= dialog
.GetPath();
1035 int filterIndex
= dialog
.GetFilterIndex();
1036 int fileType
= (filterIndex
< (int) fileTypes
.GetCount())
1037 ? fileTypes
[filterIndex
]
1038 : wxRICHTEXT_TYPE_TEXT
;
1039 m_richTextCtrl
->LoadFile(path
, fileType
);
1044 void MyFrame
::OnSave(wxCommandEvent
& event
)
1046 if (m_richTextCtrl
->GetFilename().empty())
1051 m_richTextCtrl
->SaveFile();
1054 void MyFrame
::OnSaveAs(wxCommandEvent
& WXUNUSED(event
))
1056 wxString filter
= wxRichTextBuffer
::GetExtWildcard(false, true);
1060 wxFileDialog
dialog(this,
1061 _("Choose a filename"),
1067 if (dialog
.ShowModal() == wxID_OK
)
1069 wxString path
= dialog
.GetPath();
1073 m_richTextCtrl
->SaveFile(path
);
1078 void MyFrame
::OnBold(wxCommandEvent
& WXUNUSED(event
))
1080 m_richTextCtrl
->ApplyBoldToSelection();
1083 void MyFrame
::OnItalic(wxCommandEvent
& WXUNUSED(event
))
1085 m_richTextCtrl
->ApplyItalicToSelection();
1088 void MyFrame
::OnUnderline(wxCommandEvent
& WXUNUSED(event
))
1090 m_richTextCtrl
->ApplyUnderlineToSelection();
1094 void MyFrame
::OnUpdateBold(wxUpdateUIEvent
& event
)
1096 event
.Check(m_richTextCtrl
->IsSelectionBold());
1099 void MyFrame
::OnUpdateItalic(wxUpdateUIEvent
& event
)
1101 event
.Check(m_richTextCtrl
->IsSelectionItalics());
1104 void MyFrame
::OnUpdateUnderline(wxUpdateUIEvent
& event
)
1106 event
.Check(m_richTextCtrl
->IsSelectionUnderlined());
1109 void MyFrame
::OnAlignLeft(wxCommandEvent
& WXUNUSED(event
))
1111 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_LEFT
);
1114 void MyFrame
::OnAlignCentre(wxCommandEvent
& WXUNUSED(event
))
1116 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_CENTRE
);
1119 void MyFrame
::OnAlignRight(wxCommandEvent
& WXUNUSED(event
))
1121 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_RIGHT
);
1124 void MyFrame
::OnUpdateAlignLeft(wxUpdateUIEvent
& event
)
1126 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_LEFT
));
1129 void MyFrame
::OnUpdateAlignCentre(wxUpdateUIEvent
& event
)
1131 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_CENTRE
));
1134 void MyFrame
::OnUpdateAlignRight(wxUpdateUIEvent
& event
)
1136 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_RIGHT
));
1139 void MyFrame
::OnFont(wxCommandEvent
& WXUNUSED(event
))
1141 wxRichTextRange range
;
1142 if (m_richTextCtrl
->HasSelection())
1143 range
= m_richTextCtrl
->GetSelectionRange();
1145 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1147 int pages
= wxRICHTEXT_FORMAT_FONT
;
1149 wxRichTextFormattingDialog
formatDlg(pages
, this);
1150 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1152 if (formatDlg
.ShowModal() == wxID_OK
)
1154 formatDlg
.ApplyStyle(m_richTextCtrl
, range
, wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_OPTIMIZE
|wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY
);
1157 // Old method using wxFontDialog
1159 if (!m_richTextCtrl
->HasSelection())
1162 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1163 wxFontData fontData
;
1166 attr
.SetFlags(wxTEXT_ATTR_FONT
);
1168 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1169 fontData
.SetInitialFont(attr
.GetFont());
1171 wxFontDialog
dialog(this, fontData
);
1172 if (dialog
.ShowModal() == wxID_OK
)
1174 fontData
= dialog
.GetFontData();
1175 attr
.SetFlags(wxTEXT_ATTR_FONT
);
1176 attr
.SetFont(fontData
.GetChosenFont());
1177 if (attr
.GetFont().Ok())
1179 m_richTextCtrl
->SetStyle(range
, attr
);
1185 void MyFrame
::OnImage(wxCommandEvent
& WXUNUSED(event
))
1187 wxRichTextRange range
;
1188 wxASSERT(m_richTextCtrl
->HasSelection());
1190 range
= m_richTextCtrl
->GetSelectionRange();
1191 wxASSERT(range
.ToInternal().GetLength() == 1);
1193 wxRichTextImage
* image
= wxDynamicCast(m_richTextCtrl
->GetBuffer().GetLeafObjectAtPosition(range
.GetStart()), wxRichTextImage
);
1196 wxRichTextImageDialog
imageDlg(this);
1197 imageDlg
.SetImageObject(image
, &m_richTextCtrl
->GetBuffer());
1199 if (imageDlg
.ShowModal() == wxID_OK
)
1201 image
= imageDlg
.ApplyImageAttr();
1206 void MyFrame
::OnParagraph(wxCommandEvent
& WXUNUSED(event
))
1208 wxRichTextRange range
;
1209 if (m_richTextCtrl
->HasSelection())
1210 range
= m_richTextCtrl
->GetSelectionRange();
1212 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1214 int pages
= wxRICHTEXT_FORMAT_INDENTS_SPACING
|wxRICHTEXT_FORMAT_TABS
|wxRICHTEXT_FORMAT_BULLETS
;
1216 wxRichTextFormattingDialog
formatDlg(pages
, this);
1217 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1219 if (formatDlg
.ShowModal() == wxID_OK
)
1221 formatDlg
.ApplyStyle(m_richTextCtrl
, range
);
1225 void MyFrame
::OnFormat(wxCommandEvent
& WXUNUSED(event
))
1227 wxRichTextRange range
;
1228 if (m_richTextCtrl
->HasSelection())
1229 range
= m_richTextCtrl
->GetSelectionRange();
1231 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1233 int pages
= wxRICHTEXT_FORMAT_FONT
|wxRICHTEXT_FORMAT_INDENTS_SPACING
|wxRICHTEXT_FORMAT_TABS
|wxRICHTEXT_FORMAT_BULLETS
;
1235 wxRichTextFormattingDialog
formatDlg(pages
, this);
1236 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1238 if (formatDlg
.ShowModal() == wxID_OK
)
1240 formatDlg
.ApplyStyle(m_richTextCtrl
, range
);
1244 void MyFrame
::OnUpdateFormat(wxUpdateUIEvent
& event
)
1246 event
.Enable(m_richTextCtrl
->HasSelection());
1249 void MyFrame
::OnUpdateImage(wxUpdateUIEvent
& event
)
1251 wxRichTextRange range
;
1252 wxRichTextObject
*obj
;
1254 range
= m_richTextCtrl
->GetSelectionRange();
1255 if (range
.ToInternal().GetLength() == 1)
1257 obj
= m_richTextCtrl
->GetBuffer().GetLeafObjectAtPosition(range
.GetStart());
1258 if (obj
&& obj
->IsKindOf(CLASSINFO(wxRichTextImage
)))
1265 event
.Enable(false);
1268 void MyFrame
::OnIndentMore(wxCommandEvent
& WXUNUSED(event
))
1270 wxRichTextAttr attr
;
1271 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1273 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1275 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1276 if (m_richTextCtrl
->HasSelection())
1277 range
= m_richTextCtrl
->GetSelectionRange();
1279 attr
.SetLeftIndent(attr
.GetLeftIndent() + 100);
1281 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1282 m_richTextCtrl
->SetStyle(range
, attr
);
1286 void MyFrame
::OnIndentLess(wxCommandEvent
& WXUNUSED(event
))
1288 wxRichTextAttr attr
;
1289 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1291 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1293 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1294 if (m_richTextCtrl
->HasSelection())
1295 range
= m_richTextCtrl
->GetSelectionRange();
1297 if (attr
.GetLeftIndent() > 0)
1299 attr
.SetLeftIndent(wxMax(0, attr
.GetLeftIndent() - 100));
1301 m_richTextCtrl
->SetStyle(range
, attr
);
1306 void MyFrame
::OnLineSpacingHalf(wxCommandEvent
& WXUNUSED(event
))
1308 wxRichTextAttr attr
;
1309 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1311 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1313 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1314 if (m_richTextCtrl
->HasSelection())
1315 range
= m_richTextCtrl
->GetSelectionRange();
1317 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1318 attr
.SetLineSpacing(15);
1320 m_richTextCtrl
->SetStyle(range
, attr
);
1324 void MyFrame
::OnLineSpacingDouble(wxCommandEvent
& WXUNUSED(event
))
1326 wxRichTextAttr attr
;
1327 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1329 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1331 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1332 if (m_richTextCtrl
->HasSelection())
1333 range
= m_richTextCtrl
->GetSelectionRange();
1335 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1336 attr
.SetLineSpacing(20);
1338 m_richTextCtrl
->SetStyle(range
, attr
);
1342 void MyFrame
::OnLineSpacingSingle(wxCommandEvent
& WXUNUSED(event
))
1344 wxRichTextAttr attr
;
1345 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1347 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1349 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1350 if (m_richTextCtrl
->HasSelection())
1351 range
= m_richTextCtrl
->GetSelectionRange();
1353 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1354 attr
.SetLineSpacing(0); // Can also use 10
1356 m_richTextCtrl
->SetStyle(range
, attr
);
1360 void MyFrame
::OnParagraphSpacingMore(wxCommandEvent
& WXUNUSED(event
))
1362 wxRichTextAttr attr
;
1363 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1365 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1367 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1368 if (m_richTextCtrl
->HasSelection())
1369 range
= m_richTextCtrl
->GetSelectionRange();
1371 attr
.SetParagraphSpacingAfter(attr
.GetParagraphSpacingAfter() + 20);
1373 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1374 m_richTextCtrl
->SetStyle(range
, attr
);
1378 void MyFrame
::OnParagraphSpacingLess(wxCommandEvent
& WXUNUSED(event
))
1380 wxRichTextAttr attr
;
1381 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1383 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1385 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1386 if (m_richTextCtrl
->HasSelection())
1387 range
= m_richTextCtrl
->GetSelectionRange();
1389 if (attr
.GetParagraphSpacingAfter() >= 20)
1391 attr
.SetParagraphSpacingAfter(attr
.GetParagraphSpacingAfter() - 20);
1393 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1394 m_richTextCtrl
->SetStyle(range
, attr
);
1399 void MyFrame
::OnReload(wxCommandEvent
& WXUNUSED(event
))
1401 m_richTextCtrl
->Clear();
1405 void MyFrame
::OnViewHTML(wxCommandEvent
& WXUNUSED(event
))
1407 wxDialog
dialog(this, wxID_ANY
, _("HTML"), wxDefaultPosition
, wxSize(500, 400), wxDEFAULT_DIALOG_STYLE
);
1409 wxBoxSizer
* boxSizer
= new wxBoxSizer(wxVERTICAL
);
1410 dialog
.SetSizer(boxSizer
);
1412 wxHtmlWindow
* win
= new wxHtmlWindow(& dialog
, wxID_ANY
, wxDefaultPosition
, wxSize(500, 400), wxSUNKEN_BORDER
);
1413 boxSizer
->Add(win
, 1, wxALL
, 5);
1415 wxButton
* cancelButton
= new wxButton(& dialog
, wxID_CANCEL
, wxT("&Close"));
1416 boxSizer
->Add(cancelButton
, 0, wxALL
|wxCENTRE
, 5);
1419 wxStringOutputStream
strStream(& text
);
1421 wxRichTextHTMLHandler htmlHandler
;
1422 htmlHandler
.SetFlags(wxRICHTEXT_HANDLER_SAVE_IMAGES_TO_MEMORY
);
1424 wxArrayInt fontSizeMapping
;
1425 fontSizeMapping
.Add(7);
1426 fontSizeMapping
.Add(9);
1427 fontSizeMapping
.Add(11);
1428 fontSizeMapping
.Add(12);
1429 fontSizeMapping
.Add(14);
1430 fontSizeMapping
.Add(22);
1431 fontSizeMapping
.Add(100);
1433 htmlHandler
.SetFontSizeMapping(fontSizeMapping
);
1435 if (htmlHandler
.SaveFile(& m_richTextCtrl
->GetBuffer(), strStream
))
1440 boxSizer
->Fit(& dialog
);
1444 // Now delete the temporary in-memory images
1445 htmlHandler
.DeleteTemporaryImages();
1448 // Demonstrates how you can change the style sheets and have the changes
1449 // reflected in the control content without wiping out character formatting.
1451 void MyFrame
::OnSwitchStyleSheets(wxCommandEvent
& WXUNUSED(event
))
1453 static wxRichTextStyleSheet
* gs_AlternateStyleSheet
= NULL
;
1455 wxRichTextStyleListCtrl
*styleList
= (wxRichTextStyleListCtrl
*) FindWindow(ID_RICHTEXT_STYLE_LIST
);
1456 wxRichTextStyleComboCtrl
* styleCombo
= (wxRichTextStyleComboCtrl
*) FindWindow(ID_RICHTEXT_STYLE_COMBO
);
1458 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1460 // One-time creation of an alternate style sheet
1461 if (!gs_AlternateStyleSheet
)
1463 gs_AlternateStyleSheet
= new wxRichTextStyleSheet(*sheet
);
1465 // Make some modifications
1466 for (int i
= 0; i
< (int) gs_AlternateStyleSheet
->GetParagraphStyleCount(); i
++)
1468 wxRichTextParagraphStyleDefinition
* def
= gs_AlternateStyleSheet
->GetParagraphStyle(i
);
1470 if (def
->GetStyle().HasTextColour())
1471 def
->GetStyle().SetTextColour(*wxBLUE
);
1473 if (def
->GetStyle().HasAlignment())
1475 if (def
->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_CENTRE
)
1476 def
->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_RIGHT
);
1477 else if (def
->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_LEFT
)
1478 def
->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_CENTRE
);
1480 if (def
->GetStyle().HasLeftIndent())
1482 def
->GetStyle().SetLeftIndent(def
->GetStyle().GetLeftIndent() * 2);
1488 wxRichTextStyleSheet
* tmp
= gs_AlternateStyleSheet
;
1489 gs_AlternateStyleSheet
= sheet
;
1492 m_richTextCtrl
->SetStyleSheet(sheet
);
1493 m_richTextCtrl
->ApplyStyleSheet(sheet
); // Makes the control reflect the new style definitions
1495 styleList
->SetStyleSheet(sheet
);
1496 styleList
->UpdateStyles();
1498 styleCombo
->SetStyleSheet(sheet
);
1499 styleCombo
->UpdateStyles();
1502 void MyFrame
::OnManageStyles(wxCommandEvent
& WXUNUSED(event
))
1504 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1506 int flags
= wxRICHTEXT_ORGANISER_CREATE_STYLES
|wxRICHTEXT_ORGANISER_EDIT_STYLES
;
1508 wxRichTextStyleOrganiserDialog
dlg(flags
, sheet
, NULL
, this, wxID_ANY
, _("Style Manager"));
1512 void MyFrame
::OnInsertSymbol(wxCommandEvent
& WXUNUSED(event
))
1514 wxRichTextAttr attr
;
1515 attr
.SetFlags(wxTEXT_ATTR_FONT
);
1516 m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
);
1518 wxString currentFontName
;
1519 if (attr
.HasFont() && attr
.GetFont().Ok())
1520 currentFontName
= attr
.GetFont().GetFaceName();
1522 // Don't set the initial font in the dialog (so the user is choosing
1523 // 'normal text', i.e. the current font) but do tell the dialog
1524 // what 'normal text' is.
1526 wxSymbolPickerDialog
dlg(wxT("*"), wxEmptyString
, currentFontName
, this);
1528 if (dlg
.ShowModal() == wxID_OK
)
1530 if (dlg
.HasSelection())
1532 long insertionPoint
= m_richTextCtrl
->GetInsertionPoint();
1534 m_richTextCtrl
->WriteText(dlg
.GetSymbol());
1536 if (!dlg
.UseNormalFont())
1538 wxFont
font(attr
.GetFont());
1539 font
.SetFaceName(dlg
.GetFontName());
1541 m_richTextCtrl
->SetStyle(insertionPoint
, insertionPoint
+1, attr
);
1547 void MyFrame
::OnNumberList(wxCommandEvent
& WXUNUSED(event
))
1549 if (m_richTextCtrl
->HasSelection())
1551 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1552 m_richTextCtrl
->SetListStyle(range
, wxT("Numbered List 1"), wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_RENUMBER
);
1556 void MyFrame
::OnBulletsAndNumbering(wxCommandEvent
& WXUNUSED(event
))
1558 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1560 int flags
= wxRICHTEXT_ORGANISER_BROWSE_NUMBERING
;
1562 wxRichTextStyleOrganiserDialog
dlg(flags
, sheet
, m_richTextCtrl
, this, wxID_ANY
, _("Bullets and Numbering"));
1563 if (dlg
.ShowModal() == wxID_OK
)
1565 if (dlg
.GetSelectedStyleDefinition())
1570 void MyFrame
::OnItemizeList(wxCommandEvent
& WXUNUSED(event
))
1572 if (m_richTextCtrl
->HasSelection())
1574 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1575 m_richTextCtrl
->SetListStyle(range
, wxT("Bullet List 1"));
1579 void MyFrame
::OnRenumberList(wxCommandEvent
& WXUNUSED(event
))
1581 if (m_richTextCtrl
->HasSelection())
1583 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1584 m_richTextCtrl
->NumberList(range
, NULL
, wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_RENUMBER
);
1588 void MyFrame
::OnPromoteList(wxCommandEvent
& WXUNUSED(event
))
1590 if (m_richTextCtrl
->HasSelection())
1592 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1593 m_richTextCtrl
->PromoteList(1, range
, NULL
);
1597 void MyFrame
::OnDemoteList(wxCommandEvent
& WXUNUSED(event
))
1599 if (m_richTextCtrl
->HasSelection())
1601 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1602 m_richTextCtrl
->PromoteList(-1, range
, NULL
);
1606 void MyFrame
::OnClearList(wxCommandEvent
& WXUNUSED(event
))
1608 if (m_richTextCtrl
->HasSelection())
1610 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1611 m_richTextCtrl
->ClearListStyle(range
);
1615 void MyFrame
::OnInsertURL(wxCommandEvent
& WXUNUSED(event
))
1617 wxString url
= wxGetTextFromUser(_("URL:"), _("Insert URL"));
1620 // Make a style suitable for showing a URL
1621 wxRichTextAttr urlStyle
;
1622 urlStyle
.SetTextColour(*wxBLUE
);
1623 urlStyle
.SetFontUnderlined(true);
1625 m_richTextCtrl
->BeginStyle(urlStyle
);
1626 m_richTextCtrl
->BeginURL(url
);
1627 m_richTextCtrl
->WriteText(url
);
1628 m_richTextCtrl
->EndURL();
1629 m_richTextCtrl
->EndStyle();
1633 void MyFrame
::OnInsertImage(wxCommandEvent
& WXUNUSED(event
))
1635 wxFileDialog
dialog(this, _("Choose an image"), "", "", "BMP and GIF files (*.bmp;*.gif)|*.bmp;*.gif|PNG files (*.png)|*.png");
1636 if (dialog
.ShowModal() == wxID_OK
)
1638 wxString path
= dialog
.GetPath();
1639 m_richTextCtrl
->WriteImage(path
, wxBITMAP_TYPE_ANY
);
1643 void MyFrame
::OnURL(wxTextUrlEvent
& event
)
1645 wxMessageBox(event
.GetString());
1648 // Veto style sheet replace events when loading from XML, since we want
1649 // to keep the original style sheet.
1650 void MyFrame
::OnStyleSheetReplacing(wxRichTextEvent
& event
)
1655 void MyFrame
::OnPrint(wxCommandEvent
& WXUNUSED(event
))
1657 wxGetApp().GetPrinting()->PrintBuffer(m_richTextCtrl
->GetBuffer());
1660 void MyFrame
::OnPreview(wxCommandEvent
& WXUNUSED(event
))
1662 wxGetApp().GetPrinting()->PreviewBuffer(m_richTextCtrl
->GetBuffer());
1665 void MyFrame
::OnPageSetup(wxCommandEvent
& WXUNUSED(event
))
1667 wxGetApp().GetPrinting()->PageSetup();