Bazaar/Updater : added Windows shell install -- still unbuilt

git-svn-id: svn://ultimatepp.org/upp/trunk@3024 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
micio 2011-01-16 23:10:39 +00:00
parent 16cc1bc8d1
commit 643081eb12
5 changed files with 290 additions and 143 deletions

138
bazaar/Updater/Posix.cpp Normal file
View file

@ -0,0 +1,138 @@
#include "Updater.h"
#ifdef PLATFORM_POSIX
// scans for theme folders on which put/delete the mimetype icons
// that's needed because if themed icons aren't available, the system
// uses fallback ones instead of going through hicolor ones
// btw...that must be some ill-brained people there
// the routine builds a list of folders containing 32x32 icons
// it would be of course better with svg, but Upp don't support them
Vector<String>Updater::ScanTheme(void)
{
// gathers all subfolders of /usr/share/icons that contains 32x32 subfolder
Vector<String>subFolders;
FindFile ff("/usr/share/icons/*");
while(ff)
{
if(
ff.IsFolder() &&
ff.GetName() != "." &&
ff.GetName() != ".." &&
DirectoryExists("/usr/share/icons/" + ff.GetName() + "/32x32/")
)
subFolders.Add("/usr/share/icons/" + ff.GetName() + "/");
ff.Next();
}
return subFolders;
}
// save an image as png inside multiple theme folders
// retrieved with ScanTheme
void Updater::InstallThemeIcons(Image const &img, String const &name)
{
Vector<String>folders = ScanTheme();
String imgs = PNGEncoder().SaveString(img);
for(int i = 0; i < folders.GetCount(); i++)
{
SaveFile(folders[i] + "32x32/mimetypes/" + name + ".png", imgs);
SysStart("gtk-update-icon-cache", "--quiet " + folders[i]);
}
}
// deletes all icons with given name inside folders retrieved with ScanTheme
void Updater::RemoveThemeIcons(String const &name)
{
Vector<String>folders = ScanTheme();
for(int i = 0; i < folders.GetCount(); i++)
{
FileDelete(folders[i] + "32x32/mimetypes/" + name + ".png");
SysStart("gtk-update-icon-cache", "--quiet " + folders[i]);
}
}
// links application to OS shell
// (i.e., add icon, menu entry, mimetype....)
bool Updater::ShellLink(void)
{
bool success = true;
// build desktop file
String desktop =
"[Desktop Entry]\n"
"Type=Application\n"
"Encoding=UTF-8\n"
;
desktop += "Name=" + appName + "\n";
if(comment != "")
desktop += "Comment=" + comment + "\n";
if(cathegory != "")
desktop += "Categories=" + cathegory + "\n";
desktop += "Exec=" + appName + " %f\n";
if(!IsNull(icon))
desktop += "Icon=" + appName + "\n";
desktop += "MimeType=application/x-" + appName + ";\n";
desktop += "Terminal=false\n";
// stores desktop file in global applications folder
success = SaveFile("/usr/share/applications/" + appName + ".desktop", desktop);
// places icon in /usr/share/icons/hicolor/32x32/apps
// maybe we should look for some better handling of icons...
// by now, we support only 32x32 ones in default theme
if(!IsNull(icon))
{
success &= PNGEncoder().SaveFile("/usr/share/icons/hicolor/32x32/apps/" + appName + ".png", icon);
InstallThemeIcons(icon, "application-x-" + appName);
}
// add mime type for supported extensions
String mime =
"<?xml version=\"1.0\"?>\n"
"<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>\n"
"<mime-type type=\"application/x-" + appName + "\">\n";
if(comment != "")
mime += "<comment>" + comment + "</comment>\n";
for(int i = 0; i < extensions.GetCount(); i++)
mime += "<glob pattern=\"" + extensions[i] + "\"/>\n";
mime +=
"</mime-type>\n"
"</mime-info>\n"
;
success &= SaveFile("/usr/share/mime/packages/" + appName + ".xml", mime);
success &= (SysStart("update-mime-database", "/usr/share/mime") != -1);
// updates desktop database to make it sense the changes in mimetype and application
success &= (SysStart("update-desktop-database", "") != -1);
return success;
}
// unlinks application
bool Updater::ShellUnlink(void)
{
bool success = true;
// remove desktop file
FileDelete("/usr/share/applications/" + appName + ".desktop");
// remove icon
bool appIcon = FileExists("/usr/share/icons/hicolor/32x32/apps/" + appName + ".png");
if(appIcon)
FileDelete("/usr/share/icons/hicolor/32x32/apps/" + appName + ".png");
RemoveThemeIcons("application-x-" + appName);
if(FileExists("/usr/share/mime/packages/" + appName + ".xml"))
{
FileDelete("/usr/share/mime/packages/" + appName + ".xml");
SysStart("update-mime-database", "/usr/share/mime");
}
// updates desktop database to make it sense the changes in mimetype and application
SysStart("update-desktop-database", "");
return success;
}
#endif

View file

@ -116,6 +116,9 @@ Updater::Updater()
// sets default confirm for install and uninstall
confirmInstall = true;
confirmUninstall = true;
// no desktop icon installation by default
desktopIcon = false;
}
///////////////////////////////////////////////////////////////////////////////////////
@ -718,146 +721,3 @@ Image Updater::DefaultIcon(void)
{
return UpdaterImg::DefaultIcon();
}
// scans for theme folders on which put/delete the mimetype icons
// that's needed because if themed icons aren't available, the system
// uses fallback ones instead of going through hicolor ones
// btw...that must be some ill-brained people there
// the routine builds a list of folders containing 32x32 icons
// it would be of course better with svg, but Upp don't support them
Vector<String>Updater::ScanTheme(void)
{
// gathers all subfolders of /usr/share/icons that contains 32x32 subfolder
Vector<String>subFolders;
FindFile ff("/usr/share/icons/*");
while(ff)
{
if(
ff.IsFolder() &&
ff.GetName() != "." &&
ff.GetName() != ".." &&
DirectoryExists("/usr/share/icons/" + ff.GetName() + "/32x32/")
)
subFolders.Add("/usr/share/icons/" + ff.GetName() + "/");
ff.Next();
}
return subFolders;
}
// save an image as png inside multiple theme folders
// retrieved with ScanTheme
void Updater::InstallThemeIcons(Image const &img, String const &name)
{
Vector<String>folders = ScanTheme();
String imgs = PNGEncoder().SaveString(img);
for(int i = 0; i < folders.GetCount(); i++)
{
SaveFile(folders[i] + "32x32/mimetypes/" + name + ".png", imgs);
SysStart("gtk-update-icon-cache", "--quiet " + folders[i]);
}
}
// deletes all icons with given name inside folders retrieved with ScanTheme
void Updater::RemoveThemeIcons(String const &name)
{
Vector<String>folders = ScanTheme();
for(int i = 0; i < folders.GetCount(); i++)
{
FileDelete(folders[i] + "32x32/mimetypes/" + name + ".png");
SysStart("gtk-update-icon-cache", "--quiet " + folders[i]);
}
}
// links application to OS shell
// (i.e., add icon, menu entry, mimetype....)
bool Updater::ShellLink(void)
{
bool success = true;
#ifdef PLATFORM_POSIX
// build desktop file
String desktop =
"[Desktop Entry]\n"
"Type=Application\n"
"Encoding=UTF-8\n"
;
desktop += "Name=" + appName + "\n";
if(comment != "")
desktop += "Comment=" + comment + "\n";
if(cathegory != "")
desktop += "Categories=" + cathegory + "\n";
desktop += "Exec=" + appName + " %f\n";
if(!IsNull(icon))
desktop += "Icon=" + appName + "\n";
desktop += "MimeType=application/x-" + appName + ";\n";
desktop += "Terminal=false\n";
// stores desktop file in global applications folder
success = SaveFile("/usr/share/applications/" + appName + ".desktop", desktop);
// places icon in /usr/share/icons/hicolor/32x32/apps
// maybe we should look for some better handling of icons...
// by now, we support only 32x32 ones in default theme
if(!IsNull(icon))
{
success &= PNGEncoder().SaveFile("/usr/share/icons/hicolor/32x32/apps/" + appName + ".png", icon);
InstallThemeIcons(icon, "application-x-" + appName);
}
// add mime type for supported extensions
String mime =
"<?xml version=\"1.0\"?>\n"
"<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>\n"
"<mime-type type=\"application/x-" + appName + "\">\n";
if(comment != "")
mime += "<comment>" + comment + "</comment>\n";
for(int i = 0; i < extensions.GetCount(); i++)
mime += "<glob pattern=\"" + extensions[i] + "\"/>\n";
mime +=
"</mime-type>\n"
"</mime-info>\n"
;
success &= SaveFile("/usr/share/mime/packages/" + appName + ".xml", mime);
success &= (SysStart("update-mime-database", "/usr/share/mime") != -1);
// updates desktop database to make it sense the changes in mimetype and application
success &= (SysStart("update-desktop-database", "") != -1);
#else
#endif
return success;
}
// unlinks application
bool Updater::ShellUnlink(void)
{
bool success = true;
#ifdef PLATFORM_POSIX
// remove desktop file
FileDelete("/usr/share/applications/" + appName + ".desktop");
// remove icon
bool appIcon = FileExists("/usr/share/icons/hicolor/32x32/apps/" + appName + ".png");
if(appIcon)
FileDelete("/usr/share/icons/hicolor/32x32/apps/" + appName + ".png");
RemoveThemeIcons("application-x-" + appName);
if(FileExists("/usr/share/mime/packages/" + appName + ".xml"))
{
FileDelete("/usr/share/mime/packages/" + appName + ".xml");
SysStart("update-mime-database", "/usr/share/mime");
}
// updates desktop database to make it sense the changes in mimetype and application
SysStart("update-desktop-database", "");
#else
#endif
return success;
}

View file

@ -162,6 +162,10 @@ class Updater
Vector<String> extensions;
String comment;
// flag for desktop icon install
bool desktopIcon;
#ifdef PLATFORM_POSIX
// scans for theme folders on which put/delete the mimetype icons
// that's needed because if themed icons aren't available, the system
// uses fallback ones instead of going through hicolor ones
@ -176,6 +180,7 @@ class Updater
// deletes all icons with given name inside folders retrieved with ScanTheme
void RemoveThemeIcons(String const &name);
#endif
// links application to OS shell
// (i.e., add icon, menu entry, mimetype....)
@ -247,6 +252,10 @@ class Updater
// setup application comment
Updater &SetComment(String const &c) { comment = c; return *this; }
// desktop icon
Updater &DesktopIcon(void) { desktopIcon = true; return *this; }
Updater &NoDesktopIcon(void) { desktopIcon = false; return *this; }
};

View file

@ -7,6 +7,8 @@ uses
file
Updater.iml,
Windows.cpp,
Posix.cpp,
Updater.h,
Updater.cpp;

138
bazaar/Updater/Windows.cpp Normal file
View file

@ -0,0 +1,138 @@
#include "Updater.h"
#ifdef PLATFORM_WIN32
#define Ptr Ptr_
#define byte byte_
#define CY win32_CY_
#include <winnls.h>
#include <winnetwk.h>
#include <wincon.h>
#include <shlobj.h>
#undef Ptr
#undef byte
#undef CY
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ò
String GetShellFolder(const char *name, HKEY type)
{
return GetWinRegString(name, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", type);
}
void DelKey(const char *dir, const char *key)
{
HKEY hkey;
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &hkey) != ERROR_SUCCESS)
return;
RegDeleteKey(hkey, key);
RegCloseKey(hkey);
}
bool CreateShellLink(const char *filepath, const char *linkpath, const char *desc, int icon)
{
HRESULT hres;
IShellLink* psl;
IPersistFile* ppf;
CoInitialize(NULL);
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (PVOID *) &psl);
if(SUCCEEDED(hres))
{
psl->SetPath(filepath);
psl->SetDescription(desc);
if(icon >= 0)
psl->SetIconLocation(filepath, icon);
hres = psl->QueryInterface(IID_IPersistFile, (PVOID *) &ppf);
if (SUCCEEDED(hres))
{
WCHAR szPath[_MAX_PATH] = { 0 };
MultiByteToWideChar(CP_ACP, 0, linkpath, (int)strlen(linkpath), szPath, _MAX_PATH);
hres = ppf->Save(szPath, TRUE);
ppf->Release();
}
}
psl->Release();
CoUninitialize();
return SUCCEEDED(hres);
}
// links application to OS shell
// (i.e., add icon, menu entry, mimetype....)
bool Updater::ShellLink(void)
{
bool success = true;
String exePath = GetProgramsFolder() + "/" + appName + "/" + appName + ".exe";
String linkName = appName + ".lnk";
// installs desktop icon
if(desktopIcon)
{
String desktopPath = GetShellFolder("Desktop", HKEY_USERS);
CreateShellLink(exePath, AppendFileName(desktopPath, linkName), comment, -1);
}
// installs program group
// we could use "cathegory" to create a menu group... but I don't
// know how internationalize it. On ubuntu is automatic.
// maybe we could add it later
String groupName = ""; // that could be GetLNGString(cathegory) ????
String groupFolder = GetShellFolder("Common Programs", HKEY_LOCAL_MACHINE);
if(groupName != "")
{
groupFolder = AppendFileName(groupFolder, groupName);
CreateDirectory(groupFolder, NULL);
}
CreateShellLink(exePath, AppendFileName(groupFolder, linkName), comment, -1);
// installs uninstaller
String uninstallRegPath = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + appName;
SetWinRegString(appName, "DisplayName", uninstallRegPath);
SetWinRegString(appName + " --UNINSTALL", "UninstallString", uninstallRegPath);
return success;
}
// unlinks application
bool Updater::ShellUnlink(void)
{
bool success = true;
String linkName = appName + ".lnk";
// remove uninstaller
DelKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + appName, "DisplayName");
DelKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + appName, "UninstallString");
DelKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", appName);
// remove program group
String groupName = ""; // that could be GetLNGString(cathegory) ????
String groupFolder = GetShellFolder("Common Programs", HKEY_LOCAL_MACHINE);
if(groupName != "")
{
groupFolder = AppendFileName(groupFolder, groupName);
if(PathExists(groupFolder))
DeleteFolderDeep(groupFolder);
}
else
{
Strink linkPath = AppendFileName(groupFolder, linkName);
if(FileExists(linkPath))
FileDelete(linkPath);
}
// remove desktop icon
String desktopLink = AppendFileName(GetShellFolder("Desktop", HKEY_USERS), linkName);
if(FileExists(desktopLink))
FileDelete(desktopLine);
return success;
}
#endif