diff --git a/docs/doxygen/overviews/xrc_format.h b/docs/doxygen/overviews/xrc_format.h index f20209c54c..83b8d7681a 100644 --- a/docs/doxygen/overviews/xrc_format.h +++ b/docs/doxygen/overviews/xrc_format.h @@ -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 diff --git a/include/wx/xrc/xmlres.h b/include/wx/xrc/xmlres.h index bde64138a5..c19d36dc31 100644 --- a/include/wx/xrc/xmlres.h +++ b/include/wx/xrc/xmlres.h @@ -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(); } diff --git a/interface/wx/xrc/xmlres.h b/interface/wx/xrc/xmlres.h index d420678bdb..0c625ce724 100644 --- a/interface/wx/xrc/xmlres.h +++ b/interface/wx/xrc/xmlres.h @@ -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. */ diff --git a/samples/xrc/xrcdemo.cpp b/samples/xrc/xrcdemo.cpp index 61d4d71d50..aaf76bcc53 100644 --- a/samples/xrc/xrcdemo.cpp +++ b/samples/xrc/xrcdemo.cpp @@ -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 diff --git a/src/xrc/xmladv.cpp b/src/xrc/xmladv.cpp index d1a057c92e..861f1f73ee 100644 --- a/src/xrc/xmladv.cpp +++ b/src/xrc/xmladv.cpp @@ -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; diff --git a/src/xrc/xmlres.cpp b/src/xrc/xmlres.cpp index ccad3d1a46..764fd20658 100644 --- a/src/xrc/xmlres.cpp +++ b/src/xrc/xmlres.cpp @@ -44,6 +44,7 @@ #include "wx/xml/xml.h" #include "wx/hashset.h" #include "wx/scopedptr.h" +#include "wx/config.h" #include #include @@ -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!"));