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