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