From 590a0f8bcb889dc4e99ce26a378c02cbf57b9bdb Mon Sep 17 00:00:00 2001 From: Julian Smart Date: Tue, 17 Jan 2012 12:56:53 +0000 Subject: [PATCH] Support for undoable application of custom properties, and customisation of properties menu label git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@70374 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/richtext/richtextbuffer.h | 61 ++++++++ include/wx/richtext/richtextctrl.h | 34 +++++ interface/wx/richtext/richtextbuffer.h | 60 ++++++++ interface/wx/richtext/richtextctrl.h | 39 ++++- src/richtext/richtextbuffer.cpp | 195 ++++++++++++++++++++++++- src/richtext/richtextctrl.cpp | 57 +++++--- 6 files changed, 421 insertions(+), 25 deletions(-) diff --git a/include/wx/richtext/richtextbuffer.h b/include/wx/richtext/richtextbuffer.h index 621d9516df..af21f78675 100644 --- a/include/wx/richtext/richtextbuffer.h +++ b/include/wx/richtext/richtextbuffer.h @@ -241,6 +241,29 @@ enum wxRichTextHitTestFlags // Removes the given style instead of applying it #define wxRICHTEXT_SETSTYLE_REMOVE 0x80 +/** + Flags for SetProperties. + */ + +#define wxRICHTEXT_SETPROPERTIES_NONE 0x00 + +// Specifies that this operation should be undoable +#define wxRICHTEXT_SETPROPERTIES_WITH_UNDO 0x01 + +// Specifies that the properties should only be applied to paragraphs, +// and not the content. +#define wxRICHTEXT_SETPROPERTIES_PARAGRAPHS_ONLY 0x02 + +// Specifies that the properties should only be applied to characters, +// and not the paragraph. +#define wxRICHTEXT_SETPROPERTIES_CHARACTERS_ONLY 0x04 + +// Resets the existing properties before applying the new properties. +#define wxRICHTEXT_SETPROPERTIES_RESET 0x08 + +// Removes the given properties instead of applying them. +#define wxRICHTEXT_SETPROPERTIES_REMOVE 0x10 + /** Flags for object insertion. */ @@ -1588,6 +1611,11 @@ public: */ int Find(const wxString& name) const; + /** + Removes the given property. + */ + bool Remove(const wxString& name); + /** Gets the property variant by name. */ @@ -1648,6 +1676,16 @@ public: */ void SetProperty(const wxString& name, bool value); + /** + Removes the given properties from these properties. + */ + void RemoveProperties(const wxRichTextProperties& properties); + + /** + Merges the given properties with these properties. + */ + void MergeProperties(const wxRichTextProperties& properties); + protected: wxRichTextVariantArray m_properties; }; @@ -3106,6 +3144,28 @@ public: */ virtual bool FindNextParagraphNumber(wxRichTextParagraph* previousParagraph, wxRichTextAttr& attr) const; + /** + Sets the properties for the given range, passing flags to determine how the + attributes are set. You can merge properties or replace them. + + The end point of range is specified as the last character position of the span + of text, plus one. So, for example, to set the properties for a character at + position 5, use the range (5,6). + + @a flags may contain a bit list of the following values: + - wxRICHTEXT_SETPROPERTIES_NONE: no flag. + - wxRICHTEXT_SETPROPERTIES_WITH_UNDO: specifies that this operation should be + undoable. + - wxRICHTEXT_SETPROPERTIES_PARAGRAPHS_ONLY: specifies that the properties should only be + applied to paragraphs, and not the content. + - wxRICHTEXT_SETPROPERTIES_CHARACTERS_ONLY: specifies that the properties should only be + applied to characters, and not the paragraph. + - wxRICHTEXT_SETPROPERTIES_RESET: resets (clears) the existing properties before applying + the new properties. + - wxRICHTEXT_SETPROPERTIES_REMOVE: removes the specified properties. + */ + virtual bool SetProperties(const wxRichTextRange& range, const wxRichTextProperties& properties, int flags = wxRICHTEXT_SETPROPERTIES_WITH_UNDO); + /** Test if this whole range has character attributes of the specified kind. If any of the attributes are different within the range, the test fails. You @@ -4925,6 +4985,7 @@ enum wxRichTextCommandId wxRICHTEXT_DELETE, wxRICHTEXT_CHANGE_ATTRIBUTES, wxRICHTEXT_CHANGE_STYLE, + wxRICHTEXT_CHANGE_PROPERTIES, wxRICHTEXT_CHANGE_OBJECT }; diff --git a/include/wx/richtext/richtextctrl.h b/include/wx/richtext/richtextctrl.h index 3eeedef9cc..2007281245 100644 --- a/include/wx/richtext/richtextctrl.h +++ b/include/wx/richtext/richtextctrl.h @@ -844,6 +844,28 @@ public: virtual bool PromoteList(int promoteBy, const wxRichTextRange& range, const wxString& defName, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int specifiedLevel = -1); //@} + /** + Sets the properties for the given range, passing flags to determine how the + attributes are set. You can merge properties or replace them. + + The end point of range is specified as the last character position of the span + of text, plus one. So, for example, to set the properties for a character at + position 5, use the range (5,6). + + @a flags may contain a bit list of the following values: + - wxRICHTEXT_SETSPROPERTIES_NONE: no flag. + - wxRICHTEXT_SETPROPERTIES_WITH_UNDO: specifies that this operation should be + undoable. + - wxRICHTEXT_SETPROPERTIES_PARAGRAPHS_ONLY: specifies that the properties should only be + applied to paragraphs, and not the content. + - wxRICHTEXT_SETPROPERTIES_CHARACTERS_ONLY: specifies that the properties should only be + applied to characters, and not the paragraph. + - wxRICHTEXT_SETPROPERTIES_RESET: resets (clears) the existing properties before applying + the new properties. + - wxRICHTEXT_SETPROPERTIES_REMOVE: removes the specified properties. + */ + virtual bool SetProperties(const wxRichTextRange& range, const wxRichTextProperties& properties, int flags = wxRICHTEXT_SETPROPERTIES_WITH_UNDO); + /** Deletes the content within the given range. */ @@ -1631,6 +1653,11 @@ public: */ virtual bool EditProperties(wxRichTextObject* obj, wxWindow* parent) { return obj->EditProperties(parent, & GetBuffer()); } + /** + Gets the object's properties menu label. + */ + virtual wxString GetPropertiesMenuLabel(wxRichTextObject* obj) { return obj->GetPropertiesMenuLabel(); } + // Command handlers /** @@ -2022,6 +2049,11 @@ public: long FindCaretPositionForCharacterPosition(long position, int hitTestFlags, wxRichTextParagraphLayoutBox* container, bool& caretLineStart); + /** + Processes mouse movement in order to change the cursor + */ + virtual bool ProcessMouseMovement(wxRichTextParagraphLayoutBox* container, wxRichTextObject* obj, long position, const wxPoint& pos); + /** Font names take a long time to retrieve, so cache them (on demand). */ @@ -2404,6 +2436,7 @@ wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_STYLESHEE wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_CONTENT_INSERTED, wxRichTextEvent ); wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_CONTENT_DELETED, wxRichTextEvent ); wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_STYLE_CHANGED, wxRichTextEvent ); +wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_PROPERTIES_CHANGED, wxRichTextEvent ); wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_SELECTION_CHANGED, wxRichTextEvent ); wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_BUFFER_RESET, wxRichTextEvent ); wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_FOCUS_OBJECT_CHANGED, wxRichTextEvent ); @@ -2429,6 +2462,7 @@ typedef void (wxEvtHandler::*wxRichTextEventFunction)(wxRichTextEvent&); #define EVT_RICHTEXT_CONTENT_INSERTED(id, fn) wxDECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_RICHTEXT_CONTENT_INSERTED, id, -1, wxRichTextEventHandler( fn ), NULL ), #define EVT_RICHTEXT_CONTENT_DELETED(id, fn) wxDECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_RICHTEXT_CONTENT_DELETED, id, -1, wxRichTextEventHandler( fn ), NULL ), #define EVT_RICHTEXT_STYLE_CHANGED(id, fn) wxDECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_RICHTEXT_STYLE_CHANGED, id, -1, wxRichTextEventHandler( fn ), NULL ), +#define EVT_RICHTEXT_PROPERTIES_CHANGED(id, fn) wxDECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_RICHTEXT_PROPERTIES_CHANGED, id, -1, wxRichTextEventHandler( fn ), NULL ), #define EVT_RICHTEXT_SELECTION_CHANGED(id, fn) wxDECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_RICHTEXT_SELECTION_CHANGED, id, -1, wxRichTextEventHandler( fn ), NULL ), #define EVT_RICHTEXT_BUFFER_RESET(id, fn) wxDECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_RICHTEXT_BUFFER_RESET, id, -1, wxRichTextEventHandler( fn ), NULL ), #define EVT_RICHTEXT_FOCUS_OBJECT_CHANGED(id, fn) wxDECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_RICHTEXT_FOCUS_OBJECT_CHANGED, id, -1, wxRichTextEventHandler( fn ), NULL ), diff --git a/interface/wx/richtext/richtextbuffer.h b/interface/wx/richtext/richtextbuffer.h index 66c3d542df..0fbfc691cf 100644 --- a/interface/wx/richtext/richtextbuffer.h +++ b/interface/wx/richtext/richtextbuffer.h @@ -126,6 +126,29 @@ enum wxRichTextHitTestFlags // Removes the given style instead of applying it #define wxRICHTEXT_SETSTYLE_REMOVE 0x80 +/** + Flags for SetProperties. + */ + +#define wxRICHTEXT_SETPROPERTIES_NONE 0x00 + +// Specifies that this operation should be undoable +#define wxRICHTEXT_SETPROPERTIES_WITH_UNDO 0x01 + +// Specifies that the properties should only be applied to paragraphs, +// and not the content. +#define wxRICHTEXT_SETPROPERTIES_PARAGRAPHS_ONLY 0x02 + +// Specifies that the properties should only be applied to characters, +// and not the paragraph. +#define wxRICHTEXT_SETPROPERTIES_CHARACTERS_ONLY 0x04 + +// Resets the existing properties before applying the new properties. +#define wxRICHTEXT_SETPROPERTIES_RESET 0x08 + +// Removes the given properties instead of applying them. +#define wxRICHTEXT_SETPROPERTIES_REMOVE 0x10 + /** Flags for object insertion. */ @@ -1472,6 +1495,11 @@ public: */ int Find(const wxString& name) const; + /** + Removes the given property. + */ + bool Remove(const wxString& name); + /** Gets the property variant by name. */ @@ -1532,6 +1560,16 @@ public: */ void SetProperty(const wxString& name, bool value); + /** + Removes the given properties from these properties. + */ + void RemoveProperties(const wxRichTextProperties& properties); + + /** + Merges the given properties with these properties. + */ + void MergeProperties(const wxRichTextProperties& properties); + protected: wxRichTextVariantArray m_properties; }; @@ -2987,6 +3025,28 @@ public: */ virtual bool FindNextParagraphNumber(wxRichTextParagraph* previousParagraph, wxRichTextAttr& attr) const; + /** + Sets the properties for the given range, passing flags to determine how the + attributes are set. You can merge properties or replace them. + + The end point of range is specified as the last character position of the span + of text, plus one. So, for example, to set the properties for a character at + position 5, use the range (5,6). + + @a flags may contain a bit list of the following values: + - wxRICHTEXT_SETPROPERTIES_NONE: no flag. + - wxRICHTEXT_SETPROPERTIES_WITH_UNDO: specifies that this operation should be + undoable. + - wxRICHTEXT_SETPROPERTIES_PARAGRAPHS_ONLY: specifies that the properties should only be + applied to paragraphs, and not the content. + - wxRICHTEXT_SETPROPERTIES_CHARACTERS_ONLY: specifies that the properties should only be + applied to characters, and not the paragraph. + - wxRICHTEXT_SETPROPERTIES_RESET: resets (clears) the existing properties before applying + the new properties. + - wxRICHTEXT_SETPROPERTIES_REMOVE: removes the specified properties. + */ + virtual bool SetProperties(const wxRichTextRange& range, const wxRichTextProperties& properties, int flags = wxRICHTEXT_SETPROPERTIES_WITH_UNDO); + /** Test if this whole range has character attributes of the specified kind. If any of the attributes are different within the range, the test fails. You diff --git a/interface/wx/richtext/richtextctrl.h b/interface/wx/richtext/richtextctrl.h index 42746118b8..4252ca8e23 100644 --- a/interface/wx/richtext/richtextctrl.h +++ b/interface/wx/richtext/richtextctrl.h @@ -810,6 +810,28 @@ public: virtual bool PromoteList(int promoteBy, const wxRichTextRange& range, const wxString& defName, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int specifiedLevel = -1); //@} + /** + Sets the properties for the given range, passing flags to determine how the + attributes are set. You can merge properties or replace them. + + The end point of range is specified as the last character position of the span + of text, plus one. So, for example, to set the properties for a character at + position 5, use the range (5,6). + + @a flags may contain a bit list of the following values: + - wxRICHTEXT_SETSPROPERTIES_NONE: no flag. + - wxRICHTEXT_SETPROPERTIES_WITH_UNDO: specifies that this operation should be + undoable. + - wxRICHTEXT_SETPROPERTIES_PARAGRAPHS_ONLY: specifies that the properties should only be + applied to paragraphs, and not the content. + - wxRICHTEXT_SETPROPERTIES_CHARACTERS_ONLY: specifies that the properties should only be + applied to characters, and not the paragraph. + - wxRICHTEXT_SETPROPERTIES_RESET: resets (clears) the existing properties before applying + the new properties. + - wxRICHTEXT_SETPROPERTIES_REMOVE: removes the specified properties. + */ + virtual bool SetProperties(const wxRichTextRange& range, const wxRichTextProperties& properties, int flags = wxRICHTEXT_SETPROPERTIES_WITH_UNDO); + /** Deletes the content within the given range. */ @@ -1583,12 +1605,17 @@ public: /** Returns @true if we can edit the object's properties via a GUI. */ - virtual bool CanEditProperties(wxRichTextObject* obj) const { return obj->CanEditProperties(); } + virtual bool CanEditProperties(wxRichTextObject* obj) const; /** Edits the object's properties via a GUI. */ - virtual bool EditProperties(wxRichTextObject* obj, wxWindow* parent) { return obj->EditProperties(parent, & GetBuffer()); } + virtual bool EditProperties(wxRichTextObject* obj, wxWindow* parent); + + /** + Gets the object's properties menu label. + */ + virtual wxString GetPropertiesMenuLabel(wxRichTextObject* obj); // Command handlers @@ -1981,6 +2008,11 @@ public: long FindCaretPositionForCharacterPosition(long position, int hitTestFlags, wxRichTextParagraphLayoutBox* container, bool& caretLineStart); + /** + Processes mouse movement in order to change the cursor + */ + virtual bool ProcessMouseMovement(wxRichTextParagraphLayoutBox* container, wxRichTextObject* obj, long position, const wxPoint& pos); + /** Font names take a long time to retrieve, so cache them (on demand). */ @@ -2142,6 +2174,9 @@ protected: when the control's stylesheet has been replaced, for example when a file is loaded into the control. Valid event functions: GetOldStyleSheet, GetNewStyleSheet. + @event{EVT_RICHTEXT_PROPERTIES_CHANGED(id, func)} + Process a @c wxEVT_COMMAND_RICHTEXT_PROPERTIES_CHANGED event, generated when + properties have been applied to the control. Valid event functions: GetPosition, GetRange. @event{EVT_RICHTEXT_CONTENT_INSERTED(id, func)} Process a @c wxEVT_COMMAND_RICHTEXT_CONTENT_INSERTED event, generated when content has been inserted into the control. diff --git a/src/richtext/richtextbuffer.cpp b/src/richtext/richtextbuffer.cpp index 4c0ce37240..269a15ddd2 100644 --- a/src/richtext/richtextbuffer.cpp +++ b/src/richtext/richtextbuffer.cpp @@ -3516,6 +3516,163 @@ bool wxRichTextParagraphLayoutBox::HasParagraphAttributes(const wxRichTextRange& return foundCount == matchingCount && foundCount != 0; } +/// Set character or paragraph properties +bool wxRichTextParagraphLayoutBox::SetProperties(const wxRichTextRange& range, const wxRichTextProperties& properties, int flags) +{ + wxRichTextBuffer* buffer = GetBuffer(); + + bool withUndo = ((flags & wxRICHTEXT_SETPROPERTIES_WITH_UNDO) != 0); + bool parasOnly = ((flags & wxRICHTEXT_SETPROPERTIES_PARAGRAPHS_ONLY) != 0); + bool charactersOnly = ((flags & wxRICHTEXT_SETPROPERTIES_CHARACTERS_ONLY) != 0); + bool resetExistingProperties = ((flags & wxRICHTEXT_SETPROPERTIES_RESET) != 0); + bool removeProperties = ((flags & wxRICHTEXT_SETPROPERTIES_REMOVE) != 0); + + // If we are associated with a control, make undoable; otherwise, apply immediately + // to the data. + + bool haveControl = (buffer->GetRichTextCtrl() != NULL); + + wxRichTextAction* action = NULL; + + if (haveControl && withUndo) + { + action = new wxRichTextAction(NULL, _("Change Properties"), wxRICHTEXT_CHANGE_PROPERTIES, buffer, this, buffer->GetRichTextCtrl()); + action->SetRange(range); + action->SetPosition(buffer->GetRichTextCtrl()->GetCaretPosition()); + } + + wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst(); + while (node) + { + wxRichTextParagraph* para = wxDynamicCast(node->GetData(), wxRichTextParagraph); + // wxASSERT (para != NULL); + + if (para && para->GetChildCount() > 0) + { + // Stop searching if we're beyond the range of interest + if (para->GetRange().GetStart() > range.GetEnd()) + break; + + if (!para->GetRange().IsOutside(range)) + { + // We'll be using a copy of the paragraph to make style changes, + // not updating the buffer directly. + wxRichTextParagraph* newPara wxDUMMY_INITIALIZE(NULL); + + if (haveControl && withUndo) + { + newPara = new wxRichTextParagraph(*para); + action->GetNewParagraphs().AppendChild(newPara); + + // Also store the old ones for Undo + action->GetOldParagraphs().AppendChild(new wxRichTextParagraph(*para)); + } + else + newPara = para; + + if (parasOnly) + { + if (removeProperties) + { + // Removes the given style from the paragraph + // TODO + newPara->GetProperties().RemoveProperties(properties); + } + else if (resetExistingProperties) + newPara->GetProperties() = properties; + else + newPara->GetProperties().MergeProperties(properties); + } + + // When applying paragraph styles dynamically, don't change the text objects' attributes + // since they will computed as needed. Only apply the character styling if it's _only_ + // character styling. This policy is subject to change and might be put under user control. + + // Hm. we might well be applying a mix of paragraph and character styles, in which + // case we _do_ want to apply character styles regardless of what para styles are set. + // But if we're applying a paragraph style, which has some character attributes, but + // we only want the paragraphs to hold this character style, then we _don't_ want to + // apply the character style. So we need to be able to choose. + + if (!parasOnly && charactersOnly && range.GetStart() != newPara->GetRange().GetEnd()) + { + wxRichTextRange childRange(range); + childRange.LimitTo(newPara->GetRange()); + + // Find the starting position and if necessary split it so + // we can start applying different properties. + // TODO: check that the properties actually change or are different + // from properties outside of range + wxRichTextObject* firstObject wxDUMMY_INITIALIZE(NULL); + wxRichTextObject* lastObject wxDUMMY_INITIALIZE(NULL); + + if (childRange.GetStart() == newPara->GetRange().GetStart()) + firstObject = newPara->GetChildren().GetFirst()->GetData(); + else + firstObject = newPara->SplitAt(range.GetStart()); + + // Increment by 1 because we're apply the style one _after_ the split point + long splitPoint = childRange.GetEnd(); + if (splitPoint != newPara->GetRange().GetEnd()) + splitPoint ++; + + // Find last object + if (splitPoint == newPara->GetRange().GetEnd()) + lastObject = newPara->GetChildren().GetLast()->GetData(); + else + // lastObject is set as a side-effect of splitting. It's + // returned as the object before the new object. + (void) newPara->SplitAt(splitPoint, & lastObject); + + wxASSERT(firstObject != NULL); + wxASSERT(lastObject != NULL); + + if (!firstObject || !lastObject) + continue; + + wxRichTextObjectList::compatibility_iterator firstNode = newPara->GetChildren().Find(firstObject); + wxRichTextObjectList::compatibility_iterator lastNode = newPara->GetChildren().Find(lastObject); + + wxASSERT(firstNode); + wxASSERT(lastNode); + + wxRichTextObjectList::compatibility_iterator node2 = firstNode; + + while (node2) + { + wxRichTextObject* child = node2->GetData(); + + if (removeProperties) + { + // Removes the given properties from the paragraph + child->GetProperties().RemoveProperties(properties); + } + else if (resetExistingProperties) + child->GetProperties() = properties; + else + { + child->GetProperties().MergeProperties(properties); + } + + if (node2 == lastNode) + break; + + node2 = node2->GetNext(); + } + } + } + } + + node = node->GetNext(); + } + + // Do action, or delay it until end of batch. + if (haveControl && withUndo) + buffer->SubmitAction(action); + + return true; +} + void wxRichTextParagraphLayoutBox::Reset() { Clear(); @@ -9466,6 +9623,7 @@ bool wxRichTextAction::Do() break; } case wxRICHTEXT_CHANGE_STYLE: + case wxRICHTEXT_CHANGE_PROPERTIES: { ApplyParagraphs(GetNewParagraphs()); @@ -9476,7 +9634,7 @@ bool wxRichTextAction::Do() UpdateAppearance(GetPosition()); wxRichTextEvent cmdEvent( - wxEVT_COMMAND_RICHTEXT_STYLE_CHANGED, + m_cmdId == wxRICHTEXT_CHANGE_STYLE ? wxEVT_COMMAND_RICHTEXT_STYLE_CHANGED : wxEVT_COMMAND_RICHTEXT_PROPERTIES_CHANGED, m_ctrl ? m_ctrl->GetId() : -1); cmdEvent.SetEventObject(m_ctrl ? (wxObject*) m_ctrl : (wxObject*) m_buffer); cmdEvent.SetRange(GetRange()); @@ -9619,6 +9777,7 @@ bool wxRichTextAction::Undo() break; } case wxRICHTEXT_CHANGE_STYLE: + case wxRICHTEXT_CHANGE_PROPERTIES: { ApplyParagraphs(GetOldParagraphs()); // InvalidateHierarchy goes up the hierarchy as well as down, otherwise with a nested object, @@ -9628,7 +9787,7 @@ bool wxRichTextAction::Undo() UpdateAppearance(GetPosition()); wxRichTextEvent cmdEvent( - wxEVT_COMMAND_RICHTEXT_STYLE_CHANGED, + m_cmdId == wxRICHTEXT_CHANGE_STYLE ? wxEVT_COMMAND_RICHTEXT_STYLE_CHANGED : wxEVT_COMMAND_RICHTEXT_PROPERTIES_CHANGED, m_ctrl ? m_ctrl->GetId() : -1); cmdEvent.SetEventObject(m_ctrl ? (wxObject*) m_ctrl : (wxObject*) m_buffer); cmdEvent.SetRange(GetRange()); @@ -11946,6 +12105,18 @@ int wxRichTextProperties::Find(const wxString& name) const return -1; } +bool wxRichTextProperties::Remove(const wxString& name) +{ + int idx = Find(name); + if (idx != -1) + { + m_properties.RemoveAt(idx); + return true; + } + else + return false; +} + wxVariant* wxRichTextProperties::FindOrCreateProperty(const wxString& name) { int idx = Find(name); @@ -12034,6 +12205,26 @@ void wxRichTextProperties::SetProperty(const wxString& name, bool value) SetProperty(name, wxVariant(value, name)); } +void wxRichTextProperties::RemoveProperties(const wxRichTextProperties& properties) +{ + size_t i; + for (i = 0; i < properties.GetCount(); i++) + { + wxString name = properties.GetProperties()[i].GetName(); + if (HasProperty(name)) + Remove(name); + } +} + +void wxRichTextProperties::MergeProperties(const wxRichTextProperties& properties) +{ + size_t i; + for (i = 0; i < properties.GetCount(); i++) + { + SetProperty(properties.GetProperties()[i]); + } +} + wxRichTextObject* wxRichTextObjectAddress::GetObject(wxRichTextParagraphLayoutBox* topLevelContainer) const { if (m_address.GetCount() == 0) diff --git a/src/richtext/richtextctrl.cpp b/src/richtext/richtextctrl.cpp index ef16e23b4e..626cd1357a 100644 --- a/src/richtext/richtextctrl.cpp +++ b/src/richtext/richtextctrl.cpp @@ -65,6 +65,7 @@ wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_STYLESHEET_CHANGED, wxRichTextEvent ); wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_CONTENT_INSERTED, wxRichTextEvent ); wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_CONTENT_DELETED, wxRichTextEvent ); wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_STYLE_CHANGED, wxRichTextEvent ); +wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_PROPERTIES_CHANGED, wxRichTextEvent ); wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_SELECTION_CHANGED, wxRichTextEvent ); wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_BUFFER_RESET, wxRichTextEvent ); wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_FOCUS_OBJECT_CHANGED, wxRichTextEvent ); @@ -231,10 +232,6 @@ wxRichTextCtrl::wxRichTextCtrl(wxWindow* parent, { Init(); Create(parent, id, value, pos, size, style, validator, name); - -#if wxUSE_DRAG_AND_DROP - SetDropTarget(new wxRichTextDropTarget(this)); -#endif } /// Creation @@ -334,6 +331,10 @@ bool wxRichTextCtrl::Create( wxWindow* parent, wxWindowID id, const wxString& va m_contextMenu->AppendSeparator(); m_contextMenu->Append(wxID_RICHTEXT_PROPERTIES1, _("&Properties")); +#if wxUSE_DRAG_AND_DROP + SetDropTarget(new wxRichTextDropTarget(this)); +#endif + return true; } @@ -830,18 +831,8 @@ void wxRichTextCtrl::OnMoveMouse(wxMouseEvent& event) if (hit != wxRICHTEXT_HITTEST_NONE && !(hit & wxRICHTEXT_HITTEST_OUTSIDE) && hitObj) { wxRichTextParagraphLayoutBox* actualContainer = wxDynamicCast(contextObj, wxRichTextParagraphLayoutBox); - wxRichTextAttr attr; - if (actualContainer && GetStyle(position, attr, actualContainer)) - { - if (attr.HasFlag(wxTEXT_ATTR_URL)) - { - SetCursor(m_urlCursor); - } - else if (!attr.HasFlag(wxTEXT_ATTR_URL)) - { - SetCursor(m_textCursor); - } - } + if (actualContainer) + ProcessMouseMovement(actualContainer, hitObj, position, logicalPt); } else SetCursor(m_textCursor); @@ -1406,6 +1397,25 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) } } +bool wxRichTextCtrl::ProcessMouseMovement(wxRichTextParagraphLayoutBox* container, wxRichTextObject* obj, long position, const wxPoint& pos) +{ + wxRichTextAttr attr; + if (container && GetStyle(position, attr, container)) + { + if (attr.HasFlag(wxTEXT_ATTR_URL)) + { + SetCursor(m_urlCursor); + } + else if (!attr.HasFlag(wxTEXT_ATTR_URL)) + { + SetCursor(m_textCursor); + } + return true; + } + else + return false; +} + /// Delete content if there is a selection, e.g. when pressing a key. bool wxRichTextCtrl::DeleteSelectedContent(long* newPos) { @@ -3569,6 +3579,11 @@ bool wxRichTextCtrl::GetUncombinedStyle(long position, wxRichTextAttr& style, wx return container->GetUncombinedStyle(position, style); } +bool wxRichTextCtrl::SetProperties(const wxRichTextRange& range, const wxRichTextProperties& properties, int flags) +{ + return GetFocusObject()->SetProperties(range.ToInternal(), properties, flags); +} + /// Set font, and also the buffer attributes bool wxRichTextCtrl::SetFont(const wxFont& font) { @@ -4675,13 +4690,13 @@ int wxRichTextContextMenuPropertiesInfo::AddItems(wxRichTextCtrl* ctrl, wxRichTe { Clear(); if (obj && ctrl->CanEditProperties(obj)) - AddItem(obj->GetPropertiesMenuLabel(), obj); + AddItem(ctrl->GetPropertiesMenuLabel(obj), obj); - if (container && container != obj && ctrl->CanEditProperties(container) && m_labels.Index(container->GetPropertiesMenuLabel()) == wxNOT_FOUND) - AddItem(container->GetPropertiesMenuLabel(), container); + if (container && container != obj && ctrl->CanEditProperties(container) && m_labels.Index(ctrl->GetPropertiesMenuLabel(container)) == wxNOT_FOUND) + AddItem(ctrl->GetPropertiesMenuLabel(container), container); - if (container && container->GetParent() && ctrl->CanEditProperties(container->GetParent()) && m_labels.Index(container->GetParent()->GetPropertiesMenuLabel()) == wxNOT_FOUND) - AddItem(container->GetParent()->GetPropertiesMenuLabel(), container->GetParent()); + if (container && container->GetParent() && ctrl->CanEditProperties(container->GetParent()) && m_labels.Index(ctrl->GetPropertiesMenuLabel(container->GetParent())) == wxNOT_FOUND) + AddItem(ctrl->GetPropertiesMenuLabel(container->GetParent()), container->GetParent()); return GetCount(); } -- 2.45.2