mirror of
https://github.com/linuxdeepin/dde-dock.git
synced 2025-06-01 07:05:48 +00:00
248 lines
6.8 KiB
C++
248 lines
6.8 KiB
C++
![]() |
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
|
||
|
//
|
||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||
|
|
||
|
#include "desktopinfo.h"
|
||
|
#include "locale.h"
|
||
|
#include "unistd.h"
|
||
|
|
||
|
#include <QDebug>
|
||
|
|
||
|
#include <algorithm>
|
||
|
#include <QFileInfo>
|
||
|
#include <QSettings>
|
||
|
#include <QStandardPaths>
|
||
|
#include <QVector>
|
||
|
#include <qlocale.h>
|
||
|
|
||
|
QStringList DesktopInfo::currentDesktops;
|
||
|
static QString desktopFileSuffix = ".desktop";
|
||
|
|
||
|
DesktopInfo::DesktopInfo(const QString &desktopfile)
|
||
|
: m_isValid(true)
|
||
|
{
|
||
|
QString desktopfilepath(desktopfile);
|
||
|
QFileInfo desktopFileInfo(desktopfilepath);
|
||
|
if (!(desktopfilepath.endsWith(desktopFileSuffix))) {
|
||
|
desktopfilepath = desktopfilepath + desktopFileSuffix;
|
||
|
desktopFileInfo.setFile(desktopfilepath);
|
||
|
}
|
||
|
|
||
|
if (!desktopFileInfo.isAbsolute()) {
|
||
|
for (auto dir: QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation)) {
|
||
|
QString path = dir.append("/").append(desktopfilepath);
|
||
|
if (QFile::exists(path)) desktopFileInfo.setFile(path);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
m_desktopFilePath = desktopFileInfo.absoluteFilePath();
|
||
|
m_isValid = desktopFileInfo.isAbsolute() && QFile::exists(desktopFileInfo.absoluteFilePath());
|
||
|
m_desktopFile.reset(new QSettings(m_desktopFilePath, QSettings::IniFormat));
|
||
|
m_desktopFile->setIniCodec("utf-8");
|
||
|
// check DesktopInfo valid
|
||
|
QStringList mainKeys = m_desktopFile->childGroups();
|
||
|
if (mainKeys.size() == 0)
|
||
|
m_isValid = false;
|
||
|
|
||
|
bool found = std::any_of(mainKeys.begin(), mainKeys.end(),
|
||
|
[](const auto &key) {return key == MainSection;});
|
||
|
|
||
|
if (!found)
|
||
|
m_isValid = false;
|
||
|
|
||
|
if (m_desktopFile->value(MainSection + '/' + KeyType).toString() != TypeApplication)
|
||
|
m_isValid = false;
|
||
|
|
||
|
m_name = getLocaleStr(MainSection, KeyName);
|
||
|
m_icon = m_desktopFile->value(MainSection + '/' + KeyIcon).toString();
|
||
|
m_id = getId();
|
||
|
}
|
||
|
|
||
|
DesktopInfo::~DesktopInfo()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
QString DesktopInfo::getDesktopFilePath()
|
||
|
{
|
||
|
return m_desktopFilePath;
|
||
|
}
|
||
|
|
||
|
bool DesktopInfo::isValidDesktop()
|
||
|
{
|
||
|
return m_isValid;
|
||
|
}
|
||
|
|
||
|
/** if return true, item is shown
|
||
|
* @brief DesktopInfo::shouldShow
|
||
|
* @return
|
||
|
*/
|
||
|
bool DesktopInfo::shouldShow()
|
||
|
{
|
||
|
if (getNoDisplay() || getIsHidden()) {
|
||
|
qDebug() << "hidden desktop file path: " << m_desktopFilePath;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
QStringList desktopEnvs;
|
||
|
return getShowIn(desktopEnvs);
|
||
|
}
|
||
|
|
||
|
bool DesktopInfo::getNoDisplay()
|
||
|
{
|
||
|
return m_desktopFile->value(MainSection + '/' + KeyNoDisplay).toBool();
|
||
|
}
|
||
|
|
||
|
bool DesktopInfo::getIsHidden()
|
||
|
{
|
||
|
return m_desktopFile->value(MainSection + '/' + KeyHidden).toBool();
|
||
|
}
|
||
|
|
||
|
bool DesktopInfo::getShowIn(QStringList desktopEnvs)
|
||
|
{
|
||
|
#ifdef QT_DEBUG
|
||
|
qDebug() << "desktop file path: " << m_desktopFilePath;
|
||
|
#endif
|
||
|
|
||
|
if (desktopEnvs.size() == 0) {
|
||
|
const QString env = getenv("XDG_CURRENT_DESKTOP");
|
||
|
QVector<QString> desktops = env.split(":").toVector();
|
||
|
currentDesktops.fromVector(desktops);
|
||
|
desktopEnvs.fromVector(desktops);
|
||
|
}
|
||
|
|
||
|
QStringList onlyShowIn = m_desktopFile->value(MainSection + '/' + KeyOnlyShowIn).toStringList();
|
||
|
QStringList notShowIn = m_desktopFile->value(MainSection + '/' + KeyNotShowIn).toStringList();
|
||
|
|
||
|
#ifdef QT_DEBUG
|
||
|
qDebug() << "onlyShowIn:" << onlyShowIn <<
|
||
|
", notShowIn:" << notShowIn <<
|
||
|
", desktopEnvs:" << desktopEnvs;
|
||
|
#endif
|
||
|
|
||
|
for (const auto &desktop : desktopEnvs) {
|
||
|
bool ret = std::any_of(onlyShowIn.begin(), onlyShowIn.end(),
|
||
|
[&desktop](const auto &d) {return d == desktop;});
|
||
|
#ifdef QT_DEBUG
|
||
|
qInfo() << Q_FUNC_INFO << "onlyShowIn, result:" << ret;
|
||
|
#endif
|
||
|
if (ret)
|
||
|
return true;
|
||
|
|
||
|
ret = std::any_of(notShowIn.begin(), notShowIn.end(),
|
||
|
[&desktop](const auto &d) {return d == desktop;});
|
||
|
#ifdef QT_DEBUG
|
||
|
qInfo() << Q_FUNC_INFO << "notShowIn, result:" << ret;
|
||
|
#endif
|
||
|
if (ret)
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return onlyShowIn.size() == 0;
|
||
|
}
|
||
|
|
||
|
QString DesktopInfo::getExecutable()
|
||
|
{
|
||
|
return m_desktopFile->value(MainSection + '/' + KeyExec).toString();
|
||
|
}
|
||
|
|
||
|
QList<DesktopAction> DesktopInfo::getActions()
|
||
|
{
|
||
|
QList<DesktopAction> actions;
|
||
|
for (const auto &mainKey : m_desktopFile->childGroups()) {
|
||
|
if (mainKey.startsWith("Desktop Action")
|
||
|
|| mainKey.endsWith("Shortcut Group")) {
|
||
|
DesktopAction action;
|
||
|
action.name = getLocaleStr(mainKey, KeyName);
|
||
|
action.exec = m_desktopFile->value(mainKey + '/' + KeyExec).toString();
|
||
|
action.section = mainKey;
|
||
|
actions.push_back(action);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return actions;
|
||
|
}
|
||
|
|
||
|
// 使用appId获取DesktopInfo需检查有效性
|
||
|
DesktopInfo DesktopInfo::getDesktopInfoById(const QString &appId)
|
||
|
{
|
||
|
QString desktopfile(appId);
|
||
|
if (!desktopfile.endsWith(".desktop")) desktopfile.append(".desktop");
|
||
|
for (const auto & dir : QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation)) {
|
||
|
QString filePath = dir + desktopfile;
|
||
|
//检测文件有效性
|
||
|
if (QFile::exists(filePath)) {
|
||
|
return DesktopInfo(filePath);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return DesktopInfo("");
|
||
|
}
|
||
|
|
||
|
bool DesktopInfo::getTerminal()
|
||
|
{
|
||
|
return m_desktopFile->value(MainSection + '/' + KeyTerminal).toBool();
|
||
|
}
|
||
|
|
||
|
// TryExec is Path to an executable file on disk used to determine if the program is actually installed
|
||
|
QString DesktopInfo::getTryExec()
|
||
|
{
|
||
|
return m_desktopFile->value(MainSection + '/' + KeyTryExec).toString();
|
||
|
}
|
||
|
|
||
|
// 按$PATH路径查找执行文件
|
||
|
bool DesktopInfo::findExecutable(const QString &exec)
|
||
|
{
|
||
|
static const char *path = getenv("PATH");
|
||
|
static QStringList paths = QString(path).split(':');
|
||
|
return std::any_of(paths.begin(), paths.end(), [&exec](QString path) {return QFile::exists(path + '/' + exec);});
|
||
|
}
|
||
|
|
||
|
QString DesktopInfo::getGenericName()
|
||
|
{
|
||
|
return getLocaleStr(MainSection, KeyGenericName);
|
||
|
}
|
||
|
|
||
|
QString DesktopInfo::getName()
|
||
|
{
|
||
|
return m_name;
|
||
|
}
|
||
|
|
||
|
QString DesktopInfo::getIcon()
|
||
|
{
|
||
|
return m_icon;
|
||
|
}
|
||
|
|
||
|
QString DesktopInfo::getCommandLine()
|
||
|
{
|
||
|
return m_desktopFile->value(MainSection + '/' + KeyExec).toString();
|
||
|
}
|
||
|
|
||
|
QStringList DesktopInfo::getKeywords()
|
||
|
{
|
||
|
return m_desktopFile->value(MainSection + '/' + KeyKeywords).toStringList();
|
||
|
}
|
||
|
|
||
|
QStringList DesktopInfo::getCategories()
|
||
|
{
|
||
|
return m_desktopFile->value(MainSection + '/' + KeyCategories).toStringList();
|
||
|
}
|
||
|
|
||
|
QSettings *DesktopInfo::getDesktopFile()
|
||
|
{
|
||
|
return m_desktopFile.data();
|
||
|
}
|
||
|
|
||
|
QString DesktopInfo::getId()
|
||
|
{
|
||
|
return m_id;
|
||
|
}
|
||
|
|
||
|
QString DesktopInfo::getLocaleStr(const QString §ion, const QString &key)
|
||
|
{
|
||
|
QString currentLanguageCode = QLocale::system().name();
|
||
|
QString res = m_desktopFile->value(section + '/' + key + QString("[%1]").arg(currentLanguageCode)).toString();
|
||
|
if (res.isEmpty()) res = m_desktopFile->value(section + '/' + key).toString();
|
||
|
return res;
|
||
|
}
|