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