1 /////////////////////////////////////////////////////////////////////////////
2 // Name: samples/richtext/richtext.cpp
3 // Purpose: wxWidgets rich text editor sample
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx/wx.h".
21 #include "wx/wxprec.h"
27 // for all others, include the necessary headers (this file is usually all you
28 // need because it includes almost all "standard" wxWidgets headers)
33 #include "wx/fontdlg.h"
34 #include "wx/splitter.h"
35 #include "wx/sstream.h"
36 #include "wx/html/htmlwin.h"
37 #include "wx/stopwatch.h"
40 #include "wx/filesys.h"
41 #include "wx/fs_mem.h"
45 #include "wx/cshelp.h"
49 #include "../sample.xpm"
52 #include "bitmaps/smiley.xpm"
53 // #include "bitmaps/idea.xpm"
54 #include "bitmaps/zebra.xpm"
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"
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"
74 #include "wx/richtext/richtextctrl.h"
75 #include "wx/richtext/richtextstyles.h"
76 #include "wx/richtext/richtextxml.h"
77 #include "wx/richtext/richtexthtml.h"
78 #include "wx/richtext/richtextformatdlg.h"
79 #include "wx/richtext/richtextsymboldlg.h"
80 #include "wx/richtext/richtextstyledlg.h"
81 #include "wx/richtext/richtextprint.h"
82 #include "wx/richtext/richtextimagedlg.h"
84 // ----------------------------------------------------------------------------
86 // ----------------------------------------------------------------------------
88 // ----------------------------------------------------------------------------
90 // ----------------------------------------------------------------------------
92 // Define a new application type, each program should derive a class from wxApp
93 class MyApp
: public wxApp
96 // override base class virtuals
97 // ----------------------------
99 // this one is called on application startup and is a good place for the app
100 // initialization (doing it here and not in the ctor allows to have an error
101 // return: if OnInit() returns false, the application terminates)
102 virtual bool OnInit();
103 virtual int OnExit();
107 wxRichTextStyleSheet
* GetStyleSheet() const { return m_styleSheet
; }
108 wxRichTextPrinting
* GetPrinting() const { return m_printing
; }
110 wxRichTextStyleSheet
* m_styleSheet
;
111 wxRichTextPrinting
* m_printing
;
114 // Define a new frame type: this is going to be our main frame
115 class MyFrame
: public wxFrame
119 MyFrame(const wxString
& title
, wxWindowID id
, const wxPoint
& pos
= wxDefaultPosition
,
120 const wxSize
& size
= wxDefaultSize
, long style
= wxDEFAULT_FRAME_STYLE
);
122 // event handlers (these functions should _not_ be virtual)
123 void OnQuit(wxCommandEvent
& event
);
124 void OnAbout(wxCommandEvent
& event
);
126 void OnOpen(wxCommandEvent
& event
);
127 void OnSave(wxCommandEvent
& event
);
128 void OnSaveAs(wxCommandEvent
& event
);
130 void OnBold(wxCommandEvent
& event
);
131 void OnItalic(wxCommandEvent
& event
);
132 void OnUnderline(wxCommandEvent
& event
);
134 void OnUpdateBold(wxUpdateUIEvent
& event
);
135 void OnUpdateItalic(wxUpdateUIEvent
& event
);
136 void OnUpdateUnderline(wxUpdateUIEvent
& event
);
138 void OnAlignLeft(wxCommandEvent
& event
);
139 void OnAlignCentre(wxCommandEvent
& event
);
140 void OnAlignRight(wxCommandEvent
& event
);
142 void OnUpdateAlignLeft(wxUpdateUIEvent
& event
);
143 void OnUpdateAlignCentre(wxUpdateUIEvent
& event
);
144 void OnUpdateAlignRight(wxUpdateUIEvent
& event
);
146 void OnIndentMore(wxCommandEvent
& event
);
147 void OnIndentLess(wxCommandEvent
& event
);
149 void OnFont(wxCommandEvent
& event
);
150 void OnImage(wxCommandEvent
& event
);
151 void OnUpdateImage(wxUpdateUIEvent
& event
);
152 void OnParagraph(wxCommandEvent
& event
);
153 void OnFormat(wxCommandEvent
& event
);
154 void OnUpdateFormat(wxUpdateUIEvent
& event
);
156 void OnInsertSymbol(wxCommandEvent
& event
);
158 void OnLineSpacingHalf(wxCommandEvent
& event
);
159 void OnLineSpacingDouble(wxCommandEvent
& event
);
160 void OnLineSpacingSingle(wxCommandEvent
& event
);
162 void OnParagraphSpacingMore(wxCommandEvent
& event
);
163 void OnParagraphSpacingLess(wxCommandEvent
& event
);
165 void OnNumberList(wxCommandEvent
& event
);
166 void OnBulletsAndNumbering(wxCommandEvent
& event
);
167 void OnItemizeList(wxCommandEvent
& event
);
168 void OnRenumberList(wxCommandEvent
& event
);
169 void OnPromoteList(wxCommandEvent
& event
);
170 void OnDemoteList(wxCommandEvent
& event
);
171 void OnClearList(wxCommandEvent
& event
);
173 void OnReload(wxCommandEvent
& event
);
175 void OnViewHTML(wxCommandEvent
& event
);
177 void OnSwitchStyleSheets(wxCommandEvent
& event
);
178 void OnManageStyles(wxCommandEvent
& event
);
180 void OnInsertURL(wxCommandEvent
& event
);
181 void OnURL(wxTextUrlEvent
& event
);
182 void OnStyleSheetReplacing(wxRichTextEvent
& event
);
184 void OnPrint(wxCommandEvent
& event
);
185 void OnPreview(wxCommandEvent
& event
);
186 void OnPageSetup(wxCommandEvent
& event
);
188 void OnInsertImage(wxCommandEvent
& event
);
191 // Forward command events to the current rich text control, if any
192 bool ProcessEvent(wxEvent
& event
);
195 void WriteInitialText();
198 // any class wishing to process wxWidgets events must use this macro
199 DECLARE_EVENT_TABLE()
201 wxRichTextCtrl
* m_richTextCtrl
;
204 // ----------------------------------------------------------------------------
206 // ----------------------------------------------------------------------------
208 // IDs for the controls and the menu commands
213 ID_About
= wxID_ABOUT
,
215 ID_FORMAT_BOLD
= 100,
229 ID_FORMAT_ALIGN_LEFT
,
230 ID_FORMAT_ALIGN_CENTRE
,
231 ID_FORMAT_ALIGN_RIGHT
,
233 ID_FORMAT_INDENT_MORE
,
234 ID_FORMAT_INDENT_LESS
,
236 ID_FORMAT_PARAGRAPH_SPACING_MORE
,
237 ID_FORMAT_PARAGRAPH_SPACING_LESS
,
239 ID_FORMAT_LINE_SPACING_HALF
,
240 ID_FORMAT_LINE_SPACING_DOUBLE
,
241 ID_FORMAT_LINE_SPACING_SINGLE
,
243 ID_FORMAT_NUMBER_LIST
,
244 ID_FORMAT_BULLETS_AND_NUMBERING
,
245 ID_FORMAT_ITEMIZE_LIST
,
246 ID_FORMAT_RENUMBER_LIST
,
247 ID_FORMAT_PROMOTE_LIST
,
248 ID_FORMAT_DEMOTE_LIST
,
249 ID_FORMAT_CLEAR_LIST
,
252 ID_SWITCH_STYLE_SHEETS
,
260 ID_RICHTEXT_STYLE_LIST
,
261 ID_RICHTEXT_STYLE_COMBO
264 // ----------------------------------------------------------------------------
265 // event tables and other macros for wxWidgets
266 // ----------------------------------------------------------------------------
268 // the event tables connect the wxWidgets events with the functions (event
269 // handlers) which process them. It can be also done at run-time, but for the
270 // simple menu events like this the static method is much simpler.
271 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
272 EVT_MENU(ID_Quit
, MyFrame::OnQuit
)
273 EVT_MENU(ID_About
, MyFrame::OnAbout
)
275 EVT_MENU(wxID_OPEN
, MyFrame::OnOpen
)
276 EVT_MENU(wxID_SAVE
, MyFrame::OnSave
)
277 EVT_MENU(wxID_SAVEAS
, MyFrame::OnSaveAs
)
279 EVT_MENU(ID_FORMAT_BOLD
, MyFrame::OnBold
)
280 EVT_MENU(ID_FORMAT_ITALIC
, MyFrame::OnItalic
)
281 EVT_MENU(ID_FORMAT_UNDERLINE
, MyFrame::OnUnderline
)
283 EVT_UPDATE_UI(ID_FORMAT_BOLD
, MyFrame::OnUpdateBold
)
284 EVT_UPDATE_UI(ID_FORMAT_ITALIC
, MyFrame::OnUpdateItalic
)
285 EVT_UPDATE_UI(ID_FORMAT_UNDERLINE
, MyFrame::OnUpdateUnderline
)
287 EVT_MENU(ID_FORMAT_ALIGN_LEFT
, MyFrame::OnAlignLeft
)
288 EVT_MENU(ID_FORMAT_ALIGN_CENTRE
, MyFrame::OnAlignCentre
)
289 EVT_MENU(ID_FORMAT_ALIGN_RIGHT
, MyFrame::OnAlignRight
)
291 EVT_UPDATE_UI(ID_FORMAT_ALIGN_LEFT
, MyFrame::OnUpdateAlignLeft
)
292 EVT_UPDATE_UI(ID_FORMAT_ALIGN_CENTRE
, MyFrame::OnUpdateAlignCentre
)
293 EVT_UPDATE_UI(ID_FORMAT_ALIGN_RIGHT
, MyFrame::OnUpdateAlignRight
)
295 EVT_MENU(ID_FORMAT_FONT
, MyFrame::OnFont
)
296 EVT_MENU(ID_FORMAT_IMAGE
, MyFrame::OnImage
)
297 EVT_MENU(ID_FORMAT_PARAGRAPH
, MyFrame::OnParagraph
)
298 EVT_MENU(ID_FORMAT_CONTENT
, MyFrame::OnFormat
)
299 EVT_UPDATE_UI(ID_FORMAT_CONTENT
, MyFrame::OnUpdateFormat
)
300 EVT_UPDATE_UI(ID_FORMAT_FONT
, MyFrame::OnUpdateFormat
)
301 EVT_UPDATE_UI(ID_FORMAT_IMAGE
, MyFrame::OnUpdateImage
)
302 EVT_UPDATE_UI(ID_FORMAT_PARAGRAPH
, MyFrame::OnUpdateFormat
)
303 EVT_MENU(ID_FORMAT_INDENT_MORE
, MyFrame::OnIndentMore
)
304 EVT_MENU(ID_FORMAT_INDENT_LESS
, MyFrame::OnIndentLess
)
306 EVT_MENU(ID_FORMAT_LINE_SPACING_HALF
, MyFrame::OnLineSpacingHalf
)
307 EVT_MENU(ID_FORMAT_LINE_SPACING_SINGLE
, MyFrame::OnLineSpacingSingle
)
308 EVT_MENU(ID_FORMAT_LINE_SPACING_DOUBLE
, MyFrame::OnLineSpacingDouble
)
310 EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_MORE
, MyFrame::OnParagraphSpacingMore
)
311 EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_LESS
, MyFrame::OnParagraphSpacingLess
)
313 EVT_MENU(ID_RELOAD
, MyFrame::OnReload
)
315 EVT_MENU(ID_INSERT_SYMBOL
, MyFrame::OnInsertSymbol
)
316 EVT_MENU(ID_INSERT_URL
, MyFrame::OnInsertURL
)
317 EVT_MENU(ID_INSERT_IMAGE
, MyFrame::OnInsertImage
)
319 EVT_MENU(ID_FORMAT_NUMBER_LIST
, MyFrame::OnNumberList
)
320 EVT_MENU(ID_FORMAT_BULLETS_AND_NUMBERING
, MyFrame::OnBulletsAndNumbering
)
321 EVT_MENU(ID_FORMAT_ITEMIZE_LIST
, MyFrame::OnItemizeList
)
322 EVT_MENU(ID_FORMAT_RENUMBER_LIST
, MyFrame::OnRenumberList
)
323 EVT_MENU(ID_FORMAT_PROMOTE_LIST
, MyFrame::OnPromoteList
)
324 EVT_MENU(ID_FORMAT_DEMOTE_LIST
, MyFrame::OnDemoteList
)
325 EVT_MENU(ID_FORMAT_CLEAR_LIST
, MyFrame::OnClearList
)
327 EVT_MENU(ID_VIEW_HTML
, MyFrame::OnViewHTML
)
328 EVT_MENU(ID_SWITCH_STYLE_SHEETS
, MyFrame::OnSwitchStyleSheets
)
329 EVT_MENU(ID_MANAGE_STYLES
, MyFrame::OnManageStyles
)
331 EVT_MENU(ID_PRINT
, MyFrame::OnPrint
)
332 EVT_MENU(ID_PREVIEW
, MyFrame::OnPreview
)
333 EVT_MENU(ID_PAGE_SETUP
, MyFrame::OnPageSetup
)
335 EVT_TEXT_URL(wxID_ANY
, MyFrame::OnURL
)
336 EVT_RICHTEXT_STYLESHEET_REPLACING(wxID_ANY
, MyFrame::OnStyleSheetReplacing
)
339 // Create a new application object: this macro will allow wxWidgets to create
340 // the application object during program execution (it's better than using a
341 // static object for many reasons) and also implements the accessor function
342 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
346 // ============================================================================
348 // ============================================================================
350 // ----------------------------------------------------------------------------
351 // the application class
352 // ----------------------------------------------------------------------------
354 // 'Main program' equivalent: the program execution "starts" here
357 if ( !wxApp::OnInit() )
361 wxHelpProvider::Set(new wxSimpleHelpProvider
);
364 m_styleSheet
= new wxRichTextStyleSheet
;
365 m_printing
= new wxRichTextPrinting(wxT("Test Document"));
367 m_printing
->SetFooterText(wxT("@TITLE@"), wxRICHTEXT_PAGE_ALL
, wxRICHTEXT_PAGE_CENTRE
);
368 m_printing
->SetFooterText(wxT("Page @PAGENUM@"), wxRICHTEXT_PAGE_ALL
, wxRICHTEXT_PAGE_RIGHT
);
372 // Add extra handlers (plain text is automatically added)
373 wxRichTextBuffer::AddHandler(new wxRichTextXMLHandler
);
374 wxRichTextBuffer::AddHandler(new wxRichTextHTMLHandler
);
376 // Add image handlers
378 wxImage::AddHandler( new wxPNGHandler
);
382 wxImage::AddHandler( new wxJPEGHandler
);
386 wxImage::AddHandler( new wxGIFHandler
);
390 wxFileSystem::AddHandler( new wxMemoryFSHandler
);
393 // create the main application window
394 MyFrame
*frame
= new MyFrame(wxT("wxRichTextCtrl Sample"), wxID_ANY
, wxDefaultPosition
, wxSize(700, 600));
396 m_printing
->SetParentWindow(frame
);
398 // and show it (the frames, unlike simple controls, are not shown when
399 // created initially)
402 // success: wxApp::OnRun() will be called which will enter the main message
403 // loop and the application will run. If we returned false here, the
404 // application would exit immediately.
416 void MyApp::CreateStyles()
420 wxFont
romanFont(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
421 wxFont
swissFont(12, wxSWISS
, wxNORMAL
, wxNORMAL
);
423 wxRichTextParagraphStyleDefinition
* normalPara
= new wxRichTextParagraphStyleDefinition(wxT("Normal"));
424 wxRichTextAttr normalAttr
;
425 normalAttr
.SetFontFaceName(romanFont
.GetFaceName());
426 normalAttr
.SetFontSize(12);
427 // Let's set all attributes for this style
428 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
|
429 wxTEXT_ATTR_PARA_SPACING_BEFORE
|wxTEXT_ATTR_PARA_SPACING_AFTER
|wxTEXT_ATTR_LINE_SPACING
|
430 wxTEXT_ATTR_BULLET_STYLE
|wxTEXT_ATTR_BULLET_NUMBER
);
431 normalPara
->SetStyle(normalAttr
);
433 m_styleSheet
->AddParagraphStyle(normalPara
);
435 wxRichTextParagraphStyleDefinition
* indentedPara
= new wxRichTextParagraphStyleDefinition(wxT("Indented"));
436 wxRichTextAttr indentedAttr
;
437 indentedAttr
.SetFontFaceName(romanFont
.GetFaceName());
438 indentedAttr
.SetFontSize(12);
439 indentedAttr
.SetLeftIndent(100, 0);
440 // We only want to affect indentation
441 indentedAttr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
);
442 indentedPara
->SetStyle(indentedAttr
);
444 m_styleSheet
->AddParagraphStyle(indentedPara
);
446 wxRichTextParagraphStyleDefinition
* indentedPara2
= new wxRichTextParagraphStyleDefinition(wxT("Red Bold Indented"));
447 wxRichTextAttr indentedAttr2
;
448 indentedAttr2
.SetFontFaceName(romanFont
.GetFaceName());
449 indentedAttr2
.SetFontSize(12);
450 indentedAttr2
.SetFontWeight(wxFONTWEIGHT_BOLD
);
451 indentedAttr2
.SetTextColour(*wxRED
);
452 indentedAttr2
.SetFontSize(12);
453 indentedAttr2
.SetLeftIndent(100, 0);
454 // We want to affect indentation, font and text colour
455 indentedAttr2
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
|wxTEXT_ATTR_FONT
|wxTEXT_ATTR_TEXT_COLOUR
);
456 indentedPara2
->SetStyle(indentedAttr2
);
458 m_styleSheet
->AddParagraphStyle(indentedPara2
);
460 wxRichTextParagraphStyleDefinition
* flIndentedPara
= new wxRichTextParagraphStyleDefinition(wxT("First Line Indented"));
461 wxRichTextAttr flIndentedAttr
;
462 flIndentedAttr
.SetFontFaceName(swissFont
.GetFaceName());
463 flIndentedAttr
.SetFontSize(12);
464 flIndentedAttr
.SetLeftIndent(100, -100);
465 // We only want to affect indentation
466 flIndentedAttr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
);
467 flIndentedPara
->SetStyle(flIndentedAttr
);
469 m_styleSheet
->AddParagraphStyle(flIndentedPara
);
473 wxRichTextCharacterStyleDefinition
* boldDef
= new wxRichTextCharacterStyleDefinition(wxT("Bold"));
474 wxRichTextAttr boldAttr
;
475 boldAttr
.SetFontFaceName(romanFont
.GetFaceName());
476 boldAttr
.SetFontSize(12);
477 boldAttr
.SetFontWeight(wxFONTWEIGHT_BOLD
);
478 // We only want to affect boldness
479 boldAttr
.SetFlags(wxTEXT_ATTR_FONT_WEIGHT
);
480 boldDef
->SetStyle(boldAttr
);
482 m_styleSheet
->AddCharacterStyle(boldDef
);
484 wxRichTextCharacterStyleDefinition
* italicDef
= new wxRichTextCharacterStyleDefinition(wxT("Italic"));
485 wxRichTextAttr italicAttr
;
486 italicAttr
.SetFontFaceName(romanFont
.GetFaceName());
487 italicAttr
.SetFontSize(12);
488 italicAttr
.SetFontStyle(wxFONTSTYLE_ITALIC
);
489 // We only want to affect italics
490 italicAttr
.SetFlags(wxTEXT_ATTR_FONT_ITALIC
);
491 italicDef
->SetStyle(italicAttr
);
493 m_styleSheet
->AddCharacterStyle(italicDef
);
495 wxRichTextCharacterStyleDefinition
* redDef
= new wxRichTextCharacterStyleDefinition(wxT("Red Bold"));
496 wxRichTextAttr redAttr
;
497 redAttr
.SetFontFaceName(romanFont
.GetFaceName());
498 redAttr
.SetFontSize(12);
499 redAttr
.SetFontWeight(wxFONTWEIGHT_BOLD
);
500 redAttr
.SetTextColour(*wxRED
);
501 // We only want to affect colour, weight and face
502 redAttr
.SetFlags(wxTEXT_ATTR_FONT_FACE
|wxTEXT_ATTR_FONT_WEIGHT
|wxTEXT_ATTR_TEXT_COLOUR
);
503 redDef
->SetStyle(redAttr
);
505 m_styleSheet
->AddCharacterStyle(redDef
);
507 wxRichTextListStyleDefinition
* bulletList
= new wxRichTextListStyleDefinition(wxT("Bullet List 1"));
509 for (i
= 0; i
< 10; i
++)
513 bulletText
= wxT("standard/circle");
515 bulletText
= wxT("standard/square");
517 bulletText
= wxT("standard/circle");
519 bulletText
= wxT("standard/square");
521 bulletText
= wxT("standard/circle");
523 bulletList
->SetAttributes(i
, (i
+1)*60, 60, wxTEXT_ATTR_BULLET_STYLE_STANDARD
, bulletText
);
526 m_styleSheet
->AddListStyle(bulletList
);
528 wxRichTextListStyleDefinition
* numberedList
= new wxRichTextListStyleDefinition(wxT("Numbered List 1"));
529 for (i
= 0; i
< 10; i
++)
533 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
535 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_LETTERS_LOWER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
537 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ROMAN_LOWER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
539 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ROMAN_UPPER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
541 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
543 numberStyle
|= wxTEXT_ATTR_BULLET_STYLE_ALIGN_RIGHT
;
545 numberedList
->SetAttributes(i
, (i
+1)*60, 60, numberStyle
);
548 m_styleSheet
->AddListStyle(numberedList
);
550 wxRichTextListStyleDefinition
* outlineList
= new wxRichTextListStyleDefinition(wxT("Outline List 1"));
551 for (i
= 0; i
< 10; i
++)
555 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_OUTLINE
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
557 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
559 outlineList
->SetAttributes(i
, (i
+1)*120, 120, numberStyle
);
562 m_styleSheet
->AddListStyle(outlineList
);
565 // ----------------------------------------------------------------------------
567 // ----------------------------------------------------------------------------
570 MyFrame::MyFrame(const wxString
& title
, wxWindowID id
, const wxPoint
& pos
,
571 const wxSize
& size
, long style
)
572 : wxFrame(NULL
, id
, title
, pos
, size
, style
)
574 // set the frame icon
575 SetIcon(wxICON(sample
));
578 wxMenu
*fileMenu
= new wxMenu
;
580 // the "About" item should be in the help menu
581 wxMenu
*helpMenu
= new wxMenu
;
582 helpMenu
->Append(ID_About
, wxT("&About...\tF1"), wxT("Show about dialog"));
584 fileMenu
->Append(wxID_OPEN
, wxT("&Open\tCtrl+O"), wxT("Open a file"));
585 fileMenu
->Append(wxID_SAVE
, wxT("&Save\tCtrl+S"), wxT("Save a file"));
586 fileMenu
->Append(wxID_SAVEAS
, wxT("&Save As...\tF12"), wxT("Save to a new file"));
587 fileMenu
->AppendSeparator();
588 fileMenu
->Append(ID_RELOAD
, wxT("&Reload Text\tF2"), wxT("Reload the initial text"));
589 fileMenu
->AppendSeparator();
590 fileMenu
->Append(ID_PAGE_SETUP
, wxT("Page Set&up..."), wxT("Page setup"));
591 fileMenu
->Append(ID_PRINT
, wxT("&Print...\tCtrl+P"), wxT("Print"));
592 fileMenu
->Append(ID_PREVIEW
, wxT("Print Pre&view"), wxT("Print preview"));
593 fileMenu
->AppendSeparator();
594 fileMenu
->Append(ID_VIEW_HTML
, wxT("&View as HTML"), wxT("View HTML"));
595 fileMenu
->AppendSeparator();
596 fileMenu
->Append(ID_Quit
, wxT("E&xit\tAlt+X"), wxT("Quit this program"));
598 wxMenu
* editMenu
= new wxMenu
;
599 editMenu
->Append(wxID_UNDO
, _("&Undo\tCtrl+Z"));
600 editMenu
->Append(wxID_REDO
, _("&Redo\tCtrl+Y"));
601 editMenu
->AppendSeparator();
602 editMenu
->Append(wxID_CUT
, _("Cu&t\tCtrl+X"));
603 editMenu
->Append(wxID_COPY
, _("&Copy\tCtrl+C"));
604 editMenu
->Append(wxID_PASTE
, _("&Paste\tCtrl+V"));
606 editMenu
->AppendSeparator();
607 editMenu
->Append(wxID_SELECTALL
, _("Select A&ll\tCtrl+A"));
609 editMenu
->AppendSeparator();
610 editMenu
->Append(wxID_FIND
, _("&Find...\tCtrl+F"));
611 editMenu
->Append(stID_FIND_REPLACE
, _("&Replace...\tCtrl+R"));
614 wxMenu
* formatMenu
= new wxMenu
;
615 formatMenu
->AppendCheckItem(ID_FORMAT_BOLD
, _("&Bold\tCtrl+B"));
616 formatMenu
->AppendCheckItem(ID_FORMAT_ITALIC
, _("&Italic\tCtrl+I"));
617 formatMenu
->AppendCheckItem(ID_FORMAT_UNDERLINE
, _("&Underline\tCtrl+U"));
618 formatMenu
->AppendSeparator();
619 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_LEFT
, _("L&eft Align"));
620 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_RIGHT
, _("&Right Align"));
621 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_CENTRE
, _("&Centre"));
622 formatMenu
->AppendSeparator();
623 formatMenu
->Append(ID_FORMAT_INDENT_MORE
, _("Indent &More"));
624 formatMenu
->Append(ID_FORMAT_INDENT_LESS
, _("Indent &Less"));
625 formatMenu
->AppendSeparator();
626 formatMenu
->Append(ID_FORMAT_PARAGRAPH_SPACING_MORE
, _("Increase Paragraph &Spacing"));
627 formatMenu
->Append(ID_FORMAT_PARAGRAPH_SPACING_LESS
, _("Decrease &Paragraph Spacing"));
628 formatMenu
->AppendSeparator();
629 formatMenu
->Append(ID_FORMAT_LINE_SPACING_SINGLE
, _("Normal Line Spacing"));
630 formatMenu
->Append(ID_FORMAT_LINE_SPACING_HALF
, _("1.5 Line Spacing"));
631 formatMenu
->Append(ID_FORMAT_LINE_SPACING_DOUBLE
, _("Double Line Spacing"));
632 formatMenu
->AppendSeparator();
633 formatMenu
->Append(ID_FORMAT_FONT
, _("&Font..."));
634 formatMenu
->Append(ID_FORMAT_IMAGE
, _("Image Property"));
635 formatMenu
->Append(ID_FORMAT_PARAGRAPH
, _("&Paragraph..."));
636 formatMenu
->Append(ID_FORMAT_CONTENT
, _("Font and Pa&ragraph...\tShift+Ctrl+F"));
637 formatMenu
->AppendSeparator();
638 formatMenu
->Append(ID_SWITCH_STYLE_SHEETS
, _("&Switch Style Sheets"));
639 formatMenu
->Append(ID_MANAGE_STYLES
, _("&Manage Styles"));
641 wxMenu
* listsMenu
= new wxMenu
;
642 listsMenu
->Append(ID_FORMAT_BULLETS_AND_NUMBERING
, _("Bullets and &Numbering..."));
643 listsMenu
->AppendSeparator();
644 listsMenu
->Append(ID_FORMAT_NUMBER_LIST
, _("Number List"));
645 listsMenu
->Append(ID_FORMAT_ITEMIZE_LIST
, _("Itemize List"));
646 listsMenu
->Append(ID_FORMAT_RENUMBER_LIST
, _("Renumber List"));
647 listsMenu
->Append(ID_FORMAT_PROMOTE_LIST
, _("Promote List Items"));
648 listsMenu
->Append(ID_FORMAT_DEMOTE_LIST
, _("Demote List Items"));
649 listsMenu
->Append(ID_FORMAT_CLEAR_LIST
, _("Clear List Formatting"));
651 wxMenu
* insertMenu
= new wxMenu
;
652 insertMenu
->Append(ID_INSERT_SYMBOL
, _("&Symbol...\tCtrl+I"));
653 insertMenu
->Append(ID_INSERT_URL
, _("&URL..."));
654 insertMenu
->Append(ID_INSERT_IMAGE
, _("&Image..."));
656 // now append the freshly created menu to the menu bar...
657 wxMenuBar
*menuBar
= new wxMenuBar();
658 menuBar
->Append(fileMenu
, wxT("&File"));
659 menuBar
->Append(editMenu
, wxT("&Edit"));
660 menuBar
->Append(formatMenu
, wxT("F&ormat"));
661 menuBar
->Append(listsMenu
, wxT("&Lists"));
662 menuBar
->Append(insertMenu
, wxT("&Insert"));
663 menuBar
->Append(helpMenu
, wxT("&Help"));
665 // ... and attach this menu bar to the frame
668 // create a status bar just for fun (by default with 1 pane only)
669 // but don't create it on limited screen space (WinCE)
670 bool is_pda
= wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA
;
676 SetStatusText(wxT("Welcome to wxRichTextCtrl!"));
680 wxToolBar
* toolBar
= CreateToolBar();
682 toolBar
->AddTool(wxID_OPEN
, wxEmptyString
, wxBitmap(open_xpm
), _("Open"));
683 toolBar
->AddTool(wxID_SAVEAS
, wxEmptyString
, wxBitmap(save_xpm
), _("Save"));
684 toolBar
->AddSeparator();
685 toolBar
->AddTool(wxID_CUT
, wxEmptyString
, wxBitmap(cut_xpm
), _("Cut"));
686 toolBar
->AddTool(wxID_COPY
, wxEmptyString
, wxBitmap(copy_xpm
), _("Copy"));
687 toolBar
->AddTool(wxID_PASTE
, wxEmptyString
, wxBitmap(paste_xpm
), _("Paste"));
688 toolBar
->AddSeparator();
689 toolBar
->AddTool(wxID_UNDO
, wxEmptyString
, wxBitmap(undo_xpm
), _("Undo"));
690 toolBar
->AddTool(wxID_REDO
, wxEmptyString
, wxBitmap(redo_xpm
), _("Redo"));
691 toolBar
->AddSeparator();
692 toolBar
->AddCheckTool(ID_FORMAT_BOLD
, wxEmptyString
, wxBitmap(bold_xpm
), wxNullBitmap
, _("Bold"));
693 toolBar
->AddCheckTool(ID_FORMAT_ITALIC
, wxEmptyString
, wxBitmap(italic_xpm
), wxNullBitmap
, _("Italic"));
694 toolBar
->AddCheckTool(ID_FORMAT_UNDERLINE
, wxEmptyString
, wxBitmap(underline_xpm
), wxNullBitmap
, _("Underline"));
695 toolBar
->AddSeparator();
696 toolBar
->AddCheckTool(ID_FORMAT_ALIGN_LEFT
, wxEmptyString
, wxBitmap(alignleft_xpm
), wxNullBitmap
, _("Align Left"));
697 toolBar
->AddCheckTool(ID_FORMAT_ALIGN_CENTRE
, wxEmptyString
, wxBitmap(centre_xpm
), wxNullBitmap
, _("Centre"));
698 toolBar
->AddCheckTool(ID_FORMAT_ALIGN_RIGHT
, wxEmptyString
, wxBitmap(alignright_xpm
), wxNullBitmap
, _("Align Right"));
699 toolBar
->AddSeparator();
700 toolBar
->AddTool(ID_FORMAT_INDENT_LESS
, wxEmptyString
, wxBitmap(indentless_xpm
), _("Indent Less"));
701 toolBar
->AddTool(ID_FORMAT_INDENT_MORE
, wxEmptyString
, wxBitmap(indentmore_xpm
), _("Indent More"));
702 toolBar
->AddSeparator();
703 toolBar
->AddTool(ID_FORMAT_FONT
, wxEmptyString
, wxBitmap(font_xpm
), _("Font"));
704 toolBar
->AddTool(ID_FORMAT_IMAGE
, wxString("Im"), wxBitmap(font_xpm
), _("Image Property"));
706 wxRichTextStyleComboCtrl
* combo
= new wxRichTextStyleComboCtrl(toolBar
, ID_RICHTEXT_STYLE_COMBO
, wxDefaultPosition
, wxSize(200, -1));
707 toolBar
->AddControl(combo
);
711 wxSplitterWindow
* splitter
= new wxSplitterWindow(this, wxID_ANY
, wxDefaultPosition
, GetClientSize(), wxSP_LIVE_UPDATE
);
713 wxFont textFont
= wxFont(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
714 wxFont boldFont
= wxFont(12, wxROMAN
, wxNORMAL
, wxBOLD
);
715 wxFont italicFont
= wxFont(12, wxROMAN
, wxITALIC
, wxNORMAL
);
717 m_richTextCtrl
= new wxRichTextCtrl(splitter
, ID_RICHTEXT_CTRL
, wxEmptyString
, wxDefaultPosition
, wxSize(200, 200), wxVSCROLL
|wxHSCROLL
|wxWANTS_CHARS
);
718 wxFont
font(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
720 m_richTextCtrl
->SetFont(font
);
722 m_richTextCtrl
->SetStyleSheet(wxGetApp().GetStyleSheet());
724 combo
->SetStyleSheet(wxGetApp().GetStyleSheet());
725 combo
->SetRichTextCtrl(m_richTextCtrl
);
726 combo
->UpdateStyles();
728 wxRichTextStyleListCtrl
* styleListCtrl
= new wxRichTextStyleListCtrl(splitter
, ID_RICHTEXT_STYLE_LIST
);
730 wxSize display
= wxGetDisplaySize();
731 if ( is_pda
&& ( display
.GetWidth() < display
.GetHeight() ) )
733 splitter
->SplitHorizontally(m_richTextCtrl
, styleListCtrl
);
737 splitter
->SplitVertically(m_richTextCtrl
, styleListCtrl
, 500);
740 splitter
->UpdateSize();
742 styleListCtrl
->SetStyleSheet(wxGetApp().GetStyleSheet());
743 styleListCtrl
->SetRichTextCtrl(m_richTextCtrl
);
744 styleListCtrl
->UpdateStyles();
750 void MyFrame::WriteInitialText()
752 wxRichTextCtrl
& r
= *m_richTextCtrl
;
754 r
.SetDefaultStyle(wxRichTextAttr());
756 r
.BeginSuppressUndo();
760 r
.BeginParagraphSpacing(0, 20);
762 r
.BeginAlignment(wxTEXT_ALIGNMENT_CENTRE
);
767 wxString lineBreak
= (wxChar
) 29;
769 r
.WriteText(wxString(wxT("Welcome to wxRichTextCtrl, a wxWidgets control")) + lineBreak
+ wxT("for editing and presenting styled text and images\n"));
773 r
.WriteText(wxT("by Julian Smart"));
779 r
.WriteImage(wxBitmap(zebra_xpm
));
786 r
.BeginAlignment(wxTEXT_ALIGNMENT_LEFT
);
787 wxRichTextAttr imageAttr
;
788 imageAttr
.GetTextBoxAttr().SetFloatMode(wxTEXT_BOX_ATTR_FLOAT_LEFT
);
789 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.")));
790 r
.WriteImage(wxBitmap(zebra_xpm
), wxBITMAP_TYPE_PNG
, imageAttr
);
791 imageAttr
.GetTextBoxAttr().GetTop().SetValue(200);
792 imageAttr
.GetTextBoxAttr().GetTop().SetUnits(wxTEXT_ATTR_UNITS_PIXELS
);
793 imageAttr
.GetTextBoxAttr().SetFloatMode(wxTEXT_BOX_ATTR_FLOAT_RIGHT
);
794 r
.WriteImage(wxBitmap(zebra_xpm
), wxBITMAP_TYPE_PNG
, imageAttr
);
795 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.")));
799 r
.WriteText(wxT("What can you do with this thing? "));
801 r
.WriteImage(wxBitmap(smiley_xpm
));
802 r
.WriteText(wxT(" Well, you can change text "));
804 r
.BeginTextColour(wxColour(255, 0, 0));
805 r
.WriteText(wxT("colour, like this red bit."));
808 wxRichTextAttr backgroundColourAttr
;
809 backgroundColourAttr
.SetBackgroundColour(*wxGREEN
);
810 backgroundColourAttr
.SetTextColour(wxColour(0, 0, 255));
811 r
.BeginStyle(backgroundColourAttr
);
812 r
.WriteText(wxT(" And this blue on green bit."));
815 r
.WriteText(wxT(" Naturally you can make things "));
817 r
.WriteText(wxT("bold "));
820 r
.WriteText(wxT("or italic "));
823 r
.WriteText(wxT("or underlined."));
827 r
.WriteText(wxT(" Different font sizes on the same line is allowed, too."));
830 r
.WriteText(wxT(" Next we'll show an indented paragraph."));
834 r
.BeginLeftIndent(60);
835 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."));
840 r
.WriteText(wxT("Next, we'll show a first-line indent, achieved using BeginLeftIndent(100, -40)."));
844 r
.BeginLeftIndent(100, -40);
846 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."));
851 r
.WriteText(wxT("Numbered bullets are possible, again using subindents:"));
854 r
.BeginNumberedBullet(1, 100, 60);
855 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."));
857 r
.EndNumberedBullet();
859 r
.BeginNumberedBullet(2, 100, 60);
860 r
.WriteText(wxT("This is my second item."));
862 r
.EndNumberedBullet();
864 r
.WriteText(wxT("The following paragraph is right-indented:"));
867 r
.BeginRightIndent(200);
869 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."));
874 r
.WriteText(wxT("The following paragraph is right-aligned with 1.5 line spacing:"));
877 r
.BeginAlignment(wxTEXT_ALIGNMENT_RIGHT
);
878 r
.BeginLineSpacing(wxTEXT_ATTR_LINE_SPACING_HALF
);
879 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."));
890 attr
.SetFlags(wxTEXT_ATTR_TABS
);
892 r
.SetDefaultStyle(attr
);
894 r
.WriteText(wxT("This line contains tabs:\tFirst tab\tSecond tab\tThird tab"));
897 r
.WriteText(wxT("Other notable features of wxRichTextCtrl include:"));
900 r
.BeginSymbolBullet(wxT('*'), 100, 60);
901 r
.WriteText(wxT("Compatibility with wxTextCtrl API"));
905 r
.BeginSymbolBullet(wxT('*'), 100, 60);
906 r
.WriteText(wxT("Easy stack-based BeginXXX()...EndXXX() style setting in addition to SetStyle()"));
910 r
.BeginSymbolBullet(wxT('*'), 100, 60);
911 r
.WriteText(wxT("XML loading and saving"));
915 r
.BeginSymbolBullet(wxT('*'), 100, 60);
916 r
.WriteText(wxT("Undo/Redo, with batching option and Undo suppressing"));
920 r
.BeginSymbolBullet(wxT('*'), 100, 60);
921 r
.WriteText(wxT("Clipboard copy and paste"));
925 r
.BeginSymbolBullet(wxT('*'), 100, 60);
926 r
.WriteText(wxT("wxRichTextStyleSheet with named character and paragraph styles, and control for applying named styles"));
930 r
.BeginSymbolBullet(wxT('*'), 100, 60);
931 r
.WriteText(wxT("A design that can easily be extended to other content types, ultimately with text boxes, tables, controls, and so on"));
935 // Make a style suitable for showing a URL
936 wxRichTextAttr urlStyle
;
937 urlStyle
.SetTextColour(*wxBLUE
);
938 urlStyle
.SetFontUnderlined(true);
940 r
.WriteText(wxT("wxRichTextCtrl can also display URLs, such as this one: "));
941 r
.BeginStyle(urlStyle
);
942 r
.BeginURL(wxT("http://www.wxwidgets.org"));
943 r
.WriteText(wxT("The wxWidgets Web Site"));
946 r
.WriteText(wxT(". Click on the URL to generate an event."));
950 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"));
952 r
.EndParagraphSpacing();
961 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
963 // true is to force the frame to close
967 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
970 msg
.Printf( wxT("This is a demo for wxRichTextCtrl, a control for editing styled text.\n(c) Julian Smart, 2005"));
971 wxMessageBox(msg
, wxT("About wxRichTextCtrl Sample"), wxOK
| wxICON_INFORMATION
, this);
974 // Forward command events to the current rich text control, if any
975 bool MyFrame::ProcessEvent(wxEvent
& event
)
977 if (event
.IsCommandEvent() && !event
.IsKindOf(CLASSINFO(wxChildFocusEvent
)))
979 // Problem: we can get infinite recursion because the events
980 // climb back up to this frame, and repeat.
981 // Assume that command events don't cause another command event
982 // to be called, so we can rely on inCommand not being overwritten
984 static int s_eventType
= 0;
985 static wxWindowID s_id
= 0;
987 if (s_id
!= event
.GetId() && s_eventType
!= event
.GetEventType())
989 s_eventType
= event
.GetEventType();
990 s_id
= event
.GetId();
992 wxWindow
* focusWin
= wxFindFocusDescendant(this);
993 if (focusWin
&& focusWin
->GetEventHandler()->ProcessEvent(event
))
1010 return wxFrame::ProcessEvent(event
);
1013 void MyFrame::OnOpen(wxCommandEvent
& WXUNUSED(event
))
1017 wxArrayInt fileTypes
;
1019 wxString filter
= wxRichTextBuffer::GetExtWildcard(false, false, & fileTypes
);
1020 if (!filter
.empty())
1022 filter
+= wxT("All files (*.*)|*.*");
1024 wxFileDialog
dialog(this,
1025 _("Choose a filename"),
1031 if (dialog
.ShowModal() == wxID_OK
)
1033 wxString path
= dialog
.GetPath();
1037 int filterIndex
= dialog
.GetFilterIndex();
1038 int fileType
= (filterIndex
< (int) fileTypes
.GetCount())
1039 ? fileTypes
[filterIndex
]
1040 : wxRICHTEXT_TYPE_TEXT
;
1041 m_richTextCtrl
->LoadFile(path
, fileType
);
1046 void MyFrame::OnSave(wxCommandEvent
& event
)
1048 if (m_richTextCtrl
->GetFilename().empty())
1053 m_richTextCtrl
->SaveFile();
1056 void MyFrame::OnSaveAs(wxCommandEvent
& WXUNUSED(event
))
1058 wxString filter
= wxRichTextBuffer::GetExtWildcard(false, true);
1062 wxFileDialog
dialog(this,
1063 _("Choose a filename"),
1069 if (dialog
.ShowModal() == wxID_OK
)
1071 wxString path
= dialog
.GetPath();
1076 wxStopWatch stopwatch
;
1078 m_richTextCtrl
->SaveFile(path
);
1080 long t
= stopwatch
.Time();
1081 wxLogDebug(wxT("Saving took %ldms"), t
);
1082 wxMessageBox(wxString::Format(wxT("Saving took %ldms"), t
));
1087 void MyFrame::OnBold(wxCommandEvent
& WXUNUSED(event
))
1089 m_richTextCtrl
->ApplyBoldToSelection();
1092 void MyFrame::OnItalic(wxCommandEvent
& WXUNUSED(event
))
1094 m_richTextCtrl
->ApplyItalicToSelection();
1097 void MyFrame::OnUnderline(wxCommandEvent
& WXUNUSED(event
))
1099 m_richTextCtrl
->ApplyUnderlineToSelection();
1103 void MyFrame::OnUpdateBold(wxUpdateUIEvent
& event
)
1105 event
.Check(m_richTextCtrl
->IsSelectionBold());
1108 void MyFrame::OnUpdateItalic(wxUpdateUIEvent
& event
)
1110 event
.Check(m_richTextCtrl
->IsSelectionItalics());
1113 void MyFrame::OnUpdateUnderline(wxUpdateUIEvent
& event
)
1115 event
.Check(m_richTextCtrl
->IsSelectionUnderlined());
1118 void MyFrame::OnAlignLeft(wxCommandEvent
& WXUNUSED(event
))
1120 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_LEFT
);
1123 void MyFrame::OnAlignCentre(wxCommandEvent
& WXUNUSED(event
))
1125 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_CENTRE
);
1128 void MyFrame::OnAlignRight(wxCommandEvent
& WXUNUSED(event
))
1130 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_RIGHT
);
1133 void MyFrame::OnUpdateAlignLeft(wxUpdateUIEvent
& event
)
1135 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_LEFT
));
1138 void MyFrame::OnUpdateAlignCentre(wxUpdateUIEvent
& event
)
1140 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_CENTRE
));
1143 void MyFrame::OnUpdateAlignRight(wxUpdateUIEvent
& event
)
1145 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_RIGHT
));
1148 void MyFrame::OnFont(wxCommandEvent
& WXUNUSED(event
))
1150 wxRichTextRange range
;
1151 if (m_richTextCtrl
->HasSelection())
1152 range
= m_richTextCtrl
->GetSelectionRange();
1154 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1156 int pages
= wxRICHTEXT_FORMAT_FONT
;
1158 wxRichTextFormattingDialog
formatDlg(pages
, this);
1159 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1161 if (formatDlg
.ShowModal() == wxID_OK
)
1163 formatDlg
.ApplyStyle(m_richTextCtrl
, range
, wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_OPTIMIZE
|wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY
);
1166 // Old method using wxFontDialog
1168 if (!m_richTextCtrl
->HasSelection())
1171 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1172 wxFontData fontData
;
1174 wxRichTextAttr attr
;
1175 attr
.SetFlags(wxTEXT_ATTR_FONT
);
1177 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1178 fontData
.SetInitialFont(attr
.GetFont());
1180 wxFontDialog
dialog(this, fontData
);
1181 if (dialog
.ShowModal() == wxID_OK
)
1183 fontData
= dialog
.GetFontData();
1184 attr
.SetFlags(wxTEXT_ATTR_FONT
);
1185 attr
.SetFont(fontData
.GetChosenFont());
1186 if (attr
.GetFont().Ok())
1188 m_richTextCtrl
->SetStyle(range
, attr
);
1194 void MyFrame::OnImage(wxCommandEvent
& WXUNUSED(event
))
1196 wxRichTextRange range
;
1197 wxASSERT(m_richTextCtrl
->HasSelection());
1199 range
= m_richTextCtrl
->GetSelectionRange();
1200 wxASSERT(range
.ToInternal().GetLength() == 1);
1202 wxRichTextImage
* image
= wxDynamicCast(m_richTextCtrl
->GetBuffer().GetLeafObjectAtPosition(range
.GetStart()), wxRichTextImage
);
1205 wxRichTextImageDialog
imageDlg(this);
1206 imageDlg
.SetImageObject(image
, &m_richTextCtrl
->GetBuffer());
1208 if (imageDlg
.ShowModal() == wxID_OK
)
1210 image
= imageDlg
.ApplyImageAttr();
1215 void MyFrame::OnParagraph(wxCommandEvent
& WXUNUSED(event
))
1217 wxRichTextRange range
;
1218 if (m_richTextCtrl
->HasSelection())
1219 range
= m_richTextCtrl
->GetSelectionRange();
1221 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1223 int pages
= wxRICHTEXT_FORMAT_INDENTS_SPACING
|wxRICHTEXT_FORMAT_TABS
|wxRICHTEXT_FORMAT_BULLETS
;
1225 wxRichTextFormattingDialog
formatDlg(pages
, this);
1226 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1228 if (formatDlg
.ShowModal() == wxID_OK
)
1230 formatDlg
.ApplyStyle(m_richTextCtrl
, range
);
1234 void MyFrame::OnFormat(wxCommandEvent
& WXUNUSED(event
))
1236 wxRichTextRange range
;
1237 if (m_richTextCtrl
->HasSelection())
1238 range
= m_richTextCtrl
->GetSelectionRange();
1240 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1242 int pages
= wxRICHTEXT_FORMAT_FONT
|wxRICHTEXT_FORMAT_INDENTS_SPACING
|wxRICHTEXT_FORMAT_TABS
|wxRICHTEXT_FORMAT_BULLETS
;
1244 wxRichTextFormattingDialog
formatDlg(pages
, this);
1245 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1247 if (formatDlg
.ShowModal() == wxID_OK
)
1249 formatDlg
.ApplyStyle(m_richTextCtrl
, range
);
1253 void MyFrame::OnUpdateFormat(wxUpdateUIEvent
& event
)
1255 event
.Enable(m_richTextCtrl
->HasSelection());
1258 void MyFrame::OnUpdateImage(wxUpdateUIEvent
& event
)
1260 wxRichTextRange range
;
1261 wxRichTextObject
*obj
;
1263 range
= m_richTextCtrl
->GetSelectionRange();
1264 if (range
.ToInternal().GetLength() == 1)
1266 obj
= m_richTextCtrl
->GetBuffer().GetLeafObjectAtPosition(range
.GetStart());
1267 if (obj
&& obj
->IsKindOf(CLASSINFO(wxRichTextImage
)))
1274 event
.Enable(false);
1277 void MyFrame::OnIndentMore(wxCommandEvent
& WXUNUSED(event
))
1279 wxRichTextAttr attr
;
1280 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1282 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1284 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1285 if (m_richTextCtrl
->HasSelection())
1286 range
= m_richTextCtrl
->GetSelectionRange();
1288 attr
.SetLeftIndent(attr
.GetLeftIndent() + 100);
1290 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1291 m_richTextCtrl
->SetStyle(range
, attr
);
1295 void MyFrame::OnIndentLess(wxCommandEvent
& WXUNUSED(event
))
1297 wxRichTextAttr attr
;
1298 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1300 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1302 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1303 if (m_richTextCtrl
->HasSelection())
1304 range
= m_richTextCtrl
->GetSelectionRange();
1306 if (attr
.GetLeftIndent() > 0)
1308 attr
.SetLeftIndent(wxMax(0, attr
.GetLeftIndent() - 100));
1310 m_richTextCtrl
->SetStyle(range
, attr
);
1315 void MyFrame::OnLineSpacingHalf(wxCommandEvent
& WXUNUSED(event
))
1317 wxRichTextAttr attr
;
1318 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1320 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1322 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1323 if (m_richTextCtrl
->HasSelection())
1324 range
= m_richTextCtrl
->GetSelectionRange();
1326 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1327 attr
.SetLineSpacing(15);
1329 m_richTextCtrl
->SetStyle(range
, attr
);
1333 void MyFrame::OnLineSpacingDouble(wxCommandEvent
& WXUNUSED(event
))
1335 wxRichTextAttr attr
;
1336 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1338 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1340 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1341 if (m_richTextCtrl
->HasSelection())
1342 range
= m_richTextCtrl
->GetSelectionRange();
1344 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1345 attr
.SetLineSpacing(20);
1347 m_richTextCtrl
->SetStyle(range
, attr
);
1351 void MyFrame::OnLineSpacingSingle(wxCommandEvent
& WXUNUSED(event
))
1353 wxRichTextAttr attr
;
1354 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1356 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1358 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1359 if (m_richTextCtrl
->HasSelection())
1360 range
= m_richTextCtrl
->GetSelectionRange();
1362 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1363 attr
.SetLineSpacing(0); // Can also use 10
1365 m_richTextCtrl
->SetStyle(range
, attr
);
1369 void MyFrame::OnParagraphSpacingMore(wxCommandEvent
& WXUNUSED(event
))
1371 wxRichTextAttr attr
;
1372 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1374 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1376 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1377 if (m_richTextCtrl
->HasSelection())
1378 range
= m_richTextCtrl
->GetSelectionRange();
1380 attr
.SetParagraphSpacingAfter(attr
.GetParagraphSpacingAfter() + 20);
1382 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1383 m_richTextCtrl
->SetStyle(range
, attr
);
1387 void MyFrame::OnParagraphSpacingLess(wxCommandEvent
& WXUNUSED(event
))
1389 wxRichTextAttr attr
;
1390 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1392 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1394 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1395 if (m_richTextCtrl
->HasSelection())
1396 range
= m_richTextCtrl
->GetSelectionRange();
1398 if (attr
.GetParagraphSpacingAfter() >= 20)
1400 attr
.SetParagraphSpacingAfter(attr
.GetParagraphSpacingAfter() - 20);
1402 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1403 m_richTextCtrl
->SetStyle(range
, attr
);
1408 void MyFrame::OnReload(wxCommandEvent
& WXUNUSED(event
))
1410 m_richTextCtrl
->Clear();
1414 void MyFrame::OnViewHTML(wxCommandEvent
& WXUNUSED(event
))
1416 wxDialog
dialog(this, wxID_ANY
, _("HTML"), wxDefaultPosition
, wxSize(500, 400), wxDEFAULT_DIALOG_STYLE
);
1418 wxBoxSizer
* boxSizer
= new wxBoxSizer(wxVERTICAL
);
1419 dialog
.SetSizer(boxSizer
);
1421 wxHtmlWindow
* win
= new wxHtmlWindow(& dialog
, wxID_ANY
, wxDefaultPosition
, wxSize(500, 400), wxSUNKEN_BORDER
);
1422 boxSizer
->Add(win
, 1, wxALL
, 5);
1424 wxButton
* cancelButton
= new wxButton(& dialog
, wxID_CANCEL
, wxT("&Close"));
1425 boxSizer
->Add(cancelButton
, 0, wxALL
|wxCENTRE
, 5);
1428 wxStringOutputStream
strStream(& text
);
1430 wxRichTextHTMLHandler htmlHandler
;
1431 htmlHandler
.SetFlags(wxRICHTEXT_HANDLER_SAVE_IMAGES_TO_MEMORY
);
1433 wxArrayInt fontSizeMapping
;
1434 fontSizeMapping
.Add(7);
1435 fontSizeMapping
.Add(9);
1436 fontSizeMapping
.Add(11);
1437 fontSizeMapping
.Add(12);
1438 fontSizeMapping
.Add(14);
1439 fontSizeMapping
.Add(22);
1440 fontSizeMapping
.Add(100);
1442 htmlHandler
.SetFontSizeMapping(fontSizeMapping
);
1444 if (htmlHandler
.SaveFile(& m_richTextCtrl
->GetBuffer(), strStream
))
1449 boxSizer
->Fit(& dialog
);
1453 // Now delete the temporary in-memory images
1454 htmlHandler
.DeleteTemporaryImages();
1457 // Demonstrates how you can change the style sheets and have the changes
1458 // reflected in the control content without wiping out character formatting.
1460 void MyFrame::OnSwitchStyleSheets(wxCommandEvent
& WXUNUSED(event
))
1462 static wxRichTextStyleSheet
* gs_AlternateStyleSheet
= NULL
;
1464 wxRichTextStyleListCtrl
*styleList
= (wxRichTextStyleListCtrl
*) FindWindow(ID_RICHTEXT_STYLE_LIST
);
1465 wxRichTextStyleComboCtrl
* styleCombo
= (wxRichTextStyleComboCtrl
*) FindWindow(ID_RICHTEXT_STYLE_COMBO
);
1467 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1469 // One-time creation of an alternate style sheet
1470 if (!gs_AlternateStyleSheet
)
1472 gs_AlternateStyleSheet
= new wxRichTextStyleSheet(*sheet
);
1474 // Make some modifications
1475 for (int i
= 0; i
< (int) gs_AlternateStyleSheet
->GetParagraphStyleCount(); i
++)
1477 wxRichTextParagraphStyleDefinition
* def
= gs_AlternateStyleSheet
->GetParagraphStyle(i
);
1479 if (def
->GetStyle().HasTextColour())
1480 def
->GetStyle().SetTextColour(*wxBLUE
);
1482 if (def
->GetStyle().HasAlignment())
1484 if (def
->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_CENTRE
)
1485 def
->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_RIGHT
);
1486 else if (def
->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_LEFT
)
1487 def
->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_CENTRE
);
1489 if (def
->GetStyle().HasLeftIndent())
1491 def
->GetStyle().SetLeftIndent(def
->GetStyle().GetLeftIndent() * 2);
1497 wxRichTextStyleSheet
* tmp
= gs_AlternateStyleSheet
;
1498 gs_AlternateStyleSheet
= sheet
;
1501 m_richTextCtrl
->SetStyleSheet(sheet
);
1502 m_richTextCtrl
->ApplyStyleSheet(sheet
); // Makes the control reflect the new style definitions
1504 styleList
->SetStyleSheet(sheet
);
1505 styleList
->UpdateStyles();
1507 styleCombo
->SetStyleSheet(sheet
);
1508 styleCombo
->UpdateStyles();
1511 void MyFrame::OnManageStyles(wxCommandEvent
& WXUNUSED(event
))
1513 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1515 int flags
= wxRICHTEXT_ORGANISER_CREATE_STYLES
|wxRICHTEXT_ORGANISER_EDIT_STYLES
;
1517 wxRichTextStyleOrganiserDialog
dlg(flags
, sheet
, NULL
, this, wxID_ANY
, _("Style Manager"));
1521 void MyFrame::OnInsertSymbol(wxCommandEvent
& WXUNUSED(event
))
1523 wxRichTextAttr attr
;
1524 attr
.SetFlags(wxTEXT_ATTR_FONT
);
1525 m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
);
1527 wxString currentFontName
;
1528 if (attr
.HasFont() && attr
.GetFont().Ok())
1529 currentFontName
= attr
.GetFont().GetFaceName();
1531 // Don't set the initial font in the dialog (so the user is choosing
1532 // 'normal text', i.e. the current font) but do tell the dialog
1533 // what 'normal text' is.
1535 wxSymbolPickerDialog
dlg(wxT("*"), wxEmptyString
, currentFontName
, this);
1537 if (dlg
.ShowModal() == wxID_OK
)
1539 if (dlg
.HasSelection())
1541 long insertionPoint
= m_richTextCtrl
->GetInsertionPoint();
1543 m_richTextCtrl
->WriteText(dlg
.GetSymbol());
1545 if (!dlg
.UseNormalFont())
1547 wxFont
font(attr
.GetFont());
1548 font
.SetFaceName(dlg
.GetFontName());
1550 m_richTextCtrl
->SetStyle(insertionPoint
, insertionPoint
+1, attr
);
1556 void MyFrame::OnNumberList(wxCommandEvent
& WXUNUSED(event
))
1558 if (m_richTextCtrl
->HasSelection())
1560 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1561 m_richTextCtrl
->SetListStyle(range
, wxT("Numbered List 1"), wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_RENUMBER
);
1565 void MyFrame::OnBulletsAndNumbering(wxCommandEvent
& WXUNUSED(event
))
1567 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1569 int flags
= wxRICHTEXT_ORGANISER_BROWSE_NUMBERING
;
1571 wxRichTextStyleOrganiserDialog
dlg(flags
, sheet
, m_richTextCtrl
, this, wxID_ANY
, _("Bullets and Numbering"));
1572 if (dlg
.ShowModal() == wxID_OK
)
1574 if (dlg
.GetSelectedStyleDefinition())
1579 void MyFrame::OnItemizeList(wxCommandEvent
& WXUNUSED(event
))
1581 if (m_richTextCtrl
->HasSelection())
1583 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1584 m_richTextCtrl
->SetListStyle(range
, wxT("Bullet List 1"));
1588 void MyFrame::OnRenumberList(wxCommandEvent
& WXUNUSED(event
))
1590 if (m_richTextCtrl
->HasSelection())
1592 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1593 m_richTextCtrl
->NumberList(range
, NULL
, wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_RENUMBER
);
1597 void MyFrame::OnPromoteList(wxCommandEvent
& WXUNUSED(event
))
1599 if (m_richTextCtrl
->HasSelection())
1601 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1602 m_richTextCtrl
->PromoteList(1, range
, NULL
);
1606 void MyFrame::OnDemoteList(wxCommandEvent
& WXUNUSED(event
))
1608 if (m_richTextCtrl
->HasSelection())
1610 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1611 m_richTextCtrl
->PromoteList(-1, range
, NULL
);
1615 void MyFrame::OnClearList(wxCommandEvent
& WXUNUSED(event
))
1617 if (m_richTextCtrl
->HasSelection())
1619 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1620 m_richTextCtrl
->ClearListStyle(range
);
1624 void MyFrame::OnInsertURL(wxCommandEvent
& WXUNUSED(event
))
1626 wxString url
= wxGetTextFromUser(_("URL:"), _("Insert URL"));
1629 // Make a style suitable for showing a URL
1630 wxRichTextAttr urlStyle
;
1631 urlStyle
.SetTextColour(*wxBLUE
);
1632 urlStyle
.SetFontUnderlined(true);
1634 m_richTextCtrl
->BeginStyle(urlStyle
);
1635 m_richTextCtrl
->BeginURL(url
);
1636 m_richTextCtrl
->WriteText(url
);
1637 m_richTextCtrl
->EndURL();
1638 m_richTextCtrl
->EndStyle();
1642 void MyFrame::OnInsertImage(wxCommandEvent
& WXUNUSED(event
))
1644 wxFileDialog
dialog(this, _("Choose an image"), "", "", "BMP and GIF files (*.bmp;*.gif)|*.bmp;*.gif|PNG files (*.png)|*.png");
1645 if (dialog
.ShowModal() == wxID_OK
)
1647 wxString path
= dialog
.GetPath();
1648 m_richTextCtrl
->WriteImage(path
, wxBITMAP_TYPE_ANY
);
1652 void MyFrame::OnURL(wxTextUrlEvent
& event
)
1654 wxMessageBox(event
.GetString());
1657 // Veto style sheet replace events when loading from XML, since we want
1658 // to keep the original style sheet.
1659 void MyFrame::OnStyleSheetReplacing(wxRichTextEvent
& event
)
1664 void MyFrame::OnPrint(wxCommandEvent
& WXUNUSED(event
))
1666 wxGetApp().GetPrinting()->PrintBuffer(m_richTextCtrl
->GetBuffer());
1669 void MyFrame::OnPreview(wxCommandEvent
& WXUNUSED(event
))
1671 wxGetApp().GetPrinting()->PreviewBuffer(m_richTextCtrl
->GetBuffer());
1674 void MyFrame::OnPageSetup(wxCommandEvent
& WXUNUSED(event
))
1676 wxDialog
dialog(this, wxID_ANY
, wxT("Testing"), wxPoint(10, 10), wxSize(400, 300), wxDEFAULT_DIALOG_STYLE
);
1678 wxNotebook
* nb
= new wxNotebook(& dialog
, wxID_ANY
, wxPoint(5, 5), wxSize(300, 250));
1679 wxPanel
* panel
= new wxPanel(nb
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
);
1680 wxPanel
* panel2
= new wxPanel(nb
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
);
1682 new wxRichTextCtrl(panel
, wxID_ANY
, wxEmptyString
, wxPoint(5, 5), wxSize(200, 150), wxVSCROLL
|wxTE_READONLY
);
1683 nb
->AddPage(panel
, wxT("Page 1"));
1685 new wxRichTextCtrl(panel2
, wxID_ANY
, wxEmptyString
, wxPoint(5, 5), wxSize(200, 150), wxVSCROLL
|wxTE_READONLY
);
1686 nb
->AddPage(panel2
, wxT("Page 2"));
1688 new wxButton(& dialog
, wxID_OK
, wxT("OK"), wxPoint(5, 180));
1692 // wxGetApp().GetPrinting()->PageSetup();