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 MyFrame
*frame
= new MyFrame(wxT("wxRichTextCtrl Sample"), wxID_ANY
, wxDefaultPosition
, wxSize(700, 600));
543 m_printing
->SetParentWindow(frame
);
545 // and show it (the frames, unlike simple controls, are not shown when
546 // created initially)
549 // success: wxApp::OnRun() will be called which will enter the main message
550 // loop and the application will run. If we returned false here, the
551 // application would exit immediately.
563 void MyApp::CreateStyles()
567 wxFont
romanFont(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
568 wxFont
swissFont(12, wxSWISS
, wxNORMAL
, wxNORMAL
);
570 wxRichTextParagraphStyleDefinition
* normalPara
= new wxRichTextParagraphStyleDefinition(wxT("Normal"));
571 wxRichTextAttr normalAttr
;
572 normalAttr
.SetFontFaceName(romanFont
.GetFaceName());
573 normalAttr
.SetFontSize(12);
574 // Let's set all attributes for this style
575 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
|
576 wxTEXT_ATTR_PARA_SPACING_BEFORE
|wxTEXT_ATTR_PARA_SPACING_AFTER
|wxTEXT_ATTR_LINE_SPACING
|
577 wxTEXT_ATTR_BULLET_STYLE
|wxTEXT_ATTR_BULLET_NUMBER
);
578 normalPara
->SetStyle(normalAttr
);
580 m_styleSheet
->AddParagraphStyle(normalPara
);
582 wxRichTextParagraphStyleDefinition
* indentedPara
= new wxRichTextParagraphStyleDefinition(wxT("Indented"));
583 wxRichTextAttr indentedAttr
;
584 indentedAttr
.SetFontFaceName(romanFont
.GetFaceName());
585 indentedAttr
.SetFontSize(12);
586 indentedAttr
.SetLeftIndent(100, 0);
587 // We only want to affect indentation
588 indentedAttr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
);
589 indentedPara
->SetStyle(indentedAttr
);
591 m_styleSheet
->AddParagraphStyle(indentedPara
);
593 wxRichTextParagraphStyleDefinition
* indentedPara2
= new wxRichTextParagraphStyleDefinition(wxT("Red Bold Indented"));
594 wxRichTextAttr indentedAttr2
;
595 indentedAttr2
.SetFontFaceName(romanFont
.GetFaceName());
596 indentedAttr2
.SetFontSize(12);
597 indentedAttr2
.SetFontWeight(wxFONTWEIGHT_BOLD
);
598 indentedAttr2
.SetTextColour(*wxRED
);
599 indentedAttr2
.SetFontSize(12);
600 indentedAttr2
.SetLeftIndent(100, 0);
601 // We want to affect indentation, font and text colour
602 indentedAttr2
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
|wxTEXT_ATTR_FONT
|wxTEXT_ATTR_TEXT_COLOUR
);
603 indentedPara2
->SetStyle(indentedAttr2
);
605 m_styleSheet
->AddParagraphStyle(indentedPara2
);
607 wxRichTextParagraphStyleDefinition
* flIndentedPara
= new wxRichTextParagraphStyleDefinition(wxT("First Line Indented"));
608 wxRichTextAttr flIndentedAttr
;
609 flIndentedAttr
.SetFontFaceName(swissFont
.GetFaceName());
610 flIndentedAttr
.SetFontSize(12);
611 flIndentedAttr
.SetLeftIndent(100, -100);
612 // We only want to affect indentation
613 flIndentedAttr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
|wxTEXT_ATTR_RIGHT_INDENT
);
614 flIndentedPara
->SetStyle(flIndentedAttr
);
616 m_styleSheet
->AddParagraphStyle(flIndentedPara
);
620 wxRichTextCharacterStyleDefinition
* boldDef
= new wxRichTextCharacterStyleDefinition(wxT("Bold"));
621 wxRichTextAttr boldAttr
;
622 boldAttr
.SetFontFaceName(romanFont
.GetFaceName());
623 boldAttr
.SetFontSize(12);
624 boldAttr
.SetFontWeight(wxFONTWEIGHT_BOLD
);
625 // We only want to affect boldness
626 boldAttr
.SetFlags(wxTEXT_ATTR_FONT_WEIGHT
);
627 boldDef
->SetStyle(boldAttr
);
629 m_styleSheet
->AddCharacterStyle(boldDef
);
631 wxRichTextCharacterStyleDefinition
* italicDef
= new wxRichTextCharacterStyleDefinition(wxT("Italic"));
632 wxRichTextAttr italicAttr
;
633 italicAttr
.SetFontFaceName(romanFont
.GetFaceName());
634 italicAttr
.SetFontSize(12);
635 italicAttr
.SetFontStyle(wxFONTSTYLE_ITALIC
);
636 // We only want to affect italics
637 italicAttr
.SetFlags(wxTEXT_ATTR_FONT_ITALIC
);
638 italicDef
->SetStyle(italicAttr
);
640 m_styleSheet
->AddCharacterStyle(italicDef
);
642 wxRichTextCharacterStyleDefinition
* redDef
= new wxRichTextCharacterStyleDefinition(wxT("Red Bold"));
643 wxRichTextAttr redAttr
;
644 redAttr
.SetFontFaceName(romanFont
.GetFaceName());
645 redAttr
.SetFontSize(12);
646 redAttr
.SetFontWeight(wxFONTWEIGHT_BOLD
);
647 redAttr
.SetTextColour(*wxRED
);
648 // We only want to affect colour, weight and face
649 redAttr
.SetFlags(wxTEXT_ATTR_FONT_FACE
|wxTEXT_ATTR_FONT_WEIGHT
|wxTEXT_ATTR_TEXT_COLOUR
);
650 redDef
->SetStyle(redAttr
);
652 m_styleSheet
->AddCharacterStyle(redDef
);
654 wxRichTextListStyleDefinition
* bulletList
= new wxRichTextListStyleDefinition(wxT("Bullet List 1"));
656 for (i
= 0; i
< 10; i
++)
660 bulletText
= wxT("standard/circle");
662 bulletText
= wxT("standard/square");
664 bulletText
= wxT("standard/circle");
666 bulletText
= wxT("standard/square");
668 bulletText
= wxT("standard/circle");
670 bulletList
->SetAttributes(i
, (i
+1)*60, 60, wxTEXT_ATTR_BULLET_STYLE_STANDARD
, bulletText
);
673 m_styleSheet
->AddListStyle(bulletList
);
675 wxRichTextListStyleDefinition
* numberedList
= new wxRichTextListStyleDefinition(wxT("Numbered List 1"));
676 for (i
= 0; i
< 10; i
++)
680 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
682 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_LETTERS_LOWER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
684 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ROMAN_LOWER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
686 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ROMAN_UPPER
|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES
;
688 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
690 numberStyle
|= wxTEXT_ATTR_BULLET_STYLE_ALIGN_RIGHT
;
692 numberedList
->SetAttributes(i
, (i
+1)*60, 60, numberStyle
);
695 m_styleSheet
->AddListStyle(numberedList
);
697 wxRichTextListStyleDefinition
* outlineList
= new wxRichTextListStyleDefinition(wxT("Outline List 1"));
698 for (i
= 0; i
< 10; i
++)
702 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_OUTLINE
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
704 numberStyle
= wxTEXT_ATTR_BULLET_STYLE_ARABIC
|wxTEXT_ATTR_BULLET_STYLE_PERIOD
;
706 outlineList
->SetAttributes(i
, (i
+1)*120, 120, numberStyle
);
709 m_styleSheet
->AddListStyle(outlineList
);
712 // ----------------------------------------------------------------------------
714 // ----------------------------------------------------------------------------
717 MyFrame::MyFrame(const wxString
& title
, wxWindowID id
, const wxPoint
& pos
,
718 const wxSize
& size
, long style
)
719 : wxFrame(NULL
, id
, title
, pos
, size
, style
)
722 SetWindowVariant(wxWINDOW_VARIANT_SMALL
);
725 // set the frame icon
726 SetIcon(wxICON(sample
));
729 wxMenu
*fileMenu
= new wxMenu
;
731 // the "About" item should be in the help menu
732 wxMenu
*helpMenu
= new wxMenu
;
733 helpMenu
->Append(ID_About
, wxT("&About\tF1"), wxT("Show about dialog"));
735 fileMenu
->Append(wxID_OPEN
, wxT("&Open\tCtrl+O"), wxT("Open a file"));
736 fileMenu
->Append(wxID_SAVE
, wxT("&Save\tCtrl+S"), wxT("Save a file"));
737 fileMenu
->Append(wxID_SAVEAS
, wxT("&Save As...\tF12"), wxT("Save to a new file"));
738 fileMenu
->AppendSeparator();
739 fileMenu
->Append(ID_RELOAD
, wxT("&Reload Text\tF2"), wxT("Reload the initial text"));
740 fileMenu
->AppendSeparator();
741 fileMenu
->Append(ID_PAGE_SETUP
, wxT("Page Set&up..."), wxT("Page setup"));
742 fileMenu
->Append(ID_PRINT
, wxT("&Print...\tCtrl+P"), wxT("Print"));
743 fileMenu
->Append(ID_PREVIEW
, wxT("Print Pre&view"), wxT("Print preview"));
744 fileMenu
->AppendSeparator();
745 fileMenu
->Append(ID_VIEW_HTML
, wxT("&View as HTML"), wxT("View HTML"));
746 fileMenu
->AppendSeparator();
747 fileMenu
->Append(ID_Quit
, wxT("E&xit\tAlt+X"), wxT("Quit this program"));
749 wxMenu
* editMenu
= new wxMenu
;
750 editMenu
->Append(wxID_UNDO
, _("&Undo\tCtrl+Z"));
751 editMenu
->Append(wxID_REDO
, _("&Redo\tCtrl+Y"));
752 editMenu
->AppendSeparator();
753 editMenu
->Append(wxID_CUT
, _("Cu&t\tCtrl+X"));
754 editMenu
->Append(wxID_COPY
, _("&Copy\tCtrl+C"));
755 editMenu
->Append(wxID_PASTE
, _("&Paste\tCtrl+V"));
757 editMenu
->AppendSeparator();
758 editMenu
->Append(wxID_SELECTALL
, _("Select A&ll\tCtrl+A"));
759 editMenu
->AppendSeparator();
760 editMenu
->Append(ID_SET_FONT_SCALE
, _("Set &Text Scale..."));
761 editMenu
->Append(ID_SET_DIMENSION_SCALE
, _("Set &Dimension Scale..."));
763 wxMenu
* formatMenu
= new wxMenu
;
764 formatMenu
->AppendCheckItem(ID_FORMAT_BOLD
, _("&Bold\tCtrl+B"));
765 formatMenu
->AppendCheckItem(ID_FORMAT_ITALIC
, _("&Italic\tCtrl+I"));
766 formatMenu
->AppendCheckItem(ID_FORMAT_UNDERLINE
, _("&Underline\tCtrl+U"));
767 formatMenu
->AppendSeparator();
768 formatMenu
->AppendCheckItem(ID_FORMAT_STRIKETHROUGH
, _("Stri&kethrough"));
769 formatMenu
->AppendCheckItem(ID_FORMAT_SUPERSCRIPT
, _("Superscrip&t"));
770 formatMenu
->AppendCheckItem(ID_FORMAT_SUBSCRIPT
, _("Subscrip&t"));
771 formatMenu
->AppendSeparator();
772 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_LEFT
, _("L&eft Align"));
773 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_RIGHT
, _("&Right Align"));
774 formatMenu
->AppendCheckItem(ID_FORMAT_ALIGN_CENTRE
, _("&Centre"));
775 formatMenu
->AppendSeparator();
776 formatMenu
->Append(ID_FORMAT_INDENT_MORE
, _("Indent &More"));
777 formatMenu
->Append(ID_FORMAT_INDENT_LESS
, _("Indent &Less"));
778 formatMenu
->AppendSeparator();
779 formatMenu
->Append(ID_FORMAT_PARAGRAPH_SPACING_MORE
, _("Increase Paragraph &Spacing"));
780 formatMenu
->Append(ID_FORMAT_PARAGRAPH_SPACING_LESS
, _("Decrease &Paragraph Spacing"));
781 formatMenu
->AppendSeparator();
782 formatMenu
->Append(ID_FORMAT_LINE_SPACING_SINGLE
, _("Normal Line Spacing"));
783 formatMenu
->Append(ID_FORMAT_LINE_SPACING_HALF
, _("1.5 Line Spacing"));
784 formatMenu
->Append(ID_FORMAT_LINE_SPACING_DOUBLE
, _("Double Line Spacing"));
785 formatMenu
->AppendSeparator();
786 formatMenu
->Append(ID_FORMAT_FONT
, _("&Font..."));
787 formatMenu
->Append(ID_FORMAT_IMAGE
, _("Image Property"));
788 formatMenu
->Append(ID_FORMAT_PARAGRAPH
, _("&Paragraph..."));
789 formatMenu
->Append(ID_FORMAT_CONTENT
, _("Font and Pa&ragraph...\tShift+Ctrl+F"));
790 formatMenu
->AppendSeparator();
791 formatMenu
->Append(ID_SWITCH_STYLE_SHEETS
, _("&Switch Style Sheets"));
792 formatMenu
->Append(ID_MANAGE_STYLES
, _("&Manage Styles"));
794 wxMenu
* listsMenu
= new wxMenu
;
795 listsMenu
->Append(ID_FORMAT_BULLETS_AND_NUMBERING
, _("Bullets and &Numbering..."));
796 listsMenu
->AppendSeparator();
797 listsMenu
->Append(ID_FORMAT_NUMBER_LIST
, _("Number List"));
798 listsMenu
->Append(ID_FORMAT_ITEMIZE_LIST
, _("Itemize List"));
799 listsMenu
->Append(ID_FORMAT_RENUMBER_LIST
, _("Renumber List"));
800 listsMenu
->Append(ID_FORMAT_PROMOTE_LIST
, _("Promote List Items"));
801 listsMenu
->Append(ID_FORMAT_DEMOTE_LIST
, _("Demote List Items"));
802 listsMenu
->Append(ID_FORMAT_CLEAR_LIST
, _("Clear List Formatting"));
804 wxMenu
* insertMenu
= new wxMenu
;
805 insertMenu
->Append(ID_INSERT_SYMBOL
, _("&Symbol...\tCtrl+I"));
806 insertMenu
->Append(ID_INSERT_URL
, _("&URL..."));
807 insertMenu
->Append(ID_INSERT_IMAGE
, _("&Image..."));
809 // now append the freshly created menu to the menu bar...
810 wxMenuBar
*menuBar
= new wxMenuBar();
811 menuBar
->Append(fileMenu
, wxT("&File"));
812 menuBar
->Append(editMenu
, wxT("&Edit"));
813 menuBar
->Append(formatMenu
, wxT("F&ormat"));
814 menuBar
->Append(listsMenu
, wxT("&Lists"));
815 menuBar
->Append(insertMenu
, wxT("&Insert"));
816 menuBar
->Append(helpMenu
, wxT("&Help"));
818 // ... and attach this menu bar to the frame
821 // create a status bar just for fun (by default with 1 pane only)
822 // but don't create it on limited screen space (WinCE)
823 bool is_pda
= wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA
;
829 SetStatusText(wxT("Welcome to wxRichTextCtrl!"));
833 wxBoxSizer
* sizer
= new wxBoxSizer(wxVERTICAL
);
836 // On Mac, don't create a 'native' wxToolBar because small bitmaps are not supported by native
837 // toolbars. On Mac, a non-native, small-bitmap toolbar doesn't show unless it is explicitly
838 // managed, hence the use of sizers. In a real application, use larger icons for the main
839 // toolbar to avoid the need for this workaround. Or, use the toolbar in a container window
840 // as part of a more complex hierarchy, and the toolbar will automatically be non-native.
842 wxSystemOptions::SetOption(wxT("mac.toolbar.no-native"), 1);
844 wxToolBar
* toolBar
= new wxToolBar(this, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
,
845 wxNO_BORDER
|wxTB_FLAT
|wxTB_NODIVIDER
|wxTB_NOALIGN
);
847 sizer
->Add(toolBar
, 0, wxEXPAND
);
849 toolBar
->AddTool(wxID_OPEN
, wxEmptyString
, wxBitmap(open_xpm
), _("Open"));
850 toolBar
->AddTool(wxID_SAVEAS
, wxEmptyString
, wxBitmap(save_xpm
), _("Save"));
851 toolBar
->AddSeparator();
852 toolBar
->AddTool(wxID_CUT
, wxEmptyString
, wxBitmap(cut_xpm
), _("Cut"));
853 toolBar
->AddTool(wxID_COPY
, wxEmptyString
, wxBitmap(copy_xpm
), _("Copy"));
854 toolBar
->AddTool(wxID_PASTE
, wxEmptyString
, wxBitmap(paste_xpm
), _("Paste"));
855 toolBar
->AddSeparator();
856 toolBar
->AddTool(wxID_UNDO
, wxEmptyString
, wxBitmap(undo_xpm
), _("Undo"));
857 toolBar
->AddTool(wxID_REDO
, wxEmptyString
, wxBitmap(redo_xpm
), _("Redo"));
858 toolBar
->AddSeparator();
859 toolBar
->AddCheckTool(ID_FORMAT_BOLD
, wxEmptyString
, wxBitmap(bold_xpm
), wxNullBitmap
, _("Bold"));
860 toolBar
->AddCheckTool(ID_FORMAT_ITALIC
, wxEmptyString
, wxBitmap(italic_xpm
), wxNullBitmap
, _("Italic"));
861 toolBar
->AddCheckTool(ID_FORMAT_UNDERLINE
, wxEmptyString
, wxBitmap(underline_xpm
), wxNullBitmap
, _("Underline"));
862 toolBar
->AddSeparator();
863 toolBar
->AddCheckTool(ID_FORMAT_ALIGN_LEFT
, wxEmptyString
, wxBitmap(alignleft_xpm
), wxNullBitmap
, _("Align Left"));
864 toolBar
->AddCheckTool(ID_FORMAT_ALIGN_CENTRE
, wxEmptyString
, wxBitmap(centre_xpm
), wxNullBitmap
, _("Centre"));
865 toolBar
->AddCheckTool(ID_FORMAT_ALIGN_RIGHT
, wxEmptyString
, wxBitmap(alignright_xpm
), wxNullBitmap
, _("Align Right"));
866 toolBar
->AddSeparator();
867 toolBar
->AddTool(ID_FORMAT_INDENT_LESS
, wxEmptyString
, wxBitmap(indentless_xpm
), _("Indent Less"));
868 toolBar
->AddTool(ID_FORMAT_INDENT_MORE
, wxEmptyString
, wxBitmap(indentmore_xpm
), _("Indent More"));
869 toolBar
->AddSeparator();
870 toolBar
->AddTool(ID_FORMAT_FONT
, wxEmptyString
, wxBitmap(font_xpm
), _("Font"));
871 toolBar
->AddSeparator();
873 wxRichTextStyleComboCtrl
* combo
= new wxRichTextStyleComboCtrl(toolBar
, ID_RICHTEXT_STYLE_COMBO
, wxDefaultPosition
, wxSize(160, -1), wxCB_READONLY
);
874 toolBar
->AddControl(combo
);
878 wxSplitterWindow
* splitter
= new wxSplitterWindow(this, wxID_ANY
, wxDefaultPosition
, wxSize(100,100), wxSP_LIVE_UPDATE
);
879 sizer
->Add(splitter
, 1, wxEXPAND
);
881 wxFont textFont
= wxFont(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
882 wxFont boldFont
= wxFont(12, wxROMAN
, wxNORMAL
, wxBOLD
);
883 wxFont italicFont
= wxFont(12, wxROMAN
, wxITALIC
, wxNORMAL
);
885 m_richTextCtrl
= new MyRichTextCtrl(splitter
, ID_RICHTEXT_CTRL
, wxEmptyString
, wxDefaultPosition
, wxSize(200, 200), wxVSCROLL
|wxHSCROLL
|wxWANTS_CHARS
);
886 wxASSERT(!m_richTextCtrl
->GetBuffer().GetAttributes().HasFontPixelSize());
888 wxFont
font(12, wxROMAN
, wxNORMAL
, wxNORMAL
);
890 m_richTextCtrl
->SetFont(font
);
892 wxASSERT(!m_richTextCtrl
->GetBuffer().GetAttributes().HasFontPixelSize());
894 m_richTextCtrl
->SetMargins(10, 10);
896 m_richTextCtrl
->SetStyleSheet(wxGetApp().GetStyleSheet());
898 combo
->SetStyleSheet(wxGetApp().GetStyleSheet());
899 combo
->SetRichTextCtrl(m_richTextCtrl
);
900 combo
->UpdateStyles();
902 wxRichTextStyleListCtrl
* styleListCtrl
= new wxRichTextStyleListCtrl(splitter
, ID_RICHTEXT_STYLE_LIST
);
904 wxSize display
= wxGetDisplaySize();
905 if ( is_pda
&& ( display
.GetWidth() < display
.GetHeight() ) )
907 splitter
->SplitHorizontally(m_richTextCtrl
, styleListCtrl
);
911 splitter
->SplitVertically(m_richTextCtrl
, styleListCtrl
, 500);
916 splitter
->UpdateSize();
918 styleListCtrl
->SetStyleSheet(wxGetApp().GetStyleSheet());
919 styleListCtrl
->SetRichTextCtrl(m_richTextCtrl
);
920 styleListCtrl
->UpdateStyles();
926 void MyFrame::WriteInitialText()
928 MyRichTextCtrl
& r
= *m_richTextCtrl
;
930 r
.SetDefaultStyle(wxRichTextAttr());
934 r
.BeginSuppressUndo();
936 r
.BeginParagraphSpacing(0, 20);
938 r
.BeginAlignment(wxTEXT_ALIGNMENT_CENTRE
);
943 wxString lineBreak
= (wxChar
) 29;
945 r
.WriteText(wxString(wxT("Welcome to wxRichTextCtrl, a wxWidgets control")) + lineBreak
+ wxT("for editing and presenting styled text and images\n"));
949 r
.WriteText(wxT("by Julian Smart"));
955 r
.WriteImage(wxBitmap(zebra_xpm
));
963 r
.BeginAlignment(wxTEXT_ALIGNMENT_CENTRE
);
964 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.")));
969 r
.BeginAlignment(wxTEXT_ALIGNMENT_LEFT
);
970 wxRichTextAttr imageAttr
;
971 imageAttr
.GetTextBoxAttr().SetFloatMode(wxTEXT_BOX_ATTR_FLOAT_LEFT
);
972 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
.WriteImage(wxBitmap(zebra_xpm
), wxBITMAP_TYPE_PNG
, imageAttr
);
975 imageAttr
.GetTextBoxAttr().GetTop().SetValue(200);
976 imageAttr
.GetTextBoxAttr().GetTop().SetUnits(wxTEXT_ATTR_UNITS_PIXELS
);
977 imageAttr
.GetTextBoxAttr().SetFloatMode(wxTEXT_BOX_ATTR_FLOAT_RIGHT
);
978 r
.WriteImage(wxBitmap(zebra_xpm
), wxBITMAP_TYPE_PNG
, imageAttr
);
979 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.")));
983 r
.WriteText(wxT("What can you do with this thing? "));
985 r
.WriteImage(wxBitmap(smiley_xpm
));
986 r
.WriteText(wxT(" Well, you can change text "));
988 r
.BeginTextColour(*wxRED
);
989 r
.WriteText(wxT("colour, like this red bit."));
992 wxRichTextAttr backgroundColourAttr
;
993 backgroundColourAttr
.SetBackgroundColour(*wxGREEN
);
994 backgroundColourAttr
.SetTextColour(*wxBLUE
);
995 r
.BeginStyle(backgroundColourAttr
);
996 r
.WriteText(wxT(" And this blue on green bit."));
999 r
.WriteText(wxT(" Naturally you can make things "));
1001 r
.WriteText(wxT("bold "));
1004 r
.WriteText(wxT("or italic "));
1007 r
.WriteText(wxT("or underlined."));
1010 r
.BeginFontSize(14);
1011 r
.WriteText(wxT(" Different font sizes on the same line is allowed, too."));
1014 r
.WriteText(wxT(" Next we'll show an indented paragraph."));
1018 r
.BeginLeftIndent(60);
1019 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."));
1024 r
.WriteText(wxT("Next, we'll show a first-line indent, achieved using BeginLeftIndent(100, -40)."));
1028 r
.BeginLeftIndent(100, -40);
1030 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."));
1035 r
.WriteText(wxT("Numbered bullets are possible, again using subindents:"));
1038 r
.BeginNumberedBullet(1, 100, 60);
1039 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."));
1041 r
.EndNumberedBullet();
1043 r
.BeginNumberedBullet(2, 100, 60);
1044 r
.WriteText(wxT("This is my second item."));
1046 r
.EndNumberedBullet();
1048 r
.WriteText(wxT("The following paragraph is right-indented:"));
1051 r
.BeginRightIndent(200);
1053 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."));
1058 r
.WriteText(wxT("The following paragraph is right-aligned with 1.5 line spacing:"));
1061 r
.BeginAlignment(wxTEXT_ALIGNMENT_RIGHT
);
1062 r
.BeginLineSpacing(wxTEXT_ATTR_LINE_SPACING_HALF
);
1063 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."));
1073 wxRichTextAttr attr
;
1074 attr
.SetFlags(wxTEXT_ATTR_TABS
);
1076 r
.SetDefaultStyle(attr
);
1078 r
.WriteText(wxT("This line contains tabs:\tFirst tab\tSecond tab\tThird tab"));
1081 r
.WriteText(wxT("Other notable features of wxRichTextCtrl include:"));
1084 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1085 r
.WriteText(wxT("Compatibility with wxTextCtrl API"));
1087 r
.EndSymbolBullet();
1089 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1090 r
.WriteText(wxT("Easy stack-based BeginXXX()...EndXXX() style setting in addition to SetStyle()"));
1092 r
.EndSymbolBullet();
1094 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1095 r
.WriteText(wxT("XML loading and saving"));
1097 r
.EndSymbolBullet();
1099 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1100 r
.WriteText(wxT("Undo/Redo, with batching option and Undo suppressing"));
1102 r
.EndSymbolBullet();
1104 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1105 r
.WriteText(wxT("Clipboard copy and paste"));
1107 r
.EndSymbolBullet();
1109 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1110 r
.WriteText(wxT("wxRichTextStyleSheet with named character and paragraph styles, and control for applying named styles"));
1112 r
.EndSymbolBullet();
1114 r
.BeginSymbolBullet(wxT('*'), 100, 60);
1115 r
.WriteText(wxT("A design that can easily be extended to other content types, ultimately with text boxes, tables, controls, and so on"));
1117 r
.EndSymbolBullet();
1119 // Make a style suitable for showing a URL
1120 wxRichTextAttr urlStyle
;
1121 urlStyle
.SetTextColour(*wxBLUE
);
1122 urlStyle
.SetFontUnderlined(true);
1124 r
.WriteText(wxT("wxRichTextCtrl can also display URLs, such as this one: "));
1125 r
.BeginStyle(urlStyle
);
1126 r
.BeginURL(wxT("http://www.wxwidgets.org"));
1127 r
.WriteText(wxT("The wxWidgets Web Site"));
1130 r
.WriteText(wxT(". Click on the URL to generate an event."));
1134 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"));
1136 r
.EndParagraphSpacing();
1144 wxRichTextAttr attr
;
1145 attr
.GetTextBoxAttr().GetMargins().GetLeft().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS
);
1146 attr
.GetTextBoxAttr().GetMargins().GetTop().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS
);
1147 attr
.GetTextBoxAttr().GetMargins().GetRight().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS
);
1148 attr
.GetTextBoxAttr().GetMargins().GetBottom().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS
);
1150 attr
.GetTextBoxAttr().GetBorder().SetColour(*wxBLACK
);
1151 attr
.GetTextBoxAttr().GetBorder().SetWidth(1, wxTEXT_ATTR_UNITS_PIXELS
);
1152 attr
.GetTextBoxAttr().GetBorder().SetStyle(wxTEXT_BOX_ATTR_BORDER_SOLID
);
1154 wxRichTextBox
* textBox
= r
.WriteTextBox(attr
);
1155 r
.SetFocusObject(textBox
);
1157 r
.WriteText(wxT("This is a text box. Just testing! Once more unto the breach, dear friends, once more..."));
1159 r
.SetFocusObject(NULL
); // Set the focus back to the main buffer
1160 r
.SetInsertionPointEnd();
1169 wxRichTextAttr attr
;
1170 attr
.GetTextBoxAttr().GetMargins().GetLeft().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS
);
1171 attr
.GetTextBoxAttr().GetMargins().GetTop().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS
);
1172 attr
.GetTextBoxAttr().GetMargins().GetRight().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS
);
1173 attr
.GetTextBoxAttr().GetMargins().GetBottom().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS
);
1174 attr
.GetTextBoxAttr().GetPadding() = attr
.GetTextBoxAttr().GetMargins();
1176 attr
.GetTextBoxAttr().GetBorder().SetColour(*wxBLACK
);
1177 attr
.GetTextBoxAttr().GetBorder().SetWidth(1, wxTEXT_ATTR_UNITS_PIXELS
);
1178 attr
.GetTextBoxAttr().GetBorder().SetStyle(wxTEXT_BOX_ATTR_BORDER_SOLID
);
1180 wxRichTextAttr cellAttr
= attr
;
1181 cellAttr
.GetTextBoxAttr().GetWidth().SetValue(200, wxTEXT_ATTR_UNITS_PIXELS
);
1182 cellAttr
.GetTextBoxAttr().GetHeight().SetValue(150, wxTEXT_ATTR_UNITS_PIXELS
);
1184 //wxRichTextTable* table = r.WriteTable(3, 2, attr, cellAttr);
1185 wxRichTextTable
* table
= r
.WriteTable(24, 2, attr
, cellAttr
);
1187 for (j
= 0; j
< table
->GetRowCount(); j
++)
1189 for (i
= 0; i
< table
->GetColumnCount(); i
++)
1191 wxString msg
= wxString::Format(wxT("This is cell %d, %d"), (j
+1), (i
+1));
1192 r
.SetFocusObject(table
->GetCell(j
, i
));
1196 r
.SetFocusObject(NULL
); // Set the focus back to the main buffer
1197 r
.SetInsertionPointEnd();
1203 wxRichTextProperties properties
;
1204 r
.WriteText(wxT("This is a rectangle field: "));
1205 r
.WriteField(wxT("rectangle"), properties
);
1206 r
.WriteText(wxT(" and a begin section field: "));
1207 r
.WriteField(wxT("begin-section"), properties
);
1208 r
.WriteText(wxT("This is text between the two tags."));
1209 r
.WriteField(wxT("end-section"), properties
);
1210 r
.WriteText(wxT(" Now a bitmap. "));
1211 r
.WriteField(wxT("bitmap"), properties
);
1212 r
.WriteText(wxT(" Before we go, here's a composite field: ***"));
1213 wxRichTextField
* field
= r
.WriteField(wxT("composite"), properties
);
1214 field
->UpdateField(& r
.GetBuffer()); // Creates the composite value (sort of a text box)
1215 r
.WriteText(wxT("*** End of composite field."));
1218 r
.EndSuppressUndo();
1220 // Add some locked content first - needs Undo to be enabled
1223 r
.WriteText(wxString(wxT("This is a locked object.")));
1226 r
.WriteText(wxString(wxT(" This is unlocked text. ")));
1229 r
.WriteText(wxString(wxT("More locked content.")));
1233 // Flush the Undo buffer
1234 r
.GetCommandProcessor()->ClearCommands();
1242 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
1244 // true is to force the frame to close
1248 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
1251 msg
.Printf( wxT("This is a demo for wxRichTextCtrl, a control for editing styled text.\n(c) Julian Smart, 2005"));
1252 wxMessageBox(msg
, wxT("About wxRichTextCtrl Sample"), wxOK
| wxICON_INFORMATION
, this);
1255 // Forward command events to the current rich text control, if any
1256 bool MyFrame::ProcessEvent(wxEvent
& event
)
1258 if (event
.IsCommandEvent() && !event
.IsKindOf(CLASSINFO(wxChildFocusEvent
)))
1260 // Problem: we can get infinite recursion because the events
1261 // climb back up to this frame, and repeat.
1262 // Assume that command events don't cause another command event
1263 // to be called, so we can rely on inCommand not being overwritten
1265 static int s_eventType
= 0;
1266 static wxWindowID s_id
= 0;
1268 if (s_id
!= event
.GetId() && s_eventType
!= event
.GetEventType())
1270 s_eventType
= event
.GetEventType();
1271 s_id
= event
.GetId();
1273 wxWindow
* focusWin
= wxFindFocusDescendant(this);
1274 if (focusWin
&& focusWin
->GetEventHandler()->ProcessEvent(event
))
1291 return wxFrame::ProcessEvent(event
);
1294 void MyFrame::OnOpen(wxCommandEvent
& WXUNUSED(event
))
1298 wxArrayInt fileTypes
;
1300 wxString filter
= wxRichTextBuffer::GetExtWildcard(false, false, & fileTypes
);
1301 if (!filter
.empty())
1303 filter
+= wxT("All files (*.*)|*.*");
1305 wxFileDialog
dialog(this,
1306 _("Choose a filename"),
1312 if (dialog
.ShowModal() == wxID_OK
)
1314 wxString path
= dialog
.GetPath();
1318 int filterIndex
= dialog
.GetFilterIndex();
1319 int fileType
= (filterIndex
< (int) fileTypes
.GetCount())
1320 ? fileTypes
[filterIndex
]
1321 : wxRICHTEXT_TYPE_TEXT
;
1322 m_richTextCtrl
->LoadFile(path
, fileType
);
1327 void MyFrame::OnSave(wxCommandEvent
& event
)
1329 if (m_richTextCtrl
->GetFilename().empty())
1334 m_richTextCtrl
->SaveFile();
1337 void MyFrame::OnSaveAs(wxCommandEvent
& WXUNUSED(event
))
1339 wxString filter
= wxRichTextBuffer::GetExtWildcard(false, true);
1343 wxFileDialog
dialog(this,
1344 _("Choose a filename"),
1350 if (dialog
.ShowModal() == wxID_OK
)
1352 wxString path
= dialog
.GetPath();
1357 wxStopWatch stopwatch
;
1359 m_richTextCtrl
->SaveFile(path
);
1361 long t
= stopwatch
.Time();
1362 wxLogDebug(wxT("Saving took %ldms"), t
);
1363 wxMessageBox(wxString::Format(wxT("Saving took %ldms"), t
));
1368 void MyFrame::OnBold(wxCommandEvent
& WXUNUSED(event
))
1370 m_richTextCtrl
->ApplyBoldToSelection();
1373 void MyFrame::OnItalic(wxCommandEvent
& WXUNUSED(event
))
1375 m_richTextCtrl
->ApplyItalicToSelection();
1378 void MyFrame::OnUnderline(wxCommandEvent
& WXUNUSED(event
))
1380 m_richTextCtrl
->ApplyUnderlineToSelection();
1383 void MyFrame::OnStrikethrough(wxCommandEvent
& WXUNUSED(event
))
1385 m_richTextCtrl
->ApplyTextEffectToSelection(wxTEXT_ATTR_EFFECT_STRIKETHROUGH
);
1388 void MyFrame::OnSuperscript(wxCommandEvent
& WXUNUSED(event
))
1390 m_richTextCtrl
->ApplyTextEffectToSelection(wxTEXT_ATTR_EFFECT_SUPERSCRIPT
);
1393 void MyFrame::OnSubscript(wxCommandEvent
& WXUNUSED(event
))
1395 m_richTextCtrl
->ApplyTextEffectToSelection(wxTEXT_ATTR_EFFECT_SUBSCRIPT
);
1399 void MyFrame::OnUpdateBold(wxUpdateUIEvent
& event
)
1401 event
.Check(m_richTextCtrl
->IsSelectionBold());
1404 void MyFrame::OnUpdateItalic(wxUpdateUIEvent
& event
)
1406 event
.Check(m_richTextCtrl
->IsSelectionItalics());
1409 void MyFrame::OnUpdateUnderline(wxUpdateUIEvent
& event
)
1411 event
.Check(m_richTextCtrl
->IsSelectionUnderlined());
1414 void MyFrame::OnUpdateStrikethrough(wxUpdateUIEvent
& event
)
1416 event
.Check(m_richTextCtrl
->DoesSelectionHaveTextEffectFlag(wxTEXT_ATTR_EFFECT_STRIKETHROUGH
));
1419 void MyFrame::OnUpdateSuperscript(wxUpdateUIEvent
& event
)
1421 event
.Check(m_richTextCtrl
->DoesSelectionHaveTextEffectFlag(wxTEXT_ATTR_EFFECT_SUPERSCRIPT
));
1424 void MyFrame::OnUpdateSubscript(wxUpdateUIEvent
& event
)
1426 event
.Check(m_richTextCtrl
->DoesSelectionHaveTextEffectFlag(wxTEXT_ATTR_EFFECT_SUBSCRIPT
));
1429 void MyFrame::OnAlignLeft(wxCommandEvent
& WXUNUSED(event
))
1431 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_LEFT
);
1434 void MyFrame::OnAlignCentre(wxCommandEvent
& WXUNUSED(event
))
1436 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_CENTRE
);
1439 void MyFrame::OnAlignRight(wxCommandEvent
& WXUNUSED(event
))
1441 m_richTextCtrl
->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_RIGHT
);
1444 void MyFrame::OnUpdateAlignLeft(wxUpdateUIEvent
& event
)
1446 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_LEFT
));
1449 void MyFrame::OnUpdateAlignCentre(wxUpdateUIEvent
& event
)
1451 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_CENTRE
));
1454 void MyFrame::OnUpdateAlignRight(wxUpdateUIEvent
& event
)
1456 event
.Check(m_richTextCtrl
->IsSelectionAligned(wxTEXT_ALIGNMENT_RIGHT
));
1459 void MyFrame::OnFont(wxCommandEvent
& WXUNUSED(event
))
1461 wxRichTextRange range
;
1462 if (m_richTextCtrl
->HasSelection())
1463 range
= m_richTextCtrl
->GetSelectionRange();
1465 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1467 int pages
= wxRICHTEXT_FORMAT_FONT
;
1469 wxRichTextFormattingDialog
formatDlg(pages
, this);
1470 formatDlg
.SetOptions(wxRichTextFormattingDialog::Option_AllowPixelFontSize
);
1471 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1473 if (formatDlg
.ShowModal() == wxID_OK
)
1475 formatDlg
.ApplyStyle(m_richTextCtrl
, range
, wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_OPTIMIZE
|wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY
);
1479 void MyFrame::OnImage(wxCommandEvent
& WXUNUSED(event
))
1481 wxRichTextRange range
;
1482 wxASSERT(m_richTextCtrl
->HasSelection());
1484 range
= m_richTextCtrl
->GetSelectionRange();
1485 wxASSERT(range
.ToInternal().GetLength() == 1);
1487 wxRichTextImage
* image
= wxDynamicCast(m_richTextCtrl
->GetFocusObject()->GetLeafObjectAtPosition(range
.GetStart()), wxRichTextImage
);
1490 wxRichTextObjectPropertiesDialog
imageDlg(image
, this);
1492 if (imageDlg
.ShowModal() == wxID_OK
)
1494 imageDlg
.ApplyStyle(m_richTextCtrl
);
1499 void MyFrame::OnParagraph(wxCommandEvent
& WXUNUSED(event
))
1501 wxRichTextRange range
;
1502 if (m_richTextCtrl
->HasSelection())
1503 range
= m_richTextCtrl
->GetSelectionRange();
1505 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1507 int pages
= wxRICHTEXT_FORMAT_INDENTS_SPACING
|wxRICHTEXT_FORMAT_TABS
|wxRICHTEXT_FORMAT_BULLETS
;
1509 wxRichTextFormattingDialog
formatDlg(pages
, this);
1510 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1512 if (formatDlg
.ShowModal() == wxID_OK
)
1514 formatDlg
.ApplyStyle(m_richTextCtrl
, range
);
1518 void MyFrame::OnFormat(wxCommandEvent
& WXUNUSED(event
))
1520 wxRichTextRange range
;
1521 if (m_richTextCtrl
->HasSelection())
1522 range
= m_richTextCtrl
->GetSelectionRange();
1524 range
= wxRichTextRange(0, m_richTextCtrl
->GetLastPosition()+1);
1526 int pages
= wxRICHTEXT_FORMAT_FONT
|wxRICHTEXT_FORMAT_INDENTS_SPACING
|wxRICHTEXT_FORMAT_TABS
|wxRICHTEXT_FORMAT_BULLETS
;
1528 wxRichTextFormattingDialog
formatDlg(pages
, this);
1529 formatDlg
.GetStyle(m_richTextCtrl
, range
);
1531 if (formatDlg
.ShowModal() == wxID_OK
)
1533 formatDlg
.ApplyStyle(m_richTextCtrl
, range
);
1537 void MyFrame::OnUpdateFormat(wxUpdateUIEvent
& event
)
1539 event
.Enable(m_richTextCtrl
->HasSelection());
1542 void MyFrame::OnUpdateImage(wxUpdateUIEvent
& event
)
1544 wxRichTextRange range
;
1545 wxRichTextObject
*obj
;
1547 range
= m_richTextCtrl
->GetSelectionRange();
1548 if (range
.ToInternal().GetLength() == 1)
1550 obj
= m_richTextCtrl
->GetFocusObject()->GetLeafObjectAtPosition(range
.GetStart());
1551 if (obj
&& obj
->IsKindOf(CLASSINFO(wxRichTextImage
)))
1558 event
.Enable(false);
1561 void MyFrame::OnIndentMore(wxCommandEvent
& WXUNUSED(event
))
1563 wxRichTextAttr attr
;
1564 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1566 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1568 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1569 if (m_richTextCtrl
->HasSelection())
1570 range
= m_richTextCtrl
->GetSelectionRange();
1572 attr
.SetLeftIndent(attr
.GetLeftIndent() + 100);
1574 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1575 m_richTextCtrl
->SetStyle(range
, attr
);
1579 void MyFrame::OnIndentLess(wxCommandEvent
& WXUNUSED(event
))
1581 wxRichTextAttr attr
;
1582 attr
.SetFlags(wxTEXT_ATTR_LEFT_INDENT
);
1584 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1586 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1587 if (m_richTextCtrl
->HasSelection())
1588 range
= m_richTextCtrl
->GetSelectionRange();
1590 if (attr
.GetLeftIndent() > 0)
1592 attr
.SetLeftIndent(wxMax(0, attr
.GetLeftIndent() - 100));
1594 m_richTextCtrl
->SetStyle(range
, attr
);
1599 void MyFrame::OnLineSpacingHalf(wxCommandEvent
& WXUNUSED(event
))
1601 wxRichTextAttr attr
;
1602 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1604 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1606 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1607 if (m_richTextCtrl
->HasSelection())
1608 range
= m_richTextCtrl
->GetSelectionRange();
1610 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1611 attr
.SetLineSpacing(15);
1613 m_richTextCtrl
->SetStyle(range
, attr
);
1617 void MyFrame::OnLineSpacingDouble(wxCommandEvent
& WXUNUSED(event
))
1619 wxRichTextAttr attr
;
1620 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1622 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1624 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1625 if (m_richTextCtrl
->HasSelection())
1626 range
= m_richTextCtrl
->GetSelectionRange();
1628 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1629 attr
.SetLineSpacing(20);
1631 m_richTextCtrl
->SetStyle(range
, attr
);
1635 void MyFrame::OnLineSpacingSingle(wxCommandEvent
& WXUNUSED(event
))
1637 wxRichTextAttr attr
;
1638 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1640 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1642 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1643 if (m_richTextCtrl
->HasSelection())
1644 range
= m_richTextCtrl
->GetSelectionRange();
1646 attr
.SetFlags(wxTEXT_ATTR_LINE_SPACING
);
1647 attr
.SetLineSpacing(0); // Can also use 10
1649 m_richTextCtrl
->SetStyle(range
, attr
);
1653 void MyFrame::OnParagraphSpacingMore(wxCommandEvent
& WXUNUSED(event
))
1655 wxRichTextAttr attr
;
1656 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1658 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1660 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1661 if (m_richTextCtrl
->HasSelection())
1662 range
= m_richTextCtrl
->GetSelectionRange();
1664 attr
.SetParagraphSpacingAfter(attr
.GetParagraphSpacingAfter() + 20);
1666 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1667 m_richTextCtrl
->SetStyle(range
, attr
);
1671 void MyFrame::OnParagraphSpacingLess(wxCommandEvent
& WXUNUSED(event
))
1673 wxRichTextAttr attr
;
1674 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1676 if (m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
))
1678 wxRichTextRange
range(m_richTextCtrl
->GetInsertionPoint(), m_richTextCtrl
->GetInsertionPoint());
1679 if (m_richTextCtrl
->HasSelection())
1680 range
= m_richTextCtrl
->GetSelectionRange();
1682 if (attr
.GetParagraphSpacingAfter() >= 20)
1684 attr
.SetParagraphSpacingAfter(attr
.GetParagraphSpacingAfter() - 20);
1686 attr
.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER
);
1687 m_richTextCtrl
->SetStyle(range
, attr
);
1692 void MyFrame::OnReload(wxCommandEvent
& WXUNUSED(event
))
1694 m_richTextCtrl
->Clear();
1698 void MyFrame::OnViewHTML(wxCommandEvent
& WXUNUSED(event
))
1700 wxDialog
dialog(this, wxID_ANY
, _("HTML"), wxDefaultPosition
, wxSize(500, 400), wxDEFAULT_DIALOG_STYLE
);
1702 wxBoxSizer
* boxSizer
= new wxBoxSizer(wxVERTICAL
);
1703 dialog
.SetSizer(boxSizer
);
1705 wxHtmlWindow
* win
= new wxHtmlWindow(& dialog
, wxID_ANY
, wxDefaultPosition
, wxSize(500, 400), wxSUNKEN_BORDER
);
1706 boxSizer
->Add(win
, 1, wxALL
, 5);
1708 wxButton
* cancelButton
= new wxButton(& dialog
, wxID_CANCEL
, wxT("&Close"));
1709 boxSizer
->Add(cancelButton
, 0, wxALL
|wxCENTRE
, 5);
1712 wxStringOutputStream
strStream(& text
);
1714 wxRichTextHTMLHandler htmlHandler
;
1715 htmlHandler
.SetFlags(wxRICHTEXT_HANDLER_SAVE_IMAGES_TO_MEMORY
);
1717 wxArrayInt fontSizeMapping
;
1718 fontSizeMapping
.Add(7);
1719 fontSizeMapping
.Add(9);
1720 fontSizeMapping
.Add(11);
1721 fontSizeMapping
.Add(12);
1722 fontSizeMapping
.Add(14);
1723 fontSizeMapping
.Add(22);
1724 fontSizeMapping
.Add(100);
1726 htmlHandler
.SetFontSizeMapping(fontSizeMapping
);
1728 if (htmlHandler
.SaveFile(& m_richTextCtrl
->GetBuffer(), strStream
))
1733 boxSizer
->Fit(& dialog
);
1737 // Now delete the temporary in-memory images
1738 htmlHandler
.DeleteTemporaryImages();
1741 // Demonstrates how you can change the style sheets and have the changes
1742 // reflected in the control content without wiping out character formatting.
1744 void MyFrame::OnSwitchStyleSheets(wxCommandEvent
& WXUNUSED(event
))
1746 static wxRichTextStyleSheet
* gs_AlternateStyleSheet
= NULL
;
1748 wxRichTextStyleListCtrl
*styleList
= (wxRichTextStyleListCtrl
*) FindWindow(ID_RICHTEXT_STYLE_LIST
);
1749 wxRichTextStyleComboCtrl
* styleCombo
= (wxRichTextStyleComboCtrl
*) FindWindow(ID_RICHTEXT_STYLE_COMBO
);
1751 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1753 // One-time creation of an alternate style sheet
1754 if (!gs_AlternateStyleSheet
)
1756 gs_AlternateStyleSheet
= new wxRichTextStyleSheet(*sheet
);
1758 // Make some modifications
1759 for (int i
= 0; i
< (int) gs_AlternateStyleSheet
->GetParagraphStyleCount(); i
++)
1761 wxRichTextParagraphStyleDefinition
* def
= gs_AlternateStyleSheet
->GetParagraphStyle(i
);
1763 if (def
->GetStyle().HasTextColour())
1764 def
->GetStyle().SetTextColour(*wxBLUE
);
1766 if (def
->GetStyle().HasAlignment())
1768 if (def
->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_CENTRE
)
1769 def
->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_RIGHT
);
1770 else if (def
->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_LEFT
)
1771 def
->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_CENTRE
);
1773 if (def
->GetStyle().HasLeftIndent())
1775 def
->GetStyle().SetLeftIndent(def
->GetStyle().GetLeftIndent() * 2);
1781 wxRichTextStyleSheet
* tmp
= gs_AlternateStyleSheet
;
1782 gs_AlternateStyleSheet
= sheet
;
1785 m_richTextCtrl
->SetStyleSheet(sheet
);
1786 m_richTextCtrl
->ApplyStyleSheet(sheet
); // Makes the control reflect the new style definitions
1788 styleList
->SetStyleSheet(sheet
);
1789 styleList
->UpdateStyles();
1791 styleCombo
->SetStyleSheet(sheet
);
1792 styleCombo
->UpdateStyles();
1795 void MyFrame::OnManageStyles(wxCommandEvent
& WXUNUSED(event
))
1797 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1799 int flags
= wxRICHTEXT_ORGANISER_CREATE_STYLES
|wxRICHTEXT_ORGANISER_EDIT_STYLES
;
1801 wxRichTextStyleOrganiserDialog
dlg(flags
, sheet
, NULL
, this, wxID_ANY
, _("Style Manager"));
1805 void MyFrame::OnInsertSymbol(wxCommandEvent
& WXUNUSED(event
))
1807 wxRichTextAttr attr
;
1808 attr
.SetFlags(wxTEXT_ATTR_FONT
);
1809 m_richTextCtrl
->GetStyle(m_richTextCtrl
->GetInsertionPoint(), attr
);
1811 wxString currentFontName
;
1812 if (attr
.HasFont() && attr
.GetFont().IsOk())
1813 currentFontName
= attr
.GetFont().GetFaceName();
1815 // Don't set the initial font in the dialog (so the user is choosing
1816 // 'normal text', i.e. the current font) but do tell the dialog
1817 // what 'normal text' is.
1819 wxSymbolPickerDialog
dlg(wxT("*"), wxEmptyString
, currentFontName
, this);
1821 if (dlg
.ShowModal() == wxID_OK
)
1823 if (dlg
.HasSelection())
1825 long insertionPoint
= m_richTextCtrl
->GetInsertionPoint();
1827 m_richTextCtrl
->WriteText(dlg
.GetSymbol());
1829 if (!dlg
.UseNormalFont())
1831 wxFont
font(attr
.GetFont());
1832 font
.SetFaceName(dlg
.GetFontName());
1834 m_richTextCtrl
->SetStyle(insertionPoint
, insertionPoint
+1, attr
);
1840 void MyFrame::OnNumberList(wxCommandEvent
& WXUNUSED(event
))
1842 if (m_richTextCtrl
->HasSelection())
1844 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1845 m_richTextCtrl
->SetListStyle(range
, wxT("Numbered List 1"), wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_RENUMBER
);
1849 void MyFrame::OnBulletsAndNumbering(wxCommandEvent
& WXUNUSED(event
))
1851 wxRichTextStyleSheet
* sheet
= m_richTextCtrl
->GetStyleSheet();
1853 int flags
= wxRICHTEXT_ORGANISER_BROWSE_NUMBERING
;
1855 wxRichTextStyleOrganiserDialog
dlg(flags
, sheet
, m_richTextCtrl
, this, wxID_ANY
, _("Bullets and Numbering"));
1856 if (dlg
.ShowModal() == wxID_OK
)
1858 if (dlg
.GetSelectedStyleDefinition())
1863 void MyFrame::OnItemizeList(wxCommandEvent
& WXUNUSED(event
))
1865 if (m_richTextCtrl
->HasSelection())
1867 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1868 m_richTextCtrl
->SetListStyle(range
, wxT("Bullet List 1"));
1872 void MyFrame::OnRenumberList(wxCommandEvent
& WXUNUSED(event
))
1874 if (m_richTextCtrl
->HasSelection())
1876 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1877 m_richTextCtrl
->NumberList(range
, NULL
, wxRICHTEXT_SETSTYLE_WITH_UNDO
|wxRICHTEXT_SETSTYLE_RENUMBER
);
1881 void MyFrame::OnPromoteList(wxCommandEvent
& WXUNUSED(event
))
1883 if (m_richTextCtrl
->HasSelection())
1885 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1886 m_richTextCtrl
->PromoteList(1, range
, NULL
);
1890 void MyFrame::OnDemoteList(wxCommandEvent
& WXUNUSED(event
))
1892 if (m_richTextCtrl
->HasSelection())
1894 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1895 m_richTextCtrl
->PromoteList(-1, range
, NULL
);
1899 void MyFrame::OnClearList(wxCommandEvent
& WXUNUSED(event
))
1901 if (m_richTextCtrl
->HasSelection())
1903 wxRichTextRange range
= m_richTextCtrl
->GetSelectionRange();
1904 m_richTextCtrl
->ClearListStyle(range
);
1908 void MyFrame::OnInsertURL(wxCommandEvent
& WXUNUSED(event
))
1910 wxString url
= wxGetTextFromUser(_("URL:"), _("Insert URL"));
1913 // Make a style suitable for showing a URL
1914 wxRichTextAttr urlStyle
;
1915 urlStyle
.SetTextColour(*wxBLUE
);
1916 urlStyle
.SetFontUnderlined(true);
1918 m_richTextCtrl
->BeginStyle(urlStyle
);
1919 m_richTextCtrl
->BeginURL(url
);
1920 m_richTextCtrl
->WriteText(url
);
1921 m_richTextCtrl
->EndURL();
1922 m_richTextCtrl
->EndStyle();
1926 void MyFrame::OnInsertImage(wxCommandEvent
& WXUNUSED(event
))
1928 wxFileDialog
dialog(this, _("Choose an image"), "", "", "BMP and GIF files (*.bmp;*.gif)|*.bmp;*.gif|PNG files (*.png)|*.png");
1929 if (dialog
.ShowModal() == wxID_OK
)
1931 wxString path
= dialog
.GetPath();
1932 m_richTextCtrl
->WriteImage(path
, wxBITMAP_TYPE_ANY
);
1936 void MyFrame::OnURL(wxTextUrlEvent
& event
)
1938 wxMessageBox(event
.GetString());
1941 // Veto style sheet replace events when loading from XML, since we want
1942 // to keep the original style sheet.
1943 void MyFrame::OnStyleSheetReplacing(wxRichTextEvent
& event
)
1948 void MyFrame::OnPrint(wxCommandEvent
& WXUNUSED(event
))
1950 wxGetApp().GetPrinting()->PrintBuffer(m_richTextCtrl
->GetBuffer());
1953 void MyFrame::OnPreview(wxCommandEvent
& WXUNUSED(event
))
1955 wxGetApp().GetPrinting()->PreviewBuffer(m_richTextCtrl
->GetBuffer());
1958 void MyFrame::OnPageSetup(wxCommandEvent
& WXUNUSED(event
))
1960 wxDialog
dialog(this, wxID_ANY
, wxT("Testing"), wxPoint(10, 10), wxSize(400, 300), wxDEFAULT_DIALOG_STYLE
);
1962 wxNotebook
* nb
= new wxNotebook(& dialog
, wxID_ANY
, wxPoint(5, 5), wxSize(300, 250));
1963 wxPanel
* panel
= new wxPanel(nb
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
);
1964 wxPanel
* panel2
= new wxPanel(nb
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
);
1966 new wxRichTextCtrl(panel
, wxID_ANY
, wxEmptyString
, wxPoint(5, 5), wxSize(200, 150), wxVSCROLL
|wxTE_READONLY
);
1967 nb
->AddPage(panel
, wxT("Page 1"));
1969 new wxRichTextCtrl(panel2
, wxID_ANY
, wxEmptyString
, wxPoint(5, 5), wxSize(200, 150), wxVSCROLL
|wxTE_READONLY
);
1970 nb
->AddPage(panel2
, wxT("Page 2"));
1972 new wxButton(& dialog
, wxID_OK
, wxT("OK"), wxPoint(5, 180));
1976 // wxGetApp().GetPrinting()->PageSetup();
1979 void MyFrame::OnSetFontScale(wxCommandEvent
& WXUNUSED(event
))
1981 wxString value
= wxString::Format(wxT("%g"), m_richTextCtrl
->GetFontScale());
1982 wxString text
= wxGetTextFromUser(wxT("Enter a text scale factor:"), wxT("Text Scale Factor"), value
, wxGetTopLevelParent(this));
1983 if (!text
.IsEmpty() && value
!= text
)
1986 wxSscanf(text
, wxT("%lf"), & scale
);
1987 m_richTextCtrl
->SetFontScale(scale
, true);
1991 void MyFrame::OnSetDimensionScale(wxCommandEvent
& WXUNUSED(event
))
1993 wxString value
= wxString::Format(wxT("%g"), m_richTextCtrl
->GetDimensionScale());
1994 wxString text
= wxGetTextFromUser(wxT("Enter a dimension scale factor:"), wxT("Dimension Scale Factor"), value
, wxGetTopLevelParent(this));
1995 if (!text
.IsEmpty() && value
!= text
)
1998 wxSscanf(text
, wxT("%lf"), & scale
);
1999 m_richTextCtrl
->SetDimensionScale(scale
, true);
2003 void MyRichTextCtrl::PrepareContent(wxRichTextParagraphLayoutBox
& container
)
2007 // Lock all content that's about to be added to the control
2008 wxRichTextObjectList::compatibility_iterator node
= container
.GetChildren().GetFirst();
2011 wxRichTextParagraph
* para
= wxDynamicCast(node
->GetData(), wxRichTextParagraph
);
2014 wxRichTextObjectList::compatibility_iterator childNode
= para
->GetChildren().GetFirst();
2017 wxRichTextObject
* obj
= childNode
->GetData();
2018 obj
->GetProperties().SetProperty(wxT("Lock"), m_lockId
);
2020 childNode
= childNode
->GetNext();
2023 node
= node
->GetNext();
2028 bool MyRichTextCtrl::CanDeleteRange(wxRichTextParagraphLayoutBox
& container
, const wxRichTextRange
& range
) const
2031 for (i
= range
.GetStart(); i
< range
.GetEnd(); i
++)
2033 wxRichTextObject
* obj
= container
.GetLeafObjectAtPosition(i
);
2034 if (obj
&& obj
->GetProperties().HasProperty(wxT("Lock")))
2042 bool MyRichTextCtrl::CanInsertContent(wxRichTextParagraphLayoutBox
& container
, long pos
) const
2044 wxRichTextObject
* child1
= container
.GetLeafObjectAtPosition(pos
);
2045 wxRichTextObject
* child2
= container
.GetLeafObjectAtPosition(pos
-1);
2047 long lock1
= -1, lock2
= -1;
2049 if (child1
&& child1
->GetProperties().HasProperty(wxT("Lock")))
2050 lock1
= child1
->GetProperties().GetPropertyLong(wxT("Lock"));
2051 if (child2
&& child2
->GetProperties().HasProperty(wxT("Lock")))
2052 lock2
= child2
->GetProperties().GetPropertyLong(wxT("Lock"));
2054 if (lock1
!= -1 && lock1
== lock2
)
2057 // Don't allow insertion before a locked object if it's at the beginning of the buffer.
2058 if (pos
== 0 && lock1
!= -1)
2065 class wxRichTextEnhancedDrawingHandler
: public wxRichTextDrawingHandler
2068 wxRichTextEnhancedDrawingHandler()
2070 SetName(wxT("enhanceddrawing"));
2071 m_lockBackgroundColour
= wxColour(220, 220, 220);
2075 Returns @true if this object has virtual attributes that we can provide.
2077 virtual bool HasVirtualAttributes(wxRichTextObject
* obj
) const;
2080 Provides virtual attributes that we can provide.
2082 virtual bool GetVirtualAttributes(wxRichTextAttr
& attr
, wxRichTextObject
* obj
) const;
2085 Gets the count for mixed virtual attributes for individual positions within the object.
2086 For example, individual characters within a text object may require special highlighting.
2088 virtual int GetVirtualSubobjectAttributesCount(wxRichTextObject
* WXUNUSED(obj
)) const { return 0; }
2091 Gets the mixed virtual attributes for individual positions within the object.
2092 For example, individual characters within a text object may require special highlighting.
2093 Returns the number of virtual attributes found.
2095 virtual int GetVirtualSubobjectAttributes(wxRichTextObject
* WXUNUSED(obj
), wxArrayInt
& WXUNUSED(positions
), wxRichTextAttrArray
& WXUNUSED(attributes
)) const { return 0; }
2098 Do we have virtual text for this object? Virtual text allows an application
2099 to replace characters in an object for editing and display purposes, for example
2100 for highlighting special characters.
2102 virtual bool HasVirtualText(const wxRichTextPlainText
* WXUNUSED(obj
)) const { return false; }
2105 Gets the virtual text for this object.
2107 virtual bool GetVirtualText(const wxRichTextPlainText
* WXUNUSED(obj
), wxString
& WXUNUSED(text
)) const { return false; }
2109 wxColour m_lockBackgroundColour
;
2112 bool wxRichTextEnhancedDrawingHandler::HasVirtualAttributes(wxRichTextObject
* obj
) const
2114 return obj
->GetProperties().HasProperty(wxT("Lock"));
2117 bool wxRichTextEnhancedDrawingHandler::GetVirtualAttributes(wxRichTextAttr
& attr
, wxRichTextObject
* obj
) const
2119 if (obj
->GetProperties().HasProperty(wxT("Lock")))
2121 attr
.SetBackgroundColour(m_lockBackgroundColour
);
2127 void MyRichTextCtrl::SetEnhancedDrawingHandler()
2129 wxRichTextBuffer::AddDrawingHandler(new wxRichTextEnhancedDrawingHandler
);