]> git.saurik.com Git - wxWidgets.git/blame - samples/richtext/richtext.cpp
Removed test code
[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 785 r.BeginAlignment(wxTEXT_ALIGNMENT_LEFT);
24777478
JS
786 wxRichTextAttr imageAttr;
787 imageAttr.GetTextBoxAttr().SetFloatMode(wxTEXT_BOX_ATTR_FLOAT_LEFT);
cdaed652 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.")));
24777478
JS
789 r.WriteImage(wxBitmap(zebra_xpm), wxBITMAP_TYPE_PNG, imageAttr);
790 imageAttr.GetTextBoxAttr().GetTop().SetValue(200);
791 imageAttr.GetTextBoxAttr().GetTop().SetUnits(wxTEXT_ATTR_UNITS_PIXELS);
792 imageAttr.GetTextBoxAttr().SetFloatMode(wxTEXT_BOX_ATTR_FLOAT_RIGHT);
793 r.WriteImage(wxBitmap(zebra_xpm), wxBITMAP_TYPE_PNG, imageAttr);
cdaed652
VZ
794 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.")));
795 r.EndAlignment();
796 r.Newline();
797
5d7836c4 798 r.WriteText(wxT("What can you do with this thing? "));
42688aea 799
5d7836c4
JS
800 r.WriteImage(wxBitmap(smiley_xpm));
801 r.WriteText(wxT(" Well, you can change text "));
802
803 r.BeginTextColour(wxColour(255, 0, 0));
804 r.WriteText(wxT("colour, like this red bit."));
805 r.EndTextColour();
806
3e541562
JS
807 wxRichTextAttr backgroundColourAttr;
808 backgroundColourAttr.SetBackgroundColour(*wxGREEN);
809 backgroundColourAttr.SetTextColour(wxColour(0, 0, 255));
810 r.BeginStyle(backgroundColourAttr);
811 r.WriteText(wxT(" And this blue on green bit."));
812 r.EndStyle();
5d7836c4
JS
813
814 r.WriteText(wxT(" Naturally you can make things "));
815 r.BeginBold();
816 r.WriteText(wxT("bold "));
817 r.EndBold();
818 r.BeginItalic();
819 r.WriteText(wxT("or italic "));
820 r.EndItalic();
821 r.BeginUnderline();
822 r.WriteText(wxT("or underlined."));
823 r.EndUnderline();
824
825 r.BeginFontSize(14);
826 r.WriteText(wxT(" Different font sizes on the same line is allowed, too."));
827 r.EndFontSize();
828
829 r.WriteText(wxT(" Next we'll show an indented paragraph."));
830
5d7836c4
JS
831 r.Newline();
832
99404ab0 833 r.BeginLeftIndent(60);
5d7836c4 834 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
835 r.Newline();
836
99404ab0
JS
837 r.EndLeftIndent();
838
5d7836c4
JS
839 r.WriteText(wxT("Next, we'll show a first-line indent, achieved using BeginLeftIndent(100, -40)."));
840
5d7836c4
JS
841 r.Newline();
842
99404ab0 843 r.BeginLeftIndent(100, -40);
5d7836c4 844
99404ab0 845 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
846 r.Newline();
847
99404ab0 848 r.EndLeftIndent();
5d7836c4 849
99404ab0 850 r.WriteText(wxT("Numbered bullets are possible, again using subindents:"));
5d7836c4
JS
851 r.Newline();
852
99404ab0 853 r.BeginNumberedBullet(1, 100, 60);
082cfe55 854 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 855 r.Newline();
5d7836c4
JS
856 r.EndNumberedBullet();
857
858 r.BeginNumberedBullet(2, 100, 60);
5d7836c4 859 r.WriteText(wxT("This is my second item."));
5d7836c4 860 r.Newline();
99404ab0 861 r.EndNumberedBullet();
5d7836c4
JS
862
863 r.WriteText(wxT("The following paragraph is right-indented:"));
99404ab0 864 r.Newline();
5d7836c4
JS
865
866 r.BeginRightIndent(200);
5d7836c4
JS
867
868 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
869 r.Newline();
870
99404ab0
JS
871 r.EndRightIndent();
872
5d7836c4 873 r.WriteText(wxT("The following paragraph is right-aligned with 1.5 line spacing:"));
99404ab0 874 r.Newline();
5d7836c4
JS
875
876 r.BeginAlignment(wxTEXT_ALIGNMENT_RIGHT);
877 r.BeginLineSpacing(wxTEXT_ATTR_LINE_SPACING_HALF);
5d7836c4 878 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 879 r.Newline();
5d7836c4
JS
880 r.EndLineSpacing();
881 r.EndAlignment();
882
7f0d9d71
JS
883 wxArrayInt tabs;
884 tabs.Add(400);
885 tabs.Add(600);
886 tabs.Add(800);
887 tabs.Add(1000);
24777478 888 wxRichTextAttr attr;
7f0d9d71
JS
889 attr.SetFlags(wxTEXT_ATTR_TABS);
890 attr.SetTabs(tabs);
891 r.SetDefaultStyle(attr);
4753c7ce 892
7f0d9d71 893 r.WriteText(wxT("This line contains tabs:\tFirst tab\tSecond tab\tThird tab"));
5d7836c4 894 r.Newline();
99404ab0 895
5d7836c4 896 r.WriteText(wxT("Other notable features of wxRichTextCtrl include:"));
99404ab0 897 r.Newline();
5d7836c4
JS
898
899 r.BeginSymbolBullet(wxT('*'), 100, 60);
5d7836c4 900 r.WriteText(wxT("Compatibility with wxTextCtrl API"));
99404ab0 901 r.Newline();
5d7836c4
JS
902 r.EndSymbolBullet();
903
904 r.BeginSymbolBullet(wxT('*'), 100, 60);
5d7836c4 905 r.WriteText(wxT("Easy stack-based BeginXXX()...EndXXX() style setting in addition to SetStyle()"));
99404ab0 906 r.Newline();
5d7836c4
JS
907 r.EndSymbolBullet();
908
909 r.BeginSymbolBullet(wxT('*'), 100, 60);
5d7836c4 910 r.WriteText(wxT("XML loading and saving"));
99404ab0 911 r.Newline();
5d7836c4
JS
912 r.EndSymbolBullet();
913
914 r.BeginSymbolBullet(wxT('*'), 100, 60);
5d7836c4 915 r.WriteText(wxT("Undo/Redo, with batching option and Undo suppressing"));
99404ab0 916 r.Newline();
5d7836c4
JS
917 r.EndSymbolBullet();
918
919 r.BeginSymbolBullet(wxT('*'), 100, 60);
5d7836c4 920 r.WriteText(wxT("Clipboard copy and paste"));
99404ab0 921 r.Newline();
5d7836c4
JS
922 r.EndSymbolBullet();
923
924 r.BeginSymbolBullet(wxT('*'), 100, 60);
5d7836c4 925 r.WriteText(wxT("wxRichTextStyleSheet with named character and paragraph styles, and control for applying named styles"));
99404ab0 926 r.Newline();
5d7836c4
JS
927 r.EndSymbolBullet();
928
929 r.BeginSymbolBullet(wxT('*'), 100, 60);
5d7836c4 930 r.WriteText(wxT("A design that can easily be extended to other content types, ultimately with text boxes, tables, controls, and so on"));
5d7836c4 931 r.Newline();
99404ab0 932 r.EndSymbolBullet();
5d7836c4 933
720cc10a
JS
934 // Make a style suitable for showing a URL
935 wxRichTextAttr urlStyle;
936 urlStyle.SetTextColour(*wxBLUE);
937 urlStyle.SetFontUnderlined(true);
938
939 r.WriteText(wxT("wxRichTextCtrl can also display URLs, such as this one: "));
940 r.BeginStyle(urlStyle);
941 r.BeginURL(wxT("http://www.wxwidgets.org"));
942 r.WriteText(wxT("The wxWidgets Web Site"));
943 r.EndURL();
944 r.EndStyle();
945 r.WriteText(wxT(". Click on the URL to generate an event."));
946
947 r.Newline();
948
99404ab0 949 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
950
951 r.EndParagraphSpacing();
952
cdaed652
VZ
953 r.Thaw();
954
5d7836c4
JS
955 r.EndSuppressUndo();
956}
957
5d7836c4
JS
958// event handlers
959
960void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
961{
962 // true is to force the frame to close
963 Close(true);
964}
965
966void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
967{
968 wxString msg;
9a83f860
VZ
969 msg.Printf( wxT("This is a demo for wxRichTextCtrl, a control for editing styled text.\n(c) Julian Smart, 2005"));
970 wxMessageBox(msg, wxT("About wxRichTextCtrl Sample"), wxOK | wxICON_INFORMATION, this);
5d7836c4
JS
971}
972
973// Forward command events to the current rich text control, if any
974bool MyFrame::ProcessEvent(wxEvent& event)
975{
976 if (event.IsCommandEvent() && !event.IsKindOf(CLASSINFO(wxChildFocusEvent)))
977 {
978 // Problem: we can get infinite recursion because the events
979 // climb back up to this frame, and repeat.
980 // Assume that command events don't cause another command event
981 // to be called, so we can rely on inCommand not being overwritten
982
983 static int s_eventType = 0;
984 static wxWindowID s_id = 0;
985
986 if (s_id != event.GetId() && s_eventType != event.GetEventType())
987 {
988 s_eventType = event.GetEventType();
989 s_id = event.GetId();
9a173d48 990
5d7836c4 991 wxWindow* focusWin = wxFindFocusDescendant(this);
004867db 992 if (focusWin && focusWin->GetEventHandler()->ProcessEvent(event))
5d7836c4
JS
993 {
994 //s_command = NULL;
995 s_eventType = 0;
996 s_id = 0;
9a173d48 997 return true;
5d7836c4
JS
998 }
999
1000 s_eventType = 0;
1001 s_id = 0;
1002 }
1003 else
1004 {
9a173d48 1005 return false;
5d7836c4
JS
1006 }
1007 }
1008
1009 return wxFrame::ProcessEvent(event);
1010}
1011
011b3dcb 1012void MyFrame::OnOpen(wxCommandEvent& WXUNUSED(event))
5d7836c4 1013{
9a173d48
WS
1014 wxString path;
1015 wxString filename;
1e967276
JS
1016 wxArrayInt fileTypes;
1017
1018 wxString filter = wxRichTextBuffer::GetExtWildcard(false, false, & fileTypes);
9a173d48 1019 if (!filter.empty())
5d7836c4
JS
1020 filter += wxT("|");
1021 filter += wxT("All files (*.*)|*.*");
1022
5d7836c4
JS
1023 wxFileDialog dialog(this,
1024 _("Choose a filename"),
1025 path,
1026 filename,
1027 filter,
ff3e84ff 1028 wxFD_OPEN);
5d7836c4
JS
1029
1030 if (dialog.ShowModal() == wxID_OK)
1031 {
1032 wxString path = dialog.GetPath();
9a173d48
WS
1033
1034 if (!path.empty())
5d7836c4 1035 {
1e967276 1036 int filterIndex = dialog.GetFilterIndex();
dbf38e88
WS
1037 int fileType = (filterIndex < (int) fileTypes.GetCount())
1038 ? fileTypes[filterIndex]
1039 : wxRICHTEXT_TYPE_TEXT;
1e967276 1040 m_richTextCtrl->LoadFile(path, fileType);
5d7836c4
JS
1041 }
1042 }
1043}
1044
1045void MyFrame::OnSave(wxCommandEvent& event)
1046{
9a173d48 1047 if (m_richTextCtrl->GetFilename().empty())
5d7836c4
JS
1048 {
1049 OnSaveAs(event);
1050 return;
1051 }
1052 m_richTextCtrl->SaveFile();
1053}
1054
011b3dcb 1055void MyFrame::OnSaveAs(wxCommandEvent& WXUNUSED(event))
5d7836c4
JS
1056{
1057 wxString filter = wxRichTextBuffer::GetExtWildcard(false, true);
9a173d48
WS
1058 wxString path;
1059 wxString filename;
5d7836c4
JS
1060
1061 wxFileDialog dialog(this,
1062 _("Choose a filename"),
1063 path,
1064 filename,
1065 filter,
ff3e84ff 1066 wxFD_SAVE);
5d7836c4
JS
1067
1068 if (dialog.ShowModal() == wxID_OK)
1069 {
1070 wxString path = dialog.GetPath();
9a173d48
WS
1071
1072 if (!path.empty())
5d7836c4
JS
1073 {
1074 m_richTextCtrl->SaveFile(path);
1075 }
1076 }
1077}
1078
011b3dcb 1079void MyFrame::OnBold(wxCommandEvent& WXUNUSED(event))
5d7836c4
JS
1080{
1081 m_richTextCtrl->ApplyBoldToSelection();
1082}
1083
011b3dcb 1084void MyFrame::OnItalic(wxCommandEvent& WXUNUSED(event))
5d7836c4
JS
1085{
1086 m_richTextCtrl->ApplyItalicToSelection();
1087}
1088
011b3dcb 1089void MyFrame::OnUnderline(wxCommandEvent& WXUNUSED(event))
5d7836c4
JS
1090{
1091 m_richTextCtrl->ApplyUnderlineToSelection();
1092}
1093
1094
1095void MyFrame::OnUpdateBold(wxUpdateUIEvent& event)
1096{
1097 event.Check(m_richTextCtrl->IsSelectionBold());
1098}
1099
1100void MyFrame::OnUpdateItalic(wxUpdateUIEvent& event)
1101{
1102 event.Check(m_richTextCtrl->IsSelectionItalics());
1103}
1104
1105void MyFrame::OnUpdateUnderline(wxUpdateUIEvent& event)
1106{
1107 event.Check(m_richTextCtrl->IsSelectionUnderlined());
1108}
1109
011b3dcb 1110void MyFrame::OnAlignLeft(wxCommandEvent& WXUNUSED(event))
5d7836c4
JS
1111{
1112 m_richTextCtrl->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_LEFT);
1113}
1114
011b3dcb 1115void MyFrame::OnAlignCentre(wxCommandEvent& WXUNUSED(event))
5d7836c4
JS
1116{
1117 m_richTextCtrl->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_CENTRE);
1118}
1119
011b3dcb 1120void MyFrame::OnAlignRight(wxCommandEvent& WXUNUSED(event))
5d7836c4
JS
1121{
1122 m_richTextCtrl->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_RIGHT);
1123}
1124
1125void MyFrame::OnUpdateAlignLeft(wxUpdateUIEvent& event)
1126{
1127 event.Check(m_richTextCtrl->IsSelectionAligned(wxTEXT_ALIGNMENT_LEFT));
1128}
1129
1130void MyFrame::OnUpdateAlignCentre(wxUpdateUIEvent& event)
1131{
1132 event.Check(m_richTextCtrl->IsSelectionAligned(wxTEXT_ALIGNMENT_CENTRE));
1133}
1134
1135void MyFrame::OnUpdateAlignRight(wxUpdateUIEvent& event)
1136{
1137 event.Check(m_richTextCtrl->IsSelectionAligned(wxTEXT_ALIGNMENT_RIGHT));
1138}
1139
011b3dcb 1140void MyFrame::OnFont(wxCommandEvent& WXUNUSED(event))
5d7836c4 1141{
8c9c49a1
JS
1142 wxRichTextRange range;
1143 if (m_richTextCtrl->HasSelection())
1144 range = m_richTextCtrl->GetSelectionRange();
1145 else
1146 range = wxRichTextRange(0, m_richTextCtrl->GetLastPosition()+1);
1147
1148 int pages = wxRICHTEXT_FORMAT_FONT;
1149
1150 wxRichTextFormattingDialog formatDlg(pages, this);
1151 formatDlg.GetStyle(m_richTextCtrl, range);
1152
1153 if (formatDlg.ShowModal() == wxID_OK)
1154 {
42688aea 1155 formatDlg.ApplyStyle(m_richTextCtrl, range, wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_OPTIMIZE|wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY);
8c9c49a1
JS
1156 }
1157
1158 // Old method using wxFontDialog
1159#if 0
5d7836c4
JS
1160 if (!m_richTextCtrl->HasSelection())
1161 return;
1162
1163 wxRichTextRange range = m_richTextCtrl->GetSelectionRange();
1164 wxFontData fontData;
1165
24777478 1166 wxRichTextAttr attr;
5d7836c4
JS
1167 attr.SetFlags(wxTEXT_ATTR_FONT);
1168
1169 if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
1170 fontData.SetInitialFont(attr.GetFont());
1171
1172 wxFontDialog dialog(this, fontData);
1173 if (dialog.ShowModal() == wxID_OK)
1174 {
1175 fontData = dialog.GetFontData();
1176 attr.SetFlags(wxTEXT_ATTR_FONT);
1177 attr.SetFont(fontData.GetChosenFont());
1178 if (attr.GetFont().Ok())
1179 {
1180 m_richTextCtrl->SetStyle(range, attr);
1181 }
1182 }
8c9c49a1
JS
1183#endif
1184}
1185
cdaed652
VZ
1186void MyFrame::OnImage(wxCommandEvent& WXUNUSED(event))
1187{
1188 wxRichTextRange range;
1189 wxASSERT(m_richTextCtrl->HasSelection());
1190
1191 range = m_richTextCtrl->GetSelectionRange();
1192 wxASSERT(range.ToInternal().GetLength() == 1);
1193
1194 wxRichTextImage* image = wxDynamicCast(m_richTextCtrl->GetBuffer().GetLeafObjectAtPosition(range.GetStart()), wxRichTextImage);
1195 if (image)
1196 {
1197 wxRichTextImageDialog imageDlg(this);
1198 imageDlg.SetImageObject(image, &m_richTextCtrl->GetBuffer());
1199
1200 if (imageDlg.ShowModal() == wxID_OK)
1201 {
1202 image = imageDlg.ApplyImageAttr();
1203 }
1204 }
1205}
1206
8c9c49a1
JS
1207void MyFrame::OnParagraph(wxCommandEvent& WXUNUSED(event))
1208{
1209 wxRichTextRange range;
1210 if (m_richTextCtrl->HasSelection())
1211 range = m_richTextCtrl->GetSelectionRange();
1212 else
1213 range = wxRichTextRange(0, m_richTextCtrl->GetLastPosition()+1);
1214
1215 int pages = wxRICHTEXT_FORMAT_INDENTS_SPACING|wxRICHTEXT_FORMAT_TABS|wxRICHTEXT_FORMAT_BULLETS;
1216
1217 wxRichTextFormattingDialog formatDlg(pages, this);
1218 formatDlg.GetStyle(m_richTextCtrl, range);
1219
1220 if (formatDlg.ShowModal() == wxID_OK)
1221 {
1222 formatDlg.ApplyStyle(m_richTextCtrl, range);
1223 }
1224}
1225
1226void MyFrame::OnFormat(wxCommandEvent& WXUNUSED(event))
1227{
1228 wxRichTextRange range;
1229 if (m_richTextCtrl->HasSelection())
1230 range = m_richTextCtrl->GetSelectionRange();
1231 else
1232 range = wxRichTextRange(0, m_richTextCtrl->GetLastPosition()+1);
1233
1234 int pages = wxRICHTEXT_FORMAT_FONT|wxRICHTEXT_FORMAT_INDENTS_SPACING|wxRICHTEXT_FORMAT_TABS|wxRICHTEXT_FORMAT_BULLETS;
1235
1236 wxRichTextFormattingDialog formatDlg(pages, this);
1237 formatDlg.GetStyle(m_richTextCtrl, range);
1238
1239 if (formatDlg.ShowModal() == wxID_OK)
1240 {
1241 formatDlg.ApplyStyle(m_richTextCtrl, range);
1242 }
1243}
1244
1245void MyFrame::OnUpdateFormat(wxUpdateUIEvent& event)
1246{
1247 event.Enable(m_richTextCtrl->HasSelection());
5d7836c4
JS
1248}
1249
cdaed652
VZ
1250void MyFrame::OnUpdateImage(wxUpdateUIEvent& event)
1251{
1252 wxRichTextRange range;
1253 wxRichTextObject *obj;
1254
1255 range = m_richTextCtrl->GetSelectionRange();
1256 if (range.ToInternal().GetLength() == 1)
1257 {
1258 obj = m_richTextCtrl->GetBuffer().GetLeafObjectAtPosition(range.GetStart());
1259 if (obj && obj->IsKindOf(CLASSINFO(wxRichTextImage)))
1260 {
1261 event.Enable(true);
1262 return;
1263 }
1264 }
1265
1266 event.Enable(false);
1267}
1268
011b3dcb 1269void MyFrame::OnIndentMore(wxCommandEvent& WXUNUSED(event))
5d7836c4 1270{
44cc96a8 1271 wxRichTextAttr attr;
5d7836c4
JS
1272 attr.SetFlags(wxTEXT_ATTR_LEFT_INDENT);
1273
1274 if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
1275 {
1276 wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
1277 if (m_richTextCtrl->HasSelection())
1278 range = m_richTextCtrl->GetSelectionRange();
1279
5d7836c4
JS
1280 attr.SetLeftIndent(attr.GetLeftIndent() + 100);
1281
1282 attr.SetFlags(wxTEXT_ATTR_LEFT_INDENT);
1283 m_richTextCtrl->SetStyle(range, attr);
1284 }
1285}
1286
011b3dcb 1287void MyFrame::OnIndentLess(wxCommandEvent& WXUNUSED(event))
5d7836c4 1288{
44cc96a8 1289 wxRichTextAttr attr;
5d7836c4
JS
1290 attr.SetFlags(wxTEXT_ATTR_LEFT_INDENT);
1291
1292 if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
1293 {
1294 wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
1295 if (m_richTextCtrl->HasSelection())
1296 range = m_richTextCtrl->GetSelectionRange();
1297
c3e54dee 1298 if (attr.GetLeftIndent() > 0)
5d7836c4 1299 {
c3e54dee 1300 attr.SetLeftIndent(wxMax(0, attr.GetLeftIndent() - 100));
9a173d48 1301
5d7836c4
JS
1302 m_richTextCtrl->SetStyle(range, attr);
1303 }
1304 }
1305}
1306
011b3dcb 1307void MyFrame::OnLineSpacingHalf(wxCommandEvent& WXUNUSED(event))
5d7836c4 1308{
44cc96a8 1309 wxRichTextAttr attr;
5d7836c4
JS
1310 attr.SetFlags(wxTEXT_ATTR_LINE_SPACING);
1311
1312 if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
1313 {
1314 wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
1315 if (m_richTextCtrl->HasSelection())
1316 range = m_richTextCtrl->GetSelectionRange();
1317
5d7836c4
JS
1318 attr.SetFlags(wxTEXT_ATTR_LINE_SPACING);
1319 attr.SetLineSpacing(15);
9a173d48 1320
5d7836c4
JS
1321 m_richTextCtrl->SetStyle(range, attr);
1322 }
1323}
1324
011b3dcb 1325void MyFrame::OnLineSpacingDouble(wxCommandEvent& WXUNUSED(event))
5d7836c4 1326{
44cc96a8 1327 wxRichTextAttr attr;
5d7836c4
JS
1328 attr.SetFlags(wxTEXT_ATTR_LINE_SPACING);
1329
1330 if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
1331 {
1332 wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
1333 if (m_richTextCtrl->HasSelection())
1334 range = m_richTextCtrl->GetSelectionRange();
1335
5d7836c4
JS
1336 attr.SetFlags(wxTEXT_ATTR_LINE_SPACING);
1337 attr.SetLineSpacing(20);
9a173d48 1338
5d7836c4
JS
1339 m_richTextCtrl->SetStyle(range, attr);
1340 }
1341}
1342
011b3dcb 1343void MyFrame::OnLineSpacingSingle(wxCommandEvent& WXUNUSED(event))
5d7836c4 1344{
44cc96a8 1345 wxRichTextAttr attr;
5d7836c4
JS
1346 attr.SetFlags(wxTEXT_ATTR_LINE_SPACING);
1347
1348 if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
1349 {
1350 wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
1351 if (m_richTextCtrl->HasSelection())
1352 range = m_richTextCtrl->GetSelectionRange();
1353
5d7836c4
JS
1354 attr.SetFlags(wxTEXT_ATTR_LINE_SPACING);
1355 attr.SetLineSpacing(0); // Can also use 10
9a173d48 1356
5d7836c4
JS
1357 m_richTextCtrl->SetStyle(range, attr);
1358 }
1359}
1360
011b3dcb 1361void MyFrame::OnParagraphSpacingMore(wxCommandEvent& WXUNUSED(event))
5d7836c4 1362{
44cc96a8 1363 wxRichTextAttr attr;
5d7836c4
JS
1364 attr.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER);
1365
1366 if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
1367 {
1368 wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
1369 if (m_richTextCtrl->HasSelection())
1370 range = m_richTextCtrl->GetSelectionRange();
1371
5d7836c4
JS
1372 attr.SetParagraphSpacingAfter(attr.GetParagraphSpacingAfter() + 20);
1373
1374 attr.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER);
1375 m_richTextCtrl->SetStyle(range, attr);
1376 }
1377}
1378
011b3dcb 1379void MyFrame::OnParagraphSpacingLess(wxCommandEvent& WXUNUSED(event))
5d7836c4 1380{
44cc96a8 1381 wxRichTextAttr attr;
5d7836c4
JS
1382 attr.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER);
1383
1384 if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
1385 {
1386 wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
1387 if (m_richTextCtrl->HasSelection())
1388 range = m_richTextCtrl->GetSelectionRange();
1389
1390 if (attr.GetParagraphSpacingAfter() >= 20)
1391 {
5d7836c4 1392 attr.SetParagraphSpacingAfter(attr.GetParagraphSpacingAfter() - 20);
9a173d48 1393
5d7836c4
JS
1394 attr.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER);
1395 m_richTextCtrl->SetStyle(range, attr);
1396 }
1397 }
1398}
1399
99404ab0
JS
1400void MyFrame::OnReload(wxCommandEvent& WXUNUSED(event))
1401{
1402 m_richTextCtrl->Clear();
1403 WriteInitialText();
1404}
1405
011b3dcb 1406void MyFrame::OnViewHTML(wxCommandEvent& WXUNUSED(event))
5d7836c4
JS
1407{
1408 wxDialog dialog(this, wxID_ANY, _("HTML"), wxDefaultPosition, wxSize(500, 400), wxDEFAULT_DIALOG_STYLE);
1409
1410 wxBoxSizer* boxSizer = new wxBoxSizer(wxVERTICAL);
1411 dialog.SetSizer(boxSizer);
1412
1413 wxHtmlWindow* win = new wxHtmlWindow(& dialog, wxID_ANY, wxDefaultPosition, wxSize(500, 400), wxSUNKEN_BORDER);
1414 boxSizer->Add(win, 1, wxALL, 5);
1415
1416 wxButton* cancelButton = new wxButton(& dialog, wxID_CANCEL, wxT("&Close"));
1417 boxSizer->Add(cancelButton, 0, wxALL|wxCENTRE, 5);
1418
1419 wxString text;
1420 wxStringOutputStream strStream(& text);
1421
1422 wxRichTextHTMLHandler htmlHandler;
720cc10a 1423 htmlHandler.SetFlags(wxRICHTEXT_HANDLER_SAVE_IMAGES_TO_MEMORY);
c3e54dee 1424
50f65288
WS
1425 wxArrayInt fontSizeMapping;
1426 fontSizeMapping.Add(7);
1427 fontSizeMapping.Add(9);
1428 fontSizeMapping.Add(11);
1429 fontSizeMapping.Add(12);
1430 fontSizeMapping.Add(14);
1431 fontSizeMapping.Add(22);
1432 fontSizeMapping.Add(100);
c3e54dee 1433
50f65288 1434 htmlHandler.SetFontSizeMapping(fontSizeMapping);
720cc10a 1435
5d7836c4
JS
1436 if (htmlHandler.SaveFile(& m_richTextCtrl->GetBuffer(), strStream))
1437 {
1438 win->SetPage(text);
1439 }
1440
1441 boxSizer->Fit(& dialog);
1442
1443 dialog.ShowModal();
720cc10a
JS
1444
1445 // Now delete the temporary in-memory images
1446 htmlHandler.DeleteTemporaryImages();
5d7836c4 1447}
fe5aa22c
JS
1448
1449// Demonstrates how you can change the style sheets and have the changes
1450// reflected in the control content without wiping out character formatting.
1451
1452void MyFrame::OnSwitchStyleSheets(wxCommandEvent& WXUNUSED(event))
1453{
1454 static wxRichTextStyleSheet* gs_AlternateStyleSheet = NULL;
1455
e4723634 1456 wxRichTextStyleListCtrl *styleList = (wxRichTextStyleListCtrl*) FindWindow(ID_RICHTEXT_STYLE_LIST);
fe5aa22c
JS
1457 wxRichTextStyleComboCtrl* styleCombo = (wxRichTextStyleComboCtrl*) FindWindow(ID_RICHTEXT_STYLE_COMBO);
1458
8881d9f0 1459 wxRichTextStyleSheet* sheet = m_richTextCtrl->GetStyleSheet();
fe5aa22c
JS
1460
1461 // One-time creation of an alternate style sheet
1462 if (!gs_AlternateStyleSheet)
1463 {
1464 gs_AlternateStyleSheet = new wxRichTextStyleSheet(*sheet);
1465
1466 // Make some modifications
1467 for (int i = 0; i < (int) gs_AlternateStyleSheet->GetParagraphStyleCount(); i++)
1468 {
1469 wxRichTextParagraphStyleDefinition* def = gs_AlternateStyleSheet->GetParagraphStyle(i);
1470
1471 if (def->GetStyle().HasTextColour())
1472 def->GetStyle().SetTextColour(*wxBLUE);
1473
1474 if (def->GetStyle().HasAlignment())
1475 {
1476 if (def->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_CENTRE)
1477 def->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_RIGHT);
1478 else if (def->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_LEFT)
1479 def->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_CENTRE);
1480 }
1481 if (def->GetStyle().HasLeftIndent())
1482 {
1483 def->GetStyle().SetLeftIndent(def->GetStyle().GetLeftIndent() * 2);
1484 }
1485 }
1486 }
1487
1488 // Switch sheets
1489 wxRichTextStyleSheet* tmp = gs_AlternateStyleSheet;
1490 gs_AlternateStyleSheet = sheet;
1491 sheet = tmp;
1492
8881d9f0
JS
1493 m_richTextCtrl->SetStyleSheet(sheet);
1494 m_richTextCtrl->ApplyStyleSheet(sheet); // Makes the control reflect the new style definitions
fe5aa22c
JS
1495
1496 styleList->SetStyleSheet(sheet);
1497 styleList->UpdateStyles();
1498
1499 styleCombo->SetStyleSheet(sheet);
1500 styleCombo->UpdateStyles();
1501}
8c9c49a1 1502
e4723634
JS
1503void MyFrame::OnManageStyles(wxCommandEvent& WXUNUSED(event))
1504{
8881d9f0 1505 wxRichTextStyleSheet* sheet = m_richTextCtrl->GetStyleSheet();
e4723634
JS
1506
1507 int flags = wxRICHTEXT_ORGANISER_CREATE_STYLES|wxRICHTEXT_ORGANISER_EDIT_STYLES;
1508
1509 wxRichTextStyleOrganiserDialog dlg(flags, sheet, NULL, this, wxID_ANY, _("Style Manager"));
1510 dlg.ShowModal();
1511}
1512
8c9c49a1
JS
1513void MyFrame::OnInsertSymbol(wxCommandEvent& WXUNUSED(event))
1514{
44cc96a8 1515 wxRichTextAttr attr;
8c9c49a1 1516 attr.SetFlags(wxTEXT_ATTR_FONT);
8881d9f0 1517 m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr);
8c9c49a1
JS
1518
1519 wxString currentFontName;
1520 if (attr.HasFont() && attr.GetFont().Ok())
1521 currentFontName = attr.GetFont().GetFaceName();
1522
1523 // Don't set the initial font in the dialog (so the user is choosing
1524 // 'normal text', i.e. the current font) but do tell the dialog
1525 // what 'normal text' is.
1526
1527 wxSymbolPickerDialog dlg(wxT("*"), wxEmptyString, currentFontName, this);
1528
1529 if (dlg.ShowModal() == wxID_OK)
1530 {
1531 if (dlg.HasSelection())
1532 {
8881d9f0 1533 long insertionPoint = m_richTextCtrl->GetInsertionPoint();
8c9c49a1 1534
8881d9f0 1535 m_richTextCtrl->WriteText(dlg.GetSymbol());
8c9c49a1
JS
1536
1537 if (!dlg.UseNormalFont())
1538 {
1539 wxFont font(attr.GetFont());
23c386ba 1540 font.SetFaceName(dlg.GetFontName());
8c9c49a1 1541 attr.SetFont(font);
8881d9f0 1542 m_richTextCtrl->SetStyle(insertionPoint, insertionPoint+1, attr);
8c9c49a1
JS
1543 }
1544 }
1545 }
1546}
082cfe55
JS
1547
1548void MyFrame::OnNumberList(wxCommandEvent& WXUNUSED(event))
1549{
8881d9f0 1550 if (m_richTextCtrl->HasSelection())
082cfe55 1551 {
8881d9f0
JS
1552 wxRichTextRange range = m_richTextCtrl->GetSelectionRange();
1553 m_richTextCtrl->SetListStyle(range, wxT("Numbered List 1"), wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_RENUMBER);
082cfe55
JS
1554 }
1555}
1556
e4723634
JS
1557void MyFrame::OnBulletsAndNumbering(wxCommandEvent& WXUNUSED(event))
1558{
8881d9f0 1559 wxRichTextStyleSheet* sheet = m_richTextCtrl->GetStyleSheet();
e4723634
JS
1560
1561 int flags = wxRICHTEXT_ORGANISER_BROWSE_NUMBERING;
1562
8881d9f0 1563 wxRichTextStyleOrganiserDialog dlg(flags, sheet, m_richTextCtrl, this, wxID_ANY, _("Bullets and Numbering"));
e4723634
JS
1564 if (dlg.ShowModal() == wxID_OK)
1565 {
1566 if (dlg.GetSelectedStyleDefinition())
1567 dlg.ApplyStyle();
1568 }
1569}
1570
082cfe55
JS
1571void MyFrame::OnItemizeList(wxCommandEvent& WXUNUSED(event))
1572{
8881d9f0 1573 if (m_richTextCtrl->HasSelection())
082cfe55 1574 {
8881d9f0
JS
1575 wxRichTextRange range = m_richTextCtrl->GetSelectionRange();
1576 m_richTextCtrl->SetListStyle(range, wxT("Bullet List 1"));
082cfe55
JS
1577 }
1578}
1579
1580void MyFrame::OnRenumberList(wxCommandEvent& WXUNUSED(event))
1581{
8881d9f0 1582 if (m_richTextCtrl->HasSelection())
082cfe55 1583 {
8881d9f0
JS
1584 wxRichTextRange range = m_richTextCtrl->GetSelectionRange();
1585 m_richTextCtrl->NumberList(range, NULL, wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_RENUMBER);
082cfe55
JS
1586 }
1587}
1588
1589void MyFrame::OnPromoteList(wxCommandEvent& WXUNUSED(event))
1590{
8881d9f0 1591 if (m_richTextCtrl->HasSelection())
082cfe55 1592 {
8881d9f0
JS
1593 wxRichTextRange range = m_richTextCtrl->GetSelectionRange();
1594 m_richTextCtrl->PromoteList(1, range, NULL);
082cfe55
JS
1595 }
1596}
1597
1598void MyFrame::OnDemoteList(wxCommandEvent& WXUNUSED(event))
1599{
8881d9f0 1600 if (m_richTextCtrl->HasSelection())
082cfe55 1601 {
8881d9f0
JS
1602 wxRichTextRange range = m_richTextCtrl->GetSelectionRange();
1603 m_richTextCtrl->PromoteList(-1, range, NULL);
082cfe55
JS
1604 }
1605}
1606
1607void MyFrame::OnClearList(wxCommandEvent& WXUNUSED(event))
1608{
8881d9f0 1609 if (m_richTextCtrl->HasSelection())
082cfe55 1610 {
8881d9f0
JS
1611 wxRichTextRange range = m_richTextCtrl->GetSelectionRange();
1612 m_richTextCtrl->ClearListStyle(range);
082cfe55
JS
1613 }
1614}
1615
720cc10a
JS
1616void MyFrame::OnInsertURL(wxCommandEvent& WXUNUSED(event))
1617{
1618 wxString url = wxGetTextFromUser(_("URL:"), _("Insert URL"));
1619 if (!url.IsEmpty())
1620 {
720cc10a
JS
1621 // Make a style suitable for showing a URL
1622 wxRichTextAttr urlStyle;
1623 urlStyle.SetTextColour(*wxBLUE);
1624 urlStyle.SetFontUnderlined(true);
c3e54dee 1625
8881d9f0
JS
1626 m_richTextCtrl->BeginStyle(urlStyle);
1627 m_richTextCtrl->BeginURL(url);
1628 m_richTextCtrl->WriteText(url);
1629 m_richTextCtrl->EndURL();
1630 m_richTextCtrl->EndStyle();
720cc10a
JS
1631 }
1632}
1633
cdaed652
VZ
1634void MyFrame::OnInsertImage(wxCommandEvent& WXUNUSED(event))
1635{
1636 wxFileDialog dialog(this, _("Choose an image"), "", "", "BMP and GIF files (*.bmp;*.gif)|*.bmp;*.gif|PNG files (*.png)|*.png");
1637 if (dialog.ShowModal() == wxID_OK)
1638 {
1639 wxString path = dialog.GetPath();
1640 m_richTextCtrl->WriteImage(path, wxBITMAP_TYPE_ANY);
1641 }
1642}
1643
720cc10a
JS
1644void MyFrame::OnURL(wxTextUrlEvent& event)
1645{
1646 wxMessageBox(event.GetString());
1647}
1648
1649// Veto style sheet replace events when loading from XML, since we want
1650// to keep the original style sheet.
1651void MyFrame::OnStyleSheetReplacing(wxRichTextEvent& event)
1652{
1653 event.Veto();
1654}
8881d9f0
JS
1655
1656void MyFrame::OnPrint(wxCommandEvent& WXUNUSED(event))
1657{
1658 wxGetApp().GetPrinting()->PrintBuffer(m_richTextCtrl->GetBuffer());
1659}
1660
1661void MyFrame::OnPreview(wxCommandEvent& WXUNUSED(event))
1662{
1663 wxGetApp().GetPrinting()->PreviewBuffer(m_richTextCtrl->GetBuffer());
1664}
1665
1666void MyFrame::OnPageSetup(wxCommandEvent& WXUNUSED(event))
1667{
24777478
JS
1668 wxDialog dialog(this, wxID_ANY, wxT("Testing"), wxPoint(10, 10), wxSize(400, 300), wxDEFAULT_DIALOG_STYLE);
1669
1670 wxNotebook* nb = new wxNotebook(& dialog, wxID_ANY, wxPoint(5, 5), wxSize(300, 250));
1671 wxPanel* panel = new wxPanel(nb, wxID_ANY, wxDefaultPosition, wxDefaultSize);
1672 wxPanel* panel2 = new wxPanel(nb, wxID_ANY, wxDefaultPosition, wxDefaultSize);
1673
1674 wxRichTextCtrl* richTextCtrl = new wxRichTextCtrl(panel, wxID_ANY, wxEmptyString, wxPoint(5, 5), wxSize(200, 150), wxVSCROLL|wxTE_READONLY);
1675 nb->AddPage(panel, wxT("Page 1"));
1676
1677 wxRichTextCtrl* richTextCtrl2 = new wxRichTextCtrl(panel2, wxID_ANY, wxEmptyString, wxPoint(5, 5), wxSize(200, 150), wxVSCROLL|wxTE_READONLY);
1678 nb->AddPage(panel2, wxT("Page 2"));
1679
1680 wxButton* button = new wxButton(& dialog, wxID_OK, wxT("OK"), wxPoint(5, 180));
1681
1682 dialog.ShowModal();
1683
1684// wxGetApp().GetPrinting()->PageSetup();
8881d9f0 1685}