refact: change underlying type of desktop entry
Signed-off-by: ComixHe <heyuming@deepin.org>
This commit is contained in:
parent
de1bf515d8
commit
aff8cff0ec
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<method name="setDefaultApplication">
|
<method name="setDefaultApplication">
|
||||||
<arg type="a{ss}" name="defaultApps" direction="in"/>
|
<arg type="a{ss}" name="defaultApps" direction="in"/>
|
||||||
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="KVPairs"/>
|
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="QStringMap"/>
|
||||||
</method>
|
</method>
|
||||||
|
|
||||||
<method name="unsetDefaultApplication">
|
<method name="unsetDefaultApplication">
|
||||||
|
@ -21,7 +21,8 @@ void registerComplexDbusType()
|
|||||||
qDBusRegisterMetaType<ObjectInterfaceMap>();
|
qDBusRegisterMetaType<ObjectInterfaceMap>();
|
||||||
qRegisterMetaType<ObjectMap>();
|
qRegisterMetaType<ObjectMap>();
|
||||||
qDBusRegisterMetaType<ObjectMap>();
|
qDBusRegisterMetaType<ObjectMap>();
|
||||||
qDBusRegisterMetaType<KVPairs>();
|
qDBusRegisterMetaType<QStringMap>();
|
||||||
|
qRegisterMetaType<QStringMap>();
|
||||||
qRegisterMetaType<PropMap>();
|
qRegisterMetaType<PropMap>();
|
||||||
qDBusRegisterMetaType<PropMap>();
|
qDBusRegisterMetaType<PropMap>();
|
||||||
qDBusRegisterMetaType<QDBusObjectPath>();
|
qDBusRegisterMetaType<QDBusObjectPath>();
|
||||||
|
@ -15,9 +15,9 @@ bool ApplicationFilter::hiddenCheck(const std::unique_ptr<DesktopEntry> &entry)
|
|||||||
|
|
||||||
if (hiddenVal.has_value()) {
|
if (hiddenVal.has_value()) {
|
||||||
bool ok{false};
|
bool ok{false};
|
||||||
hidden = hiddenVal.value().toBoolean(ok);
|
hidden = toBoolean(hiddenVal.value(), ok);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
qWarning() << "invalid hidden value:" << *hiddenVal.value().find(defaultKeyStr);
|
qWarning() << "invalid hidden value:" << hiddenVal.value();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -28,10 +28,9 @@ bool ApplicationFilter::tryExecCheck(const std::unique_ptr<DesktopEntry> &entry)
|
|||||||
{
|
{
|
||||||
auto tryExecVal = entry->value(DesktopFileEntryKey, "TryExec");
|
auto tryExecVal = entry->value(DesktopFileEntryKey, "TryExec");
|
||||||
if (tryExecVal.has_value()) {
|
if (tryExecVal.has_value()) {
|
||||||
bool ok{false};
|
auto executable = toString(tryExecVal.value());
|
||||||
auto executable = tryExecVal.value().toString(ok);
|
if (executable.isEmpty()) {
|
||||||
if (!ok) {
|
qWarning() << "invalid TryExec value:" << tryExecVal.value();
|
||||||
qWarning() << "invalid TryExec value:" << *tryExecVal.value().find(defaultKeyStr);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,10 +55,9 @@ bool ApplicationFilter::showInCheck(const std::unique_ptr<DesktopEntry> &entry)
|
|||||||
bool showInCurrentDE{true};
|
bool showInCurrentDE{true};
|
||||||
auto onlyShowInVal = entry->value(DesktopFileEntryKey, "OnlyShowIn");
|
auto onlyShowInVal = entry->value(DesktopFileEntryKey, "OnlyShowIn");
|
||||||
while (onlyShowInVal.has_value()) {
|
while (onlyShowInVal.has_value()) {
|
||||||
bool ok{false};
|
auto deStr = toString(onlyShowInVal.value());
|
||||||
auto deStr = onlyShowInVal.value().toString(ok);
|
if (deStr.isEmpty()) {
|
||||||
if (!ok) {
|
qWarning() << "invalid OnlyShowIn value:" << onlyShowInVal.value();
|
||||||
qWarning() << "invalid OnlyShowIn value:" << *onlyShowInVal.value().find(defaultKeyStr);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,10 +77,9 @@ bool ApplicationFilter::showInCheck(const std::unique_ptr<DesktopEntry> &entry)
|
|||||||
bool notShowInCurrentDE{false};
|
bool notShowInCurrentDE{false};
|
||||||
auto notShowInVal = entry->value(DesktopFileEntryKey, "NotShowIn");
|
auto notShowInVal = entry->value(DesktopFileEntryKey, "NotShowIn");
|
||||||
while (notShowInVal.has_value()) {
|
while (notShowInVal.has_value()) {
|
||||||
bool ok{false};
|
auto deStr = toString(notShowInVal.value());
|
||||||
auto deStr = notShowInVal.value().toString(ok);
|
if (deStr.isEmpty()) {
|
||||||
if (!ok) {
|
qWarning() << "invalid OnlyShowIn value:" << notShowInVal.value();
|
||||||
qWarning() << "invalid OnlyShowIn value:" << *notShowInVal.value().find(defaultKeyStr);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,8 +44,8 @@ QString toString(const MimeContent &content) noexcept
|
|||||||
|
|
||||||
for (auto it = content.constKeyValueBegin(); it != content.constKeyValueEnd(); ++it) {
|
for (auto it = content.constKeyValueBegin(); it != content.constKeyValueEnd(); ++it) {
|
||||||
ret.append(QString{"[%1]\n"}.arg(it->first));
|
ret.append(QString{"[%1]\n"}.arg(it->first));
|
||||||
const auto &kvPairs = it->second;
|
const auto &QStringMap = it->second;
|
||||||
for (auto inner = kvPairs.constKeyValueBegin(); inner != kvPairs.constKeyValueEnd(); ++inner) {
|
for (auto inner = QStringMap.constKeyValueBegin(); inner != QStringMap.constKeyValueEnd(); ++inner) {
|
||||||
ret.append(QString{"%1="}.arg(inner->first));
|
ret.append(QString{"%1="}.arg(inner->first));
|
||||||
for (const auto &app : inner->second) {
|
for (const auto &app : inner->second) {
|
||||||
ret.append(QString{"%2;"}.arg(app));
|
ret.append(QString{"%2;"}.arg(app));
|
||||||
|
@ -180,9 +180,10 @@ QDBusObjectPath ApplicationService::Launch(const QString &action, const QStringL
|
|||||||
if (!actionExec) {
|
if (!actionExec) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
execStr = actionExec->toString(ok);
|
|
||||||
if (!ok) {
|
execStr = toString(actionExec.value());
|
||||||
qWarning() << "exec value to string failed, try default action.";
|
if (execStr.isEmpty()) {
|
||||||
|
qWarning() << "exec value to string failed, try default action."; // we need this log.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -196,8 +197,8 @@ QDBusObjectPath ApplicationService::Launch(const QString &action, const QStringL
|
|||||||
sendErrorReply(QDBusError::Failed, msg);
|
sendErrorReply(QDBusError::Failed, msg);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
execStr = Actions->toString(ok);
|
execStr = toString(Actions.value());
|
||||||
if (!ok) {
|
if (execStr.isEmpty()) {
|
||||||
QString msg{"maybe entry actions's format is invalid, abort launch."};
|
QString msg{"maybe entry actions's format is invalid, abort launch."};
|
||||||
qWarning() << msg;
|
qWarning() << msg;
|
||||||
sendErrorReply(QDBusError::Failed, msg);
|
sendErrorReply(QDBusError::Failed, msg);
|
||||||
@ -220,8 +221,8 @@ QDBusObjectPath ApplicationService::Launch(const QString &action, const QStringL
|
|||||||
|
|
||||||
if (terminal()) {
|
if (terminal()) {
|
||||||
// don't change this sequence
|
// don't change this sequence
|
||||||
execCmds.push_front("-C"); // means run a shellscript
|
execCmds.push_front("-C"); // means run a shellscript
|
||||||
execCmds.push_front("--keep-open"); // keep terminal open, prevent exit immediately
|
execCmds.push_front("--keep-open"); // keep terminal open, prevent exit immediately
|
||||||
execCmds.push_front("deepin-terminal");
|
execCmds.push_front("deepin-terminal");
|
||||||
}
|
}
|
||||||
cmds.append(std::move(execCmds));
|
cmds.append(std::move(execCmds));
|
||||||
@ -391,7 +392,7 @@ PropMap ApplicationService::actionName() const noexcept
|
|||||||
if (!value.has_value()) {
|
if (!value.has_value()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ret.insert(action, {std::move(value).value()});
|
ret.insert(action, std::move(value).value());
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -508,9 +509,9 @@ void ApplicationService::setScaleFactor(double value) noexcept
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_customScale){
|
if (m_customScale) {
|
||||||
if (!storagePtr->updateApplicationValue(appId, ApplicationPropertiesGroup, ScaleFactor, value)) {
|
if (!storagePtr->updateApplicationValue(appId, ApplicationPropertiesGroup, ScaleFactor, value)) {
|
||||||
sendErrorReply(QDBusError::Failed,"update scaleFactor failed.");
|
sendErrorReply(QDBusError::Failed, "update scaleFactor failed.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -826,9 +827,9 @@ LaunchTask ApplicationService::unescapeExec(const QString &str, const QStringLis
|
|||||||
task.command.append(std::move(execList));
|
task.command.append(std::move(execList));
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
bool ok;
|
|
||||||
auto iconStr = val->toIconString(ok);
|
auto iconStr = toIconString(val.value());
|
||||||
if (!ok) {
|
if (iconStr.isEmpty()) {
|
||||||
qDebug() << R"(Icons Convert to string failed. %i will be ignored.)";
|
qDebug() << R"(Icons Convert to string failed. %i will be ignored.)";
|
||||||
task.command.append(std::move(execList));
|
task.command.append(std::move(execList));
|
||||||
return task;
|
return task;
|
||||||
@ -845,9 +846,17 @@ LaunchTask ApplicationService::unescapeExec(const QString &str, const QStringLis
|
|||||||
task.command.append(std::move(execList));
|
task.command.append(std::move(execList));
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
bool ok;
|
|
||||||
auto NameStr = val->toLocaleString(getUserLocale(), ok);
|
const auto &rawValue = val.value();
|
||||||
if (!ok) {
|
if (!rawValue.canConvert<QStringMap>()) {
|
||||||
|
qDebug() << "Name's underlying type mismatch:"
|
||||||
|
<< "QStringMap" << rawValue.metaType().name();
|
||||||
|
task.command.append(std::move(execList));
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto NameStr = toLocaleString(rawValue.value<QStringMap>(), getUserLocale());
|
||||||
|
if (NameStr.isEmpty()) {
|
||||||
qDebug() << R"(Name Convert to locale string failed. %c will be ignored.)";
|
qDebug() << R"(Name Convert to locale string failed. %c will be ignored.)";
|
||||||
task.command.append(std::move(execList));
|
task.command.append(std::move(execList));
|
||||||
return task;
|
return task;
|
||||||
@ -897,26 +906,29 @@ QVariant ApplicationService::findEntryValue(const QString &group,
|
|||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case EntryValueType::String: {
|
case EntryValueType::String: {
|
||||||
auto valStr = val.toString(ok);
|
auto valStr = toString(val);
|
||||||
if (ok) {
|
if (!valStr.isEmpty()) {
|
||||||
ret = QVariant::fromValue(valStr);
|
ret = QVariant::fromValue(valStr);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case EntryValueType::LocaleString: {
|
case EntryValueType::LocaleString: {
|
||||||
auto valStr = val.toLocaleString(locale, ok);
|
if (!val.canConvert<QStringMap>()) {
|
||||||
if (ok) {
|
return ret;
|
||||||
|
}
|
||||||
|
auto valStr = toLocaleString(val.value<QStringMap>(), locale);
|
||||||
|
if (!valStr.isEmpty()) {
|
||||||
ret = QVariant::fromValue(valStr);
|
ret = QVariant::fromValue(valStr);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case EntryValueType::Boolean: {
|
case EntryValueType::Boolean: {
|
||||||
auto valBool = val.toBoolean(ok);
|
auto valBool = toBoolean(val, ok);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
ret = QVariant::fromValue(valBool);
|
ret = QVariant::fromValue(valBool);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case EntryValueType::IconString: {
|
case EntryValueType::IconString: {
|
||||||
auto valStr = val.toIconString(ok);
|
auto valStr = toIconString(val);
|
||||||
if (ok) {
|
if (!valStr.isEmpty()) {
|
||||||
ret = QVariant::fromValue(valStr);
|
ret = QVariant::fromValue(valStr);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
@ -79,7 +79,7 @@ QString MimeManager1Service::queryFileTypeAndDefaultApplication(const QString &f
|
|||||||
return mimeType;
|
return mimeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MimeManager1Service::setDefaultApplication(const KVPairs &defaultApps) noexcept
|
void MimeManager1Service::setDefaultApplication(const QStringMap &defaultApps) noexcept
|
||||||
{
|
{
|
||||||
auto &app = m_infos.front().appsList();
|
auto &app = m_infos.front().appsList();
|
||||||
auto userConfig = std::find_if(
|
auto userConfig = std::find_if(
|
||||||
|
@ -28,7 +28,7 @@ public Q_SLOTS:
|
|||||||
[[nodiscard]] ObjectMap listApplications(const QString &mimeType) const noexcept;
|
[[nodiscard]] ObjectMap listApplications(const QString &mimeType) const noexcept;
|
||||||
[[nodiscard]] QString queryFileTypeAndDefaultApplication(const QString &filePath,
|
[[nodiscard]] QString queryFileTypeAndDefaultApplication(const QString &filePath,
|
||||||
QDBusObjectPath &application) const noexcept;
|
QDBusObjectPath &application) const noexcept;
|
||||||
void setDefaultApplication(const KVPairs &defaultApps) noexcept;
|
void setDefaultApplication(const QStringMap &defaultApps) noexcept;
|
||||||
void unsetDefaultApplication(const QStringList &mimeTypes) noexcept;
|
void unsetDefaultApplication(const QStringList &mimeTypes) noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
|
||||||
#include "desktopentry.h"
|
#include "desktopentry.h"
|
||||||
#include "global.h"
|
|
||||||
#include "desktopfileparser.h"
|
#include "desktopfileparser.h"
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
@ -43,17 +42,15 @@ bool DesktopEntry::checkMainEntryValidation() const noexcept
|
|||||||
qWarning() << "No Type.";
|
qWarning() << "No Type.";
|
||||||
for (auto tmp = it->constKeyValueBegin(); tmp != it->constKeyValueEnd(); ++tmp) {
|
for (auto tmp = it->constKeyValueBegin(); tmp != it->constKeyValueEnd(); ++tmp) {
|
||||||
const auto &[k, v] = *tmp;
|
const auto &[k, v] = *tmp;
|
||||||
qInfo() << "keyName:" << k;
|
qInfo() << "key:" << k << "value:" << v;
|
||||||
for (auto valIt = v.constKeyValueBegin(); valIt != v.constKeyValueEnd(); ++valIt) {
|
|
||||||
const auto &[key, value] = *valIt;
|
|
||||||
qInfo() << key << value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto &typeStr = *type->find(defaultKeyStr);
|
const auto &typeStr = type->toString();
|
||||||
|
if (typeStr.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (typeStr == "Link") {
|
if (typeStr == "Link") {
|
||||||
if (it->find("URL") == it->end()) {
|
if (it->find("URL") == it->end()) {
|
||||||
return false;
|
return false;
|
||||||
@ -239,7 +236,7 @@ std::optional<DesktopEntry::Value> DesktopEntry::value(const QString &groupKey,
|
|||||||
return *it;
|
return *it;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString DesktopEntry::Value::unescape(const QString &str) noexcept
|
QString unescape(const QString &str) noexcept
|
||||||
{
|
{
|
||||||
QString unescapedStr;
|
QString unescapedStr;
|
||||||
for (qsizetype i = 0; i < str.size(); ++i) {
|
for (qsizetype i = 0; i < str.size(); ++i) {
|
||||||
@ -283,63 +280,66 @@ QString DesktopEntry::Value::unescape(const QString &str) noexcept
|
|||||||
return unescapedStr;
|
return unescapedStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString DesktopEntry::Value::toString(bool &ok) const noexcept
|
QString toString(const DesktopEntry::Value &value) noexcept
|
||||||
{
|
{
|
||||||
ok = false;
|
QString str;
|
||||||
auto str = this->find(defaultKeyStr);
|
|
||||||
|
|
||||||
if (str == this->end()) {
|
if (value.canConvert<QStringMap>()) { // get default locale
|
||||||
|
str = value.value<QStringMap>()[defaultKeyStr];
|
||||||
|
} else {
|
||||||
|
str = value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str.isEmpty()) {
|
||||||
qWarning() << "value not found.";
|
qWarning() << "value not found.";
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto unescapedStr = unescape(*str);
|
auto unescapedStr = unescape(str);
|
||||||
if (hasNonAsciiAndControlCharacters(unescapedStr)) {
|
if (hasNonAsciiAndControlCharacters(unescapedStr)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ok = true;
|
|
||||||
return unescapedStr;
|
return unescapedStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString DesktopEntry::Value::toLocaleString(const QLocale &locale, bool &ok) const noexcept
|
QString toLocaleString(const QStringMap &localeMap, const QLocale &locale) noexcept
|
||||||
{
|
{
|
||||||
ok = false;
|
for (auto it = localeMap.constKeyValueBegin(); it != localeMap.constKeyValueEnd(); ++it) {
|
||||||
for (auto it = this->constKeyValueBegin(); it != this->constKeyValueEnd(); ++it) {
|
|
||||||
auto [a, b] = *it;
|
auto [a, b] = *it;
|
||||||
if (QLocale{a}.name() == locale.name()) {
|
if (QLocale{a}.name() == locale.name()) {
|
||||||
ok = true;
|
|
||||||
return unescape(b);
|
return unescape(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return toString(ok);
|
|
||||||
|
return toString(localeMap[defaultKeyStr]);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString DesktopEntry::Value::toIconString(bool &ok) const noexcept
|
QString toIconString(const DesktopEntry::Value &value) noexcept
|
||||||
{
|
{
|
||||||
return toString(ok);
|
return toString(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DesktopEntry::Value::toBoolean(bool &ok) const noexcept
|
bool toBoolean(const DesktopEntry::Value &value, bool &ok) noexcept
|
||||||
{
|
{
|
||||||
ok = false;
|
ok = false;
|
||||||
const auto &str = (*this)[defaultKeyStr];
|
const auto &str = toString(value);
|
||||||
if (str == "true") {
|
if (str == "true") {
|
||||||
ok = true;
|
ok = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (str == "false") {
|
if (str == "false") {
|
||||||
ok = true;
|
ok = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
float DesktopEntry::Value::toNumeric(bool &ok) const noexcept
|
float toNumeric(const DesktopEntry::Value &value, bool &ok) noexcept
|
||||||
{
|
{
|
||||||
const auto &str = (*this)[defaultKeyStr];
|
return value.toFloat(&ok);
|
||||||
QVariant v{str};
|
|
||||||
return v.toFloat(&ok);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const DesktopEntry &lhs, const DesktopEntry &rhs)
|
bool operator==(const DesktopEntry &lhs, const DesktopEntry &rhs)
|
||||||
@ -381,10 +381,3 @@ bool operator!=(const DesktopFile &lhs, const DesktopFile &rhs)
|
|||||||
{
|
{
|
||||||
return !(lhs == rhs);
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
QDebug operator<<(QDebug debug, const DesktopEntry::Value &v)
|
|
||||||
{
|
|
||||||
QDebugStateSaver saver{debug};
|
|
||||||
debug << static_cast<const QMap<QString, QString> &>(v);
|
|
||||||
return debug;
|
|
||||||
}
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include "iniParser.h"
|
#include "iniParser.h"
|
||||||
|
#include "global.h"
|
||||||
|
|
||||||
constexpr static auto defaultKeyStr = "default";
|
constexpr static auto defaultKeyStr = "default";
|
||||||
|
|
||||||
@ -105,21 +106,7 @@ private:
|
|||||||
class DesktopEntry
|
class DesktopEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
class Value final : public QMap<QString, QString>
|
using Value = QVariant;
|
||||||
{
|
|
||||||
public:
|
|
||||||
using QMap<QString, QString>::QMap;
|
|
||||||
QString toString(bool &ok) const noexcept;
|
|
||||||
bool toBoolean(bool &ok) const noexcept;
|
|
||||||
QString toIconString(bool &ok) const noexcept;
|
|
||||||
float toNumeric(bool &ok) const noexcept;
|
|
||||||
QString toLocaleString(const QLocale &locale, bool &ok) const noexcept;
|
|
||||||
friend QDebug operator<<(QDebug debug, const DesktopEntry::Value &v);
|
|
||||||
|
|
||||||
private:
|
|
||||||
[[nodiscard]] static QString unescape(const QString &str) noexcept;
|
|
||||||
};
|
|
||||||
|
|
||||||
DesktopEntry() = default;
|
DesktopEntry() = default;
|
||||||
DesktopEntry(const DesktopEntry &) = default;
|
DesktopEntry(const DesktopEntry &) = default;
|
||||||
DesktopEntry(DesktopEntry &&) = default;
|
DesktopEntry(DesktopEntry &&) = default;
|
||||||
@ -141,8 +128,6 @@ private:
|
|||||||
bool m_parsed{false};
|
bool m_parsed{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
QDebug operator<<(QDebug debug, const DesktopEntry::Value &v);
|
|
||||||
|
|
||||||
bool operator==(const DesktopEntry &lhs, const DesktopEntry &rhs);
|
bool operator==(const DesktopEntry &lhs, const DesktopEntry &rhs);
|
||||||
|
|
||||||
bool operator!=(const DesktopEntry &lhs, const DesktopEntry &rhs);
|
bool operator!=(const DesktopEntry &lhs, const DesktopEntry &rhs);
|
||||||
@ -151,4 +136,16 @@ bool operator==(const DesktopFile &lhs, const DesktopFile &rhs);
|
|||||||
|
|
||||||
bool operator!=(const DesktopFile &lhs, const DesktopFile &rhs);
|
bool operator!=(const DesktopFile &lhs, const DesktopFile &rhs);
|
||||||
|
|
||||||
|
QString unescape(const QString &str) noexcept;
|
||||||
|
|
||||||
|
QString toLocaleString(const QStringMap &localeMap, const QLocale &locale) noexcept;
|
||||||
|
|
||||||
|
QString toString(const DesktopEntry::Value &value) noexcept;
|
||||||
|
|
||||||
|
bool toBoolean(const DesktopEntry::Value &value, bool &ok) noexcept;
|
||||||
|
|
||||||
|
QString toIconString(const DesktopEntry::Value &value) noexcept;
|
||||||
|
|
||||||
|
float toNumeric(const DesktopEntry::Value &value, bool &ok) noexcept;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include "desktopfileparser.h"
|
#include "desktopfileparser.h"
|
||||||
#include "constant.h"
|
#include "constant.h"
|
||||||
|
#include "global.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
bool isInvalidLocaleString(const QString &str) noexcept
|
bool isInvalidLocaleString(const QString &str) noexcept
|
||||||
@ -25,6 +26,12 @@ bool isInvalidLocaleString(const QString &str) noexcept
|
|||||||
return re.match(str).hasMatch();
|
return re.match(str).hasMatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isLocaleString(const QString &key) noexcept
|
||||||
|
{
|
||||||
|
static QSet<QString> localeSet{"Name", "GenericName", "Comment", "Keywords"};
|
||||||
|
return localeSet.contains(key);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
ParserError DesktopFileParser::parse(Groups &ret) noexcept
|
ParserError DesktopFileParser::parse(Groups &ret) noexcept
|
||||||
@ -135,25 +142,41 @@ ParserError DesktopFileParser::addEntry(typename Groups::iterator &group) noexce
|
|||||||
// NOTE: https://stackoverflow.com/a/25583104
|
// NOTE: https://stackoverflow.com/a/25583104
|
||||||
thread_local const QRegularExpression re = _re;
|
thread_local const QRegularExpression re = _re;
|
||||||
if (re.match(key).hasMatch()) {
|
if (re.match(key).hasMatch()) {
|
||||||
qWarning() << "invalid key name, skip this line:" << line;
|
qWarning() << "invalid key name:" << key << ", skip this line:" << line;
|
||||||
return ParserError::NoError;
|
return ParserError::NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (localeStr != defaultKeyStr && !isInvalidLocaleString(localeStr)) {
|
if (localeStr != defaultKeyStr and !isInvalidLocaleString(localeStr)) {
|
||||||
qWarning().noquote() << QString("invalid LOCALE (%2) for key \"%1\"").arg(key, localeStr);
|
qWarning().noquote() << QString("invalid LOCALE (%2) for key \"%1\"").arg(key, localeStr);
|
||||||
}
|
|
||||||
|
|
||||||
auto keyIt = group->find(key);
|
|
||||||
if (keyIt != group->end() && keyIt->find(localeStr) != keyIt->end()) {
|
|
||||||
qWarning() << "duplicated localestring, skip this line:" << line;
|
|
||||||
return ParserError::NoError;
|
return ParserError::NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keyIt == group->end()) {
|
if (auto keyIt = group->find(key); keyIt != group->end()) {
|
||||||
group->insert(key, {{localeStr, valueStr}});
|
if (!isLocaleString(key)) {
|
||||||
return ParserError::NoError;
|
qWarning() << "duplicate key:" << key << "skip.";
|
||||||
|
return ParserError::NoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!keyIt->canConvert<QStringMap>()) {
|
||||||
|
qWarning() << "underlying type of value is invalid, raw value:" << *keyIt << "skip";
|
||||||
|
return ParserError::NoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto localeMap = keyIt->value<QStringMap>();
|
||||||
|
if (auto valueIt = localeMap.find(localeStr) != localeMap.end()) {
|
||||||
|
qWarning() << "duplicate locale key:" << key << "skip.";
|
||||||
|
return ParserError::NoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
localeMap.insert(localeStr, valueStr);
|
||||||
|
group->insert(key, QVariant::fromValue(localeMap));
|
||||||
|
} else {
|
||||||
|
if (isLocaleString(key)) {
|
||||||
|
group->insert(key, QVariant::fromValue(QStringMap{{localeStr, valueStr}}));
|
||||||
|
} else {
|
||||||
|
group->insert(key, QVariant::fromValue(valueStr));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
keyIt->insert(localeStr, valueStr);
|
|
||||||
return ParserError::NoError;
|
return ParserError::NoError;
|
||||||
}
|
}
|
||||||
|
@ -29,12 +29,12 @@ Q_DECLARE_LOGGING_CATEGORY(DDEAMProf)
|
|||||||
|
|
||||||
using ObjectInterfaceMap = QMap<QString, QVariantMap>;
|
using ObjectInterfaceMap = QMap<QString, QVariantMap>;
|
||||||
using ObjectMap = QMap<QDBusObjectPath, ObjectInterfaceMap>;
|
using ObjectMap = QMap<QDBusObjectPath, ObjectInterfaceMap>;
|
||||||
using KVPairs = QMap<QString, QString>;
|
using QStringMap = QMap<QString, QString>;
|
||||||
using PropMap = QMap<QString, KVPairs>;
|
using PropMap = QVariantMap;
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(ObjectInterfaceMap)
|
Q_DECLARE_METATYPE(ObjectInterfaceMap)
|
||||||
Q_DECLARE_METATYPE(ObjectMap)
|
Q_DECLARE_METATYPE(ObjectMap)
|
||||||
Q_DECLARE_METATYPE(KVPairs)
|
Q_DECLARE_METATYPE(QStringMap)
|
||||||
Q_DECLARE_METATYPE(PropMap)
|
Q_DECLARE_METATYPE(PropMap)
|
||||||
|
|
||||||
struct SystemdUnitDBusMessage
|
struct SystemdUnitDBusMessage
|
||||||
|
@ -15,7 +15,7 @@ void registerComplexDbusType() // FIXME: test shouldn't associate with DBus
|
|||||||
qDBusRegisterMetaType<ObjectInterfaceMap>();
|
qDBusRegisterMetaType<ObjectInterfaceMap>();
|
||||||
qRegisterMetaType<ObjectMap>();
|
qRegisterMetaType<ObjectMap>();
|
||||||
qDBusRegisterMetaType<ObjectMap>();
|
qDBusRegisterMetaType<ObjectMap>();
|
||||||
qDBusRegisterMetaType<QMap<QString, QString>>();
|
qDBusRegisterMetaType<QStringMap>();
|
||||||
qRegisterMetaType<PropMap>();
|
qRegisterMetaType<PropMap>();
|
||||||
qDBusRegisterMetaType<PropMap>();
|
qDBusRegisterMetaType<PropMap>();
|
||||||
qDBusRegisterMetaType<QDBusObjectPath>();
|
qDBusRegisterMetaType<QDBusObjectPath>();
|
||||||
|
@ -66,19 +66,20 @@ TEST_F(TestDesktopEntry, prase)
|
|||||||
auto name = group->constFind("Name");
|
auto name = group->constFind("Name");
|
||||||
ASSERT_NE(name, group->cend());
|
ASSERT_NE(name, group->cend());
|
||||||
|
|
||||||
bool ok;
|
const auto &nameVal = *name;
|
||||||
name->toBoolean(ok);
|
|
||||||
|
bool ok{true};
|
||||||
|
toBoolean(nameVal, ok);
|
||||||
EXPECT_FALSE(ok);
|
EXPECT_FALSE(ok);
|
||||||
|
|
||||||
name->toNumeric(ok);
|
toNumeric(nameVal, ok);
|
||||||
EXPECT_FALSE(ok);
|
EXPECT_FALSE(ok);
|
||||||
|
|
||||||
auto defaultName = name->toString(ok);
|
EXPECT_TRUE(nameVal.canConvert<QStringMap>());
|
||||||
ASSERT_TRUE(ok);
|
auto defaultName = toString(nameVal); // get default locale value.
|
||||||
EXPECT_TRUE(defaultName == "Text Editor");
|
EXPECT_TRUE(defaultName == "Text Editor");
|
||||||
|
|
||||||
auto localeString = name->toLocaleString(QLocale{"zh_CN"}, ok);
|
const auto &localeMap = nameVal.value<QStringMap>();
|
||||||
ASSERT_TRUE(ok);
|
auto localeString = toLocaleString(nameVal.value<QStringMap>(), QLocale{"zh_CN"});
|
||||||
|
|
||||||
EXPECT_TRUE(localeString == "文本编辑器");
|
EXPECT_TRUE(localeString == "文本编辑器");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user