Verified Commit ebb4a591 authored by azubieta's avatar azubieta
Browse files

Set target application icon as the helper application icon

parent cc0e6b34
......@@ -5,6 +5,11 @@
<arg type="s" direction="out"/>
<arg name="appImagePath" type="s" direction="in"/>
</method>
<method name="extractApplicationIcon">
<arg type="b" direction="out"/>
<arg name="appImagePath" type="s" direction="in"/>
<arg name="targetPath" type="s" direction="in"/>
</method>
<method name="listContents">
<arg type="as" direction="out"/>
<arg name="appImagePath" type="s" direction="in"/>
......
......@@ -6,16 +6,18 @@
#include "LauncherInterface.h"
RemoveJob::RemoveJob(const QString& target, QObject* parent)
: KJob(parent), target(target),
launcherInterface(new OrgAppimageServices1LauncherInterface("org.appimage.Services1.Launcher",
"/org/appimage/Services1/Launcher",
QDBusConnection::sessionBus(), this)) {}
: KJob(parent), target(target),
launcherInterface(new OrgAppimageServices1LauncherInterface("org.appimage.Services1.Launcher",
"/org/appimage/Services1/Launcher",
QDBusConnection::sessionBus(), this)) {}
void RemoveJob::start() {
description(this, i18n("Removing launcher entry"));
auto reply = launcherInterface->unregisterApp(target);
if (reply.isError()) {
setError(-1);
setErrorText(i18n("Remove failed: %0").arg(reply.error().message()));
setErrorText(reply.error().message());
}
QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(reply, this);
......@@ -26,9 +28,9 @@ void RemoveJob::start() {
void RemoveJob::callFinishedSlot(QDBusPendingCallWatcher* watcher) {
if (watcher->isError()) {
setError(-1);
setErrorText(i18n("Remove failed: %0").arg(watcher->error().message()));
setErrorText(watcher->error().message());
} else
description(this, i18n("Application successfully removed"));
infoMessage(this, i18n("Application successfully removed"));
// notify result delayed
QTimer::singleShot(1000, this, &RemoveJob::emitResult);
......
// libraries
#include <QIcon>
#include <QtWidgets/QApplication>
#include <utility>
// local
#include "InspectorInterface.h"
#include "TargetDataLoader.h"
TargetDataLoader::TargetDataLoader(QString target) : target(std::move(target)) {}
TargetDataLoader::TargetDataLoader(QString target, QObject* parent) : QObject(parent), target(std::move(target)) {}
void TargetDataLoader::loadTargetDataIntoApplication() {
auto inspectorInterface = new OrgAppimageServices1InspectorInterface("org.appimage.Services1.Inspector",
"/org/appimage/Services1/Inspector",
QDBusConnection::sessionBus(), this);
loadApplicationIcon(inspectorInterface);
loadApplicationName(inspectorInterface);
}
void TargetDataLoader::loadApplicationName(OrgAppimageServices1InspectorInterface* inspectorInterface) const {
auto reply = inspectorInterface->getApplicationInfo(target);
if (reply.isError())
qWarning() << "Unable to fetch AppImage information " << reply.error().message();
......@@ -26,3 +31,51 @@ void TargetDataLoader::loadTargetDataIntoApplication() {
QApplication::setApplicationName(nameValue);
}
}
void TargetDataLoader::loadApplicationIcon(OrgAppimageServices1InspectorInterface* inspectorInterface) {
QTemporaryFile temporaryIconFile("XXXXXX");
if (temporaryIconFile.open()) {
auto reply = inspectorInterface->extractApplicationIcon(target, temporaryIconFile.fileName());
if (reply.isError())
qWarning() << "Unable to fetch AppImage icon " << reply.error().message();
QString themeIconName = "application-vnd.appimage";
QImage applicationIcon(temporaryIconFile.fileName());
if (!applicationIcon.isNull()) {
// scale the icon to a valid icon size
applicationIcon = applicationIcon.scaled(512, 512, Qt::KeepAspectRatio);
// prepare target dir
QString dirPath = QDir::homePath() + "/.local/share/icons/hicolor/%1x%1/apps/";
dirPath = dirPath.arg(applicationIcon.height());
QDir::home().mkpath(dirPath);
// prepare file name
QFileInfo temporaryIconFileInfo(temporaryIconFile);
QString fileName = "plasma-appimage-integration_%2.png";
fileName = fileName.arg(temporaryIconFileInfo.baseName());
// save the icon to the right place on the hicolor theme to make it accessible from the kjob dialog
temporaryAppIconPath = dirPath + fileName;
if (applicationIcon.save(temporaryAppIconPath, "PNG")) {
// use the temporary created icon
themeIconName = "plasma-appimage-integration_" + temporaryIconFileInfo.baseName();
} else {
qWarning() << "unable so save icon to " << temporaryAppIconPath;
}
}
// double check that the icon was properly registered in the theme before using it
if (QIcon::hasThemeIcon(themeIconName)) {
QApplication::setWindowIcon(QIcon::fromTheme(themeIconName));
} else {
qDebug() << "Icon not found in theme " << themeIconName;
QApplication::setWindowIcon(QIcon::fromTheme("application-vnd.appimage"));
}
}
}
TargetDataLoader::~TargetDataLoader() {
if (QFile::exists(temporaryAppIconPath))
QFile::remove(temporaryAppIconPath);
}
......@@ -4,14 +4,22 @@
#include <QtCore/QString>
#include <QtCore/QObject>
class OrgAppimageServices1InspectorInterface;
class TargetDataLoader : public QObject {
Q_OBJECT
public:
TargetDataLoader(QString target);
explicit TargetDataLoader(QString target, QObject* parent = nullptr);
~TargetDataLoader() override;
void loadTargetDataIntoApplication();
private:
QString target;
QString temporaryAppIconPath;
void loadApplicationIcon(OrgAppimageServices1InspectorInterface* inspectorInterface);
void loadApplicationName(OrgAppimageServices1InspectorInterface* inspectorInterface) const;
};
\ No newline at end of file
......@@ -33,41 +33,6 @@ QString parseTarget(QCommandLineParser& parser) {
}
}
void executeUpdateCommand(const QString& target) {
KJob* job = new UpdateJob(target);
KIO::getJobTracker()->registerJob(job);
job->start();
if (job->error() != 0)
UpdateJob::notifyError(i18n("Update failed").arg(target), job->errorString());
}
void executeRemoveCommand(const QString& target) {
KJob* job = new RemoveJob(target);
KIO::getJobTracker()->registerJob(job);
job->start();
if (job->error() != 0)
UpdateJob::notifyError(i18n("Remove failed").arg(target), job->errorString());
}
void executeInstallCommand(const QString& target) {
KJob* job = new InstallJob(target);
KIO::getJobTracker()->registerJob(job);
job->start();
}
void executeUninstallCommand(const QString& target) {
KJob* job = new UninstallJob(target);
KIO::getJobTracker()->registerJob(job);
job->start();
}
int main(int argc, char** argv) {
QApplication app(argc, argv);
QApplication::setApplicationName("plasma-appimage-integration");
......@@ -89,30 +54,38 @@ int main(int argc, char** argv) {
const QString& command = positionalArguments.at(0);
QString target;
KJob* job = nullptr;
if (command == "update") {
QString target = parseTarget(parser);
TargetDataLoader(target).loadTargetDataIntoApplication();
executeUpdateCommand(target);
target = parseTarget(parser);
job = new UpdateJob(target);
}
if (command == "remove") {
QString target = parseTarget(parser);
TargetDataLoader(target).loadTargetDataIntoApplication();
executeRemoveCommand(target);
target = parseTarget(parser);
job = new RemoveJob(target);
}
if (command == "install") {
QString target = parseTarget(parser);
TargetDataLoader(target).loadTargetDataIntoApplication();
executeInstallCommand(target);
target = parseTarget(parser);
job = new InstallJob(target);
}
if (command == "uninstall") {
QString target = parseTarget(parser);
TargetDataLoader(target).loadTargetDataIntoApplication();
executeUninstallCommand(target);
target = parseTarget(parser);
job = new UninstallJob(target);
}
if (!target.isEmpty()) {
auto targetDataLoader = new TargetDataLoader(target, &app);
targetDataLoader->loadTargetDataIntoApplication();
}
if (job != nullptr) {
KIO::getJobTracker()->registerJob(job);
QMetaObject::invokeMethod(job, "start");
}
return QApplication::exec();
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment