From 3db2c1a45909cb8360d4fe3a090aa1f4b3ab24d6 Mon Sep 17 00:00:00 2001 From: Boyuan Yang Date: Wed, 21 Nov 2018 10:14:32 -0500 Subject: [PATCH] New upstream version 2.0.9.9 --- .gitignore | 2 + CHANGELOG.md | 19 +++ src/dsysinfo.cpp | 18 ++- src/src.pro | 1 + src/util/DRecentManager | 1 + src/util/drecentmanager.cpp | 250 ++++++++++++++++++++++++++++++++++++ src/util/drecentmanager.h | 47 +++++++ src/util/util.pri | 9 +- 8 files changed, 340 insertions(+), 7 deletions(-) create mode 100644 src/util/DRecentManager create mode 100644 src/util/drecentmanager.cpp create mode 100644 src/util/drecentmanager.h diff --git a/.gitignore b/.gitignore index fd215d3..ed3c17f 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,5 @@ cmake/DtkCore/DtkCoreConfig.cmake src/qt_lib_d*.pri bin/ +.qmake* +tools/deepin-os-release/Makefile \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 422ab19..7755499 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,22 @@ + +## 2.0.9.9 (2018-11-19) + + +#### Features + +* add DRecentManager class. ([a2defafd](https://github.com/linuxdeepin/dtkcore/commit/a2defafdcf57078461221c665e322287a43d24a8)) + +#### Bug Fixes + +* compatibility with Qt 5.6 ([0ec7f3ce](https://github.com/linuxdeepin/dtkcore/commit/0ec7f3ce389b323ecb2b103801c1cd1d55f100fa)) +* **drecentmanager:** + * xbel file does not exist. ([c57ffe71](https://github.com/linuxdeepin/dtkcore/commit/c57ffe714f26b1a8a8859e2ffbeeed3d75ee11a1)) + * uniform url format. ([413a8988](https://github.com/linuxdeepin/dtkcore/commit/413a8988116708ab8bcf9efbb9bc8f52e048efa5)) + * url encoded. ([e234a8cc](https://github.com/linuxdeepin/dtkcore/commit/e234a8cc5ad9d2c14a16950838115c4f2f27c605)) +* **recent:** chinese doc ([fb256461](https://github.com/linuxdeepin/dtkcore/commit/fb256461d1bdb0862b1a3a129978fc3932a6bcab)) + + + ## 2.0.9.8 (2018-11-09) diff --git a/src/dsysinfo.cpp b/src/dsysinfo.cpp index 1fbdb7d..32ae9c4 100644 --- a/src/dsysinfo.cpp +++ b/src/dsysinfo.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -329,21 +330,30 @@ void DSysInfoPrivate::ensureComputerInfo() const QByteArray &diskStatusJson = lsblk.readAllStandardOutput(); QJsonDocument diskStatus = QJsonDocument::fromJson(diskStatusJson); - QJsonValue diskStatusJsonValue = diskStatus["blockdevices"]; + QJsonValue diskStatusJsonValue = diskStatus.object().value("blockdevices"); QMap> deviceParentAndSizeMap; if (!diskStatusJsonValue.isUndefined()) { QJsonArray diskStatusArray = diskStatusJsonValue.toArray(); QString keyName; + for (const QJsonValue &oneValue : diskStatusArray) { - if (keyName.isNull() && deviceName == oneValue["name"].toString()) { - keyName = oneValue["kname"].toString(); + QString name = oneValue.toObject().value("name").toString(); + QString kname = oneValue.toObject().value("kname").toString(); + QString pkname = oneValue.toObject().value("pkname").toString(); + qulonglong size = oneValue.toObject().value("size").toVariant().toULongLong(); + + if (keyName.isNull() && deviceName == name) { + keyName = kname; } - deviceParentAndSizeMap[oneValue["kname"].toString()] = QPair(oneValue["pkname"].toString(), oneValue["size"].toString().toULongLong()); + + deviceParentAndSizeMap[kname] = QPair(pkname, size); } + while (!deviceParentAndSizeMap[keyName].first.isNull()) { keyName = deviceParentAndSizeMap[keyName].first; } + diskSize = deviceParentAndSizeMap[keyName].second; } #endif diff --git a/src/src.pro b/src/src.pro index 1c939b3..75ad2a8 100644 --- a/src/src.pro +++ b/src/src.pro @@ -1,5 +1,6 @@ QT -= gui QT += dbus +QT += xml CONFIG += link_pkgconfig TARGET = dtkcore diff --git a/src/util/DRecentManager b/src/util/DRecentManager new file mode 100644 index 0000000..a1be4b0 --- /dev/null +++ b/src/util/DRecentManager @@ -0,0 +1 @@ +#include "drecentmanager.h" diff --git a/src/util/drecentmanager.cpp b/src/util/drecentmanager.cpp new file mode 100644 index 0000000..5d6a0ee --- /dev/null +++ b/src/util/drecentmanager.cpp @@ -0,0 +1,250 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: rekols + * + * Maintainer: rekols + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "drecentmanager.h" +#include +#include +#include +#include +#include +#include +#include +#include + +DCORE_BEGIN_NAMESPACE + +#define RECENT_PATH QDir::homePath() + "/.local/share/recently-used.xbel" + +/*! + * \~chinese \class DRecentManager + * + * \~chinese \brief DRecentManager 是用来管理最近文件列表的类,提供了添加与删除文件项。 + * \~chinese + * \~chinese 遵循 freedesktop 标准,在本地 share 目录存放,文件名为: recently-used.xbel,所以每个用户都有不同的列表。 + * \~chinese + * \~chinese 该类的存在就是为 deepin 应用提供一个工具类,方便让打开的文件添加到最近文件列表中。 + */ + +/*! + * \~chinese \struct DRecentData + * \~chinese \brief 文件信息结构体 + * \~chinese \var appName 应用名称 + * \~chinese \var appExec 应用命令行名称 + * \~chinese \var mimeType 文件 mimetype 名称,一般不需要填写,DRecentManager 内部自动获取 + */ + +/*! + * \~chinese \brief DRecentManager::addItem 在最近列表中添加一个项 + * \~chinese \param uri 文件路径 + * \~chinese \param data 数据信息 + * \~chinese \return 如果返回 true 则成功添加,false 为添加失败 + */ + +bool DRecentManager::addItem(const QString &uri, DRecentData &data) +{ + if (!QFileInfo(uri).exists() || uri.isEmpty()) { + return false; + } + + QFile file(RECENT_PATH); + file.open(QIODevice::ReadWrite | QIODevice::Text); + + QString dateTime = QDateTime::currentDateTime().toTimeSpec(Qt::OffsetFromUTC).toString(Qt::ISODate); + QDomDocument doc; + + if (!doc.setContent(&file)) { + doc.clear(); + doc.appendChild(doc.createProcessingInstruction("xml","version=\'1.0\' encoding=\'utf-8\'")); + QDomElement xbelEle = doc.createElement("xbel"); + xbelEle.setAttribute("xmlns:mime", "http://www.freedesktop.org/standards/shared-mime-info"); + xbelEle.setAttribute("version", "1.0"); + xbelEle.setAttribute("xmlns:bookmark", "http://www.freedesktop.org/standards/desktop-bookmarks"); + doc.appendChild(xbelEle); + } + file.close(); + + // need to add file:// protocol. + QUrl url(uri); + url.setScheme("file"); + + // get the MimeType name of the file. + if (data.mimeType.isEmpty()) { + data.mimeType = QMimeDatabase().mimeTypeForFile(uri).name(); + } + + QDomElement rootEle = doc.documentElement(); + QDomNodeList nodeList = rootEle.elementsByTagName("bookmark"); + QDomElement bookmarkEle; + bool isFound = false; + + // find bookmark element exists. + for (int i = 0; i < nodeList.size(); ++i) { + const QString fileUrl = nodeList.at(i).toElement().attribute("href"); + + if (fileUrl == url.toString()) { + bookmarkEle = nodeList.at(i).toElement(); + isFound = true; + break; + } + } + + // update element content. + if (isFound) { + QDomNodeList appList = bookmarkEle.elementsByTagName("bookmark:application"); + QDomElement appEle; + bool appExists = false; + + for (int i = 0; i < appList.size(); ++i) { + appEle = appList.at(i).toElement(); + + if (appEle.attribute("name") == data.appName && + appEle.attribute("exec") == data.appExec) { + appExists = true; + break; + } + } + + if (appExists) { + int count = appEle.attribute("count").toInt() + 1; + bookmarkEle.setAttribute("modified", dateTime); + bookmarkEle.setAttribute("visited", dateTime); + appEle.setAttribute("modified", dateTime); + appEle.setAttribute("count", QString::number(count)); + } else { + QDomNode appsNode = bookmarkEle.elementsByTagName("bookmark:applications").at(0); + + appEle = doc.createElement("bookmark:application"); + appEle.setAttribute("name", data.appName); + appEle.setAttribute("exec", data.appExec); + appEle.setAttribute("modified", dateTime); + appEle.setAttribute("count", "1"); + appsNode.toElement().appendChild(appEle); + } + } + // add new elements if they don't exist. + else { + QDomElement bookmarkEle, infoEle, metadataEle, mimeEle, appsEle, appChildEle; + QString hrefStr = QString::fromLatin1(url.toEncoded(QUrl::FullyEncoded)); + + bookmarkEle = doc.createElement("bookmark"); + bookmarkEle.setAttribute("href", hrefStr); + bookmarkEle.setAttribute("added", dateTime); + bookmarkEle.setAttribute("modified", dateTime); + bookmarkEle.setAttribute("visited", dateTime); + + infoEle = doc.createElement("info"); + bookmarkEle.appendChild(infoEle); + + metadataEle = doc.createElement("metadata"); + metadataEle.setAttribute("owner", "http://freedesktop.org"); + infoEle.appendChild(metadataEle); + + mimeEle = doc.createElement("mime:mime-type"); + mimeEle.setAttribute("type", data.mimeType); + metadataEle.appendChild(mimeEle); + + appsEle = doc.createElement("bookmark:applications"); + appChildEle = doc.createElement("bookmark:application"); + appChildEle.setAttribute("name", data.appName); + appChildEle.setAttribute("exec", data.appExec); + appChildEle.setAttribute("modified", dateTime); + appChildEle.setAttribute("count", "1"); + + appsEle.appendChild(appChildEle); + metadataEle.appendChild(appsEle); + + QDomNode result = rootEle.appendChild(bookmarkEle); + if (result.isNull()) { + return false; + } + } + + // write to file. + if (!file.open(QIODevice::WriteOnly)) { + return false; + } + + QTextStream out(&file); + out.setCodec("UTF-8"); + out << doc.toString(); + out.flush(); + file.close(); + + return true; +} + +/*! + * \~chinese \brief DRecentManager::removeItem 在最近列表中移除单个文件路径 + * \~chinese \param target 需要移除的文件路径 + */ + +void DRecentManager::removeItem(const QString &target) +{ + removeItems(QStringList() << target); +} + +/*! + * \~chinese \brief DRecentManager::removeItem 在最近列表中移除多个文件路径 + * \~chinese \param list 需要移除的文件路径列表 + */ + +void DRecentManager::removeItems(const QStringList &list) +{ + QFile file(RECENT_PATH); + + if (!file.open(QIODevice::ReadOnly)) { + return; + } + + QDomDocument doc; + if (!doc.setContent(&file)) { + file.close(); + return; + } + file.close(); + + QDomElement rootEle = doc.documentElement(); + QDomNodeList nodeList = rootEle.elementsByTagName("bookmark"); + + for (int i = 0; i < nodeList.count(); ) { + const QString fileUrl = nodeList.at(i).toElement().attribute("href"); + + if (list.contains(QUrl::fromPercentEncoding(fileUrl.toUtf8()))) { + rootEle.removeChild(nodeList.at(i)); + } else { + ++i; + } + } + + if (!file.open(QIODevice::WriteOnly)) { + return; + } + + QTextStream out(&file); + out.setCodec("UTF-8"); + out << doc.toString(); + out.flush(); + file.close(); + + return; +} + +DCORE_END_NAMESPACE diff --git a/src/util/drecentmanager.h b/src/util/drecentmanager.h new file mode 100644 index 0000000..003929a --- /dev/null +++ b/src/util/drecentmanager.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: rekols + * + * Maintainer: rekols + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef DRECENTMANAGER_H +#define DRECENTMANAGER_H + +#include "dtkcore_global.h" +#include + +DCORE_BEGIN_NAMESPACE + +struct DRecentData +{ + QString appName; + QString appExec; + QString mimeType; +}; + +class DRecentManager +{ +public: + static bool addItem(const QString &uri, DRecentData &data); + static void removeItem(const QString &target); + static void removeItems(const QStringList &list); +}; + +DCORE_END_NAMESPACE + +#endif // DRECENTMANAGER_H diff --git a/src/util/util.pri b/src/util/util.pri index c8858cf..d71404b 100644 --- a/src/util/util.pri +++ b/src/util/util.pri @@ -4,7 +4,8 @@ HEADERS += \ $$PWD/dtimeunitformatter.h \ $$PWD/dabstractunitformatter.h \ $$PWD/ddisksizeformatter.h \ - $$PWD/ddbussender.h + $$PWD/ddbussender.h \ + $$PWD/drecentmanager.h INCLUDEPATH += $$PWD @@ -12,7 +13,8 @@ includes.files += $$PWD/*.h includes.files += \ $$PWD/DUtil \ $$PWD/DPinyin \ - $$PWD/DDBusSender + $$PWD/DDBusSender \ + $$PWD/DRecentManager RESOURCES += \ $$PWD/util.qrc @@ -21,4 +23,5 @@ SOURCES += \ $$PWD/dtimeunitformatter.cpp \ $$PWD/dabstractunitformatter.cpp \ $$PWD/ddisksizeformatter.cpp \ - $$PWD/ddbussender.cpp + $$PWD/ddbussender.cpp \ + $$PWD/drecentmanager.cpp -- 2.30.2