Add wxStandardPaths::GetUserDir() to get Desktop, Download etc
All major supported platforms have well defined per-user directories to store Downloads, Music, Pictures, Videos and the Desktop files. The new method wxStandardPaths::GetUserDir() allows for a unified way to access these on MSW, OS X and Unix (if XDG user dirs specification is implemented for the latter). See https://github.com/wxWidgets/wxWidgets/pull/89
This commit is contained in:
committed by
Vadim Zeitlin
parent
cfe4b4fd07
commit
a0fb808087
@@ -50,6 +50,7 @@ Changes in behaviour which may result in build errors
|
||||
All:
|
||||
|
||||
- Add UTF-8 and ZIP 64 support to wxZip{Input,Output}Stream (Tobias Taschner).
|
||||
- Add wxStandardPaths::GetUserDir() (Tobias Taschner).
|
||||
- Allow calling wxItemContainer::Add() and similar with std::vector<> argument.
|
||||
- Add "%z" support to printf()-like functions like wxString::Format() (RIVDSL).
|
||||
- Add DOCTYPE support to wxXmlDocument (Nick Matthews).
|
||||
|
@@ -26,7 +26,7 @@ public:
|
||||
virtual wxString GetUserDataDir() const;
|
||||
virtual wxString GetUserLocalDataDir() const;
|
||||
virtual wxString GetPluginsDir() const;
|
||||
virtual wxString GetDocumentsDir() const;
|
||||
virtual wxString GetUserDir(Dir userDir) const wxOVERRIDE;
|
||||
|
||||
|
||||
// MSW-specific methods
|
||||
@@ -72,6 +72,8 @@ protected:
|
||||
// get the path corresponding to the given standard CSIDL_XXX constant
|
||||
static wxString DoGetDirectory(int csidl);
|
||||
|
||||
static wxString DoGetKnownFolder(const GUID& rfid);
|
||||
|
||||
// return the directory of the application itself
|
||||
wxString GetAppDir() const;
|
||||
|
||||
|
@@ -52,7 +52,7 @@ public:
|
||||
virtual wxString
|
||||
GetLocalizedResourcesDir(const wxString& lang,
|
||||
ResourceCat category = ResourceCat_None) const;
|
||||
virtual wxString GetDocumentsDir() const;
|
||||
virtual wxString GetUserDir(Dir userDir) const wxOVERRIDE;
|
||||
|
||||
protected:
|
||||
// Ctor is protected, use wxStandardPaths::Get() instead of instantiating
|
||||
|
@@ -49,6 +49,15 @@ public:
|
||||
AppInfo_VendorName = 2 // the vendor name
|
||||
};
|
||||
|
||||
enum Dir
|
||||
{
|
||||
Dir_Documents,
|
||||
Dir_Desktop,
|
||||
Dir_Downloads,
|
||||
Dir_Music,
|
||||
Dir_Pictures,
|
||||
Dir_Videos
|
||||
};
|
||||
|
||||
// return the global standard paths object
|
||||
static wxStandardPaths& Get();
|
||||
@@ -130,7 +139,10 @@ public:
|
||||
//
|
||||
// C:\Documents and Settings\username\My Documents under Windows,
|
||||
// $HOME under Unix and ~/Documents under Mac
|
||||
virtual wxString GetDocumentsDir() const;
|
||||
virtual wxString GetDocumentsDir() const
|
||||
{
|
||||
return GetUserDir(Dir_Documents);
|
||||
}
|
||||
|
||||
// return the directory for the documents files used by this application:
|
||||
// it's a subdirectory of GetDocumentsDir() constructed using the
|
||||
@@ -140,6 +152,7 @@ public:
|
||||
// return the temporary directory for the current user
|
||||
virtual wxString GetTempDir() const;
|
||||
|
||||
virtual wxString GetUserDir(Dir userDir) const;
|
||||
|
||||
// virtual dtor for the base class
|
||||
virtual ~wxStandardPathsBase();
|
||||
@@ -205,7 +218,7 @@ public:
|
||||
virtual wxString GetLocalDataDir() const { return m_prefix; }
|
||||
virtual wxString GetUserDataDir() const { return m_prefix; }
|
||||
virtual wxString GetPluginsDir() const { return m_prefix; }
|
||||
virtual wxString GetDocumentsDir() const { return m_prefix; }
|
||||
virtual wxString GetUserDir(Dir WXUNUSED(userDir)) const { return m_prefix; }
|
||||
|
||||
protected:
|
||||
// Ctor is protected because wxStandardPaths::Get() should always be used
|
||||
|
@@ -47,7 +47,7 @@ public:
|
||||
virtual wxString GetLocalizedResourcesDir(const wxString& lang,
|
||||
ResourceCat category) const wxOVERRIDE;
|
||||
#ifndef __VMS
|
||||
virtual wxString GetDocumentsDir() const wxOVERRIDE;
|
||||
virtual wxString GetUserDir(Dir userDir) const wxOVERRIDE;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
@@ -66,6 +66,64 @@ public:
|
||||
ResourceCat_Messages
|
||||
};
|
||||
|
||||
/// Possible values for userDir parameter of GetUserDir().
|
||||
enum Dir
|
||||
{
|
||||
/**
|
||||
Directory containing user documents.
|
||||
|
||||
Example return values:
|
||||
- Unix/Mac: @c ~/Documents
|
||||
- Windows: @c "C:\Users\username\Documents"
|
||||
*/
|
||||
Dir_Documents,
|
||||
|
||||
/**
|
||||
Directory containing files on the users desktop.
|
||||
|
||||
Example return values:
|
||||
- Unix/Mac: @c ~/Desktop
|
||||
- Windows: @c "C:\Users\username\Desktop"
|
||||
*/
|
||||
Dir_Desktop,
|
||||
|
||||
/**
|
||||
Directory for downloaded files
|
||||
|
||||
Example return values:
|
||||
- Unix/Mac: @c ~/Downloads
|
||||
- Windows: @c "C:\Users\username\Downloads" (Only available on Vista and newer)
|
||||
*/
|
||||
Dir_Downloads,
|
||||
|
||||
/**
|
||||
Directory containing music files.
|
||||
|
||||
Example return values:
|
||||
- Unix/Mac: @c ~/Music
|
||||
- Windows: @c "C:\Users\username\Music"
|
||||
*/
|
||||
Dir_Music,
|
||||
|
||||
/**
|
||||
Directory containing picture files.
|
||||
|
||||
Example return values:
|
||||
- Unix/Mac: @c ~/Pictures
|
||||
- Windows: @c "C:\Users\username\Pictures"
|
||||
*/
|
||||
Dir_Pictures,
|
||||
|
||||
/**
|
||||
Directory containing video files.
|
||||
|
||||
Example return values:
|
||||
- Unix: @c ~/Videos
|
||||
- Windows: @c "C:\Users\username\Videos"
|
||||
- Mac: @c ~/Movies
|
||||
*/
|
||||
Dir_Videos
|
||||
};
|
||||
|
||||
/**
|
||||
MSW-specific function undoing the effect of IgnoreAppSubDir() calls.
|
||||
@@ -138,17 +196,11 @@ public:
|
||||
virtual wxString GetDataDir() const;
|
||||
|
||||
/**
|
||||
Return the directory containing the current user's documents.
|
||||
|
||||
Example return values:
|
||||
- Unix: @c ~ (the home directory)
|
||||
- Windows: @c "C:\Users\username\Documents" or
|
||||
@c "C:\Documents and Settings\username\My Documents"
|
||||
- Mac: @c ~/Documents
|
||||
Same as calling GetUserDir() with Dir_Documents parameter.
|
||||
|
||||
@since 2.7.0
|
||||
|
||||
@see GetAppDocumentsDir()
|
||||
@see GetAppDocumentsDir(), GetUserDir()
|
||||
*/
|
||||
virtual wxString GetDocumentsDir() const;
|
||||
|
||||
@@ -259,6 +311,17 @@ public:
|
||||
*/
|
||||
virtual wxString GetUserDataDir() const;
|
||||
|
||||
/**
|
||||
Return the path of the specified user data directory.
|
||||
|
||||
If the value could not be determined the users home directory is returned.
|
||||
|
||||
@note On Unix this supports the xdg user dirs specification.
|
||||
|
||||
@since 3.1.0
|
||||
*/
|
||||
virtual wxString GetUserDir(Dir userDir) const;
|
||||
|
||||
/**
|
||||
Return the directory for user data files which shouldn't be shared with
|
||||
the other machines.
|
||||
|
@@ -114,11 +114,6 @@ wxString wxStandardPathsBase::GetUserLocalDataDir() const
|
||||
return GetUserDataDir();
|
||||
}
|
||||
|
||||
wxString wxStandardPathsBase::GetDocumentsDir() const
|
||||
{
|
||||
return wxFileName::GetHomeDir();
|
||||
}
|
||||
|
||||
wxString wxStandardPathsBase::GetAppDocumentsDir() const
|
||||
{
|
||||
const wxString docsDir = GetDocumentsDir();
|
||||
@@ -133,6 +128,11 @@ wxString wxStandardPathsBase::GetTempDir() const
|
||||
return wxFileName::GetTempDir();
|
||||
}
|
||||
|
||||
wxString wxStandardPathsBase::GetUserDir(Dir WXUNUSED(userDir)) const
|
||||
{
|
||||
return wxFileName::GetHomeDir();
|
||||
}
|
||||
|
||||
/* static */
|
||||
wxString
|
||||
wxStandardPathsBase::AppendPathComponent(const wxString& dir,
|
||||
|
@@ -36,6 +36,7 @@
|
||||
|
||||
#include "wx/msw/private.h"
|
||||
#include "wx/msw/wrapshl.h"
|
||||
#include <initguid.h>
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// types
|
||||
@@ -43,6 +44,7 @@
|
||||
|
||||
typedef HRESULT (WINAPI *SHGetFolderPath_t)(HWND, int, HANDLE, DWORD, LPTSTR);
|
||||
typedef HRESULT (WINAPI *SHGetSpecialFolderPath_t)(HWND, LPTSTR, int, BOOL);
|
||||
typedef HRESULT (WINAPI *SHGetKnownFolderPath_t)(const GUID&, DWORD, HANDLE, PWSTR *);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// constants
|
||||
@@ -86,6 +88,9 @@ typedef HRESULT (WINAPI *SHGetSpecialFolderPath_t)(HWND, LPTSTR, int, BOOL);
|
||||
namespace
|
||||
{
|
||||
|
||||
DEFINE_GUID(wxFOLDERID_Downloads,
|
||||
0x374de290, 0x123f, 0x4565, 0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b);
|
||||
|
||||
struct ShellFunctions
|
||||
{
|
||||
ShellFunctions()
|
||||
@@ -97,6 +102,7 @@ struct ShellFunctions
|
||||
|
||||
SHGetFolderPath_t pSHGetFolderPath;
|
||||
SHGetSpecialFolderPath_t pSHGetSpecialFolderPath;
|
||||
SHGetKnownFolderPath_t pSHGetKnownFolderPath;
|
||||
|
||||
bool initialized;
|
||||
};
|
||||
@@ -146,6 +152,9 @@ void ResolveShellFunctions()
|
||||
dllShellFunctions.GetSymbol(funcname + UNICODE_SUFFIX);
|
||||
}
|
||||
|
||||
gs_shellFuncs.pSHGetKnownFolderPath = (SHGetKnownFolderPath_t)
|
||||
dllShellFunctions.GetSymbol("SHGetKnownFolderPath");
|
||||
|
||||
// finally we fall back on SHGetSpecialFolderLocation (shell32.dll 4.0),
|
||||
// but we don't need to test for it -- it is available even under Win95
|
||||
|
||||
@@ -242,6 +251,28 @@ wxString wxStandardPaths::DoGetDirectory(int csidl)
|
||||
return dir;
|
||||
}
|
||||
|
||||
wxString wxStandardPaths::DoGetKnownFolder(const GUID& rfid)
|
||||
{
|
||||
if (!gs_shellFuncs.initialized)
|
||||
ResolveShellFunctions();
|
||||
|
||||
wxString dir;
|
||||
|
||||
if ( gs_shellFuncs.pSHGetKnownFolderPath )
|
||||
{
|
||||
PWSTR pDir;
|
||||
HRESULT hr = gs_shellFuncs.pSHGetKnownFolderPath(rfid, 0, 0, &pDir);
|
||||
if ( SUCCEEDED(hr) )
|
||||
{
|
||||
dir = pDir;
|
||||
CoTaskMemFree(pDir);
|
||||
}
|
||||
}
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
|
||||
wxString wxStandardPaths::GetAppDir() const
|
||||
{
|
||||
if ( m_appDir.empty() )
|
||||
@@ -252,9 +283,38 @@ wxString wxStandardPaths::GetAppDir() const
|
||||
return m_appDir;
|
||||
}
|
||||
|
||||
wxString wxStandardPaths::GetDocumentsDir() const
|
||||
wxString wxStandardPaths::GetUserDir(Dir userDir) const
|
||||
{
|
||||
return DoGetDirectory(CSIDL_PERSONAL);
|
||||
int csidl;
|
||||
switch (userDir)
|
||||
{
|
||||
case Dir_Desktop:
|
||||
csidl = CSIDL_DESKTOPDIRECTORY;
|
||||
break;
|
||||
case Dir_Downloads:
|
||||
{
|
||||
csidl = CSIDL_PERSONAL;
|
||||
// Downloads folder is only available since Vista
|
||||
wxString dir = DoGetKnownFolder(wxFOLDERID_Downloads);
|
||||
if ( !dir.empty() )
|
||||
return dir;
|
||||
break;
|
||||
}
|
||||
case Dir_Music:
|
||||
csidl = CSIDL_MYMUSIC;
|
||||
break;
|
||||
case Dir_Pictures:
|
||||
csidl = CSIDL_MYPICTURES;
|
||||
break;
|
||||
case Dir_Videos:
|
||||
csidl = CSIDL_MYVIDEO;
|
||||
break;
|
||||
default:
|
||||
csidl = CSIDL_PERSONAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return DoGetDirectory(csidl);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@@ -96,17 +96,62 @@ wxString wxStandardPathsCF::GetFromFunc(wxCFURLRef (*func)(wxCFBundleRef)) const
|
||||
return ret;
|
||||
}
|
||||
|
||||
wxString wxStandardPathsCF::GetDocumentsDir() const
|
||||
wxString wxStandardPathsCF::GetUserDir(Dir userDir) const
|
||||
{
|
||||
#if defined( __WXMAC__ ) && wxOSX_USE_CARBON
|
||||
OSType folderType;
|
||||
switch (userDir)
|
||||
{
|
||||
case Dir_Desktop:
|
||||
folderType = kDesktopFolderType;
|
||||
break;
|
||||
case Dir_Downloads:
|
||||
folderType = kDownloadsFolderType;
|
||||
break;
|
||||
case Dir_Music:
|
||||
folderType = kMusicDocumentsFolderType;
|
||||
break;
|
||||
case Dir_Pictures:
|
||||
folderType = kPictureDocumentsFolderType;
|
||||
break;
|
||||
case Dir_Videos:
|
||||
folderType = kMovieDocumentsFolderType;
|
||||
break;
|
||||
default:
|
||||
folderType = kDocumentsFolderType;
|
||||
break;
|
||||
}
|
||||
|
||||
return wxMacFindFolderNoSeparator
|
||||
(
|
||||
kUserDomain,
|
||||
kDocumentsFolderType,
|
||||
folderType,
|
||||
kCreateFolder
|
||||
);
|
||||
#else
|
||||
return wxFileName::GetHomeDir() + wxT("/Documents");
|
||||
wxString userDirName;
|
||||
switch (userDir)
|
||||
{
|
||||
case Dir_Desktop:
|
||||
userDirName = "Desktop";
|
||||
break;
|
||||
case Dir_Downloads:
|
||||
userDirName = "Downloads";
|
||||
break;
|
||||
case Dir_Music:
|
||||
userDirName = "Music";
|
||||
break;
|
||||
case Dir_Pictures:
|
||||
userDirName = "Pictures";
|
||||
break;
|
||||
case Dir_Videos:
|
||||
userDirName = "Movies";
|
||||
break;
|
||||
default:
|
||||
userDirName = "Documents";
|
||||
break;
|
||||
}
|
||||
return wxFileName::GetHomeDir() + "/" + userDirName;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -233,7 +233,7 @@ wxStandardPaths::GetLocalizedResourcesDir(const wxString& lang,
|
||||
return GetInstallPrefix() + wxT("/share/locale/") + lang + wxT("/LC_MESSAGES");
|
||||
}
|
||||
|
||||
wxString wxStandardPaths::GetDocumentsDir() const
|
||||
wxString wxStandardPaths::GetUserDir(Dir userDir) const
|
||||
{
|
||||
{
|
||||
wxLogNull logNull;
|
||||
@@ -246,6 +246,29 @@ wxString wxStandardPaths::GetDocumentsDir() const
|
||||
wxString dirsFile = configPath + wxT("/user-dirs.dirs");
|
||||
if (wxFileExists(dirsFile))
|
||||
{
|
||||
wxString userDirId;
|
||||
switch (userDir)
|
||||
{
|
||||
case Dir_Desktop:
|
||||
userDirId = "XDG_DESKTOP_DIR";
|
||||
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))
|
||||
{
|
||||
@@ -253,13 +276,15 @@ wxString wxStandardPaths::GetDocumentsDir() const
|
||||
for (i = 0; i < textFile.GetLineCount(); i++)
|
||||
{
|
||||
wxString line(textFile[i]);
|
||||
int pos = line.Find(wxT("XDG_DOCUMENTS_DIR"));
|
||||
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
|
||||
@@ -270,7 +295,7 @@ wxString wxStandardPaths::GetDocumentsDir() const
|
||||
}
|
||||
}
|
||||
|
||||
return wxStandardPathsBase::GetDocumentsDir();
|
||||
return wxStandardPathsBase::GetUserDir(userDir);
|
||||
}
|
||||
|
||||
#endif // __VMS/!__VMS
|
||||
|
@@ -404,6 +404,11 @@ void InteractiveOutputTestCase::TestStandardPaths()
|
||||
wxPrintf(wxT("Data dir (user):\t%s\n"), stdp.GetUserDataDir().c_str());
|
||||
wxPrintf(wxT("Data dir (user local):\t%s\n"), stdp.GetUserLocalDataDir().c_str());
|
||||
wxPrintf(wxT("Documents dir:\t\t%s\n"), stdp.GetDocumentsDir().c_str());
|
||||
wxPrintf(wxT("Desktop dir:\t\t%s\n"), stdp.GetUserDir(wxStandardPaths::Dir_Desktop).c_str());
|
||||
wxPrintf(wxT("Downloads dir:\t\t%s\n"), stdp.GetUserDir(wxStandardPaths::Dir_Downloads).c_str());
|
||||
wxPrintf(wxT("Music dir:\t\t%s\n"), stdp.GetUserDir(wxStandardPaths::Dir_Music).c_str());
|
||||
wxPrintf(wxT("Pictures dir:\t\t%s\n"), stdp.GetUserDir(wxStandardPaths::Dir_Pictures).c_str());
|
||||
wxPrintf(wxT("Videos dir:\t\t%s\n"), stdp.GetUserDir(wxStandardPaths::Dir_Videos).c_str());
|
||||
wxPrintf(wxT("Executable path:\t%s\n"), stdp.GetExecutablePath().c_str());
|
||||
wxPrintf(wxT("Plugins dir:\t\t%s\n"), stdp.GetPluginsDir().c_str());
|
||||
wxPrintf(wxT("Resources dir:\t\t%s\n"), stdp.GetResourcesDir().c_str());
|
||||
|
Reference in New Issue
Block a user