feat: AM 默认程序迁移

默认程序迁移到AM中

Log: 默认程序迁移到AM
Task: https://pms.uniontech.com/task-view-140029.html
Influence: 默认程序
Change-Id: I0824c503b6ab844f09b3bf3cf740565b1e4215e5
This commit is contained in:
echengqi
2022-06-15 14:14:43 +08:00
parent 2b00b9b291
commit dfa232bb98
31 changed files with 1907 additions and 66 deletions

410
src/lib/appinfo.cpp Normal file
View 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
View 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
View 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
View 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

View File

@ -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

View File

@ -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
View 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
View 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
View 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
View 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