feat: add desktopfilegenerator and method addUserApplication
1. change type of ActionName to 'a{sa{ss}}' 2. refactor the method of serialization Signed-off-by: ComixHe <heyuming@deepin.org>
This commit is contained in:
@ -8,6 +8,7 @@
|
||||
#include "systemdsignaldispatcher.h"
|
||||
#include "propertiesForwarder.h"
|
||||
#include "applicationHooks.h"
|
||||
#include "desktopfilegenerator.h"
|
||||
#include <QFile>
|
||||
#include <QDBusMessage>
|
||||
#include <unistd.h>
|
||||
@ -548,3 +549,67 @@ ApplicationManager1Service::findApplicationsByIds(const QStringList &appIds) con
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString ApplicationManager1Service::addUserApplication(const QVariantMap &desktop_file, const QString &name) noexcept
|
||||
{
|
||||
if (name.isEmpty()) {
|
||||
sendErrorReply(QDBusError::Failed, "file name is empty.");
|
||||
return {};
|
||||
}
|
||||
|
||||
QDir xdgDataHome{getXDGDataHome() + "/applications"};
|
||||
const auto &filePath = xdgDataHome.filePath(name);
|
||||
|
||||
if (QFileInfo info{filePath}; info.exists() and info.isFile()) {
|
||||
sendErrorReply(QDBusError::Failed, QString{"file already exists:%1"}.arg(info.absoluteFilePath()));
|
||||
return {};
|
||||
}
|
||||
|
||||
QFile file{filePath};
|
||||
if (!file.open(QFile::NewOnly | QFile::WriteOnly | QFile::Text)) {
|
||||
sendErrorReply(QDBusError::Failed, file.errorString());
|
||||
return {};
|
||||
}
|
||||
|
||||
QString errMsg;
|
||||
auto fileContent = DesktopFileGenerator::generate(desktop_file, errMsg);
|
||||
if (fileContent.isEmpty() or !errMsg.isEmpty()) {
|
||||
file.remove();
|
||||
sendErrorReply(QDBusError::Failed, errMsg);
|
||||
return {};
|
||||
}
|
||||
|
||||
auto writeContent = fileContent.toLocal8Bit();
|
||||
if (file.write(writeContent) != writeContent.size()) {
|
||||
file.remove();
|
||||
sendErrorReply(QDBusError::Failed, "incomplete file content.this file will be removed.");
|
||||
return {};
|
||||
}
|
||||
|
||||
file.flush();
|
||||
|
||||
ParserError err{ParserError::NoError};
|
||||
auto ret = DesktopFile::searchDesktopFileByPath(filePath, err);
|
||||
if (err != ParserError::NoError) {
|
||||
file.remove();
|
||||
qDebug() << "add user's application failed:" << err;
|
||||
sendErrorReply(QDBusError::Failed, "search failed.");
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
file.remove();
|
||||
sendErrorReply(QDBusError::InternalError);
|
||||
return {};
|
||||
}
|
||||
|
||||
auto desktopSource = std::move(ret).value();
|
||||
auto appId = desktopSource.desktopId();
|
||||
if (!addApplication(std::move(desktopSource))) {
|
||||
file.remove();
|
||||
sendErrorReply(QDBusError::Failed, "add application to ApplicationManager failed.");
|
||||
return {};
|
||||
}
|
||||
|
||||
return appId;
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
class ApplicationService;
|
||||
|
||||
class ApplicationManager1Service final : public QObject
|
||||
class ApplicationManager1Service final : public QObject, public QDBusContext
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@ -54,6 +54,7 @@ public Q_SLOTS:
|
||||
QDBusObjectPath &instance,
|
||||
ObjectInterfaceMap &application_instance_info) const noexcept;
|
||||
void ReloadApplications();
|
||||
QString addUserApplication(const QVariantMap &desktop_file, const QString &name) noexcept;
|
||||
[[nodiscard]] ObjectMap GetManagedObjects() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
|
@ -384,59 +384,64 @@ QStringList ApplicationService::categories() const noexcept
|
||||
PropMap ApplicationService::actionName() const noexcept
|
||||
{
|
||||
PropMap ret;
|
||||
auto actionList = actions();
|
||||
const auto &actionList = actions();
|
||||
|
||||
for (auto &action : actionList) {
|
||||
action.prepend(DesktopFileActionKey);
|
||||
auto value = m_entry->value(action, "Name");
|
||||
for (const auto &action : actionList) {
|
||||
auto rawActionKey = DesktopFileActionKey % action;
|
||||
auto value = m_entry->value(rawActionKey, "Name");
|
||||
if (!value.has_value()) {
|
||||
continue;
|
||||
}
|
||||
ret.insert(action, std::move(value).value());
|
||||
ret.insert(action, std::move(value).value().value<QStringMap>());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
PropMap ApplicationService::name() const noexcept
|
||||
QStringMap ApplicationService::name() const noexcept
|
||||
{
|
||||
PropMap ret;
|
||||
auto value = m_entry->value(DesktopFileEntryKey, "Name");
|
||||
if (!value) {
|
||||
return ret;
|
||||
return {};
|
||||
}
|
||||
|
||||
ret.insert(QString{"Name"}, {std::move(value).value()});
|
||||
return ret;
|
||||
if (!value->canConvert<QStringMap>()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return value->value<QStringMap>();
|
||||
}
|
||||
|
||||
PropMap ApplicationService::genericName() const noexcept
|
||||
QStringMap ApplicationService::genericName() const noexcept
|
||||
{
|
||||
PropMap ret;
|
||||
auto value = m_entry->value(DesktopFileEntryKey, "GenericName");
|
||||
if (!value) {
|
||||
return ret;
|
||||
return {};
|
||||
}
|
||||
|
||||
ret.insert(QString{"GenericName"}, {std::move(value).value()});
|
||||
return ret;
|
||||
if (!value->canConvert<QStringMap>()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return value->value<QStringMap>();
|
||||
}
|
||||
|
||||
PropMap ApplicationService::icons() const noexcept
|
||||
QStringMap ApplicationService::icons() const noexcept
|
||||
{
|
||||
PropMap ret;
|
||||
QStringMap ret;
|
||||
auto actionList = actions();
|
||||
for (const auto &action : actionList) {
|
||||
auto value = m_entry->value(QString{action}.prepend(DesktopFileActionKey), "Icon");
|
||||
const auto &actionKey = QString{action}.prepend(DesktopFileActionKey);
|
||||
auto value = m_entry->value(actionKey, "Icon");
|
||||
if (!value.has_value()) {
|
||||
continue;
|
||||
}
|
||||
ret.insert(action, {std::move(value).value()});
|
||||
ret.insert(actionKey, value->value<QString>());
|
||||
}
|
||||
|
||||
auto mainIcon = m_entry->value(DesktopFileEntryKey, "Icon");
|
||||
if (mainIcon.has_value()) {
|
||||
ret.insert(defaultKeyStr, {std::move(mainIcon).value()});
|
||||
ret.insert(DesktopFileEntryKey, mainIcon->value<QString>());
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -50,14 +50,14 @@ public:
|
||||
Q_PROPERTY(QString ID READ id CONSTANT)
|
||||
[[nodiscard]] QString id() const noexcept;
|
||||
|
||||
Q_PROPERTY(PropMap Name READ name NOTIFY nameChanged)
|
||||
[[nodiscard]] PropMap name() const noexcept;
|
||||
Q_PROPERTY(QStringMap Name READ name NOTIFY nameChanged)
|
||||
[[nodiscard]] QStringMap name() const noexcept;
|
||||
|
||||
Q_PROPERTY(PropMap GenericName READ genericName NOTIFY genericNameChanged)
|
||||
[[nodiscard]] PropMap genericName() const noexcept;
|
||||
Q_PROPERTY(QStringMap GenericName READ genericName NOTIFY genericNameChanged)
|
||||
[[nodiscard]] QStringMap genericName() const noexcept;
|
||||
|
||||
Q_PROPERTY(PropMap Icons READ icons NOTIFY iconsChanged)
|
||||
[[nodiscard]] PropMap icons() const noexcept;
|
||||
Q_PROPERTY(QStringMap Icons READ icons NOTIFY iconsChanged)
|
||||
[[nodiscard]] QStringMap icons() const noexcept;
|
||||
|
||||
Q_PROPERTY(qulonglong LastLaunchedTime READ lastLaunchedTime NOTIFY lastLaunchedTimeChanged)
|
||||
[[nodiscard]] qulonglong lastLaunchedTime() const noexcept;
|
||||
|
Reference in New Issue
Block a user