From: Vadim Zeitlin Date: Sun, 18 Mar 2007 17:34:11 +0000 (+0000) Subject: use wxStandardPaths and wxFileName in wxFileConfig resulting in big code simplificati... X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/466e87bd8c80937ca21e8471dc45ed49480675b6 use wxStandardPaths and wxFileName in wxFileConfig resulting in big code simplification and cleanup but also in change of the default file locations under Windows (replaces patch 1620492) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@44893 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/docs/changes.txt b/docs/changes.txt index 4fe7ed481b..12766177a4 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -8,6 +8,9 @@ INCOMPATIBLE CHANGES SINCE 2.8.x Changes in behaviour not resulting in compilation errors, please read this! --------------------------------------------------------------------------- +- Default location of wxFileConfig files has changed under Windows, you will + need to update your code if you access these files directly. + Changes in behaviour which may result in compilation errors ----------------------------------------------------------- diff --git a/docs/latex/wx/config.tex b/docs/latex/wx/config.tex index 89254cf773..d7f6d8efcd 100644 --- a/docs/latex/wx/config.tex +++ b/docs/latex/wx/config.tex @@ -393,8 +393,8 @@ However, this path may be also used as user data directory (see \helpref{wxStandardPaths::GetUserDataDir}{wxstandardpathsgetuserdatadir}) if the application has several data files. In this case wxCONFIG\_USE\_SUBDIR flag, which changes the default local configuration file to \tt{~/.appname/appname} -should be used. Notice that this flag is ignored on non-Unix system, including -VMS, or if a non-default \textit{localFilename} is provided. \newsince{2.8.2} +should be used. Notice that this flag is ignored if \textit{localFilename} is +provided. \newsince{2.8.2} For wxFileConfig, you can also add wxCONFIG\_USE\_NO\_ESCAPE\_CHARACTERS which will turn off character escaping for the values of entries stored in the config diff --git a/docs/latex/wx/fileconf.tex b/docs/latex/wx/fileconf.tex index 2d0c56eae8..0c2003d678 100644 --- a/docs/latex/wx/fileconf.tex +++ b/docs/latex/wx/fileconf.tex @@ -44,6 +44,32 @@ as usual. \helpref{Save}{wxfileconfigsave} +\membersection{wxFileName::GetGlobalFile}\label{wxfilenamegetglobalfile} + +\func{static wxFileName}{GetGlobalFile}{\param{const wxString\& }{basename}} + +Return the full path to the file which would be used by wxFileConfig as global, +system-wide, file if it were constructed with \arg{basename} as ``global +filename'' parameter in the constructor. Notice that this function cannot be +used if \arg{basename} is already a full path name. + + +\membersection{wxFileName::GetLocalFile}\label{wxfilenamegetlocalfile} + +\func{static wxFileName}{GetLocalFile}{\param{const wxString\& }{basename}, \param{int }{style = $0$}} + +Return the full path to the file which would be used by wxFileConfig as local, +user-specific, file if it were constructed with \arg{basename} as ``local +filename'' parameter in the constructor. + +\arg{style} has the same meaning as in \helpref{constructor}{wxconfigbasector} +and can contain any combination of styles but only wxCONFIG\_USE\_SUBDIR bit is +examined by this function. + +Notice that this function cannot be used if \arg{basename} is already a full +path name. + + \membersection{wxFileConfig::Save}\label{wxfileconfigsave} \func{bool}{Save}{\param{wxOutputStream\& }{os}, \param{wxMBConv\& }{conv = wxConvUTF8}} diff --git a/include/wx/fileconf.h b/include/wx/fileconf.h index 1a3a073041..a2ab598635 100644 --- a/include/wx/fileconf.h +++ b/include/wx/fileconf.h @@ -20,6 +20,7 @@ #include "wx/textfile.h" #include "wx/string.h" #include "wx/confbase.h" +#include "wx/filename.h" // ---------------------------------------------------------------------------- // wxFileConfig @@ -111,8 +112,18 @@ public: // // where file is the basename of szFile, ext is its extension // or .conf (Unix) or .ini (Win) if it has none - static wxString GetGlobalFileName(const wxString& file); - static wxString GetLocalFileName(const wxString& file); + static wxFileName GetGlobalFile(const wxString& szFile); + static wxFileName GetLocalFile(const wxString& szFile, int style = 0); + + static wxString GetGlobalFileName(const wxString& szFile) + { + return GetGlobalFile(szFile).GetFullPath(); + } + + static wxString GetLocalFileName(const wxString& szFile, int style = 0) + { + return GetLocalFile(szFile, style).GetFullPath(); + } // ctor & dtor // New constructor: one size fits all. Specify wxCONFIG_USE_LOCAL_FILE or @@ -190,7 +201,7 @@ protected: private: // GetXXXFileName helpers: return ('/' terminated) directory names static wxString GetGlobalDir(); - static wxString GetLocalDir(); + static wxString GetLocalDir(int style = 0); // common part of all ctors (assumes that m_str{Local|Global}File are already // initialized @@ -220,8 +231,8 @@ private: wxFileConfigLineList *m_linesHead, // head of the linked list *m_linesTail; // tail - wxString m_strLocalFile, // local file name passed to ctor - m_strGlobalFile; // global + wxFileName m_fnLocalFile, // local file name passed to ctor + m_fnGlobalFile; // global wxString m_strPath; // current path (not '/' terminated) wxFileConfigGroup *m_pRootGroup, // the top (unnamed) group diff --git a/src/common/fileconf.cpp b/src/common/fileconf.cpp index 4662dcccef..1503ece182 100644 --- a/src/common/fileconf.cpp +++ b/src/common/fileconf.cpp @@ -42,9 +42,10 @@ #include "wx/fileconf.h" #include "wx/filefn.h" +#include "wx/stdpaths.h" + #if defined(__WXMAC__) #include "wx/mac/private.h" // includes mac headers - #include "wx/filename.h" // for MacSetTypeAndCreator #endif #if defined(__WXMSW__) @@ -260,118 +261,71 @@ public: // ---------------------------------------------------------------------------- // static functions // ---------------------------------------------------------------------------- -wxString wxFileConfig::GetGlobalDir() -{ - wxString strDir; -#ifdef __VMS__ // Note if __VMS is defined __UNIX is also defined - strDir = wxT("sys$manager:"); -#elif defined(__WXMAC__) - strDir = wxMacFindFolder( (short) kOnSystemDisk, kPreferencesFolderType, kDontCreateFolder ) ; -#elif defined( __UNIX__ ) - strDir = wxT("/etc/"); -#elif defined(__OS2__) - ULONG aulSysInfo[QSV_MAX] = {0}; - UINT drive; - APIRET rc; - - rc = DosQuerySysInfo( 1L, QSV_MAX, (PVOID)aulSysInfo, sizeof(ULONG)*QSV_MAX); - if (rc == 0) +// this function modifies in place the given wxFileName object if it doesn't +// already have an extension +// +// note that it's slightly misnamed under Mac as there it doesn't add an +// extension but modifies the file name instead, so you shouldn't suppose that +// fn.HasExt() is true after it returns +static void AddConfFileExtIfNeeded(wxFileName& fn) +{ + if ( !fn.HasExt() ) { - drive = aulSysInfo[QSV_BOOT_DRIVE - 1]; - strDir.Printf(wxT("%c:\\OS2\\"), 'A'+drive-1); +#if defined( __WXMAC__ ) + fn.SetName(fn.GetName() + wxT(" Preferences")); +#elif defined( __UNIX__ ) + fn.SetExt(wxT(".conf")); +#else // Windows + fn.SetExt(wxT(".ini")); +#endif // UNIX/Win } -#elif defined(__WXSTUBS__) - wxFAIL_MSG( wxT("TODO") ); -#elif defined(__DOS__) - // There's no such thing as global cfg dir in MS-DOS, let's return - // current directory (FIXME_MGL?) - strDir = wxT(".\\"); -#elif defined(__WXWINCE__) - strDir = wxT("\\Windows\\"); -#else // Windows - - wxChar szWinDir[MAX_PATH]; - ::GetWindowsDirectory(szWinDir, MAX_PATH); - - strDir = szWinDir; - strDir << wxT('\\'); -#endif // Unix/Windows - - return strDir; } -wxString wxFileConfig::GetLocalDir() +wxString wxFileConfig::GetGlobalDir() { - wxString strDir; - -#if defined(__WXMAC__) || defined(__DOS__) - // no local dir concept on Mac OS 9 or MS-DOS - strDir << GetGlobalDir() ; -#else - wxGetHomeDir(&strDir); - - #ifdef __UNIX__ - if ( - (strDir.Last() != wxT('/')) - #ifdef __VMS - && (strDir.Last() != wxT(']')) - #endif - ) - strDir << wxT('/'); - #else - if (strDir.Last() != wxT('\\')) - strDir << wxT('\\'); - #endif -#endif - - return strDir; + return wxStandardPaths::Get().GetConfigDir(); } -wxString wxFileConfig::GetGlobalFileName(const wxString& file) +wxString wxFileConfig::GetLocalDir(int style) { - wxString str = GetGlobalDir(); - str << file; + wxUnusedVar(style); - if ( wxStrchr(file, wxT('.')) == NULL ) -#if defined( __WXMAC__ ) - str << wxT(" Preferences") ; -#elif defined( __UNIX__ ) - str << wxT(".conf"); -#else // Windows - str << wxT(".ini"); -#endif // UNIX/Win + wxStandardPathsBase& stdp = wxStandardPaths::Get(); - return str; + // it so happens that user data directory is a subdirectory of user config + // directory on all supported platforms, which explains why we use it here + return style & wxCONFIG_USE_SUBDIR ? stdp.GetUserDataDir() + : stdp.GetUserConfigDir(); } -wxString wxFileConfig::GetLocalFileName(const wxString& file) +wxFileName wxFileConfig::GetGlobalFile(const wxString& szFile) { -#ifdef __VMS__ - // On VMS I saw the problem that the home directory was appended - // twice for the configuration file. Does that also happen for - // other platforms? - wxString str = wxT( '.' ); -#else - wxString str = GetLocalDir(); -#endif + wxFileName fn(GetGlobalDir(), szFile); -#if defined( __UNIX__ ) && !defined( __VMS ) && !defined( __WXMAC__ ) - str << wxT('.'); -#endif + AddConfFileExtIfNeeded(fn); - str << file; + return fn; +} -#if defined(__WINDOWS__) || defined(__DOS__) - if ( wxStrchr(file, wxT('.')) == NULL ) - str << wxT(".ini"); -#endif +wxFileName wxFileConfig::GetLocalFile(const wxString& szFile, int style) +{ + wxFileName fn(GetLocalDir(style), szFile); -#ifdef __WXMAC__ - str << wxT(" Preferences") ; -#endif +#ifdef __UNIX__ + if ( !(style & wxCONFIG_USE_SUBDIR) ) + { + // dot-files under Unix start with, well, a dot (but OTOH they usually + // don't have any specific extension) + fn.SetName(wxT('.') + fn.GetName()); + } + else // we do append ".conf" extension to config files in subdirectories +#endif // __UNIX__ + { + AddConfFileExtIfNeeded(fn); + } - return str; + return fn; } // ---------------------------------------------------------------------------- @@ -390,9 +344,9 @@ void wxFileConfig::Init() // It's not an error if (one of the) file(s) doesn't exist. // parse the global file - if ( !m_strGlobalFile.empty() && wxFile::Exists(m_strGlobalFile) ) + if ( m_fnGlobalFile.FileExists() ) { - wxTextFile fileGlobal(m_strGlobalFile); + wxTextFile fileGlobal(m_fnGlobalFile.GetFullPath()); if ( fileGlobal.Open(*m_conv/*ignored in ANSI build*/) ) { @@ -401,14 +355,14 @@ void wxFileConfig::Init() } else { - wxLogWarning(_("can't open global configuration file '%s'."), m_strGlobalFile.c_str()); + wxLogWarning(_("can't open global configuration file '%s'."), m_fnGlobalFile.GetFullPath().c_str()); } } // parse the local file - if ( !m_strLocalFile.empty() && wxFile::Exists(m_strLocalFile) ) + if ( m_fnLocalFile.FileExists() ) { - wxTextFile fileLocal(m_strLocalFile); + wxTextFile fileLocal(m_fnLocalFile.GetFullPath()); if ( fileLocal.Open(*m_conv/*ignored in ANSI build*/) ) { Parse(fileLocal, true /* local */); @@ -416,7 +370,7 @@ void wxFileConfig::Init() } else { - wxLogWarning(_("can't open user configuration file '%s'."), m_strLocalFile.c_str() ); + wxLogWarning(_("can't open user configuration file '%s'."), m_fnLocalFile.GetFullPath().c_str() ); } } @@ -431,47 +385,34 @@ wxFileConfig::wxFileConfig(const wxString& appName, const wxString& vendorName, : wxConfigBase(::GetAppName(appName), vendorName, strLocal, strGlobal, style), - m_strLocalFile(strLocal), m_strGlobalFile(strGlobal), + m_fnLocalFile(strLocal), + m_fnGlobalFile(strGlobal), m_conv(conv.Clone()) { // Make up names for files if empty - if ( m_strLocalFile.empty() && (style & wxCONFIG_USE_LOCAL_FILE) ) - { - m_strLocalFile = GetLocalFileName(GetAppName()); -#if defined(__UNIX__) && !defined(__VMS) - if ( style & wxCONFIG_USE_SUBDIR ) - m_strLocalFile << wxFILE_SEP_PATH << GetAppName() << _T(".conf"); -#endif - } + if ( !m_fnLocalFile.IsOk() && (style & wxCONFIG_USE_LOCAL_FILE) ) + m_fnLocalFile = GetLocalFile(GetAppName(), style); - if ( m_strGlobalFile.empty() && (style & wxCONFIG_USE_GLOBAL_FILE) ) - m_strGlobalFile = GetGlobalFileName(GetAppName()); + if ( !m_fnGlobalFile.IsOk() && (style & wxCONFIG_USE_GLOBAL_FILE) ) + m_fnGlobalFile = GetGlobalFile(GetAppName()); // Check if styles are not supplied, but filenames are, in which case // add the correct styles. - if ( !m_strLocalFile.empty() ) + if ( m_fnLocalFile.IsOk() ) SetStyle(GetStyle() | wxCONFIG_USE_LOCAL_FILE); - if ( !m_strGlobalFile.empty() ) + if ( m_fnGlobalFile.IsOk() ) SetStyle(GetStyle() | wxCONFIG_USE_GLOBAL_FILE); // if the path is not absolute, prepend the standard directory to it - // UNLESS wxCONFIG_USE_RELATIVE_PATH style is set + // unless explicitly asked not to if ( !(style & wxCONFIG_USE_RELATIVE_PATH) ) { - if ( !m_strLocalFile.empty() && !wxIsAbsolutePath(m_strLocalFile) ) - { - const wxString strLocalOrig = m_strLocalFile; - m_strLocalFile = GetLocalDir(); - m_strLocalFile << strLocalOrig; - } + if ( m_fnLocalFile.IsOk() ) + m_fnLocalFile.MakeAbsolute(GetLocalDir(style)); - if ( !m_strGlobalFile.empty() && !wxIsAbsolutePath(m_strGlobalFile) ) - { - const wxString strGlobalOrig = m_strGlobalFile; - m_strGlobalFile = GetGlobalDir(); - m_strGlobalFile << strGlobalOrig; - } + if ( m_fnGlobalFile.IsOk() ) + m_fnGlobalFile.MakeAbsolute(GetGlobalDir()); } SetUmask(-1); @@ -1041,13 +982,13 @@ bool wxFileConfig::DoWriteLong(const wxString& key, long lValue) bool wxFileConfig::Flush(bool /* bCurrentOnly */) { - if ( !IsDirty() || !m_strLocalFile ) + if ( !IsDirty() || !m_fnLocalFile.GetFullPath() ) return true; // set the umask if needed wxCHANGE_UMASK(m_umask); - wxTempFile file(m_strLocalFile); + wxTempFile file(m_fnLocalFile.GetFullPath()); if ( !file.IsOpened() ) { @@ -1079,7 +1020,7 @@ bool wxFileConfig::Flush(bool /* bCurrentOnly */) ResetDirty(); #if defined(__WXMAC__) - wxFileName(m_strLocalFile).MacSetTypeAndCreator('TEXT', 'ttxt'); + m_fnLocalFile.MacSetTypeAndCreator('TEXT', 'ttxt'); #endif // __WXMAC__ return true; @@ -1205,12 +1146,12 @@ bool wxFileConfig::DeleteAll() { CleanUp(); - if ( !m_strLocalFile.empty() ) + if ( m_fnLocalFile.IsOk() ) { - if ( wxFile::Exists(m_strLocalFile) && wxRemove(m_strLocalFile) == -1 ) + if ( m_fnLocalFile.FileExists() && wxRemove(m_fnLocalFile.GetFullPath()) == -1 ) { wxLogSysError(_("can't delete user configuration file '%s'"), - m_strLocalFile.c_str()); + m_fnLocalFile.GetFullPath().c_str()); return false; } }