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:
		| @@ -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 | The value is interpreted as path relative to the location of XRC file where the | ||||||
| reference occurs. | 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. | Alternatively, it is possible to specify the bitmap using wxArtProvider IDs. | ||||||
| In this case, the property element has no textual value (filename) and instead | 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 | has the @c stock_id XML attribute that contains stock art ID as accepted by | ||||||
|   | |||||||
| @@ -76,7 +76,8 @@ enum wxXmlResourceFlags | |||||||
| { | { | ||||||
|     wxXRC_USE_LOCALE     = 1, |     wxXRC_USE_LOCALE     = 1, | ||||||
|     wxXRC_NO_SUBCLASSING = 2, |     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 | // This class holds XML resources from one or more .xml files | ||||||
| @@ -95,6 +96,9 @@ public: | |||||||
|     //        wxXRC_NO_RELOADING |     //        wxXRC_NO_RELOADING | ||||||
|     //              don't check the modification time of the XRC files and |     //              don't check the modification time of the XRC files and | ||||||
|     //              reload them if they have changed on disk |     //              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, |     wxXmlResource(int flags = wxXRC_USE_LOCALE, | ||||||
|                   const wxString& domain = wxEmptyString); |                   const wxString& domain = wxEmptyString); | ||||||
|  |  | ||||||
| @@ -105,6 +109,12 @@ public: | |||||||
|     //        wxXRC_NO_SUBCLASSING |     //        wxXRC_NO_SUBCLASSING | ||||||
|     //              subclass property of object nodes will be ignored |     //              subclass property of object nodes will be ignored | ||||||
|     //              (useful for previews in XRC editors) |     //              (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, |     wxXmlResource(const wxString& filemask, int flags = wxXRC_USE_LOCALE, | ||||||
|                   const wxString& domain = wxEmptyString); |                   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). |     // Sets the global resources object and returns a pointer to the previous one (may be NULL). | ||||||
|     static wxXmlResource *Set(wxXmlResource *res); |     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; } |     int GetFlags() const { return m_flags; } | ||||||
|     // Set flags after construction. |     // Set flags after construction. | ||||||
|     void SetFlags(int flags) { m_flags = flags; } |     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) |     // Gets the value of a boolean attribute (only "0" and "1" are valid values) | ||||||
|     bool GetBoolAttr(const wxString& attr, bool defaultv) wxOVERRIDE; |     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). |     // Returns the window associated with the handler (may be NULL). | ||||||
|     wxWindow* GetParentAsWindow() const { return m_handler->GetParentAsWindow(); } |     wxWindow* GetParentAsWindow() const { return m_handler->GetParentAsWindow(); } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -18,7 +18,14 @@ enum wxXmlResourceFlags | |||||||
|  |  | ||||||
|     /** Prevent the XRC files from being reloaded from disk in case they have been modified there |     /** 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). */ |         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); |     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. |         Check to see if a parameter exists. | ||||||
|     */ |     */ | ||||||
|   | |||||||
| @@ -90,6 +90,10 @@ bool MyApp::OnInit() | |||||||
|     // wxXRC docs for details. |     // wxXRC docs for details. | ||||||
|     wxXmlResource::Get()->InitAllHandlers(); |     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 | #if wxUSE_RIBBON | ||||||
|     wxXmlResource::Get()->AddHandler(new wxRibbonXmlHandler); |     wxXmlResource::Get()->AddHandler(new wxRibbonXmlHandler); | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -42,7 +42,7 @@ | |||||||
| #if wxUSE_ANIMATIONCTRL | #if wxUSE_ANIMATIONCTRL | ||||||
| wxAnimation* wxXmlResourceHandlerImpl::GetAnimation(const wxString& param) | wxAnimation* wxXmlResourceHandlerImpl::GetAnimation(const wxString& param) | ||||||
| { | { | ||||||
|     const wxString name = GetParamValue(param); |     wxString name = GetFilePath(GetParamNode(param)); | ||||||
|     if ( name.empty() ) |     if ( name.empty() ) | ||||||
|         return NULL; |         return NULL; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -44,6 +44,7 @@ | |||||||
| #include "wx/xml/xml.h" | #include "wx/xml/xml.h" | ||||||
| #include "wx/hashset.h" | #include "wx/hashset.h" | ||||||
| #include "wx/scopedptr.h" | #include "wx/scopedptr.h" | ||||||
|  | #include "wx/config.h" | ||||||
|  |  | ||||||
| #include <limits.h> | #include <limits.h> | ||||||
| #include <locale.h> | #include <locale.h> | ||||||
| @@ -1825,7 +1826,7 @@ wxBitmap wxXmlResourceHandlerImpl::GetBitmap(const wxXmlNode* node, | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /* ...or load the bitmap from file: */ |     /* ...or load the bitmap from file: */ | ||||||
|     wxString name = GetParamValue(node); |     wxString name = GetFilePath(node); | ||||||
|     if (name.empty()) return wxNullBitmap; |     if (name.empty()) return wxNullBitmap; | ||||||
| #if wxUSE_FILESYSTEM | #if wxUSE_FILESYSTEM | ||||||
|     wxFSFile *fsfile = GetCurFileSystem().OpenFile(name, wxFS_READ | wxFS_SEEKABLE); |     wxFSFile *fsfile = GetCurFileSystem().OpenFile(name, wxFS_READ | wxFS_SEEKABLE); | ||||||
| @@ -1898,7 +1899,7 @@ wxIconBundle wxXmlResourceHandlerImpl::GetIconBundle(const wxString& param, | |||||||
|             return stockArt; |             return stockArt; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const wxString name = GetParamValue(param); |     const wxString name = GetFilePath(GetParamNode(param)); | ||||||
|     if ( name.empty() ) |     if ( name.empty() ) | ||||||
|         return wxNullIconBundle; |         return wxNullIconBundle; | ||||||
|  |  | ||||||
| @@ -1982,6 +1983,16 @@ wxImageList *wxXmlResourceHandlerImpl::GetImageList(const wxString& param) | |||||||
|     return imagelist; |     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) | wxXmlNode *wxXmlResourceHandlerImpl::GetParamNode(const wxString& param) | ||||||
| { | { | ||||||
|     wxCHECK_MSG(m_handler->m_node, NULL, wxT("You can't access handler data before it was initialized!")); |     wxCHECK_MSG(m_handler->m_node, NULL, wxT("You can't access handler data before it was initialized!")); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user