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"
81 #include "wx/richtext/richtextimagedlg.h"
83 // ----------------------------------------------------------------------------
85 // ----------------------------------------------------------------------------
87 // ----------------------------------------------------------------------------
89 // ----------------------------------------------------------------------------
91 // Define a new application type, each program should derive a class from wxApp
92 class MyApp
: public wxApp
95 // override base class virtuals
96 // ----------------------------
98 // this one is called on application startup and is a good place for the app
99 // initialization (doing it here and not in the ctor allows to have an error
100 // return: if OnInit() returns false, the application terminates)
101 virtual bool OnInit();
102 virtual int OnExit();
106 wxRichTextStyleSheet
* GetStyleSheet() const { return m_styleSheet
; }
107 wxRichTextPrinting
* GetPrinting() const { return m_printing
; }
109 wxRichTextStyleSheet
* m_styleSheet
;
110 wxRichTextPrinting
* m_printing
;
113 // Define a new frame type: this is going to be our main frame
114 class MyFrame
: public wxFrame
118 MyFrame(const wxString
& title
, wxWindowID id
, const wxPoint
& pos
= wxDefaultPosition
,
119 const wxSize
& size
= wxDefaultSize
, long style
= wxDEFAULT_FRAME_STYLE
);
121 // event handlers (these functions should _not_ be virtual)
122 void OnQuit(wxCommandEvent
& event
);
123 void OnAbout(wxCommandEvent
& event
);
125 void OnOpen(wxCommandEvent
& event
);
126 void OnSave(wxCommandEvent
& event
);
127 void OnSaveAs(wxCommandEvent
& event
);
129 void OnBold(wxCommandEvent
& event
);
130 void OnItalic(wxCommandEvent
& event
);
131 void OnUnderline(wxCommandEvent
& event
);
133 void OnUpdateBold(wxUpdateUIEvent
& event
);
134 void OnUpdateItalic(wxUpdateUIEvent
& event
);
135 void OnUpdateUnderline(wxUpdateUIEvent
& event
);
137 void OnAlignLeft(wxCommandEvent
& event
);
138 void OnAlignCentre(wxCommandEvent
& event
);
139 void OnAlignRight(wxCommandEvent
& event
);
141 void OnUpdateAlignLeft(wxUpdateUIEvent
& event
);
142 void OnUpdateAlignCentre(wxUpdateUIEvent
& event
);
143 void OnUpdateAlignRight(wxUpdateUIEvent
& event
);
145 void OnIndentMore(wxCommandEvent
& event
);
146 void OnIndentLess(wxCommandEvent
& event
);
148 void OnFont(wxCommandEvent
& event
);
149 void OnImage(wxCommandEvent
& event
);
150 void OnUpdateImage(wxUpdateUIEvent
& event
);
151 void OnParagraph(wxCommandEvent
& event
);
152 void OnFormat(wxCommandEvent
& event
);
153 void OnUpdateFormat(wxUpdateUIEvent
& event
);
155 void OnInsertSymbol(wxCommandEvent
& event
);
157 void OnLineSpacingHalf(wxCommandEvent
& event
);
158 void OnLineSpacingDouble(wxCommandEvent
& event
);
159 void OnLineSpacingSingle(wxCommandEvent
& event
);
161 void OnParagraphSpacingMore(wxCommandEvent
& event
);
162 void OnParagraphSpacingLess(wxCommandEvent
& event
);
164 void OnNumberList(wxCommandEvent
& event
);
165 void OnBulletsAndNumbering(wxCommandEvent
& event
);
166 void OnItemizeList(wxCommandEvent
& event
);
167 void OnRenumberList(wxCommandEvent
& event
);
168 void OnPromoteList(wxCommandEvent
& event
);
169 void OnDemoteList(wxCommandEvent
& event
);
170 void OnClearList(wxCommandEvent
& event
);
172 void OnReload(wxCommandEvent
& event
);
174 void OnViewHTML(wxCommandEvent
& event
);
176 void OnSwitchStyleSheets(wxCommandEvent
& event
);
177 void OnManageStyles(wxCommandEvent
& event
);
179 void OnInsertURL(wxCommandEvent
& event
);
180 void OnURL(wxTextUrlEvent
& event
);
181 void OnStyleSheetReplacing(wxRichTextEvent
& event
);
183 void OnPrint(wxCommandEvent
& event
);
184 void OnPreview(wxCommandEvent
& event
);
185 void OnPageSetup(wxCommandEvent
& event
);
187 void OnInsertImage(wxCommandEvent
& event
);
190 // Forward command events to the current rich text control, if any
191 bool ProcessEvent(wxEvent
& event
);
194 void WriteInitialText();
197 // any class wishing to process wxWidgets events must use this macro
198 DECLARE_EVENT_TABLE()
200 wxRichTextCtrl
* m_richTextCtrl
;
203 // ----------------------------------------------------------------------------
205 // ----------------------------------------------------------------------------
207 // IDs for the controls and the menu commands
212 ID_About
= wxID_ABOUT
,
214 ID_FORMAT_BOLD
= 100,
228 ID_FORMAT_ALIGN_LEFT
,
229 ID_FORMAT_ALIGN_CENTRE
,
230 ID_FORMAT_ALIGN_RIGHT
,
232 ID_FORMAT_INDENT_MORE
,
233 ID_FORMAT_INDENT_LESS
,
235 ID_FORMAT_PARAGRAPH_SPACING_MORE
,
236 ID_FORMAT_PARAGRAPH_SPACING_LESS
,
238 ID_FORMAT_LINE_SPACING_HALF
,
239 ID_FORMAT_LINE_SPACING_DOUBLE
,
240 ID_FORMAT_LINE_SPACING_SINGLE
,
242 ID_FORMAT_NUMBER_LIST
,
243 ID_FORMAT_BULLETS_AND_NUMBERING
,
244 ID_FORMAT_ITEMIZE_LIST
,
245 ID_FORMAT_RENUMBER_LIST
,
246 ID_FORMAT_PROMOTE_LIST
,
247 ID_FORMAT_DEMOTE_LIST
,
248 ID_FORMAT_CLEAR_LIST
,
251 ID_SWITCH_STYLE_SHEETS
,
259 ID_RICHTEXT_STYLE_LIST
,
260 ID_RICHTEXT_STYLE_COMBO
263 // ----------------------------------------------------------------------------
264 // event tables and other macros for wxWidgets
265 // ----------------------------------------------------------------------------
267 // the event tables connect the wxWidgets events with the functions (event
268 // handlers) which process them. It can be also done at run-time, but for the
269 // simple menu events like this the static method is much simpler.
270 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
271 EVT_MENU(ID_Quit
, MyFrame::OnQuit
)
272 EVT_MENU(ID_About
, MyFrame::OnAbout
)
274 EVT_MENU(wxID_OPEN
, MyFrame::OnOpen
)
275 EVT_MENU(wxID_SAVE
, MyFrame::OnSave
)
276 EVT_MENU(wxID_SAVEAS
, MyFrame::OnSaveAs
)
278 EVT_MENU(ID_FORMAT_BOLD
, MyFrame::OnBold
)
279 EVT_MENU(ID_FORMAT_ITALIC
, MyFrame::OnItalic
)
280 EVT_MENU(ID_FORMAT_UNDERLINE
, MyFrame::OnUnderline
)
282 EVT_UPDATE_UI(ID_FORMAT_BOLD
, MyFrame::OnUpdateBold
)
283 EVT_UPDATE_UI(ID_FORMAT_ITALIC
, MyFrame::OnUpdateItalic
)
284 EVT_UPDATE_UI(ID_FORMAT_UNDERLINE
, MyFrame::OnUpdateUnderline
)
286 EVT_MENU(ID_FORMAT_ALIGN_LEFT
, MyFrame::OnAlignLeft
)
287 EVT_MENU(ID_FORMAT_ALIGN_CENTRE
, MyFrame::OnAlignCentre
)
288 EVT_MENU(ID_FORMAT_ALIGN_RIGHT
, MyFrame::OnAlignRight
)
290 EVT_UPDATE_UI(ID_FORMAT_ALIGN_LEFT
, MyFrame::OnUpdateAlignLeft
)
291 EVT_UPDATE_UI(ID_FORMAT_ALIGN_CENTRE
, MyFrame::OnUpdateAlignCentre
)
292 EVT_UPDATE_UI(ID_FORMAT_ALIGN_RIGHT
, MyFrame::OnUpdateAlignRight
)
294 EVT_MENU(ID_FORMAT_FONT
, MyFrame::OnFont
)
295 EVT_MENU(ID_FORMAT_IMAGE
, MyFrame::OnImage
)
296 EVT_MENU(ID_FORMAT_PARAGRAPH
, MyFrame::OnParagraph
)
297 EVT_MENU(ID_FORMAT_CONTENT
, MyFrame::OnFormat
)
298 EVT_UPDATE_UI(ID_FORMAT_CONTENT
, MyFrame::OnUpdateFormat
)
299 EVT_UPDATE_UI(ID_FORMAT_FONT
, MyFrame::OnUpdateFormat
)
300 EVT_UPDATE_UI(ID_FORMAT_IMAGE
, MyFrame::OnUpdateImage
)
301 EVT_UPDATE_UI(ID_FORMAT_PARAGRAPH
, MyFrame::OnUpdateFormat
)
302 EVT_MENU(ID_FORMAT_INDENT_MORE
, MyFrame::OnIndentMore
)
303 EVT_MENU(ID_FORMAT_INDENT_LESS
, MyFrame::OnIndentLess
)
305 EVT_MENU(ID_FORMAT_LINE_SPACING_HALF
, MyFrame::OnLineSpacingHalf
)
306 EVT_MENU(ID_FORMAT_LINE_SPACING_SINGLE
, MyFrame::OnLineSpacingSingle
)
307 EVT_MENU(ID_FORMAT_LINE_SPACING_DOUBLE
, MyFrame::OnLineSpacingDouble
)
309 EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_MORE
, MyFrame::OnParagraphSpacingMore
)
310 EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_LESS
, MyFrame::OnParagraphSpacingLess
)
312 EVT_MENU(ID_RELOAD
, MyFrame::OnReload
)
314 EVT_MENU(ID_INSERT_SYMBOL
, MyFrame::OnInsertSymbol
)
315 EVT_MENU(ID_INSERT_URL
, MyFrame::OnInsertURL
)
316 EVT_MENU(ID_INSERT_IMAGE
, MyFrame::OnInsertImage
)
318 EVT_MENU(ID_FORMAT_NUMBER_LIST
, MyFrame::OnNumberList
)
319 EVT_MENU(ID_FORMAT_BULLETS_AND_NUMBERING
, MyFrame::OnBulletsAndNumbering
)
320 EVT_MENU(ID_FORMAT_ITEMIZE_LIST
, MyFrame::OnItemizeList
)
321 EVT_MENU(ID_FORMAT_RENUMBER_LIST
, MyFrame::OnRenumberList
)
322 EVT_MENU(ID_FORMAT_PROMOTE_LIST
, MyFrame::OnPromoteList
)
323 EVT_MENU(ID_FORMAT_DEMOTE_LIST
, MyFrame::OnDemoteList
)
324 EVT_MENU(ID_FORMAT_CLEAR_LIST
, MyFrame::OnClearList
)
326 EVT_MENU(ID_VIEW_HTML
, MyFrame::OnViewHTML
)
327 EVT_MENU(ID_SWITCH_STYLE_SHEETS
, MyFrame::OnSwitchStyleSheets
)
328 EVT_MENU(ID_MANAGE_STYLES
, MyFrame::OnManageStyles
)
330 EVT_MENU(ID_PRINT
, MyFrame::OnPrint
)
331 EVT_MENU(ID_PREVIEW
, MyFrame::OnPreview
)
332 EVT_MENU(ID_PAGE_SETUP
, MyFrame::OnPageSetup
)
334 EVT_TEXT_URL(wxID_ANY
, MyFrame::OnURL
)
335 EVT_RICHTEXT_STYLESHEET_REPLACING(wxID_ANY
, MyFrame::OnStyleSheetReplacing
)
338 // Create a new application object: this macro will allow wxWidgets to create
339 // the application object during program execution (it's better than using a
340 // static object for many reasons) and also implements the accessor function
341 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
345 // ============================================================================
347 // ============================================================================
349 // ----------------------------------------------------------------------------
350 // the application class
351 // ----------------------------------------------------------------------------
353 // 'Main program' equivalent: the program execution "starts" here
356 if ( !wxApp::OnInit() )
360 wxHelpProvider::Set(new wxSimpleHelpProvider
);
363 m_styleSheet
= new wxRichTextStyleSheet
;
364 m_printing
= new wxRichTextPrinting(wxT("Test Document"));
366 m_printing
->SetFooterText(wxT("@TITLE@"), wxRICHTEXT_PAGE_ALL
, wxRICHTEXT_PAGE_CENTRE
);
367 m_printing
->SetFooterText(wxT("Page @PAGENUM@"), wxRICHTEXT_PAGE_ALL
, wxRICHTEXT_PAGE_RIGHT
);
371 // Add extra handlers (plain text is automatically added)
372 wxRichTextBuffer::AddHandler(new wxRichTextXMLHandler
);
373 wxRichTextBuffer::AddHandler(new wxRichTextHTMLHandler
);
375 // Add image handlers
377 wxImage::AddHandler( new wxPNGHandler
);
381 wxImage::AddHandler( new wxJPEGHandler
);
385 wxImage::AddHandler( new wxGIFHandler
);
389 wxFileSystem::AddHandler( new wxMemoryFSHandler
);
392 // create the main application window
393 MyFrame
*frame
= new MyFrame(wxT("wxRichTextCtrl Sample"), wxID_ANY
, wxDefaultPosition
, wxSize(700, 600));
395 m_printing
->SetParentWindow(frame
);
397 // and show it (the frames, unlike simple controls, are not shown when
398 // created initially)
401 // success: wxApp::OnRun() will be called which will enter the main message
402 // loop and the application will run. If we returned false here, the
403 // application would exit immediately.
415 void MyApp::CreateStyles()
419 wxFont
romanFont(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
420 wxFont
swissFont(12, wxSWISS
, wxNORMAL
, wxNORMAL
);
422 wxRichTextParagraphStyleDefinition
* normalPara
= new wxRichTextParagraphStyleDefinition(wxT("Normal"));
423 wxRichTextAttr normalAttr
;
424 normalAttr
.SetFontFaceName(romanFont
.GetFaceName());
425 normalAttr
.SetFontSize(12);
426 // Let's set all attributes for this style
427 normalAttr
.SetFlags(wxTEXT_ATTR_FONT
| wxTEXT_ATTR_BACKGROUND_COLOUR
| wxTEXT_ATTR_TEXT_COLOUR
|wxTEXT_ATTR_ALIGNMENT
|wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
|wxTEXT_ATTR_TABS
|
428 wxTEXT_ATTR_PARA_SPACING_BEFORE
|wxTEXT_ATTR_PARA_SPACING_AFTER
|wxTEXT_ATTR_LINE_SPACING
|
429 wxTEXT_ATTR_BULLET_STYLE
|wxTEXT_ATTR_BULLET_NUMBER
);
430 normalPara
->SetStyle(normalAttr
);
432 m_styleSheet
->AddParagraphStyle(normalPara
);
434 wxRichTextParagraphStyleDefinition
* indentedPara
= new wxRichTextParagraphStyleDefinition(wxT("Indented"));
435 wxRichTextAttr indentedAttr
;
436 indentedAttr
.SetFontFaceName(romanFont
.GetFaceName());
437 indentedAttr
.SetFontSize(12);
438 indentedAttr
.SetLeftIndent(100, 0);
439 // We only want to affect indentation
440 indentedAttr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
);
441 indentedPara
->SetStyle(indentedAttr
);
443 m_styleSheet
->AddParagraphStyle(indentedPara
);
445 wxRichTextParagraphStyleDefinition
* indentedPara2
= new wxRichTextParagraphStyleDefinition(wxT("Red Bold Indented"));
446 wxRichTextAttr indentedAttr2
;
447 indentedAttr2
.SetFontFaceName(romanFont
.GetFaceName());
448 indentedAttr2
.SetFontSize(12);
449 indentedAttr2
.SetFontWeight(wxFONTWEIGHT_BOLD
);
450 indentedAttr2
.SetTextColour(*wxRED
);
451 indentedAttr2
.SetFontSize(12);
452 indentedAttr2
.SetLeftIndent(100, 0);
453 // We want to affect indentation, font and text colour
454 indentedAttr2
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
|wxTEXT_ATTR_FONT
|wxTEXT_ATTR_TEXT_COLOUR
);
455 indentedPara2
->SetStyle(indentedAttr2
);
457 m_styleSheet
->AddParagraphStyle(indentedPara2
);
459 wxRichTextParagraphStyleDefinition
* flIndentedPara
= new wxRichTextParagraphStyleDefinition(wxT("First Line Indented"));
460 wxRichTextAttr flIndentedAttr
;
461 flIndentedAttr
.SetFontFaceName(swissFont
.GetFaceName());
462 flIndentedAttr
.SetFontSize(12);
463 flIndentedAttr
.SetLeftIndent(100, -100);
464 // We only want to affect indentation
465 flIndentedAttr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
);
466 flIndentedPara
->SetStyle(flIndentedAttr
);
468 m_styleSheet
->AddParagraphStyle(flIndentedPara
);
472 wxRichTextCharacterStyleDefinition
* boldDef
= new wxRichTextCharacterStyleDefinition(wxT("Bold"));
473 wxRichTextAttr boldAttr
;
474 boldAttr
.SetFontFaceName(romanFont
.GetFaceName());
475 boldAttr
.SetFontSize(12);
476 boldAttr
.SetFontWeight(wxFONTWEIGHT_BOLD
);
477 // We only want to affect boldness
478 boldAttr
.SetFlags(wxTEXT_ATTR_FONT_WEIGHT
);
479 boldDef
->SetStyle(boldAttr
);
481 m_styleSheet
->AddCharacterStyle(boldDef
);
483 wxRichTextCharacterStyleDefinition
* italicDef
= new wxRichTextCharacterStyleDefinition(wxT("Italic"));
484 wxRichTextAttr italicAttr
;
485 italicAttr
.SetFontFaceName(romanFont
.GetFaceName());
486 italicAttr
.SetFontSize(12);
487 italicAttr
.SetFontStyle(wxFONTSTYLE_ITALIC
);
488 // We only want to affect italics
489 italicAttr
.SetFlags(wxTEXT_ATTR_FONT_ITALIC
);
490 italicDef
->SetStyle(italicAttr
);
492 m_styleSheet
->AddCharacterStyle(italicDef
);
494 wxRichTextCharacterStyleDefinition
* redDef
= new wxRichTextCharacterStyleDefinition(wxT("Red Bold"));
495 wxRichTextAttr redAttr
;
496 redAttr
.SetFontFaceName(romanFont
.GetFaceName());
497 redAttr
.SetFontSize(12);
498 redAttr
.SetFontWeight(wxFONTWEIGHT_BOLD
);
499 redAttr
.SetTextColour(*wxRED
);
500 // We only want to affect colour, weight and face
501 redAttr
.SetFlags(wxTEXT_ATTR_FONT_FACE
|wxTEXT_ATTR_FONT_WEIGHT
|wxTEXT_ATTR_TEXT_COLOUR
);
502 redDef
->SetStyle(redAttr
);
504 m_styleSheet
->AddCharacterStyle(redDef
);
506 wxRichTextListStyleDefinition
* bulletList
= new wxRichTextListStyleDefinition(wxT("Bullet List 1"));
508 for (i
= 0; i
< 10; i
++)
512 bulletText
= wxT("standard/circle");
514 bulletText
= wxT("standard/square");
516 bulletText
= wxT("standard/circle");
518 bulletText
= wxT("standard/square");
520 bulletText
= wxT("standard/circle");
522 bulletList
->SetAttributes(i
, (i
+1)*60, 60, wxTEXT_ATTR_BULLET_STYLE_STANDARD
, bulletText
);
525 m_styleSheet
->AddListStyle(bulletList
);
527 wxRichTextListStyleDefinition
* numberedList
= new wxRichTextListStyleDefinition(wxT("Numbered List 1"));
528 for (i
= 0; i
< 10; i
++)
532 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
534 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_LETTERS_LOWER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
536 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ROMAN_LOWER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
538 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ROMAN_UPPER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
540 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
542 numberStyle
|= wxTEXT_ATTR_BULLET_STYLE_ALIGN_RIGHT
;
544 numberedList
->SetAttributes(i
, (i
+1)*60, 60, numberStyle
);
547 m_styleSheet
->AddListStyle(numberedList
);
549 wxRichTextListStyleDefinition
* outlineList
= new wxRichTextListStyleDefinition(wxT("Outline List 1"));
550 for (i
= 0; i
< 10; i
++)
554 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_OUTLINE
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
556 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
558 outlineList
->SetAttributes(i
, (i
+1)*120, 120, numberStyle
);
561 m_styleSheet
->AddListStyle(outlineList
);
564 // ----------------------------------------------------------------------------
566 // ----------------------------------------------------------------------------
569 MyFrame::MyFrame(const wxString
& title
, wxWindowID id
, const wxPoint
& pos
,
570 const wxSize
& size
, long style
)
571 : wxFrame(NULL
, id
, title
, pos
, size
, style
)
573 // set the frame icon
574 SetIcon(wxICON(sample
));
577 wxMenu
*fileMenu
= new wxMenu
;
579 // the "About" item should be in the help menu
580 wxMenu
*helpMenu
= new wxMenu
;
581 helpMenu
->Append(ID_About
, wxT("&About...\tF1"), wxT("Show about dialog"));
583 fileMenu
->Append(wxID_OPEN
, wxT("&Open\tCtrl+O"), wxT("Open a file"));
584 fileMenu
->Append(wxID_SAVE
, wxT("&Save\tCtrl+S"), wxT("Save a file"));
585 fileMenu
->Append(wxID_SAVEAS
, wxT("&Save As...\tF12"), wxT("Save to a new file"));
586 fileMenu
->AppendSeparator();
587 fileMenu
->Append(ID_RELOAD
, wxT("&Reload Text\tF2"), wxT("Reload the initial text"));
588 fileMenu
->AppendSeparator();
589 fileMenu
->Append(ID_PAGE_SETUP
, wxT("Page Set&up..."), wxT("Page setup"));
590 fileMenu
->Append(ID_PRINT
, wxT("&Print...\tCtrl+P"), wxT("Print"));
591 fileMenu
->Append(ID_PREVIEW
, wxT("Print Pre&view"), wxT("Print preview"));
592 fileMenu
->AppendSeparator();
593 fileMenu
->Append(ID_VIEW_HTML
, wxT("&View as HTML"), wxT("View HTML"));
594 fileMenu
->AppendSeparator();
595 fileMenu
->Append(ID_Quit
, wxT("E&xit\tAlt+X"), wxT("Quit this program"));
597 wxMenu
* editMenu
= new wxMenu
;
598 editMenu
->Append(wxID_UNDO
, _("&Undo\tCtrl+Z"));
599 editMenu
->Append(wxID_REDO
, _("&Redo\tCtrl+Y"));
600 editMenu
->AppendSeparator();
601 editMenu
->Append(wxID_CUT
, _("Cu&t\tCtrl+X"));
602 editMenu
->Append(wxID_COPY
, _("&Copy\tCtrl+C"));
603 editMenu
->Append(wxID_PASTE
, _("&Paste\tCtrl+V"));
605 editMenu
->AppendSeparator();
606 editMenu
->Append(wxID_SELECTALL
, _("Select A&ll\tCtrl+A"));
608 editMenu
->AppendSeparator();
609 editMenu
->Append(wxID_FIND
, _("&Find...\tCtrl+F"));
610 editMenu
->Append(stID_FIND_REPLACE
, _("&Replace...\tCtrl+R"));
613 wxMenu
* formatMenu
= new wxMenu
;
614 formatMenu
->AppendCheckItem(ID_FORMAT_BOLD
, _("&Bold\tCtrl+B"));
615 formatMenu
->AppendCheckItem(ID_FORMAT_ITALIC
, _("&Italic\tCtrl+I"));
616 formatMenu
->AppendCheckItem(ID_FORMAT_UNDERLINE
, _("&Underline\tCtrl+U"));
617 formatMenu
->AppendSeparator();
618 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_LEFT
, _("L&eft Align"));
619 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_RIGHT
, _("&Right Align"));
620 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_CENTRE
, _("&Centre"));
621 formatMenu
->AppendSeparator();
622 formatMenu
->Append(ID_FORMAT_INDENT_MORE
, _("Indent &More"));
623 formatMenu
->Append(ID_FORMAT_INDENT_LESS
, _("Indent &Less"));
624 formatMenu
->AppendSeparator();
625 formatMenu
->Append(ID_FORMAT_PARAGRAPH_SPACING_MORE
, _("Increase Paragraph &Spacing"));
626 formatMenu
->Append(ID_FORMAT_PARAGRAPH_SPACING_LESS
, _("Decrease &Paragraph Spacing"));
627 formatMenu
->AppendSeparator();
628 formatMenu
->Append(ID_FORMAT_LINE_SPACING_SINGLE
, _("Normal Line Spacing"));
629 formatMenu
->Append(ID_FORMAT_LINE_SPACING_HALF
, _("1.5 Line Spacing"));
630 formatMenu
->Append(ID_FORMAT_LINE_SPACING_DOUBLE
, _("Double Line Spacing"));
631 formatMenu
->AppendSeparator();
632 formatMenu
->Append(ID_FORMAT_FONT
, _("&Font..."));
633 formatMenu
->Append(ID_FORMAT_IMAGE
, _("Image Property"));
634 formatMenu
->Append(ID_FORMAT_PARAGRAPH
, _("&Paragraph..."));
635 formatMenu
->Append(ID_FORMAT_CONTENT
, _("Font and Pa&ragraph...\tShift+Ctrl+F"));
636 formatMenu
->AppendSeparator();
637 formatMenu
->Append(ID_SWITCH_STYLE_SHEETS
, _("&Switch Style Sheets"));
638 formatMenu
->Append(ID_MANAGE_STYLES
, _("&Manage Styles"));
640 wxMenu
* listsMenu
= new wxMenu
;
641 listsMenu
->Append(ID_FORMAT_BULLETS_AND_NUMBERING
, _("Bullets and &Numbering..."));
642 listsMenu
->AppendSeparator();
643 listsMenu
->Append(ID_FORMAT_NUMBER_LIST
, _("Number List"));
644 listsMenu
->Append(ID_FORMAT_ITEMIZE_LIST
, _("Itemize List"));
645 listsMenu
->Append(ID_FORMAT_RENUMBER_LIST
, _("Renumber List"));
646 listsMenu
->Append(ID_FORMAT_PROMOTE_LIST
, _("Promote List Items"));
647 listsMenu
->Append(ID_FORMAT_DEMOTE_LIST
, _("Demote List Items"));
648 listsMenu
->Append(ID_FORMAT_CLEAR_LIST
, _("Clear List Formatting"));
650 wxMenu
* insertMenu
= new wxMenu
;
651 insertMenu
->Append(ID_INSERT_SYMBOL
, _("&Symbol...\tCtrl+I"));
652 insertMenu
->Append(ID_INSERT_URL
, _("&URL..."));
653 insertMenu
->Append(ID_INSERT_IMAGE
, _("&Image..."));
655 // now append the freshly created menu to the menu bar...
656 wxMenuBar
*menuBar
= new wxMenuBar();
657 menuBar
->Append(fileMenu
, wxT("&File"));
658 menuBar
->Append(editMenu
, wxT("&Edit"));
659 menuBar
->Append(formatMenu
, wxT("F&ormat"));
660 menuBar
->Append(listsMenu
, wxT("&Lists"));
661 menuBar
->Append(insertMenu
, wxT("&Insert"));
662 menuBar
->Append(helpMenu
, wxT("&Help"));
664 // ... and attach this menu bar to the frame
667 // create a status bar just for fun (by default with 1 pane only)
668 // but don't create it on limited screen space (WinCE)
669 bool is_pda
= wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA
;
675 SetStatusText(wxT("Welcome to wxRichTextCtrl!"));
679 wxToolBar
* toolBar
= CreateToolBar();
681 toolBar
->AddTool(wxID_OPEN
, wxEmptyString
, wxBitmap(open_xpm
), _("Open"));
682 toolBar
->AddTool(wxID_SAVEAS
, wxEmptyString
, wxBitmap(save_xpm
), _("Save"));
683 toolBar
->AddSeparator();
684 toolBar
->AddTool(wxID_CUT
, wxEmptyString
, wxBitmap(cut_xpm
), _("Cut"));
685 toolBar
->AddTool(wxID_COPY
, wxEmptyString
, wxBitmap(copy_xpm
), _("Copy"));
686 toolBar
->AddTool(wxID_PASTE
, wxEmptyString
, wxBitmap(paste_xpm
), _("Paste"));
687 toolBar
->AddSeparator();
688 toolBar
->AddTool(wxID_UNDO
, wxEmptyString
, wxBitmap(undo_xpm
), _("Undo"));
689 toolBar
->AddTool(wxID_REDO
, wxEmptyString
, wxBitmap(redo_xpm
), _("Redo"));
690 toolBar
->AddSeparator();
691 toolBar
->AddCheckTool(ID_FORMAT_BOLD
, wxEmptyString
, wxBitmap(bold_xpm
), wxNullBitmap
, _("Bold"));
692 toolBar
->AddCheckTool(ID_FORMAT_ITALIC
, wxEmptyString
, wxBitmap(italic_xpm
), wxNullBitmap
, _("Italic"));
693 toolBar
->AddCheckTool(ID_FORMAT_UNDERLINE
, wxEmptyString
, wxBitmap(underline_xpm
), wxNullBitmap
, _("Underline"));
694 toolBar
->AddSeparator();
695 toolBar
->AddCheckTool(ID_FORMAT_ALIGN_LEFT
, wxEmptyString
, wxBitmap(alignleft_xpm
), wxNullBitmap
, _("Align Left"));
696 toolBar
->AddCheckTool(ID_FORMAT_ALIGN_CENTRE
, wxEmptyString
, wxBitmap(centre_xpm
), wxNullBitmap
, _("Centre"));
697 toolBar
->AddCheckTool(ID_FORMAT_ALIGN_RIGHT
, wxEmptyString
, wxBitmap(alignright_xpm
), wxNullBitmap
, _("Align Right"));
698 toolBar
->AddSeparator();
699 toolBar
->AddTool(ID_FORMAT_INDENT_LESS
, wxEmptyString
, wxBitmap(indentless_xpm
), _("Indent Less"));
700 toolBar
->AddTool(ID_FORMAT_INDENT_MORE
, wxEmptyString
, wxBitmap(indentmore_xpm
), _("Indent More"));
701 toolBar
->AddSeparator();
702 toolBar
->AddTool(ID_FORMAT_FONT
, wxEmptyString
, wxBitmap(font_xpm
), _("Font"));
703 toolBar
->AddTool(ID_FORMAT_IMAGE
, wxString("Im"), wxBitmap(font_xpm
), _("Image Property"));
705 wxRichTextStyleComboCtrl
* combo
= new wxRichTextStyleComboCtrl(toolBar
, ID_RICHTEXT_STYLE_COMBO
, wxDefaultPosition
, wxSize(200, -1));
706 toolBar
->AddControl(combo
);
710 wxSplitterWindow
* splitter
= new wxSplitterWindow(this, wxID_ANY
, wxDefaultPosition
, GetClientSize(), wxSP_LIVE_UPDATE
);
712 wxFont textFont
= wxFont(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
713 wxFont boldFont
= wxFont(12, wxROMAN
, wxNORMAL
, wxBOLD
);
714 wxFont italicFont
= wxFont(12, wxROMAN
, wxITALIC
, wxNORMAL
);
716 m_richTextCtrl
= new wxRichTextCtrl(splitter
, ID_RICHTEXT_CTRL
, wxEmptyString
, wxDefaultPosition
, wxSize(200, 200), wxVSCROLL
|wxHSCROLL
|wxWANTS_CHARS
);
717 wxFont
font(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
719 m_richTextCtrl
->SetFont(font
);
721 m_richTextCtrl
->SetStyleSheet(wxGetApp().GetStyleSheet());
723 combo
->SetStyleSheet(wxGetApp().GetStyleSheet());
724 combo
->SetRichTextCtrl(m_richTextCtrl
);
725 combo
->UpdateStyles();
727 wxRichTextStyleListCtrl
* styleListCtrl
= new wxRichTextStyleListCtrl(splitter
, ID_RICHTEXT_STYLE_LIST
);
729 wxSize display
= wxGetDisplaySize();
730 if ( is_pda
&& ( display
.GetWidth() < display
.GetHeight() ) )
732 splitter
->SplitHorizontally(m_richTextCtrl
, styleListCtrl
);
736 splitter
->SplitVertically(m_richTextCtrl
, styleListCtrl
, 500);
739 splitter
->UpdateSize();
741 styleListCtrl
->SetStyleSheet(wxGetApp().GetStyleSheet());
742 styleListCtrl
->SetRichTextCtrl(m_richTextCtrl
);
743 styleListCtrl
->UpdateStyles();
749 void MyFrame::WriteInitialText()
751 wxRichTextCtrl
& r
= *m_richTextCtrl
;
753 r
.SetDefaultStyle(wxRichTextAttr());
755 r
.BeginSuppressUndo();
759 r
.BeginParagraphSpacing(0, 20);
761 r
.BeginAlignment(wxTEXT_ALIGNMENT_CENTRE
);
766 wxString lineBreak
= (wxChar
) 29;
768 r
.WriteText(wxString(wxT("Welcome to wxRichTextCtrl, a wxWidgets control")) + lineBreak
+ wxT("for editing and presenting styled text and images\n"));
772 r
.WriteText(wxT("by Julian Smart"));
778 r
.WriteImage(wxBitmap(zebra_xpm
));
785 r
.BeginAlignment(wxTEXT_ALIGNMENT_LEFT
);
786 wxRichTextAttr imageAttr
;
787 imageAttr
.GetTextBoxAttr().SetFloatMode(wxTEXT_BOX_ATTR_FLOAT_LEFT
);
788 r
.WriteText(wxString(wxT("This is a simple test for a floating left image test. The zebra image should be placed at the left side of the current buffer and all the text should flow around it at the right side. This is a simple test for a floating left image test. The zebra image should be placed at the left side of the current buffer and all the text should flow around it at the right side. This is a simple test for a floating left image test. The zebra image should be placed at the left side of the current buffer and all the text should flow around it at the right side.")));
789 r
.WriteImage(wxBitmap(zebra_xpm
), wxBITMAP_TYPE_PNG
, imageAttr
);
790 imageAttr
.GetTextBoxAttr().GetTop().SetValue(200);
791 imageAttr
.GetTextBoxAttr().GetTop().SetUnits(wxTEXT_ATTR_UNITS_PIXELS
);
792 imageAttr
.GetTextBoxAttr().SetFloatMode(wxTEXT_BOX_ATTR_FLOAT_RIGHT
);
793 r
.WriteImage(wxBitmap(zebra_xpm
), wxBITMAP_TYPE_PNG
, imageAttr
);
794 r
.WriteText(wxString(wxT("This is a simple test for a floating left image test. The zebra image should be placed at the left side of the current buffer and all the text should flow around it at the right side. This is a simple test for a floating left image test. The zebra image should be placed at the left side of the current buffer and all the text should flow around it at the right side. This is a simple test for a floating left image test. The zebra image should be placed at the left side of the current buffer and all the text should flow around it at the right side.")));
798 r
.WriteText(wxT("What can you do with this thing? "));
800 r
.WriteImage(wxBitmap(smiley_xpm
));
801 r
.WriteText(wxT(" Well, you can change text "));
803 r
.BeginTextColour(wxColour(255, 0, 0));
804 r
.WriteText(wxT("colour, like this red bit."));
807 wxRichTextAttr backgroundColourAttr
;
808 backgroundColourAttr
.SetBackgroundColour(*wxGREEN
);
809 backgroundColourAttr
.SetTextColour(wxColour(0, 0, 255));
810 r
.BeginStyle(backgroundColourAttr
);
811 r
.WriteText(wxT(" And this blue on green bit."));
814 r
.WriteText(wxT(" Naturally you can make things "));
816 r
.WriteText(wxT("bold "));
819 r
.WriteText(wxT("or italic "));
822 r
.WriteText(wxT("or underlined."));
826 r
.WriteText(wxT(" Different font sizes on the same line is allowed, too."));
829 r
.WriteText(wxT(" Next we'll show an indented paragraph."));
833 r
.BeginLeftIndent(60);
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."));
839 r
.WriteText(wxT("Next, we'll show a first-line indent, achieved using BeginLeftIndent(100, -40)."));
843 r
.BeginLeftIndent(100, -40);
845 r
.WriteText(wxT("It was in January, the most down-trodden month of an Edinburgh winter. An attractive woman came into the cafe, which is nothing remarkable."));
850 r
.WriteText(wxT("Numbered bullets are possible, again using subindents:"));
853 r
.BeginNumberedBullet(1, 100, 60);
854 r
.WriteText(wxT("This is my first item. Note that wxRichTextCtrl can apply numbering and bullets automatically based on list styles, but this list is formatted explicitly by setting indents."));
856 r
.EndNumberedBullet();
858 r
.BeginNumberedBullet(2, 100, 60);
859 r
.WriteText(wxT("This is my second item."));
861 r
.EndNumberedBullet();
863 r
.WriteText(wxT("The following paragraph is right-indented:"));
866 r
.BeginRightIndent(200);
868 r
.WriteText(wxT("It was in January, the most down-trodden month of an Edinburgh winter. An attractive woman came into the cafe, which is nothing remarkable."));
873 r
.WriteText(wxT("The following paragraph is right-aligned with 1.5 line spacing:"));
876 r
.BeginAlignment(wxTEXT_ALIGNMENT_RIGHT
);
877 r
.BeginLineSpacing(wxTEXT_ATTR_LINE_SPACING_HALF
);
878 r
.WriteText(wxT("It was in January, the most down-trodden month of an Edinburgh winter. An attractive woman came into the cafe, which is nothing remarkable."));
889 attr
.SetFlags(wxTEXT_ATTR_TABS
);
891 r
.SetDefaultStyle(attr
);
893 r
.WriteText(wxT("This line contains tabs:\tFirst tab\tSecond tab\tThird tab"));
896 r
.WriteText(wxT("Other notable features of wxRichTextCtrl include:"));
899 r
.BeginSymbolBullet(wxT('*'), 100, 60);
900 r
.WriteText(wxT("Compatibility with wxTextCtrl API"));
904 r
.BeginSymbolBullet(wxT('*'), 100, 60);
905 r
.WriteText(wxT("Easy stack-based BeginXXX()...EndXXX() style setting in addition to SetStyle()"));
909 r
.BeginSymbolBullet(wxT('*'), 100, 60);
910 r
.WriteText(wxT("XML loading and saving"));
914 r
.BeginSymbolBullet(wxT('*'), 100, 60);
915 r
.WriteText(wxT("Undo/Redo, with batching option and Undo suppressing"));
919 r
.BeginSymbolBullet(wxT('*'), 100, 60);
920 r
.WriteText(wxT("Clipboard copy and paste"));
924 r
.BeginSymbolBullet(wxT('*'), 100, 60);
925 r
.WriteText(wxT("wxRichTextStyleSheet with named character and paragraph styles, and control for applying named styles"));
929 r
.BeginSymbolBullet(wxT('*'), 100, 60);
930 r
.WriteText(wxT("A design that can easily be extended to other content types, ultimately with text boxes, tables, controls, and so on"));
934 // Make a style suitable for showing a URL
935 wxRichTextAttr urlStyle
;
936 urlStyle
.SetTextColour(*wxBLUE
);
937 urlStyle
.SetFontUnderlined(true);
939 r
.WriteText(wxT("wxRichTextCtrl can also display URLs, such as this one: "));
940 r
.BeginStyle(urlStyle
);
941 r
.BeginURL(wxT("http://www.wxwidgets.org"));
942 r
.WriteText(wxT("The wxWidgets Web Site"));
945 r
.WriteText(wxT(". Click on the URL to generate an event."));
949 r
.WriteText(wxT("Note: this sample content was generated programmatically from within the MyFrame constructor in the demo. The images were loaded from inline XPMs. Enjoy wxRichTextCtrl!\n"));
951 r
.EndParagraphSpacing();
960 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
962 // true is to force the frame to close
966 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
969 msg
.Printf( wxT("This is a demo for wxRichTextCtrl, a control for editing styled text.\n(c) Julian Smart, 2005"));
970 wxMessageBox(msg
, wxT("About wxRichTextCtrl Sample"), wxOK
| wxICON_INFORMATION
, this);
973 // Forward command events to the current rich text control, if any
974 bool MyFrame::ProcessEvent(wxEvent
& event
)
976 if (event
.IsCommandEvent() && !event
.IsKindOf(CLASSINFO(wxChildFocusEvent
)))
978 // Problem: we can get infinite recursion because the events
979 // climb back up to this frame, and repeat.
980 // Assume that command events don't cause another command event
981 // to be called, so we can rely on inCommand not being overwritten
983 static int s_eventType
= 0;
984 static wxWindowID s_id
= 0;
986 if (s_id
!= event
.GetId() && s_eventType
!= event
.GetEventType())
988 s_eventType
= event
.GetEventType();
989 s_id
= event
.GetId();
991 wxWindow
* focusWin
= wxFindFocusDescendant(this);
992 if (focusWin
&& focusWin
->GetEventHandler()->ProcessEvent(event
))
1009 return wxFrame::ProcessEvent(event
);
1012 void MyFrame::OnOpen(wxCommandEvent
& WXUNUSED(event
))
1016 wxArrayInt fileTypes
;
1018 wxString filter
= wxRichTextBuffer::GetExtWildcard(false, false, & fileTypes
);
1019 if (!filter
.empty())
1021 filter
+= wxT("All files (*.*)|*.*");
1023 wxFileDialog
dialog(this,
1024 _("Choose a filename"),
1030 if (dialog
.ShowModal() == wxID_OK
)
1032 wxString path
= dialog
.GetPath();
1036 int filterIndex
= dialog
.GetFilterIndex();
1037 int fileType
= (filterIndex
< (int) fileTypes
.GetCount())
1038 ? fileTypes
[filterIndex
]
1039 : wxRICHTEXT_TYPE_TEXT
;
1040 m_richTextCtrl
->LoadFile(path
, fileType
);
1045 void MyFrame::OnSave(wxCommandEvent
& event
)
1047 if (m_richTextCtrl
->GetFilename().empty())
1052 m_richTextCtrl
->SaveFile();
1055 void MyFrame::OnSaveAs(wxCommandEvent
& WXUNUSED(event
))
1057 wxString filter
= wxRichTextBuffer::GetExtWildcard(false, true);
1061 wxFileDialog
dialog(this,
1062 _("Choose a filename"),
1068 if (dialog
.ShowModal() == wxID_OK
)
1070 wxString path
= dialog
.GetPath();
1074 m_richTextCtrl
->SaveFile(path
);
1079 void MyFrame::OnBold(wxCommandEvent
& WXUNUSED(event
))
1081 m_richTextCtrl
->ApplyBoldToSelection();
1084 void MyFrame::OnItalic(wxCommandEvent
& WXUNUSED(event
))
1086 m_richTextCtrl
->ApplyItalicToSelection();
1089 void MyFrame::OnUnderline(wxCommandEvent
& WXUNUSED(event
))
1091 m_richTextCtrl
->ApplyUnderlineToSelection();
1095 void MyFrame::OnUpdateBold(wxUpdateUIEvent
& event
)
1097 event
.Check(m_richTextCtrl
->IsSelectionBold());
1100 void MyFrame::OnUpdateItalic(wxUpdateUIEvent
& event
)
1102 event
.Check(m_richTextCtrl
->IsSelectionItalics());
1105 void MyFrame::OnUpdateUnderline(wxUpdateUIEvent
& event
)
1107 event
.Check(m_richTextCtrl
->IsSelectionUnderlined());
1110 void MyFrame::OnAlignLeft(wxCommandEvent
& WXUNUSED(event
))
1112 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_LEFT
);
1115 void MyFrame::OnAlignCentre(wxCommandEvent
& WXUNUSED(event
))
1117 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_CENTRE
);
1120 void MyFrame::OnAlignRight(wxCommandEvent
& WXUNUSED(event
))
1122 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_RIGHT
);
1125 void MyFrame::OnUpdateAlignLeft(wxUpdateUIEvent
& event
)
1127 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_LEFT
));
1130 void MyFrame::OnUpdateAlignCentre(wxUpdateUIEvent
& event
)
1132 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_CENTRE
));
1135 void MyFrame::OnUpdateAlignRight(wxUpdateUIEvent
& event
)
1137 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_RIGHT
));
1140 void MyFrame::OnFont(wxCommandEvent
& WXUNUSED(event
))
1142 wxRichTextRange range
;
1143 if (m_richTextCtrl
->HasSelection())
1144 range
= m_richTextCtrl
->GetSelectionRange();
1146 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1148 int pages
= wxRICHTEXT_FORMAT_FONT
;
1150 wxRichTextFormattingDialog
formatDlg(pages
, this);
1151 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1153 if (formatDlg
.ShowModal() == wxID_OK
)
1155 formatDlg
.ApplyStyle(m_richTextCtrl
, range
, wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_OPTIMIZE
|wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY
);
1158 // Old method using wxFontDialog
1160 if (!m_richTextCtrl
->HasSelection())
1163 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1164 wxFontData fontData
;
1166 wxRichTextAttr attr
;
1167 attr
.SetFlags(wxTEXT_ATTR_FONT
);
1169 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1170 fontData
.SetInitialFont(attr
.GetFont());
1172 wxFontDialog
dialog(this, fontData
);
1173 if (dialog
.ShowModal() == wxID_OK
)
1175 fontData
= dialog
.GetFontData();
1176 attr
.SetFlags(wxTEXT_ATTR_FONT
);
1177 attr
.SetFont(fontData
.GetChosenFont());
1178 if (attr
.GetFont().Ok())
1180 m_richTextCtrl
->SetStyle(range
, attr
);
1186 void MyFrame::OnImage(wxCommandEvent
& WXUNUSED(event
))
1188 wxRichTextRange range
;
1189 wxASSERT(m_richTextCtrl
->HasSelection());
1191 range
= m_richTextCtrl
->GetSelectionRange();
1192 wxASSERT(range
.ToInternal().GetLength() == 1);
1194 wxRichTextImage
* image
= wxDynamicCast(m_richTextCtrl
->GetBuffer().GetLeafObjectAtPosition(range
.GetStart()), wxRichTextImage
);
1197 wxRichTextImageDialog
imageDlg(this);
1198 imageDlg
.SetImageObject(image
, &m_richTextCtrl
->GetBuffer());
1200 if (imageDlg
.ShowModal() == wxID_OK
)
1202 image
= imageDlg
.ApplyImageAttr();
1207 void MyFrame::OnParagraph(wxCommandEvent
& WXUNUSED(event
))
1209 wxRichTextRange range
;
1210 if (m_richTextCtrl
->HasSelection())
1211 range
= m_richTextCtrl
->GetSelectionRange();
1213 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1215 int pages
= wxRICHTEXT_FORMAT_INDENTS_SPACING
|wxRICHTEXT_FORMAT_TABS
|wxRICHTEXT_FORMAT_BULLETS
;
1217 wxRichTextFormattingDialog
formatDlg(pages
, this);
1218 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1220 if (formatDlg
.ShowModal() == wxID_OK
)
1222 formatDlg
.ApplyStyle(m_richTextCtrl
, range
);
1226 void MyFrame::OnFormat(wxCommandEvent
& WXUNUSED(event
))
1228 wxRichTextRange range
;
1229 if (m_richTextCtrl
->HasSelection())
1230 range
= m_richTextCtrl
->GetSelectionRange();
1232 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1234 int pages
= wxRICHTEXT_FORMAT_FONT
|wxRICHTEXT_FORMAT_INDENTS_SPACING
|wxRICHTEXT_FORMAT_TABS
|wxRICHTEXT_FORMAT_BULLETS
;
1236 wxRichTextFormattingDialog
formatDlg(pages
, this);
1237 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1239 if (formatDlg
.ShowModal() == wxID_OK
)
1241 formatDlg
.ApplyStyle(m_richTextCtrl
, range
);
1245 void MyFrame::OnUpdateFormat(wxUpdateUIEvent
& event
)
1247 event
.Enable(m_richTextCtrl
->HasSelection());
1250 void MyFrame::OnUpdateImage(wxUpdateUIEvent
& event
)
1252 wxRichTextRange range
;
1253 wxRichTextObject
*obj
;
1255 range
= m_richTextCtrl
->GetSelectionRange();
1256 if (range
.ToInternal().GetLength() == 1)
1258 obj
= m_richTextCtrl
->GetBuffer().GetLeafObjectAtPosition(range
.GetStart());
1259 if (obj
&& obj
->IsKindOf(CLASSINFO(wxRichTextImage
)))
1266 event
.Enable(false);
1269 void MyFrame::OnIndentMore(wxCommandEvent
& WXUNUSED(event
))
1271 wxRichTextAttr attr
;
1272 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1274 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1276 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1277 if (m_richTextCtrl
->HasSelection())
1278 range
= m_richTextCtrl
->GetSelectionRange();
1280 attr
.SetLeftIndent(attr
.GetLeftIndent() + 100);
1282 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1283 m_richTextCtrl
->SetStyle(range
, attr
);
1287 void MyFrame::OnIndentLess(wxCommandEvent
& WXUNUSED(event
))
1289 wxRichTextAttr attr
;
1290 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1292 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1294 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1295 if (m_richTextCtrl
->HasSelection())
1296 range
= m_richTextCtrl
->GetSelectionRange();
1298 if (attr
.GetLeftIndent() > 0)
1300 attr
.SetLeftIndent(wxMax(0, attr
.GetLeftIndent() - 100));
1302 m_richTextCtrl
->SetStyle(range
, attr
);
1307 void MyFrame::OnLineSpacingHalf(wxCommandEvent
& WXUNUSED(event
))
1309 wxRichTextAttr attr
;
1310 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1312 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1314 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1315 if (m_richTextCtrl
->HasSelection())
1316 range
= m_richTextCtrl
->GetSelectionRange();
1318 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1319 attr
.SetLineSpacing(15);
1321 m_richTextCtrl
->SetStyle(range
, attr
);
1325 void MyFrame::OnLineSpacingDouble(wxCommandEvent
& WXUNUSED(event
))
1327 wxRichTextAttr attr
;
1328 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1330 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1332 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1333 if (m_richTextCtrl
->HasSelection())
1334 range
= m_richTextCtrl
->GetSelectionRange();
1336 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1337 attr
.SetLineSpacing(20);
1339 m_richTextCtrl
->SetStyle(range
, attr
);
1343 void MyFrame::OnLineSpacingSingle(wxCommandEvent
& WXUNUSED(event
))
1345 wxRichTextAttr attr
;
1346 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1348 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1350 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1351 if (m_richTextCtrl
->HasSelection())
1352 range
= m_richTextCtrl
->GetSelectionRange();
1354 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1355 attr
.SetLineSpacing(0); // Can also use 10
1357 m_richTextCtrl
->SetStyle(range
, attr
);
1361 void MyFrame::OnParagraphSpacingMore(wxCommandEvent
& WXUNUSED(event
))
1363 wxRichTextAttr attr
;
1364 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1366 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1368 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1369 if (m_richTextCtrl
->HasSelection())
1370 range
= m_richTextCtrl
->GetSelectionRange();
1372 attr
.SetParagraphSpacingAfter(attr
.GetParagraphSpacingAfter() + 20);
1374 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1375 m_richTextCtrl
->SetStyle(range
, attr
);
1379 void MyFrame::OnParagraphSpacingLess(wxCommandEvent
& WXUNUSED(event
))
1381 wxRichTextAttr attr
;
1382 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1384 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1386 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1387 if (m_richTextCtrl
->HasSelection())
1388 range
= m_richTextCtrl
->GetSelectionRange();
1390 if (attr
.GetParagraphSpacingAfter() >= 20)
1392 attr
.SetParagraphSpacingAfter(attr
.GetParagraphSpacingAfter() - 20);
1394 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1395 m_richTextCtrl
->SetStyle(range
, attr
);
1400 void MyFrame::OnReload(wxCommandEvent
& WXUNUSED(event
))
1402 m_richTextCtrl
->Clear();
1406 void MyFrame::OnViewHTML(wxCommandEvent
& WXUNUSED(event
))
1408 wxDialog
dialog(this, wxID_ANY
, _("HTML"), wxDefaultPosition
, wxSize(500, 400), wxDEFAULT_DIALOG_STYLE
);
1410 wxBoxSizer
* boxSizer
= new wxBoxSizer(wxVERTICAL
);
1411 dialog
.SetSizer(boxSizer
);
1413 wxHtmlWindow
* win
= new wxHtmlWindow(& dialog
, wxID_ANY
, wxDefaultPosition
, wxSize(500, 400), wxSUNKEN_BORDER
);
1414 boxSizer
->Add(win
, 1, wxALL
, 5);
1416 wxButton
* cancelButton
= new wxButton(& dialog
, wxID_CANCEL
, wxT("&Close"));
1417 boxSizer
->Add(cancelButton
, 0, wxALL
|wxCENTRE
, 5);
1420 wxStringOutputStream
strStream(& text
);
1422 wxRichTextHTMLHandler htmlHandler
;
1423 htmlHandler
.SetFlags(wxRICHTEXT_HANDLER_SAVE_IMAGES_TO_MEMORY
);
1425 wxArrayInt fontSizeMapping
;
1426 fontSizeMapping
.Add(7);
1427 fontSizeMapping
.Add(9);
1428 fontSizeMapping
.Add(11);
1429 fontSizeMapping
.Add(12);
1430 fontSizeMapping
.Add(14);
1431 fontSizeMapping
.Add(22);
1432 fontSizeMapping
.Add(100);
1434 htmlHandler
.SetFontSizeMapping(fontSizeMapping
);
1436 if (htmlHandler
.SaveFile(& m_richTextCtrl
->GetBuffer(), strStream
))
1441 boxSizer
->Fit(& dialog
);
1445 // Now delete the temporary in-memory images
1446 htmlHandler
.DeleteTemporaryImages();
1449 // Demonstrates how you can change the style sheets and have the changes
1450 // reflected in the control content without wiping out character formatting.
1452 void MyFrame::OnSwitchStyleSheets(wxCommandEvent
& WXUNUSED(event
))
1454 static wxRichTextStyleSheet
* gs_AlternateStyleSheet
= NULL
;
1456 wxRichTextStyleListCtrl
*styleList
= (wxRichTextStyleListCtrl
*) FindWindow(ID_RICHTEXT_STYLE_LIST
);
1457 wxRichTextStyleComboCtrl
* styleCombo
= (wxRichTextStyleComboCtrl
*) FindWindow(ID_RICHTEXT_STYLE_COMBO
);
1459 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1461 // One-time creation of an alternate style sheet
1462 if (!gs_AlternateStyleSheet
)
1464 gs_AlternateStyleSheet
= new wxRichTextStyleSheet(*sheet
);
1466 // Make some modifications
1467 for (int i
= 0; i
< (int) gs_AlternateStyleSheet
->GetParagraphStyleCount(); i
++)
1469 wxRichTextParagraphStyleDefinition
* def
= gs_AlternateStyleSheet
->GetParagraphStyle(i
);
1471 if (def
->GetStyle().HasTextColour())
1472 def
->GetStyle().SetTextColour(*wxBLUE
);
1474 if (def
->GetStyle().HasAlignment())
1476 if (def
->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_CENTRE
)
1477 def
->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_RIGHT
);
1478 else if (def
->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_LEFT
)
1479 def
->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_CENTRE
);
1481 if (def
->GetStyle().HasLeftIndent())
1483 def
->GetStyle().SetLeftIndent(def
->GetStyle().GetLeftIndent() * 2);
1489 wxRichTextStyleSheet
* tmp
= gs_AlternateStyleSheet
;
1490 gs_AlternateStyleSheet
= sheet
;
1493 m_richTextCtrl
->SetStyleSheet(sheet
);
1494 m_richTextCtrl
->ApplyStyleSheet(sheet
); // Makes the control reflect the new style definitions
1496 styleList
->SetStyleSheet(sheet
);
1497 styleList
->UpdateStyles();
1499 styleCombo
->SetStyleSheet(sheet
);
1500 styleCombo
->UpdateStyles();
1503 void MyFrame::OnManageStyles(wxCommandEvent
& WXUNUSED(event
))
1505 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1507 int flags
= wxRICHTEXT_ORGANISER_CREATE_STYLES
|wxRICHTEXT_ORGANISER_EDIT_STYLES
;
1509 wxRichTextStyleOrganiserDialog
dlg(flags
, sheet
, NULL
, this, wxID_ANY
, _("Style Manager"));
1513 void MyFrame::OnInsertSymbol(wxCommandEvent
& WXUNUSED(event
))
1515 wxRichTextAttr attr
;
1516 attr
.SetFlags(wxTEXT_ATTR_FONT
);
1517 m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
);
1519 wxString currentFontName
;
1520 if (attr
.HasFont() && attr
.GetFont().Ok())
1521 currentFontName
= attr
.GetFont().GetFaceName();
1523 // Don't set the initial font in the dialog (so the user is choosing
1524 // 'normal text', i.e. the current font) but do tell the dialog
1525 // what 'normal text' is.
1527 wxSymbolPickerDialog
dlg(wxT("*"), wxEmptyString
, currentFontName
, this);
1529 if (dlg
.ShowModal() == wxID_OK
)
1531 if (dlg
.HasSelection())
1533 long insertionPoint
= m_richTextCtrl
->GetInsertionPoint();
1535 m_richTextCtrl
->WriteText(dlg
.GetSymbol());
1537 if (!dlg
.UseNormalFont())
1539 wxFont
font(attr
.GetFont());
1540 font
.SetFaceName(dlg
.GetFontName());
1542 m_richTextCtrl
->SetStyle(insertionPoint
, insertionPoint
+1, attr
);
1548 void MyFrame::OnNumberList(wxCommandEvent
& WXUNUSED(event
))
1550 if (m_richTextCtrl
->HasSelection())
1552 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1553 m_richTextCtrl
->SetListStyle(range
, wxT("Numbered List 1"), wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_RENUMBER
);
1557 void MyFrame::OnBulletsAndNumbering(wxCommandEvent
& WXUNUSED(event
))
1559 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1561 int flags
= wxRICHTEXT_ORGANISER_BROWSE_NUMBERING
;
1563 wxRichTextStyleOrganiserDialog
dlg(flags
, sheet
, m_richTextCtrl
, this, wxID_ANY
, _("Bullets and Numbering"));
1564 if (dlg
.ShowModal() == wxID_OK
)
1566 if (dlg
.GetSelectedStyleDefinition())
1571 void MyFrame::OnItemizeList(wxCommandEvent
& WXUNUSED(event
))
1573 if (m_richTextCtrl
->HasSelection())
1575 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1576 m_richTextCtrl
->SetListStyle(range
, wxT("Bullet List 1"));
1580 void MyFrame::OnRenumberList(wxCommandEvent
& WXUNUSED(event
))
1582 if (m_richTextCtrl
->HasSelection())
1584 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1585 m_richTextCtrl
->NumberList(range
, NULL
, wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_RENUMBER
);
1589 void MyFrame::OnPromoteList(wxCommandEvent
& WXUNUSED(event
))
1591 if (m_richTextCtrl
->HasSelection())
1593 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1594 m_richTextCtrl
->PromoteList(1, range
, NULL
);
1598 void MyFrame::OnDemoteList(wxCommandEvent
& WXUNUSED(event
))
1600 if (m_richTextCtrl
->HasSelection())
1602 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1603 m_richTextCtrl
->PromoteList(-1, range
, NULL
);
1607 void MyFrame::OnClearList(wxCommandEvent
& WXUNUSED(event
))
1609 if (m_richTextCtrl
->HasSelection())
1611 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1612 m_richTextCtrl
->ClearListStyle(range
);
1616 void MyFrame::OnInsertURL(wxCommandEvent
& WXUNUSED(event
))
1618 wxString url
= wxGetTextFromUser(_("URL:"), _("Insert URL"));
1621 // Make a style suitable for showing a URL
1622 wxRichTextAttr urlStyle
;
1623 urlStyle
.SetTextColour(*wxBLUE
);
1624 urlStyle
.SetFontUnderlined(true);
1626 m_richTextCtrl
->BeginStyle(urlStyle
);
1627 m_richTextCtrl
->BeginURL(url
);
1628 m_richTextCtrl
->WriteText(url
);
1629 m_richTextCtrl
->EndURL();
1630 m_richTextCtrl
->EndStyle();
1634 void MyFrame::OnInsertImage(wxCommandEvent
& WXUNUSED(event
))
1636 wxFileDialog
dialog(this, _("Choose an image"), "", "", "BMP and GIF files (*.bmp;*.gif)|*.bmp;*.gif|PNG files (*.png)|*.png");
1637 if (dialog
.ShowModal() == wxID_OK
)
1639 wxString path
= dialog
.GetPath();
1640 m_richTextCtrl
->WriteImage(path
, wxBITMAP_TYPE_ANY
);
1644 void MyFrame::OnURL(wxTextUrlEvent
& event
)
1646 wxMessageBox(event
.GetString());
1649 // Veto style sheet replace events when loading from XML, since we want
1650 // to keep the original style sheet.
1651 void MyFrame::OnStyleSheetReplacing(wxRichTextEvent
& event
)
1656 void MyFrame::OnPrint(wxCommandEvent
& WXUNUSED(event
))
1658 wxGetApp().GetPrinting()->PrintBuffer(m_richTextCtrl
->GetBuffer());
1661 void MyFrame::OnPreview(wxCommandEvent
& WXUNUSED(event
))
1663 wxGetApp().GetPrinting()->PreviewBuffer(m_richTextCtrl
->GetBuffer());
1666 void MyFrame::OnPageSetup(wxCommandEvent
& WXUNUSED(event
))
1668 wxDialog
dialog(this, wxID_ANY
, wxT("Testing"), wxPoint(10, 10), wxSize(400, 300), wxDEFAULT_DIALOG_STYLE
);
1670 wxNotebook
* nb
= new wxNotebook(& dialog
, wxID_ANY
, wxPoint(5, 5), wxSize(300, 250));
1671 wxPanel
* panel
= new wxPanel(nb
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
);
1672 wxPanel
* panel2
= new wxPanel(nb
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
);
1674 new wxRichTextCtrl(panel
, wxID_ANY
, wxEmptyString
, wxPoint(5, 5), wxSize(200, 150), wxVSCROLL
|wxTE_READONLY
);
1675 nb
->AddPage(panel
, wxT("Page 1"));
1677 new wxRichTextCtrl(panel2
, wxID_ANY
, wxEmptyString
, wxPoint(5, 5), wxSize(200, 150), wxVSCROLL
|wxTE_READONLY
);
1678 nb
->AddPage(panel2
, wxT("Page 2"));
1680 new wxButton(& dialog
, wxID_OK
, wxT("OK"), wxPoint(5, 180));
1684 // wxGetApp().GetPrinting()->PageSetup();