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