1///////////////////////////////////////////////////////////////////////////// 2// Name: samples/richtext/richtext.cpp 3// Purpose: wxWidgets rich text editor sample 4// Author: Julian Smart 5// Modified by: 6// Created: 2005-10-02 7// RCS-ID: $Id: richtext.cpp 51739 2008-02-12 17:05:32Z JS $ 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" 37 38#if wxUSE_FILESYSTEM 39#include "wx/filesys.h" 40#include "wx/fs_mem.h" 41#endif 42 43#if wxUSE_HELP 44#include "wx/cshelp.h" 45#endif 46 47#ifndef __WXMSW__ 48 #include "../sample.xpm" 49#endif 50 51#include "bitmaps/smiley.xpm" 52// #include "bitmaps/idea.xpm" 53#include "bitmaps/zebra.xpm" 54 55#include "bitmaps/open.xpm" 56#include "bitmaps/save.xpm" 57#include "bitmaps/copy.xpm" 58#include "bitmaps/cut.xpm" 59#include "bitmaps/paste.xpm" 60#include "bitmaps/undo.xpm" 61#include "bitmaps/redo.xpm" 62#include "bitmaps/bold.xpm" 63#include "bitmaps/italic.xpm" 64#include "bitmaps/underline.xpm" 65 66#include "bitmaps/alignleft.xpm" 67#include "bitmaps/alignright.xpm" 68#include "bitmaps/centre.xpm" 69#include "bitmaps/font.xpm" 70#include "bitmaps/indentless.xpm" 71#include "bitmaps/indentmore.xpm" 72 73#include "wx/richtext/richtextctrl.h" 74#include "wx/richtext/richtextstyles.h" 75#include "wx/richtext/richtextxml.h" 76#include "wx/richtext/richtexthtml.h" 77#include "wx/richtext/richtextformatdlg.h" 78#include "wx/richtext/richtextsymboldlg.h" 79#include "wx/richtext/richtextstyledlg.h" 80#include "wx/richtext/richtextprint.h" 81 82// ---------------------------------------------------------------------------- 83// resources 84// ---------------------------------------------------------------------------- 85 86// ---------------------------------------------------------------------------- 87// private classes 88// ---------------------------------------------------------------------------- 89 90// Define a new application type, each program should derive a class from wxApp 91class MyApp : public wxApp 92{ 93public: 94 // override base class virtuals 95 // ---------------------------- 96 97 // this one is called on application startup and is a good place for the app 98 // initialization (doing it here and not in the ctor allows to have an error 99 // return: if OnInit() returns false, the application terminates) 100 virtual bool OnInit(); 101 virtual int OnExit(); 102 103 void CreateStyles(); 104 105 wxRichTextStyleSheet* GetStyleSheet() const { return m_styleSheet; } 106 wxRichTextPrinting* GetPrinting() const { return m_printing; } 107 108 wxRichTextStyleSheet* m_styleSheet; 109 wxRichTextPrinting* m_printing; 110}; 111 112// Define a new frame type: this is going to be our main frame 113class MyFrame : public wxFrame 114{ 115public: 116 // ctor(s) 117 MyFrame(const wxString& title, wxWindowID id, const wxPoint& pos = wxDefaultPosition, 118 const wxSize& size = wxDefaultSize, long style = wxDEFAULT_FRAME_STYLE); 119 120 // event handlers (these functions should _not_ be virtual) 121 void OnQuit(wxCommandEvent& event); 122 void OnAbout(wxCommandEvent& event); 123 124 void OnOpen(wxCommandEvent& event); 125 void OnSave(wxCommandEvent& event); 126 void OnSaveAs(wxCommandEvent& event); 127 128 void OnBold(wxCommandEvent& event); 129 void OnItalic(wxCommandEvent& event); 130 void OnUnderline(wxCommandEvent& event); 131 132 void OnUpdateBold(wxUpdateUIEvent& event); 133 void OnUpdateItalic(wxUpdateUIEvent& event); 134 void OnUpdateUnderline(wxUpdateUIEvent& event); 135 136 void OnAlignLeft(wxCommandEvent& event); 137 void OnAlignCentre(wxCommandEvent& event); 138 void OnAlignRight(wxCommandEvent& event); 139 140 void OnUpdateAlignLeft(wxUpdateUIEvent& event); 141 void OnUpdateAlignCentre(wxUpdateUIEvent& event); 142 void OnUpdateAlignRight(wxUpdateUIEvent& event); 143 144 void OnIndentMore(wxCommandEvent& event); 145 void OnIndentLess(wxCommandEvent& event); 146 147 void OnFont(wxCommandEvent& event); 148 void OnParagraph(wxCommandEvent& event); 149 void OnFormat(wxCommandEvent& event); 150 void OnUpdateFormat(wxUpdateUIEvent& event); 151 152 void OnInsertSymbol(wxCommandEvent& event); 153 154 void OnLineSpacingHalf(wxCommandEvent& event); 155 void OnLineSpacingDouble(wxCommandEvent& event); 156 void OnLineSpacingSingle(wxCommandEvent& event); 157 158 void OnParagraphSpacingMore(wxCommandEvent& event); 159 void OnParagraphSpacingLess(wxCommandEvent& event); 160 161 void OnNumberList(wxCommandEvent& event); 162 void OnBulletsAndNumbering(wxCommandEvent& event); 163 void OnItemizeList(wxCommandEvent& event); 164 void OnRenumberList(wxCommandEvent& event); 165 void OnPromoteList(wxCommandEvent& event); 166 void OnDemoteList(wxCommandEvent& event); 167 void OnClearList(wxCommandEvent& event); 168 169 void OnReload(wxCommandEvent& event); 170 171 void OnViewHTML(wxCommandEvent& event); 172 173 void OnSwitchStyleSheets(wxCommandEvent& event); 174 void OnManageStyles(wxCommandEvent& event); 175 176 void OnInsertURL(wxCommandEvent& event); 177 void OnURL(wxTextUrlEvent& event); 178 void OnStyleSheetReplacing(wxRichTextEvent& event); 179 180 void OnPrint(wxCommandEvent& event); 181 void OnPreview(wxCommandEvent& event); 182 void OnPageSetup(wxCommandEvent& event); 183 184 // Forward command events to the current rich text control, if any 185 bool ProcessEvent(wxEvent& event); 186 187 // Write text 188 void WriteInitialText(); 189 190private: 191 // any class wishing to process wxWidgets events must use this macro 192 DECLARE_EVENT_TABLE() 193 194 wxRichTextCtrl* m_richTextCtrl; 195}; 196 197// ---------------------------------------------------------------------------- 198// constants 199// ---------------------------------------------------------------------------- 200 201// IDs for the controls and the menu commands 202enum 203{ 204 // menu items 205 ID_Quit = wxID_EXIT, 206 ID_About = wxID_ABOUT, 207 208 ID_FORMAT_BOLD = 100, 209 ID_FORMAT_ITALIC, 210 ID_FORMAT_UNDERLINE, 211 ID_FORMAT_FONT, 212 ID_FORMAT_PARAGRAPH, 213 ID_FORMAT_CONTENT, 214 215 ID_RELOAD, 216 217 ID_INSERT_SYMBOL, 218 ID_INSERT_URL, 219 220 ID_FORMAT_ALIGN_LEFT, 221 ID_FORMAT_ALIGN_CENTRE, 222 ID_FORMAT_ALIGN_RIGHT, 223 224 ID_FORMAT_INDENT_MORE, 225 ID_FORMAT_INDENT_LESS, 226 227 ID_FORMAT_PARAGRAPH_SPACING_MORE, 228 ID_FORMAT_PARAGRAPH_SPACING_LESS, 229 230 ID_FORMAT_LINE_SPACING_HALF, 231 ID_FORMAT_LINE_SPACING_DOUBLE, 232 ID_FORMAT_LINE_SPACING_SINGLE, 233 234 ID_FORMAT_NUMBER_LIST, 235 ID_FORMAT_BULLETS_AND_NUMBERING, 236 ID_FORMAT_ITEMIZE_LIST, 237 ID_FORMAT_RENUMBER_LIST, 238 ID_FORMAT_PROMOTE_LIST, 239 ID_FORMAT_DEMOTE_LIST, 240 ID_FORMAT_CLEAR_LIST, 241 242 ID_VIEW_HTML, 243 ID_SWITCH_STYLE_SHEETS, 244 ID_MANAGE_STYLES, 245 246 ID_PRINT, 247 ID_PREVIEW, 248 ID_PAGE_SETUP, 249 250 ID_RICHTEXT_CTRL, 251 ID_RICHTEXT_STYLE_LIST, 252 ID_RICHTEXT_STYLE_COMBO 253}; 254 255// ---------------------------------------------------------------------------- 256// event tables and other macros for wxWidgets 257// ---------------------------------------------------------------------------- 258 259// the event tables connect the wxWidgets events with the functions (event 260// handlers) which process them. It can be also done at run-time, but for the 261// simple menu events like this the static method is much simpler. 262BEGIN_EVENT_TABLE(MyFrame, wxFrame) 263 EVT_MENU(ID_Quit, MyFrame::OnQuit) 264 EVT_MENU(ID_About, MyFrame::OnAbout) 265 266 EVT_MENU(wxID_OPEN, MyFrame::OnOpen) 267 EVT_MENU(wxID_SAVE, MyFrame::OnSave) 268 EVT_MENU(wxID_SAVEAS, MyFrame::OnSaveAs) 269 270 EVT_MENU(ID_FORMAT_BOLD, MyFrame::OnBold) 271 EVT_MENU(ID_FORMAT_ITALIC, MyFrame::OnItalic) 272 EVT_MENU(ID_FORMAT_UNDERLINE, MyFrame::OnUnderline) 273 274 EVT_UPDATE_UI(ID_FORMAT_BOLD, MyFrame::OnUpdateBold) 275 EVT_UPDATE_UI(ID_FORMAT_ITALIC, MyFrame::OnUpdateItalic) 276 EVT_UPDATE_UI(ID_FORMAT_UNDERLINE, MyFrame::OnUpdateUnderline) 277 278 EVT_MENU(ID_FORMAT_ALIGN_LEFT, MyFrame::OnAlignLeft) 279 EVT_MENU(ID_FORMAT_ALIGN_CENTRE, MyFrame::OnAlignCentre) 280 EVT_MENU(ID_FORMAT_ALIGN_RIGHT, MyFrame::OnAlignRight) 281 282 EVT_UPDATE_UI(ID_FORMAT_ALIGN_LEFT, MyFrame::OnUpdateAlignLeft) 283 EVT_UPDATE_UI(ID_FORMAT_ALIGN_CENTRE, MyFrame::OnUpdateAlignCentre) 284 EVT_UPDATE_UI(ID_FORMAT_ALIGN_RIGHT, MyFrame::OnUpdateAlignRight) 285 286 EVT_MENU(ID_FORMAT_FONT, MyFrame::OnFont) 287 EVT_MENU(ID_FORMAT_PARAGRAPH, MyFrame::OnParagraph) 288 EVT_MENU(ID_FORMAT_CONTENT, MyFrame::OnFormat) 289 EVT_UPDATE_UI(ID_FORMAT_CONTENT, MyFrame::OnUpdateFormat) 290 EVT_UPDATE_UI(ID_FORMAT_FONT, MyFrame::OnUpdateFormat) 291 EVT_UPDATE_UI(ID_FORMAT_PARAGRAPH, MyFrame::OnUpdateFormat) 292 EVT_MENU(ID_FORMAT_INDENT_MORE, MyFrame::OnIndentMore) 293 EVT_MENU(ID_FORMAT_INDENT_LESS, MyFrame::OnIndentLess) 294 295 EVT_MENU(ID_FORMAT_LINE_SPACING_HALF, MyFrame::OnLineSpacingHalf) 296 EVT_MENU(ID_FORMAT_LINE_SPACING_SINGLE, MyFrame::OnLineSpacingSingle) 297 EVT_MENU(ID_FORMAT_LINE_SPACING_DOUBLE, MyFrame::OnLineSpacingDouble) 298 299 EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_MORE, MyFrame::OnParagraphSpacingMore) 300 EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_LESS, MyFrame::OnParagraphSpacingLess) 301 302 EVT_MENU(ID_RELOAD, MyFrame::OnReload) 303 304 EVT_MENU(ID_INSERT_SYMBOL, MyFrame::OnInsertSymbol) 305 EVT_MENU(ID_INSERT_URL, MyFrame::OnInsertURL) 306 307 EVT_MENU(ID_FORMAT_NUMBER_LIST, MyFrame::OnNumberList) 308 EVT_MENU(ID_FORMAT_BULLETS_AND_NUMBERING, MyFrame::OnBulletsAndNumbering) 309 EVT_MENU(ID_FORMAT_ITEMIZE_LIST, MyFrame::OnItemizeList) 310 EVT_MENU(ID_FORMAT_RENUMBER_LIST, MyFrame::OnRenumberList) 311 EVT_MENU(ID_FORMAT_PROMOTE_LIST, MyFrame::OnPromoteList) 312 EVT_MENU(ID_FORMAT_DEMOTE_LIST, MyFrame::OnDemoteList) 313 EVT_MENU(ID_FORMAT_CLEAR_LIST, MyFrame::OnClearList) 314 315 EVT_MENU(ID_VIEW_HTML, MyFrame::OnViewHTML) 316 EVT_MENU(ID_SWITCH_STYLE_SHEETS, MyFrame::OnSwitchStyleSheets) 317 EVT_MENU(ID_MANAGE_STYLES, MyFrame::OnManageStyles) 318 319 EVT_MENU(ID_PRINT, MyFrame::OnPrint) 320 EVT_MENU(ID_PREVIEW, MyFrame::OnPreview) 321 EVT_MENU(ID_PAGE_SETUP, MyFrame::OnPageSetup) 322 323 EVT_TEXT_URL(wxID_ANY, MyFrame::OnURL) 324 EVT_RICHTEXT_STYLESHEET_REPLACING(wxID_ANY, MyFrame::OnStyleSheetReplacing) 325END_EVENT_TABLE() 326 327// Create a new application object: this macro will allow wxWidgets to create 328// the application object during program execution (it's better than using a 329// static object for many reasons) and also implements the accessor function 330// wxGetApp() which will return the reference of the right type (i.e. MyApp and 331// not wxApp) 332IMPLEMENT_APP(MyApp) 333 334// ============================================================================ 335// implementation 336// ============================================================================ 337 338// ---------------------------------------------------------------------------- 339// the application class 340// ---------------------------------------------------------------------------- 341 342// 'Main program' equivalent: the program execution "starts" here 343bool MyApp::OnInit() 344{ 345#if wxUSE_HELP 346 wxHelpProvider::Set(new wxSimpleHelpProvider); 347#endif 348 349 m_styleSheet = new wxRichTextStyleSheet; 350 m_printing = new wxRichTextPrinting(wxT("Test Document")); 351 352 m_printing->SetFooterText(wxT("@TITLE@"), wxRICHTEXT_PAGE_ALL, wxRICHTEXT_PAGE_CENTRE); 353 m_printing->SetFooterText(wxT("Page @PAGENUM@"), wxRICHTEXT_PAGE_ALL, wxRICHTEXT_PAGE_RIGHT); 354 355 CreateStyles(); 356 357 // Add extra handlers (plain text is automatically added) 358 wxRichTextBuffer::AddHandler(new wxRichTextXMLHandler); 359 wxRichTextBuffer::AddHandler(new wxRichTextHTMLHandler); 360 361 // Add image handlers 362#if wxUSE_LIBPNG 363 wxImage::AddHandler( new wxPNGHandler ); 364#endif 365 366#if wxUSE_LIBJPEG 367 wxImage::AddHandler( new wxJPEGHandler ); 368#endif 369 370#if wxUSE_GIF 371 wxImage::AddHandler( new wxGIFHandler ); 372#endif 373 374#if wxUSE_FILESYSTEM 375 wxFileSystem::AddHandler( new wxMemoryFSHandler ); 376#endif 377 378 // create the main application window 379 MyFrame *frame = new MyFrame(_T("wxRichTextCtrl Sample"), wxID_ANY, wxDefaultPosition, wxSize(700, 600)); 380 381 m_printing->SetParentWindow(frame); 382 383 // and show it (the frames, unlike simple controls, are not shown when 384 // created initially) 385 frame->Show(true); 386 387 // success: wxApp::OnRun() will be called which will enter the main message 388 // loop and the application will run. If we returned false here, the 389 // application would exit immediately. 390 return true; 391} 392 393int MyApp::OnExit() 394{ 395 delete m_printing; 396 delete m_styleSheet; 397 398 return 0; 399} 400 401void MyApp::CreateStyles() 402{ 403 // Paragraph styles 404 405 wxFont romanFont(12, wxROMAN, wxNORMAL, wxNORMAL); 406 wxFont swissFont(12, wxSWISS, wxNORMAL, wxNORMAL); 407 408 wxRichTextParagraphStyleDefinition* normalPara = new wxRichTextParagraphStyleDefinition(wxT("Normal")); 409 wxRichTextAttr normalAttr; 410 normalAttr.SetFontFaceName(romanFont.GetFaceName()); 411 normalAttr.SetFontSize(12); 412 // Let's set all attributes for this style 413 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| 414 wxTEXT_ATTR_PARA_SPACING_BEFORE|wxTEXT_ATTR_PARA_SPACING_AFTER|wxTEXT_ATTR_LINE_SPACING| 415 wxTEXT_ATTR_BULLET_STYLE|wxTEXT_ATTR_BULLET_NUMBER); 416 normalPara->SetStyle(normalAttr); 417 418 m_styleSheet->AddParagraphStyle(normalPara); 419 420 wxRichTextParagraphStyleDefinition* indentedPara = new wxRichTextParagraphStyleDefinition(wxT("Indented")); 421 wxRichTextAttr indentedAttr; 422 indentedAttr.SetFontFaceName(romanFont.GetFaceName()); 423 indentedAttr.SetFontSize(12); 424 indentedAttr.SetLeftIndent(100, 0); 425 // We only want to affect indentation 426 indentedAttr.SetFlags(wxTEXT_ATTR_LEFT_INDENT|wxTEXT_ATTR_RIGHT_INDENT); 427 indentedPara->SetStyle(indentedAttr); 428 429 m_styleSheet->AddParagraphStyle(indentedPara); 430 431 wxRichTextParagraphStyleDefinition* indentedPara2 = new wxRichTextParagraphStyleDefinition(wxT("Red Bold Indented")); 432 wxRichTextAttr indentedAttr2; 433 indentedAttr2.SetFontFaceName(romanFont.GetFaceName()); 434 indentedAttr2.SetFontSize(12); 435 indentedAttr2.SetFontWeight(wxBOLD); 436 indentedAttr2.SetTextColour(*wxRED); 437 indentedAttr2.SetFontSize(12); 438 indentedAttr2.SetLeftIndent(100, 0); 439 // We want to affect indentation, font and text colour 440 indentedAttr2.SetFlags(wxTEXT_ATTR_LEFT_INDENT|wxTEXT_ATTR_RIGHT_INDENT|wxTEXT_ATTR_FONT|wxTEXT_ATTR_TEXT_COLOUR); 441 indentedPara2->SetStyle(indentedAttr2); 442 443 m_styleSheet->AddParagraphStyle(indentedPara2); 444 445 wxRichTextParagraphStyleDefinition* flIndentedPara = new wxRichTextParagraphStyleDefinition(wxT("First Line Indented")); 446 wxRichTextAttr flIndentedAttr; 447 flIndentedAttr.SetFontFaceName(swissFont.GetFaceName()); 448 flIndentedAttr.SetFontSize(12); 449 flIndentedAttr.SetLeftIndent(100, -100); 450 // We only want to affect indentation 451 flIndentedAttr.SetFlags(wxTEXT_ATTR_LEFT_INDENT|wxTEXT_ATTR_RIGHT_INDENT); 452 flIndentedPara->SetStyle(flIndentedAttr); 453 454 m_styleSheet->AddParagraphStyle(flIndentedPara); 455 456 // Character styles 457 458 wxRichTextCharacterStyleDefinition* boldDef = new wxRichTextCharacterStyleDefinition(wxT("Bold")); 459 wxRichTextAttr boldAttr; 460 boldAttr.SetFontFaceName(romanFont.GetFaceName()); 461 boldAttr.SetFontSize(12); 462 boldAttr.SetFontWeight(wxBOLD); 463 // We only want to affect boldness 464 boldAttr.SetFlags(wxTEXT_ATTR_FONT_WEIGHT); 465 boldDef->SetStyle(boldAttr); 466 467 m_styleSheet->AddCharacterStyle(boldDef); 468 469 wxRichTextCharacterStyleDefinition* italicDef = new wxRichTextCharacterStyleDefinition(wxT("Italic")); 470 wxRichTextAttr italicAttr; 471 italicAttr.SetFontFaceName(romanFont.GetFaceName()); 472 italicAttr.SetFontSize(12); 473 italicAttr.SetFontStyle(wxITALIC); 474 // We only want to affect italics 475 italicAttr.SetFlags(wxTEXT_ATTR_FONT_ITALIC); 476 italicDef->SetStyle(italicAttr); 477 478 m_styleSheet->AddCharacterStyle(italicDef); 479 480 wxRichTextCharacterStyleDefinition* redDef = new wxRichTextCharacterStyleDefinition(wxT("Red Bold")); 481 wxRichTextAttr redAttr; 482 redAttr.SetFontFaceName(romanFont.GetFaceName()); 483 redAttr.SetFontSize(12); 484 redAttr.SetFontWeight(wxBOLD); 485 redAttr.SetTextColour(*wxRED); 486 // We only want to affect colour, weight and face 487 redAttr.SetFlags(wxTEXT_ATTR_FONT_FACE|wxTEXT_ATTR_FONT_WEIGHT|wxTEXT_ATTR_TEXT_COLOUR); 488 redDef->SetStyle(redAttr); 489 490 m_styleSheet->AddCharacterStyle(redDef); 491 492 wxRichTextListStyleDefinition* bulletList = new wxRichTextListStyleDefinition(wxT("Bullet List 1")); 493 int i; 494 for (i = 0; i < 10; i++) 495 { 496 wxString bulletText; 497 if (i == 0) 498 bulletText = wxT("standard/circle"); 499 else if (i == 1) 500 bulletText = wxT("standard/square"); 501 else if (i == 2) 502 bulletText = wxT("standard/circle"); 503 else if (i == 3) 504 bulletText = wxT("standard/square"); 505 else 506 bulletText = wxT("standard/circle"); 507 508 bulletList->SetAttributes(i, (i+1)*60, 60, wxTEXT_ATTR_BULLET_STYLE_STANDARD, bulletText); 509 } 510 511 m_styleSheet->AddListStyle(bulletList); 512 513 wxRichTextListStyleDefinition* numberedList = new wxRichTextListStyleDefinition(wxT("Numbered List 1")); 514 for (i = 0; i < 10; i++) 515 { 516 long numberStyle; 517 if (i == 0) 518 numberStyle = wxTEXT_ATTR_BULLET_STYLE_ARABIC|wxTEXT_ATTR_BULLET_STYLE_PERIOD; 519 else if (i == 1) 520 numberStyle = wxTEXT_ATTR_BULLET_STYLE_LETTERS_LOWER|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES; 521 else if (i == 2) 522 numberStyle = wxTEXT_ATTR_BULLET_STYLE_ROMAN_LOWER|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES; 523 else if (i == 3) 524 numberStyle = wxTEXT_ATTR_BULLET_STYLE_ROMAN_UPPER|wxTEXT_ATTR_BULLET_STYLE_PARENTHESES; 525 else 526 numberStyle = wxTEXT_ATTR_BULLET_STYLE_ARABIC|wxTEXT_ATTR_BULLET_STYLE_PERIOD; 527 528 numberStyle |= wxTEXT_ATTR_BULLET_STYLE_ALIGN_RIGHT; 529 530 numberedList->SetAttributes(i, (i+1)*60, 60, numberStyle); 531 } 532 533 m_styleSheet->AddListStyle(numberedList); 534 535 wxRichTextListStyleDefinition* outlineList = new wxRichTextListStyleDefinition(wxT("Outline List 1")); 536 for (i = 0; i < 10; i++) 537 { 538 long numberStyle; 539 if (i < 4) 540 numberStyle = wxTEXT_ATTR_BULLET_STYLE_OUTLINE|wxTEXT_ATTR_BULLET_STYLE_PERIOD; 541 else 542 numberStyle = wxTEXT_ATTR_BULLET_STYLE_ARABIC|wxTEXT_ATTR_BULLET_STYLE_PERIOD; 543 544 outlineList->SetAttributes(i, (i+1)*120, 120, numberStyle); 545 } 546 547 m_styleSheet->AddListStyle(outlineList); 548} 549 550// ---------------------------------------------------------------------------- 551// main frame 552// ---------------------------------------------------------------------------- 553 554// frame constructor 555MyFrame::MyFrame(const wxString& title, wxWindowID id, const wxPoint& pos, 556 const wxSize& size, long style) 557 : wxFrame(NULL, id, title, pos, size, style) 558{ 559 // set the frame icon 560 SetIcon(wxICON(sample)); 561 562 // create a menu bar 563 wxMenu *fileMenu = new wxMenu; 564 565 // the "About" item should be in the help menu 566 wxMenu *helpMenu = new wxMenu; 567 helpMenu->Append(ID_About, _T("&About...\tF1"), _T("Show about dialog")); 568 569 fileMenu->Append(wxID_OPEN, _T("&Open\tCtrl+O"), _T("Open a file")); 570 fileMenu->Append(wxID_SAVE, _T("&Save\tCtrl+S"), _T("Save a file")); 571 fileMenu->Append(wxID_SAVEAS, _T("&Save As...\tF12"), _T("Save to a new file")); 572 fileMenu->AppendSeparator(); 573 fileMenu->Append(ID_RELOAD, _T("&Reload Text\tF2"), _T("Reload the initial text")); 574 fileMenu->AppendSeparator(); 575 fileMenu->Append(ID_PAGE_SETUP, _T("Page Set&up..."), _T("Page setup")); 576 fileMenu->Append(ID_PRINT, _T("&Print...\tCtrl+P"), _T("Print")); 577 fileMenu->Append(ID_PREVIEW, _T("Print Pre&view"), _T("Print preview")); 578 fileMenu->AppendSeparator(); 579 fileMenu->Append(ID_VIEW_HTML, _T("&View as HTML"), _T("View HTML")); 580 fileMenu->AppendSeparator(); 581 fileMenu->Append(ID_Quit, _T("E&xit\tAlt+X"), _T("Quit this program")); 582 583 wxMenu* editMenu = new wxMenu; 584 editMenu->Append(wxID_UNDO, _("&Undo\tCtrl+Z")); 585 editMenu->Append(wxID_REDO, _("&Redo\tCtrl+Y")); 586 editMenu->AppendSeparator(); 587 editMenu->Append(wxID_CUT, _("Cu&t\tCtrl+X")); 588 editMenu->Append(wxID_COPY, _("&Copy\tCtrl+C")); 589 editMenu->Append(wxID_PASTE, _("&Paste\tCtrl+V")); 590 591 editMenu->AppendSeparator(); 592 editMenu->Append(wxID_SELECTALL, _("Select A&ll\tCtrl+A")); 593#if 0 594 editMenu->AppendSeparator(); 595 editMenu->Append(wxID_FIND, _("&Find...\tCtrl+F")); 596 editMenu->Append(stID_FIND_REPLACE, _("&Replace...\tCtrl+R")); 597#endif 598 599 wxMenu* formatMenu = new wxMenu; 600 formatMenu->AppendCheckItem(ID_FORMAT_BOLD, _("&Bold\tCtrl+B")); 601 formatMenu->AppendCheckItem(ID_FORMAT_ITALIC, _("&Italic\tCtrl+I")); 602 formatMenu->AppendCheckItem(ID_FORMAT_UNDERLINE, _("&Underline\tCtrl+U")); 603 formatMenu->AppendSeparator(); 604 formatMenu->AppendCheckItem(ID_FORMAT_ALIGN_LEFT, _("L&eft Align")); 605 formatMenu->AppendCheckItem(ID_FORMAT_ALIGN_RIGHT, _("&Right Align")); 606 formatMenu->AppendCheckItem(ID_FORMAT_ALIGN_CENTRE, _("&Centre")); 607 formatMenu->AppendSeparator(); 608 formatMenu->Append(ID_FORMAT_INDENT_MORE, _("Indent &More")); 609 formatMenu->Append(ID_FORMAT_INDENT_LESS, _("Indent &Less")); 610 formatMenu->AppendSeparator(); 611 formatMenu->Append(ID_FORMAT_PARAGRAPH_SPACING_MORE, _("Increase Paragraph &Spacing")); 612 formatMenu->Append(ID_FORMAT_PARAGRAPH_SPACING_LESS, _("Decrease &Paragraph Spacing")); 613 formatMenu->AppendSeparator(); 614 formatMenu->Append(ID_FORMAT_LINE_SPACING_SINGLE, _("Normal Line Spacing")); 615 formatMenu->Append(ID_FORMAT_LINE_SPACING_HALF, _("1.5 Line Spacing")); 616 formatMenu->Append(ID_FORMAT_LINE_SPACING_DOUBLE, _("Double Line Spacing")); 617 formatMenu->AppendSeparator(); 618 formatMenu->Append(ID_FORMAT_FONT, _("&Font...")); 619 formatMenu->Append(ID_FORMAT_PARAGRAPH, _("&Paragraph...")); 620 formatMenu->Append(ID_FORMAT_CONTENT, _("Font and Pa&ragraph...\tShift+Ctrl+F")); 621 formatMenu->AppendSeparator(); 622 formatMenu->Append(ID_SWITCH_STYLE_SHEETS, _("&Switch Style Sheets")); 623 formatMenu->Append(ID_MANAGE_STYLES, _("&Manage Styles")); 624 625 wxMenu* listsMenu = new wxMenu; 626 listsMenu->Append(ID_FORMAT_BULLETS_AND_NUMBERING, _("Bullets and &Numbering...")); 627 listsMenu->AppendSeparator(); 628 listsMenu->Append(ID_FORMAT_NUMBER_LIST, _("Number List")); 629 listsMenu->Append(ID_FORMAT_ITEMIZE_LIST, _("Itemize List")); 630 listsMenu->Append(ID_FORMAT_RENUMBER_LIST, _("Renumber List")); 631 listsMenu->Append(ID_FORMAT_PROMOTE_LIST, _("Promote List Items")); 632 listsMenu->Append(ID_FORMAT_DEMOTE_LIST, _("Demote List Items")); 633 listsMenu->Append(ID_FORMAT_CLEAR_LIST, _("Clear List Formatting")); 634 635 wxMenu* insertMenu = new wxMenu; 636 insertMenu->Append(ID_INSERT_SYMBOL, _("&Symbol...\tCtrl+I")); 637 insertMenu->Append(ID_INSERT_URL, _("&URL...")); 638 639 // now append the freshly created menu to the menu bar... 640 wxMenuBar *menuBar = new wxMenuBar(); 641 menuBar->Append(fileMenu, _T("&File")); 642 menuBar->Append(editMenu, _T("&Edit")); 643 menuBar->Append(formatMenu, _T("F&ormat")); 644 menuBar->Append(listsMenu, _T("&Lists")); 645 menuBar->Append(insertMenu, _T("&Insert")); 646 menuBar->Append(helpMenu, _T("&Help")); 647 648 // ... and attach this menu bar to the frame 649 SetMenuBar(menuBar); 650 651 // create a status bar just for fun (by default with 1 pane only) 652 // but don't create it on limited screen space (WinCE) 653 bool is_pda = wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA; 654 655#if wxUSE_STATUSBAR 656 if ( !is_pda ) 657 { 658 CreateStatusBar(2); 659 SetStatusText(_T("Welcome to wxRichTextCtrl!")); 660 } 661#endif 662 663 wxToolBar* toolBar = CreateToolBar(); 664 665 toolBar->AddTool(wxID_OPEN, wxBitmap(open_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Open")); 666 toolBar->AddTool(wxID_SAVEAS, wxBitmap(save_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Save")); 667 toolBar->AddSeparator(); 668 toolBar->AddTool(wxID_CUT, wxBitmap(cut_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Cut")); 669 toolBar->AddTool(wxID_COPY, wxBitmap(copy_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Copy")); 670 toolBar->AddTool(wxID_PASTE, wxBitmap(paste_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Paste")); 671 toolBar->AddSeparator(); 672 toolBar->AddTool(wxID_UNDO, wxBitmap(undo_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Undo")); 673 toolBar->AddTool(wxID_REDO, wxBitmap(redo_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Redo")); 674 toolBar->AddSeparator(); 675 toolBar->AddTool(ID_FORMAT_BOLD, wxBitmap(bold_xpm), wxNullBitmap, true, -1, -1, (wxObject *) NULL, _("Bold")); 676 toolBar->AddTool(ID_FORMAT_ITALIC, wxBitmap(italic_xpm), wxNullBitmap, true, -1, -1, (wxObject *) NULL, _("Italic")); 677 toolBar->AddTool(ID_FORMAT_UNDERLINE, wxBitmap(underline_xpm), wxNullBitmap, true, -1, -1, (wxObject *) NULL, _("Underline")); 678 toolBar->AddSeparator(); 679 toolBar->AddTool(ID_FORMAT_ALIGN_LEFT, wxBitmap(alignleft_xpm), wxNullBitmap, true, -1, -1, (wxObject *) NULL, _("Align Left")); 680 toolBar->AddTool(ID_FORMAT_ALIGN_CENTRE, wxBitmap(centre_xpm), wxNullBitmap, true, -1, -1, (wxObject *) NULL, _("Centre")); 681 toolBar->AddTool(ID_FORMAT_ALIGN_RIGHT, wxBitmap(alignright_xpm), wxNullBitmap, true, -1, -1, (wxObject *) NULL, _("Align Right")); 682 toolBar->AddSeparator(); 683 toolBar->AddTool(ID_FORMAT_INDENT_LESS, wxBitmap(indentless_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Indent Less")); 684 toolBar->AddTool(ID_FORMAT_INDENT_MORE, wxBitmap(indentmore_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Indent More")); 685 toolBar->AddSeparator(); 686 toolBar->AddTool(ID_FORMAT_FONT, wxBitmap(font_xpm), wxNullBitmap, false, -1, -1, (wxObject *) NULL, _("Font")); 687 688 wxRichTextStyleComboCtrl* combo = new wxRichTextStyleComboCtrl(toolBar, ID_RICHTEXT_STYLE_COMBO, wxDefaultPosition, wxSize(200, -1)); 689 toolBar->AddControl(combo); 690 691 toolBar->Realize(); 692 693 wxSplitterWindow* splitter = new wxSplitterWindow(this, wxID_ANY, wxDefaultPosition, GetClientSize(), wxSP_NO_XP_THEME|wxSP_3D|wxSP_LIVE_UPDATE); 694 695 wxFont textFont = wxFont(12, wxROMAN, wxNORMAL, wxNORMAL); 696 wxFont boldFont = wxFont(12, wxROMAN, wxNORMAL, wxBOLD); 697 wxFont italicFont = wxFont(12, wxROMAN, wxITALIC, wxNORMAL); 698 699 m_richTextCtrl = new wxRichTextCtrl(splitter, ID_RICHTEXT_CTRL, wxEmptyString, wxDefaultPosition, wxSize(200, 200), wxVSCROLL|wxHSCROLL|wxNO_BORDER|wxWANTS_CHARS); 700 wxFont font(12, wxROMAN, wxNORMAL, wxNORMAL); 701 702 m_richTextCtrl->SetFont(font); 703 704 m_richTextCtrl->SetStyleSheet(wxGetApp().GetStyleSheet()); 705 706 combo->SetStyleSheet(wxGetApp().GetStyleSheet()); 707 combo->SetRichTextCtrl(m_richTextCtrl); 708 combo->UpdateStyles(); 709 710 wxRichTextStyleListCtrl* styleListCtrl = new wxRichTextStyleListCtrl(splitter, ID_RICHTEXT_STYLE_LIST); 711 712 wxSize display = wxGetDisplaySize(); 713 if ( is_pda && ( display.GetWidth() < display.GetHeight() ) ) 714 { 715 splitter->SplitHorizontally(m_richTextCtrl, styleListCtrl); 716 } 717 else 718 { 719 splitter->SplitVertically(m_richTextCtrl, styleListCtrl, 500); 720 } 721 722 splitter->UpdateSize(); 723 724 styleListCtrl->SetStyleSheet(wxGetApp().GetStyleSheet()); 725 styleListCtrl->SetRichTextCtrl(m_richTextCtrl); 726 styleListCtrl->UpdateStyles(); 727 728 WriteInitialText(); 729} 730 731// Write text 732void MyFrame::WriteInitialText() 733{ 734 wxRichTextCtrl& r = *m_richTextCtrl; 735 736 r.SetDefaultStyle(wxRichTextAttr()); 737 738 r.BeginSuppressUndo(); 739 740 r.BeginParagraphSpacing(0, 20); 741 742 r.BeginAlignment(wxTEXT_ALIGNMENT_CENTRE); 743 r.BeginBold(); 744 745 r.BeginFontSize(14); 746 747 wxString lineBreak = (wxChar) 29; 748 749 r.WriteText(wxString(wxT("Welcome to wxRichTextCtrl, a wxWidgets control")) + lineBreak + wxT("for editing and presenting styled text and images\n")); 750 r.EndFontSize(); 751 //r.Newline(); 752 753 r.BeginItalic(); 754 r.WriteText(wxT("by Julian Smart")); 755 r.EndItalic(); 756 757 r.EndBold(); 758 r.Newline(); 759 760 r.WriteImage(wxBitmap(zebra_xpm)); 761 762 r.Newline(); 763 r.Newline(); 764 765 r.EndAlignment(); 766 767 r.WriteText(wxT("What can you do with this thing? ")); 768 769 r.WriteImage(wxBitmap(smiley_xpm)); 770 r.WriteText(wxT(" Well, you can change text ")); 771 772 r.BeginTextColour(wxColour(255, 0, 0)); 773 r.WriteText(wxT("colour, like this red bit.")); 774 r.EndTextColour(); 775 776 wxRichTextAttr backgroundColourAttr; 777 backgroundColourAttr.SetBackgroundColour(*wxGREEN); 778 backgroundColourAttr.SetTextColour(wxColour(0, 0, 255)); 779 r.BeginStyle(backgroundColourAttr); 780 r.WriteText(wxT(" And this blue on green bit.")); 781 r.EndStyle(); 782 783 r.WriteText(wxT(" Naturally you can make things ")); 784 r.BeginBold(); 785 r.WriteText(wxT("bold ")); 786 r.EndBold(); 787 r.BeginItalic(); 788 r.WriteText(wxT("or italic ")); 789 r.EndItalic(); 790 r.BeginUnderline(); 791 r.WriteText(wxT("or underlined.")); 792 r.EndUnderline(); 793 794 r.BeginFontSize(14); 795 r.WriteText(wxT(" Different font sizes on the same line is allowed, too.")); 796 r.EndFontSize(); 797 798 r.WriteText(wxT(" Next we'll show an indented paragraph.")); 799 800 r.Newline(); 801 802 r.BeginLeftIndent(60); 803 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.")); 804 r.Newline(); 805 806 r.EndLeftIndent(); 807 808 r.WriteText(wxT("Next, we'll show a first-line indent, achieved using BeginLeftIndent(100, -40).")); 809 810 r.Newline(); 811 812 r.BeginLeftIndent(100, -40); 813 814 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.")); 815 r.Newline(); 816 817 r.EndLeftIndent(); 818 819 r.WriteText(wxT("Numbered bullets are possible, again using subindents:")); 820 r.Newline(); 821 822 r.BeginNumberedBullet(1, 100, 60); 823 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.")); 824 r.Newline(); 825 826 r.EndNumberedBullet(); 827 828 r.BeginNumberedBullet(2, 100, 60); 829 r.WriteText(wxT("This is my second item.")); 830 r.Newline(); 831 832 r.EndNumberedBullet(); 833 834 r.WriteText(wxT("The following paragraph is right-indented:")); 835 r.Newline(); 836 837 r.BeginRightIndent(200); 838 839 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.")); 840 r.Newline(); 841 842 r.EndRightIndent(); 843 844 r.WriteText(wxT("The following paragraph is right-aligned with 1.5 line spacing:")); 845 r.Newline(); 846 847 r.BeginAlignment(wxTEXT_ALIGNMENT_RIGHT); 848 r.BeginLineSpacing(wxTEXT_ATTR_LINE_SPACING_HALF); 849 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.")); 850 r.Newline(); 851 r.EndLineSpacing(); 852 r.EndAlignment(); 853 854 wxArrayInt tabs; 855 tabs.Add(400); 856 tabs.Add(600); 857 tabs.Add(800); 858 tabs.Add(1000); 859 wxTextAttrEx attr; 860 attr.SetFlags(wxTEXT_ATTR_TABS); 861 attr.SetTabs(tabs); 862 r.SetDefaultStyle(attr); 863 864 r.WriteText(wxT("This line contains tabs:\tFirst tab\tSecond tab\tThird tab")); 865 r.Newline(); 866 867 r.WriteText(wxT("Other notable features of wxRichTextCtrl include:")); 868 r.Newline(); 869 870 r.BeginSymbolBullet(wxT('*'), 100, 60); 871 r.WriteText(wxT("Compatibility with wxTextCtrl API")); 872 r.Newline(); 873 r.EndSymbolBullet(); 874 875 r.BeginSymbolBullet(wxT('*'), 100, 60); 876 r.WriteText(wxT("Easy stack-based BeginXXX()...EndXXX() style setting in addition to SetStyle()")); 877 r.Newline(); 878 r.EndSymbolBullet(); 879 880 r.BeginSymbolBullet(wxT('*'), 100, 60); 881 r.WriteText(wxT("XML loading and saving")); 882 r.Newline(); 883 r.EndSymbolBullet(); 884 885 r.BeginSymbolBullet(wxT('*'), 100, 60); 886 r.WriteText(wxT("Undo/Redo, with batching option and Undo suppressing")); 887 r.Newline(); 888 r.EndSymbolBullet(); 889 890 r.BeginSymbolBullet(wxT('*'), 100, 60); 891 r.WriteText(wxT("Clipboard copy and paste")); 892 r.Newline(); 893 r.EndSymbolBullet(); 894 895 r.BeginSymbolBullet(wxT('*'), 100, 60); 896 r.WriteText(wxT("wxRichTextStyleSheet with named character and paragraph styles, and control for applying named styles")); 897 r.Newline(); 898 r.EndSymbolBullet(); 899 900 r.BeginSymbolBullet(wxT('*'), 100, 60); 901 r.WriteText(wxT("A design that can easily be extended to other content types, ultimately with text boxes, tables, controls, and so on")); 902 r.Newline(); 903 r.EndSymbolBullet(); 904 905 // Make a style suitable for showing a URL 906 wxRichTextAttr urlStyle; 907 urlStyle.SetTextColour(*wxBLUE); 908 urlStyle.SetFontUnderlined(true); 909 910 r.WriteText(wxT("wxRichTextCtrl can also display URLs, such as this one: ")); 911 r.BeginStyle(urlStyle); 912 r.BeginURL(wxT("http://www.wxwidgets.org")); 913 r.WriteText(wxT("The wxWidgets Web Site")); 914 r.EndURL(); 915 r.EndStyle(); 916 r.WriteText(wxT(". Click on the URL to generate an event.")); 917 918 r.Newline(); 919 920 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!")); 921 922 r.Newline(); 923 924 r.EndParagraphSpacing(); 925 926 r.EndSuppressUndo(); 927} 928 929 930// event handlers 931 932void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) 933{ 934 // true is to force the frame to close 935 Close(true); 936} 937 938void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) 939{ 940 wxString msg; 941 msg.Printf( _T("This is a demo for wxRichTextCtrl, a control for editing styled text.\n(c) Julian Smart, 2005")); 942 wxMessageBox(msg, _T("About wxRichTextCtrl Sample"), wxOK | wxICON_INFORMATION, this); 943} 944 945// Forward command events to the current rich text control, if any 946bool MyFrame::ProcessEvent(wxEvent& event) 947{ 948 if (event.IsCommandEvent() && !event.IsKindOf(CLASSINFO(wxChildFocusEvent))) 949 { 950 // Problem: we can get infinite recursion because the events 951 // climb back up to this frame, and repeat. 952 // Assume that command events don't cause another command event 953 // to be called, so we can rely on inCommand not being overwritten 954 955 static int s_eventType = 0; 956 static wxWindowID s_id = 0; 957 958 if (s_id != event.GetId() && s_eventType != event.GetEventType()) 959 { 960 s_eventType = event.GetEventType(); 961 s_id = event.GetId(); 962 963 wxWindow* focusWin = wxFindFocusDescendant(this); 964 if (focusWin && focusWin->ProcessEvent(event)) 965 { 966 //s_command = NULL; 967 s_eventType = 0; 968 s_id = 0; 969 return true; 970 } 971 972 s_eventType = 0; 973 s_id = 0; 974 } 975 else 976 { 977 return false; 978 } 979 } 980 981 return wxFrame::ProcessEvent(event); 982} 983 984void MyFrame::OnOpen(wxCommandEvent& WXUNUSED(event)) 985{ 986 wxString path; 987 wxString filename; 988 wxArrayInt fileTypes; 989 990 wxString filter = wxRichTextBuffer::GetExtWildcard(false, false, & fileTypes); 991 if (!filter.empty()) 992 filter += wxT("|"); 993 filter += wxT("All files (*.*)|*.*"); 994 995 wxFileDialog dialog(this, 996 _("Choose a filename"), 997 path, 998 filename, 999 filter, 1000 wxFD_OPEN); 1001 1002 if (dialog.ShowModal() == wxID_OK) 1003 { 1004 wxString path = dialog.GetPath(); 1005 1006 if (!path.empty()) 1007 { 1008 int filterIndex = dialog.GetFilterIndex(); 1009 int fileType = (filterIndex < (int) fileTypes.GetCount()) 1010 ? fileTypes[filterIndex] 1011 : wxRICHTEXT_TYPE_TEXT; 1012 m_richTextCtrl->LoadFile(path, fileType); 1013 } 1014 } 1015} 1016 1017void MyFrame::OnSave(wxCommandEvent& event) 1018{ 1019 if (m_richTextCtrl->GetFilename().empty()) 1020 { 1021 OnSaveAs(event); 1022 return; 1023 } 1024 m_richTextCtrl->SaveFile(); 1025} 1026 1027void MyFrame::OnSaveAs(wxCommandEvent& WXUNUSED(event)) 1028{ 1029 wxString filter = wxRichTextBuffer::GetExtWildcard(false, true); 1030 wxString path; 1031 wxString filename; 1032 1033 wxFileDialog dialog(this, 1034 _("Choose a filename"), 1035 path, 1036 filename, 1037 filter, 1038 wxFD_SAVE); 1039 1040 if (dialog.ShowModal() == wxID_OK) 1041 { 1042 wxString path = dialog.GetPath(); 1043 1044 if (!path.empty()) 1045 { 1046 m_richTextCtrl->SaveFile(path); 1047 } 1048 } 1049} 1050 1051void MyFrame::OnBold(wxCommandEvent& WXUNUSED(event)) 1052{ 1053 m_richTextCtrl->ApplyBoldToSelection(); 1054} 1055 1056void MyFrame::OnItalic(wxCommandEvent& WXUNUSED(event)) 1057{ 1058 m_richTextCtrl->ApplyItalicToSelection(); 1059} 1060 1061void MyFrame::OnUnderline(wxCommandEvent& WXUNUSED(event)) 1062{ 1063 m_richTextCtrl->ApplyUnderlineToSelection(); 1064} 1065 1066 1067void MyFrame::OnUpdateBold(wxUpdateUIEvent& event) 1068{ 1069 event.Check(m_richTextCtrl->IsSelectionBold()); 1070} 1071 1072void MyFrame::OnUpdateItalic(wxUpdateUIEvent& event) 1073{ 1074 event.Check(m_richTextCtrl->IsSelectionItalics()); 1075} 1076 1077void MyFrame::OnUpdateUnderline(wxUpdateUIEvent& event) 1078{ 1079 event.Check(m_richTextCtrl->IsSelectionUnderlined()); 1080} 1081 1082void MyFrame::OnAlignLeft(wxCommandEvent& WXUNUSED(event)) 1083{ 1084 m_richTextCtrl->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_LEFT); 1085} 1086 1087void MyFrame::OnAlignCentre(wxCommandEvent& WXUNUSED(event)) 1088{ 1089 m_richTextCtrl->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_CENTRE); 1090} 1091 1092void MyFrame::OnAlignRight(wxCommandEvent& WXUNUSED(event)) 1093{ 1094 m_richTextCtrl->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_RIGHT); 1095} 1096 1097void MyFrame::OnUpdateAlignLeft(wxUpdateUIEvent& event) 1098{ 1099 event.Check(m_richTextCtrl->IsSelectionAligned(wxTEXT_ALIGNMENT_LEFT)); 1100} 1101 1102void MyFrame::OnUpdateAlignCentre(wxUpdateUIEvent& event) 1103{ 1104 event.Check(m_richTextCtrl->IsSelectionAligned(wxTEXT_ALIGNMENT_CENTRE)); 1105} 1106 1107void MyFrame::OnUpdateAlignRight(wxUpdateUIEvent& event) 1108{ 1109 event.Check(m_richTextCtrl->IsSelectionAligned(wxTEXT_ALIGNMENT_RIGHT)); 1110} 1111 1112void MyFrame::OnFont(wxCommandEvent& WXUNUSED(event)) 1113{ 1114 wxRichTextRange range; 1115 if (m_richTextCtrl->HasSelection()) 1116 range = m_richTextCtrl->GetSelectionRange(); 1117 else 1118 range = wxRichTextRange(0, m_richTextCtrl->GetLastPosition()+1); 1119 1120 int pages = wxRICHTEXT_FORMAT_FONT; 1121 1122 wxRichTextFormattingDialog formatDlg(pages, this); 1123 formatDlg.GetStyle(m_richTextCtrl, range); 1124 1125 if (formatDlg.ShowModal() == wxID_OK) 1126 { 1127 formatDlg.ApplyStyle(m_richTextCtrl, range, wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_OPTIMIZE|wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY); 1128 } 1129 1130 // Old method using wxFontDialog 1131#if 0 1132 if (!m_richTextCtrl->HasSelection()) 1133 return; 1134 1135 wxRichTextRange range = m_richTextCtrl->GetSelectionRange(); 1136 wxFontData fontData; 1137 1138 wxTextAttrEx attr; 1139 attr.SetFlags(wxTEXT_ATTR_FONT); 1140 1141 if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr)) 1142 fontData.SetInitialFont(attr.GetFont()); 1143 1144 wxFontDialog dialog(this, fontData); 1145 if (dialog.ShowModal() == wxID_OK) 1146 { 1147 fontData = dialog.GetFontData(); 1148 attr.SetFlags(wxTEXT_ATTR_FONT); 1149 attr.SetFont(fontData.GetChosenFont()); 1150 if (attr.GetFont().Ok()) 1151 { 1152 m_richTextCtrl->SetStyle(range, attr); 1153 } 1154 } 1155#endif 1156} 1157 1158void MyFrame::OnParagraph(wxCommandEvent& WXUNUSED(event)) 1159{ 1160 wxRichTextRange range; 1161 if (m_richTextCtrl->HasSelection()) 1162 range = m_richTextCtrl->GetSelectionRange(); 1163 else 1164 range = wxRichTextRange(0, m_richTextCtrl->GetLastPosition()+1); 1165 1166 int pages = wxRICHTEXT_FORMAT_INDENTS_SPACING|wxRICHTEXT_FORMAT_TABS|wxRICHTEXT_FORMAT_BULLETS; 1167 1168 wxRichTextFormattingDialog formatDlg(pages, this); 1169 formatDlg.GetStyle(m_richTextCtrl, range); 1170 1171 if (formatDlg.ShowModal() == wxID_OK) 1172 { 1173 formatDlg.ApplyStyle(m_richTextCtrl, range); 1174 } 1175} 1176 1177void MyFrame::OnFormat(wxCommandEvent& WXUNUSED(event)) 1178{ 1179 wxRichTextRange range; 1180 if (m_richTextCtrl->HasSelection()) 1181 range = m_richTextCtrl->GetSelectionRange(); 1182 else 1183 range = wxRichTextRange(0, m_richTextCtrl->GetLastPosition()+1); 1184 1185 int pages = wxRICHTEXT_FORMAT_FONT|wxRICHTEXT_FORMAT_INDENTS_SPACING|wxRICHTEXT_FORMAT_TABS|wxRICHTEXT_FORMAT_BULLETS; 1186 1187 wxRichTextFormattingDialog formatDlg(pages, this); 1188 formatDlg.GetStyle(m_richTextCtrl, range); 1189 1190 if (formatDlg.ShowModal() == wxID_OK) 1191 { 1192 formatDlg.ApplyStyle(m_richTextCtrl, range); 1193 } 1194} 1195 1196void MyFrame::OnUpdateFormat(wxUpdateUIEvent& event) 1197{ 1198 event.Enable(m_richTextCtrl->HasSelection()); 1199} 1200 1201void MyFrame::OnIndentMore(wxCommandEvent& WXUNUSED(event)) 1202{ 1203 wxTextAttrEx attr; 1204 attr.SetFlags(wxTEXT_ATTR_LEFT_INDENT); 1205 1206 if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr)) 1207 { 1208 wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint()); 1209 if (m_richTextCtrl->HasSelection()) 1210 range = m_richTextCtrl->GetSelectionRange(); 1211 1212 attr.SetLeftIndent(attr.GetLeftIndent() + 100); 1213 1214 attr.SetFlags(wxTEXT_ATTR_LEFT_INDENT); 1215 m_richTextCtrl->SetStyle(range, attr); 1216 } 1217} 1218 1219void MyFrame::OnIndentLess(wxCommandEvent& WXUNUSED(event)) 1220{ 1221 wxTextAttrEx attr; 1222 attr.SetFlags(wxTEXT_ATTR_LEFT_INDENT); 1223 1224 if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr)) 1225 { 1226 wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint()); 1227 if (m_richTextCtrl->HasSelection()) 1228 range = m_richTextCtrl->GetSelectionRange(); 1229 1230 if (attr.GetLeftIndent() > 0) 1231 { 1232 attr.SetLeftIndent(wxMax(0, attr.GetLeftIndent() - 100)); 1233 1234 m_richTextCtrl->SetStyle(range, attr); 1235 } 1236 } 1237} 1238 1239void MyFrame::OnLineSpacingHalf(wxCommandEvent& WXUNUSED(event)) 1240{ 1241 wxTextAttrEx attr; 1242 attr.SetFlags(wxTEXT_ATTR_LINE_SPACING); 1243 1244 if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr)) 1245 { 1246 wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint()); 1247 if (m_richTextCtrl->HasSelection()) 1248 range = m_richTextCtrl->GetSelectionRange(); 1249 1250 attr.SetFlags(wxTEXT_ATTR_LINE_SPACING); 1251 attr.SetLineSpacing(15); 1252 1253 m_richTextCtrl->SetStyle(range, attr); 1254 } 1255} 1256 1257void MyFrame::OnLineSpacingDouble(wxCommandEvent& WXUNUSED(event)) 1258{ 1259 wxTextAttrEx attr; 1260 attr.SetFlags(wxTEXT_ATTR_LINE_SPACING); 1261 1262 if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr)) 1263 { 1264 wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint()); 1265 if (m_richTextCtrl->HasSelection()) 1266 range = m_richTextCtrl->GetSelectionRange(); 1267 1268 attr.SetFlags(wxTEXT_ATTR_LINE_SPACING); 1269 attr.SetLineSpacing(20); 1270 1271 m_richTextCtrl->SetStyle(range, attr); 1272 } 1273} 1274 1275void MyFrame::OnLineSpacingSingle(wxCommandEvent& WXUNUSED(event)) 1276{ 1277 wxTextAttrEx attr; 1278 attr.SetFlags(wxTEXT_ATTR_LINE_SPACING); 1279 1280 if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr)) 1281 { 1282 wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint()); 1283 if (m_richTextCtrl->HasSelection()) 1284 range = m_richTextCtrl->GetSelectionRange(); 1285 1286 attr.SetFlags(wxTEXT_ATTR_LINE_SPACING); 1287 attr.SetLineSpacing(0); // Can also use 10 1288 1289 m_richTextCtrl->SetStyle(range, attr); 1290 } 1291} 1292 1293void MyFrame::OnParagraphSpacingMore(wxCommandEvent& WXUNUSED(event)) 1294{ 1295 wxTextAttrEx attr; 1296 attr.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER); 1297 1298 if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr)) 1299 { 1300 wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint()); 1301 if (m_richTextCtrl->HasSelection()) 1302 range = m_richTextCtrl->GetSelectionRange(); 1303 1304 attr.SetParagraphSpacingAfter(attr.GetParagraphSpacingAfter() + 20); 1305 1306 attr.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER); 1307 m_richTextCtrl->SetStyle(range, attr); 1308 } 1309} 1310 1311void MyFrame::OnParagraphSpacingLess(wxCommandEvent& WXUNUSED(event)) 1312{ 1313 wxTextAttrEx attr; 1314 attr.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER); 1315 1316 if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr)) 1317 { 1318 wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint()); 1319 if (m_richTextCtrl->HasSelection()) 1320 range = m_richTextCtrl->GetSelectionRange(); 1321 1322 if (attr.GetParagraphSpacingAfter() >= 20) 1323 { 1324 attr.SetParagraphSpacingAfter(attr.GetParagraphSpacingAfter() - 20); 1325 1326 attr.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER); 1327 m_richTextCtrl->SetStyle(range, attr); 1328 } 1329 } 1330} 1331 1332void MyFrame::OnReload(wxCommandEvent& WXUNUSED(event)) 1333{ 1334 m_richTextCtrl->Clear(); 1335 WriteInitialText(); 1336} 1337 1338void MyFrame::OnViewHTML(wxCommandEvent& WXUNUSED(event)) 1339{ 1340 wxDialog dialog(this, wxID_ANY, _("HTML"), wxDefaultPosition, wxSize(500, 400), wxDEFAULT_DIALOG_STYLE); 1341 1342 wxBoxSizer* boxSizer = new wxBoxSizer(wxVERTICAL); 1343 dialog.SetSizer(boxSizer); 1344 1345 wxHtmlWindow* win = new wxHtmlWindow(& dialog, wxID_ANY, wxDefaultPosition, wxSize(500, 400), wxSUNKEN_BORDER); 1346 boxSizer->Add(win, 1, wxALL, 5); 1347 1348 wxButton* cancelButton = new wxButton(& dialog, wxID_CANCEL, wxT("&Close")); 1349 boxSizer->Add(cancelButton, 0, wxALL|wxCENTRE, 5); 1350 1351 wxString text; 1352 wxStringOutputStream strStream(& text); 1353 1354 wxRichTextHTMLHandler htmlHandler; 1355 htmlHandler.SetFlags(wxRICHTEXT_HANDLER_SAVE_IMAGES_TO_MEMORY); 1356 1357 wxArrayInt fontSizeMapping; 1358 fontSizeMapping.Add(7); 1359 fontSizeMapping.Add(9); 1360 fontSizeMapping.Add(11); 1361 fontSizeMapping.Add(12); 1362 fontSizeMapping.Add(14); 1363 fontSizeMapping.Add(22); 1364 fontSizeMapping.Add(100); 1365 1366 htmlHandler.SetFontSizeMapping(fontSizeMapping); 1367 1368 if (htmlHandler.SaveFile(& m_richTextCtrl->GetBuffer(), strStream)) 1369 { 1370 win->SetPage(text); 1371 } 1372 1373 boxSizer->Fit(& dialog); 1374 1375 dialog.ShowModal(); 1376 1377 // Now delete the temporary in-memory images 1378 htmlHandler.DeleteTemporaryImages(); 1379} 1380 1381// Demonstrates how you can change the style sheets and have the changes 1382// reflected in the control content without wiping out character formatting. 1383 1384void MyFrame::OnSwitchStyleSheets(wxCommandEvent& WXUNUSED(event)) 1385{ 1386 static wxRichTextStyleSheet* gs_AlternateStyleSheet = NULL; 1387 1388 wxRichTextStyleListCtrl *styleList = (wxRichTextStyleListCtrl*) FindWindow(ID_RICHTEXT_STYLE_LIST); 1389 wxRichTextStyleComboCtrl* styleCombo = (wxRichTextStyleComboCtrl*) FindWindow(ID_RICHTEXT_STYLE_COMBO); 1390 1391 wxRichTextStyleSheet* sheet = m_richTextCtrl->GetStyleSheet(); 1392 1393 // One-time creation of an alternate style sheet 1394 if (!gs_AlternateStyleSheet) 1395 { 1396 gs_AlternateStyleSheet = new wxRichTextStyleSheet(*sheet); 1397 1398 // Make some modifications 1399 for (int i = 0; i < (int) gs_AlternateStyleSheet->GetParagraphStyleCount(); i++) 1400 { 1401 wxRichTextParagraphStyleDefinition* def = gs_AlternateStyleSheet->GetParagraphStyle(i); 1402 1403 if (def->GetStyle().HasTextColour()) 1404 def->GetStyle().SetTextColour(*wxBLUE); 1405 1406 if (def->GetStyle().HasAlignment()) 1407 { 1408 if (def->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_CENTRE) 1409 def->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_RIGHT); 1410 else if (def->GetStyle().GetAlignment() == wxTEXT_ALIGNMENT_LEFT) 1411 def->GetStyle().SetAlignment(wxTEXT_ALIGNMENT_CENTRE); 1412 } 1413 if (def->GetStyle().HasLeftIndent()) 1414 { 1415 def->GetStyle().SetLeftIndent(def->GetStyle().GetLeftIndent() * 2); 1416 } 1417 } 1418 } 1419 1420 // Switch sheets 1421 wxRichTextStyleSheet* tmp = gs_AlternateStyleSheet; 1422 gs_AlternateStyleSheet = sheet; 1423 sheet = tmp; 1424 1425 m_richTextCtrl->SetStyleSheet(sheet); 1426 m_richTextCtrl->ApplyStyleSheet(sheet); // Makes the control reflect the new style definitions 1427 1428 styleList->SetStyleSheet(sheet); 1429 styleList->UpdateStyles(); 1430 1431 styleCombo->SetStyleSheet(sheet); 1432 styleCombo->UpdateStyles(); 1433} 1434 1435void MyFrame::OnManageStyles(wxCommandEvent& WXUNUSED(event)) 1436{ 1437 wxRichTextStyleSheet* sheet = m_richTextCtrl->GetStyleSheet(); 1438 1439 int flags = wxRICHTEXT_ORGANISER_CREATE_STYLES|wxRICHTEXT_ORGANISER_EDIT_STYLES; 1440 1441 wxRichTextStyleOrganiserDialog dlg(flags, sheet, NULL, this, wxID_ANY, _("Style Manager")); 1442 dlg.ShowModal(); 1443} 1444 1445void MyFrame::OnInsertSymbol(wxCommandEvent& WXUNUSED(event)) 1446{ 1447 wxTextAttrEx attr; 1448 attr.SetFlags(wxTEXT_ATTR_FONT); 1449 m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr); 1450 1451 wxString currentFontName; 1452 if (attr.HasFont() && attr.GetFont().Ok()) 1453 currentFontName = attr.GetFont().GetFaceName(); 1454 1455 // Don't set the initial font in the dialog (so the user is choosing 1456 // 'normal text', i.e. the current font) but do tell the dialog 1457 // what 'normal text' is. 1458 1459 wxSymbolPickerDialog dlg(wxT("*"), wxEmptyString, currentFontName, this); 1460 1461 if (dlg.ShowModal() == wxID_OK) 1462 { 1463 if (dlg.HasSelection()) 1464 { 1465 long insertionPoint = m_richTextCtrl->GetInsertionPoint(); 1466 1467 m_richTextCtrl->WriteText(dlg.GetSymbol()); 1468 1469 if (!dlg.UseNormalFont()) 1470 { 1471 wxFont font(attr.GetFont()); 1472 font.SetFaceName(dlg.GetFontName()); 1473 attr.SetFont(font); 1474 m_richTextCtrl->SetStyle(insertionPoint, insertionPoint+1, attr); 1475 } 1476 } 1477 } 1478} 1479 1480void MyFrame::OnNumberList(wxCommandEvent& WXUNUSED(event)) 1481{ 1482 if (m_richTextCtrl->HasSelection()) 1483 { 1484 wxRichTextRange range = m_richTextCtrl->GetSelectionRange(); 1485 m_richTextCtrl->SetListStyle(range, wxT("Numbered List 1"), wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_RENUMBER); 1486 } 1487} 1488 1489void MyFrame::OnBulletsAndNumbering(wxCommandEvent& WXUNUSED(event)) 1490{ 1491 wxRichTextStyleSheet* sheet = m_richTextCtrl->GetStyleSheet(); 1492 1493 int flags = wxRICHTEXT_ORGANISER_BROWSE_NUMBERING; 1494 1495 wxRichTextStyleOrganiserDialog dlg(flags, sheet, m_richTextCtrl, this, wxID_ANY, _("Bullets and Numbering")); 1496 if (dlg.ShowModal() == wxID_OK) 1497 { 1498 if (dlg.GetSelectedStyleDefinition()) 1499 dlg.ApplyStyle(); 1500 } 1501} 1502 1503void MyFrame::OnItemizeList(wxCommandEvent& WXUNUSED(event)) 1504{ 1505 if (m_richTextCtrl->HasSelection()) 1506 { 1507 wxRichTextRange range = m_richTextCtrl->GetSelectionRange(); 1508 m_richTextCtrl->SetListStyle(range, wxT("Bullet List 1")); 1509 } 1510} 1511 1512void MyFrame::OnRenumberList(wxCommandEvent& WXUNUSED(event)) 1513{ 1514 if (m_richTextCtrl->HasSelection()) 1515 { 1516 wxRichTextRange range = m_richTextCtrl->GetSelectionRange(); 1517 m_richTextCtrl->NumberList(range, NULL, wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_RENUMBER); 1518 } 1519} 1520 1521void MyFrame::OnPromoteList(wxCommandEvent& WXUNUSED(event)) 1522{ 1523 if (m_richTextCtrl->HasSelection()) 1524 { 1525 wxRichTextRange range = m_richTextCtrl->GetSelectionRange(); 1526 m_richTextCtrl->PromoteList(1, range, NULL); 1527 } 1528} 1529 1530void MyFrame::OnDemoteList(wxCommandEvent& WXUNUSED(event)) 1531{ 1532 if (m_richTextCtrl->HasSelection()) 1533 { 1534 wxRichTextRange range = m_richTextCtrl->GetSelectionRange(); 1535 m_richTextCtrl->PromoteList(-1, range, NULL); 1536 } 1537} 1538 1539void MyFrame::OnClearList(wxCommandEvent& WXUNUSED(event)) 1540{ 1541 if (m_richTextCtrl->HasSelection()) 1542 { 1543 wxRichTextRange range = m_richTextCtrl->GetSelectionRange(); 1544 m_richTextCtrl->ClearListStyle(range); 1545 } 1546} 1547 1548void MyFrame::OnInsertURL(wxCommandEvent& WXUNUSED(event)) 1549{ 1550 wxString url = wxGetTextFromUser(_("URL:"), _("Insert URL")); 1551 if (!url.IsEmpty()) 1552 { 1553 // Make a style suitable for showing a URL 1554 wxRichTextAttr urlStyle; 1555 urlStyle.SetTextColour(*wxBLUE); 1556 urlStyle.SetFontUnderlined(true); 1557 1558 m_richTextCtrl->BeginStyle(urlStyle); 1559 m_richTextCtrl->BeginURL(url); 1560 m_richTextCtrl->WriteText(url); 1561 m_richTextCtrl->EndURL(); 1562 m_richTextCtrl->EndStyle(); 1563 } 1564} 1565 1566void MyFrame::OnURL(wxTextUrlEvent& event) 1567{ 1568 wxMessageBox(event.GetString()); 1569} 1570 1571// Veto style sheet replace events when loading from XML, since we want 1572// to keep the original style sheet. 1573void MyFrame::OnStyleSheetReplacing(wxRichTextEvent& event) 1574{ 1575 event.Veto(); 1576} 1577 1578void MyFrame::OnPrint(wxCommandEvent& WXUNUSED(event)) 1579{ 1580 wxGetApp().GetPrinting()->PrintBuffer(m_richTextCtrl->GetBuffer()); 1581} 1582 1583void MyFrame::OnPreview(wxCommandEvent& WXUNUSED(event)) 1584{ 1585 wxGetApp().GetPrinting()->PreviewBuffer(m_richTextCtrl->GetBuffer()); 1586} 1587 1588void MyFrame::OnPageSetup(wxCommandEvent& WXUNUSED(event)) 1589{ 1590 wxGetApp().GetPrinting()->PageSetup(); 1591} 1592