Changed: Write shortcuts under OS X
This commit is contained in:
parent
962c6f0798
commit
d3a72f1506
9 changed files with 252 additions and 24 deletions
54
code/ryzom/tools/client/ryzom_installer/res/Info.plist
Normal file
54
code/ryzom/tools/client/ryzom_installer/res/Info.plist
Normal file
|
@ -0,0 +1,54 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>shortcut.sh</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>$NAME</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>ryzom.icns</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$IDENTIFIER</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleLocalizations</key>
|
||||
<array>
|
||||
<string>en</string>
|
||||
<string>fr</string>
|
||||
<string>de</string>
|
||||
<string>ru</string>
|
||||
<string>es</string>
|
||||
</array>
|
||||
<key>CFBundleLongVersionString</key>
|
||||
<string>$VERSION</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$NAME</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$VERSION</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>MacOSX</string>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.role-playing-games</string>
|
||||
<key>LSFileQuarantineEnabled</key>
|
||||
<false/>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.6</string>
|
||||
<key>LSRequiresCarbon</key>
|
||||
<true/>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>$COPYRIGHT</string>
|
||||
</dict>
|
||||
</plist>
|
1
code/ryzom/tools/client/ryzom_installer/res/PkgInfo
Normal file
1
code/ryzom/tools/client/ryzom_installer/res/PkgInfo
Normal file
|
@ -0,0 +1 @@
|
|||
APPL????
|
|
@ -4,10 +4,13 @@
|
|||
</qresource>
|
||||
<qresource prefix="/icons">
|
||||
<file>ryzom.ico</file>
|
||||
<file>ryzom_installer.png</file>
|
||||
<file>ryzom.png</file>
|
||||
<file>ryzom.icns</file>
|
||||
</qresource>
|
||||
<qresource prefix="/templates">
|
||||
<file>template.desktop</file>
|
||||
<file>ryzom_installer.ini</file>
|
||||
<file>Info.plist</file>
|
||||
<file>PkgInfo</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
BIN
code/ryzom/tools/client/ryzom_installer/res/ryzom.icns
Normal file
BIN
code/ryzom/tools/client/ryzom_installer/res/ryzom.icns
Normal file
Binary file not shown.
4
code/ryzom/tools/client/ryzom_installer/res/shortcut.sh
Normal file
4
code/ryzom/tools/client/ryzom_installer/res/shortcut.sh
Normal file
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
# autogenerated file - do not edit
|
||||
|
||||
$COMMAND
|
|
@ -791,15 +791,18 @@ QStringList CConfigFile::getInstallerRequiredFiles() const
|
|||
// unsupported compiler
|
||||
#endif
|
||||
|
||||
// include current executable
|
||||
files << QFileInfo(QApplication::applicationFilePath()).fileName();
|
||||
#elif defined(Q_OS_MAC)
|
||||
// TODO: for OS X
|
||||
// everything is in a directory
|
||||
files << "Ryzom Installer.app";
|
||||
#else
|
||||
// icon under Linux
|
||||
files << "ryzom_installer.png";
|
||||
#endif
|
||||
|
||||
// include current executable
|
||||
files << QFileInfo(QApplication::applicationFilePath()).fileName();
|
||||
#endif
|
||||
|
||||
return files;
|
||||
}
|
||||
|
|
|
@ -788,6 +788,8 @@ void COperationDialog::copyInstaller()
|
|||
#ifdef Q_OS_WIN32
|
||||
// under Windows, icon is included in executable
|
||||
icon = executable;
|
||||
#elif defined(Q_OS_MAC)
|
||||
// everything is in bundle
|
||||
#else
|
||||
// icon is in the same directory as installer
|
||||
icon = config->getInstallationDirectory() + "/ryzom_installer.png";
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "stdpch.h"
|
||||
#include "utils.h"
|
||||
#include "configfile.h"
|
||||
|
||||
#include "nel/misc/path.h"
|
||||
|
||||
|
@ -40,6 +41,36 @@ QString qBytesToHumanReadable(qint64 bytes)
|
|||
return QString::fromUtf8(NLMISC::bytesToHumanReadableUnits(bytes, units).c_str());
|
||||
}
|
||||
|
||||
QString nameToId(const QString &name)
|
||||
{
|
||||
QString res;
|
||||
|
||||
// only allows simple characters
|
||||
QRegExp allowedCharacters("^[0-9a-zA-Z-]$");
|
||||
|
||||
for (int i = 0, len = name.length(); i < len; ++i)
|
||||
{
|
||||
if (allowedCharacters.indexIn(name.at(i)) > -1)
|
||||
{
|
||||
// allowed character
|
||||
res += name[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
// not allowed, replace by a space
|
||||
res += " ";
|
||||
}
|
||||
}
|
||||
|
||||
// simplify all spaces
|
||||
res = res.simplified();
|
||||
|
||||
// replace spaces by minus
|
||||
res.replace(" ", "-");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool isDirectoryEmpty(const QString &directory, bool recursize)
|
||||
{
|
||||
bool res = true;
|
||||
|
@ -250,37 +281,89 @@ bool resolveShortcut(const QWidget &window, const QString &shortcut, QString &pa
|
|||
return SUCCEEDED(hres);
|
||||
}
|
||||
|
||||
#elif defined(NL_OS_MAC)
|
||||
|
||||
bool createShortcut(const QString &shortcut, const QString &name, const QString &executable, const QString &arguments, const QString &icon, const QString &workingDir)
|
||||
{
|
||||
QString appPath(shortcut + ".app");
|
||||
|
||||
// directories
|
||||
QString contentsPath(appPath + "/Contents");
|
||||
QString binaryPath(contentsPath + "/MacOS");
|
||||
QString dataPath(contentsPath + "/Resources");
|
||||
|
||||
// files
|
||||
QString binaryFile(binaryPath + "/shortcut.sh");
|
||||
QString iconFile(dataPath + "/ryzom.icns");
|
||||
QString pkgInfoFile(contentsPath + "/PkgInfo");
|
||||
QString plistFile(contentsPath + "/Info.plist");
|
||||
|
||||
// silently create directories
|
||||
QDir().mkpath(binaryPath);
|
||||
QDir().mkpath(dataPath);
|
||||
|
||||
if (!isDirectoryWritable(binaryPath) || !isDirectoryWritable(dataPath)) return false;
|
||||
|
||||
// write icon
|
||||
if (!writeResource(":/icons/ryzom.icns", iconFile)) return false;
|
||||
|
||||
// write PkgInfo
|
||||
if (!writeResource(":/templates/PkgInfo", pkgInfoFile)) return false;
|
||||
|
||||
// variables
|
||||
QMap<QString, QString> strings;
|
||||
|
||||
// build command
|
||||
QString command = QString("open \"%1\"").arg(executable);
|
||||
if (!arguments.isEmpty()) command += " --args " + arguments;
|
||||
|
||||
strings.clear();
|
||||
strings["COMMAND"] = command;
|
||||
|
||||
// write shortcut.sh
|
||||
if (!writeResourceWithTemplates(":/templates/shortcut.sh", binaryFile, strings)) return false;
|
||||
|
||||
// set executable flags to .sh
|
||||
QFile::setPermissions(binaryFile, QFile::permissions(binaryFile) | QFile::ExeGroup | QFile::ExeUser | QFile::ExeOther);
|
||||
|
||||
CConfigFile *config = CConfigFile::getInstance();
|
||||
|
||||
strings.clear();
|
||||
strings["NAME"] = name;
|
||||
strings["COPYRIGHT"] = config->getProductPublisher();
|
||||
strings["VERSION"] = QApplication::applicationVersion();
|
||||
strings["IDENTIFIER"] = "com.winchgate.Ryzom-" + nameToId(name);
|
||||
|
||||
// write Info.plist
|
||||
if (!writeResourceWithTemplates(":/templates/Info.plist", plistFile, strings)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool resolveShortcut(const QWidget &window, const QString &pathLink, QString &pathObj)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
bool createShortcut(const QString &shortcut, const QString &name, const QString &executable, const QString &arguments, const QString &icon, const QString &workingDir)
|
||||
{
|
||||
// open template
|
||||
QFile file(":/templates/template.desktop");
|
||||
|
||||
if (!file.open(QFile::ReadOnly)) return false;
|
||||
|
||||
QString data = QString::fromUtf8(file.readAll());
|
||||
|
||||
file.close();
|
||||
|
||||
// build command
|
||||
QString command = executable;
|
||||
if (!arguments.isEmpty()) command += " " + arguments;
|
||||
|
||||
// replace strings
|
||||
data.replace("$NAME", name);
|
||||
data.replace("$COMMAND", command);
|
||||
data.replace("$ICON", icon);
|
||||
// variables
|
||||
QMap<QString, QString> strings;
|
||||
strings["NAME"] = name;
|
||||
strings["COMMAND"] = command;
|
||||
strings["ICON"] = icon;
|
||||
|
||||
// destination file
|
||||
QString path(shortcut + ".desktop");
|
||||
|
||||
// write file
|
||||
file.setFileName(path);
|
||||
|
||||
if (!file.open(QFile::WriteOnly)) return false;
|
||||
|
||||
file.write(data.toUtf8());
|
||||
file.close();
|
||||
// replace strings
|
||||
if (!writeResourceWithTemplates(":/templates/template.desktop", path, strings)) return false;
|
||||
|
||||
// set executable flags to .desktop
|
||||
QFile::setPermissions(path, QFile::permissions(path) | QFile::ExeGroup | QFile::ExeUser | QFile::ExeOther);
|
||||
|
@ -307,7 +390,13 @@ bool removeShortcut(const QString &shortcut)
|
|||
if (!NLMISC::CFile::isExists(qToUtf8(fullPath))) return false;
|
||||
|
||||
// remove it
|
||||
#if defined(Q_OS_MAC)
|
||||
// under OS X, it's a directory
|
||||
return QDir(fullPath).removeRecursively();
|
||||
#else
|
||||
// a file under other platforms
|
||||
return QFile::remove(fullPath);
|
||||
#endif
|
||||
}
|
||||
|
||||
QString appendShortcutExtension(const QString &shortcut)
|
||||
|
@ -317,7 +406,7 @@ QString appendShortcutExtension(const QString &shortcut)
|
|||
#if defined(Q_OS_WIN32)
|
||||
extension = ".lnk";
|
||||
#elif defined(Q_OS_MAC)
|
||||
// TODO
|
||||
extension = ".app";
|
||||
#else
|
||||
extension = ".desktop";
|
||||
#endif
|
||||
|
@ -391,6 +480,75 @@ QString getVersionFromExecutable(const QString &path)
|
|||
return "";
|
||||
}
|
||||
|
||||
bool writeResource(const QString &resource, const QString &path)
|
||||
{
|
||||
// all resources start with :/
|
||||
if (!resource.startsWith(":/")) return false;
|
||||
|
||||
// open resource
|
||||
QFile file(resource);
|
||||
|
||||
// unable to open it
|
||||
if (!file.open(QFile::ReadOnly)) return false;
|
||||
|
||||
QByteArray data(file.readAll());
|
||||
|
||||
file.close();
|
||||
|
||||
// write file
|
||||
file.setFileName(path);
|
||||
|
||||
// unable to write it
|
||||
if (!file.open(QFile::WriteOnly)) return false;
|
||||
|
||||
// problem writting
|
||||
if (file.write(data) != data.length()) return false;
|
||||
|
||||
file.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool writeResourceWithTemplates(const QString &resource, const QString &path, const QMap<QString, QString> &strings)
|
||||
{
|
||||
// all resources start with :/
|
||||
if (!resource.startsWith(":/")) return false;
|
||||
|
||||
// open resource
|
||||
QFile file(resource);
|
||||
|
||||
// unable to open it
|
||||
if (!file.open(QFile::ReadOnly)) return false;
|
||||
|
||||
// data are UTF-8 text
|
||||
QString data = QString::fromUtf8(file.readAll());
|
||||
|
||||
file.close();
|
||||
|
||||
// write file
|
||||
file.setFileName(path);
|
||||
|
||||
// unable to write it
|
||||
if (!file.open(QFile::WriteOnly)) return false;
|
||||
|
||||
// replace strings
|
||||
QMap<QString, QString>::ConstIterator it = strings.begin(), iend = strings.end();
|
||||
|
||||
while (it != iend)
|
||||
{
|
||||
// replace variables with their value
|
||||
data.replace("$" + it.key(), it.value());
|
||||
|
||||
++it;
|
||||
}
|
||||
|
||||
// write
|
||||
file.write(data.toUtf8());
|
||||
file.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CCOMHelper::CCOMHelper()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
*/
|
||||
|
||||
QString qBytesToHumanReadable(qint64 bytes);
|
||||
QString nameToId(const QString &name);
|
||||
|
||||
bool isDirectoryEmpty(const QString &directory, bool recursize);
|
||||
|
||||
|
@ -57,6 +58,8 @@ bool resolveShortcut(const QWidget &window, const QString &shortcut, QString &pa
|
|||
QString appendShortcutExtension(const QString &shortcut);
|
||||
|
||||
QString getVersionFromExecutable(const QString &path);
|
||||
bool writeResource(const QString &resource, const QString &path);
|
||||
bool writeResourceWithTemplates(const QString &resource, const QString &path, const QMap<QString, QString> &strings);
|
||||
|
||||
class CCOMHelper
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue