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/cshelp.h"
43 #include "../sample.xpm"
46 #include "bitmaps/smiley.xpm"
47 // #include "bitmaps/idea.xpm"
48 #include "bitmaps/zebra.xpm"
50 #include "bitmaps/open.xpm"
51 #include "bitmaps/save.xpm"
52 #include "bitmaps/copy.xpm"
53 #include "bitmaps/cut.xpm"
54 #include "bitmaps/paste.xpm"
55 #include "bitmaps/undo.xpm"
56 #include "bitmaps/redo.xpm"
57 #include "bitmaps/bold.xpm"
58 #include "bitmaps/italic.xpm"
59 #include "bitmaps/underline.xpm"
61 #include "bitmaps/alignleft.xpm"
62 #include "bitmaps/alignright.xpm"
63 #include "bitmaps/centre.xpm"
64 #include "bitmaps/font.xpm"
65 #include "bitmaps/indentless.xpm"
66 #include "bitmaps/indentmore.xpm"
68 #include "wx/richtext/richtextctrl.h"
69 #include "wx/richtext/richtextstyles.h"
70 #include "wx/richtext/richtextxml.h"
71 #include "wx/richtext/richtexthtml.h"
72 #include "wx/richtext/richtextformatdlg.h"
73 #include "wx/richtext/richtextsymboldlg.h"
74 #include "wx/richtext/richtextstyledlg.h"
76 // ----------------------------------------------------------------------------
78 // ----------------------------------------------------------------------------
80 // ----------------------------------------------------------------------------
82 // ----------------------------------------------------------------------------
84 // Define a new application type, each program should derive a class from wxApp
85 class MyApp
: public wxApp
88 // override base class virtuals
89 // ----------------------------
91 // this one is called on application startup and is a good place for the app
92 // initialization (doing it here and not in the ctor allows to have an error
93 // return: if OnInit() returns false, the application terminates)
94 virtual bool OnInit();
99 wxRichTextStyleSheet
* GetStyleSheet() const { return m_styleSheet
; }
101 wxRichTextStyleSheet
* m_styleSheet
;
104 // Define a new frame type: this is going to be our main frame
105 class MyFrame
: public wxFrame
109 MyFrame(const wxString
& title
, wxWindowID id
, const wxPoint
& pos
= wxDefaultPosition
,
110 const wxSize
& size
= wxDefaultSize
, long style
= wxDEFAULT_FRAME_STYLE
);
112 // event handlers (these functions should _not_ be virtual)
113 void OnQuit(wxCommandEvent
& event
);
114 void OnAbout(wxCommandEvent
& event
);
116 void OnOpen(wxCommandEvent
& event
);
117 void OnSave(wxCommandEvent
& event
);
118 void OnSaveAs(wxCommandEvent
& event
);
120 void OnBold(wxCommandEvent
& event
);
121 void OnItalic(wxCommandEvent
& event
);
122 void OnUnderline(wxCommandEvent
& event
);
124 void OnUpdateBold(wxUpdateUIEvent
& event
);
125 void OnUpdateItalic(wxUpdateUIEvent
& event
);
126 void OnUpdateUnderline(wxUpdateUIEvent
& event
);
128 void OnAlignLeft(wxCommandEvent
& event
);
129 void OnAlignCentre(wxCommandEvent
& event
);
130 void OnAlignRight(wxCommandEvent
& event
);
132 void OnUpdateAlignLeft(wxUpdateUIEvent
& event
);
133 void OnUpdateAlignCentre(wxUpdateUIEvent
& event
);
134 void OnUpdateAlignRight(wxUpdateUIEvent
& event
);
136 void OnIndentMore(wxCommandEvent
& event
);
137 void OnIndentLess(wxCommandEvent
& event
);
139 void OnFont(wxCommandEvent
& event
);
140 void OnParagraph(wxCommandEvent
& event
);
141 void OnFormat(wxCommandEvent
& event
);
142 void OnUpdateFormat(wxUpdateUIEvent
& event
);
144 void OnInsertSymbol(wxCommandEvent
& event
);
146 void OnLineSpacingHalf(wxCommandEvent
& event
);
147 void OnLineSpacingDouble(wxCommandEvent
& event
);
148 void OnLineSpacingSingle(wxCommandEvent
& event
);
150 void OnParagraphSpacingMore(wxCommandEvent
& event
);
151 void OnParagraphSpacingLess(wxCommandEvent
& event
);
153 void OnNumberList(wxCommandEvent
& event
);
154 void OnBulletsAndNumbering(wxCommandEvent
& event
);
155 void OnItemizeList(wxCommandEvent
& event
);
156 void OnRenumberList(wxCommandEvent
& event
);
157 void OnPromoteList(wxCommandEvent
& event
);
158 void OnDemoteList(wxCommandEvent
& event
);
159 void OnClearList(wxCommandEvent
& event
);
161 void OnViewHTML(wxCommandEvent
& event
);
163 void OnSwitchStyleSheets(wxCommandEvent
& event
);
164 void OnManageStyles(wxCommandEvent
& event
);
166 // Forward command events to the current rich text control, if any
167 bool ProcessEvent(wxEvent
& event
);
170 // any class wishing to process wxWidgets events must use this macro
171 DECLARE_EVENT_TABLE()
173 wxRichTextCtrl
* m_richTextCtrl
;
176 // ----------------------------------------------------------------------------
178 // ----------------------------------------------------------------------------
180 // IDs for the controls and the menu commands
185 ID_About
= wxID_ABOUT
,
187 ID_FORMAT_BOLD
= 100,
196 ID_FORMAT_ALIGN_LEFT
,
197 ID_FORMAT_ALIGN_CENTRE
,
198 ID_FORMAT_ALIGN_RIGHT
,
200 ID_FORMAT_INDENT_MORE
,
201 ID_FORMAT_INDENT_LESS
,
203 ID_FORMAT_PARAGRAPH_SPACING_MORE
,
204 ID_FORMAT_PARAGRAPH_SPACING_LESS
,
206 ID_FORMAT_LINE_SPACING_HALF
,
207 ID_FORMAT_LINE_SPACING_DOUBLE
,
208 ID_FORMAT_LINE_SPACING_SINGLE
,
210 ID_FORMAT_NUMBER_LIST
,
211 ID_FORMAT_BULLETS_AND_NUMBERING
,
212 ID_FORMAT_ITEMIZE_LIST
,
213 ID_FORMAT_RENUMBER_LIST
,
214 ID_FORMAT_PROMOTE_LIST
,
215 ID_FORMAT_DEMOTE_LIST
,
216 ID_FORMAT_CLEAR_LIST
,
219 ID_SWITCH_STYLE_SHEETS
,
223 ID_RICHTEXT_STYLE_LIST
,
224 ID_RICHTEXT_STYLE_COMBO
227 // ----------------------------------------------------------------------------
228 // event tables and other macros for wxWidgets
229 // ----------------------------------------------------------------------------
231 // the event tables connect the wxWidgets events with the functions (event
232 // handlers) which process them. It can be also done at run-time, but for the
233 // simple menu events like this the static method is much simpler.
234 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
235 EVT_MENU(ID_Quit
, MyFrame::OnQuit
)
236 EVT_MENU(ID_About
, MyFrame::OnAbout
)
238 EVT_MENU(wxID_OPEN
, MyFrame::OnOpen
)
239 EVT_MENU(wxID_SAVE
, MyFrame::OnSave
)
240 EVT_MENU(wxID_SAVEAS
, MyFrame::OnSaveAs
)
242 EVT_MENU(ID_FORMAT_BOLD
, MyFrame::OnBold
)
243 EVT_MENU(ID_FORMAT_ITALIC
, MyFrame::OnItalic
)
244 EVT_MENU(ID_FORMAT_UNDERLINE
, MyFrame::OnUnderline
)
246 EVT_UPDATE_UI(ID_FORMAT_BOLD
, MyFrame::OnUpdateBold
)
247 EVT_UPDATE_UI(ID_FORMAT_ITALIC
, MyFrame::OnUpdateItalic
)
248 EVT_UPDATE_UI(ID_FORMAT_UNDERLINE
, MyFrame::OnUpdateUnderline
)
250 EVT_MENU(ID_FORMAT_ALIGN_LEFT
, MyFrame::OnAlignLeft
)
251 EVT_MENU(ID_FORMAT_ALIGN_CENTRE
, MyFrame::OnAlignCentre
)
252 EVT_MENU(ID_FORMAT_ALIGN_RIGHT
, MyFrame::OnAlignRight
)
254 EVT_UPDATE_UI(ID_FORMAT_ALIGN_LEFT
, MyFrame::OnUpdateAlignLeft
)
255 EVT_UPDATE_UI(ID_FORMAT_ALIGN_CENTRE
, MyFrame::OnUpdateAlignCentre
)
256 EVT_UPDATE_UI(ID_FORMAT_ALIGN_RIGHT
, MyFrame::OnUpdateAlignRight
)
258 EVT_MENU(ID_FORMAT_FONT
, MyFrame::OnFont
)
259 EVT_MENU(ID_FORMAT_PARAGRAPH
, MyFrame::OnParagraph
)
260 EVT_MENU(ID_FORMAT_CONTENT
, MyFrame::OnFormat
)
261 EVT_UPDATE_UI(ID_FORMAT_CONTENT
, MyFrame::OnUpdateFormat
)
262 EVT_UPDATE_UI(ID_FORMAT_FONT
, MyFrame::OnUpdateFormat
)
263 EVT_UPDATE_UI(ID_FORMAT_PARAGRAPH
, MyFrame::OnUpdateFormat
)
264 EVT_MENU(ID_FORMAT_INDENT_MORE
, MyFrame::OnIndentMore
)
265 EVT_MENU(ID_FORMAT_INDENT_LESS
, MyFrame::OnIndentLess
)
267 EVT_MENU(ID_FORMAT_LINE_SPACING_HALF
, MyFrame::OnLineSpacingHalf
)
268 EVT_MENU(ID_FORMAT_LINE_SPACING_SINGLE
, MyFrame::OnLineSpacingSingle
)
269 EVT_MENU(ID_FORMAT_LINE_SPACING_DOUBLE
, MyFrame::OnLineSpacingDouble
)
271 EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_MORE
, MyFrame::OnParagraphSpacingMore
)
272 EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_LESS
, MyFrame::OnParagraphSpacingLess
)
274 EVT_MENU(ID_INSERT_SYMBOL
, MyFrame::OnInsertSymbol
)
276 EVT_MENU(ID_FORMAT_NUMBER_LIST
, MyFrame::OnNumberList
)
277 EVT_MENU(ID_FORMAT_BULLETS_AND_NUMBERING
, MyFrame::OnBulletsAndNumbering
)
278 EVT_MENU(ID_FORMAT_ITEMIZE_LIST
, MyFrame::OnItemizeList
)
279 EVT_MENU(ID_FORMAT_RENUMBER_LIST
, MyFrame::OnRenumberList
)
280 EVT_MENU(ID_FORMAT_PROMOTE_LIST
, MyFrame::OnPromoteList
)
281 EVT_MENU(ID_FORMAT_DEMOTE_LIST
, MyFrame::OnDemoteList
)
282 EVT_MENU(ID_FORMAT_CLEAR_LIST
, MyFrame::OnClearList
)
284 EVT_MENU(ID_VIEW_HTML
, MyFrame::OnViewHTML
)
285 EVT_MENU(ID_SWITCH_STYLE_SHEETS
, MyFrame::OnSwitchStyleSheets
)
286 EVT_MENU(ID_MANAGE_STYLES
, MyFrame::OnManageStyles
)
289 // Create a new application object: this macro will allow wxWidgets to create
290 // the application object during program execution (it's better than using a
291 // static object for many reasons) and also implements the accessor function
292 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
296 // ============================================================================
298 // ============================================================================
300 // ----------------------------------------------------------------------------
301 // the application class
302 // ----------------------------------------------------------------------------
304 // 'Main program' equivalent: the program execution "starts" here
308 wxHelpProvider::Set(new wxSimpleHelpProvider
);
311 m_styleSheet
= new wxRichTextStyleSheet
;
315 // Add extra handlers (plain text is automatically added)
316 wxRichTextBuffer::AddHandler(new wxRichTextXMLHandler
);
317 wxRichTextBuffer::AddHandler(new wxRichTextHTMLHandler
);
319 // Add image handlers
321 wxImage::AddHandler( new wxPNGHandler
);
325 wxImage::AddHandler( new wxJPEGHandler
);
329 wxImage::AddHandler( new wxGIFHandler
);
332 // create the main application window
333 MyFrame
*frame
= new MyFrame(_T("wxRichTextCtrl Sample"), wxID_ANY
, wxDefaultPosition
, wxSize(700, 600));
335 // and show it (the frames, unlike simple controls, are not shown when
336 // created initially)
339 // success: wxApp::OnRun() will be called which will enter the main message
340 // loop and the application will run. If we returned false here, the
341 // application would exit immediately.
351 void MyApp::CreateStyles()
355 wxFont
romanFont(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
356 wxFont
swissFont(12, wxSWISS
, wxNORMAL
, wxNORMAL
);
358 wxRichTextParagraphStyleDefinition
* normalPara
= new wxRichTextParagraphStyleDefinition(wxT("Normal"));
359 wxRichTextAttr normalAttr
;
360 normalAttr
.SetFontFaceName(romanFont
.GetFaceName());
361 normalAttr
.SetFontSize(12);
362 // Let's set all attributes for this style
363 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
|
364 wxTEXT_ATTR_PARA_SPACING_BEFORE
|wxTEXT_ATTR_PARA_SPACING_AFTER
|wxTEXT_ATTR_LINE_SPACING
|
365 wxTEXT_ATTR_BULLET_STYLE
|wxTEXT_ATTR_BULLET_NUMBER
);
366 normalPara
->SetStyle(normalAttr
);
368 m_styleSheet
->AddParagraphStyle(normalPara
);
370 wxRichTextParagraphStyleDefinition
* indentedPara
= new wxRichTextParagraphStyleDefinition(wxT("Indented"));
371 wxRichTextAttr indentedAttr
;
372 indentedAttr
.SetFontFaceName(romanFont
.GetFaceName());
373 indentedAttr
.SetFontSize(12);
374 indentedAttr
.SetLeftIndent(100, 0);
375 // We only want to affect indentation
376 indentedAttr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
);
377 indentedPara
->SetStyle(indentedAttr
);
379 m_styleSheet
->AddParagraphStyle(indentedPara
);
381 wxRichTextParagraphStyleDefinition
* indentedPara2
= new wxRichTextParagraphStyleDefinition(wxT("Red Bold Indented"));
382 wxRichTextAttr indentedAttr2
;
383 indentedAttr2
.SetFontFaceName(romanFont
.GetFaceName());
384 indentedAttr2
.SetFontSize(12);
385 indentedAttr2
.SetFontWeight(wxBOLD
);
386 indentedAttr2
.SetTextColour(*wxRED
);
387 indentedAttr2
.SetFontSize(12);
388 indentedAttr2
.SetLeftIndent(100, 0);
389 // We want to affect indentation, font and text colour
390 indentedAttr2
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
|wxTEXT_ATTR_FONT
|wxTEXT_ATTR_TEXT_COLOUR
);
391 indentedPara2
->SetStyle(indentedAttr2
);
393 m_styleSheet
->AddParagraphStyle(indentedPara2
);
395 wxRichTextParagraphStyleDefinition
* flIndentedPara
= new wxRichTextParagraphStyleDefinition(wxT("First Line Indented"));
396 wxRichTextAttr flIndentedAttr
;
397 flIndentedAttr
.SetFontFaceName(swissFont
.GetFaceName());
398 flIndentedAttr
.SetFontSize(12);
399 flIndentedAttr
.SetLeftIndent(100, -100);
400 // We only want to affect indentation
401 flIndentedAttr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
);
402 flIndentedPara
->SetStyle(flIndentedAttr
);
404 m_styleSheet
->AddParagraphStyle(flIndentedPara
);
408 wxRichTextCharacterStyleDefinition
* boldDef
= new wxRichTextCharacterStyleDefinition(wxT("Bold"));
409 wxRichTextAttr boldAttr
;
410 boldAttr
.SetFontFaceName(romanFont
.GetFaceName());
411 boldAttr
.SetFontSize(12);
412 boldAttr
.SetFontWeight(wxBOLD
);
413 // We only want to affect boldness
414 boldAttr
.SetFlags(wxTEXT_ATTR_FONT_WEIGHT
);
415 boldDef
->SetStyle(boldAttr
);
417 m_styleSheet
->AddCharacterStyle(boldDef
);
419 wxRichTextCharacterStyleDefinition
* italicDef
= new wxRichTextCharacterStyleDefinition(wxT("Italic"));
420 wxRichTextAttr italicAttr
;
421 italicAttr
.SetFontFaceName(romanFont
.GetFaceName());
422 italicAttr
.SetFontSize(12);
423 italicAttr
.SetFontStyle(wxITALIC
);
424 // We only want to affect italics
425 italicAttr
.SetFlags(wxTEXT_ATTR_FONT_ITALIC
);
426 italicDef
->SetStyle(italicAttr
);
428 m_styleSheet
->AddCharacterStyle(italicDef
);
430 wxRichTextCharacterStyleDefinition
* redDef
= new wxRichTextCharacterStyleDefinition(wxT("Red Bold"));
431 wxRichTextAttr redAttr
;
432 redAttr
.SetFontFaceName(romanFont
.GetFaceName());
433 redAttr
.SetFontSize(12);
434 redAttr
.SetFontWeight(wxBOLD
);
435 redAttr
.SetTextColour(*wxRED
);
436 // We only want to affect colour, weight and face
437 redAttr
.SetFlags(wxTEXT_ATTR_FONT_FACE
|wxTEXT_ATTR_FONT_WEIGHT
|wxTEXT_ATTR_TEXT_COLOUR
);
438 redDef
->SetStyle(redAttr
);
440 m_styleSheet
->AddCharacterStyle(redDef
);
442 wxRichTextListStyleDefinition
* bulletList
= new wxRichTextListStyleDefinition(wxT("Bullet List 1"));
444 for (i
= 0; i
< 10; i
++)
446 wxString bulletSymbol
;
448 bulletSymbol
= wxT("*");
450 bulletSymbol
= wxT("-");
452 bulletSymbol
= wxT("*");
454 bulletSymbol
= wxT("-");
456 bulletSymbol
= wxT("*");
458 bulletList
->SetAttributes(i
, (i
+1)*60, 60, wxTEXT_ATTR_BULLET_STYLE_SYMBOL
, bulletSymbol
);
461 m_styleSheet
->AddListStyle(bulletList
);
463 wxRichTextListStyleDefinition
* numberedList
= new wxRichTextListStyleDefinition(wxT("Numbered List 1"));
464 for (i
= 0; i
< 10; i
++)
468 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
470 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_LETTERS_LOWER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
472 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ROMAN_LOWER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
474 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ROMAN_UPPER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
476 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
478 numberedList
->SetAttributes(i
, (i
+1)*60, 60, numberStyle
);
481 m_styleSheet
->AddListStyle(numberedList
);
484 // ----------------------------------------------------------------------------
486 // ----------------------------------------------------------------------------
489 MyFrame::MyFrame(const wxString
& title
, wxWindowID id
, const wxPoint
& pos
,
490 const wxSize
& size
, long style
)
491 : wxFrame(NULL
, id
, title
, pos
, size
, style
)
493 // set the frame icon
494 SetIcon(wxICON(sample
));
497 wxMenu
*fileMenu
= new wxMenu
;
499 // the "About" item should be in the help menu
500 wxMenu
*helpMenu
= new wxMenu
;
501 helpMenu
->Append(ID_About
, _T("&About...\tF1"), _T("Show about dialog"));
503 fileMenu
->Append(wxID_OPEN
, _T("&Open\tCtrl+O"), _T("Open a file"));
504 fileMenu
->Append(wxID_SAVE
, _T("&Save\tCtrl+S"), _T("Save a file"));
505 fileMenu
->Append(wxID_SAVEAS
, _T("&Save As...\tF12"), _T("Save to a new file"));
506 fileMenu
->AppendSeparator();
507 fileMenu
->Append(ID_VIEW_HTML
, _T("&View as HTML"), _T("View HTML"));
508 fileMenu
->AppendSeparator();
509 fileMenu
->Append(ID_Quit
, _T("E&xit\tAlt+X"), _T("Quit this program"));
511 wxMenu
* editMenu
= new wxMenu
;
512 editMenu
->Append(wxID_UNDO
, _("&Undo\tCtrl+Z"));
513 editMenu
->Append(wxID_REDO
, _("&Redo\tCtrl+Y"));
514 editMenu
->AppendSeparator();
515 editMenu
->Append(wxID_CUT
, _("Cu&t\tCtrl+X"));
516 editMenu
->Append(wxID_COPY
, _("&Copy\tCtrl+C"));
517 editMenu
->Append(wxID_PASTE
, _("&Paste\tCtrl+V"));
519 editMenu
->Append(wxID_CLEAR
, _("&Delete\tDel"));
521 editMenu
->AppendSeparator();
522 editMenu
->Append(wxID_SELECTALL
, _("Select A&ll\tCtrl+A"));
524 editMenu
->AppendSeparator();
525 editMenu
->Append(wxID_FIND
, _("&Find...\tCtrl+F"));
526 editMenu
->Append(stID_FIND_REPLACE
, _("&Replace...\tCtrl+R"));
529 wxMenu
* formatMenu
= new wxMenu
;
530 formatMenu
->AppendCheckItem(ID_FORMAT_BOLD
, _("&Bold\tCtrl+B"));
531 formatMenu
->AppendCheckItem(ID_FORMAT_ITALIC
, _("&Italic\tCtrl+I"));
532 formatMenu
->AppendCheckItem(ID_FORMAT_UNDERLINE
, _("&Underline\tCtrl+U"));
533 formatMenu
->AppendSeparator();
534 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_LEFT
, _("L&eft Align"));
535 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_RIGHT
, _("&Right Align"));
536 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_CENTRE
, _("&Centre"));
537 formatMenu
->AppendSeparator();
538 formatMenu
->Append(ID_FORMAT_INDENT_MORE
, _("Indent &More"));
539 formatMenu
->Append(ID_FORMAT_INDENT_LESS
, _("Indent &Less"));
540 formatMenu
->AppendSeparator();
541 formatMenu
->Append(ID_FORMAT_PARAGRAPH_SPACING_MORE
, _("Increase Paragraph &Spacing"));
542 formatMenu
->Append(ID_FORMAT_PARAGRAPH_SPACING_LESS
, _("Decrease &Paragraph Spacing"));
543 formatMenu
->AppendSeparator();
544 formatMenu
->Append(ID_FORMAT_LINE_SPACING_SINGLE
, _("Normal Line Spacing"));
545 formatMenu
->Append(ID_FORMAT_LINE_SPACING_HALF
, _("1.5 Line Spacing"));
546 formatMenu
->Append(ID_FORMAT_LINE_SPACING_DOUBLE
, _("Double Line Spacing"));
547 formatMenu
->AppendSeparator();
548 formatMenu
->Append(ID_FORMAT_FONT
, _("&Font..."));
549 formatMenu
->Append(ID_FORMAT_PARAGRAPH
, _("&Paragraph..."));
550 formatMenu
->Append(ID_FORMAT_CONTENT
, _("Font and Pa&ragraph...\tShift+Ctrl+F"));
551 formatMenu
->AppendSeparator();
552 formatMenu
->Append(ID_SWITCH_STYLE_SHEETS
, _("&Switch Style Sheets"));
553 formatMenu
->Append(ID_MANAGE_STYLES
, _("&Manage Styles"));
555 wxMenu
* listsMenu
= new wxMenu
;
556 listsMenu
->Append(ID_FORMAT_BULLETS_AND_NUMBERING
, _("Bullets and &Numbering..."));
557 listsMenu
->AppendSeparator();
558 listsMenu
->Append(ID_FORMAT_NUMBER_LIST
, _("Number List"));
559 listsMenu
->Append(ID_FORMAT_ITEMIZE_LIST
, _("Itemize List"));
560 listsMenu
->Append(ID_FORMAT_RENUMBER_LIST
, _("Renumber List"));
561 listsMenu
->Append(ID_FORMAT_PROMOTE_LIST
, _("Promote List Items"));
562 listsMenu
->Append(ID_FORMAT_DEMOTE_LIST
, _("Demote List Items"));
563 listsMenu
->Append(ID_FORMAT_CLEAR_LIST
, _("Clear List Formatting"));
565 wxMenu
* insertMenu
= new wxMenu
;
566 insertMenu
->Append(ID_INSERT_SYMBOL
, _("&Symbol...\tCtrl+I"));
568 // now append the freshly created menu to the menu bar...
569 wxMenuBar
*menuBar
= new wxMenuBar();
570 menuBar
->Append(fileMenu
, _T("&File"));
571 menuBar
->Append(editMenu
, _T("&Edit"));
572 menuBar
->Append(formatMenu
, _T("F&ormat"));
573 menuBar
->Append(listsMenu
, _T("&Lists"));
574 menuBar
->Append(insertMenu
, _T("&Insert"));
575 menuBar
->Append(helpMenu
, _T("&Help"));
577 // ... and attach this menu bar to the frame
580 // create a status bar just for fun (by default with 1 pane only)
581 // but don't create it on limited screen space (WinCE)
582 bool is_pda
= wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA
;
588 SetStatusText(_T("Welcome to wxRichTextCtrl!"));
592 wxToolBar
* toolBar
= CreateToolBar();
594 toolBar
->AddTool(wxID_OPEN
, wxBitmap(open_xpm
), wxNullBitmap
, false, -1, -1, (wxObject
*) NULL
, _("Open"));
595 toolBar
->AddTool(wxID_SAVEAS
, wxBitmap(save_xpm
), wxNullBitmap
, false, -1, -1, (wxObject
*) NULL
, _("Save"));
596 toolBar
->AddSeparator();
597 toolBar
->AddTool(wxID_CUT
, wxBitmap(cut_xpm
), wxNullBitmap
, false, -1, -1, (wxObject
*) NULL
, _("Cut"));
598 toolBar
->AddTool(wxID_COPY
, wxBitmap(copy_xpm
), wxNullBitmap
, false, -1, -1, (wxObject
*) NULL
, _("Copy"));
599 toolBar
->AddTool(wxID_PASTE
, wxBitmap(paste_xpm
), wxNullBitmap
, false, -1, -1, (wxObject
*) NULL
, _("Paste"));
600 toolBar
->AddSeparator();
601 toolBar
->AddTool(wxID_UNDO
, wxBitmap(undo_xpm
), wxNullBitmap
, false, -1, -1, (wxObject
*) NULL
, _("Undo"));
602 toolBar
->AddTool(wxID_REDO
, wxBitmap(redo_xpm
), wxNullBitmap
, false, -1, -1, (wxObject
*) NULL
, _("Redo"));
603 toolBar
->AddSeparator();
604 toolBar
->AddTool(ID_FORMAT_BOLD
, wxBitmap(bold_xpm
), wxNullBitmap
, true, -1, -1, (wxObject
*) NULL
, _("Bold"));
605 toolBar
->AddTool(ID_FORMAT_ITALIC
, wxBitmap(italic_xpm
), wxNullBitmap
, true, -1, -1, (wxObject
*) NULL
, _("Italic"));
606 toolBar
->AddTool(ID_FORMAT_UNDERLINE
, wxBitmap(underline_xpm
), wxNullBitmap
, true, -1, -1, (wxObject
*) NULL
, _("Underline"));
607 toolBar
->AddSeparator();
608 toolBar
->AddTool(ID_FORMAT_ALIGN_LEFT
, wxBitmap(alignleft_xpm
), wxNullBitmap
, true, -1, -1, (wxObject
*) NULL
, _("Align Left"));
609 toolBar
->AddTool(ID_FORMAT_ALIGN_CENTRE
, wxBitmap(centre_xpm
), wxNullBitmap
, true, -1, -1, (wxObject
*) NULL
, _("Centre"));
610 toolBar
->AddTool(ID_FORMAT_ALIGN_RIGHT
, wxBitmap(alignright_xpm
), wxNullBitmap
, true, -1, -1, (wxObject
*) NULL
, _("Align Right"));
611 toolBar
->AddSeparator();
612 toolBar
->AddTool(ID_FORMAT_INDENT_LESS
, wxBitmap(indentless_xpm
), wxNullBitmap
, false, -1, -1, (wxObject
*) NULL
, _("Indent Less"));
613 toolBar
->AddTool(ID_FORMAT_INDENT_MORE
, wxBitmap(indentmore_xpm
), wxNullBitmap
, false, -1, -1, (wxObject
*) NULL
, _("Indent More"));
614 toolBar
->AddSeparator();
615 toolBar
->AddTool(ID_FORMAT_FONT
, wxBitmap(font_xpm
), wxNullBitmap
, false, -1, -1, (wxObject
*) NULL
, _("Font"));
617 wxRichTextStyleComboCtrl
* combo
= new wxRichTextStyleComboCtrl(toolBar
, ID_RICHTEXT_STYLE_COMBO
, wxDefaultPosition
, wxSize(200, -1));
618 toolBar
->AddControl(combo
);
622 wxSplitterWindow
* splitter
= new wxSplitterWindow(this, wxID_ANY
, wxDefaultPosition
, GetClientSize(), wxSP_NO_XP_THEME
|wxSP_3D
|wxSP_LIVE_UPDATE
);
624 wxFont textFont
= wxFont(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
625 wxFont boldFont
= wxFont(12, wxROMAN
, wxNORMAL
, wxBOLD
);
626 wxFont italicFont
= wxFont(12, wxROMAN
, wxITALIC
, wxNORMAL
);
628 m_richTextCtrl
= new wxRichTextCtrl(splitter
, ID_RICHTEXT_CTRL
, wxEmptyString
, wxDefaultPosition
, wxSize(200, 200), wxVSCROLL
|wxHSCROLL
|wxNO_BORDER
|wxWANTS_CHARS
);
629 wxFont
font(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
631 m_richTextCtrl
->SetFont(font
);
633 m_richTextCtrl
->SetStyleSheet(wxGetApp().GetStyleSheet());
635 combo
->SetStyleSheet(wxGetApp().GetStyleSheet());
636 combo
->SetRichTextCtrl(m_richTextCtrl
);
637 combo
->UpdateStyles();
639 wxRichTextStyleListCtrl
* styleListCtrl
= new wxRichTextStyleListCtrl(splitter
, ID_RICHTEXT_STYLE_LIST
);
641 wxSize display
= wxGetDisplaySize();
642 if ( is_pda
&& ( display
.GetWidth() < display
.GetHeight() ) )
644 splitter
->SplitHorizontally(m_richTextCtrl
, styleListCtrl
);
648 splitter
->SplitVertically(m_richTextCtrl
, styleListCtrl
, 500);
651 splitter
->UpdateSize();
653 styleListCtrl
->SetStyleSheet(wxGetApp().GetStyleSheet());
654 styleListCtrl
->SetRichTextCtrl(m_richTextCtrl
);
655 styleListCtrl
->UpdateStyles();
657 wxRichTextCtrl
& r
= *m_richTextCtrl
;
659 r
.BeginSuppressUndo();
661 r
.BeginParagraphSpacing(0, 20);
663 r
.BeginAlignment(wxTEXT_ALIGNMENT_CENTRE
);
667 r
.WriteText(wxT("Welcome to wxRichTextCtrl, a wxWidgets control for editing and presenting styled text and images"));
672 r
.WriteText(wxT("by Julian Smart"));
678 r
.WriteImage(wxBitmap(zebra_xpm
));
685 r
.WriteText(wxT("What can you do with this thing? "));
686 r
.WriteImage(wxBitmap(smiley_xpm
));
687 r
.WriteText(wxT(" Well, you can change text "));
689 r
.BeginTextColour(wxColour(255, 0, 0));
690 r
.WriteText(wxT("colour, like this red bit."));
693 r
.BeginTextColour(wxColour(0, 0, 255));
694 r
.WriteText(wxT(" And this blue bit."));
697 r
.WriteText(wxT(" Naturally you can make things "));
699 r
.WriteText(wxT("bold "));
702 r
.WriteText(wxT("or italic "));
705 r
.WriteText(wxT("or underlined."));
709 r
.WriteText(wxT(" Different font sizes on the same line is allowed, too."));
712 r
.WriteText(wxT(" Next we'll show an indented paragraph."));
714 r
.BeginLeftIndent(60);
717 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."));
722 r
.WriteText(wxT("Next, we'll show a first-line indent, achieved using BeginLeftIndent(100, -40)."));
724 r
.BeginLeftIndent(100, -40);
727 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."));
732 r
.WriteText(wxT("Numbered bullets are possible, again using subindents:"));
734 r
.BeginNumberedBullet(1, 100, 60);
737 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."));
738 r
.EndNumberedBullet();
740 r
.BeginNumberedBullet(2, 100, 60);
743 r
.WriteText(wxT("This is my second item."));
744 r
.EndNumberedBullet();
748 r
.WriteText(wxT("The following paragraph is right-indented:"));
750 r
.BeginRightIndent(200);
753 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."));
758 r
.WriteText(wxT("The following paragraph is right-aligned with 1.5 line spacing:"));
760 r
.BeginAlignment(wxTEXT_ALIGNMENT_RIGHT
);
761 r
.BeginLineSpacing(wxTEXT_ATTR_LINE_SPACING_HALF
);
764 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."));
774 attr
.SetFlags(wxTEXT_ATTR_TABS
);
776 r
.SetDefaultStyle(attr
);
779 r
.WriteText(wxT("This line contains tabs:\tFirst tab\tSecond tab\tThird tab"));
782 r
.WriteText(wxT("Other notable features of wxRichTextCtrl include:"));
784 r
.BeginSymbolBullet(wxT('*'), 100, 60);
786 r
.WriteText(wxT("Compatibility with wxTextCtrl API"));
789 r
.BeginSymbolBullet(wxT('*'), 100, 60);
791 r
.WriteText(wxT("Easy stack-based BeginXXX()...EndXXX() style setting in addition to SetStyle()"));
794 r
.BeginSymbolBullet(wxT('*'), 100, 60);
796 r
.WriteText(wxT("XML loading and saving"));
799 r
.BeginSymbolBullet(wxT('*'), 100, 60);
801 r
.WriteText(wxT("Undo/Redo, with batching option and Undo suppressing"));
804 r
.BeginSymbolBullet(wxT('*'), 100, 60);
806 r
.WriteText(wxT("Clipboard copy and paste"));
809 r
.BeginSymbolBullet(wxT('*'), 100, 60);
811 r
.WriteText(wxT("wxRichTextStyleSheet with named character and paragraph styles, and control for applying named styles"));
814 r
.BeginSymbolBullet(wxT('*'), 100, 60);
816 r
.WriteText(wxT("A design that can easily be extended to other content types, ultimately with text boxes, tables, controls, and so on"));
821 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!"));
823 r
.EndParagraphSpacing();
831 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
833 // true is to force the frame to close
837 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
840 msg
.Printf( _T("This is a demo for wxRichTextCtrl, a control for editing styled text.\n(c) Julian Smart, 2005"));
841 wxMessageBox(msg
, _T("About wxRichTextCtrl Sample"), wxOK
| wxICON_INFORMATION
, this);
844 // Forward command events to the current rich text control, if any
845 bool MyFrame::ProcessEvent(wxEvent
& event
)
847 if (event
.IsCommandEvent() && !event
.IsKindOf(CLASSINFO(wxChildFocusEvent
)))
849 // Problem: we can get infinite recursion because the events
850 // climb back up to this frame, and repeat.
851 // Assume that command events don't cause another command event
852 // to be called, so we can rely on inCommand not being overwritten
854 static int s_eventType
= 0;
855 static wxWindowID s_id
= 0;
857 if (s_id
!= event
.GetId() && s_eventType
!= event
.GetEventType())
859 s_eventType
= event
.GetEventType();
860 s_id
= event
.GetId();
862 wxWindow
* focusWin
= wxFindFocusDescendant(this);
863 if (focusWin
&& focusWin
->ProcessEvent(event
))
880 return wxFrame::ProcessEvent(event
);
883 void MyFrame::OnOpen(wxCommandEvent
& WXUNUSED(event
))
887 wxArrayInt fileTypes
;
889 wxString filter
= wxRichTextBuffer::GetExtWildcard(false, false, & fileTypes
);
892 filter
+= wxT("All files (*.*)|*.*");
894 wxFileDialog
dialog(this,
895 _("Choose a filename"),
901 if (dialog
.ShowModal() == wxID_OK
)
903 wxString path
= dialog
.GetPath();
907 int filterIndex
= dialog
.GetFilterIndex();
908 int fileType
= (filterIndex
< (int) fileTypes
.GetCount())
909 ? fileTypes
[filterIndex
]
910 : wxRICHTEXT_TYPE_TEXT
;
911 m_richTextCtrl
->LoadFile(path
, fileType
);
916 void MyFrame::OnSave(wxCommandEvent
& event
)
918 if (m_richTextCtrl
->GetFilename().empty())
923 m_richTextCtrl
->SaveFile();
926 void MyFrame::OnSaveAs(wxCommandEvent
& WXUNUSED(event
))
928 wxString filter
= wxRichTextBuffer::GetExtWildcard(false, true);
932 wxFileDialog
dialog(this,
933 _("Choose a filename"),
939 if (dialog
.ShowModal() == wxID_OK
)
941 wxString path
= dialog
.GetPath();
945 m_richTextCtrl
->SaveFile(path
);
950 void MyFrame::OnBold(wxCommandEvent
& WXUNUSED(event
))
952 m_richTextCtrl
->ApplyBoldToSelection();
955 void MyFrame::OnItalic(wxCommandEvent
& WXUNUSED(event
))
957 m_richTextCtrl
->ApplyItalicToSelection();
960 void MyFrame::OnUnderline(wxCommandEvent
& WXUNUSED(event
))
962 m_richTextCtrl
->ApplyUnderlineToSelection();
966 void MyFrame::OnUpdateBold(wxUpdateUIEvent
& event
)
968 event
.Check(m_richTextCtrl
->IsSelectionBold());
971 void MyFrame::OnUpdateItalic(wxUpdateUIEvent
& event
)
973 event
.Check(m_richTextCtrl
->IsSelectionItalics());
976 void MyFrame::OnUpdateUnderline(wxUpdateUIEvent
& event
)
978 event
.Check(m_richTextCtrl
->IsSelectionUnderlined());
981 void MyFrame::OnAlignLeft(wxCommandEvent
& WXUNUSED(event
))
983 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_LEFT
);
986 void MyFrame::OnAlignCentre(wxCommandEvent
& WXUNUSED(event
))
988 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_CENTRE
);
991 void MyFrame::OnAlignRight(wxCommandEvent
& WXUNUSED(event
))
993 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_RIGHT
);
996 void MyFrame::OnUpdateAlignLeft(wxUpdateUIEvent
& event
)
998 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_LEFT
));
1001 void MyFrame::OnUpdateAlignCentre(wxUpdateUIEvent
& event
)
1003 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_CENTRE
));
1006 void MyFrame::OnUpdateAlignRight(wxUpdateUIEvent
& event
)
1008 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_RIGHT
));
1011 void MyFrame::OnFont(wxCommandEvent
& WXUNUSED(event
))
1013 wxRichTextRange range
;
1014 if (m_richTextCtrl
->HasSelection())
1015 range
= m_richTextCtrl
->GetSelectionRange();
1017 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1019 int pages
= wxRICHTEXT_FORMAT_FONT
;
1021 wxRichTextFormattingDialog
formatDlg(pages
, this);
1022 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1024 if (formatDlg
.ShowModal() == wxID_OK
)
1026 formatDlg
.ApplyStyle(m_richTextCtrl
, range
);
1029 // Old method using wxFontDialog
1031 if (!m_richTextCtrl
->HasSelection())
1034 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1035 wxFontData fontData
;
1038 attr
.SetFlags(wxTEXT_ATTR_FONT
);
1040 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1041 fontData
.SetInitialFont(attr
.GetFont());
1043 wxFontDialog
dialog(this, fontData
);
1044 if (dialog
.ShowModal() == wxID_OK
)
1046 fontData
= dialog
.GetFontData();
1047 attr
.SetFlags(wxTEXT_ATTR_FONT
);
1048 attr
.SetFont(fontData
.GetChosenFont());
1049 if (attr
.GetFont().Ok())
1051 m_richTextCtrl
->SetStyle(range
, attr
);
1057 void MyFrame::OnParagraph(wxCommandEvent
& WXUNUSED(event
))
1059 wxRichTextRange range
;
1060 if (m_richTextCtrl
->HasSelection())
1061 range
= m_richTextCtrl
->GetSelectionRange();
1063 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1065 int pages
= wxRICHTEXT_FORMAT_INDENTS_SPACING
|wxRICHTEXT_FORMAT_TABS
|wxRICHTEXT_FORMAT_BULLETS
;
1067 wxRichTextFormattingDialog
formatDlg(pages
, this);
1068 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1070 if (formatDlg
.ShowModal() == wxID_OK
)
1072 formatDlg
.ApplyStyle(m_richTextCtrl
, range
);
1076 void MyFrame::OnFormat(wxCommandEvent
& WXUNUSED(event
))
1078 wxRichTextRange range
;
1079 if (m_richTextCtrl
->HasSelection())
1080 range
= m_richTextCtrl
->GetSelectionRange();
1082 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1084 int pages
= wxRICHTEXT_FORMAT_FONT
|wxRICHTEXT_FORMAT_INDENTS_SPACING
|wxRICHTEXT_FORMAT_TABS
|wxRICHTEXT_FORMAT_BULLETS
;
1086 wxRichTextFormattingDialog
formatDlg(pages
, this);
1087 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1089 if (formatDlg
.ShowModal() == wxID_OK
)
1091 formatDlg
.ApplyStyle(m_richTextCtrl
, range
);
1095 void MyFrame::OnUpdateFormat(wxUpdateUIEvent
& event
)
1097 event
.Enable(m_richTextCtrl
->HasSelection());
1100 void MyFrame::OnIndentMore(wxCommandEvent
& WXUNUSED(event
))
1103 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1105 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1107 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1108 if (m_richTextCtrl
->HasSelection())
1109 range
= m_richTextCtrl
->GetSelectionRange();
1111 wxFontData fontData
;
1112 attr
.SetLeftIndent(attr
.GetLeftIndent() + 100);
1114 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1115 m_richTextCtrl
->SetStyle(range
, attr
);
1119 void MyFrame::OnIndentLess(wxCommandEvent
& WXUNUSED(event
))
1122 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1124 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1126 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1127 if (m_richTextCtrl
->HasSelection())
1128 range
= m_richTextCtrl
->GetSelectionRange();
1130 if (attr
.GetLeftIndent() >= 100)
1132 wxFontData fontData
;
1133 attr
.SetLeftIndent(attr
.GetLeftIndent() - 100);
1135 m_richTextCtrl
->SetStyle(range
, attr
);
1140 void MyFrame::OnLineSpacingHalf(wxCommandEvent
& WXUNUSED(event
))
1143 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1145 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1147 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1148 if (m_richTextCtrl
->HasSelection())
1149 range
= m_richTextCtrl
->GetSelectionRange();
1151 wxFontData fontData
;
1152 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1153 attr
.SetLineSpacing(15);
1155 m_richTextCtrl
->SetStyle(range
, attr
);
1159 void MyFrame::OnLineSpacingDouble(wxCommandEvent
& WXUNUSED(event
))
1162 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1164 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1166 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1167 if (m_richTextCtrl
->HasSelection())
1168 range
= m_richTextCtrl
->GetSelectionRange();
1170 wxFontData fontData
;
1171 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1172 attr
.SetLineSpacing(20);
1174 m_richTextCtrl
->SetStyle(range
, attr
);
1178 void MyFrame::OnLineSpacingSingle(wxCommandEvent
& WXUNUSED(event
))
1181 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1183 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1185 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1186 if (m_richTextCtrl
->HasSelection())
1187 range
= m_richTextCtrl
->GetSelectionRange();
1189 wxFontData fontData
;
1190 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1191 attr
.SetLineSpacing(0); // Can also use 10
1193 m_richTextCtrl
->SetStyle(range
, attr
);
1197 void MyFrame::OnParagraphSpacingMore(wxCommandEvent
& WXUNUSED(event
))
1200 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1202 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1204 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1205 if (m_richTextCtrl
->HasSelection())
1206 range
= m_richTextCtrl
->GetSelectionRange();
1208 wxFontData fontData
;
1209 attr
.SetParagraphSpacingAfter(attr
.GetParagraphSpacingAfter() + 20);
1211 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1212 m_richTextCtrl
->SetStyle(range
, attr
);
1216 void MyFrame::OnParagraphSpacingLess(wxCommandEvent
& WXUNUSED(event
))
1219 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1221 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1223 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1224 if (m_richTextCtrl
->HasSelection())
1225 range
= m_richTextCtrl
->GetSelectionRange();
1227 if (attr
.GetParagraphSpacingAfter() >= 20)
1229 wxFontData fontData
;
1230 attr
.SetParagraphSpacingAfter(attr
.GetParagraphSpacingAfter() - 20);
1232 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1233 m_richTextCtrl
->SetStyle(range
, attr
);
1238 void MyFrame::OnViewHTML(wxCommandEvent
& WXUNUSED(event
))
1240 wxDialog
dialog(this, wxID_ANY
, _("HTML"), wxDefaultPosition
, wxSize(500, 400), wxDEFAULT_DIALOG_STYLE
);
1242 wxBoxSizer
* boxSizer
= new wxBoxSizer(wxVERTICAL
);
1243 dialog
.SetSizer(boxSizer
);
1245 wxHtmlWindow
* win
= new wxHtmlWindow(& dialog
, wxID_ANY
, wxDefaultPosition
, wxSize(500, 400), wxSUNKEN_BORDER
);
1246 boxSizer
->Add(win
, 1, wxALL
, 5);
1248 wxButton
* cancelButton
= new wxButton(& dialog
, wxID_CANCEL
, wxT("&Close"));
1249 boxSizer
->Add(cancelButton
, 0, wxALL
|wxCENTRE
, 5);
1252 wxStringOutputStream
strStream(& text
);
1254 wxRichTextHTMLHandler htmlHandler
;
1255 if (htmlHandler
.SaveFile(& m_richTextCtrl
->GetBuffer(), strStream
))
1260 boxSizer
->Fit(& dialog
);
1265 // Demonstrates how you can change the style sheets and have the changes
1266 // reflected in the control content without wiping out character formatting.
1268 void MyFrame::OnSwitchStyleSheets(wxCommandEvent
& WXUNUSED(event
))
1270 static wxRichTextStyleSheet
* gs_AlternateStyleSheet
= NULL
;
1272 wxRichTextCtrl
* ctrl
= (wxRichTextCtrl
*) FindWindow(ID_RICHTEXT_CTRL
);
1273 wxRichTextStyleListCtrl
*styleList
= (wxRichTextStyleListCtrl
*) FindWindow(ID_RICHTEXT_STYLE_LIST
);
1274 wxRichTextStyleComboCtrl
* styleCombo
= (wxRichTextStyleComboCtrl
*) FindWindow(ID_RICHTEXT_STYLE_COMBO
);
1276 wxRichTextStyleSheet
* sheet
= ctrl
->GetStyleSheet();
1278 // One-time creation of an alternate style sheet
1279 if (!gs_AlternateStyleSheet
)
1281 gs_AlternateStyleSheet
= new wxRichTextStyleSheet(*sheet
);
1283 // Make some modifications
1284 for (int i
= 0; i
< (int) gs_AlternateStyleSheet
->GetParagraphStyleCount(); i
++)
1286 wxRichTextParagraphStyleDefinition
* def
= gs_AlternateStyleSheet
->GetParagraphStyle(i
);
1288 if (def
->GetStyle().HasTextColour())
1289 def
->GetStyle().SetTextColour(*wxBLUE
);
1291 if (def
->GetStyle().HasAlignment())
1293 if (def
->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_CENTRE
)
1294 def
->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_RIGHT
);
1295 else if (def
->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_LEFT
)
1296 def
->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_CENTRE
);
1298 if (def
->GetStyle().HasLeftIndent())
1300 def
->GetStyle().SetLeftIndent(def
->GetStyle().GetLeftIndent() * 2);
1306 wxRichTextStyleSheet
* tmp
= gs_AlternateStyleSheet
;
1307 gs_AlternateStyleSheet
= sheet
;
1310 ctrl
->SetStyleSheet(sheet
);
1311 ctrl
->ApplyStyleSheet(sheet
); // Makes the control reflect the new style definitions
1313 styleList
->SetStyleSheet(sheet
);
1314 styleList
->UpdateStyles();
1316 styleCombo
->SetStyleSheet(sheet
);
1317 styleCombo
->UpdateStyles();
1320 void MyFrame::OnManageStyles(wxCommandEvent
& WXUNUSED(event
))
1322 wxRichTextCtrl
* ctrl
= (wxRichTextCtrl
*) FindWindow(ID_RICHTEXT_CTRL
);
1323 wxRichTextStyleSheet
* sheet
= ctrl
->GetStyleSheet();
1325 int flags
= wxRICHTEXT_ORGANISER_CREATE_STYLES
|wxRICHTEXT_ORGANISER_EDIT_STYLES
;
1327 wxRichTextStyleOrganiserDialog
dlg(flags
, sheet
, NULL
, this, wxID_ANY
, _("Style Manager"));
1331 void MyFrame::OnInsertSymbol(wxCommandEvent
& WXUNUSED(event
))
1333 wxRichTextCtrl
* ctrl
= (wxRichTextCtrl
*) FindWindow(ID_RICHTEXT_CTRL
);
1336 attr
.SetFlags(wxTEXT_ATTR_FONT
);
1337 ctrl
->GetStyle(ctrl
->GetInsertionPoint(), attr
);
1339 wxString currentFontName
;
1340 if (attr
.HasFont() && attr
.GetFont().Ok())
1341 currentFontName
= attr
.GetFont().GetFaceName();
1343 // Don't set the initial font in the dialog (so the user is choosing
1344 // 'normal text', i.e. the current font) but do tell the dialog
1345 // what 'normal text' is.
1347 wxSymbolPickerDialog
dlg(wxT("*"), wxEmptyString
, currentFontName
, this);
1349 if (dlg
.ShowModal() == wxID_OK
)
1351 if (dlg
.HasSelection())
1353 long insertionPoint
= ctrl
->GetInsertionPoint();
1355 ctrl
->WriteText(dlg
.GetSymbol());
1357 if (!dlg
.UseNormalFont())
1359 wxFont
font(attr
.GetFont());
1360 font
.SetFaceName(dlg
.GetFontName());
1362 ctrl
->SetStyle(insertionPoint
, insertionPoint
+1, attr
);
1368 void MyFrame::OnNumberList(wxCommandEvent
& WXUNUSED(event
))
1370 wxRichTextCtrl
* ctrl
= (wxRichTextCtrl
*) FindWindow(ID_RICHTEXT_CTRL
);
1372 if (ctrl
->HasSelection())
1374 wxRichTextRange range
= ctrl
->GetSelectionRange();
1375 ctrl
->SetListStyle(range
, wxT("Numbered List 1"), wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_RENUMBER
);
1379 void MyFrame::OnBulletsAndNumbering(wxCommandEvent
& WXUNUSED(event
))
1381 wxRichTextCtrl
* ctrl
= (wxRichTextCtrl
*) FindWindow(ID_RICHTEXT_CTRL
);
1382 wxRichTextStyleSheet
* sheet
= ctrl
->GetStyleSheet();
1384 int flags
= wxRICHTEXT_ORGANISER_BROWSE_NUMBERING
;
1386 wxRichTextStyleOrganiserDialog
dlg(flags
, sheet
, ctrl
, this, wxID_ANY
, _("Bullets and Numbering"));
1387 if (dlg
.ShowModal() == wxID_OK
)
1389 if (dlg
.GetSelectedStyleDefinition())
1394 void MyFrame::OnItemizeList(wxCommandEvent
& WXUNUSED(event
))
1396 wxRichTextCtrl
* ctrl
= (wxRichTextCtrl
*) FindWindow(ID_RICHTEXT_CTRL
);
1398 if (ctrl
->HasSelection())
1400 wxRichTextRange range
= ctrl
->GetSelectionRange();
1401 ctrl
->SetListStyle(range
, wxT("Bullet List 1"));
1405 void MyFrame::OnRenumberList(wxCommandEvent
& WXUNUSED(event
))
1407 wxRichTextCtrl
* ctrl
= (wxRichTextCtrl
*) FindWindow(ID_RICHTEXT_CTRL
);
1409 if (ctrl
->HasSelection())
1411 wxRichTextRange range
= ctrl
->GetSelectionRange();
1412 ctrl
->NumberList(range
, NULL
, wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_RENUMBER
);
1416 void MyFrame::OnPromoteList(wxCommandEvent
& WXUNUSED(event
))
1418 wxRichTextCtrl
* ctrl
= (wxRichTextCtrl
*) FindWindow(ID_RICHTEXT_CTRL
);
1420 if (ctrl
->HasSelection())
1422 wxRichTextRange range
= ctrl
->GetSelectionRange();
1423 ctrl
->PromoteList(1, range
, NULL
);
1427 void MyFrame::OnDemoteList(wxCommandEvent
& WXUNUSED(event
))
1429 wxRichTextCtrl
* ctrl
= (wxRichTextCtrl
*) FindWindow(ID_RICHTEXT_CTRL
);
1431 if (ctrl
->HasSelection())
1433 wxRichTextRange range
= ctrl
->GetSelectionRange();
1434 ctrl
->PromoteList(-1, range
, NULL
);
1438 void MyFrame::OnClearList(wxCommandEvent
& WXUNUSED(event
))
1440 wxRichTextCtrl
* ctrl
= (wxRichTextCtrl
*) FindWindow(ID_RICHTEXT_CTRL
);
1442 if (ctrl
->HasSelection())
1444 wxRichTextRange range
= ctrl
->GetSelectionRange();
1445 ctrl
->ClearListStyle(range
);