|
|
@ -16,6 +16,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
#include "stdpch.h"
|
|
|
|
#include "stdpch.h"
|
|
|
|
#include "utils.h"
|
|
|
|
#include "utils.h"
|
|
|
|
|
|
|
|
#include "configfile.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "nel/misc/path.h"
|
|
|
|
#include "nel/misc/path.h"
|
|
|
|
|
|
|
|
|
|
|
@ -40,6 +41,36 @@ QString qBytesToHumanReadable(qint64 bytes)
|
|
|
|
return QString::fromUtf8(NLMISC::bytesToHumanReadableUnits(bytes, units).c_str());
|
|
|
|
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 isDirectoryEmpty(const QString &directory, bool recursize)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
bool res = true;
|
|
|
|
bool res = true;
|
|
|
@ -250,37 +281,89 @@ bool resolveShortcut(const QWidget &window, const QString &shortcut, QString &pa
|
|
|
|
return SUCCEEDED(hres);
|
|
|
|
return SUCCEEDED(hres);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
#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)
|
|
|
|
bool createShortcut(const QString &shortcut, const QString &name, const QString &executable, const QString &arguments, const QString &icon, const QString &workingDir)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// open template
|
|
|
|
QString appPath(shortcut + ".app");
|
|
|
|
QFile file(":/templates/template.desktop");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!file.open(QFile::ReadOnly)) return false;
|
|
|
|
// directories
|
|
|
|
|
|
|
|
QString contentsPath(appPath + "/Contents");
|
|
|
|
|
|
|
|
QString binaryPath(contentsPath + "/MacOS");
|
|
|
|
|
|
|
|
QString dataPath(contentsPath + "/Resources");
|
|
|
|
|
|
|
|
|
|
|
|
QString data = QString::fromUtf8(file.readAll());
|
|
|
|
// files
|
|
|
|
|
|
|
|
QString binaryFile(binaryPath + "/shortcut.sh");
|
|
|
|
|
|
|
|
QString iconFile(dataPath + "/ryzom.icns");
|
|
|
|
|
|
|
|
QString pkgInfoFile(contentsPath + "/PkgInfo");
|
|
|
|
|
|
|
|
QString plistFile(contentsPath + "/Info.plist");
|
|
|
|
|
|
|
|
|
|
|
|
file.close();
|
|
|
|
// 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)
|
|
|
|
|
|
|
|
{
|
|
|
|
// build command
|
|
|
|
// build command
|
|
|
|
QString command = executable;
|
|
|
|
QString command = executable;
|
|
|
|
if (!arguments.isEmpty()) command += " " + arguments;
|
|
|
|
if (!arguments.isEmpty()) command += " " + arguments;
|
|
|
|
|
|
|
|
|
|
|
|
// replace strings
|
|
|
|
// variables
|
|
|
|
data.replace("$NAME", name);
|
|
|
|
QMap<QString, QString> strings;
|
|
|
|
data.replace("$COMMAND", command);
|
|
|
|
strings["NAME"] = name;
|
|
|
|
data.replace("$ICON", icon);
|
|
|
|
strings["COMMAND"] = command;
|
|
|
|
|
|
|
|
strings["ICON"] = icon;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// destination file
|
|
|
|
QString path(shortcut + ".desktop");
|
|
|
|
QString path(shortcut + ".desktop");
|
|
|
|
|
|
|
|
|
|
|
|
// write file
|
|
|
|
// replace strings
|
|
|
|
file.setFileName(path);
|
|
|
|
if (!writeResourceWithTemplates(":/templates/template.desktop", path, strings)) return false;
|
|
|
|
|
|
|
|
|
|
|
|
if (!file.open(QFile::WriteOnly)) return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
file.write(data.toUtf8());
|
|
|
|
|
|
|
|
file.close();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// set executable flags to .desktop
|
|
|
|
// set executable flags to .desktop
|
|
|
|
QFile::setPermissions(path, QFile::permissions(path) | QFile::ExeGroup | QFile::ExeUser | QFile::ExeOther);
|
|
|
|
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;
|
|
|
|
if (!NLMISC::CFile::isExists(qToUtf8(fullPath))) return false;
|
|
|
|
|
|
|
|
|
|
|
|
// remove it
|
|
|
|
// 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);
|
|
|
|
return QFile::remove(fullPath);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QString appendShortcutExtension(const QString &shortcut)
|
|
|
|
QString appendShortcutExtension(const QString &shortcut)
|
|
|
@ -317,7 +406,7 @@ QString appendShortcutExtension(const QString &shortcut)
|
|
|
|
#if defined(Q_OS_WIN32)
|
|
|
|
#if defined(Q_OS_WIN32)
|
|
|
|
extension = ".lnk";
|
|
|
|
extension = ".lnk";
|
|
|
|
#elif defined(Q_OS_MAC)
|
|
|
|
#elif defined(Q_OS_MAC)
|
|
|
|
// TODO
|
|
|
|
extension = ".app";
|
|
|
|
#else
|
|
|
|
#else
|
|
|
|
extension = ".desktop";
|
|
|
|
extension = ".desktop";
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
@ -391,6 +480,75 @@ QString getVersionFromExecutable(const QString &path)
|
|
|
|
return "";
|
|
|
|
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()
|
|
|
|
CCOMHelper::CCOMHelper()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
#ifdef Q_OS_WIN
|
|
|
|