add public wxXmlResource::GetResourceNode() which can be used directly instead of deriving from wxXmlResource and using FindResource()
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@59096 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
		@@ -357,6 +357,7 @@ All:
 | 
			
		||||
- Added wxStrnlen() for safe computation of string length.
 | 
			
		||||
- Added wxImage::Clear() (troelsk).
 | 
			
		||||
- Added wxLog::Log().
 | 
			
		||||
- Added wxXmlResource::GetResourceNode().
 | 
			
		||||
 | 
			
		||||
All (Unix):
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -227,7 +227,7 @@ public:
 | 
			
		||||
        { return GetVersion() -
 | 
			
		||||
                 (major*256*256*256 + minor*256*256 + release*256 + revision); }
 | 
			
		||||
 | 
			
		||||
//// Singleton accessors.
 | 
			
		||||
    //// Singleton accessors.
 | 
			
		||||
 | 
			
		||||
    // Gets the global resources object or creates one if none exists.
 | 
			
		||||
    static wxXmlResource *Get();
 | 
			
		||||
@@ -245,16 +245,48 @@ public:
 | 
			
		||||
    const wxString& GetDomain() const { return m_domain; }
 | 
			
		||||
    void SetDomain(const wxString& domain);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // This function returns the wxXmlNode containing the definition of the
 | 
			
		||||
    // object with the given name or NULL.
 | 
			
		||||
    //
 | 
			
		||||
    // It can be used to access additional information defined in the XRC file
 | 
			
		||||
    // and not used by wxXmlResource itself.
 | 
			
		||||
    const wxXmlNode *GetResourceNode(const wxString& name) const
 | 
			
		||||
        { return GetResourceNodeAndLocation(name, wxString(), true); }
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    // Scans the resources list for unloaded files and loads them. Also reloads
 | 
			
		||||
    // files that have been modified since last loading.
 | 
			
		||||
    bool UpdateResources();
 | 
			
		||||
 | 
			
		||||
    // Finds a resource (calls UpdateResources) and returns a node containing it.
 | 
			
		||||
    wxXmlNode *FindResource(const wxString& name, const wxString& classname, bool recursive = false);
 | 
			
		||||
 | 
			
		||||
    // Helper function: finds a resource (calls UpdateResources) and returns a node containing it.
 | 
			
		||||
    wxXmlNode *DoFindResource(wxXmlNode *parent, const wxString& name, const wxString& classname, bool recursive);
 | 
			
		||||
    // Common implementation of GetResourceNode() and FindResource(): searches
 | 
			
		||||
    // all top-level or all (if recursive == true) nodes if all loaded XRC
 | 
			
		||||
    // files and returns the node, if found, as well as the path of the file it
 | 
			
		||||
    // was found in if path is non-NULL
 | 
			
		||||
    wxXmlNode *GetResourceNodeAndLocation(const wxString& name,
 | 
			
		||||
                                          const wxString& classname,
 | 
			
		||||
                                          bool recursive = false,
 | 
			
		||||
                                          wxString *path = NULL) const;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // Note that these functions are used outside of wxWidgets itself, e.g.
 | 
			
		||||
    // there are several known cases of inheriting from wxXmlResource just to
 | 
			
		||||
    // be able to call FindResource() so we keep them for compatibility even if
 | 
			
		||||
    // their names are not really consistent with GetResourceNode() public
 | 
			
		||||
    // function and FindResource() is also non-const because it changes the
 | 
			
		||||
    // current path of m_curFileSystem to ensure that relative paths work
 | 
			
		||||
    // correctly when CreateResFromNode() is called immediately afterwards
 | 
			
		||||
    // (something const public function intentionally does not do)
 | 
			
		||||
 | 
			
		||||
    // Returns the node containing the resource with the given name and class
 | 
			
		||||
    // name unless it's empty (then any class matches) or NULL if not found.
 | 
			
		||||
    wxXmlNode *FindResource(const wxString& name, const wxString& classname,
 | 
			
		||||
                            bool recursive = false);
 | 
			
		||||
 | 
			
		||||
    // Helper function used by FindResource() to look under the given node.
 | 
			
		||||
    wxXmlNode *DoFindResource(wxXmlNode *parent, const wxString& name,
 | 
			
		||||
                              const wxString& classname, bool recursive) const;
 | 
			
		||||
 | 
			
		||||
    // Creates a resource from information in the given node
 | 
			
		||||
    // (Uses only 'handlerToUse' if != NULL)
 | 
			
		||||
 
 | 
			
		||||
@@ -142,6 +142,26 @@ public:
 | 
			
		||||
    */
 | 
			
		||||
    int GetFlags() const;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
        Returns the wxXmlNode containing the definition of the object with the
 | 
			
		||||
        given name or @NULL.
 | 
			
		||||
 | 
			
		||||
        This function recursively searches all the loaded XRC files for an
 | 
			
		||||
        object with the specified @a name. If the object is found, the
 | 
			
		||||
        wxXmlNode corresponding to it is returned, so this function can be used
 | 
			
		||||
        to access additional information defined in the XRC file and not used
 | 
			
		||||
        by wxXmlResource itself, e.g. contents of application-specific XML
 | 
			
		||||
        tags.
 | 
			
		||||
 | 
			
		||||
        @param name
 | 
			
		||||
            The name of the resource which must be unique for this function to
 | 
			
		||||
            work correctly, if there is more than one resource with the given
 | 
			
		||||
            name the choice of the one returned by this function is undefined.
 | 
			
		||||
        @return
 | 
			
		||||
            The node corresponding to the resource with the given name or @NULL.
 | 
			
		||||
    */
 | 
			
		||||
    const wxXmlNode *GetResourceNode(const wxString& name) const;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
        Returns version information (a.b.c.d = d + 256*c + 2562*b + 2563*a).
 | 
			
		||||
    */
 | 
			
		||||
 
 | 
			
		||||
@@ -70,6 +70,22 @@ class wxXmlResourceDataRecords : public wxVector<wxXmlResourceDataRecord*>
 | 
			
		||||
    // this is a class so that it can be forward-declared
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
namespace
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
// helper used by DoFindResource() and elsewhere: returns true if this is an
 | 
			
		||||
// object or object_ref node
 | 
			
		||||
//
 | 
			
		||||
// node must be non-NULL
 | 
			
		||||
inline bool IsObjectNode(wxXmlNode *node)
 | 
			
		||||
{
 | 
			
		||||
    return node->GetType() == wxXML_ELEMENT_NODE &&
 | 
			
		||||
             (node->GetName() == wxS("object") ||
 | 
			
		||||
                node->GetName() == wxS("object_ref"));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // anonymous namespace
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
wxXmlResource *wxXmlResource::ms_instance = NULL;
 | 
			
		||||
 | 
			
		||||
@@ -551,86 +567,114 @@ bool wxXmlResource::UpdateResources()
 | 
			
		||||
    return rt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
wxXmlNode *wxXmlResource::DoFindResource(wxXmlNode *parent,
 | 
			
		||||
                                         const wxString& name,
 | 
			
		||||
                                         const wxString& classname,
 | 
			
		||||
                                         bool recursive)
 | 
			
		||||
                                         bool recursive) const
 | 
			
		||||
{
 | 
			
		||||
    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")) &&
 | 
			
		||||
             node->GetAttribute(wxT("name"), &dummy) && dummy == name )
 | 
			
		||||
        if ( IsObjectNode(node) && node->GetAttribute(wxS("name")) == name )
 | 
			
		||||
        {
 | 
			
		||||
            wxString cls(node->GetAttribute(wxT("class"), wxEmptyString));
 | 
			
		||||
            if (!classname || cls == classname)
 | 
			
		||||
            // empty class name matches everything
 | 
			
		||||
            if ( classname.empty() )
 | 
			
		||||
                return node;
 | 
			
		||||
 | 
			
		||||
            wxString cls(node->GetAttribute(wxS("class")));
 | 
			
		||||
 | 
			
		||||
            // object_ref may not have 'class' attribute:
 | 
			
		||||
            if (cls.empty() && node->GetName() == wxT("object_ref"))
 | 
			
		||||
            if (cls.empty() && node->GetName() == wxS("object_ref"))
 | 
			
		||||
            {
 | 
			
		||||
                wxString refName = node->GetAttribute(wxT("ref"), wxEmptyString);
 | 
			
		||||
                wxString refName = node->GetAttribute(wxS("ref"));
 | 
			
		||||
                if (refName.empty())
 | 
			
		||||
                    continue;
 | 
			
		||||
                wxXmlNode* refNode = FindResource(refName, wxEmptyString, true);
 | 
			
		||||
                if (refNode &&
 | 
			
		||||
                    refNode->GetAttribute(wxT("class"), wxEmptyString) == classname)
 | 
			
		||||
                {
 | 
			
		||||
                    return node;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                const wxXmlNode * const refNode = GetResourceNode(refName);
 | 
			
		||||
                if ( refNode )
 | 
			
		||||
                    cls = refNode->GetAttribute(wxS("class"));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ( cls == classname )
 | 
			
		||||
                return node;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // then recurse in child nodes
 | 
			
		||||
    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")) )
 | 
			
		||||
            if ( IsObjectNode(node) )
 | 
			
		||||
            {
 | 
			
		||||
                wxXmlNode* found = DoFindResource(node, name, classname, true);
 | 
			
		||||
                if ( found )
 | 
			
		||||
                    return found;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
   return NULL;
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
wxXmlNode *wxXmlResource::FindResource(const wxString& name,
 | 
			
		||||
                                       const wxString& classname,
 | 
			
		||||
                                       bool recursive)
 | 
			
		||||
{
 | 
			
		||||
    UpdateResources(); //ensure everything is up-to-date
 | 
			
		||||
    wxString path;
 | 
			
		||||
    wxXmlNode * const
 | 
			
		||||
        node = GetResourceNodeAndLocation(name, classname, recursive, &path);
 | 
			
		||||
 | 
			
		||||
    if ( !node )
 | 
			
		||||
    {
 | 
			
		||||
        wxLogError(_("XRC resource '%s' (class '%s') not found!"),
 | 
			
		||||
                   name, classname);
 | 
			
		||||
    }
 | 
			
		||||
#if wxUSE_FILESYSTEM
 | 
			
		||||
    else // node was found
 | 
			
		||||
    {
 | 
			
		||||
        // ensure that relative paths work correctly when loading this node
 | 
			
		||||
        // (which should happen as soon as we return as FindResource() result
 | 
			
		||||
        // is always passed to CreateResFromNode())
 | 
			
		||||
        m_curFileSystem.ChangePathTo(path);
 | 
			
		||||
    }
 | 
			
		||||
#endif // wxUSE_FILESYSTEM
 | 
			
		||||
 | 
			
		||||
    return node;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
wxXmlNode *
 | 
			
		||||
wxXmlResource::GetResourceNodeAndLocation(const wxString& name,
 | 
			
		||||
                                          const wxString& classname,
 | 
			
		||||
                                          bool recursive,
 | 
			
		||||
                                          wxString *path) const
 | 
			
		||||
{
 | 
			
		||||
    // ensure everything is up-to-date: this is needed to support on-remand
 | 
			
		||||
    // reloading of XRC files
 | 
			
		||||
    const_cast<wxXmlResource *>(this)->UpdateResources();
 | 
			
		||||
 | 
			
		||||
    wxString dummy;
 | 
			
		||||
    for ( wxXmlResourceDataRecords::const_iterator f = Data().begin();
 | 
			
		||||
          f != Data().end(); ++f )
 | 
			
		||||
    {
 | 
			
		||||
        wxXmlResourceDataRecord* const rec = *f;
 | 
			
		||||
        if ( rec->Doc == NULL || rec->Doc->GetRoot() == NULL )
 | 
			
		||||
        wxXmlResourceDataRecord *const rec = *f;
 | 
			
		||||
        wxXmlDocument * const doc = rec->Doc;
 | 
			
		||||
        if ( !doc || !doc->GetRoot() )
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        wxXmlNode* found = DoFindResource(rec->Doc->GetRoot(),
 | 
			
		||||
                                          name, classname, recursive);
 | 
			
		||||
        wxXmlNode * const
 | 
			
		||||
            found = DoFindResource(doc->GetRoot(), name, classname, recursive);
 | 
			
		||||
        if ( found )
 | 
			
		||||
        {
 | 
			
		||||
#if wxUSE_FILESYSTEM
 | 
			
		||||
            m_curFileSystem.ChangePathTo(rec->File);
 | 
			
		||||
#endif
 | 
			
		||||
            if ( path )
 | 
			
		||||
                *path = rec->File;
 | 
			
		||||
 | 
			
		||||
            return found;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    wxLogError(_("XRC resource '%s' (class '%s') not found!"),
 | 
			
		||||
               name.c_str(), classname.c_str());
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1518,17 +1562,13 @@ void wxXmlResourceHandler::SetupWindow(wxWindow *wnd)
 | 
			
		||||
 | 
			
		||||
void wxXmlResourceHandler::CreateChildren(wxObject *parent, bool this_hnd_only)
 | 
			
		||||
{
 | 
			
		||||
    wxXmlNode *n = m_node->GetChildren();
 | 
			
		||||
 | 
			
		||||
    while (n)
 | 
			
		||||
    for ( wxXmlNode *n = m_node->GetChildren(); n; n = n->GetNext() )
 | 
			
		||||
    {
 | 
			
		||||
        if (n->GetType() == wxXML_ELEMENT_NODE &&
 | 
			
		||||
           (n->GetName() == wxT("object") || n->GetName() == wxT("object_ref")))
 | 
			
		||||
        if ( IsObjectNode(n) )
 | 
			
		||||
        {
 | 
			
		||||
            m_resource->CreateResFromNode(n, parent, NULL,
 | 
			
		||||
                                          this_hnd_only ? this : NULL);
 | 
			
		||||
        }
 | 
			
		||||
        n = n->GetNext();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user