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