]> git.saurik.com Git - wxWidgets.git/blame - samples/richtext/richtext.cpp
Changes needed for scanning the aui header files with SWIG for
[wxWidgets.git] / samples / richtext / richtext.cpp
CommitLineData
5d7836c4 1/////////////////////////////////////////////////////////////////////////////
dbf38e88 2// Name: samples/richtext/richtext.cpp
5d7836c4
JS
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#include "bitmaps/sample.xpm"
39#include "bitmaps/smiley.xpm"
40// #include "bitmaps/idea.xpm"
41#include "bitmaps/zebra.xpm"
42
43#include "bitmaps/open.xpm"
44#include "bitmaps/save.xpm"
45#include "bitmaps/copy.xpm"
46#include "bitmaps/cut.xpm"
47#include "bitmaps/paste.xpm"
48#include "bitmaps/undo.xpm"
49#include "bitmaps/redo.xpm"
50#include "bitmaps/bold.xpm"
51#include "bitmaps/italic.xpm"
52#include "bitmaps/underline.xpm"
53
54#include "bitmaps/alignleft.xpm"
55#include "bitmaps/alignright.xpm"
56#include "bitmaps/centre.xpm"
57#include "bitmaps/font.xpm"
58#include "bitmaps/indentless.xpm"
59#include "bitmaps/indentmore.xpm"
60
011b3dcb
JS
61#include "wx/richtext/richtextctrl.h"
62#include "wx/richtext/richtextstyles.h"
63#include "wx/richtext/richtextxml.h"
b71e9aa4 64#include "wx/richtext/richtexthtml.h"
5d7836c4
JS
65
66// ----------------------------------------------------------------------------
67// resources
68// ----------------------------------------------------------------------------
69
70// ----------------------------------------------------------------------------
71// private classes
72// ----------------------------------------------------------------------------
73
74// Define a new application type, each program should derive a class from wxApp
75class MyApp : public wxApp
76{
77public:
78 // override base class virtuals
79 // ----------------------------
80
81 // this one is called on application startup and is a good place for the app
82 // initialization (doing it here and not in the ctor allows to have an error
83 // return: if OnInit() returns false, the application terminates)
84 virtual bool OnInit();
85 virtual int OnExit();
86
87 void CreateStyles();
88
89 wxRichTextStyleSheet* GetStyleSheet() const { return m_styleSheet; }
90
91 wxRichTextStyleSheet* m_styleSheet;
92};
93
94// Define a new frame type: this is going to be our main frame
95class MyFrame : public wxFrame
96{
97public:
98 // ctor(s)
99 MyFrame(const wxString& title, wxWindowID id, const wxPoint& pos = wxDefaultPosition,
100 const wxSize& size = wxDefaultSize, long style = wxDEFAULT_FRAME_STYLE);
101
102 // event handlers (these functions should _not_ be virtual)
103 void OnQuit(wxCommandEvent& event);
104 void OnAbout(wxCommandEvent& event);
105
106 void OnOpen(wxCommandEvent& event);
107 void OnSave(wxCommandEvent& event);
108 void OnSaveAs(wxCommandEvent& event);
109
110 void OnBold(wxCommandEvent& event);
111 void OnItalic(wxCommandEvent& event);
112 void OnUnderline(wxCommandEvent& event);
113
114 void OnUpdateBold(wxUpdateUIEvent& event);
115 void OnUpdateItalic(wxUpdateUIEvent& event);
116 void OnUpdateUnderline(wxUpdateUIEvent& event);
117
118 void OnAlignLeft(wxCommandEvent& event);
119 void OnAlignCentre(wxCommandEvent& event);
120 void OnAlignRight(wxCommandEvent& event);
121
122 void OnUpdateAlignLeft(wxUpdateUIEvent& event);
123 void OnUpdateAlignCentre(wxUpdateUIEvent& event);
124 void OnUpdateAlignRight(wxUpdateUIEvent& event);
125
126 void OnFont(wxCommandEvent& event);
127 void OnIndentMore(wxCommandEvent& event);
128 void OnIndentLess(wxCommandEvent& event);
129
130 void OnLineSpacingHalf(wxCommandEvent& event);
131 void OnLineSpacingDouble(wxCommandEvent& event);
132 void OnLineSpacingSingle(wxCommandEvent& event);
133
134 void OnParagraphSpacingMore(wxCommandEvent& event);
135 void OnParagraphSpacingLess(wxCommandEvent& event);
136
137 void OnViewHTML(wxCommandEvent& event);
138
139 // Forward command events to the current rich text control, if any
140 bool ProcessEvent(wxEvent& event);
141
142private:
143 // any class wishing to process wxWidgets events must use this macro
144 DECLARE_EVENT_TABLE()
145
146 wxRichTextCtrl* m_richTextCtrl;
147};
148
149// ----------------------------------------------------------------------------
150// constants
151// ----------------------------------------------------------------------------
152
153// IDs for the controls and the menu commands
154enum
155{
156 // menu items
157 ID_Quit = wxID_EXIT,
158 ID_About = wxID_ABOUT,
159
160 ID_FORMAT_BOLD = 100,
161 ID_FORMAT_ITALIC,
162 ID_FORMAT_UNDERLINE,
163 ID_FORMAT_FONT,
164
165 ID_FORMAT_ALIGN_LEFT,
166 ID_FORMAT_ALIGN_CENTRE,
167 ID_FORMAT_ALIGN_RIGHT,
168
169 ID_FORMAT_INDENT_MORE,
170 ID_FORMAT_INDENT_LESS,
171
172 ID_FORMAT_PARAGRAPH_SPACING_MORE,
173 ID_FORMAT_PARAGRAPH_SPACING_LESS,
174
175 ID_FORMAT_LINE_SPACING_HALF,
176 ID_FORMAT_LINE_SPACING_DOUBLE,
177 ID_FORMAT_LINE_SPACING_SINGLE,
178
179 ID_VIEW_HTML
180};
181
182// ----------------------------------------------------------------------------
183// event tables and other macros for wxWidgets
184// ----------------------------------------------------------------------------
185
186// the event tables connect the wxWidgets events with the functions (event
187// handlers) which process them. It can be also done at run-time, but for the
188// simple menu events like this the static method is much simpler.
189BEGIN_EVENT_TABLE(MyFrame, wxFrame)
190 EVT_MENU(ID_Quit, MyFrame::OnQuit)
191 EVT_MENU(ID_About, MyFrame::OnAbout)
192
193 EVT_MENU(wxID_OPEN, MyFrame::OnOpen)
194 EVT_MENU(wxID_SAVE, MyFrame::OnSave)
195 EVT_MENU(wxID_SAVEAS, MyFrame::OnSaveAs)
196
197 EVT_MENU(ID_FORMAT_BOLD, MyFrame::OnBold)
198 EVT_MENU(ID_FORMAT_ITALIC, MyFrame::OnItalic)
199 EVT_MENU(ID_FORMAT_UNDERLINE, MyFrame::OnUnderline)
200
201 EVT_UPDATE_UI(ID_FORMAT_BOLD, MyFrame::OnUpdateBold)
202 EVT_UPDATE_UI(ID_FORMAT_ITALIC, MyFrame::OnUpdateItalic)
203 EVT_UPDATE_UI(ID_FORMAT_UNDERLINE, MyFrame::OnUpdateUnderline)
204
205 EVT_MENU(ID_FORMAT_ALIGN_LEFT, MyFrame::OnAlignLeft)
206 EVT_MENU(ID_FORMAT_ALIGN_CENTRE, MyFrame::OnAlignCentre)
207 EVT_MENU(ID_FORMAT_ALIGN_RIGHT, MyFrame::OnAlignRight)
208
209 EVT_UPDATE_UI(ID_FORMAT_ALIGN_LEFT, MyFrame::OnUpdateAlignLeft)
210 EVT_UPDATE_UI(ID_FORMAT_ALIGN_CENTRE, MyFrame::OnUpdateAlignCentre)
211 EVT_UPDATE_UI(ID_FORMAT_ALIGN_RIGHT, MyFrame::OnUpdateAlignRight)
212
213 EVT_MENU(ID_FORMAT_FONT, MyFrame::OnFont)
214 EVT_MENU(ID_FORMAT_INDENT_MORE, MyFrame::OnIndentMore)
215 EVT_MENU(ID_FORMAT_INDENT_LESS, MyFrame::OnIndentLess)
216
217 EVT_MENU(ID_FORMAT_LINE_SPACING_HALF, MyFrame::OnLineSpacingHalf)
218 EVT_MENU(ID_FORMAT_LINE_SPACING_SINGLE, MyFrame::OnLineSpacingSingle)
219 EVT_MENU(ID_FORMAT_LINE_SPACING_DOUBLE, MyFrame::OnLineSpacingDouble)
220
221 EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_MORE, MyFrame::OnParagraphSpacingMore)
222 EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_LESS, MyFrame::OnParagraphSpacingLess)
223
224 EVT_MENU(ID_VIEW_HTML, MyFrame::OnViewHTML)
225END_EVENT_TABLE()
226
227// Create a new application object: this macro will allow wxWidgets to create
228// the application object during program execution (it's better than using a
229// static object for many reasons) and also implements the accessor function
230// wxGetApp() which will return the reference of the right type (i.e. MyApp and
231// not wxApp)
232IMPLEMENT_APP(MyApp)
233
234// ============================================================================
235// implementation
236// ============================================================================
237
238// ----------------------------------------------------------------------------
239// the application class
240// ----------------------------------------------------------------------------
241
242// 'Main program' equivalent: the program execution "starts" here
243bool MyApp::OnInit()
244{
245 m_styleSheet = new wxRichTextStyleSheet;
246
247 CreateStyles();
248
249 // Add extra handlers (plain text is automatically added)
250 wxRichTextBuffer::AddHandler(new wxRichTextXMLHandler);
251 wxRichTextBuffer::AddHandler(new wxRichTextHTMLHandler);
252
253 // Add image handlers
254#if wxUSE_LIBPNG
255 wxImage::AddHandler( new wxPNGHandler );
256#endif
9a173d48 257
5d7836c4
JS
258#if wxUSE_LIBJPEG
259 wxImage::AddHandler( new wxJPEGHandler );
260#endif
261
262#if wxUSE_GIF
263 wxImage::AddHandler( new wxGIFHandler );
264#endif
265
266 // create the main application window
267 MyFrame *frame = new MyFrame(_T("wxRichTextCtrl Sample"), wxID_ANY, wxDefaultPosition, wxSize(600, 500));
268
269 // and show it (the frames, unlike simple controls, are not shown when
270 // created initially)
271 frame->Show(true);
272
273 // success: wxApp::OnRun() will be called which will enter the main message
274 // loop and the application will run. If we returned false here, the
275 // application would exit immediately.
276 return true;
277}
278
279int MyApp::OnExit()
280{
281 delete m_styleSheet;
282 return 0;
283}
284
285void MyApp::CreateStyles()
286{
287 // Paragraph styles
288
289 wxFont romanFont(12, wxROMAN, wxNORMAL, wxNORMAL);
290 wxFont swissFont(12, wxSWISS, wxNORMAL, wxNORMAL);
291
292 wxRichTextParagraphStyleDefinition* normalPara = new wxRichTextParagraphStyleDefinition(wxT("Normal"));
293 wxRichTextAttr normalAttr;
294 normalAttr.SetFontFaceName(romanFont.GetFaceName());
295 normalAttr.SetFontSize(12);
296 // Let's set all attributes for this style
297 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|
298 wxTEXT_ATTR_PARA_SPACING_BEFORE|wxTEXT_ATTR_PARA_SPACING_AFTER|wxTEXT_ATTR_LINE_SPACING|
299 wxTEXT_ATTR_BULLET_STYLE|wxTEXT_ATTR_BULLET_NUMBER);
300 normalPara->SetStyle(normalAttr);
9a173d48 301
5d7836c4
JS
302 m_styleSheet->AddParagraphStyle(normalPara);
303
304 wxRichTextParagraphStyleDefinition* indentedPara = new wxRichTextParagraphStyleDefinition(wxT("Indented"));
305 wxRichTextAttr indentedAttr;
306 indentedAttr.SetFontFaceName(romanFont.GetFaceName());
307 indentedAttr.SetFontSize(12);
308 indentedAttr.SetLeftIndent(100, 0);
309 // We only want to affect indentation
310 indentedAttr.SetFlags(wxTEXT_ATTR_LEFT_INDENT|wxTEXT_ATTR_RIGHT_INDENT);
311 indentedPara->SetStyle(indentedAttr);
9a173d48 312
5d7836c4
JS
313 m_styleSheet->AddParagraphStyle(indentedPara);
314
27e20452
JS
315 wxRichTextParagraphStyleDefinition* indentedPara2 = new wxRichTextParagraphStyleDefinition(wxT("Red Bold Indented"));
316 wxRichTextAttr indentedAttr2;
317 indentedAttr2.SetFontFaceName(romanFont.GetFaceName());
318 indentedAttr2.SetFontSize(12);
319 indentedAttr2.SetFontWeight(wxBOLD);
320 indentedAttr2.SetTextColour(*wxRED);
321 indentedAttr2.SetFontSize(12);
322 indentedAttr2.SetLeftIndent(100, 0);
323 // We want to affect indentation, font and text colour
324 indentedAttr2.SetFlags(wxTEXT_ATTR_LEFT_INDENT|wxTEXT_ATTR_RIGHT_INDENT|wxTEXT_ATTR_FONT|wxTEXT_ATTR_TEXT_COLOUR);
325 indentedPara2->SetStyle(indentedAttr2);
326
327 m_styleSheet->AddParagraphStyle(indentedPara2);
328
5d7836c4
JS
329 wxRichTextParagraphStyleDefinition* flIndentedPara = new wxRichTextParagraphStyleDefinition(wxT("First Line Indented"));
330 wxRichTextAttr flIndentedAttr;
331 flIndentedAttr.SetFontFaceName(swissFont.GetFaceName());
332 flIndentedAttr.SetFontSize(12);
333 flIndentedAttr.SetLeftIndent(100, -100);
334 // We only want to affect indentation
335 flIndentedAttr.SetFlags(wxTEXT_ATTR_LEFT_INDENT|wxTEXT_ATTR_RIGHT_INDENT);
336 flIndentedPara->SetStyle(flIndentedAttr);
9a173d48 337
5d7836c4
JS
338 m_styleSheet->AddParagraphStyle(flIndentedPara);
339
340 // Character styles
341
342 wxRichTextCharacterStyleDefinition* boldDef = new wxRichTextCharacterStyleDefinition(wxT("Bold"));
343 wxRichTextAttr boldAttr;
344 boldAttr.SetFontFaceName(romanFont.GetFaceName());
345 boldAttr.SetFontSize(12);
346 boldAttr.SetFontWeight(wxBOLD);
347 // We only want to affect boldness
348 boldAttr.SetFlags(wxTEXT_ATTR_FONT_WEIGHT);
349 boldDef->SetStyle(boldAttr);
9a173d48 350
5d7836c4
JS
351 m_styleSheet->AddCharacterStyle(boldDef);
352
353 wxRichTextCharacterStyleDefinition* italicDef = new wxRichTextCharacterStyleDefinition(wxT("Italic"));
354 wxRichTextAttr italicAttr;
355 italicAttr.SetFontFaceName(romanFont.GetFaceName());
356 italicAttr.SetFontSize(12);
357 italicAttr.SetFontStyle(wxITALIC);
358 // We only want to affect italics
359 italicAttr.SetFlags(wxTEXT_ATTR_FONT_ITALIC);
360 italicDef->SetStyle(italicAttr);
9a173d48 361
5d7836c4
JS
362 m_styleSheet->AddCharacterStyle(italicDef);
363
364 wxRichTextCharacterStyleDefinition* redDef = new wxRichTextCharacterStyleDefinition(wxT("Red Bold"));
365 wxRichTextAttr redAttr;
366 redAttr.SetFontFaceName(romanFont.GetFaceName());
367 redAttr.SetFontSize(12);
368 redAttr.SetFontWeight(wxBOLD);
369 redAttr.SetTextColour(*wxRED);
370 // We only want to affect colour, weight and face
371 redAttr.SetFlags(wxTEXT_ATTR_FONT_FACE|wxTEXT_ATTR_FONT_WEIGHT|wxTEXT_ATTR_TEXT_COLOUR);
372 redDef->SetStyle(redAttr);
9a173d48 373
5d7836c4
JS
374 m_styleSheet->AddCharacterStyle(redDef);
375}
376
377// ----------------------------------------------------------------------------
378// main frame
379// ----------------------------------------------------------------------------
380
381// frame constructor
382MyFrame::MyFrame(const wxString& title, wxWindowID id, const wxPoint& pos,
383 const wxSize& size, long style)
384 : wxFrame(NULL, id, title, pos, size, style)
385{
386 // set the frame icon
387 SetIcon(sample_xpm);
388
389 // create a menu bar
390 wxMenu *fileMenu = new wxMenu;
391
392 // the "About" item should be in the help menu
393 wxMenu *helpMenu = new wxMenu;
394 helpMenu->Append(ID_About, _T("&About...\tF1"), _T("Show about dialog"));
395
396 fileMenu->Append(wxID_OPEN, _T("&Open\tCtrl+O"), _T("Open a file"));
397 fileMenu->Append(wxID_SAVE, _T("&Save\tCtrl+S"), _T("Save a file"));
398 fileMenu->Append(wxID_SAVEAS, _T("&Save As...\tF12"), _T("Save to a new file"));
399 fileMenu->AppendSeparator();
400 fileMenu->Append(ID_VIEW_HTML, _T("&View as HTML"), _T("View HTML"));
401 fileMenu->AppendSeparator();
c4cd20cf 402 fileMenu->Append(ID_Quit, _T("E&xit\tAlt+X"), _T("Quit this program"));
5d7836c4
JS
403
404 wxMenu* editMenu = new wxMenu;
405 editMenu->Append(wxID_UNDO, _("&Undo\tCtrl+Z"));
406 editMenu->Append(wxID_REDO, _("&Redo\tCtrl+Y"));
407 editMenu->AppendSeparator();
408 editMenu->Append(wxID_CUT, _("Cu&t\tCtrl+X"));
409 editMenu->Append(wxID_COPY, _("&Copy\tCtrl+C"));
410 editMenu->Append(wxID_PASTE, _("&Paste\tCtrl+V"));
411
412 editMenu->Append(wxID_CLEAR, _("&Delete\tDel"));
413
414 editMenu->AppendSeparator();
415 editMenu->Append(wxID_SELECTALL, _("Select A&ll\tCtrl+A"));
416#if 0
417 editMenu->AppendSeparator();
418 editMenu->Append(wxID_FIND, _("&Find...\tCtrl+F"));
419 editMenu->Append(stID_FIND_REPLACE, _("&Replace...\tCtrl+R"));
420#endif
421
422 wxMenu* formatMenu = new wxMenu;
423 formatMenu->AppendCheckItem(ID_FORMAT_BOLD, _("&Bold\tCtrl+B"));
424 formatMenu->AppendCheckItem(ID_FORMAT_ITALIC, _("&Italic\tCtrl+I"));
425 formatMenu->AppendCheckItem(ID_FORMAT_UNDERLINE, _("&Underline\tCtrl+U"));
426 formatMenu->AppendSeparator();
427 formatMenu->AppendCheckItem(ID_FORMAT_ALIGN_LEFT, _("L&eft Align"));
428 formatMenu->AppendCheckItem(ID_FORMAT_ALIGN_RIGHT, _("&Right Align"));
429 formatMenu->AppendCheckItem(ID_FORMAT_ALIGN_CENTRE, _("&Centre"));
430 formatMenu->AppendSeparator();
c4cd20cf 431 formatMenu->Append(ID_FORMAT_INDENT_MORE, _("Indent &More"));
5d7836c4
JS
432 formatMenu->Append(ID_FORMAT_INDENT_LESS, _("Indent &Less"));
433 formatMenu->AppendSeparator();
434 formatMenu->Append(ID_FORMAT_PARAGRAPH_SPACING_MORE, _("Increase Paragraph &Spacing"));
435 formatMenu->Append(ID_FORMAT_PARAGRAPH_SPACING_LESS, _("Decrease &Paragraph Spacing"));
436 formatMenu->AppendSeparator();
437 formatMenu->Append(ID_FORMAT_LINE_SPACING_SINGLE, _("Normal Line Spacing"));
438 formatMenu->Append(ID_FORMAT_LINE_SPACING_HALF, _("1.5 Line Spacing"));
439 formatMenu->Append(ID_FORMAT_LINE_SPACING_DOUBLE, _("Double Line Spacing"));
440 formatMenu->AppendSeparator();
441 formatMenu->Append(ID_FORMAT_FONT, _("&Font..."));
442
443 // now append the freshly created menu to the menu bar...
444 wxMenuBar *menuBar = new wxMenuBar();
445 menuBar->Append(fileMenu, _T("&File"));
446 menuBar->Append(editMenu, _T("&Edit"));
447 menuBar->Append(formatMenu, _T("F&ormat"));
448 menuBar->Append(helpMenu, _T("&Help"));
449
450 // ... and attach this menu bar to the frame
451 SetMenuBar(menuBar);
452
453 // create a status bar just for fun (by default with 1 pane only)
9a173d48 454#if wxUSE_STATUSBAR
5d7836c4
JS
455 CreateStatusBar(2);
456 SetStatusText(_T("Welcome to wxRichTextCtrl!"));
9a173d48 457#endif
5d7836c4
JS
458
459 wxToolBar* toolBar = CreateToolBar();
460
9a173d48
WS
461 toolBar->AddTool(wxID_OPEN, wxBitmap(open_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Open"));
462 toolBar->AddTool(wxID_SAVEAS, wxBitmap(save_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Save"));
5d7836c4 463 toolBar->AddSeparator();
9a173d48
WS
464 toolBar->AddTool(wxID_CUT, wxBitmap(cut_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Cut"));
465 toolBar->AddTool(wxID_COPY, wxBitmap(copy_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Copy"));
466 toolBar->AddTool(wxID_PASTE, wxBitmap(paste_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Paste"));
5d7836c4 467 toolBar->AddSeparator();
9a173d48
WS
468 toolBar->AddTool(wxID_UNDO, wxBitmap(undo_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Undo"));
469 toolBar->AddTool(wxID_REDO, wxBitmap(redo_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Redo"));
5d7836c4 470 toolBar->AddSeparator();
9a173d48
WS
471 toolBar->AddTool(ID_FORMAT_BOLD, wxBitmap(bold_xpm), wxNullBitmap, true, -1, -1, (wxObject *) NULL, _("Bold"));
472 toolBar->AddTool(ID_FORMAT_ITALIC, wxBitmap(italic_xpm), wxNullBitmap, true, -1, -1, (wxObject *) NULL, _("Italic"));
473 toolBar->AddTool(ID_FORMAT_UNDERLINE, wxBitmap(underline_xpm), wxNullBitmap, true, -1, -1, (wxObject *) NULL, _("Underline"));
5d7836c4 474 toolBar->AddSeparator();
9a173d48
WS
475 toolBar->AddTool(ID_FORMAT_ALIGN_LEFT, wxBitmap(alignleft_xpm), wxNullBitmap, true, -1, -1, (wxObject *) NULL, _("Align Left"));
476 toolBar->AddTool(ID_FORMAT_ALIGN_CENTRE, wxBitmap(centre_xpm), wxNullBitmap, true, -1, -1, (wxObject *) NULL, _("Centre"));
477 toolBar->AddTool(ID_FORMAT_ALIGN_RIGHT, wxBitmap(alignright_xpm), wxNullBitmap, true, -1, -1, (wxObject *) NULL, _("Align Right"));
5d7836c4 478 toolBar->AddSeparator();
9a173d48
WS
479 toolBar->AddTool(ID_FORMAT_INDENT_LESS, wxBitmap(indentless_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Indent Less"));
480 toolBar->AddTool(ID_FORMAT_INDENT_MORE, wxBitmap(indentmore_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Indent More"));
5d7836c4 481 toolBar->AddSeparator();
9a173d48 482 toolBar->AddTool(ID_FORMAT_FONT, wxBitmap(font_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Font"));
5d7836c4
JS
483
484 toolBar->Realize();
485
c59f6793 486 wxSplitterWindow* splitter = new wxSplitterWindow(this, wxID_ANY, wxDefaultPosition, GetClientSize(), wxSP_NO_XP_THEME|wxSP_3D|wxSP_LIVE_UPDATE);
5d7836c4
JS
487
488 wxFont textFont = wxFont(12, wxROMAN, wxNORMAL, wxNORMAL);
489 wxFont boldFont = wxFont(12, wxROMAN, wxNORMAL, wxBOLD);
490 wxFont italicFont = wxFont(12, wxROMAN, wxITALIC, wxNORMAL);
491
27e20452 492 m_richTextCtrl = new wxRichTextCtrl(splitter, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200, 200), wxVSCROLL|wxHSCROLL|wxNO_BORDER|wxWANTS_CHARS);
ff2baa25
JS
493 wxFont font(12, wxROMAN, wxNORMAL, wxNORMAL);
494
ff2baa25 495 m_richTextCtrl->SetFont(font);
5d7836c4
JS
496
497 wxRichTextStyleListBox* styleListBox = new wxRichTextStyleListBox(splitter, wxID_ANY);
498 splitter->SplitVertically(m_richTextCtrl, styleListBox, 400);
499
c59f6793
JS
500 splitter->UpdateSize();
501
5d7836c4
JS
502 styleListBox->SetStyleSheet(wxGetApp().GetStyleSheet());
503 styleListBox->SetRichTextCtrl(m_richTextCtrl);
504 styleListBox->UpdateStyles();
505
506 wxRichTextCtrl& r = *m_richTextCtrl;
507
508 r.BeginSuppressUndo();
509
510 r.BeginParagraphSpacing(0, 20);
511
512 r.BeginAlignment(wxTEXT_ALIGNMENT_CENTRE);
513 r.BeginBold();
514
515 r.BeginFontSize(14);
516 r.WriteText(wxT("Welcome to wxRichTextCtrl, a wxWidgets control for editing and presenting styled text and images"));
517 r.EndFontSize();
518 r.Newline();
519
520 r.BeginItalic();
521 r.WriteText(wxT("by Julian Smart"));
522 r.EndItalic();
523
524 r.EndBold();
525
526 r.Newline();
527 r.WriteImage(wxBitmap(zebra_xpm));
528
529 r.EndAlignment();
530
531 r.Newline();
532 r.Newline();
533
534 r.WriteText(wxT("What can you do with this thing? "));
535 r.WriteImage(wxBitmap(smiley_xpm));
536 r.WriteText(wxT(" Well, you can change text "));
537
538 r.BeginTextColour(wxColour(255, 0, 0));
539 r.WriteText(wxT("colour, like this red bit."));
540 r.EndTextColour();
541
542 r.BeginTextColour(wxColour(0, 0, 255));
543 r.WriteText(wxT(" And this blue bit."));
544 r.EndTextColour();
545
546 r.WriteText(wxT(" Naturally you can make things "));
547 r.BeginBold();
548 r.WriteText(wxT("bold "));
549 r.EndBold();
550 r.BeginItalic();
551 r.WriteText(wxT("or italic "));
552 r.EndItalic();
553 r.BeginUnderline();
554 r.WriteText(wxT("or underlined."));
555 r.EndUnderline();
556
557 r.BeginFontSize(14);
558 r.WriteText(wxT(" Different font sizes on the same line is allowed, too."));
559 r.EndFontSize();
560
561 r.WriteText(wxT(" Next we'll show an indented paragraph."));
562
563 r.BeginLeftIndent(60);
564 r.Newline();
565
566 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."));
567 r.EndLeftIndent();
568
569 r.Newline();
570
571 r.WriteText(wxT("Next, we'll show a first-line indent, achieved using BeginLeftIndent(100, -40)."));
572
573 r.BeginLeftIndent(100, -40);
574 r.Newline();
575
576 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."));
577 r.EndLeftIndent();
578
579 r.Newline();
580
581 r.WriteText(wxT("Numbered bullets are possible, again using subindents:"));
582
583 r.BeginNumberedBullet(1, 100, 60);
584 r.Newline();
585
586 r.WriteText(wxT("This is my first item. Note that wxRichTextCtrl doesn't automatically do numbering, but this will be added later."));
587 r.EndNumberedBullet();
588
589 r.BeginNumberedBullet(2, 100, 60);
590 r.Newline();
591
592 r.WriteText(wxT("This is my second item."));
593 r.EndNumberedBullet();
594
595 r.Newline();
596
597 r.WriteText(wxT("The following paragraph is right-indented:"));
598
599 r.BeginRightIndent(200);
600 r.Newline();
601
602 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."));
603 r.EndRightIndent();
604
605 r.Newline();
606
607 r.WriteText(wxT("The following paragraph is right-aligned with 1.5 line spacing:"));
608
609 r.BeginAlignment(wxTEXT_ALIGNMENT_RIGHT);
610 r.BeginLineSpacing(wxTEXT_ATTR_LINE_SPACING_HALF);
611 r.Newline();
612
613 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."));
614 r.EndLineSpacing();
615 r.EndAlignment();
616
7f0d9d71
JS
617 wxArrayInt tabs;
618 tabs.Add(400);
619 tabs.Add(600);
620 tabs.Add(800);
621 tabs.Add(1000);
622 wxTextAttrEx attr;
623 attr.SetFlags(wxTEXT_ATTR_TABS);
624 attr.SetTabs(tabs);
625 r.SetDefaultStyle(attr);
626
627 r.Newline();
628 r.WriteText(wxT("This line contains tabs:\tFirst tab\tSecond tab\tThird tab"));
629
5d7836c4
JS
630 r.Newline();
631 r.WriteText(wxT("Other notable features of wxRichTextCtrl include:"));
632
633 r.BeginSymbolBullet(wxT('*'), 100, 60);
634 r.Newline();
635 r.WriteText(wxT("Compatibility with wxTextCtrl API"));
636 r.EndSymbolBullet();
637
638 r.BeginSymbolBullet(wxT('*'), 100, 60);
639 r.Newline();
640 r.WriteText(wxT("Easy stack-based BeginXXX()...EndXXX() style setting in addition to SetStyle()"));
641 r.EndSymbolBullet();
642
643 r.BeginSymbolBullet(wxT('*'), 100, 60);
644 r.Newline();
645 r.WriteText(wxT("XML loading and saving"));
646 r.EndSymbolBullet();
647
648 r.BeginSymbolBullet(wxT('*'), 100, 60);
649 r.Newline();
650 r.WriteText(wxT("Undo/Redo, with batching option and Undo suppressing"));
651 r.EndSymbolBullet();
652
653 r.BeginSymbolBullet(wxT('*'), 100, 60);
654 r.Newline();
655 r.WriteText(wxT("Clipboard copy and paste"));
656 r.EndSymbolBullet();
657
658 r.BeginSymbolBullet(wxT('*'), 100, 60);
659 r.Newline();
660 r.WriteText(wxT("wxRichTextStyleSheet with named character and paragraph styles, and control for applying named styles"));
661 r.EndSymbolBullet();
662
663 r.BeginSymbolBullet(wxT('*'), 100, 60);
664 r.Newline();
665 r.WriteText(wxT("A design that can easily be extended to other content types, ultimately with text boxes, tables, controls, and so on"));
666 r.EndSymbolBullet();
667
668 r.Newline();
669
670 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!"));
671
672 r.EndParagraphSpacing();
673
674 r.EndSuppressUndo();
675}
676
677
678// event handlers
679
680void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
681{
682 // true is to force the frame to close
683 Close(true);
684}
685
686void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
687{
688 wxString msg;
689 msg.Printf( _T("This is a demo for wxRichTextCtrl, a control for editing styled text.\n(c) Julian Smart, 2005"));
690 wxMessageBox(msg, _T("About wxRichTextCtrl Sample"), wxOK | wxICON_INFORMATION, this);
691}
692
693// Forward command events to the current rich text control, if any
694bool MyFrame::ProcessEvent(wxEvent& event)
695{
696 if (event.IsCommandEvent() && !event.IsKindOf(CLASSINFO(wxChildFocusEvent)))
697 {
698 // Problem: we can get infinite recursion because the events
699 // climb back up to this frame, and repeat.
700 // Assume that command events don't cause another command event
701 // to be called, so we can rely on inCommand not being overwritten
702
703 static int s_eventType = 0;
704 static wxWindowID s_id = 0;
705
706 if (s_id != event.GetId() && s_eventType != event.GetEventType())
707 {
708 s_eventType = event.GetEventType();
709 s_id = event.GetId();
9a173d48 710
5d7836c4
JS
711 wxWindow* focusWin = wxFindFocusDescendant(this);
712 if (focusWin && focusWin->ProcessEvent(event))
713 {
714 //s_command = NULL;
715 s_eventType = 0;
716 s_id = 0;
9a173d48 717 return true;
5d7836c4
JS
718 }
719
720 s_eventType = 0;
721 s_id = 0;
722 }
723 else
724 {
9a173d48 725 return false;
5d7836c4
JS
726 }
727 }
728
729 return wxFrame::ProcessEvent(event);
730}
731
011b3dcb 732void MyFrame::OnOpen(wxCommandEvent& WXUNUSED(event))
5d7836c4 733{
9a173d48
WS
734 wxString path;
735 wxString filename;
1e967276
JS
736 wxArrayInt fileTypes;
737
738 wxString filter = wxRichTextBuffer::GetExtWildcard(false, false, & fileTypes);
9a173d48 739 if (!filter.empty())
5d7836c4
JS
740 filter += wxT("|");
741 filter += wxT("All files (*.*)|*.*");
742
5d7836c4
JS
743 wxFileDialog dialog(this,
744 _("Choose a filename"),
745 path,
746 filename,
747 filter,
ff3e84ff 748 wxFD_OPEN);
5d7836c4
JS
749
750 if (dialog.ShowModal() == wxID_OK)
751 {
752 wxString path = dialog.GetPath();
9a173d48
WS
753
754 if (!path.empty())
5d7836c4 755 {
1e967276 756 int filterIndex = dialog.GetFilterIndex();
dbf38e88
WS
757 int fileType = (filterIndex < (int) fileTypes.GetCount())
758 ? fileTypes[filterIndex]
759 : wxRICHTEXT_TYPE_TEXT;
1e967276 760 m_richTextCtrl->LoadFile(path, fileType);
5d7836c4
JS
761 }
762 }
763}
764
765void MyFrame::OnSave(wxCommandEvent& event)
766{
9a173d48 767 if (m_richTextCtrl->GetFilename().empty())
5d7836c4
JS
768 {
769 OnSaveAs(event);
770 return;
771 }
772 m_richTextCtrl->SaveFile();
773}
774
011b3dcb 775void MyFrame::OnSaveAs(wxCommandEvent& WXUNUSED(event))
5d7836c4
JS
776{
777 wxString filter = wxRichTextBuffer::GetExtWildcard(false, true);
9a173d48
WS
778 wxString path;
779 wxString filename;
5d7836c4
JS
780
781 wxFileDialog dialog(this,
782 _("Choose a filename"),
783 path,
784 filename,
785 filter,
ff3e84ff 786 wxFD_SAVE);
5d7836c4
JS
787
788 if (dialog.ShowModal() == wxID_OK)
789 {
790 wxString path = dialog.GetPath();
9a173d48
WS
791
792 if (!path.empty())
5d7836c4
JS
793 {
794 m_richTextCtrl->SaveFile(path);
795 }
796 }
797}
798
011b3dcb 799void MyFrame::OnBold(wxCommandEvent& WXUNUSED(event))
5d7836c4
JS
800{
801 m_richTextCtrl->ApplyBoldToSelection();
802}
803
011b3dcb 804void MyFrame::OnItalic(wxCommandEvent& WXUNUSED(event))
5d7836c4
JS
805{
806 m_richTextCtrl->ApplyItalicToSelection();
807}
808
011b3dcb 809void MyFrame::OnUnderline(wxCommandEvent& WXUNUSED(event))
5d7836c4
JS
810{
811 m_richTextCtrl->ApplyUnderlineToSelection();
812}
813
814
815void MyFrame::OnUpdateBold(wxUpdateUIEvent& event)
816{
817 event.Check(m_richTextCtrl->IsSelectionBold());
818}
819
820void MyFrame::OnUpdateItalic(wxUpdateUIEvent& event)
821{
822 event.Check(m_richTextCtrl->IsSelectionItalics());
823}
824
825void MyFrame::OnUpdateUnderline(wxUpdateUIEvent& event)
826{
827 event.Check(m_richTextCtrl->IsSelectionUnderlined());
828}
829
011b3dcb 830void MyFrame::OnAlignLeft(wxCommandEvent& WXUNUSED(event))
5d7836c4
JS
831{
832 m_richTextCtrl->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_LEFT);
833}
834
011b3dcb 835void MyFrame::OnAlignCentre(wxCommandEvent& WXUNUSED(event))
5d7836c4
JS
836{
837 m_richTextCtrl->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_CENTRE);
838}
839
011b3dcb 840void MyFrame::OnAlignRight(wxCommandEvent& WXUNUSED(event))
5d7836c4
JS
841{
842 m_richTextCtrl->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_RIGHT);
843}
844
845void MyFrame::OnUpdateAlignLeft(wxUpdateUIEvent& event)
846{
847 event.Check(m_richTextCtrl->IsSelectionAligned(wxTEXT_ALIGNMENT_LEFT));
848}
849
850void MyFrame::OnUpdateAlignCentre(wxUpdateUIEvent& event)
851{
852 event.Check(m_richTextCtrl->IsSelectionAligned(wxTEXT_ALIGNMENT_CENTRE));
853}
854
855void MyFrame::OnUpdateAlignRight(wxUpdateUIEvent& event)
856{
857 event.Check(m_richTextCtrl->IsSelectionAligned(wxTEXT_ALIGNMENT_RIGHT));
858}
859
011b3dcb 860void MyFrame::OnFont(wxCommandEvent& WXUNUSED(event))
5d7836c4
JS
861{
862 if (!m_richTextCtrl->HasSelection())
863 return;
864
865 wxRichTextRange range = m_richTextCtrl->GetSelectionRange();
866 wxFontData fontData;
867
868 wxTextAttrEx attr;
869 attr.SetFlags(wxTEXT_ATTR_FONT);
870
871 if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
872 fontData.SetInitialFont(attr.GetFont());
873
874 wxFontDialog dialog(this, fontData);
875 if (dialog.ShowModal() == wxID_OK)
876 {
877 fontData = dialog.GetFontData();
878 attr.SetFlags(wxTEXT_ATTR_FONT);
879 attr.SetFont(fontData.GetChosenFont());
880 if (attr.GetFont().Ok())
881 {
882 m_richTextCtrl->SetStyle(range, attr);
883 }
884 }
885}
886
011b3dcb 887void MyFrame::OnIndentMore(wxCommandEvent& WXUNUSED(event))
5d7836c4
JS
888{
889 wxTextAttrEx attr;
890 attr.SetFlags(wxTEXT_ATTR_LEFT_INDENT);
891
892 if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
893 {
894 wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
895 if (m_richTextCtrl->HasSelection())
896 range = m_richTextCtrl->GetSelectionRange();
897
898 wxFontData fontData;
899 attr.SetLeftIndent(attr.GetLeftIndent() + 100);
900
901 attr.SetFlags(wxTEXT_ATTR_LEFT_INDENT);
902 m_richTextCtrl->SetStyle(range, attr);
903 }
904}
905
011b3dcb 906void MyFrame::OnIndentLess(wxCommandEvent& WXUNUSED(event))
5d7836c4
JS
907{
908 wxTextAttrEx attr;
909 attr.SetFlags(wxTEXT_ATTR_LEFT_INDENT);
910
911 if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
912 {
913 wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
914 if (m_richTextCtrl->HasSelection())
915 range = m_richTextCtrl->GetSelectionRange();
916
917 if (attr.GetLeftIndent() >= 100)
918 {
919 wxFontData fontData;
920 attr.SetLeftIndent(attr.GetLeftIndent() - 100);
9a173d48 921
5d7836c4
JS
922 m_richTextCtrl->SetStyle(range, attr);
923 }
924 }
925}
926
011b3dcb 927void MyFrame::OnLineSpacingHalf(wxCommandEvent& WXUNUSED(event))
5d7836c4
JS
928{
929 wxTextAttrEx attr;
930 attr.SetFlags(wxTEXT_ATTR_LINE_SPACING);
931
932 if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
933 {
934 wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
935 if (m_richTextCtrl->HasSelection())
936 range = m_richTextCtrl->GetSelectionRange();
937
938 wxFontData fontData;
939 attr.SetFlags(wxTEXT_ATTR_LINE_SPACING);
940 attr.SetLineSpacing(15);
9a173d48 941
5d7836c4
JS
942 m_richTextCtrl->SetStyle(range, attr);
943 }
944}
945
011b3dcb 946void MyFrame::OnLineSpacingDouble(wxCommandEvent& WXUNUSED(event))
5d7836c4
JS
947{
948 wxTextAttrEx attr;
949 attr.SetFlags(wxTEXT_ATTR_LINE_SPACING);
950
951 if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
952 {
953 wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
954 if (m_richTextCtrl->HasSelection())
955 range = m_richTextCtrl->GetSelectionRange();
956
957 wxFontData fontData;
958 attr.SetFlags(wxTEXT_ATTR_LINE_SPACING);
959 attr.SetLineSpacing(20);
9a173d48 960
5d7836c4
JS
961 m_richTextCtrl->SetStyle(range, attr);
962 }
963}
964
011b3dcb 965void MyFrame::OnLineSpacingSingle(wxCommandEvent& WXUNUSED(event))
5d7836c4
JS
966{
967 wxTextAttrEx attr;
968 attr.SetFlags(wxTEXT_ATTR_LINE_SPACING);
969
970 if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
971 {
972 wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
973 if (m_richTextCtrl->HasSelection())
974 range = m_richTextCtrl->GetSelectionRange();
975
976 wxFontData fontData;
977 attr.SetFlags(wxTEXT_ATTR_LINE_SPACING);
978 attr.SetLineSpacing(0); // Can also use 10
9a173d48 979
5d7836c4
JS
980 m_richTextCtrl->SetStyle(range, attr);
981 }
982}
983
011b3dcb 984void MyFrame::OnParagraphSpacingMore(wxCommandEvent& WXUNUSED(event))
5d7836c4
JS
985{
986 wxTextAttrEx attr;
987 attr.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER);
988
989 if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
990 {
991 wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
992 if (m_richTextCtrl->HasSelection())
993 range = m_richTextCtrl->GetSelectionRange();
994
995 wxFontData fontData;
996 attr.SetParagraphSpacingAfter(attr.GetParagraphSpacingAfter() + 20);
997
998 attr.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER);
999 m_richTextCtrl->SetStyle(range, attr);
1000 }
1001}
1002
011b3dcb 1003void MyFrame::OnParagraphSpacingLess(wxCommandEvent& WXUNUSED(event))
5d7836c4
JS
1004{
1005 wxTextAttrEx attr;
1006 attr.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER);
1007
1008 if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
1009 {
1010 wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
1011 if (m_richTextCtrl->HasSelection())
1012 range = m_richTextCtrl->GetSelectionRange();
1013
1014 if (attr.GetParagraphSpacingAfter() >= 20)
1015 {
1016 wxFontData fontData;
1017 attr.SetParagraphSpacingAfter(attr.GetParagraphSpacingAfter() - 20);
9a173d48 1018
5d7836c4
JS
1019 attr.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER);
1020 m_richTextCtrl->SetStyle(range, attr);
1021 }
1022 }
1023}
1024
011b3dcb 1025void MyFrame::OnViewHTML(wxCommandEvent& WXUNUSED(event))
5d7836c4
JS
1026{
1027 wxDialog dialog(this, wxID_ANY, _("HTML"), wxDefaultPosition, wxSize(500, 400), wxDEFAULT_DIALOG_STYLE);
1028
1029 wxBoxSizer* boxSizer = new wxBoxSizer(wxVERTICAL);
1030 dialog.SetSizer(boxSizer);
1031
1032 wxHtmlWindow* win = new wxHtmlWindow(& dialog, wxID_ANY, wxDefaultPosition, wxSize(500, 400), wxSUNKEN_BORDER);
1033 boxSizer->Add(win, 1, wxALL, 5);
1034
1035 wxButton* cancelButton = new wxButton(& dialog, wxID_CANCEL, wxT("&Close"));
1036 boxSizer->Add(cancelButton, 0, wxALL|wxCENTRE, 5);
1037
1038 wxString text;
1039 wxStringOutputStream strStream(& text);
1040
1041 wxRichTextHTMLHandler htmlHandler;
1042 if (htmlHandler.SaveFile(& m_richTextCtrl->GetBuffer(), strStream))
1043 {
1044 win->SetPage(text);
1045 }
1046
1047 boxSizer->Fit(& dialog);
1048
1049 dialog.ShowModal();
1050}