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 wxStrnlen() for safe computation of string length.
|
||||||
- Added wxImage::Clear() (troelsk).
|
- Added wxImage::Clear() (troelsk).
|
||||||
- Added wxLog::Log().
|
- Added wxLog::Log().
|
||||||
|
- Added wxXmlResource::GetResourceNode().
|
||||||
|
|
||||||
All (Unix):
|
All (Unix):
|
||||||
|
|
||||||
|
@@ -227,7 +227,7 @@ public:
|
|||||||
{ return GetVersion() -
|
{ return GetVersion() -
|
||||||
(major*256*256*256 + minor*256*256 + release*256 + revision); }
|
(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.
|
// Gets the global resources object or creates one if none exists.
|
||||||
static wxXmlResource *Get();
|
static wxXmlResource *Get();
|
||||||
@@ -245,16 +245,48 @@ public:
|
|||||||
const wxString& GetDomain() const { return m_domain; }
|
const wxString& GetDomain() const { return m_domain; }
|
||||||
void SetDomain(const wxString& 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:
|
protected:
|
||||||
// Scans the resources list for unloaded files and loads them. Also reloads
|
// Scans the resources list for unloaded files and loads them. Also reloads
|
||||||
// files that have been modified since last loading.
|
// files that have been modified since last loading.
|
||||||
bool UpdateResources();
|
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.
|
// Common implementation of GetResourceNode() and FindResource(): searches
|
||||||
wxXmlNode *DoFindResource(wxXmlNode *parent, const wxString& name, const wxString& classname, bool recursive);
|
// 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
|
// Creates a resource from information in the given node
|
||||||
// (Uses only 'handlerToUse' if != NULL)
|
// (Uses only 'handlerToUse' if != NULL)
|
||||||
|
@@ -142,6 +142,26 @@ public:
|
|||||||
*/
|
*/
|
||||||
int GetFlags() const;
|
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).
|
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
|
// 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;
|
wxXmlResource *wxXmlResource::ms_instance = NULL;
|
||||||
|
|
||||||
@@ -551,86 +567,114 @@ bool wxXmlResource::UpdateResources()
|
|||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
wxXmlNode *wxXmlResource::DoFindResource(wxXmlNode *parent,
|
wxXmlNode *wxXmlResource::DoFindResource(wxXmlNode *parent,
|
||||||
const wxString& name,
|
const wxString& name,
|
||||||
const wxString& classname,
|
const wxString& classname,
|
||||||
bool recursive)
|
bool recursive) const
|
||||||
{
|
{
|
||||||
wxString dummy;
|
|
||||||
wxXmlNode *node;
|
wxXmlNode *node;
|
||||||
|
|
||||||
// first search for match at the top-level nodes (as this is
|
// first search for match at the top-level nodes (as this is
|
||||||
// where the resource is most commonly looked for):
|
// where the resource is most commonly looked for):
|
||||||
for (node = parent->GetChildren(); node; node = node->GetNext())
|
for (node = parent->GetChildren(); node; node = node->GetNext())
|
||||||
{
|
{
|
||||||
if ( node->GetType() == wxXML_ELEMENT_NODE &&
|
if ( IsObjectNode(node) && node->GetAttribute(wxS("name")) == name )
|
||||||
(node->GetName() == wxT("object") ||
|
|
||||||
node->GetName() == wxT("object_ref")) &&
|
|
||||||
node->GetAttribute(wxT("name"), &dummy) && dummy == name )
|
|
||||||
{
|
{
|
||||||
wxString cls(node->GetAttribute(wxT("class"), wxEmptyString));
|
// empty class name matches everything
|
||||||
if (!classname || cls == classname)
|
if ( classname.empty() )
|
||||||
return node;
|
return node;
|
||||||
|
|
||||||
|
wxString cls(node->GetAttribute(wxS("class")));
|
||||||
|
|
||||||
// object_ref may not have 'class' attribute:
|
// 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())
|
if (refName.empty())
|
||||||
continue;
|
continue;
|
||||||
wxXmlNode* refNode = FindResource(refName, wxEmptyString, true);
|
|
||||||
if (refNode &&
|
const wxXmlNode * const refNode = GetResourceNode(refName);
|
||||||
refNode->GetAttribute(wxT("class"), wxEmptyString) == classname)
|
if ( refNode )
|
||||||
{
|
cls = refNode->GetAttribute(wxS("class"));
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( cls == classname )
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// then recurse in child nodes
|
||||||
if ( recursive )
|
if ( recursive )
|
||||||
|
{
|
||||||
for (node = parent->GetChildren(); node; node = node->GetNext())
|
for (node = parent->GetChildren(); node; node = node->GetNext())
|
||||||
{
|
{
|
||||||
if ( node->GetType() == wxXML_ELEMENT_NODE &&
|
if ( IsObjectNode(node) )
|
||||||
(node->GetName() == wxT("object") ||
|
|
||||||
node->GetName() == wxT("object_ref")) )
|
|
||||||
{
|
{
|
||||||
wxXmlNode* found = DoFindResource(node, name, classname, true);
|
wxXmlNode* found = DoFindResource(node, name, classname, true);
|
||||||
if ( found )
|
if ( found )
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxXmlNode *wxXmlResource::FindResource(const wxString& name,
|
wxXmlNode *wxXmlResource::FindResource(const wxString& name,
|
||||||
const wxString& classname,
|
const wxString& classname,
|
||||||
bool recursive)
|
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();
|
for ( wxXmlResourceDataRecords::const_iterator f = Data().begin();
|
||||||
f != Data().end(); ++f )
|
f != Data().end(); ++f )
|
||||||
{
|
{
|
||||||
wxXmlResourceDataRecord* const rec = *f;
|
wxXmlResourceDataRecord *const rec = *f;
|
||||||
if ( rec->Doc == NULL || rec->Doc->GetRoot() == NULL )
|
wxXmlDocument * const doc = rec->Doc;
|
||||||
|
if ( !doc || !doc->GetRoot() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
wxXmlNode* found = DoFindResource(rec->Doc->GetRoot(),
|
wxXmlNode * const
|
||||||
name, classname, recursive);
|
found = DoFindResource(doc->GetRoot(), name, classname, recursive);
|
||||||
if ( found )
|
if ( found )
|
||||||
{
|
{
|
||||||
#if wxUSE_FILESYSTEM
|
if ( path )
|
||||||
m_curFileSystem.ChangePathTo(rec->File);
|
*path = rec->File;
|
||||||
#endif
|
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wxLogError(_("XRC resource '%s' (class '%s') not found!"),
|
|
||||||
name.c_str(), classname.c_str());
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1518,17 +1562,13 @@ void wxXmlResourceHandler::SetupWindow(wxWindow *wnd)
|
|||||||
|
|
||||||
void wxXmlResourceHandler::CreateChildren(wxObject *parent, bool this_hnd_only)
|
void wxXmlResourceHandler::CreateChildren(wxObject *parent, bool this_hnd_only)
|
||||||
{
|
{
|
||||||
wxXmlNode *n = m_node->GetChildren();
|
for ( wxXmlNode *n = m_node->GetChildren(); n; n = n->GetNext() )
|
||||||
|
|
||||||
while (n)
|
|
||||||
{
|
{
|
||||||
if (n->GetType() == wxXML_ELEMENT_NODE &&
|
if ( IsObjectNode(n) )
|
||||||
(n->GetName() == wxT("object") || n->GetName() == wxT("object_ref")))
|
|
||||||
{
|
{
|
||||||
m_resource->CreateResFromNode(n, parent, NULL,
|
m_resource->CreateResFromNode(n, parent, NULL,
|
||||||
this_hnd_only ? this : NULL);
|
this_hnd_only ? this : NULL);
|
||||||
}
|
}
|
||||||
n = n->GetNext();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user