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"
39 #include "wx/filesys.h"
40 #include "wx/fs_mem.h"
44 #include "wx/cshelp.h"
48 #include "../sample.xpm"
51 #include "bitmaps/smiley.xpm"
52 // #include "bitmaps/idea.xpm"
53 #include "bitmaps/zebra.xpm"
55 #include "bitmaps/open.xpm"
56 #include "bitmaps/save.xpm"
57 #include "bitmaps/copy.xpm"
58 #include "bitmaps/cut.xpm"
59 #include "bitmaps/paste.xpm"
60 #include "bitmaps/undo.xpm"
61 #include "bitmaps/redo.xpm"
62 #include "bitmaps/bold.xpm"
63 #include "bitmaps/italic.xpm"
64 #include "bitmaps/underline.xpm"
66 #include "bitmaps/alignleft.xpm"
67 #include "bitmaps/alignright.xpm"
68 #include "bitmaps/centre.xpm"
69 #include "bitmaps/font.xpm"
70 #include "bitmaps/indentless.xpm"
71 #include "bitmaps/indentmore.xpm"
73 #include "wx/richtext/richtextctrl.h"
74 #include "wx/richtext/richtextstyles.h"
75 #include "wx/richtext/richtextxml.h"
76 #include "wx/richtext/richtexthtml.h"
77 #include "wx/richtext/richtextformatdlg.h"
78 #include "wx/richtext/richtextsymboldlg.h"
79 #include "wx/richtext/richtextstyledlg.h"
80 #include "wx/richtext/richtextprint.h"
82 // ----------------------------------------------------------------------------
84 // ----------------------------------------------------------------------------
86 // ----------------------------------------------------------------------------
88 // ----------------------------------------------------------------------------
90 // Define a new application type, each program should derive a class from wxApp
91 class MyApp
: public wxApp
94 // override base class virtuals
95 // ----------------------------
97 // this one is called on application startup and is a good place for the app
98 // initialization (doing it here and not in the ctor allows to have an error
99 // return: if OnInit() returns false, the application terminates)
100 virtual bool OnInit();
101 virtual int OnExit();
105 wxRichTextStyleSheet
* GetStyleSheet() const { return m_styleSheet
; }
106 wxRichTextPrinting
* GetPrinting() const { return m_printing
; }
108 wxRichTextStyleSheet
* m_styleSheet
;
109 wxRichTextPrinting
* m_printing
;
112 // Define a new frame type: this is going to be our main frame
113 class MyFrame
: public wxFrame
117 MyFrame(const wxString
& title
, wxWindowID id
, const wxPoint
& pos
= wxDefaultPosition
,
118 const wxSize
& size
= wxDefaultSize
, long style
= wxDEFAULT_FRAME_STYLE
);
120 // event handlers (these functions should _not_ be virtual)
121 void OnQuit(wxCommandEvent
& event
);
122 void OnAbout(wxCommandEvent
& event
);
124 void OnOpen(wxCommandEvent
& event
);
125 void OnSave(wxCommandEvent
& event
);
126 void OnSaveAs(wxCommandEvent
& event
);
128 void OnBold(wxCommandEvent
& event
);
129 void OnItalic(wxCommandEvent
& event
);
130 void OnUnderline(wxCommandEvent
& event
);
132 void OnUpdateBold(wxUpdateUIEvent
& event
);
133 void OnUpdateItalic(wxUpdateUIEvent
& event
);
134 void OnUpdateUnderline(wxUpdateUIEvent
& event
);
136 void OnAlignLeft(wxCommandEvent
& event
);
137 void OnAlignCentre(wxCommandEvent
& event
);
138 void OnAlignRight(wxCommandEvent
& event
);
140 void OnUpdateAlignLeft(wxUpdateUIEvent
& event
);
141 void OnUpdateAlignCentre(wxUpdateUIEvent
& event
);
142 void OnUpdateAlignRight(wxUpdateUIEvent
& event
);
144 void OnIndentMore(wxCommandEvent
& event
);
145 void OnIndentLess(wxCommandEvent
& event
);
147 void OnFont(wxCommandEvent
& event
);
148 void OnParagraph(wxCommandEvent
& event
);
149 void OnFormat(wxCommandEvent
& event
);
150 void OnUpdateFormat(wxUpdateUIEvent
& event
);
152 void OnInsertSymbol(wxCommandEvent
& event
);
154 void OnLineSpacingHalf(wxCommandEvent
& event
);
155 void OnLineSpacingDouble(wxCommandEvent
& event
);
156 void OnLineSpacingSingle(wxCommandEvent
& event
);
158 void OnParagraphSpacingMore(wxCommandEvent
& event
);
159 void OnParagraphSpacingLess(wxCommandEvent
& event
);
161 void OnNumberList(wxCommandEvent
& event
);
162 void OnBulletsAndNumbering(wxCommandEvent
& event
);
163 void OnItemizeList(wxCommandEvent
& event
);
164 void OnRenumberList(wxCommandEvent
& event
);
165 void OnPromoteList(wxCommandEvent
& event
);
166 void OnDemoteList(wxCommandEvent
& event
);
167 void OnClearList(wxCommandEvent
& event
);
169 void OnViewHTML(wxCommandEvent
& event
);
171 void OnSwitchStyleSheets(wxCommandEvent
& event
);
172 void OnManageStyles(wxCommandEvent
& event
);
174 void OnInsertURL(wxCommandEvent
& event
);
175 void OnURL(wxTextUrlEvent
& event
);
176 void OnStyleSheetReplacing(wxRichTextEvent
& event
);
178 void OnPrint(wxCommandEvent
& event
);
179 void OnPreview(wxCommandEvent
& event
);
180 void OnPageSetup(wxCommandEvent
& event
);
182 // Forward command events to the current rich text control, if any
183 bool ProcessEvent(wxEvent
& event
);
186 // any class wishing to process wxWidgets events must use this macro
187 DECLARE_EVENT_TABLE()
189 wxRichTextCtrl
* m_richTextCtrl
;
192 // ----------------------------------------------------------------------------
194 // ----------------------------------------------------------------------------
196 // IDs for the controls and the menu commands
201 ID_About
= wxID_ABOUT
,
203 ID_FORMAT_BOLD
= 100,
213 ID_FORMAT_ALIGN_LEFT
,
214 ID_FORMAT_ALIGN_CENTRE
,
215 ID_FORMAT_ALIGN_RIGHT
,
217 ID_FORMAT_INDENT_MORE
,
218 ID_FORMAT_INDENT_LESS
,
220 ID_FORMAT_PARAGRAPH_SPACING_MORE
,
221 ID_FORMAT_PARAGRAPH_SPACING_LESS
,
223 ID_FORMAT_LINE_SPACING_HALF
,
224 ID_FORMAT_LINE_SPACING_DOUBLE
,
225 ID_FORMAT_LINE_SPACING_SINGLE
,
227 ID_FORMAT_NUMBER_LIST
,
228 ID_FORMAT_BULLETS_AND_NUMBERING
,
229 ID_FORMAT_ITEMIZE_LIST
,
230 ID_FORMAT_RENUMBER_LIST
,
231 ID_FORMAT_PROMOTE_LIST
,
232 ID_FORMAT_DEMOTE_LIST
,
233 ID_FORMAT_CLEAR_LIST
,
236 ID_SWITCH_STYLE_SHEETS
,
244 ID_RICHTEXT_STYLE_LIST
,
245 ID_RICHTEXT_STYLE_COMBO
248 // ----------------------------------------------------------------------------
249 // event tables and other macros for wxWidgets
250 // ----------------------------------------------------------------------------
252 // the event tables connect the wxWidgets events with the functions (event
253 // handlers) which process them. It can be also done at run-time, but for the
254 // simple menu events like this the static method is much simpler.
255 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
256 EVT_MENU(ID_Quit
, MyFrame::OnQuit
)
257 EVT_MENU(ID_About
, MyFrame::OnAbout
)
259 EVT_MENU(wxID_OPEN
, MyFrame::OnOpen
)
260 EVT_MENU(wxID_SAVE
, MyFrame::OnSave
)
261 EVT_MENU(wxID_SAVEAS
, MyFrame::OnSaveAs
)
263 EVT_MENU(ID_FORMAT_BOLD
, MyFrame::OnBold
)
264 EVT_MENU(ID_FORMAT_ITALIC
, MyFrame::OnItalic
)
265 EVT_MENU(ID_FORMAT_UNDERLINE
, MyFrame::OnUnderline
)
267 EVT_UPDATE_UI(ID_FORMAT_BOLD
, MyFrame::OnUpdateBold
)
268 EVT_UPDATE_UI(ID_FORMAT_ITALIC
, MyFrame::OnUpdateItalic
)
269 EVT_UPDATE_UI(ID_FORMAT_UNDERLINE
, MyFrame::OnUpdateUnderline
)
271 EVT_MENU(ID_FORMAT_ALIGN_LEFT
, MyFrame::OnAlignLeft
)
272 EVT_MENU(ID_FORMAT_ALIGN_CENTRE
, MyFrame::OnAlignCentre
)
273 EVT_MENU(ID_FORMAT_ALIGN_RIGHT
, MyFrame::OnAlignRight
)
275 EVT_UPDATE_UI(ID_FORMAT_ALIGN_LEFT
, MyFrame::OnUpdateAlignLeft
)
276 EVT_UPDATE_UI(ID_FORMAT_ALIGN_CENTRE
, MyFrame::OnUpdateAlignCentre
)
277 EVT_UPDATE_UI(ID_FORMAT_ALIGN_RIGHT
, MyFrame::OnUpdateAlignRight
)
279 EVT_MENU(ID_FORMAT_FONT
, MyFrame::OnFont
)
280 EVT_MENU(ID_FORMAT_PARAGRAPH
, MyFrame::OnParagraph
)
281 EVT_MENU(ID_FORMAT_CONTENT
, MyFrame::OnFormat
)
282 EVT_UPDATE_UI(ID_FORMAT_CONTENT
, MyFrame::OnUpdateFormat
)
283 EVT_UPDATE_UI(ID_FORMAT_FONT
, MyFrame::OnUpdateFormat
)
284 EVT_UPDATE_UI(ID_FORMAT_PARAGRAPH
, MyFrame::OnUpdateFormat
)
285 EVT_MENU(ID_FORMAT_INDENT_MORE
, MyFrame::OnIndentMore
)
286 EVT_MENU(ID_FORMAT_INDENT_LESS
, MyFrame::OnIndentLess
)
288 EVT_MENU(ID_FORMAT_LINE_SPACING_HALF
, MyFrame::OnLineSpacingHalf
)
289 EVT_MENU(ID_FORMAT_LINE_SPACING_SINGLE
, MyFrame::OnLineSpacingSingle
)
290 EVT_MENU(ID_FORMAT_LINE_SPACING_DOUBLE
, MyFrame::OnLineSpacingDouble
)
292 EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_MORE
, MyFrame::OnParagraphSpacingMore
)
293 EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_LESS
, MyFrame::OnParagraphSpacingLess
)
295 EVT_MENU(ID_INSERT_SYMBOL
, MyFrame::OnInsertSymbol
)
296 EVT_MENU(ID_INSERT_URL
, MyFrame::OnInsertURL
)
298 EVT_MENU(ID_FORMAT_NUMBER_LIST
, MyFrame::OnNumberList
)
299 EVT_MENU(ID_FORMAT_BULLETS_AND_NUMBERING
, MyFrame::OnBulletsAndNumbering
)
300 EVT_MENU(ID_FORMAT_ITEMIZE_LIST
, MyFrame::OnItemizeList
)
301 EVT_MENU(ID_FORMAT_RENUMBER_LIST
, MyFrame::OnRenumberList
)
302 EVT_MENU(ID_FORMAT_PROMOTE_LIST
, MyFrame::OnPromoteList
)
303 EVT_MENU(ID_FORMAT_DEMOTE_LIST
, MyFrame::OnDemoteList
)
304 EVT_MENU(ID_FORMAT_CLEAR_LIST
, MyFrame::OnClearList
)
306 EVT_MENU(ID_VIEW_HTML
, MyFrame::OnViewHTML
)
307 EVT_MENU(ID_SWITCH_STYLE_SHEETS
, MyFrame::OnSwitchStyleSheets
)
308 EVT_MENU(ID_MANAGE_STYLES
, MyFrame::OnManageStyles
)
310 EVT_MENU(ID_PRINT
, MyFrame::OnPrint
)
311 EVT_MENU(ID_PREVIEW
, MyFrame::OnPreview
)
312 EVT_MENU(ID_PAGE_SETUP
, MyFrame::OnPageSetup
)
314 EVT_TEXT_URL(wxID_ANY
, MyFrame::OnURL
)
315 EVT_RICHTEXT_STYLESHEET_REPLACING(wxID_ANY
, MyFrame::OnStyleSheetReplacing
)
318 // Create a new application object: this macro will allow wxWidgets to create
319 // the application object during program execution (it's better than using a
320 // static object for many reasons) and also implements the accessor function
321 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
325 // ============================================================================
327 // ============================================================================
329 // ----------------------------------------------------------------------------
330 // the application class
331 // ----------------------------------------------------------------------------
333 // 'Main program' equivalent: the program execution "starts" here
336 if ( !wxApp::OnInit() )
340 wxHelpProvider::Set(new wxSimpleHelpProvider
);
343 m_styleSheet
= new wxRichTextStyleSheet
;
344 m_printing
= new wxRichTextPrinting(wxT("Test Document"));
346 m_printing
->SetFooterText(wxT("@TITLE@"), wxRICHTEXT_PAGE_ALL
, wxRICHTEXT_PAGE_CENTRE
);
347 m_printing
->SetFooterText(wxT("Page @PAGENUM@"), wxRICHTEXT_PAGE_ALL
, wxRICHTEXT_PAGE_RIGHT
);
351 // Add extra handlers (plain text is automatically added)
352 wxRichTextBuffer::AddHandler(new wxRichTextXMLHandler
);
353 wxRichTextBuffer::AddHandler(new wxRichTextHTMLHandler
);
355 // Add image handlers
357 wxImage::AddHandler( new wxPNGHandler
);
361 wxImage::AddHandler( new wxJPEGHandler
);
365 wxImage::AddHandler( new wxGIFHandler
);
369 wxFileSystem::AddHandler( new wxMemoryFSHandler
);
372 // create the main application window
373 MyFrame
*frame
= new MyFrame(_T("wxRichTextCtrl Sample"), wxID_ANY
, wxDefaultPosition
, wxSize(700, 600));
375 m_printing
->SetParentWindow(frame
);
377 // and show it (the frames, unlike simple controls, are not shown when
378 // created initially)
381 // success: wxApp::OnRun() will be called which will enter the main message
382 // loop and the application will run. If we returned false here, the
383 // application would exit immediately.
395 void MyApp::CreateStyles()
399 wxFont
romanFont(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
400 wxFont
swissFont(12, wxSWISS
, wxNORMAL
, wxNORMAL
);
402 wxRichTextParagraphStyleDefinition
* normalPara
= new wxRichTextParagraphStyleDefinition(wxT("Normal"));
403 wxRichTextAttr normalAttr
;
404 normalAttr
.SetFontFaceName(romanFont
.GetFaceName());
405 normalAttr
.SetFontSize(12);
406 // Let's set all attributes for this style
407 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
|
408 wxTEXT_ATTR_PARA_SPACING_BEFORE
|wxTEXT_ATTR_PARA_SPACING_AFTER
|wxTEXT_ATTR_LINE_SPACING
|
409 wxTEXT_ATTR_BULLET_STYLE
|wxTEXT_ATTR_BULLET_NUMBER
);
410 normalPara
->SetStyle(normalAttr
);
412 m_styleSheet
->AddParagraphStyle(normalPara
);
414 wxRichTextParagraphStyleDefinition
* indentedPara
= new wxRichTextParagraphStyleDefinition(wxT("Indented"));
415 wxRichTextAttr indentedAttr
;
416 indentedAttr
.SetFontFaceName(romanFont
.GetFaceName());
417 indentedAttr
.SetFontSize(12);
418 indentedAttr
.SetLeftIndent(100, 0);
419 // We only want to affect indentation
420 indentedAttr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
);
421 indentedPara
->SetStyle(indentedAttr
);
423 m_styleSheet
->AddParagraphStyle(indentedPara
);
425 wxRichTextParagraphStyleDefinition
* indentedPara2
= new wxRichTextParagraphStyleDefinition(wxT("Red Bold Indented"));
426 wxRichTextAttr indentedAttr2
;
427 indentedAttr2
.SetFontFaceName(romanFont
.GetFaceName());
428 indentedAttr2
.SetFontSize(12);
429 indentedAttr2
.SetFontWeight(wxBOLD
);
430 indentedAttr2
.SetTextColour(*wxRED
);
431 indentedAttr2
.SetFontSize(12);
432 indentedAttr2
.SetLeftIndent(100, 0);
433 // We want to affect indentation, font and text colour
434 indentedAttr2
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
|wxTEXT_ATTR_FONT
|wxTEXT_ATTR_TEXT_COLOUR
);
435 indentedPara2
->SetStyle(indentedAttr2
);
437 m_styleSheet
->AddParagraphStyle(indentedPara2
);
439 wxRichTextParagraphStyleDefinition
* flIndentedPara
= new wxRichTextParagraphStyleDefinition(wxT("First Line Indented"));
440 wxRichTextAttr flIndentedAttr
;
441 flIndentedAttr
.SetFontFaceName(swissFont
.GetFaceName());
442 flIndentedAttr
.SetFontSize(12);
443 flIndentedAttr
.SetLeftIndent(100, -100);
444 // We only want to affect indentation
445 flIndentedAttr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
);
446 flIndentedPara
->SetStyle(flIndentedAttr
);
448 m_styleSheet
->AddParagraphStyle(flIndentedPara
);
452 wxRichTextCharacterStyleDefinition
* boldDef
= new wxRichTextCharacterStyleDefinition(wxT("Bold"));
453 wxRichTextAttr boldAttr
;
454 boldAttr
.SetFontFaceName(romanFont
.GetFaceName());
455 boldAttr
.SetFontSize(12);
456 boldAttr
.SetFontWeight(wxBOLD
);
457 // We only want to affect boldness
458 boldAttr
.SetFlags(wxTEXT_ATTR_FONT_WEIGHT
);
459 boldDef
->SetStyle(boldAttr
);
461 m_styleSheet
->AddCharacterStyle(boldDef
);
463 wxRichTextCharacterStyleDefinition
* italicDef
= new wxRichTextCharacterStyleDefinition(wxT("Italic"));
464 wxRichTextAttr italicAttr
;
465 italicAttr
.SetFontFaceName(romanFont
.GetFaceName());
466 italicAttr
.SetFontSize(12);
467 italicAttr
.SetFontStyle(wxITALIC
);
468 // We only want to affect italics
469 italicAttr
.SetFlags(wxTEXT_ATTR_FONT_ITALIC
);
470 italicDef
->SetStyle(italicAttr
);
472 m_styleSheet
->AddCharacterStyle(italicDef
);
474 wxRichTextCharacterStyleDefinition
* redDef
= new wxRichTextCharacterStyleDefinition(wxT("Red Bold"));
475 wxRichTextAttr redAttr
;
476 redAttr
.SetFontFaceName(romanFont
.GetFaceName());
477 redAttr
.SetFontSize(12);
478 redAttr
.SetFontWeight(wxBOLD
);
479 redAttr
.SetTextColour(*wxRED
);
480 // We only want to affect colour, weight and face
481 redAttr
.SetFlags(wxTEXT_ATTR_FONT_FACE
|wxTEXT_ATTR_FONT_WEIGHT
|wxTEXT_ATTR_TEXT_COLOUR
);
482 redDef
->SetStyle(redAttr
);
484 m_styleSheet
->AddCharacterStyle(redDef
);
486 wxRichTextListStyleDefinition
* bulletList
= new wxRichTextListStyleDefinition(wxT("Bullet List 1"));
488 for (i
= 0; i
< 10; i
++)
492 bulletText
= wxT("standard/circle");
494 bulletText
= wxT("standard/square");
496 bulletText
= wxT("standard/circle");
498 bulletText
= wxT("standard/square");
500 bulletText
= wxT("standard/circle");
502 bulletList
->SetAttributes(i
, (i
+1)*60, 60, wxTEXT_ATTR_BULLET_STYLE_STANDARD
, bulletText
);
505 m_styleSheet
->AddListStyle(bulletList
);
507 wxRichTextListStyleDefinition
* numberedList
= new wxRichTextListStyleDefinition(wxT("Numbered List 1"));
508 for (i
= 0; i
< 10; i
++)
512 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
514 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_LETTERS_LOWER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
516 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ROMAN_LOWER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
518 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ROMAN_UPPER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
520 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
522 numberStyle
|= wxTEXT_ATTR_BULLET_STYLE_ALIGN_RIGHT
;
524 numberedList
->SetAttributes(i
, (i
+1)*60, 60, numberStyle
);
527 m_styleSheet
->AddListStyle(numberedList
);
529 wxRichTextListStyleDefinition
* outlineList
= new wxRichTextListStyleDefinition(wxT("Outline List 1"));
530 for (i
= 0; i
< 10; i
++)
534 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_OUTLINE
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
536 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
538 outlineList
->SetAttributes(i
, (i
+1)*120, 120, numberStyle
);
541 m_styleSheet
->AddListStyle(outlineList
);
544 // ----------------------------------------------------------------------------
546 // ----------------------------------------------------------------------------
549 MyFrame::MyFrame(const wxString
& title
, wxWindowID id
, const wxPoint
& pos
,
550 const wxSize
& size
, long style
)
551 : wxFrame(NULL
, id
, title
, pos
, size
, style
)
553 // set the frame icon
554 SetIcon(wxICON(sample
));
557 wxMenu
*fileMenu
= new wxMenu
;
559 // the "About" item should be in the help menu
560 wxMenu
*helpMenu
= new wxMenu
;
561 helpMenu
->Append(ID_About
, _T("&About...\tF1"), _T("Show about dialog"));
563 fileMenu
->Append(wxID_OPEN
, _T("&Open\tCtrl+O"), _T("Open a file"));
564 fileMenu
->Append(wxID_SAVE
, _T("&Save\tCtrl+S"), _T("Save a file"));
565 fileMenu
->Append(wxID_SAVEAS
, _T("&Save As...\tF12"), _T("Save to a new file"));
566 fileMenu
->AppendSeparator();
567 fileMenu
->Append(ID_PAGE_SETUP
, _T("Page Set&up..."), _T("Page setup"));
568 fileMenu
->Append(ID_PRINT
, _T("&Print...\tCtrl+P"), _T("Print"));
569 fileMenu
->Append(ID_PREVIEW
, _T("Print Pre&view"), _T("Print preview"));
570 fileMenu
->AppendSeparator();
571 fileMenu
->Append(ID_VIEW_HTML
, _T("&View as HTML"), _T("View HTML"));
572 fileMenu
->AppendSeparator();
573 fileMenu
->Append(ID_Quit
, _T("E&xit\tAlt+X"), _T("Quit this program"));
575 wxMenu
* editMenu
= new wxMenu
;
576 editMenu
->Append(wxID_UNDO
, _("&Undo\tCtrl+Z"));
577 editMenu
->Append(wxID_REDO
, _("&Redo\tCtrl+Y"));
578 editMenu
->AppendSeparator();
579 editMenu
->Append(wxID_CUT
, _("Cu&t\tCtrl+X"));
580 editMenu
->Append(wxID_COPY
, _("&Copy\tCtrl+C"));
581 editMenu
->Append(wxID_PASTE
, _("&Paste\tCtrl+V"));
583 editMenu
->AppendSeparator();
584 editMenu
->Append(wxID_SELECTALL
, _("Select A&ll\tCtrl+A"));
586 editMenu
->AppendSeparator();
587 editMenu
->Append(wxID_FIND
, _("&Find...\tCtrl+F"));
588 editMenu
->Append(stID_FIND_REPLACE
, _("&Replace...\tCtrl+R"));
591 wxMenu
* formatMenu
= new wxMenu
;
592 formatMenu
->AppendCheckItem(ID_FORMAT_BOLD
, _("&Bold\tCtrl+B"));
593 formatMenu
->AppendCheckItem(ID_FORMAT_ITALIC
, _("&Italic\tCtrl+I"));
594 formatMenu
->AppendCheckItem(ID_FORMAT_UNDERLINE
, _("&Underline\tCtrl+U"));
595 formatMenu
->AppendSeparator();
596 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_LEFT
, _("L&eft Align"));
597 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_RIGHT
, _("&Right Align"));
598 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_CENTRE
, _("&Centre"));
599 formatMenu
->AppendSeparator();
600 formatMenu
->Append(ID_FORMAT_INDENT_MORE
, _("Indent &More"));
601 formatMenu
->Append(ID_FORMAT_INDENT_LESS
, _("Indent &Less"));
602 formatMenu
->AppendSeparator();
603 formatMenu
->Append(ID_FORMAT_PARAGRAPH_SPACING_MORE
, _("Increase Paragraph &Spacing"));
604 formatMenu
->Append(ID_FORMAT_PARAGRAPH_SPACING_LESS
, _("Decrease &Paragraph Spacing"));
605 formatMenu
->AppendSeparator();
606 formatMenu
->Append(ID_FORMAT_LINE_SPACING_SINGLE
, _("Normal Line Spacing"));
607 formatMenu
->Append(ID_FORMAT_LINE_SPACING_HALF
, _("1.5 Line Spacing"));
608 formatMenu
->Append(ID_FORMAT_LINE_SPACING_DOUBLE
, _("Double Line Spacing"));
609 formatMenu
->AppendSeparator();
610 formatMenu
->Append(ID_FORMAT_FONT
, _("&Font..."));
611 formatMenu
->Append(ID_FORMAT_PARAGRAPH
, _("&Paragraph..."));
612 formatMenu
->Append(ID_FORMAT_CONTENT
, _("Font and Pa&ragraph...\tShift+Ctrl+F"));
613 formatMenu
->AppendSeparator();
614 formatMenu
->Append(ID_SWITCH_STYLE_SHEETS
, _("&Switch Style Sheets"));
615 formatMenu
->Append(ID_MANAGE_STYLES
, _("&Manage Styles"));
617 wxMenu
* listsMenu
= new wxMenu
;
618 listsMenu
->Append(ID_FORMAT_BULLETS_AND_NUMBERING
, _("Bullets and &Numbering..."));
619 listsMenu
->AppendSeparator();
620 listsMenu
->Append(ID_FORMAT_NUMBER_LIST
, _("Number List"));
621 listsMenu
->Append(ID_FORMAT_ITEMIZE_LIST
, _("Itemize List"));
622 listsMenu
->Append(ID_FORMAT_RENUMBER_LIST
, _("Renumber List"));
623 listsMenu
->Append(ID_FORMAT_PROMOTE_LIST
, _("Promote List Items"));
624 listsMenu
->Append(ID_FORMAT_DEMOTE_LIST
, _("Demote List Items"));
625 listsMenu
->Append(ID_FORMAT_CLEAR_LIST
, _("Clear List Formatting"));
627 wxMenu
* insertMenu
= new wxMenu
;
628 insertMenu
->Append(ID_INSERT_SYMBOL
, _("&Symbol...\tCtrl+I"));
629 insertMenu
->Append(ID_INSERT_URL
, _("&URL..."));
631 // now append the freshly created menu to the menu bar...
632 wxMenuBar
*menuBar
= new wxMenuBar();
633 menuBar
->Append(fileMenu
, _T("&File"));
634 menuBar
->Append(editMenu
, _T("&Edit"));
635 menuBar
->Append(formatMenu
, _T("F&ormat"));
636 menuBar
->Append(listsMenu
, _T("&Lists"));
637 menuBar
->Append(insertMenu
, _T("&Insert"));
638 menuBar
->Append(helpMenu
, _T("&Help"));
640 // ... and attach this menu bar to the frame
643 // create a status bar just for fun (by default with 1 pane only)
644 // but don't create it on limited screen space (WinCE)
645 bool is_pda
= wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA
;
651 SetStatusText(_T("Welcome to wxRichTextCtrl!"));
655 wxToolBar
* toolBar
= CreateToolBar();
657 toolBar
->AddTool(wxID_OPEN
, wxBitmap(open_xpm
), wxNullBitmap
, false, -1, -1, (wxObject
*) NULL
, _("Open"));
658 toolBar
->AddTool(wxID_SAVEAS
, wxBitmap(save_xpm
), wxNullBitmap
, false, -1, -1, (wxObject
*) NULL
, _("Save"));
659 toolBar
->AddSeparator();
660 toolBar
->AddTool(wxID_CUT
, wxBitmap(cut_xpm
), wxNullBitmap
, false, -1, -1, (wxObject
*) NULL
, _("Cut"));
661 toolBar
->AddTool(wxID_COPY
, wxBitmap(copy_xpm
), wxNullBitmap
, false, -1, -1, (wxObject
*) NULL
, _("Copy"));
662 toolBar
->AddTool(wxID_PASTE
, wxBitmap(paste_xpm
), wxNullBitmap
, false, -1, -1, (wxObject
*) NULL
, _("Paste"));
663 toolBar
->AddSeparator();
664 toolBar
->AddTool(wxID_UNDO
, wxBitmap(undo_xpm
), wxNullBitmap
, false, -1, -1, (wxObject
*) NULL
, _("Undo"));
665 toolBar
->AddTool(wxID_REDO
, wxBitmap(redo_xpm
), wxNullBitmap
, false, -1, -1, (wxObject
*) NULL
, _("Redo"));
666 toolBar
->AddSeparator();
667 toolBar
->AddTool(ID_FORMAT_BOLD
, wxBitmap(bold_xpm
), wxNullBitmap
, true, -1, -1, (wxObject
*) NULL
, _("Bold"));
668 toolBar
->AddTool(ID_FORMAT_ITALIC
, wxBitmap(italic_xpm
), wxNullBitmap
, true, -1, -1, (wxObject
*) NULL
, _("Italic"));
669 toolBar
->AddTool(ID_FORMAT_UNDERLINE
, wxBitmap(underline_xpm
), wxNullBitmap
, true, -1, -1, (wxObject
*) NULL
, _("Underline"));
670 toolBar
->AddSeparator();
671 toolBar
->AddTool(ID_FORMAT_ALIGN_LEFT
, wxBitmap(alignleft_xpm
), wxNullBitmap
, true, -1, -1, (wxObject
*) NULL
, _("Align Left"));
672 toolBar
->AddTool(ID_FORMAT_ALIGN_CENTRE
, wxBitmap(centre_xpm
), wxNullBitmap
, true, -1, -1, (wxObject
*) NULL
, _("Centre"));
673 toolBar
->AddTool(ID_FORMAT_ALIGN_RIGHT
, wxBitmap(alignright_xpm
), wxNullBitmap
, true, -1, -1, (wxObject
*) NULL
, _("Align Right"));
674 toolBar
->AddSeparator();
675 toolBar
->AddTool(ID_FORMAT_INDENT_LESS
, wxBitmap(indentless_xpm
), wxNullBitmap
, false, -1, -1, (wxObject
*) NULL
, _("Indent Less"));
676 toolBar
->AddTool(ID_FORMAT_INDENT_MORE
, wxBitmap(indentmore_xpm
), wxNullBitmap
, false, -1, -1, (wxObject
*) NULL
, _("Indent More"));
677 toolBar
->AddSeparator();
678 toolBar
->AddTool(ID_FORMAT_FONT
, wxBitmap(font_xpm
), wxNullBitmap
, false, -1, -1, (wxObject
*) NULL
, _("Font"));
680 wxRichTextStyleComboCtrl
* combo
= new wxRichTextStyleComboCtrl(toolBar
, ID_RICHTEXT_STYLE_COMBO
, wxDefaultPosition
, wxSize(200, -1));
681 toolBar
->AddControl(combo
);
685 wxSplitterWindow
* splitter
= new wxSplitterWindow(this, wxID_ANY
, wxDefaultPosition
, GetClientSize(), wxSP_LIVE_UPDATE
);
687 wxFont textFont
= wxFont(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
688 wxFont boldFont
= wxFont(12, wxROMAN
, wxNORMAL
, wxBOLD
);
689 wxFont italicFont
= wxFont(12, wxROMAN
, wxITALIC
, wxNORMAL
);
691 m_richTextCtrl
= new wxRichTextCtrl(splitter
, ID_RICHTEXT_CTRL
, wxEmptyString
, wxDefaultPosition
, wxSize(200, 200), wxVSCROLL
|wxHSCROLL
|wxWANTS_CHARS
);
692 wxFont
font(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
694 m_richTextCtrl
->SetFont(font
);
696 m_richTextCtrl
->SetStyleSheet(wxGetApp().GetStyleSheet());
698 combo
->SetStyleSheet(wxGetApp().GetStyleSheet());
699 combo
->SetRichTextCtrl(m_richTextCtrl
);
700 combo
->UpdateStyles();
702 wxRichTextStyleListCtrl
* styleListCtrl
= new wxRichTextStyleListCtrl(splitter
, ID_RICHTEXT_STYLE_LIST
);
704 wxSize display
= wxGetDisplaySize();
705 if ( is_pda
&& ( display
.GetWidth() < display
.GetHeight() ) )
707 splitter
->SplitHorizontally(m_richTextCtrl
, styleListCtrl
);
711 splitter
->SplitVertically(m_richTextCtrl
, styleListCtrl
, 500);
714 splitter
->UpdateSize();
716 styleListCtrl
->SetStyleSheet(wxGetApp().GetStyleSheet());
717 styleListCtrl
->SetRichTextCtrl(m_richTextCtrl
);
718 styleListCtrl
->UpdateStyles();
720 wxRichTextCtrl
& r
= *m_richTextCtrl
;
722 r
.BeginSuppressUndo();
724 r
.BeginParagraphSpacing(0, 20);
726 r
.BeginAlignment(wxTEXT_ALIGNMENT_CENTRE
);
731 wxString lineBreak
= (wxChar
) 29;
733 r
.WriteText(wxString(wxT("Welcome to wxRichTextCtrl, a wxWidgets control")) + lineBreak
+ wxT("for editing and presenting styled text and images"));
738 r
.WriteText(wxT("by Julian Smart"));
744 r
.WriteImage(wxBitmap(zebra_xpm
));
751 r
.WriteText(wxT("What can you do with this thing? "));
753 r
.WriteImage(wxBitmap(smiley_xpm
));
754 r
.WriteText(wxT(" Well, you can change text "));
756 r
.BeginTextColour(wxColour(255, 0, 0));
757 r
.WriteText(wxT("colour, like this red bit."));
760 wxRichTextAttr backgroundColourAttr
;
761 backgroundColourAttr
.SetBackgroundColour(*wxGREEN
);
762 backgroundColourAttr
.SetTextColour(wxColour(0, 0, 255));
763 r
.BeginStyle(backgroundColourAttr
);
764 r
.WriteText(wxT(" And this blue on green bit."));
767 r
.WriteText(wxT(" Naturally you can make things "));
769 r
.WriteText(wxT("bold "));
772 r
.WriteText(wxT("or italic "));
775 r
.WriteText(wxT("or underlined."));
779 r
.WriteText(wxT(" Different font sizes on the same line is allowed, too."));
782 r
.WriteText(wxT(" Next we'll show an indented paragraph."));
784 r
.BeginLeftIndent(60);
787 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."));
792 r
.WriteText(wxT("Next, we'll show a first-line indent, achieved using BeginLeftIndent(100, -40)."));
794 r
.BeginLeftIndent(100, -40);
797 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."));
802 r
.WriteText(wxT("Numbered bullets are possible, again using subindents:"));
804 r
.BeginNumberedBullet(1, 100, 60);
807 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."));
808 r
.EndNumberedBullet();
810 r
.BeginNumberedBullet(2, 100, 60);
813 r
.WriteText(wxT("This is my second item."));
814 r
.EndNumberedBullet();
818 r
.WriteText(wxT("The following paragraph is right-indented:"));
820 r
.BeginRightIndent(200);
823 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."));
828 r
.WriteText(wxT("The following paragraph is right-aligned with 1.5 line spacing:"));
830 r
.BeginAlignment(wxTEXT_ALIGNMENT_RIGHT
);
831 r
.BeginLineSpacing(wxTEXT_ATTR_LINE_SPACING_HALF
);
834 r
.WriteText(wxT("It was in January, the most down-trodden month of an Edinburgh winter. An attractive woman came into the cafe, which is nothing remarkable."));
844 attr
.SetFlags(wxTEXT_ATTR_TABS
);
846 r
.SetDefaultStyle(attr
);
849 r
.WriteText(wxT("This line contains tabs:\tFirst tab\tSecond tab\tThird tab"));
852 r
.WriteText(wxT("Other notable features of wxRichTextCtrl include:"));
854 r
.BeginSymbolBullet(wxT('*'), 100, 60);
856 r
.WriteText(wxT("Compatibility with wxTextCtrl API"));
859 r
.BeginSymbolBullet(wxT('*'), 100, 60);
861 r
.WriteText(wxT("Easy stack-based BeginXXX()...EndXXX() style setting in addition to SetStyle()"));
864 r
.BeginSymbolBullet(wxT('*'), 100, 60);
866 r
.WriteText(wxT("XML loading and saving"));
869 r
.BeginSymbolBullet(wxT('*'), 100, 60);
871 r
.WriteText(wxT("Undo/Redo, with batching option and Undo suppressing"));
874 r
.BeginSymbolBullet(wxT('*'), 100, 60);
876 r
.WriteText(wxT("Clipboard copy and paste"));
879 r
.BeginSymbolBullet(wxT('*'), 100, 60);
881 r
.WriteText(wxT("wxRichTextStyleSheet with named character and paragraph styles, and control for applying named styles"));
884 r
.BeginSymbolBullet(wxT('*'), 100, 60);
886 r
.WriteText(wxT("A design that can easily be extended to other content types, ultimately with text boxes, tables, controls, and so on"));
891 // Make a style suitable for showing a URL
892 wxRichTextAttr urlStyle
;
893 urlStyle
.SetTextColour(*wxBLUE
);
894 urlStyle
.SetFontUnderlined(true);
896 r
.WriteText(wxT("wxRichTextCtrl can also display URLs, such as this one: "));
897 r
.BeginStyle(urlStyle
);
898 r
.BeginURL(wxT("http://www.wxwidgets.org"));
899 r
.WriteText(wxT("The wxWidgets Web Site"));
902 r
.WriteText(wxT(". Click on the URL to generate an event."));
906 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!"));
908 r
.EndParagraphSpacing();
916 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
918 // true is to force the frame to close
922 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
925 msg
.Printf( _T("This is a demo for wxRichTextCtrl, a control for editing styled text.\n(c) Julian Smart, 2005"));
926 wxMessageBox(msg
, _T("About wxRichTextCtrl Sample"), wxOK
| wxICON_INFORMATION
, this);
929 // Forward command events to the current rich text control, if any
930 bool MyFrame::ProcessEvent(wxEvent
& event
)
932 if (event
.IsCommandEvent() && !event
.IsKindOf(CLASSINFO(wxChildFocusEvent
)))
934 // Problem: we can get infinite recursion because the events
935 // climb back up to this frame, and repeat.
936 // Assume that command events don't cause another command event
937 // to be called, so we can rely on inCommand not being overwritten
939 static int s_eventType
= 0;
940 static wxWindowID s_id
= 0;
942 if (s_id
!= event
.GetId() && s_eventType
!= event
.GetEventType())
944 s_eventType
= event
.GetEventType();
945 s_id
= event
.GetId();
947 wxWindow
* focusWin
= wxFindFocusDescendant(this);
948 if (focusWin
&& focusWin
->ProcessEvent(event
))
965 return wxFrame::ProcessEvent(event
);
968 void MyFrame::OnOpen(wxCommandEvent
& WXUNUSED(event
))
972 wxArrayInt fileTypes
;
974 wxString filter
= wxRichTextBuffer::GetExtWildcard(false, false, & fileTypes
);
977 filter
+= wxT("All files (*.*)|*.*");
979 wxFileDialog
dialog(this,
980 _("Choose a filename"),
986 if (dialog
.ShowModal() == wxID_OK
)
988 wxString path
= dialog
.GetPath();
992 int filterIndex
= dialog
.GetFilterIndex();
993 int fileType
= (filterIndex
< (int) fileTypes
.GetCount())
994 ? fileTypes
[filterIndex
]
995 : wxRICHTEXT_TYPE_TEXT
;
996 m_richTextCtrl
->LoadFile(path
, fileType
);
1001 void MyFrame::OnSave(wxCommandEvent
& event
)
1003 if (m_richTextCtrl
->GetFilename().empty())
1008 m_richTextCtrl
->SaveFile();
1011 void MyFrame::OnSaveAs(wxCommandEvent
& WXUNUSED(event
))
1013 wxString filter
= wxRichTextBuffer::GetExtWildcard(false, true);
1017 wxFileDialog
dialog(this,
1018 _("Choose a filename"),
1024 if (dialog
.ShowModal() == wxID_OK
)
1026 wxString path
= dialog
.GetPath();
1030 m_richTextCtrl
->SaveFile(path
);
1035 void MyFrame::OnBold(wxCommandEvent
& WXUNUSED(event
))
1037 m_richTextCtrl
->ApplyBoldToSelection();
1040 void MyFrame::OnItalic(wxCommandEvent
& WXUNUSED(event
))
1042 m_richTextCtrl
->ApplyItalicToSelection();
1045 void MyFrame::OnUnderline(wxCommandEvent
& WXUNUSED(event
))
1047 m_richTextCtrl
->ApplyUnderlineToSelection();
1051 void MyFrame::OnUpdateBold(wxUpdateUIEvent
& event
)
1053 event
.Check(m_richTextCtrl
->IsSelectionBold());
1056 void MyFrame::OnUpdateItalic(wxUpdateUIEvent
& event
)
1058 event
.Check(m_richTextCtrl
->IsSelectionItalics());
1061 void MyFrame::OnUpdateUnderline(wxUpdateUIEvent
& event
)
1063 event
.Check(m_richTextCtrl
->IsSelectionUnderlined());
1066 void MyFrame::OnAlignLeft(wxCommandEvent
& WXUNUSED(event
))
1068 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_LEFT
);
1071 void MyFrame::OnAlignCentre(wxCommandEvent
& WXUNUSED(event
))
1073 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_CENTRE
);
1076 void MyFrame::OnAlignRight(wxCommandEvent
& WXUNUSED(event
))
1078 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_RIGHT
);
1081 void MyFrame::OnUpdateAlignLeft(wxUpdateUIEvent
& event
)
1083 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_LEFT
));
1086 void MyFrame::OnUpdateAlignCentre(wxUpdateUIEvent
& event
)
1088 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_CENTRE
));
1091 void MyFrame::OnUpdateAlignRight(wxUpdateUIEvent
& event
)
1093 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_RIGHT
));
1096 void MyFrame::OnFont(wxCommandEvent
& WXUNUSED(event
))
1098 wxRichTextRange range
;
1099 if (m_richTextCtrl
->HasSelection())
1100 range
= m_richTextCtrl
->GetSelectionRange();
1102 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1104 int pages
= wxRICHTEXT_FORMAT_FONT
;
1106 wxRichTextFormattingDialog
formatDlg(pages
, this);
1107 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1109 if (formatDlg
.ShowModal() == wxID_OK
)
1111 formatDlg
.ApplyStyle(m_richTextCtrl
, range
, wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_OPTIMIZE
|wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY
);
1114 // Old method using wxFontDialog
1116 if (!m_richTextCtrl
->HasSelection())
1119 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1120 wxFontData fontData
;
1123 attr
.SetFlags(wxTEXT_ATTR_FONT
);
1125 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1126 fontData
.SetInitialFont(attr
.GetFont());
1128 wxFontDialog
dialog(this, fontData
);
1129 if (dialog
.ShowModal() == wxID_OK
)
1131 fontData
= dialog
.GetFontData();
1132 attr
.SetFlags(wxTEXT_ATTR_FONT
);
1133 attr
.SetFont(fontData
.GetChosenFont());
1134 if (attr
.GetFont().Ok())
1136 m_richTextCtrl
->SetStyle(range
, attr
);
1142 void MyFrame::OnParagraph(wxCommandEvent
& WXUNUSED(event
))
1144 wxRichTextRange range
;
1145 if (m_richTextCtrl
->HasSelection())
1146 range
= m_richTextCtrl
->GetSelectionRange();
1148 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1150 int pages
= wxRICHTEXT_FORMAT_INDENTS_SPACING
|wxRICHTEXT_FORMAT_TABS
|wxRICHTEXT_FORMAT_BULLETS
;
1152 wxRichTextFormattingDialog
formatDlg(pages
, this);
1153 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1155 if (formatDlg
.ShowModal() == wxID_OK
)
1157 formatDlg
.ApplyStyle(m_richTextCtrl
, range
);
1161 void MyFrame::OnFormat(wxCommandEvent
& WXUNUSED(event
))
1163 wxRichTextRange range
;
1164 if (m_richTextCtrl
->HasSelection())
1165 range
= m_richTextCtrl
->GetSelectionRange();
1167 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1169 int pages
= wxRICHTEXT_FORMAT_FONT
|wxRICHTEXT_FORMAT_INDENTS_SPACING
|wxRICHTEXT_FORMAT_TABS
|wxRICHTEXT_FORMAT_BULLETS
;
1171 wxRichTextFormattingDialog
formatDlg(pages
, this);
1172 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1174 if (formatDlg
.ShowModal() == wxID_OK
)
1176 formatDlg
.ApplyStyle(m_richTextCtrl
, range
);
1180 void MyFrame::OnUpdateFormat(wxUpdateUIEvent
& event
)
1182 event
.Enable(m_richTextCtrl
->HasSelection());
1185 void MyFrame::OnIndentMore(wxCommandEvent
& WXUNUSED(event
))
1187 wxRichTextAttr attr
;
1188 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1190 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1192 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1193 if (m_richTextCtrl
->HasSelection())
1194 range
= m_richTextCtrl
->GetSelectionRange();
1196 attr
.SetLeftIndent(attr
.GetLeftIndent() + 100);
1198 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1199 m_richTextCtrl
->SetStyle(range
, attr
);
1203 void MyFrame::OnIndentLess(wxCommandEvent
& WXUNUSED(event
))
1205 wxRichTextAttr attr
;
1206 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1208 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1210 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1211 if (m_richTextCtrl
->HasSelection())
1212 range
= m_richTextCtrl
->GetSelectionRange();
1214 if (attr
.GetLeftIndent() > 0)
1216 attr
.SetLeftIndent(wxMax(0, attr
.GetLeftIndent() - 100));
1218 m_richTextCtrl
->SetStyle(range
, attr
);
1223 void MyFrame::OnLineSpacingHalf(wxCommandEvent
& WXUNUSED(event
))
1225 wxRichTextAttr attr
;
1226 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1228 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1230 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1231 if (m_richTextCtrl
->HasSelection())
1232 range
= m_richTextCtrl
->GetSelectionRange();
1234 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1235 attr
.SetLineSpacing(15);
1237 m_richTextCtrl
->SetStyle(range
, attr
);
1241 void MyFrame::OnLineSpacingDouble(wxCommandEvent
& WXUNUSED(event
))
1243 wxRichTextAttr attr
;
1244 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1246 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1248 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1249 if (m_richTextCtrl
->HasSelection())
1250 range
= m_richTextCtrl
->GetSelectionRange();
1252 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1253 attr
.SetLineSpacing(20);
1255 m_richTextCtrl
->SetStyle(range
, attr
);
1259 void MyFrame::OnLineSpacingSingle(wxCommandEvent
& WXUNUSED(event
))
1261 wxRichTextAttr attr
;
1262 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1264 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1266 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1267 if (m_richTextCtrl
->HasSelection())
1268 range
= m_richTextCtrl
->GetSelectionRange();
1270 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1271 attr
.SetLineSpacing(0); // Can also use 10
1273 m_richTextCtrl
->SetStyle(range
, attr
);
1277 void MyFrame::OnParagraphSpacingMore(wxCommandEvent
& WXUNUSED(event
))
1279 wxRichTextAttr attr
;
1280 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
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
.SetParagraphSpacingAfter(attr
.GetParagraphSpacingAfter() + 20);
1290 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1291 m_richTextCtrl
->SetStyle(range
, attr
);
1295 void MyFrame::OnParagraphSpacingLess(wxCommandEvent
& WXUNUSED(event
))
1297 wxRichTextAttr attr
;
1298 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
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
.GetParagraphSpacingAfter() >= 20)
1308 attr
.SetParagraphSpacingAfter(attr
.GetParagraphSpacingAfter() - 20);
1310 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1311 m_richTextCtrl
->SetStyle(range
, attr
);
1316 void MyFrame::OnViewHTML(wxCommandEvent
& WXUNUSED(event
))
1318 wxDialog
dialog(this, wxID_ANY
, _("HTML"), wxDefaultPosition
, wxSize(500, 400), wxDEFAULT_DIALOG_STYLE
);
1320 wxBoxSizer
* boxSizer
= new wxBoxSizer(wxVERTICAL
);
1321 dialog
.SetSizer(boxSizer
);
1323 wxHtmlWindow
* win
= new wxHtmlWindow(& dialog
, wxID_ANY
, wxDefaultPosition
, wxSize(500, 400), wxSUNKEN_BORDER
);
1324 boxSizer
->Add(win
, 1, wxALL
, 5);
1326 wxButton
* cancelButton
= new wxButton(& dialog
, wxID_CANCEL
, wxT("&Close"));
1327 boxSizer
->Add(cancelButton
, 0, wxALL
|wxCENTRE
, 5);
1330 wxStringOutputStream
strStream(& text
);
1332 wxRichTextHTMLHandler htmlHandler
;
1333 htmlHandler
.SetFlags(wxRICHTEXT_HANDLER_SAVE_IMAGES_TO_MEMORY
);
1335 wxArrayInt fontSizeMapping
;
1336 fontSizeMapping
.Add(7);
1337 fontSizeMapping
.Add(9);
1338 fontSizeMapping
.Add(11);
1339 fontSizeMapping
.Add(12);
1340 fontSizeMapping
.Add(14);
1341 fontSizeMapping
.Add(22);
1342 fontSizeMapping
.Add(100);
1344 htmlHandler
.SetFontSizeMapping(fontSizeMapping
);
1346 if (htmlHandler
.SaveFile(& m_richTextCtrl
->GetBuffer(), strStream
))
1351 boxSizer
->Fit(& dialog
);
1355 // Now delete the temporary in-memory images
1356 htmlHandler
.DeleteTemporaryImages();
1359 // Demonstrates how you can change the style sheets and have the changes
1360 // reflected in the control content without wiping out character formatting.
1362 void MyFrame::OnSwitchStyleSheets(wxCommandEvent
& WXUNUSED(event
))
1364 static wxRichTextStyleSheet
* gs_AlternateStyleSheet
= NULL
;
1366 wxRichTextStyleListCtrl
*styleList
= (wxRichTextStyleListCtrl
*) FindWindow(ID_RICHTEXT_STYLE_LIST
);
1367 wxRichTextStyleComboCtrl
* styleCombo
= (wxRichTextStyleComboCtrl
*) FindWindow(ID_RICHTEXT_STYLE_COMBO
);
1369 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1371 // One-time creation of an alternate style sheet
1372 if (!gs_AlternateStyleSheet
)
1374 gs_AlternateStyleSheet
= new wxRichTextStyleSheet(*sheet
);
1376 // Make some modifications
1377 for (int i
= 0; i
< (int) gs_AlternateStyleSheet
->GetParagraphStyleCount(); i
++)
1379 wxRichTextParagraphStyleDefinition
* def
= gs_AlternateStyleSheet
->GetParagraphStyle(i
);
1381 if (def
->GetStyle().HasTextColour())
1382 def
->GetStyle().SetTextColour(*wxBLUE
);
1384 if (def
->GetStyle().HasAlignment())
1386 if (def
->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_CENTRE
)
1387 def
->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_RIGHT
);
1388 else if (def
->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_LEFT
)
1389 def
->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_CENTRE
);
1391 if (def
->GetStyle().HasLeftIndent())
1393 def
->GetStyle().SetLeftIndent(def
->GetStyle().GetLeftIndent() * 2);
1399 wxRichTextStyleSheet
* tmp
= gs_AlternateStyleSheet
;
1400 gs_AlternateStyleSheet
= sheet
;
1403 m_richTextCtrl
->SetStyleSheet(sheet
);
1404 m_richTextCtrl
->ApplyStyleSheet(sheet
); // Makes the control reflect the new style definitions
1406 styleList
->SetStyleSheet(sheet
);
1407 styleList
->UpdateStyles();
1409 styleCombo
->SetStyleSheet(sheet
);
1410 styleCombo
->UpdateStyles();
1413 void MyFrame::OnManageStyles(wxCommandEvent
& WXUNUSED(event
))
1415 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1417 int flags
= wxRICHTEXT_ORGANISER_CREATE_STYLES
|wxRICHTEXT_ORGANISER_EDIT_STYLES
;
1419 wxRichTextStyleOrganiserDialog
dlg(flags
, sheet
, NULL
, this, wxID_ANY
, _("Style Manager"));
1423 void MyFrame::OnInsertSymbol(wxCommandEvent
& WXUNUSED(event
))
1425 wxRichTextAttr attr
;
1426 attr
.SetFlags(wxTEXT_ATTR_FONT
);
1427 m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
);
1429 wxString currentFontName
;
1430 if (attr
.HasFont() && attr
.GetFont().Ok())
1431 currentFontName
= attr
.GetFont().GetFaceName();
1433 // Don't set the initial font in the dialog (so the user is choosing
1434 // 'normal text', i.e. the current font) but do tell the dialog
1435 // what 'normal text' is.
1437 wxSymbolPickerDialog
dlg(wxT("*"), wxEmptyString
, currentFontName
, this);
1439 if (dlg
.ShowModal() == wxID_OK
)
1441 if (dlg
.HasSelection())
1443 long insertionPoint
= m_richTextCtrl
->GetInsertionPoint();
1445 m_richTextCtrl
->WriteText(dlg
.GetSymbol());
1447 if (!dlg
.UseNormalFont())
1449 wxFont
font(attr
.GetFont());
1450 font
.SetFaceName(dlg
.GetFontName());
1452 m_richTextCtrl
->SetStyle(insertionPoint
, insertionPoint
+1, attr
);
1458 void MyFrame::OnNumberList(wxCommandEvent
& WXUNUSED(event
))
1460 if (m_richTextCtrl
->HasSelection())
1462 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1463 m_richTextCtrl
->SetListStyle(range
, wxT("Numbered List 1"), wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_RENUMBER
);
1467 void MyFrame::OnBulletsAndNumbering(wxCommandEvent
& WXUNUSED(event
))
1469 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1471 int flags
= wxRICHTEXT_ORGANISER_BROWSE_NUMBERING
;
1473 wxRichTextStyleOrganiserDialog
dlg(flags
, sheet
, m_richTextCtrl
, this, wxID_ANY
, _("Bullets and Numbering"));
1474 if (dlg
.ShowModal() == wxID_OK
)
1476 if (dlg
.GetSelectedStyleDefinition())
1481 void MyFrame::OnItemizeList(wxCommandEvent
& WXUNUSED(event
))
1483 if (m_richTextCtrl
->HasSelection())
1485 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1486 m_richTextCtrl
->SetListStyle(range
, wxT("Bullet List 1"));
1490 void MyFrame::OnRenumberList(wxCommandEvent
& WXUNUSED(event
))
1492 if (m_richTextCtrl
->HasSelection())
1494 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1495 m_richTextCtrl
->NumberList(range
, NULL
, wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_RENUMBER
);
1499 void MyFrame::OnPromoteList(wxCommandEvent
& WXUNUSED(event
))
1501 if (m_richTextCtrl
->HasSelection())
1503 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1504 m_richTextCtrl
->PromoteList(1, range
, NULL
);
1508 void MyFrame::OnDemoteList(wxCommandEvent
& WXUNUSED(event
))
1510 if (m_richTextCtrl
->HasSelection())
1512 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1513 m_richTextCtrl
->PromoteList(-1, range
, NULL
);
1517 void MyFrame::OnClearList(wxCommandEvent
& WXUNUSED(event
))
1519 if (m_richTextCtrl
->HasSelection())
1521 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1522 m_richTextCtrl
->ClearListStyle(range
);
1526 void MyFrame::OnInsertURL(wxCommandEvent
& WXUNUSED(event
))
1528 wxString url
= wxGetTextFromUser(_("URL:"), _("Insert URL"));
1531 // Make a style suitable for showing a URL
1532 wxRichTextAttr urlStyle
;
1533 urlStyle
.SetTextColour(*wxBLUE
);
1534 urlStyle
.SetFontUnderlined(true);
1536 m_richTextCtrl
->BeginStyle(urlStyle
);
1537 m_richTextCtrl
->BeginURL(url
);
1538 m_richTextCtrl
->WriteText(url
);
1539 m_richTextCtrl
->EndURL();
1540 m_richTextCtrl
->EndStyle();
1544 void MyFrame::OnURL(wxTextUrlEvent
& event
)
1546 wxMessageBox(event
.GetString());
1549 // Veto style sheet replace events when loading from XML, since we want
1550 // to keep the original style sheet.
1551 void MyFrame::OnStyleSheetReplacing(wxRichTextEvent
& event
)
1556 void MyFrame::OnPrint(wxCommandEvent
& WXUNUSED(event
))
1558 wxGetApp().GetPrinting()->PrintBuffer(m_richTextCtrl
->GetBuffer());
1561 void MyFrame::OnPreview(wxCommandEvent
& WXUNUSED(event
))
1563 wxGetApp().GetPrinting()->PreviewBuffer(m_richTextCtrl
->GetBuffer());
1566 void MyFrame::OnPageSetup(wxCommandEvent
& WXUNUSED(event
))
1568 wxGetApp().GetPrinting()->PageSetup();