1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        samples/richtext/richtext.cpp
3 // Purpose:     wxWidgets rich text editor sample
4 // Author:      Julian Smart
5 // Modified by:
6 // Created:     2005-10-02
7 // RCS-ID:      $Id: richtext.cpp 51739 2008-02-12 17:05:32Z JS $
8 // Copyright:   (c) Julian Smart
9 // Licence:     wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11 
12 // ============================================================================
13 // declarations
14 // ============================================================================
15 
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19 
20 // For compilers that support precompilation, includes "wx/wx.h".
21 #include "wx/wxprec.h"
22 
23 #ifdef __BORLANDC__
24     #pragma hdrstop
25 #endif
26 
27 // for all others, include the necessary headers (this file is usually all you
28 // need because it includes almost all "standard" wxWidgets headers)
29 #ifndef WX_PRECOMP
30     #include "wx/wx.h"
31 #endif
32 
33 #include "wx/fontdlg.h"
34 #include "wx/splitter.h"
35 #include "wx/sstream.h"
36 #include "wx/html/htmlwin.h"
37 
38 #if wxUSE_FILESYSTEM
39 #include "wx/filesys.h"
40 #include "wx/fs_mem.h"
41 #endif
42 
43 #if wxUSE_HELP
44 #include "wx/cshelp.h"
45 #endif
46 
47 #ifndef __WXMSW__
48     #include "../sample.xpm"
49 #endif
50 
51 #include "bitmaps/smiley.xpm"
52 // #include "bitmaps/idea.xpm"
53 #include "bitmaps/zebra.xpm"
54 
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"
65 
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"
72 
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 
82 // ----------------------------------------------------------------------------
83 // resources
84 // ----------------------------------------------------------------------------
85 
86 // ----------------------------------------------------------------------------
87 // private classes
88 // ----------------------------------------------------------------------------
89 
90 // Define a new application type, each program should derive a class from wxApp
91 class MyApp : public wxApp
92 {
93 public:
94     // override base class virtuals
95     // ----------------------------
96 
97     // this one is called on application startup and is a good place for the app
98     // initialization (doing it here and not in the ctor allows to have an error
99     // return: if OnInit() returns false, the application terminates)
100     virtual bool OnInit();
101     virtual int OnExit();
102 
103     void CreateStyles();
104 
GetStyleSheet() const105     wxRichTextStyleSheet* GetStyleSheet() const { return m_styleSheet; }
GetPrinting() const106     wxRichTextPrinting* GetPrinting() const { return m_printing; }
107 
108     wxRichTextStyleSheet*   m_styleSheet;
109     wxRichTextPrinting*     m_printing;
110 };
111 
112 // Define a new frame type: this is going to be our main frame
113 class MyFrame : public wxFrame
114 {
115 public:
116     // ctor(s)
117     MyFrame(const wxString& title, wxWindowID id, const wxPoint& pos = wxDefaultPosition,
118         const wxSize& size = wxDefaultSize, long style = wxDEFAULT_FRAME_STYLE);
119 
120     // event handlers (these functions should _not_ be virtual)
121     void OnQuit(wxCommandEvent& event);
122     void OnAbout(wxCommandEvent& event);
123 
124     void OnOpen(wxCommandEvent& event);
125     void OnSave(wxCommandEvent& event);
126     void OnSaveAs(wxCommandEvent& event);
127 
128     void OnBold(wxCommandEvent& event);
129     void OnItalic(wxCommandEvent& event);
130     void OnUnderline(wxCommandEvent& event);
131 
132     void OnUpdateBold(wxUpdateUIEvent& event);
133     void OnUpdateItalic(wxUpdateUIEvent& event);
134     void OnUpdateUnderline(wxUpdateUIEvent& event);
135 
136     void OnAlignLeft(wxCommandEvent& event);
137     void OnAlignCentre(wxCommandEvent& event);
138     void OnAlignRight(wxCommandEvent& event);
139 
140     void OnUpdateAlignLeft(wxUpdateUIEvent& event);
141     void OnUpdateAlignCentre(wxUpdateUIEvent& event);
142     void OnUpdateAlignRight(wxUpdateUIEvent& event);
143 
144     void OnIndentMore(wxCommandEvent& event);
145     void OnIndentLess(wxCommandEvent& event);
146 
147     void OnFont(wxCommandEvent& event);
148     void OnParagraph(wxCommandEvent& event);
149     void OnFormat(wxCommandEvent& event);
150     void OnUpdateFormat(wxUpdateUIEvent& event);
151 
152     void OnInsertSymbol(wxCommandEvent& event);
153 
154     void OnLineSpacingHalf(wxCommandEvent& event);
155     void OnLineSpacingDouble(wxCommandEvent& event);
156     void OnLineSpacingSingle(wxCommandEvent& event);
157 
158     void OnParagraphSpacingMore(wxCommandEvent& event);
159     void OnParagraphSpacingLess(wxCommandEvent& event);
160 
161     void OnNumberList(wxCommandEvent& event);
162     void OnBulletsAndNumbering(wxCommandEvent& event);
163     void OnItemizeList(wxCommandEvent& event);
164     void OnRenumberList(wxCommandEvent& event);
165     void OnPromoteList(wxCommandEvent& event);
166     void OnDemoteList(wxCommandEvent& event);
167     void OnClearList(wxCommandEvent& event);
168 
169     void OnReload(wxCommandEvent& event);
170 
171     void OnViewHTML(wxCommandEvent& event);
172 
173     void OnSwitchStyleSheets(wxCommandEvent& event);
174     void OnManageStyles(wxCommandEvent& event);
175 
176     void OnInsertURL(wxCommandEvent& event);
177     void OnURL(wxTextUrlEvent& event);
178     void OnStyleSheetReplacing(wxRichTextEvent& event);
179 
180     void OnPrint(wxCommandEvent& event);
181     void OnPreview(wxCommandEvent& event);
182     void OnPageSetup(wxCommandEvent& event);
183 
184     // Forward command events to the current rich text control, if any
185     bool ProcessEvent(wxEvent& event);
186 
187     // Write text
188     void WriteInitialText();
189 
190 private:
191     // any class wishing to process wxWidgets events must use this macro
192     DECLARE_EVENT_TABLE()
193 
194     wxRichTextCtrl*         m_richTextCtrl;
195 };
196 
197 // ----------------------------------------------------------------------------
198 // constants
199 // ----------------------------------------------------------------------------
200 
201 // IDs for the controls and the menu commands
202 enum
203 {
204     // menu items
205     ID_Quit = wxID_EXIT,
206     ID_About = wxID_ABOUT,
207 
208     ID_FORMAT_BOLD = 100,
209     ID_FORMAT_ITALIC,
210     ID_FORMAT_UNDERLINE,
211     ID_FORMAT_FONT,
212     ID_FORMAT_PARAGRAPH,
213     ID_FORMAT_CONTENT,
214 
215     ID_RELOAD,
216 
217     ID_INSERT_SYMBOL,
218     ID_INSERT_URL,
219 
220     ID_FORMAT_ALIGN_LEFT,
221     ID_FORMAT_ALIGN_CENTRE,
222     ID_FORMAT_ALIGN_RIGHT,
223 
224     ID_FORMAT_INDENT_MORE,
225     ID_FORMAT_INDENT_LESS,
226 
227     ID_FORMAT_PARAGRAPH_SPACING_MORE,
228     ID_FORMAT_PARAGRAPH_SPACING_LESS,
229 
230     ID_FORMAT_LINE_SPACING_HALF,
231     ID_FORMAT_LINE_SPACING_DOUBLE,
232     ID_FORMAT_LINE_SPACING_SINGLE,
233 
234     ID_FORMAT_NUMBER_LIST,
235     ID_FORMAT_BULLETS_AND_NUMBERING,
236     ID_FORMAT_ITEMIZE_LIST,
237     ID_FORMAT_RENUMBER_LIST,
238     ID_FORMAT_PROMOTE_LIST,
239     ID_FORMAT_DEMOTE_LIST,
240     ID_FORMAT_CLEAR_LIST,
241 
242     ID_VIEW_HTML,
243     ID_SWITCH_STYLE_SHEETS,
244     ID_MANAGE_STYLES,
245 
246     ID_PRINT,
247     ID_PREVIEW,
248     ID_PAGE_SETUP,
249 
250     ID_RICHTEXT_CTRL,
251     ID_RICHTEXT_STYLE_LIST,
252     ID_RICHTEXT_STYLE_COMBO
253 };
254 
255 // ----------------------------------------------------------------------------
256 // event tables and other macros for wxWidgets
257 // ----------------------------------------------------------------------------
258 
259 // the event tables connect the wxWidgets events with the functions (event
260 // handlers) which process them. It can be also done at run-time, but for the
261 // simple menu events like this the static method is much simpler.
BEGIN_EVENT_TABLE(MyFrame,wxFrame)262 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
263     EVT_MENU(ID_Quit,  MyFrame::OnQuit)
264     EVT_MENU(ID_About, MyFrame::OnAbout)
265 
266     EVT_MENU(wxID_OPEN,  MyFrame::OnOpen)
267     EVT_MENU(wxID_SAVE,  MyFrame::OnSave)
268     EVT_MENU(wxID_SAVEAS,  MyFrame::OnSaveAs)
269 
270     EVT_MENU(ID_FORMAT_BOLD,  MyFrame::OnBold)
271     EVT_MENU(ID_FORMAT_ITALIC,  MyFrame::OnItalic)
272     EVT_MENU(ID_FORMAT_UNDERLINE,  MyFrame::OnUnderline)
273 
274     EVT_UPDATE_UI(ID_FORMAT_BOLD,  MyFrame::OnUpdateBold)
275     EVT_UPDATE_UI(ID_FORMAT_ITALIC,  MyFrame::OnUpdateItalic)
276     EVT_UPDATE_UI(ID_FORMAT_UNDERLINE,  MyFrame::OnUpdateUnderline)
277 
278     EVT_MENU(ID_FORMAT_ALIGN_LEFT,  MyFrame::OnAlignLeft)
279     EVT_MENU(ID_FORMAT_ALIGN_CENTRE,  MyFrame::OnAlignCentre)
280     EVT_MENU(ID_FORMAT_ALIGN_RIGHT,  MyFrame::OnAlignRight)
281 
282     EVT_UPDATE_UI(ID_FORMAT_ALIGN_LEFT,  MyFrame::OnUpdateAlignLeft)
283     EVT_UPDATE_UI(ID_FORMAT_ALIGN_CENTRE,  MyFrame::OnUpdateAlignCentre)
284     EVT_UPDATE_UI(ID_FORMAT_ALIGN_RIGHT,  MyFrame::OnUpdateAlignRight)
285 
286     EVT_MENU(ID_FORMAT_FONT,  MyFrame::OnFont)
287     EVT_MENU(ID_FORMAT_PARAGRAPH,  MyFrame::OnParagraph)
288     EVT_MENU(ID_FORMAT_CONTENT,  MyFrame::OnFormat)
289     EVT_UPDATE_UI(ID_FORMAT_CONTENT,  MyFrame::OnUpdateFormat)
290     EVT_UPDATE_UI(ID_FORMAT_FONT,  MyFrame::OnUpdateFormat)
291     EVT_UPDATE_UI(ID_FORMAT_PARAGRAPH,  MyFrame::OnUpdateFormat)
292     EVT_MENU(ID_FORMAT_INDENT_MORE,  MyFrame::OnIndentMore)
293     EVT_MENU(ID_FORMAT_INDENT_LESS,  MyFrame::OnIndentLess)
294 
295     EVT_MENU(ID_FORMAT_LINE_SPACING_HALF,  MyFrame::OnLineSpacingHalf)
296     EVT_MENU(ID_FORMAT_LINE_SPACING_SINGLE,  MyFrame::OnLineSpacingSingle)
297     EVT_MENU(ID_FORMAT_LINE_SPACING_DOUBLE,  MyFrame::OnLineSpacingDouble)
298 
299     EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_MORE,  MyFrame::OnParagraphSpacingMore)
300     EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_LESS,  MyFrame::OnParagraphSpacingLess)
301 
302     EVT_MENU(ID_RELOAD,  MyFrame::OnReload)
303 
304     EVT_MENU(ID_INSERT_SYMBOL,  MyFrame::OnInsertSymbol)
305     EVT_MENU(ID_INSERT_URL,  MyFrame::OnInsertURL)
306 
307     EVT_MENU(ID_FORMAT_NUMBER_LIST, MyFrame::OnNumberList)
308     EVT_MENU(ID_FORMAT_BULLETS_AND_NUMBERING, MyFrame::OnBulletsAndNumbering)
309     EVT_MENU(ID_FORMAT_ITEMIZE_LIST, MyFrame::OnItemizeList)
310     EVT_MENU(ID_FORMAT_RENUMBER_LIST, MyFrame::OnRenumberList)
311     EVT_MENU(ID_FORMAT_PROMOTE_LIST, MyFrame::OnPromoteList)
312     EVT_MENU(ID_FORMAT_DEMOTE_LIST, MyFrame::OnDemoteList)
313     EVT_MENU(ID_FORMAT_CLEAR_LIST, MyFrame::OnClearList)
314 
315     EVT_MENU(ID_VIEW_HTML, MyFrame::OnViewHTML)
316     EVT_MENU(ID_SWITCH_STYLE_SHEETS, MyFrame::OnSwitchStyleSheets)
317     EVT_MENU(ID_MANAGE_STYLES, MyFrame::OnManageStyles)
318 
319     EVT_MENU(ID_PRINT, MyFrame::OnPrint)
320     EVT_MENU(ID_PREVIEW, MyFrame::OnPreview)
321     EVT_MENU(ID_PAGE_SETUP, MyFrame::OnPageSetup)
322 
323     EVT_TEXT_URL(wxID_ANY, MyFrame::OnURL)
324     EVT_RICHTEXT_STYLESHEET_REPLACING(wxID_ANY, MyFrame::OnStyleSheetReplacing)
325 END_EVENT_TABLE()
326 
327 // Create a new application object: this macro will allow wxWidgets to create
328 // the application object during program execution (it's better than using a
329 // static object for many reasons) and also implements the accessor function
330 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
331 // not wxApp)
332 IMPLEMENT_APP(MyApp)
333 
334 // ============================================================================
335 // implementation
336 // ============================================================================
337 
338 // ----------------------------------------------------------------------------
339 // the application class
340 // ----------------------------------------------------------------------------
341 
342 // 'Main program' equivalent: the program execution "starts" here
343 bool MyApp::OnInit()
344 {
345 #if wxUSE_HELP
346     wxHelpProvider::Set(new wxSimpleHelpProvider);
347 #endif
348 
349     m_styleSheet = new wxRichTextStyleSheet;
350     m_printing = new wxRichTextPrinting(wxT("Test Document"));
351 
352     m_printing->SetFooterText(wxT("@TITLE@"), wxRICHTEXT_PAGE_ALL, wxRICHTEXT_PAGE_CENTRE);
353     m_printing->SetFooterText(wxT("Page @PAGENUM@"), wxRICHTEXT_PAGE_ALL, wxRICHTEXT_PAGE_RIGHT);
354 
355     CreateStyles();
356 
357     // Add extra handlers (plain text is automatically added)
358     wxRichTextBuffer::AddHandler(new wxRichTextXMLHandler);
359     wxRichTextBuffer::AddHandler(new wxRichTextHTMLHandler);
360 
361     // Add image handlers
362 #if wxUSE_LIBPNG
363     wxImage::AddHandler( new wxPNGHandler );
364 #endif
365 
366 #if wxUSE_LIBJPEG
367     wxImage::AddHandler( new wxJPEGHandler );
368 #endif
369 
370 #if wxUSE_GIF
371     wxImage::AddHandler( new wxGIFHandler );
372 #endif
373 
374 #if wxUSE_FILESYSTEM
375     wxFileSystem::AddHandler( new wxMemoryFSHandler );
376 #endif
377 
378     // create the main application window
379     MyFrame *frame = new MyFrame(_T("wxRichTextCtrl Sample"), wxID_ANY, wxDefaultPosition, wxSize(700, 600));
380 
381     m_printing->SetParentWindow(frame);
382 
383     // and show it (the frames, unlike simple controls, are not shown when
384     // created initially)
385     frame->Show(true);
386 
387     // success: wxApp::OnRun() will be called which will enter the main message
388     // loop and the application will run. If we returned false here, the
389     // application would exit immediately.
390     return true;
391 }
392 
OnExit()393 int MyApp::OnExit()
394 {
395     delete m_printing;
396     delete m_styleSheet;
397 
398     return 0;
399 }
400 
CreateStyles()401 void MyApp::CreateStyles()
402 {
403     // Paragraph styles
404 
405     wxFont romanFont(12, wxROMAN, wxNORMAL, wxNORMAL);
406     wxFont swissFont(12, wxSWISS, wxNORMAL, wxNORMAL);
407 
408     wxRichTextParagraphStyleDefinition* normalPara = new wxRichTextParagraphStyleDefinition(wxT("Normal"));
409     wxRichTextAttr normalAttr;
410     normalAttr.SetFontFaceName(romanFont.GetFaceName());
411     normalAttr.SetFontSize(12);
412     // Let's set all attributes for this style
413     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|
414                             wxTEXT_ATTR_PARA_SPACING_BEFORE|wxTEXT_ATTR_PARA_SPACING_AFTER|wxTEXT_ATTR_LINE_SPACING|
415                             wxTEXT_ATTR_BULLET_STYLE|wxTEXT_ATTR_BULLET_NUMBER);
416     normalPara->SetStyle(normalAttr);
417 
418     m_styleSheet->AddParagraphStyle(normalPara);
419 
420     wxRichTextParagraphStyleDefinition* indentedPara = new wxRichTextParagraphStyleDefinition(wxT("Indented"));
421     wxRichTextAttr indentedAttr;
422     indentedAttr.SetFontFaceName(romanFont.GetFaceName());
423     indentedAttr.SetFontSize(12);
424     indentedAttr.SetLeftIndent(100, 0);
425     // We only want to affect indentation
426     indentedAttr.SetFlags(wxTEXT_ATTR_LEFT_INDENT|wxTEXT_ATTR_RIGHT_INDENT);
427     indentedPara->SetStyle(indentedAttr);
428 
429     m_styleSheet->AddParagraphStyle(indentedPara);
430 
431     wxRichTextParagraphStyleDefinition* indentedPara2 = new wxRichTextParagraphStyleDefinition(wxT("Red Bold Indented"));
432     wxRichTextAttr indentedAttr2;
433     indentedAttr2.SetFontFaceName(romanFont.GetFaceName());
434     indentedAttr2.SetFontSize(12);
435     indentedAttr2.SetFontWeight(wxBOLD);
436     indentedAttr2.SetTextColour(*wxRED);
437     indentedAttr2.SetFontSize(12);
438     indentedAttr2.SetLeftIndent(100, 0);
439     // We want to affect indentation, font and text colour
440     indentedAttr2.SetFlags(wxTEXT_ATTR_LEFT_INDENT|wxTEXT_ATTR_RIGHT_INDENT|wxTEXT_ATTR_FONT|wxTEXT_ATTR_TEXT_COLOUR);
441     indentedPara2->SetStyle(indentedAttr2);
442 
443     m_styleSheet->AddParagraphStyle(indentedPara2);
444 
445     wxRichTextParagraphStyleDefinition* flIndentedPara = new wxRichTextParagraphStyleDefinition(wxT("First Line Indented"));
446     wxRichTextAttr flIndentedAttr;
447     flIndentedAttr.SetFontFaceName(swissFont.GetFaceName());
448     flIndentedAttr.SetFontSize(12);
449     flIndentedAttr.SetLeftIndent(100, -100);
450     // We only want to affect indentation
451     flIndentedAttr.SetFlags(wxTEXT_ATTR_LEFT_INDENT|wxTEXT_ATTR_RIGHT_INDENT);
452     flIndentedPara->SetStyle(flIndentedAttr);
453 
454     m_styleSheet->AddParagraphStyle(flIndentedPara);
455 
456     // Character styles
457 
458     wxRichTextCharacterStyleDefinition* boldDef = new wxRichTextCharacterStyleDefinition(wxT("Bold"));
459     wxRichTextAttr boldAttr;
460     boldAttr.SetFontFaceName(romanFont.GetFaceName());
461     boldAttr.SetFontSize(12);
462     boldAttr.SetFontWeight(wxBOLD);
463     // We only want to affect boldness
464     boldAttr.SetFlags(wxTEXT_ATTR_FONT_WEIGHT);
465     boldDef->SetStyle(boldAttr);
466 
467     m_styleSheet->AddCharacterStyle(boldDef);
468 
469     wxRichTextCharacterStyleDefinition* italicDef = new wxRichTextCharacterStyleDefinition(wxT("Italic"));
470     wxRichTextAttr italicAttr;
471     italicAttr.SetFontFaceName(romanFont.GetFaceName());
472     italicAttr.SetFontSize(12);
473     italicAttr.SetFontStyle(wxITALIC);
474     // We only want to affect italics
475     italicAttr.SetFlags(wxTEXT_ATTR_FONT_ITALIC);
476     italicDef->SetStyle(italicAttr);
477 
478     m_styleSheet->AddCharacterStyle(italicDef);
479 
480     wxRichTextCharacterStyleDefinition* redDef = new wxRichTextCharacterStyleDefinition(wxT("Red Bold"));
481     wxRichTextAttr redAttr;
482     redAttr.SetFontFaceName(romanFont.GetFaceName());
483     redAttr.SetFontSize(12);
484     redAttr.SetFontWeight(wxBOLD);
485     redAttr.SetTextColour(*wxRED);
486     // We only want to affect colour, weight and face
487     redAttr.SetFlags(wxTEXT_ATTR_FONT_FACE|wxTEXT_ATTR_FONT_WEIGHT|wxTEXT_ATTR_TEXT_COLOUR);
488     redDef->SetStyle(redAttr);
489 
490     m_styleSheet->AddCharacterStyle(redDef);
491 
492     wxRichTextListStyleDefinition* bulletList = new wxRichTextListStyleDefinition(wxT("Bullet List 1"));
493     int i;
494     for (i = 0; i < 10; i++)
495     {
496         wxString bulletText;
497         if (i == 0)
498             bulletText = wxT("standard/circle");
499         else if (i == 1)
500             bulletText = wxT("standard/square");
501         else if (i == 2)
502             bulletText = wxT("standard/circle");
503         else if (i == 3)
504             bulletText = wxT("standard/square");
505         else
506             bulletText = wxT("standard/circle");
507 
508         bulletList->SetAttributes(i, (i+1)*60, 60, wxTEXT_ATTR_BULLET_STYLE_STANDARD, bulletText);
509     }
510 
511     m_styleSheet->AddListStyle(bulletList);
512 
513     wxRichTextListStyleDefinition* numberedList = new wxRichTextListStyleDefinition(wxT("Numbered List 1"));
514     for (i = 0; i < 10; i++)
515     {
516         long numberStyle;
517         if (i == 0)
518             numberStyle = wxTEXT_ATTR_BULLET_STYLE_ARABIC|wxTEXT_ATTR_BULLET_STYLE_PERIOD;
519         else if (i == 1)
520             numberStyle = wxTEXT_ATTR_BULLET_STYLE_LETTERS_LOWER|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES;
521         else if (i == 2)
522             numberStyle = wxTEXT_ATTR_BULLET_STYLE_ROMAN_LOWER|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES;
523         else if (i == 3)
524             numberStyle = wxTEXT_ATTR_BULLET_STYLE_ROMAN_UPPER|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES;
525         else
526             numberStyle = wxTEXT_ATTR_BULLET_STYLE_ARABIC|wxTEXT_ATTR_BULLET_STYLE_PERIOD;
527 
528         numberStyle |= wxTEXT_ATTR_BULLET_STYLE_ALIGN_RIGHT;
529 
530         numberedList->SetAttributes(i, (i+1)*60, 60, numberStyle);
531     }
532 
533     m_styleSheet->AddListStyle(numberedList);
534 
535     wxRichTextListStyleDefinition* outlineList = new wxRichTextListStyleDefinition(wxT("Outline List 1"));
536     for (i = 0; i < 10; i++)
537     {
538         long numberStyle;
539         if (i < 4)
540             numberStyle = wxTEXT_ATTR_BULLET_STYLE_OUTLINE|wxTEXT_ATTR_BULLET_STYLE_PERIOD;
541         else
542             numberStyle = wxTEXT_ATTR_BULLET_STYLE_ARABIC|wxTEXT_ATTR_BULLET_STYLE_PERIOD;
543 
544         outlineList->SetAttributes(i, (i+1)*120, 120, numberStyle);
545     }
546 
547     m_styleSheet->AddListStyle(outlineList);
548 }
549 
550 // ----------------------------------------------------------------------------
551 // main frame
552 // ----------------------------------------------------------------------------
553 
554 // frame constructor
MyFrame(const wxString & title,wxWindowID id,const wxPoint & pos,const wxSize & size,long style)555 MyFrame::MyFrame(const wxString& title, wxWindowID id, const wxPoint& pos,
556         const wxSize& size, long style)
557        : wxFrame(NULL, id, title, pos, size, style)
558 {
559     // set the frame icon
560     SetIcon(wxICON(sample));
561 
562     // create a menu bar
563     wxMenu *fileMenu = new wxMenu;
564 
565     // the "About" item should be in the help menu
566     wxMenu *helpMenu = new wxMenu;
567     helpMenu->Append(ID_About, _T("&About...\tF1"), _T("Show about dialog"));
568 
569     fileMenu->Append(wxID_OPEN, _T("&Open\tCtrl+O"), _T("Open a file"));
570     fileMenu->Append(wxID_SAVE, _T("&Save\tCtrl+S"), _T("Save a file"));
571     fileMenu->Append(wxID_SAVEAS, _T("&Save As...\tF12"), _T("Save to a new file"));
572     fileMenu->AppendSeparator();
573     fileMenu->Append(ID_RELOAD, _T("&Reload Text\tF2"), _T("Reload the initial text"));
574     fileMenu->AppendSeparator();
575     fileMenu->Append(ID_PAGE_SETUP, _T("Page Set&up..."), _T("Page setup"));
576     fileMenu->Append(ID_PRINT, _T("&Print...\tCtrl+P"), _T("Print"));
577     fileMenu->Append(ID_PREVIEW, _T("Print Pre&view"), _T("Print preview"));
578     fileMenu->AppendSeparator();
579     fileMenu->Append(ID_VIEW_HTML, _T("&View as HTML"), _T("View HTML"));
580     fileMenu->AppendSeparator();
581     fileMenu->Append(ID_Quit, _T("E&xit\tAlt+X"), _T("Quit this program"));
582 
583     wxMenu* editMenu = new wxMenu;
584     editMenu->Append(wxID_UNDO, _("&Undo\tCtrl+Z"));
585     editMenu->Append(wxID_REDO, _("&Redo\tCtrl+Y"));
586     editMenu->AppendSeparator();
587     editMenu->Append(wxID_CUT, _("Cu&t\tCtrl+X"));
588     editMenu->Append(wxID_COPY, _("&Copy\tCtrl+C"));
589     editMenu->Append(wxID_PASTE, _("&Paste\tCtrl+V"));
590 
591     editMenu->AppendSeparator();
592     editMenu->Append(wxID_SELECTALL, _("Select A&ll\tCtrl+A"));
593 #if 0
594     editMenu->AppendSeparator();
595     editMenu->Append(wxID_FIND, _("&Find...\tCtrl+F"));
596     editMenu->Append(stID_FIND_REPLACE, _("&Replace...\tCtrl+R"));
597 #endif
598 
599     wxMenu* formatMenu = new wxMenu;
600     formatMenu->AppendCheckItem(ID_FORMAT_BOLD, _("&Bold\tCtrl+B"));
601     formatMenu->AppendCheckItem(ID_FORMAT_ITALIC, _("&Italic\tCtrl+I"));
602     formatMenu->AppendCheckItem(ID_FORMAT_UNDERLINE, _("&Underline\tCtrl+U"));
603     formatMenu->AppendSeparator();
604     formatMenu->AppendCheckItem(ID_FORMAT_ALIGN_LEFT, _("L&eft Align"));
605     formatMenu->AppendCheckItem(ID_FORMAT_ALIGN_RIGHT, _("&Right Align"));
606     formatMenu->AppendCheckItem(ID_FORMAT_ALIGN_CENTRE, _("&Centre"));
607     formatMenu->AppendSeparator();
608     formatMenu->Append(ID_FORMAT_INDENT_MORE, _("Indent &More"));
609     formatMenu->Append(ID_FORMAT_INDENT_LESS, _("Indent &Less"));
610     formatMenu->AppendSeparator();
611     formatMenu->Append(ID_FORMAT_PARAGRAPH_SPACING_MORE, _("Increase Paragraph &Spacing"));
612     formatMenu->Append(ID_FORMAT_PARAGRAPH_SPACING_LESS, _("Decrease &Paragraph Spacing"));
613     formatMenu->AppendSeparator();
614     formatMenu->Append(ID_FORMAT_LINE_SPACING_SINGLE, _("Normal Line Spacing"));
615     formatMenu->Append(ID_FORMAT_LINE_SPACING_HALF, _("1.5 Line Spacing"));
616     formatMenu->Append(ID_FORMAT_LINE_SPACING_DOUBLE, _("Double Line Spacing"));
617     formatMenu->AppendSeparator();
618     formatMenu->Append(ID_FORMAT_FONT, _("&Font..."));
619     formatMenu->Append(ID_FORMAT_PARAGRAPH, _("&Paragraph..."));
620     formatMenu->Append(ID_FORMAT_CONTENT, _("Font and Pa&ragraph...\tShift+Ctrl+F"));
621     formatMenu->AppendSeparator();
622     formatMenu->Append(ID_SWITCH_STYLE_SHEETS, _("&Switch Style Sheets"));
623     formatMenu->Append(ID_MANAGE_STYLES, _("&Manage Styles"));
624 
625     wxMenu* listsMenu = new wxMenu;
626     listsMenu->Append(ID_FORMAT_BULLETS_AND_NUMBERING, _("Bullets and &Numbering..."));
627     listsMenu->AppendSeparator();
628     listsMenu->Append(ID_FORMAT_NUMBER_LIST, _("Number List"));
629     listsMenu->Append(ID_FORMAT_ITEMIZE_LIST, _("Itemize List"));
630     listsMenu->Append(ID_FORMAT_RENUMBER_LIST, _("Renumber List"));
631     listsMenu->Append(ID_FORMAT_PROMOTE_LIST, _("Promote List Items"));
632     listsMenu->Append(ID_FORMAT_DEMOTE_LIST, _("Demote List Items"));
633     listsMenu->Append(ID_FORMAT_CLEAR_LIST, _("Clear List Formatting"));
634 
635     wxMenu* insertMenu = new wxMenu;
636     insertMenu->Append(ID_INSERT_SYMBOL, _("&Symbol...\tCtrl+I"));
637     insertMenu->Append(ID_INSERT_URL, _("&URL..."));
638 
639     // now append the freshly created menu to the menu bar...
640     wxMenuBar *menuBar = new wxMenuBar();
641     menuBar->Append(fileMenu, _T("&File"));
642     menuBar->Append(editMenu, _T("&Edit"));
643     menuBar->Append(formatMenu, _T("F&ormat"));
644     menuBar->Append(listsMenu, _T("&Lists"));
645     menuBar->Append(insertMenu, _T("&Insert"));
646     menuBar->Append(helpMenu, _T("&Help"));
647 
648     // ... and attach this menu bar to the frame
649     SetMenuBar(menuBar);
650 
651     // create a status bar just for fun (by default with 1 pane only)
652     // but don't create it on limited screen space (WinCE)
653     bool is_pda = wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA;
654 
655 #if wxUSE_STATUSBAR
656     if ( !is_pda )
657     {
658         CreateStatusBar(2);
659         SetStatusText(_T("Welcome to wxRichTextCtrl!"));
660     }
661 #endif
662 
663     wxToolBar* toolBar = CreateToolBar();
664 
665     toolBar->AddTool(wxID_OPEN, wxBitmap(open_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Open"));
666     toolBar->AddTool(wxID_SAVEAS, wxBitmap(save_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Save"));
667     toolBar->AddSeparator();
668     toolBar->AddTool(wxID_CUT, wxBitmap(cut_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Cut"));
669     toolBar->AddTool(wxID_COPY, wxBitmap(copy_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Copy"));
670     toolBar->AddTool(wxID_PASTE, wxBitmap(paste_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Paste"));
671     toolBar->AddSeparator();
672     toolBar->AddTool(wxID_UNDO, wxBitmap(undo_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Undo"));
673     toolBar->AddTool(wxID_REDO, wxBitmap(redo_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Redo"));
674     toolBar->AddSeparator();
675     toolBar->AddTool(ID_FORMAT_BOLD, wxBitmap(bold_xpm), wxNullBitmap, true, -1, -1, (wxObject *) NULL, _("Bold"));
676     toolBar->AddTool(ID_FORMAT_ITALIC, wxBitmap(italic_xpm), wxNullBitmap, true, -1, -1, (wxObject *) NULL, _("Italic"));
677     toolBar->AddTool(ID_FORMAT_UNDERLINE, wxBitmap(underline_xpm), wxNullBitmap, true, -1, -1, (wxObject *) NULL, _("Underline"));
678     toolBar->AddSeparator();
679     toolBar->AddTool(ID_FORMAT_ALIGN_LEFT, wxBitmap(alignleft_xpm), wxNullBitmap, true, -1, -1, (wxObject *) NULL, _("Align Left"));
680     toolBar->AddTool(ID_FORMAT_ALIGN_CENTRE, wxBitmap(centre_xpm), wxNullBitmap, true, -1, -1, (wxObject *) NULL, _("Centre"));
681     toolBar->AddTool(ID_FORMAT_ALIGN_RIGHT, wxBitmap(alignright_xpm), wxNullBitmap, true, -1, -1, (wxObject *) NULL, _("Align Right"));
682     toolBar->AddSeparator();
683     toolBar->AddTool(ID_FORMAT_INDENT_LESS, wxBitmap(indentless_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Indent Less"));
684     toolBar->AddTool(ID_FORMAT_INDENT_MORE, wxBitmap(indentmore_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Indent More"));
685     toolBar->AddSeparator();
686     toolBar->AddTool(ID_FORMAT_FONT, wxBitmap(font_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Font"));
687 
688     wxRichTextStyleComboCtrl* combo = new wxRichTextStyleComboCtrl(toolBar, ID_RICHTEXT_STYLE_COMBO, wxDefaultPosition, wxSize(200, -1));
689     toolBar->AddControl(combo);
690 
691     toolBar->Realize();
692 
693     wxSplitterWindow* splitter = new wxSplitterWindow(this, wxID_ANY, wxDefaultPosition, GetClientSize(), wxSP_NO_XP_THEME|wxSP_3D|wxSP_LIVE_UPDATE);
694 
695     wxFont textFont = wxFont(12, wxROMAN, wxNORMAL, wxNORMAL);
696     wxFont boldFont = wxFont(12, wxROMAN, wxNORMAL, wxBOLD);
697     wxFont italicFont = wxFont(12, wxROMAN, wxITALIC, wxNORMAL);
698 
699     m_richTextCtrl = new wxRichTextCtrl(splitter, ID_RICHTEXT_CTRL, wxEmptyString, wxDefaultPosition, wxSize(200, 200), wxVSCROLL|wxHSCROLL|wxNO_BORDER|wxWANTS_CHARS);
700     wxFont font(12, wxROMAN, wxNORMAL, wxNORMAL);
701 
702     m_richTextCtrl->SetFont(font);
703 
704     m_richTextCtrl->SetStyleSheet(wxGetApp().GetStyleSheet());
705 
706     combo->SetStyleSheet(wxGetApp().GetStyleSheet());
707     combo->SetRichTextCtrl(m_richTextCtrl);
708     combo->UpdateStyles();
709 
710     wxRichTextStyleListCtrl* styleListCtrl = new wxRichTextStyleListCtrl(splitter, ID_RICHTEXT_STYLE_LIST);
711 
712     wxSize display = wxGetDisplaySize();
713     if ( is_pda && ( display.GetWidth() < display.GetHeight() ) )
714     {
715         splitter->SplitHorizontally(m_richTextCtrl, styleListCtrl);
716     }
717     else
718     {
719         splitter->SplitVertically(m_richTextCtrl, styleListCtrl, 500);
720     }
721 
722     splitter->UpdateSize();
723 
724     styleListCtrl->SetStyleSheet(wxGetApp().GetStyleSheet());
725     styleListCtrl->SetRichTextCtrl(m_richTextCtrl);
726     styleListCtrl->UpdateStyles();
727 
728     WriteInitialText();
729 }
730 
731 // Write text
WriteInitialText()732 void MyFrame::WriteInitialText()
733 {
734     wxRichTextCtrl& r = *m_richTextCtrl;
735 
736     r.SetDefaultStyle(wxRichTextAttr());
737 
738     r.BeginSuppressUndo();
739 
740     r.BeginParagraphSpacing(0, 20);
741 
742     r.BeginAlignment(wxTEXT_ALIGNMENT_CENTRE);
743     r.BeginBold();
744 
745     r.BeginFontSize(14);
746 
747     wxString lineBreak = (wxChar) 29;
748 
749     r.WriteText(wxString(wxT("Welcome to wxRichTextCtrl, a wxWidgets control")) + lineBreak + wxT("for editing and presenting styled text and images\n"));
750     r.EndFontSize();
751     //r.Newline();
752 
753     r.BeginItalic();
754     r.WriteText(wxT("by Julian Smart"));
755     r.EndItalic();
756 
757     r.EndBold();
758     r.Newline();
759 
760     r.WriteImage(wxBitmap(zebra_xpm));
761 
762     r.Newline();
763     r.Newline();
764 
765     r.EndAlignment();
766 
767     r.WriteText(wxT("What can you do with this thing? "));
768 
769     r.WriteImage(wxBitmap(smiley_xpm));
770     r.WriteText(wxT(" Well, you can change text "));
771 
772     r.BeginTextColour(wxColour(255, 0, 0));
773     r.WriteText(wxT("colour, like this red bit."));
774     r.EndTextColour();
775 
776     wxRichTextAttr backgroundColourAttr;
777     backgroundColourAttr.SetBackgroundColour(*wxGREEN);
778     backgroundColourAttr.SetTextColour(wxColour(0, 0, 255));
779     r.BeginStyle(backgroundColourAttr);
780     r.WriteText(wxT(" And this blue on green bit."));
781     r.EndStyle();
782 
783     r.WriteText(wxT(" Naturally you can make things "));
784     r.BeginBold();
785     r.WriteText(wxT("bold "));
786     r.EndBold();
787     r.BeginItalic();
788     r.WriteText(wxT("or italic "));
789     r.EndItalic();
790     r.BeginUnderline();
791     r.WriteText(wxT("or underlined."));
792     r.EndUnderline();
793 
794     r.BeginFontSize(14);
795     r.WriteText(wxT(" Different font sizes on the same line is allowed, too."));
796     r.EndFontSize();
797 
798     r.WriteText(wxT(" Next we'll show an indented paragraph."));
799 
800     r.Newline();
801 
802     r.BeginLeftIndent(60);
803     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."));
804     r.Newline();
805 
806     r.EndLeftIndent();
807 
808     r.WriteText(wxT("Next, we'll show a first-line indent, achieved using BeginLeftIndent(100, -40)."));
809 
810     r.Newline();
811 
812     r.BeginLeftIndent(100, -40);
813 
814     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."));
815     r.Newline();
816 
817     r.EndLeftIndent();
818 
819     r.WriteText(wxT("Numbered bullets are possible, again using subindents:"));
820     r.Newline();
821 
822     r.BeginNumberedBullet(1, 100, 60);
823     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."));
824     r.Newline();
825 
826     r.EndNumberedBullet();
827 
828     r.BeginNumberedBullet(2, 100, 60);
829     r.WriteText(wxT("This is my second item."));
830     r.Newline();
831 
832     r.EndNumberedBullet();
833 
834     r.WriteText(wxT("The following paragraph is right-indented:"));
835     r.Newline();
836 
837     r.BeginRightIndent(200);
838 
839     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."));
840     r.Newline();
841 
842     r.EndRightIndent();
843 
844     r.WriteText(wxT("The following paragraph is right-aligned with 1.5 line spacing:"));
845     r.Newline();
846 
847     r.BeginAlignment(wxTEXT_ALIGNMENT_RIGHT);
848     r.BeginLineSpacing(wxTEXT_ATTR_LINE_SPACING_HALF);
849     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."));
850     r.Newline();
851     r.EndLineSpacing();
852     r.EndAlignment();
853 
854     wxArrayInt tabs;
855     tabs.Add(400);
856     tabs.Add(600);
857     tabs.Add(800);
858     tabs.Add(1000);
859     wxTextAttrEx attr;
860     attr.SetFlags(wxTEXT_ATTR_TABS);
861     attr.SetTabs(tabs);
862     r.SetDefaultStyle(attr);
863 
864     r.WriteText(wxT("This line contains tabs:\tFirst tab\tSecond tab\tThird tab"));
865     r.Newline();
866 
867     r.WriteText(wxT("Other notable features of wxRichTextCtrl include:"));
868     r.Newline();
869 
870     r.BeginSymbolBullet(wxT('*'), 100, 60);
871     r.WriteText(wxT("Compatibility with wxTextCtrl API"));
872     r.Newline();
873     r.EndSymbolBullet();
874 
875     r.BeginSymbolBullet(wxT('*'), 100, 60);
876     r.WriteText(wxT("Easy stack-based BeginXXX()...EndXXX() style setting in addition to SetStyle()"));
877     r.Newline();
878     r.EndSymbolBullet();
879 
880     r.BeginSymbolBullet(wxT('*'), 100, 60);
881     r.WriteText(wxT("XML loading and saving"));
882     r.Newline();
883     r.EndSymbolBullet();
884 
885     r.BeginSymbolBullet(wxT('*'), 100, 60);
886     r.WriteText(wxT("Undo/Redo, with batching option and Undo suppressing"));
887     r.Newline();
888     r.EndSymbolBullet();
889 
890     r.BeginSymbolBullet(wxT('*'), 100, 60);
891     r.WriteText(wxT("Clipboard copy and paste"));
892     r.Newline();
893     r.EndSymbolBullet();
894 
895     r.BeginSymbolBullet(wxT('*'), 100, 60);
896     r.WriteText(wxT("wxRichTextStyleSheet with named character and paragraph styles, and control for applying named styles"));
897     r.Newline();
898     r.EndSymbolBullet();
899 
900     r.BeginSymbolBullet(wxT('*'), 100, 60);
901     r.WriteText(wxT("A design that can easily be extended to other content types, ultimately with text boxes, tables, controls, and so on"));
902     r.Newline();
903     r.EndSymbolBullet();
904 
905     // Make a style suitable for showing a URL
906     wxRichTextAttr urlStyle;
907     urlStyle.SetTextColour(*wxBLUE);
908     urlStyle.SetFontUnderlined(true);
909 
910     r.WriteText(wxT("wxRichTextCtrl can also display URLs, such as this one: "));
911     r.BeginStyle(urlStyle);
912     r.BeginURL(wxT("http://www.wxwidgets.org"));
913     r.WriteText(wxT("The wxWidgets Web Site"));
914     r.EndURL();
915     r.EndStyle();
916     r.WriteText(wxT(". Click on the URL to generate an event."));
917 
918     r.Newline();
919 
920     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!"));
921 
922     r.Newline();
923 
924     r.EndParagraphSpacing();
925 
926     r.EndSuppressUndo();
927 }
928 
929 
930 // event handlers
931 
OnQuit(wxCommandEvent & WXUNUSED (event))932 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
933 {
934     // true is to force the frame to close
935     Close(true);
936 }
937 
OnAbout(wxCommandEvent & WXUNUSED (event))938 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
939 {
940     wxString msg;
941     msg.Printf( _T("This is a demo for wxRichTextCtrl, a control for editing styled text.\n(c) Julian Smart, 2005"));
942     wxMessageBox(msg, _T("About wxRichTextCtrl Sample"), wxOK | wxICON_INFORMATION, this);
943 }
944 
945 // Forward command events to the current rich text control, if any
ProcessEvent(wxEvent & event)946 bool MyFrame::ProcessEvent(wxEvent& event)
947 {
948     if (event.IsCommandEvent() && !event.IsKindOf(CLASSINFO(wxChildFocusEvent)))
949     {
950         // Problem: we can get infinite recursion because the events
951         // climb back up to this frame, and repeat.
952         // Assume that command events don't cause another command event
953         // to be called, so we can rely on inCommand not being overwritten
954 
955         static int s_eventType = 0;
956         static wxWindowID s_id = 0;
957 
958         if (s_id != event.GetId() && s_eventType != event.GetEventType())
959         {
960             s_eventType = event.GetEventType();
961             s_id = event.GetId();
962 
963             wxWindow* focusWin = wxFindFocusDescendant(this);
964             if (focusWin && focusWin->ProcessEvent(event))
965             {
966                 //s_command = NULL;
967                 s_eventType = 0;
968                 s_id = 0;
969                 return true;
970             }
971 
972             s_eventType = 0;
973             s_id = 0;
974         }
975         else
976         {
977             return false;
978         }
979     }
980 
981     return wxFrame::ProcessEvent(event);
982 }
983 
OnOpen(wxCommandEvent & WXUNUSED (event))984 void MyFrame::OnOpen(wxCommandEvent& WXUNUSED(event))
985 {
986     wxString path;
987     wxString filename;
988     wxArrayInt fileTypes;
989 
990     wxString filter = wxRichTextBuffer::GetExtWildcard(false, false, & fileTypes);
991     if (!filter.empty())
992         filter += wxT("|");
993     filter += wxT("All files (*.*)|*.*");
994 
995     wxFileDialog dialog(this,
996         _("Choose a filename"),
997         path,
998         filename,
999         filter,
1000         wxFD_OPEN);
1001 
1002     if (dialog.ShowModal() == wxID_OK)
1003     {
1004         wxString path = dialog.GetPath();
1005 
1006         if (!path.empty())
1007         {
1008             int filterIndex = dialog.GetFilterIndex();
1009             int fileType = (filterIndex < (int) fileTypes.GetCount())
1010                            ? fileTypes[filterIndex]
1011                            : wxRICHTEXT_TYPE_TEXT;
1012             m_richTextCtrl->LoadFile(path, fileType);
1013         }
1014     }
1015 }
1016 
OnSave(wxCommandEvent & event)1017 void MyFrame::OnSave(wxCommandEvent& event)
1018 {
1019     if (m_richTextCtrl->GetFilename().empty())
1020     {
1021         OnSaveAs(event);
1022         return;
1023     }
1024     m_richTextCtrl->SaveFile();
1025 }
1026 
OnSaveAs(wxCommandEvent & WXUNUSED (event))1027 void MyFrame::OnSaveAs(wxCommandEvent& WXUNUSED(event))
1028 {
1029     wxString filter = wxRichTextBuffer::GetExtWildcard(false, true);
1030     wxString path;
1031     wxString filename;
1032 
1033     wxFileDialog dialog(this,
1034         _("Choose a filename"),
1035         path,
1036         filename,
1037         filter,
1038         wxFD_SAVE);
1039 
1040     if (dialog.ShowModal() == wxID_OK)
1041     {
1042         wxString path = dialog.GetPath();
1043 
1044         if (!path.empty())
1045         {
1046             m_richTextCtrl->SaveFile(path);
1047         }
1048     }
1049 }
1050 
OnBold(wxCommandEvent & WXUNUSED (event))1051 void MyFrame::OnBold(wxCommandEvent& WXUNUSED(event))
1052 {
1053     m_richTextCtrl->ApplyBoldToSelection();
1054 }
1055 
OnItalic(wxCommandEvent & WXUNUSED (event))1056 void MyFrame::OnItalic(wxCommandEvent& WXUNUSED(event))
1057 {
1058     m_richTextCtrl->ApplyItalicToSelection();
1059 }
1060 
OnUnderline(wxCommandEvent & WXUNUSED (event))1061 void MyFrame::OnUnderline(wxCommandEvent& WXUNUSED(event))
1062 {
1063     m_richTextCtrl->ApplyUnderlineToSelection();
1064 }
1065 
1066 
OnUpdateBold(wxUpdateUIEvent & event)1067 void MyFrame::OnUpdateBold(wxUpdateUIEvent& event)
1068 {
1069     event.Check(m_richTextCtrl->IsSelectionBold());
1070 }
1071 
OnUpdateItalic(wxUpdateUIEvent & event)1072 void MyFrame::OnUpdateItalic(wxUpdateUIEvent& event)
1073 {
1074     event.Check(m_richTextCtrl->IsSelectionItalics());
1075 }
1076 
OnUpdateUnderline(wxUpdateUIEvent & event)1077 void MyFrame::OnUpdateUnderline(wxUpdateUIEvent& event)
1078 {
1079     event.Check(m_richTextCtrl->IsSelectionUnderlined());
1080 }
1081 
OnAlignLeft(wxCommandEvent & WXUNUSED (event))1082 void MyFrame::OnAlignLeft(wxCommandEvent& WXUNUSED(event))
1083 {
1084     m_richTextCtrl->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_LEFT);
1085 }
1086 
OnAlignCentre(wxCommandEvent & WXUNUSED (event))1087 void MyFrame::OnAlignCentre(wxCommandEvent& WXUNUSED(event))
1088 {
1089     m_richTextCtrl->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_CENTRE);
1090 }
1091 
OnAlignRight(wxCommandEvent & WXUNUSED (event))1092 void MyFrame::OnAlignRight(wxCommandEvent& WXUNUSED(event))
1093 {
1094     m_richTextCtrl->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_RIGHT);
1095 }
1096 
OnUpdateAlignLeft(wxUpdateUIEvent & event)1097 void MyFrame::OnUpdateAlignLeft(wxUpdateUIEvent& event)
1098 {
1099     event.Check(m_richTextCtrl->IsSelectionAligned(wxTEXT_ALIGNMENT_LEFT));
1100 }
1101 
OnUpdateAlignCentre(wxUpdateUIEvent & event)1102 void MyFrame::OnUpdateAlignCentre(wxUpdateUIEvent& event)
1103 {
1104     event.Check(m_richTextCtrl->IsSelectionAligned(wxTEXT_ALIGNMENT_CENTRE));
1105 }
1106 
OnUpdateAlignRight(wxUpdateUIEvent & event)1107 void MyFrame::OnUpdateAlignRight(wxUpdateUIEvent& event)
1108 {
1109     event.Check(m_richTextCtrl->IsSelectionAligned(wxTEXT_ALIGNMENT_RIGHT));
1110 }
1111 
OnFont(wxCommandEvent & WXUNUSED (event))1112 void MyFrame::OnFont(wxCommandEvent& WXUNUSED(event))
1113 {
1114     wxRichTextRange range;
1115     if (m_richTextCtrl->HasSelection())
1116         range = m_richTextCtrl->GetSelectionRange();
1117     else
1118         range = wxRichTextRange(0, m_richTextCtrl->GetLastPosition()+1);
1119 
1120     int pages = wxRICHTEXT_FORMAT_FONT;
1121 
1122     wxRichTextFormattingDialog formatDlg(pages, this);
1123     formatDlg.GetStyle(m_richTextCtrl, range);
1124 
1125     if (formatDlg.ShowModal() == wxID_OK)
1126     {
1127         formatDlg.ApplyStyle(m_richTextCtrl, range, wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_OPTIMIZE|wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY);
1128     }
1129 
1130     // Old method using wxFontDialog
1131 #if 0
1132     if (!m_richTextCtrl->HasSelection())
1133         return;
1134 
1135     wxRichTextRange range = m_richTextCtrl->GetSelectionRange();
1136     wxFontData fontData;
1137 
1138     wxTextAttrEx attr;
1139     attr.SetFlags(wxTEXT_ATTR_FONT);
1140 
1141     if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
1142         fontData.SetInitialFont(attr.GetFont());
1143 
1144     wxFontDialog dialog(this, fontData);
1145     if (dialog.ShowModal() == wxID_OK)
1146     {
1147         fontData = dialog.GetFontData();
1148         attr.SetFlags(wxTEXT_ATTR_FONT);
1149         attr.SetFont(fontData.GetChosenFont());
1150         if (attr.GetFont().Ok())
1151         {
1152             m_richTextCtrl->SetStyle(range, attr);
1153         }
1154     }
1155 #endif
1156 }
1157 
OnParagraph(wxCommandEvent & WXUNUSED (event))1158 void MyFrame::OnParagraph(wxCommandEvent& WXUNUSED(event))
1159 {
1160     wxRichTextRange range;
1161     if (m_richTextCtrl->HasSelection())
1162         range = m_richTextCtrl->GetSelectionRange();
1163     else
1164         range = wxRichTextRange(0, m_richTextCtrl->GetLastPosition()+1);
1165 
1166     int pages = wxRICHTEXT_FORMAT_INDENTS_SPACING|wxRICHTEXT_FORMAT_TABS|wxRICHTEXT_FORMAT_BULLETS;
1167 
1168     wxRichTextFormattingDialog formatDlg(pages, this);
1169     formatDlg.GetStyle(m_richTextCtrl, range);
1170 
1171     if (formatDlg.ShowModal() == wxID_OK)
1172     {
1173         formatDlg.ApplyStyle(m_richTextCtrl, range);
1174     }
1175 }
1176 
OnFormat(wxCommandEvent & WXUNUSED (event))1177 void MyFrame::OnFormat(wxCommandEvent& WXUNUSED(event))
1178 {
1179     wxRichTextRange range;
1180     if (m_richTextCtrl->HasSelection())
1181         range = m_richTextCtrl->GetSelectionRange();
1182     else
1183         range = wxRichTextRange(0, m_richTextCtrl->GetLastPosition()+1);
1184 
1185     int pages = wxRICHTEXT_FORMAT_FONT|wxRICHTEXT_FORMAT_INDENTS_SPACING|wxRICHTEXT_FORMAT_TABS|wxRICHTEXT_FORMAT_BULLETS;
1186 
1187     wxRichTextFormattingDialog formatDlg(pages, this);
1188     formatDlg.GetStyle(m_richTextCtrl, range);
1189 
1190     if (formatDlg.ShowModal() == wxID_OK)
1191     {
1192         formatDlg.ApplyStyle(m_richTextCtrl, range);
1193     }
1194 }
1195 
OnUpdateFormat(wxUpdateUIEvent & event)1196 void MyFrame::OnUpdateFormat(wxUpdateUIEvent& event)
1197 {
1198     event.Enable(m_richTextCtrl->HasSelection());
1199 }
1200 
OnIndentMore(wxCommandEvent & WXUNUSED (event))1201 void MyFrame::OnIndentMore(wxCommandEvent& WXUNUSED(event))
1202 {
1203     wxTextAttrEx attr;
1204     attr.SetFlags(wxTEXT_ATTR_LEFT_INDENT);
1205 
1206     if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
1207     {
1208         wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
1209         if (m_richTextCtrl->HasSelection())
1210             range = m_richTextCtrl->GetSelectionRange();
1211 
1212         attr.SetLeftIndent(attr.GetLeftIndent() + 100);
1213 
1214         attr.SetFlags(wxTEXT_ATTR_LEFT_INDENT);
1215         m_richTextCtrl->SetStyle(range, attr);
1216     }
1217 }
1218 
OnIndentLess(wxCommandEvent & WXUNUSED (event))1219 void MyFrame::OnIndentLess(wxCommandEvent& WXUNUSED(event))
1220 {
1221     wxTextAttrEx attr;
1222     attr.SetFlags(wxTEXT_ATTR_LEFT_INDENT);
1223 
1224     if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
1225     {
1226         wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
1227         if (m_richTextCtrl->HasSelection())
1228             range = m_richTextCtrl->GetSelectionRange();
1229 
1230         if (attr.GetLeftIndent() > 0)
1231         {
1232             attr.SetLeftIndent(wxMax(0, attr.GetLeftIndent() - 100));
1233 
1234             m_richTextCtrl->SetStyle(range, attr);
1235         }
1236     }
1237 }
1238 
OnLineSpacingHalf(wxCommandEvent & WXUNUSED (event))1239 void MyFrame::OnLineSpacingHalf(wxCommandEvent& WXUNUSED(event))
1240 {
1241     wxTextAttrEx attr;
1242     attr.SetFlags(wxTEXT_ATTR_LINE_SPACING);
1243 
1244     if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
1245     {
1246         wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
1247         if (m_richTextCtrl->HasSelection())
1248             range = m_richTextCtrl->GetSelectionRange();
1249 
1250         attr.SetFlags(wxTEXT_ATTR_LINE_SPACING);
1251         attr.SetLineSpacing(15);
1252 
1253         m_richTextCtrl->SetStyle(range, attr);
1254     }
1255 }
1256 
OnLineSpacingDouble(wxCommandEvent & WXUNUSED (event))1257 void MyFrame::OnLineSpacingDouble(wxCommandEvent& WXUNUSED(event))
1258 {
1259     wxTextAttrEx attr;
1260     attr.SetFlags(wxTEXT_ATTR_LINE_SPACING);
1261 
1262     if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
1263     {
1264         wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
1265         if (m_richTextCtrl->HasSelection())
1266             range = m_richTextCtrl->GetSelectionRange();
1267 
1268         attr.SetFlags(wxTEXT_ATTR_LINE_SPACING);
1269         attr.SetLineSpacing(20);
1270 
1271         m_richTextCtrl->SetStyle(range, attr);
1272     }
1273 }
1274 
OnLineSpacingSingle(wxCommandEvent & WXUNUSED (event))1275 void MyFrame::OnLineSpacingSingle(wxCommandEvent& WXUNUSED(event))
1276 {
1277     wxTextAttrEx attr;
1278     attr.SetFlags(wxTEXT_ATTR_LINE_SPACING);
1279 
1280     if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
1281     {
1282         wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
1283         if (m_richTextCtrl->HasSelection())
1284             range = m_richTextCtrl->GetSelectionRange();
1285 
1286         attr.SetFlags(wxTEXT_ATTR_LINE_SPACING);
1287         attr.SetLineSpacing(0); // Can also use 10
1288 
1289         m_richTextCtrl->SetStyle(range, attr);
1290     }
1291 }
1292 
OnParagraphSpacingMore(wxCommandEvent & WXUNUSED (event))1293 void MyFrame::OnParagraphSpacingMore(wxCommandEvent& WXUNUSED(event))
1294 {
1295     wxTextAttrEx attr;
1296     attr.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER);
1297 
1298     if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
1299     {
1300         wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
1301         if (m_richTextCtrl->HasSelection())
1302             range = m_richTextCtrl->GetSelectionRange();
1303 
1304         attr.SetParagraphSpacingAfter(attr.GetParagraphSpacingAfter() + 20);
1305 
1306         attr.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER);
1307         m_richTextCtrl->SetStyle(range, attr);
1308     }
1309 }
1310 
OnParagraphSpacingLess(wxCommandEvent & WXUNUSED (event))1311 void MyFrame::OnParagraphSpacingLess(wxCommandEvent& WXUNUSED(event))
1312 {
1313     wxTextAttrEx attr;
1314     attr.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER);
1315 
1316     if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
1317     {
1318         wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
1319         if (m_richTextCtrl->HasSelection())
1320             range = m_richTextCtrl->GetSelectionRange();
1321 
1322         if (attr.GetParagraphSpacingAfter() >= 20)
1323         {
1324             attr.SetParagraphSpacingAfter(attr.GetParagraphSpacingAfter() - 20);
1325 
1326             attr.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER);
1327             m_richTextCtrl->SetStyle(range, attr);
1328         }
1329     }
1330 }
1331 
OnReload(wxCommandEvent & WXUNUSED (event))1332 void MyFrame::OnReload(wxCommandEvent& WXUNUSED(event))
1333 {
1334     m_richTextCtrl->Clear();
1335     WriteInitialText();
1336 }
1337 
OnViewHTML(wxCommandEvent & WXUNUSED (event))1338 void MyFrame::OnViewHTML(wxCommandEvent& WXUNUSED(event))
1339 {
1340     wxDialog dialog(this, wxID_ANY, _("HTML"), wxDefaultPosition, wxSize(500, 400), wxDEFAULT_DIALOG_STYLE);
1341 
1342     wxBoxSizer* boxSizer = new wxBoxSizer(wxVERTICAL);
1343     dialog.SetSizer(boxSizer);
1344 
1345     wxHtmlWindow* win = new wxHtmlWindow(& dialog, wxID_ANY, wxDefaultPosition, wxSize(500, 400), wxSUNKEN_BORDER);
1346     boxSizer->Add(win, 1, wxALL, 5);
1347 
1348     wxButton* cancelButton = new wxButton(& dialog, wxID_CANCEL, wxT("&Close"));
1349     boxSizer->Add(cancelButton, 0, wxALL|wxCENTRE, 5);
1350 
1351     wxString text;
1352     wxStringOutputStream strStream(& text);
1353 
1354     wxRichTextHTMLHandler htmlHandler;
1355     htmlHandler.SetFlags(wxRICHTEXT_HANDLER_SAVE_IMAGES_TO_MEMORY);
1356 
1357     wxArrayInt fontSizeMapping;
1358     fontSizeMapping.Add(7);
1359     fontSizeMapping.Add(9);
1360     fontSizeMapping.Add(11);
1361     fontSizeMapping.Add(12);
1362     fontSizeMapping.Add(14);
1363     fontSizeMapping.Add(22);
1364     fontSizeMapping.Add(100);
1365 
1366     htmlHandler.SetFontSizeMapping(fontSizeMapping);
1367 
1368     if (htmlHandler.SaveFile(& m_richTextCtrl->GetBuffer(), strStream))
1369     {
1370         win->SetPage(text);
1371     }
1372 
1373     boxSizer->Fit(& dialog);
1374 
1375     dialog.ShowModal();
1376 
1377     // Now delete the temporary in-memory images
1378     htmlHandler.DeleteTemporaryImages();
1379 }
1380 
1381 // Demonstrates how you can change the style sheets and have the changes
1382 // reflected in the control content without wiping out character formatting.
1383 
OnSwitchStyleSheets(wxCommandEvent & WXUNUSED (event))1384 void MyFrame::OnSwitchStyleSheets(wxCommandEvent& WXUNUSED(event))
1385 {
1386     static wxRichTextStyleSheet* gs_AlternateStyleSheet = NULL;
1387 
1388     wxRichTextStyleListCtrl *styleList = (wxRichTextStyleListCtrl*) FindWindow(ID_RICHTEXT_STYLE_LIST);
1389     wxRichTextStyleComboCtrl* styleCombo = (wxRichTextStyleComboCtrl*) FindWindow(ID_RICHTEXT_STYLE_COMBO);
1390 
1391     wxRichTextStyleSheet* sheet = m_richTextCtrl->GetStyleSheet();
1392 
1393     // One-time creation of an alternate style sheet
1394     if (!gs_AlternateStyleSheet)
1395     {
1396         gs_AlternateStyleSheet = new wxRichTextStyleSheet(*sheet);
1397 
1398         // Make some modifications
1399         for (int i = 0; i < (int) gs_AlternateStyleSheet->GetParagraphStyleCount(); i++)
1400         {
1401             wxRichTextParagraphStyleDefinition* def = gs_AlternateStyleSheet->GetParagraphStyle(i);
1402 
1403             if (def->GetStyle().HasTextColour())
1404                 def->GetStyle().SetTextColour(*wxBLUE);
1405 
1406             if (def->GetStyle().HasAlignment())
1407             {
1408                 if (def->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_CENTRE)
1409                     def->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_RIGHT);
1410                 else if (def->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_LEFT)
1411                     def->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_CENTRE);
1412             }
1413             if (def->GetStyle().HasLeftIndent())
1414             {
1415                 def->GetStyle().SetLeftIndent(def->GetStyle().GetLeftIndent() * 2);
1416             }
1417         }
1418     }
1419 
1420     // Switch sheets
1421     wxRichTextStyleSheet* tmp = gs_AlternateStyleSheet;
1422     gs_AlternateStyleSheet = sheet;
1423     sheet = tmp;
1424 
1425     m_richTextCtrl->SetStyleSheet(sheet);
1426     m_richTextCtrl->ApplyStyleSheet(sheet); // Makes the control reflect the new style definitions
1427 
1428     styleList->SetStyleSheet(sheet);
1429     styleList->UpdateStyles();
1430 
1431     styleCombo->SetStyleSheet(sheet);
1432     styleCombo->UpdateStyles();
1433 }
1434 
OnManageStyles(wxCommandEvent & WXUNUSED (event))1435 void MyFrame::OnManageStyles(wxCommandEvent& WXUNUSED(event))
1436 {
1437     wxRichTextStyleSheet* sheet = m_richTextCtrl->GetStyleSheet();
1438 
1439     int flags = wxRICHTEXT_ORGANISER_CREATE_STYLES|wxRICHTEXT_ORGANISER_EDIT_STYLES;
1440 
1441     wxRichTextStyleOrganiserDialog dlg(flags, sheet, NULL, this, wxID_ANY, _("Style Manager"));
1442     dlg.ShowModal();
1443 }
1444 
OnInsertSymbol(wxCommandEvent & WXUNUSED (event))1445 void MyFrame::OnInsertSymbol(wxCommandEvent& WXUNUSED(event))
1446 {
1447     wxTextAttrEx attr;
1448     attr.SetFlags(wxTEXT_ATTR_FONT);
1449     m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr);
1450 
1451     wxString currentFontName;
1452     if (attr.HasFont() && attr.GetFont().Ok())
1453         currentFontName = attr.GetFont().GetFaceName();
1454 
1455     // Don't set the initial font in the dialog (so the user is choosing
1456     // 'normal text', i.e. the current font) but do tell the dialog
1457     // what 'normal text' is.
1458 
1459     wxSymbolPickerDialog dlg(wxT("*"), wxEmptyString, currentFontName, this);
1460 
1461     if (dlg.ShowModal() == wxID_OK)
1462     {
1463         if (dlg.HasSelection())
1464         {
1465             long insertionPoint = m_richTextCtrl->GetInsertionPoint();
1466 
1467             m_richTextCtrl->WriteText(dlg.GetSymbol());
1468 
1469             if (!dlg.UseNormalFont())
1470             {
1471                 wxFont font(attr.GetFont());
1472                 font.SetFaceName(dlg.GetFontName());
1473                 attr.SetFont(font);
1474                 m_richTextCtrl->SetStyle(insertionPoint, insertionPoint+1, attr);
1475             }
1476         }
1477     }
1478 }
1479 
OnNumberList(wxCommandEvent & WXUNUSED (event))1480 void MyFrame::OnNumberList(wxCommandEvent& WXUNUSED(event))
1481 {
1482     if (m_richTextCtrl->HasSelection())
1483     {
1484         wxRichTextRange range = m_richTextCtrl->GetSelectionRange();
1485         m_richTextCtrl->SetListStyle(range, wxT("Numbered List 1"), wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_RENUMBER);
1486     }
1487 }
1488 
OnBulletsAndNumbering(wxCommandEvent & WXUNUSED (event))1489 void MyFrame::OnBulletsAndNumbering(wxCommandEvent& WXUNUSED(event))
1490 {
1491     wxRichTextStyleSheet* sheet = m_richTextCtrl->GetStyleSheet();
1492 
1493     int flags = wxRICHTEXT_ORGANISER_BROWSE_NUMBERING;
1494 
1495     wxRichTextStyleOrganiserDialog dlg(flags, sheet, m_richTextCtrl, this, wxID_ANY, _("Bullets and Numbering"));
1496     if (dlg.ShowModal() == wxID_OK)
1497     {
1498         if (dlg.GetSelectedStyleDefinition())
1499             dlg.ApplyStyle();
1500     }
1501 }
1502 
OnItemizeList(wxCommandEvent & WXUNUSED (event))1503 void MyFrame::OnItemizeList(wxCommandEvent& WXUNUSED(event))
1504 {
1505     if (m_richTextCtrl->HasSelection())
1506     {
1507         wxRichTextRange range = m_richTextCtrl->GetSelectionRange();
1508         m_richTextCtrl->SetListStyle(range, wxT("Bullet List 1"));
1509     }
1510 }
1511 
OnRenumberList(wxCommandEvent & WXUNUSED (event))1512 void MyFrame::OnRenumberList(wxCommandEvent& WXUNUSED(event))
1513 {
1514     if (m_richTextCtrl->HasSelection())
1515     {
1516         wxRichTextRange range = m_richTextCtrl->GetSelectionRange();
1517         m_richTextCtrl->NumberList(range, NULL, wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_RENUMBER);
1518     }
1519 }
1520 
OnPromoteList(wxCommandEvent & WXUNUSED (event))1521 void MyFrame::OnPromoteList(wxCommandEvent& WXUNUSED(event))
1522 {
1523     if (m_richTextCtrl->HasSelection())
1524     {
1525         wxRichTextRange range = m_richTextCtrl->GetSelectionRange();
1526         m_richTextCtrl->PromoteList(1, range, NULL);
1527     }
1528 }
1529 
OnDemoteList(wxCommandEvent & WXUNUSED (event))1530 void MyFrame::OnDemoteList(wxCommandEvent& WXUNUSED(event))
1531 {
1532     if (m_richTextCtrl->HasSelection())
1533     {
1534         wxRichTextRange range = m_richTextCtrl->GetSelectionRange();
1535         m_richTextCtrl->PromoteList(-1, range, NULL);
1536     }
1537 }
1538 
OnClearList(wxCommandEvent & WXUNUSED (event))1539 void MyFrame::OnClearList(wxCommandEvent& WXUNUSED(event))
1540 {
1541     if (m_richTextCtrl->HasSelection())
1542     {
1543         wxRichTextRange range = m_richTextCtrl->GetSelectionRange();
1544         m_richTextCtrl->ClearListStyle(range);
1545     }
1546 }
1547 
OnInsertURL(wxCommandEvent & WXUNUSED (event))1548 void MyFrame::OnInsertURL(wxCommandEvent& WXUNUSED(event))
1549 {
1550     wxString url = wxGetTextFromUser(_("URL:"), _("Insert URL"));
1551     if (!url.IsEmpty())
1552     {
1553         // Make a style suitable for showing a URL
1554         wxRichTextAttr urlStyle;
1555         urlStyle.SetTextColour(*wxBLUE);
1556         urlStyle.SetFontUnderlined(true);
1557 
1558         m_richTextCtrl->BeginStyle(urlStyle);
1559         m_richTextCtrl->BeginURL(url);
1560         m_richTextCtrl->WriteText(url);
1561         m_richTextCtrl->EndURL();
1562         m_richTextCtrl->EndStyle();
1563     }
1564 }
1565 
OnURL(wxTextUrlEvent & event)1566 void MyFrame::OnURL(wxTextUrlEvent& event)
1567 {
1568     wxMessageBox(event.GetString());
1569 }
1570 
1571 // Veto style sheet replace events when loading from XML, since we want
1572 // to keep the original style sheet.
OnStyleSheetReplacing(wxRichTextEvent & event)1573 void MyFrame::OnStyleSheetReplacing(wxRichTextEvent& event)
1574 {
1575     event.Veto();
1576 }
1577 
OnPrint(wxCommandEvent & WXUNUSED (event))1578 void MyFrame::OnPrint(wxCommandEvent& WXUNUSED(event))
1579 {
1580     wxGetApp().GetPrinting()->PrintBuffer(m_richTextCtrl->GetBuffer());
1581 }
1582 
OnPreview(wxCommandEvent & WXUNUSED (event))1583 void MyFrame::OnPreview(wxCommandEvent& WXUNUSED(event))
1584 {
1585     wxGetApp().GetPrinting()->PreviewBuffer(m_richTextCtrl->GetBuffer());
1586 }
1587 
OnPageSetup(wxCommandEvent & WXUNUSED (event))1588 void MyFrame::OnPageSetup(wxCommandEvent& WXUNUSED(event))
1589 {
1590     wxGetApp().GetPrinting()->PageSetup();
1591 }
1592