c59f6793fb
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@35976 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
1027 lines
34 KiB
C++
1027 lines
34 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: richedit.cpp
|
|
// Purpose: wxWidgets rich text editor sample
|
|
// Author: Julian Smart
|
|
// Modified by:
|
|
// Created: 2005-10-02
|
|
// RCS-ID: $Id$
|
|
// Copyright: (c) Julian Smart
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// ============================================================================
|
|
// declarations
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// headers
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// For compilers that support precompilation, includes "wx/wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#ifdef __BORLANDC__
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
// for all others, include the necessary headers (this file is usually all you
|
|
// need because it includes almost all "standard" wxWidgets headers)
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/wx.h"
|
|
#endif
|
|
|
|
#include "wx/fontdlg.h"
|
|
#include "wx/splitter.h"
|
|
#include "wx/sstream.h"
|
|
#include "wx/html/htmlwin.h"
|
|
|
|
#include "bitmaps/sample.xpm"
|
|
#include "bitmaps/smiley.xpm"
|
|
// #include "bitmaps/idea.xpm"
|
|
#include "bitmaps/zebra.xpm"
|
|
|
|
#include "bitmaps/open.xpm"
|
|
#include "bitmaps/save.xpm"
|
|
#include "bitmaps/copy.xpm"
|
|
#include "bitmaps/cut.xpm"
|
|
#include "bitmaps/paste.xpm"
|
|
#include "bitmaps/undo.xpm"
|
|
#include "bitmaps/redo.xpm"
|
|
#include "bitmaps/bold.xpm"
|
|
#include "bitmaps/italic.xpm"
|
|
#include "bitmaps/underline.xpm"
|
|
|
|
#include "bitmaps/alignleft.xpm"
|
|
#include "bitmaps/alignright.xpm"
|
|
#include "bitmaps/centre.xpm"
|
|
#include "bitmaps/font.xpm"
|
|
#include "bitmaps/indentless.xpm"
|
|
#include "bitmaps/indentmore.xpm"
|
|
|
|
#include "wx/richtext/richtextctrl.h"
|
|
#include "wx/richtext/richtextstyles.h"
|
|
#include "wx/richtext/richtextxml.h"
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// resources
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// private classes
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Define a new application type, each program should derive a class from wxApp
|
|
class MyApp : public wxApp
|
|
{
|
|
public:
|
|
// override base class virtuals
|
|
// ----------------------------
|
|
|
|
// this one is called on application startup and is a good place for the app
|
|
// initialization (doing it here and not in the ctor allows to have an error
|
|
// return: if OnInit() returns false, the application terminates)
|
|
virtual bool OnInit();
|
|
virtual int OnExit();
|
|
|
|
void CreateStyles();
|
|
|
|
wxRichTextStyleSheet* GetStyleSheet() const { return m_styleSheet; }
|
|
|
|
wxRichTextStyleSheet* m_styleSheet;
|
|
};
|
|
|
|
// Define a new frame type: this is going to be our main frame
|
|
class MyFrame : public wxFrame
|
|
{
|
|
public:
|
|
// ctor(s)
|
|
MyFrame(const wxString& title, wxWindowID id, const wxPoint& pos = wxDefaultPosition,
|
|
const wxSize& size = wxDefaultSize, long style = wxDEFAULT_FRAME_STYLE);
|
|
|
|
// event handlers (these functions should _not_ be virtual)
|
|
void OnQuit(wxCommandEvent& event);
|
|
void OnAbout(wxCommandEvent& event);
|
|
|
|
void OnOpen(wxCommandEvent& event);
|
|
void OnSave(wxCommandEvent& event);
|
|
void OnSaveAs(wxCommandEvent& event);
|
|
|
|
void OnBold(wxCommandEvent& event);
|
|
void OnItalic(wxCommandEvent& event);
|
|
void OnUnderline(wxCommandEvent& event);
|
|
|
|
void OnUpdateBold(wxUpdateUIEvent& event);
|
|
void OnUpdateItalic(wxUpdateUIEvent& event);
|
|
void OnUpdateUnderline(wxUpdateUIEvent& event);
|
|
|
|
void OnAlignLeft(wxCommandEvent& event);
|
|
void OnAlignCentre(wxCommandEvent& event);
|
|
void OnAlignRight(wxCommandEvent& event);
|
|
|
|
void OnUpdateAlignLeft(wxUpdateUIEvent& event);
|
|
void OnUpdateAlignCentre(wxUpdateUIEvent& event);
|
|
void OnUpdateAlignRight(wxUpdateUIEvent& event);
|
|
|
|
void OnFont(wxCommandEvent& event);
|
|
void OnIndentMore(wxCommandEvent& event);
|
|
void OnIndentLess(wxCommandEvent& event);
|
|
|
|
void OnLineSpacingHalf(wxCommandEvent& event);
|
|
void OnLineSpacingDouble(wxCommandEvent& event);
|
|
void OnLineSpacingSingle(wxCommandEvent& event);
|
|
|
|
void OnParagraphSpacingMore(wxCommandEvent& event);
|
|
void OnParagraphSpacingLess(wxCommandEvent& event);
|
|
|
|
void OnViewHTML(wxCommandEvent& event);
|
|
|
|
// Forward command events to the current rich text control, if any
|
|
bool ProcessEvent(wxEvent& event);
|
|
|
|
private:
|
|
// any class wishing to process wxWidgets events must use this macro
|
|
DECLARE_EVENT_TABLE()
|
|
|
|
wxRichTextCtrl* m_richTextCtrl;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// constants
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// IDs for the controls and the menu commands
|
|
enum
|
|
{
|
|
// menu items
|
|
ID_Quit = wxID_EXIT,
|
|
ID_About = wxID_ABOUT,
|
|
|
|
ID_FORMAT_BOLD = 100,
|
|
ID_FORMAT_ITALIC,
|
|
ID_FORMAT_UNDERLINE,
|
|
ID_FORMAT_FONT,
|
|
|
|
ID_FORMAT_ALIGN_LEFT,
|
|
ID_FORMAT_ALIGN_CENTRE,
|
|
ID_FORMAT_ALIGN_RIGHT,
|
|
|
|
ID_FORMAT_INDENT_MORE,
|
|
ID_FORMAT_INDENT_LESS,
|
|
|
|
ID_FORMAT_PARAGRAPH_SPACING_MORE,
|
|
ID_FORMAT_PARAGRAPH_SPACING_LESS,
|
|
|
|
ID_FORMAT_LINE_SPACING_HALF,
|
|
ID_FORMAT_LINE_SPACING_DOUBLE,
|
|
ID_FORMAT_LINE_SPACING_SINGLE,
|
|
|
|
ID_VIEW_HTML
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// event tables and other macros for wxWidgets
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// the event tables connect the wxWidgets events with the functions (event
|
|
// handlers) which process them. It can be also done at run-time, but for the
|
|
// simple menu events like this the static method is much simpler.
|
|
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
|
EVT_MENU(ID_Quit, MyFrame::OnQuit)
|
|
EVT_MENU(ID_About, MyFrame::OnAbout)
|
|
|
|
EVT_MENU(wxID_OPEN, MyFrame::OnOpen)
|
|
EVT_MENU(wxID_SAVE, MyFrame::OnSave)
|
|
EVT_MENU(wxID_SAVEAS, MyFrame::OnSaveAs)
|
|
|
|
EVT_MENU(ID_FORMAT_BOLD, MyFrame::OnBold)
|
|
EVT_MENU(ID_FORMAT_ITALIC, MyFrame::OnItalic)
|
|
EVT_MENU(ID_FORMAT_UNDERLINE, MyFrame::OnUnderline)
|
|
|
|
EVT_UPDATE_UI(ID_FORMAT_BOLD, MyFrame::OnUpdateBold)
|
|
EVT_UPDATE_UI(ID_FORMAT_ITALIC, MyFrame::OnUpdateItalic)
|
|
EVT_UPDATE_UI(ID_FORMAT_UNDERLINE, MyFrame::OnUpdateUnderline)
|
|
|
|
EVT_MENU(ID_FORMAT_ALIGN_LEFT, MyFrame::OnAlignLeft)
|
|
EVT_MENU(ID_FORMAT_ALIGN_CENTRE, MyFrame::OnAlignCentre)
|
|
EVT_MENU(ID_FORMAT_ALIGN_RIGHT, MyFrame::OnAlignRight)
|
|
|
|
EVT_UPDATE_UI(ID_FORMAT_ALIGN_LEFT, MyFrame::OnUpdateAlignLeft)
|
|
EVT_UPDATE_UI(ID_FORMAT_ALIGN_CENTRE, MyFrame::OnUpdateAlignCentre)
|
|
EVT_UPDATE_UI(ID_FORMAT_ALIGN_RIGHT, MyFrame::OnUpdateAlignRight)
|
|
|
|
EVT_MENU(ID_FORMAT_FONT, MyFrame::OnFont)
|
|
EVT_MENU(ID_FORMAT_INDENT_MORE, MyFrame::OnIndentMore)
|
|
EVT_MENU(ID_FORMAT_INDENT_LESS, MyFrame::OnIndentLess)
|
|
|
|
EVT_MENU(ID_FORMAT_LINE_SPACING_HALF, MyFrame::OnLineSpacingHalf)
|
|
EVT_MENU(ID_FORMAT_LINE_SPACING_SINGLE, MyFrame::OnLineSpacingSingle)
|
|
EVT_MENU(ID_FORMAT_LINE_SPACING_DOUBLE, MyFrame::OnLineSpacingDouble)
|
|
|
|
EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_MORE, MyFrame::OnParagraphSpacingMore)
|
|
EVT_MENU(ID_FORMAT_PARAGRAPH_SPACING_LESS, MyFrame::OnParagraphSpacingLess)
|
|
|
|
EVT_MENU(ID_VIEW_HTML, MyFrame::OnViewHTML)
|
|
END_EVENT_TABLE()
|
|
|
|
// Create a new application object: this macro will allow wxWidgets to create
|
|
// the application object during program execution (it's better than using a
|
|
// static object for many reasons) and also implements the accessor function
|
|
// wxGetApp() which will return the reference of the right type (i.e. MyApp and
|
|
// not wxApp)
|
|
IMPLEMENT_APP(MyApp)
|
|
|
|
// ============================================================================
|
|
// implementation
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// the application class
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// 'Main program' equivalent: the program execution "starts" here
|
|
bool MyApp::OnInit()
|
|
{
|
|
m_styleSheet = new wxRichTextStyleSheet;
|
|
|
|
CreateStyles();
|
|
|
|
// Add extra handlers (plain text is automatically added)
|
|
wxRichTextBuffer::AddHandler(new wxRichTextXMLHandler);
|
|
wxRichTextBuffer::AddHandler(new wxRichTextHTMLHandler);
|
|
|
|
// Add image handlers
|
|
#if wxUSE_LIBPNG
|
|
wxImage::AddHandler( new wxPNGHandler );
|
|
#endif
|
|
|
|
#if wxUSE_LIBJPEG
|
|
wxImage::AddHandler( new wxJPEGHandler );
|
|
#endif
|
|
|
|
#if wxUSE_GIF
|
|
wxImage::AddHandler( new wxGIFHandler );
|
|
#endif
|
|
|
|
// create the main application window
|
|
MyFrame *frame = new MyFrame(_T("wxRichTextCtrl Sample"), wxID_ANY, wxDefaultPosition, wxSize(600, 500));
|
|
|
|
// and show it (the frames, unlike simple controls, are not shown when
|
|
// created initially)
|
|
frame->Show(true);
|
|
|
|
// success: wxApp::OnRun() will be called which will enter the main message
|
|
// loop and the application will run. If we returned false here, the
|
|
// application would exit immediately.
|
|
return true;
|
|
}
|
|
|
|
int MyApp::OnExit()
|
|
{
|
|
delete m_styleSheet;
|
|
return 0;
|
|
}
|
|
|
|
void MyApp::CreateStyles()
|
|
{
|
|
// Paragraph styles
|
|
|
|
wxFont romanFont(12, wxROMAN, wxNORMAL, wxNORMAL);
|
|
wxFont swissFont(12, wxSWISS, wxNORMAL, wxNORMAL);
|
|
|
|
wxRichTextParagraphStyleDefinition* normalPara = new wxRichTextParagraphStyleDefinition(wxT("Normal"));
|
|
wxRichTextAttr normalAttr;
|
|
normalAttr.SetFontFaceName(romanFont.GetFaceName());
|
|
normalAttr.SetFontSize(12);
|
|
// Let's set all attributes for this style
|
|
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|
|
|
wxTEXT_ATTR_PARA_SPACING_BEFORE|wxTEXT_ATTR_PARA_SPACING_AFTER|wxTEXT_ATTR_LINE_SPACING|
|
|
wxTEXT_ATTR_BULLET_STYLE|wxTEXT_ATTR_BULLET_NUMBER);
|
|
normalPara->SetStyle(normalAttr);
|
|
|
|
m_styleSheet->AddParagraphStyle(normalPara);
|
|
|
|
wxRichTextParagraphStyleDefinition* indentedPara = new wxRichTextParagraphStyleDefinition(wxT("Indented"));
|
|
wxRichTextAttr indentedAttr;
|
|
indentedAttr.SetFontFaceName(romanFont.GetFaceName());
|
|
indentedAttr.SetFontSize(12);
|
|
indentedAttr.SetLeftIndent(100, 0);
|
|
// We only want to affect indentation
|
|
indentedAttr.SetFlags(wxTEXT_ATTR_LEFT_INDENT|wxTEXT_ATTR_RIGHT_INDENT);
|
|
indentedPara->SetStyle(indentedAttr);
|
|
|
|
m_styleSheet->AddParagraphStyle(indentedPara);
|
|
|
|
wxRichTextParagraphStyleDefinition* flIndentedPara = new wxRichTextParagraphStyleDefinition(wxT("First Line Indented"));
|
|
wxRichTextAttr flIndentedAttr;
|
|
flIndentedAttr.SetFontFaceName(swissFont.GetFaceName());
|
|
flIndentedAttr.SetFontSize(12);
|
|
flIndentedAttr.SetLeftIndent(100, -100);
|
|
// We only want to affect indentation
|
|
flIndentedAttr.SetFlags(wxTEXT_ATTR_LEFT_INDENT|wxTEXT_ATTR_RIGHT_INDENT);
|
|
flIndentedPara->SetStyle(flIndentedAttr);
|
|
|
|
m_styleSheet->AddParagraphStyle(flIndentedPara);
|
|
|
|
// Character styles
|
|
|
|
wxRichTextCharacterStyleDefinition* boldDef = new wxRichTextCharacterStyleDefinition(wxT("Bold"));
|
|
wxRichTextAttr boldAttr;
|
|
boldAttr.SetFontFaceName(romanFont.GetFaceName());
|
|
boldAttr.SetFontSize(12);
|
|
boldAttr.SetFontWeight(wxBOLD);
|
|
// We only want to affect boldness
|
|
boldAttr.SetFlags(wxTEXT_ATTR_FONT_WEIGHT);
|
|
boldDef->SetStyle(boldAttr);
|
|
|
|
m_styleSheet->AddCharacterStyle(boldDef);
|
|
|
|
wxRichTextCharacterStyleDefinition* italicDef = new wxRichTextCharacterStyleDefinition(wxT("Italic"));
|
|
wxRichTextAttr italicAttr;
|
|
italicAttr.SetFontFaceName(romanFont.GetFaceName());
|
|
italicAttr.SetFontSize(12);
|
|
italicAttr.SetFontStyle(wxITALIC);
|
|
// We only want to affect italics
|
|
italicAttr.SetFlags(wxTEXT_ATTR_FONT_ITALIC);
|
|
italicDef->SetStyle(italicAttr);
|
|
|
|
m_styleSheet->AddCharacterStyle(italicDef);
|
|
|
|
wxRichTextCharacterStyleDefinition* redDef = new wxRichTextCharacterStyleDefinition(wxT("Red Bold"));
|
|
wxRichTextAttr redAttr;
|
|
redAttr.SetFontFaceName(romanFont.GetFaceName());
|
|
redAttr.SetFontSize(12);
|
|
redAttr.SetFontWeight(wxBOLD);
|
|
redAttr.SetTextColour(*wxRED);
|
|
// We only want to affect colour, weight and face
|
|
redAttr.SetFlags(wxTEXT_ATTR_FONT_FACE|wxTEXT_ATTR_FONT_WEIGHT|wxTEXT_ATTR_TEXT_COLOUR);
|
|
redDef->SetStyle(redAttr);
|
|
|
|
m_styleSheet->AddCharacterStyle(redDef);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// main frame
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// frame constructor
|
|
MyFrame::MyFrame(const wxString& title, wxWindowID id, const wxPoint& pos,
|
|
const wxSize& size, long style)
|
|
: wxFrame(NULL, id, title, pos, size, style)
|
|
{
|
|
// set the frame icon
|
|
SetIcon(sample_xpm);
|
|
|
|
// create a menu bar
|
|
wxMenu *fileMenu = new wxMenu;
|
|
|
|
// the "About" item should be in the help menu
|
|
wxMenu *helpMenu = new wxMenu;
|
|
helpMenu->Append(ID_About, _T("&About...\tF1"), _T("Show about dialog"));
|
|
|
|
fileMenu->Append(wxID_OPEN, _T("&Open\tCtrl+O"), _T("Open a file"));
|
|
fileMenu->Append(wxID_SAVE, _T("&Save\tCtrl+S"), _T("Save a file"));
|
|
fileMenu->Append(wxID_SAVEAS, _T("&Save As...\tF12"), _T("Save to a new file"));
|
|
fileMenu->AppendSeparator();
|
|
fileMenu->Append(ID_VIEW_HTML, _T("&View as HTML"), _T("View HTML"));
|
|
fileMenu->AppendSeparator();
|
|
fileMenu->Append(ID_Quit, _T("E&xit\tAlt-X"), _T("Quit this program"));
|
|
|
|
wxMenu* editMenu = new wxMenu;
|
|
editMenu->Append(wxID_UNDO, _("&Undo\tCtrl+Z"));
|
|
editMenu->Append(wxID_REDO, _("&Redo\tCtrl+Y"));
|
|
editMenu->AppendSeparator();
|
|
editMenu->Append(wxID_CUT, _("Cu&t\tCtrl+X"));
|
|
editMenu->Append(wxID_COPY, _("&Copy\tCtrl+C"));
|
|
editMenu->Append(wxID_PASTE, _("&Paste\tCtrl+V"));
|
|
|
|
editMenu->Append(wxID_CLEAR, _("&Delete\tDel"));
|
|
|
|
editMenu->AppendSeparator();
|
|
editMenu->Append(wxID_SELECTALL, _("Select A&ll\tCtrl+A"));
|
|
#if 0
|
|
editMenu->AppendSeparator();
|
|
editMenu->Append(wxID_FIND, _("&Find...\tCtrl+F"));
|
|
editMenu->Append(stID_FIND_REPLACE, _("&Replace...\tCtrl+R"));
|
|
#endif
|
|
|
|
wxMenu* formatMenu = new wxMenu;
|
|
formatMenu->AppendCheckItem(ID_FORMAT_BOLD, _("&Bold\tCtrl+B"));
|
|
formatMenu->AppendCheckItem(ID_FORMAT_ITALIC, _("&Italic\tCtrl+I"));
|
|
formatMenu->AppendCheckItem(ID_FORMAT_UNDERLINE, _("&Underline\tCtrl+U"));
|
|
formatMenu->AppendSeparator();
|
|
formatMenu->AppendCheckItem(ID_FORMAT_ALIGN_LEFT, _("L&eft Align"));
|
|
formatMenu->AppendCheckItem(ID_FORMAT_ALIGN_RIGHT, _("&Right Align"));
|
|
formatMenu->AppendCheckItem(ID_FORMAT_ALIGN_CENTRE, _("&Centre"));
|
|
formatMenu->AppendSeparator();
|
|
formatMenu->Append(ID_FORMAT_INDENT_MORE, _("I&ndent &More"));
|
|
formatMenu->Append(ID_FORMAT_INDENT_LESS, _("Indent &Less"));
|
|
formatMenu->AppendSeparator();
|
|
formatMenu->Append(ID_FORMAT_PARAGRAPH_SPACING_MORE, _("Increase Paragraph &Spacing"));
|
|
formatMenu->Append(ID_FORMAT_PARAGRAPH_SPACING_LESS, _("Decrease &Paragraph Spacing"));
|
|
formatMenu->AppendSeparator();
|
|
formatMenu->Append(ID_FORMAT_LINE_SPACING_SINGLE, _("Normal Line Spacing"));
|
|
formatMenu->Append(ID_FORMAT_LINE_SPACING_HALF, _("1.5 Line Spacing"));
|
|
formatMenu->Append(ID_FORMAT_LINE_SPACING_DOUBLE, _("Double Line Spacing"));
|
|
formatMenu->AppendSeparator();
|
|
formatMenu->Append(ID_FORMAT_FONT, _("&Font..."));
|
|
|
|
// now append the freshly created menu to the menu bar...
|
|
wxMenuBar *menuBar = new wxMenuBar();
|
|
menuBar->Append(fileMenu, _T("&File"));
|
|
menuBar->Append(editMenu, _T("&Edit"));
|
|
menuBar->Append(formatMenu, _T("F&ormat"));
|
|
menuBar->Append(helpMenu, _T("&Help"));
|
|
|
|
// ... and attach this menu bar to the frame
|
|
SetMenuBar(menuBar);
|
|
|
|
// create a status bar just for fun (by default with 1 pane only)
|
|
CreateStatusBar(2);
|
|
SetStatusText(_T("Welcome to wxRichTextCtrl!"));
|
|
|
|
wxToolBar* toolBar = CreateToolBar();
|
|
|
|
toolBar->AddTool(wxID_OPEN, wxBitmap(open_xpm), wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, _("Open"));
|
|
toolBar->AddTool(wxID_SAVEAS, wxBitmap(save_xpm), wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, _("Save"));
|
|
toolBar->AddSeparator();
|
|
toolBar->AddTool(wxID_CUT, wxBitmap(cut_xpm), wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, _("Cut"));
|
|
toolBar->AddTool(wxID_COPY, wxBitmap(copy_xpm), wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, _("Copy"));
|
|
toolBar->AddTool(wxID_PASTE, wxBitmap(paste_xpm), wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, _("Paste"));
|
|
toolBar->AddSeparator();
|
|
toolBar->AddTool(wxID_UNDO, wxBitmap(undo_xpm), wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, _("Undo"));
|
|
toolBar->AddTool(wxID_REDO, wxBitmap(redo_xpm), wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, _("Redo"));
|
|
toolBar->AddSeparator();
|
|
toolBar->AddTool(ID_FORMAT_BOLD, wxBitmap(bold_xpm), wxNullBitmap, TRUE, -1, -1, (wxObject *) NULL, _("Bold"));
|
|
toolBar->AddTool(ID_FORMAT_ITALIC, wxBitmap(italic_xpm), wxNullBitmap, TRUE, -1, -1, (wxObject *) NULL, _("Italic"));
|
|
toolBar->AddTool(ID_FORMAT_UNDERLINE, wxBitmap(underline_xpm), wxNullBitmap, TRUE, -1, -1, (wxObject *) NULL, _("Underline"));
|
|
toolBar->AddSeparator();
|
|
toolBar->AddTool(ID_FORMAT_ALIGN_LEFT, wxBitmap(alignleft_xpm), wxNullBitmap, TRUE, -1, -1, (wxObject *) NULL, _("Align Left"));
|
|
toolBar->AddTool(ID_FORMAT_ALIGN_CENTRE, wxBitmap(centre_xpm), wxNullBitmap, TRUE, -1, -1, (wxObject *) NULL, _("Centre"));
|
|
toolBar->AddTool(ID_FORMAT_ALIGN_RIGHT, wxBitmap(alignright_xpm), wxNullBitmap, TRUE, -1, -1, (wxObject *) NULL, _("Align Right"));
|
|
toolBar->AddSeparator();
|
|
toolBar->AddTool(ID_FORMAT_INDENT_LESS, wxBitmap(indentless_xpm), wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, _("Indent Less"));
|
|
toolBar->AddTool(ID_FORMAT_INDENT_MORE, wxBitmap(indentmore_xpm), wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, _("Indent More"));
|
|
toolBar->AddSeparator();
|
|
toolBar->AddTool(ID_FORMAT_FONT, wxBitmap(font_xpm), wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, _("Font"));
|
|
|
|
toolBar->Realize();
|
|
|
|
wxSplitterWindow* splitter = new wxSplitterWindow(this, wxID_ANY, wxDefaultPosition, GetClientSize(), wxSP_NO_XP_THEME|wxSP_3D|wxSP_LIVE_UPDATE);
|
|
|
|
wxFont textFont = wxFont(12, wxROMAN, wxNORMAL, wxNORMAL);
|
|
wxFont boldFont = wxFont(12, wxROMAN, wxNORMAL, wxBOLD);
|
|
wxFont italicFont = wxFont(12, wxROMAN, wxITALIC, wxNORMAL);
|
|
|
|
m_richTextCtrl = new wxRichTextCtrl(splitter, wxID_ANY, wxDefaultPosition, wxSize(200, 200), wxVSCROLL|wxHSCROLL|wxNO_BORDER);
|
|
wxFont font(12, wxROMAN, wxNORMAL, wxNORMAL);
|
|
|
|
#ifdef __WXMAC__
|
|
font.SetNoAntiAliasing(true);
|
|
#endif
|
|
m_richTextCtrl->SetFont(font);
|
|
|
|
wxRichTextStyleListBox* styleListBox = new wxRichTextStyleListBox(splitter, wxID_ANY);
|
|
splitter->SplitVertically(m_richTextCtrl, styleListBox, 400);
|
|
|
|
splitter->UpdateSize();
|
|
|
|
styleListBox->SetStyleSheet(wxGetApp().GetStyleSheet());
|
|
styleListBox->SetRichTextCtrl(m_richTextCtrl);
|
|
styleListBox->UpdateStyles();
|
|
|
|
wxRichTextCtrl& r = *m_richTextCtrl;
|
|
|
|
r.BeginSuppressUndo();
|
|
|
|
r.BeginParagraphSpacing(0, 20);
|
|
|
|
r.BeginAlignment(wxTEXT_ALIGNMENT_CENTRE);
|
|
r.BeginBold();
|
|
|
|
r.BeginFontSize(14);
|
|
r.WriteText(wxT("Welcome to wxRichTextCtrl, a wxWidgets control for editing and presenting styled text and images"));
|
|
r.EndFontSize();
|
|
r.Newline();
|
|
|
|
r.BeginItalic();
|
|
r.WriteText(wxT("by Julian Smart"));
|
|
r.EndItalic();
|
|
|
|
r.EndBold();
|
|
|
|
r.Newline();
|
|
r.WriteImage(wxBitmap(zebra_xpm));
|
|
|
|
r.EndAlignment();
|
|
|
|
r.Newline();
|
|
r.Newline();
|
|
|
|
r.WriteText(wxT("What can you do with this thing? "));
|
|
r.WriteImage(wxBitmap(smiley_xpm));
|
|
r.WriteText(wxT(" Well, you can change text "));
|
|
|
|
r.BeginTextColour(wxColour(255, 0, 0));
|
|
r.WriteText(wxT("colour, like this red bit."));
|
|
r.EndTextColour();
|
|
|
|
r.BeginTextColour(wxColour(0, 0, 255));
|
|
r.WriteText(wxT(" And this blue bit."));
|
|
r.EndTextColour();
|
|
|
|
r.WriteText(wxT(" Naturally you can make things "));
|
|
r.BeginBold();
|
|
r.WriteText(wxT("bold "));
|
|
r.EndBold();
|
|
r.BeginItalic();
|
|
r.WriteText(wxT("or italic "));
|
|
r.EndItalic();
|
|
r.BeginUnderline();
|
|
r.WriteText(wxT("or underlined."));
|
|
r.EndUnderline();
|
|
|
|
r.BeginFontSize(14);
|
|
r.WriteText(wxT(" Different font sizes on the same line is allowed, too."));
|
|
r.EndFontSize();
|
|
|
|
r.WriteText(wxT(" Next we'll show an indented paragraph."));
|
|
|
|
r.BeginLeftIndent(60);
|
|
r.Newline();
|
|
|
|
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."));
|
|
r.EndLeftIndent();
|
|
|
|
r.Newline();
|
|
|
|
r.WriteText(wxT("Next, we'll show a first-line indent, achieved using BeginLeftIndent(100, -40)."));
|
|
|
|
r.BeginLeftIndent(100, -40);
|
|
r.Newline();
|
|
|
|
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."));
|
|
r.EndLeftIndent();
|
|
|
|
r.Newline();
|
|
|
|
r.WriteText(wxT("Numbered bullets are possible, again using subindents:"));
|
|
|
|
r.BeginNumberedBullet(1, 100, 60);
|
|
r.Newline();
|
|
|
|
r.WriteText(wxT("This is my first item. Note that wxRichTextCtrl doesn't automatically do numbering, but this will be added later."));
|
|
r.EndNumberedBullet();
|
|
|
|
r.BeginNumberedBullet(2, 100, 60);
|
|
r.Newline();
|
|
|
|
r.WriteText(wxT("This is my second item."));
|
|
r.EndNumberedBullet();
|
|
|
|
r.Newline();
|
|
|
|
r.WriteText(wxT("The following paragraph is right-indented:"));
|
|
|
|
r.BeginRightIndent(200);
|
|
r.Newline();
|
|
|
|
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."));
|
|
r.EndRightIndent();
|
|
|
|
r.Newline();
|
|
|
|
r.WriteText(wxT("The following paragraph is right-aligned with 1.5 line spacing:"));
|
|
|
|
r.BeginAlignment(wxTEXT_ALIGNMENT_RIGHT);
|
|
r.BeginLineSpacing(wxTEXT_ATTR_LINE_SPACING_HALF);
|
|
r.Newline();
|
|
|
|
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."));
|
|
r.EndLineSpacing();
|
|
r.EndAlignment();
|
|
|
|
r.Newline();
|
|
r.WriteText(wxT("Other notable features of wxRichTextCtrl include:"));
|
|
|
|
r.BeginSymbolBullet(wxT('*'), 100, 60);
|
|
r.Newline();
|
|
r.WriteText(wxT("Compatibility with wxTextCtrl API"));
|
|
r.EndSymbolBullet();
|
|
|
|
r.BeginSymbolBullet(wxT('*'), 100, 60);
|
|
r.Newline();
|
|
r.WriteText(wxT("Easy stack-based BeginXXX()...EndXXX() style setting in addition to SetStyle()"));
|
|
r.EndSymbolBullet();
|
|
|
|
r.BeginSymbolBullet(wxT('*'), 100, 60);
|
|
r.Newline();
|
|
r.WriteText(wxT("XML loading and saving"));
|
|
r.EndSymbolBullet();
|
|
|
|
r.BeginSymbolBullet(wxT('*'), 100, 60);
|
|
r.Newline();
|
|
r.WriteText(wxT("Undo/Redo, with batching option and Undo suppressing"));
|
|
r.EndSymbolBullet();
|
|
|
|
r.BeginSymbolBullet(wxT('*'), 100, 60);
|
|
r.Newline();
|
|
r.WriteText(wxT("Clipboard copy and paste"));
|
|
r.EndSymbolBullet();
|
|
|
|
r.BeginSymbolBullet(wxT('*'), 100, 60);
|
|
r.Newline();
|
|
r.WriteText(wxT("wxRichTextStyleSheet with named character and paragraph styles, and control for applying named styles"));
|
|
r.EndSymbolBullet();
|
|
|
|
r.BeginSymbolBullet(wxT('*'), 100, 60);
|
|
r.Newline();
|
|
r.WriteText(wxT("A design that can easily be extended to other content types, ultimately with text boxes, tables, controls, and so on"));
|
|
r.EndSymbolBullet();
|
|
|
|
r.Newline();
|
|
|
|
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!"));
|
|
|
|
r.EndParagraphSpacing();
|
|
|
|
r.EndSuppressUndo();
|
|
}
|
|
|
|
|
|
// event handlers
|
|
|
|
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
// true is to force the frame to close
|
|
Close(true);
|
|
}
|
|
|
|
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxString msg;
|
|
msg.Printf( _T("This is a demo for wxRichTextCtrl, a control for editing styled text.\n(c) Julian Smart, 2005"));
|
|
wxMessageBox(msg, _T("About wxRichTextCtrl Sample"), wxOK | wxICON_INFORMATION, this);
|
|
}
|
|
|
|
// Forward command events to the current rich text control, if any
|
|
bool MyFrame::ProcessEvent(wxEvent& event)
|
|
{
|
|
if (event.IsCommandEvent() && !event.IsKindOf(CLASSINFO(wxChildFocusEvent)))
|
|
{
|
|
// Problem: we can get infinite recursion because the events
|
|
// climb back up to this frame, and repeat.
|
|
// Assume that command events don't cause another command event
|
|
// to be called, so we can rely on inCommand not being overwritten
|
|
|
|
static int s_eventType = 0;
|
|
static wxWindowID s_id = 0;
|
|
|
|
if (s_id != event.GetId() && s_eventType != event.GetEventType())
|
|
{
|
|
s_eventType = event.GetEventType();
|
|
s_id = event.GetId();
|
|
|
|
wxWindow* focusWin = wxFindFocusDescendant(this);
|
|
if (focusWin && focusWin->ProcessEvent(event))
|
|
{
|
|
//s_command = NULL;
|
|
s_eventType = 0;
|
|
s_id = 0;
|
|
return TRUE;
|
|
}
|
|
|
|
s_eventType = 0;
|
|
s_id = 0;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return wxFrame::ProcessEvent(event);
|
|
}
|
|
|
|
void MyFrame::OnOpen(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxString path = wxEmptyString;
|
|
wxString filename = wxEmptyString;
|
|
wxArrayInt fileTypes;
|
|
|
|
wxString filter = wxRichTextBuffer::GetExtWildcard(false, false, & fileTypes);
|
|
if (!filter.IsEmpty())
|
|
filter += wxT("|");
|
|
filter += wxT("All files (*.*)|*.*");
|
|
|
|
wxFileDialog dialog(this,
|
|
_("Choose a filename"),
|
|
path,
|
|
filename,
|
|
filter,
|
|
wxOPEN);
|
|
|
|
if (dialog.ShowModal() == wxID_OK)
|
|
{
|
|
wxString path = dialog.GetPath();
|
|
|
|
if (!path.IsEmpty())
|
|
{
|
|
int fileType = 0;
|
|
int filterIndex = dialog.GetFilterIndex();
|
|
if (filterIndex < (int) fileTypes.GetCount())
|
|
fileType = fileTypes[filterIndex];
|
|
else
|
|
fileType = wxRICHTEXT_TYPE_TEXT;
|
|
m_richTextCtrl->LoadFile(path, fileType);
|
|
}
|
|
}
|
|
}
|
|
|
|
void MyFrame::OnSave(wxCommandEvent& event)
|
|
{
|
|
if (m_richTextCtrl->GetFilename().IsEmpty())
|
|
{
|
|
OnSaveAs(event);
|
|
return;
|
|
}
|
|
m_richTextCtrl->SaveFile();
|
|
}
|
|
|
|
void MyFrame::OnSaveAs(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxString filter = wxRichTextBuffer::GetExtWildcard(false, true);
|
|
wxString path = wxEmptyString;
|
|
wxString filename = wxEmptyString;
|
|
|
|
wxFileDialog dialog(this,
|
|
_("Choose a filename"),
|
|
path,
|
|
filename,
|
|
filter,
|
|
wxSAVE);
|
|
|
|
if (dialog.ShowModal() == wxID_OK)
|
|
{
|
|
wxString path = dialog.GetPath();
|
|
|
|
if (!path.IsEmpty())
|
|
{
|
|
m_richTextCtrl->SaveFile(path);
|
|
}
|
|
}
|
|
}
|
|
|
|
void MyFrame::OnBold(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
m_richTextCtrl->ApplyBoldToSelection();
|
|
}
|
|
|
|
void MyFrame::OnItalic(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
m_richTextCtrl->ApplyItalicToSelection();
|
|
}
|
|
|
|
void MyFrame::OnUnderline(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
m_richTextCtrl->ApplyUnderlineToSelection();
|
|
}
|
|
|
|
|
|
void MyFrame::OnUpdateBold(wxUpdateUIEvent& event)
|
|
{
|
|
event.Check(m_richTextCtrl->IsSelectionBold());
|
|
}
|
|
|
|
void MyFrame::OnUpdateItalic(wxUpdateUIEvent& event)
|
|
{
|
|
event.Check(m_richTextCtrl->IsSelectionItalics());
|
|
}
|
|
|
|
void MyFrame::OnUpdateUnderline(wxUpdateUIEvent& event)
|
|
{
|
|
event.Check(m_richTextCtrl->IsSelectionUnderlined());
|
|
}
|
|
|
|
void MyFrame::OnAlignLeft(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
m_richTextCtrl->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_LEFT);
|
|
}
|
|
|
|
void MyFrame::OnAlignCentre(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
m_richTextCtrl->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_CENTRE);
|
|
}
|
|
|
|
void MyFrame::OnAlignRight(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
m_richTextCtrl->ApplyAlignmentToSelection(wxTEXT_ALIGNMENT_RIGHT);
|
|
}
|
|
|
|
void MyFrame::OnUpdateAlignLeft(wxUpdateUIEvent& event)
|
|
{
|
|
event.Check(m_richTextCtrl->IsSelectionAligned(wxTEXT_ALIGNMENT_LEFT));
|
|
}
|
|
|
|
void MyFrame::OnUpdateAlignCentre(wxUpdateUIEvent& event)
|
|
{
|
|
event.Check(m_richTextCtrl->IsSelectionAligned(wxTEXT_ALIGNMENT_CENTRE));
|
|
}
|
|
|
|
void MyFrame::OnUpdateAlignRight(wxUpdateUIEvent& event)
|
|
{
|
|
event.Check(m_richTextCtrl->IsSelectionAligned(wxTEXT_ALIGNMENT_RIGHT));
|
|
}
|
|
|
|
void MyFrame::OnFont(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
if (!m_richTextCtrl->HasSelection())
|
|
return;
|
|
|
|
wxRichTextRange range = m_richTextCtrl->GetSelectionRange();
|
|
wxFontData fontData;
|
|
|
|
wxTextAttrEx attr;
|
|
attr.SetFlags(wxTEXT_ATTR_FONT);
|
|
|
|
if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
|
|
fontData.SetInitialFont(attr.GetFont());
|
|
|
|
wxFontDialog dialog(this, fontData);
|
|
if (dialog.ShowModal() == wxID_OK)
|
|
{
|
|
fontData = dialog.GetFontData();
|
|
attr.SetFlags(wxTEXT_ATTR_FONT);
|
|
attr.SetFont(fontData.GetChosenFont());
|
|
if (attr.GetFont().Ok())
|
|
{
|
|
m_richTextCtrl->SetStyle(range, attr);
|
|
}
|
|
}
|
|
}
|
|
|
|
void MyFrame::OnIndentMore(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxTextAttrEx attr;
|
|
attr.SetFlags(wxTEXT_ATTR_LEFT_INDENT);
|
|
|
|
if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
|
|
{
|
|
wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
|
|
if (m_richTextCtrl->HasSelection())
|
|
range = m_richTextCtrl->GetSelectionRange();
|
|
|
|
wxFontData fontData;
|
|
attr.SetLeftIndent(attr.GetLeftIndent() + 100);
|
|
|
|
attr.SetFlags(wxTEXT_ATTR_LEFT_INDENT);
|
|
m_richTextCtrl->SetStyle(range, attr);
|
|
}
|
|
}
|
|
|
|
void MyFrame::OnIndentLess(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxTextAttrEx attr;
|
|
attr.SetFlags(wxTEXT_ATTR_LEFT_INDENT);
|
|
|
|
if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
|
|
{
|
|
wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
|
|
if (m_richTextCtrl->HasSelection())
|
|
range = m_richTextCtrl->GetSelectionRange();
|
|
|
|
if (attr.GetLeftIndent() >= 100)
|
|
{
|
|
wxFontData fontData;
|
|
attr.SetLeftIndent(attr.GetLeftIndent() - 100);
|
|
|
|
m_richTextCtrl->SetStyle(range, attr);
|
|
}
|
|
}
|
|
}
|
|
|
|
void MyFrame::OnLineSpacingHalf(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxTextAttrEx attr;
|
|
attr.SetFlags(wxTEXT_ATTR_LINE_SPACING);
|
|
|
|
if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
|
|
{
|
|
wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
|
|
if (m_richTextCtrl->HasSelection())
|
|
range = m_richTextCtrl->GetSelectionRange();
|
|
|
|
wxFontData fontData;
|
|
attr.SetFlags(wxTEXT_ATTR_LINE_SPACING);
|
|
attr.SetLineSpacing(15);
|
|
|
|
m_richTextCtrl->SetStyle(range, attr);
|
|
}
|
|
}
|
|
|
|
void MyFrame::OnLineSpacingDouble(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxTextAttrEx attr;
|
|
attr.SetFlags(wxTEXT_ATTR_LINE_SPACING);
|
|
|
|
if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
|
|
{
|
|
wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
|
|
if (m_richTextCtrl->HasSelection())
|
|
range = m_richTextCtrl->GetSelectionRange();
|
|
|
|
wxFontData fontData;
|
|
attr.SetFlags(wxTEXT_ATTR_LINE_SPACING);
|
|
attr.SetLineSpacing(20);
|
|
|
|
m_richTextCtrl->SetStyle(range, attr);
|
|
}
|
|
}
|
|
|
|
void MyFrame::OnLineSpacingSingle(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxTextAttrEx attr;
|
|
attr.SetFlags(wxTEXT_ATTR_LINE_SPACING);
|
|
|
|
if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
|
|
{
|
|
wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
|
|
if (m_richTextCtrl->HasSelection())
|
|
range = m_richTextCtrl->GetSelectionRange();
|
|
|
|
wxFontData fontData;
|
|
attr.SetFlags(wxTEXT_ATTR_LINE_SPACING);
|
|
attr.SetLineSpacing(0); // Can also use 10
|
|
|
|
m_richTextCtrl->SetStyle(range, attr);
|
|
}
|
|
}
|
|
|
|
void MyFrame::OnParagraphSpacingMore(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxTextAttrEx attr;
|
|
attr.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER);
|
|
|
|
if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
|
|
{
|
|
wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
|
|
if (m_richTextCtrl->HasSelection())
|
|
range = m_richTextCtrl->GetSelectionRange();
|
|
|
|
wxFontData fontData;
|
|
attr.SetParagraphSpacingAfter(attr.GetParagraphSpacingAfter() + 20);
|
|
|
|
attr.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER);
|
|
m_richTextCtrl->SetStyle(range, attr);
|
|
}
|
|
}
|
|
|
|
void MyFrame::OnParagraphSpacingLess(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxTextAttrEx attr;
|
|
attr.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER);
|
|
|
|
if (m_richTextCtrl->GetStyle(m_richTextCtrl->GetInsertionPoint(), attr))
|
|
{
|
|
wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
|
|
if (m_richTextCtrl->HasSelection())
|
|
range = m_richTextCtrl->GetSelectionRange();
|
|
|
|
if (attr.GetParagraphSpacingAfter() >= 20)
|
|
{
|
|
wxFontData fontData;
|
|
attr.SetParagraphSpacingAfter(attr.GetParagraphSpacingAfter() - 20);
|
|
|
|
attr.SetFlags(wxTEXT_ATTR_PARA_SPACING_AFTER);
|
|
m_richTextCtrl->SetStyle(range, attr);
|
|
}
|
|
}
|
|
}
|
|
|
|
void MyFrame::OnViewHTML(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxDialog dialog(this, wxID_ANY, _("HTML"), wxDefaultPosition, wxSize(500, 400), wxDEFAULT_DIALOG_STYLE);
|
|
|
|
wxBoxSizer* boxSizer = new wxBoxSizer(wxVERTICAL);
|
|
dialog.SetSizer(boxSizer);
|
|
|
|
wxHtmlWindow* win = new wxHtmlWindow(& dialog, wxID_ANY, wxDefaultPosition, wxSize(500, 400), wxSUNKEN_BORDER);
|
|
boxSizer->Add(win, 1, wxALL, 5);
|
|
|
|
wxButton* cancelButton = new wxButton(& dialog, wxID_CANCEL, wxT("&Close"));
|
|
boxSizer->Add(cancelButton, 0, wxALL|wxCENTRE, 5);
|
|
|
|
wxString text;
|
|
wxStringOutputStream strStream(& text);
|
|
|
|
wxRichTextHTMLHandler htmlHandler;
|
|
if (htmlHandler.SaveFile(& m_richTextCtrl->GetBuffer(), strStream))
|
|
{
|
|
win->SetPage(text);
|
|
}
|
|
|
|
boxSizer->Fit(& dialog);
|
|
|
|
dialog.ShowModal();
|
|
}
|
|
|