Merge branch 'config-xdg'
Make it easier to use wxFileConfig in XDG-compliant way. See #24180.
This commit is contained in:
commit
b294a6b2bc
15 changed files with 372 additions and 40 deletions
|
|
@ -168,6 +168,10 @@ Currently the following symbols exist:
|
|||
implemented in a generic way, using a critical section.}
|
||||
@itemdef{wxHAS_BITMAPTOGGLEBUTTON, Defined in @c wx/tglbtn.h if
|
||||
wxBitmapToggleButton class is available in addition to wxToggleButton.}
|
||||
@itemdef{wxHAS_CONFIG_AS_FILECONFIG, Defined if wxConfig is defined as
|
||||
wxFileConfig. This constant is available since wxWidgets 3.3.0.}
|
||||
@itemdef{wxHAS_CONFIG_AS_REGCONFIG, Defined if wxConfig is defined as
|
||||
wxRegConfig. This constant is available since wxWidgets 3.3.0.}
|
||||
@itemdef{wxHAS_CONFIG_TEMPLATE_RW, Defined if the currently used compiler
|
||||
supports template Read() and Write() methods in wxConfig.}
|
||||
@itemdef{wxHAS_DEPRECATED_ATTR, Defined if C++14 @c [[deprecated]] attribute is
|
||||
|
|
|
|||
|
|
@ -62,7 +62,8 @@ enum
|
|||
wxCONFIG_USE_GLOBAL_FILE = 2,
|
||||
wxCONFIG_USE_RELATIVE_PATH = 4,
|
||||
wxCONFIG_USE_NO_ESCAPE_CHARACTERS = 8,
|
||||
wxCONFIG_USE_SUBDIR = 16
|
||||
wxCONFIG_USE_SUBDIR = 16,
|
||||
wxCONFIG_USE_XDG = 32
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -23,9 +23,11 @@
|
|||
#if defined(__WINDOWS__) && wxUSE_CONFIG_NATIVE
|
||||
#include "wx/msw/regconf.h"
|
||||
#define wxConfig wxRegConfig
|
||||
#define wxHAS_CONFIG_AS_REGCONFIG
|
||||
#else // either we're under Unix or wish to always use config files
|
||||
#include "wx/fileconf.h"
|
||||
#define wxConfig wxFileConfig
|
||||
#define wxHAS_CONFIG_AS_FILECONFIG
|
||||
#endif
|
||||
|
||||
#endif // wxUSE_CONFIG
|
||||
|
|
|
|||
|
|
@ -123,6 +123,22 @@ public:
|
|||
return GetLocalFile(szFile, style).GetFullPath();
|
||||
}
|
||||
|
||||
// Function to migrate, i.e. move, an existing local config file to another
|
||||
// location. Old and new style determine the existing and new file paths.
|
||||
struct MigrationResult
|
||||
{
|
||||
// If empty, it means the old file wasn't found and nothing was done.
|
||||
wxString oldPath;
|
||||
|
||||
// The name of the new file.
|
||||
wxString newPath;
|
||||
|
||||
// If empty, means the file was successfully migrated.
|
||||
wxString error;
|
||||
};
|
||||
static MigrationResult
|
||||
MigrateLocalFile(const wxString& name, int newStyle, int oldStyle = 0);
|
||||
|
||||
// ctor & dtor
|
||||
// New constructor: one size fits all. Specify wxCONFIG_USE_LOCAL_FILE or
|
||||
// wxCONFIG_USE_GLOBAL_FILE to say which files should be used.
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ public:
|
|||
enum Dir
|
||||
{
|
||||
Dir_Cache,
|
||||
Dir_Config,
|
||||
Dir_Documents,
|
||||
Dir_Desktop,
|
||||
Dir_Downloads,
|
||||
|
|
@ -184,6 +185,11 @@ public:
|
|||
|
||||
bool UsesAppInfo(int info) const { return (m_usedAppInfo & info) != 0; }
|
||||
|
||||
// append application information determined by m_usedAppInfo to dir
|
||||
wxNODISCARD
|
||||
wxString AppendAppInfo(const wxString& dir) const;
|
||||
|
||||
|
||||
void SetFileLayout(FileLayout layout)
|
||||
{
|
||||
m_fileLayout = layout;
|
||||
|
|
@ -203,10 +209,6 @@ protected:
|
|||
// path separator or dot (.) is not already at the end of dir
|
||||
static wxString AppendPathComponent(const wxString& dir, const wxString& component);
|
||||
|
||||
// append application information determined by m_usedAppInfo to dir
|
||||
wxString AppendAppInfo(const wxString& dir) const;
|
||||
|
||||
|
||||
// combination of AppInfo_XXX flags used by AppendAppInfo()
|
||||
int m_usedAppInfo;
|
||||
|
||||
|
|
|
|||
|
|
@ -6,14 +6,41 @@
|
|||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// Flags for constructor style parameter
|
||||
/// Flags for wxConfig constructor style parameter.
|
||||
enum
|
||||
{
|
||||
wxCONFIG_USE_LOCAL_FILE = 1,
|
||||
wxCONFIG_USE_GLOBAL_FILE = 2,
|
||||
wxCONFIG_USE_RELATIVE_PATH = 4,
|
||||
wxCONFIG_USE_NO_ESCAPE_CHARACTERS = 8,
|
||||
wxCONFIG_USE_SUBDIR = 16
|
||||
|
||||
/**
|
||||
Use subdirectory for the local configuration file location.
|
||||
|
||||
Specifying this flag changes the default local configuration file
|
||||
location to `~/.appname/appname.conf`. Please note that this path is
|
||||
_not_ affected by layout set using wxStandardPaths::SetFileLayout() and
|
||||
it is recommended to use wxCONFIG_USE_XDG flag in addition to this file
|
||||
on contemporary Linux systems.
|
||||
|
||||
@since 2.8.2
|
||||
*/
|
||||
wxCONFIG_USE_SUBDIR = 16,
|
||||
|
||||
/**
|
||||
Use XDG-compliant file location on Unix systems.
|
||||
|
||||
If wxCONFIG_USE_SUBDIR is not specified, using this flag has the same
|
||||
effect as calling wxStandardPaths::SetFileLayout() with
|
||||
wxStandardPaths::FileLayout_XDG, i.e. it changes the default local
|
||||
configuration file location to `~/.config/appname.conf`.
|
||||
|
||||
In combination with wxCONFIG_USE_SUBDIR, this flag changes the default
|
||||
configuration file location to ~/.config/appname/appname.conf`.
|
||||
|
||||
@since 3.3.0
|
||||
*/
|
||||
wxCONFIG_USE_XDG = 32
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -30,7 +57,9 @@ enum
|
|||
with the registry under Windows or text-based config files under Unix.
|
||||
To make writing the portable code even easier, wxWidgets provides a typedef
|
||||
wxConfig which is mapped onto the native wxConfigBase implementation on the
|
||||
given platform: i.e. wxRegConfig under Windows and wxFileConfig otherwise.
|
||||
given platform: i.e. wxRegConfig under Windows (in this case
|
||||
`wxHAS_CONFIG_AS_REGCONFIG` preprocessor symbol is defined) and
|
||||
wxFileConfig otherwise (in this case `wxHAS_CONFIG_AS_FILECONFIG` is).
|
||||
|
||||
See @ref overview_config for a description of all features of this class.
|
||||
|
||||
|
|
@ -296,14 +325,16 @@ public:
|
|||
@n For wxFileConfig you can also add @c wxCONFIG_USE_RELATIVE_PATH by
|
||||
logically or'ing it to either of the _FILE options to tell
|
||||
wxFileConfig to use relative instead of absolute paths.
|
||||
@n On non-VMS Unix systems, the default local configuration file is
|
||||
"~/.appname". However, this path may be also used as user data
|
||||
@n On Unix-like systems, the default local configuration file is
|
||||
`~/.appname` unless wxStandardPaths::SetFileLayout() is called with
|
||||
wxStandardPaths::FileLayout_XDG parameter in which case the default
|
||||
becomes `~/.config/appname.conf`.
|
||||
@n Note that this default path may be also used as user data
|
||||
directory (see wxStandardPaths::GetUserDataDir()) if the
|
||||
application has several data files. In this case
|
||||
@c wxCONFIG_USE_SUBDIR flag, which changes the default local
|
||||
configuration file to "~/.appname/appname" should be used. Notice
|
||||
that this flag is ignored if @a localFilename is provided.
|
||||
@c wxCONFIG_USE_SUBDIR is new since wxWidgets version 2.8.2.
|
||||
application has several data files. In this case it is recommended
|
||||
to use ::wxCONFIG_USE_XDG flag (available since wxWidgets 3.3.0)
|
||||
and/or older ::wxCONFIG_USE_SUBDIR (available since 2.8.2) to
|
||||
change the default local configuration file location.
|
||||
@n For wxFileConfig, you can also add
|
||||
@c wxCONFIG_USE_NO_ESCAPE_CHARACTERS which will turn off character
|
||||
escaping for the values of entries stored in the config file: for
|
||||
|
|
|
|||
|
|
@ -18,6 +18,25 @@
|
|||
used explicitly if you want to use files and not the registry even under
|
||||
Windows.
|
||||
|
||||
@section fileconf_paths Configuration Files Paths
|
||||
|
||||
The default path for local (or user) configuration file is `~/.appname`,
|
||||
i.e. it is stored directly in the user home directory. This default
|
||||
path is backwards-compatible but not recommended any more and it is advised
|
||||
to call wxStandardPaths::SetFileLayout() with
|
||||
wxStandardPaths::FileLayout_XDG parameter to change the default path to
|
||||
`~/.config/appname.conf`. MigrateLocalFile() may be helpful for moving the
|
||||
existing configuration file to the new location.
|
||||
|
||||
Alternatively, it is possible to specify ::wxCONFIG_USE_XDG flag in the
|
||||
style parameter of the constructor to use this XDG-compliant path without
|
||||
changing the global file layout.
|
||||
|
||||
And for the programs using multiple configuration files it is recommended
|
||||
to use both ::wxCONFIG_USE_XDG and ::wxCONFIG_USE_SUBDIR which change the
|
||||
default file path to `~/.config/appname/appname.conf` -- and allow the
|
||||
program to store other files in the same `~/.config/appname` directory.
|
||||
|
||||
@library{wxbase}
|
||||
@category{cfg}
|
||||
|
||||
|
|
@ -71,8 +90,8 @@ public:
|
|||
parameter in the constructor.
|
||||
|
||||
@a style has the same meaning as in @ref wxConfigBase::wxConfigBase "wxConfig constructor"
|
||||
and can contain any combination of styles but only wxCONFIG_USE_SUBDIR bit is
|
||||
examined by this function.
|
||||
and can contain any combination of styles but only wxCONFIG_USE_SUBDIR
|
||||
and wxCONFIG_USE_XDG are really used by this function.
|
||||
|
||||
Notice that this function cannot be used if @a basename is already a full path name.
|
||||
*/
|
||||
|
|
@ -81,6 +100,70 @@ public:
|
|||
static wxString GetGlobalFileName(const wxString& szFile);
|
||||
static wxString GetLocalFileName(const wxString& szFile, int style = 0);
|
||||
|
||||
/**
|
||||
Contains return value of MigrateLocalFile().
|
||||
|
||||
@since 3.3.0
|
||||
*/
|
||||
struct MigrationResult
|
||||
{
|
||||
/// If empty, it means the old file wasn't found and nothing was done.
|
||||
wxString oldPath;
|
||||
|
||||
/// The name of the new file.
|
||||
wxString newPath;
|
||||
|
||||
/// If empty, means the file was successfully migrated.
|
||||
wxString error;
|
||||
};
|
||||
|
||||
/**
|
||||
Move the existing configuration file to a new location.
|
||||
|
||||
This function is useful for moving legacy configuration files in
|
||||
`~/.appname` or `~/.appname/appname.conf` to the XDG-compliant location
|
||||
under `~/.config`. To do this, simply specify ::wxCONFIG_USE_XDG as
|
||||
part of @a newStyle.
|
||||
|
||||
The returned MigrationResult object describes what, if anything, was
|
||||
done: if its `oldPath` member is empty, it means that the file
|
||||
corresponding to @a oldStyle was not found and nothing was done.
|
||||
Otherwise, if its `error` member is empty, the old file was found and
|
||||
moved to `newPath`. And if `error` is not empty, it contains the
|
||||
user-readable error message describing why moving the file failed.
|
||||
|
||||
Typical example of using this function is shown in the widgets sample:
|
||||
@code
|
||||
// Execute this early during the application startup, before the
|
||||
// global wxConfig object is created.
|
||||
const auto res = wxFileConfig::MigrateLocalFile("app", wxCONFIG_USE_XDG);
|
||||
if ( !res.oldPath.empty() ) {
|
||||
if ( res.error.empty() ) {
|
||||
wxLogMessage("Config file was migrated from \"%s\" to \"%s\"",
|
||||
res.oldPath, res.newPath);
|
||||
} else {
|
||||
wxLogWarning("Migrating old config failed: %s.", res.error);
|
||||
}
|
||||
}
|
||||
|
||||
// Note that this must be done after calling MigrateLocalFile(),
|
||||
// otherwise the old style would use XDG layout already and the actual
|
||||
// file at non-XDG-compliant location wouldn't be migrated.
|
||||
wxStandardPaths::Get().SetFileLayout(wxStandardPaths::FileLayout_XDG);
|
||||
@endcode
|
||||
|
||||
@param name Name of the configuration file.
|
||||
@param newStyle Style which is used by the current version of the
|
||||
program, typically including ::wxCONFIG_USE_XDG and possibly also
|
||||
including ::wxCONFIG_USE_SUBDIR.
|
||||
@param oldStyle Style which was used by the previous versions of the
|
||||
program, possibly including ::wxCONFIG_USE_SUBDIR.
|
||||
|
||||
@since 3.3.0
|
||||
*/
|
||||
static MigrationResult
|
||||
MigrateLocalFile(const wxString& name, int newStyle, int oldStyle = 0);
|
||||
|
||||
/**
|
||||
Saves all config data to the given stream, returns @true if data was saved
|
||||
successfully or @false on error.
|
||||
|
|
|
|||
|
|
@ -79,6 +79,18 @@ public:
|
|||
*/
|
||||
Dir_Cache,
|
||||
|
||||
/**
|
||||
Directory containing configuration information.
|
||||
|
||||
Example return values:
|
||||
- Unix: `~/.config`
|
||||
- Windows: `C:\Users\username\AppData\Roaming`
|
||||
- Mac: @c `~/Library/Preferences`
|
||||
|
||||
@since 3.3.0
|
||||
*/
|
||||
Dir_Config,
|
||||
|
||||
/**
|
||||
Directory containing user documents.
|
||||
|
||||
|
|
@ -195,6 +207,20 @@ public:
|
|||
ConfigFileConv_Ext
|
||||
};
|
||||
|
||||
/**
|
||||
Append application and/or vendor name to the given directory.
|
||||
|
||||
By default, appends the subdirectory with the application name, as
|
||||
returned by wxApp::GetAppName(), to the given directory.
|
||||
|
||||
This behaviour is affected by UseAppInfo(), e.g. if this function is
|
||||
called with `AppInfo_VendorName` then the vendor name would be appended
|
||||
instead of the application name.
|
||||
|
||||
@since 3.3.0
|
||||
*/
|
||||
wxString AppendAppInfo(const wxString& dir) const;
|
||||
|
||||
/**
|
||||
MSW-specific function undoing the effect of IgnoreAppSubDir() calls.
|
||||
|
||||
|
|
@ -370,17 +396,25 @@ public:
|
|||
- Mac: @c ~/Library/Preferences
|
||||
|
||||
Only use this method if you have a single configuration file to put in this
|
||||
directory, otherwise GetUserDataDir() is more appropriate as the latter
|
||||
adds @c appinfo to the path, unlike this function.
|
||||
directory, otherwise calling AppendAppInfo() with the value returned by
|
||||
GetDir() with wxStandardPaths::Dir_Config is more appropriate.
|
||||
*/
|
||||
virtual wxString GetUserConfigDir() const;
|
||||
|
||||
/**
|
||||
Return the directory for the user-dependent application data files:
|
||||
Return the directory for the user-dependent application data files.
|
||||
|
||||
The returned path is:
|
||||
|
||||
- Unix: @c ~/.appinfo
|
||||
- Windows: @c "C:\Users\username\AppData\Roaming\appinfo" or
|
||||
@c "C:\Documents and Settings\username\Application Data\appinfo"
|
||||
- Mac: @c "~/Library/Application Support/appinfo"
|
||||
|
||||
Please note that under Unix this function return value doesn't depend
|
||||
on the file layout, and so returns a possibly unexpected value when
|
||||
wxStandardPaths::FileLayout_XDG is used. Consider using GetUserDir()
|
||||
instead if you use XDG layout, as this function does respect it.
|
||||
*/
|
||||
virtual wxString GetUserDataDir() const;
|
||||
|
||||
|
|
@ -505,6 +539,8 @@ public:
|
|||
|
||||
By default, only the application name is used.
|
||||
|
||||
@see AppendAppInfo()
|
||||
|
||||
@since 2.9.0
|
||||
*/
|
||||
void UseAppInfo(int info);
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@
|
|||
#include "wx/msgdlg.h"
|
||||
#endif
|
||||
|
||||
#include "wx/config.h"
|
||||
#include "wx/stdpaths.h"
|
||||
|
||||
#include "wx/sysopt.h"
|
||||
#include "wx/bookctrl.h"
|
||||
#include "wx/treebook.h"
|
||||
|
|
@ -141,6 +144,30 @@ public:
|
|||
#if USE_LOG
|
||||
m_logTarget = nullptr;
|
||||
#endif // USE_LOG
|
||||
|
||||
#ifdef wxHAS_CONFIG_AS_FILECONFIG
|
||||
// We want to put our config file (implicitly created for persistent
|
||||
// controls settings) in XDG-compliant location, so we want to change
|
||||
// the default file layout, but before doing this migrate any existing
|
||||
// config files to the new location as the previous versions of this
|
||||
// sample didn't use XDG layout.
|
||||
const auto
|
||||
res = wxFileConfig::MigrateLocalFile("widgets", wxCONFIG_USE_XDG);
|
||||
if ( !res.oldPath.empty() )
|
||||
{
|
||||
if ( res.error.empty() )
|
||||
{
|
||||
wxLogMessage("Config file was migrated from \"%s\" to \"%s\"",
|
||||
res.oldPath, res.newPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogWarning("Migrating old config failed: %s.", res.error);
|
||||
}
|
||||
}
|
||||
|
||||
wxStandardPaths::Get().SetFileLayout(wxStandardPaths::FileLayout_XDG);
|
||||
#endif // wxHAS_CONFIG_AS_FILECONFIG
|
||||
}
|
||||
WidgetsApp(const WidgetsApp&) = delete;
|
||||
WidgetsApp& operator=(const WidgetsApp&) = delete;
|
||||
|
|
|
|||
|
|
@ -56,12 +56,13 @@ bool wxConfigBase::ms_bAutoCreate = true;
|
|||
|
||||
wxConfigBase *wxAppTraitsBase::CreateConfig()
|
||||
{
|
||||
return new
|
||||
#if defined(__WINDOWS__) && wxUSE_CONFIG_NATIVE
|
||||
wxRegConfig(wxTheApp->GetAppName(), wxTheApp->GetVendorName());
|
||||
#else // either we're under Unix or wish to use files even under Windows
|
||||
wxFileConfig(wxTheApp->GetAppName());
|
||||
#endif
|
||||
#if defined(wxHAS_CONFIG_AS_REGCONFIG)
|
||||
return new wxRegConfig(wxTheApp->GetAppName(), wxTheApp->GetVendorName());
|
||||
#elif defined(wxHAS_CONFIG_AS_FILECONFIG)
|
||||
return new wxFileConfig(wxTheApp->GetAppName());
|
||||
#else
|
||||
#error No wxConfig implementation defined.
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -247,42 +247,154 @@ wxString wxFileConfig::GetGlobalDir()
|
|||
|
||||
wxString wxFileConfig::GetLocalDir(int style)
|
||||
{
|
||||
wxUnusedVar(style);
|
||||
const wxStandardPathsBase& stdp = wxStandardPaths::Get();
|
||||
|
||||
wxStandardPathsBase& stdp = wxStandardPaths::Get();
|
||||
if ( style & wxCONFIG_USE_XDG )
|
||||
{
|
||||
// When XDG-compliant layout is requested, we need to use this function
|
||||
// as GetUserDataDir() doesn't support it.
|
||||
wxString dir = stdp.GetUserDir(wxStandardPaths::Dir_Config);
|
||||
|
||||
// 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
|
||||
if ( style & wxCONFIG_USE_SUBDIR )
|
||||
dir = stdp.AppendAppInfo(dir);
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
// Normally we'd like to use GetUserConfigDir() and just append app info
|
||||
// subdirectories to it, but we can't do it for compatibility reasons:
|
||||
// there are existing configuration files in the locations returned by
|
||||
// these functions already, so return the same values as we always did.
|
||||
return style & wxCONFIG_USE_SUBDIR ? stdp.GetUserDataDir()
|
||||
: stdp.GetUserConfigDir();
|
||||
}
|
||||
|
||||
wxFileName wxFileConfig::GetGlobalFile(const wxString& szFile)
|
||||
{
|
||||
wxStandardPathsBase& stdp = wxStandardPaths::Get();
|
||||
const wxStandardPathsBase& stdp = wxStandardPaths::Get();
|
||||
|
||||
return wxFileName(GetGlobalDir(), stdp.MakeConfigFileName(szFile));
|
||||
}
|
||||
|
||||
wxFileName wxFileConfig::GetLocalFile(const wxString& szFile, int style)
|
||||
{
|
||||
wxStandardPathsBase& stdp = wxStandardPaths::Get();
|
||||
const wxStandardPathsBase& stdp = wxStandardPaths::Get();
|
||||
|
||||
// If the config file is located in a subdirectory, we always use an
|
||||
// extension for it, but we use just the leading dot if it is located
|
||||
// directly in the home directory. Note that if wxStandardPaths is
|
||||
// configured to follow XDG specification, all config files go to a
|
||||
// subdirectory of XDG_CONFIG_HOME anyhow, so in this case we'll still end
|
||||
// up using the extension even if wxCONFIG_USE_SUBDIR is not set, but this
|
||||
// is the correct and expected (if a little confusing) behaviour.
|
||||
// up using the extension even if neither wxCONFIG_USE_SUBDIR nor
|
||||
// wxCONFIG_USE_XDG is set, but this is the correct and expected (if a
|
||||
// little confusing) behaviour.
|
||||
const wxStandardPaths::ConfigFileConv
|
||||
conv = style & wxCONFIG_USE_SUBDIR
|
||||
conv = style & (wxCONFIG_USE_SUBDIR | wxCONFIG_USE_XDG)
|
||||
? wxStandardPaths::ConfigFileConv_Ext
|
||||
: wxStandardPaths::ConfigFileConv_Dot;
|
||||
|
||||
return wxFileName(GetLocalDir(style), stdp.MakeConfigFileName(szFile, conv));
|
||||
}
|
||||
|
||||
wxFileConfig::MigrationResult
|
||||
wxFileConfig::MigrateLocalFile(const wxString& name, int newStyle, int oldStyle)
|
||||
{
|
||||
MigrationResult res;
|
||||
|
||||
const auto oldPath = GetLocalFile(name, oldStyle);
|
||||
if ( !oldPath.FileExists() )
|
||||
return res;
|
||||
|
||||
const auto newPath = GetLocalFile(name, newStyle);
|
||||
if ( newPath == oldPath )
|
||||
return res;
|
||||
|
||||
res.oldPath = oldPath.GetFullPath();
|
||||
res.newPath = newPath.GetFullPath();
|
||||
|
||||
// This class ensures that we (at least try to) rename the existing config
|
||||
// file back to its original name if we fail with an error.
|
||||
class RenameBackOnError
|
||||
{
|
||||
public:
|
||||
explicit RenameBackOnError(wxFileConfig::MigrationResult& res)
|
||||
: m_res(res)
|
||||
{
|
||||
}
|
||||
|
||||
void Init(const wxString& tempPath)
|
||||
{
|
||||
m_tempPath = tempPath;
|
||||
}
|
||||
|
||||
void Dismiss()
|
||||
{
|
||||
m_tempPath.clear();
|
||||
}
|
||||
|
||||
~RenameBackOnError()
|
||||
{
|
||||
if ( !m_tempPath.empty() )
|
||||
{
|
||||
if ( !wxRenameFile(m_tempPath, m_res.oldPath) )
|
||||
{
|
||||
// This should never happen, but if it does, do at least
|
||||
// let the user know that we moved their file to a wrong
|
||||
// place and couldn't put it back.
|
||||
m_res.error += wxString::Format(
|
||||
_(" and additionally, the existing configuration file"
|
||||
" was renamed to \"%s\" and couldn't be renamed back,"
|
||||
" please rename it to its original path \"%s\""),
|
||||
m_tempPath,
|
||||
m_res.oldPath
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
MigrationResult& m_res;
|
||||
|
||||
wxString m_tempPath;
|
||||
} renameBackOnError{res};
|
||||
|
||||
wxString currentPath = res.oldPath;
|
||||
|
||||
const auto newDir = newPath.GetPath();
|
||||
if ( !wxFileName::DirExists(newDir) )
|
||||
{
|
||||
// There is an annoying failure mode here when the new directory can't
|
||||
// be created because its name is the same as the name of the existing
|
||||
// file, e.g. when oldStyle==0 and newStyle==wxCONFIG_USE_SUBDIR and
|
||||
// XDG layout is not used, so check for this specially.
|
||||
if ( newDir == res.oldPath )
|
||||
{
|
||||
currentPath = wxFileName::CreateTempFileName(currentPath);
|
||||
if ( !wxRenameFile(res.oldPath, currentPath) )
|
||||
{
|
||||
res.error = _("failed to rename the existing file");
|
||||
return res;
|
||||
}
|
||||
|
||||
renameBackOnError.Init(currentPath);
|
||||
}
|
||||
|
||||
if ( !wxFileName::Mkdir(newDir, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL) )
|
||||
{
|
||||
res.error = _("failed to create the new file directory");
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !wxRenameFile(currentPath, res.newPath) )
|
||||
{
|
||||
res.error = _("failed to move the file to the new location");
|
||||
return res;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ctor
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -488,14 +488,18 @@ static void DoCommonPostCleanup()
|
|||
|
||||
void wxEntryCleanup()
|
||||
{
|
||||
DoCommonPreCleanup();
|
||||
|
||||
|
||||
// delete the application object
|
||||
if ( wxTheApp )
|
||||
{
|
||||
wxTheApp->CleanUp();
|
||||
}
|
||||
|
||||
// It's important to call this after wxApp::CleanUp() as it can log some
|
||||
// messages that will be flushed inside DoCommonPreCleanup().
|
||||
DoCommonPreCleanup();
|
||||
|
||||
if ( wxTheApp )
|
||||
{
|
||||
// reset the global pointer to it to nullptr before destroying it as in
|
||||
// some circumstances this can result in executing the code using
|
||||
// wxTheApp and using half-destroyed object is no good
|
||||
|
|
|
|||
|
|
@ -189,6 +189,9 @@ wxString wxStandardPaths::GetUserDir(Dir userDir) const
|
|||
case Dir_Cache:
|
||||
csidl = CSIDL_LOCAL_APPDATA;
|
||||
break;
|
||||
case Dir_Config:
|
||||
csidl = CSIDL_APPDATA;
|
||||
break;
|
||||
case Dir_Desktop:
|
||||
csidl = CSIDL_DESKTOPDIRECTORY;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -101,12 +101,18 @@ wxStandardPaths::GetLocalizedResourcesDir(const wxString& lang,
|
|||
|
||||
wxString wxStandardPaths::GetUserDir(Dir userDir) const
|
||||
{
|
||||
wxString subdir;
|
||||
|
||||
NSSearchPathDirectory dirType;
|
||||
switch (userDir)
|
||||
{
|
||||
case Dir_Cache:
|
||||
dirType = NSCachesDirectory;
|
||||
break;
|
||||
case Dir_Config:
|
||||
dirType = NSLibraryDirectory;
|
||||
subdir = "/Preferences";
|
||||
break;
|
||||
case Dir_Desktop:
|
||||
dirType = NSDesktopDirectory;
|
||||
break;
|
||||
|
|
@ -127,7 +133,7 @@ wxString wxStandardPaths::GetUserDir(Dir userDir) const
|
|||
break;
|
||||
}
|
||||
|
||||
return GetFMDirectory(dirType, NSUserDomainMask);
|
||||
return GetFMDirectory(dirType, NSUserDomainMask) + subdir;
|
||||
}
|
||||
|
||||
wxString
|
||||
|
|
|
|||
|
|
@ -274,7 +274,11 @@ wxString wxStandardPaths::GetUserDir(Dir userDir) const
|
|||
return cacheDir;
|
||||
}
|
||||
|
||||
const wxFileName dirsFile(GetXDGConfigHome(), wxS("user-dirs.dirs"));
|
||||
const wxString configDir = GetXDGConfigHome();
|
||||
if (userDir == Dir_Config)
|
||||
return configDir;
|
||||
|
||||
const wxFileName dirsFile(configDir, wxS("user-dirs.dirs"));
|
||||
if ( dirsFile.FileExists() )
|
||||
{
|
||||
wxString userDirId;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue