]>
Commit | Line | Data |
---|---|---|
5d7836c4 | 1 | ///////////////////////////////////////////////////////////////////////////// |
dbf38e88 | 2 | // Name: samples/richtext/richtext.cpp |
5d7836c4 JS |
3 | // Purpose: wxWidgets rich text editor sample |
4 | // Author: Julian Smart | |
5 | // Modified by: | |
6 | // Created: 2005-10-02 | |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) Julian Smart | |
9 | // Licence: wxWindows licence | |
10 | ///////////////////////////////////////////////////////////////////////////// | |
11 | ||
12 | // ============================================================================ | |
13 | // declarations | |
14 | // ============================================================================ | |
15 | ||
16 | // ---------------------------------------------------------------------------- | |
17 | // headers | |
18 | // ---------------------------------------------------------------------------- | |
19 | ||
20 | // For compilers that support precompilation, includes "wx/wx.h". | |
21 | #include "wx/wxprec.h" | |
22 | ||
23 | #ifdef __BORLANDC__ | |
24 | #pragma hdrstop | |
25 | #endif | |
26 | ||
27 | // for all others, include the necessary headers (this file is usually all you | |
28 | // need because it includes almost all "standard" wxWidgets headers) | |
29 | #ifndef WX_PRECOMP | |
30 | #include "wx/wx.h" | |
31 | #endif | |
32 | ||
33 | #include "wx/fontdlg.h" | |
34 | #include "wx/splitter.h" | |
35 | #include "wx/sstream.h" | |
36 | #include "wx/html/htmlwin.h" | |
bec80f4f | 37 | #include "wx/stopwatch.h" |
b4e415df | 38 | #include "wx/sysopt.h" |
5d7836c4 | 39 | |
720cc10a JS |
40 | #if wxUSE_FILESYSTEM |
41 | #include "wx/filesys.h" | |
42 | #include "wx/fs_mem.h" | |
43 | #endif | |
44 | ||
2569ebc2 JS |
45 | #if wxUSE_HELP |
46 | #include "wx/cshelp.h" | |
47 | #endif | |
48 | ||
e7092398 | 49 | #ifndef wxHAS_IMAGES_IN_RESOURCES |
1226b3b3 WS |
50 | #include "../sample.xpm" |
51 | #endif | |
52 | ||
5d7836c4 JS |
53 | #include "bitmaps/smiley.xpm" |
54 | // #include "bitmaps/idea.xpm" | |
55 | #include "bitmaps/zebra.xpm" | |
56 | ||
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" | |
67 | ||
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" | |
74 | ||
011b3dcb JS |
75 | #include "wx/richtext/richtextctrl.h" |
76 | #include "wx/richtext/richtextstyles.h" | |
77 | #include "wx/richtext/richtextxml.h" | |
b71e9aa4 | 78 | #include "wx/richtext/richtexthtml.h" |
8c9c49a1 JS |
79 | #include "wx/richtext/richtextformatdlg.h" |
80 | #include "wx/richtext/richtextsymboldlg.h" | |
e4723634 | 81 | #include "wx/richtext/richtextstyledlg.h" |
8881d9f0 | 82 | #include "wx/richtext/richtextprint.h" |
cdaed652 | 83 | #include "wx/richtext/richtextimagedlg.h" |
5d7836c4 | 84 | |
32423dd8 JS |
85 | // A custom field type |
86 | class wxRichTextFieldTypePropertiesTest: public wxRichTextFieldTypeStandard | |
87 | { | |
88 | public: | |
89 | wxRichTextFieldTypePropertiesTest(const wxString& name, const wxString& label, int displayStyle = wxRICHTEXT_FIELD_STYLE_RECTANGLE): | |
90 | wxRichTextFieldTypeStandard(name, label, displayStyle) | |
91 | { | |
92 | } | |
93 | wxRichTextFieldTypePropertiesTest(const wxString& name, const wxBitmap& bitmap, int displayStyle = wxRICHTEXT_FIELD_STYLE_RECTANGLE): | |
94 | wxRichTextFieldTypeStandard(name, bitmap, displayStyle) | |
95 | { | |
96 | } | |
97 | ||
98 | virtual bool CanEditProperties(wxRichTextField* WXUNUSED(obj)) const { return true; } | |
99 | virtual bool EditProperties(wxRichTextField* WXUNUSED(obj), wxWindow* WXUNUSED(parent), wxRichTextBuffer* WXUNUSED(buffer)) | |
100 | { | |
101 | wxString label = GetLabel(); | |
102 | wxMessageBox(wxString::Format(wxT("Editing %s"), label.c_str())); | |
103 | return true; | |
104 | } | |
105 | ||
106 | virtual wxString GetPropertiesMenuLabel(wxRichTextField* WXUNUSED(obj)) const | |
107 | { | |
108 | return GetLabel(); | |
109 | } | |
110 | }; | |
111 | ||
112 | // A custom composite field type | |
113 | class wxRichTextFieldTypeCompositeTest: public wxRichTextFieldTypePropertiesTest | |
114 | { | |
115 | public: | |
116 | wxRichTextFieldTypeCompositeTest(const wxString& name, const wxString& label): | |
117 | wxRichTextFieldTypePropertiesTest(name, label, wxRICHTEXT_FIELD_STYLE_COMPOSITE) | |
118 | { | |
119 | } | |
120 | ||
121 | virtual bool UpdateField(wxRichTextBuffer* buffer, wxRichTextField* obj) | |
122 | { | |
123 | if (buffer) | |
124 | { | |
125 | wxRichTextAttr attr(buffer->GetAttributes()); | |
126 | attr.GetTextBoxAttr().Reset(); | |
127 | attr.SetParagraphSpacingAfter(0); | |
128 | attr.SetLineSpacing(10); | |
129 | obj->SetAttributes(attr); | |
130 | } | |
131 | obj->GetChildren().Clear(); | |
132 | wxRichTextParagraph* para = new wxRichTextParagraph; | |
133 | wxRichTextPlainText* text = new wxRichTextPlainText(GetLabel()); | |
134 | para->AppendChild(text); | |
135 | obj->AppendChild(para); | |
136 | return true; | |
137 | } | |
138 | }; | |
139 | ||
5d7836c4 JS |
140 | // ---------------------------------------------------------------------------- |
141 | // resources | |
142 | // ---------------------------------------------------------------------------- | |
143 | ||
144 | // ---------------------------------------------------------------------------- | |
145 | // private classes | |
146 | // ---------------------------------------------------------------------------- | |
147 | ||
cc2aecde JS |
148 | // Define a new application type, each program should derive a class from wxApp |
149 | class MyRichTextCtrl: public wxRichTextCtrl | |
150 | { | |
151 | public: | |
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) | |
155 | { | |
156 | m_lockId = 0; | |
157 | m_locked = false; | |
158 | } | |
159 | ||
160 | void SetLockId(long id) { m_lockId = id; } | |
161 | long GetLockId() const { return m_lockId; } | |
162 | ||
163 | void BeginLock() { m_lockId ++; m_locked = true; } | |
164 | void EndLock() { m_locked = false; } | |
165 | bool IsLocked() const { return m_locked; } | |
166 | ||
167 | static void SetEnhancedDrawingHandler(); | |
168 | ||
169 | /** | |
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. | |
172 | */ | |
173 | virtual void PrepareContent(wxRichTextParagraphLayoutBox& container); | |
174 | ||
175 | /** | |
176 | Can we delete this range? | |
177 | Sends an event to the control. | |
178 | */ | |
179 | virtual bool CanDeleteRange(wxRichTextParagraphLayoutBox& container, const wxRichTextRange& range) const; | |
180 | ||
181 | /** | |
182 | Can we insert content at this position? | |
183 | Sends an event to the control. | |
184 | */ | |
185 | virtual bool CanInsertContent(wxRichTextParagraphLayoutBox& container, long pos) const; | |
186 | ||
187 | long m_lockId; | |
188 | bool m_locked; | |
189 | }; | |
190 | ||
5d7836c4 JS |
191 | // Define a new application type, each program should derive a class from wxApp |
192 | class MyApp : public wxApp | |
193 | { | |
194 | public: | |
195 | // override base class virtuals | |
196 | // ---------------------------- | |
197 | ||
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(); | |
203 | ||
204 | void CreateStyles(); | |
205 | ||
206 | wxRichTextStyleSheet* GetStyleSheet() const { return m_styleSheet; } | |
8881d9f0 | 207 | wxRichTextPrinting* GetPrinting() const { return m_printing; } |
5d7836c4 | 208 | |
8881d9f0 JS |
209 | wxRichTextStyleSheet* m_styleSheet; |
210 | wxRichTextPrinting* m_printing; | |
5d7836c4 JS |
211 | }; |
212 | ||
213 | // Define a new frame type: this is going to be our main frame | |
214 | class MyFrame : public wxFrame | |
215 | { | |
216 | public: | |
217 | // ctor(s) | |
218 | MyFrame(const wxString& title, wxWindowID id, const wxPoint& pos = wxDefaultPosition, | |
219 | const wxSize& size = wxDefaultSize, long style = wxDEFAULT_FRAME_STYLE); | |
220 | ||
221 | // event handlers (these functions should _not_ be virtual) | |
222 | void OnQuit(wxCommandEvent& event); | |
223 | void OnAbout(wxCommandEvent& event); | |
224 | ||
225 | void OnOpen(wxCommandEvent& event); | |
226 | void OnSave(wxCommandEvent& event); | |
227 | void OnSaveAs(wxCommandEvent& event); | |
228 | ||
229 | void OnBold(wxCommandEvent& event); | |
230 | void OnItalic(wxCommandEvent& event); | |
231 | void OnUnderline(wxCommandEvent& event); | |
232 | ||
75936ec6 JS |
233 | void OnStrikethrough(wxCommandEvent& event); |
234 | void OnSuperscript(wxCommandEvent& event); | |
235 | void OnSubscript(wxCommandEvent& event); | |
236 | ||
5d7836c4 JS |
237 | void OnUpdateBold(wxUpdateUIEvent& event); |
238 | void OnUpdateItalic(wxUpdateUIEvent& event); | |
239 | void OnUpdateUnderline(wxUpdateUIEvent& event); | |
75936ec6 JS |
240 | void OnUpdateStrikethrough(wxUpdateUIEvent& event); |
241 | void OnUpdateSuperscript(wxUpdateUIEvent& event); | |
242 | void OnUpdateSubscript(wxUpdateUIEvent& event); | |
5d7836c4 JS |
243 | |
244 | void OnAlignLeft(wxCommandEvent& event); | |
245 | void OnAlignCentre(wxCommandEvent& event); | |
246 | void OnAlignRight(wxCommandEvent& event); | |
247 | ||
248 | void OnUpdateAlignLeft(wxUpdateUIEvent& event); | |
249 | void OnUpdateAlignCentre(wxUpdateUIEvent& event); | |
250 | void OnUpdateAlignRight(wxUpdateUIEvent& event); | |
251 | ||
5d7836c4 JS |
252 | void OnIndentMore(wxCommandEvent& event); |
253 | void OnIndentLess(wxCommandEvent& event); | |
254 | ||
8c9c49a1 | 255 | void OnFont(wxCommandEvent& event); |
cdaed652 VZ |
256 | void OnImage(wxCommandEvent& event); |
257 | void OnUpdateImage(wxUpdateUIEvent& event); | |
8c9c49a1 JS |
258 | void OnParagraph(wxCommandEvent& event); |
259 | void OnFormat(wxCommandEvent& event); | |
260 | void OnUpdateFormat(wxUpdateUIEvent& event); | |
261 | ||
262 | void OnInsertSymbol(wxCommandEvent& event); | |
263 | ||
5d7836c4 JS |
264 | void OnLineSpacingHalf(wxCommandEvent& event); |
265 | void OnLineSpacingDouble(wxCommandEvent& event); | |
266 | void OnLineSpacingSingle(wxCommandEvent& event); | |
267 | ||
268 | void OnParagraphSpacingMore(wxCommandEvent& event); | |
269 | void OnParagraphSpacingLess(wxCommandEvent& event); | |
270 | ||
082cfe55 | 271 | void OnNumberList(wxCommandEvent& event); |
e4723634 | 272 | void OnBulletsAndNumbering(wxCommandEvent& event); |
082cfe55 JS |
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); | |
278 | ||
99404ab0 JS |
279 | void OnReload(wxCommandEvent& event); |
280 | ||
5d7836c4 JS |
281 | void OnViewHTML(wxCommandEvent& event); |
282 | ||
fe5aa22c | 283 | void OnSwitchStyleSheets(wxCommandEvent& event); |
e4723634 | 284 | void OnManageStyles(wxCommandEvent& event); |
fe5aa22c | 285 | |
720cc10a JS |
286 | void OnInsertURL(wxCommandEvent& event); |
287 | void OnURL(wxTextUrlEvent& event); | |
288 | void OnStyleSheetReplacing(wxRichTextEvent& event); | |
289 | ||
8881d9f0 JS |
290 | void OnPrint(wxCommandEvent& event); |
291 | void OnPreview(wxCommandEvent& event); | |
292 | void OnPageSetup(wxCommandEvent& event); | |
293 | ||
cdaed652 | 294 | void OnInsertImage(wxCommandEvent& event); |
32423dd8 JS |
295 | |
296 | void OnSetFontScale(wxCommandEvent& event); | |
297 | void OnSetDimensionScale(wxCommandEvent& event); | |
004867db FM |
298 | protected: |
299 | ||
5d7836c4 JS |
300 | // Forward command events to the current rich text control, if any |
301 | bool ProcessEvent(wxEvent& event); | |
302 | ||
99404ab0 JS |
303 | // Write text |
304 | void WriteInitialText(); | |
305 | ||
5d7836c4 JS |
306 | private: |
307 | // any class wishing to process wxWidgets events must use this macro | |
308 | DECLARE_EVENT_TABLE() | |
309 | ||
cc2aecde | 310 | MyRichTextCtrl* m_richTextCtrl; |
5d7836c4 JS |
311 | }; |
312 | ||
313 | // ---------------------------------------------------------------------------- | |
314 | // constants | |
315 | // ---------------------------------------------------------------------------- | |
316 | ||
317 | // IDs for the controls and the menu commands | |
318 | enum | |
319 | { | |
320 | // menu items | |
321 | ID_Quit = wxID_EXIT, | |
322 | ID_About = wxID_ABOUT, | |
323 | ||
324 | ID_FORMAT_BOLD = 100, | |
325 | ID_FORMAT_ITALIC, | |
326 | ID_FORMAT_UNDERLINE, | |
75936ec6 JS |
327 | ID_FORMAT_STRIKETHROUGH, |
328 | ID_FORMAT_SUPERSCRIPT, | |
329 | ID_FORMAT_SUBSCRIPT, | |
5d7836c4 | 330 | ID_FORMAT_FONT, |
cdaed652 | 331 | ID_FORMAT_IMAGE, |
8c9c49a1 JS |
332 | ID_FORMAT_PARAGRAPH, |
333 | ID_FORMAT_CONTENT, | |
334 | ||
99404ab0 JS |
335 | ID_RELOAD, |
336 | ||
8c9c49a1 | 337 | ID_INSERT_SYMBOL, |
720cc10a | 338 | ID_INSERT_URL, |
cdaed652 | 339 | ID_INSERT_IMAGE, |
5d7836c4 JS |
340 | |
341 | ID_FORMAT_ALIGN_LEFT, | |
342 | ID_FORMAT_ALIGN_CENTRE, | |
343 | ID_FORMAT_ALIGN_RIGHT, | |
344 | ||
345 | ID_FORMAT_INDENT_MORE, | |
346 | ID_FORMAT_INDENT_LESS, | |
347 | ||
348 | ID_FORMAT_PARAGRAPH_SPACING_MORE, | |
349 | ID_FORMAT_PARAGRAPH_SPACING_LESS, | |
350 | ||
351 | ID_FORMAT_LINE_SPACING_HALF, | |
352 | ID_FORMAT_LINE_SPACING_DOUBLE, | |
353 | ID_FORMAT_LINE_SPACING_SINGLE, | |
354 | ||
082cfe55 | 355 | ID_FORMAT_NUMBER_LIST, |
e4723634 | 356 | ID_FORMAT_BULLETS_AND_NUMBERING, |
082cfe55 JS |
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, | |
362 | ||
32423dd8 JS |
363 | ID_SET_FONT_SCALE, |
364 | ID_SET_DIMENSION_SCALE, | |
365 | ||
fe5aa22c JS |
366 | ID_VIEW_HTML, |
367 | ID_SWITCH_STYLE_SHEETS, | |
e4723634 | 368 | ID_MANAGE_STYLES, |
fe5aa22c | 369 | |
8881d9f0 JS |
370 | ID_PRINT, |
371 | ID_PREVIEW, | |
372 | ID_PAGE_SETUP, | |
373 | ||
fe5aa22c JS |
374 | ID_RICHTEXT_CTRL, |
375 | ID_RICHTEXT_STYLE_LIST, | |
376 | ID_RICHTEXT_STYLE_COMBO | |
5d7836c4 JS |
377 | }; |
378 | ||
379 | // ---------------------------------------------------------------------------- | |
380 | // event tables and other macros for wxWidgets | |
381 | // ---------------------------------------------------------------------------- | |
382 | ||
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) | |
389 | ||
390 | EVT_MENU(wxID_OPEN, MyFrame::OnOpen) | |
391 | EVT_MENU(wxID_SAVE, MyFrame::OnSave) | |
392 | EVT_MENU(wxID_SAVEAS, MyFrame::OnSaveAs) | |
393 | ||
394 | EVT_MENU(ID_FORMAT_BOLD, MyFrame::OnBold) | |
395 | EVT_MENU(ID_FORMAT_ITALIC, MyFrame::OnItalic) | |
396 | EVT_MENU(ID_FORMAT_UNDERLINE, MyFrame::OnUnderline) | |
397 | ||
75936ec6 JS |
398 | EVT_MENU(ID_FORMAT_STRIKETHROUGH, MyFrame::OnStrikethrough) |
399 | EVT_MENU(ID_FORMAT_SUPERSCRIPT, MyFrame::OnSuperscript) | |
400 | EVT_MENU(ID_FORMAT_SUBSCRIPT, MyFrame::OnSubscript) | |
401 | ||
5d7836c4 JS |
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) | |
405 | ||
75936ec6 JS |
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) | |
409 | ||
5d7836c4 JS |
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) | |
413 | ||
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) | |
417 | ||
418 | EVT_MENU(ID_FORMAT_FONT, MyFrame::OnFont) | |
cdaed652 | 419 | EVT_MENU(ID_FORMAT_IMAGE, MyFrame::OnImage) |
8c9c49a1 JS |
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) | |
cdaed652 | 424 | EVT_UPDATE_UI(ID_FORMAT_IMAGE, MyFrame::OnUpdateImage) |
8c9c49a1 | 425 | EVT_UPDATE_UI(ID_FORMAT_PARAGRAPH, MyFrame::OnUpdateFormat) |
5d7836c4 JS |
426 | EVT_MENU(ID_FORMAT_INDENT_MORE, MyFrame::OnIndentMore) |
427 | EVT_MENU(ID_FORMAT_INDENT_LESS, MyFrame::OnIndentLess) | |
428 | ||
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) | |
432 | ||
433 | EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_MORE, MyFrame::OnParagraphSpacingMore) | |
434 | EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_LESS, MyFrame::OnParagraphSpacingLess) | |
435 | ||
99404ab0 JS |
436 | EVT_MENU(ID_RELOAD, MyFrame::OnReload) |
437 | ||
8c9c49a1 | 438 | EVT_MENU(ID_INSERT_SYMBOL, MyFrame::OnInsertSymbol) |
720cc10a | 439 | EVT_MENU(ID_INSERT_URL, MyFrame::OnInsertURL) |
cdaed652 | 440 | EVT_MENU(ID_INSERT_IMAGE, MyFrame::OnInsertImage) |
8c9c49a1 | 441 | |
082cfe55 | 442 | EVT_MENU(ID_FORMAT_NUMBER_LIST, MyFrame::OnNumberList) |
e4723634 | 443 | EVT_MENU(ID_FORMAT_BULLETS_AND_NUMBERING, MyFrame::OnBulletsAndNumbering) |
082cfe55 JS |
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) | |
449 | ||
5d7836c4 | 450 | EVT_MENU(ID_VIEW_HTML, MyFrame::OnViewHTML) |
fe5aa22c | 451 | EVT_MENU(ID_SWITCH_STYLE_SHEETS, MyFrame::OnSwitchStyleSheets) |
e4723634 | 452 | EVT_MENU(ID_MANAGE_STYLES, MyFrame::OnManageStyles) |
720cc10a | 453 | |
8881d9f0 JS |
454 | EVT_MENU(ID_PRINT, MyFrame::OnPrint) |
455 | EVT_MENU(ID_PREVIEW, MyFrame::OnPreview) | |
456 | EVT_MENU(ID_PAGE_SETUP, MyFrame::OnPageSetup) | |
457 | ||
720cc10a JS |
458 | EVT_TEXT_URL(wxID_ANY, MyFrame::OnURL) |
459 | EVT_RICHTEXT_STYLESHEET_REPLACING(wxID_ANY, MyFrame::OnStyleSheetReplacing) | |
32423dd8 JS |
460 | |
461 | EVT_MENU(ID_SET_FONT_SCALE, MyFrame::OnSetFontScale) | |
462 | EVT_MENU(ID_SET_DIMENSION_SCALE, MyFrame::OnSetDimensionScale) | |
5d7836c4 JS |
463 | END_EVENT_TABLE() |
464 | ||
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 | |
469 | // not wxApp) | |
470 | IMPLEMENT_APP(MyApp) | |
471 | ||
472 | // ============================================================================ | |
473 | // implementation | |
474 | // ============================================================================ | |
475 | ||
476 | // ---------------------------------------------------------------------------- | |
477 | // the application class | |
478 | // ---------------------------------------------------------------------------- | |
479 | ||
480 | // 'Main program' equivalent: the program execution "starts" here | |
481 | bool MyApp::OnInit() | |
482 | { | |
45e6e6f8 VZ |
483 | if ( !wxApp::OnInit() ) |
484 | return false; | |
485 | ||
2569ebc2 JS |
486 | #if wxUSE_HELP |
487 | wxHelpProvider::Set(new wxSimpleHelpProvider); | |
488 | #endif | |
489 | ||
5d7836c4 | 490 | m_styleSheet = new wxRichTextStyleSheet; |
8881d9f0 JS |
491 | m_printing = new wxRichTextPrinting(wxT("Test Document")); |
492 | ||
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); | |
5d7836c4 JS |
495 | |
496 | CreateStyles(); | |
497 | ||
cc2aecde JS |
498 | MyRichTextCtrl::SetEnhancedDrawingHandler(); |
499 | ||
5d7836c4 JS |
500 | // Add extra handlers (plain text is automatically added) |
501 | wxRichTextBuffer::AddHandler(new wxRichTextXMLHandler); | |
502 | wxRichTextBuffer::AddHandler(new wxRichTextHTMLHandler); | |
503 | ||
32423dd8 JS |
504 | // Add field types |
505 | ||
506 | wxRichTextBuffer::AddFieldType(new wxRichTextFieldTypePropertiesTest(wxT("rectangle"), wxT("RECTANGLE"), wxRichTextFieldTypeStandard::wxRICHTEXT_FIELD_STYLE_RECTANGLE)); | |
507 | ||
508 | wxRichTextFieldTypeStandard* s1 = new wxRichTextFieldTypeStandard(wxT("begin-section"), wxT("SECTION"), wxRichTextFieldTypeStandard::wxRICHTEXT_FIELD_STYLE_START_TAG); | |
509 | s1->SetBackgroundColour(*wxBLUE); | |
510 | ||
511 | wxRichTextFieldTypeStandard* s2 = new wxRichTextFieldTypeStandard(wxT("end-section"), wxT("SECTION"), wxRichTextFieldTypeStandard::wxRICHTEXT_FIELD_STYLE_END_TAG); | |
512 | s2->SetBackgroundColour(*wxBLUE); | |
513 | ||
514 | wxRichTextFieldTypeStandard* s3 = new wxRichTextFieldTypeStandard(wxT("bitmap"), wxBitmap(paste_xpm), wxRichTextFieldTypeStandard::wxRICHTEXT_FIELD_STYLE_NO_BORDER); | |
515 | ||
516 | wxRichTextBuffer::AddFieldType(s1); | |
517 | wxRichTextBuffer::AddFieldType(s2); | |
518 | wxRichTextBuffer::AddFieldType(s3); | |
519 | ||
520 | wxRichTextFieldTypeCompositeTest* s4 = new wxRichTextFieldTypeCompositeTest(wxT("composite"), wxT("This is a field value")); | |
521 | wxRichTextBuffer::AddFieldType(s4); | |
522 | ||
5d7836c4 JS |
523 | // Add image handlers |
524 | #if wxUSE_LIBPNG | |
525 | wxImage::AddHandler( new wxPNGHandler ); | |
526 | #endif | |
9a173d48 | 527 | |
5d7836c4 JS |
528 | #if wxUSE_LIBJPEG |
529 | wxImage::AddHandler( new wxJPEGHandler ); | |
530 | #endif | |
531 | ||
532 | #if wxUSE_GIF | |
533 | wxImage::AddHandler( new wxGIFHandler ); | |
534 | #endif | |
535 | ||
720cc10a JS |
536 | #if wxUSE_FILESYSTEM |
537 | wxFileSystem::AddHandler( new wxMemoryFSHandler ); | |
538 | #endif | |
539 | ||
5d7836c4 | 540 | // create the main application window |
9a83f860 | 541 | MyFrame *frame = new MyFrame(wxT("wxRichTextCtrl Sample"), wxID_ANY, wxDefaultPosition, wxSize(700, 600)); |
5d7836c4 | 542 | |
8881d9f0 JS |
543 | m_printing->SetParentWindow(frame); |
544 | ||
5d7836c4 JS |
545 | // and show it (the frames, unlike simple controls, are not shown when |
546 | // created initially) | |
547 | frame->Show(true); | |
548 | ||
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. | |
552 | return true; | |
553 | } | |
554 | ||
555 | int MyApp::OnExit() | |
556 | { | |
8881d9f0 | 557 | delete m_printing; |
5d7836c4 | 558 | delete m_styleSheet; |
8881d9f0 | 559 | |
5d7836c4 JS |
560 | return 0; |
561 | } | |
562 | ||
563 | void MyApp::CreateStyles() | |
564 | { | |
565 | // Paragraph styles | |
566 | ||
567 | wxFont romanFont(12, wxROMAN, wxNORMAL, wxNORMAL); | |
568 | wxFont swissFont(12, wxSWISS, wxNORMAL, wxNORMAL); | |
569 | ||
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); | |
9a173d48 | 579 | |
5d7836c4 JS |
580 | m_styleSheet->AddParagraphStyle(normalPara); |
581 | ||
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); | |
9a173d48 | 590 | |
5d7836c4 JS |
591 | m_styleSheet->AddParagraphStyle(indentedPara); |
592 | ||
27e20452 JS |
593 | wxRichTextParagraphStyleDefinition* indentedPara2 = new wxRichTextParagraphStyleDefinition(wxT("Red Bold Indented")); |
594 | wxRichTextAttr indentedAttr2; | |
595 | indentedAttr2.SetFontFaceName(romanFont.GetFaceName()); | |
596 | indentedAttr2.SetFontSize(12); | |
00621a0d | 597 | indentedAttr2.SetFontWeight(wxFONTWEIGHT_BOLD); |
27e20452 JS |
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); | |
604 | ||
605 | m_styleSheet->AddParagraphStyle(indentedPara2); | |
606 | ||
5d7836c4 JS |
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); | |
9a173d48 | 615 | |
5d7836c4 JS |
616 | m_styleSheet->AddParagraphStyle(flIndentedPara); |
617 | ||
618 | // Character styles | |
619 | ||
620 | wxRichTextCharacterStyleDefinition* boldDef = new wxRichTextCharacterStyleDefinition(wxT("Bold")); | |
621 | wxRichTextAttr boldAttr; | |
622 | boldAttr.SetFontFaceName(romanFont.GetFaceName()); | |
623 | boldAttr.SetFontSize(12); | |
00621a0d | 624 | boldAttr.SetFontWeight(wxFONTWEIGHT_BOLD); |
5d7836c4 JS |
625 | // We only want to affect boldness |
626 | boldAttr.SetFlags(wxTEXT_ATTR_FONT_WEIGHT); | |
627 | boldDef->SetStyle(boldAttr); | |
9a173d48 | 628 | |
5d7836c4 JS |
629 | m_styleSheet->AddCharacterStyle(boldDef); |
630 | ||
631 | wxRichTextCharacterStyleDefinition* italicDef = new wxRichTextCharacterStyleDefinition(wxT("Italic")); | |
632 | wxRichTextAttr italicAttr; | |
633 | italicAttr.SetFontFaceName(romanFont.GetFaceName()); | |
634 | italicAttr.SetFontSize(12); | |
00621a0d | 635 | italicAttr.SetFontStyle(wxFONTSTYLE_ITALIC); |
5d7836c4 JS |
636 | // We only want to affect italics |
637 | italicAttr.SetFlags(wxTEXT_ATTR_FONT_ITALIC); | |
638 | italicDef->SetStyle(italicAttr); | |
9a173d48 | 639 | |
5d7836c4 JS |
640 | m_styleSheet->AddCharacterStyle(italicDef); |
641 | ||
642 | wxRichTextCharacterStyleDefinition* redDef = new wxRichTextCharacterStyleDefinition(wxT("Red Bold")); | |
643 | wxRichTextAttr redAttr; | |
644 | redAttr.SetFontFaceName(romanFont.GetFaceName()); | |
645 | redAttr.SetFontSize(12); | |
00621a0d | 646 | redAttr.SetFontWeight(wxFONTWEIGHT_BOLD); |
5d7836c4 JS |
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); | |
9a173d48 | 651 | |
5d7836c4 | 652 | m_styleSheet->AddCharacterStyle(redDef); |
082cfe55 JS |
653 | |
654 | wxRichTextListStyleDefinition* bulletList = new wxRichTextListStyleDefinition(wxT("Bullet List 1")); | |
655 | int i; | |
656 | for (i = 0; i < 10; i++) | |
657 | { | |
720cc10a | 658 | wxString bulletText; |
082cfe55 | 659 | if (i == 0) |
720cc10a | 660 | bulletText = wxT("standard/circle"); |
082cfe55 | 661 | else if (i == 1) |
720cc10a | 662 | bulletText = wxT("standard/square"); |
082cfe55 | 663 | else if (i == 2) |
720cc10a | 664 | bulletText = wxT("standard/circle"); |
082cfe55 | 665 | else if (i == 3) |
720cc10a | 666 | bulletText = wxT("standard/square"); |
082cfe55 | 667 | else |
720cc10a | 668 | bulletText = wxT("standard/circle"); |
082cfe55 | 669 | |
720cc10a | 670 | bulletList->SetAttributes(i, (i+1)*60, 60, wxTEXT_ATTR_BULLET_STYLE_STANDARD, bulletText); |
082cfe55 JS |
671 | } |
672 | ||
673 | m_styleSheet->AddListStyle(bulletList); | |
674 | ||
675 | wxRichTextListStyleDefinition* numberedList = new wxRichTextListStyleDefinition(wxT("Numbered List 1")); | |
676 | for (i = 0; i < 10; i++) | |
677 | { | |
678 | long numberStyle; | |
679 | if (i == 0) | |
680 | numberStyle = wxTEXT_ATTR_BULLET_STYLE_ARABIC|wxTEXT_ATTR_BULLET_STYLE_PERIOD; | |
681 | else if (i == 1) | |
682 | numberStyle = wxTEXT_ATTR_BULLET_STYLE_LETTERS_LOWER|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES; | |
683 | else if (i == 2) | |
684 | numberStyle = wxTEXT_ATTR_BULLET_STYLE_ROMAN_LOWER|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES; | |
685 | else if (i == 3) | |
686 | numberStyle = wxTEXT_ATTR_BULLET_STYLE_ROMAN_UPPER|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES; | |
687 | else | |
688 | numberStyle = wxTEXT_ATTR_BULLET_STYLE_ARABIC|wxTEXT_ATTR_BULLET_STYLE_PERIOD; | |
689 | ||
720cc10a JS |
690 | numberStyle |= wxTEXT_ATTR_BULLET_STYLE_ALIGN_RIGHT; |
691 | ||
082cfe55 JS |
692 | numberedList->SetAttributes(i, (i+1)*60, 60, numberStyle); |
693 | } | |
694 | ||
695 | m_styleSheet->AddListStyle(numberedList); | |
720cc10a JS |
696 | |
697 | wxRichTextListStyleDefinition* outlineList = new wxRichTextListStyleDefinition(wxT("Outline List 1")); | |
698 | for (i = 0; i < 10; i++) | |
699 | { | |
700 | long numberStyle; | |
701 | if (i < 4) | |
702 | numberStyle = wxTEXT_ATTR_BULLET_STYLE_OUTLINE|wxTEXT_ATTR_BULLET_STYLE_PERIOD; | |
703 | else | |
704 | numberStyle = wxTEXT_ATTR_BULLET_STYLE_ARABIC|wxTEXT_ATTR_BULLET_STYLE_PERIOD; | |
705 | ||
706 | outlineList->SetAttributes(i, (i+1)*120, 120, numberStyle); | |
707 | } | |
708 | ||
709 | m_styleSheet->AddListStyle(outlineList); | |
5d7836c4 JS |
710 | } |
711 | ||
712 | // ---------------------------------------------------------------------------- | |
713 | // main frame | |
714 | // ---------------------------------------------------------------------------- | |
715 | ||
716 | // frame constructor | |
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) | |
720 | { | |
b4e415df JS |
721 | #ifdef __WXMAC__ |
722 | SetWindowVariant(wxWINDOW_VARIANT_SMALL); | |
723 | #endif | |
724 | ||
5d7836c4 | 725 | // set the frame icon |
1226b3b3 | 726 | SetIcon(wxICON(sample)); |
5d7836c4 JS |
727 | |
728 | // create a menu bar | |
729 | wxMenu *fileMenu = new wxMenu; | |
730 | ||
731 | // the "About" item should be in the help menu | |
732 | wxMenu *helpMenu = new wxMenu; | |
2d143b66 | 733 | helpMenu->Append(ID_About, wxT("&About\tF1"), wxT("Show about dialog")); |
5d7836c4 | 734 | |
9a83f860 VZ |
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")); | |
5d7836c4 | 738 | fileMenu->AppendSeparator(); |
9a83f860 | 739 | fileMenu->Append(ID_RELOAD, wxT("&Reload Text\tF2"), wxT("Reload the initial text")); |
99404ab0 | 740 | fileMenu->AppendSeparator(); |
9a83f860 VZ |
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")); | |
8881d9f0 | 744 | fileMenu->AppendSeparator(); |
9a83f860 | 745 | fileMenu->Append(ID_VIEW_HTML, wxT("&View as HTML"), wxT("View HTML")); |
5d7836c4 | 746 | fileMenu->AppendSeparator(); |
9a83f860 | 747 | fileMenu->Append(ID_Quit, wxT("E&xit\tAlt+X"), wxT("Quit this program")); |
5d7836c4 JS |
748 | |
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")); | |
756 | ||
5d7836c4 JS |
757 | editMenu->AppendSeparator(); |
758 | editMenu->Append(wxID_SELECTALL, _("Select A&ll\tCtrl+A")); | |
5d7836c4 | 759 | editMenu->AppendSeparator(); |
32423dd8 JS |
760 | editMenu->Append(ID_SET_FONT_SCALE, _("Set &Text Scale...")); |
761 | editMenu->Append(ID_SET_DIMENSION_SCALE, _("Set &Dimension Scale...")); | |
5d7836c4 JS |
762 | |
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(); | |
75936ec6 JS |
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(); | |
5d7836c4 JS |
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(); | |
c4cd20cf | 776 | formatMenu->Append(ID_FORMAT_INDENT_MORE, _("Indent &More")); |
5d7836c4 JS |
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...")); | |
cdaed652 | 787 | formatMenu->Append(ID_FORMAT_IMAGE, _("Image Property")); |
8c9c49a1 JS |
788 | formatMenu->Append(ID_FORMAT_PARAGRAPH, _("&Paragraph...")); |
789 | formatMenu->Append(ID_FORMAT_CONTENT, _("Font and Pa&ragraph...\tShift+Ctrl+F")); | |
fe5aa22c JS |
790 | formatMenu->AppendSeparator(); |
791 | formatMenu->Append(ID_SWITCH_STYLE_SHEETS, _("&Switch Style Sheets")); | |
e4723634 JS |
792 | formatMenu->Append(ID_MANAGE_STYLES, _("&Manage Styles")); |
793 | ||
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")); | |
5d7836c4 | 803 | |
8c9c49a1 JS |
804 | wxMenu* insertMenu = new wxMenu; |
805 | insertMenu->Append(ID_INSERT_SYMBOL, _("&Symbol...\tCtrl+I")); | |
720cc10a | 806 | insertMenu->Append(ID_INSERT_URL, _("&URL...")); |
cdaed652 | 807 | insertMenu->Append(ID_INSERT_IMAGE, _("&Image...")); |
8c9c49a1 | 808 | |
5d7836c4 JS |
809 | // now append the freshly created menu to the menu bar... |
810 | wxMenuBar *menuBar = new wxMenuBar(); | |
9a83f860 VZ |
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")); | |
5d7836c4 JS |
817 | |
818 | // ... and attach this menu bar to the frame | |
819 | SetMenuBar(menuBar); | |
820 | ||
821 | // create a status bar just for fun (by default with 1 pane only) | |
4753c7ce WS |
822 | // but don't create it on limited screen space (WinCE) |
823 | bool is_pda = wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA; | |
824 | ||
9a173d48 | 825 | #if wxUSE_STATUSBAR |
4753c7ce WS |
826 | if ( !is_pda ) |
827 | { | |
828 | CreateStatusBar(2); | |
9a83f860 | 829 | SetStatusText(wxT("Welcome to wxRichTextCtrl!")); |
4753c7ce | 830 | } |
9a173d48 | 831 | #endif |
5d7836c4 | 832 | |
b4e415df JS |
833 | wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); |
834 | SetSizer(sizer); | |
835 | ||
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. | |
841 | ||
842 | wxSystemOptions::SetOption(wxT("mac.toolbar.no-native"), 1); | |
843 | ||
844 | wxToolBar* toolBar = new wxToolBar(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, | |
845 | wxNO_BORDER|wxTB_FLAT|wxTB_NODIVIDER|wxTB_NOALIGN); | |
846 | ||
847 | sizer->Add(toolBar, 0, wxEXPAND); | |
5d7836c4 | 848 | |
bbe28fbb PC |
849 | toolBar->AddTool(wxID_OPEN, wxEmptyString, wxBitmap(open_xpm), _("Open")); |
850 | toolBar->AddTool(wxID_SAVEAS, wxEmptyString, wxBitmap(save_xpm), _("Save")); | |
5d7836c4 | 851 | toolBar->AddSeparator(); |
bbe28fbb PC |
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")); | |
5d7836c4 | 855 | toolBar->AddSeparator(); |
bbe28fbb PC |
856 | toolBar->AddTool(wxID_UNDO, wxEmptyString, wxBitmap(undo_xpm), _("Undo")); |
857 | toolBar->AddTool(wxID_REDO, wxEmptyString, wxBitmap(redo_xpm), _("Redo")); | |
5d7836c4 | 858 | toolBar->AddSeparator(); |
bbe28fbb PC |
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")); | |
5d7836c4 | 862 | toolBar->AddSeparator(); |
bbe28fbb PC |
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")); | |
5d7836c4 | 866 | toolBar->AddSeparator(); |
bbe28fbb PC |
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")); | |
5d7836c4 | 869 | toolBar->AddSeparator(); |
bbe28fbb | 870 | toolBar->AddTool(ID_FORMAT_FONT, wxEmptyString, wxBitmap(font_xpm), _("Font")); |
b4e415df | 871 | toolBar->AddSeparator(); |
5d7836c4 | 872 | |
b4e415df | 873 | wxRichTextStyleComboCtrl* combo = new wxRichTextStyleComboCtrl(toolBar, ID_RICHTEXT_STYLE_COMBO, wxDefaultPosition, wxSize(160, -1), wxCB_READONLY); |
e637208a JS |
874 | toolBar->AddControl(combo); |
875 | ||
5d7836c4 JS |
876 | toolBar->Realize(); |
877 | ||
b4e415df JS |
878 | wxSplitterWindow* splitter = new wxSplitterWindow(this, wxID_ANY, wxDefaultPosition, wxSize(100,100), wxSP_LIVE_UPDATE); |
879 | sizer->Add(splitter, 1, wxEXPAND); | |
5d7836c4 JS |
880 | |
881 | wxFont textFont = wxFont(12, wxROMAN, wxNORMAL, wxNORMAL); | |
882 | wxFont boldFont = wxFont(12, wxROMAN, wxNORMAL, wxBOLD); | |
883 | wxFont italicFont = wxFont(12, wxROMAN, wxITALIC, wxNORMAL); | |
884 | ||
cc2aecde | 885 | m_richTextCtrl = new MyRichTextCtrl(splitter, ID_RICHTEXT_CTRL, wxEmptyString, wxDefaultPosition, wxSize(200, 200), wxVSCROLL|wxHSCROLL|wxWANTS_CHARS); |
32423dd8 JS |
886 | wxASSERT(!m_richTextCtrl->GetBuffer().GetAttributes().HasFontPixelSize()); |
887 | ||
ff2baa25 JS |
888 | wxFont font(12, wxROMAN, wxNORMAL, wxNORMAL); |
889 | ||
ff2baa25 | 890 | m_richTextCtrl->SetFont(font); |
5d7836c4 | 891 | |
32423dd8 JS |
892 | wxASSERT(!m_richTextCtrl->GetBuffer().GetAttributes().HasFontPixelSize()); |
893 | ||
603f702b JS |
894 | m_richTextCtrl->SetMargins(10, 10); |
895 | ||
fe5aa22c JS |
896 | m_richTextCtrl->SetStyleSheet(wxGetApp().GetStyleSheet()); |
897 | ||
e637208a JS |
898 | combo->SetStyleSheet(wxGetApp().GetStyleSheet()); |
899 | combo->SetRichTextCtrl(m_richTextCtrl); | |
900 | combo->UpdateStyles(); | |
901 | ||
082cfe55 | 902 | wxRichTextStyleListCtrl* styleListCtrl = new wxRichTextStyleListCtrl(splitter, ID_RICHTEXT_STYLE_LIST); |
4753c7ce WS |
903 | |
904 | wxSize display = wxGetDisplaySize(); | |
905 | if ( is_pda && ( display.GetWidth() < display.GetHeight() ) ) | |
906 | { | |
082cfe55 | 907 | splitter->SplitHorizontally(m_richTextCtrl, styleListCtrl); |
4753c7ce WS |
908 | } |
909 | else | |
910 | { | |
082cfe55 | 911 | splitter->SplitVertically(m_richTextCtrl, styleListCtrl, 500); |
4753c7ce | 912 | } |
5d7836c4 | 913 | |
b4e415df JS |
914 | Layout(); |
915 | ||
c59f6793 JS |
916 | splitter->UpdateSize(); |
917 | ||
082cfe55 JS |
918 | styleListCtrl->SetStyleSheet(wxGetApp().GetStyleSheet()); |
919 | styleListCtrl->SetRichTextCtrl(m_richTextCtrl); | |
920 | styleListCtrl->UpdateStyles(); | |
5d7836c4 | 921 | |
99404ab0 JS |
922 | WriteInitialText(); |
923 | } | |
924 | ||
925 | // Write text | |
926 | void MyFrame::WriteInitialText() | |
927 | { | |
cc2aecde | 928 | MyRichTextCtrl& r = *m_richTextCtrl; |
5d7836c4 | 929 | |
99404ab0 JS |
930 | r.SetDefaultStyle(wxRichTextAttr()); |
931 | ||
b4e415df | 932 | r.Freeze(); |
cc2aecde | 933 | |
5d7836c4 JS |
934 | r.BeginSuppressUndo(); |
935 | ||
936 | r.BeginParagraphSpacing(0, 20); | |
937 | ||
938 | r.BeginAlignment(wxTEXT_ALIGNMENT_CENTRE); | |
939 | r.BeginBold(); | |
940 | ||
941 | r.BeginFontSize(14); | |
c3e54dee | 942 | |
50f65288 | 943 | wxString lineBreak = (wxChar) 29; |
c3e54dee | 944 | |
99404ab0 | 945 | r.WriteText(wxString(wxT("Welcome to wxRichTextCtrl, a wxWidgets control")) + lineBreak + wxT("for editing and presenting styled text and images\n")); |
5d7836c4 | 946 | r.EndFontSize(); |
5d7836c4 JS |
947 | |
948 | r.BeginItalic(); | |
949 | r.WriteText(wxT("by Julian Smart")); | |
950 | r.EndItalic(); | |
951 | ||
952 | r.EndBold(); | |
5d7836c4 | 953 | r.Newline(); |
42688aea | 954 | |
5d7836c4 JS |
955 | r.WriteImage(wxBitmap(zebra_xpm)); |
956 | ||
5d7836c4 JS |
957 | r.Newline(); |
958 | r.Newline(); | |
959 | ||
99404ab0 JS |
960 | r.EndAlignment(); |
961 | ||
32423dd8 JS |
962 | #if 0 |
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."))); | |
965 | r.Newline(); | |
966 | r.EndAlignment(); | |
967 | #endif | |
968 | ||
cdaed652 | 969 | r.BeginAlignment(wxTEXT_ALIGNMENT_LEFT); |
24777478 JS |
970 | wxRichTextAttr imageAttr; |
971 | imageAttr.GetTextBoxAttr().SetFloatMode(wxTEXT_BOX_ATTR_FLOAT_LEFT); | |
cdaed652 | 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."))); |
24777478 | 973 | r.WriteImage(wxBitmap(zebra_xpm), wxBITMAP_TYPE_PNG, imageAttr); |
75936ec6 | 974 | |
24777478 JS |
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); | |
5ad9ae3a | 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."))); |
cdaed652 VZ |
980 | r.EndAlignment(); |
981 | r.Newline(); | |
982 | ||
5d7836c4 | 983 | r.WriteText(wxT("What can you do with this thing? ")); |
42688aea | 984 | |
5d7836c4 JS |
985 | r.WriteImage(wxBitmap(smiley_xpm)); |
986 | r.WriteText(wxT(" Well, you can change text ")); | |
987 | ||
ea92bb67 | 988 | r.BeginTextColour(*wxRED); |
5d7836c4 JS |
989 | r.WriteText(wxT("colour, like this red bit.")); |
990 | r.EndTextColour(); | |
991 | ||
3e541562 JS |
992 | wxRichTextAttr backgroundColourAttr; |
993 | backgroundColourAttr.SetBackgroundColour(*wxGREEN); | |
ea92bb67 | 994 | backgroundColourAttr.SetTextColour(*wxBLUE); |
3e541562 JS |
995 | r.BeginStyle(backgroundColourAttr); |
996 | r.WriteText(wxT(" And this blue on green bit.")); | |
997 | r.EndStyle(); | |
5d7836c4 JS |
998 | |
999 | r.WriteText(wxT(" Naturally you can make things ")); | |
1000 | r.BeginBold(); | |
1001 | r.WriteText(wxT("bold ")); | |
1002 | r.EndBold(); | |
1003 | r.BeginItalic(); | |
1004 | r.WriteText(wxT("or italic ")); | |
1005 | r.EndItalic(); | |
1006 | r.BeginUnderline(); | |
1007 | r.WriteText(wxT("or underlined.")); | |
1008 | r.EndUnderline(); | |
1009 | ||
1010 | r.BeginFontSize(14); | |
1011 | r.WriteText(wxT(" Different font sizes on the same line is allowed, too.")); | |
1012 | r.EndFontSize(); | |
1013 | ||
1014 | r.WriteText(wxT(" Next we'll show an indented paragraph.")); | |
1015 | ||
5d7836c4 JS |
1016 | r.Newline(); |
1017 | ||
99404ab0 | 1018 | r.BeginLeftIndent(60); |
5d7836c4 | 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.")); |
5d7836c4 JS |
1020 | r.Newline(); |
1021 | ||
99404ab0 JS |
1022 | r.EndLeftIndent(); |
1023 | ||
5d7836c4 JS |
1024 | r.WriteText(wxT("Next, we'll show a first-line indent, achieved using BeginLeftIndent(100, -40).")); |
1025 | ||
5d7836c4 JS |
1026 | r.Newline(); |
1027 | ||
99404ab0 | 1028 | r.BeginLeftIndent(100, -40); |
5d7836c4 | 1029 | |
99404ab0 | 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.")); |
5d7836c4 JS |
1031 | r.Newline(); |
1032 | ||
99404ab0 | 1033 | r.EndLeftIndent(); |
5d7836c4 | 1034 | |
99404ab0 | 1035 | r.WriteText(wxT("Numbered bullets are possible, again using subindents:")); |
5d7836c4 JS |
1036 | r.Newline(); |
1037 | ||
99404ab0 | 1038 | r.BeginNumberedBullet(1, 100, 60); |
082cfe55 | 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.")); |
99404ab0 | 1040 | r.Newline(); |
5d7836c4 JS |
1041 | r.EndNumberedBullet(); |
1042 | ||
1043 | r.BeginNumberedBullet(2, 100, 60); | |
5d7836c4 | 1044 | r.WriteText(wxT("This is my second item.")); |
5d7836c4 | 1045 | r.Newline(); |
99404ab0 | 1046 | r.EndNumberedBullet(); |
5d7836c4 JS |
1047 | |
1048 | r.WriteText(wxT("The following paragraph is right-indented:")); | |
99404ab0 | 1049 | r.Newline(); |
5d7836c4 JS |
1050 | |
1051 | r.BeginRightIndent(200); | |
5d7836c4 JS |
1052 | |
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.")); | |
5d7836c4 JS |
1054 | r.Newline(); |
1055 | ||
99404ab0 JS |
1056 | r.EndRightIndent(); |
1057 | ||
5d7836c4 | 1058 | r.WriteText(wxT("The following paragraph is right-aligned with 1.5 line spacing:")); |
99404ab0 | 1059 | r.Newline(); |
5d7836c4 JS |
1060 | |
1061 | r.BeginAlignment(wxTEXT_ALIGNMENT_RIGHT); | |
1062 | r.BeginLineSpacing(wxTEXT_ATTR_LINE_SPACING_HALF); | |
5d7836c4 | 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.")); |
99404ab0 | 1064 | r.Newline(); |
5d7836c4 JS |
1065 | r.EndLineSpacing(); |
1066 | r.EndAlignment(); | |
1067 | ||
7f0d9d71 JS |
1068 | wxArrayInt tabs; |
1069 | tabs.Add(400); | |
1070 | tabs.Add(600); | |
1071 | tabs.Add(800); | |
1072 | tabs.Add(1000); | |
24777478 | 1073 | wxRichTextAttr attr; |
7f0d9d71 JS |
1074 | attr.SetFlags(wxTEXT_ATTR_TABS); |
1075 | attr.SetTabs(tabs); | |
1076 | r.SetDefaultStyle(attr); | |
4753c7ce | 1077 | |
7f0d9d71 | 1078 | r.WriteText(wxT("This line contains tabs:\tFirst tab\tSecond tab\tThird tab")); |
5d7836c4 | 1079 | r.Newline(); |
99404ab0 | 1080 | |
5d7836c4 | 1081 | r.WriteText(wxT("Other notable features of wxRichTextCtrl include:")); |
99404ab0 | 1082 | r.Newline(); |
5d7836c4 JS |
1083 | |
1084 | r.BeginSymbolBullet(wxT('*'), 100, 60); | |
5d7836c4 | 1085 | r.WriteText(wxT("Compatibility with wxTextCtrl API")); |
99404ab0 | 1086 | r.Newline(); |
5d7836c4 JS |
1087 | r.EndSymbolBullet(); |
1088 | ||
1089 | r.BeginSymbolBullet(wxT('*'), 100, 60); | |
5d7836c4 | 1090 | r.WriteText(wxT("Easy stack-based BeginXXX()...EndXXX() style setting in addition to SetStyle()")); |
99404ab0 | 1091 | r.Newline(); |
5d7836c4 JS |
1092 | r.EndSymbolBullet(); |
1093 | ||
1094 | r.BeginSymbolBullet(wxT('*'), 100, 60); | |
5d7836c4 | 1095 | r.WriteText(wxT("XML loading and saving")); |
99404ab0 | 1096 | r.Newline(); |
5d7836c4 JS |
1097 | r.EndSymbolBullet(); |
1098 | ||
1099 | r.BeginSymbolBullet(wxT('*'), 100, 60); | |
5d7836c4 | 1100 | r.WriteText(wxT("Undo/Redo, with batching option and Undo suppressing")); |
99404ab0 | 1101 | r.Newline(); |
5d7836c4 JS |
1102 | r.EndSymbolBullet(); |
1103 | ||
1104 | r.BeginSymbolBullet(wxT('*'), 100, 60); | |
5d7836c4 | 1105 | r.WriteText(wxT("Clipboard copy and paste")); |
99404ab0 | 1106 | r.Newline(); |
5d7836c4 JS |
1107 | r.EndSymbolBullet(); |
1108 | ||
1109 | r.BeginSymbolBullet(wxT('*'), 100, 60); | |
5d7836c4 | 1110 | r.WriteText(wxT("wxRichTextStyleSheet with named character and paragraph styles, and control for applying named styles")); |
99404ab0 | 1111 | r.Newline(); |
5d7836c4 JS |
1112 | r.EndSymbolBullet(); |
1113 | ||
1114 | r.BeginSymbolBullet(wxT('*'), 100, 60); | |
5d7836c4 | 1115 | r.WriteText(wxT("A design that can easily be extended to other content types, ultimately with text boxes, tables, controls, and so on")); |
5d7836c4 | 1116 | r.Newline(); |
99404ab0 | 1117 | r.EndSymbolBullet(); |
5d7836c4 | 1118 | |
720cc10a JS |
1119 | // Make a style suitable for showing a URL |
1120 | wxRichTextAttr urlStyle; | |
1121 | urlStyle.SetTextColour(*wxBLUE); | |
1122 | urlStyle.SetFontUnderlined(true); | |
1123 | ||
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")); | |
1128 | r.EndURL(); | |
1129 | r.EndStyle(); | |
1130 | r.WriteText(wxT(". Click on the URL to generate an event.")); | |
1131 | ||
1132 | r.Newline(); | |
1133 | ||
99404ab0 | 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")); |
5d7836c4 JS |
1135 | |
1136 | r.EndParagraphSpacing(); | |
603f702b | 1137 | |
32423dd8 | 1138 | #if 1 |
603f702b JS |
1139 | { |
1140 | // Add a text box | |
1141 | ||
1142 | r.Newline(); | |
75936ec6 | 1143 | |
603f702b JS |
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); | |
5d7836c4 | 1149 | |
603f702b JS |
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); | |
1153 | ||
1154 | wxRichTextBox* textBox = r.WriteTextBox(attr); | |
1155 | r.SetFocusObject(textBox); | |
1156 | ||
1157 | r.WriteText(wxT("This is a text box. Just testing! Once more unto the breach, dear friends, once more...")); | |
1158 | ||
1159 | r.SetFocusObject(NULL); // Set the focus back to the main buffer | |
1160 | r.SetInsertionPointEnd(); | |
1161 | } | |
1162 | #endif | |
1163 | #if 1 | |
1164 | { | |
1165 | // Add a table | |
1166 | ||
1167 | r.Newline(); | |
75936ec6 | 1168 | |
603f702b JS |
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(); | |
1175 | ||
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); | |
1179 | ||
1180 | wxRichTextAttr cellAttr = attr; | |
1181 | cellAttr.GetTextBoxAttr().GetWidth().SetValue(200, wxTEXT_ATTR_UNITS_PIXELS); | |
1182 | cellAttr.GetTextBoxAttr().GetHeight().SetValue(150, wxTEXT_ATTR_UNITS_PIXELS); | |
1183 | ||
f7667b84 JS |
1184 | //wxRichTextTable* table = r.WriteTable(3, 2, attr, cellAttr); |
1185 | wxRichTextTable* table = r.WriteTable(24, 2, attr, cellAttr); | |
603f702b JS |
1186 | int i, j; |
1187 | for (j = 0; j < table->GetRowCount(); j++) | |
1188 | { | |
1189 | for (i = 0; i < table->GetColumnCount(); i++) | |
1190 | { | |
1191 | wxString msg = wxString::Format(wxT("This is cell %d, %d"), (j+1), (i+1)); | |
1192 | r.SetFocusObject(table->GetCell(j, i)); | |
1193 | r.WriteText(msg); | |
1194 | } | |
1195 | } | |
1196 | r.SetFocusObject(NULL); // Set the focus back to the main buffer | |
1197 | r.SetInsertionPointEnd(); | |
1198 | } | |
1199 | #endif | |
75936ec6 | 1200 | |
32423dd8 JS |
1201 | r.Newline(); |
1202 | ||
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.")); | |
1216 | ||
1217 | r.Newline(); | |
5d7836c4 | 1218 | r.EndSuppressUndo(); |
b4e415df JS |
1219 | |
1220 | // Add some locked content first - needs Undo to be enabled | |
1221 | { | |
1222 | r.BeginLock(); | |
1223 | r.WriteText(wxString(wxT("This is a locked object."))); | |
1224 | r.EndLock(); | |
1225 | ||
1226 | r.WriteText(wxString(wxT(" This is unlocked text. "))); | |
1227 | ||
1228 | r.BeginLock(); | |
1229 | r.WriteText(wxString(wxT("More locked content."))); | |
1230 | r.EndLock(); | |
1231 | r.Newline(); | |
1232 | ||
1233 | // Flush the Undo buffer | |
1234 | r.GetCommandProcessor()->ClearCommands(); | |
1235 | } | |
1236 | ||
1237 | r.Thaw(); | |
5d7836c4 JS |
1238 | } |
1239 | ||
5d7836c4 JS |
1240 | // event handlers |
1241 | ||
1242 | void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) | |
1243 | { | |
1244 | // true is to force the frame to close | |
1245 | Close(true); | |
1246 | } | |
1247 | ||
1248 | void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) | |
1249 | { | |
1250 | wxString msg; | |
9a83f860 VZ |
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); | |
5d7836c4 JS |
1253 | } |
1254 | ||
1255 | // Forward command events to the current rich text control, if any | |
1256 | bool MyFrame::ProcessEvent(wxEvent& event) | |
1257 | { | |
1258 | if (event.IsCommandEvent() && !event.IsKindOf(CLASSINFO(wxChildFocusEvent))) | |
1259 | { | |
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 | |
1264 | ||
1265 | static int s_eventType = 0; | |
1266 | static wxWindowID s_id = 0; | |
1267 | ||
1268 | if (s_id != event.GetId() && s_eventType != event.GetEventType()) | |
1269 | { | |
1270 | s_eventType = event.GetEventType(); | |
1271 | s_id = event.GetId(); | |
9a173d48 | 1272 | |
5d7836c4 | 1273 | wxWindow* focusWin = wxFindFocusDescendant(this); |
004867db | 1274 | if (focusWin && focusWin->GetEventHandler()->ProcessEvent(event)) |
5d7836c4 JS |
1275 | { |
1276 | //s_command = NULL; | |
1277 | s_eventType = 0; | |
1278 | s_id = 0; | |
9a173d48 | 1279 | return true; |
5d7836c4 JS |
1280 | } |
1281 | ||
1282 | s_eventType = 0; | |
1283 | s_id = 0; | |
1284 | } | |
1285 | else | |
1286 | { | |
9a173d48 | 1287 | return false; |
5d7836c4 JS |
1288 | } |
1289 | } | |
1290 | ||
1291 | return wxFrame::ProcessEvent(event); | |
1292 | } | |
1293 | ||
011b3dcb | 1294 | void MyFrame::OnOpen(wxCommandEvent& WXUNUSED(event)) |
5d7836c4 | 1295 | { |
9a173d48 WS |
1296 | wxString path; |
1297 | wxString filename; | |
1e967276 JS |
1298 | wxArrayInt fileTypes; |
1299 | ||
1300 | wxString filter = wxRichTextBuffer::GetExtWildcard(false, false, & fileTypes); | |
9a173d48 | 1301 | if (!filter.empty()) |
5d7836c4 JS |
1302 | filter += wxT("|"); |
1303 | filter += wxT("All files (*.*)|*.*"); | |
1304 | ||
5d7836c4 JS |
1305 | wxFileDialog dialog(this, |
1306 | _("Choose a filename"), | |
1307 | path, | |
1308 | filename, | |
1309 | filter, | |
ff3e84ff | 1310 | wxFD_OPEN); |
5d7836c4 JS |
1311 | |
1312 | if (dialog.ShowModal() == wxID_OK) | |
1313 | { | |
1314 | wxString path = dialog.GetPath(); | |
9a173d48 WS |
1315 | |
1316 | if (!path.empty()) | |
5d7836c4 | 1317 | { |
1e967276 | 1318 | int filterIndex = dialog.GetFilterIndex(); |
dbf38e88 WS |
1319 | int fileType = (filterIndex < (int) fileTypes.GetCount()) |
1320 | ? fileTypes[filterIndex] | |
1321 | : wxRICHTEXT_TYPE_TEXT; | |
1e967276 | 1322 | m_richTextCtrl->LoadFile(path, fileType); |
5d7836c4 JS |
1323 | } |
1324 | } | |
1325 | } | |
1326 | ||
1327 | void MyFrame::OnSave(wxCommandEvent& event) | |
1328 | { | |
9a173d48 | 1329 | if (m_richTextCtrl->GetFilename().empty()) |
5d7836c4 JS |
1330 | { |
1331 | OnSaveAs(event); | |
1332 | return; | |
1333 | } | |
1334 | m_richTextCtrl->SaveFile(); | |
1335 | } | |
1336 | ||
011b3dcb | 1337 | void MyFrame::OnSaveAs(wxCommandEvent& WXUNUSED(event)) |
5d7836c4 JS |
1338 | { |
1339 | wxString filter = wxRichTextBuffer::GetExtWildcard(false, true); | |
9a173d48 WS |
1340 | wxString path; |
1341 | wxString filename; | |
5d7836c4 JS |
1342 | |
1343 | wxFileDialog dialog(this, | |
1344 | _("Choose a filename"), | |
1345 | path, | |
1346 | filename, | |
1347 | filter, | |
ff3e84ff | 1348 | wxFD_SAVE); |
5d7836c4 JS |
1349 | |
1350 | if (dialog.ShowModal() == wxID_OK) | |
1351 | { | |
1352 | wxString path = dialog.GetPath(); | |
9a173d48 WS |
1353 | |
1354 | if (!path.empty()) | |
5d7836c4 | 1355 | { |
bec80f4f JS |
1356 | wxBusyCursor busy; |
1357 | wxStopWatch stopwatch; | |
1358 | ||
5d7836c4 | 1359 | m_richTextCtrl->SaveFile(path); |
bec80f4f JS |
1360 | |
1361 | long t = stopwatch.Time(); | |
1362 | wxLogDebug(wxT("Saving took %ldms"), t); | |
1363 | wxMessageBox(wxString::Format(wxT("Saving took %ldms"), t)); | |
5d7836c4 JS |
1364 | } |
1365 | } | |
1366 | } | |
1367 | ||
011b3dcb | 1368 | void MyFrame::OnBold(wxCommandEvent& WXUNUSED(event)) |
5d7836c4 JS |
1369 | { |
1370 | m_richTextCtrl->ApplyBoldToSelection(); | |
1371 | } | |
1372 | ||
011b3dcb | 1373 | void MyFrame::OnItalic(wxCommandEvent& WXUNUSED(event)) |
5d7836c4 JS |
1374 | { |
1375 | m_richTextCtrl->ApplyItalicToSelection(); | |
1376 | } | |
1377 | ||
011b3dcb | 1378 | void MyFrame::OnUnderline(wxCommandEvent& WXUNUSED(event)) |
5d7836c4 JS |
1379 | { |
1380 | m_richTextCtrl->ApplyUnderlineToSelection(); | |
1381 | } | |
1382 | ||
75936ec6 JS |
1383 | void MyFrame::OnStrikethrough(wxCommandEvent& WXUNUSED(event)) |
1384 | { | |
1385 | m_richTextCtrl->ApplyTextEffectToSelection(wxTEXT_ATTR_EFFECT_STRIKETHROUGH); | |
1386 | } | |
1387 | ||
1388 | void MyFrame::OnSuperscript(wxCommandEvent& WXUNUSED(event)) | |
1389 | { | |
1390 | m_richTextCtrl->ApplyTextEffectToSelection(wxTEXT_ATTR_EFFECT_SUPERSCRIPT); | |
1391 | } | |
1392 | ||
1393 | void MyFrame::OnSubscript(wxCommandEvent& WXUNUSED(event)) | |
1394 | { | |
1395 | m_richTextCtrl->ApplyTextEffectToSelection(wxTEXT_ATTR_EFFECT_SUBSCRIPT); | |
1396 | } | |
1397 | ||
5d7836c4 JS |
1398 | |
1399 | void MyFrame::OnUpdateBold(wxUpdateUIEvent& event) | |
1400 | { | |
1401 | event.Check(m_richTextCtrl->IsSelectionBold()); | |
1402 | } | |
1403 | ||
1404 | void MyFrame::OnUpdateItalic(wxUpdateUIEvent& event) | |
1405 | { | |
1406 | event.Check(m_richTextCtrl->IsSelectionItalics()); | |
1407 | } | |
1408 | ||
1409 | void MyFrame::OnUpdateUnderline(wxUpdateUIEvent& event) | |
1410 | { | |
1411 | event.Check(m_richTextCtrl->IsSelectionUnderlined()); | |
1412 | } | |
1413 | ||
75936ec6 JS |
1414 | void MyFrame::OnUpdateStrikethrough(wxUpdateUIEvent& event) |
1415 | { | |
1416 | event.Check(m_richTextCtrl->DoesSelectionHaveTextEffectFlag(wxTEXT_ATTR_EFFECT_STRIKETHROUGH)); | |
1417 | } | |
1418 | ||
1419 | void MyFrame::OnUpdateSuperscript(wxUpdateUIEvent& event) | |
1420 | { | |
1421 | event.Check(m_richTextCtrl->DoesSelectionHaveTextEffectFlag(wxTEXT_ATTR_EFFECT_SUPERSCRIPT)); | |
1422 | } | |
1423 | ||
1424 | void MyFrame::OnUpdateSubscript(wxUpdateUIEvent& event) | |
1425 | { | |
1426 | event.Check(m_richTextCtrl->DoesSelectionHaveTextEffectFlag(wxTEXT_ATTR_EFFECT_SUBSCRIPT)); | |
1427 | } | |
1428 | ||
011b3dcb | 1429 | void MyFrame::OnAlignLeft(wxCommandEvent& WXUNUSED(event)) |
5d7836c4 JS |
1430 | { |
1431 | m_richTextCtrl->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_LEFT); | |
1432 | } | |
1433 | ||
011b3dcb | 1434 | void MyFrame::OnAlignCentre(wxCommandEvent& WXUNUSED(event)) |
5d7836c4 JS |
1435 | { |
1436 | m_richTextCtrl->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_CENTRE); | |
1437 | } | |
1438 | ||
011b3dcb | 1439 | void MyFrame::OnAlignRight(wxCommandEvent& WXUNUSED(event)) |
5d7836c4 JS |
1440 | { |
1441 | m_richTextCtrl->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_RIGHT); | |
1442 | } | |
1443 | ||
1444 | void MyFrame::OnUpdateAlignLeft(wxUpdateUIEvent& event) | |
1445 | { | |
1446 | event.Check(m_richTextCtrl->IsSelectionAligned(wxTEXT_ALIGNMENT_LEFT)); | |
1447 | } | |
1448 | ||
1449 | void MyFrame::OnUpdateAlignCentre(wxUpdateUIEvent& event) | |
1450 | { | |
1451 | event.Check(m_richTextCtrl->IsSelectionAligned(wxTEXT_ALIGNMENT_CENTRE)); | |
1452 | } | |
1453 | ||
1454 | void MyFrame::OnUpdateAlignRight(wxUpdateUIEvent& event) | |
1455 | { | |
1456 | event.Check(m_richTextCtrl->IsSelectionAligned(wxTEXT_ALIGNMENT_RIGHT)); | |
1457 | } | |
1458 | ||
011b3dcb | 1459 | void MyFrame::OnFont(wxCommandEvent& WXUNUSED(event)) |
5d7836c4 | 1460 | { |
8c9c49a1 JS |
1461 | wxRichTextRange range; |
1462 | if (m_richTextCtrl->HasSelection()) | |
1463 | range = m_richTextCtrl->GetSelectionRange(); | |
1464 | else | |
1465 | range = wxRichTextRange(0, m_richTextCtrl->GetLastPosition()+1); | |
1466 | ||
1467 | int pages = wxRICHTEXT_FORMAT_FONT; | |
1468 | ||
1469 | wxRichTextFormattingDialog formatDlg(pages, this); | |
32423dd8 | 1470 | formatDlg.SetOptions(wxRichTextFormattingDialog::Option_AllowPixelFontSize); |
8c9c49a1 JS |
1471 | formatDlg.GetStyle(m_richTextCtrl, range); |
1472 | ||
1473 | if (formatDlg.ShowModal() == wxID_OK) | |
1474 | { | |
42688aea | 1475 | formatDlg.ApplyStyle(m_richTextCtrl, range, wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_OPTIMIZE|wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY); |
8c9c49a1 | 1476 | } |
8c9c49a1 JS |
1477 | } |
1478 | ||
cdaed652 VZ |
1479 | void MyFrame::OnImage(wxCommandEvent& WXUNUSED(event)) |
1480 | { | |
1481 | wxRichTextRange range; | |
1482 | wxASSERT(m_richTextCtrl->HasSelection()); | |
1483 | ||
1484 | range = m_richTextCtrl->GetSelectionRange(); | |
1485 | wxASSERT(range.ToInternal().GetLength() == 1); | |
1486 | ||
603f702b | 1487 | wxRichTextImage* image = wxDynamicCast(m_richTextCtrl->GetFocusObject()->GetLeafObjectAtPosition(range.GetStart()), wxRichTextImage); |
cdaed652 VZ |
1488 | if (image) |
1489 | { | |
603f702b | 1490 | wxRichTextObjectPropertiesDialog imageDlg(image, this); |
cdaed652 VZ |
1491 | |
1492 | if (imageDlg.ShowModal() == wxID_OK) | |
1493 | { | |
603f702b | 1494 | imageDlg.ApplyStyle(m_richTextCtrl); |
cdaed652 VZ |
1495 | } |
1496 | } | |
1497 | } | |
1498 | ||
8c9c49a1 JS |
1499 | void MyFrame::OnParagraph(wxCommandEvent& WXUNUSED(event)) |
1500 | { | |
1501 | wxRichTextRange range; | |
1502 | if (m_richTextCtrl->HasSelection()) | |
1503 | range = m_richTextCtrl->GetSelectionRange(); | |
1504 | else | |
1505 | range = wxRichTextRange(0, m_richTextCtrl->GetLastPosition()+1); | |
1506 | ||
1507 | int pages = wxRICHTEXT_FORMAT_INDENTS_SPACING|wxRICHTEXT_FORMAT_TABS|wxRICHTEXT_FORMAT_BULLETS; | |
1508 | ||
1509 | wxRichTextFormattingDialog formatDlg(pages, this); | |
1510 | formatDlg.GetStyle(m_richTextCtrl, range); | |
1511 | ||
1512 | if (formatDlg.ShowModal() == wxID_OK) | |
1513 | { | |
1514 | formatDlg.ApplyStyle(m_richTextCtrl, range); | |
1515 | } | |
1516 | } | |
1517 | ||
1518 | void MyFrame::OnFormat(wxCommandEvent& WXUNUSED(event)) | |
1519 | { | |
1520 | wxRichTextRange range; | |
1521 | if (m_richTextCtrl->HasSelection()) | |
1522 | range = m_richTextCtrl->GetSelectionRange(); | |
1523 | else | |
1524 | range = wxRichTextRange(0, m_richTextCtrl->GetLastPosition()+1); | |
1525 | ||
1526 | int pages = wxRICHTEXT_FORMAT_FONT|wxRICHTEXT_FORMAT_INDENTS_SPACING|wxRICHTEXT_FORMAT_TABS|wxRICHTEXT_FORMAT_BULLETS; | |
1527 | ||
1528 | wxRichTextFormattingDialog formatDlg(pages, this); | |
1529 | formatDlg.GetStyle(m_richTextCtrl, range); | |
1530 | ||
1531 | if (formatDlg.ShowModal() == wxID_OK) | |
1532 | { | |
1533 | formatDlg.ApplyStyle(m_richTextCtrl, range); | |
1534 | } | |
1535 | } | |
1536 | ||
1537 | void MyFrame::OnUpdateFormat(wxUpdateUIEvent& event) | |
1538 | { | |
1539 | event.Enable(m_richTextCtrl->HasSelection()); | |
5d7836c4 JS |
1540 | } |
1541 | ||
cdaed652 VZ |
1542 | void MyFrame::OnUpdateImage(wxUpdateUIEvent& event) |
1543 | { | |
1544 | wxRichTextRange range; | |
1545 | wxRichTextObject *obj; | |
1546 | ||
1547 | range = m_richTextCtrl->GetSelectionRange(); | |
1548 | if (range.ToInternal().GetLength() == 1) | |
1549 | { | |
603f702b | 1550 | obj = m_richTextCtrl->GetFocusObject()->GetLeafObjectAtPosition(range.GetStart()); |
cdaed652 VZ |
1551 | if (obj && obj->IsKindOf(CLASSINFO(wxRichTextImage))) |
1552 | { | |
1553 | event.Enable(true); | |
1554 | return; | |
1555 | } | |
1556 | } | |
1557 | ||
1558 | event.Enable(false); | |
1559 | } | |
1560 | ||
011b3dcb | 1561 | void MyFrame::OnIndentMore(wxCommandEvent& WXUNUSED(event)) |
5d7836c4 | 1562 | { |
44cc96a8 | 1563 | wxRichTextAttr attr; |
5d7836c4 JS |
1564 | attr.SetFlags(wxTEXT_ATTR_LEFT_INDENT); |
1565 | ||
1566 | if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr)) | |
1567 | { | |
1568 | wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint()); | |
1569 | if (m_richTextCtrl->HasSelection()) | |
1570 | range = m_richTextCtrl->GetSelectionRange(); | |
1571 | ||
5d7836c4 JS |
1572 | attr.SetLeftIndent(attr.GetLeftIndent() + 100); |
1573 | ||
1574 | attr.SetFlags(wxTEXT_ATTR_LEFT_INDENT); | |
1575 | m_richTextCtrl->SetStyle(range, attr); | |
1576 | } | |
1577 | } | |
1578 | ||
011b3dcb | 1579 | void MyFrame::OnIndentLess(wxCommandEvent& WXUNUSED(event)) |
5d7836c4 | 1580 | { |
44cc96a8 | 1581 | wxRichTextAttr attr; |
5d7836c4 JS |
1582 | attr.SetFlags(wxTEXT_ATTR_LEFT_INDENT); |
1583 | ||
1584 | if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr)) | |
1585 | { | |
1586 | wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint()); | |
1587 | if (m_richTextCtrl->HasSelection()) | |
1588 | range = m_richTextCtrl->GetSelectionRange(); | |
1589 | ||
c3e54dee | 1590 | if (attr.GetLeftIndent() > 0) |
5d7836c4 | 1591 | { |
c3e54dee | 1592 | attr.SetLeftIndent(wxMax(0, attr.GetLeftIndent() - 100)); |
9a173d48 | 1593 | |
5d7836c4 JS |
1594 | m_richTextCtrl->SetStyle(range, attr); |
1595 | } | |
1596 | } | |
1597 | } | |
1598 | ||
011b3dcb | 1599 | void MyFrame::OnLineSpacingHalf(wxCommandEvent& WXUNUSED(event)) |
5d7836c4 | 1600 | { |
44cc96a8 | 1601 | wxRichTextAttr attr; |
5d7836c4 JS |
1602 | attr.SetFlags(wxTEXT_ATTR_LINE_SPACING); |
1603 | ||
1604 | if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr)) | |
1605 | { | |
1606 | wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint()); | |
1607 | if (m_richTextCtrl->HasSelection()) | |
1608 | range = m_richTextCtrl->GetSelectionRange(); | |
1609 | ||
5d7836c4 JS |
1610 | attr.SetFlags(wxTEXT_ATTR_LINE_SPACING); |
1611 | attr.SetLineSpacing(15); | |
9a173d48 | 1612 | |
5d7836c4 JS |
1613 | m_richTextCtrl->SetStyle(range, attr); |
1614 | } | |
1615 | } | |
1616 | ||
011b3dcb | 1617 | void MyFrame::OnLineSpacingDouble(wxCommandEvent& WXUNUSED(event)) |
5d7836c4 | 1618 | { |
44cc96a8 | 1619 | wxRichTextAttr attr; |
5d7836c4 JS |
1620 | attr.SetFlags(wxTEXT_ATTR_LINE_SPACING); |
1621 | ||
1622 | if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr)) | |
1623 | { | |
1624 | wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint()); | |
1625 | if (m_richTextCtrl->HasSelection()) | |
1626 | range = m_richTextCtrl->GetSelectionRange(); | |
1627 | ||
5d7836c4 JS |
1628 | attr.SetFlags(wxTEXT_ATTR_LINE_SPACING); |
1629 | attr.SetLineSpacing(20); | |
9a173d48 | 1630 | |
5d7836c4 JS |
1631 | m_richTextCtrl->SetStyle(range, attr); |
1632 | } | |
1633 | } | |
1634 | ||
011b3dcb | 1635 | void MyFrame::OnLineSpacingSingle(wxCommandEvent& WXUNUSED(event)) |
5d7836c4 | 1636 | { |
44cc96a8 | 1637 | wxRichTextAttr attr; |
5d7836c4 JS |
1638 | attr.SetFlags(wxTEXT_ATTR_LINE_SPACING); |
1639 | ||
1640 | if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr)) | |
1641 | { | |
1642 | wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint()); | |
1643 | if (m_richTextCtrl->HasSelection()) | |
1644 | range = m_richTextCtrl->GetSelectionRange(); | |
1645 | ||
5d7836c4 JS |
1646 | attr.SetFlags(wxTEXT_ATTR_LINE_SPACING); |
1647 | attr.SetLineSpacing(0); // Can also use 10 | |
9a173d48 | 1648 | |
5d7836c4 JS |
1649 | m_richTextCtrl->SetStyle(range, attr); |
1650 | } | |
1651 | } | |
1652 | ||
011b3dcb | 1653 | void MyFrame::OnParagraphSpacingMore(wxCommandEvent& WXUNUSED(event)) |
5d7836c4 | 1654 | { |
44cc96a8 | 1655 | wxRichTextAttr attr; |
5d7836c4 JS |
1656 | attr.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER); |
1657 | ||
1658 | if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr)) | |
1659 | { | |
1660 | wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint()); | |
1661 | if (m_richTextCtrl->HasSelection()) | |
1662 | range = m_richTextCtrl->GetSelectionRange(); | |
1663 | ||
5d7836c4 JS |
1664 | attr.SetParagraphSpacingAfter(attr.GetParagraphSpacingAfter() + 20); |
1665 | ||
1666 | attr.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER); | |
1667 | m_richTextCtrl->SetStyle(range, attr); | |
1668 | } | |
1669 | } | |
1670 | ||
011b3dcb | 1671 | void MyFrame::OnParagraphSpacingLess(wxCommandEvent& WXUNUSED(event)) |
5d7836c4 | 1672 | { |
44cc96a8 | 1673 | wxRichTextAttr attr; |
5d7836c4 JS |
1674 | attr.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER); |
1675 | ||
1676 | if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr)) | |
1677 | { | |
1678 | wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint()); | |
1679 | if (m_richTextCtrl->HasSelection()) | |
1680 | range = m_richTextCtrl->GetSelectionRange(); | |
1681 | ||
1682 | if (attr.GetParagraphSpacingAfter() >= 20) | |
1683 | { | |
5d7836c4 | 1684 | attr.SetParagraphSpacingAfter(attr.GetParagraphSpacingAfter() - 20); |
9a173d48 | 1685 | |
5d7836c4 JS |
1686 | attr.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER); |
1687 | m_richTextCtrl->SetStyle(range, attr); | |
1688 | } | |
1689 | } | |
1690 | } | |
1691 | ||
99404ab0 JS |
1692 | void MyFrame::OnReload(wxCommandEvent& WXUNUSED(event)) |
1693 | { | |
1694 | m_richTextCtrl->Clear(); | |
1695 | WriteInitialText(); | |
1696 | } | |
1697 | ||
011b3dcb | 1698 | void MyFrame::OnViewHTML(wxCommandEvent& WXUNUSED(event)) |
5d7836c4 JS |
1699 | { |
1700 | wxDialog dialog(this, wxID_ANY, _("HTML"), wxDefaultPosition, wxSize(500, 400), wxDEFAULT_DIALOG_STYLE); | |
1701 | ||
1702 | wxBoxSizer* boxSizer = new wxBoxSizer(wxVERTICAL); | |
1703 | dialog.SetSizer(boxSizer); | |
1704 | ||
1705 | wxHtmlWindow* win = new wxHtmlWindow(& dialog, wxID_ANY, wxDefaultPosition, wxSize(500, 400), wxSUNKEN_BORDER); | |
1706 | boxSizer->Add(win, 1, wxALL, 5); | |
1707 | ||
1708 | wxButton* cancelButton = new wxButton(& dialog, wxID_CANCEL, wxT("&Close")); | |
1709 | boxSizer->Add(cancelButton, 0, wxALL|wxCENTRE, 5); | |
1710 | ||
1711 | wxString text; | |
1712 | wxStringOutputStream strStream(& text); | |
1713 | ||
1714 | wxRichTextHTMLHandler htmlHandler; | |
720cc10a | 1715 | htmlHandler.SetFlags(wxRICHTEXT_HANDLER_SAVE_IMAGES_TO_MEMORY); |
c3e54dee | 1716 | |
50f65288 WS |
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); | |
c3e54dee | 1725 | |
50f65288 | 1726 | htmlHandler.SetFontSizeMapping(fontSizeMapping); |
720cc10a | 1727 | |
5d7836c4 JS |
1728 | if (htmlHandler.SaveFile(& m_richTextCtrl->GetBuffer(), strStream)) |
1729 | { | |
1730 | win->SetPage(text); | |
1731 | } | |
1732 | ||
1733 | boxSizer->Fit(& dialog); | |
1734 | ||
1735 | dialog.ShowModal(); | |
720cc10a JS |
1736 | |
1737 | // Now delete the temporary in-memory images | |
1738 | htmlHandler.DeleteTemporaryImages(); | |
5d7836c4 | 1739 | } |
fe5aa22c JS |
1740 | |
1741 | // Demonstrates how you can change the style sheets and have the changes | |
1742 | // reflected in the control content without wiping out character formatting. | |
1743 | ||
1744 | void MyFrame::OnSwitchStyleSheets(wxCommandEvent& WXUNUSED(event)) | |
1745 | { | |
1746 | static wxRichTextStyleSheet* gs_AlternateStyleSheet = NULL; | |
1747 | ||
e4723634 | 1748 | wxRichTextStyleListCtrl *styleList = (wxRichTextStyleListCtrl*) FindWindow(ID_RICHTEXT_STYLE_LIST); |
fe5aa22c JS |
1749 | wxRichTextStyleComboCtrl* styleCombo = (wxRichTextStyleComboCtrl*) FindWindow(ID_RICHTEXT_STYLE_COMBO); |
1750 | ||
8881d9f0 | 1751 | wxRichTextStyleSheet* sheet = m_richTextCtrl->GetStyleSheet(); |
fe5aa22c JS |
1752 | |
1753 | // One-time creation of an alternate style sheet | |
1754 | if (!gs_AlternateStyleSheet) | |
1755 | { | |
1756 | gs_AlternateStyleSheet = new wxRichTextStyleSheet(*sheet); | |
1757 | ||
1758 | // Make some modifications | |
1759 | for (int i = 0; i < (int) gs_AlternateStyleSheet->GetParagraphStyleCount(); i++) | |
1760 | { | |
1761 | wxRichTextParagraphStyleDefinition* def = gs_AlternateStyleSheet->GetParagraphStyle(i); | |
1762 | ||
1763 | if (def->GetStyle().HasTextColour()) | |
1764 | def->GetStyle().SetTextColour(*wxBLUE); | |
1765 | ||
1766 | if (def->GetStyle().HasAlignment()) | |
1767 | { | |
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); | |
1772 | } | |
1773 | if (def->GetStyle().HasLeftIndent()) | |
1774 | { | |
1775 | def->GetStyle().SetLeftIndent(def->GetStyle().GetLeftIndent() * 2); | |
1776 | } | |
1777 | } | |
1778 | } | |
1779 | ||
1780 | // Switch sheets | |
1781 | wxRichTextStyleSheet* tmp = gs_AlternateStyleSheet; | |
1782 | gs_AlternateStyleSheet = sheet; | |
1783 | sheet = tmp; | |
1784 | ||
8881d9f0 JS |
1785 | m_richTextCtrl->SetStyleSheet(sheet); |
1786 | m_richTextCtrl->ApplyStyleSheet(sheet); // Makes the control reflect the new style definitions | |
fe5aa22c JS |
1787 | |
1788 | styleList->SetStyleSheet(sheet); | |
1789 | styleList->UpdateStyles(); | |
1790 | ||
1791 | styleCombo->SetStyleSheet(sheet); | |
1792 | styleCombo->UpdateStyles(); | |
1793 | } | |
8c9c49a1 | 1794 | |
e4723634 JS |
1795 | void MyFrame::OnManageStyles(wxCommandEvent& WXUNUSED(event)) |
1796 | { | |
8881d9f0 | 1797 | wxRichTextStyleSheet* sheet = m_richTextCtrl->GetStyleSheet(); |
e4723634 JS |
1798 | |
1799 | int flags = wxRICHTEXT_ORGANISER_CREATE_STYLES|wxRICHTEXT_ORGANISER_EDIT_STYLES; | |
1800 | ||
1801 | wxRichTextStyleOrganiserDialog dlg(flags, sheet, NULL, this, wxID_ANY, _("Style Manager")); | |
1802 | dlg.ShowModal(); | |
1803 | } | |
1804 | ||
8c9c49a1 JS |
1805 | void MyFrame::OnInsertSymbol(wxCommandEvent& WXUNUSED(event)) |
1806 | { | |
44cc96a8 | 1807 | wxRichTextAttr attr; |
8c9c49a1 | 1808 | attr.SetFlags(wxTEXT_ATTR_FONT); |
8881d9f0 | 1809 | m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr); |
8c9c49a1 JS |
1810 | |
1811 | wxString currentFontName; | |
a1b806b9 | 1812 | if (attr.HasFont() && attr.GetFont().IsOk()) |
8c9c49a1 JS |
1813 | currentFontName = attr.GetFont().GetFaceName(); |
1814 | ||
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. | |
1818 | ||
1819 | wxSymbolPickerDialog dlg(wxT("*"), wxEmptyString, currentFontName, this); | |
1820 | ||
1821 | if (dlg.ShowModal() == wxID_OK) | |
1822 | { | |
1823 | if (dlg.HasSelection()) | |
1824 | { | |
8881d9f0 | 1825 | long insertionPoint = m_richTextCtrl->GetInsertionPoint(); |
8c9c49a1 | 1826 | |
8881d9f0 | 1827 | m_richTextCtrl->WriteText(dlg.GetSymbol()); |
8c9c49a1 JS |
1828 | |
1829 | if (!dlg.UseNormalFont()) | |
1830 | { | |
1831 | wxFont font(attr.GetFont()); | |
23c386ba | 1832 | font.SetFaceName(dlg.GetFontName()); |
8c9c49a1 | 1833 | attr.SetFont(font); |
8881d9f0 | 1834 | m_richTextCtrl->SetStyle(insertionPoint, insertionPoint+1, attr); |
8c9c49a1 JS |
1835 | } |
1836 | } | |
1837 | } | |
1838 | } | |
082cfe55 JS |
1839 | |
1840 | void MyFrame::OnNumberList(wxCommandEvent& WXUNUSED(event)) | |
1841 | { | |
8881d9f0 | 1842 | if (m_richTextCtrl->HasSelection()) |
082cfe55 | 1843 | { |
8881d9f0 JS |
1844 | wxRichTextRange range = m_richTextCtrl->GetSelectionRange(); |
1845 | m_richTextCtrl->SetListStyle(range, wxT("Numbered List 1"), wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_RENUMBER); | |
082cfe55 JS |
1846 | } |
1847 | } | |
1848 | ||
e4723634 JS |
1849 | void MyFrame::OnBulletsAndNumbering(wxCommandEvent& WXUNUSED(event)) |
1850 | { | |
8881d9f0 | 1851 | wxRichTextStyleSheet* sheet = m_richTextCtrl->GetStyleSheet(); |
e4723634 JS |
1852 | |
1853 | int flags = wxRICHTEXT_ORGANISER_BROWSE_NUMBERING; | |
1854 | ||
8881d9f0 | 1855 | wxRichTextStyleOrganiserDialog dlg(flags, sheet, m_richTextCtrl, this, wxID_ANY, _("Bullets and Numbering")); |
e4723634 JS |
1856 | if (dlg.ShowModal() == wxID_OK) |
1857 | { | |
1858 | if (dlg.GetSelectedStyleDefinition()) | |
1859 | dlg.ApplyStyle(); | |
1860 | } | |
1861 | } | |
1862 | ||
082cfe55 JS |
1863 | void MyFrame::OnItemizeList(wxCommandEvent& WXUNUSED(event)) |
1864 | { | |
8881d9f0 | 1865 | if (m_richTextCtrl->HasSelection()) |
082cfe55 | 1866 | { |
8881d9f0 JS |
1867 | wxRichTextRange range = m_richTextCtrl->GetSelectionRange(); |
1868 | m_richTextCtrl->SetListStyle(range, wxT("Bullet List 1")); | |
082cfe55 JS |
1869 | } |
1870 | } | |
1871 | ||
1872 | void MyFrame::OnRenumberList(wxCommandEvent& WXUNUSED(event)) | |
1873 | { | |
8881d9f0 | 1874 | if (m_richTextCtrl->HasSelection()) |
082cfe55 | 1875 | { |
8881d9f0 JS |
1876 | wxRichTextRange range = m_richTextCtrl->GetSelectionRange(); |
1877 | m_richTextCtrl->NumberList(range, NULL, wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_RENUMBER); | |
082cfe55 JS |
1878 | } |
1879 | } | |
1880 | ||
1881 | void MyFrame::OnPromoteList(wxCommandEvent& WXUNUSED(event)) | |
1882 | { | |
8881d9f0 | 1883 | if (m_richTextCtrl->HasSelection()) |
082cfe55 | 1884 | { |
8881d9f0 JS |
1885 | wxRichTextRange range = m_richTextCtrl->GetSelectionRange(); |
1886 | m_richTextCtrl->PromoteList(1, range, NULL); | |
082cfe55 JS |
1887 | } |
1888 | } | |
1889 | ||
1890 | void MyFrame::OnDemoteList(wxCommandEvent& WXUNUSED(event)) | |
1891 | { | |
8881d9f0 | 1892 | if (m_richTextCtrl->HasSelection()) |
082cfe55 | 1893 | { |
8881d9f0 JS |
1894 | wxRichTextRange range = m_richTextCtrl->GetSelectionRange(); |
1895 | m_richTextCtrl->PromoteList(-1, range, NULL); | |
082cfe55 JS |
1896 | } |
1897 | } | |
1898 | ||
1899 | void MyFrame::OnClearList(wxCommandEvent& WXUNUSED(event)) | |
1900 | { | |
8881d9f0 | 1901 | if (m_richTextCtrl->HasSelection()) |
082cfe55 | 1902 | { |
8881d9f0 JS |
1903 | wxRichTextRange range = m_richTextCtrl->GetSelectionRange(); |
1904 | m_richTextCtrl->ClearListStyle(range); | |
082cfe55 JS |
1905 | } |
1906 | } | |
1907 | ||
720cc10a JS |
1908 | void MyFrame::OnInsertURL(wxCommandEvent& WXUNUSED(event)) |
1909 | { | |
1910 | wxString url = wxGetTextFromUser(_("URL:"), _("Insert URL")); | |
1911 | if (!url.IsEmpty()) | |
1912 | { | |
720cc10a JS |
1913 | // Make a style suitable for showing a URL |
1914 | wxRichTextAttr urlStyle; | |
1915 | urlStyle.SetTextColour(*wxBLUE); | |
1916 | urlStyle.SetFontUnderlined(true); | |
c3e54dee | 1917 | |
8881d9f0 JS |
1918 | m_richTextCtrl->BeginStyle(urlStyle); |
1919 | m_richTextCtrl->BeginURL(url); | |
1920 | m_richTextCtrl->WriteText(url); | |
1921 | m_richTextCtrl->EndURL(); | |
1922 | m_richTextCtrl->EndStyle(); | |
720cc10a JS |
1923 | } |
1924 | } | |
1925 | ||
cdaed652 VZ |
1926 | void MyFrame::OnInsertImage(wxCommandEvent& WXUNUSED(event)) |
1927 | { | |
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) | |
1930 | { | |
1931 | wxString path = dialog.GetPath(); | |
1932 | m_richTextCtrl->WriteImage(path, wxBITMAP_TYPE_ANY); | |
1933 | } | |
1934 | } | |
1935 | ||
720cc10a JS |
1936 | void MyFrame::OnURL(wxTextUrlEvent& event) |
1937 | { | |
1938 | wxMessageBox(event.GetString()); | |
1939 | } | |
1940 | ||
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) | |
1944 | { | |
1945 | event.Veto(); | |
1946 | } | |
8881d9f0 JS |
1947 | |
1948 | void MyFrame::OnPrint(wxCommandEvent& WXUNUSED(event)) | |
1949 | { | |
1950 | wxGetApp().GetPrinting()->PrintBuffer(m_richTextCtrl->GetBuffer()); | |
1951 | } | |
1952 | ||
1953 | void MyFrame::OnPreview(wxCommandEvent& WXUNUSED(event)) | |
1954 | { | |
1955 | wxGetApp().GetPrinting()->PreviewBuffer(m_richTextCtrl->GetBuffer()); | |
1956 | } | |
1957 | ||
1958 | void MyFrame::OnPageSetup(wxCommandEvent& WXUNUSED(event)) | |
1959 | { | |
24777478 JS |
1960 | wxDialog dialog(this, wxID_ANY, wxT("Testing"), wxPoint(10, 10), wxSize(400, 300), wxDEFAULT_DIALOG_STYLE); |
1961 | ||
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); | |
1965 | ||
d275b15d | 1966 | new wxRichTextCtrl(panel, wxID_ANY, wxEmptyString, wxPoint(5, 5), wxSize(200, 150), wxVSCROLL|wxTE_READONLY); |
24777478 JS |
1967 | nb->AddPage(panel, wxT("Page 1")); |
1968 | ||
d275b15d | 1969 | new wxRichTextCtrl(panel2, wxID_ANY, wxEmptyString, wxPoint(5, 5), wxSize(200, 150), wxVSCROLL|wxTE_READONLY); |
24777478 JS |
1970 | nb->AddPage(panel2, wxT("Page 2")); |
1971 | ||
d275b15d | 1972 | new wxButton(& dialog, wxID_OK, wxT("OK"), wxPoint(5, 180)); |
24777478 JS |
1973 | |
1974 | dialog.ShowModal(); | |
1975 | ||
1976 | // wxGetApp().GetPrinting()->PageSetup(); | |
8881d9f0 | 1977 | } |
cc2aecde | 1978 | |
32423dd8 JS |
1979 | void MyFrame::OnSetFontScale(wxCommandEvent& WXUNUSED(event)) |
1980 | { | |
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) | |
1984 | { | |
1985 | double scale = 1.0; | |
1986 | wxSscanf(text, wxT("%lf"), & scale); | |
1987 | m_richTextCtrl->SetFontScale(scale, true); | |
1988 | } | |
1989 | } | |
1990 | ||
1991 | void MyFrame::OnSetDimensionScale(wxCommandEvent& WXUNUSED(event)) | |
1992 | { | |
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) | |
1996 | { | |
1997 | double scale = 1.0; | |
1998 | wxSscanf(text, wxT("%lf"), & scale); | |
1999 | m_richTextCtrl->SetDimensionScale(scale, true); | |
2000 | } | |
2001 | } | |
2002 | ||
cc2aecde JS |
2003 | void MyRichTextCtrl::PrepareContent(wxRichTextParagraphLayoutBox& container) |
2004 | { | |
2005 | if (IsLocked()) | |
2006 | { | |
2007 | // Lock all content that's about to be added to the control | |
2008 | wxRichTextObjectList::compatibility_iterator node = container.GetChildren().GetFirst(); | |
2009 | while (node) | |
2010 | { | |
2011 | wxRichTextParagraph* para = wxDynamicCast(node->GetData(), wxRichTextParagraph); | |
2012 | if (para) | |
2013 | { | |
2014 | wxRichTextObjectList::compatibility_iterator childNode = para->GetChildren().GetFirst(); | |
2015 | while (childNode) | |
2016 | { | |
2017 | wxRichTextObject* obj = childNode->GetData(); | |
2018 | obj->GetProperties().SetProperty(wxT("Lock"), m_lockId); | |
2019 | ||
2020 | childNode = childNode->GetNext(); | |
2021 | } | |
2022 | } | |
2023 | node = node->GetNext(); | |
2024 | } | |
2025 | } | |
2026 | } | |
2027 | ||
2028 | bool MyRichTextCtrl::CanDeleteRange(wxRichTextParagraphLayoutBox& container, const wxRichTextRange& range) const | |
2029 | { | |
2030 | long i; | |
2031 | for (i = range.GetStart(); i < range.GetEnd(); i++) | |
2032 | { | |
2033 | wxRichTextObject* obj = container.GetLeafObjectAtPosition(i); | |
2034 | if (obj && obj->GetProperties().HasProperty(wxT("Lock"))) | |
2035 | { | |
2036 | return false; | |
2037 | } | |
2038 | } | |
2039 | return true; | |
2040 | } | |
2041 | ||
2042 | bool MyRichTextCtrl::CanInsertContent(wxRichTextParagraphLayoutBox& container, long pos) const | |
2043 | { | |
2044 | wxRichTextObject* child1 = container.GetLeafObjectAtPosition(pos); | |
2045 | wxRichTextObject* child2 = container.GetLeafObjectAtPosition(pos-1); | |
2046 | ||
2047 | long lock1 = -1, lock2 = -1; | |
2048 | ||
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")); | |
2053 | ||
2054 | if (lock1 != -1 && lock1 == lock2) | |
2055 | return false; | |
2056 | ||
2057 | // Don't allow insertion before a locked object if it's at the beginning of the buffer. | |
2058 | if (pos == 0 && lock1 != -1) | |
2059 | return false; | |
2060 | ||
2061 | return true; | |
2062 | } | |
2063 | ||
2064 | ||
2065 | class wxRichTextEnhancedDrawingHandler: public wxRichTextDrawingHandler | |
2066 | { | |
2067 | public: | |
2068 | wxRichTextEnhancedDrawingHandler() | |
2069 | { | |
2070 | SetName(wxT("enhanceddrawing")); | |
2071 | m_lockBackgroundColour = wxColour(220, 220, 220); | |
2072 | } | |
2073 | ||
2074 | /** | |
2075 | Returns @true if this object has virtual attributes that we can provide. | |
2076 | */ | |
2077 | virtual bool HasVirtualAttributes(wxRichTextObject* obj) const; | |
2078 | ||
2079 | /** | |
2080 | Provides virtual attributes that we can provide. | |
2081 | */ | |
2082 | virtual bool GetVirtualAttributes(wxRichTextAttr& attr, wxRichTextObject* obj) const; | |
2083 | ||
f7667b84 JS |
2084 | /** |
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. | |
2087 | */ | |
2088 | virtual int GetVirtualSubobjectAttributesCount(wxRichTextObject* WXUNUSED(obj)) const { return 0; } | |
2089 | ||
2090 | /** | |
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. | |
2094 | */ | |
2095 | virtual int GetVirtualSubobjectAttributes(wxRichTextObject* WXUNUSED(obj), wxArrayInt& WXUNUSED(positions), wxRichTextAttrArray& WXUNUSED(attributes)) const { return 0; } | |
2096 | ||
2097 | /** | |
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. | |
2101 | */ | |
2102 | virtual bool HasVirtualText(const wxRichTextPlainText* WXUNUSED(obj)) const { return false; } | |
2103 | ||
2104 | /** | |
2105 | Gets the virtual text for this object. | |
2106 | */ | |
2107 | virtual bool GetVirtualText(const wxRichTextPlainText* WXUNUSED(obj), wxString& WXUNUSED(text)) const { return false; } | |
2108 | ||
cc2aecde JS |
2109 | wxColour m_lockBackgroundColour; |
2110 | }; | |
2111 | ||
2112 | bool wxRichTextEnhancedDrawingHandler::HasVirtualAttributes(wxRichTextObject* obj) const | |
2113 | { | |
2114 | return obj->GetProperties().HasProperty(wxT("Lock")); | |
2115 | } | |
2116 | ||
2117 | bool wxRichTextEnhancedDrawingHandler::GetVirtualAttributes(wxRichTextAttr& attr, wxRichTextObject* obj) const | |
2118 | { | |
2119 | if (obj->GetProperties().HasProperty(wxT("Lock"))) | |
2120 | { | |
2121 | attr.SetBackgroundColour(m_lockBackgroundColour); | |
2122 | return true; | |
2123 | } | |
2124 | return false; | |
2125 | } | |
2126 | ||
2127 | void MyRichTextCtrl::SetEnhancedDrawingHandler() | |
2128 | { | |
2129 | wxRichTextBuffer::AddDrawingHandler(new wxRichTextEnhancedDrawingHandler); | |
2130 | } |