feat: AM 默认程序迁移
默认程序迁移到AM中 Log: 默认程序迁移到AM Task: https://pms.uniontech.com/task-view-140029.html Influence: 默认程序 Change-Id: I0824c503b6ab844f09b3bf3cf740565b1e4215e5
This commit is contained in:
410
src/lib/appinfo.cpp
Normal file
410
src/lib/appinfo.cpp
Normal file
@ -0,0 +1,410 @@
|
||||
#include "appinfo.h"
|
||||
#include "utils.h"
|
||||
#include "dlocale.h"
|
||||
#include "appinfocommon.h"
|
||||
|
||||
#include <string>
|
||||
#include <gio/gio.h>
|
||||
#include <gio/gdesktopappinfo.h>
|
||||
#include <string.h>
|
||||
#include <QDir>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
|
||||
bool AppInfoManger::onceInit = false;
|
||||
std::vector<std::string> AppInfoManger::xdgDataDirs;
|
||||
std::vector<std::string> AppInfoManger::xdgAppDirs;
|
||||
|
||||
AppInfoManger::AppInfoManger()
|
||||
{
|
||||
canDelete = false;
|
||||
}
|
||||
|
||||
std::vector<std::string> AppInfoManger::getStringList(std::string session, std::string key)
|
||||
{
|
||||
return keyFile.getStrList(session, key);
|
||||
}
|
||||
|
||||
std::string AppInfoManger::toJson()
|
||||
{
|
||||
QJsonDocument doc;
|
||||
QJsonObject obj;
|
||||
|
||||
obj["Id"] = desktopId.c_str();
|
||||
obj["Name"] = appName.c_str();
|
||||
obj["DisplayName"] = displayName.c_str();
|
||||
obj["Description"] = comment.c_str();
|
||||
obj["Icon"] = icon.c_str();
|
||||
obj["Exec"] = cmdline.c_str();
|
||||
obj["CanDelete"] = canDelete;
|
||||
|
||||
if (!obj.isEmpty()) {
|
||||
doc.setObject(obj);
|
||||
}
|
||||
|
||||
return doc.toJson(QJsonDocument::Compact).toStdString();
|
||||
}
|
||||
|
||||
std::string AppInfoManger::getFileName()
|
||||
{
|
||||
return fileName;
|
||||
}
|
||||
|
||||
std::shared_ptr<AppInfoManger> AppInfoManger::loadByDesktopId(std::string desktopId)
|
||||
{
|
||||
std::shared_ptr<AppInfoManger> appInfo;
|
||||
|
||||
if (!hasEnding(desktopId, AppinfoCommon::DesktopExt)) {
|
||||
desktopId += AppinfoCommon::DesktopExt;
|
||||
}
|
||||
|
||||
if (QDir::isAbsolutePath(desktopId.c_str())) {
|
||||
appInfo = AppInfoManger::initAppInfoByFile(desktopId);
|
||||
if (appInfo) {
|
||||
appInfo->desktopId = AppInfoManger::getDesktopIdFile(desktopId);
|
||||
}
|
||||
return appInfo;
|
||||
}
|
||||
|
||||
std::vector<std::string> appDirs = AppInfoManger::getXdgAppsDirs();
|
||||
|
||||
for (auto iter : appDirs) {
|
||||
appInfo = AppInfoManger::initAppInfoByFile(iter + "/" + desktopId);
|
||||
if (appInfo) {
|
||||
appInfo->desktopId = desktopId;
|
||||
return appInfo;
|
||||
}
|
||||
}
|
||||
|
||||
return appInfo;
|
||||
}
|
||||
|
||||
std::shared_ptr<AppInfoManger> AppInfoManger::initAppInfoByFile(std::string fileName)
|
||||
{
|
||||
std::shared_ptr<AppInfoManger> appInfo;
|
||||
KeyFile keyFile;
|
||||
|
||||
bool bSuccess = keyFile.loadFile(fileName);
|
||||
if (!bSuccess) {
|
||||
return appInfo;
|
||||
}
|
||||
|
||||
std::string type = keyFile.getStr(AppinfoCommon::MainSection, AppinfoCommon::KeyType);
|
||||
|
||||
if (type != AppinfoCommon::TypeApplication) {
|
||||
return appInfo;
|
||||
}
|
||||
|
||||
appInfo = std::make_shared<AppInfoManger>();
|
||||
|
||||
appInfo->appName = getAppName(keyFile);
|
||||
appInfo->icon = AppInfoManger::getIconByKeyFile(keyFile);
|
||||
appInfo->displayName = appInfo->appName;
|
||||
appInfo->comment = keyFile.getLocaleStr(AppinfoCommon::MainSection, AppinfoCommon::KeyComment);
|
||||
appInfo->cmdline = keyFile.getStr(AppinfoCommon::MainSection, AppinfoCommon::KeyExec);
|
||||
appInfo->fileName = fileName;
|
||||
appInfo->keyFile = keyFile;
|
||||
|
||||
if (!appInfo->shouldShow()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return appInfo;
|
||||
}
|
||||
|
||||
std::string AppInfoManger::getIconByKeyFile(KeyFile& keyFile)
|
||||
{
|
||||
std::string icon = keyFile.getStr(AppinfoCommon::MainSection, AppinfoCommon::KeyIcon);
|
||||
|
||||
if (!QDir::isAbsolutePath(icon.c_str())) {
|
||||
if (hasEnding(icon, ".png")) {
|
||||
icon = icon.substr(0, icon.length() - strlen(".png"));
|
||||
}
|
||||
|
||||
if (hasEnding(icon, ".xpm")) {
|
||||
icon = icon.substr(0, icon.length() - strlen(".xpm"));
|
||||
}
|
||||
|
||||
if (hasEnding(icon, ".svg")) {
|
||||
icon = icon.substr(0, icon.length() - strlen(".svg"));
|
||||
}
|
||||
}
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
std::string AppInfoManger::getDesktopIdFile(std::string fileName)
|
||||
{
|
||||
if (hasEnding(fileName, AppinfoCommon::DesktopExt)) {
|
||||
fileName = fileName.substr(0, fileName.size() - strlen(AppinfoCommon::DesktopExt.c_str()) + 1);
|
||||
}
|
||||
|
||||
auto index = fileName.find("/applications/");
|
||||
if (index == fileName.npos) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string dir = fileName.substr(0, index);
|
||||
|
||||
std::vector<std::string> dataDIrs = AppInfoManger::getXdgDataDirs();
|
||||
|
||||
if (std::find(dataDIrs.begin(), dataDIrs.end(), dir) != dataDIrs.end()) {
|
||||
|
||||
return fileName.substr(index + 14, fileName.size() - (index + 14 + 1));
|
||||
}
|
||||
|
||||
return fileName;
|
||||
}
|
||||
|
||||
bool AppInfoManger::shouldShow()
|
||||
{
|
||||
if (!keyFile.getStr(AppinfoCommon::MainSection, AppinfoCommon::KeyNoDisplay).empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!keyFile.getStr(AppinfoCommon::MainSection, AppinfoCommon::KeyHidden).empty()) {
|
||||
return false;
|
||||
}
|
||||
QString deskEnv = getenv("XDG_CURRENT_DESKTOP");
|
||||
|
||||
auto envList = deskEnv.split(":");
|
||||
|
||||
std::vector<std::string> onlyShowIn = keyFile.getStrList(AppinfoCommon::MainSection, AppinfoCommon::KeyOnlyShowIn);
|
||||
std::vector<std::string> notShowIn = keyFile.getStrList(AppinfoCommon::MainSection, AppinfoCommon::KeyNotShowIn);
|
||||
|
||||
for (auto iter : envList) {
|
||||
if (std::find(onlyShowIn.begin(), onlyShowIn.end(), iter.toStdString()) != onlyShowIn.end()) {
|
||||
return true;
|
||||
}
|
||||
if (std::find(notShowIn.begin(), notShowIn.end(), iter.toStdString()) != notShowIn.end()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return onlyShowIn.empty();
|
||||
}
|
||||
|
||||
std::string AppInfoManger::getDefaultApp(std::string mimeType, bool supportUri)
|
||||
{
|
||||
GAppInfo* gAppInfo = g_app_info_get_default_for_type(mimeType.c_str(), supportUri);
|
||||
|
||||
if (gAppInfo == nullptr) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (supportUri && !g_app_info_supports_uris(gAppInfo)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return g_app_info_get_id(gAppInfo);
|
||||
}
|
||||
|
||||
std::vector<std::string> AppInfoManger::getAppList(std::string mimeType)
|
||||
{
|
||||
std::vector<std::string> retVector;
|
||||
GList* appInfoList = g_app_info_get_all_for_type(mimeType.c_str());
|
||||
|
||||
while (appInfoList) {
|
||||
GAppInfo* gAppInfo = static_cast<GAppInfo*>(appInfoList->data);
|
||||
|
||||
const char* appId = g_app_info_get_id(gAppInfo);
|
||||
if (appId) {
|
||||
retVector.push_back(appId);
|
||||
}
|
||||
appInfoList = appInfoList->next;
|
||||
}
|
||||
|
||||
return retVector;
|
||||
}
|
||||
|
||||
|
||||
bool AppInfoManger::getDefaultApp(std::string mimeType, std::string desktopId)
|
||||
{
|
||||
GDesktopAppInfo* gDesktopAppInfo = g_desktop_app_info_new(desktopId.c_str());
|
||||
|
||||
if (gDesktopAppInfo == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GAppInfo* gAppInfo = G_APP_INFO(gDesktopAppInfo);
|
||||
|
||||
GError* err;
|
||||
g_app_info_set_as_default_for_type(gAppInfo, mimeType.c_str(), &err);
|
||||
|
||||
if (err != nullptr) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string AppInfoManger::getAppName(KeyFile& keyFile)
|
||||
{
|
||||
std::string name;
|
||||
|
||||
std::string xDeepinVendor = keyFile.getStr(AppinfoCommon::MainSection, AppinfoCommon::DeepinVendor);
|
||||
|
||||
if (xDeepinVendor == "deepin") {
|
||||
name = keyFile.getLocaleStr(AppinfoCommon::MainSection, AppinfoCommon::KeyGenericName);
|
||||
} else {
|
||||
name = keyFile.getLocaleStr(AppinfoCommon::MainSection, AppinfoCommon::KeyName);
|
||||
}
|
||||
|
||||
if (name.empty()) {
|
||||
name = AppInfoManger::getDesktopIdFile(keyFile.getFilePath());
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
std::vector<std::string>& AppInfoManger::getXdgDataDirs()
|
||||
{
|
||||
if (!AppInfoManger::onceInit) {
|
||||
AppInfoManger::onceInit = true;
|
||||
|
||||
AppInfoManger::xdgDataDirs.push_back(getUserDataDir());
|
||||
for (auto iter : getSystemDataDirs()) {
|
||||
xdgDataDirs.push_back(iter);
|
||||
}
|
||||
|
||||
for (auto dataDir : AppInfoManger::xdgDataDirs) {
|
||||
AppInfoManger::xdgAppDirs.push_back(dataDir + "/applications");
|
||||
}
|
||||
}
|
||||
|
||||
return AppInfoManger::xdgDataDirs;
|
||||
}
|
||||
|
||||
std::vector<std::string>& AppInfoManger::getXdgAppsDirs()
|
||||
{
|
||||
if (!AppInfoManger::onceInit) {
|
||||
AppInfoManger::onceInit = true;
|
||||
|
||||
AppInfoManger::xdgDataDirs.push_back(getUserDataDir());
|
||||
|
||||
for (auto iter : getSystemDataDirs()) {
|
||||
xdgDataDirs.push_back(iter);
|
||||
}
|
||||
|
||||
for (auto dataDir : AppInfoManger::xdgDataDirs) {
|
||||
AppInfoManger::xdgAppDirs.push_back(dataDir + "/applications");
|
||||
}
|
||||
}
|
||||
|
||||
return AppInfoManger::xdgAppDirs;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<AppInfoManger>> AppInfoManger::getAll(std::map<std::string, std::vector<std::string>> skipDirs)
|
||||
{
|
||||
std::vector<std::shared_ptr<AppInfoManger>> ret;
|
||||
|
||||
std::vector<std::string> xdgAppDirs = AppInfoManger::getXdgAppsDirs();
|
||||
|
||||
std::vector<std::pair<std::string, std::map<std::string, int>>> appPathNameInfos;
|
||||
for (auto iter : xdgAppDirs) {
|
||||
std::map<std::string, int> tempMap;
|
||||
if (skipDirs.count(iter) != 0) {
|
||||
walk(iter, skipDirs[iter], tempMap);
|
||||
} else {
|
||||
std::vector<std::string> temp;
|
||||
walk(iter, temp, tempMap);
|
||||
}
|
||||
appPathNameInfos.push_back(std::make_pair(iter, tempMap));
|
||||
}
|
||||
|
||||
std::map<std::string, int> recordMap;
|
||||
|
||||
for (auto appPathNameInfo : appPathNameInfos) {
|
||||
for (auto appName : appPathNameInfo.second) {
|
||||
std::string tempAppName = appName.first;
|
||||
if (hasBeginWith(appName.first, "./")) {
|
||||
tempAppName = appName.first.substr(appName.first.find_first_of("./") + 2, appName.first.size() - 2);
|
||||
}
|
||||
if (recordMap.count(tempAppName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::shared_ptr<AppInfoManger> appInfo = AppInfoManger::loadByDesktopId(appPathNameInfo.first + "/" + tempAppName);
|
||||
if (!appInfo) {
|
||||
continue;
|
||||
}
|
||||
|
||||
recordMap[tempAppName] = 0;
|
||||
|
||||
if (appInfo->shouldShow()) {
|
||||
ret.push_back(appInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
std::string AppInfoManger::getDesktopId()
|
||||
{
|
||||
return desktopId;
|
||||
}
|
||||
|
||||
std::string AppInfoManger::getAppName()
|
||||
{
|
||||
return appName;
|
||||
}
|
||||
std::string AppInfoManger::getDisplayName()
|
||||
{
|
||||
return displayName;
|
||||
}
|
||||
std::string AppInfoManger::getComment()
|
||||
{
|
||||
return comment;
|
||||
}
|
||||
std::string AppInfoManger::getIcon()
|
||||
{
|
||||
return icon;
|
||||
}
|
||||
|
||||
std::string AppInfoManger::getCmdline()
|
||||
{
|
||||
return cmdline;
|
||||
}
|
||||
|
||||
bool AppInfoManger::getCanDelete()
|
||||
{
|
||||
return canDelete;
|
||||
}
|
||||
|
||||
void AppInfoManger::setCanDelete(bool bCanDelete)
|
||||
{
|
||||
canDelete = bCanDelete;
|
||||
}
|
||||
std::vector<std::string> AppInfoManger::getCategories()
|
||||
{
|
||||
return keyFile.getStrList(AppinfoCommon::MainSection, AppinfoCommon::KeyCategories);
|
||||
}
|
||||
|
||||
void AppInfoManger::setDesktopId(std::string desktopId)
|
||||
{
|
||||
this->desktopId = desktopId;
|
||||
}
|
||||
|
||||
std::string AppInfoManger::toJson(std::vector<std::shared_ptr<AppInfoManger>> appInfos)
|
||||
{
|
||||
QJsonDocument doc;
|
||||
QJsonObject obj;
|
||||
QJsonArray arr;
|
||||
for (auto iter : appInfos) {
|
||||
obj["Id"] = iter->getDesktopId().c_str();
|
||||
obj["Name"] = iter->getAppName().c_str();
|
||||
obj["DisplayName"] = iter->getDisplayName().c_str();
|
||||
obj["Description"] = iter->getComment().c_str();
|
||||
obj["Icon"] = iter->getIcon().c_str();
|
||||
obj["Exec"] = iter->getCmdline().c_str();
|
||||
obj["CanDelete"] = iter->getCanDelete();
|
||||
arr.push_back(obj);
|
||||
}
|
||||
|
||||
if (!arr.empty()) {
|
||||
doc.setArray(arr);
|
||||
}
|
||||
|
||||
return doc.toJson(QJsonDocument::Compact).toStdString();
|
||||
}
|
56
src/lib/appinfo.h
Normal file
56
src/lib/appinfo.h
Normal file
@ -0,0 +1,56 @@
|
||||
#ifndef APPINFO_H
|
||||
#define APPINFO_H
|
||||
|
||||
#include "keyfile.h"
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
class AppInfoManger
|
||||
{
|
||||
public:
|
||||
AppInfoManger();
|
||||
std::vector<std::string> getStringList(std::string session, std::string key);
|
||||
std::string toJson();
|
||||
std::string getFileName();
|
||||
static std::shared_ptr<AppInfoManger> loadByDesktopId(std::string desktopId);
|
||||
static std::string getDefaultApp(std::string mimeType, bool supportUri);
|
||||
static std::vector<std::string> getAppList(std::string mimeType);
|
||||
static bool getDefaultApp(std::string mimeType, std::string desktopId);
|
||||
static std::vector<std::string>& getXdgDataDirs();
|
||||
static std::vector<std::string>& getXdgAppsDirs();
|
||||
static std::vector<std::shared_ptr<AppInfoManger>> getAll(std::map<std::string, std::vector<std::string>> skipDirs);
|
||||
std::string getDesktopId();
|
||||
std::string getAppName();
|
||||
std::string getDisplayName();
|
||||
std::string getComment();
|
||||
std::string getIcon();
|
||||
std::string getCmdline();
|
||||
bool getCanDelete();
|
||||
void setCanDelete(bool bCanDelete);
|
||||
std::vector<std::string> getCategories();
|
||||
void setDesktopId(std::string desktopId);
|
||||
static std::string toJson(std::vector<std::shared_ptr<AppInfoManger>> appInfos);
|
||||
|
||||
private:
|
||||
static std::shared_ptr<AppInfoManger> initAppInfoByFile(std::string fileName);
|
||||
static std::string getAppName(KeyFile& keyFile);
|
||||
static std::string getIconByKeyFile(KeyFile& keyFile);
|
||||
static std::string getDesktopIdFile(std::string fileName);
|
||||
bool shouldShow();
|
||||
private:
|
||||
std::string desktopId;
|
||||
std::string appName;
|
||||
std::string displayName;
|
||||
std::string comment;
|
||||
std::string icon;
|
||||
std::string cmdline;
|
||||
bool canDelete;
|
||||
std::string fileName;
|
||||
KeyFile keyFile;
|
||||
static std::vector<std::string> xdgDataDirs;
|
||||
static std::vector<std::string> xdgAppDirs;
|
||||
static bool onceInit;
|
||||
};
|
||||
|
||||
#endif // APPINFO_H
|
40
src/lib/appinfocommon.cpp
Normal file
40
src/lib/appinfocommon.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
#include "appinfocommon.h"
|
||||
|
||||
const std::string AppinfoCommon::MainSection = "Desktop Entry";
|
||||
const std::string AppinfoCommon::KeyType = "Type";
|
||||
const std::string AppinfoCommon::KeyVersion = "Version";
|
||||
const std::string AppinfoCommon::KeyName = "Name";
|
||||
const std::string AppinfoCommon::KeyGenericName = "GenericName";
|
||||
const std::string AppinfoCommon::KeyNoDisplay = "NoDisplay";
|
||||
const std::string AppinfoCommon::KeyComment = "Comment";
|
||||
const std::string AppinfoCommon::KeyIcon = "Icon";
|
||||
const std::string AppinfoCommon::KeyHidden = "Hidden";
|
||||
const std::string AppinfoCommon::KeyOnlyShowIn = "OnlyShowIn";
|
||||
const std::string AppinfoCommon::KeyNotShowIn = "NotShowIn";
|
||||
const std::string AppinfoCommon::KeyTryExec = "TryExec";
|
||||
const std::string AppinfoCommon::KeyExec = "Exec";
|
||||
const std::string AppinfoCommon::KeyPath = "Path";
|
||||
const std::string AppinfoCommon::KeyTerminal = "Terminal";
|
||||
const std::string AppinfoCommon::KeyMimeType = "MimeType";
|
||||
const std::string AppinfoCommon::KeyCategories = "Categories";
|
||||
const std::string AppinfoCommon::KeyKeywords = "Keywords";
|
||||
const std::string AppinfoCommon::KeyStartupNotify = "StartupNotify";
|
||||
const std::string AppinfoCommon::KeyStartupWMClass = "StartupWMClass";
|
||||
const std::string AppinfoCommon::KeyURL = "URL";
|
||||
const std::string AppinfoCommon::KeyActions = "Actions";
|
||||
const std::string AppinfoCommon::KeyDBusActivatable = "DBusActivatable";
|
||||
|
||||
const std::string AppinfoCommon::TypeApplication = "Application";
|
||||
const std::string AppinfoCommon::TypeLink = "Link";
|
||||
const std::string AppinfoCommon::TypeDirectory = "Directory";
|
||||
|
||||
const std::string AppinfoCommon::EnvDesktopEnv = "XDG_CURRENT_DESKTOP";
|
||||
const std::string AppinfoCommon::DesktopExt = ".desktop";
|
||||
const std::string AppinfoCommon::GsSchemaStartdde = "com.deepin.dde.startdde";
|
||||
const std::string AppinfoCommon::EnableInvoker = "ENABLE_TURBO_INVOKER";
|
||||
const std::string AppinfoCommon::TurboInvokerFailedMsg = "Failed to invoke: Booster:";
|
||||
const std::string AppinfoCommon::TurboInvokerErrMsg = "deepin-turbo-invoker: error";
|
||||
const std::string AppinfoCommon::SectionDefaultApps = "Default Applications";
|
||||
const std::string AppinfoCommon::SectionAddedAssociations = "Added Associations";
|
||||
const std::string AppinfoCommon::DeepinVendor = "X-Deepin-Vendor";
|
||||
const std::string AppinfoCommon::AppMimeTerminal = "application/x-terminal";
|
48
src/lib/appinfocommon.h
Normal file
48
src/lib/appinfocommon.h
Normal file
@ -0,0 +1,48 @@
|
||||
#ifndef APPINFOCOMMON_H
|
||||
#define APPINFOCOMMON_H
|
||||
#include <string>
|
||||
|
||||
class AppinfoCommon
|
||||
{
|
||||
public:
|
||||
const static std::string MainSection;
|
||||
const static std::string KeyType;
|
||||
const static std::string KeyVersion;
|
||||
const static std::string KeyName;
|
||||
const static std::string KeyGenericName;
|
||||
const static std::string KeyNoDisplay;
|
||||
const static std::string KeyComment;
|
||||
const static std::string KeyIcon;
|
||||
const static std::string KeyHidden;
|
||||
const static std::string KeyOnlyShowIn;
|
||||
const static std::string KeyNotShowIn;
|
||||
const static std::string KeyTryExec;
|
||||
const static std::string KeyExec;
|
||||
const static std::string KeyPath;
|
||||
const static std::string KeyTerminal;
|
||||
const static std::string KeyMimeType;
|
||||
const static std::string KeyCategories;
|
||||
const static std::string KeyKeywords;
|
||||
const static std::string KeyStartupNotify;
|
||||
const static std::string KeyStartupWMClass;
|
||||
const static std::string KeyURL;
|
||||
const static std::string KeyActions;
|
||||
const static std::string KeyDBusActivatable;
|
||||
|
||||
const static std::string TypeApplication;
|
||||
const static std::string TypeLink;
|
||||
const static std::string TypeDirectory;
|
||||
|
||||
const static std::string EnvDesktopEnv;
|
||||
const static std::string DesktopExt;
|
||||
const static std::string GsSchemaStartdde;
|
||||
const static std::string EnableInvoker;
|
||||
const static std::string TurboInvokerFailedMsg;
|
||||
const static std::string TurboInvokerErrMsg;
|
||||
const static std::string SectionDefaultApps;
|
||||
const static std::string SectionAddedAssociations;
|
||||
const static std::string DeepinVendor ;
|
||||
const static std::string AppMimeTerminal;
|
||||
};
|
||||
|
||||
#endif // APPINFOCOMMON_H
|
@ -44,8 +44,8 @@ public:
|
||||
static std::string userAutoStartDir();
|
||||
|
||||
private:
|
||||
static void filterNotAbs(std::vector<std::string> &dirs);
|
||||
static void addSuffixSlash(std::vector<std::string> &dirs);
|
||||
static void filterNotAbs(std::vector<std::string>& dirs);
|
||||
static void addSuffixSlash(std::vector<std::string>& dirs);
|
||||
};
|
||||
|
||||
#endif // BASEDIR_H
|
||||
|
@ -54,6 +54,10 @@ public:
|
||||
bool saveToFile(const std::string &filePath);
|
||||
bool loadFile(const std::string &filePath);
|
||||
std::vector<std::string> getMainKeys();
|
||||
std::string getFilePath()
|
||||
{
|
||||
return m_filePath;
|
||||
}
|
||||
|
||||
// for test
|
||||
void print();
|
||||
|
160
src/lib/terminalinfo.cpp
Normal file
160
src/lib/terminalinfo.cpp
Normal file
@ -0,0 +1,160 @@
|
||||
#include "terminalinfo.h"
|
||||
#include "utils.h"
|
||||
#include "appinfocommon.h"
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
TerminalInfo& TerminalInfo::getInstanceTerminal()
|
||||
{
|
||||
static TerminalInfo terminal;
|
||||
|
||||
return terminal;
|
||||
}
|
||||
|
||||
TerminalInfo::TerminalInfo()
|
||||
: gsSchemaDefaultTerminal("com.deepin.desktop.default-applications.terminal")
|
||||
, gsKeyExec("exec")
|
||||
, gsKeyExecArg("exec-arg")
|
||||
, gsKeyAppId("app-id")
|
||||
, categoryTerminalEmulator("TerminalEmulator")
|
||||
, execXTerminalEmulator("x-terminal-emulator")
|
||||
, defaultTerminal(new QGSettings(gsSchemaDefaultTerminal.c_str()))
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
void TerminalInfo::resetTerminal()
|
||||
{
|
||||
defaultTerminal->reset(gsKeyExec.c_str());
|
||||
defaultTerminal->reset(gsKeyExecArg.c_str());
|
||||
defaultTerminal->reset(gsKeyExecArg.c_str());
|
||||
}
|
||||
|
||||
std::string TerminalInfo::getPresetTerminalPath()
|
||||
{
|
||||
std::string path;
|
||||
|
||||
for (auto term : terms) {
|
||||
path = lookPath(term);
|
||||
if (!path.empty()) {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void TerminalInfo::init()
|
||||
{
|
||||
termBlackList = {"guake",
|
||||
"tilda",
|
||||
"org.kde.yakuake",
|
||||
"qterminal_drop",
|
||||
"Terminal"
|
||||
};
|
||||
|
||||
execArgMap = {{"gnome-terminal", "-x"},
|
||||
{"mate-terminal", "-x"},
|
||||
{"terminator", "-x"},
|
||||
{"xfce4-terminal", "-x"}
|
||||
};
|
||||
|
||||
terms = {"deepin-terminal",
|
||||
"gnome-terminal",
|
||||
"terminator",
|
||||
"xfce4-terminal",
|
||||
"rxvt",
|
||||
"xterm"
|
||||
};
|
||||
}
|
||||
std::shared_ptr<AppInfoManger> TerminalInfo::getDefaultTerminal()
|
||||
{
|
||||
|
||||
std::string appId = defaultTerminal->get(gsKeyAppId.c_str()).toString().toStdString();
|
||||
|
||||
if (!hasEnding(appId, AppinfoCommon::DesktopExt)) {
|
||||
appId += AppinfoCommon::DesktopExt;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<AppInfoManger>> appInfos = getTerminalInfos();
|
||||
|
||||
for (auto iter : appInfos) {
|
||||
if (iter->getDesktopId() == appId) {
|
||||
return iter;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto appInfo : appInfos) {
|
||||
for (auto term : terms) {
|
||||
if (appInfo->getCmdline() == term) {
|
||||
return appInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool TerminalInfo::setDefaultTerminal(std::string id)
|
||||
{
|
||||
std::vector<std::shared_ptr<AppInfoManger>> appInfos = getTerminalInfos();
|
||||
|
||||
for (auto iter : appInfos) {
|
||||
if (iter->getDesktopId() == id) {
|
||||
std::string cmdline = iter->getCmdline();
|
||||
std::string exec = cmdline.substr(0, cmdline.find(" "));
|
||||
defaultTerminal->set(gsKeyExec.c_str(), exec.c_str());
|
||||
|
||||
std::string arg = "-e";
|
||||
if (execArgMap.count(exec) != 0) {
|
||||
arg = execArgMap[exec];
|
||||
}
|
||||
defaultTerminal->set(gsKeyExecArg.c_str(), arg.c_str());
|
||||
|
||||
if (hasEnding(id, AppinfoCommon::DesktopExt)) {
|
||||
id = id.substr(0, id.find(AppinfoCommon::DesktopExt));
|
||||
}
|
||||
defaultTerminal->set(gsKeyAppId.c_str(), id.c_str());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<AppInfoManger>> TerminalInfo::getTerminalInfos()
|
||||
{
|
||||
std::map<std::string, std::vector<std::string>> skipDirs;
|
||||
std::vector<std::shared_ptr<AppInfoManger>> appInfos = AppInfoManger::getAll(skipDirs);
|
||||
|
||||
std::vector<std::shared_ptr<AppInfoManger>>::iterator iter = appInfos.begin();
|
||||
|
||||
while (iter != appInfos.end()) {
|
||||
if (isTerminalApp(*iter)) {
|
||||
(*iter)->setDesktopId((*iter)->getDesktopId() + AppinfoCommon::DesktopExt);
|
||||
iter++;
|
||||
} else {
|
||||
iter = appInfos.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
return appInfos;
|
||||
}
|
||||
|
||||
bool TerminalInfo::isTerminalApp(std::shared_ptr<AppInfoManger> appInfo)
|
||||
{
|
||||
if (std::find(termBlackList.begin(), termBlackList.end(), appInfo->getDesktopId()) != termBlackList.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<std::string> categories = appInfo->getCategories();
|
||||
if (std::find(categories.begin(), categories.end(), categoryTerminalEmulator) == categories.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string cmdline = appInfo->getCmdline();
|
||||
if (cmdline.find(execXTerminalEmulator) != std::string::npos) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
43
src/lib/terminalinfo.h
Normal file
43
src/lib/terminalinfo.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef TERMINALINFO_H
|
||||
#define TERMINALINFO_H
|
||||
|
||||
#include "appinfo.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <QGSettings>
|
||||
|
||||
class TerminalInfo
|
||||
{
|
||||
public:
|
||||
static TerminalInfo& getInstanceTerminal();
|
||||
void resetTerminal();
|
||||
std::string getPresetTerminalPath();
|
||||
bool setDefaultTerminal(std::string id);
|
||||
std::shared_ptr<AppInfoManger> getDefaultTerminal();
|
||||
std::vector<std::shared_ptr<AppInfoManger>> getTerminalInfos();
|
||||
TerminalInfo(const TerminalInfo& term) = delete;
|
||||
TerminalInfo& operator=(const TerminalInfo& term) = delete;
|
||||
|
||||
private:
|
||||
TerminalInfo();
|
||||
void init();
|
||||
|
||||
bool isTerminalApp(std::shared_ptr<AppInfoManger> appInfo);
|
||||
|
||||
private:
|
||||
|
||||
std::vector<std::string> termBlackList;
|
||||
std::map<std::string, std::string> execArgMap;
|
||||
std::vector<std::string> terms;
|
||||
const std::string gsSchemaDefaultTerminal;
|
||||
const std::string gsKeyExec;
|
||||
const std::string gsKeyExecArg;
|
||||
const std::string gsKeyAppId;
|
||||
const std::string categoryTerminalEmulator;
|
||||
const std::string execXTerminalEmulator;
|
||||
std::shared_ptr<QGSettings> defaultTerminal;
|
||||
};
|
||||
|
||||
#endif // TERMINALINFO_H
|
198
src/lib/utils.cpp
Normal file
198
src/lib/utils.cpp
Normal file
@ -0,0 +1,198 @@
|
||||
#include "utils.h"
|
||||
|
||||
#define HOME "HOME"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
std::string getUserDir(const char* envName);
|
||||
std::vector<std::string> getSystemDirs(const char* envName);
|
||||
|
||||
std::string getUserHomeDir()
|
||||
{
|
||||
const char* dir = getenv(HOME);
|
||||
|
||||
if (dir) {
|
||||
return dir;
|
||||
}
|
||||
|
||||
struct passwd* user = getpwent();
|
||||
if (user) {
|
||||
return user->pw_dir;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string getUserDataDir()
|
||||
{
|
||||
// default $HOME/.local/share
|
||||
std::string userDataDir = getUserDir("XDG_DATA_HOME");
|
||||
|
||||
if (userDataDir.empty()) {
|
||||
userDataDir = getUserHomeDir();
|
||||
if (!userDataDir.empty()) {
|
||||
userDataDir += "/.local/share";
|
||||
}
|
||||
}
|
||||
return userDataDir;
|
||||
}
|
||||
|
||||
std::string getUserConfigDir()
|
||||
{
|
||||
// default $HOME/.config
|
||||
std::string userConfigDir = getUserDir("XDG_CONFIG_HOME");
|
||||
|
||||
if (userConfigDir.empty()) {
|
||||
userConfigDir = getUserHomeDir();
|
||||
if (!userConfigDir.empty()) {
|
||||
userConfigDir += "/.config";
|
||||
}
|
||||
|
||||
}
|
||||
return userConfigDir;
|
||||
}
|
||||
|
||||
std::string getUserDir(const char* envName)
|
||||
{
|
||||
const char* envDir = getenv(envName);
|
||||
if (!envDir) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (!QDir::isAbsolutePath(envDir)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return envDir;
|
||||
}
|
||||
|
||||
std::vector<std::string> getSystemDataDirs()
|
||||
{
|
||||
std::vector<std::string> systemDir = getSystemDirs("XDG_DATA_DIRS");
|
||||
|
||||
if (systemDir.empty()) {
|
||||
systemDir.push_back({"/usr/local/share", "/usr/share"});
|
||||
}
|
||||
|
||||
return systemDir;
|
||||
}
|
||||
|
||||
std::vector<std::string> getSystemConfigDirs()
|
||||
{
|
||||
std::vector<std::string> systemDir = getSystemDirs("XDG_CONFIG_DIRS");
|
||||
|
||||
if (systemDir.empty()) {
|
||||
systemDir.push_back("/etc/xdg");
|
||||
}
|
||||
|
||||
return systemDir;
|
||||
}
|
||||
|
||||
std::vector<std::string> getSystemDirs(const char* envName)
|
||||
{
|
||||
std::vector<std::string> dirVector;
|
||||
const char* envDir = getenv(envName);
|
||||
if (envDir == nullptr) {
|
||||
return dirVector;
|
||||
}
|
||||
|
||||
QString tempDirs(envDir);
|
||||
auto tempList = tempDirs.split(":");
|
||||
|
||||
for (auto iter : tempList) {
|
||||
if (QDir::isAbsolutePath(iter)) {
|
||||
dirVector.push_back(iter.toStdString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return dirVector;
|
||||
}
|
||||
|
||||
std::string lookPath(std::string file)
|
||||
{
|
||||
std::string path;
|
||||
|
||||
if (file.find("/") != std::string::npos) {
|
||||
if (access(path.c_str(), X_OK) != -1) {
|
||||
return file;
|
||||
} else {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
char* pathEnv = getenv("PATH");
|
||||
|
||||
char* temp = strtok(pathEnv, ";");
|
||||
|
||||
while (temp) {
|
||||
path = std::string(temp) + "/" + file;
|
||||
|
||||
if (access(path.c_str(), X_OK) != -1) {
|
||||
return path;
|
||||
} else {
|
||||
path = "";
|
||||
temp = strtok(nullptr, "/");
|
||||
}
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
void walk(std::string root, std::vector<std::string>& skipdir, std::map<std::string, int>& retMap)
|
||||
{
|
||||
walk(root, ".", skipdir, retMap);
|
||||
}
|
||||
|
||||
void walk(std::string root, std::string name, std::vector<std::string>& skipdir, std::map<std::string, int>& retMap)
|
||||
{
|
||||
QDir dir(root.c_str());
|
||||
|
||||
if (dir.exists()) {
|
||||
if (std::find(skipdir.begin(), skipdir.end(), name) != skipdir.end()) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasEnding(name, ".desktop")) {
|
||||
retMap[name] = 0;
|
||||
}
|
||||
|
||||
std::string path = root + "/" + name;
|
||||
QDir temp(path.c_str());
|
||||
|
||||
QStringList entryList = temp.entryList();
|
||||
for (auto iter : entryList) {
|
||||
QFile file(iter);
|
||||
|
||||
if (file.exists()) {
|
||||
continue;
|
||||
}
|
||||
walk(root, name + "/" + iter.toStdString(), skipdir, retMap);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool hasEnding(std::string const& fullString, std::string const& ending)
|
||||
{
|
||||
if (fullString.length() >= ending.length()) {
|
||||
return fullString.compare(fullString.length() - ending.length(), ending.length(), ending) == 0;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool hasBeginWith(std::string const& fullString, std::string const& ending)
|
||||
{
|
||||
if (fullString.length() >= ending.length()) {
|
||||
return (0 == fullString.compare(0, ending.length(), ending));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
32
src/lib/utils.h
Normal file
32
src/lib/utils.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
#include <string>
|
||||
#include <pwd.h>
|
||||
#include <QDir>
|
||||
#include <vector>
|
||||
|
||||
std::string getUserHomeDir();
|
||||
|
||||
std::string getUserDataDir();
|
||||
|
||||
std::string getUserConfigDir();
|
||||
|
||||
std::string getUserDir(const char* envName);
|
||||
|
||||
std::vector<std::string> getSystemDataDirs();
|
||||
|
||||
std::vector<std::string> getSystemConfigDirs();
|
||||
|
||||
std::vector<std::string> getSystemDirs(const char* envName);
|
||||
|
||||
std::string lookPath(std::string file);
|
||||
|
||||
void walk(std::string root, std::vector<std::string>& skipdir, std::map<std::string, int>& retMap);
|
||||
|
||||
void walk(std::string root, std::string name, std::vector<std::string>& skipdir, std::map<std::string, int>& retMap);
|
||||
|
||||
bool hasEnding(std::string const& fullString, std::string const& ending);
|
||||
|
||||
bool hasBeginWith(std::string const& fullString, std::string const& ending);
|
||||
#endif // UTILS_H
|
||||
|
Reference in New Issue
Block a user