#include "wx/sstream.h"
#include "wx/html/htmlwin.h"
#include "wx/stopwatch.h"
+#include "wx/sysopt.h"
#if wxUSE_FILESYSTEM
#include "wx/filesys.h"
#include "wx/cshelp.h"
#endif
-#ifndef __WXMSW__
+#ifndef wxHAS_IMAGES_IN_RESOURCES
#include "../sample.xpm"
#endif
// private classes
// ----------------------------------------------------------------------------
+// Define a new application type, each program should derive a class from wxApp
+class MyRichTextCtrl: public wxRichTextCtrl
+{
+public:
+ MyRichTextCtrl( wxWindow* parent, wxWindowID id = -1, const wxString& value = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+ long style = wxRE_MULTILINE, const wxValidator& validator = wxDefaultValidator, const wxString& name = wxTextCtrlNameStr):
+ wxRichTextCtrl(parent, id, value, pos, size, style, validator, name)
+ {
+ m_lockId = 0;
+ m_locked = false;
+ }
+
+ void SetLockId(long id) { m_lockId = id; }
+ long GetLockId() const { return m_lockId; }
+
+ void BeginLock() { m_lockId ++; m_locked = true; }
+ void EndLock() { m_locked = false; }
+ bool IsLocked() const { return m_locked; }
+
+ static void SetEnhancedDrawingHandler();
+
+ /**
+ Prepares the content just before insertion (or after buffer reset). Called by the same function in wxRichTextBuffer.
+ Currently is only called if undo mode is on.
+ */
+ virtual void PrepareContent(wxRichTextParagraphLayoutBox& container);
+
+ /**
+ Can we delete this range?
+ Sends an event to the control.
+ */
+ virtual bool CanDeleteRange(wxRichTextParagraphLayoutBox& container, const wxRichTextRange& range) const;
+
+ /**
+ Can we insert content at this position?
+ Sends an event to the control.
+ */
+ virtual bool CanInsertContent(wxRichTextParagraphLayoutBox& container, long pos) const;
+
+ long m_lockId;
+ bool m_locked;
+};
+
// Define a new application type, each program should derive a class from wxApp
class MyApp : public wxApp
{
// any class wishing to process wxWidgets events must use this macro
DECLARE_EVENT_TABLE()
- wxRichTextCtrl* m_richTextCtrl;
+ MyRichTextCtrl* m_richTextCtrl;
};
// ----------------------------------------------------------------------------
CreateStyles();
+ MyRichTextCtrl::SetEnhancedDrawingHandler();
+
// Add extra handlers (plain text is automatically added)
wxRichTextBuffer::AddHandler(new wxRichTextXMLHandler);
wxRichTextBuffer::AddHandler(new wxRichTextHTMLHandler);
const wxSize& size, long style)
: wxFrame(NULL, id, title, pos, size, style)
{
+#ifdef __WXMAC__
+ SetWindowVariant(wxWINDOW_VARIANT_SMALL);
+#endif
+
// set the frame icon
SetIcon(wxICON(sample));
}
#endif
- wxToolBar* toolBar = CreateToolBar();
+ wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
+ SetSizer(sizer);
+
+ // On Mac, don't create a 'native' wxToolBar because small bitmaps are not supported by native
+ // toolbars. On Mac, a non-native, small-bitmap toolbar doesn't show unless it is explicitly
+ // managed, hence the use of sizers. In a real application, use larger icons for the main
+ // toolbar to avoid the need for this workaround. Or, use the toolbar in a container window
+ // as part of a more complex hierarchy, and the toolbar will automatically be non-native.
+
+ wxSystemOptions::SetOption(wxT("mac.toolbar.no-native"), 1);
+
+ wxToolBar* toolBar = new wxToolBar(this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
+ wxNO_BORDER|wxTB_FLAT|wxTB_NODIVIDER|wxTB_NOALIGN);
+
+ sizer->Add(toolBar, 0, wxEXPAND);
toolBar->AddTool(wxID_OPEN, wxEmptyString, wxBitmap(open_xpm), _("Open"));
toolBar->AddTool(wxID_SAVEAS, wxEmptyString, wxBitmap(save_xpm), _("Save"));
toolBar->AddTool(ID_FORMAT_INDENT_MORE, wxEmptyString, wxBitmap(indentmore_xpm), _("Indent More"));
toolBar->AddSeparator();
toolBar->AddTool(ID_FORMAT_FONT, wxEmptyString, wxBitmap(font_xpm), _("Font"));
- toolBar->AddTool(ID_FORMAT_IMAGE, wxString("Im"), wxBitmap(font_xpm), _("Image Property"));
+ toolBar->AddSeparator();
- wxRichTextStyleComboCtrl* combo = new wxRichTextStyleComboCtrl(toolBar, ID_RICHTEXT_STYLE_COMBO, wxDefaultPosition, wxSize(200, -1));
+ wxRichTextStyleComboCtrl* combo = new wxRichTextStyleComboCtrl(toolBar, ID_RICHTEXT_STYLE_COMBO, wxDefaultPosition, wxSize(160, -1), wxCB_READONLY);
toolBar->AddControl(combo);
toolBar->Realize();
- wxSplitterWindow* splitter = new wxSplitterWindow(this, wxID_ANY, wxDefaultPosition, GetClientSize(), wxSP_LIVE_UPDATE);
+ wxSplitterWindow* splitter = new wxSplitterWindow(this, wxID_ANY, wxDefaultPosition, wxSize(100,100), wxSP_LIVE_UPDATE);
+ sizer->Add(splitter, 1, wxEXPAND);
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, ID_RICHTEXT_CTRL, wxEmptyString, wxDefaultPosition, wxSize(200, 200), wxVSCROLL|wxHSCROLL|wxWANTS_CHARS);
+ m_richTextCtrl = new MyRichTextCtrl(splitter, ID_RICHTEXT_CTRL, wxEmptyString, wxDefaultPosition, wxSize(200, 200), wxVSCROLL|wxHSCROLL|wxWANTS_CHARS);
wxFont font(12, wxROMAN, wxNORMAL, wxNORMAL);
m_richTextCtrl->SetFont(font);
splitter->SplitVertically(m_richTextCtrl, styleListCtrl, 500);
}
+ Layout();
+
splitter->UpdateSize();
styleListCtrl->SetStyleSheet(wxGetApp().GetStyleSheet());
// Write text
void MyFrame::WriteInitialText()
{
- wxRichTextCtrl& r = *m_richTextCtrl;
+ MyRichTextCtrl& r = *m_richTextCtrl;
r.SetDefaultStyle(wxRichTextAttr());
- r.BeginSuppressUndo();
-
r.Freeze();
+ r.BeginSuppressUndo();
+
r.BeginParagraphSpacing(0, 20);
r.BeginAlignment(wxTEXT_ALIGNMENT_CENTRE);
}
#endif
- r.Thaw();
-
r.EndSuppressUndo();
+
+ // Add some locked content first - needs Undo to be enabled
+ {
+ r.BeginLock();
+ r.WriteText(wxString(wxT("This is a locked object.")));
+ r.EndLock();
+
+ r.WriteText(wxString(wxT(" This is unlocked text. ")));
+
+ r.BeginLock();
+ r.WriteText(wxString(wxT("More locked content.")));
+ r.EndLock();
+ r.Newline();
+
+ // Flush the Undo buffer
+ r.GetCommandProcessor()->ClearCommands();
+ }
+
+ r.Thaw();
}
// event handlers
// wxGetApp().GetPrinting()->PageSetup();
}
+
+void MyRichTextCtrl::PrepareContent(wxRichTextParagraphLayoutBox& container)
+{
+ if (IsLocked())
+ {
+ // Lock all content that's about to be added to the control
+ wxRichTextObjectList::compatibility_iterator node = container.GetChildren().GetFirst();
+ while (node)
+ {
+ wxRichTextParagraph* para = wxDynamicCast(node->GetData(), wxRichTextParagraph);
+ if (para)
+ {
+ wxRichTextObjectList::compatibility_iterator childNode = para->GetChildren().GetFirst();
+ while (childNode)
+ {
+ wxRichTextObject* obj = childNode->GetData();
+ obj->GetProperties().SetProperty(wxT("Lock"), m_lockId);
+
+ childNode = childNode->GetNext();
+ }
+ }
+ node = node->GetNext();
+ }
+ }
+}
+
+bool MyRichTextCtrl::CanDeleteRange(wxRichTextParagraphLayoutBox& container, const wxRichTextRange& range) const
+{
+ long i;
+ for (i = range.GetStart(); i < range.GetEnd(); i++)
+ {
+ wxRichTextObject* obj = container.GetLeafObjectAtPosition(i);
+ if (obj && obj->GetProperties().HasProperty(wxT("Lock")))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool MyRichTextCtrl::CanInsertContent(wxRichTextParagraphLayoutBox& container, long pos) const
+{
+ wxRichTextObject* child1 = container.GetLeafObjectAtPosition(pos);
+ wxRichTextObject* child2 = container.GetLeafObjectAtPosition(pos-1);
+
+ long lock1 = -1, lock2 = -1;
+
+ if (child1 && child1->GetProperties().HasProperty(wxT("Lock")))
+ lock1 = child1->GetProperties().GetPropertyLong(wxT("Lock"));
+ if (child2 && child2->GetProperties().HasProperty(wxT("Lock")))
+ lock2 = child2->GetProperties().GetPropertyLong(wxT("Lock"));
+
+ if (lock1 != -1 && lock1 == lock2)
+ return false;
+
+ // Don't allow insertion before a locked object if it's at the beginning of the buffer.
+ if (pos == 0 && lock1 != -1)
+ return false;
+
+ return true;
+}
+
+
+class wxRichTextEnhancedDrawingHandler: public wxRichTextDrawingHandler
+{
+public:
+ wxRichTextEnhancedDrawingHandler()
+ {
+ SetName(wxT("enhanceddrawing"));
+ m_lockBackgroundColour = wxColour(220, 220, 220);
+ }
+
+ /**
+ Returns @true if this object has virtual attributes that we can provide.
+ */
+ virtual bool HasVirtualAttributes(wxRichTextObject* obj) const;
+
+ /**
+ Provides virtual attributes that we can provide.
+ */
+ virtual bool GetVirtualAttributes(wxRichTextAttr& attr, wxRichTextObject* obj) const;
+
+ wxColour m_lockBackgroundColour;
+};
+
+bool wxRichTextEnhancedDrawingHandler::HasVirtualAttributes(wxRichTextObject* obj) const
+{
+ return obj->GetProperties().HasProperty(wxT("Lock"));
+}
+
+bool wxRichTextEnhancedDrawingHandler::GetVirtualAttributes(wxRichTextAttr& attr, wxRichTextObject* obj) const
+{
+ if (obj->GetProperties().HasProperty(wxT("Lock")))
+ {
+ attr.SetBackgroundColour(m_lockBackgroundColour);
+ return true;
+ }
+ return false;
+}
+
+void MyRichTextCtrl::SetEnhancedDrawingHandler()
+{
+ wxRichTextBuffer::AddDrawingHandler(new wxRichTextEnhancedDrawingHandler);
+}