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,55 +567,55 @@ 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)
|
||||
{
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -608,29 +624,57 @@ 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