Make FileLayout_XXX elements of an enum
Slight improvement to the previous commit: make FileLayout_Classic and FileLayout_XDG elements of an enum instead of using an untyped "int" for them which didn't really make any sense because these values are not bit masks but exclusive choices for the layout. Also rewrite the checks for them to use "switch" instead of "if" to be warned by the compiler if we ever add another enum value but forget to update the code to handle it. Finally, improve the documentation (add missing "@since") and comments.
This commit is contained in:
@@ -60,10 +60,11 @@ public:
|
|||||||
Dir_Videos
|
Dir_Videos
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
// Layout to use for user config/data files under Unix.
|
||||||
|
enum FileLayout
|
||||||
{
|
{
|
||||||
FileLayout_Classic = 0,
|
FileLayout_Classic, // Default: use home directory.
|
||||||
FileLayout_XDG = 1
|
FileLayout_XDG // Recommended: use XDG specification.
|
||||||
};
|
};
|
||||||
|
|
||||||
// return the global standard paths object
|
// return the global standard paths object
|
||||||
@@ -174,14 +175,14 @@ public:
|
|||||||
|
|
||||||
bool UsesAppInfo(int info) const { return (m_usedAppInfo & info) != 0; }
|
bool UsesAppInfo(int info) const { return (m_usedAppInfo & info) != 0; }
|
||||||
|
|
||||||
void SetFileLayout(int layout)
|
void SetFileLayout(FileLayout layout)
|
||||||
{
|
{
|
||||||
m_usedFileLayout = layout;
|
m_fileLayout = layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetFileLayout() const
|
FileLayout GetFileLayout() const
|
||||||
{
|
{
|
||||||
return m_usedFileLayout;
|
return m_fileLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -199,7 +200,9 @@ protected:
|
|||||||
|
|
||||||
// combination of AppInfo_XXX flags used by AppendAppInfo()
|
// combination of AppInfo_XXX flags used by AppendAppInfo()
|
||||||
int m_usedAppInfo;
|
int m_usedAppInfo;
|
||||||
int m_usedFileLayout;
|
|
||||||
|
// The file layout to use, currently only used under Unix.
|
||||||
|
FileLayout m_fileLayout;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if wxUSE_STDPATHS
|
#if wxUSE_STDPATHS
|
||||||
|
@@ -135,16 +135,34 @@ public:
|
|||||||
Dir_Videos
|
Dir_Videos
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
/**
|
||||||
|
Possible values for SetFileLayout() argument.
|
||||||
|
|
||||||
|
The elements of this enum correspond to the different file layout
|
||||||
|
standards under Unix systems.
|
||||||
|
|
||||||
|
@since 3.1.1
|
||||||
|
*/
|
||||||
|
enum FileLayout
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
Use the classic file layout
|
Use the classic file layout.
|
||||||
*/
|
|
||||||
|
User configuration and data files are located directly in the home
|
||||||
|
directory.
|
||||||
|
|
||||||
|
This is the default behaviour for compatibility reasons.
|
||||||
|
*/
|
||||||
FileLayout_Classic,
|
FileLayout_Classic,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Use a XDG styled file layout (Unix)
|
Use a XDG styled file layout.
|
||||||
*/
|
|
||||||
|
File layout follows the XDG Base Directory Specification (see
|
||||||
|
https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html).
|
||||||
|
|
||||||
|
This is the recommended layout for new applications.
|
||||||
|
*/
|
||||||
FileLayout_XDG
|
FileLayout_XDG
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -313,8 +331,11 @@ public:
|
|||||||
virtual wxString GetTempDir() const;
|
virtual wxString GetTempDir() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Return the directory for the user config files:
|
Return the directory for the user config files.
|
||||||
- Unix: @c ~ (the home directory)
|
|
||||||
|
This directory is:
|
||||||
|
- Unix: @c ~ (the home directory) or @c XDG_CONFIG_HOME depending on
|
||||||
|
GetFileLayout() return value
|
||||||
- Windows: @c "C:\Users\username\AppData\Roaming" or
|
- Windows: @c "C:\Users\username\AppData\Roaming" or
|
||||||
@c "C:\Documents and Settings\username\Application Data"
|
@c "C:\Documents and Settings\username\Application Data"
|
||||||
- Mac: @c ~/Library/Preferences
|
- Mac: @c ~/Library/Preferences
|
||||||
@@ -339,7 +360,8 @@ public:
|
|||||||
|
|
||||||
If the value could not be determined the users home directory is returned.
|
If the value could not be determined the users home directory is returned.
|
||||||
|
|
||||||
@note On Unix this supports the xdg user dirs specification.
|
@note On Unix this method respects the XDG base directory specification
|
||||||
|
only if SetFileLayout() with @c FileLayout_XDG had been called.
|
||||||
|
|
||||||
@since 3.1.0
|
@since 3.1.0
|
||||||
*/
|
*/
|
||||||
@@ -458,17 +480,24 @@ public:
|
|||||||
void UseAppInfo(int info);
|
void UseAppInfo(int info);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the current file layout
|
Returns the current file layout.
|
||||||
Valid values for @a are:
|
|
||||||
- @c FileLayout_Classic,
|
The default layout is @c FileLayout_Classic for compatibility, however
|
||||||
- @c FileLayout_XDG
|
newer applications are encouraged to set it to @c FileLayout_XDG on
|
||||||
|
program startup.
|
||||||
|
|
||||||
|
@since 3.1.1
|
||||||
*/
|
*/
|
||||||
void SetFileLayout(int layout);
|
void SetFileLayout(FileLayout layout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the current file layout
|
Returns the current file layout.
|
||||||
|
|
||||||
|
@see SetFileLayout()
|
||||||
|
|
||||||
|
@since 3.1.1
|
||||||
*/
|
*/
|
||||||
int GetFileLayout() const;
|
FileLayout GetFileLayout() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Return the file name which would be used by wxFileConfig as local,
|
Return the file name which would be used by wxFileConfig as local,
|
||||||
|
@@ -97,6 +97,8 @@ wxStandardPathsBase::wxStandardPathsBase()
|
|||||||
// Derived classes can call this in their constructors
|
// Derived classes can call this in their constructors
|
||||||
// to set the platform-specific settings
|
// to set the platform-specific settings
|
||||||
UseAppInfo(AppInfo_AppName);
|
UseAppInfo(AppInfo_AppName);
|
||||||
|
|
||||||
|
// Default for compatibility with the existing config files.
|
||||||
SetFileLayout(FileLayout_Classic);
|
SetFileLayout(FileLayout_Classic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -53,17 +53,23 @@ void wxStandardPaths::SetInstallPrefix(const wxString& prefix)
|
|||||||
|
|
||||||
wxString wxStandardPaths::GetUserConfigDir() const
|
wxString wxStandardPaths::GetUserConfigDir() const
|
||||||
{
|
{
|
||||||
if (GetFileLayout() & FileLayout_XDG)
|
wxString dir;
|
||||||
|
|
||||||
|
switch ( GetFileLayout() )
|
||||||
{
|
{
|
||||||
wxString configPath;
|
case FileLayout_Classic:
|
||||||
if (wxGetenv(wxT("XDG_CONFIG_HOME")))
|
dir = wxFileName::GetHomeDir();
|
||||||
configPath = wxGetenv(wxT("XDG_CONFIG_HOME"));
|
break;
|
||||||
else
|
|
||||||
configPath = wxFileName::GetHomeDir() + wxT("/.config");
|
case FileLayout_XDG:
|
||||||
return configPath;
|
if ( !wxGetEnv(wxS("XDG_CONFIG_HOME"), &dir) || dir.empty() )
|
||||||
|
dir = wxFileName::GetHomeDir() + wxS("/.config");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return wxFileName::GetHomeDir();
|
wxASSERT_MSG( !dir.empty(), wxS("unsupported file layout") );
|
||||||
|
|
||||||
|
return dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -246,73 +252,81 @@ wxStandardPaths::GetLocalizedResourcesDir(const wxString& lang,
|
|||||||
|
|
||||||
wxString wxStandardPaths::GetUserDir(Dir userDir) const
|
wxString wxStandardPaths::GetUserDir(Dir userDir) const
|
||||||
{
|
{
|
||||||
if (GetFileLayout() & FileLayout_XDG)
|
switch ( GetFileLayout() )
|
||||||
{
|
{
|
||||||
wxLogNull logNull;
|
case FileLayout_Classic:
|
||||||
wxString homeDir = wxFileName::GetHomeDir();
|
// Fall back to the base class below.
|
||||||
if (userDir == Dir_Cache)
|
break;
|
||||||
{
|
|
||||||
if (wxGetenv(wxT("XDG_CACHE_HOME")))
|
|
||||||
return wxGetenv(wxT("XDG_CACHE_HOME"));
|
|
||||||
else
|
|
||||||
return homeDir + wxT("/.cache");
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString configPath;
|
case FileLayout_XDG:
|
||||||
if (wxGetenv(wxT("XDG_CONFIG_HOME")))
|
|
||||||
configPath = wxGetenv(wxT("XDG_CONFIG_HOME"));
|
|
||||||
else
|
|
||||||
configPath = homeDir + wxT("/.config");
|
|
||||||
wxString dirsFile = configPath + wxT("/user-dirs.dirs");
|
|
||||||
if (wxFileExists(dirsFile))
|
|
||||||
{
|
|
||||||
wxString userDirId;
|
|
||||||
switch (userDir)
|
|
||||||
{
|
{
|
||||||
case Dir_Desktop:
|
wxLogNull logNull;
|
||||||
userDirId = "XDG_DESKTOP_DIR";
|
wxString homeDir = wxFileName::GetHomeDir();
|
||||||
break;
|
if (userDir == Dir_Cache)
|
||||||
case Dir_Downloads:
|
|
||||||
userDirId = "XDG_DOWNLOAD_DIR";
|
|
||||||
break;
|
|
||||||
case Dir_Music:
|
|
||||||
userDirId = "XDG_MUSIC_DIR";
|
|
||||||
break;
|
|
||||||
case Dir_Pictures:
|
|
||||||
userDirId = "XDG_PICTURES_DIR";
|
|
||||||
break;
|
|
||||||
case Dir_Videos:
|
|
||||||
userDirId = "XDG_VIDEOS_DIR";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
userDirId = "XDG_DOCUMENTS_DIR";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxTextFile textFile;
|
|
||||||
if (textFile.Open(dirsFile))
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
for (i = 0; i < textFile.GetLineCount(); i++)
|
|
||||||
{
|
{
|
||||||
wxString line(textFile[i]);
|
if (wxGetenv(wxT("XDG_CACHE_HOME")))
|
||||||
int pos = line.Find(userDirId);
|
return wxGetenv(wxT("XDG_CACHE_HOME"));
|
||||||
if (pos != wxNOT_FOUND)
|
else
|
||||||
|
return homeDir + wxT("/.cache");
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString configPath;
|
||||||
|
if (wxGetenv(wxT("XDG_CONFIG_HOME")))
|
||||||
|
configPath = wxGetenv(wxT("XDG_CONFIG_HOME"));
|
||||||
|
else
|
||||||
|
configPath = homeDir + wxT("/.config");
|
||||||
|
wxString dirsFile = configPath + wxT("/user-dirs.dirs");
|
||||||
|
if (wxFileExists(dirsFile))
|
||||||
|
{
|
||||||
|
wxString userDirId;
|
||||||
|
switch (userDir)
|
||||||
{
|
{
|
||||||
wxString value = line.AfterFirst(wxT('='));
|
case Dir_Desktop:
|
||||||
value.Replace(wxT("$HOME"), homeDir);
|
userDirId = "XDG_DESKTOP_DIR";
|
||||||
value.Trim(true);
|
|
||||||
value.Trim(false);
|
|
||||||
// Remove quotes
|
|
||||||
value.Replace("\"", "", true /* replace all */);
|
|
||||||
if (!value.IsEmpty() && wxDirExists(value))
|
|
||||||
return value;
|
|
||||||
else
|
|
||||||
break;
|
break;
|
||||||
|
case Dir_Downloads:
|
||||||
|
userDirId = "XDG_DOWNLOAD_DIR";
|
||||||
|
break;
|
||||||
|
case Dir_Music:
|
||||||
|
userDirId = "XDG_MUSIC_DIR";
|
||||||
|
break;
|
||||||
|
case Dir_Pictures:
|
||||||
|
userDirId = "XDG_PICTURES_DIR";
|
||||||
|
break;
|
||||||
|
case Dir_Videos:
|
||||||
|
userDirId = "XDG_VIDEOS_DIR";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
userDirId = "XDG_DOCUMENTS_DIR";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxTextFile textFile;
|
||||||
|
if (textFile.Open(dirsFile))
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < textFile.GetLineCount(); i++)
|
||||||
|
{
|
||||||
|
wxString line(textFile[i]);
|
||||||
|
int pos = line.Find(userDirId);
|
||||||
|
if (pos != wxNOT_FOUND)
|
||||||
|
{
|
||||||
|
wxString value = line.AfterFirst(wxT('='));
|
||||||
|
value.Replace(wxT("$HOME"), homeDir);
|
||||||
|
value.Trim(true);
|
||||||
|
value.Trim(false);
|
||||||
|
// Remove quotes
|
||||||
|
value.Replace("\"", "", true /* replace all */);
|
||||||
|
if (!value.IsEmpty() && wxDirExists(value))
|
||||||
|
return value;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return wxStandardPathsBase::GetUserDir(userDir);
|
return wxStandardPathsBase::GetUserDir(userDir);
|
||||||
@@ -323,10 +337,27 @@ wxString wxStandardPaths::GetUserDir(Dir userDir) const
|
|||||||
wxString wxStandardPaths::MakeConfigFileName(const wxString& basename, int style) const
|
wxString wxStandardPaths::MakeConfigFileName(const wxString& basename, int style) const
|
||||||
{
|
{
|
||||||
wxFileName fn(wxEmptyString, basename);
|
wxFileName fn(wxEmptyString, basename);
|
||||||
if (style & wxCONFIG_USE_SUBDIR || GetFileLayout() & FileLayout_XDG)
|
switch ( GetFileLayout() )
|
||||||
fn.SetExt(wxT("conf"));
|
{
|
||||||
else
|
case FileLayout_Classic:
|
||||||
fn.SetName(wxT('.') + fn.GetName());
|
if ( !(style & wxCONFIG_USE_SUBDIR) )
|
||||||
|
{
|
||||||
|
// The standard convention is to not use the extensions for the
|
||||||
|
// config files in the home directory and just prepend a dot to
|
||||||
|
// them instead.
|
||||||
|
fn.SetName(wxT('.') + fn.GetName());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//else: fall through to add the extension
|
||||||
|
wxFALLTHROUGH;
|
||||||
|
|
||||||
|
case FileLayout_XDG:
|
||||||
|
// We always use the extension for the config files when using XDG
|
||||||
|
// layout as they don't go to the home directory anyhow.
|
||||||
|
fn.SetExt(wxS("conf"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return fn.GetFullName();
|
return fn.GetFullName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user