From 9550c37e2972810ddb55ed695ccd766815f0c170 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 31 Jan 2024 02:48:10 +0100 Subject: [PATCH] Support inherited attributes in wxPropertyGrid XRC handler Allow specifying recurse="1" to inherit the attribute, as this is much nicer than having to specify it for all the children. Also add support for this to wxPropertyGridPopulator, which is used by the XRC handler. --- docs/doxygen/overviews/xrc_format.h | 5 +++++ include/wx/propgrid/propgrid.h | 6 +++++- interface/wx/propgrid/propgrid.h | 8 +++++++- src/propgrid/propgrid.cpp | 21 ++++++++++++++++++++- src/xrc/xh_propgrid.cpp | 6 +++++- 5 files changed, 42 insertions(+), 4 deletions(-) diff --git a/docs/doxygen/overviews/xrc_format.h b/docs/doxygen/overviews/xrc_format.h index 7d6c0e2257..7d377bd218 100644 --- a/docs/doxygen/overviews/xrc_format.h +++ b/docs/doxygen/overviews/xrc_format.h @@ -1865,6 +1865,11 @@ to use it. @row3col{choices, @ref overview_xrcformat_type_string, Space-separated string containing the possible choices for the properties using them, e.g. wxFlagsProperty or wxEnumProperty.} +@row3col{attribute, @ref overview_xrcformat_type_string, + Value for the property attribute with the name specified by the `name` + attribute of this element. Additional `recurse` attribute is supported and, + if specified with the value of `1`, results in the attribute being set for + this property and all its children recursively.} @endTable These elements define individual rows of @ref xrc_wxpropertygrid or @ref diff --git a/include/wx/propgrid/propgrid.h b/include/wx/propgrid/propgrid.h index fa6f8e46cb..5080c05e7b 100644 --- a/include/wx/propgrid/propgrid.h +++ b/include/wx/propgrid/propgrid.h @@ -2157,7 +2157,8 @@ public: // Empty string mean autodetect. bool AddAttribute( const wxString& name, const wxString& type, - const wxString& value ); + const wxString& value, + wxPGPropertyValuesFlags flags = wxPGPropertyValuesFlags::DontRecurse ); // Called once in AddChildren. virtual void DoScanForChildren() = 0; @@ -2197,6 +2198,9 @@ protected: // Tree-hierarchy of added properties (that can have children). std::vector m_propHierarchy; + // Recursively set attributes. + std::unordered_map m_inheritedAttributes; + // Hashmap for string-id to wxPGChoicesData mapping. std::unordered_map m_dictIdChoices; }; diff --git a/interface/wx/propgrid/propgrid.h b/interface/wx/propgrid/propgrid.h index b3c426752e..3993ada9b2 100644 --- a/interface/wx/propgrid/propgrid.h +++ b/interface/wx/propgrid/propgrid.h @@ -1534,10 +1534,16 @@ public: @param value Attribute value. + + @param flags + Flags used when setting the attribute. Currently only + wxPGPropertyValuesFlags::Recurse is used here. This parameter is + only available since wxWidgets 3.3.0. */ bool AddAttribute( const wxString& name, const wxString& type, - const wxString& value ); + const wxString& value, + wxPGPropertyValuesFlags flags = wxPGPropertyValuesFlags::DontRecurse ); /** Called once in AddChildren. diff --git a/src/propgrid/propgrid.cpp b/src/propgrid/propgrid.cpp index 7112061fca..9e3a6a4262 100644 --- a/src/propgrid/propgrid.cpp +++ b/src/propgrid/propgrid.cpp @@ -6416,9 +6416,22 @@ wxPGProperty* wxPropertyGridPopulator::Add( const wxString& propClass, void wxPropertyGridPopulator::AddChildren( wxPGProperty* property ) { + // Preserve inherited attributes to be able to restore them later: + // attributes recursively set for the children of this property shouldn't + // be inherited by its siblings. + const auto inheritedAttributesOrig = m_inheritedAttributes; + + // Apply inherited attributes to the property. + for ( const auto& it : m_inheritedAttributes ) + { + property->SetAttribute(it.first, it.second); + } + m_propHierarchy.push_back(property); DoScanForChildren(); m_propHierarchy.pop_back(); + + m_inheritedAttributes = std::move(inheritedAttributesOrig); } // ----------------------------------------------------------------------- @@ -6540,7 +6553,8 @@ bool wxPropertyGridPopulator::ToLongPCT( const wxString& s, long* pval, long max bool wxPropertyGridPopulator::AddAttribute( const wxString& name, const wxString& type, - const wxString& value ) + const wxString& value, + wxPGPropertyValuesFlags flags ) { if ( m_propHierarchy.empty() ) return false; @@ -6589,6 +6603,11 @@ bool wxPropertyGridPopulator::AddAttribute( const wxString& name, } } + if ( !!(flags & wxPGPropertyValuesFlags::Recurse) ) + { + m_inheritedAttributes[name] = variant; + } + p->SetAttribute( name, variant ); return true; diff --git a/src/xrc/xh_propgrid.cpp b/src/xrc/xh_propgrid.cpp index 409a817fa4..a4af1b32a2 100644 --- a/src/xrc/xh_propgrid.cpp +++ b/src/xrc/xh_propgrid.cpp @@ -175,8 +175,12 @@ wxObject *wxPropertyGridXmlHandler::DoCreateResource() wxString s1 = node->GetAttribute("name"); if ( s1.length() ) { + wxPGPropertyValuesFlags flags = node->GetAttribute("recurse") == "1" + ? wxPGPropertyValuesFlags::Recurse + : wxPGPropertyValuesFlags::DontRecurse; + m_populator->AddAttribute( s1, node->GetAttribute("type"), - node->GetNodeContent() ); + node->GetNodeContent(), flags ); } } else if( m_class == wxT("wxPropertyGrid"))