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"
38 #include "wx/sysopt.h"
41 #include "wx/filesys.h"
42 #include "wx/fs_mem.h"
46 #include "wx/cshelp.h"
49 #ifndef wxHAS_IMAGES_IN_RESOURCES
50 #include "../sample.xpm"
53 #include "bitmaps/smiley.xpm"
54 // #include "bitmaps/idea.xpm"
55 #include "bitmaps/zebra.xpm"
57 #include "bitmaps/open.xpm"
58 #include "bitmaps/save.xpm"
59 #include "bitmaps/copy.xpm"
60 #include "bitmaps/cut.xpm"
61 #include "bitmaps/paste.xpm"
62 #include "bitmaps/undo.xpm"
63 #include "bitmaps/redo.xpm"
64 #include "bitmaps/bold.xpm"
65 #include "bitmaps/italic.xpm"
66 #include "bitmaps/underline.xpm"
68 #include "bitmaps/alignleft.xpm"
69 #include "bitmaps/alignright.xpm"
70 #include "bitmaps/centre.xpm"
71 #include "bitmaps/font.xpm"
72 #include "bitmaps/indentless.xpm"
73 #include "bitmaps/indentmore.xpm"
75 #include "wx/richtext/richtextctrl.h"
76 #include "wx/richtext/richtextstyles.h"
77 #include "wx/richtext/richtextxml.h"
78 #include "wx/richtext/richtexthtml.h"
79 #include "wx/richtext/richtextformatdlg.h"
80 #include "wx/richtext/richtextsymboldlg.h"
81 #include "wx/richtext/richtextstyledlg.h"
82 #include "wx/richtext/richtextprint.h"
83 #include "wx/richtext/richtextimagedlg.h"
85 // ----------------------------------------------------------------------------
87 // ----------------------------------------------------------------------------
89 // ----------------------------------------------------------------------------
91 // ----------------------------------------------------------------------------
93 // Define a new application type, each program should derive a class from wxApp
94 class MyRichTextCtrl
: public wxRichTextCtrl
97 MyRichTextCtrl( wxWindow
* parent
, wxWindowID id
= -1, const wxString
& value
= wxEmptyString
, const wxPoint
& pos
= wxDefaultPosition
, const wxSize
& size
= wxDefaultSize
,
98 long style
= wxRE_MULTILINE
, const wxValidator
& validator
= wxDefaultValidator
, const wxString
& name
= wxTextCtrlNameStr
):
99 wxRichTextCtrl(parent
, id
, value
, pos
, size
, style
, validator
, name
)
105 void SetLockId(long id
) { m_lockId
= id
; }
106 long GetLockId() const { return m_lockId
; }
108 void BeginLock() { m_lockId
++; m_locked
= true; }
109 void EndLock() { m_locked
= false; }
110 bool IsLocked() const { return m_locked
; }
112 static void SetEnhancedDrawingHandler();
115 Prepares the content just before insertion (or after buffer reset). Called by the same function in wxRichTextBuffer.
116 Currently is only called if undo mode is on.
118 virtual void PrepareContent(wxRichTextParagraphLayoutBox
& container
);
121 Can we delete this range?
122 Sends an event to the control.
124 virtual bool CanDeleteRange(wxRichTextParagraphLayoutBox
& container
, const wxRichTextRange
& range
) const;
127 Can we insert content at this position?
128 Sends an event to the control.
130 virtual bool CanInsertContent(wxRichTextParagraphLayoutBox
& container
, long pos
) const;
136 // Define a new application type, each program should derive a class from wxApp
137 class MyApp
: public wxApp
140 // override base class virtuals
141 // ----------------------------
143 // this one is called on application startup and is a good place for the app
144 // initialization (doing it here and not in the ctor allows to have an error
145 // return: if OnInit() returns false, the application terminates)
146 virtual bool OnInit();
147 virtual int OnExit();
151 wxRichTextStyleSheet
* GetStyleSheet() const { return m_styleSheet
; }
152 wxRichTextPrinting
* GetPrinting() const { return m_printing
; }
154 wxRichTextStyleSheet
* m_styleSheet
;
155 wxRichTextPrinting
* m_printing
;
158 // Define a new frame type: this is going to be our main frame
159 class MyFrame
: public wxFrame
163 MyFrame(const wxString
& title
, wxWindowID id
, const wxPoint
& pos
= wxDefaultPosition
,
164 const wxSize
& size
= wxDefaultSize
, long style
= wxDEFAULT_FRAME_STYLE
);
166 // event handlers (these functions should _not_ be virtual)
167 void OnQuit(wxCommandEvent
& event
);
168 void OnAbout(wxCommandEvent
& event
);
170 void OnOpen(wxCommandEvent
& event
);
171 void OnSave(wxCommandEvent
& event
);
172 void OnSaveAs(wxCommandEvent
& event
);
174 void OnBold(wxCommandEvent
& event
);
175 void OnItalic(wxCommandEvent
& event
);
176 void OnUnderline(wxCommandEvent
& event
);
178 void OnStrikethrough(wxCommandEvent
& event
);
179 void OnSuperscript(wxCommandEvent
& event
);
180 void OnSubscript(wxCommandEvent
& event
);
182 void OnUpdateBold(wxUpdateUIEvent
& event
);
183 void OnUpdateItalic(wxUpdateUIEvent
& event
);
184 void OnUpdateUnderline(wxUpdateUIEvent
& event
);
185 void OnUpdateStrikethrough(wxUpdateUIEvent
& event
);
186 void OnUpdateSuperscript(wxUpdateUIEvent
& event
);
187 void OnUpdateSubscript(wxUpdateUIEvent
& event
);
189 void OnAlignLeft(wxCommandEvent
& event
);
190 void OnAlignCentre(wxCommandEvent
& event
);
191 void OnAlignRight(wxCommandEvent
& event
);
193 void OnUpdateAlignLeft(wxUpdateUIEvent
& event
);
194 void OnUpdateAlignCentre(wxUpdateUIEvent
& event
);
195 void OnUpdateAlignRight(wxUpdateUIEvent
& event
);
197 void OnIndentMore(wxCommandEvent
& event
);
198 void OnIndentLess(wxCommandEvent
& event
);
200 void OnFont(wxCommandEvent
& event
);
201 void OnImage(wxCommandEvent
& event
);
202 void OnUpdateImage(wxUpdateUIEvent
& event
);
203 void OnParagraph(wxCommandEvent
& event
);
204 void OnFormat(wxCommandEvent
& event
);
205 void OnUpdateFormat(wxUpdateUIEvent
& event
);
207 void OnInsertSymbol(wxCommandEvent
& event
);
209 void OnLineSpacingHalf(wxCommandEvent
& event
);
210 void OnLineSpacingDouble(wxCommandEvent
& event
);
211 void OnLineSpacingSingle(wxCommandEvent
& event
);
213 void OnParagraphSpacingMore(wxCommandEvent
& event
);
214 void OnParagraphSpacingLess(wxCommandEvent
& event
);
216 void OnNumberList(wxCommandEvent
& event
);
217 void OnBulletsAndNumbering(wxCommandEvent
& event
);
218 void OnItemizeList(wxCommandEvent
& event
);
219 void OnRenumberList(wxCommandEvent
& event
);
220 void OnPromoteList(wxCommandEvent
& event
);
221 void OnDemoteList(wxCommandEvent
& event
);
222 void OnClearList(wxCommandEvent
& event
);
224 void OnReload(wxCommandEvent
& event
);
226 void OnViewHTML(wxCommandEvent
& event
);
228 void OnSwitchStyleSheets(wxCommandEvent
& event
);
229 void OnManageStyles(wxCommandEvent
& event
);
231 void OnInsertURL(wxCommandEvent
& event
);
232 void OnURL(wxTextUrlEvent
& event
);
233 void OnStyleSheetReplacing(wxRichTextEvent
& event
);
235 void OnPrint(wxCommandEvent
& event
);
236 void OnPreview(wxCommandEvent
& event
);
237 void OnPageSetup(wxCommandEvent
& event
);
239 void OnInsertImage(wxCommandEvent
& event
);
242 // Forward command events to the current rich text control, if any
243 bool ProcessEvent(wxEvent
& event
);
246 void WriteInitialText();
249 // any class wishing to process wxWidgets events must use this macro
250 DECLARE_EVENT_TABLE()
252 MyRichTextCtrl
* m_richTextCtrl
;
255 // ----------------------------------------------------------------------------
257 // ----------------------------------------------------------------------------
259 // IDs for the controls and the menu commands
264 ID_About
= wxID_ABOUT
,
266 ID_FORMAT_BOLD
= 100,
269 ID_FORMAT_STRIKETHROUGH
,
270 ID_FORMAT_SUPERSCRIPT
,
283 ID_FORMAT_ALIGN_LEFT
,
284 ID_FORMAT_ALIGN_CENTRE
,
285 ID_FORMAT_ALIGN_RIGHT
,
287 ID_FORMAT_INDENT_MORE
,
288 ID_FORMAT_INDENT_LESS
,
290 ID_FORMAT_PARAGRAPH_SPACING_MORE
,
291 ID_FORMAT_PARAGRAPH_SPACING_LESS
,
293 ID_FORMAT_LINE_SPACING_HALF
,
294 ID_FORMAT_LINE_SPACING_DOUBLE
,
295 ID_FORMAT_LINE_SPACING_SINGLE
,
297 ID_FORMAT_NUMBER_LIST
,
298 ID_FORMAT_BULLETS_AND_NUMBERING
,
299 ID_FORMAT_ITEMIZE_LIST
,
300 ID_FORMAT_RENUMBER_LIST
,
301 ID_FORMAT_PROMOTE_LIST
,
302 ID_FORMAT_DEMOTE_LIST
,
303 ID_FORMAT_CLEAR_LIST
,
306 ID_SWITCH_STYLE_SHEETS
,
314 ID_RICHTEXT_STYLE_LIST
,
315 ID_RICHTEXT_STYLE_COMBO
318 // ----------------------------------------------------------------------------
319 // event tables and other macros for wxWidgets
320 // ----------------------------------------------------------------------------
322 // the event tables connect the wxWidgets events with the functions (event
323 // handlers) which process them. It can be also done at run-time, but for the
324 // simple menu events like this the static method is much simpler.
325 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
326 EVT_MENU(ID_Quit
, MyFrame::OnQuit
)
327 EVT_MENU(ID_About
, MyFrame::OnAbout
)
329 EVT_MENU(wxID_OPEN
, MyFrame::OnOpen
)
330 EVT_MENU(wxID_SAVE
, MyFrame::OnSave
)
331 EVT_MENU(wxID_SAVEAS
, MyFrame::OnSaveAs
)
333 EVT_MENU(ID_FORMAT_BOLD
, MyFrame::OnBold
)
334 EVT_MENU(ID_FORMAT_ITALIC
, MyFrame::OnItalic
)
335 EVT_MENU(ID_FORMAT_UNDERLINE
, MyFrame::OnUnderline
)
337 EVT_MENU(ID_FORMAT_STRIKETHROUGH
, MyFrame::OnStrikethrough
)
338 EVT_MENU(ID_FORMAT_SUPERSCRIPT
, MyFrame::OnSuperscript
)
339 EVT_MENU(ID_FORMAT_SUBSCRIPT
, MyFrame::OnSubscript
)
341 EVT_UPDATE_UI(ID_FORMAT_BOLD
, MyFrame::OnUpdateBold
)
342 EVT_UPDATE_UI(ID_FORMAT_ITALIC
, MyFrame::OnUpdateItalic
)
343 EVT_UPDATE_UI(ID_FORMAT_UNDERLINE
, MyFrame::OnUpdateUnderline
)
345 EVT_UPDATE_UI(ID_FORMAT_STRIKETHROUGH
, MyFrame::OnUpdateStrikethrough
)
346 EVT_UPDATE_UI(ID_FORMAT_SUPERSCRIPT
, MyFrame::OnUpdateSuperscript
)
347 EVT_UPDATE_UI(ID_FORMAT_SUBSCRIPT
, MyFrame::OnUpdateSubscript
)
349 EVT_MENU(ID_FORMAT_ALIGN_LEFT
, MyFrame::OnAlignLeft
)
350 EVT_MENU(ID_FORMAT_ALIGN_CENTRE
, MyFrame::OnAlignCentre
)
351 EVT_MENU(ID_FORMAT_ALIGN_RIGHT
, MyFrame::OnAlignRight
)
353 EVT_UPDATE_UI(ID_FORMAT_ALIGN_LEFT
, MyFrame::OnUpdateAlignLeft
)
354 EVT_UPDATE_UI(ID_FORMAT_ALIGN_CENTRE
, MyFrame::OnUpdateAlignCentre
)
355 EVT_UPDATE_UI(ID_FORMAT_ALIGN_RIGHT
, MyFrame::OnUpdateAlignRight
)
357 EVT_MENU(ID_FORMAT_FONT
, MyFrame::OnFont
)
358 EVT_MENU(ID_FORMAT_IMAGE
, MyFrame::OnImage
)
359 EVT_MENU(ID_FORMAT_PARAGRAPH
, MyFrame::OnParagraph
)
360 EVT_MENU(ID_FORMAT_CONTENT
, MyFrame::OnFormat
)
361 EVT_UPDATE_UI(ID_FORMAT_CONTENT
, MyFrame::OnUpdateFormat
)
362 EVT_UPDATE_UI(ID_FORMAT_FONT
, MyFrame::OnUpdateFormat
)
363 EVT_UPDATE_UI(ID_FORMAT_IMAGE
, MyFrame::OnUpdateImage
)
364 EVT_UPDATE_UI(ID_FORMAT_PARAGRAPH
, MyFrame::OnUpdateFormat
)
365 EVT_MENU(ID_FORMAT_INDENT_MORE
, MyFrame::OnIndentMore
)
366 EVT_MENU(ID_FORMAT_INDENT_LESS
, MyFrame::OnIndentLess
)
368 EVT_MENU(ID_FORMAT_LINE_SPACING_HALF
, MyFrame::OnLineSpacingHalf
)
369 EVT_MENU(ID_FORMAT_LINE_SPACING_SINGLE
, MyFrame::OnLineSpacingSingle
)
370 EVT_MENU(ID_FORMAT_LINE_SPACING_DOUBLE
, MyFrame::OnLineSpacingDouble
)
372 EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_MORE
, MyFrame::OnParagraphSpacingMore
)
373 EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_LESS
, MyFrame::OnParagraphSpacingLess
)
375 EVT_MENU(ID_RELOAD
, MyFrame::OnReload
)
377 EVT_MENU(ID_INSERT_SYMBOL
, MyFrame::OnInsertSymbol
)
378 EVT_MENU(ID_INSERT_URL
, MyFrame::OnInsertURL
)
379 EVT_MENU(ID_INSERT_IMAGE
, MyFrame::OnInsertImage
)
381 EVT_MENU(ID_FORMAT_NUMBER_LIST
, MyFrame::OnNumberList
)
382 EVT_MENU(ID_FORMAT_BULLETS_AND_NUMBERING
, MyFrame::OnBulletsAndNumbering
)
383 EVT_MENU(ID_FORMAT_ITEMIZE_LIST
, MyFrame::OnItemizeList
)
384 EVT_MENU(ID_FORMAT_RENUMBER_LIST
, MyFrame::OnRenumberList
)
385 EVT_MENU(ID_FORMAT_PROMOTE_LIST
, MyFrame::OnPromoteList
)
386 EVT_MENU(ID_FORMAT_DEMOTE_LIST
, MyFrame::OnDemoteList
)
387 EVT_MENU(ID_FORMAT_CLEAR_LIST
, MyFrame::OnClearList
)
389 EVT_MENU(ID_VIEW_HTML
, MyFrame::OnViewHTML
)
390 EVT_MENU(ID_SWITCH_STYLE_SHEETS
, MyFrame::OnSwitchStyleSheets
)
391 EVT_MENU(ID_MANAGE_STYLES
, MyFrame::OnManageStyles
)
393 EVT_MENU(ID_PRINT
, MyFrame::OnPrint
)
394 EVT_MENU(ID_PREVIEW
, MyFrame::OnPreview
)
395 EVT_MENU(ID_PAGE_SETUP
, MyFrame::OnPageSetup
)
397 EVT_TEXT_URL(wxID_ANY
, MyFrame::OnURL
)
398 EVT_RICHTEXT_STYLESHEET_REPLACING(wxID_ANY
, MyFrame::OnStyleSheetReplacing
)
401 // Create a new application object: this macro will allow wxWidgets to create
402 // the application object during program execution (it's better than using a
403 // static object for many reasons) and also implements the accessor function
404 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
408 // ============================================================================
410 // ============================================================================
412 // ----------------------------------------------------------------------------
413 // the application class
414 // ----------------------------------------------------------------------------
416 // 'Main program' equivalent: the program execution "starts" here
419 if ( !wxApp::OnInit() )
423 wxHelpProvider::Set(new wxSimpleHelpProvider
);
426 m_styleSheet
= new wxRichTextStyleSheet
;
427 m_printing
= new wxRichTextPrinting(wxT("Test Document"));
429 m_printing
->SetFooterText(wxT("@TITLE@"), wxRICHTEXT_PAGE_ALL
, wxRICHTEXT_PAGE_CENTRE
);
430 m_printing
->SetFooterText(wxT("Page @PAGENUM@"), wxRICHTEXT_PAGE_ALL
, wxRICHTEXT_PAGE_RIGHT
);
434 MyRichTextCtrl::SetEnhancedDrawingHandler();
436 // Add extra handlers (plain text is automatically added)
437 wxRichTextBuffer::AddHandler(new wxRichTextXMLHandler
);
438 wxRichTextBuffer::AddHandler(new wxRichTextHTMLHandler
);
440 // Add image handlers
442 wxImage::AddHandler( new wxPNGHandler
);
446 wxImage::AddHandler( new wxJPEGHandler
);
450 wxImage::AddHandler( new wxGIFHandler
);
454 wxFileSystem::AddHandler( new wxMemoryFSHandler
);
457 // create the main application window
458 MyFrame
*frame
= new MyFrame(wxT("wxRichTextCtrl Sample"), wxID_ANY
, wxDefaultPosition
, wxSize(700, 600));
460 m_printing
->SetParentWindow(frame
);
462 // and show it (the frames, unlike simple controls, are not shown when
463 // created initially)
466 // success: wxApp::OnRun() will be called which will enter the main message
467 // loop and the application will run. If we returned false here, the
468 // application would exit immediately.
480 void MyApp::CreateStyles()
484 wxFont
romanFont(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
485 wxFont
swissFont(12, wxSWISS
, wxNORMAL
, wxNORMAL
);
487 wxRichTextParagraphStyleDefinition
* normalPara
= new wxRichTextParagraphStyleDefinition(wxT("Normal"));
488 wxRichTextAttr normalAttr
;
489 normalAttr
.SetFontFaceName(romanFont
.GetFaceName());
490 normalAttr
.SetFontSize(12);
491 // Let's set all attributes for this style
492 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
|
493 wxTEXT_ATTR_PARA_SPACING_BEFORE
|wxTEXT_ATTR_PARA_SPACING_AFTER
|wxTEXT_ATTR_LINE_SPACING
|
494 wxTEXT_ATTR_BULLET_STYLE
|wxTEXT_ATTR_BULLET_NUMBER
);
495 normalPara
->SetStyle(normalAttr
);
497 m_styleSheet
->AddParagraphStyle(normalPara
);
499 wxRichTextParagraphStyleDefinition
* indentedPara
= new wxRichTextParagraphStyleDefinition(wxT("Indented"));
500 wxRichTextAttr indentedAttr
;
501 indentedAttr
.SetFontFaceName(romanFont
.GetFaceName());
502 indentedAttr
.SetFontSize(12);
503 indentedAttr
.SetLeftIndent(100, 0);
504 // We only want to affect indentation
505 indentedAttr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
);
506 indentedPara
->SetStyle(indentedAttr
);
508 m_styleSheet
->AddParagraphStyle(indentedPara
);
510 wxRichTextParagraphStyleDefinition
* indentedPara2
= new wxRichTextParagraphStyleDefinition(wxT("Red Bold Indented"));
511 wxRichTextAttr indentedAttr2
;
512 indentedAttr2
.SetFontFaceName(romanFont
.GetFaceName());
513 indentedAttr2
.SetFontSize(12);
514 indentedAttr2
.SetFontWeight(wxFONTWEIGHT_BOLD
);
515 indentedAttr2
.SetTextColour(*wxRED
);
516 indentedAttr2
.SetFontSize(12);
517 indentedAttr2
.SetLeftIndent(100, 0);
518 // We want to affect indentation, font and text colour
519 indentedAttr2
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
|wxTEXT_ATTR_FONT
|wxTEXT_ATTR_TEXT_COLOUR
);
520 indentedPara2
->SetStyle(indentedAttr2
);
522 m_styleSheet
->AddParagraphStyle(indentedPara2
);
524 wxRichTextParagraphStyleDefinition
* flIndentedPara
= new wxRichTextParagraphStyleDefinition(wxT("First Line Indented"));
525 wxRichTextAttr flIndentedAttr
;
526 flIndentedAttr
.SetFontFaceName(swissFont
.GetFaceName());
527 flIndentedAttr
.SetFontSize(12);
528 flIndentedAttr
.SetLeftIndent(100, -100);
529 // We only want to affect indentation
530 flIndentedAttr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
);
531 flIndentedPara
->SetStyle(flIndentedAttr
);
533 m_styleSheet
->AddParagraphStyle(flIndentedPara
);
537 wxRichTextCharacterStyleDefinition
* boldDef
= new wxRichTextCharacterStyleDefinition(wxT("Bold"));
538 wxRichTextAttr boldAttr
;
539 boldAttr
.SetFontFaceName(romanFont
.GetFaceName());
540 boldAttr
.SetFontSize(12);
541 boldAttr
.SetFontWeight(wxFONTWEIGHT_BOLD
);
542 // We only want to affect boldness
543 boldAttr
.SetFlags(wxTEXT_ATTR_FONT_WEIGHT
);
544 boldDef
->SetStyle(boldAttr
);
546 m_styleSheet
->AddCharacterStyle(boldDef
);
548 wxRichTextCharacterStyleDefinition
* italicDef
= new wxRichTextCharacterStyleDefinition(wxT("Italic"));
549 wxRichTextAttr italicAttr
;
550 italicAttr
.SetFontFaceName(romanFont
.GetFaceName());
551 italicAttr
.SetFontSize(12);
552 italicAttr
.SetFontStyle(wxFONTSTYLE_ITALIC
);
553 // We only want to affect italics
554 italicAttr
.SetFlags(wxTEXT_ATTR_FONT_ITALIC
);
555 italicDef
->SetStyle(italicAttr
);
557 m_styleSheet
->AddCharacterStyle(italicDef
);
559 wxRichTextCharacterStyleDefinition
* redDef
= new wxRichTextCharacterStyleDefinition(wxT("Red Bold"));
560 wxRichTextAttr redAttr
;
561 redAttr
.SetFontFaceName(romanFont
.GetFaceName());
562 redAttr
.SetFontSize(12);
563 redAttr
.SetFontWeight(wxFONTWEIGHT_BOLD
);
564 redAttr
.SetTextColour(*wxRED
);
565 // We only want to affect colour, weight and face
566 redAttr
.SetFlags(wxTEXT_ATTR_FONT_FACE
|wxTEXT_ATTR_FONT_WEIGHT
|wxTEXT_ATTR_TEXT_COLOUR
);
567 redDef
->SetStyle(redAttr
);
569 m_styleSheet
->AddCharacterStyle(redDef
);
571 wxRichTextListStyleDefinition
* bulletList
= new wxRichTextListStyleDefinition(wxT("Bullet List 1"));
573 for (i
= 0; i
< 10; i
++)
577 bulletText
= wxT("standard/circle");
579 bulletText
= wxT("standard/square");
581 bulletText
= wxT("standard/circle");
583 bulletText
= wxT("standard/square");
585 bulletText
= wxT("standard/circle");
587 bulletList
->SetAttributes(i
, (i
+1)*60, 60, wxTEXT_ATTR_BULLET_STYLE_STANDARD
, bulletText
);
590 m_styleSheet
->AddListStyle(bulletList
);
592 wxRichTextListStyleDefinition
* numberedList
= new wxRichTextListStyleDefinition(wxT("Numbered List 1"));
593 for (i
= 0; i
< 10; i
++)
597 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
599 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_LETTERS_LOWER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
601 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ROMAN_LOWER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
603 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ROMAN_UPPER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
605 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
607 numberStyle
|= wxTEXT_ATTR_BULLET_STYLE_ALIGN_RIGHT
;
609 numberedList
->SetAttributes(i
, (i
+1)*60, 60, numberStyle
);
612 m_styleSheet
->AddListStyle(numberedList
);
614 wxRichTextListStyleDefinition
* outlineList
= new wxRichTextListStyleDefinition(wxT("Outline List 1"));
615 for (i
= 0; i
< 10; i
++)
619 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_OUTLINE
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
621 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
623 outlineList
->SetAttributes(i
, (i
+1)*120, 120, numberStyle
);
626 m_styleSheet
->AddListStyle(outlineList
);
629 // ----------------------------------------------------------------------------
631 // ----------------------------------------------------------------------------
634 MyFrame::MyFrame(const wxString
& title
, wxWindowID id
, const wxPoint
& pos
,
635 const wxSize
& size
, long style
)
636 : wxFrame(NULL
, id
, title
, pos
, size
, style
)
639 SetWindowVariant(wxWINDOW_VARIANT_SMALL
);
642 // set the frame icon
643 SetIcon(wxICON(sample
));
646 wxMenu
*fileMenu
= new wxMenu
;
648 // the "About" item should be in the help menu
649 wxMenu
*helpMenu
= new wxMenu
;
650 helpMenu
->Append(ID_About
, wxT("&About\tF1"), wxT("Show about dialog"));
652 fileMenu
->Append(wxID_OPEN
, wxT("&Open\tCtrl+O"), wxT("Open a file"));
653 fileMenu
->Append(wxID_SAVE
, wxT("&Save\tCtrl+S"), wxT("Save a file"));
654 fileMenu
->Append(wxID_SAVEAS
, wxT("&Save As...\tF12"), wxT("Save to a new file"));
655 fileMenu
->AppendSeparator();
656 fileMenu
->Append(ID_RELOAD
, wxT("&Reload Text\tF2"), wxT("Reload the initial text"));
657 fileMenu
->AppendSeparator();
658 fileMenu
->Append(ID_PAGE_SETUP
, wxT("Page Set&up..."), wxT("Page setup"));
659 fileMenu
->Append(ID_PRINT
, wxT("&Print...\tCtrl+P"), wxT("Print"));
660 fileMenu
->Append(ID_PREVIEW
, wxT("Print Pre&view"), wxT("Print preview"));
661 fileMenu
->AppendSeparator();
662 fileMenu
->Append(ID_VIEW_HTML
, wxT("&View as HTML"), wxT("View HTML"));
663 fileMenu
->AppendSeparator();
664 fileMenu
->Append(ID_Quit
, wxT("E&xit\tAlt+X"), wxT("Quit this program"));
666 wxMenu
* editMenu
= new wxMenu
;
667 editMenu
->Append(wxID_UNDO
, _("&Undo\tCtrl+Z"));
668 editMenu
->Append(wxID_REDO
, _("&Redo\tCtrl+Y"));
669 editMenu
->AppendSeparator();
670 editMenu
->Append(wxID_CUT
, _("Cu&t\tCtrl+X"));
671 editMenu
->Append(wxID_COPY
, _("&Copy\tCtrl+C"));
672 editMenu
->Append(wxID_PASTE
, _("&Paste\tCtrl+V"));
674 editMenu
->AppendSeparator();
675 editMenu
->Append(wxID_SELECTALL
, _("Select A&ll\tCtrl+A"));
677 editMenu
->AppendSeparator();
678 editMenu
->Append(wxID_FIND
, _("&Find...\tCtrl+F"));
679 editMenu
->Append(stID_FIND_REPLACE
, _("&Replace...\tCtrl+R"));
682 wxMenu
* formatMenu
= new wxMenu
;
683 formatMenu
->AppendCheckItem(ID_FORMAT_BOLD
, _("&Bold\tCtrl+B"));
684 formatMenu
->AppendCheckItem(ID_FORMAT_ITALIC
, _("&Italic\tCtrl+I"));
685 formatMenu
->AppendCheckItem(ID_FORMAT_UNDERLINE
, _("&Underline\tCtrl+U"));
686 formatMenu
->AppendSeparator();
687 formatMenu
->AppendCheckItem(ID_FORMAT_STRIKETHROUGH
, _("Stri&kethrough"));
688 formatMenu
->AppendCheckItem(ID_FORMAT_SUPERSCRIPT
, _("Superscrip&t"));
689 formatMenu
->AppendCheckItem(ID_FORMAT_SUBSCRIPT
, _("Subscrip&t"));
690 formatMenu
->AppendSeparator();
691 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_LEFT
, _("L&eft Align"));
692 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_RIGHT
, _("&Right Align"));
693 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_CENTRE
, _("&Centre"));
694 formatMenu
->AppendSeparator();
695 formatMenu
->Append(ID_FORMAT_INDENT_MORE
, _("Indent &More"));
696 formatMenu
->Append(ID_FORMAT_INDENT_LESS
, _("Indent &Less"));
697 formatMenu
->AppendSeparator();
698 formatMenu
->Append(ID_FORMAT_PARAGRAPH_SPACING_MORE
, _("Increase Paragraph &Spacing"));
699 formatMenu
->Append(ID_FORMAT_PARAGRAPH_SPACING_LESS
, _("Decrease &Paragraph Spacing"));
700 formatMenu
->AppendSeparator();
701 formatMenu
->Append(ID_FORMAT_LINE_SPACING_SINGLE
, _("Normal Line Spacing"));
702 formatMenu
->Append(ID_FORMAT_LINE_SPACING_HALF
, _("1.5 Line Spacing"));
703 formatMenu
->Append(ID_FORMAT_LINE_SPACING_DOUBLE
, _("Double Line Spacing"));
704 formatMenu
->AppendSeparator();
705 formatMenu
->Append(ID_FORMAT_FONT
, _("&Font..."));
706 formatMenu
->Append(ID_FORMAT_IMAGE
, _("Image Property"));
707 formatMenu
->Append(ID_FORMAT_PARAGRAPH
, _("&Paragraph..."));
708 formatMenu
->Append(ID_FORMAT_CONTENT
, _("Font and Pa&ragraph...\tShift+Ctrl+F"));
709 formatMenu
->AppendSeparator();
710 formatMenu
->Append(ID_SWITCH_STYLE_SHEETS
, _("&Switch Style Sheets"));
711 formatMenu
->Append(ID_MANAGE_STYLES
, _("&Manage Styles"));
713 wxMenu
* listsMenu
= new wxMenu
;
714 listsMenu
->Append(ID_FORMAT_BULLETS_AND_NUMBERING
, _("Bullets and &Numbering..."));
715 listsMenu
->AppendSeparator();
716 listsMenu
->Append(ID_FORMAT_NUMBER_LIST
, _("Number List"));
717 listsMenu
->Append(ID_FORMAT_ITEMIZE_LIST
, _("Itemize List"));
718 listsMenu
->Append(ID_FORMAT_RENUMBER_LIST
, _("Renumber List"));
719 listsMenu
->Append(ID_FORMAT_PROMOTE_LIST
, _("Promote List Items"));
720 listsMenu
->Append(ID_FORMAT_DEMOTE_LIST
, _("Demote List Items"));
721 listsMenu
->Append(ID_FORMAT_CLEAR_LIST
, _("Clear List Formatting"));
723 wxMenu
* insertMenu
= new wxMenu
;
724 insertMenu
->Append(ID_INSERT_SYMBOL
, _("&Symbol...\tCtrl+I"));
725 insertMenu
->Append(ID_INSERT_URL
, _("&URL..."));
726 insertMenu
->Append(ID_INSERT_IMAGE
, _("&Image..."));
728 // now append the freshly created menu to the menu bar...
729 wxMenuBar
*menuBar
= new wxMenuBar();
730 menuBar
->Append(fileMenu
, wxT("&File"));
731 menuBar
->Append(editMenu
, wxT("&Edit"));
732 menuBar
->Append(formatMenu
, wxT("F&ormat"));
733 menuBar
->Append(listsMenu
, wxT("&Lists"));
734 menuBar
->Append(insertMenu
, wxT("&Insert"));
735 menuBar
->Append(helpMenu
, wxT("&Help"));
737 // ... and attach this menu bar to the frame
740 // create a status bar just for fun (by default with 1 pane only)
741 // but don't create it on limited screen space (WinCE)
742 bool is_pda
= wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA
;
748 SetStatusText(wxT("Welcome to wxRichTextCtrl!"));
752 wxBoxSizer
* sizer
= new wxBoxSizer(wxVERTICAL
);
755 // On Mac, don't create a 'native' wxToolBar because small bitmaps are not supported by native
756 // toolbars. On Mac, a non-native, small-bitmap toolbar doesn't show unless it is explicitly
757 // managed, hence the use of sizers. In a real application, use larger icons for the main
758 // toolbar to avoid the need for this workaround. Or, use the toolbar in a container window
759 // as part of a more complex hierarchy, and the toolbar will automatically be non-native.
761 wxSystemOptions::SetOption(wxT("mac.toolbar.no-native"), 1);
763 wxToolBar
* toolBar
= new wxToolBar(this, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
,
764 wxNO_BORDER
|wxTB_FLAT
|wxTB_NODIVIDER
|wxTB_NOALIGN
);
766 sizer
->Add(toolBar
, 0, wxEXPAND
);
768 toolBar
->AddTool(wxID_OPEN
, wxEmptyString
, wxBitmap(open_xpm
), _("Open"));
769 toolBar
->AddTool(wxID_SAVEAS
, wxEmptyString
, wxBitmap(save_xpm
), _("Save"));
770 toolBar
->AddSeparator();
771 toolBar
->AddTool(wxID_CUT
, wxEmptyString
, wxBitmap(cut_xpm
), _("Cut"));
772 toolBar
->AddTool(wxID_COPY
, wxEmptyString
, wxBitmap(copy_xpm
), _("Copy"));
773 toolBar
->AddTool(wxID_PASTE
, wxEmptyString
, wxBitmap(paste_xpm
), _("Paste"));
774 toolBar
->AddSeparator();
775 toolBar
->AddTool(wxID_UNDO
, wxEmptyString
, wxBitmap(undo_xpm
), _("Undo"));
776 toolBar
->AddTool(wxID_REDO
, wxEmptyString
, wxBitmap(redo_xpm
), _("Redo"));
777 toolBar
->AddSeparator();
778 toolBar
->AddCheckTool(ID_FORMAT_BOLD
, wxEmptyString
, wxBitmap(bold_xpm
), wxNullBitmap
, _("Bold"));
779 toolBar
->AddCheckTool(ID_FORMAT_ITALIC
, wxEmptyString
, wxBitmap(italic_xpm
), wxNullBitmap
, _("Italic"));
780 toolBar
->AddCheckTool(ID_FORMAT_UNDERLINE
, wxEmptyString
, wxBitmap(underline_xpm
), wxNullBitmap
, _("Underline"));
781 toolBar
->AddSeparator();
782 toolBar
->AddCheckTool(ID_FORMAT_ALIGN_LEFT
, wxEmptyString
, wxBitmap(alignleft_xpm
), wxNullBitmap
, _("Align Left"));
783 toolBar
->AddCheckTool(ID_FORMAT_ALIGN_CENTRE
, wxEmptyString
, wxBitmap(centre_xpm
), wxNullBitmap
, _("Centre"));
784 toolBar
->AddCheckTool(ID_FORMAT_ALIGN_RIGHT
, wxEmptyString
, wxBitmap(alignright_xpm
), wxNullBitmap
, _("Align Right"));
785 toolBar
->AddSeparator();
786 toolBar
->AddTool(ID_FORMAT_INDENT_LESS
, wxEmptyString
, wxBitmap(indentless_xpm
), _("Indent Less"));
787 toolBar
->AddTool(ID_FORMAT_INDENT_MORE
, wxEmptyString
, wxBitmap(indentmore_xpm
), _("Indent More"));
788 toolBar
->AddSeparator();
789 toolBar
->AddTool(ID_FORMAT_FONT
, wxEmptyString
, wxBitmap(font_xpm
), _("Font"));
790 toolBar
->AddSeparator();
792 wxRichTextStyleComboCtrl
* combo
= new wxRichTextStyleComboCtrl(toolBar
, ID_RICHTEXT_STYLE_COMBO
, wxDefaultPosition
, wxSize(160, -1), wxCB_READONLY
);
793 toolBar
->AddControl(combo
);
797 wxSplitterWindow
* splitter
= new wxSplitterWindow(this, wxID_ANY
, wxDefaultPosition
, wxSize(100,100), wxSP_LIVE_UPDATE
);
798 sizer
->Add(splitter
, 1, wxEXPAND
);
800 wxFont textFont
= wxFont(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
801 wxFont boldFont
= wxFont(12, wxROMAN
, wxNORMAL
, wxBOLD
);
802 wxFont italicFont
= wxFont(12, wxROMAN
, wxITALIC
, wxNORMAL
);
804 m_richTextCtrl
= new MyRichTextCtrl(splitter
, ID_RICHTEXT_CTRL
, wxEmptyString
, wxDefaultPosition
, wxSize(200, 200), wxVSCROLL
|wxHSCROLL
|wxWANTS_CHARS
);
805 wxFont
font(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
807 m_richTextCtrl
->SetFont(font
);
809 m_richTextCtrl
->SetMargins(10, 10);
811 m_richTextCtrl
->SetStyleSheet(wxGetApp().GetStyleSheet());
813 combo
->SetStyleSheet(wxGetApp().GetStyleSheet());
814 combo
->SetRichTextCtrl(m_richTextCtrl
);
815 combo
->UpdateStyles();
817 wxRichTextStyleListCtrl
* styleListCtrl
= new wxRichTextStyleListCtrl(splitter
, ID_RICHTEXT_STYLE_LIST
);
819 wxSize display
= wxGetDisplaySize();
820 if ( is_pda
&& ( display
.GetWidth() < display
.GetHeight() ) )
822 splitter
->SplitHorizontally(m_richTextCtrl
, styleListCtrl
);
826 splitter
->SplitVertically(m_richTextCtrl
, styleListCtrl
, 500);
831 splitter
->UpdateSize();
833 styleListCtrl
->SetStyleSheet(wxGetApp().GetStyleSheet());
834 styleListCtrl
->SetRichTextCtrl(m_richTextCtrl
);
835 styleListCtrl
->UpdateStyles();
841 void MyFrame::WriteInitialText()
843 MyRichTextCtrl
& r
= *m_richTextCtrl
;
845 r
.SetDefaultStyle(wxRichTextAttr());
849 r
.BeginSuppressUndo();
851 r
.BeginParagraphSpacing(0, 20);
853 r
.BeginAlignment(wxTEXT_ALIGNMENT_CENTRE
);
858 wxString lineBreak
= (wxChar
) 29;
860 r
.WriteText(wxString(wxT("Welcome to wxRichTextCtrl, a wxWidgets control")) + lineBreak
+ wxT("for editing and presenting styled text and images\n"));
864 r
.WriteText(wxT("by Julian Smart"));
870 r
.WriteImage(wxBitmap(zebra_xpm
));
877 r
.BeginAlignment(wxTEXT_ALIGNMENT_LEFT
);
878 wxRichTextAttr imageAttr
;
879 imageAttr
.GetTextBoxAttr().SetFloatMode(wxTEXT_BOX_ATTR_FLOAT_LEFT
);
880 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.")));
881 r
.WriteImage(wxBitmap(zebra_xpm
), wxBITMAP_TYPE_PNG
, imageAttr
);
883 imageAttr
.GetTextBoxAttr().GetTop().SetValue(200);
884 imageAttr
.GetTextBoxAttr().GetTop().SetUnits(wxTEXT_ATTR_UNITS_PIXELS
);
885 imageAttr
.GetTextBoxAttr().SetFloatMode(wxTEXT_BOX_ATTR_FLOAT_RIGHT
);
886 r
.WriteImage(wxBitmap(zebra_xpm
), wxBITMAP_TYPE_PNG
, imageAttr
);
887 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.")));
891 r
.WriteText(wxT("What can you do with this thing? "));
893 r
.WriteImage(wxBitmap(smiley_xpm
));
894 r
.WriteText(wxT(" Well, you can change text "));
896 r
.BeginTextColour(wxColour(255, 0, 0));
897 r
.WriteText(wxT("colour, like this red bit."));
900 wxRichTextAttr backgroundColourAttr
;
901 backgroundColourAttr
.SetBackgroundColour(*wxGREEN
);
902 backgroundColourAttr
.SetTextColour(wxColour(0, 0, 255));
903 r
.BeginStyle(backgroundColourAttr
);
904 r
.WriteText(wxT(" And this blue on green bit."));
907 r
.WriteText(wxT(" Naturally you can make things "));
909 r
.WriteText(wxT("bold "));
912 r
.WriteText(wxT("or italic "));
915 r
.WriteText(wxT("or underlined."));
919 r
.WriteText(wxT(" Different font sizes on the same line is allowed, too."));
922 r
.WriteText(wxT(" Next we'll show an indented paragraph."));
926 r
.BeginLeftIndent(60);
927 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."));
932 r
.WriteText(wxT("Next, we'll show a first-line indent, achieved using BeginLeftIndent(100, -40)."));
936 r
.BeginLeftIndent(100, -40);
938 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."));
943 r
.WriteText(wxT("Numbered bullets are possible, again using subindents:"));
946 r
.BeginNumberedBullet(1, 100, 60);
947 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."));
949 r
.EndNumberedBullet();
951 r
.BeginNumberedBullet(2, 100, 60);
952 r
.WriteText(wxT("This is my second item."));
954 r
.EndNumberedBullet();
956 r
.WriteText(wxT("The following paragraph is right-indented:"));
959 r
.BeginRightIndent(200);
961 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."));
966 r
.WriteText(wxT("The following paragraph is right-aligned with 1.5 line spacing:"));
969 r
.BeginAlignment(wxTEXT_ALIGNMENT_RIGHT
);
970 r
.BeginLineSpacing(wxTEXT_ATTR_LINE_SPACING_HALF
);
971 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."));
982 attr
.SetFlags(wxTEXT_ATTR_TABS
);
984 r
.SetDefaultStyle(attr
);
986 r
.WriteText(wxT("This line contains tabs:\tFirst tab\tSecond tab\tThird tab"));
989 r
.WriteText(wxT("Other notable features of wxRichTextCtrl include:"));
992 r
.BeginSymbolBullet(wxT('*'), 100, 60);
993 r
.WriteText(wxT("Compatibility with wxTextCtrl API"));
997 r
.BeginSymbolBullet(wxT('*'), 100, 60);
998 r
.WriteText(wxT("Easy stack-based BeginXXX()...EndXXX() style setting in addition to SetStyle()"));
1000 r
.EndSymbolBullet();
1002 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1003 r
.WriteText(wxT("XML loading and saving"));
1005 r
.EndSymbolBullet();
1007 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1008 r
.WriteText(wxT("Undo/Redo, with batching option and Undo suppressing"));
1010 r
.EndSymbolBullet();
1012 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1013 r
.WriteText(wxT("Clipboard copy and paste"));
1015 r
.EndSymbolBullet();
1017 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1018 r
.WriteText(wxT("wxRichTextStyleSheet with named character and paragraph styles, and control for applying named styles"));
1020 r
.EndSymbolBullet();
1022 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1023 r
.WriteText(wxT("A design that can easily be extended to other content types, ultimately with text boxes, tables, controls, and so on"));
1025 r
.EndSymbolBullet();
1027 // Make a style suitable for showing a URL
1028 wxRichTextAttr urlStyle
;
1029 urlStyle
.SetTextColour(*wxBLUE
);
1030 urlStyle
.SetFontUnderlined(true);
1032 r
.WriteText(wxT("wxRichTextCtrl can also display URLs, such as this one: "));
1033 r
.BeginStyle(urlStyle
);
1034 r
.BeginURL(wxT("http://www.wxwidgets.org"));
1035 r
.WriteText(wxT("The wxWidgets Web Site"));
1038 r
.WriteText(wxT(". Click on the URL to generate an event."));
1042 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"));
1044 r
.EndParagraphSpacing();
1052 wxRichTextAttr attr
;
1053 attr
.GetTextBoxAttr().GetMargins().GetLeft().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS
);
1054 attr
.GetTextBoxAttr().GetMargins().GetTop().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS
);
1055 attr
.GetTextBoxAttr().GetMargins().GetRight().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS
);
1056 attr
.GetTextBoxAttr().GetMargins().GetBottom().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS
);
1058 attr
.GetTextBoxAttr().GetBorder().SetColour(*wxBLACK
);
1059 attr
.GetTextBoxAttr().GetBorder().SetWidth(1, wxTEXT_ATTR_UNITS_PIXELS
);
1060 attr
.GetTextBoxAttr().GetBorder().SetStyle(wxTEXT_BOX_ATTR_BORDER_SOLID
);
1062 wxRichTextBox
* textBox
= r
.WriteTextBox(attr
);
1063 r
.SetFocusObject(textBox
);
1065 r
.WriteText(wxT("This is a text box. Just testing! Once more unto the breach, dear friends, once more..."));
1067 r
.SetFocusObject(NULL
); // Set the focus back to the main buffer
1068 r
.SetInsertionPointEnd();
1077 wxRichTextAttr attr
;
1078 attr
.GetTextBoxAttr().GetMargins().GetLeft().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS
);
1079 attr
.GetTextBoxAttr().GetMargins().GetTop().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS
);
1080 attr
.GetTextBoxAttr().GetMargins().GetRight().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS
);
1081 attr
.GetTextBoxAttr().GetMargins().GetBottom().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS
);
1082 attr
.GetTextBoxAttr().GetPadding() = attr
.GetTextBoxAttr().GetMargins();
1084 attr
.GetTextBoxAttr().GetBorder().SetColour(*wxBLACK
);
1085 attr
.GetTextBoxAttr().GetBorder().SetWidth(1, wxTEXT_ATTR_UNITS_PIXELS
);
1086 attr
.GetTextBoxAttr().GetBorder().SetStyle(wxTEXT_BOX_ATTR_BORDER_SOLID
);
1088 wxRichTextAttr cellAttr
= attr
;
1089 cellAttr
.GetTextBoxAttr().GetWidth().SetValue(200, wxTEXT_ATTR_UNITS_PIXELS
);
1090 cellAttr
.GetTextBoxAttr().GetHeight().SetValue(150, wxTEXT_ATTR_UNITS_PIXELS
);
1092 wxRichTextTable
* table
= r
.WriteTable(3, 2, attr
, cellAttr
);
1094 for (j
= 0; j
< table
->GetRowCount(); j
++)
1096 for (i
= 0; i
< table
->GetColumnCount(); i
++)
1098 wxString msg
= wxString::Format(wxT("This is cell %d, %d"), (j
+1), (i
+1));
1099 r
.SetFocusObject(table
->GetCell(j
, i
));
1103 r
.SetFocusObject(NULL
); // Set the focus back to the main buffer
1104 r
.SetInsertionPointEnd();
1108 r
.EndSuppressUndo();
1110 // Add some locked content first - needs Undo to be enabled
1113 r
.WriteText(wxString(wxT("This is a locked object.")));
1116 r
.WriteText(wxString(wxT(" This is unlocked text. ")));
1119 r
.WriteText(wxString(wxT("More locked content.")));
1123 // Flush the Undo buffer
1124 r
.GetCommandProcessor()->ClearCommands();
1132 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
1134 // true is to force the frame to close
1138 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
1141 msg
.Printf( wxT("This is a demo for wxRichTextCtrl, a control for editing styled text.\n(c) Julian Smart, 2005"));
1142 wxMessageBox(msg
, wxT("About wxRichTextCtrl Sample"), wxOK
| wxICON_INFORMATION
, this);
1145 // Forward command events to the current rich text control, if any
1146 bool MyFrame::ProcessEvent(wxEvent
& event
)
1148 if (event
.IsCommandEvent() && !event
.IsKindOf(CLASSINFO(wxChildFocusEvent
)))
1150 // Problem: we can get infinite recursion because the events
1151 // climb back up to this frame, and repeat.
1152 // Assume that command events don't cause another command event
1153 // to be called, so we can rely on inCommand not being overwritten
1155 static int s_eventType
= 0;
1156 static wxWindowID s_id
= 0;
1158 if (s_id
!= event
.GetId() && s_eventType
!= event
.GetEventType())
1160 s_eventType
= event
.GetEventType();
1161 s_id
= event
.GetId();
1163 wxWindow
* focusWin
= wxFindFocusDescendant(this);
1164 if (focusWin
&& focusWin
->GetEventHandler()->ProcessEvent(event
))
1181 return wxFrame::ProcessEvent(event
);
1184 void MyFrame::OnOpen(wxCommandEvent
& WXUNUSED(event
))
1188 wxArrayInt fileTypes
;
1190 wxString filter
= wxRichTextBuffer::GetExtWildcard(false, false, & fileTypes
);
1191 if (!filter
.empty())
1193 filter
+= wxT("All files (*.*)|*.*");
1195 wxFileDialog
dialog(this,
1196 _("Choose a filename"),
1202 if (dialog
.ShowModal() == wxID_OK
)
1204 wxString path
= dialog
.GetPath();
1208 int filterIndex
= dialog
.GetFilterIndex();
1209 int fileType
= (filterIndex
< (int) fileTypes
.GetCount())
1210 ? fileTypes
[filterIndex
]
1211 : wxRICHTEXT_TYPE_TEXT
;
1212 m_richTextCtrl
->LoadFile(path
, fileType
);
1217 void MyFrame::OnSave(wxCommandEvent
& event
)
1219 if (m_richTextCtrl
->GetFilename().empty())
1224 m_richTextCtrl
->SaveFile();
1227 void MyFrame::OnSaveAs(wxCommandEvent
& WXUNUSED(event
))
1229 wxString filter
= wxRichTextBuffer::GetExtWildcard(false, true);
1233 wxFileDialog
dialog(this,
1234 _("Choose a filename"),
1240 if (dialog
.ShowModal() == wxID_OK
)
1242 wxString path
= dialog
.GetPath();
1247 wxStopWatch stopwatch
;
1249 m_richTextCtrl
->SaveFile(path
);
1251 long t
= stopwatch
.Time();
1252 wxLogDebug(wxT("Saving took %ldms"), t
);
1253 wxMessageBox(wxString::Format(wxT("Saving took %ldms"), t
));
1258 void MyFrame::OnBold(wxCommandEvent
& WXUNUSED(event
))
1260 m_richTextCtrl
->ApplyBoldToSelection();
1263 void MyFrame::OnItalic(wxCommandEvent
& WXUNUSED(event
))
1265 m_richTextCtrl
->ApplyItalicToSelection();
1268 void MyFrame::OnUnderline(wxCommandEvent
& WXUNUSED(event
))
1270 m_richTextCtrl
->ApplyUnderlineToSelection();
1273 void MyFrame::OnStrikethrough(wxCommandEvent
& WXUNUSED(event
))
1275 m_richTextCtrl
->ApplyTextEffectToSelection(wxTEXT_ATTR_EFFECT_STRIKETHROUGH
);
1278 void MyFrame::OnSuperscript(wxCommandEvent
& WXUNUSED(event
))
1280 m_richTextCtrl
->ApplyTextEffectToSelection(wxTEXT_ATTR_EFFECT_SUPERSCRIPT
);
1283 void MyFrame::OnSubscript(wxCommandEvent
& WXUNUSED(event
))
1285 m_richTextCtrl
->ApplyTextEffectToSelection(wxTEXT_ATTR_EFFECT_SUBSCRIPT
);
1289 void MyFrame::OnUpdateBold(wxUpdateUIEvent
& event
)
1291 event
.Check(m_richTextCtrl
->IsSelectionBold());
1294 void MyFrame::OnUpdateItalic(wxUpdateUIEvent
& event
)
1296 event
.Check(m_richTextCtrl
->IsSelectionItalics());
1299 void MyFrame::OnUpdateUnderline(wxUpdateUIEvent
& event
)
1301 event
.Check(m_richTextCtrl
->IsSelectionUnderlined());
1304 void MyFrame::OnUpdateStrikethrough(wxUpdateUIEvent
& event
)
1306 event
.Check(m_richTextCtrl
->DoesSelectionHaveTextEffectFlag(wxTEXT_ATTR_EFFECT_STRIKETHROUGH
));
1309 void MyFrame::OnUpdateSuperscript(wxUpdateUIEvent
& event
)
1311 event
.Check(m_richTextCtrl
->DoesSelectionHaveTextEffectFlag(wxTEXT_ATTR_EFFECT_SUPERSCRIPT
));
1314 void MyFrame::OnUpdateSubscript(wxUpdateUIEvent
& event
)
1316 event
.Check(m_richTextCtrl
->DoesSelectionHaveTextEffectFlag(wxTEXT_ATTR_EFFECT_SUBSCRIPT
));
1319 void MyFrame::OnAlignLeft(wxCommandEvent
& WXUNUSED(event
))
1321 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_LEFT
);
1324 void MyFrame::OnAlignCentre(wxCommandEvent
& WXUNUSED(event
))
1326 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_CENTRE
);
1329 void MyFrame::OnAlignRight(wxCommandEvent
& WXUNUSED(event
))
1331 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_RIGHT
);
1334 void MyFrame::OnUpdateAlignLeft(wxUpdateUIEvent
& event
)
1336 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_LEFT
));
1339 void MyFrame::OnUpdateAlignCentre(wxUpdateUIEvent
& event
)
1341 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_CENTRE
));
1344 void MyFrame::OnUpdateAlignRight(wxUpdateUIEvent
& event
)
1346 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_RIGHT
));
1349 void MyFrame::OnFont(wxCommandEvent
& WXUNUSED(event
))
1351 wxRichTextRange range
;
1352 if (m_richTextCtrl
->HasSelection())
1353 range
= m_richTextCtrl
->GetSelectionRange();
1355 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1357 int pages
= wxRICHTEXT_FORMAT_FONT
;
1359 wxRichTextFormattingDialog
formatDlg(pages
, this);
1360 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1362 if (formatDlg
.ShowModal() == wxID_OK
)
1364 formatDlg
.ApplyStyle(m_richTextCtrl
, range
, wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_OPTIMIZE
|wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY
);
1367 // Old method using wxFontDialog
1369 if (!m_richTextCtrl
->HasSelection())
1372 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1373 wxFontData fontData
;
1375 wxRichTextAttr attr
;
1376 attr
.SetFlags(wxTEXT_ATTR_FONT
);
1378 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1379 fontData
.SetInitialFont(attr
.GetFont());
1381 wxFontDialog
dialog(this, fontData
);
1382 if (dialog
.ShowModal() == wxID_OK
)
1384 fontData
= dialog
.GetFontData();
1385 attr
.SetFlags(wxTEXT_ATTR_FONT
);
1386 attr
.SetFont(fontData
.GetChosenFont());
1387 if (attr
.GetFont().IsOk())
1389 m_richTextCtrl
->SetStyle(range
, attr
);
1395 void MyFrame::OnImage(wxCommandEvent
& WXUNUSED(event
))
1397 wxRichTextRange range
;
1398 wxASSERT(m_richTextCtrl
->HasSelection());
1400 range
= m_richTextCtrl
->GetSelectionRange();
1401 wxASSERT(range
.ToInternal().GetLength() == 1);
1403 wxRichTextImage
* image
= wxDynamicCast(m_richTextCtrl
->GetFocusObject()->GetLeafObjectAtPosition(range
.GetStart()), wxRichTextImage
);
1406 wxRichTextObjectPropertiesDialog
imageDlg(image
, this);
1408 if (imageDlg
.ShowModal() == wxID_OK
)
1410 imageDlg
.ApplyStyle(m_richTextCtrl
);
1415 void MyFrame::OnParagraph(wxCommandEvent
& WXUNUSED(event
))
1417 wxRichTextRange range
;
1418 if (m_richTextCtrl
->HasSelection())
1419 range
= m_richTextCtrl
->GetSelectionRange();
1421 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1423 int pages
= wxRICHTEXT_FORMAT_INDENTS_SPACING
|wxRICHTEXT_FORMAT_TABS
|wxRICHTEXT_FORMAT_BULLETS
;
1425 wxRichTextFormattingDialog
formatDlg(pages
, this);
1426 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1428 if (formatDlg
.ShowModal() == wxID_OK
)
1430 formatDlg
.ApplyStyle(m_richTextCtrl
, range
);
1434 void MyFrame::OnFormat(wxCommandEvent
& WXUNUSED(event
))
1436 wxRichTextRange range
;
1437 if (m_richTextCtrl
->HasSelection())
1438 range
= m_richTextCtrl
->GetSelectionRange();
1440 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1442 int pages
= wxRICHTEXT_FORMAT_FONT
|wxRICHTEXT_FORMAT_INDENTS_SPACING
|wxRICHTEXT_FORMAT_TABS
|wxRICHTEXT_FORMAT_BULLETS
;
1444 wxRichTextFormattingDialog
formatDlg(pages
, this);
1445 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1447 if (formatDlg
.ShowModal() == wxID_OK
)
1449 formatDlg
.ApplyStyle(m_richTextCtrl
, range
);
1453 void MyFrame::OnUpdateFormat(wxUpdateUIEvent
& event
)
1455 event
.Enable(m_richTextCtrl
->HasSelection());
1458 void MyFrame::OnUpdateImage(wxUpdateUIEvent
& event
)
1460 wxRichTextRange range
;
1461 wxRichTextObject
*obj
;
1463 range
= m_richTextCtrl
->GetSelectionRange();
1464 if (range
.ToInternal().GetLength() == 1)
1466 obj
= m_richTextCtrl
->GetFocusObject()->GetLeafObjectAtPosition(range
.GetStart());
1467 if (obj
&& obj
->IsKindOf(CLASSINFO(wxRichTextImage
)))
1474 event
.Enable(false);
1477 void MyFrame::OnIndentMore(wxCommandEvent
& WXUNUSED(event
))
1479 wxRichTextAttr attr
;
1480 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1482 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1484 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1485 if (m_richTextCtrl
->HasSelection())
1486 range
= m_richTextCtrl
->GetSelectionRange();
1488 attr
.SetLeftIndent(attr
.GetLeftIndent() + 100);
1490 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1491 m_richTextCtrl
->SetStyle(range
, attr
);
1495 void MyFrame::OnIndentLess(wxCommandEvent
& WXUNUSED(event
))
1497 wxRichTextAttr attr
;
1498 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1500 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1502 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1503 if (m_richTextCtrl
->HasSelection())
1504 range
= m_richTextCtrl
->GetSelectionRange();
1506 if (attr
.GetLeftIndent() > 0)
1508 attr
.SetLeftIndent(wxMax(0, attr
.GetLeftIndent() - 100));
1510 m_richTextCtrl
->SetStyle(range
, attr
);
1515 void MyFrame::OnLineSpacingHalf(wxCommandEvent
& WXUNUSED(event
))
1517 wxRichTextAttr attr
;
1518 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1520 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1522 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1523 if (m_richTextCtrl
->HasSelection())
1524 range
= m_richTextCtrl
->GetSelectionRange();
1526 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1527 attr
.SetLineSpacing(15);
1529 m_richTextCtrl
->SetStyle(range
, attr
);
1533 void MyFrame::OnLineSpacingDouble(wxCommandEvent
& WXUNUSED(event
))
1535 wxRichTextAttr attr
;
1536 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1538 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1540 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1541 if (m_richTextCtrl
->HasSelection())
1542 range
= m_richTextCtrl
->GetSelectionRange();
1544 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1545 attr
.SetLineSpacing(20);
1547 m_richTextCtrl
->SetStyle(range
, attr
);
1551 void MyFrame::OnLineSpacingSingle(wxCommandEvent
& WXUNUSED(event
))
1553 wxRichTextAttr attr
;
1554 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1556 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1558 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1559 if (m_richTextCtrl
->HasSelection())
1560 range
= m_richTextCtrl
->GetSelectionRange();
1562 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1563 attr
.SetLineSpacing(0); // Can also use 10
1565 m_richTextCtrl
->SetStyle(range
, attr
);
1569 void MyFrame::OnParagraphSpacingMore(wxCommandEvent
& WXUNUSED(event
))
1571 wxRichTextAttr attr
;
1572 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1574 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1576 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1577 if (m_richTextCtrl
->HasSelection())
1578 range
= m_richTextCtrl
->GetSelectionRange();
1580 attr
.SetParagraphSpacingAfter(attr
.GetParagraphSpacingAfter() + 20);
1582 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1583 m_richTextCtrl
->SetStyle(range
, attr
);
1587 void MyFrame::OnParagraphSpacingLess(wxCommandEvent
& WXUNUSED(event
))
1589 wxRichTextAttr attr
;
1590 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1592 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1594 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1595 if (m_richTextCtrl
->HasSelection())
1596 range
= m_richTextCtrl
->GetSelectionRange();
1598 if (attr
.GetParagraphSpacingAfter() >= 20)
1600 attr
.SetParagraphSpacingAfter(attr
.GetParagraphSpacingAfter() - 20);
1602 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1603 m_richTextCtrl
->SetStyle(range
, attr
);
1608 void MyFrame::OnReload(wxCommandEvent
& WXUNUSED(event
))
1610 m_richTextCtrl
->Clear();
1614 void MyFrame::OnViewHTML(wxCommandEvent
& WXUNUSED(event
))
1616 wxDialog
dialog(this, wxID_ANY
, _("HTML"), wxDefaultPosition
, wxSize(500, 400), wxDEFAULT_DIALOG_STYLE
);
1618 wxBoxSizer
* boxSizer
= new wxBoxSizer(wxVERTICAL
);
1619 dialog
.SetSizer(boxSizer
);
1621 wxHtmlWindow
* win
= new wxHtmlWindow(& dialog
, wxID_ANY
, wxDefaultPosition
, wxSize(500, 400), wxSUNKEN_BORDER
);
1622 boxSizer
->Add(win
, 1, wxALL
, 5);
1624 wxButton
* cancelButton
= new wxButton(& dialog
, wxID_CANCEL
, wxT("&Close"));
1625 boxSizer
->Add(cancelButton
, 0, wxALL
|wxCENTRE
, 5);
1628 wxStringOutputStream
strStream(& text
);
1630 wxRichTextHTMLHandler htmlHandler
;
1631 htmlHandler
.SetFlags(wxRICHTEXT_HANDLER_SAVE_IMAGES_TO_MEMORY
);
1633 wxArrayInt fontSizeMapping
;
1634 fontSizeMapping
.Add(7);
1635 fontSizeMapping
.Add(9);
1636 fontSizeMapping
.Add(11);
1637 fontSizeMapping
.Add(12);
1638 fontSizeMapping
.Add(14);
1639 fontSizeMapping
.Add(22);
1640 fontSizeMapping
.Add(100);
1642 htmlHandler
.SetFontSizeMapping(fontSizeMapping
);
1644 if (htmlHandler
.SaveFile(& m_richTextCtrl
->GetBuffer(), strStream
))
1649 boxSizer
->Fit(& dialog
);
1653 // Now delete the temporary in-memory images
1654 htmlHandler
.DeleteTemporaryImages();
1657 // Demonstrates how you can change the style sheets and have the changes
1658 // reflected in the control content without wiping out character formatting.
1660 void MyFrame::OnSwitchStyleSheets(wxCommandEvent
& WXUNUSED(event
))
1662 static wxRichTextStyleSheet
* gs_AlternateStyleSheet
= NULL
;
1664 wxRichTextStyleListCtrl
*styleList
= (wxRichTextStyleListCtrl
*) FindWindow(ID_RICHTEXT_STYLE_LIST
);
1665 wxRichTextStyleComboCtrl
* styleCombo
= (wxRichTextStyleComboCtrl
*) FindWindow(ID_RICHTEXT_STYLE_COMBO
);
1667 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1669 // One-time creation of an alternate style sheet
1670 if (!gs_AlternateStyleSheet
)
1672 gs_AlternateStyleSheet
= new wxRichTextStyleSheet(*sheet
);
1674 // Make some modifications
1675 for (int i
= 0; i
< (int) gs_AlternateStyleSheet
->GetParagraphStyleCount(); i
++)
1677 wxRichTextParagraphStyleDefinition
* def
= gs_AlternateStyleSheet
->GetParagraphStyle(i
);
1679 if (def
->GetStyle().HasTextColour())
1680 def
->GetStyle().SetTextColour(*wxBLUE
);
1682 if (def
->GetStyle().HasAlignment())
1684 if (def
->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_CENTRE
)
1685 def
->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_RIGHT
);
1686 else if (def
->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_LEFT
)
1687 def
->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_CENTRE
);
1689 if (def
->GetStyle().HasLeftIndent())
1691 def
->GetStyle().SetLeftIndent(def
->GetStyle().GetLeftIndent() * 2);
1697 wxRichTextStyleSheet
* tmp
= gs_AlternateStyleSheet
;
1698 gs_AlternateStyleSheet
= sheet
;
1701 m_richTextCtrl
->SetStyleSheet(sheet
);
1702 m_richTextCtrl
->ApplyStyleSheet(sheet
); // Makes the control reflect the new style definitions
1704 styleList
->SetStyleSheet(sheet
);
1705 styleList
->UpdateStyles();
1707 styleCombo
->SetStyleSheet(sheet
);
1708 styleCombo
->UpdateStyles();
1711 void MyFrame::OnManageStyles(wxCommandEvent
& WXUNUSED(event
))
1713 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1715 int flags
= wxRICHTEXT_ORGANISER_CREATE_STYLES
|wxRICHTEXT_ORGANISER_EDIT_STYLES
;
1717 wxRichTextStyleOrganiserDialog
dlg(flags
, sheet
, NULL
, this, wxID_ANY
, _("Style Manager"));
1721 void MyFrame::OnInsertSymbol(wxCommandEvent
& WXUNUSED(event
))
1723 wxRichTextAttr attr
;
1724 attr
.SetFlags(wxTEXT_ATTR_FONT
);
1725 m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
);
1727 wxString currentFontName
;
1728 if (attr
.HasFont() && attr
.GetFont().IsOk())
1729 currentFontName
= attr
.GetFont().GetFaceName();
1731 // Don't set the initial font in the dialog (so the user is choosing
1732 // 'normal text', i.e. the current font) but do tell the dialog
1733 // what 'normal text' is.
1735 wxSymbolPickerDialog
dlg(wxT("*"), wxEmptyString
, currentFontName
, this);
1737 if (dlg
.ShowModal() == wxID_OK
)
1739 if (dlg
.HasSelection())
1741 long insertionPoint
= m_richTextCtrl
->GetInsertionPoint();
1743 m_richTextCtrl
->WriteText(dlg
.GetSymbol());
1745 if (!dlg
.UseNormalFont())
1747 wxFont
font(attr
.GetFont());
1748 font
.SetFaceName(dlg
.GetFontName());
1750 m_richTextCtrl
->SetStyle(insertionPoint
, insertionPoint
+1, attr
);
1756 void MyFrame::OnNumberList(wxCommandEvent
& WXUNUSED(event
))
1758 if (m_richTextCtrl
->HasSelection())
1760 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1761 m_richTextCtrl
->SetListStyle(range
, wxT("Numbered List 1"), wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_RENUMBER
);
1765 void MyFrame::OnBulletsAndNumbering(wxCommandEvent
& WXUNUSED(event
))
1767 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1769 int flags
= wxRICHTEXT_ORGANISER_BROWSE_NUMBERING
;
1771 wxRichTextStyleOrganiserDialog
dlg(flags
, sheet
, m_richTextCtrl
, this, wxID_ANY
, _("Bullets and Numbering"));
1772 if (dlg
.ShowModal() == wxID_OK
)
1774 if (dlg
.GetSelectedStyleDefinition())
1779 void MyFrame::OnItemizeList(wxCommandEvent
& WXUNUSED(event
))
1781 if (m_richTextCtrl
->HasSelection())
1783 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1784 m_richTextCtrl
->SetListStyle(range
, wxT("Bullet List 1"));
1788 void MyFrame::OnRenumberList(wxCommandEvent
& WXUNUSED(event
))
1790 if (m_richTextCtrl
->HasSelection())
1792 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1793 m_richTextCtrl
->NumberList(range
, NULL
, wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_RENUMBER
);
1797 void MyFrame::OnPromoteList(wxCommandEvent
& WXUNUSED(event
))
1799 if (m_richTextCtrl
->HasSelection())
1801 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1802 m_richTextCtrl
->PromoteList(1, range
, NULL
);
1806 void MyFrame::OnDemoteList(wxCommandEvent
& WXUNUSED(event
))
1808 if (m_richTextCtrl
->HasSelection())
1810 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1811 m_richTextCtrl
->PromoteList(-1, range
, NULL
);
1815 void MyFrame::OnClearList(wxCommandEvent
& WXUNUSED(event
))
1817 if (m_richTextCtrl
->HasSelection())
1819 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1820 m_richTextCtrl
->ClearListStyle(range
);
1824 void MyFrame::OnInsertURL(wxCommandEvent
& WXUNUSED(event
))
1826 wxString url
= wxGetTextFromUser(_("URL:"), _("Insert URL"));
1829 // Make a style suitable for showing a URL
1830 wxRichTextAttr urlStyle
;
1831 urlStyle
.SetTextColour(*wxBLUE
);
1832 urlStyle
.SetFontUnderlined(true);
1834 m_richTextCtrl
->BeginStyle(urlStyle
);
1835 m_richTextCtrl
->BeginURL(url
);
1836 m_richTextCtrl
->WriteText(url
);
1837 m_richTextCtrl
->EndURL();
1838 m_richTextCtrl
->EndStyle();
1842 void MyFrame::OnInsertImage(wxCommandEvent
& WXUNUSED(event
))
1844 wxFileDialog
dialog(this, _("Choose an image"), "", "", "BMP and GIF files (*.bmp;*.gif)|*.bmp;*.gif|PNG files (*.png)|*.png");
1845 if (dialog
.ShowModal() == wxID_OK
)
1847 wxString path
= dialog
.GetPath();
1848 m_richTextCtrl
->WriteImage(path
, wxBITMAP_TYPE_ANY
);
1852 void MyFrame::OnURL(wxTextUrlEvent
& event
)
1854 wxMessageBox(event
.GetString());
1857 // Veto style sheet replace events when loading from XML, since we want
1858 // to keep the original style sheet.
1859 void MyFrame::OnStyleSheetReplacing(wxRichTextEvent
& event
)
1864 void MyFrame::OnPrint(wxCommandEvent
& WXUNUSED(event
))
1866 wxGetApp().GetPrinting()->PrintBuffer(m_richTextCtrl
->GetBuffer());
1869 void MyFrame::OnPreview(wxCommandEvent
& WXUNUSED(event
))
1871 wxGetApp().GetPrinting()->PreviewBuffer(m_richTextCtrl
->GetBuffer());
1874 void MyFrame::OnPageSetup(wxCommandEvent
& WXUNUSED(event
))
1876 wxDialog
dialog(this, wxID_ANY
, wxT("Testing"), wxPoint(10, 10), wxSize(400, 300), wxDEFAULT_DIALOG_STYLE
);
1878 wxNotebook
* nb
= new wxNotebook(& dialog
, wxID_ANY
, wxPoint(5, 5), wxSize(300, 250));
1879 wxPanel
* panel
= new wxPanel(nb
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
);
1880 wxPanel
* panel2
= new wxPanel(nb
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
);
1882 new wxRichTextCtrl(panel
, wxID_ANY
, wxEmptyString
, wxPoint(5, 5), wxSize(200, 150), wxVSCROLL
|wxTE_READONLY
);
1883 nb
->AddPage(panel
, wxT("Page 1"));
1885 new wxRichTextCtrl(panel2
, wxID_ANY
, wxEmptyString
, wxPoint(5, 5), wxSize(200, 150), wxVSCROLL
|wxTE_READONLY
);
1886 nb
->AddPage(panel2
, wxT("Page 2"));
1888 new wxButton(& dialog
, wxID_OK
, wxT("OK"), wxPoint(5, 180));
1892 // wxGetApp().GetPrinting()->PageSetup();
1895 void MyRichTextCtrl::PrepareContent(wxRichTextParagraphLayoutBox
& container
)
1899 // Lock all content that's about to be added to the control
1900 wxRichTextObjectList::compatibility_iterator node
= container
.GetChildren().GetFirst();
1903 wxRichTextParagraph
* para
= wxDynamicCast(node
->GetData(), wxRichTextParagraph
);
1906 wxRichTextObjectList::compatibility_iterator childNode
= para
->GetChildren().GetFirst();
1909 wxRichTextObject
* obj
= childNode
->GetData();
1910 obj
->GetProperties().SetProperty(wxT("Lock"), m_lockId
);
1912 childNode
= childNode
->GetNext();
1915 node
= node
->GetNext();
1920 bool MyRichTextCtrl::CanDeleteRange(wxRichTextParagraphLayoutBox
& container
, const wxRichTextRange
& range
) const
1923 for (i
= range
.GetStart(); i
< range
.GetEnd(); i
++)
1925 wxRichTextObject
* obj
= container
.GetLeafObjectAtPosition(i
);
1926 if (obj
&& obj
->GetProperties().HasProperty(wxT("Lock")))
1934 bool MyRichTextCtrl::CanInsertContent(wxRichTextParagraphLayoutBox
& container
, long pos
) const
1936 wxRichTextObject
* child1
= container
.GetLeafObjectAtPosition(pos
);
1937 wxRichTextObject
* child2
= container
.GetLeafObjectAtPosition(pos
-1);
1939 long lock1
= -1, lock2
= -1;
1941 if (child1
&& child1
->GetProperties().HasProperty(wxT("Lock")))
1942 lock1
= child1
->GetProperties().GetPropertyLong(wxT("Lock"));
1943 if (child2
&& child2
->GetProperties().HasProperty(wxT("Lock")))
1944 lock2
= child2
->GetProperties().GetPropertyLong(wxT("Lock"));
1946 if (lock1
!= -1 && lock1
== lock2
)
1949 // Don't allow insertion before a locked object if it's at the beginning of the buffer.
1950 if (pos
== 0 && lock1
!= -1)
1957 class wxRichTextEnhancedDrawingHandler
: public wxRichTextDrawingHandler
1960 wxRichTextEnhancedDrawingHandler()
1962 SetName(wxT("enhanceddrawing"));
1963 m_lockBackgroundColour
= wxColour(220, 220, 220);
1967 Returns @true if this object has virtual attributes that we can provide.
1969 virtual bool HasVirtualAttributes(wxRichTextObject
* obj
) const;
1972 Provides virtual attributes that we can provide.
1974 virtual bool GetVirtualAttributes(wxRichTextAttr
& attr
, wxRichTextObject
* obj
) const;
1976 wxColour m_lockBackgroundColour
;
1979 bool wxRichTextEnhancedDrawingHandler::HasVirtualAttributes(wxRichTextObject
* obj
) const
1981 return obj
->GetProperties().HasProperty(wxT("Lock"));
1984 bool wxRichTextEnhancedDrawingHandler::GetVirtualAttributes(wxRichTextAttr
& attr
, wxRichTextObject
* obj
) const
1986 if (obj
->GetProperties().HasProperty(wxT("Lock")))
1988 attr
.SetBackgroundColour(m_lockBackgroundColour
);
1994 void MyRichTextCtrl::SetEnhancedDrawingHandler()
1996 wxRichTextBuffer::AddDrawingHandler(new wxRichTextEnhancedDrawingHandler
);