mirror of
https://github.com/linuxdeepin/dde-dock.git
synced 2025-06-01 07:05:48 +00:00
257 lines
7.0 KiB
C++
257 lines
7.0 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 "taskmanager/common.h"
|
||
#include "unistd.h"
|
||
|
||
#include <QDebug>
|
||
|
||
#include <algorithm>
|
||
#include <QFileInfo>
|
||
#include <QSettings>
|
||
#include <QStandardPaths>
|
||
#include <QVector>
|
||
#include <QLocale>
|
||
|
||
QStringList DesktopInfo::currentDesktops;
|
||
static QString desktopFileSuffix = ".desktop";
|
||
|
||
DesktopInfo::DesktopInfo(const QString &desktopfile)
|
||
: m_isValid(true)
|
||
, m_isInstalled(false)
|
||
{
|
||
QString desktopfilepath(desktopfile);
|
||
QFileInfo desktopFileInfo(desktopfilepath);
|
||
if (!(desktopfilepath.endsWith(desktopFileSuffix))) {
|
||
desktopfilepath = desktopfilepath + desktopFileSuffix;
|
||
desktopFileInfo.setFile(desktopfilepath);
|
||
}
|
||
|
||
auto desktopFileName = desktopFileInfo.fileName();
|
||
// 优先加载系统中的desktopfile,而不是用户传递过来的
|
||
for (auto dir: QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation)) {
|
||
QString path = dir.append("/").append(desktopFileName);
|
||
if (QFile::exists(path)){
|
||
desktopFileInfo.setFile(path);
|
||
m_isInstalled = true;
|
||
}
|
||
}
|
||
|
||
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;
|
||
}
|
||
|
||
bool DesktopInfo::isInstalled()
|
||
{
|
||
return m_isInstalled;
|
||
}
|
||
|
||
/** 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(DesktopFileActionKey)) {
|
||
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;
|
||
}
|