mirror of https://github.com/AxioDL/metaforce.git
Initial system location finder (unix only)
This commit is contained in:
parent
4ca3cb8081
commit
29fd504475
|
@ -1 +1 @@
|
||||||
Subproject commit 9c173505248875ee9bf7e943030a134401da6e05
|
Subproject commit 4d7e9656f1b3ac11ab0609b4e6a68c9612418e79
|
|
@ -91,6 +91,7 @@ public:
|
||||||
: m_utf8(WideToUTF8(str)) {}
|
: m_utf8(WideToUTF8(str)) {}
|
||||||
operator const std::string&() const {return m_utf8;}
|
operator const std::string&() const {return m_utf8;}
|
||||||
const std::string& str() const {return m_utf8;}
|
const std::string& str() const {return m_utf8;}
|
||||||
|
const char* c_str() const {return m_utf8.c_str();}
|
||||||
std::string operator+(const std::string& other) const {return m_utf8 + other;}
|
std::string operator+(const std::string& other) const {return m_utf8 + other;}
|
||||||
std::string operator+(const char* other) const {return m_utf8 + other;}
|
std::string operator+(const char* other) const {return m_utf8 + other;}
|
||||||
};
|
};
|
||||||
|
@ -104,6 +105,7 @@ public:
|
||||||
: m_sys(UTF8ToWide(str)) {}
|
: m_sys(UTF8ToWide(str)) {}
|
||||||
operator const std::wstring&() const {return m_sys;}
|
operator const std::wstring&() const {return m_sys;}
|
||||||
const std::wstring& sys_str() const {return m_sys;}
|
const std::wstring& sys_str() const {return m_sys;}
|
||||||
|
const SystemChar* c_str() const {return m_sys.c_str();}
|
||||||
std::wstring operator+(const std::wstring& other) const {return m_sys + other;}
|
std::wstring operator+(const std::wstring& other) const {return m_sys + other;}
|
||||||
std::wstring operator+(const wchar_t* other) const {return m_sys + other;}
|
std::wstring operator+(const wchar_t* other) const {return m_sys + other;}
|
||||||
};
|
};
|
||||||
|
@ -129,6 +131,7 @@ public:
|
||||||
: m_utf8(str) {}
|
: m_utf8(str) {}
|
||||||
operator const std::string&() const {return m_utf8;}
|
operator const std::string&() const {return m_utf8;}
|
||||||
const std::string& str() const {return m_utf8;}
|
const std::string& str() const {return m_utf8;}
|
||||||
|
const char* c_str() const {return m_utf8.c_str();}
|
||||||
std::string operator+(const std::string& other) const {return std::string(m_utf8) + other;}
|
std::string operator+(const std::string& other) const {return std::string(m_utf8) + other;}
|
||||||
std::string operator+(const char* other) const {return std::string(m_utf8) + other;}
|
std::string operator+(const char* other) const {return std::string(m_utf8) + other;}
|
||||||
};
|
};
|
||||||
|
@ -142,6 +145,7 @@ public:
|
||||||
: m_sys(str) {}
|
: m_sys(str) {}
|
||||||
operator const std::string&() const {return m_sys;}
|
operator const std::string&() const {return m_sys;}
|
||||||
const std::string& sys_str() const {return m_sys;}
|
const std::string& sys_str() const {return m_sys;}
|
||||||
|
const SystemChar* c_str() const {return m_sys.c_str();}
|
||||||
std::string operator+(const std::string& other) const {return m_sys + other;}
|
std::string operator+(const std::string& other) const {return m_sys + other;}
|
||||||
std::string operator+(const char* other) const {return m_sys + other;}
|
std::string operator+(const char* other) const {return m_sys + other;}
|
||||||
};
|
};
|
||||||
|
@ -561,10 +565,10 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DirectoryEnumerator(const HECL::SystemString& path, Mode mode=Mode::DirsThenFilesSorted,
|
DirectoryEnumerator(const HECL::SystemString& path, Mode mode=Mode::DirsThenFilesSorted,
|
||||||
bool sizeSort=false, bool reverse=false)
|
bool sizeSort=false, bool reverse=false, bool noHidden=false)
|
||||||
: DirectoryEnumerator(path.c_str(), mode, sizeSort, reverse) {}
|
: DirectoryEnumerator(path.c_str(), mode, sizeSort, reverse, noHidden) {}
|
||||||
DirectoryEnumerator(const HECL::SystemChar* path, Mode mode=Mode::DirsThenFilesSorted,
|
DirectoryEnumerator(const HECL::SystemChar* path, Mode mode=Mode::DirsThenFilesSorted,
|
||||||
bool sizeSort=false, bool reverse=false);
|
bool sizeSort=false, bool reverse=false, bool noHidden=false);
|
||||||
|
|
||||||
operator bool() const {return m_entries.size() != 0;}
|
operator bool() const {return m_entries.size() != 0;}
|
||||||
size_t size() const {return m_entries.size();}
|
size_t size() const {return m_entries.size();}
|
||||||
|
@ -572,6 +576,11 @@ public:
|
||||||
std::vector<Entry>::const_iterator end() const {return m_entries.cend();}
|
std::vector<Entry>::const_iterator end() const {return m_entries.cend();}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Build list of common OS-specific directories
|
||||||
|
*/
|
||||||
|
std::vector<HECL::SystemString> GetSystemLocations();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Special ProjectRootPath class for opening HECLDatabase::IProject instances
|
* @brief Special ProjectRootPath class for opening HECLDatabase::IProject instances
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,5 +1,21 @@
|
||||||
#include "HECL/HECL.hpp"
|
#include "HECL/HECL.hpp"
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#ifndef _WIN32_IE
|
||||||
|
#define _WIN32_IE 0x0400
|
||||||
|
#endif
|
||||||
|
#include <shlobj.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <Carbon/Carbon.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
#include <mntent.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace HECL
|
namespace HECL
|
||||||
{
|
{
|
||||||
unsigned VerbosityLevel = 0;
|
unsigned VerbosityLevel = 0;
|
||||||
|
@ -118,7 +134,7 @@ bool IsPathYAML(const HECL::ProjectPath& path)
|
||||||
}
|
}
|
||||||
|
|
||||||
HECL::DirectoryEnumerator::DirectoryEnumerator(const HECL::SystemChar* path, Mode mode,
|
HECL::DirectoryEnumerator::DirectoryEnumerator(const HECL::SystemChar* path, Mode mode,
|
||||||
bool sizeSort, bool reverse)
|
bool sizeSort, bool reverse, bool noHidden)
|
||||||
{
|
{
|
||||||
HECL::Sstat theStat;
|
HECL::Sstat theStat;
|
||||||
if (HECL::Stat(path, &theStat) || !S_ISDIR(theStat.st_mode))
|
if (HECL::Stat(path, &theStat) || !S_ISDIR(theStat.st_mode))
|
||||||
|
@ -138,6 +154,8 @@ HECL::DirectoryEnumerator::DirectoryEnumerator(const HECL::SystemChar* path, Mod
|
||||||
{
|
{
|
||||||
if (!wcscmp(d.cFileName, _S(".")) || !wcscmp(d.cFileName, _S("..")))
|
if (!wcscmp(d.cFileName, _S(".")) || !wcscmp(d.cFileName, _S("..")))
|
||||||
continue;
|
continue;
|
||||||
|
if (noHidden && (d.cFileName == L'.' || (d.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0))
|
||||||
|
continue;
|
||||||
HECL::SystemString fp(path);
|
HECL::SystemString fp(path);
|
||||||
fp += _S('/');
|
fp += _S('/');
|
||||||
fp += d.cFileName;
|
fp += d.cFileName;
|
||||||
|
@ -165,6 +183,8 @@ HECL::DirectoryEnumerator::DirectoryEnumerator(const HECL::SystemChar* path, Mod
|
||||||
{
|
{
|
||||||
if (!wcscmp(d.cFileName, _S(".")) || !wcscmp(d.cFileName, _S("..")))
|
if (!wcscmp(d.cFileName, _S(".")) || !wcscmp(d.cFileName, _S("..")))
|
||||||
continue;
|
continue;
|
||||||
|
if (noHidden && (d.cFileName == L'.' || (d.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0))
|
||||||
|
continue;
|
||||||
HECL::SystemString fp(path);
|
HECL::SystemString fp(path);
|
||||||
fp +=_S('/');
|
fp +=_S('/');
|
||||||
fp += d.cFileName;
|
fp += d.cFileName;
|
||||||
|
@ -198,6 +218,8 @@ HECL::DirectoryEnumerator::DirectoryEnumerator(const HECL::SystemChar* path, Mod
|
||||||
{
|
{
|
||||||
if (!wcscmp(d.cFileName, _S(".")) || !wcscmp(d.cFileName, _S("..")))
|
if (!wcscmp(d.cFileName, _S(".")) || !wcscmp(d.cFileName, _S("..")))
|
||||||
continue;
|
continue;
|
||||||
|
if (noHidden && (d.cFileName == L'.' || (d.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0))
|
||||||
|
continue;
|
||||||
HECL::SystemString fp(path);
|
HECL::SystemString fp(path);
|
||||||
fp += _S('/');
|
fp += _S('/');
|
||||||
fp += d.cFileName;
|
fp += d.cFileName;
|
||||||
|
@ -221,6 +243,8 @@ HECL::DirectoryEnumerator::DirectoryEnumerator(const HECL::SystemChar* path, Mod
|
||||||
{
|
{
|
||||||
if (!wcscmp(d.cFileName, _S(".")) || !wcscmp(d.cFileName, _S("..")))
|
if (!wcscmp(d.cFileName, _S(".")) || !wcscmp(d.cFileName, _S("..")))
|
||||||
continue;
|
continue;
|
||||||
|
if (noHidden && (d.cFileName == L'.' || (d.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0))
|
||||||
|
continue;
|
||||||
HECL::SystemString fp(path);
|
HECL::SystemString fp(path);
|
||||||
fp += _S('/');
|
fp += _S('/');
|
||||||
fp += d.cFileName;
|
fp += d.cFileName;
|
||||||
|
@ -256,6 +280,8 @@ HECL::DirectoryEnumerator::DirectoryEnumerator(const HECL::SystemChar* path, Mod
|
||||||
{
|
{
|
||||||
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
|
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
|
||||||
continue;
|
continue;
|
||||||
|
if (noHidden && d->d_name[0] == '.')
|
||||||
|
continue;
|
||||||
HECL::SystemString fp(path);
|
HECL::SystemString fp(path);
|
||||||
fp += '/';
|
fp += '/';
|
||||||
fp += d->d_name;
|
fp += d->d_name;
|
||||||
|
@ -283,6 +309,8 @@ HECL::DirectoryEnumerator::DirectoryEnumerator(const HECL::SystemChar* path, Mod
|
||||||
{
|
{
|
||||||
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
|
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
|
||||||
continue;
|
continue;
|
||||||
|
if (noHidden && d->d_name[0] == '.')
|
||||||
|
continue;
|
||||||
HECL::SystemString fp(path);
|
HECL::SystemString fp(path);
|
||||||
fp += '/';
|
fp += '/';
|
||||||
fp += d->d_name;
|
fp += d->d_name;
|
||||||
|
@ -315,6 +343,8 @@ HECL::DirectoryEnumerator::DirectoryEnumerator(const HECL::SystemChar* path, Mod
|
||||||
{
|
{
|
||||||
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
|
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
|
||||||
continue;
|
continue;
|
||||||
|
if (noHidden && d->d_name[0] == '.')
|
||||||
|
continue;
|
||||||
HECL::SystemString fp(path);
|
HECL::SystemString fp(path);
|
||||||
fp += '/';
|
fp += '/';
|
||||||
fp += d->d_name;
|
fp += d->d_name;
|
||||||
|
@ -338,6 +368,8 @@ HECL::DirectoryEnumerator::DirectoryEnumerator(const HECL::SystemChar* path, Mod
|
||||||
{
|
{
|
||||||
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
|
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
|
||||||
continue;
|
continue;
|
||||||
|
if (noHidden && d->d_name[0] == '.')
|
||||||
|
continue;
|
||||||
HECL::SystemString fp(path);
|
HECL::SystemString fp(path);
|
||||||
fp += '/';
|
fp += '/';
|
||||||
fp += d->d_name;
|
fp += d->d_name;
|
||||||
|
@ -363,4 +395,171 @@ HECL::DirectoryEnumerator::DirectoryEnumerator(const HECL::SystemChar* path, Mod
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<HECL::SystemString> GetSystemLocations()
|
||||||
|
{
|
||||||
|
HECL::Sstat theStat;
|
||||||
|
std::vector<HECL::SystemString> ret;
|
||||||
|
#ifdef WIN32
|
||||||
|
/* Add the drive names to the listing */
|
||||||
|
{
|
||||||
|
wchar_t wline[FILE_MAXDIR];
|
||||||
|
__int64 tmp;
|
||||||
|
char tmps[4], *name;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
tmp = GetLogicalDrives();
|
||||||
|
|
||||||
|
for (i = 0; i < 26; i++) {
|
||||||
|
if ((tmp >> i) & 1) {
|
||||||
|
tmps[0] = 'A' + i;
|
||||||
|
tmps[1] = ':';
|
||||||
|
tmps[2] = '\\';
|
||||||
|
tmps[3] = '\0';
|
||||||
|
name = NULL;
|
||||||
|
|
||||||
|
/* Flee from horrible win querying hover floppy drives! */
|
||||||
|
if (i > 1) {
|
||||||
|
/* Try to get volume label as well... */
|
||||||
|
BLI_strncpy_wchar_from_utf8(wline, tmps, 4);
|
||||||
|
if (GetVolumeInformationW(wline, wline + 4, FILE_MAXDIR - 4, NULL, NULL, NULL, NULL, 0)) {
|
||||||
|
size_t label_len;
|
||||||
|
|
||||||
|
BLI_strncpy_wchar_as_utf8(line, wline + 4, FILE_MAXDIR - 4);
|
||||||
|
|
||||||
|
label_len = MIN2(strlen(line), FILE_MAXDIR - 6);
|
||||||
|
BLI_snprintf(line + label_len, 6, " (%.2s)", tmps);
|
||||||
|
|
||||||
|
name = line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, tmps, name, FS_INSERT_SORTED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adding Desktop and My Documents */
|
||||||
|
if (read_bookmarks) {
|
||||||
|
SHGetSpecialFolderPathW(0, wline, CSIDL_PERSONAL, 0);
|
||||||
|
BLI_strncpy_wchar_as_utf8(line, wline, FILE_MAXDIR);
|
||||||
|
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED);
|
||||||
|
SHGetSpecialFolderPathW(0, wline, CSIDL_DESKTOPDIRECTORY, 0);
|
||||||
|
BLI_strncpy_wchar_as_utf8(line, wline, FILE_MAXDIR);
|
||||||
|
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#ifdef __APPLE__
|
||||||
|
{
|
||||||
|
/* Get mounted volumes better method OSX 10.6 and higher, see: */
|
||||||
|
/*https://developer.apple.com/library/mac/#documentation/CoreFOundation/Reference/CFURLRef/Reference/reference.html*/
|
||||||
|
/* we get all volumes sorted including network and do not relay on user-defined finder visibility, less confusing */
|
||||||
|
|
||||||
|
CFURLRef cfURL = NULL;
|
||||||
|
CFURLEnumeratorResult result = kCFURLEnumeratorSuccess;
|
||||||
|
CFURLEnumeratorRef volEnum = CFURLEnumeratorCreateForMountedVolumes(NULL, kCFURLEnumeratorSkipInvisibles, NULL);
|
||||||
|
|
||||||
|
while (result != kCFURLEnumeratorEnd) {
|
||||||
|
unsigned char defPath[FILE_MAX];
|
||||||
|
|
||||||
|
result = CFURLEnumeratorGetNextURL(volEnum, &cfURL, NULL);
|
||||||
|
if (result != kCFURLEnumeratorSuccess)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CFURLGetFileSystemRepresentation(cfURL, false, (UInt8 *)defPath, FILE_MAX);
|
||||||
|
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, (char *)defPath, NULL, FS_INSERT_SORTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRelease(volEnum);
|
||||||
|
|
||||||
|
/* Finally get user favorite places */
|
||||||
|
if (read_bookmarks) {
|
||||||
|
UInt32 seed;
|
||||||
|
OSErr err = noErr;
|
||||||
|
CFArrayRef pathesArray;
|
||||||
|
LSSharedFileListRef list;
|
||||||
|
LSSharedFileListItemRef itemRef;
|
||||||
|
CFIndex i, pathesCount;
|
||||||
|
CFURLRef cfURL = NULL;
|
||||||
|
CFStringRef pathString = NULL;
|
||||||
|
list = LSSharedFileListCreate(NULL, kLSSharedFileListFavoriteItems, NULL);
|
||||||
|
pathesArray = LSSharedFileListCopySnapshot(list, &seed);
|
||||||
|
pathesCount = CFArrayGetCount(pathesArray);
|
||||||
|
|
||||||
|
for (i = 0; i < pathesCount; i++) {
|
||||||
|
itemRef = (LSSharedFileListItemRef)CFArrayGetValueAtIndex(pathesArray, i);
|
||||||
|
|
||||||
|
err = LSSharedFileListItemResolve(itemRef,
|
||||||
|
kLSSharedFileListNoUserInteraction |
|
||||||
|
kLSSharedFileListDoNotMountVolumes,
|
||||||
|
&cfURL, NULL);
|
||||||
|
if (err != noErr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pathString = CFURLCopyFileSystemPath(cfURL, kCFURLPOSIXPathStyle);
|
||||||
|
|
||||||
|
if (pathString == NULL || !CFStringGetCString(pathString, line, sizeof(line), kCFStringEncodingUTF8))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Exclude "all my files" as it makes no sense in blender fileselector */
|
||||||
|
/* Exclude "airdrop" if wlan not active as it would show "" ) */
|
||||||
|
if (!strstr(line, "myDocuments.cannedSearch") && (*line != '\0')) {
|
||||||
|
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_LAST);
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRelease(pathString);
|
||||||
|
CFRelease(cfURL);
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRelease(pathesArray);
|
||||||
|
CFRelease(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* unix */
|
||||||
|
{
|
||||||
|
const char* home = getenv("HOME");
|
||||||
|
|
||||||
|
if (home)
|
||||||
|
{
|
||||||
|
ret.push_back(home);
|
||||||
|
std::string desktop(home);
|
||||||
|
desktop += "/Desktop";
|
||||||
|
if (!HECL::Stat(desktop.c_str(), &theStat))
|
||||||
|
ret.push_back(std::move(desktop));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
#ifdef __linux__
|
||||||
|
/* Loop over mount points */
|
||||||
|
struct mntent *mnt;
|
||||||
|
|
||||||
|
FILE* fp = setmntent(MOUNTED, "r");
|
||||||
|
if (fp)
|
||||||
|
{
|
||||||
|
while ((mnt = getmntent(fp)))
|
||||||
|
{
|
||||||
|
if (strlen(mnt->mnt_fsname) < 4 || strncmp(mnt->mnt_fsname, "/dev", 4))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
std::string mntStr(mnt->mnt_dir);
|
||||||
|
if (mntStr.size() > 1 && mntStr.back() == '/')
|
||||||
|
mntStr.pop_back();
|
||||||
|
ret.push_back(std::move(mntStr));
|
||||||
|
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
endmntent(fp);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* Fallback */
|
||||||
|
if (!found)
|
||||||
|
ret.push_back("/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue