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