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"))