Allow expanding environment variables in XRC file paths

Add a new flag wxXRC_USE_ENVVARS for wxXmlResourceFlags that triggers a
call to wxExpandEnvVars() for bitmap, icon and animation paths.

This flag is not set by default to avoid silently changing the behaviour
of existing applications.

Closes https://github.com/wxWidgets/wxWidgets/pull/1445
This commit is contained in:
ousnius 2019-07-28 13:36:19 +02:00 committed by Vadim Zeitlin
parent cd2e3dd2cf
commit 2a2fa8c5af
6 changed files with 55 additions and 6 deletions

View File

@ -352,6 +352,9 @@ wxFileSystem URL) of the bitmap to use. For example:
The value is interpreted as path relative to the location of XRC file where the
reference occurs.
Bitmap file paths can include environment variables that are expanded if
wxXRC_USE_ENVVARS was passed to the wxXmlResource constructor.
Alternatively, it is possible to specify the bitmap using wxArtProvider IDs.
In this case, the property element has no textual value (filename) and instead
has the @c stock_id XML attribute that contains stock art ID as accepted by

View File

@ -76,7 +76,8 @@ enum wxXmlResourceFlags
{
wxXRC_USE_LOCALE = 1,
wxXRC_NO_SUBCLASSING = 2,
wxXRC_NO_RELOADING = 4
wxXRC_NO_RELOADING = 4,
wxXRC_USE_ENVVARS = 8
};
// This class holds XML resources from one or more .xml files
@ -95,6 +96,9 @@ public:
// wxXRC_NO_RELOADING
// don't check the modification time of the XRC files and
// reload them if they have changed on disk
// wxXRC_USE_ENVVARS
// expand environment variables for paths
// (such as bitmaps or icons).
wxXmlResource(int flags = wxXRC_USE_LOCALE,
const wxString& domain = wxEmptyString);
@ -105,6 +109,12 @@ public:
// wxXRC_NO_SUBCLASSING
// subclass property of object nodes will be ignored
// (useful for previews in XRC editors)
// wxXRC_NO_RELOADING
// don't check the modification time of the XRC files and
// reload them if they have changed on disk
// wxXRC_USE_ENVVARS
// expand environment variables for paths
// (such as bitmaps or icons).
wxXmlResource(const wxString& filemask, int flags = wxXRC_USE_LOCALE,
const wxString& domain = wxEmptyString);
@ -279,7 +289,7 @@ public:
// Sets the global resources object and returns a pointer to the previous one (may be NULL).
static wxXmlResource *Set(wxXmlResource *res);
// Returns flags, which may be a bitlist of wxXRC_USE_LOCALE and wxXRC_NO_SUBCLASSING.
// Returns flags, which is a bitlist of wxXmlResourceFlags.
int GetFlags() const { return m_flags; }
// Set flags after construction.
void SetFlags(int flags) { m_flags = flags; }
@ -591,6 +601,10 @@ public:
// Gets the value of a boolean attribute (only "0" and "1" are valid values)
bool GetBoolAttr(const wxString& attr, bool defaultv) wxOVERRIDE;
// Gets a file path from the given node, expanding environment variables in
// it if wxXRC_USE_ENVVARS is in use.
wxString GetFilePath(const wxXmlNode* node);
// Returns the window associated with the handler (may be NULL).
wxWindow* GetParentAsWindow() const { return m_handler->GetParentAsWindow(); }

View File

@ -18,7 +18,14 @@ enum wxXmlResourceFlags
/** Prevent the XRC files from being reloaded from disk in case they have been modified there
since being last loaded (may slightly speed up loading them). */
wxXRC_NO_RELOADING = 4
wxXRC_NO_RELOADING = 4,
/**
Expand environment variables for paths in XRC (such as bitmaps or icons).
@since 3.1.3
*/
wxXRC_USE_ENVVARS = 8
};
@ -737,6 +744,16 @@ protected:
*/
wxString GetText(const wxString& param, bool translate = true);
/**
Gets a file path from the given node.
This function expands environment variables in the path if
wxXRC_USE_ENVVARS is used.
@since 3.1.3
*/
wxString GetFilePath(const wxXmlNode* node);
/**
Check to see if a parameter exists.
*/

View File

@ -90,6 +90,10 @@ bool MyApp::OnInit()
// wxXRC docs for details.
wxXmlResource::Get()->InitAllHandlers();
// Allow using environment variables in the file paths in the resources,
// while keeping the default wxXRC_USE_LOCALE flag.
wxXmlResource::Get()->SetFlags(wxXRC_USE_LOCALE | wxXRC_USE_ENVVARS);
#if wxUSE_RIBBON
wxXmlResource::Get()->AddHandler(new wxRibbonXmlHandler);
#endif

View File

@ -42,7 +42,7 @@
#if wxUSE_ANIMATIONCTRL
wxAnimation* wxXmlResourceHandlerImpl::GetAnimation(const wxString& param)
{
const wxString name = GetParamValue(param);
wxString name = GetFilePath(GetParamNode(param));
if ( name.empty() )
return NULL;

View File

@ -44,6 +44,7 @@
#include "wx/xml/xml.h"
#include "wx/hashset.h"
#include "wx/scopedptr.h"
#include "wx/config.h"
#include <limits.h>
#include <locale.h>
@ -1825,7 +1826,7 @@ wxBitmap wxXmlResourceHandlerImpl::GetBitmap(const wxXmlNode* node,
}
/* ...or load the bitmap from file: */
wxString name = GetParamValue(node);
wxString name = GetFilePath(node);
if (name.empty()) return wxNullBitmap;
#if wxUSE_FILESYSTEM
wxFSFile *fsfile = GetCurFileSystem().OpenFile(name, wxFS_READ | wxFS_SEEKABLE);
@ -1898,7 +1899,7 @@ wxIconBundle wxXmlResourceHandlerImpl::GetIconBundle(const wxString& param,
return stockArt;
}
const wxString name = GetParamValue(param);
const wxString name = GetFilePath(GetParamNode(param));
if ( name.empty() )
return wxNullIconBundle;
@ -1982,6 +1983,16 @@ wxImageList *wxXmlResourceHandlerImpl::GetImageList(const wxString& param)
return imagelist;
}
wxString wxXmlResourceHandlerImpl::GetFilePath(const wxXmlNode* node)
{
wxString path = GetParamValue(node);
if ( m_handler->m_resource->GetFlags() & wxXRC_USE_ENVVARS )
path = wxExpandEnvVars(path);
return path;
}
wxXmlNode *wxXmlResourceHandlerImpl::GetParamNode(const wxString& param)
{
wxCHECK_MSG(m_handler->m_node, NULL, wxT("You can't access handler data before it was initialized!"));