Skip to content
This repository has been archived by the owner on Sep 2, 2021. It is now read-only.

Commit

Permalink
Merge pull request #680 from niteskum/niteskum/CherryPickFromMaster
Browse files Browse the repository at this point in the history
Merge pull request #677 from niteskum/graphicsFileExternalApplication
  • Loading branch information
narayani28 authored Mar 24, 2020
2 parents 5f03d51 + 3532759 commit 6cac7a9
Show file tree
Hide file tree
Showing 6 changed files with 269 additions and 0 deletions.
17 changes: 17 additions & 0 deletions appshell/appshell_extensions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,23 @@ class ProcessMessageDelegate : public ClientHandler::ProcessMessageDelegate {
responseArgs->SetInt(2, port);
}

} else if (message_name == "getSystemDefaultApp") {
// Parameters:
// 0: int32 - callback id
// 1: string - list of file extensions
if (argList->GetSize() != 2 ||
argList->GetType(1) != VTYPE_STRING) {
error = ERR_INVALID_PARAMS;
}

ExtensionString defaultApp;
if (error == NO_ERROR) {
error = getSystemDefaultApp(argList->GetString(1), defaultApp);
}

// Set response args for this function
responseArgs->SetString(2, defaultApp);

} else if (message_name == "QuitApplication") {
// Parameters - none

Expand Down
20 changes: 20 additions & 0 deletions appshell/appshell_extensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,26 @@ if (!brackets) {
}, path);
};

/**
* Checks If fileytype has assigned system default app
*
* @param {string} filetypes list of file Types for which deafult app to checked.
* @param {function(err)} callback Asynchronous callback function. The callback gets two arguments
* (filetypes, err)
* filetypes which has system default app assigned.
*
* Possible error values:
* NO_ERROR
* ERR_INVALID_PARAMS
* ERR_NOT_FOUND
*
* @return None. This is an asynchronous call that sends all return information to the callback.
*/
native function getSystemDefaultApp();
appshell.app.getSystemDefaultApp = function (filetypes, callback) {
getSystemDefaultApp(callback || _dummyCallback, filetypes);
};

/**
* Quits native shell application
*/
Expand Down
5 changes: 5 additions & 0 deletions appshell/appshell_extensions_gtk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,11 @@ int32 OpenURLInDefaultBrowser(ExtensionString url)
return NO_ERROR;
}

int32 getSystemDefaultApp(const ExtensionString& fileTypes, ExtensionString& fileTypesWithdefaultApp)
{
return NO_ERROR;
}

int32 IsNetworkDrive(ExtensionString path, bool& isRemote)
{
return NO_ERROR;
Expand Down
56 changes: 56 additions & 0 deletions appshell/appshell_extensions_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,62 @@ void CloseLiveBrowser(CefRefPtr<CefBrowser> browser, CefRefPtr<CefProcessMessage
);
}

int32 getSystemDefaultApp(const ExtensionString& fileTypes, ExtensionString& fileTypesWithdefaultApp)
{

char delim[] = ",";
char separator[] = "##";
std::vector<ExtensionString> extArray;
char* token = std::strtok((char*)fileTypes.c_str(), delim);
while (token) {
extArray.push_back(token);
token = std::strtok(NULL, delim);
}

for (std::vector<ExtensionString>::const_iterator it = extArray.begin(); it != extArray.end(); ++it)
{
ExtensionString appPath;

CFStringRef contentType = CFStringCreateWithCString (NULL, (*it).c_str(), kCFStringEncodingUTF8);

if(!contentType)
continue;

CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension,
contentType,
NULL);
if(UTI)
{
CFURLRef bundle_id;

bundle_id = LSCopyDefaultApplicationURLForContentType(UTI, kLSRolesEditor, NULL);

if(bundle_id)
{
NSBundle *bundle = [NSBundle bundleWithURL: (NSURL*)bundle_id];

if (bundle)
{
appPath = [(NSString *)[bundle objectForInfoDictionaryKey: @"CFBundleExecutable"] cStringUsingEncoding:NSUTF8StringEncoding];
}

fileTypesWithdefaultApp = fileTypesWithdefaultApp + *it + separator + appPath + ",";

CFRelease(bundle_id);
}

CFRelease(UTI);
}

CFRelease(contentType);
}

return NO_ERROR;
}




int32 OpenURLInDefaultBrowser(ExtensionString url)
{
NSString* urlString = [NSString stringWithUTF8String:url.c_str()];
Expand Down
2 changes: 2 additions & 0 deletions appshell/appshell_extensions_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ void MoveFileOrDirectoryToTrash(ExtensionString filename, CefRefPtr<CefBrowser>

int32 CopyFile(ExtensionString src, ExtensionString dest);

int32 getSystemDefaultApp(const ExtensionString& fileTypes, ExtensionString& fileTypesWithdefaultApp);

int32 GetNodeState(int32& state);

void OnBeforeShutdown();
Expand Down
169 changes: 169 additions & 0 deletions appshell/appshell_extensions_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,175 @@ void CloseLiveBrowser(CefRefPtr<CefBrowser> browser, CefRefPtr<CefProcessMessage
}
}


static BOOL ResolveAppPathCommon(const ExtensionString& lpszKey, const ExtensionString& lpszVal, ExtensionString& appPath)
{
HKEY keyRoot = NULL;
BOOL result = FALSE;
ULONG regKey(REG_SZ);

if (::RegOpenKeyEx(HKEY_CLASSES_ROOT, lpszKey.c_str(), 0, KEY_QUERY_VALUE, &keyRoot) == ERROR_SUCCESS)
{
TCHAR editorPath[255];
ULONG fTypeSize = 255;

if (::RegQueryValueEx(keyRoot, lpszVal.c_str(), NULL, &regKey, (LPBYTE)editorPath, &fTypeSize) == ERROR_SUCCESS)
{
if (editorPath != L"")
{
appPath = editorPath;
//appPath = appPath.substr(appPath.find_last_of(L"/\\") + 1);
int iExe = appPath.find(L".exe");
if (iExe == -1)
iExe = appPath.find(L".EXE");
if (iExe != -1)
appPath = appPath.substr(0, iExe+4);

if (appPath[0] == '\"')
appPath = appPath.substr(1);

result = TRUE;
}


}
::RegCloseKey(keyRoot);
}

return result;

}

static BOOL ResolveAppPathFromProgID(const ExtensionString& lpszProgID, ExtensionString& appPath)
{

ExtensionString key = lpszProgID + L"\\shell\\open\\command";


if (!ResolveAppPathCommon(key, L"", appPath))
{
key = lpszProgID + L"\\Application";
if (ResolveAppPathCommon(key, L"AppUserModelID", appPath)) {
appPath = appPath.substr(0, appPath.find(L"_"));
return true;
}
return false;
}
return true;

}

BOOL GetShellDefaultOpenWithProgPath(const ExtensionString& fileExt, ExtensionString &appPath)
{
HKEY extKey = NULL;
ExtensionString key = fileExt;
BOOL result = FALSE;
ULONG regKey(REG_SZ);

if (fileExt.empty())
return false;

if (fileExt[0] != '.')
key = L"." + fileExt;

key = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\" + key + L"\\UserChoice";

if (::RegOpenKeyEx(HKEY_CURRENT_USER, key.c_str(), 0, KEY_QUERY_VALUE, &extKey) == ERROR_SUCCESS)
{
TCHAR editorPath[255];
ULONG fTypeSize = 255;

if (::RegQueryValueEx(extKey, L"Progid", NULL, &regKey, (LPBYTE)editorPath, &fTypeSize) == ERROR_SUCCESS)
{
result = ResolveAppPathFromProgID(editorPath, appPath);

}

::RegCloseKey(extKey);
}

return result;
}


BOOL GetLegacyWin32SystemEditor(const ExtensionString& fileExt, ExtensionString &appPath)
{
HKEY rootKey;
ULONG regKey(REG_SZ);
ExtensionString key = fileExt;

if (fileExt.empty())
return false;

if (fileExt[0] != '.')
key = L"." + key;

// find the key for the file extension
if (RegOpenKeyEx(HKEY_CLASSES_ROOT, key.c_str(), 0, KEY_QUERY_VALUE, &rootKey) == ERROR_SUCCESS)
{
TCHAR nextKeyStr[255];
ULONG strSize = 255;
// get the value of the key
if (RegQueryValueEx(rootKey, L"", NULL, &regKey,
(LPBYTE)nextKeyStr, &strSize) == ERROR_SUCCESS)
{
RegCloseKey(rootKey);
return ResolveAppPathFromProgID(nextKeyStr, appPath);
}
RegCloseKey(rootKey);
}

key = key + L"\\OpenWithProgids";
HKEY extKey;
// find the key for the file extension
if (RegOpenKeyEx(HKEY_CLASSES_ROOT, key.c_str(), 0, KEY_QUERY_VALUE | KEY_READ, &extKey) == ERROR_SUCCESS)
{
TCHAR subKeyStr[255];
ULONG subKeySize = 255;
DWORD index = 0;
LONG err = RegEnumValue(extKey, index, subKeyStr, &subKeySize,
0, 0, 0, NULL);
if (err != ERROR_NO_MORE_ITEMS)
{
RegCloseKey(extKey);
return ResolveAppPathFromProgID(subKeyStr, appPath);
}

RegCloseKey(extKey);
}

return FALSE;
}

int32 getSystemDefaultApp(const ExtensionString& fileTypes, ExtensionString& fileTypesWithdefaultApp)
{
wchar_t* nextPtr;
wchar_t delim[] = L",";
std::vector<ExtensionString> extArray;
ExtensionString separator = L"##";

wchar_t* token = std::wcstok((wchar_t*)fileTypes.c_str(), delim, &nextPtr);

while (token) {
extArray.push_back(token);
token = wcstok(NULL, delim, &nextPtr);
}

for (std::vector<ExtensionString>::const_iterator it = extArray.begin(); it != extArray.end(); ++it) {
ExtensionString appPath;
BOOL result = GetShellDefaultOpenWithProgPath(*it, appPath);

if (!result)
result = GetLegacyWin32SystemEditor(*it, appPath);

if (result)
fileTypesWithdefaultApp = fileTypesWithdefaultApp + *it + separator + appPath + L",";
}

return NO_ERROR;

}

int32 OpenURLInDefaultBrowser(ExtensionString url)
{
DWORD result = (DWORD)ShellExecute(NULL, L"open", url.c_str(), NULL, NULL, SW_SHOWNORMAL);
Expand Down

0 comments on commit 6cac7a9

Please sign in to comment.