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 // A custom field type
86 class wxRichTextFieldTypePropertiesTest
: public wxRichTextFieldTypeStandard
89 wxRichTextFieldTypePropertiesTest(const wxString
& name
, const wxString
& label
, int displayStyle
= wxRICHTEXT_FIELD_STYLE_RECTANGLE
):
90 wxRichTextFieldTypeStandard(name
, label
, displayStyle
)
93 wxRichTextFieldTypePropertiesTest(const wxString
& name
, const wxBitmap
& bitmap
, int displayStyle
= wxRICHTEXT_FIELD_STYLE_RECTANGLE
):
94 wxRichTextFieldTypeStandard(name
, bitmap
, displayStyle
)
98 virtual bool CanEditProperties(wxRichTextField
* WXUNUSED(obj
)) const { return true; }
99 virtual bool EditProperties(wxRichTextField
* WXUNUSED(obj
), wxWindow
* WXUNUSED(parent
), wxRichTextBuffer
* WXUNUSED(buffer
))
101 wxString label
= GetLabel();
102 wxMessageBox(wxString::Format(wxT("Editing %s"), label
.c_str()));
106 virtual wxString
GetPropertiesMenuLabel(wxRichTextField
* WXUNUSED(obj
)) const
112 // A custom composite field type
113 class wxRichTextFieldTypeCompositeTest
: public wxRichTextFieldTypePropertiesTest
116 wxRichTextFieldTypeCompositeTest(const wxString
& name
, const wxString
& label
):
117 wxRichTextFieldTypePropertiesTest(name
, label
, wxRICHTEXT_FIELD_STYLE_COMPOSITE
)
121 virtual bool UpdateField(wxRichTextBuffer
* buffer
, wxRichTextField
* obj
)
125 wxRichTextAttr
attr(buffer
->GetAttributes());
126 attr
.GetTextBoxAttr().Reset();
127 attr
.SetParagraphSpacingAfter(0);
128 attr
.SetLineSpacing(10);
129 obj
->SetAttributes(attr
);
131 obj
->GetChildren().Clear();
132 wxRichTextParagraph
* para
= new wxRichTextParagraph
;
133 wxRichTextPlainText
* text
= new wxRichTextPlainText(GetLabel());
134 para
->AppendChild(text
);
135 obj
->AppendChild(para
);
140 // ----------------------------------------------------------------------------
142 // ----------------------------------------------------------------------------
144 // ----------------------------------------------------------------------------
146 // ----------------------------------------------------------------------------
148 // Define a new application type, each program should derive a class from wxApp
149 class MyRichTextCtrl
: public wxRichTextCtrl
152 MyRichTextCtrl( wxWindow
* parent
, wxWindowID id
= -1, const wxString
& value
= wxEmptyString
, const wxPoint
& pos
= wxDefaultPosition
, const wxSize
& size
= wxDefaultSize
,
153 long style
= wxRE_MULTILINE
, const wxValidator
& validator
= wxDefaultValidator
, const wxString
& name
= wxTextCtrlNameStr
):
154 wxRichTextCtrl(parent
, id
, value
, pos
, size
, style
, validator
, name
)
160 void SetLockId(long id
) { m_lockId
= id
; }
161 long GetLockId() const { return m_lockId
; }
163 void BeginLock() { m_lockId
++; m_locked
= true; }
164 void EndLock() { m_locked
= false; }
165 bool IsLocked() const { return m_locked
; }
167 static void SetEnhancedDrawingHandler();
170 Prepares the content just before insertion (or after buffer reset). Called by the same function in wxRichTextBuffer.
171 Currently is only called if undo mode is on.
173 virtual void PrepareContent(wxRichTextParagraphLayoutBox
& container
);
176 Can we delete this range?
177 Sends an event to the control.
179 virtual bool CanDeleteRange(wxRichTextParagraphLayoutBox
& container
, const wxRichTextRange
& range
) const;
182 Can we insert content at this position?
183 Sends an event to the control.
185 virtual bool CanInsertContent(wxRichTextParagraphLayoutBox
& container
, long pos
) const;
191 // Define a new application type, each program should derive a class from wxApp
192 class MyApp
: public wxApp
195 // override base class virtuals
196 // ----------------------------
198 // this one is called on application startup and is a good place for the app
199 // initialization (doing it here and not in the ctor allows to have an error
200 // return: if OnInit() returns false, the application terminates)
201 virtual bool OnInit();
202 virtual int OnExit();
206 wxRichTextStyleSheet
* GetStyleSheet() const { return m_styleSheet
; }
207 wxRichTextPrinting
* GetPrinting() const { return m_printing
; }
209 wxRichTextStyleSheet
* m_styleSheet
;
210 wxRichTextPrinting
* m_printing
;
213 // Define a new frame type: this is going to be our main frame
214 class MyFrame
: public wxFrame
218 MyFrame(const wxString
& title
, wxWindowID id
, const wxPoint
& pos
= wxDefaultPosition
,
219 const wxSize
& size
= wxDefaultSize
, long style
= wxDEFAULT_FRAME_STYLE
);
221 // event handlers (these functions should _not_ be virtual)
222 void OnQuit(wxCommandEvent
& event
);
223 void OnAbout(wxCommandEvent
& event
);
225 void OnOpen(wxCommandEvent
& event
);
226 void OnSave(wxCommandEvent
& event
);
227 void OnSaveAs(wxCommandEvent
& event
);
229 void OnBold(wxCommandEvent
& event
);
230 void OnItalic(wxCommandEvent
& event
);
231 void OnUnderline(wxCommandEvent
& event
);
233 void OnStrikethrough(wxCommandEvent
& event
);
234 void OnSuperscript(wxCommandEvent
& event
);
235 void OnSubscript(wxCommandEvent
& event
);
237 void OnUpdateBold(wxUpdateUIEvent
& event
);
238 void OnUpdateItalic(wxUpdateUIEvent
& event
);
239 void OnUpdateUnderline(wxUpdateUIEvent
& event
);
240 void OnUpdateStrikethrough(wxUpdateUIEvent
& event
);
241 void OnUpdateSuperscript(wxUpdateUIEvent
& event
);
242 void OnUpdateSubscript(wxUpdateUIEvent
& event
);
244 void OnAlignLeft(wxCommandEvent
& event
);
245 void OnAlignCentre(wxCommandEvent
& event
);
246 void OnAlignRight(wxCommandEvent
& event
);
248 void OnUpdateAlignLeft(wxUpdateUIEvent
& event
);
249 void OnUpdateAlignCentre(wxUpdateUIEvent
& event
);
250 void OnUpdateAlignRight(wxUpdateUIEvent
& event
);
252 void OnIndentMore(wxCommandEvent
& event
);
253 void OnIndentLess(wxCommandEvent
& event
);
255 void OnFont(wxCommandEvent
& event
);
256 void OnImage(wxCommandEvent
& event
);
257 void OnUpdateImage(wxUpdateUIEvent
& event
);
258 void OnParagraph(wxCommandEvent
& event
);
259 void OnFormat(wxCommandEvent
& event
);
260 void OnUpdateFormat(wxUpdateUIEvent
& event
);
262 void OnInsertSymbol(wxCommandEvent
& event
);
264 void OnLineSpacingHalf(wxCommandEvent
& event
);
265 void OnLineSpacingDouble(wxCommandEvent
& event
);
266 void OnLineSpacingSingle(wxCommandEvent
& event
);
268 void OnParagraphSpacingMore(wxCommandEvent
& event
);
269 void OnParagraphSpacingLess(wxCommandEvent
& event
);
271 void OnNumberList(wxCommandEvent
& event
);
272 void OnBulletsAndNumbering(wxCommandEvent
& event
);
273 void OnItemizeList(wxCommandEvent
& event
);
274 void OnRenumberList(wxCommandEvent
& event
);
275 void OnPromoteList(wxCommandEvent
& event
);
276 void OnDemoteList(wxCommandEvent
& event
);
277 void OnClearList(wxCommandEvent
& event
);
279 void OnReload(wxCommandEvent
& event
);
281 void OnViewHTML(wxCommandEvent
& event
);
283 void OnSwitchStyleSheets(wxCommandEvent
& event
);
284 void OnManageStyles(wxCommandEvent
& event
);
286 void OnInsertURL(wxCommandEvent
& event
);
287 void OnURL(wxTextUrlEvent
& event
);
288 void OnStyleSheetReplacing(wxRichTextEvent
& event
);
290 void OnPrint(wxCommandEvent
& event
);
291 void OnPreview(wxCommandEvent
& event
);
292 void OnPageSetup(wxCommandEvent
& event
);
294 void OnInsertImage(wxCommandEvent
& event
);
296 void OnSetFontScale(wxCommandEvent
& event
);
297 void OnSetDimensionScale(wxCommandEvent
& event
);
300 // Forward command events to the current rich text control, if any
301 bool ProcessEvent(wxEvent
& event
);
304 void WriteInitialText();
307 // any class wishing to process wxWidgets events must use this macro
308 DECLARE_EVENT_TABLE()
310 MyRichTextCtrl
* m_richTextCtrl
;
313 // ----------------------------------------------------------------------------
315 // ----------------------------------------------------------------------------
317 // IDs for the controls and the menu commands
322 ID_About
= wxID_ABOUT
,
324 ID_FORMAT_BOLD
= 100,
327 ID_FORMAT_STRIKETHROUGH
,
328 ID_FORMAT_SUPERSCRIPT
,
341 ID_FORMAT_ALIGN_LEFT
,
342 ID_FORMAT_ALIGN_CENTRE
,
343 ID_FORMAT_ALIGN_RIGHT
,
345 ID_FORMAT_INDENT_MORE
,
346 ID_FORMAT_INDENT_LESS
,
348 ID_FORMAT_PARAGRAPH_SPACING_MORE
,
349 ID_FORMAT_PARAGRAPH_SPACING_LESS
,
351 ID_FORMAT_LINE_SPACING_HALF
,
352 ID_FORMAT_LINE_SPACING_DOUBLE
,
353 ID_FORMAT_LINE_SPACING_SINGLE
,
355 ID_FORMAT_NUMBER_LIST
,
356 ID_FORMAT_BULLETS_AND_NUMBERING
,
357 ID_FORMAT_ITEMIZE_LIST
,
358 ID_FORMAT_RENUMBER_LIST
,
359 ID_FORMAT_PROMOTE_LIST
,
360 ID_FORMAT_DEMOTE_LIST
,
361 ID_FORMAT_CLEAR_LIST
,
364 ID_SET_DIMENSION_SCALE
,
367 ID_SWITCH_STYLE_SHEETS
,
375 ID_RICHTEXT_STYLE_LIST
,
376 ID_RICHTEXT_STYLE_COMBO
379 // ----------------------------------------------------------------------------
380 // event tables and other macros for wxWidgets
381 // ----------------------------------------------------------------------------
383 // the event tables connect the wxWidgets events with the functions (event
384 // handlers) which process them. It can be also done at run-time, but for the
385 // simple menu events like this the static method is much simpler.
386 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
387 EVT_MENU(ID_Quit
, MyFrame::OnQuit
)
388 EVT_MENU(ID_About
, MyFrame::OnAbout
)
390 EVT_MENU(wxID_OPEN
, MyFrame::OnOpen
)
391 EVT_MENU(wxID_SAVE
, MyFrame::OnSave
)
392 EVT_MENU(wxID_SAVEAS
, MyFrame::OnSaveAs
)
394 EVT_MENU(ID_FORMAT_BOLD
, MyFrame::OnBold
)
395 EVT_MENU(ID_FORMAT_ITALIC
, MyFrame::OnItalic
)
396 EVT_MENU(ID_FORMAT_UNDERLINE
, MyFrame::OnUnderline
)
398 EVT_MENU(ID_FORMAT_STRIKETHROUGH
, MyFrame::OnStrikethrough
)
399 EVT_MENU(ID_FORMAT_SUPERSCRIPT
, MyFrame::OnSuperscript
)
400 EVT_MENU(ID_FORMAT_SUBSCRIPT
, MyFrame::OnSubscript
)
402 EVT_UPDATE_UI(ID_FORMAT_BOLD
, MyFrame::OnUpdateBold
)
403 EVT_UPDATE_UI(ID_FORMAT_ITALIC
, MyFrame::OnUpdateItalic
)
404 EVT_UPDATE_UI(ID_FORMAT_UNDERLINE
, MyFrame::OnUpdateUnderline
)
406 EVT_UPDATE_UI(ID_FORMAT_STRIKETHROUGH
, MyFrame::OnUpdateStrikethrough
)
407 EVT_UPDATE_UI(ID_FORMAT_SUPERSCRIPT
, MyFrame::OnUpdateSuperscript
)
408 EVT_UPDATE_UI(ID_FORMAT_SUBSCRIPT
, MyFrame::OnUpdateSubscript
)
410 EVT_MENU(ID_FORMAT_ALIGN_LEFT
, MyFrame::OnAlignLeft
)
411 EVT_MENU(ID_FORMAT_ALIGN_CENTRE
, MyFrame::OnAlignCentre
)
412 EVT_MENU(ID_FORMAT_ALIGN_RIGHT
, MyFrame::OnAlignRight
)
414 EVT_UPDATE_UI(ID_FORMAT_ALIGN_LEFT
, MyFrame::OnUpdateAlignLeft
)
415 EVT_UPDATE_UI(ID_FORMAT_ALIGN_CENTRE
, MyFrame::OnUpdateAlignCentre
)
416 EVT_UPDATE_UI(ID_FORMAT_ALIGN_RIGHT
, MyFrame::OnUpdateAlignRight
)
418 EVT_MENU(ID_FORMAT_FONT
, MyFrame::OnFont
)
419 EVT_MENU(ID_FORMAT_IMAGE
, MyFrame::OnImage
)
420 EVT_MENU(ID_FORMAT_PARAGRAPH
, MyFrame::OnParagraph
)
421 EVT_MENU(ID_FORMAT_CONTENT
, MyFrame::OnFormat
)
422 EVT_UPDATE_UI(ID_FORMAT_CONTENT
, MyFrame::OnUpdateFormat
)
423 EVT_UPDATE_UI(ID_FORMAT_FONT
, MyFrame::OnUpdateFormat
)
424 EVT_UPDATE_UI(ID_FORMAT_IMAGE
, MyFrame::OnUpdateImage
)
425 EVT_UPDATE_UI(ID_FORMAT_PARAGRAPH
, MyFrame::OnUpdateFormat
)
426 EVT_MENU(ID_FORMAT_INDENT_MORE
, MyFrame::OnIndentMore
)
427 EVT_MENU(ID_FORMAT_INDENT_LESS
, MyFrame::OnIndentLess
)
429 EVT_MENU(ID_FORMAT_LINE_SPACING_HALF
, MyFrame::OnLineSpacingHalf
)
430 EVT_MENU(ID_FORMAT_LINE_SPACING_SINGLE
, MyFrame::OnLineSpacingSingle
)
431 EVT_MENU(ID_FORMAT_LINE_SPACING_DOUBLE
, MyFrame::OnLineSpacingDouble
)
433 EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_MORE
, MyFrame::OnParagraphSpacingMore
)
434 EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_LESS
, MyFrame::OnParagraphSpacingLess
)
436 EVT_MENU(ID_RELOAD
, MyFrame::OnReload
)
438 EVT_MENU(ID_INSERT_SYMBOL
, MyFrame::OnInsertSymbol
)
439 EVT_MENU(ID_INSERT_URL
, MyFrame::OnInsertURL
)
440 EVT_MENU(ID_INSERT_IMAGE
, MyFrame::OnInsertImage
)
442 EVT_MENU(ID_FORMAT_NUMBER_LIST
, MyFrame::OnNumberList
)
443 EVT_MENU(ID_FORMAT_BULLETS_AND_NUMBERING
, MyFrame::OnBulletsAndNumbering
)
444 EVT_MENU(ID_FORMAT_ITEMIZE_LIST
, MyFrame::OnItemizeList
)
445 EVT_MENU(ID_FORMAT_RENUMBER_LIST
, MyFrame::OnRenumberList
)
446 EVT_MENU(ID_FORMAT_PROMOTE_LIST
, MyFrame::OnPromoteList
)
447 EVT_MENU(ID_FORMAT_DEMOTE_LIST
, MyFrame::OnDemoteList
)
448 EVT_MENU(ID_FORMAT_CLEAR_LIST
, MyFrame::OnClearList
)
450 EVT_MENU(ID_VIEW_HTML
, MyFrame::OnViewHTML
)
451 EVT_MENU(ID_SWITCH_STYLE_SHEETS
, MyFrame::OnSwitchStyleSheets
)
452 EVT_MENU(ID_MANAGE_STYLES
, MyFrame::OnManageStyles
)
454 EVT_MENU(ID_PRINT
, MyFrame::OnPrint
)
455 EVT_MENU(ID_PREVIEW
, MyFrame::OnPreview
)
456 EVT_MENU(ID_PAGE_SETUP
, MyFrame::OnPageSetup
)
458 EVT_TEXT_URL(wxID_ANY
, MyFrame::OnURL
)
459 EVT_RICHTEXT_STYLESHEET_REPLACING(wxID_ANY
, MyFrame::OnStyleSheetReplacing
)
461 EVT_MENU(ID_SET_FONT_SCALE
, MyFrame::OnSetFontScale
)
462 EVT_MENU(ID_SET_DIMENSION_SCALE
, MyFrame::OnSetDimensionScale
)
465 // Create a new application object: this macro will allow wxWidgets to create
466 // the application object during program execution (it's better than using a
467 // static object for many reasons) and also implements the accessor function
468 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
472 // ============================================================================
474 // ============================================================================
476 // ----------------------------------------------------------------------------
477 // the application class
478 // ----------------------------------------------------------------------------
480 // 'Main program' equivalent: the program execution "starts" here
483 if ( !wxApp::OnInit() )
487 wxHelpProvider::Set(new wxSimpleHelpProvider
);
490 m_styleSheet
= new wxRichTextStyleSheet
;
491 m_printing
= new wxRichTextPrinting(wxT("Test Document"));
493 m_printing
->SetFooterText(wxT("@TITLE@"), wxRICHTEXT_PAGE_ALL
, wxRICHTEXT_PAGE_CENTRE
);
494 m_printing
->SetFooterText(wxT("Page @PAGENUM@"), wxRICHTEXT_PAGE_ALL
, wxRICHTEXT_PAGE_RIGHT
);
498 MyRichTextCtrl::SetEnhancedDrawingHandler();
500 // Add extra handlers (plain text is automatically added)
501 wxRichTextBuffer::AddHandler(new wxRichTextXMLHandler
);
502 wxRichTextBuffer::AddHandler(new wxRichTextHTMLHandler
);
506 wxRichTextBuffer::AddFieldType(new wxRichTextFieldTypePropertiesTest(wxT("rectangle"), wxT("RECTANGLE"), wxRichTextFieldTypeStandard::wxRICHTEXT_FIELD_STYLE_RECTANGLE
));
508 wxRichTextFieldTypeStandard
* s1
= new wxRichTextFieldTypeStandard(wxT("begin-section"), wxT("SECTION"), wxRichTextFieldTypeStandard::wxRICHTEXT_FIELD_STYLE_START_TAG
);
509 s1
->SetBackgroundColour(*wxBLUE
);
511 wxRichTextFieldTypeStandard
* s2
= new wxRichTextFieldTypeStandard(wxT("end-section"), wxT("SECTION"), wxRichTextFieldTypeStandard::wxRICHTEXT_FIELD_STYLE_END_TAG
);
512 s2
->SetBackgroundColour(*wxBLUE
);
514 wxRichTextFieldTypeStandard
* s3
= new wxRichTextFieldTypeStandard(wxT("bitmap"), wxBitmap(paste_xpm
), wxRichTextFieldTypeStandard::wxRICHTEXT_FIELD_STYLE_NO_BORDER
);
516 wxRichTextBuffer::AddFieldType(s1
);
517 wxRichTextBuffer::AddFieldType(s2
);
518 wxRichTextBuffer::AddFieldType(s3
);
520 wxRichTextFieldTypeCompositeTest
* s4
= new wxRichTextFieldTypeCompositeTest(wxT("composite"), wxT("This is a field value"));
521 wxRichTextBuffer::AddFieldType(s4
);
523 // Add image handlers
525 wxImage::AddHandler( new wxPNGHandler
);
529 wxImage::AddHandler( new wxJPEGHandler
);
533 wxImage::AddHandler( new wxGIFHandler
);
537 wxFileSystem::AddHandler( new wxMemoryFSHandler
);
540 // create the main application window
541 wxSize size
= wxGetDisplaySize();
542 size
.Scale(0.75, 0.75);
543 MyFrame
*frame
= new MyFrame(wxT("wxRichTextCtrl Sample"), wxID_ANY
, wxDefaultPosition
, size
);
545 m_printing
->SetParentWindow(frame
);
547 // and show it (the frames, unlike simple controls, are not shown when
548 // created initially)
551 // success: wxApp::OnRun() will be called which will enter the main message
552 // loop and the application will run. If we returned false here, the
553 // application would exit immediately.
565 void MyApp::CreateStyles()
569 wxFont
romanFont(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
570 wxFont
swissFont(12, wxSWISS
, wxNORMAL
, wxNORMAL
);
572 wxRichTextParagraphStyleDefinition
* normalPara
= new wxRichTextParagraphStyleDefinition(wxT("Normal"));
573 wxRichTextAttr normalAttr
;
574 normalAttr
.SetFontFaceName(romanFont
.GetFaceName());
575 normalAttr
.SetFontSize(12);
576 // Let's set all attributes for this style
577 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
|
578 wxTEXT_ATTR_PARA_SPACING_BEFORE
|wxTEXT_ATTR_PARA_SPACING_AFTER
|wxTEXT_ATTR_LINE_SPACING
|
579 wxTEXT_ATTR_BULLET_STYLE
|wxTEXT_ATTR_BULLET_NUMBER
);
580 normalPara
->SetStyle(normalAttr
);
582 m_styleSheet
->AddParagraphStyle(normalPara
);
584 wxRichTextParagraphStyleDefinition
* indentedPara
= new wxRichTextParagraphStyleDefinition(wxT("Indented"));
585 wxRichTextAttr indentedAttr
;
586 indentedAttr
.SetFontFaceName(romanFont
.GetFaceName());
587 indentedAttr
.SetFontSize(12);
588 indentedAttr
.SetLeftIndent(100, 0);
589 // We only want to affect indentation
590 indentedAttr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
);
591 indentedPara
->SetStyle(indentedAttr
);
593 m_styleSheet
->AddParagraphStyle(indentedPara
);
595 wxRichTextParagraphStyleDefinition
* indentedPara2
= new wxRichTextParagraphStyleDefinition(wxT("Red Bold Indented"));
596 wxRichTextAttr indentedAttr2
;
597 indentedAttr2
.SetFontFaceName(romanFont
.GetFaceName());
598 indentedAttr2
.SetFontSize(12);
599 indentedAttr2
.SetFontWeight(wxFONTWEIGHT_BOLD
);
600 indentedAttr2
.SetTextColour(*wxRED
);
601 indentedAttr2
.SetFontSize(12);
602 indentedAttr2
.SetLeftIndent(100, 0);
603 // We want to affect indentation, font and text colour
604 indentedAttr2
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
|wxTEXT_ATTR_FONT
|wxTEXT_ATTR_TEXT_COLOUR
);
605 indentedPara2
->SetStyle(indentedAttr2
);
607 m_styleSheet
->AddParagraphStyle(indentedPara2
);
609 wxRichTextParagraphStyleDefinition
* flIndentedPara
= new wxRichTextParagraphStyleDefinition(wxT("First Line Indented"));
610 wxRichTextAttr flIndentedAttr
;
611 flIndentedAttr
.SetFontFaceName(swissFont
.GetFaceName());
612 flIndentedAttr
.SetFontSize(12);
613 flIndentedAttr
.SetLeftIndent(100, -100);
614 // We only want to affect indentation
615 flIndentedAttr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
);
616 flIndentedPara
->SetStyle(flIndentedAttr
);
618 m_styleSheet
->AddParagraphStyle(flIndentedPara
);
622 wxRichTextCharacterStyleDefinition
* boldDef
= new wxRichTextCharacterStyleDefinition(wxT("Bold"));
623 wxRichTextAttr boldAttr
;
624 boldAttr
.SetFontFaceName(romanFont
.GetFaceName());
625 boldAttr
.SetFontSize(12);
626 boldAttr
.SetFontWeight(wxFONTWEIGHT_BOLD
);
627 // We only want to affect boldness
628 boldAttr
.SetFlags(wxTEXT_ATTR_FONT_WEIGHT
);
629 boldDef
->SetStyle(boldAttr
);
631 m_styleSheet
->AddCharacterStyle(boldDef
);
633 wxRichTextCharacterStyleDefinition
* italicDef
= new wxRichTextCharacterStyleDefinition(wxT("Italic"));
634 wxRichTextAttr italicAttr
;
635 italicAttr
.SetFontFaceName(romanFont
.GetFaceName());
636 italicAttr
.SetFontSize(12);
637 italicAttr
.SetFontStyle(wxFONTSTYLE_ITALIC
);
638 // We only want to affect italics
639 italicAttr
.SetFlags(wxTEXT_ATTR_FONT_ITALIC
);
640 italicDef
->SetStyle(italicAttr
);
642 m_styleSheet
->AddCharacterStyle(italicDef
);
644 wxRichTextCharacterStyleDefinition
* redDef
= new wxRichTextCharacterStyleDefinition(wxT("Red Bold"));
645 wxRichTextAttr redAttr
;
646 redAttr
.SetFontFaceName(romanFont
.GetFaceName());
647 redAttr
.SetFontSize(12);
648 redAttr
.SetFontWeight(wxFONTWEIGHT_BOLD
);
649 redAttr
.SetTextColour(*wxRED
);
650 // We only want to affect colour, weight and face
651 redAttr
.SetFlags(wxTEXT_ATTR_FONT_FACE
|wxTEXT_ATTR_FONT_WEIGHT
|wxTEXT_ATTR_TEXT_COLOUR
);
652 redDef
->SetStyle(redAttr
);
654 m_styleSheet
->AddCharacterStyle(redDef
);
656 wxRichTextListStyleDefinition
* bulletList
= new wxRichTextListStyleDefinition(wxT("Bullet List 1"));
658 for (i
= 0; i
< 10; i
++)
662 bulletText
= wxT("standard/circle");
664 bulletText
= wxT("standard/square");
666 bulletText
= wxT("standard/circle");
668 bulletText
= wxT("standard/square");
670 bulletText
= wxT("standard/circle");
672 bulletList
->SetAttributes(i
, (i
+1)*60, 60, wxTEXT_ATTR_BULLET_STYLE_STANDARD
, bulletText
);
675 m_styleSheet
->AddListStyle(bulletList
);
677 wxRichTextListStyleDefinition
* numberedList
= new wxRichTextListStyleDefinition(wxT("Numbered List 1"));
678 for (i
= 0; i
< 10; i
++)
682 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
684 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_LETTERS_LOWER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
686 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ROMAN_LOWER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
688 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ROMAN_UPPER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
690 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
692 numberStyle
|= wxTEXT_ATTR_BULLET_STYLE_ALIGN_RIGHT
;
694 numberedList
->SetAttributes(i
, (i
+1)*60, 60, numberStyle
);
697 m_styleSheet
->AddListStyle(numberedList
);
699 wxRichTextListStyleDefinition
* outlineList
= new wxRichTextListStyleDefinition(wxT("Outline List 1"));
700 for (i
= 0; i
< 10; i
++)
704 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_OUTLINE
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
706 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
708 outlineList
->SetAttributes(i
, (i
+1)*120, 120, numberStyle
);
711 m_styleSheet
->AddListStyle(outlineList
);
714 // ----------------------------------------------------------------------------
716 // ----------------------------------------------------------------------------
719 MyFrame::MyFrame(const wxString
& title
, wxWindowID id
, const wxPoint
& pos
,
720 const wxSize
& size
, long style
)
721 : wxFrame(NULL
, id
, title
, pos
, size
, style
)
724 SetWindowVariant(wxWINDOW_VARIANT_SMALL
);
727 // set the frame icon
728 SetIcon(wxICON(sample
));
731 wxMenu
*fileMenu
= new wxMenu
;
733 // the "About" item should be in the help menu
734 wxMenu
*helpMenu
= new wxMenu
;
735 helpMenu
->Append(ID_About
, wxT("&About\tF1"), wxT("Show about dialog"));
737 fileMenu
->Append(wxID_OPEN
, wxT("&Open\tCtrl+O"), wxT("Open a file"));
738 fileMenu
->Append(wxID_SAVE
, wxT("&Save\tCtrl+S"), wxT("Save a file"));
739 fileMenu
->Append(wxID_SAVEAS
, wxT("&Save As...\tF12"), wxT("Save to a new file"));
740 fileMenu
->AppendSeparator();
741 fileMenu
->Append(ID_RELOAD
, wxT("&Reload Text\tF2"), wxT("Reload the initial text"));
742 fileMenu
->AppendSeparator();
743 fileMenu
->Append(ID_PAGE_SETUP
, wxT("Page Set&up..."), wxT("Page setup"));
744 fileMenu
->Append(ID_PRINT
, wxT("&Print...\tCtrl+P"), wxT("Print"));
745 fileMenu
->Append(ID_PREVIEW
, wxT("Print Pre&view"), wxT("Print preview"));
746 fileMenu
->AppendSeparator();
747 fileMenu
->Append(ID_VIEW_HTML
, wxT("&View as HTML"), wxT("View HTML"));
748 fileMenu
->AppendSeparator();
749 fileMenu
->Append(ID_Quit
, wxT("E&xit\tAlt+X"), wxT("Quit this program"));
751 wxMenu
* editMenu
= new wxMenu
;
752 editMenu
->Append(wxID_UNDO
, _("&Undo\tCtrl+Z"));
753 editMenu
->Append(wxID_REDO
, _("&Redo\tCtrl+Y"));
754 editMenu
->AppendSeparator();
755 editMenu
->Append(wxID_CUT
, _("Cu&t\tCtrl+X"));
756 editMenu
->Append(wxID_COPY
, _("&Copy\tCtrl+C"));
757 editMenu
->Append(wxID_PASTE
, _("&Paste\tCtrl+V"));
759 editMenu
->AppendSeparator();
760 editMenu
->Append(wxID_SELECTALL
, _("Select A&ll\tCtrl+A"));
761 editMenu
->AppendSeparator();
762 editMenu
->Append(ID_SET_FONT_SCALE
, _("Set &Text Scale..."));
763 editMenu
->Append(ID_SET_DIMENSION_SCALE
, _("Set &Dimension Scale..."));
765 wxMenu
* formatMenu
= new wxMenu
;
766 formatMenu
->AppendCheckItem(ID_FORMAT_BOLD
, _("&Bold\tCtrl+B"));
767 formatMenu
->AppendCheckItem(ID_FORMAT_ITALIC
, _("&Italic\tCtrl+I"));
768 formatMenu
->AppendCheckItem(ID_FORMAT_UNDERLINE
, _("&Underline\tCtrl+U"));
769 formatMenu
->AppendSeparator();
770 formatMenu
->AppendCheckItem(ID_FORMAT_STRIKETHROUGH
, _("Stri&kethrough"));
771 formatMenu
->AppendCheckItem(ID_FORMAT_SUPERSCRIPT
, _("Superscrip&t"));
772 formatMenu
->AppendCheckItem(ID_FORMAT_SUBSCRIPT
, _("Subscrip&t"));
773 formatMenu
->AppendSeparator();
774 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_LEFT
, _("L&eft Align"));
775 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_RIGHT
, _("&Right Align"));
776 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_CENTRE
, _("&Centre"));
777 formatMenu
->AppendSeparator();
778 formatMenu
->Append(ID_FORMAT_INDENT_MORE
, _("Indent &More"));
779 formatMenu
->Append(ID_FORMAT_INDENT_LESS
, _("Indent &Less"));
780 formatMenu
->AppendSeparator();
781 formatMenu
->Append(ID_FORMAT_PARAGRAPH_SPACING_MORE
, _("Increase Paragraph &Spacing"));
782 formatMenu
->Append(ID_FORMAT_PARAGRAPH_SPACING_LESS
, _("Decrease &Paragraph Spacing"));
783 formatMenu
->AppendSeparator();
784 formatMenu
->Append(ID_FORMAT_LINE_SPACING_SINGLE
, _("Normal Line Spacing"));
785 formatMenu
->Append(ID_FORMAT_LINE_SPACING_HALF
, _("1.5 Line Spacing"));
786 formatMenu
->Append(ID_FORMAT_LINE_SPACING_DOUBLE
, _("Double Line Spacing"));
787 formatMenu
->AppendSeparator();
788 formatMenu
->Append(ID_FORMAT_FONT
, _("&Font..."));
789 formatMenu
->Append(ID_FORMAT_IMAGE
, _("Image Property"));
790 formatMenu
->Append(ID_FORMAT_PARAGRAPH
, _("&Paragraph..."));
791 formatMenu
->Append(ID_FORMAT_CONTENT
, _("Font and Pa&ragraph...\tShift+Ctrl+F"));
792 formatMenu
->AppendSeparator();
793 formatMenu
->Append(ID_SWITCH_STYLE_SHEETS
, _("&Switch Style Sheets"));
794 formatMenu
->Append(ID_MANAGE_STYLES
, _("&Manage Styles"));
796 wxMenu
* listsMenu
= new wxMenu
;
797 listsMenu
->Append(ID_FORMAT_BULLETS_AND_NUMBERING
, _("Bullets and &Numbering..."));
798 listsMenu
->AppendSeparator();
799 listsMenu
->Append(ID_FORMAT_NUMBER_LIST
, _("Number List"));
800 listsMenu
->Append(ID_FORMAT_ITEMIZE_LIST
, _("Itemize List"));
801 listsMenu
->Append(ID_FORMAT_RENUMBER_LIST
, _("Renumber List"));
802 listsMenu
->Append(ID_FORMAT_PROMOTE_LIST
, _("Promote List Items"));
803 listsMenu
->Append(ID_FORMAT_DEMOTE_LIST
, _("Demote List Items"));
804 listsMenu
->Append(ID_FORMAT_CLEAR_LIST
, _("Clear List Formatting"));
806 wxMenu
* insertMenu
= new wxMenu
;
807 insertMenu
->Append(ID_INSERT_SYMBOL
, _("&Symbol...\tCtrl+I"));
808 insertMenu
->Append(ID_INSERT_URL
, _("&URL..."));
809 insertMenu
->Append(ID_INSERT_IMAGE
, _("&Image..."));
811 // now append the freshly created menu to the menu bar...
812 wxMenuBar
*menuBar
= new wxMenuBar();
813 menuBar
->Append(fileMenu
, wxT("&File"));
814 menuBar
->Append(editMenu
, wxT("&Edit"));
815 menuBar
->Append(formatMenu
, wxT("F&ormat"));
816 menuBar
->Append(listsMenu
, wxT("&Lists"));
817 menuBar
->Append(insertMenu
, wxT("&Insert"));
818 menuBar
->Append(helpMenu
, wxT("&Help"));
820 // ... and attach this menu bar to the frame
823 // create a status bar just for fun (by default with 1 pane only)
824 // but don't create it on limited screen space (WinCE)
825 bool is_pda
= wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA
;
831 SetStatusText(wxT("Welcome to wxRichTextCtrl!"));
835 wxBoxSizer
* sizer
= new wxBoxSizer(wxVERTICAL
);
838 // On Mac, don't create a 'native' wxToolBar because small bitmaps are not supported by native
839 // toolbars. On Mac, a non-native, small-bitmap toolbar doesn't show unless it is explicitly
840 // managed, hence the use of sizers. In a real application, use larger icons for the main
841 // toolbar to avoid the need for this workaround. Or, use the toolbar in a container window
842 // as part of a more complex hierarchy, and the toolbar will automatically be non-native.
844 wxSystemOptions::SetOption(wxT("mac.toolbar.no-native"), 1);
846 wxToolBar
* toolBar
= new wxToolBar(this, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
,
847 wxNO_BORDER
|wxTB_FLAT
|wxTB_NODIVIDER
|wxTB_NOALIGN
);
849 sizer
->Add(toolBar
, 0, wxEXPAND
);
851 toolBar
->AddTool(wxID_OPEN
, wxEmptyString
, wxBitmap(open_xpm
), _("Open"));
852 toolBar
->AddTool(wxID_SAVEAS
, wxEmptyString
, wxBitmap(save_xpm
), _("Save"));
853 toolBar
->AddSeparator();
854 toolBar
->AddTool(wxID_CUT
, wxEmptyString
, wxBitmap(cut_xpm
), _("Cut"));
855 toolBar
->AddTool(wxID_COPY
, wxEmptyString
, wxBitmap(copy_xpm
), _("Copy"));
856 toolBar
->AddTool(wxID_PASTE
, wxEmptyString
, wxBitmap(paste_xpm
), _("Paste"));
857 toolBar
->AddSeparator();
858 toolBar
->AddTool(wxID_UNDO
, wxEmptyString
, wxBitmap(undo_xpm
), _("Undo"));
859 toolBar
->AddTool(wxID_REDO
, wxEmptyString
, wxBitmap(redo_xpm
), _("Redo"));
860 toolBar
->AddSeparator();
861 toolBar
->AddCheckTool(ID_FORMAT_BOLD
, wxEmptyString
, wxBitmap(bold_xpm
), wxNullBitmap
, _("Bold"));
862 toolBar
->AddCheckTool(ID_FORMAT_ITALIC
, wxEmptyString
, wxBitmap(italic_xpm
), wxNullBitmap
, _("Italic"));
863 toolBar
->AddCheckTool(ID_FORMAT_UNDERLINE
, wxEmptyString
, wxBitmap(underline_xpm
), wxNullBitmap
, _("Underline"));
864 toolBar
->AddSeparator();
865 toolBar
->AddCheckTool(ID_FORMAT_ALIGN_LEFT
, wxEmptyString
, wxBitmap(alignleft_xpm
), wxNullBitmap
, _("Align Left"));
866 toolBar
->AddCheckTool(ID_FORMAT_ALIGN_CENTRE
, wxEmptyString
, wxBitmap(centre_xpm
), wxNullBitmap
, _("Centre"));
867 toolBar
->AddCheckTool(ID_FORMAT_ALIGN_RIGHT
, wxEmptyString
, wxBitmap(alignright_xpm
), wxNullBitmap
, _("Align Right"));
868 toolBar
->AddSeparator();
869 toolBar
->AddTool(ID_FORMAT_INDENT_LESS
, wxEmptyString
, wxBitmap(indentless_xpm
), _("Indent Less"));
870 toolBar
->AddTool(ID_FORMAT_INDENT_MORE
, wxEmptyString
, wxBitmap(indentmore_xpm
), _("Indent More"));
871 toolBar
->AddSeparator();
872 toolBar
->AddTool(ID_FORMAT_FONT
, wxEmptyString
, wxBitmap(font_xpm
), _("Font"));
873 toolBar
->AddSeparator();
875 wxRichTextStyleComboCtrl
* combo
= new wxRichTextStyleComboCtrl(toolBar
, ID_RICHTEXT_STYLE_COMBO
, wxDefaultPosition
, wxSize(160, -1), wxCB_READONLY
);
876 toolBar
->AddControl(combo
);
880 wxSplitterWindow
* splitter
= new wxSplitterWindow(this, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
, wxSP_LIVE_UPDATE
);
881 sizer
->Add(splitter
, 1, wxEXPAND
);
883 wxFont textFont
= wxFont(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
884 wxFont boldFont
= wxFont(12, wxROMAN
, wxNORMAL
, wxBOLD
);
885 wxFont italicFont
= wxFont(12, wxROMAN
, wxITALIC
, wxNORMAL
);
887 m_richTextCtrl
= new MyRichTextCtrl(splitter
, ID_RICHTEXT_CTRL
, wxEmptyString
, wxDefaultPosition
, wxDefaultSize
, wxVSCROLL
|wxHSCROLL
|wxWANTS_CHARS
);
888 wxASSERT(!m_richTextCtrl
->GetBuffer().GetAttributes().HasFontPixelSize());
890 wxFont
font(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
892 m_richTextCtrl
->SetFont(font
);
894 wxASSERT(!m_richTextCtrl
->GetBuffer().GetAttributes().HasFontPixelSize());
896 m_richTextCtrl
->SetMargins(10, 10);
898 m_richTextCtrl
->SetStyleSheet(wxGetApp().GetStyleSheet());
900 combo
->SetStyleSheet(wxGetApp().GetStyleSheet());
901 combo
->SetRichTextCtrl(m_richTextCtrl
);
902 combo
->UpdateStyles();
904 wxRichTextStyleListCtrl
* styleListCtrl
= new wxRichTextStyleListCtrl(splitter
, ID_RICHTEXT_STYLE_LIST
);
906 wxSize display
= wxGetDisplaySize();
907 if ( is_pda
&& ( display
.GetWidth() < display
.GetHeight() ) )
909 splitter
->SplitHorizontally(m_richTextCtrl
, styleListCtrl
);
913 int width
= GetClientSize().GetWidth() * 0.8;
914 splitter
->SplitVertically(m_richTextCtrl
, styleListCtrl
, width
);
915 splitter
->SetSashGravity(0.8);
920 splitter
->UpdateSize();
922 styleListCtrl
->SetStyleSheet(wxGetApp().GetStyleSheet());
923 styleListCtrl
->SetRichTextCtrl(m_richTextCtrl
);
924 styleListCtrl
->UpdateStyles();
930 void MyFrame::WriteInitialText()
932 MyRichTextCtrl
& r
= *m_richTextCtrl
;
934 r
.SetDefaultStyle(wxRichTextAttr());
938 r
.BeginSuppressUndo();
940 r
.BeginParagraphSpacing(0, 20);
942 r
.BeginAlignment(wxTEXT_ALIGNMENT_CENTRE
);
947 wxString lineBreak
= (wxChar
) 29;
949 r
.WriteText(wxString(wxT("Welcome to wxRichTextCtrl, a wxWidgets control")) + lineBreak
+ wxT("for editing and presenting styled text and images\n"));
953 r
.WriteText(wxT("by Julian Smart"));
959 r
.WriteImage(wxBitmap(zebra_xpm
));
967 r
.BeginAlignment(wxTEXT_ALIGNMENT_CENTRE
);
968 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.")));
973 r
.BeginAlignment(wxTEXT_ALIGNMENT_LEFT
);
974 wxRichTextAttr imageAttr
;
975 imageAttr
.GetTextBoxAttr().SetFloatMode(wxTEXT_BOX_ATTR_FLOAT_LEFT
);
976 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.")));
977 r
.WriteImage(wxBitmap(zebra_xpm
), wxBITMAP_TYPE_PNG
, imageAttr
);
979 imageAttr
.GetTextBoxAttr().GetTop().SetValue(200);
980 imageAttr
.GetTextBoxAttr().GetTop().SetUnits(wxTEXT_ATTR_UNITS_PIXELS
);
981 imageAttr
.GetTextBoxAttr().SetFloatMode(wxTEXT_BOX_ATTR_FLOAT_RIGHT
);
982 r
.WriteImage(wxBitmap(zebra_xpm
), wxBITMAP_TYPE_PNG
, imageAttr
);
983 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.")));
987 r
.WriteText(wxT("What can you do with this thing? "));
989 r
.WriteImage(wxBitmap(smiley_xpm
));
990 r
.WriteText(wxT(" Well, you can change text "));
992 r
.BeginTextColour(*wxRED
);
993 r
.WriteText(wxT("colour, like this red bit."));
996 wxRichTextAttr backgroundColourAttr
;
997 backgroundColourAttr
.SetBackgroundColour(*wxGREEN
);
998 backgroundColourAttr
.SetTextColour(*wxBLUE
);
999 r
.BeginStyle(backgroundColourAttr
);
1000 r
.WriteText(wxT(" And this blue on green bit."));
1003 r
.WriteText(wxT(" Naturally you can make things "));
1005 r
.WriteText(wxT("bold "));
1008 r
.WriteText(wxT("or italic "));
1011 r
.WriteText(wxT("or underlined."));
1014 r
.BeginFontSize(14);
1015 r
.WriteText(wxT(" Different font sizes on the same line is allowed, too."));
1018 r
.WriteText(wxT(" Next we'll show an indented paragraph."));
1022 r
.BeginLeftIndent(60);
1023 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."));
1028 r
.WriteText(wxT("Next, we'll show a first-line indent, achieved using BeginLeftIndent(100, -40)."));
1032 r
.BeginLeftIndent(100, -40);
1034 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."));
1039 r
.WriteText(wxT("Numbered bullets are possible, again using subindents:"));
1042 r
.BeginNumberedBullet(1, 100, 60);
1043 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."));
1045 r
.EndNumberedBullet();
1047 r
.BeginNumberedBullet(2, 100, 60);
1048 r
.WriteText(wxT("This is my second item."));
1050 r
.EndNumberedBullet();
1052 r
.WriteText(wxT("The following paragraph is right-indented:"));
1055 r
.BeginRightIndent(200);
1057 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."));
1062 r
.WriteText(wxT("The following paragraph is right-aligned with 1.5 line spacing:"));
1065 r
.BeginAlignment(wxTEXT_ALIGNMENT_RIGHT
);
1066 r
.BeginLineSpacing(wxTEXT_ATTR_LINE_SPACING_HALF
);
1067 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."));
1077 wxRichTextAttr attr
;
1078 attr
.SetFlags(wxTEXT_ATTR_TABS
);
1080 r
.SetDefaultStyle(attr
);
1082 r
.WriteText(wxT("This line contains tabs:\tFirst tab\tSecond tab\tThird tab"));
1085 r
.WriteText(wxT("Other notable features of wxRichTextCtrl include:"));
1088 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1089 r
.WriteText(wxT("Compatibility with wxTextCtrl API"));
1091 r
.EndSymbolBullet();
1093 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1094 r
.WriteText(wxT("Easy stack-based BeginXXX()...EndXXX() style setting in addition to SetStyle()"));
1096 r
.EndSymbolBullet();
1098 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1099 r
.WriteText(wxT("XML loading and saving"));
1101 r
.EndSymbolBullet();
1103 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1104 r
.WriteText(wxT("Undo/Redo, with batching option and Undo suppressing"));
1106 r
.EndSymbolBullet();
1108 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1109 r
.WriteText(wxT("Clipboard copy and paste"));
1111 r
.EndSymbolBullet();
1113 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1114 r
.WriteText(wxT("wxRichTextStyleSheet with named character and paragraph styles, and control for applying named styles"));
1116 r
.EndSymbolBullet();
1118 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1119 r
.WriteText(wxT("A design that can easily be extended to other content types, ultimately with text boxes, tables, controls, and so on"));
1121 r
.EndSymbolBullet();
1123 // Make a style suitable for showing a URL
1124 wxRichTextAttr urlStyle
;
1125 urlStyle
.SetTextColour(*wxBLUE
);
1126 urlStyle
.SetFontUnderlined(true);
1128 r
.WriteText(wxT("wxRichTextCtrl can also display URLs, such as this one: "));
1129 r
.BeginStyle(urlStyle
);
1130 r
.BeginURL(wxT("http://www.wxwidgets.org"));
1131 r
.WriteText(wxT("The wxWidgets Web Site"));
1134 r
.WriteText(wxT(". Click on the URL to generate an event."));
1138 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"));
1140 r
.EndParagraphSpacing();
1148 wxRichTextAttr attr
;
1149 attr
.GetTextBoxAttr().GetMargins().GetLeft().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS
);
1150 attr
.GetTextBoxAttr().GetMargins().GetTop().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS
);
1151 attr
.GetTextBoxAttr().GetMargins().GetRight().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS
);
1152 attr
.GetTextBoxAttr().GetMargins().GetBottom().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS
);
1154 attr
.GetTextBoxAttr().GetBorder().SetColour(*wxBLACK
);
1155 attr
.GetTextBoxAttr().GetBorder().SetWidth(1, wxTEXT_ATTR_UNITS_PIXELS
);
1156 attr
.GetTextBoxAttr().GetBorder().SetStyle(wxTEXT_BOX_ATTR_BORDER_SOLID
);
1158 wxRichTextBox
* textBox
= r
.WriteTextBox(attr
);
1159 r
.SetFocusObject(textBox
);
1161 r
.WriteText(wxT("This is a text box. Just testing! Once more unto the breach, dear friends, once more..."));
1163 r
.SetFocusObject(NULL
); // Set the focus back to the main buffer
1164 r
.SetInsertionPointEnd();
1173 wxRichTextAttr attr
;
1174 attr
.GetTextBoxAttr().GetMargins().GetLeft().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS
);
1175 attr
.GetTextBoxAttr().GetMargins().GetTop().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS
);
1176 attr
.GetTextBoxAttr().GetMargins().GetRight().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS
);
1177 attr
.GetTextBoxAttr().GetMargins().GetBottom().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS
);
1178 attr
.GetTextBoxAttr().GetPadding() = attr
.GetTextBoxAttr().GetMargins();
1180 attr
.GetTextBoxAttr().GetBorder().SetColour(*wxBLACK
);
1181 attr
.GetTextBoxAttr().GetBorder().SetWidth(1, wxTEXT_ATTR_UNITS_PIXELS
);
1182 attr
.GetTextBoxAttr().GetBorder().SetStyle(wxTEXT_BOX_ATTR_BORDER_SOLID
);
1184 wxRichTextAttr cellAttr
= attr
;
1185 cellAttr
.GetTextBoxAttr().GetWidth().SetValue(200, wxTEXT_ATTR_UNITS_PIXELS
);
1186 cellAttr
.GetTextBoxAttr().GetHeight().SetValue(150, wxTEXT_ATTR_UNITS_PIXELS
);
1188 wxRichTextTable
* table
= r
.WriteTable(6, 4, attr
, cellAttr
);
1191 for (j
= 0; j
< table
->GetRowCount(); j
++)
1193 for (i
= 0; i
< table
->GetColumnCount(); i
++)
1195 wxString msg
= wxString::Format(wxT("This is cell %d, %d"), (j
+1), (i
+1));
1196 r
.SetFocusObject(table
->GetCell(j
, i
));
1201 // Demonstrate colspan and rowspan
1202 wxRichTextCell
* cell
= table
->GetCell(1, 0);
1203 cell
->SetColspan(2);
1204 r
.SetFocusObject(cell
);
1206 r
.WriteText("This cell spans 2 columns");
1208 cell
= table
->GetCell(1, 3);
1209 cell
->SetRowspan(2);
1210 r
.SetFocusObject(cell
);
1212 r
.WriteText("This cell spans 2 rows");
1214 cell
= table
->GetCell(2, 1);
1215 cell
->SetColspan(2);
1216 cell
->SetRowspan(3);
1217 r
.SetFocusObject(cell
);
1219 r
.WriteText("This cell spans 2 columns and 3 rows");
1221 r
.SetFocusObject(NULL
); // Set the focus back to the main buffer
1222 r
.SetInsertionPointEnd();
1226 r
.Newline(); r
.Newline();
1228 wxRichTextProperties properties
;
1229 r
.WriteText(wxT("This is a rectangle field: "));
1230 r
.WriteField(wxT("rectangle"), properties
);
1231 r
.WriteText(wxT(" and a begin section field: "));
1232 r
.WriteField(wxT("begin-section"), properties
);
1233 r
.WriteText(wxT("This is text between the two tags."));
1234 r
.WriteField(wxT("end-section"), properties
);
1235 r
.WriteText(wxT(" Now a bitmap. "));
1236 r
.WriteField(wxT("bitmap"), properties
);
1237 r
.WriteText(wxT(" Before we go, here's a composite field: ***"));
1238 wxRichTextField
* field
= r
.WriteField(wxT("composite"), properties
);
1239 field
->UpdateField(& r
.GetBuffer()); // Creates the composite value (sort of a text box)
1240 r
.WriteText(wxT("*** End of composite field."));
1243 r
.EndSuppressUndo();
1245 // Add some locked content first - needs Undo to be enabled
1248 r
.WriteText(wxString(wxT("This is a locked object.")));
1251 r
.WriteText(wxString(wxT(" This is unlocked text. ")));
1254 r
.WriteText(wxString(wxT("More locked content.")));
1258 // Flush the Undo buffer
1259 r
.GetCommandProcessor()->ClearCommands();
1267 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
1269 // true is to force the frame to close
1273 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
1276 msg
.Printf( wxT("This is a demo for wxRichTextCtrl, a control for editing styled text.\n(c) Julian Smart, 2005"));
1277 wxMessageBox(msg
, wxT("About wxRichTextCtrl Sample"), wxOK
| wxICON_INFORMATION
, this);
1280 // Forward command events to the current rich text control, if any
1281 bool MyFrame::ProcessEvent(wxEvent
& event
)
1283 if (event
.IsCommandEvent() && !event
.IsKindOf(CLASSINFO(wxChildFocusEvent
)))
1285 // Problem: we can get infinite recursion because the events
1286 // climb back up to this frame, and repeat.
1287 // Assume that command events don't cause another command event
1288 // to be called, so we can rely on inCommand not being overwritten
1290 static int s_eventType
= 0;
1291 static wxWindowID s_id
= 0;
1293 if (s_id
!= event
.GetId() && s_eventType
!= event
.GetEventType())
1295 s_eventType
= event
.GetEventType();
1296 s_id
= event
.GetId();
1298 wxWindow
* focusWin
= wxFindFocusDescendant(this);
1299 if (focusWin
&& focusWin
->GetEventHandler()->ProcessEvent(event
))
1316 return wxFrame::ProcessEvent(event
);
1319 void MyFrame::OnOpen(wxCommandEvent
& WXUNUSED(event
))
1323 wxArrayInt fileTypes
;
1325 wxString filter
= wxRichTextBuffer::GetExtWildcard(false, false, & fileTypes
);
1326 if (!filter
.empty())
1328 filter
+= wxT("All files (*.*)|*.*");
1330 wxFileDialog
dialog(this,
1331 _("Choose a filename"),
1337 if (dialog
.ShowModal() == wxID_OK
)
1339 wxString path
= dialog
.GetPath();
1343 int filterIndex
= dialog
.GetFilterIndex();
1344 int fileType
= (filterIndex
< (int) fileTypes
.GetCount())
1345 ? fileTypes
[filterIndex
]
1346 : wxRICHTEXT_TYPE_TEXT
;
1347 m_richTextCtrl
->LoadFile(path
, fileType
);
1352 void MyFrame::OnSave(wxCommandEvent
& event
)
1354 if (m_richTextCtrl
->GetFilename().empty())
1359 m_richTextCtrl
->SaveFile();
1362 void MyFrame::OnSaveAs(wxCommandEvent
& WXUNUSED(event
))
1364 wxString filter
= wxRichTextBuffer::GetExtWildcard(false, true);
1368 wxFileDialog
dialog(this,
1369 _("Choose a filename"),
1375 if (dialog
.ShowModal() == wxID_OK
)
1377 wxString path
= dialog
.GetPath();
1382 wxStopWatch stopwatch
;
1384 m_richTextCtrl
->SaveFile(path
);
1386 long t
= stopwatch
.Time();
1387 wxLogDebug(wxT("Saving took %ldms"), t
);
1388 wxMessageBox(wxString::Format(wxT("Saving took %ldms"), t
));
1393 void MyFrame::OnBold(wxCommandEvent
& WXUNUSED(event
))
1395 m_richTextCtrl
->ApplyBoldToSelection();
1398 void MyFrame::OnItalic(wxCommandEvent
& WXUNUSED(event
))
1400 m_richTextCtrl
->ApplyItalicToSelection();
1403 void MyFrame::OnUnderline(wxCommandEvent
& WXUNUSED(event
))
1405 m_richTextCtrl
->ApplyUnderlineToSelection();
1408 void MyFrame::OnStrikethrough(wxCommandEvent
& WXUNUSED(event
))
1410 m_richTextCtrl
->ApplyTextEffectToSelection(wxTEXT_ATTR_EFFECT_STRIKETHROUGH
);
1413 void MyFrame::OnSuperscript(wxCommandEvent
& WXUNUSED(event
))
1415 m_richTextCtrl
->ApplyTextEffectToSelection(wxTEXT_ATTR_EFFECT_SUPERSCRIPT
);
1418 void MyFrame::OnSubscript(wxCommandEvent
& WXUNUSED(event
))
1420 m_richTextCtrl
->ApplyTextEffectToSelection(wxTEXT_ATTR_EFFECT_SUBSCRIPT
);
1424 void MyFrame::OnUpdateBold(wxUpdateUIEvent
& event
)
1426 event
.Check(m_richTextCtrl
->IsSelectionBold());
1429 void MyFrame::OnUpdateItalic(wxUpdateUIEvent
& event
)
1431 event
.Check(m_richTextCtrl
->IsSelectionItalics());
1434 void MyFrame::OnUpdateUnderline(wxUpdateUIEvent
& event
)
1436 event
.Check(m_richTextCtrl
->IsSelectionUnderlined());
1439 void MyFrame::OnUpdateStrikethrough(wxUpdateUIEvent
& event
)
1441 event
.Check(m_richTextCtrl
->DoesSelectionHaveTextEffectFlag(wxTEXT_ATTR_EFFECT_STRIKETHROUGH
));
1444 void MyFrame::OnUpdateSuperscript(wxUpdateUIEvent
& event
)
1446 event
.Check(m_richTextCtrl
->DoesSelectionHaveTextEffectFlag(wxTEXT_ATTR_EFFECT_SUPERSCRIPT
));
1449 void MyFrame::OnUpdateSubscript(wxUpdateUIEvent
& event
)
1451 event
.Check(m_richTextCtrl
->DoesSelectionHaveTextEffectFlag(wxTEXT_ATTR_EFFECT_SUBSCRIPT
));
1454 void MyFrame::OnAlignLeft(wxCommandEvent
& WXUNUSED(event
))
1456 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_LEFT
);
1459 void MyFrame::OnAlignCentre(wxCommandEvent
& WXUNUSED(event
))
1461 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_CENTRE
);
1464 void MyFrame::OnAlignRight(wxCommandEvent
& WXUNUSED(event
))
1466 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_RIGHT
);
1469 void MyFrame::OnUpdateAlignLeft(wxUpdateUIEvent
& event
)
1471 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_LEFT
));
1474 void MyFrame::OnUpdateAlignCentre(wxUpdateUIEvent
& event
)
1476 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_CENTRE
));
1479 void MyFrame::OnUpdateAlignRight(wxUpdateUIEvent
& event
)
1481 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_RIGHT
));
1484 void MyFrame::OnFont(wxCommandEvent
& WXUNUSED(event
))
1486 wxRichTextRange range
;
1487 if (m_richTextCtrl
->HasSelection())
1488 range
= m_richTextCtrl
->GetSelectionRange();
1490 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1492 int pages
= wxRICHTEXT_FORMAT_FONT
;
1494 wxRichTextFormattingDialog
formatDlg(pages
, this);
1495 formatDlg
.SetOptions(wxRichTextFormattingDialog::Option_AllowPixelFontSize
);
1496 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1498 if (formatDlg
.ShowModal() == wxID_OK
)
1500 formatDlg
.ApplyStyle(m_richTextCtrl
, range
, wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_OPTIMIZE
|wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY
);
1504 void MyFrame::OnImage(wxCommandEvent
& WXUNUSED(event
))
1506 wxRichTextRange range
;
1507 wxASSERT(m_richTextCtrl
->HasSelection());
1509 range
= m_richTextCtrl
->GetSelectionRange();
1510 wxASSERT(range
.ToInternal().GetLength() == 1);
1512 wxRichTextImage
* image
= wxDynamicCast(m_richTextCtrl
->GetFocusObject()->GetLeafObjectAtPosition(range
.GetStart()), wxRichTextImage
);
1515 wxRichTextObjectPropertiesDialog
imageDlg(image
, this);
1517 if (imageDlg
.ShowModal() == wxID_OK
)
1519 imageDlg
.ApplyStyle(m_richTextCtrl
);
1524 void MyFrame::OnParagraph(wxCommandEvent
& WXUNUSED(event
))
1526 wxRichTextRange range
;
1527 if (m_richTextCtrl
->HasSelection())
1528 range
= m_richTextCtrl
->GetSelectionRange();
1530 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1532 int pages
= wxRICHTEXT_FORMAT_INDENTS_SPACING
|wxRICHTEXT_FORMAT_TABS
|wxRICHTEXT_FORMAT_BULLETS
;
1534 wxRichTextFormattingDialog
formatDlg(pages
, this);
1535 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1537 if (formatDlg
.ShowModal() == wxID_OK
)
1539 formatDlg
.ApplyStyle(m_richTextCtrl
, range
);
1543 void MyFrame::OnFormat(wxCommandEvent
& WXUNUSED(event
))
1545 wxRichTextRange range
;
1546 if (m_richTextCtrl
->HasSelection())
1547 range
= m_richTextCtrl
->GetSelectionRange();
1549 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1551 int pages
= wxRICHTEXT_FORMAT_FONT
|wxRICHTEXT_FORMAT_INDENTS_SPACING
|wxRICHTEXT_FORMAT_TABS
|wxRICHTEXT_FORMAT_BULLETS
;
1553 wxRichTextFormattingDialog
formatDlg(pages
, this);
1554 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1556 if (formatDlg
.ShowModal() == wxID_OK
)
1558 formatDlg
.ApplyStyle(m_richTextCtrl
, range
);
1562 void MyFrame::OnUpdateFormat(wxUpdateUIEvent
& event
)
1564 event
.Enable(m_richTextCtrl
->HasSelection());
1567 void MyFrame::OnUpdateImage(wxUpdateUIEvent
& event
)
1569 wxRichTextRange range
;
1570 wxRichTextObject
*obj
;
1572 range
= m_richTextCtrl
->GetSelectionRange();
1573 if (range
.ToInternal().GetLength() == 1)
1575 obj
= m_richTextCtrl
->GetFocusObject()->GetLeafObjectAtPosition(range
.GetStart());
1576 if (obj
&& obj
->IsKindOf(CLASSINFO(wxRichTextImage
)))
1583 event
.Enable(false);
1586 void MyFrame::OnIndentMore(wxCommandEvent
& WXUNUSED(event
))
1588 wxRichTextAttr attr
;
1589 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1591 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1593 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1594 if (m_richTextCtrl
->HasSelection())
1595 range
= m_richTextCtrl
->GetSelectionRange();
1597 attr
.SetLeftIndent(attr
.GetLeftIndent() + 100);
1599 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1600 m_richTextCtrl
->SetStyle(range
, attr
);
1604 void MyFrame::OnIndentLess(wxCommandEvent
& WXUNUSED(event
))
1606 wxRichTextAttr attr
;
1607 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1609 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1611 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1612 if (m_richTextCtrl
->HasSelection())
1613 range
= m_richTextCtrl
->GetSelectionRange();
1615 if (attr
.GetLeftIndent() > 0)
1617 attr
.SetLeftIndent(wxMax(0, attr
.GetLeftIndent() - 100));
1619 m_richTextCtrl
->SetStyle(range
, attr
);
1624 void MyFrame::OnLineSpacingHalf(wxCommandEvent
& WXUNUSED(event
))
1626 wxRichTextAttr attr
;
1627 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1629 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1631 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1632 if (m_richTextCtrl
->HasSelection())
1633 range
= m_richTextCtrl
->GetSelectionRange();
1635 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1636 attr
.SetLineSpacing(15);
1638 m_richTextCtrl
->SetStyle(range
, attr
);
1642 void MyFrame::OnLineSpacingDouble(wxCommandEvent
& WXUNUSED(event
))
1644 wxRichTextAttr attr
;
1645 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1647 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1649 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1650 if (m_richTextCtrl
->HasSelection())
1651 range
= m_richTextCtrl
->GetSelectionRange();
1653 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1654 attr
.SetLineSpacing(20);
1656 m_richTextCtrl
->SetStyle(range
, attr
);
1660 void MyFrame::OnLineSpacingSingle(wxCommandEvent
& WXUNUSED(event
))
1662 wxRichTextAttr attr
;
1663 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1665 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1667 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1668 if (m_richTextCtrl
->HasSelection())
1669 range
= m_richTextCtrl
->GetSelectionRange();
1671 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1672 attr
.SetLineSpacing(0); // Can also use 10
1674 m_richTextCtrl
->SetStyle(range
, attr
);
1678 void MyFrame::OnParagraphSpacingMore(wxCommandEvent
& WXUNUSED(event
))
1680 wxRichTextAttr attr
;
1681 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1683 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1685 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1686 if (m_richTextCtrl
->HasSelection())
1687 range
= m_richTextCtrl
->GetSelectionRange();
1689 attr
.SetParagraphSpacingAfter(attr
.GetParagraphSpacingAfter() + 20);
1691 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1692 m_richTextCtrl
->SetStyle(range
, attr
);
1696 void MyFrame::OnParagraphSpacingLess(wxCommandEvent
& WXUNUSED(event
))
1698 wxRichTextAttr attr
;
1699 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1701 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1703 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1704 if (m_richTextCtrl
->HasSelection())
1705 range
= m_richTextCtrl
->GetSelectionRange();
1707 if (attr
.GetParagraphSpacingAfter() >= 20)
1709 attr
.SetParagraphSpacingAfter(attr
.GetParagraphSpacingAfter() - 20);
1711 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1712 m_richTextCtrl
->SetStyle(range
, attr
);
1717 void MyFrame::OnReload(wxCommandEvent
& WXUNUSED(event
))
1719 m_richTextCtrl
->Clear();
1723 void MyFrame::OnViewHTML(wxCommandEvent
& WXUNUSED(event
))
1725 wxDialog
dialog(this, wxID_ANY
, _("HTML"), wxDefaultPosition
, wxSize(500, 400), wxDEFAULT_DIALOG_STYLE
);
1727 wxBoxSizer
* boxSizer
= new wxBoxSizer(wxVERTICAL
);
1728 dialog
.SetSizer(boxSizer
);
1730 wxHtmlWindow
* win
= new wxHtmlWindow(& dialog
, wxID_ANY
, wxDefaultPosition
, wxSize(500, 400), wxSUNKEN_BORDER
);
1731 boxSizer
->Add(win
, 1, wxALL
, 5);
1733 wxButton
* cancelButton
= new wxButton(& dialog
, wxID_CANCEL
, wxT("&Close"));
1734 boxSizer
->Add(cancelButton
, 0, wxALL
|wxCENTRE
, 5);
1737 wxStringOutputStream
strStream(& text
);
1739 wxRichTextHTMLHandler htmlHandler
;
1740 htmlHandler
.SetFlags(wxRICHTEXT_HANDLER_SAVE_IMAGES_TO_MEMORY
);
1742 wxArrayInt fontSizeMapping
;
1743 fontSizeMapping
.Add(7);
1744 fontSizeMapping
.Add(9);
1745 fontSizeMapping
.Add(11);
1746 fontSizeMapping
.Add(12);
1747 fontSizeMapping
.Add(14);
1748 fontSizeMapping
.Add(22);
1749 fontSizeMapping
.Add(100);
1751 htmlHandler
.SetFontSizeMapping(fontSizeMapping
);
1753 if (htmlHandler
.SaveFile(& m_richTextCtrl
->GetBuffer(), strStream
))
1758 boxSizer
->Fit(& dialog
);
1762 // Now delete the temporary in-memory images
1763 htmlHandler
.DeleteTemporaryImages();
1766 // Demonstrates how you can change the style sheets and have the changes
1767 // reflected in the control content without wiping out character formatting.
1769 void MyFrame::OnSwitchStyleSheets(wxCommandEvent
& WXUNUSED(event
))
1771 static wxRichTextStyleSheet
* gs_AlternateStyleSheet
= NULL
;
1773 wxRichTextStyleListCtrl
*styleList
= (wxRichTextStyleListCtrl
*) FindWindow(ID_RICHTEXT_STYLE_LIST
);
1774 wxRichTextStyleComboCtrl
* styleCombo
= (wxRichTextStyleComboCtrl
*) FindWindow(ID_RICHTEXT_STYLE_COMBO
);
1776 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1778 // One-time creation of an alternate style sheet
1779 if (!gs_AlternateStyleSheet
)
1781 gs_AlternateStyleSheet
= new wxRichTextStyleSheet(*sheet
);
1783 // Make some modifications
1784 for (int i
= 0; i
< (int) gs_AlternateStyleSheet
->GetParagraphStyleCount(); i
++)
1786 wxRichTextParagraphStyleDefinition
* def
= gs_AlternateStyleSheet
->GetParagraphStyle(i
);
1788 if (def
->GetStyle().HasTextColour())
1789 def
->GetStyle().SetTextColour(*wxBLUE
);
1791 if (def
->GetStyle().HasAlignment())
1793 if (def
->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_CENTRE
)
1794 def
->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_RIGHT
);
1795 else if (def
->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_LEFT
)
1796 def
->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_CENTRE
);
1798 if (def
->GetStyle().HasLeftIndent())
1800 def
->GetStyle().SetLeftIndent(def
->GetStyle().GetLeftIndent() * 2);
1806 wxRichTextStyleSheet
* tmp
= gs_AlternateStyleSheet
;
1807 gs_AlternateStyleSheet
= sheet
;
1810 m_richTextCtrl
->SetStyleSheet(sheet
);
1811 m_richTextCtrl
->ApplyStyleSheet(sheet
); // Makes the control reflect the new style definitions
1813 styleList
->SetStyleSheet(sheet
);
1814 styleList
->UpdateStyles();
1816 styleCombo
->SetStyleSheet(sheet
);
1817 styleCombo
->UpdateStyles();
1820 void MyFrame::OnManageStyles(wxCommandEvent
& WXUNUSED(event
))
1822 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1824 int flags
= wxRICHTEXT_ORGANISER_CREATE_STYLES
|wxRICHTEXT_ORGANISER_EDIT_STYLES
;
1826 wxRichTextStyleOrganiserDialog
dlg(flags
, sheet
, NULL
, this, wxID_ANY
, _("Style Manager"));
1830 void MyFrame::OnInsertSymbol(wxCommandEvent
& WXUNUSED(event
))
1832 wxRichTextAttr attr
;
1833 attr
.SetFlags(wxTEXT_ATTR_FONT
);
1834 m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
);
1836 wxString currentFontName
;
1837 if (attr
.HasFont() && attr
.GetFont().IsOk())
1838 currentFontName
= attr
.GetFont().GetFaceName();
1840 // Don't set the initial font in the dialog (so the user is choosing
1841 // 'normal text', i.e. the current font) but do tell the dialog
1842 // what 'normal text' is.
1844 wxSymbolPickerDialog
dlg(wxT("*"), wxEmptyString
, currentFontName
, this);
1846 if (dlg
.ShowModal() == wxID_OK
)
1848 if (dlg
.HasSelection())
1850 long insertionPoint
= m_richTextCtrl
->GetInsertionPoint();
1852 m_richTextCtrl
->WriteText(dlg
.GetSymbol());
1854 if (!dlg
.UseNormalFont())
1856 wxFont
font(attr
.GetFont());
1857 font
.SetFaceName(dlg
.GetFontName());
1859 m_richTextCtrl
->SetStyle(insertionPoint
, insertionPoint
+1, attr
);
1865 void MyFrame::OnNumberList(wxCommandEvent
& WXUNUSED(event
))
1867 if (m_richTextCtrl
->HasSelection())
1869 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1870 m_richTextCtrl
->SetListStyle(range
, wxT("Numbered List 1"), wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_RENUMBER
);
1874 void MyFrame::OnBulletsAndNumbering(wxCommandEvent
& WXUNUSED(event
))
1876 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1878 int flags
= wxRICHTEXT_ORGANISER_BROWSE_NUMBERING
;
1880 wxRichTextStyleOrganiserDialog
dlg(flags
, sheet
, m_richTextCtrl
, this, wxID_ANY
, _("Bullets and Numbering"));
1881 if (dlg
.ShowModal() == wxID_OK
)
1883 if (dlg
.GetSelectedStyleDefinition())
1888 void MyFrame::OnItemizeList(wxCommandEvent
& WXUNUSED(event
))
1890 if (m_richTextCtrl
->HasSelection())
1892 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1893 m_richTextCtrl
->SetListStyle(range
, wxT("Bullet List 1"));
1897 void MyFrame::OnRenumberList(wxCommandEvent
& WXUNUSED(event
))
1899 if (m_richTextCtrl
->HasSelection())
1901 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1902 m_richTextCtrl
->NumberList(range
, NULL
, wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_RENUMBER
);
1906 void MyFrame::OnPromoteList(wxCommandEvent
& WXUNUSED(event
))
1908 if (m_richTextCtrl
->HasSelection())
1910 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1911 m_richTextCtrl
->PromoteList(1, range
, NULL
);
1915 void MyFrame::OnDemoteList(wxCommandEvent
& WXUNUSED(event
))
1917 if (m_richTextCtrl
->HasSelection())
1919 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1920 m_richTextCtrl
->PromoteList(-1, range
, NULL
);
1924 void MyFrame::OnClearList(wxCommandEvent
& WXUNUSED(event
))
1926 if (m_richTextCtrl
->HasSelection())
1928 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1929 m_richTextCtrl
->ClearListStyle(range
);
1933 void MyFrame::OnInsertURL(wxCommandEvent
& WXUNUSED(event
))
1935 wxString url
= wxGetTextFromUser(_("URL:"), _("Insert URL"));
1938 // Make a style suitable for showing a URL
1939 wxRichTextAttr urlStyle
;
1940 urlStyle
.SetTextColour(*wxBLUE
);
1941 urlStyle
.SetFontUnderlined(true);
1943 m_richTextCtrl
->BeginStyle(urlStyle
);
1944 m_richTextCtrl
->BeginURL(url
);
1945 m_richTextCtrl
->WriteText(url
);
1946 m_richTextCtrl
->EndURL();
1947 m_richTextCtrl
->EndStyle();
1951 void MyFrame::OnInsertImage(wxCommandEvent
& WXUNUSED(event
))
1953 wxFileDialog
dialog(this, _("Choose an image"), "", "", "BMP and GIF files (*.bmp;*.gif)|*.bmp;*.gif|PNG files (*.png)|*.png");
1954 if (dialog
.ShowModal() == wxID_OK
)
1956 wxString path
= dialog
.GetPath();
1957 m_richTextCtrl
->WriteImage(path
, wxBITMAP_TYPE_ANY
);
1961 void MyFrame::OnURL(wxTextUrlEvent
& event
)
1963 wxMessageBox(event
.GetString());
1966 // Veto style sheet replace events when loading from XML, since we want
1967 // to keep the original style sheet.
1968 void MyFrame::OnStyleSheetReplacing(wxRichTextEvent
& event
)
1973 void MyFrame::OnPrint(wxCommandEvent
& WXUNUSED(event
))
1975 wxGetApp().GetPrinting()->PrintBuffer(m_richTextCtrl
->GetBuffer());
1978 void MyFrame::OnPreview(wxCommandEvent
& WXUNUSED(event
))
1980 wxGetApp().GetPrinting()->PreviewBuffer(m_richTextCtrl
->GetBuffer());
1983 void MyFrame::OnPageSetup(wxCommandEvent
& WXUNUSED(event
))
1985 wxDialog
dialog(this, wxID_ANY
, wxT("Testing"), wxPoint(10, 10), wxSize(400, 300), wxDEFAULT_DIALOG_STYLE
);
1987 wxNotebook
* nb
= new wxNotebook(& dialog
, wxID_ANY
, wxPoint(5, 5), wxSize(300, 250));
1988 wxPanel
* panel
= new wxPanel(nb
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
);
1989 wxPanel
* panel2
= new wxPanel(nb
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
);
1991 new wxRichTextCtrl(panel
, wxID_ANY
, wxEmptyString
, wxPoint(5, 5), wxSize(200, 150), wxVSCROLL
|wxTE_READONLY
);
1992 nb
->AddPage(panel
, wxT("Page 1"));
1994 new wxRichTextCtrl(panel2
, wxID_ANY
, wxEmptyString
, wxPoint(5, 5), wxSize(200, 150), wxVSCROLL
|wxTE_READONLY
);
1995 nb
->AddPage(panel2
, wxT("Page 2"));
1997 new wxButton(& dialog
, wxID_OK
, wxT("OK"), wxPoint(5, 180));
2001 // wxGetApp().GetPrinting()->PageSetup();
2004 void MyFrame::OnSetFontScale(wxCommandEvent
& WXUNUSED(event
))
2006 wxString value
= wxString::Format(wxT("%g"), m_richTextCtrl
->GetFontScale());
2007 wxString text
= wxGetTextFromUser(wxT("Enter a text scale factor:"), wxT("Text Scale Factor"), value
, wxGetTopLevelParent(this));
2008 if (!text
.IsEmpty() && value
!= text
)
2011 wxSscanf(text
, wxT("%lf"), & scale
);
2012 m_richTextCtrl
->SetFontScale(scale
, true);
2016 void MyFrame::OnSetDimensionScale(wxCommandEvent
& WXUNUSED(event
))
2018 wxString value
= wxString::Format(wxT("%g"), m_richTextCtrl
->GetDimensionScale());
2019 wxString text
= wxGetTextFromUser(wxT("Enter a dimension scale factor:"), wxT("Dimension Scale Factor"), value
, wxGetTopLevelParent(this));
2020 if (!text
.IsEmpty() && value
!= text
)
2023 wxSscanf(text
, wxT("%lf"), & scale
);
2024 m_richTextCtrl
->SetDimensionScale(scale
, true);
2028 void MyRichTextCtrl::PrepareContent(wxRichTextParagraphLayoutBox
& container
)
2032 // Lock all content that's about to be added to the control
2033 wxRichTextObjectList::compatibility_iterator node
= container
.GetChildren().GetFirst();
2036 wxRichTextParagraph
* para
= wxDynamicCast(node
->GetData(), wxRichTextParagraph
);
2039 wxRichTextObjectList::compatibility_iterator childNode
= para
->GetChildren().GetFirst();
2042 wxRichTextObject
* obj
= childNode
->GetData();
2043 obj
->GetProperties().SetProperty(wxT("Lock"), m_lockId
);
2045 childNode
= childNode
->GetNext();
2048 node
= node
->GetNext();
2053 bool MyRichTextCtrl::CanDeleteRange(wxRichTextParagraphLayoutBox
& container
, const wxRichTextRange
& range
) const
2056 for (i
= range
.GetStart(); i
< range
.GetEnd(); i
++)
2058 wxRichTextObject
* obj
= container
.GetLeafObjectAtPosition(i
);
2059 if (obj
&& obj
->GetProperties().HasProperty(wxT("Lock")))
2067 bool MyRichTextCtrl::CanInsertContent(wxRichTextParagraphLayoutBox
& container
, long pos
) const
2069 wxRichTextObject
* child1
= container
.GetLeafObjectAtPosition(pos
);
2070 wxRichTextObject
* child2
= container
.GetLeafObjectAtPosition(pos
-1);
2072 long lock1
= -1, lock2
= -1;
2074 if (child1
&& child1
->GetProperties().HasProperty(wxT("Lock")))
2075 lock1
= child1
->GetProperties().GetPropertyLong(wxT("Lock"));
2076 if (child2
&& child2
->GetProperties().HasProperty(wxT("Lock")))
2077 lock2
= child2
->GetProperties().GetPropertyLong(wxT("Lock"));
2079 if (lock1
!= -1 && lock1
== lock2
)
2082 // Don't allow insertion before a locked object if it's at the beginning of the buffer.
2083 if (pos
== 0 && lock1
!= -1)
2090 class wxRichTextEnhancedDrawingHandler
: public wxRichTextDrawingHandler
2093 wxRichTextEnhancedDrawingHandler()
2095 SetName(wxT("enhanceddrawing"));
2096 m_lockBackgroundColour
= wxColour(220, 220, 220);
2100 Returns @true if this object has virtual attributes that we can provide.
2102 virtual bool HasVirtualAttributes(wxRichTextObject
* obj
) const;
2105 Provides virtual attributes that we can provide.
2107 virtual bool GetVirtualAttributes(wxRichTextAttr
& attr
, wxRichTextObject
* obj
) const;
2110 Gets the count for mixed virtual attributes for individual positions within the object.
2111 For example, individual characters within a text object may require special highlighting.
2113 virtual int GetVirtualSubobjectAttributesCount(wxRichTextObject
* WXUNUSED(obj
)) const { return 0; }
2116 Gets the mixed virtual attributes for individual positions within the object.
2117 For example, individual characters within a text object may require special highlighting.
2118 Returns the number of virtual attributes found.
2120 virtual int GetVirtualSubobjectAttributes(wxRichTextObject
* WXUNUSED(obj
), wxArrayInt
& WXUNUSED(positions
), wxRichTextAttrArray
& WXUNUSED(attributes
)) const { return 0; }
2123 Do we have virtual text for this object? Virtual text allows an application
2124 to replace characters in an object for editing and display purposes, for example
2125 for highlighting special characters.
2127 virtual bool HasVirtualText(const wxRichTextPlainText
* WXUNUSED(obj
)) const { return false; }
2130 Gets the virtual text for this object.
2132 virtual bool GetVirtualText(const wxRichTextPlainText
* WXUNUSED(obj
), wxString
& WXUNUSED(text
)) const { return false; }
2134 wxColour m_lockBackgroundColour
;
2137 bool wxRichTextEnhancedDrawingHandler::HasVirtualAttributes(wxRichTextObject
* obj
) const
2139 return obj
->GetProperties().HasProperty(wxT("Lock"));
2142 bool wxRichTextEnhancedDrawingHandler::GetVirtualAttributes(wxRichTextAttr
& attr
, wxRichTextObject
* obj
) const
2144 if (obj
->GetProperties().HasProperty(wxT("Lock")))
2146 attr
.SetBackgroundColour(m_lockBackgroundColour
);
2152 void MyRichTextCtrl::SetEnhancedDrawingHandler()
2154 wxRichTextBuffer::AddDrawingHandler(new wxRichTextEnhancedDrawingHandler
);