1 /////////////////////////////////////////////////////////////////////////////
2 // Name: samples/richtext/richtext.cpp
3 // Purpose: wxWidgets rich text editor sample
4 // Author: Julian Smart
7 // Copyright: (c) Julian Smart
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 // For compilers that support precompilation, includes "wx/wx.h".
20 #include "wx/wxprec.h"
26 // for all others, include the necessary headers (this file is usually all you
27 // need because it includes almost all "standard" wxWidgets headers)
32 #include "wx/fontdlg.h"
33 #include "wx/splitter.h"
34 #include "wx/sstream.h"
35 #include "wx/html/htmlwin.h"
36 #include "wx/stopwatch.h"
37 #include "wx/sysopt.h"
40 #include "wx/filesys.h"
41 #include "wx/fs_mem.h"
45 #include "wx/cshelp.h"
48 #ifndef wxHAS_IMAGES_IN_RESOURCES
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 // A custom field type
85 class wxRichTextFieldTypePropertiesTest
: public wxRichTextFieldTypeStandard
88 wxRichTextFieldTypePropertiesTest(const wxString
& name
, const wxString
& label
, int displayStyle
= wxRICHTEXT_FIELD_STYLE_RECTANGLE
):
89 wxRichTextFieldTypeStandard(name
, label
, displayStyle
)
92 wxRichTextFieldTypePropertiesTest(const wxString
& name
, const wxBitmap
& bitmap
, int displayStyle
= wxRICHTEXT_FIELD_STYLE_RECTANGLE
):
93 wxRichTextFieldTypeStandard(name
, bitmap
, displayStyle
)
97 virtual bool CanEditProperties(wxRichTextField
* WXUNUSED(obj
)) const { return true; }
98 virtual bool EditProperties(wxRichTextField
* WXUNUSED(obj
), wxWindow
* WXUNUSED(parent
), wxRichTextBuffer
* WXUNUSED(buffer
))
100 wxString label
= GetLabel();
101 wxMessageBox(wxString::Format(wxT("Editing %s"), label
.c_str()));
105 virtual wxString
GetPropertiesMenuLabel(wxRichTextField
* WXUNUSED(obj
)) const
111 // A custom composite field type
112 class wxRichTextFieldTypeCompositeTest
: public wxRichTextFieldTypePropertiesTest
115 wxRichTextFieldTypeCompositeTest(const wxString
& name
, const wxString
& label
):
116 wxRichTextFieldTypePropertiesTest(name
, label
, wxRICHTEXT_FIELD_STYLE_COMPOSITE
)
120 virtual bool UpdateField(wxRichTextBuffer
* buffer
, wxRichTextField
* obj
)
124 wxRichTextAttr
attr(buffer
->GetAttributes());
125 attr
.GetTextBoxAttr().Reset();
126 attr
.SetParagraphSpacingAfter(0);
127 attr
.SetLineSpacing(10);
128 obj
->SetAttributes(attr
);
130 obj
->GetChildren().Clear();
131 wxRichTextParagraph
* para
= new wxRichTextParagraph
;
132 wxRichTextPlainText
* text
= new wxRichTextPlainText(GetLabel());
133 para
->AppendChild(text
);
134 obj
->AppendChild(para
);
139 // ----------------------------------------------------------------------------
141 // ----------------------------------------------------------------------------
143 // ----------------------------------------------------------------------------
145 // ----------------------------------------------------------------------------
147 // Define a new application type, each program should derive a class from wxApp
148 class MyRichTextCtrl
: public wxRichTextCtrl
151 MyRichTextCtrl( wxWindow
* parent
, wxWindowID id
= -1, const wxString
& value
= wxEmptyString
, const wxPoint
& pos
= wxDefaultPosition
, const wxSize
& size
= wxDefaultSize
,
152 long style
= wxRE_MULTILINE
, const wxValidator
& validator
= wxDefaultValidator
, const wxString
& name
= wxTextCtrlNameStr
):
153 wxRichTextCtrl(parent
, id
, value
, pos
, size
, style
, validator
, name
)
159 void SetLockId(long id
) { m_lockId
= id
; }
160 long GetLockId() const { return m_lockId
; }
162 void BeginLock() { m_lockId
++; m_locked
= true; }
163 void EndLock() { m_locked
= false; }
164 bool IsLocked() const { return m_locked
; }
166 static void SetEnhancedDrawingHandler();
169 Prepares the content just before insertion (or after buffer reset). Called by the same function in wxRichTextBuffer.
170 Currently is only called if undo mode is on.
172 virtual void PrepareContent(wxRichTextParagraphLayoutBox
& container
);
175 Can we delete this range?
176 Sends an event to the control.
178 virtual bool CanDeleteRange(wxRichTextParagraphLayoutBox
& container
, const wxRichTextRange
& range
) const;
181 Can we insert content at this position?
182 Sends an event to the control.
184 virtual bool CanInsertContent(wxRichTextParagraphLayoutBox
& container
, long pos
) const;
190 // Define a new application type, each program should derive a class from wxApp
191 class MyApp
: public wxApp
194 // override base class virtuals
195 // ----------------------------
197 // this one is called on application startup and is a good place for the app
198 // initialization (doing it here and not in the ctor allows to have an error
199 // return: if OnInit() returns false, the application terminates)
200 virtual bool OnInit();
201 virtual int OnExit();
205 wxRichTextStyleSheet
* GetStyleSheet() const { return m_styleSheet
; }
206 wxRichTextPrinting
* GetPrinting() const { return m_printing
; }
208 wxRichTextStyleSheet
* m_styleSheet
;
209 wxRichTextPrinting
* m_printing
;
212 // Define a new frame type: this is going to be our main frame
213 class MyFrame
: public wxFrame
217 MyFrame(const wxString
& title
, wxWindowID id
, const wxPoint
& pos
= wxDefaultPosition
,
218 const wxSize
& size
= wxDefaultSize
, long style
= wxDEFAULT_FRAME_STYLE
);
220 // event handlers (these functions should _not_ be virtual)
221 void OnQuit(wxCommandEvent
& event
);
222 void OnAbout(wxCommandEvent
& event
);
224 void OnOpen(wxCommandEvent
& event
);
225 void OnSave(wxCommandEvent
& event
);
226 void OnSaveAs(wxCommandEvent
& event
);
228 void OnBold(wxCommandEvent
& event
);
229 void OnItalic(wxCommandEvent
& event
);
230 void OnUnderline(wxCommandEvent
& event
);
232 void OnStrikethrough(wxCommandEvent
& event
);
233 void OnSuperscript(wxCommandEvent
& event
);
234 void OnSubscript(wxCommandEvent
& event
);
236 void OnUpdateBold(wxUpdateUIEvent
& event
);
237 void OnUpdateItalic(wxUpdateUIEvent
& event
);
238 void OnUpdateUnderline(wxUpdateUIEvent
& event
);
239 void OnUpdateStrikethrough(wxUpdateUIEvent
& event
);
240 void OnUpdateSuperscript(wxUpdateUIEvent
& event
);
241 void OnUpdateSubscript(wxUpdateUIEvent
& event
);
243 void OnAlignLeft(wxCommandEvent
& event
);
244 void OnAlignCentre(wxCommandEvent
& event
);
245 void OnAlignRight(wxCommandEvent
& event
);
247 void OnUpdateAlignLeft(wxUpdateUIEvent
& event
);
248 void OnUpdateAlignCentre(wxUpdateUIEvent
& event
);
249 void OnUpdateAlignRight(wxUpdateUIEvent
& event
);
251 void OnIndentMore(wxCommandEvent
& event
);
252 void OnIndentLess(wxCommandEvent
& event
);
254 void OnFont(wxCommandEvent
& event
);
255 void OnImage(wxCommandEvent
& event
);
256 void OnUpdateImage(wxUpdateUIEvent
& event
);
257 void OnParagraph(wxCommandEvent
& event
);
258 void OnFormat(wxCommandEvent
& event
);
259 void OnUpdateFormat(wxUpdateUIEvent
& event
);
261 void OnInsertSymbol(wxCommandEvent
& event
);
263 void OnLineSpacingHalf(wxCommandEvent
& event
);
264 void OnLineSpacingDouble(wxCommandEvent
& event
);
265 void OnLineSpacingSingle(wxCommandEvent
& event
);
267 void OnParagraphSpacingMore(wxCommandEvent
& event
);
268 void OnParagraphSpacingLess(wxCommandEvent
& event
);
270 void OnNumberList(wxCommandEvent
& event
);
271 void OnBulletsAndNumbering(wxCommandEvent
& event
);
272 void OnItemizeList(wxCommandEvent
& event
);
273 void OnRenumberList(wxCommandEvent
& event
);
274 void OnPromoteList(wxCommandEvent
& event
);
275 void OnDemoteList(wxCommandEvent
& event
);
276 void OnClearList(wxCommandEvent
& event
);
278 void OnReload(wxCommandEvent
& event
);
280 void OnViewHTML(wxCommandEvent
& event
);
282 void OnSwitchStyleSheets(wxCommandEvent
& event
);
283 void OnManageStyles(wxCommandEvent
& event
);
285 void OnInsertURL(wxCommandEvent
& event
);
286 void OnURL(wxTextUrlEvent
& event
);
287 void OnStyleSheetReplacing(wxRichTextEvent
& event
);
289 void OnPrint(wxCommandEvent
& event
);
290 void OnPreview(wxCommandEvent
& event
);
291 void OnPageSetup(wxCommandEvent
& event
);
293 void OnInsertImage(wxCommandEvent
& event
);
295 void OnSetFontScale(wxCommandEvent
& event
);
296 void OnSetDimensionScale(wxCommandEvent
& event
);
299 // Forward command events to the current rich text control, if any
300 bool ProcessEvent(wxEvent
& event
);
303 void WriteInitialText();
306 // any class wishing to process wxWidgets events must use this macro
307 DECLARE_EVENT_TABLE()
309 MyRichTextCtrl
* m_richTextCtrl
;
312 // ----------------------------------------------------------------------------
314 // ----------------------------------------------------------------------------
316 // IDs for the controls and the menu commands
321 ID_About
= wxID_ABOUT
,
323 ID_FORMAT_BOLD
= 100,
326 ID_FORMAT_STRIKETHROUGH
,
327 ID_FORMAT_SUPERSCRIPT
,
340 ID_FORMAT_ALIGN_LEFT
,
341 ID_FORMAT_ALIGN_CENTRE
,
342 ID_FORMAT_ALIGN_RIGHT
,
344 ID_FORMAT_INDENT_MORE
,
345 ID_FORMAT_INDENT_LESS
,
347 ID_FORMAT_PARAGRAPH_SPACING_MORE
,
348 ID_FORMAT_PARAGRAPH_SPACING_LESS
,
350 ID_FORMAT_LINE_SPACING_HALF
,
351 ID_FORMAT_LINE_SPACING_DOUBLE
,
352 ID_FORMAT_LINE_SPACING_SINGLE
,
354 ID_FORMAT_NUMBER_LIST
,
355 ID_FORMAT_BULLETS_AND_NUMBERING
,
356 ID_FORMAT_ITEMIZE_LIST
,
357 ID_FORMAT_RENUMBER_LIST
,
358 ID_FORMAT_PROMOTE_LIST
,
359 ID_FORMAT_DEMOTE_LIST
,
360 ID_FORMAT_CLEAR_LIST
,
363 ID_SET_DIMENSION_SCALE
,
366 ID_SWITCH_STYLE_SHEETS
,
374 ID_RICHTEXT_STYLE_LIST
,
375 ID_RICHTEXT_STYLE_COMBO
378 // ----------------------------------------------------------------------------
379 // event tables and other macros for wxWidgets
380 // ----------------------------------------------------------------------------
382 // the event tables connect the wxWidgets events with the functions (event
383 // handlers) which process them. It can be also done at run-time, but for the
384 // simple menu events like this the static method is much simpler.
385 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
386 EVT_MENU(ID_Quit
, MyFrame::OnQuit
)
387 EVT_MENU(ID_About
, MyFrame::OnAbout
)
389 EVT_MENU(wxID_OPEN
, MyFrame::OnOpen
)
390 EVT_MENU(wxID_SAVE
, MyFrame::OnSave
)
391 EVT_MENU(wxID_SAVEAS
, MyFrame::OnSaveAs
)
393 EVT_MENU(ID_FORMAT_BOLD
, MyFrame::OnBold
)
394 EVT_MENU(ID_FORMAT_ITALIC
, MyFrame::OnItalic
)
395 EVT_MENU(ID_FORMAT_UNDERLINE
, MyFrame::OnUnderline
)
397 EVT_MENU(ID_FORMAT_STRIKETHROUGH
, MyFrame::OnStrikethrough
)
398 EVT_MENU(ID_FORMAT_SUPERSCRIPT
, MyFrame::OnSuperscript
)
399 EVT_MENU(ID_FORMAT_SUBSCRIPT
, MyFrame::OnSubscript
)
401 EVT_UPDATE_UI(ID_FORMAT_BOLD
, MyFrame::OnUpdateBold
)
402 EVT_UPDATE_UI(ID_FORMAT_ITALIC
, MyFrame::OnUpdateItalic
)
403 EVT_UPDATE_UI(ID_FORMAT_UNDERLINE
, MyFrame::OnUpdateUnderline
)
405 EVT_UPDATE_UI(ID_FORMAT_STRIKETHROUGH
, MyFrame::OnUpdateStrikethrough
)
406 EVT_UPDATE_UI(ID_FORMAT_SUPERSCRIPT
, MyFrame::OnUpdateSuperscript
)
407 EVT_UPDATE_UI(ID_FORMAT_SUBSCRIPT
, MyFrame::OnUpdateSubscript
)
409 EVT_MENU(ID_FORMAT_ALIGN_LEFT
, MyFrame::OnAlignLeft
)
410 EVT_MENU(ID_FORMAT_ALIGN_CENTRE
, MyFrame::OnAlignCentre
)
411 EVT_MENU(ID_FORMAT_ALIGN_RIGHT
, MyFrame::OnAlignRight
)
413 EVT_UPDATE_UI(ID_FORMAT_ALIGN_LEFT
, MyFrame::OnUpdateAlignLeft
)
414 EVT_UPDATE_UI(ID_FORMAT_ALIGN_CENTRE
, MyFrame::OnUpdateAlignCentre
)
415 EVT_UPDATE_UI(ID_FORMAT_ALIGN_RIGHT
, MyFrame::OnUpdateAlignRight
)
417 EVT_MENU(ID_FORMAT_FONT
, MyFrame::OnFont
)
418 EVT_MENU(ID_FORMAT_IMAGE
, MyFrame::OnImage
)
419 EVT_MENU(ID_FORMAT_PARAGRAPH
, MyFrame::OnParagraph
)
420 EVT_MENU(ID_FORMAT_CONTENT
, MyFrame::OnFormat
)
421 EVT_UPDATE_UI(ID_FORMAT_CONTENT
, MyFrame::OnUpdateFormat
)
422 EVT_UPDATE_UI(ID_FORMAT_FONT
, MyFrame::OnUpdateFormat
)
423 EVT_UPDATE_UI(ID_FORMAT_IMAGE
, MyFrame::OnUpdateImage
)
424 EVT_UPDATE_UI(ID_FORMAT_PARAGRAPH
, MyFrame::OnUpdateFormat
)
425 EVT_MENU(ID_FORMAT_INDENT_MORE
, MyFrame::OnIndentMore
)
426 EVT_MENU(ID_FORMAT_INDENT_LESS
, MyFrame::OnIndentLess
)
428 EVT_MENU(ID_FORMAT_LINE_SPACING_HALF
, MyFrame::OnLineSpacingHalf
)
429 EVT_MENU(ID_FORMAT_LINE_SPACING_SINGLE
, MyFrame::OnLineSpacingSingle
)
430 EVT_MENU(ID_FORMAT_LINE_SPACING_DOUBLE
, MyFrame::OnLineSpacingDouble
)
432 EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_MORE
, MyFrame::OnParagraphSpacingMore
)
433 EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_LESS
, MyFrame::OnParagraphSpacingLess
)
435 EVT_MENU(ID_RELOAD
, MyFrame::OnReload
)
437 EVT_MENU(ID_INSERT_SYMBOL
, MyFrame::OnInsertSymbol
)
438 EVT_MENU(ID_INSERT_URL
, MyFrame::OnInsertURL
)
439 EVT_MENU(ID_INSERT_IMAGE
, MyFrame::OnInsertImage
)
441 EVT_MENU(ID_FORMAT_NUMBER_LIST
, MyFrame::OnNumberList
)
442 EVT_MENU(ID_FORMAT_BULLETS_AND_NUMBERING
, MyFrame::OnBulletsAndNumbering
)
443 EVT_MENU(ID_FORMAT_ITEMIZE_LIST
, MyFrame::OnItemizeList
)
444 EVT_MENU(ID_FORMAT_RENUMBER_LIST
, MyFrame::OnRenumberList
)
445 EVT_MENU(ID_FORMAT_PROMOTE_LIST
, MyFrame::OnPromoteList
)
446 EVT_MENU(ID_FORMAT_DEMOTE_LIST
, MyFrame::OnDemoteList
)
447 EVT_MENU(ID_FORMAT_CLEAR_LIST
, MyFrame::OnClearList
)
449 EVT_MENU(ID_VIEW_HTML
, MyFrame::OnViewHTML
)
450 EVT_MENU(ID_SWITCH_STYLE_SHEETS
, MyFrame::OnSwitchStyleSheets
)
451 EVT_MENU(ID_MANAGE_STYLES
, MyFrame::OnManageStyles
)
453 EVT_MENU(ID_PRINT
, MyFrame::OnPrint
)
454 EVT_MENU(ID_PREVIEW
, MyFrame::OnPreview
)
455 EVT_MENU(ID_PAGE_SETUP
, MyFrame::OnPageSetup
)
457 EVT_TEXT_URL(wxID_ANY
, MyFrame::OnURL
)
458 EVT_RICHTEXT_STYLESHEET_REPLACING(wxID_ANY
, MyFrame::OnStyleSheetReplacing
)
460 EVT_MENU(ID_SET_FONT_SCALE
, MyFrame::OnSetFontScale
)
461 EVT_MENU(ID_SET_DIMENSION_SCALE
, MyFrame::OnSetDimensionScale
)
464 // Create a new application object: this macro will allow wxWidgets to create
465 // the application object during program execution (it's better than using a
466 // static object for many reasons) and also implements the accessor function
467 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
471 // ============================================================================
473 // ============================================================================
475 // ----------------------------------------------------------------------------
476 // the application class
477 // ----------------------------------------------------------------------------
479 // 'Main program' equivalent: the program execution "starts" here
482 if ( !wxApp::OnInit() )
486 wxHelpProvider::Set(new wxSimpleHelpProvider
);
489 m_styleSheet
= new wxRichTextStyleSheet
;
490 m_printing
= new wxRichTextPrinting(wxT("Test Document"));
492 m_printing
->SetFooterText(wxT("@TITLE@"), wxRICHTEXT_PAGE_ALL
, wxRICHTEXT_PAGE_CENTRE
);
493 m_printing
->SetFooterText(wxT("Page @PAGENUM@"), wxRICHTEXT_PAGE_ALL
, wxRICHTEXT_PAGE_RIGHT
);
497 MyRichTextCtrl::SetEnhancedDrawingHandler();
499 // Add extra handlers (plain text is automatically added)
500 wxRichTextBuffer::AddHandler(new wxRichTextXMLHandler
);
501 wxRichTextBuffer::AddHandler(new wxRichTextHTMLHandler
);
505 wxRichTextBuffer::AddFieldType(new wxRichTextFieldTypePropertiesTest(wxT("rectangle"), wxT("RECTANGLE"), wxRichTextFieldTypeStandard::wxRICHTEXT_FIELD_STYLE_RECTANGLE
));
507 wxRichTextFieldTypeStandard
* s1
= new wxRichTextFieldTypeStandard(wxT("begin-section"), wxT("SECTION"), wxRichTextFieldTypeStandard::wxRICHTEXT_FIELD_STYLE_START_TAG
);
508 s1
->SetBackgroundColour(*wxBLUE
);
510 wxRichTextFieldTypeStandard
* s2
= new wxRichTextFieldTypeStandard(wxT("end-section"), wxT("SECTION"), wxRichTextFieldTypeStandard::wxRICHTEXT_FIELD_STYLE_END_TAG
);
511 s2
->SetBackgroundColour(*wxBLUE
);
513 wxRichTextFieldTypeStandard
* s3
= new wxRichTextFieldTypeStandard(wxT("bitmap"), wxBitmap(paste_xpm
), wxRichTextFieldTypeStandard::wxRICHTEXT_FIELD_STYLE_NO_BORDER
);
515 wxRichTextBuffer::AddFieldType(s1
);
516 wxRichTextBuffer::AddFieldType(s2
);
517 wxRichTextBuffer::AddFieldType(s3
);
519 wxRichTextFieldTypeCompositeTest
* s4
= new wxRichTextFieldTypeCompositeTest(wxT("composite"), wxT("This is a field value"));
520 wxRichTextBuffer::AddFieldType(s4
);
522 // Add image handlers
524 wxImage::AddHandler( new wxPNGHandler
);
528 wxImage::AddHandler( new wxJPEGHandler
);
532 wxImage::AddHandler( new wxGIFHandler
);
536 wxFileSystem::AddHandler( new wxMemoryFSHandler
);
539 // create the main application window
540 wxSize size
= wxGetDisplaySize();
541 size
.Scale(0.75, 0.75);
542 MyFrame
*frame
= new MyFrame(wxT("wxRichTextCtrl Sample"), wxID_ANY
, wxDefaultPosition
, size
);
544 m_printing
->SetParentWindow(frame
);
546 // and show it (the frames, unlike simple controls, are not shown when
547 // created initially)
550 // success: wxApp::OnRun() will be called which will enter the main message
551 // loop and the application will run. If we returned false here, the
552 // application would exit immediately.
564 void MyApp::CreateStyles()
568 wxFont
romanFont(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
569 wxFont
swissFont(12, wxSWISS
, wxNORMAL
, wxNORMAL
);
571 wxRichTextParagraphStyleDefinition
* normalPara
= new wxRichTextParagraphStyleDefinition(wxT("Normal"));
572 wxRichTextAttr normalAttr
;
573 normalAttr
.SetFontFaceName(romanFont
.GetFaceName());
574 normalAttr
.SetFontSize(12);
575 // Let's set all attributes for this style
576 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
|
577 wxTEXT_ATTR_PARA_SPACING_BEFORE
|wxTEXT_ATTR_PARA_SPACING_AFTER
|wxTEXT_ATTR_LINE_SPACING
|
578 wxTEXT_ATTR_BULLET_STYLE
|wxTEXT_ATTR_BULLET_NUMBER
);
579 normalPara
->SetStyle(normalAttr
);
581 m_styleSheet
->AddParagraphStyle(normalPara
);
583 wxRichTextParagraphStyleDefinition
* indentedPara
= new wxRichTextParagraphStyleDefinition(wxT("Indented"));
584 wxRichTextAttr indentedAttr
;
585 indentedAttr
.SetFontFaceName(romanFont
.GetFaceName());
586 indentedAttr
.SetFontSize(12);
587 indentedAttr
.SetLeftIndent(100, 0);
588 // We only want to affect indentation
589 indentedAttr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
);
590 indentedPara
->SetStyle(indentedAttr
);
592 m_styleSheet
->AddParagraphStyle(indentedPara
);
594 wxRichTextParagraphStyleDefinition
* indentedPara2
= new wxRichTextParagraphStyleDefinition(wxT("Red Bold Indented"));
595 wxRichTextAttr indentedAttr2
;
596 indentedAttr2
.SetFontFaceName(romanFont
.GetFaceName());
597 indentedAttr2
.SetFontSize(12);
598 indentedAttr2
.SetFontWeight(wxFONTWEIGHT_BOLD
);
599 indentedAttr2
.SetTextColour(*wxRED
);
600 indentedAttr2
.SetFontSize(12);
601 indentedAttr2
.SetLeftIndent(100, 0);
602 // We want to affect indentation, font and text colour
603 indentedAttr2
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
|wxTEXT_ATTR_FONT
|wxTEXT_ATTR_TEXT_COLOUR
);
604 indentedPara2
->SetStyle(indentedAttr2
);
606 m_styleSheet
->AddParagraphStyle(indentedPara2
);
608 wxRichTextParagraphStyleDefinition
* flIndentedPara
= new wxRichTextParagraphStyleDefinition(wxT("First Line Indented"));
609 wxRichTextAttr flIndentedAttr
;
610 flIndentedAttr
.SetFontFaceName(swissFont
.GetFaceName());
611 flIndentedAttr
.SetFontSize(12);
612 flIndentedAttr
.SetLeftIndent(100, -100);
613 // We only want to affect indentation
614 flIndentedAttr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
);
615 flIndentedPara
->SetStyle(flIndentedAttr
);
617 m_styleSheet
->AddParagraphStyle(flIndentedPara
);
621 wxRichTextCharacterStyleDefinition
* boldDef
= new wxRichTextCharacterStyleDefinition(wxT("Bold"));
622 wxRichTextAttr boldAttr
;
623 boldAttr
.SetFontFaceName(romanFont
.GetFaceName());
624 boldAttr
.SetFontSize(12);
625 boldAttr
.SetFontWeight(wxFONTWEIGHT_BOLD
);
626 // We only want to affect boldness
627 boldAttr
.SetFlags(wxTEXT_ATTR_FONT_WEIGHT
);
628 boldDef
->SetStyle(boldAttr
);
630 m_styleSheet
->AddCharacterStyle(boldDef
);
632 wxRichTextCharacterStyleDefinition
* italicDef
= new wxRichTextCharacterStyleDefinition(wxT("Italic"));
633 wxRichTextAttr italicAttr
;
634 italicAttr
.SetFontFaceName(romanFont
.GetFaceName());
635 italicAttr
.SetFontSize(12);
636 italicAttr
.SetFontStyle(wxFONTSTYLE_ITALIC
);
637 // We only want to affect italics
638 italicAttr
.SetFlags(wxTEXT_ATTR_FONT_ITALIC
);
639 italicDef
->SetStyle(italicAttr
);
641 m_styleSheet
->AddCharacterStyle(italicDef
);
643 wxRichTextCharacterStyleDefinition
* redDef
= new wxRichTextCharacterStyleDefinition(wxT("Red Bold"));
644 wxRichTextAttr redAttr
;
645 redAttr
.SetFontFaceName(romanFont
.GetFaceName());
646 redAttr
.SetFontSize(12);
647 redAttr
.SetFontWeight(wxFONTWEIGHT_BOLD
);
648 redAttr
.SetTextColour(*wxRED
);
649 // We only want to affect colour, weight and face
650 redAttr
.SetFlags(wxTEXT_ATTR_FONT_FACE
|wxTEXT_ATTR_FONT_WEIGHT
|wxTEXT_ATTR_TEXT_COLOUR
);
651 redDef
->SetStyle(redAttr
);
653 m_styleSheet
->AddCharacterStyle(redDef
);
655 wxRichTextListStyleDefinition
* bulletList
= new wxRichTextListStyleDefinition(wxT("Bullet List 1"));
657 for (i
= 0; i
< 10; i
++)
661 bulletText
= wxT("standard/circle");
663 bulletText
= wxT("standard/square");
665 bulletText
= wxT("standard/circle");
667 bulletText
= wxT("standard/square");
669 bulletText
= wxT("standard/circle");
671 bulletList
->SetAttributes(i
, (i
+1)*60, 60, wxTEXT_ATTR_BULLET_STYLE_STANDARD
, bulletText
);
674 m_styleSheet
->AddListStyle(bulletList
);
676 wxRichTextListStyleDefinition
* numberedList
= new wxRichTextListStyleDefinition(wxT("Numbered List 1"));
677 for (i
= 0; i
< 10; i
++)
681 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
683 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_LETTERS_LOWER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
685 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ROMAN_LOWER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
687 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ROMAN_UPPER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
689 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
691 numberStyle
|= wxTEXT_ATTR_BULLET_STYLE_ALIGN_RIGHT
;
693 numberedList
->SetAttributes(i
, (i
+1)*60, 60, numberStyle
);
696 m_styleSheet
->AddListStyle(numberedList
);
698 wxRichTextListStyleDefinition
* outlineList
= new wxRichTextListStyleDefinition(wxT("Outline List 1"));
699 for (i
= 0; i
< 10; i
++)
703 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_OUTLINE
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
705 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
707 outlineList
->SetAttributes(i
, (i
+1)*120, 120, numberStyle
);
710 m_styleSheet
->AddListStyle(outlineList
);
713 // ----------------------------------------------------------------------------
715 // ----------------------------------------------------------------------------
718 MyFrame::MyFrame(const wxString
& title
, wxWindowID id
, const wxPoint
& pos
,
719 const wxSize
& size
, long style
)
720 : wxFrame(NULL
, id
, title
, pos
, size
, style
)
723 SetWindowVariant(wxWINDOW_VARIANT_SMALL
);
726 // set the frame icon
727 SetIcon(wxICON(sample
));
730 wxMenu
*fileMenu
= new wxMenu
;
732 // the "About" item should be in the help menu
733 wxMenu
*helpMenu
= new wxMenu
;
734 helpMenu
->Append(ID_About
, wxT("&About\tF1"), wxT("Show about dialog"));
736 fileMenu
->Append(wxID_OPEN
, wxT("&Open\tCtrl+O"), wxT("Open a file"));
737 fileMenu
->Append(wxID_SAVE
, wxT("&Save\tCtrl+S"), wxT("Save a file"));
738 fileMenu
->Append(wxID_SAVEAS
, wxT("&Save As...\tF12"), wxT("Save to a new file"));
739 fileMenu
->AppendSeparator();
740 fileMenu
->Append(ID_RELOAD
, wxT("&Reload Text\tF2"), wxT("Reload the initial text"));
741 fileMenu
->AppendSeparator();
742 fileMenu
->Append(ID_PAGE_SETUP
, wxT("Page Set&up..."), wxT("Page setup"));
743 fileMenu
->Append(ID_PRINT
, wxT("&Print...\tCtrl+P"), wxT("Print"));
744 fileMenu
->Append(ID_PREVIEW
, wxT("Print Pre&view"), wxT("Print preview"));
745 fileMenu
->AppendSeparator();
746 fileMenu
->Append(ID_VIEW_HTML
, wxT("&View as HTML"), wxT("View HTML"));
747 fileMenu
->AppendSeparator();
748 fileMenu
->Append(ID_Quit
, wxT("E&xit\tAlt+X"), wxT("Quit this program"));
750 wxMenu
* editMenu
= new wxMenu
;
751 editMenu
->Append(wxID_UNDO
, _("&Undo\tCtrl+Z"));
752 editMenu
->Append(wxID_REDO
, _("&Redo\tCtrl+Y"));
753 editMenu
->AppendSeparator();
754 editMenu
->Append(wxID_CUT
, _("Cu&t\tCtrl+X"));
755 editMenu
->Append(wxID_COPY
, _("&Copy\tCtrl+C"));
756 editMenu
->Append(wxID_PASTE
, _("&Paste\tCtrl+V"));
758 editMenu
->AppendSeparator();
759 editMenu
->Append(wxID_SELECTALL
, _("Select A&ll\tCtrl+A"));
760 editMenu
->AppendSeparator();
761 editMenu
->Append(ID_SET_FONT_SCALE
, _("Set &Text Scale..."));
762 editMenu
->Append(ID_SET_DIMENSION_SCALE
, _("Set &Dimension Scale..."));
764 wxMenu
* formatMenu
= new wxMenu
;
765 formatMenu
->AppendCheckItem(ID_FORMAT_BOLD
, _("&Bold\tCtrl+B"));
766 formatMenu
->AppendCheckItem(ID_FORMAT_ITALIC
, _("&Italic\tCtrl+I"));
767 formatMenu
->AppendCheckItem(ID_FORMAT_UNDERLINE
, _("&Underline\tCtrl+U"));
768 formatMenu
->AppendSeparator();
769 formatMenu
->AppendCheckItem(ID_FORMAT_STRIKETHROUGH
, _("Stri&kethrough"));
770 formatMenu
->AppendCheckItem(ID_FORMAT_SUPERSCRIPT
, _("Superscrip&t"));
771 formatMenu
->AppendCheckItem(ID_FORMAT_SUBSCRIPT
, _("Subscrip&t"));
772 formatMenu
->AppendSeparator();
773 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_LEFT
, _("L&eft Align"));
774 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_RIGHT
, _("&Right Align"));
775 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_CENTRE
, _("&Centre"));
776 formatMenu
->AppendSeparator();
777 formatMenu
->Append(ID_FORMAT_INDENT_MORE
, _("Indent &More"));
778 formatMenu
->Append(ID_FORMAT_INDENT_LESS
, _("Indent &Less"));
779 formatMenu
->AppendSeparator();
780 formatMenu
->Append(ID_FORMAT_PARAGRAPH_SPACING_MORE
, _("Increase Paragraph &Spacing"));
781 formatMenu
->Append(ID_FORMAT_PARAGRAPH_SPACING_LESS
, _("Decrease &Paragraph Spacing"));
782 formatMenu
->AppendSeparator();
783 formatMenu
->Append(ID_FORMAT_LINE_SPACING_SINGLE
, _("Normal Line Spacing"));
784 formatMenu
->Append(ID_FORMAT_LINE_SPACING_HALF
, _("1.5 Line Spacing"));
785 formatMenu
->Append(ID_FORMAT_LINE_SPACING_DOUBLE
, _("Double Line Spacing"));
786 formatMenu
->AppendSeparator();
787 formatMenu
->Append(ID_FORMAT_FONT
, _("&Font..."));
788 formatMenu
->Append(ID_FORMAT_IMAGE
, _("Image Property"));
789 formatMenu
->Append(ID_FORMAT_PARAGRAPH
, _("&Paragraph..."));
790 formatMenu
->Append(ID_FORMAT_CONTENT
, _("Font and Pa&ragraph...\tShift+Ctrl+F"));
791 formatMenu
->AppendSeparator();
792 formatMenu
->Append(ID_SWITCH_STYLE_SHEETS
, _("&Switch Style Sheets"));
793 formatMenu
->Append(ID_MANAGE_STYLES
, _("&Manage Styles"));
795 wxMenu
* listsMenu
= new wxMenu
;
796 listsMenu
->Append(ID_FORMAT_BULLETS_AND_NUMBERING
, _("Bullets and &Numbering..."));
797 listsMenu
->AppendSeparator();
798 listsMenu
->Append(ID_FORMAT_NUMBER_LIST
, _("Number List"));
799 listsMenu
->Append(ID_FORMAT_ITEMIZE_LIST
, _("Itemize List"));
800 listsMenu
->Append(ID_FORMAT_RENUMBER_LIST
, _("Renumber List"));
801 listsMenu
->Append(ID_FORMAT_PROMOTE_LIST
, _("Promote List Items"));
802 listsMenu
->Append(ID_FORMAT_DEMOTE_LIST
, _("Demote List Items"));
803 listsMenu
->Append(ID_FORMAT_CLEAR_LIST
, _("Clear List Formatting"));
805 wxMenu
* insertMenu
= new wxMenu
;
806 insertMenu
->Append(ID_INSERT_SYMBOL
, _("&Symbol...\tCtrl+I"));
807 insertMenu
->Append(ID_INSERT_URL
, _("&URL..."));
808 insertMenu
->Append(ID_INSERT_IMAGE
, _("&Image..."));
810 // now append the freshly created menu to the menu bar...
811 wxMenuBar
*menuBar
= new wxMenuBar();
812 menuBar
->Append(fileMenu
, wxT("&File"));
813 menuBar
->Append(editMenu
, wxT("&Edit"));
814 menuBar
->Append(formatMenu
, wxT("F&ormat"));
815 menuBar
->Append(listsMenu
, wxT("&Lists"));
816 menuBar
->Append(insertMenu
, wxT("&Insert"));
817 menuBar
->Append(helpMenu
, wxT("&Help"));
819 // ... and attach this menu bar to the frame
822 // create a status bar just for fun (by default with 1 pane only)
823 // but don't create it on limited screen space (WinCE)
824 bool is_pda
= wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA
;
830 SetStatusText(wxT("Welcome to wxRichTextCtrl!"));
834 wxBoxSizer
* sizer
= new wxBoxSizer(wxVERTICAL
);
837 // On Mac, don't create a 'native' wxToolBar because small bitmaps are not supported by native
838 // toolbars. On Mac, a non-native, small-bitmap toolbar doesn't show unless it is explicitly
839 // managed, hence the use of sizers. In a real application, use larger icons for the main
840 // toolbar to avoid the need for this workaround. Or, use the toolbar in a container window
841 // as part of a more complex hierarchy, and the toolbar will automatically be non-native.
843 wxSystemOptions::SetOption(wxT("mac.toolbar.no-native"), 1);
845 wxToolBar
* toolBar
= new wxToolBar(this, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
,
846 wxNO_BORDER
|wxTB_FLAT
|wxTB_NODIVIDER
|wxTB_NOALIGN
);
848 sizer
->Add(toolBar
, 0, wxEXPAND
);
850 toolBar
->AddTool(wxID_OPEN
, wxEmptyString
, wxBitmap(open_xpm
), _("Open"));
851 toolBar
->AddTool(wxID_SAVEAS
, wxEmptyString
, wxBitmap(save_xpm
), _("Save"));
852 toolBar
->AddSeparator();
853 toolBar
->AddTool(wxID_CUT
, wxEmptyString
, wxBitmap(cut_xpm
), _("Cut"));
854 toolBar
->AddTool(wxID_COPY
, wxEmptyString
, wxBitmap(copy_xpm
), _("Copy"));
855 toolBar
->AddTool(wxID_PASTE
, wxEmptyString
, wxBitmap(paste_xpm
), _("Paste"));
856 toolBar
->AddSeparator();
857 toolBar
->AddTool(wxID_UNDO
, wxEmptyString
, wxBitmap(undo_xpm
), _("Undo"));
858 toolBar
->AddTool(wxID_REDO
, wxEmptyString
, wxBitmap(redo_xpm
), _("Redo"));
859 toolBar
->AddSeparator();
860 toolBar
->AddCheckTool(ID_FORMAT_BOLD
, wxEmptyString
, wxBitmap(bold_xpm
), wxNullBitmap
, _("Bold"));
861 toolBar
->AddCheckTool(ID_FORMAT_ITALIC
, wxEmptyString
, wxBitmap(italic_xpm
), wxNullBitmap
, _("Italic"));
862 toolBar
->AddCheckTool(ID_FORMAT_UNDERLINE
, wxEmptyString
, wxBitmap(underline_xpm
), wxNullBitmap
, _("Underline"));
863 toolBar
->AddSeparator();
864 toolBar
->AddCheckTool(ID_FORMAT_ALIGN_LEFT
, wxEmptyString
, wxBitmap(alignleft_xpm
), wxNullBitmap
, _("Align Left"));
865 toolBar
->AddCheckTool(ID_FORMAT_ALIGN_CENTRE
, wxEmptyString
, wxBitmap(centre_xpm
), wxNullBitmap
, _("Centre"));
866 toolBar
->AddCheckTool(ID_FORMAT_ALIGN_RIGHT
, wxEmptyString
, wxBitmap(alignright_xpm
), wxNullBitmap
, _("Align Right"));
867 toolBar
->AddSeparator();
868 toolBar
->AddTool(ID_FORMAT_INDENT_LESS
, wxEmptyString
, wxBitmap(indentless_xpm
), _("Indent Less"));
869 toolBar
->AddTool(ID_FORMAT_INDENT_MORE
, wxEmptyString
, wxBitmap(indentmore_xpm
), _("Indent More"));
870 toolBar
->AddSeparator();
871 toolBar
->AddTool(ID_FORMAT_FONT
, wxEmptyString
, wxBitmap(font_xpm
), _("Font"));
872 toolBar
->AddSeparator();
874 wxRichTextStyleComboCtrl
* combo
= new wxRichTextStyleComboCtrl(toolBar
, ID_RICHTEXT_STYLE_COMBO
, wxDefaultPosition
, wxSize(160, -1), wxCB_READONLY
);
875 toolBar
->AddControl(combo
);
879 wxSplitterWindow
* splitter
= new wxSplitterWindow(this, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
, wxSP_LIVE_UPDATE
);
880 sizer
->Add(splitter
, 1, wxEXPAND
);
882 wxFont textFont
= wxFont(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
883 wxFont boldFont
= wxFont(12, wxROMAN
, wxNORMAL
, wxBOLD
);
884 wxFont italicFont
= wxFont(12, wxROMAN
, wxITALIC
, wxNORMAL
);
886 m_richTextCtrl
= new MyRichTextCtrl(splitter
, ID_RICHTEXT_CTRL
, wxEmptyString
, wxDefaultPosition
, wxDefaultSize
, wxVSCROLL
|wxHSCROLL
|wxWANTS_CHARS
);
887 wxASSERT(!m_richTextCtrl
->GetBuffer().GetAttributes().HasFontPixelSize());
889 wxFont
font(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
891 m_richTextCtrl
->SetFont(font
);
893 wxASSERT(!m_richTextCtrl
->GetBuffer().GetAttributes().HasFontPixelSize());
895 m_richTextCtrl
->SetMargins(10, 10);
897 m_richTextCtrl
->SetStyleSheet(wxGetApp().GetStyleSheet());
899 combo
->SetStyleSheet(wxGetApp().GetStyleSheet());
900 combo
->SetRichTextCtrl(m_richTextCtrl
);
901 combo
->UpdateStyles();
903 wxRichTextStyleListCtrl
* styleListCtrl
= new wxRichTextStyleListCtrl(splitter
, ID_RICHTEXT_STYLE_LIST
);
905 wxSize display
= wxGetDisplaySize();
906 if ( is_pda
&& ( display
.GetWidth() < display
.GetHeight() ) )
908 splitter
->SplitHorizontally(m_richTextCtrl
, styleListCtrl
);
912 int width
= GetClientSize().GetWidth() * 0.8;
913 splitter
->SplitVertically(m_richTextCtrl
, styleListCtrl
, width
);
914 splitter
->SetSashGravity(0.8);
919 splitter
->UpdateSize();
921 styleListCtrl
->SetStyleSheet(wxGetApp().GetStyleSheet());
922 styleListCtrl
->SetRichTextCtrl(m_richTextCtrl
);
923 styleListCtrl
->UpdateStyles();
929 void MyFrame::WriteInitialText()
931 MyRichTextCtrl
& r
= *m_richTextCtrl
;
933 r
.SetDefaultStyle(wxRichTextAttr());
937 r
.BeginSuppressUndo();
939 r
.BeginParagraphSpacing(0, 20);
941 r
.BeginAlignment(wxTEXT_ALIGNMENT_CENTRE
);
946 wxString lineBreak
= (wxChar
) 29;
948 r
.WriteText(wxString(wxT("Welcome to wxRichTextCtrl, a wxWidgets control")) + lineBreak
+ wxT("for editing and presenting styled text and images\n"));
952 r
.WriteText(wxT("by Julian Smart"));
958 r
.WriteImage(wxBitmap(zebra_xpm
));
966 r
.BeginAlignment(wxTEXT_ALIGNMENT_CENTRE
);
967 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.")));
972 r
.BeginAlignment(wxTEXT_ALIGNMENT_LEFT
);
973 wxRichTextAttr imageAttr
;
974 imageAttr
.GetTextBoxAttr().SetFloatMode(wxTEXT_BOX_ATTR_FLOAT_LEFT
);
975 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.")));
976 r
.WriteImage(wxBitmap(zebra_xpm
), wxBITMAP_TYPE_PNG
, imageAttr
);
978 imageAttr
.GetTextBoxAttr().GetTop().SetValue(200);
979 imageAttr
.GetTextBoxAttr().GetTop().SetUnits(wxTEXT_ATTR_UNITS_PIXELS
);
980 imageAttr
.GetTextBoxAttr().SetFloatMode(wxTEXT_BOX_ATTR_FLOAT_RIGHT
);
981 r
.WriteImage(wxBitmap(zebra_xpm
), wxBITMAP_TYPE_PNG
, imageAttr
);
982 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.")));
986 r
.WriteText(wxT("What can you do with this thing? "));
988 r
.WriteImage(wxBitmap(smiley_xpm
));
989 r
.WriteText(wxT(" Well, you can change text "));
991 r
.BeginTextColour(*wxRED
);
992 r
.WriteText(wxT("colour, like this red bit."));
995 wxRichTextAttr backgroundColourAttr
;
996 backgroundColourAttr
.SetBackgroundColour(*wxGREEN
);
997 backgroundColourAttr
.SetTextColour(*wxBLUE
);
998 r
.BeginStyle(backgroundColourAttr
);
999 r
.WriteText(wxT(" And this blue on green bit."));
1002 r
.WriteText(wxT(" Naturally you can make things "));
1004 r
.WriteText(wxT("bold "));
1007 r
.WriteText(wxT("or italic "));
1010 r
.WriteText(wxT("or underlined."));
1013 r
.BeginFontSize(14);
1014 r
.WriteText(wxT(" Different font sizes on the same line is allowed, too."));
1017 r
.WriteText(wxT(" Next we'll show an indented paragraph."));
1021 r
.BeginLeftIndent(60);
1022 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."));
1027 r
.WriteText(wxT("Next, we'll show a first-line indent, achieved using BeginLeftIndent(100, -40)."));
1031 r
.BeginLeftIndent(100, -40);
1033 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."));
1038 r
.WriteText(wxT("Numbered bullets are possible, again using subindents:"));
1041 r
.BeginNumberedBullet(1, 100, 60);
1042 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."));
1044 r
.EndNumberedBullet();
1046 r
.BeginNumberedBullet(2, 100, 60);
1047 r
.WriteText(wxT("This is my second item."));
1049 r
.EndNumberedBullet();
1051 r
.WriteText(wxT("The following paragraph is right-indented:"));
1054 r
.BeginRightIndent(200);
1056 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."));
1061 r
.WriteText(wxT("The following paragraph is right-aligned with 1.5 line spacing:"));
1064 r
.BeginAlignment(wxTEXT_ALIGNMENT_RIGHT
);
1065 r
.BeginLineSpacing(wxTEXT_ATTR_LINE_SPACING_HALF
);
1066 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."));
1076 wxRichTextAttr attr
;
1077 attr
.SetFlags(wxTEXT_ATTR_TABS
);
1079 r
.SetDefaultStyle(attr
);
1081 r
.WriteText(wxT("This line contains tabs:\tFirst tab\tSecond tab\tThird tab"));
1084 r
.WriteText(wxT("Other notable features of wxRichTextCtrl include:"));
1087 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1088 r
.WriteText(wxT("Compatibility with wxTextCtrl API"));
1090 r
.EndSymbolBullet();
1092 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1093 r
.WriteText(wxT("Easy stack-based BeginXXX()...EndXXX() style setting in addition to SetStyle()"));
1095 r
.EndSymbolBullet();
1097 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1098 r
.WriteText(wxT("XML loading and saving"));
1100 r
.EndSymbolBullet();
1102 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1103 r
.WriteText(wxT("Undo/Redo, with batching option and Undo suppressing"));
1105 r
.EndSymbolBullet();
1107 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1108 r
.WriteText(wxT("Clipboard copy and paste"));
1110 r
.EndSymbolBullet();
1112 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1113 r
.WriteText(wxT("wxRichTextStyleSheet with named character and paragraph styles, and control for applying named styles"));
1115 r
.EndSymbolBullet();
1117 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1118 r
.WriteText(wxT("A design that can easily be extended to other content types, ultimately with text boxes, tables, controls, and so on"));
1120 r
.EndSymbolBullet();
1122 // Make a style suitable for showing a URL
1123 wxRichTextAttr urlStyle
;
1124 urlStyle
.SetTextColour(*wxBLUE
);
1125 urlStyle
.SetFontUnderlined(true);
1127 r
.WriteText(wxT("wxRichTextCtrl can also display URLs, such as this one: "));
1128 r
.BeginStyle(urlStyle
);
1129 r
.BeginURL(wxT("http://www.wxwidgets.org"));
1130 r
.WriteText(wxT("The wxWidgets Web Site"));
1133 r
.WriteText(wxT(". Click on the URL to generate an event."));
1137 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"));
1139 r
.EndParagraphSpacing();
1147 wxRichTextAttr attr
;
1148 attr
.GetTextBoxAttr().GetMargins().GetLeft().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS
);
1149 attr
.GetTextBoxAttr().GetMargins().GetTop().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS
);
1150 attr
.GetTextBoxAttr().GetMargins().GetRight().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS
);
1151 attr
.GetTextBoxAttr().GetMargins().GetBottom().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS
);
1153 attr
.GetTextBoxAttr().GetBorder().SetColour(*wxBLACK
);
1154 attr
.GetTextBoxAttr().GetBorder().SetWidth(1, wxTEXT_ATTR_UNITS_PIXELS
);
1155 attr
.GetTextBoxAttr().GetBorder().SetStyle(wxTEXT_BOX_ATTR_BORDER_SOLID
);
1157 wxRichTextBox
* textBox
= r
.WriteTextBox(attr
);
1158 r
.SetFocusObject(textBox
);
1160 r
.WriteText(wxT("This is a text box. Just testing! Once more unto the breach, dear friends, once more..."));
1162 r
.SetFocusObject(NULL
); // Set the focus back to the main buffer
1163 r
.SetInsertionPointEnd();
1172 wxRichTextAttr attr
;
1173 attr
.GetTextBoxAttr().GetMargins().GetLeft().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS
);
1174 attr
.GetTextBoxAttr().GetMargins().GetTop().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS
);
1175 attr
.GetTextBoxAttr().GetMargins().GetRight().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS
);
1176 attr
.GetTextBoxAttr().GetMargins().GetBottom().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS
);
1177 attr
.GetTextBoxAttr().GetPadding() = attr
.GetTextBoxAttr().GetMargins();
1179 attr
.GetTextBoxAttr().GetBorder().SetColour(*wxBLACK
);
1180 attr
.GetTextBoxAttr().GetBorder().SetWidth(1, wxTEXT_ATTR_UNITS_PIXELS
);
1181 attr
.GetTextBoxAttr().GetBorder().SetStyle(wxTEXT_BOX_ATTR_BORDER_SOLID
);
1183 wxRichTextAttr cellAttr
= attr
;
1184 cellAttr
.GetTextBoxAttr().GetWidth().SetValue(200, wxTEXT_ATTR_UNITS_PIXELS
);
1185 cellAttr
.GetTextBoxAttr().GetHeight().SetValue(150, wxTEXT_ATTR_UNITS_PIXELS
);
1187 wxRichTextTable
* table
= r
.WriteTable(6, 4, attr
, cellAttr
);
1190 for (j
= 0; j
< table
->GetRowCount(); j
++)
1192 for (i
= 0; i
< table
->GetColumnCount(); i
++)
1194 wxString msg
= wxString::Format(wxT("This is cell %d, %d"), (j
+1), (i
+1));
1195 r
.SetFocusObject(table
->GetCell(j
, i
));
1200 // Demonstrate colspan and rowspan
1201 wxRichTextCell
* cell
= table
->GetCell(1, 0);
1202 cell
->SetColspan(2);
1203 r
.SetFocusObject(cell
);
1205 r
.WriteText("This cell spans 2 columns");
1207 cell
= table
->GetCell(1, 3);
1208 cell
->SetRowspan(2);
1209 r
.SetFocusObject(cell
);
1211 r
.WriteText("This cell spans 2 rows");
1213 cell
= table
->GetCell(2, 1);
1214 cell
->SetColspan(2);
1215 cell
->SetRowspan(3);
1216 r
.SetFocusObject(cell
);
1218 r
.WriteText("This cell spans 2 columns and 3 rows");
1220 r
.SetFocusObject(NULL
); // Set the focus back to the main buffer
1221 r
.SetInsertionPointEnd();
1225 r
.Newline(); r
.Newline();
1227 wxRichTextProperties properties
;
1228 r
.WriteText(wxT("This is a rectangle field: "));
1229 r
.WriteField(wxT("rectangle"), properties
);
1230 r
.WriteText(wxT(" and a begin section field: "));
1231 r
.WriteField(wxT("begin-section"), properties
);
1232 r
.WriteText(wxT("This is text between the two tags."));
1233 r
.WriteField(wxT("end-section"), properties
);
1234 r
.WriteText(wxT(" Now a bitmap. "));
1235 r
.WriteField(wxT("bitmap"), properties
);
1236 r
.WriteText(wxT(" Before we go, here's a composite field: ***"));
1237 wxRichTextField
* field
= r
.WriteField(wxT("composite"), properties
);
1238 field
->UpdateField(& r
.GetBuffer()); // Creates the composite value (sort of a text box)
1239 r
.WriteText(wxT("*** End of composite field."));
1242 r
.EndSuppressUndo();
1244 // Add some locked content first - needs Undo to be enabled
1247 r
.WriteText(wxString(wxT("This is a locked object.")));
1250 r
.WriteText(wxString(wxT(" This is unlocked text. ")));
1253 r
.WriteText(wxString(wxT("More locked content.")));
1257 // Flush the Undo buffer
1258 r
.GetCommandProcessor()->ClearCommands();
1266 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
1268 // true is to force the frame to close
1272 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
1275 msg
.Printf( wxT("This is a demo for wxRichTextCtrl, a control for editing styled text.\n(c) Julian Smart, 2005"));
1276 wxMessageBox(msg
, wxT("About wxRichTextCtrl Sample"), wxOK
| wxICON_INFORMATION
, this);
1279 // Forward command events to the current rich text control, if any
1280 bool MyFrame::ProcessEvent(wxEvent
& event
)
1282 if (event
.IsCommandEvent() && !event
.IsKindOf(CLASSINFO(wxChildFocusEvent
)))
1284 // Problem: we can get infinite recursion because the events
1285 // climb back up to this frame, and repeat.
1286 // Assume that command events don't cause another command event
1287 // to be called, so we can rely on inCommand not being overwritten
1289 static int s_eventType
= 0;
1290 static wxWindowID s_id
= 0;
1292 if (s_id
!= event
.GetId() && s_eventType
!= event
.GetEventType())
1294 s_eventType
= event
.GetEventType();
1295 s_id
= event
.GetId();
1297 wxWindow
* focusWin
= wxFindFocusDescendant(this);
1298 if (focusWin
&& focusWin
->GetEventHandler()->ProcessEvent(event
))
1315 return wxFrame::ProcessEvent(event
);
1318 void MyFrame::OnOpen(wxCommandEvent
& WXUNUSED(event
))
1322 wxArrayInt fileTypes
;
1324 wxString filter
= wxRichTextBuffer::GetExtWildcard(false, false, & fileTypes
);
1325 if (!filter
.empty())
1327 filter
+= wxT("All files (*.*)|*.*");
1329 wxFileDialog
dialog(this,
1330 _("Choose a filename"),
1336 if (dialog
.ShowModal() == wxID_OK
)
1338 wxString path
= dialog
.GetPath();
1342 int filterIndex
= dialog
.GetFilterIndex();
1343 int fileType
= (filterIndex
< (int) fileTypes
.GetCount())
1344 ? fileTypes
[filterIndex
]
1345 : wxRICHTEXT_TYPE_TEXT
;
1346 m_richTextCtrl
->LoadFile(path
, fileType
);
1351 void MyFrame::OnSave(wxCommandEvent
& event
)
1353 if (m_richTextCtrl
->GetFilename().empty())
1358 m_richTextCtrl
->SaveFile();
1361 void MyFrame::OnSaveAs(wxCommandEvent
& WXUNUSED(event
))
1363 wxString filter
= wxRichTextBuffer::GetExtWildcard(false, true);
1367 wxFileDialog
dialog(this,
1368 _("Choose a filename"),
1374 if (dialog
.ShowModal() == wxID_OK
)
1376 wxString path
= dialog
.GetPath();
1381 wxStopWatch stopwatch
;
1383 m_richTextCtrl
->SaveFile(path
);
1385 long t
= stopwatch
.Time();
1386 wxLogDebug(wxT("Saving took %ldms"), t
);
1387 wxMessageBox(wxString::Format(wxT("Saving took %ldms"), t
));
1392 void MyFrame::OnBold(wxCommandEvent
& WXUNUSED(event
))
1394 m_richTextCtrl
->ApplyBoldToSelection();
1397 void MyFrame::OnItalic(wxCommandEvent
& WXUNUSED(event
))
1399 m_richTextCtrl
->ApplyItalicToSelection();
1402 void MyFrame::OnUnderline(wxCommandEvent
& WXUNUSED(event
))
1404 m_richTextCtrl
->ApplyUnderlineToSelection();
1407 void MyFrame::OnStrikethrough(wxCommandEvent
& WXUNUSED(event
))
1409 m_richTextCtrl
->ApplyTextEffectToSelection(wxTEXT_ATTR_EFFECT_STRIKETHROUGH
);
1412 void MyFrame::OnSuperscript(wxCommandEvent
& WXUNUSED(event
))
1414 m_richTextCtrl
->ApplyTextEffectToSelection(wxTEXT_ATTR_EFFECT_SUPERSCRIPT
);
1417 void MyFrame::OnSubscript(wxCommandEvent
& WXUNUSED(event
))
1419 m_richTextCtrl
->ApplyTextEffectToSelection(wxTEXT_ATTR_EFFECT_SUBSCRIPT
);
1423 void MyFrame::OnUpdateBold(wxUpdateUIEvent
& event
)
1425 event
.Check(m_richTextCtrl
->IsSelectionBold());
1428 void MyFrame::OnUpdateItalic(wxUpdateUIEvent
& event
)
1430 event
.Check(m_richTextCtrl
->IsSelectionItalics());
1433 void MyFrame::OnUpdateUnderline(wxUpdateUIEvent
& event
)
1435 event
.Check(m_richTextCtrl
->IsSelectionUnderlined());
1438 void MyFrame::OnUpdateStrikethrough(wxUpdateUIEvent
& event
)
1440 event
.Check(m_richTextCtrl
->DoesSelectionHaveTextEffectFlag(wxTEXT_ATTR_EFFECT_STRIKETHROUGH
));
1443 void MyFrame::OnUpdateSuperscript(wxUpdateUIEvent
& event
)
1445 event
.Check(m_richTextCtrl
->DoesSelectionHaveTextEffectFlag(wxTEXT_ATTR_EFFECT_SUPERSCRIPT
));
1448 void MyFrame::OnUpdateSubscript(wxUpdateUIEvent
& event
)
1450 event
.Check(m_richTextCtrl
->DoesSelectionHaveTextEffectFlag(wxTEXT_ATTR_EFFECT_SUBSCRIPT
));
1453 void MyFrame::OnAlignLeft(wxCommandEvent
& WXUNUSED(event
))
1455 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_LEFT
);
1458 void MyFrame::OnAlignCentre(wxCommandEvent
& WXUNUSED(event
))
1460 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_CENTRE
);
1463 void MyFrame::OnAlignRight(wxCommandEvent
& WXUNUSED(event
))
1465 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_RIGHT
);
1468 void MyFrame::OnUpdateAlignLeft(wxUpdateUIEvent
& event
)
1470 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_LEFT
));
1473 void MyFrame::OnUpdateAlignCentre(wxUpdateUIEvent
& event
)
1475 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_CENTRE
));
1478 void MyFrame::OnUpdateAlignRight(wxUpdateUIEvent
& event
)
1480 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_RIGHT
));
1483 void MyFrame::OnFont(wxCommandEvent
& WXUNUSED(event
))
1485 wxRichTextRange range
;
1486 if (m_richTextCtrl
->HasSelection())
1487 range
= m_richTextCtrl
->GetSelectionRange();
1489 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1491 int pages
= wxRICHTEXT_FORMAT_FONT
;
1493 wxRichTextFormattingDialog
formatDlg(pages
, this);
1494 formatDlg
.SetOptions(wxRichTextFormattingDialog::Option_AllowPixelFontSize
);
1495 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1497 if (formatDlg
.ShowModal() == wxID_OK
)
1499 formatDlg
.ApplyStyle(m_richTextCtrl
, range
, wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_OPTIMIZE
|wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY
);
1503 void MyFrame::OnImage(wxCommandEvent
& WXUNUSED(event
))
1505 wxRichTextRange range
;
1506 wxASSERT(m_richTextCtrl
->HasSelection());
1508 range
= m_richTextCtrl
->GetSelectionRange();
1509 wxASSERT(range
.ToInternal().GetLength() == 1);
1511 wxRichTextImage
* image
= wxDynamicCast(m_richTextCtrl
->GetFocusObject()->GetLeafObjectAtPosition(range
.GetStart()), wxRichTextImage
);
1514 wxRichTextObjectPropertiesDialog
imageDlg(image
, this);
1516 if (imageDlg
.ShowModal() == wxID_OK
)
1518 imageDlg
.ApplyStyle(m_richTextCtrl
);
1523 void MyFrame::OnParagraph(wxCommandEvent
& WXUNUSED(event
))
1525 wxRichTextRange range
;
1526 if (m_richTextCtrl
->HasSelection())
1527 range
= m_richTextCtrl
->GetSelectionRange();
1529 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1531 int pages
= wxRICHTEXT_FORMAT_INDENTS_SPACING
|wxRICHTEXT_FORMAT_TABS
|wxRICHTEXT_FORMAT_BULLETS
;
1533 wxRichTextFormattingDialog
formatDlg(pages
, this);
1534 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1536 if (formatDlg
.ShowModal() == wxID_OK
)
1538 formatDlg
.ApplyStyle(m_richTextCtrl
, range
);
1542 void MyFrame::OnFormat(wxCommandEvent
& WXUNUSED(event
))
1544 wxRichTextRange range
;
1545 if (m_richTextCtrl
->HasSelection())
1546 range
= m_richTextCtrl
->GetSelectionRange();
1548 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1550 int pages
= wxRICHTEXT_FORMAT_FONT
|wxRICHTEXT_FORMAT_INDENTS_SPACING
|wxRICHTEXT_FORMAT_TABS
|wxRICHTEXT_FORMAT_BULLETS
;
1552 wxRichTextFormattingDialog
formatDlg(pages
, this);
1553 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1555 if (formatDlg
.ShowModal() == wxID_OK
)
1557 formatDlg
.ApplyStyle(m_richTextCtrl
, range
);
1561 void MyFrame::OnUpdateFormat(wxUpdateUIEvent
& event
)
1563 event
.Enable(m_richTextCtrl
->HasSelection());
1566 void MyFrame::OnUpdateImage(wxUpdateUIEvent
& event
)
1568 wxRichTextRange range
;
1569 wxRichTextObject
*obj
;
1571 range
= m_richTextCtrl
->GetSelectionRange();
1572 if (range
.ToInternal().GetLength() == 1)
1574 obj
= m_richTextCtrl
->GetFocusObject()->GetLeafObjectAtPosition(range
.GetStart());
1575 if (obj
&& obj
->IsKindOf(CLASSINFO(wxRichTextImage
)))
1582 event
.Enable(false);
1585 void MyFrame::OnIndentMore(wxCommandEvent
& WXUNUSED(event
))
1587 wxRichTextAttr attr
;
1588 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1590 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1592 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1593 if (m_richTextCtrl
->HasSelection())
1594 range
= m_richTextCtrl
->GetSelectionRange();
1596 attr
.SetLeftIndent(attr
.GetLeftIndent() + 100);
1598 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1599 m_richTextCtrl
->SetStyle(range
, attr
);
1603 void MyFrame::OnIndentLess(wxCommandEvent
& WXUNUSED(event
))
1605 wxRichTextAttr attr
;
1606 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1608 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1610 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1611 if (m_richTextCtrl
->HasSelection())
1612 range
= m_richTextCtrl
->GetSelectionRange();
1614 if (attr
.GetLeftIndent() > 0)
1616 attr
.SetLeftIndent(wxMax(0, attr
.GetLeftIndent() - 100));
1618 m_richTextCtrl
->SetStyle(range
, attr
);
1623 void MyFrame::OnLineSpacingHalf(wxCommandEvent
& WXUNUSED(event
))
1625 wxRichTextAttr attr
;
1626 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1628 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1630 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1631 if (m_richTextCtrl
->HasSelection())
1632 range
= m_richTextCtrl
->GetSelectionRange();
1634 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1635 attr
.SetLineSpacing(15);
1637 m_richTextCtrl
->SetStyle(range
, attr
);
1641 void MyFrame::OnLineSpacingDouble(wxCommandEvent
& WXUNUSED(event
))
1643 wxRichTextAttr attr
;
1644 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1646 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1648 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1649 if (m_richTextCtrl
->HasSelection())
1650 range
= m_richTextCtrl
->GetSelectionRange();
1652 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1653 attr
.SetLineSpacing(20);
1655 m_richTextCtrl
->SetStyle(range
, attr
);
1659 void MyFrame::OnLineSpacingSingle(wxCommandEvent
& WXUNUSED(event
))
1661 wxRichTextAttr attr
;
1662 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1664 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1666 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1667 if (m_richTextCtrl
->HasSelection())
1668 range
= m_richTextCtrl
->GetSelectionRange();
1670 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1671 attr
.SetLineSpacing(0); // Can also use 10
1673 m_richTextCtrl
->SetStyle(range
, attr
);
1677 void MyFrame::OnParagraphSpacingMore(wxCommandEvent
& WXUNUSED(event
))
1679 wxRichTextAttr attr
;
1680 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1682 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1684 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1685 if (m_richTextCtrl
->HasSelection())
1686 range
= m_richTextCtrl
->GetSelectionRange();
1688 attr
.SetParagraphSpacingAfter(attr
.GetParagraphSpacingAfter() + 20);
1690 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1691 m_richTextCtrl
->SetStyle(range
, attr
);
1695 void MyFrame::OnParagraphSpacingLess(wxCommandEvent
& WXUNUSED(event
))
1697 wxRichTextAttr attr
;
1698 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1700 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1702 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1703 if (m_richTextCtrl
->HasSelection())
1704 range
= m_richTextCtrl
->GetSelectionRange();
1706 if (attr
.GetParagraphSpacingAfter() >= 20)
1708 attr
.SetParagraphSpacingAfter(attr
.GetParagraphSpacingAfter() - 20);
1710 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1711 m_richTextCtrl
->SetStyle(range
, attr
);
1716 void MyFrame::OnReload(wxCommandEvent
& WXUNUSED(event
))
1718 m_richTextCtrl
->Clear();
1722 void MyFrame::OnViewHTML(wxCommandEvent
& WXUNUSED(event
))
1724 wxDialog
dialog(this, wxID_ANY
, _("HTML"), wxDefaultPosition
, wxSize(500, 400), wxDEFAULT_DIALOG_STYLE
);
1726 wxBoxSizer
* boxSizer
= new wxBoxSizer(wxVERTICAL
);
1727 dialog
.SetSizer(boxSizer
);
1729 wxHtmlWindow
* win
= new wxHtmlWindow(& dialog
, wxID_ANY
, wxDefaultPosition
, wxSize(500, 400), wxSUNKEN_BORDER
);
1730 boxSizer
->Add(win
, 1, wxALL
, 5);
1732 wxButton
* cancelButton
= new wxButton(& dialog
, wxID_CANCEL
, wxT("&Close"));
1733 boxSizer
->Add(cancelButton
, 0, wxALL
|wxCENTRE
, 5);
1736 wxStringOutputStream
strStream(& text
);
1738 wxRichTextHTMLHandler htmlHandler
;
1739 htmlHandler
.SetFlags(wxRICHTEXT_HANDLER_SAVE_IMAGES_TO_MEMORY
);
1741 wxArrayInt fontSizeMapping
;
1742 fontSizeMapping
.Add(7);
1743 fontSizeMapping
.Add(9);
1744 fontSizeMapping
.Add(11);
1745 fontSizeMapping
.Add(12);
1746 fontSizeMapping
.Add(14);
1747 fontSizeMapping
.Add(22);
1748 fontSizeMapping
.Add(100);
1750 htmlHandler
.SetFontSizeMapping(fontSizeMapping
);
1752 if (htmlHandler
.SaveFile(& m_richTextCtrl
->GetBuffer(), strStream
))
1757 boxSizer
->Fit(& dialog
);
1761 // Now delete the temporary in-memory images
1762 htmlHandler
.DeleteTemporaryImages();
1765 // Demonstrates how you can change the style sheets and have the changes
1766 // reflected in the control content without wiping out character formatting.
1768 void MyFrame::OnSwitchStyleSheets(wxCommandEvent
& WXUNUSED(event
))
1770 static wxRichTextStyleSheet
* gs_AlternateStyleSheet
= NULL
;
1772 wxRichTextStyleListCtrl
*styleList
= (wxRichTextStyleListCtrl
*) FindWindow(ID_RICHTEXT_STYLE_LIST
);
1773 wxRichTextStyleComboCtrl
* styleCombo
= (wxRichTextStyleComboCtrl
*) FindWindow(ID_RICHTEXT_STYLE_COMBO
);
1775 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1777 // One-time creation of an alternate style sheet
1778 if (!gs_AlternateStyleSheet
)
1780 gs_AlternateStyleSheet
= new wxRichTextStyleSheet(*sheet
);
1782 // Make some modifications
1783 for (int i
= 0; i
< (int) gs_AlternateStyleSheet
->GetParagraphStyleCount(); i
++)
1785 wxRichTextParagraphStyleDefinition
* def
= gs_AlternateStyleSheet
->GetParagraphStyle(i
);
1787 if (def
->GetStyle().HasTextColour())
1788 def
->GetStyle().SetTextColour(*wxBLUE
);
1790 if (def
->GetStyle().HasAlignment())
1792 if (def
->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_CENTRE
)
1793 def
->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_RIGHT
);
1794 else if (def
->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_LEFT
)
1795 def
->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_CENTRE
);
1797 if (def
->GetStyle().HasLeftIndent())
1799 def
->GetStyle().SetLeftIndent(def
->GetStyle().GetLeftIndent() * 2);
1805 wxRichTextStyleSheet
* tmp
= gs_AlternateStyleSheet
;
1806 gs_AlternateStyleSheet
= sheet
;
1809 m_richTextCtrl
->SetStyleSheet(sheet
);
1810 m_richTextCtrl
->ApplyStyleSheet(sheet
); // Makes the control reflect the new style definitions
1812 styleList
->SetStyleSheet(sheet
);
1813 styleList
->UpdateStyles();
1815 styleCombo
->SetStyleSheet(sheet
);
1816 styleCombo
->UpdateStyles();
1819 void MyFrame::OnManageStyles(wxCommandEvent
& WXUNUSED(event
))
1821 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1823 int flags
= wxRICHTEXT_ORGANISER_CREATE_STYLES
|wxRICHTEXT_ORGANISER_EDIT_STYLES
;
1825 wxRichTextStyleOrganiserDialog
dlg(flags
, sheet
, NULL
, this, wxID_ANY
, _("Style Manager"));
1829 void MyFrame::OnInsertSymbol(wxCommandEvent
& WXUNUSED(event
))
1831 wxRichTextAttr attr
;
1832 attr
.SetFlags(wxTEXT_ATTR_FONT
);
1833 m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
);
1835 wxString currentFontName
;
1836 if (attr
.HasFont() && attr
.GetFont().IsOk())
1837 currentFontName
= attr
.GetFont().GetFaceName();
1839 // Don't set the initial font in the dialog (so the user is choosing
1840 // 'normal text', i.e. the current font) but do tell the dialog
1841 // what 'normal text' is.
1843 wxSymbolPickerDialog
dlg(wxT("*"), wxEmptyString
, currentFontName
, this);
1845 if (dlg
.ShowModal() == wxID_OK
)
1847 if (dlg
.HasSelection())
1849 long insertionPoint
= m_richTextCtrl
->GetInsertionPoint();
1851 m_richTextCtrl
->WriteText(dlg
.GetSymbol());
1853 if (!dlg
.UseNormalFont())
1855 wxFont
font(attr
.GetFont());
1856 font
.SetFaceName(dlg
.GetFontName());
1858 m_richTextCtrl
->SetStyle(insertionPoint
, insertionPoint
+1, attr
);
1864 void MyFrame::OnNumberList(wxCommandEvent
& WXUNUSED(event
))
1866 if (m_richTextCtrl
->HasSelection())
1868 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1869 m_richTextCtrl
->SetListStyle(range
, wxT("Numbered List 1"), wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_RENUMBER
);
1873 void MyFrame::OnBulletsAndNumbering(wxCommandEvent
& WXUNUSED(event
))
1875 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1877 int flags
= wxRICHTEXT_ORGANISER_BROWSE_NUMBERING
;
1879 wxRichTextStyleOrganiserDialog
dlg(flags
, sheet
, m_richTextCtrl
, this, wxID_ANY
, _("Bullets and Numbering"));
1880 if (dlg
.ShowModal() == wxID_OK
)
1882 if (dlg
.GetSelectedStyleDefinition())
1887 void MyFrame::OnItemizeList(wxCommandEvent
& WXUNUSED(event
))
1889 if (m_richTextCtrl
->HasSelection())
1891 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1892 m_richTextCtrl
->SetListStyle(range
, wxT("Bullet List 1"));
1896 void MyFrame::OnRenumberList(wxCommandEvent
& WXUNUSED(event
))
1898 if (m_richTextCtrl
->HasSelection())
1900 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1901 m_richTextCtrl
->NumberList(range
, NULL
, wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_RENUMBER
);
1905 void MyFrame::OnPromoteList(wxCommandEvent
& WXUNUSED(event
))
1907 if (m_richTextCtrl
->HasSelection())
1909 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1910 m_richTextCtrl
->PromoteList(1, range
, NULL
);
1914 void MyFrame::OnDemoteList(wxCommandEvent
& WXUNUSED(event
))
1916 if (m_richTextCtrl
->HasSelection())
1918 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1919 m_richTextCtrl
->PromoteList(-1, range
, NULL
);
1923 void MyFrame::OnClearList(wxCommandEvent
& WXUNUSED(event
))
1925 if (m_richTextCtrl
->HasSelection())
1927 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1928 m_richTextCtrl
->ClearListStyle(range
);
1932 void MyFrame::OnInsertURL(wxCommandEvent
& WXUNUSED(event
))
1934 wxString url
= wxGetTextFromUser(_("URL:"), _("Insert URL"));
1937 // Make a style suitable for showing a URL
1938 wxRichTextAttr urlStyle
;
1939 urlStyle
.SetTextColour(*wxBLUE
);
1940 urlStyle
.SetFontUnderlined(true);
1942 m_richTextCtrl
->BeginStyle(urlStyle
);
1943 m_richTextCtrl
->BeginURL(url
);
1944 m_richTextCtrl
->WriteText(url
);
1945 m_richTextCtrl
->EndURL();
1946 m_richTextCtrl
->EndStyle();
1950 void MyFrame::OnInsertImage(wxCommandEvent
& WXUNUSED(event
))
1952 wxFileDialog
dialog(this, _("Choose an image"), "", "", "BMP and GIF files (*.bmp;*.gif)|*.bmp;*.gif|PNG files (*.png)|*.png");
1953 if (dialog
.ShowModal() == wxID_OK
)
1955 wxString path
= dialog
.GetPath();
1956 m_richTextCtrl
->WriteImage(path
, wxBITMAP_TYPE_ANY
);
1960 void MyFrame::OnURL(wxTextUrlEvent
& event
)
1962 wxMessageBox(event
.GetString());
1965 // Veto style sheet replace events when loading from XML, since we want
1966 // to keep the original style sheet.
1967 void MyFrame::OnStyleSheetReplacing(wxRichTextEvent
& event
)
1972 void MyFrame::OnPrint(wxCommandEvent
& WXUNUSED(event
))
1974 wxGetApp().GetPrinting()->PrintBuffer(m_richTextCtrl
->GetBuffer());
1977 void MyFrame::OnPreview(wxCommandEvent
& WXUNUSED(event
))
1979 wxGetApp().GetPrinting()->PreviewBuffer(m_richTextCtrl
->GetBuffer());
1982 void MyFrame::OnPageSetup(wxCommandEvent
& WXUNUSED(event
))
1984 wxDialog
dialog(this, wxID_ANY
, wxT("Testing"), wxPoint(10, 10), wxSize(400, 300), wxDEFAULT_DIALOG_STYLE
);
1986 wxNotebook
* nb
= new wxNotebook(& dialog
, wxID_ANY
, wxPoint(5, 5), wxSize(300, 250));
1987 wxPanel
* panel
= new wxPanel(nb
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
);
1988 wxPanel
* panel2
= new wxPanel(nb
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
);
1990 new wxRichTextCtrl(panel
, wxID_ANY
, wxEmptyString
, wxPoint(5, 5), wxSize(200, 150), wxVSCROLL
|wxTE_READONLY
);
1991 nb
->AddPage(panel
, wxT("Page 1"));
1993 new wxRichTextCtrl(panel2
, wxID_ANY
, wxEmptyString
, wxPoint(5, 5), wxSize(200, 150), wxVSCROLL
|wxTE_READONLY
);
1994 nb
->AddPage(panel2
, wxT("Page 2"));
1996 new wxButton(& dialog
, wxID_OK
, wxT("OK"), wxPoint(5, 180));
2000 // wxGetApp().GetPrinting()->PageSetup();
2003 void MyFrame::OnSetFontScale(wxCommandEvent
& WXUNUSED(event
))
2005 wxString value
= wxString::Format(wxT("%g"), m_richTextCtrl
->GetFontScale());
2006 wxString text
= wxGetTextFromUser(wxT("Enter a text scale factor:"), wxT("Text Scale Factor"), value
, wxGetTopLevelParent(this));
2007 if (!text
.IsEmpty() && value
!= text
)
2010 wxSscanf(text
, wxT("%lf"), & scale
);
2011 m_richTextCtrl
->SetFontScale(scale
, true);
2015 void MyFrame::OnSetDimensionScale(wxCommandEvent
& WXUNUSED(event
))
2017 wxString value
= wxString::Format(wxT("%g"), m_richTextCtrl
->GetDimensionScale());
2018 wxString text
= wxGetTextFromUser(wxT("Enter a dimension scale factor:"), wxT("Dimension Scale Factor"), value
, wxGetTopLevelParent(this));
2019 if (!text
.IsEmpty() && value
!= text
)
2022 wxSscanf(text
, wxT("%lf"), & scale
);
2023 m_richTextCtrl
->SetDimensionScale(scale
, true);
2027 void MyRichTextCtrl::PrepareContent(wxRichTextParagraphLayoutBox
& container
)
2031 // Lock all content that's about to be added to the control
2032 wxRichTextObjectList::compatibility_iterator node
= container
.GetChildren().GetFirst();
2035 wxRichTextParagraph
* para
= wxDynamicCast(node
->GetData(), wxRichTextParagraph
);
2038 wxRichTextObjectList::compatibility_iterator childNode
= para
->GetChildren().GetFirst();
2041 wxRichTextObject
* obj
= childNode
->GetData();
2042 obj
->GetProperties().SetProperty(wxT("Lock"), m_lockId
);
2044 childNode
= childNode
->GetNext();
2047 node
= node
->GetNext();
2052 bool MyRichTextCtrl::CanDeleteRange(wxRichTextParagraphLayoutBox
& container
, const wxRichTextRange
& range
) const
2055 for (i
= range
.GetStart(); i
< range
.GetEnd(); i
++)
2057 wxRichTextObject
* obj
= container
.GetLeafObjectAtPosition(i
);
2058 if (obj
&& obj
->GetProperties().HasProperty(wxT("Lock")))
2066 bool MyRichTextCtrl::CanInsertContent(wxRichTextParagraphLayoutBox
& container
, long pos
) const
2068 wxRichTextObject
* child1
= container
.GetLeafObjectAtPosition(pos
);
2069 wxRichTextObject
* child2
= container
.GetLeafObjectAtPosition(pos
-1);
2071 long lock1
= -1, lock2
= -1;
2073 if (child1
&& child1
->GetProperties().HasProperty(wxT("Lock")))
2074 lock1
= child1
->GetProperties().GetPropertyLong(wxT("Lock"));
2075 if (child2
&& child2
->GetProperties().HasProperty(wxT("Lock")))
2076 lock2
= child2
->GetProperties().GetPropertyLong(wxT("Lock"));
2078 if (lock1
!= -1 && lock1
== lock2
)
2081 // Don't allow insertion before a locked object if it's at the beginning of the buffer.
2082 if (pos
== 0 && lock1
!= -1)
2089 class wxRichTextEnhancedDrawingHandler
: public wxRichTextDrawingHandler
2092 wxRichTextEnhancedDrawingHandler()
2094 SetName(wxT("enhanceddrawing"));
2095 m_lockBackgroundColour
= wxColour(220, 220, 220);
2099 Returns @true if this object has virtual attributes that we can provide.
2101 virtual bool HasVirtualAttributes(wxRichTextObject
* obj
) const;
2104 Provides virtual attributes that we can provide.
2106 virtual bool GetVirtualAttributes(wxRichTextAttr
& attr
, wxRichTextObject
* obj
) const;
2109 Gets the count for mixed virtual attributes for individual positions within the object.
2110 For example, individual characters within a text object may require special highlighting.
2112 virtual int GetVirtualSubobjectAttributesCount(wxRichTextObject
* WXUNUSED(obj
)) const { return 0; }
2115 Gets the mixed virtual attributes for individual positions within the object.
2116 For example, individual characters within a text object may require special highlighting.
2117 Returns the number of virtual attributes found.
2119 virtual int GetVirtualSubobjectAttributes(wxRichTextObject
* WXUNUSED(obj
), wxArrayInt
& WXUNUSED(positions
), wxRichTextAttrArray
& WXUNUSED(attributes
)) const { return 0; }
2122 Do we have virtual text for this object? Virtual text allows an application
2123 to replace characters in an object for editing and display purposes, for example
2124 for highlighting special characters.
2126 virtual bool HasVirtualText(const wxRichTextPlainText
* WXUNUSED(obj
)) const { return false; }
2129 Gets the virtual text for this object.
2131 virtual bool GetVirtualText(const wxRichTextPlainText
* WXUNUSED(obj
), wxString
& WXUNUSED(text
)) const { return false; }
2133 wxColour m_lockBackgroundColour
;
2136 bool wxRichTextEnhancedDrawingHandler::HasVirtualAttributes(wxRichTextObject
* obj
) const
2138 return obj
->GetProperties().HasProperty(wxT("Lock"));
2141 bool wxRichTextEnhancedDrawingHandler::GetVirtualAttributes(wxRichTextAttr
& attr
, wxRichTextObject
* obj
) const
2143 if (obj
->GetProperties().HasProperty(wxT("Lock")))
2145 attr
.SetBackgroundColour(m_lockBackgroundColour
);
2151 void MyRichTextCtrl::SetEnhancedDrawingHandler()
2153 wxRichTextBuffer::AddDrawingHandler(new wxRichTextEnhancedDrawingHandler
);