1 /////////////////////////////////////////////////////////////////////////////
2 // Name: samples/richtext/richtext.cpp
3 // Purpose: wxWidgets rich text editor sample
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx/wx.h".
21 #include "wx/wxprec.h"
27 // for all others, include the necessary headers (this file is usually all you
28 // need because it includes almost all "standard" wxWidgets headers)
33 #include "wx/fontdlg.h"
34 #include "wx/splitter.h"
35 #include "wx/sstream.h"
36 #include "wx/html/htmlwin.h"
37 #include "wx/stopwatch.h"
40 #include "wx/filesys.h"
41 #include "wx/fs_mem.h"
45 #include "wx/cshelp.h"
49 #include "../sample.xpm"
52 #include "bitmaps/smiley.xpm"
53 // #include "bitmaps/idea.xpm"
54 #include "bitmaps/zebra.xpm"
56 #include "bitmaps/open.xpm"
57 #include "bitmaps/save.xpm"
58 #include "bitmaps/copy.xpm"
59 #include "bitmaps/cut.xpm"
60 #include "bitmaps/paste.xpm"
61 #include "bitmaps/undo.xpm"
62 #include "bitmaps/redo.xpm"
63 #include "bitmaps/bold.xpm"
64 #include "bitmaps/italic.xpm"
65 #include "bitmaps/underline.xpm"
67 #include "bitmaps/alignleft.xpm"
68 #include "bitmaps/alignright.xpm"
69 #include "bitmaps/centre.xpm"
70 #include "bitmaps/font.xpm"
71 #include "bitmaps/indentless.xpm"
72 #include "bitmaps/indentmore.xpm"
74 #include "wx/richtext/richtextctrl.h"
75 #include "wx/richtext/richtextstyles.h"
76 #include "wx/richtext/richtextxml.h"
77 #include "wx/richtext/richtexthtml.h"
78 #include "wx/richtext/richtextformatdlg.h"
79 #include "wx/richtext/richtextsymboldlg.h"
80 #include "wx/richtext/richtextstyledlg.h"
81 #include "wx/richtext/richtextprint.h"
82 #include "wx/richtext/richtextimagedlg.h"
84 // ----------------------------------------------------------------------------
86 // ----------------------------------------------------------------------------
88 // ----------------------------------------------------------------------------
90 // ----------------------------------------------------------------------------
92 // Define a new application type, each program should derive a class from wxApp
93 class MyRichTextCtrl
: public wxRichTextCtrl
96 MyRichTextCtrl( wxWindow
* parent
, wxWindowID id
= -1, const wxString
& value
= wxEmptyString
, const wxPoint
& pos
= wxDefaultPosition
, const wxSize
& size
= wxDefaultSize
,
97 long style
= wxRE_MULTILINE
, const wxValidator
& validator
= wxDefaultValidator
, const wxString
& name
= wxTextCtrlNameStr
):
98 wxRichTextCtrl(parent
, id
, value
, pos
, size
, style
, validator
, name
)
104 void SetLockId(long id
) { m_lockId
= id
; }
105 long GetLockId() const { return m_lockId
; }
107 void BeginLock() { m_lockId
++; m_locked
= true; }
108 void EndLock() { m_locked
= false; }
109 bool IsLocked() const { return m_locked
; }
111 static void SetEnhancedDrawingHandler();
114 Prepares the content just before insertion (or after buffer reset). Called by the same function in wxRichTextBuffer.
115 Currently is only called if undo mode is on.
117 virtual void PrepareContent(wxRichTextParagraphLayoutBox
& container
);
120 Can we delete this range?
121 Sends an event to the control.
123 virtual bool CanDeleteRange(wxRichTextParagraphLayoutBox
& container
, const wxRichTextRange
& range
) const;
126 Can we insert content at this position?
127 Sends an event to the control.
129 virtual bool CanInsertContent(wxRichTextParagraphLayoutBox
& container
, long pos
) const;
135 // Define a new application type, each program should derive a class from wxApp
136 class MyApp
: public wxApp
139 // override base class virtuals
140 // ----------------------------
142 // this one is called on application startup and is a good place for the app
143 // initialization (doing it here and not in the ctor allows to have an error
144 // return: if OnInit() returns false, the application terminates)
145 virtual bool OnInit();
146 virtual int OnExit();
150 wxRichTextStyleSheet
* GetStyleSheet() const { return m_styleSheet
; }
151 wxRichTextPrinting
* GetPrinting() const { return m_printing
; }
153 wxRichTextStyleSheet
* m_styleSheet
;
154 wxRichTextPrinting
* m_printing
;
157 // Define a new frame type: this is going to be our main frame
158 class MyFrame
: public wxFrame
162 MyFrame(const wxString
& title
, wxWindowID id
, const wxPoint
& pos
= wxDefaultPosition
,
163 const wxSize
& size
= wxDefaultSize
, long style
= wxDEFAULT_FRAME_STYLE
);
165 // event handlers (these functions should _not_ be virtual)
166 void OnQuit(wxCommandEvent
& event
);
167 void OnAbout(wxCommandEvent
& event
);
169 void OnOpen(wxCommandEvent
& event
);
170 void OnSave(wxCommandEvent
& event
);
171 void OnSaveAs(wxCommandEvent
& event
);
173 void OnBold(wxCommandEvent
& event
);
174 void OnItalic(wxCommandEvent
& event
);
175 void OnUnderline(wxCommandEvent
& event
);
177 void OnStrikethrough(wxCommandEvent
& event
);
178 void OnSuperscript(wxCommandEvent
& event
);
179 void OnSubscript(wxCommandEvent
& event
);
181 void OnUpdateBold(wxUpdateUIEvent
& event
);
182 void OnUpdateItalic(wxUpdateUIEvent
& event
);
183 void OnUpdateUnderline(wxUpdateUIEvent
& event
);
184 void OnUpdateStrikethrough(wxUpdateUIEvent
& event
);
185 void OnUpdateSuperscript(wxUpdateUIEvent
& event
);
186 void OnUpdateSubscript(wxUpdateUIEvent
& event
);
188 void OnAlignLeft(wxCommandEvent
& event
);
189 void OnAlignCentre(wxCommandEvent
& event
);
190 void OnAlignRight(wxCommandEvent
& event
);
192 void OnUpdateAlignLeft(wxUpdateUIEvent
& event
);
193 void OnUpdateAlignCentre(wxUpdateUIEvent
& event
);
194 void OnUpdateAlignRight(wxUpdateUIEvent
& event
);
196 void OnIndentMore(wxCommandEvent
& event
);
197 void OnIndentLess(wxCommandEvent
& event
);
199 void OnFont(wxCommandEvent
& event
);
200 void OnImage(wxCommandEvent
& event
);
201 void OnUpdateImage(wxUpdateUIEvent
& event
);
202 void OnParagraph(wxCommandEvent
& event
);
203 void OnFormat(wxCommandEvent
& event
);
204 void OnUpdateFormat(wxUpdateUIEvent
& event
);
206 void OnInsertSymbol(wxCommandEvent
& event
);
208 void OnLineSpacingHalf(wxCommandEvent
& event
);
209 void OnLineSpacingDouble(wxCommandEvent
& event
);
210 void OnLineSpacingSingle(wxCommandEvent
& event
);
212 void OnParagraphSpacingMore(wxCommandEvent
& event
);
213 void OnParagraphSpacingLess(wxCommandEvent
& event
);
215 void OnNumberList(wxCommandEvent
& event
);
216 void OnBulletsAndNumbering(wxCommandEvent
& event
);
217 void OnItemizeList(wxCommandEvent
& event
);
218 void OnRenumberList(wxCommandEvent
& event
);
219 void OnPromoteList(wxCommandEvent
& event
);
220 void OnDemoteList(wxCommandEvent
& event
);
221 void OnClearList(wxCommandEvent
& event
);
223 void OnReload(wxCommandEvent
& event
);
225 void OnViewHTML(wxCommandEvent
& event
);
227 void OnSwitchStyleSheets(wxCommandEvent
& event
);
228 void OnManageStyles(wxCommandEvent
& event
);
230 void OnInsertURL(wxCommandEvent
& event
);
231 void OnURL(wxTextUrlEvent
& event
);
232 void OnStyleSheetReplacing(wxRichTextEvent
& event
);
234 void OnPrint(wxCommandEvent
& event
);
235 void OnPreview(wxCommandEvent
& event
);
236 void OnPageSetup(wxCommandEvent
& event
);
238 void OnInsertImage(wxCommandEvent
& event
);
241 // Forward command events to the current rich text control, if any
242 bool ProcessEvent(wxEvent
& event
);
245 void WriteInitialText();
248 // any class wishing to process wxWidgets events must use this macro
249 DECLARE_EVENT_TABLE()
251 MyRichTextCtrl
* m_richTextCtrl
;
254 // ----------------------------------------------------------------------------
256 // ----------------------------------------------------------------------------
258 // IDs for the controls and the menu commands
263 ID_About
= wxID_ABOUT
,
265 ID_FORMAT_BOLD
= 100,
268 ID_FORMAT_STRIKETHROUGH
,
269 ID_FORMAT_SUPERSCRIPT
,
282 ID_FORMAT_ALIGN_LEFT
,
283 ID_FORMAT_ALIGN_CENTRE
,
284 ID_FORMAT_ALIGN_RIGHT
,
286 ID_FORMAT_INDENT_MORE
,
287 ID_FORMAT_INDENT_LESS
,
289 ID_FORMAT_PARAGRAPH_SPACING_MORE
,
290 ID_FORMAT_PARAGRAPH_SPACING_LESS
,
292 ID_FORMAT_LINE_SPACING_HALF
,
293 ID_FORMAT_LINE_SPACING_DOUBLE
,
294 ID_FORMAT_LINE_SPACING_SINGLE
,
296 ID_FORMAT_NUMBER_LIST
,
297 ID_FORMAT_BULLETS_AND_NUMBERING
,
298 ID_FORMAT_ITEMIZE_LIST
,
299 ID_FORMAT_RENUMBER_LIST
,
300 ID_FORMAT_PROMOTE_LIST
,
301 ID_FORMAT_DEMOTE_LIST
,
302 ID_FORMAT_CLEAR_LIST
,
305 ID_SWITCH_STYLE_SHEETS
,
313 ID_RICHTEXT_STYLE_LIST
,
314 ID_RICHTEXT_STYLE_COMBO
317 // ----------------------------------------------------------------------------
318 // event tables and other macros for wxWidgets
319 // ----------------------------------------------------------------------------
321 // the event tables connect the wxWidgets events with the functions (event
322 // handlers) which process them. It can be also done at run-time, but for the
323 // simple menu events like this the static method is much simpler.
324 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
325 EVT_MENU(ID_Quit
, MyFrame::OnQuit
)
326 EVT_MENU(ID_About
, MyFrame::OnAbout
)
328 EVT_MENU(wxID_OPEN
, MyFrame::OnOpen
)
329 EVT_MENU(wxID_SAVE
, MyFrame::OnSave
)
330 EVT_MENU(wxID_SAVEAS
, MyFrame::OnSaveAs
)
332 EVT_MENU(ID_FORMAT_BOLD
, MyFrame::OnBold
)
333 EVT_MENU(ID_FORMAT_ITALIC
, MyFrame::OnItalic
)
334 EVT_MENU(ID_FORMAT_UNDERLINE
, MyFrame::OnUnderline
)
336 EVT_MENU(ID_FORMAT_STRIKETHROUGH
, MyFrame::OnStrikethrough
)
337 EVT_MENU(ID_FORMAT_SUPERSCRIPT
, MyFrame::OnSuperscript
)
338 EVT_MENU(ID_FORMAT_SUBSCRIPT
, MyFrame::OnSubscript
)
340 EVT_UPDATE_UI(ID_FORMAT_BOLD
, MyFrame::OnUpdateBold
)
341 EVT_UPDATE_UI(ID_FORMAT_ITALIC
, MyFrame::OnUpdateItalic
)
342 EVT_UPDATE_UI(ID_FORMAT_UNDERLINE
, MyFrame::OnUpdateUnderline
)
344 EVT_UPDATE_UI(ID_FORMAT_STRIKETHROUGH
, MyFrame::OnUpdateStrikethrough
)
345 EVT_UPDATE_UI(ID_FORMAT_SUPERSCRIPT
, MyFrame::OnUpdateSuperscript
)
346 EVT_UPDATE_UI(ID_FORMAT_SUBSCRIPT
, MyFrame::OnUpdateSubscript
)
348 EVT_MENU(ID_FORMAT_ALIGN_LEFT
, MyFrame::OnAlignLeft
)
349 EVT_MENU(ID_FORMAT_ALIGN_CENTRE
, MyFrame::OnAlignCentre
)
350 EVT_MENU(ID_FORMAT_ALIGN_RIGHT
, MyFrame::OnAlignRight
)
352 EVT_UPDATE_UI(ID_FORMAT_ALIGN_LEFT
, MyFrame::OnUpdateAlignLeft
)
353 EVT_UPDATE_UI(ID_FORMAT_ALIGN_CENTRE
, MyFrame::OnUpdateAlignCentre
)
354 EVT_UPDATE_UI(ID_FORMAT_ALIGN_RIGHT
, MyFrame::OnUpdateAlignRight
)
356 EVT_MENU(ID_FORMAT_FONT
, MyFrame::OnFont
)
357 EVT_MENU(ID_FORMAT_IMAGE
, MyFrame::OnImage
)
358 EVT_MENU(ID_FORMAT_PARAGRAPH
, MyFrame::OnParagraph
)
359 EVT_MENU(ID_FORMAT_CONTENT
, MyFrame::OnFormat
)
360 EVT_UPDATE_UI(ID_FORMAT_CONTENT
, MyFrame::OnUpdateFormat
)
361 EVT_UPDATE_UI(ID_FORMAT_FONT
, MyFrame::OnUpdateFormat
)
362 EVT_UPDATE_UI(ID_FORMAT_IMAGE
, MyFrame::OnUpdateImage
)
363 EVT_UPDATE_UI(ID_FORMAT_PARAGRAPH
, MyFrame::OnUpdateFormat
)
364 EVT_MENU(ID_FORMAT_INDENT_MORE
, MyFrame::OnIndentMore
)
365 EVT_MENU(ID_FORMAT_INDENT_LESS
, MyFrame::OnIndentLess
)
367 EVT_MENU(ID_FORMAT_LINE_SPACING_HALF
, MyFrame::OnLineSpacingHalf
)
368 EVT_MENU(ID_FORMAT_LINE_SPACING_SINGLE
, MyFrame::OnLineSpacingSingle
)
369 EVT_MENU(ID_FORMAT_LINE_SPACING_DOUBLE
, MyFrame::OnLineSpacingDouble
)
371 EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_MORE
, MyFrame::OnParagraphSpacingMore
)
372 EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_LESS
, MyFrame::OnParagraphSpacingLess
)
374 EVT_MENU(ID_RELOAD
, MyFrame::OnReload
)
376 EVT_MENU(ID_INSERT_SYMBOL
, MyFrame::OnInsertSymbol
)
377 EVT_MENU(ID_INSERT_URL
, MyFrame::OnInsertURL
)
378 EVT_MENU(ID_INSERT_IMAGE
, MyFrame::OnInsertImage
)
380 EVT_MENU(ID_FORMAT_NUMBER_LIST
, MyFrame::OnNumberList
)
381 EVT_MENU(ID_FORMAT_BULLETS_AND_NUMBERING
, MyFrame::OnBulletsAndNumbering
)
382 EVT_MENU(ID_FORMAT_ITEMIZE_LIST
, MyFrame::OnItemizeList
)
383 EVT_MENU(ID_FORMAT_RENUMBER_LIST
, MyFrame::OnRenumberList
)
384 EVT_MENU(ID_FORMAT_PROMOTE_LIST
, MyFrame::OnPromoteList
)
385 EVT_MENU(ID_FORMAT_DEMOTE_LIST
, MyFrame::OnDemoteList
)
386 EVT_MENU(ID_FORMAT_CLEAR_LIST
, MyFrame::OnClearList
)
388 EVT_MENU(ID_VIEW_HTML
, MyFrame::OnViewHTML
)
389 EVT_MENU(ID_SWITCH_STYLE_SHEETS
, MyFrame::OnSwitchStyleSheets
)
390 EVT_MENU(ID_MANAGE_STYLES
, MyFrame::OnManageStyles
)
392 EVT_MENU(ID_PRINT
, MyFrame::OnPrint
)
393 EVT_MENU(ID_PREVIEW
, MyFrame::OnPreview
)
394 EVT_MENU(ID_PAGE_SETUP
, MyFrame::OnPageSetup
)
396 EVT_TEXT_URL(wxID_ANY
, MyFrame::OnURL
)
397 EVT_RICHTEXT_STYLESHEET_REPLACING(wxID_ANY
, MyFrame::OnStyleSheetReplacing
)
400 // Create a new application object: this macro will allow wxWidgets to create
401 // the application object during program execution (it's better than using a
402 // static object for many reasons) and also implements the accessor function
403 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
407 // ============================================================================
409 // ============================================================================
411 // ----------------------------------------------------------------------------
412 // the application class
413 // ----------------------------------------------------------------------------
415 // 'Main program' equivalent: the program execution "starts" here
418 if ( !wxApp::OnInit() )
422 wxHelpProvider::Set(new wxSimpleHelpProvider
);
425 m_styleSheet
= new wxRichTextStyleSheet
;
426 m_printing
= new wxRichTextPrinting(wxT("Test Document"));
428 m_printing
->SetFooterText(wxT("@TITLE@"), wxRICHTEXT_PAGE_ALL
, wxRICHTEXT_PAGE_CENTRE
);
429 m_printing
->SetFooterText(wxT("Page @PAGENUM@"), wxRICHTEXT_PAGE_ALL
, wxRICHTEXT_PAGE_RIGHT
);
433 MyRichTextCtrl::SetEnhancedDrawingHandler();
435 // Add extra handlers (plain text is automatically added)
436 wxRichTextBuffer::AddHandler(new wxRichTextXMLHandler
);
437 wxRichTextBuffer::AddHandler(new wxRichTextHTMLHandler
);
439 // Add image handlers
441 wxImage::AddHandler( new wxPNGHandler
);
445 wxImage::AddHandler( new wxJPEGHandler
);
449 wxImage::AddHandler( new wxGIFHandler
);
453 wxFileSystem::AddHandler( new wxMemoryFSHandler
);
456 // create the main application window
457 MyFrame
*frame
= new MyFrame(wxT("wxRichTextCtrl Sample"), wxID_ANY
, wxDefaultPosition
, wxSize(700, 600));
459 m_printing
->SetParentWindow(frame
);
461 // and show it (the frames, unlike simple controls, are not shown when
462 // created initially)
465 // success: wxApp::OnRun() will be called which will enter the main message
466 // loop and the application will run. If we returned false here, the
467 // application would exit immediately.
479 void MyApp::CreateStyles()
483 wxFont
romanFont(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
484 wxFont
swissFont(12, wxSWISS
, wxNORMAL
, wxNORMAL
);
486 wxRichTextParagraphStyleDefinition
* normalPara
= new wxRichTextParagraphStyleDefinition(wxT("Normal"));
487 wxRichTextAttr normalAttr
;
488 normalAttr
.SetFontFaceName(romanFont
.GetFaceName());
489 normalAttr
.SetFontSize(12);
490 // Let's set all attributes for this style
491 normalAttr
.SetFlags(wxTEXT_ATTR_FONT
| wxTEXT_ATTR_BACKGROUND_COLOUR
| wxTEXT_ATTR_TEXT_COLOUR
|wxTEXT_ATTR_ALIGNMENT
|wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
|wxTEXT_ATTR_TABS
|
492 wxTEXT_ATTR_PARA_SPACING_BEFORE
|wxTEXT_ATTR_PARA_SPACING_AFTER
|wxTEXT_ATTR_LINE_SPACING
|
493 wxTEXT_ATTR_BULLET_STYLE
|wxTEXT_ATTR_BULLET_NUMBER
);
494 normalPara
->SetStyle(normalAttr
);
496 m_styleSheet
->AddParagraphStyle(normalPara
);
498 wxRichTextParagraphStyleDefinition
* indentedPara
= new wxRichTextParagraphStyleDefinition(wxT("Indented"));
499 wxRichTextAttr indentedAttr
;
500 indentedAttr
.SetFontFaceName(romanFont
.GetFaceName());
501 indentedAttr
.SetFontSize(12);
502 indentedAttr
.SetLeftIndent(100, 0);
503 // We only want to affect indentation
504 indentedAttr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
);
505 indentedPara
->SetStyle(indentedAttr
);
507 m_styleSheet
->AddParagraphStyle(indentedPara
);
509 wxRichTextParagraphStyleDefinition
* indentedPara2
= new wxRichTextParagraphStyleDefinition(wxT("Red Bold Indented"));
510 wxRichTextAttr indentedAttr2
;
511 indentedAttr2
.SetFontFaceName(romanFont
.GetFaceName());
512 indentedAttr2
.SetFontSize(12);
513 indentedAttr2
.SetFontWeight(wxFONTWEIGHT_BOLD
);
514 indentedAttr2
.SetTextColour(*wxRED
);
515 indentedAttr2
.SetFontSize(12);
516 indentedAttr2
.SetLeftIndent(100, 0);
517 // We want to affect indentation, font and text colour
518 indentedAttr2
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
|wxTEXT_ATTR_FONT
|wxTEXT_ATTR_TEXT_COLOUR
);
519 indentedPara2
->SetStyle(indentedAttr2
);
521 m_styleSheet
->AddParagraphStyle(indentedPara2
);
523 wxRichTextParagraphStyleDefinition
* flIndentedPara
= new wxRichTextParagraphStyleDefinition(wxT("First Line Indented"));
524 wxRichTextAttr flIndentedAttr
;
525 flIndentedAttr
.SetFontFaceName(swissFont
.GetFaceName());
526 flIndentedAttr
.SetFontSize(12);
527 flIndentedAttr
.SetLeftIndent(100, -100);
528 // We only want to affect indentation
529 flIndentedAttr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
);
530 flIndentedPara
->SetStyle(flIndentedAttr
);
532 m_styleSheet
->AddParagraphStyle(flIndentedPara
);
536 wxRichTextCharacterStyleDefinition
* boldDef
= new wxRichTextCharacterStyleDefinition(wxT("Bold"));
537 wxRichTextAttr boldAttr
;
538 boldAttr
.SetFontFaceName(romanFont
.GetFaceName());
539 boldAttr
.SetFontSize(12);
540 boldAttr
.SetFontWeight(wxFONTWEIGHT_BOLD
);
541 // We only want to affect boldness
542 boldAttr
.SetFlags(wxTEXT_ATTR_FONT_WEIGHT
);
543 boldDef
->SetStyle(boldAttr
);
545 m_styleSheet
->AddCharacterStyle(boldDef
);
547 wxRichTextCharacterStyleDefinition
* italicDef
= new wxRichTextCharacterStyleDefinition(wxT("Italic"));
548 wxRichTextAttr italicAttr
;
549 italicAttr
.SetFontFaceName(romanFont
.GetFaceName());
550 italicAttr
.SetFontSize(12);
551 italicAttr
.SetFontStyle(wxFONTSTYLE_ITALIC
);
552 // We only want to affect italics
553 italicAttr
.SetFlags(wxTEXT_ATTR_FONT_ITALIC
);
554 italicDef
->SetStyle(italicAttr
);
556 m_styleSheet
->AddCharacterStyle(italicDef
);
558 wxRichTextCharacterStyleDefinition
* redDef
= new wxRichTextCharacterStyleDefinition(wxT("Red Bold"));
559 wxRichTextAttr redAttr
;
560 redAttr
.SetFontFaceName(romanFont
.GetFaceName());
561 redAttr
.SetFontSize(12);
562 redAttr
.SetFontWeight(wxFONTWEIGHT_BOLD
);
563 redAttr
.SetTextColour(*wxRED
);
564 // We only want to affect colour, weight and face
565 redAttr
.SetFlags(wxTEXT_ATTR_FONT_FACE
|wxTEXT_ATTR_FONT_WEIGHT
|wxTEXT_ATTR_TEXT_COLOUR
);
566 redDef
->SetStyle(redAttr
);
568 m_styleSheet
->AddCharacterStyle(redDef
);
570 wxRichTextListStyleDefinition
* bulletList
= new wxRichTextListStyleDefinition(wxT("Bullet List 1"));
572 for (i
= 0; i
< 10; i
++)
576 bulletText
= wxT("standard/circle");
578 bulletText
= wxT("standard/square");
580 bulletText
= wxT("standard/circle");
582 bulletText
= wxT("standard/square");
584 bulletText
= wxT("standard/circle");
586 bulletList
->SetAttributes(i
, (i
+1)*60, 60, wxTEXT_ATTR_BULLET_STYLE_STANDARD
, bulletText
);
589 m_styleSheet
->AddListStyle(bulletList
);
591 wxRichTextListStyleDefinition
* numberedList
= new wxRichTextListStyleDefinition(wxT("Numbered List 1"));
592 for (i
= 0; i
< 10; i
++)
596 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
598 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_LETTERS_LOWER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
600 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ROMAN_LOWER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
602 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ROMAN_UPPER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
604 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
606 numberStyle
|= wxTEXT_ATTR_BULLET_STYLE_ALIGN_RIGHT
;
608 numberedList
->SetAttributes(i
, (i
+1)*60, 60, numberStyle
);
611 m_styleSheet
->AddListStyle(numberedList
);
613 wxRichTextListStyleDefinition
* outlineList
= new wxRichTextListStyleDefinition(wxT("Outline List 1"));
614 for (i
= 0; i
< 10; i
++)
618 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_OUTLINE
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
620 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
622 outlineList
->SetAttributes(i
, (i
+1)*120, 120, numberStyle
);
625 m_styleSheet
->AddListStyle(outlineList
);
628 // ----------------------------------------------------------------------------
630 // ----------------------------------------------------------------------------
633 MyFrame::MyFrame(const wxString
& title
, wxWindowID id
, const wxPoint
& pos
,
634 const wxSize
& size
, long style
)
635 : wxFrame(NULL
, id
, title
, pos
, size
, style
)
637 // set the frame icon
638 SetIcon(wxICON(sample
));
641 wxMenu
*fileMenu
= new wxMenu
;
643 // the "About" item should be in the help menu
644 wxMenu
*helpMenu
= new wxMenu
;
645 helpMenu
->Append(ID_About
, wxT("&About\tF1"), wxT("Show about dialog"));
647 fileMenu
->Append(wxID_OPEN
, wxT("&Open\tCtrl+O"), wxT("Open a file"));
648 fileMenu
->Append(wxID_SAVE
, wxT("&Save\tCtrl+S"), wxT("Save a file"));
649 fileMenu
->Append(wxID_SAVEAS
, wxT("&Save As...\tF12"), wxT("Save to a new file"));
650 fileMenu
->AppendSeparator();
651 fileMenu
->Append(ID_RELOAD
, wxT("&Reload Text\tF2"), wxT("Reload the initial text"));
652 fileMenu
->AppendSeparator();
653 fileMenu
->Append(ID_PAGE_SETUP
, wxT("Page Set&up..."), wxT("Page setup"));
654 fileMenu
->Append(ID_PRINT
, wxT("&Print...\tCtrl+P"), wxT("Print"));
655 fileMenu
->Append(ID_PREVIEW
, wxT("Print Pre&view"), wxT("Print preview"));
656 fileMenu
->AppendSeparator();
657 fileMenu
->Append(ID_VIEW_HTML
, wxT("&View as HTML"), wxT("View HTML"));
658 fileMenu
->AppendSeparator();
659 fileMenu
->Append(ID_Quit
, wxT("E&xit\tAlt+X"), wxT("Quit this program"));
661 wxMenu
* editMenu
= new wxMenu
;
662 editMenu
->Append(wxID_UNDO
, _("&Undo\tCtrl+Z"));
663 editMenu
->Append(wxID_REDO
, _("&Redo\tCtrl+Y"));
664 editMenu
->AppendSeparator();
665 editMenu
->Append(wxID_CUT
, _("Cu&t\tCtrl+X"));
666 editMenu
->Append(wxID_COPY
, _("&Copy\tCtrl+C"));
667 editMenu
->Append(wxID_PASTE
, _("&Paste\tCtrl+V"));
669 editMenu
->AppendSeparator();
670 editMenu
->Append(wxID_SELECTALL
, _("Select A&ll\tCtrl+A"));
672 editMenu
->AppendSeparator();
673 editMenu
->Append(wxID_FIND
, _("&Find...\tCtrl+F"));
674 editMenu
->Append(stID_FIND_REPLACE
, _("&Replace...\tCtrl+R"));
677 wxMenu
* formatMenu
= new wxMenu
;
678 formatMenu
->AppendCheckItem(ID_FORMAT_BOLD
, _("&Bold\tCtrl+B"));
679 formatMenu
->AppendCheckItem(ID_FORMAT_ITALIC
, _("&Italic\tCtrl+I"));
680 formatMenu
->AppendCheckItem(ID_FORMAT_UNDERLINE
, _("&Underline\tCtrl+U"));
681 formatMenu
->AppendSeparator();
682 formatMenu
->AppendCheckItem(ID_FORMAT_STRIKETHROUGH
, _("Stri&kethrough"));
683 formatMenu
->AppendCheckItem(ID_FORMAT_SUPERSCRIPT
, _("Superscrip&t"));
684 formatMenu
->AppendCheckItem(ID_FORMAT_SUBSCRIPT
, _("Subscrip&t"));
685 formatMenu
->AppendSeparator();
686 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_LEFT
, _("L&eft Align"));
687 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_RIGHT
, _("&Right Align"));
688 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_CENTRE
, _("&Centre"));
689 formatMenu
->AppendSeparator();
690 formatMenu
->Append(ID_FORMAT_INDENT_MORE
, _("Indent &More"));
691 formatMenu
->Append(ID_FORMAT_INDENT_LESS
, _("Indent &Less"));
692 formatMenu
->AppendSeparator();
693 formatMenu
->Append(ID_FORMAT_PARAGRAPH_SPACING_MORE
, _("Increase Paragraph &Spacing"));
694 formatMenu
->Append(ID_FORMAT_PARAGRAPH_SPACING_LESS
, _("Decrease &Paragraph Spacing"));
695 formatMenu
->AppendSeparator();
696 formatMenu
->Append(ID_FORMAT_LINE_SPACING_SINGLE
, _("Normal Line Spacing"));
697 formatMenu
->Append(ID_FORMAT_LINE_SPACING_HALF
, _("1.5 Line Spacing"));
698 formatMenu
->Append(ID_FORMAT_LINE_SPACING_DOUBLE
, _("Double Line Spacing"));
699 formatMenu
->AppendSeparator();
700 formatMenu
->Append(ID_FORMAT_FONT
, _("&Font..."));
701 formatMenu
->Append(ID_FORMAT_IMAGE
, _("Image Property"));
702 formatMenu
->Append(ID_FORMAT_PARAGRAPH
, _("&Paragraph..."));
703 formatMenu
->Append(ID_FORMAT_CONTENT
, _("Font and Pa&ragraph...\tShift+Ctrl+F"));
704 formatMenu
->AppendSeparator();
705 formatMenu
->Append(ID_SWITCH_STYLE_SHEETS
, _("&Switch Style Sheets"));
706 formatMenu
->Append(ID_MANAGE_STYLES
, _("&Manage Styles"));
708 wxMenu
* listsMenu
= new wxMenu
;
709 listsMenu
->Append(ID_FORMAT_BULLETS_AND_NUMBERING
, _("Bullets and &Numbering..."));
710 listsMenu
->AppendSeparator();
711 listsMenu
->Append(ID_FORMAT_NUMBER_LIST
, _("Number List"));
712 listsMenu
->Append(ID_FORMAT_ITEMIZE_LIST
, _("Itemize List"));
713 listsMenu
->Append(ID_FORMAT_RENUMBER_LIST
, _("Renumber List"));
714 listsMenu
->Append(ID_FORMAT_PROMOTE_LIST
, _("Promote List Items"));
715 listsMenu
->Append(ID_FORMAT_DEMOTE_LIST
, _("Demote List Items"));
716 listsMenu
->Append(ID_FORMAT_CLEAR_LIST
, _("Clear List Formatting"));
718 wxMenu
* insertMenu
= new wxMenu
;
719 insertMenu
->Append(ID_INSERT_SYMBOL
, _("&Symbol...\tCtrl+I"));
720 insertMenu
->Append(ID_INSERT_URL
, _("&URL..."));
721 insertMenu
->Append(ID_INSERT_IMAGE
, _("&Image..."));
723 // now append the freshly created menu to the menu bar...
724 wxMenuBar
*menuBar
= new wxMenuBar();
725 menuBar
->Append(fileMenu
, wxT("&File"));
726 menuBar
->Append(editMenu
, wxT("&Edit"));
727 menuBar
->Append(formatMenu
, wxT("F&ormat"));
728 menuBar
->Append(listsMenu
, wxT("&Lists"));
729 menuBar
->Append(insertMenu
, wxT("&Insert"));
730 menuBar
->Append(helpMenu
, wxT("&Help"));
732 // ... and attach this menu bar to the frame
735 // create a status bar just for fun (by default with 1 pane only)
736 // but don't create it on limited screen space (WinCE)
737 bool is_pda
= wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA
;
743 SetStatusText(wxT("Welcome to wxRichTextCtrl!"));
747 wxToolBar
* toolBar
= CreateToolBar();
749 toolBar
->AddTool(wxID_OPEN
, wxEmptyString
, wxBitmap(open_xpm
), _("Open"));
750 toolBar
->AddTool(wxID_SAVEAS
, wxEmptyString
, wxBitmap(save_xpm
), _("Save"));
751 toolBar
->AddSeparator();
752 toolBar
->AddTool(wxID_CUT
, wxEmptyString
, wxBitmap(cut_xpm
), _("Cut"));
753 toolBar
->AddTool(wxID_COPY
, wxEmptyString
, wxBitmap(copy_xpm
), _("Copy"));
754 toolBar
->AddTool(wxID_PASTE
, wxEmptyString
, wxBitmap(paste_xpm
), _("Paste"));
755 toolBar
->AddSeparator();
756 toolBar
->AddTool(wxID_UNDO
, wxEmptyString
, wxBitmap(undo_xpm
), _("Undo"));
757 toolBar
->AddTool(wxID_REDO
, wxEmptyString
, wxBitmap(redo_xpm
), _("Redo"));
758 toolBar
->AddSeparator();
759 toolBar
->AddCheckTool(ID_FORMAT_BOLD
, wxEmptyString
, wxBitmap(bold_xpm
), wxNullBitmap
, _("Bold"));
760 toolBar
->AddCheckTool(ID_FORMAT_ITALIC
, wxEmptyString
, wxBitmap(italic_xpm
), wxNullBitmap
, _("Italic"));
761 toolBar
->AddCheckTool(ID_FORMAT_UNDERLINE
, wxEmptyString
, wxBitmap(underline_xpm
), wxNullBitmap
, _("Underline"));
762 toolBar
->AddSeparator();
763 toolBar
->AddCheckTool(ID_FORMAT_ALIGN_LEFT
, wxEmptyString
, wxBitmap(alignleft_xpm
), wxNullBitmap
, _("Align Left"));
764 toolBar
->AddCheckTool(ID_FORMAT_ALIGN_CENTRE
, wxEmptyString
, wxBitmap(centre_xpm
), wxNullBitmap
, _("Centre"));
765 toolBar
->AddCheckTool(ID_FORMAT_ALIGN_RIGHT
, wxEmptyString
, wxBitmap(alignright_xpm
), wxNullBitmap
, _("Align Right"));
766 toolBar
->AddSeparator();
767 toolBar
->AddTool(ID_FORMAT_INDENT_LESS
, wxEmptyString
, wxBitmap(indentless_xpm
), _("Indent Less"));
768 toolBar
->AddTool(ID_FORMAT_INDENT_MORE
, wxEmptyString
, wxBitmap(indentmore_xpm
), _("Indent More"));
769 toolBar
->AddSeparator();
770 toolBar
->AddTool(ID_FORMAT_FONT
, wxEmptyString
, wxBitmap(font_xpm
), _("Font"));
771 toolBar
->AddTool(ID_FORMAT_IMAGE
, wxString("Im"), wxBitmap(font_xpm
), _("Image Property"));
773 wxRichTextStyleComboCtrl
* combo
= new wxRichTextStyleComboCtrl(toolBar
, ID_RICHTEXT_STYLE_COMBO
, wxDefaultPosition
, wxSize(200, -1));
774 toolBar
->AddControl(combo
);
778 wxSplitterWindow
* splitter
= new wxSplitterWindow(this, wxID_ANY
, wxDefaultPosition
, GetClientSize(), wxSP_LIVE_UPDATE
);
780 wxFont textFont
= wxFont(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
781 wxFont boldFont
= wxFont(12, wxROMAN
, wxNORMAL
, wxBOLD
);
782 wxFont italicFont
= wxFont(12, wxROMAN
, wxITALIC
, wxNORMAL
);
784 m_richTextCtrl
= new MyRichTextCtrl(splitter
, ID_RICHTEXT_CTRL
, wxEmptyString
, wxDefaultPosition
, wxSize(200, 200), wxVSCROLL
|wxHSCROLL
|wxWANTS_CHARS
);
785 wxFont
font(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
787 m_richTextCtrl
->SetFont(font
);
789 m_richTextCtrl
->SetMargins(10, 10);
791 m_richTextCtrl
->SetStyleSheet(wxGetApp().GetStyleSheet());
793 combo
->SetStyleSheet(wxGetApp().GetStyleSheet());
794 combo
->SetRichTextCtrl(m_richTextCtrl
);
795 combo
->UpdateStyles();
797 wxRichTextStyleListCtrl
* styleListCtrl
= new wxRichTextStyleListCtrl(splitter
, ID_RICHTEXT_STYLE_LIST
);
799 wxSize display
= wxGetDisplaySize();
800 if ( is_pda
&& ( display
.GetWidth() < display
.GetHeight() ) )
802 splitter
->SplitHorizontally(m_richTextCtrl
, styleListCtrl
);
806 splitter
->SplitVertically(m_richTextCtrl
, styleListCtrl
, 500);
809 splitter
->UpdateSize();
811 styleListCtrl
->SetStyleSheet(wxGetApp().GetStyleSheet());
812 styleListCtrl
->SetRichTextCtrl(m_richTextCtrl
);
813 styleListCtrl
->UpdateStyles();
819 void MyFrame::WriteInitialText()
821 MyRichTextCtrl
& r
= *m_richTextCtrl
;
823 r
.SetDefaultStyle(wxRichTextAttr());
825 // Add some locked content first - needs Undo to be enabled
828 r
.WriteText(wxString(wxT("This is a locked object.")));
831 r
.WriteText(wxString(wxT(" This is unlocked text. ")));
834 r
.WriteText(wxString(wxT("More locked content.")));
838 // Flush the Undo buffer
839 r
.GetCommandProcessor()->ClearCommands();
842 r
.BeginSuppressUndo();
846 r
.BeginParagraphSpacing(0, 20);
848 r
.BeginAlignment(wxTEXT_ALIGNMENT_CENTRE
);
853 wxString lineBreak
= (wxChar
) 29;
855 r
.WriteText(wxString(wxT("Welcome to wxRichTextCtrl, a wxWidgets control")) + lineBreak
+ wxT("for editing and presenting styled text and images\n"));
859 r
.WriteText(wxT("by Julian Smart"));
865 r
.WriteImage(wxBitmap(zebra_xpm
));
872 r
.BeginAlignment(wxTEXT_ALIGNMENT_LEFT
);
873 wxRichTextAttr imageAttr
;
874 imageAttr
.GetTextBoxAttr().SetFloatMode(wxTEXT_BOX_ATTR_FLOAT_LEFT
);
875 r
.WriteText(wxString(wxT("This is a simple test for a floating left image test. The zebra image should be placed at the left side of the current buffer and all the text should flow around it at the right side. This is a simple test for a floating left image test. The zebra image should be placed at the left side of the current buffer and all the text should flow around it at the right side. This is a simple test for a floating left image test. The zebra image should be placed at the left side of the current buffer and all the text should flow around it at the right side.")));
876 r
.WriteImage(wxBitmap(zebra_xpm
), wxBITMAP_TYPE_PNG
, imageAttr
);
878 imageAttr
.GetTextBoxAttr().GetTop().SetValue(200);
879 imageAttr
.GetTextBoxAttr().GetTop().SetUnits(wxTEXT_ATTR_UNITS_PIXELS
);
880 imageAttr
.GetTextBoxAttr().SetFloatMode(wxTEXT_BOX_ATTR_FLOAT_RIGHT
);
881 r
.WriteImage(wxBitmap(zebra_xpm
), wxBITMAP_TYPE_PNG
, imageAttr
);
882 r
.WriteText(wxString(wxT("This is a simple test for a floating right image test. The zebra image should be placed at the right side of the current buffer and all the text should flow around it at the left side. This is a simple test for a floating left image test. The zebra image should be placed at the right side of the current buffer and all the text should flow around it at the left side. This is a simple test for a floating left image test. The zebra image should be placed at the right side of the current buffer and all the text should flow around it at the left side.")));
886 r
.WriteText(wxT("What can you do with this thing? "));
888 r
.WriteImage(wxBitmap(smiley_xpm
));
889 r
.WriteText(wxT(" Well, you can change text "));
891 r
.BeginTextColour(wxColour(255, 0, 0));
892 r
.WriteText(wxT("colour, like this red bit."));
895 wxRichTextAttr backgroundColourAttr
;
896 backgroundColourAttr
.SetBackgroundColour(*wxGREEN
);
897 backgroundColourAttr
.SetTextColour(wxColour(0, 0, 255));
898 r
.BeginStyle(backgroundColourAttr
);
899 r
.WriteText(wxT(" And this blue on green bit."));
902 r
.WriteText(wxT(" Naturally you can make things "));
904 r
.WriteText(wxT("bold "));
907 r
.WriteText(wxT("or italic "));
910 r
.WriteText(wxT("or underlined."));
914 r
.WriteText(wxT(" Different font sizes on the same line is allowed, too."));
917 r
.WriteText(wxT(" Next we'll show an indented paragraph."));
921 r
.BeginLeftIndent(60);
922 r
.WriteText(wxT("It was in January, the most down-trodden month of an Edinburgh winter. An attractive woman came into the cafe, which is nothing remarkable."));
927 r
.WriteText(wxT("Next, we'll show a first-line indent, achieved using BeginLeftIndent(100, -40)."));
931 r
.BeginLeftIndent(100, -40);
933 r
.WriteText(wxT("It was in January, the most down-trodden month of an Edinburgh winter. An attractive woman came into the cafe, which is nothing remarkable."));
938 r
.WriteText(wxT("Numbered bullets are possible, again using subindents:"));
941 r
.BeginNumberedBullet(1, 100, 60);
942 r
.WriteText(wxT("This is my first item. Note that wxRichTextCtrl can apply numbering and bullets automatically based on list styles, but this list is formatted explicitly by setting indents."));
944 r
.EndNumberedBullet();
946 r
.BeginNumberedBullet(2, 100, 60);
947 r
.WriteText(wxT("This is my second item."));
949 r
.EndNumberedBullet();
951 r
.WriteText(wxT("The following paragraph is right-indented:"));
954 r
.BeginRightIndent(200);
956 r
.WriteText(wxT("It was in January, the most down-trodden month of an Edinburgh winter. An attractive woman came into the cafe, which is nothing remarkable."));
961 r
.WriteText(wxT("The following paragraph is right-aligned with 1.5 line spacing:"));
964 r
.BeginAlignment(wxTEXT_ALIGNMENT_RIGHT
);
965 r
.BeginLineSpacing(wxTEXT_ATTR_LINE_SPACING_HALF
);
966 r
.WriteText(wxT("It was in January, the most down-trodden month of an Edinburgh winter. An attractive woman came into the cafe, which is nothing remarkable."));
977 attr
.SetFlags(wxTEXT_ATTR_TABS
);
979 r
.SetDefaultStyle(attr
);
981 r
.WriteText(wxT("This line contains tabs:\tFirst tab\tSecond tab\tThird tab"));
984 r
.WriteText(wxT("Other notable features of wxRichTextCtrl include:"));
987 r
.BeginSymbolBullet(wxT('*'), 100, 60);
988 r
.WriteText(wxT("Compatibility with wxTextCtrl API"));
992 r
.BeginSymbolBullet(wxT('*'), 100, 60);
993 r
.WriteText(wxT("Easy stack-based BeginXXX()...EndXXX() style setting in addition to SetStyle()"));
997 r
.BeginSymbolBullet(wxT('*'), 100, 60);
998 r
.WriteText(wxT("XML loading and saving"));
1000 r
.EndSymbolBullet();
1002 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1003 r
.WriteText(wxT("Undo/Redo, with batching option and Undo suppressing"));
1005 r
.EndSymbolBullet();
1007 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1008 r
.WriteText(wxT("Clipboard copy and paste"));
1010 r
.EndSymbolBullet();
1012 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1013 r
.WriteText(wxT("wxRichTextStyleSheet with named character and paragraph styles, and control for applying named styles"));
1015 r
.EndSymbolBullet();
1017 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1018 r
.WriteText(wxT("A design that can easily be extended to other content types, ultimately with text boxes, tables, controls, and so on"));
1020 r
.EndSymbolBullet();
1022 // Make a style suitable for showing a URL
1023 wxRichTextAttr urlStyle
;
1024 urlStyle
.SetTextColour(*wxBLUE
);
1025 urlStyle
.SetFontUnderlined(true);
1027 r
.WriteText(wxT("wxRichTextCtrl can also display URLs, such as this one: "));
1028 r
.BeginStyle(urlStyle
);
1029 r
.BeginURL(wxT("http://www.wxwidgets.org"));
1030 r
.WriteText(wxT("The wxWidgets Web Site"));
1033 r
.WriteText(wxT(". Click on the URL to generate an event."));
1037 r
.WriteText(wxT("Note: this sample content was generated programmatically from within the MyFrame constructor in the demo. The images were loaded from inline XPMs. Enjoy wxRichTextCtrl!\n"));
1039 r
.EndParagraphSpacing();
1047 wxRichTextAttr attr
;
1048 attr
.GetTextBoxAttr().GetMargins().GetLeft().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS
);
1049 attr
.GetTextBoxAttr().GetMargins().GetTop().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS
);
1050 attr
.GetTextBoxAttr().GetMargins().GetRight().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS
);
1051 attr
.GetTextBoxAttr().GetMargins().GetBottom().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS
);
1053 attr
.GetTextBoxAttr().GetBorder().SetColour(*wxBLACK
);
1054 attr
.GetTextBoxAttr().GetBorder().SetWidth(1, wxTEXT_ATTR_UNITS_PIXELS
);
1055 attr
.GetTextBoxAttr().GetBorder().SetStyle(wxTEXT_BOX_ATTR_BORDER_SOLID
);
1057 wxRichTextBox
* textBox
= r
.WriteTextBox(attr
);
1058 r
.SetFocusObject(textBox
);
1060 r
.WriteText(wxT("This is a text box. Just testing! Once more unto the breach, dear friends, once more..."));
1062 r
.SetFocusObject(NULL
); // Set the focus back to the main buffer
1063 r
.SetInsertionPointEnd();
1072 wxRichTextAttr attr
;
1073 attr
.GetTextBoxAttr().GetMargins().GetLeft().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS
);
1074 attr
.GetTextBoxAttr().GetMargins().GetTop().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS
);
1075 attr
.GetTextBoxAttr().GetMargins().GetRight().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS
);
1076 attr
.GetTextBoxAttr().GetMargins().GetBottom().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS
);
1077 attr
.GetTextBoxAttr().GetPadding() = attr
.GetTextBoxAttr().GetMargins();
1079 attr
.GetTextBoxAttr().GetBorder().SetColour(*wxBLACK
);
1080 attr
.GetTextBoxAttr().GetBorder().SetWidth(1, wxTEXT_ATTR_UNITS_PIXELS
);
1081 attr
.GetTextBoxAttr().GetBorder().SetStyle(wxTEXT_BOX_ATTR_BORDER_SOLID
);
1083 wxRichTextAttr cellAttr
= attr
;
1084 cellAttr
.GetTextBoxAttr().GetWidth().SetValue(200, wxTEXT_ATTR_UNITS_PIXELS
);
1085 cellAttr
.GetTextBoxAttr().GetHeight().SetValue(150, wxTEXT_ATTR_UNITS_PIXELS
);
1087 wxRichTextTable
* table
= r
.WriteTable(3, 2, attr
, cellAttr
);
1089 for (j
= 0; j
< table
->GetRowCount(); j
++)
1091 for (i
= 0; i
< table
->GetColumnCount(); i
++)
1093 wxString msg
= wxString::Format(wxT("This is cell %d, %d"), (j
+1), (i
+1));
1094 r
.SetFocusObject(table
->GetCell(j
, i
));
1098 r
.SetFocusObject(NULL
); // Set the focus back to the main buffer
1099 r
.SetInsertionPointEnd();
1105 r
.EndSuppressUndo();
1110 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
1112 // true is to force the frame to close
1116 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
1119 msg
.Printf( wxT("This is a demo for wxRichTextCtrl, a control for editing styled text.\n(c) Julian Smart, 2005"));
1120 wxMessageBox(msg
, wxT("About wxRichTextCtrl Sample"), wxOK
| wxICON_INFORMATION
, this);
1123 // Forward command events to the current rich text control, if any
1124 bool MyFrame::ProcessEvent(wxEvent
& event
)
1126 if (event
.IsCommandEvent() && !event
.IsKindOf(CLASSINFO(wxChildFocusEvent
)))
1128 // Problem: we can get infinite recursion because the events
1129 // climb back up to this frame, and repeat.
1130 // Assume that command events don't cause another command event
1131 // to be called, so we can rely on inCommand not being overwritten
1133 static int s_eventType
= 0;
1134 static wxWindowID s_id
= 0;
1136 if (s_id
!= event
.GetId() && s_eventType
!= event
.GetEventType())
1138 s_eventType
= event
.GetEventType();
1139 s_id
= event
.GetId();
1141 wxWindow
* focusWin
= wxFindFocusDescendant(this);
1142 if (focusWin
&& focusWin
->GetEventHandler()->ProcessEvent(event
))
1159 return wxFrame::ProcessEvent(event
);
1162 void MyFrame::OnOpen(wxCommandEvent
& WXUNUSED(event
))
1166 wxArrayInt fileTypes
;
1168 wxString filter
= wxRichTextBuffer::GetExtWildcard(false, false, & fileTypes
);
1169 if (!filter
.empty())
1171 filter
+= wxT("All files (*.*)|*.*");
1173 wxFileDialog
dialog(this,
1174 _("Choose a filename"),
1180 if (dialog
.ShowModal() == wxID_OK
)
1182 wxString path
= dialog
.GetPath();
1186 int filterIndex
= dialog
.GetFilterIndex();
1187 int fileType
= (filterIndex
< (int) fileTypes
.GetCount())
1188 ? fileTypes
[filterIndex
]
1189 : wxRICHTEXT_TYPE_TEXT
;
1190 m_richTextCtrl
->LoadFile(path
, fileType
);
1195 void MyFrame::OnSave(wxCommandEvent
& event
)
1197 if (m_richTextCtrl
->GetFilename().empty())
1202 m_richTextCtrl
->SaveFile();
1205 void MyFrame::OnSaveAs(wxCommandEvent
& WXUNUSED(event
))
1207 wxString filter
= wxRichTextBuffer::GetExtWildcard(false, true);
1211 wxFileDialog
dialog(this,
1212 _("Choose a filename"),
1218 if (dialog
.ShowModal() == wxID_OK
)
1220 wxString path
= dialog
.GetPath();
1225 wxStopWatch stopwatch
;
1227 m_richTextCtrl
->SaveFile(path
);
1229 long t
= stopwatch
.Time();
1230 wxLogDebug(wxT("Saving took %ldms"), t
);
1231 wxMessageBox(wxString::Format(wxT("Saving took %ldms"), t
));
1236 void MyFrame::OnBold(wxCommandEvent
& WXUNUSED(event
))
1238 m_richTextCtrl
->ApplyBoldToSelection();
1241 void MyFrame::OnItalic(wxCommandEvent
& WXUNUSED(event
))
1243 m_richTextCtrl
->ApplyItalicToSelection();
1246 void MyFrame::OnUnderline(wxCommandEvent
& WXUNUSED(event
))
1248 m_richTextCtrl
->ApplyUnderlineToSelection();
1251 void MyFrame::OnStrikethrough(wxCommandEvent
& WXUNUSED(event
))
1253 m_richTextCtrl
->ApplyTextEffectToSelection(wxTEXT_ATTR_EFFECT_STRIKETHROUGH
);
1256 void MyFrame::OnSuperscript(wxCommandEvent
& WXUNUSED(event
))
1258 m_richTextCtrl
->ApplyTextEffectToSelection(wxTEXT_ATTR_EFFECT_SUPERSCRIPT
);
1261 void MyFrame::OnSubscript(wxCommandEvent
& WXUNUSED(event
))
1263 m_richTextCtrl
->ApplyTextEffectToSelection(wxTEXT_ATTR_EFFECT_SUBSCRIPT
);
1267 void MyFrame::OnUpdateBold(wxUpdateUIEvent
& event
)
1269 event
.Check(m_richTextCtrl
->IsSelectionBold());
1272 void MyFrame::OnUpdateItalic(wxUpdateUIEvent
& event
)
1274 event
.Check(m_richTextCtrl
->IsSelectionItalics());
1277 void MyFrame::OnUpdateUnderline(wxUpdateUIEvent
& event
)
1279 event
.Check(m_richTextCtrl
->IsSelectionUnderlined());
1282 void MyFrame::OnUpdateStrikethrough(wxUpdateUIEvent
& event
)
1284 event
.Check(m_richTextCtrl
->DoesSelectionHaveTextEffectFlag(wxTEXT_ATTR_EFFECT_STRIKETHROUGH
));
1287 void MyFrame::OnUpdateSuperscript(wxUpdateUIEvent
& event
)
1289 event
.Check(m_richTextCtrl
->DoesSelectionHaveTextEffectFlag(wxTEXT_ATTR_EFFECT_SUPERSCRIPT
));
1292 void MyFrame::OnUpdateSubscript(wxUpdateUIEvent
& event
)
1294 event
.Check(m_richTextCtrl
->DoesSelectionHaveTextEffectFlag(wxTEXT_ATTR_EFFECT_SUBSCRIPT
));
1297 void MyFrame::OnAlignLeft(wxCommandEvent
& WXUNUSED(event
))
1299 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_LEFT
);
1302 void MyFrame::OnAlignCentre(wxCommandEvent
& WXUNUSED(event
))
1304 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_CENTRE
);
1307 void MyFrame::OnAlignRight(wxCommandEvent
& WXUNUSED(event
))
1309 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_RIGHT
);
1312 void MyFrame::OnUpdateAlignLeft(wxUpdateUIEvent
& event
)
1314 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_LEFT
));
1317 void MyFrame::OnUpdateAlignCentre(wxUpdateUIEvent
& event
)
1319 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_CENTRE
));
1322 void MyFrame::OnUpdateAlignRight(wxUpdateUIEvent
& event
)
1324 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_RIGHT
));
1327 void MyFrame::OnFont(wxCommandEvent
& WXUNUSED(event
))
1329 wxRichTextRange range
;
1330 if (m_richTextCtrl
->HasSelection())
1331 range
= m_richTextCtrl
->GetSelectionRange();
1333 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1335 int pages
= wxRICHTEXT_FORMAT_FONT
;
1337 wxRichTextFormattingDialog
formatDlg(pages
, this);
1338 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1340 if (formatDlg
.ShowModal() == wxID_OK
)
1342 formatDlg
.ApplyStyle(m_richTextCtrl
, range
, wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_OPTIMIZE
|wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY
);
1345 // Old method using wxFontDialog
1347 if (!m_richTextCtrl
->HasSelection())
1350 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1351 wxFontData fontData
;
1353 wxRichTextAttr attr
;
1354 attr
.SetFlags(wxTEXT_ATTR_FONT
);
1356 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1357 fontData
.SetInitialFont(attr
.GetFont());
1359 wxFontDialog
dialog(this, fontData
);
1360 if (dialog
.ShowModal() == wxID_OK
)
1362 fontData
= dialog
.GetFontData();
1363 attr
.SetFlags(wxTEXT_ATTR_FONT
);
1364 attr
.SetFont(fontData
.GetChosenFont());
1365 if (attr
.GetFont().IsOk())
1367 m_richTextCtrl
->SetStyle(range
, attr
);
1373 void MyFrame::OnImage(wxCommandEvent
& WXUNUSED(event
))
1375 wxRichTextRange range
;
1376 wxASSERT(m_richTextCtrl
->HasSelection());
1378 range
= m_richTextCtrl
->GetSelectionRange();
1379 wxASSERT(range
.ToInternal().GetLength() == 1);
1381 wxRichTextImage
* image
= wxDynamicCast(m_richTextCtrl
->GetFocusObject()->GetLeafObjectAtPosition(range
.GetStart()), wxRichTextImage
);
1384 wxRichTextObjectPropertiesDialog
imageDlg(image
, this);
1386 if (imageDlg
.ShowModal() == wxID_OK
)
1388 imageDlg
.ApplyStyle(m_richTextCtrl
);
1393 void MyFrame::OnParagraph(wxCommandEvent
& WXUNUSED(event
))
1395 wxRichTextRange range
;
1396 if (m_richTextCtrl
->HasSelection())
1397 range
= m_richTextCtrl
->GetSelectionRange();
1399 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1401 int pages
= wxRICHTEXT_FORMAT_INDENTS_SPACING
|wxRICHTEXT_FORMAT_TABS
|wxRICHTEXT_FORMAT_BULLETS
;
1403 wxRichTextFormattingDialog
formatDlg(pages
, this);
1404 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1406 if (formatDlg
.ShowModal() == wxID_OK
)
1408 formatDlg
.ApplyStyle(m_richTextCtrl
, range
);
1412 void MyFrame::OnFormat(wxCommandEvent
& WXUNUSED(event
))
1414 wxRichTextRange range
;
1415 if (m_richTextCtrl
->HasSelection())
1416 range
= m_richTextCtrl
->GetSelectionRange();
1418 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1420 int pages
= wxRICHTEXT_FORMAT_FONT
|wxRICHTEXT_FORMAT_INDENTS_SPACING
|wxRICHTEXT_FORMAT_TABS
|wxRICHTEXT_FORMAT_BULLETS
;
1422 wxRichTextFormattingDialog
formatDlg(pages
, this);
1423 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1425 if (formatDlg
.ShowModal() == wxID_OK
)
1427 formatDlg
.ApplyStyle(m_richTextCtrl
, range
);
1431 void MyFrame::OnUpdateFormat(wxUpdateUIEvent
& event
)
1433 event
.Enable(m_richTextCtrl
->HasSelection());
1436 void MyFrame::OnUpdateImage(wxUpdateUIEvent
& event
)
1438 wxRichTextRange range
;
1439 wxRichTextObject
*obj
;
1441 range
= m_richTextCtrl
->GetSelectionRange();
1442 if (range
.ToInternal().GetLength() == 1)
1444 obj
= m_richTextCtrl
->GetFocusObject()->GetLeafObjectAtPosition(range
.GetStart());
1445 if (obj
&& obj
->IsKindOf(CLASSINFO(wxRichTextImage
)))
1452 event
.Enable(false);
1455 void MyFrame::OnIndentMore(wxCommandEvent
& WXUNUSED(event
))
1457 wxRichTextAttr attr
;
1458 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1460 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1462 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1463 if (m_richTextCtrl
->HasSelection())
1464 range
= m_richTextCtrl
->GetSelectionRange();
1466 attr
.SetLeftIndent(attr
.GetLeftIndent() + 100);
1468 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1469 m_richTextCtrl
->SetStyle(range
, attr
);
1473 void MyFrame::OnIndentLess(wxCommandEvent
& WXUNUSED(event
))
1475 wxRichTextAttr attr
;
1476 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1478 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1480 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1481 if (m_richTextCtrl
->HasSelection())
1482 range
= m_richTextCtrl
->GetSelectionRange();
1484 if (attr
.GetLeftIndent() > 0)
1486 attr
.SetLeftIndent(wxMax(0, attr
.GetLeftIndent() - 100));
1488 m_richTextCtrl
->SetStyle(range
, attr
);
1493 void MyFrame::OnLineSpacingHalf(wxCommandEvent
& WXUNUSED(event
))
1495 wxRichTextAttr attr
;
1496 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1498 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1500 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1501 if (m_richTextCtrl
->HasSelection())
1502 range
= m_richTextCtrl
->GetSelectionRange();
1504 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1505 attr
.SetLineSpacing(15);
1507 m_richTextCtrl
->SetStyle(range
, attr
);
1511 void MyFrame::OnLineSpacingDouble(wxCommandEvent
& WXUNUSED(event
))
1513 wxRichTextAttr attr
;
1514 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1516 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1518 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1519 if (m_richTextCtrl
->HasSelection())
1520 range
= m_richTextCtrl
->GetSelectionRange();
1522 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1523 attr
.SetLineSpacing(20);
1525 m_richTextCtrl
->SetStyle(range
, attr
);
1529 void MyFrame::OnLineSpacingSingle(wxCommandEvent
& WXUNUSED(event
))
1531 wxRichTextAttr attr
;
1532 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1534 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1536 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1537 if (m_richTextCtrl
->HasSelection())
1538 range
= m_richTextCtrl
->GetSelectionRange();
1540 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1541 attr
.SetLineSpacing(0); // Can also use 10
1543 m_richTextCtrl
->SetStyle(range
, attr
);
1547 void MyFrame::OnParagraphSpacingMore(wxCommandEvent
& WXUNUSED(event
))
1549 wxRichTextAttr attr
;
1550 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1552 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1554 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1555 if (m_richTextCtrl
->HasSelection())
1556 range
= m_richTextCtrl
->GetSelectionRange();
1558 attr
.SetParagraphSpacingAfter(attr
.GetParagraphSpacingAfter() + 20);
1560 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1561 m_richTextCtrl
->SetStyle(range
, attr
);
1565 void MyFrame::OnParagraphSpacingLess(wxCommandEvent
& WXUNUSED(event
))
1567 wxRichTextAttr attr
;
1568 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1570 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1572 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1573 if (m_richTextCtrl
->HasSelection())
1574 range
= m_richTextCtrl
->GetSelectionRange();
1576 if (attr
.GetParagraphSpacingAfter() >= 20)
1578 attr
.SetParagraphSpacingAfter(attr
.GetParagraphSpacingAfter() - 20);
1580 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1581 m_richTextCtrl
->SetStyle(range
, attr
);
1586 void MyFrame::OnReload(wxCommandEvent
& WXUNUSED(event
))
1588 m_richTextCtrl
->Clear();
1592 void MyFrame::OnViewHTML(wxCommandEvent
& WXUNUSED(event
))
1594 wxDialog
dialog(this, wxID_ANY
, _("HTML"), wxDefaultPosition
, wxSize(500, 400), wxDEFAULT_DIALOG_STYLE
);
1596 wxBoxSizer
* boxSizer
= new wxBoxSizer(wxVERTICAL
);
1597 dialog
.SetSizer(boxSizer
);
1599 wxHtmlWindow
* win
= new wxHtmlWindow(& dialog
, wxID_ANY
, wxDefaultPosition
, wxSize(500, 400), wxSUNKEN_BORDER
);
1600 boxSizer
->Add(win
, 1, wxALL
, 5);
1602 wxButton
* cancelButton
= new wxButton(& dialog
, wxID_CANCEL
, wxT("&Close"));
1603 boxSizer
->Add(cancelButton
, 0, wxALL
|wxCENTRE
, 5);
1606 wxStringOutputStream
strStream(& text
);
1608 wxRichTextHTMLHandler htmlHandler
;
1609 htmlHandler
.SetFlags(wxRICHTEXT_HANDLER_SAVE_IMAGES_TO_MEMORY
);
1611 wxArrayInt fontSizeMapping
;
1612 fontSizeMapping
.Add(7);
1613 fontSizeMapping
.Add(9);
1614 fontSizeMapping
.Add(11);
1615 fontSizeMapping
.Add(12);
1616 fontSizeMapping
.Add(14);
1617 fontSizeMapping
.Add(22);
1618 fontSizeMapping
.Add(100);
1620 htmlHandler
.SetFontSizeMapping(fontSizeMapping
);
1622 if (htmlHandler
.SaveFile(& m_richTextCtrl
->GetBuffer(), strStream
))
1627 boxSizer
->Fit(& dialog
);
1631 // Now delete the temporary in-memory images
1632 htmlHandler
.DeleteTemporaryImages();
1635 // Demonstrates how you can change the style sheets and have the changes
1636 // reflected in the control content without wiping out character formatting.
1638 void MyFrame::OnSwitchStyleSheets(wxCommandEvent
& WXUNUSED(event
))
1640 static wxRichTextStyleSheet
* gs_AlternateStyleSheet
= NULL
;
1642 wxRichTextStyleListCtrl
*styleList
= (wxRichTextStyleListCtrl
*) FindWindow(ID_RICHTEXT_STYLE_LIST
);
1643 wxRichTextStyleComboCtrl
* styleCombo
= (wxRichTextStyleComboCtrl
*) FindWindow(ID_RICHTEXT_STYLE_COMBO
);
1645 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1647 // One-time creation of an alternate style sheet
1648 if (!gs_AlternateStyleSheet
)
1650 gs_AlternateStyleSheet
= new wxRichTextStyleSheet(*sheet
);
1652 // Make some modifications
1653 for (int i
= 0; i
< (int) gs_AlternateStyleSheet
->GetParagraphStyleCount(); i
++)
1655 wxRichTextParagraphStyleDefinition
* def
= gs_AlternateStyleSheet
->GetParagraphStyle(i
);
1657 if (def
->GetStyle().HasTextColour())
1658 def
->GetStyle().SetTextColour(*wxBLUE
);
1660 if (def
->GetStyle().HasAlignment())
1662 if (def
->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_CENTRE
)
1663 def
->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_RIGHT
);
1664 else if (def
->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_LEFT
)
1665 def
->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_CENTRE
);
1667 if (def
->GetStyle().HasLeftIndent())
1669 def
->GetStyle().SetLeftIndent(def
->GetStyle().GetLeftIndent() * 2);
1675 wxRichTextStyleSheet
* tmp
= gs_AlternateStyleSheet
;
1676 gs_AlternateStyleSheet
= sheet
;
1679 m_richTextCtrl
->SetStyleSheet(sheet
);
1680 m_richTextCtrl
->ApplyStyleSheet(sheet
); // Makes the control reflect the new style definitions
1682 styleList
->SetStyleSheet(sheet
);
1683 styleList
->UpdateStyles();
1685 styleCombo
->SetStyleSheet(sheet
);
1686 styleCombo
->UpdateStyles();
1689 void MyFrame::OnManageStyles(wxCommandEvent
& WXUNUSED(event
))
1691 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1693 int flags
= wxRICHTEXT_ORGANISER_CREATE_STYLES
|wxRICHTEXT_ORGANISER_EDIT_STYLES
;
1695 wxRichTextStyleOrganiserDialog
dlg(flags
, sheet
, NULL
, this, wxID_ANY
, _("Style Manager"));
1699 void MyFrame::OnInsertSymbol(wxCommandEvent
& WXUNUSED(event
))
1701 wxRichTextAttr attr
;
1702 attr
.SetFlags(wxTEXT_ATTR_FONT
);
1703 m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
);
1705 wxString currentFontName
;
1706 if (attr
.HasFont() && attr
.GetFont().IsOk())
1707 currentFontName
= attr
.GetFont().GetFaceName();
1709 // Don't set the initial font in the dialog (so the user is choosing
1710 // 'normal text', i.e. the current font) but do tell the dialog
1711 // what 'normal text' is.
1713 wxSymbolPickerDialog
dlg(wxT("*"), wxEmptyString
, currentFontName
, this);
1715 if (dlg
.ShowModal() == wxID_OK
)
1717 if (dlg
.HasSelection())
1719 long insertionPoint
= m_richTextCtrl
->GetInsertionPoint();
1721 m_richTextCtrl
->WriteText(dlg
.GetSymbol());
1723 if (!dlg
.UseNormalFont())
1725 wxFont
font(attr
.GetFont());
1726 font
.SetFaceName(dlg
.GetFontName());
1728 m_richTextCtrl
->SetStyle(insertionPoint
, insertionPoint
+1, attr
);
1734 void MyFrame::OnNumberList(wxCommandEvent
& WXUNUSED(event
))
1736 if (m_richTextCtrl
->HasSelection())
1738 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1739 m_richTextCtrl
->SetListStyle(range
, wxT("Numbered List 1"), wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_RENUMBER
);
1743 void MyFrame::OnBulletsAndNumbering(wxCommandEvent
& WXUNUSED(event
))
1745 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1747 int flags
= wxRICHTEXT_ORGANISER_BROWSE_NUMBERING
;
1749 wxRichTextStyleOrganiserDialog
dlg(flags
, sheet
, m_richTextCtrl
, this, wxID_ANY
, _("Bullets and Numbering"));
1750 if (dlg
.ShowModal() == wxID_OK
)
1752 if (dlg
.GetSelectedStyleDefinition())
1757 void MyFrame::OnItemizeList(wxCommandEvent
& WXUNUSED(event
))
1759 if (m_richTextCtrl
->HasSelection())
1761 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1762 m_richTextCtrl
->SetListStyle(range
, wxT("Bullet List 1"));
1766 void MyFrame::OnRenumberList(wxCommandEvent
& WXUNUSED(event
))
1768 if (m_richTextCtrl
->HasSelection())
1770 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1771 m_richTextCtrl
->NumberList(range
, NULL
, wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_RENUMBER
);
1775 void MyFrame::OnPromoteList(wxCommandEvent
& WXUNUSED(event
))
1777 if (m_richTextCtrl
->HasSelection())
1779 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1780 m_richTextCtrl
->PromoteList(1, range
, NULL
);
1784 void MyFrame::OnDemoteList(wxCommandEvent
& WXUNUSED(event
))
1786 if (m_richTextCtrl
->HasSelection())
1788 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1789 m_richTextCtrl
->PromoteList(-1, range
, NULL
);
1793 void MyFrame::OnClearList(wxCommandEvent
& WXUNUSED(event
))
1795 if (m_richTextCtrl
->HasSelection())
1797 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1798 m_richTextCtrl
->ClearListStyle(range
);
1802 void MyFrame::OnInsertURL(wxCommandEvent
& WXUNUSED(event
))
1804 wxString url
= wxGetTextFromUser(_("URL:"), _("Insert URL"));
1807 // Make a style suitable for showing a URL
1808 wxRichTextAttr urlStyle
;
1809 urlStyle
.SetTextColour(*wxBLUE
);
1810 urlStyle
.SetFontUnderlined(true);
1812 m_richTextCtrl
->BeginStyle(urlStyle
);
1813 m_richTextCtrl
->BeginURL(url
);
1814 m_richTextCtrl
->WriteText(url
);
1815 m_richTextCtrl
->EndURL();
1816 m_richTextCtrl
->EndStyle();
1820 void MyFrame::OnInsertImage(wxCommandEvent
& WXUNUSED(event
))
1822 wxFileDialog
dialog(this, _("Choose an image"), "", "", "BMP and GIF files (*.bmp;*.gif)|*.bmp;*.gif|PNG files (*.png)|*.png");
1823 if (dialog
.ShowModal() == wxID_OK
)
1825 wxString path
= dialog
.GetPath();
1826 m_richTextCtrl
->WriteImage(path
, wxBITMAP_TYPE_ANY
);
1830 void MyFrame::OnURL(wxTextUrlEvent
& event
)
1832 wxMessageBox(event
.GetString());
1835 // Veto style sheet replace events when loading from XML, since we want
1836 // to keep the original style sheet.
1837 void MyFrame::OnStyleSheetReplacing(wxRichTextEvent
& event
)
1842 void MyFrame::OnPrint(wxCommandEvent
& WXUNUSED(event
))
1844 wxGetApp().GetPrinting()->PrintBuffer(m_richTextCtrl
->GetBuffer());
1847 void MyFrame::OnPreview(wxCommandEvent
& WXUNUSED(event
))
1849 wxGetApp().GetPrinting()->PreviewBuffer(m_richTextCtrl
->GetBuffer());
1852 void MyFrame::OnPageSetup(wxCommandEvent
& WXUNUSED(event
))
1854 wxDialog
dialog(this, wxID_ANY
, wxT("Testing"), wxPoint(10, 10), wxSize(400, 300), wxDEFAULT_DIALOG_STYLE
);
1856 wxNotebook
* nb
= new wxNotebook(& dialog
, wxID_ANY
, wxPoint(5, 5), wxSize(300, 250));
1857 wxPanel
* panel
= new wxPanel(nb
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
);
1858 wxPanel
* panel2
= new wxPanel(nb
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
);
1860 new wxRichTextCtrl(panel
, wxID_ANY
, wxEmptyString
, wxPoint(5, 5), wxSize(200, 150), wxVSCROLL
|wxTE_READONLY
);
1861 nb
->AddPage(panel
, wxT("Page 1"));
1863 new wxRichTextCtrl(panel2
, wxID_ANY
, wxEmptyString
, wxPoint(5, 5), wxSize(200, 150), wxVSCROLL
|wxTE_READONLY
);
1864 nb
->AddPage(panel2
, wxT("Page 2"));
1866 new wxButton(& dialog
, wxID_OK
, wxT("OK"), wxPoint(5, 180));
1870 // wxGetApp().GetPrinting()->PageSetup();
1873 void MyRichTextCtrl::PrepareContent(wxRichTextParagraphLayoutBox
& container
)
1877 // Lock all content that's about to be added to the control
1878 wxRichTextObjectList::compatibility_iterator node
= container
.GetChildren().GetFirst();
1881 wxRichTextParagraph
* para
= wxDynamicCast(node
->GetData(), wxRichTextParagraph
);
1884 wxRichTextObjectList::compatibility_iterator childNode
= para
->GetChildren().GetFirst();
1887 wxRichTextObject
* obj
= childNode
->GetData();
1888 obj
->GetProperties().SetProperty(wxT("Lock"), m_lockId
);
1890 childNode
= childNode
->GetNext();
1893 node
= node
->GetNext();
1898 bool MyRichTextCtrl::CanDeleteRange(wxRichTextParagraphLayoutBox
& container
, const wxRichTextRange
& range
) const
1901 for (i
= range
.GetStart(); i
< range
.GetEnd(); i
++)
1903 wxRichTextObject
* obj
= container
.GetLeafObjectAtPosition(i
);
1904 if (obj
&& obj
->GetProperties().HasProperty(wxT("Lock")))
1912 bool MyRichTextCtrl::CanInsertContent(wxRichTextParagraphLayoutBox
& container
, long pos
) const
1914 wxRichTextObject
* child1
= container
.GetLeafObjectAtPosition(pos
);
1915 wxRichTextObject
* child2
= container
.GetLeafObjectAtPosition(pos
-1);
1917 long lock1
= -1, lock2
= -1;
1919 if (child1
&& child1
->GetProperties().HasProperty(wxT("Lock")))
1920 lock1
= child1
->GetProperties().GetPropertyLong(wxT("Lock"));
1921 if (child2
&& child2
->GetProperties().HasProperty(wxT("Lock")))
1922 lock2
= child2
->GetProperties().GetPropertyLong(wxT("Lock"));
1924 if (lock1
!= -1 && lock1
== lock2
)
1927 // Don't allow insertion before a locked object if it's at the beginning of the buffer.
1928 if (pos
== 0 && lock1
!= -1)
1935 class wxRichTextEnhancedDrawingHandler
: public wxRichTextDrawingHandler
1938 wxRichTextEnhancedDrawingHandler()
1940 SetName(wxT("enhanceddrawing"));
1941 m_lockBackgroundColour
= wxColour(220, 220, 220);
1945 Returns @true if this object has virtual attributes that we can provide.
1947 virtual bool HasVirtualAttributes(wxRichTextObject
* obj
) const;
1950 Provides virtual attributes that we can provide.
1952 virtual bool GetVirtualAttributes(wxRichTextAttr
& attr
, wxRichTextObject
* obj
) const;
1954 wxColour m_lockBackgroundColour
;
1957 bool wxRichTextEnhancedDrawingHandler::HasVirtualAttributes(wxRichTextObject
* obj
) const
1959 return obj
->GetProperties().HasProperty(wxT("Lock"));
1962 bool wxRichTextEnhancedDrawingHandler::GetVirtualAttributes(wxRichTextAttr
& attr
, wxRichTextObject
* obj
) const
1964 if (obj
->GetProperties().HasProperty(wxT("Lock")))
1966 attr
.SetBackgroundColour(m_lockBackgroundColour
);
1972 void MyRichTextCtrl::SetEnhancedDrawingHandler()
1974 wxRichTextBuffer::AddDrawingHandler(new wxRichTextEnhancedDrawingHandler
);