From 47793ab85a3fa3efd6039a28cfbef9cee20e7d9d Mon Sep 17 00:00:00 2001 From: =?utf8?q?V=C3=A1clav=20Slav=C3=ADk?= Date: Thu, 17 Jan 2002 00:16:54 +0000 Subject: [PATCH] implemented Alex's symlinks in XRC git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@13608 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- contrib/include/wx/xrc/xmlres.h | 3 +- contrib/src/xrc/xmlres.cpp | 130 +++++++++++++++++++++++++++----- include/wx/xrc/xmlres.h | 3 +- src/xrc/xmlres.cpp | 130 +++++++++++++++++++++++++++----- 4 files changed, 226 insertions(+), 40 deletions(-) diff --git a/contrib/include/wx/xrc/xmlres.h b/contrib/include/wx/xrc/xmlres.h index 7574284b4a..01f70f294b 100644 --- a/contrib/include/wx/xrc/xmlres.h +++ b/contrib/include/wx/xrc/xmlres.h @@ -179,7 +179,8 @@ protected: void UpdateResources(); // Finds resource (calls UpdateResources) and returns node containing it - wxXmlNode *FindResource(const wxString& name, const wxString& classname); + wxXmlNode *FindResource(const wxString& name, const wxString& classname, bool recursive = FALSE); + wxXmlNode *DoFindResource(wxXmlNode *parent, const wxString& name, const wxString& classname, bool recursive); // Creates resource from info in given node: wxObject *CreateResFromNode(wxXmlNode *node, wxObject *parent, wxObject *instance = NULL); diff --git a/contrib/src/xrc/xmlres.cpp b/contrib/src/xrc/xmlres.cpp index 745d4213fd..a802efe57c 100644 --- a/contrib/src/xrc/xmlres.cpp +++ b/contrib/src/xrc/xmlres.cpp @@ -344,29 +344,64 @@ void wxXmlResource::UpdateResources() } +wxXmlNode *wxXmlResource::DoFindResource(wxXmlNode *parent, + const wxString& name, + const wxString& classname, + bool recursive) +{ + wxString dummy; + wxXmlNode *node; + + // first search for match at the top-level nodes (as this is + // where the resource is most commonly looked for): + for (node = parent->GetChildren(); node; node = node->GetNext()) + { + if ( node->GetType() == wxXML_ELEMENT_NODE && + (node->GetName() == wxT("object") || + node->GetName() == wxT("object_ref")) && + (!classname || + node->GetPropVal(wxT("class"), wxEmptyString) == classname) && + node->GetPropVal(wxT("name"), &dummy) && dummy == name ) + return node; + } + + if ( recursive ) + for (node = parent->GetChildren(); node; node = node->GetNext()) + { + if ( node->GetType() == wxXML_ELEMENT_NODE && + (node->GetName() == wxT("object") || + node->GetName() == wxT("object_ref")) ) + { + wxXmlNode* found = DoFindResource(node, name, classname, TRUE); + if ( found ) + return found; + } + } + + return NULL; +} -wxXmlNode *wxXmlResource::FindResource(const wxString& name, const wxString& classname) +wxXmlNode *wxXmlResource::FindResource(const wxString& name, + const wxString& classname, + bool recursive) { UpdateResources(); //ensure everything is up-to-date wxString dummy; for (size_t f = 0; f < m_data.GetCount(); f++) { - if (m_data[f].Doc == NULL || m_data[f].Doc->GetRoot() == NULL) continue; - for (wxXmlNode *node = m_data[f].Doc->GetRoot()->GetChildren(); - node; node = node->GetNext()) - if (node->GetType() == wxXML_ELEMENT_NODE && - (!classname || - node->GetPropVal(wxT("class"), wxEmptyString) == classname) && - node->GetName() == wxT("object") && - node->GetPropVal(wxT("name"), &dummy) && - dummy == name) - { + if ( m_data[f].Doc == NULL || m_data[f].Doc->GetRoot() == NULL ) + continue; + + wxXmlNode* found = DoFindResource(m_data[f].Doc->GetRoot(), + name, classname, recursive); + if ( found ) + { #if wxUSE_FILESYSTEM - m_curFileSystem.ChangePathTo(m_data[f].File); + m_curFileSystem.ChangePathTo(m_data[f].File); #endif - return node; - } + return found; + } } wxLogError(_("XRC resource '%s' (class '%s') not found!"), @@ -374,12 +409,74 @@ wxXmlNode *wxXmlResource::FindResource(const wxString& name, const wxString& cla return NULL; } +static void MergeNodes(wxXmlNode& dest, wxXmlNode& with) +{ + // Merge properties: + for (wxXmlProperty *prop = with.GetProperties(); prop; prop = prop->GetNext()) + { + wxXmlProperty *dprop; + for (dprop = dest.GetProperties(); dprop; dprop = dprop->GetNext()) + { + + if ( dprop->GetName() == prop->GetName() ) + { + dprop->SetValue(prop->GetValue()); + break; + } + } + if ( !dprop ) + dest.AddProperty(prop->GetName(), prop->GetValue()); + } + + // Merge child nodes: + for (wxXmlNode* node = with.GetChildren(); node; node = node->GetNext()) + { + wxString name = node->GetPropVal(wxT("name"), wxEmptyString); + wxXmlNode *dnode; + + for (dnode = dest.GetChildren(); dnode; dnode = dnode->GetNext() ) + { + if ( dnode->GetName() == node->GetName() && + dnode->GetPropVal("name", wxEmptyString) == name && + dnode->GetType() == node->GetType() ) + { + MergeNodes(*dnode, *node); + break; + } + } + + if ( !dnode ) + dest.AddChild(new wxXmlNode(*node)); + } + + if ( dest.GetType() == wxXML_TEXT_NODE && with.GetContent().Length() ) + dest.SetContent(with.GetContent()); +} wxObject *wxXmlResource::CreateResFromNode(wxXmlNode *node, wxObject *parent, wxObject *instance) { if (node == NULL) return NULL; + // handling of referenced resource + if ( node->GetName() == wxT("object_ref") ) + { + wxString refName = node->GetPropVal(wxT("ref"), wxEmptyString); + wxXmlNode* refNode = FindResource(refName, wxEmptyString, TRUE); + + if ( !refNode ) + { + wxLogError(_("Referenced object node with ref=\"%s\" not found!"), + refName.c_str()); + return NULL; + } + + wxXmlNode copy(*refNode); + MergeNodes(copy, *node); + + return CreateResFromNode(©, parent, instance); + } + wxXmlResourceHandler *handler; wxObject *ret; wxNode * ND = m_handlers.GetFirst(); @@ -403,11 +500,6 @@ wxObject *wxXmlResource::CreateResFromNode(wxXmlNode *node, wxObject *parent, wx - - - - - wxXmlResourceHandler::wxXmlResourceHandler() : m_node(NULL), m_parent(NULL), m_instance(NULL), m_parentAsWindow(NULL), m_instanceAsWindow(NULL) diff --git a/include/wx/xrc/xmlres.h b/include/wx/xrc/xmlres.h index 7574284b4a..01f70f294b 100644 --- a/include/wx/xrc/xmlres.h +++ b/include/wx/xrc/xmlres.h @@ -179,7 +179,8 @@ protected: void UpdateResources(); // Finds resource (calls UpdateResources) and returns node containing it - wxXmlNode *FindResource(const wxString& name, const wxString& classname); + wxXmlNode *FindResource(const wxString& name, const wxString& classname, bool recursive = FALSE); + wxXmlNode *DoFindResource(wxXmlNode *parent, const wxString& name, const wxString& classname, bool recursive); // Creates resource from info in given node: wxObject *CreateResFromNode(wxXmlNode *node, wxObject *parent, wxObject *instance = NULL); diff --git a/src/xrc/xmlres.cpp b/src/xrc/xmlres.cpp index 745d4213fd..a802efe57c 100644 --- a/src/xrc/xmlres.cpp +++ b/src/xrc/xmlres.cpp @@ -344,29 +344,64 @@ void wxXmlResource::UpdateResources() } +wxXmlNode *wxXmlResource::DoFindResource(wxXmlNode *parent, + const wxString& name, + const wxString& classname, + bool recursive) +{ + wxString dummy; + wxXmlNode *node; + + // first search for match at the top-level nodes (as this is + // where the resource is most commonly looked for): + for (node = parent->GetChildren(); node; node = node->GetNext()) + { + if ( node->GetType() == wxXML_ELEMENT_NODE && + (node->GetName() == wxT("object") || + node->GetName() == wxT("object_ref")) && + (!classname || + node->GetPropVal(wxT("class"), wxEmptyString) == classname) && + node->GetPropVal(wxT("name"), &dummy) && dummy == name ) + return node; + } + + if ( recursive ) + for (node = parent->GetChildren(); node; node = node->GetNext()) + { + if ( node->GetType() == wxXML_ELEMENT_NODE && + (node->GetName() == wxT("object") || + node->GetName() == wxT("object_ref")) ) + { + wxXmlNode* found = DoFindResource(node, name, classname, TRUE); + if ( found ) + return found; + } + } + + return NULL; +} -wxXmlNode *wxXmlResource::FindResource(const wxString& name, const wxString& classname) +wxXmlNode *wxXmlResource::FindResource(const wxString& name, + const wxString& classname, + bool recursive) { UpdateResources(); //ensure everything is up-to-date wxString dummy; for (size_t f = 0; f < m_data.GetCount(); f++) { - if (m_data[f].Doc == NULL || m_data[f].Doc->GetRoot() == NULL) continue; - for (wxXmlNode *node = m_data[f].Doc->GetRoot()->GetChildren(); - node; node = node->GetNext()) - if (node->GetType() == wxXML_ELEMENT_NODE && - (!classname || - node->GetPropVal(wxT("class"), wxEmptyString) == classname) && - node->GetName() == wxT("object") && - node->GetPropVal(wxT("name"), &dummy) && - dummy == name) - { + if ( m_data[f].Doc == NULL || m_data[f].Doc->GetRoot() == NULL ) + continue; + + wxXmlNode* found = DoFindResource(m_data[f].Doc->GetRoot(), + name, classname, recursive); + if ( found ) + { #if wxUSE_FILESYSTEM - m_curFileSystem.ChangePathTo(m_data[f].File); + m_curFileSystem.ChangePathTo(m_data[f].File); #endif - return node; - } + return found; + } } wxLogError(_("XRC resource '%s' (class '%s') not found!"), @@ -374,12 +409,74 @@ wxXmlNode *wxXmlResource::FindResource(const wxString& name, const wxString& cla return NULL; } +static void MergeNodes(wxXmlNode& dest, wxXmlNode& with) +{ + // Merge properties: + for (wxXmlProperty *prop = with.GetProperties(); prop; prop = prop->GetNext()) + { + wxXmlProperty *dprop; + for (dprop = dest.GetProperties(); dprop; dprop = dprop->GetNext()) + { + + if ( dprop->GetName() == prop->GetName() ) + { + dprop->SetValue(prop->GetValue()); + break; + } + } + if ( !dprop ) + dest.AddProperty(prop->GetName(), prop->GetValue()); + } + + // Merge child nodes: + for (wxXmlNode* node = with.GetChildren(); node; node = node->GetNext()) + { + wxString name = node->GetPropVal(wxT("name"), wxEmptyString); + wxXmlNode *dnode; + + for (dnode = dest.GetChildren(); dnode; dnode = dnode->GetNext() ) + { + if ( dnode->GetName() == node->GetName() && + dnode->GetPropVal("name", wxEmptyString) == name && + dnode->GetType() == node->GetType() ) + { + MergeNodes(*dnode, *node); + break; + } + } + + if ( !dnode ) + dest.AddChild(new wxXmlNode(*node)); + } + + if ( dest.GetType() == wxXML_TEXT_NODE && with.GetContent().Length() ) + dest.SetContent(with.GetContent()); +} wxObject *wxXmlResource::CreateResFromNode(wxXmlNode *node, wxObject *parent, wxObject *instance) { if (node == NULL) return NULL; + // handling of referenced resource + if ( node->GetName() == wxT("object_ref") ) + { + wxString refName = node->GetPropVal(wxT("ref"), wxEmptyString); + wxXmlNode* refNode = FindResource(refName, wxEmptyString, TRUE); + + if ( !refNode ) + { + wxLogError(_("Referenced object node with ref=\"%s\" not found!"), + refName.c_str()); + return NULL; + } + + wxXmlNode copy(*refNode); + MergeNodes(copy, *node); + + return CreateResFromNode(©, parent, instance); + } + wxXmlResourceHandler *handler; wxObject *ret; wxNode * ND = m_handlers.GetFirst(); @@ -403,11 +500,6 @@ wxObject *wxXmlResource::CreateResFromNode(wxXmlNode *node, wxObject *parent, wx - - - - - wxXmlResourceHandler::wxXmlResourceHandler() : m_node(NULL), m_parent(NULL), m_instance(NULL), m_parentAsWindow(NULL), m_instanceAsWindow(NULL) -- 2.45.2