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