mirror of https://github.com/buggins/dlangui.git
commit
2f39fd8891
|
@ -27,6 +27,12 @@
|
|||
"subConfigurations" : {
|
||||
"dlangui" : "sdl"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name" : "minimal",
|
||||
"subConfigurations" : {
|
||||
"dlangui" : "minimal"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -427,7 +427,7 @@ RootEntry[] getBookmarkPaths() nothrow
|
|||
|
||||
string linksFolder = linksFolderZ[0..wcslen(linksFolderZ)].toUTF8;
|
||||
|
||||
CoInitialize(null);
|
||||
enforce(SUCCEEDED(CoInitialize(null)));
|
||||
scope(exit) CoUninitialize();
|
||||
|
||||
HRESULT hres;
|
||||
|
@ -435,7 +435,7 @@ RootEntry[] getBookmarkPaths() nothrow
|
|||
|
||||
auto clsidShellLink = CLSID_ShellLink;
|
||||
auto iidShellLink = IID_IShellLinkW;
|
||||
hres = CoCreateInstance(&clsidShellLink, null, CLSCTX_INPROC, &iidShellLink, cast(LPVOID*)&psl);
|
||||
hres = CoCreateInstance(&clsidShellLink, null, CLSCTX.CLSCTX_INPROC_SERVER, &iidShellLink, cast(LPVOID*)&psl);
|
||||
enforce(SUCCEEDED(hres), "Failed to create IShellLink instance");
|
||||
scope(exit) psl.Release();
|
||||
|
||||
|
@ -456,7 +456,7 @@ RootEntry[] getBookmarkPaths() nothrow
|
|||
hres = ppf.Load(linkFile.name.toUTF16z, STGM_READ);
|
||||
enforce(SUCCEEDED(hres), "Failed to load link file");
|
||||
|
||||
hres = psl.Resolve(null, 0);
|
||||
hres = psl.Resolve(null, SLR_FLAGS.SLR_NO_UI);
|
||||
enforce(SUCCEEDED(hres), "Failed to resolve link");
|
||||
|
||||
hres = psl.GetPath(szGotPath.ptr, szGotPath.length, &wfd, 0);
|
||||
|
@ -464,7 +464,7 @@ RootEntry[] getBookmarkPaths() nothrow
|
|||
|
||||
auto path = szGotPath[0..wcslen(szGotPath.ptr)];
|
||||
|
||||
if (path.length) {
|
||||
if (path.length && path.isDir) {
|
||||
res ~= RootEntry(RootEntryType.BOOKMARK, path.toUTF8, linkFile.name.baseName.stripExtension.toUTF32);
|
||||
}
|
||||
} catch(Exception e) {
|
||||
|
|
|
@ -1277,14 +1277,14 @@ class SDLPlatform : Platform {
|
|||
return toReturn.data;
|
||||
}
|
||||
|
||||
static auto unescapeExecArgument(string arg) nothrow pure
|
||||
static auto unescapeValue(string arg) nothrow pure
|
||||
{
|
||||
static immutable Tuple!(char, char)[] pairs = [
|
||||
tuple('s', ' '), tuple('n', '\n'), tuple('r', '\r'), tuple('t', '\t'),
|
||||
tuple('"', '"'), tuple('\'', '\''), tuple('\\', '\\'), tuple('>', '>'),
|
||||
tuple('<', '<'), tuple('~', '~'), tuple('|', '|'), tuple('&', '&'),
|
||||
tuple(';', ';'), tuple('$', '$'), tuple('*', '*'), tuple('?', '?'),
|
||||
tuple('#', '#'), tuple('(', '('), tuple(')', ')'), tuple('`', '`')
|
||||
tuple('s', ' '),
|
||||
tuple('n', '\n'),
|
||||
tuple('r', '\r'),
|
||||
tuple('t', '\t'),
|
||||
tuple('\\', '\\')
|
||||
];
|
||||
return doUnescape(arg, pairs);
|
||||
}
|
||||
|
@ -1292,7 +1292,10 @@ class SDLPlatform : Platform {
|
|||
static string unescapeQuotedArgument(string value) nothrow pure
|
||||
{
|
||||
static immutable Tuple!(char, char)[] pairs = [
|
||||
tuple('`', '`'), tuple('$', '$'), tuple('"', '"'), tuple('\\', '\\')
|
||||
tuple('`', '`'),
|
||||
tuple('$', '$'),
|
||||
tuple('"', '"'),
|
||||
tuple('\\', '\\')
|
||||
];
|
||||
return doUnescape(value, pairs);
|
||||
}
|
||||
|
@ -1345,7 +1348,7 @@ class SDLPlatform : Platform {
|
|||
|
||||
static string[] parseExecString(string execString) pure
|
||||
{
|
||||
return unquoteExecString(execString).map!(unescapeExecArgument).array;
|
||||
return unquoteExecString(execString).map!(unescapeValue).array;
|
||||
}
|
||||
|
||||
static string[] expandExecArgs(in string[] execArgs, in string[] urls = null, string iconName = null, string name = null, string fileName = null) pure
|
||||
|
@ -1411,6 +1414,39 @@ class SDLPlatform : Platform {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static void parseConfigFile(string fileName, string wantedGroup, bool delegate (in char[], in char[]) onKeyValue)
|
||||
{
|
||||
bool inNeededGroup;
|
||||
foreach(line; File(fileName).byLine()) {
|
||||
if (!line.length || line[0] == '#') {
|
||||
continue;
|
||||
} else if (line[0] == '[') {
|
||||
if (line.equal(wantedGroup)) {
|
||||
inNeededGroup = true;
|
||||
} else {
|
||||
if (inNeededGroup) {
|
||||
break;
|
||||
}
|
||||
inNeededGroup = false;
|
||||
}
|
||||
} else if (line[0].isAlpha) {
|
||||
if (inNeededGroup) {
|
||||
auto splitted = findSplit(line, "=");
|
||||
if (splitted[1].length) {
|
||||
auto key = splitted[0];
|
||||
auto value = splitted[2];
|
||||
if (!onKeyValue(key, value)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//unexpected line content
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static string[] findFileManagerCommand(string app, const(string)[] appDirs, const(string)[] binPaths) nothrow
|
||||
{
|
||||
|
@ -1429,54 +1465,28 @@ class SDLPlatform : Platform {
|
|||
|
||||
if (fileExists) {
|
||||
try {
|
||||
bool inDesktopEntry;
|
||||
bool canOpenDirectory; //not used for now. Some file managers does not have MimeType in their .desktop file.
|
||||
string exec;
|
||||
string tryExec;
|
||||
|
||||
foreach(line; File(appPath).byLine()) {
|
||||
if (exec.length || tryExec.length) {
|
||||
break;
|
||||
parseConfigFile(appPath, "[Desktop Entry]", delegate bool(in char[] key, in char[] value) {
|
||||
if (key.equal("MimeType")) {
|
||||
canOpenDirectory = value.splitter(';').canFind("inode/directory");
|
||||
} else if (key.equal("Exec")) {
|
||||
exec = value.idup;
|
||||
} else if (key.equal("TryExec")) {
|
||||
tryExec = value.idup;
|
||||
}
|
||||
if (!line.length || line[0] == '#') {
|
||||
continue;
|
||||
} else if (line[0] == '[') {
|
||||
if (line.equal("[Desktop Entry]")) {
|
||||
inDesktopEntry = true;
|
||||
} else {
|
||||
if (inDesktopEntry) {
|
||||
break;
|
||||
}
|
||||
inDesktopEntry = false;
|
||||
}
|
||||
} else if (line[0].isAlpha) {
|
||||
if (inDesktopEntry) {
|
||||
auto splitted = findSplit(line, "=");
|
||||
if (splitted[1].length) {
|
||||
auto key = splitted[0];
|
||||
auto value = splitted[2];
|
||||
if (key.equal("MimeType")) {
|
||||
canOpenDirectory = value.splitter(';').canFind("inode/directory");
|
||||
} else if (key.equal("Exec")) {
|
||||
exec = value.idup;
|
||||
} else if (key.equal("TryExec")) {
|
||||
tryExec = value.idup;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//unexpected line content
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
if (tryExec.length) {
|
||||
auto program = findExecutable(tryExec, binPaths);
|
||||
if (program.length) {
|
||||
return [program];
|
||||
}
|
||||
}
|
||||
if (exec.length) {
|
||||
if (tryExec.length) {
|
||||
auto program = findExecutable(tryExec, binPaths);
|
||||
if (!program.length) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return expandExecArgs(parseExecString(exec));
|
||||
}
|
||||
|
||||
|
@ -1544,95 +1554,60 @@ class SDLPlatform : Platform {
|
|||
string appHome = environment.get("XDG_DATA_HOME", buildPath(environment.get("HOME"), ".local/share")).buildPath("applications");
|
||||
|
||||
auto configDirs = environment.get("XDG_CONFIG_DIRS", "/etc/xdg").splitter(':').find!(p => p.length > 0);
|
||||
auto appDirs = environment.get("XDG_DATA_DIRS", "/usr/local/share:/usr/share").splitter(':').find!(p => p.length > 0).map!(p => buildPath(p, "applications"));
|
||||
auto appDirs = environment.get("XDG_DATA_DIRS", "/usr/local/share:/usr/share").splitter(':').filter!(p => p.length > 0).map!(p => buildPath(p, "applications"));
|
||||
|
||||
auto allAppDirs = chain(only(appHome), appDirs).array;
|
||||
auto binPaths = environment.get("PATH").splitter(':').find!(p => p.length > 0).array;
|
||||
auto binPaths = environment.get("PATH").splitter(':').filter!(p => p.length > 0).array;
|
||||
|
||||
string[] fileManagerArgs;
|
||||
foreach(mimeappsList; chain(only(configHome), only(appHome), configDirs, appDirs).map!(p => buildPath(p, "mimeapps.list"))) {
|
||||
try {
|
||||
bool inDefaultApps;
|
||||
foreach(line; File(mimeappsList).byLine()) {
|
||||
if (!line.length || line[0] == '#') {
|
||||
continue;
|
||||
} else if (line[0] == '[') {
|
||||
if (line.equal("[Default Applications]")) {
|
||||
inDefaultApps = true;
|
||||
} else {
|
||||
if (inDefaultApps) {
|
||||
break;
|
||||
}
|
||||
inDefaultApps = false;
|
||||
}
|
||||
} else if (line[0].isAlpha) {
|
||||
if (inDefaultApps) {
|
||||
auto keyValue = findSplit(line, "=");
|
||||
auto key = keyValue[0];
|
||||
auto value = keyValue[2];
|
||||
if (keyValue[1].length && key.equal("inode/directory") && value.length) {
|
||||
auto app = value.idup;
|
||||
auto fileManagerArgs = findFileManagerCommand(app, allAppDirs, binPaths);
|
||||
|
||||
if (fileManagerArgs.length) {
|
||||
execShowInFileManager(fileManagerArgs, toOpen);
|
||||
return true;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//unexpected line content
|
||||
break;
|
||||
parseConfigFile(mimeappsList, "[Default Applications]", delegate bool(in char[] key, in char[] value) {
|
||||
if (key.equal("inode/directory") && value.length) {
|
||||
auto app = value.idup;
|
||||
fileManagerArgs = findFileManagerCommand(app, allAppDirs, binPaths);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
} catch(Exception e) {
|
||||
|
||||
}
|
||||
|
||||
if (fileManagerArgs.length) {
|
||||
execShowInFileManager(fileManagerArgs, toOpen);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach(mimeinfoCache; allAppDirs.map!(p => buildPath(p, "mimeinfo.cache"))) {
|
||||
try {
|
||||
bool inMimeCache;
|
||||
foreach(line; File(mimeinfoCache).byLine()) {
|
||||
if (!line.length || line[0] == '#') {
|
||||
continue;
|
||||
} else if (line[0] == '[') {
|
||||
if (line.equal("[MIME Cache]")) {
|
||||
inMimeCache = true;
|
||||
} else {
|
||||
if (inMimeCache) {
|
||||
break;
|
||||
}
|
||||
inMimeCache = false;
|
||||
}
|
||||
} else if (line[0].isAlpha) {
|
||||
if (inMimeCache) {
|
||||
auto keyValue = findSplit(line, "=");
|
||||
auto key = keyValue[0];
|
||||
auto value = keyValue[2];
|
||||
if (keyValue[1].length && key.equal("inode/directory") && value.length) {
|
||||
auto alternatives = value.splitter(';').filter!(p => p.length > 0);
|
||||
foreach(alternative; alternatives) {
|
||||
auto fileManagerArgs = findFileManagerCommand(alternative.idup, allAppDirs, binPaths);
|
||||
if (fileManagerArgs.length) {
|
||||
execShowInFileManager(fileManagerArgs, toOpen);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//unexpected line content
|
||||
break;
|
||||
parseConfigFile(mimeinfoCache, "[MIME Cache]", delegate bool(in char[] key, in char[] value) {
|
||||
if (key > "inode/directory") { //no need to proceed, since MIME types are sorted in alphabetical order.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (key.equal("inode/directory") && value.length) {
|
||||
auto alternatives = value.splitter(';').filter!(p => p.length > 0);
|
||||
foreach(alternative; alternatives) {
|
||||
fileManagerArgs = findFileManagerCommand(alternative.idup, allAppDirs, binPaths);
|
||||
if (fileManagerArgs.length) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
} catch(Exception e) {
|
||||
|
||||
}
|
||||
|
||||
if (fileManagerArgs.length) {
|
||||
execShowInFileManager(fileManagerArgs, toOpen);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Log.e("showInFileManager -- could not find application to open directory");
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue