From: Boyuan Yang Date: Sun, 7 Nov 2021 13:25:42 +0000 (+0000) Subject: Import dtkcore_5.5.17.1.orig.tar.gz X-Git-Tag: archive/raspbian/5.5.17.1-1+rpi1~1^2~2 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=a7db55316d50a6d529dbb0cf1af31c6c458b0bec;p=dtkcore.git Import dtkcore_5.5.17.1.orig.tar.gz [dgit import orig dtkcore_5.5.17.1.orig.tar.gz] --- a7db55316d50a6d529dbb0cf1af31c6c458b0bec diff --git a/.clog.toml b/.clog.toml new file mode 100644 index 0000000..646b8fe --- /dev/null +++ b/.clog.toml @@ -0,0 +1,5 @@ +[clog] +repository = "https://github.com/linuxdeepin/dtkcore" +from-latest-tag = true + +changelog = "CHANGELOG.md" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..51c4921 --- /dev/null +++ b/.gitignore @@ -0,0 +1,31 @@ +# Compiled Object files +*.slo +*.lo +*.o + +# Compiled Dynamic libraries +*.so +*.dylib + +# Compiled Static libraries +*.lai +*.la +*.a + +build*/ +*.pro.user* +*.DS_Store + +# executeable files +*.qm + +src/DtkCores +src/dtkcore_config.h +cmake/DtkCore/DtkCoreConfig.cmake +src/qt_lib_d*.pri + +bin/ +.qmake* +Makefile + +cmake/DtkCore* diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..6da6602 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,5 @@ +include: + - remote: 'https://gitlab.deepin.io/dev-tools/letmeci/raw/master/gitlab-ci/dde.yml' +variables: + CPPCHECK: "true" + CODESPELL: "true" diff --git a/.packit.yaml b/.packit.yaml new file mode 100644 index 0000000..307fc7c --- /dev/null +++ b/.packit.yaml @@ -0,0 +1,17 @@ +# See the documentation for more information: +# https://packit.dev/docs/configuration/ + +specfile_path: rpm/dtkcore.spec + +# add or remove files that should be synced +synced_files: + - rpm/dtkcore.spec + - .packit.yaml + +upstream_package_name: dtkcore +# downstream (Fedora) RPM package name +downstream_package_name: dtkcore + +actions: + fix-spec-file: | + bash -c "sed -i -r \"0,/Version:/ s/Version:(\s*)\S*/Version:\1${PACKIT_PROJECT_VERSION}/\" rpm/dtkcore.spec" diff --git a/.project.json b/.project.json new file mode 100644 index 0000000..778d07c --- /dev/null +++ b/.project.json @@ -0,0 +1,6 @@ +{ + "Type": "homebrew", + "3rdparty": ["tools/qdbusxml2cpp"], + "ignore": ["src/translations","src/widgets/assets","doc",".tx"], + "license": ["GPLv3"] +} diff --git a/.qmake.conf b/.qmake.conf new file mode 100644 index 0000000..545ff2f --- /dev/null +++ b/.qmake.conf @@ -0,0 +1,5 @@ +DTK_VERSION=5.5.0 +ver_list = $$split(DTK_VERSION, .) +V1 = $$first(ver_list) +V2 = $$member(ver_list, 1, 1) +DTK_MODULE_NAME=dtkcore$${V1}.$${V2} diff --git a/.release.json b/.release.json new file mode 100644 index 0000000..169c9a8 --- /dev/null +++ b/.release.json @@ -0,0 +1,16 @@ +{ + "commit": { + "quilt": false, + "pkgver": "echo $(git tag | sort -V | tail -n1)'+r'$(git log $(git describe --abbrev=0 --tags)..HEAD --oneline|wc -l)'+g'$(git rev-parse --short HEAD);", + "dist": "experimental" + }, + "release": { + "quilt": true, + "pkgver": "git describe --abbrev=0 --tags %(ref)s", + "dist": "unstable" + }, + "release-candidate": { + "quilt": true, + "dist": "unstable" + } +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..15fbd7f --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,266 @@ + +## 2.0.14 (2019-05-23) + +#### Bug Fixes + +* **DSettings:** crash when calling getOption() if option doesn't exist ([90ac734b](https://github.com/linuxdeepin/dtkcore/commit/90ac734b872203ea698808a7197aa7a9c7e2b5bd)) + + + + +## 2.0.12 (2019-04-18) + + + + + +## 2.0.11 (2019-04-17) + + +#### Bug Fixes + +* Cross-builds incorrectly, built packages contain paths from build architecture ([8d32577a](https://github.com/linuxdeepin/dtkcore/commit/8d32577a89e54b5c9c834caae83d98e50f59df77)) +* https://github.com/linuxdeepin/dtkcore/issues/10 ([3f99873a](https://github.com/linuxdeepin/dtkcore/commit/3f99873a786f6830688ecd0d8d2e2bf8dfb63ce0)) + + + + +## 2.0.10 (2019-03-27) + + +#### Bug Fixes + +* crash at application ([d852a218](https://github.com/linuxdeepin/dtkcore/commit/d852a21811f9f86e04274fc9f732d7c7a210ef3f)) + +#### Features + +* add DNotifySender ([89bbcd7c](https://github.com/linuxdeepin/dtkcore/commit/89bbcd7c3821985bb2bca51247394fd4a65b25bf)) + + + + +## 2.0.9.17 (2019-02-26) + + + + + +## 2.0.9.16 (2019-02-26) + + +#### Bug Fixes + +* deepin-os-release support cpu model and other info query ([cbeb47c9](https://github.com/linuxdeepin/dtkcore/commit/cbeb47c97e31d2b5dd3c198c60ee74332fecb293)) + + + + +## 2.0.9.15 (2019-01-25) + + +#### Bug Fixes + +* failed build the deepin-os-release on Qt 5.7.1 ([8bae8654](https://github.com/linuxdeepin/dtkcore/commit/8bae8654bdb20a7f773130d22b9db139460ba575)) +* use main project c/cxx/ld flags on build deepin-os-release ([86dbd507](https://github.com/linuxdeepin/dtkcore/commit/86dbd507c1b3b101c1816f091782430ec1ce20ce)) + + + + +## 2.0.9.14 (2019-01-02) + + + + + +## 2.0.9.13 (2018-12-28) + + + + + +## 2.0.9.12 (2018-12-24) + + +#### Bug Fixes + +* **DPathBuf:** missing default constructor ([74374cb4](https://github.com/linuxdeepin/dtkcore/commit/74374cb4cf0245ab1fe73f62fe0d13566f945db3)) + +#### Features + +* support connan build ([ba2d213f](https://github.com/linuxdeepin/dtkcore/commit/ba2d213fd6c7e36e118288305e5892c339250623)) + + + + +## 2.0.9.11 (2018-12-14) + + + + + +## 2.0.9.10 (2018-12-05) + + +#### Bug Fixes + +* include unistd.h instead of sys/unistd.h ([39c50a13](https://github.com/linuxdeepin/dtkcore/commit/39c50a1398c34123e3806a3060a4c64e7f45ed68)) +* url encoding ([4a6b7b61](https://github.com/linuxdeepin/dtkcore/commit/4a6b7b61bb3ad9ab417eda69249b5e9aced0aa97)) + + + + +## 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) + + +#### Bug Fixes + +* can't get correct disk size in some case ([20a12b62](https://github.com/linuxdeepin/dtkcore/commit/20a12b622ea7b01f0616c15a8af85e31fc2d36cb)) + + + + +## 2.0.9.5 (2018-10-26) + + +#### Features + +* update version number for expermimental ([02b5d5c1](https://github.com/linuxdeepin/dtkcore/commit/02b5d5c1e01a05f57651b774b02cae31ef9a549f)) + + + + +## 2.0.9 (2018-07-20) + + +#### Bug Fixes + +* remove qt symbols ([57ec78ba](https://github.com/linuxdeepin/dtkcore/commit/57ec78ba685a53692b0260d3d558d8b0915fc3e4)) +* non array type value is wrong on parse josn file ([9f138664](https://github.com/linuxdeepin/dtkcore/commit/9f13866439d8d650893434594da023e7d331d866)) + + + + +### 2.0.8.1 (2018-05-14) + + +#### Bug Fixes + +* update symbols ([f6c53cc4](https://github.com/linuxdeepin/dtkcore/commit/f6c53cc493c1bcf55dca54dbf500e2e484af73c9)) +* add LIBDTKCORESHARED_EXPORT for windows ([6fb1096f](https://github.com/linuxdeepin/dtkcore/commit/6fb1096f6d0784937cf84f0e4ae1f5f7587085e5)) +* **changelog:** update email format ([cb09a0ca](https://github.com/linuxdeepin/dtkcore/commit/cb09a0cadcf2fa0ba271b1d98d3b96a993eb892b)) + + + + +## 2.0.8 (2018-05-02) + + +#### Features + +* add symbols ([048de455](https://github.com/linuxdeepin/dtkcore/commit/048de4551bdd770aca5e9c12798362f913061654)) + + + + +## 2.0.7 (2018-03-01) + + +#### Bug Fixes + +* cmake link depends ([cdfcff9e](https://github.com/linuxdeepin/dtkcore/commit/cdfcff9e2f3e92bc6dbb45644d2714d6c4dbdda0)) +* better static lib support ([99886406](https://github.com/linuxdeepin/dtkcore/commit/99886406a0cae849fad23286fdf64bb399e37da0)) +* read settings value failed ([cf1c7698](https://github.com/linuxdeepin/dtkcore/commit/cf1c769893773794dff5a67c235c5d1f3234541a)) +* set default should not use ([146529f6](https://github.com/linuxdeepin/dtkcore/commit/146529f6887e798606f2bf763ab8a760969bff26)) +* fix dtk-settings install path ([1893cff3](https://github.com/linuxdeepin/dtkcore/commit/1893cff301dacb546a246a4f824dab68eac51351)) +* develop package no install the "version.pri" file ([5667b562](https://github.com/linuxdeepin/dtkcore/commit/5667b562630565fca5abed690f3d3478dd3c7603)) +* awk script failed ([524a3fa6](https://github.com/linuxdeepin/dtkcore/commit/524a3fa6021ee54db416503520aea65ef0e2c3a0)) +* set default build version for debian changelog ([ec6e2a83](https://github.com/linuxdeepin/dtkcore/commit/ec6e2a8376c7aca7162b4fbb782b998c9a6ab630)) +* set its value only if VERSION is empty ([1836000c](https://github.com/linuxdeepin/dtkcore/commit/1836000c49eb149a6495322c4cbb1474d5d48204)) + +#### Features + +* add hide support for group ([e7e4fb66](https://github.com/linuxdeepin/dtkcore/commit/e7e4fb669276fbce61c6378e74ae82573e7c0313)) +* add get option interface ([d8682485](https://github.com/linuxdeepin/dtkcore/commit/d8682485a6737da83fb28f22335f1da1afb8956c)) +* add group interface for DSettingsGroup ([c876180f](https://github.com/linuxdeepin/dtkcore/commit/c876180f535e3027dce63628f31379ef874367ed)) +* support generate cmake with qt function ([524b0559](https://github.com/linuxdeepin/dtkcore/commit/524b055929b7be84375a45f9d10cbc3a0ecac6de)) +* config pkg config with dtk_module ([137b9138](https://github.com/linuxdeepin/dtkcore/commit/137b91388d9b9db24c8136dd4e2c6e690a5712c5)) +* support qt module ([17ca0de9](https://github.com/linuxdeepin/dtkcore/commit/17ca0de9156a320cea32208dcff2f8cdf7d6a237)) +* add the "version.pri" file ([07aab9fd](https://github.com/linuxdeepin/dtkcore/commit/07aab9fd6478c83c7bae1062f64b4bd20b21869c)) +* remove build version from install path ([3bf0bfb5](https://github.com/linuxdeepin/dtkcore/commit/3bf0bfb5f49c3e83d4c36cc33f219150bf3731d8)) +* make version parser easier ([6d3b4ead](https://github.com/linuxdeepin/dtkcore/commit/6d3b4ead7080158d1d8977bf7cf99ae842e574ec)) +* set verion when build ([9083dbd3](https://github.com/linuxdeepin/dtkcore/commit/9083dbd3e29bf9d06b1032901ba13848fa964f4c)) +* add .qmake.conf file ([2890f643](https://github.com/linuxdeepin/dtkcore/commit/2890f643a57c3532ab623410f7c6c6dbfdd6788d)) +* add DtkCore and dtkcore_config.h headers ([308a0cc4](https://github.com/linuxdeepin/dtkcore/commit/308a0cc41101499c04308b4ef3bb2fff4ab8d783)) +* **DSettings:** support set default value ([5fe9bfd0](https://github.com/linuxdeepin/dtkcore/commit/5fe9bfd0a5e20cef7393639712302825b803db29)) + + + + +## 2.0.6 (2018-01-15) + + + + + +## 2.0.5.3 (2017-12-27) + + +#### Bug Fixes + +* Adapt lintian ([27df15df](https://github.com/linuxdeepin/dtkcore/commit/27df15df32788002491a24f06f098a5f849a4988)) +* break forever loop for syncing backend data ([f70e500e](https://github.com/linuxdeepin/dtkcore/commit/f70e500ec2fd5c751e40833bdc4df586614bcff2)) + +#### Features + +* **util:** add dpinyin ([128d7d67](https://github.com/linuxdeepin/dtkcore/commit/128d7d678e921bc580dd732b14a454973397899c)) + + + + +## 2.0.5.2 (2017-11-28) + + +#### Bug Fixes + +* make macosx build success ([af04bbe1](https://github.com/linuxdeepin/dtkcore/commit/af04bbe193a4b4251908f830d927ebdc8f4459e7)) +* windows build failed ([66c4c812](https://github.com/linuxdeepin/dtkcore/commit/66c4c812eb29634710642f4e9d6b3d69cc692cb2)) + +#### Features + +* add macro D_DECL_DEPRECATED ([89e49868](https://github.com/linuxdeepin/dtkcore/commit/89e49868f113ef01c03bcf5b6846eec95c428382)) + + + + +## 2.0.5 (2017-11-06) + + +#### Bug Fixes + +* build failed on used dbasefilewatcher.h project ([34fbe4b3](34fbe4b3)) +* add miss libgsettings-qt-dev ([f61c1b54](f61c1b54)) +* not select python version ([7e7e8832](7e7e8832)) + +#### Features + +* support gsettingsbackend, remove dsettings-key ([26a29800](26a29800)) +* create gsettingsbackend ([b94b97b1](b94b97b1)) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0a04128 --- /dev/null +++ b/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/README.md b/README.md new file mode 100644 index 0000000..150a69d --- /dev/null +++ b/README.md @@ -0,0 +1,52 @@ +## Deepin Tool Kit Core {#mainpage} + +Deepint Tool Kit (Dtk) is the base development tool of all C++/Qt Developer work on Deepin. + +You should read the [Deepin Application Specification](\ref doc/Specification) firstly. + +## Dependencies + +### Build dependencies + +* Qt >= 5.6 + +## Installation + +### Build from source code + +1. Make sure you have installed all dependencies. + +2. Build: + +```` +$ mkdir build +$ cd build +$ qmake .. +$ make +```` + +3. Install: + +```` +$ sudo make install +```` + +## Getting help + +Any usage issues can ask for help via + +* [Gitter](https://gitter.im/orgs/linuxdeepin/rooms) +* [IRC channel](https://webchat.freenode.net/?channels=deepin) +* [Forum](https://bbs.deepin.org) +* [WiKi](https://wiki.deepin.org/) + +## Getting involved + +We encourage you to report issues and contribute changes + +* [Contribution guide for developers](https://github.com/linuxdeepin/developer-center/wiki/Contribution-Guidelines-for-Developers-en). (English) +* [开发者代码贡献指南](https://github.com/linuxdeepin/developer-center/wiki/Contribution-Guidelines-for-Developers) (中文) + +## License + +deepin-tool-kit is licensed under [GPLv3](LICENSE). diff --git a/cmake/DtkCMake/DtkCMakeConfig.cmake b/cmake/DtkCMake/DtkCMakeConfig.cmake new file mode 100644 index 0000000..f8d62f1 --- /dev/null +++ b/cmake/DtkCMake/DtkCMakeConfig.cmake @@ -0,0 +1,76 @@ +function(addDefinitions macro) + string(TOUPPER ${macro} macro) + add_definitions(-D${macro}) +endfunction() + +add_definitions(-DQ_HOST_NAME=\"${CMAKE_HOST_SYSTEM_PROCESSOR}\") +addDefinitions(Q_HOST_${CMAKE_HOST_SYSTEM_PROCESSOR}) + +find_package(DtkCore REQUIRED) + +set(DEEPIN_OS_RELEASE_TOOL_PATH ${DTKCORE_TOOL_DIR}) +set(DEEPIN_OS_RELEASE_TOOL ${DEEPIN_OS_RELEASE_TOOL_PATH}/deepin-os-release) + +if(NOT EXISTS "${DEEPIN_OS_RELEASE_TOOL}") + message(FATAL_ERROR "\"${DEEPIN_OS_RELEASE_TOOL}\" is not exists. Install \"dtkcore-bin\" first") +endif() + +function(formatString string) + string(REGEX REPLACE "\\s+" "_" string ${string}) +endfunction() + +macro(execDeepinOsRelease args output) + exec_program(${DEEPIN_OS_RELEASE_TOOL} ARGS ${args} OUTPUT_VARIABLE ${output} RETURN_VALUE exitCode) + + if(NOT ${exitCode} EQUAL 0) + message(FATAL_ERROR "exec deepin-os-release failed, with args: ${args}, error message: ${output}") + endif() +endmacro() + +execDeepinOsRelease(--deepin-type DEEPIN_OS_TYPE) +execDeepinOsRelease(--deepin-version DEEPIN_OS_VERSION) +execDeepinOsRelease(--product-type CMAKE_PLATFORM_ID) +execDeepinOsRelease(--product-version CMAKE_PLATFORM_VERSION) + +if("${CMAKE_PLATFORM_ID}" STREQUAL "") + message(WARNING "No value of the \"--product-type\" in the process \"${DEEPIN_OS_RELEASE_TOOL}\"") +else() + formatString(CMAKE_PLATFORM_ID) + + message("OS: ${CMAKE_PLATFORM_ID}, Version: ${CMAKE_PLATFORM_VERSION}") + + if(NOT "${CMAKE_PLATFORM_ID}" STREQUAL "") + addDefinitions(Q_OS_${CMAKE_PLATFORM_ID}) + string(TOUPPER ${CMAKE_PLATFORM_ID} CMAKE_PLATFORM_ID) + set(OS_${CMAKE_PLATFORM_ID} TRUE) + endif() + + formatString(CMAKE_PLATFORM_VERSION) + add_definitions(-DQ_OS_VERSION=\"${CMAKE_PLATFORM_VERSION}\") + + #uos base with deepin + if("${CMAKE_PLATFORM_ID}" STREQUAL "UOS") + addDefinitions(Q_OS_DEEPIN) + set(OS_DEEPIN TRUE) + endif() +endif() + +if("${DEEPIN_OS_TYPE}" STREQUAL "") + message(WARNING "No value of the \"--deepin-type\" in the process \"${DEEPIN_OS_RELEASE_TOOL}\"") +else() + formatString(DEEPIN_OS_TYPE) + + message("Deepin OS Type: ${DEEPIN_OS_TYPE}") + message("Deepin OS Version: ${DEEPIN_OS_VERSION}") + + if(NOT "${DEEPIN_OS_TYPE}" STREQUAL "") + addDefinitions(Q_OS_DEEPIN_${DEEPIN_OS_TYPE}) + addDefinitions(DEEPIN_DDE) + string(TOUPPER ${DEEPIN_OS_TYPE} DEEPIN_OS_TYPE) + set(OS_DEEPIN_${DEEPIN_OS_TYPE} TRUE) + set(DEEPIN_DDE TRUE) + endif() + + formatString(DEEPIN_OS_VERSION) + add_definitions(-DQ_OS_DEEPIN_VERSION=\"${DEEPIN_OS_VERSION}\") +endif() diff --git a/cmake/DtkTools/DtkSettingsToolsMacros.cmake b/cmake/DtkTools/DtkSettingsToolsMacros.cmake new file mode 100644 index 0000000..da1cd10 --- /dev/null +++ b/cmake/DtkTools/DtkSettingsToolsMacros.cmake @@ -0,0 +1,53 @@ +#============================================================================= +# Copyright 2019 Deepin Technology Co., Ltd. +# Copyright 2019 Gary Wang +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of authors nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#============================================================================= + +function(DTK_CREATE_I18N_FROM_JSON _generated_file_list _input_json_file _output_cpp_file_name) + set (generated_file_list) # 0(failed) or 1(successed) files in the list. + + get_filename_component(_input_json_abs_path ${_input_json_file} ABSOLUTE) + get_filename_component(_input_json_abs_dir ${_input_json_abs_path} DIRECTORY) + set (_output_cpp_abs_path ${_input_json_abs_dir}/${_output_cpp_file_name}) + + if (DTK_SETTINGS_TOOLS_FOUND) + add_custom_command(OUTPUT ${_output_cpp_abs_path} + COMMAND ${DTK_SETTINGS_TOOLS_EXECUTABLE} + ARGS ${_input_json_abs_path} -o ${_output_cpp_abs_path} + DEPENDS ${_input_json_abs_path} VERBATIM) + list(APPEND generated_file_list ${_output_cpp_abs_path}) + else () + message (WARNING "The dtk-settings tools could not be found at ${DTK_SETTINGS_TOOLS_EXECUTABLE}") + message (WARNING "Package distributor may create a seprated package for tools like `libdtkcore-bin`.") + endif () + + set(${_generated_file_list} ${generated_file_list} PARENT_SCOPE) +endfunction() diff --git a/cmake/DtkTools/DtkToolsConfig.cmake b/cmake/DtkTools/DtkToolsConfig.cmake new file mode 100644 index 0000000..02ec88e --- /dev/null +++ b/cmake/DtkTools/DtkToolsConfig.cmake @@ -0,0 +1,9 @@ +find_package(DtkCore REQUIRED) + +set (DTK_SETTINGS_TOOLS_EXECUTABLE ${DTKCORE_TOOL_DIR}/dtk-settings) + +if (EXISTS ${DTK_SETTINGS_TOOLS_EXECUTABLE}) + set(DTK_SETTINGS_TOOLS_FOUND TRUE) +endif () + +include("${CMAKE_CURRENT_LIST_DIR}/DtkSettingsToolsMacros.cmake") \ No newline at end of file diff --git a/conanfile.py b/conanfile.py new file mode 100644 index 0000000..3a6161f --- /dev/null +++ b/conanfile.py @@ -0,0 +1,87 @@ +from conans import ConanFile, tools + + +class DtkcoreConan(ConanFile): + name = 'dtkcore' + version = '2.0.9' + license = 'GPL' + author = 'Iceyer me@iceyer.net' + url = 'https://github.com/linuxdeepin/dtkcore' + description = 'cross platform ui library' + topics = ('qt', 'dtk') + settings = 'os', 'compiler', 'build_type', 'arch' + options = {'shared': [True, False]} + default_options = 'shared=False' + generators = 'qmake' + exports_sources = '*' + requires = 'jom_installer/1.1.2@bincrafters/stable', 'qt/5.6.3@iceyer/stable' + + def extend_include_path(self): + return '%s/include/libdtk-%s/DCore' % (self.package_folder, self.version) + + # def source(self): + # self.run('git clone https://github.com/linuxdeepin/dtkcore.git source') + # self.run('cd source && git checkout 2.0.9.9') + + def build(self): + outdir = self.build_folder + # includedir = outdir + '/include' + mkspecsdir = outdir + '/mkspecs' + # libdir = outdir + '/lib' + + env_vars = tools.vcvars_dict(self.settings) + env_vars['_CL_'] = '/utf-8' + with tools.environment_append(env_vars): + command = 'qmake -r' + command += ' VERSION=%s' % self.version + # command += ' CONFIG-=debug_and_release' + # command += ' CONFIG-=debug_and_release_target' + command += ' CONFIG+=release' + command += ' PREFIX=%s' % outdir + command += ' MKSPECS_INSTALL_DIR=%s' % mkspecsdir + command += ' DTK_STATIC_LIB=YES' + command += ' DTK_STATIC_TRANSLATION=YES' + command += ' DTK_NO_MULTIMEDIA=YES' + command += ' %s' % self.source_folder + self.run(command) + self.run('jom clean') + self.run('jom') + self.run('jom install') + + def package(self): + self.deploy() + + outdir = self.build_folder + self.copy('*', dst='include', src=outdir+'/include') + self.copy('*.lib', dst='lib', src=outdir+'/lib') + self.copy('*', dst='mkspecs', src=outdir+'/mkspecs') + + def package_info(self): + self.cpp_info.libs = ['dtkcore'] + self.cpp_info.includedirs.append(self.extend_include_path()) + self.env_info.QMAKEPATH = self.cpp_info.rootpath + self.env_info.QMAKEFEATURES = self.cpp_info.rootpath + '/mkspecs/features' + + def deploy(self): + try: + content = [] + module_pri = self.build_folder + '/mkspecs/modules/qt_lib_dtkcore.pri' + s = open(module_pri) + for line in s.readlines(): + if line.startswith('QT.dtkcore.tools'): + line = 'QT.dtkcore.tools = %s\n' % ( + self.package_folder + '/bin') + elif line.startswith('QT.dtkcore.libs'): + line = 'QT.dtkcore.libs = %s\n' % ( + self.package_folder + '/lib') + elif line.startswith('QT.dtkcore.includes'): + line = 'QT.dtkcore.includes = %s\n' % ( + self.extend_include_path()) + content.append(line) + s.close() + + # print('create module file', content) + s = open(module_pri, 'w') + s.writelines(content) + except FileNotFoundError: + print('skip update qt module file') diff --git a/debian/api.json b/debian/api.json new file mode 100755 index 0000000..a62fabb --- /dev/null +++ b/debian/api.json @@ -0,0 +1,47 @@ +{"Filepath":"src/ddesktopentry.h","Functions":[{"Uniquefunname":"Status DDesktopEntry(const QString \u0026 filePath)","Funname":"DDesktopEntry","Returntype":"Status","Args":"const QString \u0026 filePath"},{"Uniquefunname":"Status DDesktopEntry::DDesktopEntry(const QString \u0026 filePath)","Funname":"DDesktopEntry::DDesktopEntry","Returntype":"Status","Args":"const QString \u0026 filePath"},{"Uniquefunname":"QStringList DDesktopEntry::allGroups(bool sorted=false) cons)","Funname":"DDesktopEntry::allGroups","Returntype":"QStringList","Args":"bool sorted=false) cons"},{"Uniquefunname":"QString DDesktopEntry::comment() cons)","Funname":"DDesktopEntry::comment","Returntype":"QString","Args":") cons"},{"Uniquefunname":"bool DDesktopEntry::contains(const QString \u0026 key,const QString \u0026 section=\"\") cons)","Funname":"DDesktopEntry::contains","Returntype":"bool","Args":"const QString \u0026 key,const QString \u0026 section=\"\") cons"},{"Uniquefunname":"QString DDesktopEntry::ddeDisplayName() cons)","Funname":"DDesktopEntry::ddeDisplayName","Returntype":"QString","Args":") cons"},{"Uniquefunname":"QString \u0026 DDesktopEntry::escape(QString \u0026 str)","Funname":"DDesktopEntry::escape","Returntype":"QString \u0026","Args":"QString \u0026 str"},{"Uniquefunname":"QString \u0026 DDesktopEntry::escapeExec(QString \u0026 str)","Funname":"DDesktopEntry::escapeExec","Returntype":"QString \u0026","Args":"QString \u0026 str"},{"Uniquefunname":"QString DDesktopEntry::genericName() cons)","Funname":"DDesktopEntry::genericName","Returntype":"QString","Args":") cons"},{"Uniquefunname":"QStringList DDesktopEntry::keys(const QString \u0026 section=\"\") cons)","Funname":"DDesktopEntry::keys","Returntype":"QStringList","Args":"const QString \u0026 section=\"\") cons"},{"Uniquefunname":"QString DDesktopEntry::localizedValue(const QString \u0026 key,const QLocale \u0026 locale,const QString \u0026 section=\"\",const QString \u0026 defaultValue=QString ()) cons)","Funname":"DDesktopEntry::localizedValue","Returntype":"QString","Args":"const QString \u0026 key,const QLocale \u0026 locale,const QString \u0026 section=\"\",const QString \u0026 defaultValue=QString ()) cons"},{"Uniquefunname":"QString DDesktopEntry::localizedValue(const QString \u0026 key,const QString \u0026 localeKey=\"\",const QString \u0026 section=\"\",const QString \u0026 defaultValue=QString ()) cons)","Funname":"DDesktopEntry::localizedValue","Returntype":"QString","Args":"const QString \u0026 key,const QString \u0026 localeKey=\"\",const QString \u0026 section=\"\",const QString \u0026 defaultValue=QString ()) cons"},{"Uniquefunname":"QString DDesktopEntry::name() cons)","Funname":"DDesktopEntry::name","Returntype":"QString","Args":") cons"},{"Uniquefunname":"QString DDesktopEntry::rawValue(const QString \u0026 key,const QString \u0026 section=\"\",const QString \u0026 defaultValue=QString ()) cons)","Funname":"DDesktopEntry::rawValue","Returntype":"QString","Args":"const QString \u0026 key,const QString \u0026 section=\"\",const QString \u0026 defaultValue=QString ()) cons"},{"Uniquefunname":"bool DDesktopEntry::removeEntry(const QString \u0026 key,const QString \u0026 section=\"\")","Funname":"DDesktopEntry::removeEntry","Returntype":"bool","Args":"const QString \u0026 key,const QString \u0026 section=\"\""},{"Uniquefunname":"bool DDesktopEntry::save() cons)","Funname":"DDesktopEntry::save","Returntype":"bool","Args":") cons"},{"Uniquefunname":"bool DDesktopEntry::setLocalizedValue(const QString \u0026 value,const QString \u0026 localeKey,const QString \u0026 key,const QString \u0026 section=\"\")","Funname":"DDesktopEntry::setLocalizedValue","Returntype":"bool","Args":"const QString \u0026 value,const QString \u0026 localeKey,const QString \u0026 key,const QString \u0026 section=\"\""},{"Uniquefunname":"bool DDesktopEntry::setRawValue(const QString \u0026 value,const QString \u0026 key,const QString \u0026 section=\"\")","Funname":"DDesktopEntry::setRawValue","Returntype":"bool","Args":"const QString \u0026 value,const QString \u0026 key,const QString \u0026 section=\"\""},{"Uniquefunname":"bool DDesktopEntry::setStatus(const Status \u0026 status)","Funname":"DDesktopEntry::setStatus","Returntype":"bool","Args":"const Status \u0026 status"},{"Uniquefunname":"bool DDesktopEntry::setStringValue(const QString \u0026 value,const QString \u0026 key,const QString \u0026 section=\"\")","Funname":"DDesktopEntry::setStringValue","Returntype":"bool","Args":"const QString \u0026 value,const QString \u0026 key,const QString \u0026 section=\"\""},{"Uniquefunname":"Status DDesktopEntry::status() cons)","Funname":"DDesktopEntry::status","Returntype":"Status","Args":") cons"},{"Uniquefunname":"QStringList DDesktopEntry::stringListValue(const QString \u0026 key,const QString \u0026 section=\"\") cons)","Funname":"DDesktopEntry::stringListValue","Returntype":"QStringList","Args":"const QString \u0026 key,const QString \u0026 section=\"\") cons"},{"Uniquefunname":"QString DDesktopEntry::stringValue(const QString \u0026 key,const QString \u0026 section=\"\",const QString \u0026 defaultValue=QString ()) cons)","Funname":"DDesktopEntry::stringValue","Returntype":"QString","Args":"const QString \u0026 key,const QString \u0026 section=\"\",const QString \u0026 defaultValue=QString ()) cons"},{"Uniquefunname":"QString \u0026 DDesktopEntry::unescape(QString \u0026 str,bool unescapeSemicolons=false)","Funname":"DDesktopEntry::unescape","Returntype":"QString \u0026","Args":"QString \u0026 str,bool unescapeSemicolons=false"},{"Uniquefunname":"QString \u0026 DDesktopEntry::unescapeExec(QString \u0026 str)","Funname":"DDesktopEntry::unescapeExec","Returntype":"QString \u0026","Args":"QString \u0026 str"},{"Uniquefunname":" DDesktopEntry::~DDesktopEntry()","Funname":"DDesktopEntry::~DDesktopEntry","Returntype":"","Args":""},{"Uniquefunname":"QStringList allGroups(bool sorted=false) cons)","Funname":"allGroups","Returntype":"QStringList","Args":"bool sorted=false) cons"},{"Uniquefunname":"QString comment() cons)","Funname":"comment","Returntype":"QString","Args":") cons"},{"Uniquefunname":"bool contains(const QString \u0026 key,const QString \u0026 section=\"\") cons)","Funname":"contains","Returntype":"bool","Args":"const QString \u0026 key,const QString \u0026 section=\"\") cons"},{"Uniquefunname":"QString ddeDisplayName() cons)","Funname":"ddeDisplayName","Returntype":"QString","Args":") cons"},{"Uniquefunname":"QString \u0026 escape(QString \u0026 str)","Funname":"escape","Returntype":"QString \u0026","Args":"QString \u0026 str"},{"Uniquefunname":"QString \u0026 escapeExec(QString \u0026 str)","Funname":"escapeExec","Returntype":"QString \u0026","Args":"QString \u0026 str"},{"Uniquefunname":"QString genericName() cons)","Funname":"genericName","Returntype":"QString","Args":") cons"},{"Uniquefunname":"QStringList keys(const QString \u0026 section=\"\") cons)","Funname":"keys","Returntype":"QStringList","Args":"const QString \u0026 section=\"\") cons"},{"Uniquefunname":"QString localizedValue(const QString \u0026 key,const QLocale \u0026 locale,const QString \u0026 section=\"\",const QString \u0026 defaultValue=QString ()) cons)","Funname":"localizedValue","Returntype":"QString","Args":"const QString \u0026 key,const QLocale \u0026 locale,const QString \u0026 section=\"\",const QString \u0026 defaultValue=QString ()) cons"},{"Uniquefunname":"QString localizedValue(const QString \u0026 key,const QString \u0026 localeKey=\"\",const QString \u0026 section=\"\",const QString \u0026 defaultValue=QString ()) cons)","Funname":"localizedValue","Returntype":"QString","Args":"const QString \u0026 key,const QString \u0026 localeKey=\"\",const QString \u0026 section=\"\",const QString \u0026 defaultValue=QString ()) cons"},{"Uniquefunname":"QString name() cons)","Funname":"name","Returntype":"QString","Args":") cons"},{"Uniquefunname":"QString rawValue(const QString \u0026 key,const QString \u0026 section=\"\",const QString \u0026 defaultValue=QString ()) cons)","Funname":"rawValue","Returntype":"QString","Args":"const QString \u0026 key,const QString \u0026 section=\"\",const QString \u0026 defaultValue=QString ()) cons"},{"Uniquefunname":"bool removeEntry(const QString \u0026 key,const QString \u0026 section=\"\")","Funname":"removeEntry","Returntype":"bool","Args":"const QString \u0026 key,const QString \u0026 section=\"\""},{"Uniquefunname":"bool save() cons)","Funname":"save","Returntype":"bool","Args":") cons"},{"Uniquefunname":"bool setLocalizedValue(const QString \u0026 value,const QString \u0026 localeKey,const QString \u0026 key,const QString \u0026 section=\"\")","Funname":"setLocalizedValue","Returntype":"bool","Args":"const QString \u0026 value,const QString \u0026 localeKey,const QString \u0026 key,const QString \u0026 section=\"\""},{"Uniquefunname":"bool setRawValue(const QString \u0026 value,const QString \u0026 key,const QString \u0026 section=\"\")","Funname":"setRawValue","Returntype":"bool","Args":"const QString \u0026 value,const QString \u0026 key,const QString \u0026 section=\"\""},{"Uniquefunname":"bool setStatus(const Status \u0026 status)","Funname":"setStatus","Returntype":"bool","Args":"const Status \u0026 status"},{"Uniquefunname":"bool setStringValue(const QString \u0026 value,const QString \u0026 key,const QString \u0026 section=\"\")","Funname":"setStringValue","Returntype":"bool","Args":"const QString \u0026 value,const QString \u0026 key,const QString \u0026 section=\"\""},{"Uniquefunname":"Status status() cons)","Funname":"status","Returntype":"Status","Args":") cons"},{"Uniquefunname":"QStringList stringListValue(const QString \u0026 key,const QString \u0026 section=\"\") cons)","Funname":"stringListValue","Returntype":"QStringList","Args":"const QString \u0026 key,const QString \u0026 section=\"\") cons"},{"Uniquefunname":"QString stringValue(const QString \u0026 key,const QString \u0026 section=\"\",const QString \u0026 defaultValue=QString ()) cons)","Funname":"stringValue","Returntype":"QString","Args":"const QString \u0026 key,const QString \u0026 section=\"\",const QString \u0026 defaultValue=QString ()) cons"},{"Uniquefunname":"QString \u0026 unescape(QString \u0026 str,bool unescapeSemicolons=false)","Funname":"unescape","Returntype":"QString \u0026","Args":"QString \u0026 str,bool unescapeSemicolons=false"},{"Uniquefunname":"QString \u0026 unescapeExec(QString \u0026 str)","Funname":"unescapeExec","Returntype":"QString \u0026","Args":"QString \u0026 str"},{"Uniquefunname":" ~DDesktopEntry()","Funname":"~DDesktopEntry","Returntype":"","Args":""}],"Records":[{"Name":"enum:DDesktopEntry::Status","Fields":["AccessError","DDesktopEntry::AccessError","DDesktopEntry::FormatError","DDesktopEntry::NoError","FormatError","NoError"]},{"Name":"enum:DDesktopEntry::EntryType","Fields":["Application","DDesktopEntry::Application","DDesktopEntry::Directory","DDesktopEntry::FSDevice","DDesktopEntry::Link","DDesktopEntry::Service","DDesktopEntry::ServiceType","DDesktopEntry::Unknown","Directory","FSDevice","Link","Service","ServiceType","Unknown"]},{"Name":"enum:DDesktopEntry::ValueType","Fields":["Boolean","DDesktopEntry::Boolean","DDesktopEntry::NotExisted","DDesktopEntry::Numeric","DDesktopEntry::String","DDesktopEntry::Strings","DDesktopEntry::Unparsed","NotExisted","Numeric","String","Strings","Unparsed"]},{"Name":"class:DDesktopEntry","Fields":["QScopedPointer\u003cDDesktopEntryPrivate\u003e DDesktopEntry::d_ptr"]}]} +{"Filepath":"src/dsecurestring.h","Functions":[{"Uniquefunname":" DSecureString(const QString \u0026 other)","Funname":"DSecureString","Returntype":"","Args":"const QString \u0026 other"},{"Uniquefunname":" DSecureString::DSecureString(const QString \u0026 other)","Funname":"DSecureString::DSecureString","Returntype":"","Args":"const QString \u0026 other"},{"Uniquefunname":" DSecureString::~DSecureString()","Funname":"DSecureString::~DSecureString","Returntype":"","Args":""},{"Uniquefunname":" ~DSecureString()","Funname":"~DSecureString","Returntype":"","Args":""}],"Records":null} +{"Filepath":"src/dsysinfo.h","Functions":[{"Uniquefunname":"QString DSysInfo::buildVersion()","Funname":"DSysInfo::buildVersion","Returntype":"QString","Args":""},{"Uniquefunname":"QString DSysInfo::computerName()","Funname":"DSysInfo::computerName","Returntype":"QString","Args":""},{"Uniquefunname":"QString DSysInfo::cpuModelName()","Funname":"DSysInfo::cpuModelName","Returntype":"QString","Args":""},{"Uniquefunname":"QString DSysInfo::deepinCopyright()","Funname":"DSysInfo::deepinCopyright","Returntype":"QString","Args":""},{"Uniquefunname":" DSysInfo::deepinDistributionInfoPath()","Funname":"DSysInfo::deepinDistributionInfoPath","Returntype":"","Args":""},{"Uniquefunname":" DSysInfo::deepinDistributorLogo(LogoType type=Normal,const QString \u0026 fallback=QString ())","Funname":"DSysInfo::deepinDistributorLogo","Returntype":"","Args":"LogoType type=Normal,const QString \u0026 fallback=QString ()"},{"Uniquefunname":" DSysInfo::deepinDistributorName()","Funname":"DSysInfo::deepinDistributorName","Returntype":"","Args":""},{"Uniquefunname":" DSysInfo::deepinDistributorWebsite()","Funname":"DSysInfo::deepinDistributorWebsite","Returntype":"","Args":""},{"Uniquefunname":"QString DSysInfo::deepinEdition()","Funname":"DSysInfo::deepinEdition","Returntype":"QString","Args":""},{"Uniquefunname":"DeepinType DSysInfo::deepinType()","Funname":"DSysInfo::deepinType","Returntype":"DeepinType","Args":""},{"Uniquefunname":"QString DSysInfo::deepinTypeDisplayName(const QLocale \u0026 locale=QLocale::system ())","Funname":"DSysInfo::deepinTypeDisplayName","Returntype":"QString","Args":"const QLocale \u0026 locale=QLocale::system ()"},{"Uniquefunname":"QString DSysInfo::deepinVersion()","Funname":"DSysInfo::deepinVersion","Returntype":"QString","Args":""},{"Uniquefunname":"QString DSysInfo::distributionInfoPath()","Funname":"DSysInfo::distributionInfoPath","Returntype":"QString","Args":""},{"Uniquefunname":"QString DSysInfo::distributionInfoSectionName(OrgType type)","Funname":"DSysInfo::distributionInfoSectionName","Returntype":"QString","Args":"OrgType type"},{"Uniquefunname":"QString DSysInfo::distributionOrgLogo(OrgType orgType=Distribution,LogoType type=Normal,const QString \u0026 fallback=QString ())","Funname":"DSysInfo::distributionOrgLogo","Returntype":"QString","Args":"OrgType orgType=Distribution,LogoType type=Normal,const QString \u0026 fallback=QString ()"},{"Uniquefunname":"QString DSysInfo::distributionOrgName(OrgType type=Distribution,const QLocale \u0026 locale=QLocale::system ())","Funname":"DSysInfo::distributionOrgName","Returntype":"QString","Args":"OrgType type=Distribution,const QLocale \u0026 locale=QLocale::system ()"},{"Uniquefunname":"QPair\u003cQString,QString\u003e DSysInfo::distributionOrgWebsite(OrgType type=Distribution)","Funname":"DSysInfo::distributionOrgWebsite","Returntype":"QPair\u003cQString,QString\u003e","Args":"OrgType type=Distribution"},{"Uniquefunname":"bool DSysInfo::isCommunityEdition()","Funname":"DSysInfo::isCommunityEdition","Returntype":"bool","Args":""},{"Uniquefunname":"bool DSysInfo::isDDE()","Funname":"DSysInfo::isDDE","Returntype":"bool","Args":""},{"Uniquefunname":"bool DSysInfo::isDeepin()","Funname":"DSysInfo::isDeepin","Returntype":"bool","Args":""},{"Uniquefunname":"QString DSysInfo::majorVersion()","Funname":"DSysInfo::majorVersion","Returntype":"QString","Args":""},{"Uniquefunname":"qint64 DSysInfo::memoryInstalledSize()","Funname":"DSysInfo::memoryInstalledSize","Returntype":"qint64","Args":""},{"Uniquefunname":"qint64 DSysInfo::memoryTotalSize()","Funname":"DSysInfo::memoryTotalSize","Returntype":"qint64","Args":""},{"Uniquefunname":"QString DSysInfo::minorVersion()","Funname":"DSysInfo::minorVersion","Returntype":"QString","Args":""},{"Uniquefunname":"QString DSysInfo::operatingSystemName()","Funname":"DSysInfo::operatingSystemName","Returntype":"QString","Args":""},{"Uniquefunname":"ProductType DSysInfo::productType()","Funname":"DSysInfo::productType","Returntype":"ProductType","Args":""},{"Uniquefunname":"QString DSysInfo::productTypeString()","Funname":"DSysInfo::productTypeString","Returntype":"QString","Args":""},{"Uniquefunname":"QString DSysInfo::productVersion()","Funname":"DSysInfo::productVersion","Returntype":"QString","Args":""},{"Uniquefunname":"QString DSysInfo::spVersion()","Funname":"DSysInfo::spVersion","Returntype":"QString","Args":""},{"Uniquefunname":"qint64 DSysInfo::systemDiskSize()","Funname":"DSysInfo::systemDiskSize","Returntype":"qint64","Args":""},{"Uniquefunname":"QString DSysInfo::udpateVersion()","Funname":"DSysInfo::udpateVersion","Returntype":"QString","Args":""},{"Uniquefunname":"UosArch DSysInfo::uosArch()","Funname":"DSysInfo::uosArch","Returntype":"UosArch","Args":""},{"Uniquefunname":"QString DSysInfo::uosEditionName(const QLocale \u0026 locale=QLocale::system ())","Funname":"DSysInfo::uosEditionName","Returntype":"QString","Args":"const QLocale \u0026 locale=QLocale::system ()"},{"Uniquefunname":"UosEdition DSysInfo::uosEditionType()","Funname":"DSysInfo::uosEditionType","Returntype":"UosEdition","Args":""},{"Uniquefunname":"QString DSysInfo::uosProductTypeName(const QLocale \u0026 locale=QLocale::system ())","Funname":"DSysInfo::uosProductTypeName","Returntype":"QString","Args":"const QLocale \u0026 locale=QLocale::system ()"},{"Uniquefunname":"QString DSysInfo::uosSystemName(const QLocale \u0026 locale=QLocale::system ())","Funname":"DSysInfo::uosSystemName","Returntype":"QString","Args":"const QLocale \u0026 locale=QLocale::system ()"},{"Uniquefunname":"UosType DSysInfo::uosType()","Funname":"DSysInfo::uosType","Returntype":"UosType","Args":""},{"Uniquefunname":"QString buildVersion()","Funname":"buildVersion","Returntype":"QString","Args":""},{"Uniquefunname":"QString computerName()","Funname":"computerName","Returntype":"QString","Args":""},{"Uniquefunname":"QString cpuModelName()","Funname":"cpuModelName","Returntype":"QString","Args":""},{"Uniquefunname":"QString deepinCopyright()","Funname":"deepinCopyright","Returntype":"QString","Args":""},{"Uniquefunname":" deepinDistributionInfoPath()","Funname":"deepinDistributionInfoPath","Returntype":"","Args":""},{"Uniquefunname":" deepinDistributorLogo(LogoType type=Normal,const QString \u0026 fallback=QString ())","Funname":"deepinDistributorLogo","Returntype":"","Args":"LogoType type=Normal,const QString \u0026 fallback=QString ()"},{"Uniquefunname":" deepinDistributorName()","Funname":"deepinDistributorName","Returntype":"","Args":""},{"Uniquefunname":" deepinDistributorWebsite()","Funname":"deepinDistributorWebsite","Returntype":"","Args":""},{"Uniquefunname":"QString deepinEdition()","Funname":"deepinEdition","Returntype":"QString","Args":""},{"Uniquefunname":"DeepinType deepinType()","Funname":"deepinType","Returntype":"DeepinType","Args":""},{"Uniquefunname":"QString deepinTypeDisplayName(const QLocale \u0026 locale=QLocale::system ())","Funname":"deepinTypeDisplayName","Returntype":"QString","Args":"const QLocale \u0026 locale=QLocale::system ()"},{"Uniquefunname":"QString deepinVersion()","Funname":"deepinVersion","Returntype":"QString","Args":""},{"Uniquefunname":"QString distributionInfoPath()","Funname":"distributionInfoPath","Returntype":"QString","Args":""},{"Uniquefunname":"QString distributionInfoSectionName(OrgType type)","Funname":"distributionInfoSectionName","Returntype":"QString","Args":"OrgType type"},{"Uniquefunname":"QString distributionOrgLogo(OrgType orgType=Distribution,LogoType type=Normal,const QString \u0026 fallback=QString ())","Funname":"distributionOrgLogo","Returntype":"QString","Args":"OrgType orgType=Distribution,LogoType type=Normal,const QString \u0026 fallback=QString ()"},{"Uniquefunname":"QString distributionOrgName(OrgType type=Distribution,const QLocale \u0026 locale=QLocale::system ())","Funname":"distributionOrgName","Returntype":"QString","Args":"OrgType type=Distribution,const QLocale \u0026 locale=QLocale::system ()"},{"Uniquefunname":"QPair\u003cQString,QString\u003e distributionOrgWebsite(OrgType type=Distribution)","Funname":"distributionOrgWebsite","Returntype":"QPair\u003cQString,QString\u003e","Args":"OrgType type=Distribution"},{"Uniquefunname":"bool isCommunityEdition()","Funname":"isCommunityEdition","Returntype":"bool","Args":""},{"Uniquefunname":"bool isDDE()","Funname":"isDDE","Returntype":"bool","Args":""},{"Uniquefunname":"bool isDeepin()","Funname":"isDeepin","Returntype":"bool","Args":""},{"Uniquefunname":"QString majorVersion()","Funname":"majorVersion","Returntype":"QString","Args":""},{"Uniquefunname":"qint64 memoryInstalledSize()","Funname":"memoryInstalledSize","Returntype":"qint64","Args":""},{"Uniquefunname":"qint64 memoryTotalSize()","Funname":"memoryTotalSize","Returntype":"qint64","Args":""},{"Uniquefunname":"QString minorVersion()","Funname":"minorVersion","Returntype":"QString","Args":""},{"Uniquefunname":"QString operatingSystemName()","Funname":"operatingSystemName","Returntype":"QString","Args":""},{"Uniquefunname":"ProductType productType()","Funname":"productType","Returntype":"ProductType","Args":""},{"Uniquefunname":"QString productTypeString()","Funname":"productTypeString","Returntype":"QString","Args":""},{"Uniquefunname":"QString productVersion()","Funname":"productVersion","Returntype":"QString","Args":""},{"Uniquefunname":"QString spVersion()","Funname":"spVersion","Returntype":"QString","Args":""},{"Uniquefunname":"qint64 systemDiskSize()","Funname":"systemDiskSize","Returntype":"qint64","Args":""},{"Uniquefunname":"QString udpateVersion()","Funname":"udpateVersion","Returntype":"QString","Args":""},{"Uniquefunname":"UosArch uosArch()","Funname":"uosArch","Returntype":"UosArch","Args":""},{"Uniquefunname":"QString uosEditionName(const QLocale \u0026 locale=QLocale::system ())","Funname":"uosEditionName","Returntype":"QString","Args":"const QLocale \u0026 locale=QLocale::system ()"},{"Uniquefunname":"UosEdition uosEditionType()","Funname":"uosEditionType","Returntype":"UosEdition","Args":""},{"Uniquefunname":"QString uosProductTypeName(const QLocale \u0026 locale=QLocale::system ())","Funname":"uosProductTypeName","Returntype":"QString","Args":"const QLocale \u0026 locale=QLocale::system ()"},{"Uniquefunname":"QString uosSystemName(const QLocale \u0026 locale=QLocale::system ())","Funname":"uosSystemName","Returntype":"QString","Args":"const QLocale \u0026 locale=QLocale::system ()"},{"Uniquefunname":"UosType uosType()","Funname":"uosType","Returntype":"UosType","Args":""}],"Records":[{"Name":"enum:DSysInfo::ProductType","Fields":["ArchLinux","CentOS","DSysInfo::ArchLinux","DSysInfo::CentOS","DSysInfo::Debian","DSysInfo::Deepin","DSysInfo::Fedora","DSysInfo::LinuxMint","DSysInfo::Manjaro","DSysInfo::SailfishOS","DSysInfo::Ubuntu","DSysInfo::UnknownType","DSysInfo::Uos","DSysInfo::openSUSE","Debian","Deepin","Fedora","LinuxMint","Manjaro","SailfishOS","Ubuntu","UnknownType","Uos","openSUSE"]},{"Name":"macro","Fields":["DSYSINFO_H"]},{"Name":"enum:DSysInfo::DeepinType","Fields":["DSysInfo::DeepinDesktop","DSysInfo::DeepinPersonal","DSysInfo::DeepinProfessional","DSysInfo::DeepinServer","DSysInfo::UnknownDeepin","DeepinDesktop","DeepinPersonal","DeepinProfessional","DeepinServer","UnknownDeepin"]},{"Name":"enum:DSysInfo::OrgType","Fields":["DSysInfo::Distribution","DSysInfo::Distributor","DSysInfo::Manufacturer","Distribution","Distributor","Manufacturer"]},{"Name":"enum:DSysInfo::LogoType","Fields":["DSysInfo::Light","DSysInfo::Normal","DSysInfo::Symbolic","DSysInfo::Transparent","Light","Normal","Symbolic","Transparent"]},{"Name":"enum:DSysInfo::UosArch","Fields":["DSysInfo::UosAMD64","DSysInfo::UosARM64","DSysInfo::UosArchUnknown","DSysInfo::UosMIPS64","DSysInfo::UosSW64","UosAMD64","UosARM64","UosArchUnknown","UosMIPS64","UosSW64"]},{"Name":"enum:DSysInfo::UosEdition","Fields":["DSysInfo::UosCommunity","DSysInfo::UosDeviceEdition","DSysInfo::UosEditionCount","DSysInfo::UosEditionUnknown","DSysInfo::UosEducation","DSysInfo::UosEnterprise","DSysInfo::UosEnterpriseC","DSysInfo::UosEuler","DSysInfo::UosHome","DSysInfo::UosMilitary","DSysInfo::UosMilitaryS","DSysInfo::UosProfessional","UosCommunity","UosDeviceEdition","UosEditionCount","UosEditionUnknown","UosEducation","UosEnterprise","UosEnterpriseC","UosEuler","UosHome","UosMilitary","UosMilitaryS","UosProfessional"]},{"Name":"enum:DSysInfo::UosType","Fields":["DSysInfo::UosDesktop","DSysInfo::UosDevice","DSysInfo::UosServer","DSysInfo::UosTypeCount","DSysInfo::UosTypeUnknown","UosDesktop","UosDevice","UosServer","UosTypeCount","UosTypeUnknown"]}]} +{"Filepath":"src/dtkcore_global.h","Functions":[{"Uniquefunname":"int LIBDTKCORESHARED_EXPORT dtkVersion()","Funname":"dtkVersion","Returntype":"int LIBDTKCORESHARED_EXPORT","Args":""},{"Uniquefunname":"const LIBDTKCORESHARED_EXPORT char * dtkVersionString()","Funname":"dtkVersionString","Returntype":"const LIBDTKCORESHARED_EXPORT char *","Args":""}],"Records":[{"Name":"macro","Fields":["DCORE_BEGIN_NAMESPACE","DCORE_BEGIN_NAMESPACE","DCORE_END_NAMESPACE","DCORE_END_NAMESPACE","DCORE_NAMESPACE","DCORE_USE_NAMESPACE","DCORE_USE_NAMESPACE","DTK_BEGIN_NAMESPACE","DTK_BEGIN_NAMESPACE","DTK_CORE_NAMESPACE","DTK_END_NAMESPACE","DTK_END_NAMESPACE","DTK_NAMESPACE","DTK_USE_NAMESPACE","DTK_USE_NAMESPACE","DTK_VERSION","DTK_VERSION_CHECK(major,minor,patch,build)","D_DECL_DEPRECATED","D_DECL_DEPRECATED_X","D_DECL_DEPRECATED_X(text)","LIBDTKCORESHARED_EXPORT","LIBDTKCORESHARED_EXPORT"]}]} +{"Filepath":"src/base/dobject.h","Functions":[{"Uniquefunname":" DObject(DObject * parent=nullptr)","Funname":"DObject","Returntype":"","Args":"DObject * parent=nullptr"},{"Uniquefunname":" DObject(DObjectPrivate \u0026 dd,DObject * parent=nullptr)","Funname":"DObject","Returntype":"","Args":"DObjectPrivate \u0026 dd,DObject * parent=nullptr"},{"Uniquefunname":" DObject::DObject(DObject * parent=nullptr)","Funname":"DObject::DObject","Returntype":"","Args":"DObject * parent=nullptr"},{"Uniquefunname":" DObject::DObject(DObjectPrivate \u0026 dd,DObject * parent=nullptr)","Funname":"DObject::DObject","Returntype":"","Args":"DObjectPrivate \u0026 dd,DObject * parent=nullptr"},{"Uniquefunname":" DObject::~DObject()","Funname":"DObject::~DObject","Returntype":"","Args":""},{"Uniquefunname":" ~DObject()","Funname":"~DObject","Returntype":"","Args":""}],"Records":[{"Name":"macro","Fields":["DOBJECT_H","D_D(Class)","D_DC(Class)","D_DECLARE_PRIVATE(Class)","D_DECLARE_PUBLIC(Class)","D_PRIVATE_SLOT(Func)","D_Q(Class)","D_QC(Class)"]},{"Name":"class:DObject","Fields":["QScopedPointer\u003cDObjectPrivate\u003e DObject::d_d_ptr"]}]} +{"Filepath":"src/base/dsingleton.h","Functions":[{"Uniquefunname":" DSingleton(const DSingleton \u0026)","Funname":"DSingleton","Returntype":"","Args":"const DSingleton \u0026"},{"Uniquefunname":" DSingleton(void)","Funname":"DSingleton","Returntype":"","Args":"void"},{"Uniquefunname":" DSingleton::DSingleton(const DSingleton \u0026)","Funname":"DSingleton::DSingleton","Returntype":"","Args":"const DSingleton \u0026"},{"Uniquefunname":" DSingleton::DSingleton(void)","Funname":"DSingleton::DSingleton","Returntype":"","Args":"void"},{"Uniquefunname":" static inline T *instance()","Funname":"DSingleton::instance","Returntype":"T *","Args":""},{"Uniquefunname":"DSingleton \u0026 DSingleton::operator =(const DSingleton \u0026)","Funname":"DSingleton::operator =","Returntype":"DSingleton \u0026","Args":"const DSingleton \u0026"},{"Uniquefunname":" DSingleton::~DSingleton(void)","Funname":"DSingleton::~DSingleton","Returntype":"","Args":"void"},{"Uniquefunname":" static inline T *instance()","Funname":"instance","Returntype":"T *","Args":""},{"Uniquefunname":"DSingleton \u0026 operator =(const DSingleton \u0026)","Funname":"operator =","Returntype":"DSingleton \u0026","Args":"const DSingleton \u0026"},{"Uniquefunname":" ~DSingleton(void)","Funname":"~DSingleton","Returntype":"","Args":"void"}],"Records":[{"Name":"macro","Fields":["DSINGLETON_H"]}]} +{"Filepath":"src/base/private/dobject_p.h","Functions":[{"Uniquefunname":" DObjectPrivate(DObject * qq)","Funname":"DObjectPrivate","Returntype":"","Args":"DObject * qq"},{"Uniquefunname":" DObjectPrivate::DObjectPrivate(DObject * qq)","Funname":"DObjectPrivate::DObjectPrivate","Returntype":"","Args":"DObject * qq"},{"Uniquefunname":" DObjectPrivate::~DObjectPrivate()","Funname":"DObjectPrivate::~DObjectPrivate","Returntype":"","Args":""},{"Uniquefunname":" ~DObjectPrivate()","Funname":"~DObjectPrivate","Returntype":"","Args":""}],"Records":[{"Name":"macro","Fields":["DOBJECT_P_H"]},{"Name":"class:DObjectPrivate","Fields":["DObject * DObjectPrivate::q_ptr"]}]} +{"Filepath":"src/filesystem/dbasefilewatcher.h","Functions":[{"Uniquefunname":" DBaseFileWatcher(DBaseFileWatcherPrivate \u0026 dd,const QUrl \u0026 url,QObject * parent=0)","Funname":"DBaseFileWatcher","Returntype":"","Args":"DBaseFileWatcherPrivate \u0026 dd,const QUrl \u0026 url,QObject * parent=0"},{"Uniquefunname":" DBaseFileWatcher::DBaseFileWatcher(DBaseFileWatcherPrivate \u0026 dd,const QUrl \u0026 url,QObject * parent=0)","Funname":"DBaseFileWatcher::DBaseFileWatcher","Returntype":"","Args":"DBaseFileWatcherPrivate \u0026 dd,const QUrl \u0026 url,QObject * parent=0"},{"Uniquefunname":"void DBaseFileWatcher::fileAttributeChanged(const QUrl \u0026 url)","Funname":"DBaseFileWatcher::fileAttributeChanged","Returntype":"void","Args":"const QUrl \u0026 url"},{"Uniquefunname":"void DBaseFileWatcher::fileClosed(const QUrl \u0026 url)","Funname":"DBaseFileWatcher::fileClosed","Returntype":"void","Args":"const QUrl \u0026 url"},{"Uniquefunname":"void DBaseFileWatcher::fileModified(const QUrl \u0026 url)","Funname":"DBaseFileWatcher::fileModified","Returntype":"void","Args":"const QUrl \u0026 url"},{"Uniquefunname":"void DBaseFileWatcher::fileMoved(const QUrl \u0026 fromUrl,const QUrl \u0026 toUrl)","Funname":"DBaseFileWatcher::fileMoved","Returntype":"void","Args":"const QUrl \u0026 fromUrl,const QUrl \u0026 toUrl"},{"Uniquefunname":"QUrl DBaseFileWatcher::fileUrl() cons)","Funname":"DBaseFileWatcher::fileUrl","Returntype":"QUrl","Args":") cons"},{"Uniquefunname":"bool DBaseFileWatcher::ghostSignal(const QUrl \u0026 targetUrl,SignalType1 signal,const QUrl \u0026 arg1)","Funname":"DBaseFileWatcher::ghostSignal","Returntype":"bool","Args":"const QUrl \u0026 targetUrl,SignalType1 signal,const QUrl \u0026 arg1"},{"Uniquefunname":"bool DBaseFileWatcher::ghostSignal(const QUrl \u0026 targetUrl,SignalType2 signal,const QUrl \u0026 arg1,const QUrl \u0026 arg2)","Funname":"DBaseFileWatcher::ghostSignal","Returntype":"bool","Args":"const QUrl \u0026 targetUrl,SignalType2 signal,const QUrl \u0026 arg1,const QUrl \u0026 arg2"},{"Uniquefunname":"bool DBaseFileWatcher::restartWatcher()","Funname":"DBaseFileWatcher::restartWatcher","Returntype":"bool","Args":""},{"Uniquefunname":"void DBaseFileWatcher::setEnabledSubfileWatcher(const QUrl \u0026 subfileUrl,bool enabled=true)","Funname":"DBaseFileWatcher::setEnabledSubfileWatcher","Returntype":"void","Args":"const QUrl \u0026 subfileUrl,bool enabled=true"},{"Uniquefunname":"bool DBaseFileWatcher::startWatcher()","Funname":"DBaseFileWatcher::startWatcher","Returntype":"bool","Args":""},{"Uniquefunname":"bool DBaseFileWatcher::stopWatcher()","Funname":"DBaseFileWatcher::stopWatcher","Returntype":"bool","Args":""},{"Uniquefunname":"void DBaseFileWatcher::subfileCreated(const QUrl \u0026 url)","Funname":"DBaseFileWatcher::subfileCreated","Returntype":"void","Args":"const QUrl \u0026 url"},{"Uniquefunname":" DBaseFileWatcher::~DBaseFileWatcher()","Funname":"DBaseFileWatcher::~DBaseFileWatcher","Returntype":"","Args":""},{"Uniquefunname":"void fileAttributeChanged(const QUrl \u0026 url)","Funname":"fileAttributeChanged","Returntype":"void","Args":"const QUrl \u0026 url"},{"Uniquefunname":"void fileClosed(const QUrl \u0026 url)","Funname":"fileClosed","Returntype":"void","Args":"const QUrl \u0026 url"},{"Uniquefunname":"void fileModified(const QUrl \u0026 url)","Funname":"fileModified","Returntype":"void","Args":"const QUrl \u0026 url"},{"Uniquefunname":"void fileMoved(const QUrl \u0026 fromUrl,const QUrl \u0026 toUrl)","Funname":"fileMoved","Returntype":"void","Args":"const QUrl \u0026 fromUrl,const QUrl \u0026 toUrl"},{"Uniquefunname":"QUrl fileUrl() cons)","Funname":"fileUrl","Returntype":"QUrl","Args":") cons"},{"Uniquefunname":"bool ghostSignal(const QUrl \u0026 targetUrl,SignalType1 signal,const QUrl \u0026 arg1)","Funname":"ghostSignal","Returntype":"bool","Args":"const QUrl \u0026 targetUrl,SignalType1 signal,const QUrl \u0026 arg1"},{"Uniquefunname":"bool ghostSignal(const QUrl \u0026 targetUrl,SignalType2 signal,const QUrl \u0026 arg1,const QUrl \u0026 arg2)","Funname":"ghostSignal","Returntype":"bool","Args":"const QUrl \u0026 targetUrl,SignalType2 signal,const QUrl \u0026 arg1,const QUrl \u0026 arg2"},{"Uniquefunname":"bool restartWatcher()","Funname":"restartWatcher","Returntype":"bool","Args":""},{"Uniquefunname":"void setEnabledSubfileWatcher(const QUrl \u0026 subfileUrl,bool enabled=true)","Funname":"setEnabledSubfileWatcher","Returntype":"void","Args":"const QUrl \u0026 subfileUrl,bool enabled=true"},{"Uniquefunname":"bool startWatcher()","Funname":"startWatcher","Returntype":"bool","Args":""},{"Uniquefunname":"bool stopWatcher()","Funname":"stopWatcher","Returntype":"bool","Args":""},{"Uniquefunname":"void subfileCreated(const QUrl \u0026 url)","Funname":"subfileCreated","Returntype":"void","Args":"const QUrl \u0026 url"},{"Uniquefunname":" ~DBaseFileWatcher()","Funname":"~DBaseFileWatcher","Returntype":"","Args":""}],"Records":[{"Name":"macro","Fields":["DBASEFILEWATCHER_H"]}]} +{"Filepath":"src/filesystem/dfilesystemwatcher.h","Functions":[{"Uniquefunname":" DFileSystemWatcher(QObject * parent=Q_NULLPTR)","Funname":"DFileSystemWatcher","Returntype":"","Args":"QObject * parent=Q_NULLPTR"},{"Uniquefunname":" DFileSystemWatcher(const QStringList \u0026 paths,QObject * parent=Q_NULLPTR)","Funname":"DFileSystemWatcher","Returntype":"","Args":"const QStringList \u0026 paths,QObject * parent=Q_NULLPTR"},{"Uniquefunname":" DFileSystemWatcher::DFileSystemWatcher(QObject * parent=Q_NULLPTR)","Funname":"DFileSystemWatcher::DFileSystemWatcher","Returntype":"","Args":"QObject * parent=Q_NULLPTR"},{"Uniquefunname":" DFileSystemWatcher::DFileSystemWatcher(const QStringList \u0026 paths,QObject * parent=Q_NULLPTR)","Funname":"DFileSystemWatcher::DFileSystemWatcher","Returntype":"","Args":"const QStringList \u0026 paths,QObject * parent=Q_NULLPTR"},{"Uniquefunname":"bool DFileSystemWatcher::addPath(const QString \u0026 file)","Funname":"DFileSystemWatcher::addPath","Returntype":"bool","Args":"const QString \u0026 file"},{"Uniquefunname":"QStringList DFileSystemWatcher::addPaths(const QStringList \u0026 files)","Funname":"DFileSystemWatcher::addPaths","Returntype":"QStringList","Args":"const QStringList \u0026 files"},{"Uniquefunname":"QStringList DFileSystemWatcher::directories() cons)","Funname":"DFileSystemWatcher::directories","Returntype":"QStringList","Args":") cons"},{"Uniquefunname":"void DFileSystemWatcher::fileAttributeChanged(const QString \u0026 path,const QString \u0026 name,QPrivateSignal)","Funname":"DFileSystemWatcher::fileAttributeChanged","Returntype":"void","Args":"const QString \u0026 path,const QString \u0026 name,QPrivateSignal"},{"Uniquefunname":"void DFileSystemWatcher::fileClosed(const QString \u0026 path,const QString \u0026 name,QPrivateSignal)","Funname":"DFileSystemWatcher::fileClosed","Returntype":"void","Args":"const QString \u0026 path,const QString \u0026 name,QPrivateSignal"},{"Uniquefunname":"void DFileSystemWatcher::fileCreated(const QString \u0026 path,const QString \u0026 name,QPrivateSignal)","Funname":"DFileSystemWatcher::fileCreated","Returntype":"void","Args":"const QString \u0026 path,const QString \u0026 name,QPrivateSignal"},{"Uniquefunname":"void DFileSystemWatcher::fileModified(const QString \u0026 path,const QString \u0026 name,QPrivateSignal)","Funname":"DFileSystemWatcher::fileModified","Returntype":"void","Args":"const QString \u0026 path,const QString \u0026 name,QPrivateSignal"},{"Uniquefunname":"void DFileSystemWatcher::fileMoved(const QString \u0026 fromPath,const QString \u0026 fromName,const QString \u0026 toPath,const QString \u0026 toName,QPrivateSignal)","Funname":"DFileSystemWatcher::fileMoved","Returntype":"void","Args":"const QString \u0026 fromPath,const QString \u0026 fromName,const QString \u0026 toPath,const QString \u0026 toName,QPrivateSignal"},{"Uniquefunname":"QStringList DFileSystemWatcher::files() cons)","Funname":"DFileSystemWatcher::files","Returntype":"QStringList","Args":") cons"},{"Uniquefunname":"bool DFileSystemWatcher::removePath(const QString \u0026 file)","Funname":"DFileSystemWatcher::removePath","Returntype":"bool","Args":"const QString \u0026 file"},{"Uniquefunname":"QStringList DFileSystemWatcher::removePaths(const QStringList \u0026 files)","Funname":"DFileSystemWatcher::removePaths","Returntype":"QStringList","Args":"const QStringList \u0026 files"},{"Uniquefunname":" DFileSystemWatcher::~DFileSystemWatcher()","Funname":"DFileSystemWatcher::~DFileSystemWatcher","Returntype":"","Args":""},{"Uniquefunname":"bool addPath(const QString \u0026 file)","Funname":"addPath","Returntype":"bool","Args":"const QString \u0026 file"},{"Uniquefunname":"QStringList addPaths(const QStringList \u0026 files)","Funname":"addPaths","Returntype":"QStringList","Args":"const QStringList \u0026 files"},{"Uniquefunname":"QStringList directories() cons)","Funname":"directories","Returntype":"QStringList","Args":") cons"},{"Uniquefunname":"void fileAttributeChanged(const QString \u0026 path,const QString \u0026 name,QPrivateSignal)","Funname":"fileAttributeChanged","Returntype":"void","Args":"const QString \u0026 path,const QString \u0026 name,QPrivateSignal"},{"Uniquefunname":"void fileClosed(const QString \u0026 path,const QString \u0026 name,QPrivateSignal)","Funname":"fileClosed","Returntype":"void","Args":"const QString \u0026 path,const QString \u0026 name,QPrivateSignal"},{"Uniquefunname":"void fileCreated(const QString \u0026 path,const QString \u0026 name,QPrivateSignal)","Funname":"fileCreated","Returntype":"void","Args":"const QString \u0026 path,const QString \u0026 name,QPrivateSignal"},{"Uniquefunname":"void fileModified(const QString \u0026 path,const QString \u0026 name,QPrivateSignal)","Funname":"fileModified","Returntype":"void","Args":"const QString \u0026 path,const QString \u0026 name,QPrivateSignal"},{"Uniquefunname":"void fileMoved(const QString \u0026 fromPath,const QString \u0026 fromName,const QString \u0026 toPath,const QString \u0026 toName,QPrivateSignal)","Funname":"fileMoved","Returntype":"void","Args":"const QString \u0026 fromPath,const QString \u0026 fromName,const QString \u0026 toPath,const QString \u0026 toName,QPrivateSignal"},{"Uniquefunname":"QStringList files() cons)","Funname":"files","Returntype":"QStringList","Args":") cons"},{"Uniquefunname":"bool removePath(const QString \u0026 file)","Funname":"removePath","Returntype":"bool","Args":"const QString \u0026 file"},{"Uniquefunname":"QStringList removePaths(const QStringList \u0026 files)","Funname":"removePaths","Returntype":"QStringList","Args":"const QStringList \u0026 files"},{"Uniquefunname":" ~DFileSystemWatcher()","Funname":"~DFileSystemWatcher","Returntype":"","Args":""}],"Records":[{"Name":"macro","Fields":["DFILESYSTEMWATCHER_H"]}]} +{"Filepath":"src/filesystem/dfilewatcher.h","Functions":[{"Uniquefunname":" DFileWatcher(const QString \u0026 filePath,QObject * parent=0)","Funname":"DFileWatcher","Returntype":"","Args":"const QString \u0026 filePath,QObject * parent=0"},{"Uniquefunname":" DFileWatcher::DFileWatcher(const QString \u0026 filePath,QObject * parent=0)","Funname":"DFileWatcher::DFileWatcher","Returntype":"","Args":"const QString \u0026 filePath,QObject * parent=0"},{"Uniquefunname":"void DFileWatcher::onFileAttributeChanged(const QString \u0026 path,const QString \u0026 name)","Funname":"DFileWatcher::onFileAttributeChanged","Returntype":"void","Args":"const QString \u0026 path,const QString \u0026 name"},{"Uniquefunname":"void DFileWatcher::onFileClosed(const QString \u0026 path,const QString \u0026 name)","Funname":"DFileWatcher::onFileClosed","Returntype":"void","Args":"const QString \u0026 path,const QString \u0026 name"},{"Uniquefunname":"void DFileWatcher::onFileCreated(const QString \u0026 path,const QString \u0026 name)","Funname":"DFileWatcher::onFileCreated","Returntype":"void","Args":"const QString \u0026 path,const QString \u0026 name"},{"Uniquefunname":"void DFileWatcher::onFileDeleted(const QString \u0026 path,const QString \u0026 name)","Funname":"DFileWatcher::onFileDeleted","Returntype":"void","Args":"const QString \u0026 path,const QString \u0026 name"},{"Uniquefunname":"void DFileWatcher::onFileModified(const QString \u0026 path,const QString \u0026 name)","Funname":"DFileWatcher::onFileModified","Returntype":"void","Args":"const QString \u0026 path,const QString \u0026 name"},{"Uniquefunname":"void DFileWatcher::onFileMoved(const QString \u0026 fromPath,const QString \u0026 fromName,const QString \u0026 toPath,const QString \u0026 toName)","Funname":"DFileWatcher::onFileMoved","Returntype":"void","Args":"const QString \u0026 fromPath,const QString \u0026 fromName,const QString \u0026 toPath,const QString \u0026 toName"},{"Uniquefunname":"void onFileAttributeChanged(const QString \u0026 path,const QString \u0026 name)","Funname":"onFileAttributeChanged","Returntype":"void","Args":"const QString \u0026 path,const QString \u0026 name"},{"Uniquefunname":"void onFileClosed(const QString \u0026 path,const QString \u0026 name)","Funname":"onFileClosed","Returntype":"void","Args":"const QString \u0026 path,const QString \u0026 name"},{"Uniquefunname":"void onFileCreated(const QString \u0026 path,const QString \u0026 name)","Funname":"onFileCreated","Returntype":"void","Args":"const QString \u0026 path,const QString \u0026 name"},{"Uniquefunname":"void onFileDeleted(const QString \u0026 path,const QString \u0026 name)","Funname":"onFileDeleted","Returntype":"void","Args":"const QString \u0026 path,const QString \u0026 name"},{"Uniquefunname":"void onFileModified(const QString \u0026 path,const QString \u0026 name)","Funname":"onFileModified","Returntype":"void","Args":"const QString \u0026 path,const QString \u0026 name"},{"Uniquefunname":"void onFileMoved(const QString \u0026 fromPath,const QString \u0026 fromName,const QString \u0026 toPath,const QString \u0026 toName)","Funname":"onFileMoved","Returntype":"void","Args":"const QString \u0026 fromPath,const QString \u0026 fromName,const QString \u0026 toPath,const QString \u0026 toName"}],"Records":[{"Name":"macro","Fields":["DFILEWATCHER_H"]}]} +{"Filepath":"src/filesystem/dfilewatchermanager.h","Functions":[{"Uniquefunname":" DFileWatcherManager(QObject * parent=0)","Funname":"DFileWatcherManager","Returntype":"","Args":"QObject * parent=0"},{"Uniquefunname":" DFileWatcherManager::DFileWatcherManager(QObject * parent=0)","Funname":"DFileWatcherManager::DFileWatcherManager","Returntype":"","Args":"QObject * parent=0"},{"Uniquefunname":"DFileWatcher * DFileWatcherManager::add(const QString \u0026 filePath)","Funname":"DFileWatcherManager::add","Returntype":"DFileWatcher *","Args":"const QString \u0026 filePath"},{"Uniquefunname":"void DFileWatcherManager::fileAttributeChanged(const QString \u0026 filePath)","Funname":"DFileWatcherManager::fileAttributeChanged","Returntype":"void","Args":"const QString \u0026 filePath"},{"Uniquefunname":"void DFileWatcherManager::fileClosed(const QString \u0026 filePath)","Funname":"DFileWatcherManager::fileClosed","Returntype":"void","Args":"const QString \u0026 filePath"},{"Uniquefunname":"void DFileWatcherManager::fileModified(const QString \u0026 filePath)","Funname":"DFileWatcherManager::fileModified","Returntype":"void","Args":"const QString \u0026 filePath"},{"Uniquefunname":"void DFileWatcherManager::fileMoved(const QString \u0026 fromFilePath,const QString \u0026 toFilePath)","Funname":"DFileWatcherManager::fileMoved","Returntype":"void","Args":"const QString \u0026 fromFilePath,const QString \u0026 toFilePath"},{"Uniquefunname":"void DFileWatcherManager::remove(const QString \u0026 filePath)","Funname":"DFileWatcherManager::remove","Returntype":"void","Args":"const QString \u0026 filePath"},{"Uniquefunname":"void DFileWatcherManager::subfileCreated(const QString \u0026 filePath)","Funname":"DFileWatcherManager::subfileCreated","Returntype":"void","Args":"const QString \u0026 filePath"},{"Uniquefunname":" DFileWatcherManager::~DFileWatcherManager()","Funname":"DFileWatcherManager::~DFileWatcherManager","Returntype":"","Args":""},{"Uniquefunname":"DFileWatcher * add(const QString \u0026 filePath)","Funname":"add","Returntype":"DFileWatcher *","Args":"const QString \u0026 filePath"},{"Uniquefunname":"void fileAttributeChanged(const QString \u0026 filePath)","Funname":"fileAttributeChanged","Returntype":"void","Args":"const QString \u0026 filePath"},{"Uniquefunname":"void fileClosed(const QString \u0026 filePath)","Funname":"fileClosed","Returntype":"void","Args":"const QString \u0026 filePath"},{"Uniquefunname":"void fileModified(const QString \u0026 filePath)","Funname":"fileModified","Returntype":"void","Args":"const QString \u0026 filePath"},{"Uniquefunname":"void fileMoved(const QString \u0026 fromFilePath,const QString \u0026 toFilePath)","Funname":"fileMoved","Returntype":"void","Args":"const QString \u0026 fromFilePath,const QString \u0026 toFilePath"},{"Uniquefunname":"void remove(const QString \u0026 filePath)","Funname":"remove","Returntype":"void","Args":"const QString \u0026 filePath"},{"Uniquefunname":"void subfileCreated(const QString \u0026 filePath)","Funname":"subfileCreated","Returntype":"void","Args":"const QString \u0026 filePath"},{"Uniquefunname":" ~DFileWatcherManager()","Funname":"~DFileWatcherManager","Returntype":"","Args":""}],"Records":[{"Name":"macro","Fields":["DFILEWATCHERMANAGER_H"]},{"Name":"class:DFileWatcherManager","Fields":["QScopedPointer\u003cDFileWatcherManagerPrivate\u003e DFileWatcherManager::d_ptr"]}]} +{"Filepath":"src/filesystem/dpathbuf.h","Functions":[{"Uniquefunname":" DPathBuf()","Funname":"DPathBuf","Returntype":"","Args":""},{"Uniquefunname":" DPathBuf(const QString \u0026 path)","Funname":"DPathBuf","Returntype":"","Args":"const QString \u0026 path"},{"Uniquefunname":" DPathBuf::DPathBuf()","Funname":"DPathBuf::DPathBuf","Returntype":"","Args":""},{"Uniquefunname":" DPathBuf::DPathBuf(const QString \u0026 path)","Funname":"DPathBuf::DPathBuf","Returntype":"","Args":"const QString \u0026 path"},{"Uniquefunname":" DPathBuf \u0026join(const QString \u0026p)","Funname":"DPathBuf::join","Returntype":"DPathBuf \u0026","Args":"const QString \u0026 p"},{"Uniquefunname":"DPathBuf DPathBuf::operator /(const QString \u0026 p) cons)","Funname":"DPathBuf::operator /","Returntype":"DPathBuf","Args":"const QString \u0026 p) cons"},{"Uniquefunname":"DPathBuf DPathBuf::operator /(const char * p) cons)","Funname":"DPathBuf::operator /","Returntype":"DPathBuf","Args":"const char * p) cons"},{"Uniquefunname":" DPathBuf \u0026operator\\/=(const QString \u0026p)","Funname":"DPathBuf::operator /=","Returntype":"DPathBuf \u0026","Args":"const QString \u0026 p"},{"Uniquefunname":" DPathBuf \u0026operator\\/=(const char *p)","Funname":"DPathBuf::operator /=","Returntype":"DPathBuf \u0026","Args":"const char * p"},{"Uniquefunname":"QString DPathBuf::toString() cons)","Funname":"DPathBuf::toString","Returntype":"QString","Args":") cons"},{"Uniquefunname":" DPathBuf \u0026join(const QString \u0026p)","Funname":"join","Returntype":"DPathBuf \u0026","Args":"const QString \u0026 p"},{"Uniquefunname":"DPathBuf operator /(const QString \u0026 p) cons)","Funname":"operator /","Returntype":"DPathBuf","Args":"const QString \u0026 p) cons"},{"Uniquefunname":"DPathBuf operator /(const char * p) cons)","Funname":"operator /","Returntype":"DPathBuf","Args":"const char * p) cons"},{"Uniquefunname":" DPathBuf \u0026operator\\/=(const QString \u0026p)","Funname":"operator /=","Returntype":"DPathBuf \u0026","Args":"const QString \u0026 p"},{"Uniquefunname":" DPathBuf \u0026operator\\/=(const char *p)","Funname":"operator /=","Returntype":"DPathBuf \u0026","Args":"const char * p"},{"Uniquefunname":"QString toString() cons)","Funname":"toString","Returntype":"QString","Args":") cons"}],"Records":[{"Name":"class:DPathBuf","Fields":["QString DPathBuf::m_path"]}]} +{"Filepath":"src/filesystem/dstandardpaths.h","Functions":[{"Uniquefunname":" DStandardPaths()","Funname":"DStandardPaths","Returntype":"","Args":""},{"Uniquefunname":" DStandardPaths::DStandardPaths()","Funname":"DStandardPaths::DStandardPaths","Returntype":"","Args":""},{"Uniquefunname":"QString DStandardPaths::findExecutable(const QString \u0026 executableName,const QStringList \u0026 paths=QStringList ())","Funname":"DStandardPaths::findExecutable","Returntype":"QString","Args":"const QString \u0026 executableName,const QStringList \u0026 paths=QStringList ()"},{"Uniquefunname":"QString DStandardPaths::locate(QStandardPaths::StandardLocation type,const QString \u0026 fileName,QStandardPaths::LocateOptions options=QStandardPaths::LocateFile)","Funname":"DStandardPaths::locate","Returntype":"QString","Args":"QStandardPaths::StandardLocation type,const QString \u0026 fileName,QStandardPaths::LocateOptions options=QStandardPaths::LocateFile"},{"Uniquefunname":"QStringList DStandardPaths::locateAll(QStandardPaths::StandardLocation type,const QString \u0026 fileName,QStandardPaths::LocateOptions options=QStandardPaths::LocateFile)","Funname":"DStandardPaths::locateAll","Returntype":"QStringList","Args":"QStandardPaths::StandardLocation type,const QString \u0026 fileName,QStandardPaths::LocateOptions options=QStandardPaths::LocateFile"},{"Uniquefunname":"void DStandardPaths::setMode(Mode mode)","Funname":"DStandardPaths::setMode","Returntype":"void","Args":"Mode mode"},{"Uniquefunname":"QStringList DStandardPaths::standardLocations(QStandardPaths::StandardLocation type)","Funname":"DStandardPaths::standardLocations","Returntype":"QStringList","Args":"QStandardPaths::StandardLocation type"},{"Uniquefunname":"QString DStandardPaths::writableLocation(QStandardPaths::StandardLocation type)","Funname":"DStandardPaths::writableLocation","Returntype":"QString","Args":"QStandardPaths::StandardLocation type"},{"Uniquefunname":" DStandardPaths::~DStandardPaths()","Funname":"DStandardPaths::~DStandardPaths","Returntype":"","Args":""},{"Uniquefunname":"QString findExecutable(const QString \u0026 executableName,const QStringList \u0026 paths=QStringList ())","Funname":"findExecutable","Returntype":"QString","Args":"const QString \u0026 executableName,const QStringList \u0026 paths=QStringList ()"},{"Uniquefunname":"QString locate(QStandardPaths::StandardLocation type,const QString \u0026 fileName,QStandardPaths::LocateOptions options=QStandardPaths::LocateFile)","Funname":"locate","Returntype":"QString","Args":"QStandardPaths::StandardLocation type,const QString \u0026 fileName,QStandardPaths::LocateOptions options=QStandardPaths::LocateFile"},{"Uniquefunname":"QStringList locateAll(QStandardPaths::StandardLocation type,const QString \u0026 fileName,QStandardPaths::LocateOptions options=QStandardPaths::LocateFile)","Funname":"locateAll","Returntype":"QStringList","Args":"QStandardPaths::StandardLocation type,const QString \u0026 fileName,QStandardPaths::LocateOptions options=QStandardPaths::LocateFile"},{"Uniquefunname":"void setMode(Mode mode)","Funname":"setMode","Returntype":"void","Args":"Mode mode"},{"Uniquefunname":"QStringList standardLocations(QStandardPaths::StandardLocation type)","Funname":"standardLocations","Returntype":"QStringList","Args":"QStandardPaths::StandardLocation type"},{"Uniquefunname":"QString writableLocation(QStandardPaths::StandardLocation type)","Funname":"writableLocation","Returntype":"QString","Args":"QStandardPaths::StandardLocation type"},{"Uniquefunname":" ~DStandardPaths()","Funname":"~DStandardPaths","Returntype":"","Args":""}],"Records":[{"Name":"enum:DStandardPaths::Mode","Fields":["Auto","DStandardPaths::Auto","DStandardPaths::Snap","DStandardPaths::Test","Snap","Test"]},{"Name":"macro","Fields":["DTK_CORE_FILESYSTEM_DSTANDARDPATHS_H"]}]} +{"Filepath":"src/filesystem/dtrashmanager.h","Functions":[{"Uniquefunname":" DTrashManager()","Funname":"DTrashManager","Returntype":"","Args":""},{"Uniquefunname":" DTrashManager::DTrashManager()","Funname":"DTrashManager::DTrashManager","Returntype":"","Args":""},{"Uniquefunname":"bool DTrashManager::cleanTrash()","Funname":"DTrashManager::cleanTrash","Returntype":"bool","Args":""},{"Uniquefunname":"DTrashManager * DTrashManager::instance()","Funname":"DTrashManager::instance","Returntype":"DTrashManager *","Args":""},{"Uniquefunname":"bool DTrashManager::moveToTrash(const QString \u0026 filePath,bool followSymlink=false)","Funname":"DTrashManager::moveToTrash","Returntype":"bool","Args":"const QString \u0026 filePath,bool followSymlink=false"},{"Uniquefunname":"bool DTrashManager::trashIsEmpty() cons)","Funname":"DTrashManager::trashIsEmpty","Returntype":"bool","Args":") cons"},{"Uniquefunname":"bool cleanTrash()","Funname":"cleanTrash","Returntype":"bool","Args":""},{"Uniquefunname":"DTrashManager * instance()","Funname":"instance","Returntype":"DTrashManager *","Args":""},{"Uniquefunname":"bool moveToTrash(const QString \u0026 filePath,bool followSymlink=false)","Funname":"moveToTrash","Returntype":"bool","Args":"const QString \u0026 filePath,bool followSymlink=false"},{"Uniquefunname":"bool trashIsEmpty() cons)","Funname":"trashIsEmpty","Returntype":"bool","Args":") cons"}],"Records":[{"Name":"macro","Fields":["DTRASHMANAGER_H"]}]} +{"Filepath":"src/filesystem/private/dbasefilewatcher_p.h","Functions":[{"Uniquefunname":" DBaseFileWatcherPrivate(DBaseFileWatcher * qq)","Funname":"DBaseFileWatcherPrivate","Returntype":"","Args":"DBaseFileWatcher * qq"},{"Uniquefunname":" DBaseFileWatcherPrivate::DBaseFileWatcherPrivate(DBaseFileWatcher * qq)","Funname":"DBaseFileWatcherPrivate::DBaseFileWatcherPrivate","Returntype":"","Args":"DBaseFileWatcher * qq"},{"Uniquefunname":"bool DBaseFileWatcherPrivate::start()","Funname":"DBaseFileWatcherPrivate::start","Returntype":"bool","Args":""},{"Uniquefunname":"bool DBaseFileWatcherPrivate::stop()","Funname":"DBaseFileWatcherPrivate::stop","Returntype":"bool","Args":""},{"Uniquefunname":"bool start()","Funname":"start","Returntype":"bool","Args":""},{"Uniquefunname":"bool stop()","Funname":"stop","Returntype":"bool","Args":""}],"Records":[{"Name":"macro","Fields":["DBASEFILEWATCHER_P_H"]},{"Name":"class:DBaseFileWatcherPrivate","Fields":["bool DBaseFileWatcherPrivate::started","QUrl DBaseFileWatcherPrivate::url","QList\u003cDBaseFileWatcher * \u003e DBaseFileWatcherPrivate::watcherList"]}]} +{"Filepath":"src/filesystem/private/dfilesystemwatcher_dummy_p.h","Functions":[{"Uniquefunname":" DFileSystemWatcherPrivate(int fd,DFileSystemWatcher * qq)","Funname":"DFileSystemWatcherPrivate","Returntype":"","Args":"int fd,DFileSystemWatcher * qq"},{"Uniquefunname":" DFileSystemWatcherPrivate::DFileSystemWatcherPrivate(int fd,DFileSystemWatcher * qq)","Funname":"DFileSystemWatcherPrivate::DFileSystemWatcherPrivate","Returntype":"","Args":"int fd,DFileSystemWatcher * qq"},{"Uniquefunname":"void DFileSystemWatcherPrivate::_q_readFromInotify()","Funname":"DFileSystemWatcherPrivate::_q_readFromInotify","Returntype":"void","Args":""},{"Uniquefunname":"void DFileSystemWatcherPrivate::_q_readFromInotify()","Funname":"DFileSystemWatcherPrivate::_q_readFromInotify","Returntype":"void","Args":""},{"Uniquefunname":" DFileSystemWatcherPrivate::~DFileSystemWatcherPrivate()","Funname":"DFileSystemWatcherPrivate::~DFileSystemWatcherPrivate","Returntype":"","Args":""},{"Uniquefunname":"void _q_readFromInotify()","Funname":"_q_readFromInotify","Returntype":"void","Args":""},{"Uniquefunname":"void DFileSystemWatcherPrivate::_q_readFromInotify()","Funname":"_q_readFromInotify","Returntype":"void","Args":""},{"Uniquefunname":" ~DFileSystemWatcherPrivate()","Funname":"~DFileSystemWatcherPrivate","Returntype":"","Args":""}],"Records":[{"Name":"macro","Fields":["DFILESYSTEMWATCHER_WIN_P_H"]}]} +{"Filepath":"src/filesystem/private/dfilesystemwatcher_linux_p.h","Functions":[{"Uniquefunname":" DFileSystemWatcherPrivate(int fd,DFileSystemWatcher * qq)","Funname":"DFileSystemWatcherPrivate","Returntype":"","Args":"int fd,DFileSystemWatcher * qq"},{"Uniquefunname":" DFileSystemWatcherPrivate::DFileSystemWatcherPrivate(int fd,DFileSystemWatcher * qq)","Funname":"DFileSystemWatcherPrivate::DFileSystemWatcherPrivate","Returntype":"","Args":"int fd,DFileSystemWatcher * qq"},{"Uniquefunname":"void DFileSystemWatcherPrivate::_q_readFromInotify()","Funname":"DFileSystemWatcherPrivate::_q_readFromInotify","Returntype":"void","Args":""},{"Uniquefunname":"QStringList DFileSystemWatcherPrivate::addPaths(const QStringList \u0026 paths,QStringList * files,QStringList * directories)","Funname":"DFileSystemWatcherPrivate::addPaths","Returntype":"QStringList","Args":"const QStringList \u0026 paths,QStringList * files,QStringList * directories"},{"Uniquefunname":"void DFileSystemWatcherPrivate::onDirectoryChanged(const QString \u0026 path,bool removed)","Funname":"DFileSystemWatcherPrivate::onDirectoryChanged","Returntype":"void","Args":"const QString \u0026 path,bool removed"},{"Uniquefunname":"void DFileSystemWatcherPrivate::onFileChanged(const QString \u0026 path,bool removed)","Funname":"DFileSystemWatcherPrivate::onFileChanged","Returntype":"void","Args":"const QString \u0026 path,bool removed"},{"Uniquefunname":"QStringList DFileSystemWatcherPrivate::removePaths(const QStringList \u0026 paths,QStringList * files,QStringList * directories)","Funname":"DFileSystemWatcherPrivate::removePaths","Returntype":"QStringList","Args":"const QStringList \u0026 paths,QStringList * files,QStringList * directories"},{"Uniquefunname":" DFileSystemWatcherPrivate::~DFileSystemWatcherPrivate()","Funname":"DFileSystemWatcherPrivate::~DFileSystemWatcherPrivate","Returntype":"","Args":""},{"Uniquefunname":"void _q_readFromInotify()","Funname":"_q_readFromInotify","Returntype":"void","Args":""},{"Uniquefunname":"QStringList addPaths(const QStringList \u0026 paths,QStringList * files,QStringList * directories)","Funname":"addPaths","Returntype":"QStringList","Args":"const QStringList \u0026 paths,QStringList * files,QStringList * directories"},{"Uniquefunname":"void onDirectoryChanged(const QString \u0026 path,bool removed)","Funname":"onDirectoryChanged","Returntype":"void","Args":"const QString \u0026 path,bool removed"},{"Uniquefunname":"void onFileChanged(const QString \u0026 path,bool removed)","Funname":"onFileChanged","Returntype":"void","Args":"const QString \u0026 path,bool removed"},{"Uniquefunname":"QStringList removePaths(const QStringList \u0026 paths,QStringList * files,QStringList * directories)","Funname":"removePaths","Returntype":"QStringList","Args":"const QStringList \u0026 paths,QStringList * files,QStringList * directories"},{"Uniquefunname":" ~DFileSystemWatcherPrivate()","Funname":"~DFileSystemWatcherPrivate","Returntype":"","Args":""}],"Records":[{"Name":"macro","Fields":["DFILESYSTEMWATCHER_P_H"]},{"Name":"class:DFileSystemWatcherPrivate","Fields":["QStringList DFileSystemWatcherPrivate::directories","QStringList DFileSystemWatcherPrivate::files","QMultiHash\u003cint,QString\u003e DFileSystemWatcherPrivate::idToPath","int DFileSystemWatcherPrivate::inotifyFd","QSocketNotifier DFileSystemWatcherPrivate::notifier","QHash\u003cQString,int\u003e DFileSystemWatcherPrivate::pathToID"]}]} +{"Filepath":"src/filesystem/private/dfilesystemwatcher_win_p.h","Functions":[{"Uniquefunname":" DFileSystemWatcherPrivate(int fd,DFileSystemWatcher * qq)","Funname":"DFileSystemWatcherPrivate","Returntype":"","Args":"int fd,DFileSystemWatcher * qq"},{"Uniquefunname":" DFileSystemWatcherPrivate::DFileSystemWatcherPrivate(int fd,DFileSystemWatcher * qq)","Funname":"DFileSystemWatcherPrivate::DFileSystemWatcherPrivate","Returntype":"","Args":"int fd,DFileSystemWatcher * qq"},{"Uniquefunname":"void DFileSystemWatcherPrivate::_q_readFromInotify()","Funname":"DFileSystemWatcherPrivate::_q_readFromInotify","Returntype":"void","Args":""},{"Uniquefunname":"void DFileSystemWatcherPrivate::_q_readFromInotify()","Funname":"DFileSystemWatcherPrivate::_q_readFromInotify","Returntype":"void","Args":""},{"Uniquefunname":" DFileSystemWatcherPrivate::~DFileSystemWatcherPrivate()","Funname":"DFileSystemWatcherPrivate::~DFileSystemWatcherPrivate","Returntype":"","Args":""},{"Uniquefunname":"void _q_readFromInotify()","Funname":"_q_readFromInotify","Returntype":"void","Args":""},{"Uniquefunname":"void DFileSystemWatcherPrivate::_q_readFromInotify()","Funname":"_q_readFromInotify","Returntype":"void","Args":""},{"Uniquefunname":" ~DFileSystemWatcherPrivate()","Funname":"~DFileSystemWatcherPrivate","Returntype":"","Args":""}],"Records":[{"Name":"macro","Fields":["DFILESYSTEMWATCHER_WIN_P_H"]}]} +{"Filepath":"src/log/AbstractAppender.h","Functions":[{"Uniquefunname":" AbstractAppender()","Funname":"AbstractAppender","Returntype":"","Args":""},{"Uniquefunname":" AbstractAppender::AbstractAppender()","Funname":"AbstractAppender::AbstractAppender","Returntype":"","Args":""},{"Uniquefunname":"void AbstractAppender::append(const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message)","Funname":"AbstractAppender::append","Returntype":"void","Args":"const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message"},{"Uniquefunname":"Logger AbstractAppender::detailsLevel() cons)","Funname":"AbstractAppender::detailsLevel","Returntype":"Logger","Args":") cons"},{"Uniquefunname":"void AbstractAppender::setDetailsLevel(Logger::LogLevel level)","Funname":"AbstractAppender::setDetailsLevel","Returntype":"void","Args":"Logger::LogLevel level"},{"Uniquefunname":"void AbstractAppender::setDetailsLevel(const QString \u0026 level)","Funname":"AbstractAppender::setDetailsLevel","Returntype":"void","Args":"const QString \u0026 level"},{"Uniquefunname":"void AbstractAppender::write(const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message)","Funname":"AbstractAppender::write","Returntype":"void","Args":"const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message"},{"Uniquefunname":" AbstractAppender::~AbstractAppender()","Funname":"AbstractAppender::~AbstractAppender","Returntype":"","Args":""},{"Uniquefunname":"void append(const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message)","Funname":"append","Returntype":"void","Args":"const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message"},{"Uniquefunname":"Logger detailsLevel() cons)","Funname":"detailsLevel","Returntype":"Logger","Args":") cons"},{"Uniquefunname":"void setDetailsLevel(Logger::LogLevel level)","Funname":"setDetailsLevel","Returntype":"void","Args":"Logger::LogLevel level"},{"Uniquefunname":"void setDetailsLevel(const QString \u0026 level)","Funname":"setDetailsLevel","Returntype":"void","Args":"const QString \u0026 level"},{"Uniquefunname":"void write(const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message)","Funname":"write","Returntype":"void","Args":"const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message"},{"Uniquefunname":" ~AbstractAppender()","Funname":"~AbstractAppender","Returntype":"","Args":""}],"Records":[{"Name":"macro","Fields":["ABSTRACTAPPENDER_H"]},{"Name":"class:AbstractAppender","Fields":["Logger::LogLevel AbstractAppender::m_detailsLevel","QMutex AbstractAppender::m_detailsLevelMutex","QMutex AbstractAppender::m_writeMutex"]}]} +{"Filepath":"src/log/AbstractStringAppender.h","Functions":[{"Uniquefunname":" AbstractStringAppender()","Funname":"AbstractStringAppender","Returntype":"","Args":""},{"Uniquefunname":" AbstractStringAppender::AbstractStringAppender()","Funname":"AbstractStringAppender::AbstractStringAppender","Returntype":"","Args":""},{"Uniquefunname":"QString AbstractStringAppender::format() cons)","Funname":"AbstractStringAppender::format","Returntype":"QString","Args":") cons"},{"Uniquefunname":"QString AbstractStringAppender::formattedString(const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message) cons)","Funname":"AbstractStringAppender::formattedString","Returntype":"QString","Args":"const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message) cons"},{"Uniquefunname":"QByteArray AbstractStringAppender::qCleanupFuncinfo(const char *)","Funname":"AbstractStringAppender::qCleanupFuncinfo","Returntype":"QByteArray","Args":"const char *"},{"Uniquefunname":"void AbstractStringAppender::setFormat(const QString \u0026)","Funname":"AbstractStringAppender::setFormat","Returntype":"void","Args":"const QString \u0026"},{"Uniquefunname":"QString AbstractStringAppender::stripFunctionName(const char *)","Funname":"AbstractStringAppender::stripFunctionName","Returntype":"QString","Args":"const char *"},{"Uniquefunname":"QString format() cons)","Funname":"format","Returntype":"QString","Args":") cons"},{"Uniquefunname":"QString formattedString(const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message) cons)","Funname":"formattedString","Returntype":"QString","Args":"const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message) cons"},{"Uniquefunname":"QByteArray qCleanupFuncinfo(const char *)","Funname":"qCleanupFuncinfo","Returntype":"QByteArray","Args":"const char *"},{"Uniquefunname":"void setFormat(const QString \u0026)","Funname":"setFormat","Returntype":"void","Args":"const QString \u0026"},{"Uniquefunname":"QString stripFunctionName(const char *)","Funname":"stripFunctionName","Returntype":"QString","Args":"const char *"}],"Records":[{"Name":"macro","Fields":["ABSTRACTSTRINGAPPENDER_H"]},{"Name":"class:AbstractStringAppender","Fields":["QString AbstractStringAppender::m_format","QReadWriteLock AbstractStringAppender::m_formatLock"]}]} +{"Filepath":"src/log/ConsoleAppender.h","Functions":[{"Uniquefunname":" ConsoleAppender()","Funname":"ConsoleAppender","Returntype":"","Args":""},{"Uniquefunname":" ConsoleAppender::ConsoleAppender()","Funname":"ConsoleAppender::ConsoleAppender","Returntype":"","Args":""},{"Uniquefunname":"void ConsoleAppender::append(const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message)","Funname":"ConsoleAppender::append","Returntype":"void","Args":"const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message"},{"Uniquefunname":"QString ConsoleAppender::format() cons)","Funname":"ConsoleAppender::format","Returntype":"QString","Args":") cons"},{"Uniquefunname":"void ConsoleAppender::ignoreEnvironmentPattern(bool ignore)","Funname":"ConsoleAppender::ignoreEnvironmentPattern","Returntype":"void","Args":"bool ignore"},{"Uniquefunname":"void append(const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message)","Funname":"append","Returntype":"void","Args":"const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message"},{"Uniquefunname":"QString format() cons)","Funname":"format","Returntype":"QString","Args":") cons"},{"Uniquefunname":"void ignoreEnvironmentPattern(bool ignore)","Funname":"ignoreEnvironmentPattern","Returntype":"void","Args":"bool ignore"}],"Records":[{"Name":"macro","Fields":["CONSOLEAPPENDER_H"]},{"Name":"class:ConsoleAppender","Fields":["bool ConsoleAppender::m_ignoreEnvPattern"]}]} +{"Filepath":"src/log/CuteLogger_global.h","Functions":null,"Records":[{"Name":"macro","Fields":["CUTELOGGERSHARED_EXPORT","CUTELOGGERSHARED_EXPORT","CUTELOGGER_GLOBAL_H"]}]} +{"Filepath":"src/log/FileAppender.h","Functions":[{"Uniquefunname":" FileAppender(const QString \u0026 fileName=QString ())","Funname":"FileAppender","Returntype":"","Args":"const QString \u0026 fileName=QString ()"},{"Uniquefunname":" FileAppender::FileAppender(const QString \u0026 fileName=QString ())","Funname":"FileAppender::FileAppender","Returntype":"","Args":"const QString \u0026 fileName=QString ()"},{"Uniquefunname":"void FileAppender::append(const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message)","Funname":"FileAppender::append","Returntype":"void","Args":"const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message"},{"Uniquefunname":"void FileAppender::closeFile()","Funname":"FileAppender::closeFile","Returntype":"void","Args":""},{"Uniquefunname":"QString FileAppender::fileName() cons)","Funname":"FileAppender::fileName","Returntype":"QString","Args":") cons"},{"Uniquefunname":"bool FileAppender::openFile()","Funname":"FileAppender::openFile","Returntype":"bool","Args":""},{"Uniquefunname":"void FileAppender::setFileName(const QString \u0026)","Funname":"FileAppender::setFileName","Returntype":"void","Args":"const QString \u0026"},{"Uniquefunname":"qint64 FileAppender::size() cons)","Funname":"FileAppender::size","Returntype":"qint64","Args":") cons"},{"Uniquefunname":" FileAppender::~FileAppender()","Funname":"FileAppender::~FileAppender","Returntype":"","Args":""},{"Uniquefunname":"void append(const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message)","Funname":"append","Returntype":"void","Args":"const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message"},{"Uniquefunname":"void closeFile()","Funname":"closeFile","Returntype":"void","Args":""},{"Uniquefunname":"QString fileName() cons)","Funname":"fileName","Returntype":"QString","Args":") cons"},{"Uniquefunname":"bool openFile()","Funname":"openFile","Returntype":"bool","Args":""},{"Uniquefunname":"void setFileName(const QString \u0026)","Funname":"setFileName","Returntype":"void","Args":"const QString \u0026"},{"Uniquefunname":"qint64 size() cons)","Funname":"size","Returntype":"qint64","Args":") cons"},{"Uniquefunname":" ~FileAppender()","Funname":"~FileAppender","Returntype":"","Args":""}],"Records":[{"Name":"macro","Fields":["FILEAPPENDER_H"]},{"Name":"class:FileAppender","Fields":["QFile FileAppender::m_logFile","QMutex FileAppender::m_logFileMutex","QTextStream FileAppender::m_logStream"]}]} +{"Filepath":"src/log/LogManager.h","Functions":[{"Uniquefunname":" DLogManager(const DLogManager \u0026)","Funname":"DLogManager","Returntype":"","Args":"const DLogManager \u0026"},{"Uniquefunname":" DLogManager()","Funname":"DLogManager","Returntype":"","Args":""},{"Uniquefunname":" DLogManager::DLogManager(const DLogManager \u0026)","Funname":"DLogManager::DLogManager","Returntype":"","Args":"const DLogManager \u0026"},{"Uniquefunname":" DLogManager::DLogManager()","Funname":"DLogManager::DLogManager","Returntype":"","Args":""},{"Uniquefunname":"QString DLogManager::getlogFilePath()","Funname":"DLogManager::getlogFilePath","Returntype":"QString","Args":""},{"Uniquefunname":"void DLogManager::initConsoleAppender()","Funname":"DLogManager::initConsoleAppender","Returntype":"void","Args":""},{"Uniquefunname":"void DLogManager::initRollingFileAppender()","Funname":"DLogManager::initRollingFileAppender","Returntype":"void","Args":""},{"Uniquefunname":"DLogManager * DLogManager::instance()","Funname":"DLogManager::instance","Returntype":"DLogManager *","Args":""},{"Uniquefunname":"QString DLogManager::joinPath(const QString \u0026 path,const QString \u0026 fileName)","Funname":"DLogManager::joinPath","Returntype":"QString","Args":"const QString \u0026 path,const QString \u0026 fileName"},{"Uniquefunname":"DLogManager \u0026 DLogManager::operator =(const DLogManager \u0026)","Funname":"DLogManager::operator =","Returntype":"DLogManager \u0026","Args":"const DLogManager \u0026"},{"Uniquefunname":"void DLogManager::registerConsoleAppender()","Funname":"DLogManager::registerConsoleAppender","Returntype":"void","Args":""},{"Uniquefunname":"void DLogManager::registerFileAppender()","Funname":"DLogManager::registerFileAppender","Returntype":"void","Args":""},{"Uniquefunname":"void DLogManager::setLogFormat(const QString \u0026 format)","Funname":"DLogManager::setLogFormat","Returntype":"void","Args":"const QString \u0026 format"},{"Uniquefunname":"void DLogManager::setlogFilePath(const QString \u0026 logFilePath)","Funname":"DLogManager::setlogFilePath","Returntype":"void","Args":"const QString \u0026 logFilePath"},{"Uniquefunname":" DLogManager::~DLogManager()","Funname":"DLogManager::~DLogManager","Returntype":"","Args":""},{"Uniquefunname":"QString getlogFilePath()","Funname":"getlogFilePath","Returntype":"QString","Args":""},{"Uniquefunname":"void initConsoleAppender()","Funname":"initConsoleAppender","Returntype":"void","Args":""},{"Uniquefunname":"void initRollingFileAppender()","Funname":"initRollingFileAppender","Returntype":"void","Args":""},{"Uniquefunname":"DLogManager * instance()","Funname":"instance","Returntype":"DLogManager *","Args":""},{"Uniquefunname":"QString joinPath(const QString \u0026 path,const QString \u0026 fileName)","Funname":"joinPath","Returntype":"QString","Args":"const QString \u0026 path,const QString \u0026 fileName"},{"Uniquefunname":"DLogManager \u0026 operator =(const DLogManager \u0026)","Funname":"operator =","Returntype":"DLogManager \u0026","Args":"const DLogManager \u0026"},{"Uniquefunname":"void registerConsoleAppender()","Funname":"registerConsoleAppender","Returntype":"void","Args":""},{"Uniquefunname":"void registerFileAppender()","Funname":"registerFileAppender","Returntype":"void","Args":""},{"Uniquefunname":"void setLogFormat(const QString \u0026 format)","Funname":"setLogFormat","Returntype":"void","Args":"const QString \u0026 format"},{"Uniquefunname":"void setlogFilePath(const QString \u0026 logFilePath)","Funname":"setlogFilePath","Returntype":"void","Args":"const QString \u0026 logFilePath"},{"Uniquefunname":" ~DLogManager()","Funname":"~DLogManager","Returntype":"","Args":""}],"Records":[{"Name":"class:DLogManager","Fields":["ConsoleAppender * DLogManager::m_consoleAppender","QString DLogManager::m_format","QString DLogManager::m_logPath","RollingFileAppender * DLogManager::m_rollingFileAppender"]},{"Name":"macro","Fields":["LOGMANAGER_H"]}]} +{"Filepath":"src/log/Logger.h","Functions":[{"Uniquefunname":"Q_DECL_CONSTEXPR CuteMessageLogger(Logger * l,Logger::LogLevel level,const char * file,int line,const char * function)","Funname":"CuteMessageLogger","Returntype":"Q_DECL_CONSTEXPR","Args":"Logger * l,Logger::LogLevel level,const char * file,int line,const char * function"},{"Uniquefunname":"Q_DECL_CONSTEXPR CuteMessageLogger(Logger * l,Logger::LogLevel level,const char * file,int line,const char * function,const char * category)","Funname":"CuteMessageLogger","Returntype":"Q_DECL_CONSTEXPR","Args":"Logger * l,Logger::LogLevel level,const char * file,int line,const char * function,const char * category"},{"Uniquefunname":"Q_DECL_CONSTEXPR CuteMessageLogger::CuteMessageLogger(Logger * l,Logger::LogLevel level,const char * file,int line,const char * function)","Funname":"CuteMessageLogger::CuteMessageLogger","Returntype":"Q_DECL_CONSTEXPR","Args":"Logger * l,Logger::LogLevel level,const char * file,int line,const char * function"},{"Uniquefunname":"Q_DECL_CONSTEXPR CuteMessageLogger::CuteMessageLogger(Logger * l,Logger::LogLevel level,const char * file,int line,const char * function,const char * category)","Funname":"CuteMessageLogger::CuteMessageLogger","Returntype":"Q_DECL_CONSTEXPR","Args":"Logger * l,Logger::LogLevel level,const char * file,int line,const char * function,const char * category"},{"Uniquefunname":"QDebug CuteMessageLogger::write() cons)","Funname":"CuteMessageLogger::write","Returntype":"QDebug","Args":") cons"},{"Uniquefunname":"void CuteMessageLogger::write(const QString \u0026 msg) cons)","Funname":"CuteMessageLogger::write","Returntype":"void","Args":"const QString \u0026 msg) cons"},{"Uniquefunname":"void CuteMessageLogger::write(const char * msg,...) cons)","Funname":"CuteMessageLogger::write","Returntype":"void","Args":"const char * msg,...) cons"},{"Uniquefunname":" Logger()","Funname":"Logger","Returntype":"","Args":""},{"Uniquefunname":" Logger(const QString \u0026 defaultCategory)","Funname":"Logger","Returntype":"","Args":"const QString \u0026 defaultCategory"},{"Uniquefunname":" Logger::Logger()","Funname":"Logger::Logger","Returntype":"","Args":""},{"Uniquefunname":" Logger::Logger(const QString \u0026 defaultCategory)","Funname":"Logger::Logger","Returntype":"","Args":"const QString \u0026 defaultCategory"},{"Uniquefunname":" Q_DECLARE_PRIVATE(Logger)","Funname":"Logger::Q_DECLARE_PRIVATE","Returntype":"","Args":"Logger"},{"Uniquefunname":"QString Logger::defaultCategory() cons)","Funname":"Logger::defaultCategory","Returntype":"QString","Args":") cons"},{"Uniquefunname":"Logger * Logger::globalInstance()","Funname":"Logger::globalInstance","Returntype":"Logger *","Args":""},{"Uniquefunname":"LogLevel Logger::levelFromString(const QString \u0026 s)","Funname":"Logger::levelFromString","Returntype":"LogLevel","Args":"const QString \u0026 s"},{"Uniquefunname":"QString Logger::levelToString(LogLevel logLevel)","Funname":"Logger::levelToString","Returntype":"QString","Args":"LogLevel logLevel"},{"Uniquefunname":"void Logger::logToGlobalInstance(const QString \u0026 category,bool logToGlobal=false)","Funname":"Logger::logToGlobalInstance","Returntype":"void","Args":"const QString \u0026 category,bool logToGlobal=false"},{"Uniquefunname":"void Logger::registerAppender(AbstractAppender * appender)","Funname":"Logger::registerAppender","Returntype":"void","Args":"AbstractAppender * appender"},{"Uniquefunname":"void Logger::registerCategoryAppender(const QString \u0026 category,AbstractAppender * appender)","Funname":"Logger::registerCategoryAppender","Returntype":"void","Args":"const QString \u0026 category,AbstractAppender * appender"},{"Uniquefunname":"void Logger::setDefaultCategory(const QString \u0026 category)","Funname":"Logger::setDefaultCategory","Returntype":"void","Args":"const QString \u0026 category"},{"Uniquefunname":"QDebug Logger::write(LogLevel logLevel,const char * file,int line,const char * function,const char * category)","Funname":"Logger::write","Returntype":"QDebug","Args":"LogLevel logLevel,const char * file,int line,const char * function,const char * category"},{"Uniquefunname":"void Logger::write(LogLevel logLevel,const char * file,int line,const char * function,const char * category,const QString \u0026 message)","Funname":"Logger::write","Returntype":"void","Args":"LogLevel logLevel,const char * file,int line,const char * function,const char * category,const QString \u0026 message"},{"Uniquefunname":"void Logger::write(const QDateTime \u0026 timeStamp,LogLevel logLevel,const char * file,int line,const char * function,const char * category,const QString \u0026 message,bool fromLocalInstance)","Funname":"Logger::write","Returntype":"void","Args":"const QDateTime \u0026 timeStamp,LogLevel logLevel,const char * file,int line,const char * function,const char * category,const QString \u0026 message,bool fromLocalInstance"},{"Uniquefunname":"void Logger::write(const QDateTime \u0026 timeStamp,LogLevel logLevel,const char * file,int line,const char * function,const char * category,const QString \u0026 message)","Funname":"Logger::write","Returntype":"void","Args":"const QDateTime \u0026 timeStamp,LogLevel logLevel,const char * file,int line,const char * function,const char * category,const QString \u0026 message"},{"Uniquefunname":"void Logger::writeAssert(const char * file,int line,const char * function,const char * condition)","Funname":"Logger::writeAssert","Returntype":"void","Args":"const char * file,int line,const char * function,const char * condition"},{"Uniquefunname":" Logger::~Logger()","Funname":"Logger::~Logger","Returntype":"","Args":""},{"Uniquefunname":" LoggerTimingHelper(Logger * l,Logger::LogLevel logLevel,const char * file,int line,const char * function)","Funname":"LoggerTimingHelper","Returntype":"","Args":"Logger * l,Logger::LogLevel logLevel,const char * file,int line,const char * function"},{"Uniquefunname":" LoggerTimingHelper::LoggerTimingHelper(Logger * l,Logger::LogLevel logLevel,const char * file,int line,const char * function)","Funname":"LoggerTimingHelper::LoggerTimingHelper","Returntype":"","Args":"Logger * l,Logger::LogLevel logLevel,const char * file,int line,const char * function"},{"Uniquefunname":"void LoggerTimingHelper::start(const QString \u0026 msg=QString ())","Funname":"LoggerTimingHelper::start","Returntype":"void","Args":"const QString \u0026 msg=QString ()"},{"Uniquefunname":" void start(const char *msg, ...)","Funname":"LoggerTimingHelper::start","Returntype":"void","Args":"const char * msg,..."},{"Uniquefunname":" LoggerTimingHelper::~LoggerTimingHelper()","Funname":"LoggerTimingHelper::~LoggerTimingHelper","Returntype":"","Args":""},{"Uniquefunname":" Q_DECLARE_PRIVATE(Logger)","Funname":"Q_DECLARE_PRIVATE","Returntype":"","Args":"Logger"},{"Uniquefunname":"QString defaultCategory() cons)","Funname":"defaultCategory","Returntype":"QString","Args":") cons"},{"Uniquefunname":"Logger * globalInstance()","Funname":"globalInstance","Returntype":"Logger *","Args":""},{"Uniquefunname":"LogLevel levelFromString(const QString \u0026 s)","Funname":"levelFromString","Returntype":"LogLevel","Args":"const QString \u0026 s"},{"Uniquefunname":"QString levelToString(LogLevel logLevel)","Funname":"levelToString","Returntype":"QString","Args":"LogLevel logLevel"},{"Uniquefunname":"void logToGlobalInstance(const QString \u0026 category,bool logToGlobal=false)","Funname":"logToGlobalInstance","Returntype":"void","Args":"const QString \u0026 category,bool logToGlobal=false"},{"Uniquefunname":"CUTELOGGERSHARED_EXPORT Logger * loggerInstance()","Funname":"loggerInstance","Returntype":"CUTELOGGERSHARED_EXPORT Logger *","Args":""},{"Uniquefunname":"void registerAppender(AbstractAppender * appender)","Funname":"registerAppender","Returntype":"void","Args":"AbstractAppender * appender"},{"Uniquefunname":"void registerCategoryAppender(const QString \u0026 category,AbstractAppender * appender)","Funname":"registerCategoryAppender","Returntype":"void","Args":"const QString \u0026 category,AbstractAppender * appender"},{"Uniquefunname":"void setDefaultCategory(const QString \u0026 category)","Funname":"setDefaultCategory","Returntype":"void","Args":"const QString \u0026 category"},{"Uniquefunname":"void start(const QString \u0026 msg=QString ())","Funname":"start","Returntype":"void","Args":"const QString \u0026 msg=QString ()"},{"Uniquefunname":" void start(const char *msg, ...)","Funname":"start","Returntype":"void","Args":"const char * msg,..."},{"Uniquefunname":"QDebug write() cons)","Funname":"write","Returntype":"QDebug","Args":") cons"},{"Uniquefunname":"QDebug write(LogLevel logLevel,const char * file,int line,const char * function,const char * category)","Funname":"write","Returntype":"QDebug","Args":"LogLevel logLevel,const char * file,int line,const char * function,const char * category"},{"Uniquefunname":"void write(LogLevel logLevel,const char * file,int line,const char * function,const char * category,const QString \u0026 message)","Funname":"write","Returntype":"void","Args":"LogLevel logLevel,const char * file,int line,const char * function,const char * category,const QString \u0026 message"},{"Uniquefunname":"void write(const QDateTime \u0026 timeStamp,LogLevel logLevel,const char * file,int line,const char * function,const char * category,const QString \u0026 message,bool fromLocalInstance)","Funname":"write","Returntype":"void","Args":"const QDateTime \u0026 timeStamp,LogLevel logLevel,const char * file,int line,const char * function,const char * category,const QString \u0026 message,bool fromLocalInstance"},{"Uniquefunname":"void write(const QDateTime \u0026 timeStamp,LogLevel logLevel,const char * file,int line,const char * function,const char * category,const QString \u0026 message)","Funname":"write","Returntype":"void","Args":"const QDateTime \u0026 timeStamp,LogLevel logLevel,const char * file,int line,const char * function,const char * category,const QString \u0026 message"},{"Uniquefunname":"void write(const QString \u0026 msg) cons)","Funname":"write","Returntype":"void","Args":"const QString \u0026 msg) cons"},{"Uniquefunname":"void write(const char * msg,...) cons)","Funname":"write","Returntype":"void","Args":"const char * msg,...) cons"},{"Uniquefunname":"void writeAssert(const char * file,int line,const char * function,const char * condition)","Funname":"writeAssert","Returntype":"void","Args":"const char * file,int line,const char * function,const char * condition"},{"Uniquefunname":" ~Logger()","Funname":"~Logger","Returntype":"","Args":""},{"Uniquefunname":" ~LoggerTimingHelper()","Funname":"~LoggerTimingHelper","Returntype":"","Args":""}],"Records":[{"Name":"class:CuteMessageLogger","Fields":["const char * CuteMessageLogger::m_category","const char * CuteMessageLogger::m_file","const char * CuteMessageLogger::m_function","Logger * CuteMessageLogger::m_l","Logger::LogLevel CuteMessageLogger::m_level","int CuteMessageLogger::m_line"]},{"Name":"enum:Logger::LogLevel","Fields":["Debug","Error","Fatal","Info","Logger::Debug","Logger::Error","Logger::Fatal","Logger::Info","Logger::Trace","Logger::Warning","Trace","Warning"]},{"Name":"macro","Fields":["LOGGER_H","dAssert(cond)","dAssertX(cond,msg)","dCDebug(category)","dCError(category)","dCFatal(category)","dCInfo(category)","dCTrace(category)","dCWarning(category)","dCategory(category)","dDebug","dDebugTime","dError","dFatal","dGlobalCategory(category)","dInfo","dInfoTime","dTrace","dTraceTime","dWarning","logger"]},{"Name":"class:LoggerTimingHelper","Fields":["QString LoggerTimingHelper::m_block","const char * LoggerTimingHelper::m_file","const char * LoggerTimingHelper::m_function","int LoggerTimingHelper::m_line","Logger::LogLevel LoggerTimingHelper::m_logLevel","Logger * LoggerTimingHelper::m_logger","QTime LoggerTimingHelper::m_time"]}]} +{"Filepath":"src/log/OutputDebugAppender.h","Functions":[{"Uniquefunname":"void OutputDebugAppender::append(const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message)","Funname":"OutputDebugAppender::append","Returntype":"void","Args":"const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message"},{"Uniquefunname":"void append(const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message)","Funname":"append","Returntype":"void","Args":"const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message"}],"Records":[{"Name":"macro","Fields":["OUTPUTDEBUGAPPENDER_H"]}]} +{"Filepath":"src/log/RollingFileAppender.h","Functions":[{"Uniquefunname":" RollingFileAppender(const QString \u0026 fileName=QString ())","Funname":"RollingFileAppender","Returntype":"","Args":"const QString \u0026 fileName=QString ()"},{"Uniquefunname":" RollingFileAppender::RollingFileAppender(const QString \u0026 fileName=QString ())","Funname":"RollingFileAppender::RollingFileAppender","Returntype":"","Args":"const QString \u0026 fileName=QString ()"},{"Uniquefunname":"void RollingFileAppender::append(const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message)","Funname":"RollingFileAppender::append","Returntype":"void","Args":"const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message"},{"Uniquefunname":"void RollingFileAppender::computeFrequency()","Funname":"RollingFileAppender::computeFrequency","Returntype":"void","Args":""},{"Uniquefunname":"void RollingFileAppender::computeRollOverTime()","Funname":"RollingFileAppender::computeRollOverTime","Returntype":"void","Args":""},{"Uniquefunname":"DatePattern RollingFileAppender::datePattern() cons)","Funname":"RollingFileAppender::datePattern","Returntype":"DatePattern","Args":") cons"},{"Uniquefunname":"QString RollingFileAppender::datePatternString() cons)","Funname":"RollingFileAppender::datePatternString","Returntype":"QString","Args":") cons"},{"Uniquefunname":"int RollingFileAppender::logFilesLimit() cons)","Funname":"RollingFileAppender::logFilesLimit","Returntype":"int","Args":") cons"},{"Uniquefunname":"qint64 RollingFileAppender::logSizeLimit() cons)","Funname":"RollingFileAppender::logSizeLimit","Returntype":"qint64","Args":") cons"},{"Uniquefunname":"void RollingFileAppender::removeOldFiles()","Funname":"RollingFileAppender::removeOldFiles","Returntype":"void","Args":""},{"Uniquefunname":"void RollingFileAppender::rollOver()","Funname":"RollingFileAppender::rollOver","Returntype":"void","Args":""},{"Uniquefunname":"void RollingFileAppender::setDatePattern(DatePattern datePattern)","Funname":"RollingFileAppender::setDatePattern","Returntype":"void","Args":"DatePattern datePattern"},{"Uniquefunname":"void RollingFileAppender::setDatePattern(const QString \u0026 datePattern)","Funname":"RollingFileAppender::setDatePattern","Returntype":"void","Args":"const QString \u0026 datePattern"},{"Uniquefunname":"void RollingFileAppender::setDatePatternString(const QString \u0026 datePatternString)","Funname":"RollingFileAppender::setDatePatternString","Returntype":"void","Args":"const QString \u0026 datePatternString"},{"Uniquefunname":"void RollingFileAppender::setLogFilesLimit(int limit)","Funname":"RollingFileAppender::setLogFilesLimit","Returntype":"void","Args":"int limit"},{"Uniquefunname":"void RollingFileAppender::setLogSizeLimit(int qint64)","Funname":"RollingFileAppender::setLogSizeLimit","Returntype":"void","Args":"int qint64"},{"Uniquefunname":"void append(const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message)","Funname":"append","Returntype":"void","Args":"const QDateTime \u0026 timeStamp,Logger::LogLevel logLevel,const char * file,int line,const char * function,const QString \u0026 category,const QString \u0026 message"},{"Uniquefunname":"void computeFrequency()","Funname":"computeFrequency","Returntype":"void","Args":""},{"Uniquefunname":"void computeRollOverTime()","Funname":"computeRollOverTime","Returntype":"void","Args":""},{"Uniquefunname":"DatePattern datePattern() cons)","Funname":"datePattern","Returntype":"DatePattern","Args":") cons"},{"Uniquefunname":"QString datePatternString() cons)","Funname":"datePatternString","Returntype":"QString","Args":") cons"},{"Uniquefunname":"int logFilesLimit() cons)","Funname":"logFilesLimit","Returntype":"int","Args":") cons"},{"Uniquefunname":"qint64 logSizeLimit() cons)","Funname":"logSizeLimit","Returntype":"qint64","Args":") cons"},{"Uniquefunname":"void removeOldFiles()","Funname":"removeOldFiles","Returntype":"void","Args":""},{"Uniquefunname":"void rollOver()","Funname":"rollOver","Returntype":"void","Args":""},{"Uniquefunname":"void setDatePattern(DatePattern datePattern)","Funname":"setDatePattern","Returntype":"void","Args":"DatePattern datePattern"},{"Uniquefunname":"void setDatePattern(const QString \u0026 datePattern)","Funname":"setDatePattern","Returntype":"void","Args":"const QString \u0026 datePattern"},{"Uniquefunname":"void setDatePatternString(const QString \u0026 datePatternString)","Funname":"setDatePatternString","Returntype":"void","Args":"const QString \u0026 datePatternString"},{"Uniquefunname":"void setLogFilesLimit(int limit)","Funname":"setLogFilesLimit","Returntype":"void","Args":"int limit"},{"Uniquefunname":"void setLogSizeLimit(int qint64)","Funname":"setLogSizeLimit","Returntype":"void","Args":"int qint64"}],"Records":[{"Name":"enum:RollingFileAppender::DatePattern","Fields":["DailyRollover","HalfDailyRollover","HourlyRollover","MinutelyRollover","MonthlyRollover","RollingFileAppender::DailyRollover","RollingFileAppender::HalfDailyRollover","RollingFileAppender::HourlyRollover","RollingFileAppender::MinutelyRollover","RollingFileAppender::MonthlyRollover","RollingFileAppender::WeeklyRollover","WeeklyRollover"]},{"Name":"macro","Fields":["ROLLINGFILEAPPENDER_H"]},{"Name":"class:RollingFileAppender","Fields":["QString RollingFileAppender::m_datePatternString","DatePattern RollingFileAppender::m_frequency","int RollingFileAppender::m_logFilesLimit","qint64 RollingFileAppender::m_logSizeLimit","QString RollingFileAppender::m_rollOverSuffix","QDateTime RollingFileAppender::m_rollOverTime","QMutex RollingFileAppender::m_rollingMutex"]}]} +{"Filepath":"src/settings/dsettings.h","Functions":[{"Uniquefunname":" DSettings(QObject * parent=Q_NULLPTR)","Funname":"DSettings","Returntype":"","Args":"QObject * parent=Q_NULLPTR"},{"Uniquefunname":" DSettings::DSettings(QObject * parent=Q_NULLPTR)","Funname":"DSettings::DSettings","Returntype":"","Args":"QObject * parent=Q_NULLPTR"},{"Uniquefunname":"QPointer\u003cDSettings\u003e DSettings::fromJson(const QByteArray \u0026 json)","Funname":"DSettings::fromJson","Returntype":"QPointer\u003cDSettings\u003e","Args":"const QByteArray \u0026 json"},{"Uniquefunname":"QPointer\u003cDSettings\u003e DSettings::fromJsonFile(const QString \u0026 filepath)","Funname":"DSettings::fromJsonFile","Returntype":"QPointer\u003cDSettings\u003e","Args":"const QString \u0026 filepath"},{"Uniquefunname":"QVariant DSettings::getOption(const QString \u0026 key) cons)","Funname":"DSettings::getOption","Returntype":"QVariant","Args":"const QString \u0026 key) cons"},{"Uniquefunname":"QPointer\u003cDSettingsGroup\u003e DSettings::group(const QString \u0026 key) cons)","Funname":"DSettings::group","Returntype":"QPointer\u003cDSettingsGroup\u003e","Args":"const QString \u0026 key) cons"},{"Uniquefunname":"QStringList DSettings::groupKeys() cons)","Funname":"DSettings::groupKeys","Returntype":"QStringList","Args":") cons"},{"Uniquefunname":"QList\u003cQPointer\u003cDSettingsGroup\u003e\u003e DSettings::groups() cons)","Funname":"DSettings::groups","Returntype":"QList\u003cQPointer\u003cDSettingsGroup\u003e\u003e","Args":") cons"},{"Uniquefunname":"QStringList DSettings::keys() cons)","Funname":"DSettings::keys","Returntype":"QStringList","Args":") cons"},{"Uniquefunname":"void DSettings::loadValue()","Funname":"DSettings::loadValue","Returntype":"void","Args":""},{"Uniquefunname":"QJsonObject DSettings::meta() cons)","Funname":"DSettings::meta","Returntype":"QJsonObject","Args":") cons"},{"Uniquefunname":"QPointer\u003cDSettingsOption\u003e DSettings::option(const QString \u0026 key) cons)","Funname":"DSettings::option","Returntype":"QPointer\u003cDSettingsOption\u003e","Args":"const QString \u0026 key) cons"},{"Uniquefunname":"QList\u003cQPointer\u003cDSettingsOption\u003e\u003e DSettings::options() cons)","Funname":"DSettings::options","Returntype":"QList\u003cQPointer\u003cDSettingsOption\u003e\u003e","Args":") cons"},{"Uniquefunname":"void DSettings::parseJson(const QByteArray \u0026 json)","Funname":"DSettings::parseJson","Returntype":"void","Args":"const QByteArray \u0026 json"},{"Uniquefunname":"void DSettings::reset()","Funname":"DSettings::reset","Returntype":"void","Args":""},{"Uniquefunname":"void DSettings::setBackend(DSettingsBackend * backend=nullptr)","Funname":"DSettings::setBackend","Returntype":"void","Args":"DSettingsBackend * backend=nullptr"},{"Uniquefunname":"void DSettings::setOption(const QString \u0026 key,const QVariant \u0026 value)","Funname":"DSettings::setOption","Returntype":"void","Args":"const QString \u0026 key,const QVariant \u0026 value"},{"Uniquefunname":"void DSettings::sync()","Funname":"DSettings::sync","Returntype":"void","Args":""},{"Uniquefunname":"QVariant DSettings::value(const QString \u0026 key) cons)","Funname":"DSettings::value","Returntype":"QVariant","Args":"const QString \u0026 key) cons"},{"Uniquefunname":" DSettings::~DSettings()","Funname":"DSettings::~DSettings","Returntype":"","Args":""},{"Uniquefunname":"QPointer\u003cDSettings\u003e fromJson(const QByteArray \u0026 json)","Funname":"fromJson","Returntype":"QPointer\u003cDSettings\u003e","Args":"const QByteArray \u0026 json"},{"Uniquefunname":"QPointer\u003cDSettings\u003e fromJsonFile(const QString \u0026 filepath)","Funname":"fromJsonFile","Returntype":"QPointer\u003cDSettings\u003e","Args":"const QString \u0026 filepath"},{"Uniquefunname":"QVariant getOption(const QString \u0026 key) cons)","Funname":"getOption","Returntype":"QVariant","Args":"const QString \u0026 key) cons"},{"Uniquefunname":"QPointer\u003cDSettingsGroup\u003e group(const QString \u0026 key) cons)","Funname":"group","Returntype":"QPointer\u003cDSettingsGroup\u003e","Args":"const QString \u0026 key) cons"},{"Uniquefunname":"QStringList groupKeys() cons)","Funname":"groupKeys","Returntype":"QStringList","Args":") cons"},{"Uniquefunname":"QList\u003cQPointer\u003cDSettingsGroup\u003e\u003e groups() cons)","Funname":"groups","Returntype":"QList\u003cQPointer\u003cDSettingsGroup\u003e\u003e","Args":") cons"},{"Uniquefunname":"QStringList keys() cons)","Funname":"keys","Returntype":"QStringList","Args":") cons"},{"Uniquefunname":"void loadValue()","Funname":"loadValue","Returntype":"void","Args":""},{"Uniquefunname":"QJsonObject meta() cons)","Funname":"meta","Returntype":"QJsonObject","Args":") cons"},{"Uniquefunname":"QPointer\u003cDSettingsOption\u003e option(const QString \u0026 key) cons)","Funname":"option","Returntype":"QPointer\u003cDSettingsOption\u003e","Args":"const QString \u0026 key) cons"},{"Uniquefunname":"QList\u003cQPointer\u003cDSettingsOption\u003e\u003e options() cons)","Funname":"options","Returntype":"QList\u003cQPointer\u003cDSettingsOption\u003e\u003e","Args":") cons"},{"Uniquefunname":"void parseJson(const QByteArray \u0026 json)","Funname":"parseJson","Returntype":"void","Args":"const QByteArray \u0026 json"},{"Uniquefunname":"void reset()","Funname":"reset","Returntype":"void","Args":""},{"Uniquefunname":"void setBackend(DSettingsBackend * backend=nullptr)","Funname":"setBackend","Returntype":"void","Args":"DSettingsBackend * backend=nullptr"},{"Uniquefunname":"void setOption(const QString \u0026 key,const QVariant \u0026 value)","Funname":"setOption","Returntype":"void","Args":"const QString \u0026 key,const QVariant \u0026 value"},{"Uniquefunname":"void sync()","Funname":"sync","Returntype":"void","Args":""},{"Uniquefunname":"QVariant value(const QString \u0026 key) cons)","Funname":"value","Returntype":"QVariant","Args":"const QString \u0026 key) cons"},{"Uniquefunname":" ~DSettings()","Funname":"~DSettings","Returntype":"","Args":""}],"Records":[{"Name":"class:DSettings","Fields":["QScopedPointer\u003cDSettingsPrivate\u003e DSettings::dd_ptr"]}]} +{"Filepath":"src/settings/dsettingsbackend.h","Functions":[{"Uniquefunname":" explicit DSettingsBackend(QObject *parent = Q_NULLPTR): QObject(parent)","Funname":"DSettingsBackend","Returntype":"","Args":"QObject * parent=Q_NULLPTR"},{"Uniquefunname":" explicit DSettingsBackend(QObject *parent = Q_NULLPTR): QObject(parent)","Funname":"DSettingsBackend::DSettingsBackend","Returntype":"","Args":"QObject * parent=Q_NULLPTR"},{"Uniquefunname":"void DSettingsBackend::doSetOption(const QString \u0026 key,const QVariant \u0026 value)","Funname":"DSettingsBackend::doSetOption","Returntype":"void","Args":"const QString \u0026 key,const QVariant \u0026 value"},{"Uniquefunname":"void DSettingsBackend::doSync()","Funname":"DSettingsBackend::doSync","Returntype":"void","Args":""},{"Uniquefunname":"QVariant DSettingsBackend::getOption(const QString \u0026 key) cons)","Funname":"DSettingsBackend::getOption","Returntype":"QVariant","Args":"const QString \u0026 key) cons"},{"Uniquefunname":"QStringList DSettingsBackend::keys() cons)","Funname":"DSettingsBackend::keys","Returntype":"QStringList","Args":") cons"},{"Uniquefunname":"void DSettingsBackend::setOption(const QString \u0026 key,const QVariant \u0026 value)","Funname":"DSettingsBackend::setOption","Returntype":"void","Args":"const QString \u0026 key,const QVariant \u0026 value"},{"Uniquefunname":" DSettingsBackend::~DSettingsBackend()","Funname":"DSettingsBackend::~DSettingsBackend","Returntype":"","Args":""},{"Uniquefunname":"void doSetOption(const QString \u0026 key,const QVariant \u0026 value)","Funname":"doSetOption","Returntype":"void","Args":"const QString \u0026 key,const QVariant \u0026 value"},{"Uniquefunname":"void doSync()","Funname":"doSync","Returntype":"void","Args":""},{"Uniquefunname":"QVariant getOption(const QString \u0026 key) cons)","Funname":"getOption","Returntype":"QVariant","Args":"const QString \u0026 key) cons"},{"Uniquefunname":"QStringList keys() cons)","Funname":"keys","Returntype":"QStringList","Args":") cons"},{"Uniquefunname":"void setOption(const QString \u0026 key,const QVariant \u0026 value)","Funname":"setOption","Returntype":"void","Args":"const QString \u0026 key,const QVariant \u0026 value"},{"Uniquefunname":" ~DSettingsBackend()","Funname":"~DSettingsBackend","Returntype":"","Args":""}],"Records":null} +{"Filepath":"src/settings/dsettingsgroup.h","Functions":[{"Uniquefunname":" DSettingsGroup(QObject * parent=Q_NULLPTR)","Funname":"DSettingsGroup","Returntype":"","Args":"QObject * parent=Q_NULLPTR"},{"Uniquefunname":" DSettingsGroup::DSettingsGroup(QObject * parent=Q_NULLPTR)","Funname":"DSettingsGroup::DSettingsGroup","Returntype":"","Args":"QObject * parent=Q_NULLPTR"},{"Uniquefunname":"QPointer\u003cDSettingsGroup\u003e DSettingsGroup::childGroup(const QString \u0026 groupKey) cons)","Funname":"DSettingsGroup::childGroup","Returntype":"QPointer\u003cDSettingsGroup\u003e","Args":"const QString \u0026 groupKey) cons"},{"Uniquefunname":"QList\u003cQPointer\u003cDSettingsGroup\u003e\u003e DSettingsGroup::childGroups() cons)","Funname":"DSettingsGroup::childGroups","Returntype":"QList\u003cQPointer\u003cDSettingsGroup\u003e\u003e","Args":") cons"},{"Uniquefunname":"QList\u003cQPointer\u003cDSettingsOption\u003e\u003e DSettingsGroup::childOptions() cons)","Funname":"DSettingsGroup::childOptions","Returntype":"QList\u003cQPointer\u003cDSettingsOption\u003e\u003e","Args":") cons"},{"Uniquefunname":"QPointer\u003cDSettingsGroup\u003e DSettingsGroup::fromJson(const QString \u0026 prefixKey,const QJsonObject \u0026 group)","Funname":"DSettingsGroup::fromJson","Returntype":"QPointer\u003cDSettingsGroup\u003e","Args":"const QString \u0026 prefixKey,const QJsonObject \u0026 group"},{"Uniquefunname":"bool DSettingsGroup::isHidden() cons)","Funname":"DSettingsGroup::isHidden","Returntype":"bool","Args":") cons"},{"Uniquefunname":"QString DSettingsGroup::key() cons)","Funname":"DSettingsGroup::key","Returntype":"QString","Args":") cons"},{"Uniquefunname":"QString DSettingsGroup::name() cons)","Funname":"DSettingsGroup::name","Returntype":"QString","Args":") cons"},{"Uniquefunname":"QPointer\u003cDSettingsOption\u003e DSettingsGroup::option(const QString \u0026 key) cons)","Funname":"DSettingsGroup::option","Returntype":"QPointer\u003cDSettingsOption\u003e","Args":"const QString \u0026 key) cons"},{"Uniquefunname":"QList\u003cQPointer\u003cDSettingsOption\u003e\u003e DSettingsGroup::options() cons)","Funname":"DSettingsGroup::options","Returntype":"QList\u003cQPointer\u003cDSettingsOption\u003e\u003e","Args":") cons"},{"Uniquefunname":"QPointer\u003cDSettingsGroup\u003e DSettingsGroup::parentGroup() cons)","Funname":"DSettingsGroup::parentGroup","Returntype":"QPointer\u003cDSettingsGroup\u003e","Args":") cons"},{"Uniquefunname":"void DSettingsGroup::parseJson(const QString \u0026 prefixKey,const QJsonObject \u0026 group)","Funname":"DSettingsGroup::parseJson","Returntype":"void","Args":"const QString \u0026 prefixKey,const QJsonObject \u0026 group"},{"Uniquefunname":"void DSettingsGroup::setParentGroup(QPointer\u003cDSettingsGroup\u003e parentGroup)","Funname":"DSettingsGroup::setParentGroup","Returntype":"void","Args":"QPointer\u003cDSettingsGroup\u003e parentGroup"},{"Uniquefunname":" DSettingsGroup::~DSettingsGroup()","Funname":"DSettingsGroup::~DSettingsGroup","Returntype":"","Args":""},{"Uniquefunname":"QPointer\u003cDSettingsGroup\u003e childGroup(const QString \u0026 groupKey) cons)","Funname":"childGroup","Returntype":"QPointer\u003cDSettingsGroup\u003e","Args":"const QString \u0026 groupKey) cons"},{"Uniquefunname":"QList\u003cQPointer\u003cDSettingsGroup\u003e\u003e childGroups() cons)","Funname":"childGroups","Returntype":"QList\u003cQPointer\u003cDSettingsGroup\u003e\u003e","Args":") cons"},{"Uniquefunname":"QList\u003cQPointer\u003cDSettingsOption\u003e\u003e childOptions() cons)","Funname":"childOptions","Returntype":"QList\u003cQPointer\u003cDSettingsOption\u003e\u003e","Args":") cons"},{"Uniquefunname":"QPointer\u003cDSettingsGroup\u003e fromJson(const QString \u0026 prefixKey,const QJsonObject \u0026 group)","Funname":"fromJson","Returntype":"QPointer\u003cDSettingsGroup\u003e","Args":"const QString \u0026 prefixKey,const QJsonObject \u0026 group"},{"Uniquefunname":"bool isHidden() cons)","Funname":"isHidden","Returntype":"bool","Args":") cons"},{"Uniquefunname":"QString key() cons)","Funname":"key","Returntype":"QString","Args":") cons"},{"Uniquefunname":"QString name() cons)","Funname":"name","Returntype":"QString","Args":") cons"},{"Uniquefunname":"QPointer\u003cDSettingsOption\u003e option(const QString \u0026 key) cons)","Funname":"option","Returntype":"QPointer\u003cDSettingsOption\u003e","Args":"const QString \u0026 key) cons"},{"Uniquefunname":"QList\u003cQPointer\u003cDSettingsOption\u003e\u003e options() cons)","Funname":"options","Returntype":"QList\u003cQPointer\u003cDSettingsOption\u003e\u003e","Args":") cons"},{"Uniquefunname":"QPointer\u003cDSettingsGroup\u003e parentGroup() cons)","Funname":"parentGroup","Returntype":"QPointer\u003cDSettingsGroup\u003e","Args":") cons"},{"Uniquefunname":"void parseJson(const QString \u0026 prefixKey,const QJsonObject \u0026 group)","Funname":"parseJson","Returntype":"void","Args":"const QString \u0026 prefixKey,const QJsonObject \u0026 group"},{"Uniquefunname":"void setParentGroup(QPointer\u003cDSettingsGroup\u003e parentGroup)","Funname":"setParentGroup","Returntype":"void","Args":"QPointer\u003cDSettingsGroup\u003e parentGroup"},{"Uniquefunname":" ~DSettingsGroup()","Funname":"~DSettingsGroup","Returntype":"","Args":""}],"Records":[{"Name":"class:DSettingsGroup","Fields":["QScopedPointer\u003cDSettingsGroupPrivate\u003e DSettingsGroup::dd_ptr"]}]} +{"Filepath":"src/settings/dsettingsoption.h","Functions":[{"Uniquefunname":" DSettingsOption(QObject * parent=Q_NULLPTR)","Funname":"DSettingsOption","Returntype":"","Args":"QObject * parent=Q_NULLPTR"},{"Uniquefunname":" DSettingsOption::DSettingsOption(QObject * parent=Q_NULLPTR)","Funname":"DSettingsOption::DSettingsOption","Returntype":"","Args":"QObject * parent=Q_NULLPTR"},{"Uniquefunname":"bool DSettingsOption::canReset() cons)","Funname":"DSettingsOption::canReset","Returntype":"bool","Args":") cons"},{"Uniquefunname":"QVariant DSettingsOption::data(const QString \u0026 dataType) cons)","Funname":"DSettingsOption::data","Returntype":"QVariant","Args":"const QString \u0026 dataType) cons"},{"Uniquefunname":"void DSettingsOption::dataChanged(const QString \u0026 dataType,QVariant value)","Funname":"DSettingsOption::dataChanged","Returntype":"void","Args":"const QString \u0026 dataType,QVariant value"},{"Uniquefunname":"QVariant DSettingsOption::defaultValue() cons)","Funname":"DSettingsOption::defaultValue","Returntype":"QVariant","Args":") cons"},{"Uniquefunname":"QPointer\u003cDSettingsOption\u003e DSettingsOption::fromJson(const QString \u0026 prefixKey,const QJsonObject \u0026 json)","Funname":"DSettingsOption::fromJson","Returntype":"QPointer\u003cDSettingsOption\u003e","Args":"const QString \u0026 prefixKey,const QJsonObject \u0026 json"},{"Uniquefunname":"bool DSettingsOption::isHidden() cons)","Funname":"DSettingsOption::isHidden","Returntype":"bool","Args":") cons"},{"Uniquefunname":"QString DSettingsOption::key() cons)","Funname":"DSettingsOption::key","Returntype":"QString","Args":") cons"},{"Uniquefunname":"QString DSettingsOption::name() cons)","Funname":"DSettingsOption::name","Returntype":"QString","Args":") cons"},{"Uniquefunname":"QPointer\u003cDSettingsGroup\u003e DSettingsOption::parentGroup() cons)","Funname":"DSettingsOption::parentGroup","Returntype":"QPointer\u003cDSettingsGroup\u003e","Args":") cons"},{"Uniquefunname":"void DSettingsOption::parseJson(const QString \u0026 prefixKey,const QJsonObject \u0026 option)","Funname":"DSettingsOption::parseJson","Returntype":"void","Args":"const QString \u0026 prefixKey,const QJsonObject \u0026 option"},{"Uniquefunname":"void DSettingsOption::setData(const QString \u0026 dataType,QVariant value)","Funname":"DSettingsOption::setData","Returntype":"void","Args":"const QString \u0026 dataType,QVariant value"},{"Uniquefunname":"void DSettingsOption::setParentGroup(QPointer\u003cDSettingsGroup\u003e parentGroup)","Funname":"DSettingsOption::setParentGroup","Returntype":"void","Args":"QPointer\u003cDSettingsGroup\u003e parentGroup"},{"Uniquefunname":"void DSettingsOption::setValue(QVariant value)","Funname":"DSettingsOption::setValue","Returntype":"void","Args":"QVariant value"},{"Uniquefunname":"QVariant DSettingsOption::value() cons)","Funname":"DSettingsOption::value","Returntype":"QVariant","Args":") cons"},{"Uniquefunname":"QString DSettingsOption::viewType() cons)","Funname":"DSettingsOption::viewType","Returntype":"QString","Args":") cons"},{"Uniquefunname":" DSettingsOption::~DSettingsOption()","Funname":"DSettingsOption::~DSettingsOption","Returntype":"","Args":""},{"Uniquefunname":"bool canReset() cons)","Funname":"canReset","Returntype":"bool","Args":") cons"},{"Uniquefunname":"QVariant data(const QString \u0026 dataType) cons)","Funname":"data","Returntype":"QVariant","Args":"const QString \u0026 dataType) cons"},{"Uniquefunname":"void dataChanged(const QString \u0026 dataType,QVariant value)","Funname":"dataChanged","Returntype":"void","Args":"const QString \u0026 dataType,QVariant value"},{"Uniquefunname":"QVariant defaultValue() cons)","Funname":"defaultValue","Returntype":"QVariant","Args":") cons"},{"Uniquefunname":"QPointer\u003cDSettingsOption\u003e fromJson(const QString \u0026 prefixKey,const QJsonObject \u0026 json)","Funname":"fromJson","Returntype":"QPointer\u003cDSettingsOption\u003e","Args":"const QString \u0026 prefixKey,const QJsonObject \u0026 json"},{"Uniquefunname":"bool isHidden() cons)","Funname":"isHidden","Returntype":"bool","Args":") cons"},{"Uniquefunname":"QString key() cons)","Funname":"key","Returntype":"QString","Args":") cons"},{"Uniquefunname":"QString name() cons)","Funname":"name","Returntype":"QString","Args":") cons"},{"Uniquefunname":"QPointer\u003cDSettingsGroup\u003e parentGroup() cons)","Funname":"parentGroup","Returntype":"QPointer\u003cDSettingsGroup\u003e","Args":") cons"},{"Uniquefunname":"void parseJson(const QString \u0026 prefixKey,const QJsonObject \u0026 option)","Funname":"parseJson","Returntype":"void","Args":"const QString \u0026 prefixKey,const QJsonObject \u0026 option"},{"Uniquefunname":"void setData(const QString \u0026 dataType,QVariant value)","Funname":"setData","Returntype":"void","Args":"const QString \u0026 dataType,QVariant value"},{"Uniquefunname":"void setParentGroup(QPointer\u003cDSettingsGroup\u003e parentGroup)","Funname":"setParentGroup","Returntype":"void","Args":"QPointer\u003cDSettingsGroup\u003e parentGroup"},{"Uniquefunname":"void setValue(QVariant value)","Funname":"setValue","Returntype":"void","Args":"QVariant value"},{"Uniquefunname":"QVariant value() cons)","Funname":"value","Returntype":"QVariant","Args":") cons"},{"Uniquefunname":"QString viewType() cons)","Funname":"viewType","Returntype":"QString","Args":") cons"},{"Uniquefunname":" ~DSettingsOption()","Funname":"~DSettingsOption","Returntype":"","Args":""}],"Records":[{"Name":"class:DSettingsOption","Fields":["QScopedPointer\u003cDSettingsOptionPrivate\u003e DSettingsOption::dd_ptr"]}]} +{"Filepath":"src/settings/backend/gsettingsbackend.h","Functions":[{"Uniquefunname":" GSettingsBackend(DSettings * settings,QObject * parent=nullptr)","Funname":"GSettingsBackend","Returntype":"","Args":"DSettings * settings,QObject * parent=nullptr"},{"Uniquefunname":" GSettingsBackend::GSettingsBackend(DSettings * settings,QObject * parent=nullptr)","Funname":"GSettingsBackend::GSettingsBackend","Returntype":"","Args":"DSettings * settings,QObject * parent=nullptr"},{"Uniquefunname":"void GSettingsBackend::doSetOption(const QString \u0026 key,const QVariant \u0026 value)","Funname":"GSettingsBackend::doSetOption","Returntype":"void","Args":"const QString \u0026 key,const QVariant \u0026 value"},{"Uniquefunname":"void GSettingsBackend::doSync()","Funname":"GSettingsBackend::doSync","Returntype":"void","Args":""},{"Uniquefunname":"QVariant GSettingsBackend::getOption(const QString \u0026 key) cons)","Funname":"GSettingsBackend::getOption","Returntype":"QVariant","Args":"const QString \u0026 key) cons"},{"Uniquefunname":"QStringList GSettingsBackend::keys() cons)","Funname":"GSettingsBackend::keys","Returntype":"QStringList","Args":") cons"},{"Uniquefunname":" GSettingsBackend::~GSettingsBackend()","Funname":"GSettingsBackend::~GSettingsBackend","Returntype":"","Args":""},{"Uniquefunname":"void doSetOption(const QString \u0026 key,const QVariant \u0026 value)","Funname":"doSetOption","Returntype":"void","Args":"const QString \u0026 key,const QVariant \u0026 value"},{"Uniquefunname":"void doSync()","Funname":"doSync","Returntype":"void","Args":""},{"Uniquefunname":"QVariant getOption(const QString \u0026 key) cons)","Funname":"getOption","Returntype":"QVariant","Args":"const QString \u0026 key) cons"},{"Uniquefunname":"QStringList keys() cons)","Funname":"keys","Returntype":"QStringList","Args":") cons"},{"Uniquefunname":" ~GSettingsBackend()","Funname":"~GSettingsBackend","Returntype":"","Args":""}],"Records":[{"Name":"class:GSettingsBackend","Fields":["QScopedPointer\u003cGSettingsBackendPrivate\u003e GSettingsBackend::d_ptr"]}]} +{"Filepath":"src/settings/backend/qsettingbackend.h","Functions":[{"Uniquefunname":" QSettingBackend(const QString \u0026 filepath,QObject * parent=0)","Funname":"QSettingBackend","Returntype":"","Args":"const QString \u0026 filepath,QObject * parent=0"},{"Uniquefunname":" QSettingBackend::QSettingBackend(const QString \u0026 filepath,QObject * parent=0)","Funname":"QSettingBackend::QSettingBackend","Returntype":"","Args":"const QString \u0026 filepath,QObject * parent=0"},{"Uniquefunname":"void QSettingBackend::doSetOption(const QString \u0026 key,const QVariant \u0026 value)","Funname":"QSettingBackend::doSetOption","Returntype":"void","Args":"const QString \u0026 key,const QVariant \u0026 value"},{"Uniquefunname":"void QSettingBackend::doSync()","Funname":"QSettingBackend::doSync","Returntype":"void","Args":""},{"Uniquefunname":"QVariant QSettingBackend::getOption(const QString \u0026 key) cons)","Funname":"QSettingBackend::getOption","Returntype":"QVariant","Args":"const QString \u0026 key) cons"},{"Uniquefunname":"QStringList QSettingBackend::keys() cons)","Funname":"QSettingBackend::keys","Returntype":"QStringList","Args":") cons"},{"Uniquefunname":" QSettingBackend::~QSettingBackend()","Funname":"QSettingBackend::~QSettingBackend","Returntype":"","Args":""},{"Uniquefunname":"void doSetOption(const QString \u0026 key,const QVariant \u0026 value)","Funname":"doSetOption","Returntype":"void","Args":"const QString \u0026 key,const QVariant \u0026 value"},{"Uniquefunname":"void doSync()","Funname":"doSync","Returntype":"void","Args":""},{"Uniquefunname":"QVariant getOption(const QString \u0026 key) cons)","Funname":"getOption","Returntype":"QVariant","Args":"const QString \u0026 key) cons"},{"Uniquefunname":"QStringList keys() cons)","Funname":"keys","Returntype":"QStringList","Args":") cons"},{"Uniquefunname":" ~QSettingBackend()","Funname":"~QSettingBackend","Returntype":"","Args":""}],"Records":[{"Name":"class:QSettingBackend","Fields":["QScopedPointer\u003cQSettingBackendPrivate\u003e QSettingBackend::d_ptr"]}]} +{"Filepath":"src/util/dabstractunitformatter.h","Functions":[{"Uniquefunname":" DAbstractUnitFormatter()","Funname":"DAbstractUnitFormatter","Returntype":"","Args":""},{"Uniquefunname":" DAbstractUnitFormatter::DAbstractUnitFormatter()","Funname":"DAbstractUnitFormatter::DAbstractUnitFormatter","Returntype":"","Args":""},{"Uniquefunname":"QPair\u003cqreal,int\u003e DAbstractUnitFormatter::format(const qreal value,const int unit) cons)","Funname":"DAbstractUnitFormatter::format","Returntype":"QPair\u003cqreal,int\u003e","Args":"const qreal value,const int unit) cons"},{"Uniquefunname":"qreal DAbstractUnitFormatter::formatAs(qreal value,int currentUnit,const int targetUnit) cons)","Funname":"DAbstractUnitFormatter::formatAs","Returntype":"qreal","Args":"qreal value,int currentUnit,const int targetUnit) cons"},{"Uniquefunname":"QList\u003cQPair\u003cqreal,int\u003e\u003e DAbstractUnitFormatter::formatAsUnitList(const qreal value,int unit) cons)","Funname":"DAbstractUnitFormatter::formatAsUnitList","Returntype":"QList\u003cQPair\u003cqreal,int\u003e\u003e","Args":"const qreal value,int unit) cons"},{"Uniquefunname":"uint DAbstractUnitFormatter::unitConvertRate(int unitId) cons)","Funname":"DAbstractUnitFormatter::unitConvertRate","Returntype":"uint","Args":"int unitId) cons"},{"Uniquefunname":"int DAbstractUnitFormatter::unitMax() cons)","Funname":"DAbstractUnitFormatter::unitMax","Returntype":"int","Args":") cons"},{"Uniquefunname":"int DAbstractUnitFormatter::unitMin() cons)","Funname":"DAbstractUnitFormatter::unitMin","Returntype":"int","Args":") cons"},{"Uniquefunname":"QString DAbstractUnitFormatter::unitStr(int unitId) cons)","Funname":"DAbstractUnitFormatter::unitStr","Returntype":"QString","Args":"int unitId) cons"},{"Uniquefunname":"qreal DAbstractUnitFormatter::unitValueMax(int unitId) cons)","Funname":"DAbstractUnitFormatter::unitValueMax","Returntype":"qreal","Args":"int unitId) cons"},{"Uniquefunname":"qreal DAbstractUnitFormatter::unitValueMin(int unitId) cons)","Funname":"DAbstractUnitFormatter::unitValueMin","Returntype":"qreal","Args":"int unitId) cons"},{"Uniquefunname":" DAbstractUnitFormatter::~DAbstractUnitFormatter()","Funname":"DAbstractUnitFormatter::~DAbstractUnitFormatter","Returntype":"","Args":""},{"Uniquefunname":"QPair\u003cqreal,int\u003e format(const qreal value,const int unit) cons)","Funname":"format","Returntype":"QPair\u003cqreal,int\u003e","Args":"const qreal value,const int unit) cons"},{"Uniquefunname":"qreal formatAs(qreal value,int currentUnit,const int targetUnit) cons)","Funname":"formatAs","Returntype":"qreal","Args":"qreal value,int currentUnit,const int targetUnit) cons"},{"Uniquefunname":"QList\u003cQPair\u003cqreal,int\u003e\u003e formatAsUnitList(const qreal value,int unit) cons)","Funname":"formatAsUnitList","Returntype":"QList\u003cQPair\u003cqreal,int\u003e\u003e","Args":"const qreal value,int unit) cons"},{"Uniquefunname":"uint unitConvertRate(int unitId) cons)","Funname":"unitConvertRate","Returntype":"uint","Args":"int unitId) cons"},{"Uniquefunname":"int unitMax() cons)","Funname":"unitMax","Returntype":"int","Args":") cons"},{"Uniquefunname":"int unitMin() cons)","Funname":"unitMin","Returntype":"int","Args":") cons"},{"Uniquefunname":"QString unitStr(int unitId) cons)","Funname":"unitStr","Returntype":"QString","Args":"int unitId) cons"},{"Uniquefunname":"qreal unitValueMax(int unitId) cons)","Funname":"unitValueMax","Returntype":"qreal","Args":"int unitId) cons"},{"Uniquefunname":"qreal unitValueMin(int unitId) cons)","Funname":"unitValueMin","Returntype":"qreal","Args":"int unitId) cons"},{"Uniquefunname":" ~DAbstractUnitFormatter()","Funname":"~DAbstractUnitFormatter","Returntype":"","Args":""}],"Records":[{"Name":"macro","Fields":["DABSTRACTUNITFORMATTER_H"]}]} +{"Filepath":"src/util/ddbussender.h","Functions":[{"Uniquefunname":" DDBusCaller(const QString \u0026 method,std::shared_ptr\u003cDDBusData\u003e data)","Funname":"DDBusCaller","Returntype":"","Args":"const QString \u0026 method,std::shared_ptr\u003cDDBusData\u003e data"},{"Uniquefunname":" DDBusCaller::DDBusCaller(const QString \u0026 method,std::shared_ptr\u003cDDBusData\u003e data)","Funname":"DDBusCaller::DDBusCaller","Returntype":"","Args":"const QString \u0026 method,std::shared_ptr\u003cDDBusData\u003e data"},{"Uniquefunname":"DDBusCaller DDBusCaller::arg(const T \u0026 argument)","Funname":"DDBusCaller::arg","Returntype":"DDBusCaller","Args":"const T \u0026 argument"},{"Uniquefunname":"DDBusCaller DDBusCaller::arg(const T \u0026argument)","Funname":"DDBusCaller::arg","Returntype":"DDBusCaller","Args":"const T \u0026 argument"},{"Uniquefunname":"QDBusPendingCall DDBusCaller::call()","Funname":"DDBusCaller::call","Returntype":"QDBusPendingCall","Args":""},{"Uniquefunname":" DDBusData()","Funname":"DDBusData","Returntype":"","Args":""},{"Uniquefunname":" DDBusData::DDBusData()","Funname":"DDBusData::DDBusData","Returntype":"","Args":""},{"Uniquefunname":" DDBusProperty(const QString \u0026 property,std::shared_ptr\u003cDDBusData\u003e data)","Funname":"DDBusProperty","Returntype":"","Args":"const QString \u0026 property,std::shared_ptr\u003cDDBusData\u003e data"},{"Uniquefunname":" DDBusProperty::DDBusProperty(const QString \u0026 property,std::shared_ptr\u003cDDBusData\u003e data)","Funname":"DDBusProperty::DDBusProperty","Returntype":"","Args":"const QString \u0026 property,std::shared_ptr\u003cDDBusData\u003e data"},{"Uniquefunname":"QDBusPendingCall DDBusProperty::get()","Funname":"DDBusProperty::get","Returntype":"QDBusPendingCall","Args":""},{"Uniquefunname":"QDBusPendingCall DDBusProperty::set(const T \u0026 value)","Funname":"DDBusProperty::set","Returntype":"QDBusPendingCall","Args":"const T \u0026 value"},{"Uniquefunname":"QDBusPendingCall DDBusProperty::set(const T \u0026value)","Funname":"DDBusProperty::set","Returntype":"QDBusPendingCall","Args":"const T \u0026 value"},{"Uniquefunname":" DDBusSender()","Funname":"DDBusSender","Returntype":"","Args":""},{"Uniquefunname":" DDBusSender::DDBusSender()","Funname":"DDBusSender::DDBusSender","Returntype":"","Args":""},{"Uniquefunname":"DDBusSender DDBusSender::interface(const QString \u0026 interface)","Funname":"DDBusSender::interface","Returntype":"DDBusSender","Args":"const QString \u0026 interface"},{"Uniquefunname":"DDBusCaller DDBusSender::method(const QString \u0026 method)","Funname":"DDBusSender::method","Returntype":"DDBusCaller","Args":"const QString \u0026 method"},{"Uniquefunname":"DDBusSender DDBusSender::path(const QString \u0026 path)","Funname":"DDBusSender::path","Returntype":"DDBusSender","Args":"const QString \u0026 path"},{"Uniquefunname":"DDBusProperty DDBusSender::property(const QString \u0026 property)","Funname":"DDBusSender::property","Returntype":"DDBusProperty","Args":"const QString \u0026 property"},{"Uniquefunname":"DDBusSender DDBusSender::service(const QString \u0026 service)","Funname":"DDBusSender::service","Returntype":"DDBusSender","Args":"const QString \u0026 service"},{"Uniquefunname":"DDBusSender DDBusSender::type(const QDBusConnection::BusType busType)","Funname":"DDBusSender::type","Returntype":"DDBusSender","Args":"const QDBusConnection::BusType busType"},{"Uniquefunname":"DDBusCaller arg(const T \u0026 argument)","Funname":"arg","Returntype":"DDBusCaller","Args":"const T \u0026 argument"},{"Uniquefunname":"DDBusCaller DDBusCaller::arg(const T \u0026argument)","Funname":"arg","Returntype":"DDBusCaller","Args":"const T \u0026 argument"},{"Uniquefunname":"QDBusPendingCall call()","Funname":"call","Returntype":"QDBusPendingCall","Args":""},{"Uniquefunname":"QDBusPendingCall get()","Funname":"get","Returntype":"QDBusPendingCall","Args":""},{"Uniquefunname":"DDBusSender interface(const QString \u0026 interface)","Funname":"interface","Returntype":"DDBusSender","Args":"const QString \u0026 interface"},{"Uniquefunname":"DDBusCaller method(const QString \u0026 method)","Funname":"method","Returntype":"DDBusCaller","Args":"const QString \u0026 method"},{"Uniquefunname":"DDBusSender path(const QString \u0026 path)","Funname":"path","Returntype":"DDBusSender","Args":"const QString \u0026 path"},{"Uniquefunname":"DDBusProperty property(const QString \u0026 property)","Funname":"property","Returntype":"DDBusProperty","Args":"const QString \u0026 property"},{"Uniquefunname":"DDBusSender service(const QString \u0026 service)","Funname":"service","Returntype":"DDBusSender","Args":"const QString \u0026 service"},{"Uniquefunname":"QDBusPendingCall set(const T \u0026 value)","Funname":"set","Returntype":"QDBusPendingCall","Args":"const T \u0026 value"},{"Uniquefunname":"QDBusPendingCall DDBusProperty::set(const T \u0026value)","Funname":"set","Returntype":"QDBusPendingCall","Args":"const T \u0026 value"},{"Uniquefunname":"DDBusSender type(const QDBusConnection::BusType busType)","Funname":"type","Returntype":"DDBusSender","Args":"const QDBusConnection::BusType busType"}],"Records":[{"Name":"macro","Fields":["DDBUSSENDER_H"]},{"Name":"class:DDBusCaller","Fields":["QVariantList DDBusCaller::m_arguments","std::shared_ptr\u003cDDBusData\u003e DDBusCaller::m_dbusData","QString DDBusCaller::m_methodName"]},{"Name":"class:DDBusData","Fields":["QDBusConnection DDBusData::connection","QString DDBusData::interface","QString DDBusData::path","QString DDBusData::queryName","QString DDBusData::service"]},{"Name":"class:DDBusProperty","Fields":["std::shared_ptr\u003cDDBusData\u003e DDBusProperty::m_dbusData","QString DDBusProperty::m_propertyName"]},{"Name":"class:DDBusSender","Fields":["std::shared_ptr\u003cDDBusData\u003e DDBusSender::m_dbusData"]}]} +{"Filepath":"src/util/ddisksizeformatter.h","Functions":[{"Uniquefunname":" DDiskSizeFormatter()","Funname":"DDiskSizeFormatter","Returntype":"","Args":""},{"Uniquefunname":" DDiskSizeFormatter::DDiskSizeFormatter()","Funname":"DDiskSizeFormatter::DDiskSizeFormatter","Returntype":"","Args":""},{"Uniquefunname":"DDiskSizeFormatter DDiskSizeFormatter::rate(int rate)","Funname":"DDiskSizeFormatter::rate","Returntype":"DDiskSizeFormatter","Args":"int rate"},{"Uniquefunname":"uint DDiskSizeFormatter::unitConvertRate(int unitId) cons)","Funname":"DDiskSizeFormatter::unitConvertRate","Returntype":"uint","Args":"int unitId) cons"},{"Uniquefunname":"int DDiskSizeFormatter::unitMax() cons)","Funname":"DDiskSizeFormatter::unitMax","Returntype":"int","Args":") cons"},{"Uniquefunname":"int DDiskSizeFormatter::unitMin() cons)","Funname":"DDiskSizeFormatter::unitMin","Returntype":"int","Args":") cons"},{"Uniquefunname":"QString DDiskSizeFormatter::unitStr(int unitId) cons)","Funname":"DDiskSizeFormatter::unitStr","Returntype":"QString","Args":"int unitId) cons"},{"Uniquefunname":"DDiskSizeFormatter rate(int rate)","Funname":"rate","Returntype":"DDiskSizeFormatter","Args":"int rate"},{"Uniquefunname":"uint unitConvertRate(int unitId) cons)","Funname":"unitConvertRate","Returntype":"uint","Args":"int unitId) cons"},{"Uniquefunname":"int unitMax() cons)","Funname":"unitMax","Returntype":"int","Args":") cons"},{"Uniquefunname":"int unitMin() cons)","Funname":"unitMin","Returntype":"int","Args":") cons"},{"Uniquefunname":"QString unitStr(int unitId) cons)","Funname":"unitStr","Returntype":"QString","Args":"int unitId) cons"}],"Records":[{"Name":"enum:DDiskSizeFormatter::DiskUnits","Fields":["B","DDiskSizeFormatter::B","DDiskSizeFormatter::G","DDiskSizeFormatter::K","DDiskSizeFormatter::M","DDiskSizeFormatter::T","G","K","M","T"]},{"Name":"class:DDiskSizeFormatter","Fields":["int DDiskSizeFormatter::m_rate"]},{"Name":"macro","Fields":["DISKSIZEFORMATTER_H"]}]} +{"Filepath":"src/util/dexportedinterface.h","Functions":[{"Uniquefunname":" DExportedInterface(QObject * parent=nullptr)","Funname":"DExportedInterface","Returntype":"","Args":"QObject * parent=nullptr"},{"Uniquefunname":" DUtil::DExportedInterface::DExportedInterface(QObject * parent=nullptr)","Funname":"DUtil::DExportedInterface::DExportedInterface","Returntype":"","Args":"QObject * parent=nullptr"},{"Uniquefunname":"QVariant DUtil::DExportedInterface::invoke(const QString \u0026 action,const QString \u0026 parameters) cons)","Funname":"DUtil::DExportedInterface::invoke","Returntype":"QVariant","Args":"const QString \u0026 action,const QString \u0026 parameters) cons"},{"Uniquefunname":"void DUtil::DExportedInterface::registerAction(const QString \u0026 action,const QString \u0026 description,const std::function\u003cQVariant (QString)\u003e handler=nullptr)","Funname":"DUtil::DExportedInterface::registerAction","Returntype":"void","Args":"const QString \u0026 action,const QString \u0026 description,const std::function\u003cQVariant (QString)\u003e handler=nullptr"},{"Uniquefunname":" DUtil::DExportedInterface::~DExportedInterface()","Funname":"DUtil::DExportedInterface::~DExportedInterface","Returntype":"","Args":""},{"Uniquefunname":"QVariant invoke(const QString \u0026 action,const QString \u0026 parameters) cons)","Funname":"invoke","Returntype":"QVariant","Args":"const QString \u0026 action,const QString \u0026 parameters) cons"},{"Uniquefunname":"void registerAction(const QString \u0026 action,const QString \u0026 description,const std::function\u003cQVariant (QString)\u003e handler=nullptr)","Funname":"registerAction","Returntype":"void","Args":"const QString \u0026 action,const QString \u0026 description,const std::function\u003cQVariant (QString)\u003e handler=nullptr"},{"Uniquefunname":" ~DExportedInterface()","Funname":"~DExportedInterface","Returntype":"","Args":""}],"Records":[{"Name":"macro","Fields":["DEXPORTEDINTERFACE_H"]},{"Name":"namespace","Fields":["DUtil"]}]} +{"Filepath":"src/util/dfileservices.h","Functions":[{"Uniquefunname":"QString DFileServices::errorMessage()","Funname":"DFileServices::errorMessage","Returntype":"QString","Args":""},{"Uniquefunname":"bool DFileServices::showFileItem(QString localFilePath,const QString \u0026 startupId=QString ())","Funname":"DFileServices::showFileItem","Returntype":"bool","Args":"QString localFilePath,const QString \u0026 startupId=QString ()"},{"Uniquefunname":"bool DFileServices::showFileItem(QUrl url,const QString \u0026 startupId=QString ())","Funname":"DFileServices::showFileItem","Returntype":"bool","Args":"QUrl url,const QString \u0026 startupId=QString ()"},{"Uniquefunname":"bool DFileServices::showFileItemPropertie(QString localFilePath,const QString \u0026 startupId=QString ())","Funname":"DFileServices::showFileItemPropertie","Returntype":"bool","Args":"QString localFilePath,const QString \u0026 startupId=QString ()"},{"Uniquefunname":"bool DFileServices::showFileItemPropertie(QUrl url,const QString \u0026 startupId=QString ())","Funname":"DFileServices::showFileItemPropertie","Returntype":"bool","Args":"QUrl url,const QString \u0026 startupId=QString ()"},{"Uniquefunname":"bool DFileServices::showFileItemProperties(const QList\u003cQString\u003e localFilePaths,const QString \u0026 startupId=QString ())","Funname":"DFileServices::showFileItemProperties","Returntype":"bool","Args":"const QList\u003cQString\u003e localFilePaths,const QString \u0026 startupId=QString ()"},{"Uniquefunname":"bool DFileServices::showFileItemProperties(const QList\u003cQUrl\u003e urls,const QString \u0026 startupId=QString ())","Funname":"DFileServices::showFileItemProperties","Returntype":"bool","Args":"const QList\u003cQUrl\u003e urls,const QString \u0026 startupId=QString ()"},{"Uniquefunname":"bool DFileServices::showFileItems(const QList\u003cQString\u003e localFilePaths,const QString \u0026 startupId=QString ())","Funname":"DFileServices::showFileItems","Returntype":"bool","Args":"const QList\u003cQString\u003e localFilePaths,const QString \u0026 startupId=QString ()"},{"Uniquefunname":"bool DFileServices::showFileItems(const QList\u003cQUrl\u003e urls,const QString \u0026 startupId=QString ())","Funname":"DFileServices::showFileItems","Returntype":"bool","Args":"const QList\u003cQUrl\u003e urls,const QString \u0026 startupId=QString ()"},{"Uniquefunname":"bool DFileServices::showFolder(QString localFilePath,const QString \u0026 startupId=QString ())","Funname":"DFileServices::showFolder","Returntype":"bool","Args":"QString localFilePath,const QString \u0026 startupId=QString ()"},{"Uniquefunname":"bool DFileServices::showFolder(QUrl url,const QString \u0026 startupId=QString ())","Funname":"DFileServices::showFolder","Returntype":"bool","Args":"QUrl url,const QString \u0026 startupId=QString ()"},{"Uniquefunname":"bool DFileServices::showFolders(const QList\u003cQString\u003e localFilePaths,const QString \u0026 startupId=QString ())","Funname":"DFileServices::showFolders","Returntype":"bool","Args":"const QList\u003cQString\u003e localFilePaths,const QString \u0026 startupId=QString ()"},{"Uniquefunname":"bool DFileServices::showFolders(const QList\u003cQUrl\u003e urls,const QString \u0026 startupId=QString ())","Funname":"DFileServices::showFolders","Returntype":"bool","Args":"const QList\u003cQUrl\u003e urls,const QString \u0026 startupId=QString ()"},{"Uniquefunname":"bool DFileServices::trash(QString localFilePath)","Funname":"DFileServices::trash","Returntype":"bool","Args":"QString localFilePath"},{"Uniquefunname":"bool DFileServices::trash(QUrl urlstartupId)","Funname":"DFileServices::trash","Returntype":"bool","Args":"QUrl urlstartupId"},{"Uniquefunname":"bool DFileServices::trash(const QList\u003cQString\u003e localFilePaths)","Funname":"DFileServices::trash","Returntype":"bool","Args":"const QList\u003cQString\u003e localFilePaths"},{"Uniquefunname":"bool DFileServices::trash(const QList\u003cQUrl\u003e urls)","Funname":"DFileServices::trash","Returntype":"bool","Args":"const QList\u003cQUrl\u003e urls"},{"Uniquefunname":"QString errorMessage()","Funname":"errorMessage","Returntype":"QString","Args":""},{"Uniquefunname":"bool showFileItem(QString localFilePath,const QString \u0026 startupId=QString ())","Funname":"showFileItem","Returntype":"bool","Args":"QString localFilePath,const QString \u0026 startupId=QString ()"},{"Uniquefunname":"bool showFileItem(QUrl url,const QString \u0026 startupId=QString ())","Funname":"showFileItem","Returntype":"bool","Args":"QUrl url,const QString \u0026 startupId=QString ()"},{"Uniquefunname":"bool showFileItemPropertie(QString localFilePath,const QString \u0026 startupId=QString ())","Funname":"showFileItemPropertie","Returntype":"bool","Args":"QString localFilePath,const QString \u0026 startupId=QString ()"},{"Uniquefunname":"bool showFileItemPropertie(QUrl url,const QString \u0026 startupId=QString ())","Funname":"showFileItemPropertie","Returntype":"bool","Args":"QUrl url,const QString \u0026 startupId=QString ()"},{"Uniquefunname":"bool showFileItemProperties(const QList\u003cQString\u003e localFilePaths,const QString \u0026 startupId=QString ())","Funname":"showFileItemProperties","Returntype":"bool","Args":"const QList\u003cQString\u003e localFilePaths,const QString \u0026 startupId=QString ()"},{"Uniquefunname":"bool showFileItemProperties(const QList\u003cQUrl\u003e urls,const QString \u0026 startupId=QString ())","Funname":"showFileItemProperties","Returntype":"bool","Args":"const QList\u003cQUrl\u003e urls,const QString \u0026 startupId=QString ()"},{"Uniquefunname":"bool showFileItems(const QList\u003cQString\u003e localFilePaths,const QString \u0026 startupId=QString ())","Funname":"showFileItems","Returntype":"bool","Args":"const QList\u003cQString\u003e localFilePaths,const QString \u0026 startupId=QString ()"},{"Uniquefunname":"bool showFileItems(const QList\u003cQUrl\u003e urls,const QString \u0026 startupId=QString ())","Funname":"showFileItems","Returntype":"bool","Args":"const QList\u003cQUrl\u003e urls,const QString \u0026 startupId=QString ()"},{"Uniquefunname":"bool showFolder(QString localFilePath,const QString \u0026 startupId=QString ())","Funname":"showFolder","Returntype":"bool","Args":"QString localFilePath,const QString \u0026 startupId=QString ()"},{"Uniquefunname":"bool showFolder(QUrl url,const QString \u0026 startupId=QString ())","Funname":"showFolder","Returntype":"bool","Args":"QUrl url,const QString \u0026 startupId=QString ()"},{"Uniquefunname":"bool showFolders(const QList\u003cQString\u003e localFilePaths,const QString \u0026 startupId=QString ())","Funname":"showFolders","Returntype":"bool","Args":"const QList\u003cQString\u003e localFilePaths,const QString \u0026 startupId=QString ()"},{"Uniquefunname":"bool showFolders(const QList\u003cQUrl\u003e urls,const QString \u0026 startupId=QString ())","Funname":"showFolders","Returntype":"bool","Args":"const QList\u003cQUrl\u003e urls,const QString \u0026 startupId=QString ()"},{"Uniquefunname":"bool trash(QString localFilePath)","Funname":"trash","Returntype":"bool","Args":"QString localFilePath"},{"Uniquefunname":"bool trash(QUrl urlstartupId)","Funname":"trash","Returntype":"bool","Args":"QUrl urlstartupId"},{"Uniquefunname":"bool trash(const QList\u003cQString\u003e localFilePaths)","Funname":"trash","Returntype":"bool","Args":"const QList\u003cQString\u003e localFilePaths"},{"Uniquefunname":"bool trash(const QList\u003cQUrl\u003e urls)","Funname":"trash","Returntype":"bool","Args":"const QList\u003cQUrl\u003e urls"}],"Records":[{"Name":"macro","Fields":["DFILESERVICES_H"]}]} +{"Filepath":"src/util/dnotifysender.h","Functions":[{"Uniquefunname":" DNotifySender(const QString \u0026 summary)","Funname":"DNotifySender","Returntype":"","Args":"const QString \u0026 summary"},{"Uniquefunname":" DUtil::DNotifySender::DNotifySender(const QString \u0026 summary)","Funname":"DUtil::DNotifySender::DNotifySender","Returntype":"","Args":"const QString \u0026 summary"},{"Uniquefunname":"DNotifySender DUtil::DNotifySender::actions(const QStringList \u0026 actions=QStringList ())","Funname":"DUtil::DNotifySender::actions","Returntype":"DNotifySender","Args":"const QStringList \u0026 actions=QStringList ()"},{"Uniquefunname":"DNotifySender DUtil::DNotifySender::appBody(const QString \u0026 appBody=QString ())","Funname":"DUtil::DNotifySender::appBody","Returntype":"DNotifySender","Args":"const QString \u0026 appBody=QString ()"},{"Uniquefunname":"DNotifySender DUtil::DNotifySender::appIcon(const QString \u0026 appIcon=QString ())","Funname":"DUtil::DNotifySender::appIcon","Returntype":"DNotifySender","Args":"const QString \u0026 appIcon=QString ()"},{"Uniquefunname":"DNotifySender DUtil::DNotifySender::appName(const QString \u0026 appName=QString ())","Funname":"DUtil::DNotifySender::appName","Returntype":"DNotifySender","Args":"const QString \u0026 appName=QString ()"},{"Uniquefunname":"QDBusPendingCall DUtil::DNotifySender::call()","Funname":"DUtil::DNotifySender::call","Returntype":"QDBusPendingCall","Args":""},{"Uniquefunname":"DNotifySender DUtil::DNotifySender::hints(const QVariantMap \u0026 hints=QVariantMap ())","Funname":"DUtil::DNotifySender::hints","Returntype":"DNotifySender","Args":"const QVariantMap \u0026 hints=QVariantMap ()"},{"Uniquefunname":"DNotifySender DUtil::DNotifySender::replaceId(const uint replaceId=0)","Funname":"DUtil::DNotifySender::replaceId","Returntype":"DNotifySender","Args":"const uint replaceId=0"},{"Uniquefunname":"DNotifySender DUtil::DNotifySender::timeOut(const int timeOut=-1)","Funname":"DUtil::DNotifySender::timeOut","Returntype":"DNotifySender","Args":"const int timeOut=-1"},{"Uniquefunname":"DNotifySender actions(const QStringList \u0026 actions=QStringList ())","Funname":"actions","Returntype":"DNotifySender","Args":"const QStringList \u0026 actions=QStringList ()"},{"Uniquefunname":"DNotifySender appBody(const QString \u0026 appBody=QString ())","Funname":"appBody","Returntype":"DNotifySender","Args":"const QString \u0026 appBody=QString ()"},{"Uniquefunname":"DNotifySender appIcon(const QString \u0026 appIcon=QString ())","Funname":"appIcon","Returntype":"DNotifySender","Args":"const QString \u0026 appIcon=QString ()"},{"Uniquefunname":"DNotifySender appName(const QString \u0026 appName=QString ())","Funname":"appName","Returntype":"DNotifySender","Args":"const QString \u0026 appName=QString ()"},{"Uniquefunname":"QDBusPendingCall call()","Funname":"call","Returntype":"QDBusPendingCall","Args":""},{"Uniquefunname":"DNotifySender hints(const QVariantMap \u0026 hints=QVariantMap ())","Funname":"hints","Returntype":"DNotifySender","Args":"const QVariantMap \u0026 hints=QVariantMap ()"},{"Uniquefunname":"DNotifySender replaceId(const uint replaceId=0)","Funname":"replaceId","Returntype":"DNotifySender","Args":"const uint replaceId=0"},{"Uniquefunname":"DNotifySender timeOut(const int timeOut=-1)","Funname":"timeOut","Returntype":"DNotifySender","Args":"const int timeOut=-1"}],"Records":[{"Name":"macro","Fields":["DNOTIFYSENDER_H"]},{"Name":"namespace","Fields":["DUtil"]},{"Name":"class:DUtil::DNotifySender","Fields":["std::shared_ptr\u003cDNotifyData\u003e DUtil::DNotifySender::m_dbusData"]}]} +{"Filepath":"src/util/dpinyin.h","Functions":[{"Uniquefunname":"DCORE_BEGIN_NAMESPACE QString LIBDTKCORESHARED_EXPORT Chinese2Pinyin(const QString \u0026 words)","Funname":"Chinese2Pinyin","Returntype":"DCORE_BEGIN_NAMESPACE QString LIBDTKCORESHARED_EXPORT","Args":"const QString \u0026 words"}],"Records":[{"Name":"macro","Fields":["DPINYIN_H"]}]} +{"Filepath":"src/util/drecentmanager.h","Functions":[{"Uniquefunname":"bool DRecentManager::addItem(const QString \u0026 uri,DRecentData \u0026 data)","Funname":"DRecentManager::addItem","Returntype":"bool","Args":"const QString \u0026 uri,DRecentData \u0026 data"},{"Uniquefunname":"void DRecentManager::removeItem(const QString \u0026 target)","Funname":"DRecentManager::removeItem","Returntype":"void","Args":"const QString \u0026 target"},{"Uniquefunname":"void DRecentManager::removeItems(const QStringList \u0026 list)","Funname":"DRecentManager::removeItems","Returntype":"void","Args":"const QStringList \u0026 list"},{"Uniquefunname":"bool addItem(const QString \u0026 uri,DRecentData \u0026 data)","Funname":"addItem","Returntype":"bool","Args":"const QString \u0026 uri,DRecentData \u0026 data"},{"Uniquefunname":"void removeItem(const QString \u0026 target)","Funname":"removeItem","Returntype":"void","Args":"const QString \u0026 target"},{"Uniquefunname":"void removeItems(const QStringList \u0026 list)","Funname":"removeItems","Returntype":"void","Args":"const QStringList \u0026 list"}],"Records":[{"Name":"macro","Fields":["DRECENTMANAGER_H"]},{"Name":"struct:DRecentData","Fields":["QString DRecentData::appExec","QString DRecentData::appName","QString DRecentData::mimeType"]}]} +{"Filepath":"src/util/dthreadutils.h","Functions":[{"Uniquefunname":" DThreadUtil::FunctionCallProxy::FunctionCallProxy(QThread * thread)","Funname":"DThreadUtil::FunctionCallProxy::FunctionCallProxy","Returntype":"","Args":"QThread * thread"},{"Uniquefunname":"void DThreadUtil::FunctionCallProxy::proxyCall(QSemaphore * s,QThread * thread,QObject * target,FunctionType fun)","Funname":"DThreadUtil::FunctionCallProxy::proxyCall","Returntype":"void","Args":"QSemaphore * s,QThread * thread,QObject * target,FunctionType fun"},{"Uniquefunname":"ReturnType DThreadUtil::_TMP::runInThread(QSemaphore * s,QThread * thread,QObject * target,std::function\u003cReturnType ()\u003e fun)","Funname":"DThreadUtil::_TMP::runInThread","Returntype":"ReturnType","Args":"QSemaphore * s,QThread * thread,QObject * target,std::function\u003cReturnType ()\u003e fun"},{"Uniquefunname":"void DThreadUtil::_TMP::runInThread(QSemaphore * s,QThread * thread,QObject * target,std::function\u003cvoid ()\u003e fun)","Funname":"DThreadUtil::_TMP::runInThread","Returntype":"void","Args":"QSemaphore * s,QThread * thread,QObject * target,std::function\u003cvoid ()\u003e fun"},{"Uniquefunname":"QtPrivate DThreadUtil::runInMainThread(T * target,typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args)","Funname":"DThreadUtil::runInMainThread","Returntype":"QtPrivate","Args":"T * target,typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args"},{"Uniquefunname":"QtPrivate DThreadUtil::runInMainThread(typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args)","Funname":"DThreadUtil::runInMainThread","Returntype":"QtPrivate","Args":"typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args"},{"Uniquefunname":"inline auto runInMainThread(Fun fun, Args\u0026\u0026... args) -\u003e decltype(fun(args...))","Funname":"DThreadUtil::runInMainThread","Returntype":"decltype (fun (args...))","Args":"Fun fun,Args \u0026\u0026...args"},{"Uniquefunname":"inline auto runInMainThread(QObject *target, Fun fun, Args\u0026\u0026... args) -\u003e decltype(fun(args...))","Funname":"DThreadUtil::runInMainThread","Returntype":"decltype (fun (args...))","Args":"QObject * target,Fun fun,Args \u0026\u0026...args"},{"Uniquefunname":"QtPrivate DThreadUtil::runInThread(QSemaphore * s,QThread * thread,QObject * target,typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args)","Funname":"DThreadUtil::runInThread","Returntype":"QtPrivate","Args":"QSemaphore * s,QThread * thread,QObject * target,typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args"},{"Uniquefunname":"QtPrivate DThreadUtil::runInThread(QSemaphore * s,QThread * thread,typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args)","Funname":"DThreadUtil::runInThread","Returntype":"QtPrivate","Args":"QSemaphore * s,QThread * thread,typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args"},{"Uniquefunname":"QtPrivate DThreadUtil::runInThread(QThread * thread,T * target,typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args)","Funname":"DThreadUtil::runInThread","Returntype":"QtPrivate","Args":"QThread * thread,T * target,typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args"},{"Uniquefunname":"QtPrivate DThreadUtil::runInThread(QThread * thread,typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args)","Funname":"DThreadUtil::runInThread","Returntype":"QtPrivate","Args":"QThread * thread,typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args"},{"Uniquefunname":"decltype (fun (args...)) DThreadUtil::runInThread(QSemaphore * s,QThread * thread,Fun fun,Args \u0026\u0026...args)","Funname":"DThreadUtil::runInThread","Returntype":"decltype (fun (args...))","Args":"QSemaphore * s,QThread * thread,Fun fun,Args \u0026\u0026...args"},{"Uniquefunname":"decltype (fun (args...)) DThreadUtil::runInThread(QSemaphore * s,QThread * thread,QObject * target,Fun fun,Args \u0026\u0026...args)","Funname":"DThreadUtil::runInThread","Returntype":"decltype (fun (args...))","Args":"QSemaphore * s,QThread * thread,QObject * target,Fun fun,Args \u0026\u0026...args"},{"Uniquefunname":"inline auto runInThread(QThread *thread, Fun fun, Args\u0026\u0026... args) -\u003e decltype(fun(args...))","Funname":"DThreadUtil::runInThread","Returntype":"decltype (fun (args...))","Args":"QThread * thread,Fun fun,Args \u0026\u0026...args"},{"Uniquefunname":"decltype (fun (args...)) DThreadUtil::runInThread(QThread * thread,QObject * target,Fun fun,Args \u0026\u0026...args)","Funname":"DThreadUtil::runInThread","Returntype":"decltype (fun (args...))","Args":"QThread * thread,QObject * target,Fun fun,Args \u0026\u0026...args"},{"Uniquefunname":" FunctionCallProxy(QThread * thread)","Funname":"FunctionCallProxy","Returntype":"","Args":"QThread * thread"},{"Uniquefunname":" __anon3f53fe290102())","Funname":"__anon3f53fe290102","Returntype":"","Args":")"},{"Uniquefunname":"void proxyCall(QSemaphore * s,QThread * thread,QObject * target,FunctionType fun)","Funname":"proxyCall","Returntype":"void","Args":"QSemaphore * s,QThread * thread,QObject * target,FunctionType fun"},{"Uniquefunname":"QtPrivate runInMainThread(T * target,typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args)","Funname":"runInMainThread","Returntype":"QtPrivate","Args":"T * target,typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args"},{"Uniquefunname":"QtPrivate runInMainThread(typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args)","Funname":"runInMainThread","Returntype":"QtPrivate","Args":"typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args"},{"Uniquefunname":"inline auto runInMainThread(Fun fun, Args\u0026\u0026... args) -\u003e decltype(fun(args...))","Funname":"runInMainThread","Returntype":"decltype (fun (args...))","Args":"Fun fun,Args \u0026\u0026...args"},{"Uniquefunname":"inline auto runInMainThread(QObject *target, Fun fun, Args\u0026\u0026... args) -\u003e decltype(fun(args...))","Funname":"runInMainThread","Returntype":"decltype (fun (args...))","Args":"QObject * target,Fun fun,Args \u0026\u0026...args"},{"Uniquefunname":"QtPrivate runInThread(QSemaphore * s,QThread * thread,QObject * target,typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args)","Funname":"runInThread","Returntype":"QtPrivate","Args":"QSemaphore * s,QThread * thread,QObject * target,typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args"},{"Uniquefunname":"QtPrivate runInThread(QSemaphore * s,QThread * thread,typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args)","Funname":"runInThread","Returntype":"QtPrivate","Args":"QSemaphore * s,QThread * thread,typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args"},{"Uniquefunname":"QtPrivate runInThread(QThread * thread,T * target,typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args)","Funname":"runInThread","Returntype":"QtPrivate","Args":"QThread * thread,T * target,typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args"},{"Uniquefunname":"QtPrivate runInThread(QThread * thread,typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args)","Funname":"runInThread","Returntype":"QtPrivate","Args":"QThread * thread,typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args"},{"Uniquefunname":"ReturnType runInThread(QSemaphore * s,QThread * thread,QObject * target,std::function\u003cReturnType ()\u003e fun)","Funname":"runInThread","Returntype":"ReturnType","Args":"QSemaphore * s,QThread * thread,QObject * target,std::function\u003cReturnType ()\u003e fun"},{"Uniquefunname":"void runInThread(QSemaphore * s,QThread * thread,QObject * target,std::function\u003cvoid ()\u003e fun)","Funname":"runInThread","Returntype":"void","Args":"QSemaphore * s,QThread * thread,QObject * target,std::function\u003cvoid ()\u003e fun"},{"Uniquefunname":"decltype (fun (args...)) runInThread(QSemaphore * s,QThread * thread,Fun fun,Args \u0026\u0026...args)","Funname":"runInThread","Returntype":"decltype (fun (args...))","Args":"QSemaphore * s,QThread * thread,Fun fun,Args \u0026\u0026...args"},{"Uniquefunname":"decltype (fun (args...)) runInThread(QSemaphore * s,QThread * thread,QObject * target,Fun fun,Args \u0026\u0026...args)","Funname":"runInThread","Returntype":"decltype (fun (args...))","Args":"QSemaphore * s,QThread * thread,QObject * target,Fun fun,Args \u0026\u0026...args"},{"Uniquefunname":"inline auto runInThread(QThread *thread, Fun fun, Args\u0026\u0026... args) -\u003e decltype(fun(args...))","Funname":"runInThread","Returntype":"decltype (fun (args...))","Args":"QThread * thread,Fun fun,Args \u0026\u0026...args"},{"Uniquefunname":"decltype (fun (args...)) runInThread(QThread * thread,QObject * target,Fun fun,Args \u0026\u0026...args)","Funname":"runInThread","Returntype":"decltype (fun (args...))","Args":"QThread * thread,QObject * target,Fun fun,Args \u0026\u0026...args"}],"Records":[{"Name":"macro","Fields":["DTHREADUTILS_H"]},{"Name":"namespace","Fields":["DThreadUtil"]}]} +{"Filepath":"src/util/dtimeunitformatter.h","Functions":[{"Uniquefunname":" DTimeUnitFormatter()","Funname":"DTimeUnitFormatter","Returntype":"","Args":""},{"Uniquefunname":" DTimeUnitFormatter::DTimeUnitFormatter()","Funname":"DTimeUnitFormatter::DTimeUnitFormatter","Returntype":"","Args":""},{"Uniquefunname":"uint DTimeUnitFormatter::unitConvertRate(int unitId) cons)","Funname":"DTimeUnitFormatter::unitConvertRate","Returntype":"uint","Args":"int unitId) cons"},{"Uniquefunname":"int DTimeUnitFormatter::unitMax() cons)","Funname":"DTimeUnitFormatter::unitMax","Returntype":"int","Args":") cons"},{"Uniquefunname":"int DTimeUnitFormatter::unitMin() cons)","Funname":"DTimeUnitFormatter::unitMin","Returntype":"int","Args":") cons"},{"Uniquefunname":"QString DTimeUnitFormatter::unitStr(int unitId) cons)","Funname":"DTimeUnitFormatter::unitStr","Returntype":"QString","Args":"int unitId) cons"},{"Uniquefunname":"uint unitConvertRate(int unitId) cons)","Funname":"unitConvertRate","Returntype":"uint","Args":"int unitId) cons"},{"Uniquefunname":"int unitMax() cons)","Funname":"unitMax","Returntype":"int","Args":") cons"},{"Uniquefunname":"int unitMin() cons)","Funname":"unitMin","Returntype":"int","Args":") cons"},{"Uniquefunname":"QString unitStr(int unitId) cons)","Funname":"unitStr","Returntype":"QString","Args":"int unitId) cons"}],"Records":[{"Name":"macro","Fields":["DTIMEUNITFORMATTER_H"]},{"Name":"enum:DTimeUnitFormatter::TimeUnits","Fields":["DTimeUnitFormatter::Day","DTimeUnitFormatter::Hour","DTimeUnitFormatter::Minute","DTimeUnitFormatter::Seconds","Day","Hour","Minute","Seconds"]}]} +{"Filepath":"src/util/dutil.h","Functions":[{"Uniquefunname":"void SecureErase(T \u0026obj)","Funname":"DUtil::SecureErase","Returntype":"void","Args":"T \u0026 obj"},{"Uniquefunname":"void SecureErase(T *p, size_t size)","Funname":"DUtil::SecureErase","Returntype":"void","Args":"T * p,size_t size"},{"Uniquefunname":"inline void TimerSingleShot(int msec, Func1 slot)","Funname":"DUtil::TimerSingleShot","Returntype":"void","Args":"int msec,Func1 slot"},{"Uniquefunname":"void SecureErase(T \u0026obj)","Funname":"SecureErase","Returntype":"void","Args":"T \u0026 obj"},{"Uniquefunname":"void SecureErase(T *p, size_t size)","Funname":"SecureErase","Returntype":"void","Args":"T * p,size_t size"},{"Uniquefunname":"inline void TimerSingleShot(int msec, Func1 slot)","Funname":"TimerSingleShot","Returntype":"void","Args":"int msec,Func1 slot"}],"Records":[{"Name":"namespace","Fields":["DUtil"]}]} +{"Filepath":"src/util/dvtablehook.h","Functions":[{"Uniquefunname":"Ret DVtableHook::StdFunWrap::call(Obj * o,Args...args)","Funname":"DVtableHook::StdFunWrap::call","Returntype":"Ret","Args":"Obj * o,Args...args"},{"Uniquefunname":"StdFunType DVtableHook::StdFunWrap::fun(StdFunType f,bool check=true)","Funname":"DVtableHook::StdFunWrap::fun","Returntype":"StdFunType","Args":"StdFunType f,bool check=true"},{"Uniquefunname":"void DVtableHook::_destory_helper(const T * obj)","Funname":"DVtableHook::_destory_helper","Returntype":"void","Args":"const T * obj"},{"Uniquefunname":"void DVtableHook::autoCleanVtable(const void * obj)","Funname":"DVtableHook::autoCleanVtable","Returntype":"void","Args":"const void * obj"},{"Uniquefunname":"QtPrivate DVtableHook::callOriginalFun(typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args)","Funname":"DVtableHook::callOriginalFun","Returntype":"QtPrivate","Args":"typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args"},{"Uniquefunname":" DVtableHook::callOriginalFun::_ResetVFun::~_ResetVFun()","Funname":"DVtableHook::callOriginalFun::_ResetVFun::~_ResetVFun","Returntype":"","Args":""},{"Uniquefunname":"bool DVtableHook::clearGhostVtable(const void * obj)","Funname":"DVtableHook::clearGhostVtable","Returntype":"bool","Args":"const void * obj"},{"Uniquefunname":"bool DVtableHook::copyVtable(quintptr ** obj)","Funname":"DVtableHook::copyVtable","Returntype":"bool","Args":"quintptr ** obj"},{"Uniquefunname":"bool DVtableHook::ensureVtable(const void * obj,std::function\u003cvoid (void)\u003e destoryObjFun)","Funname":"DVtableHook::ensureVtable","Returntype":"bool","Args":"const void * obj,std::function\u003cvoid (void)\u003e destoryObjFun"},{"Uniquefunname":"bool DVtableHook::forceWriteMemory(void * adr,const void * data,size_t length)","Funname":"DVtableHook::forceWriteMemory","Returntype":"bool","Args":"void * adr,const void * data,size_t length"},{"Uniquefunname":"int DVtableHook::getDestructFunIndex(quintptr ** obj,std::function\u003cvoid (void)\u003e destoryObjFun)","Funname":"DVtableHook::getDestructFunIndex","Returntype":"int","Args":"quintptr ** obj,std::function\u003cvoid (void)\u003e destoryObjFun"},{"Uniquefunname":"const QObject * DVtableHook::getQObject(...)","Funname":"DVtableHook::getQObject","Returntype":"const QObject *","Args":"..."},{"Uniquefunname":"const QObject * DVtableHook::getQObject(const QObject * obj)","Funname":"DVtableHook::getQObject","Returntype":"const QObject *","Args":"const QObject * obj"},{"Uniquefunname":" static quintptr *getVtableOfClass()","Funname":"DVtableHook::getVtableOfClass","Returntype":"quintptr *","Args":""},{"Uniquefunname":" static inline quintptr *getVtableOfObject(const void *obj)","Funname":"DVtableHook::getVtableOfObject","Returntype":"quintptr *","Args":"const void * obj"},{"Uniquefunname":" static inline int getVtableSize(quintptr **obj)","Funname":"DVtableHook::getVtableSize","Returntype":"int","Args":"quintptr ** obj"},{"Uniquefunname":"bool DVtableHook::hasVtable(const void * obj)","Funname":"DVtableHook::hasVtable","Returntype":"bool","Args":"const void * obj"},{"Uniquefunname":" static Fun originalFun(const typename QtPrivate::FunctionPointer\u003cFun\u003e::Object *obj, Fun fun)","Funname":"DVtableHook::originalFun","Returntype":"Fun","Args":"const typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun"},{"Uniquefunname":"quintptr DVtableHook::originalFun(const void * obj,quintptr functionOffset)","Funname":"DVtableHook::originalFun","Returntype":"quintptr","Args":"const void * obj,quintptr functionOffset"},{"Uniquefunname":" overrideVfptrFun(quintptr *vfptr_t1, Fun1 fun1, Fun2 fun2, bool forceWrite)","Funname":"DVtableHook::overrideVfptrFun","Returntype":"std","Args":"quintptr * vfptr_t1,Fun1 fun1,Fun2 fun2,bool forceWrite"},{"Uniquefunname":" static bool overrideVfptrFun(Fun1 fun1, Fun2 fun2)","Funname":"DVtableHook::overrideVfptrFun","Returntype":"bool","Args":"Fun1 fun1,Fun2 fun2"},{"Uniquefunname":"bool DVtableHook::overrideVfptrFun(Fun1 fun1,const typename QtPrivate::FunctionPointer\u003cFun2\u003e::Object * t2,Fun2 fun2)","Funname":"DVtableHook::overrideVfptrFun","Returntype":"bool","Args":"Fun1 fun1,const typename QtPrivate::FunctionPointer\u003cFun2\u003e::Object * t2,Fun2 fun2"},{"Uniquefunname":"bool DVtableHook::overrideVfptrFun(const typename QtPrivate::FunctionPointer\u003cFun1\u003e::Object * t1,Fun1 fun1,Fun2 fun2)","Funname":"DVtableHook::overrideVfptrFun","Returntype":"bool","Args":"const typename QtPrivate::FunctionPointer\u003cFun1\u003e::Object * t1,Fun1 fun1,Fun2 fun2"},{"Uniquefunname":"bool DVtableHook::overrideVfptrFun(const typename QtPrivate::FunctionPointer\u003cFun1\u003e::Object * t1,Fun1 fun1,const typename QtPrivate::FunctionPointer\u003cFun2\u003e::Object * t2,Fun2 fun2)","Funname":"DVtableHook::overrideVfptrFun","Returntype":"bool","Args":"const typename QtPrivate::FunctionPointer\u003cFun1\u003e::Object * t1,Fun1 fun1,const typename QtPrivate::FunctionPointer\u003cFun2\u003e::Object * t2,Fun2 fun2"},{"Uniquefunname":"bool DVtableHook::overrideVfptrFun(quintptr * vfptr_t1,Fun1 fun1,quintptr * vfptr_t2,Fun2 fun2,bool forceWrite)","Funname":"DVtableHook::overrideVfptrFun","Returntype":"bool","Args":"quintptr * vfptr_t1,Fun1 fun1,quintptr * vfptr_t2,Fun2 fun2,bool forceWrite"},{"Uniquefunname":"bool DVtableHook::resetVfptrFun(const typename QtPrivate::FunctionPointer\u003cFun1\u003e::Object * obj,Fun1 fun)","Funname":"DVtableHook::resetVfptrFun","Returntype":"bool","Args":"const typename QtPrivate::FunctionPointer\u003cFun1\u003e::Object * obj,Fun1 fun"},{"Uniquefunname":"quintptr DVtableHook::resetVfptrFun(const void * obj,quintptr functionOffset)","Funname":"DVtableHook::resetVfptrFun","Returntype":"quintptr","Args":"const void * obj,quintptr functionOffset"},{"Uniquefunname":"void DVtableHook::resetVtable(const void * obj)","Funname":"DVtableHook::resetVtable","Returntype":"void","Args":"const void * obj"},{"Uniquefunname":"QFunctionPointer DVtableHook::resolve(const char * symbol)","Funname":"DVtableHook::resolve","Returntype":"QFunctionPointer","Args":"const char * symbol"},{"Uniquefunname":" static inline quintptr toQuintptr(const void *ptr)","Funname":"DVtableHook::toQuintptr","Returntype":"quintptr","Args":"const void * ptr"},{"Uniquefunname":"void _destory_helper(const T * obj)","Funname":"_destory_helper","Returntype":"void","Args":"const T * obj"},{"Uniquefunname":"void autoCleanVtable(const void * obj)","Funname":"autoCleanVtable","Returntype":"void","Args":"const void * obj"},{"Uniquefunname":"Ret call(Obj * o,Args...args)","Funname":"call","Returntype":"Ret","Args":"Obj * o,Args...args"},{"Uniquefunname":"QtPrivate callOriginalFun(typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args)","Funname":"callOriginalFun","Returntype":"QtPrivate","Args":"typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun,Args \u0026\u0026...args"},{"Uniquefunname":"bool clearGhostVtable(const void * obj)","Funname":"clearGhostVtable","Returntype":"bool","Args":"const void * obj"},{"Uniquefunname":"bool copyVtable(quintptr ** obj)","Funname":"copyVtable","Returntype":"bool","Args":"quintptr ** obj"},{"Uniquefunname":"bool ensureVtable(const void * obj,std::function\u003cvoid (void)\u003e destoryObjFun)","Funname":"ensureVtable","Returntype":"bool","Args":"const void * obj,std::function\u003cvoid (void)\u003e destoryObjFun"},{"Uniquefunname":"bool forceWriteMemory(void * adr,const void * data,size_t length)","Funname":"forceWriteMemory","Returntype":"bool","Args":"void * adr,const void * data,size_t length"},{"Uniquefunname":"StdFunType fun(StdFunType f,bool check=true)","Funname":"fun","Returntype":"StdFunType","Args":"StdFunType f,bool check=true"},{"Uniquefunname":"int getDestructFunIndex(quintptr ** obj,std::function\u003cvoid (void)\u003e destoryObjFun)","Funname":"getDestructFunIndex","Returntype":"int","Args":"quintptr ** obj,std::function\u003cvoid (void)\u003e destoryObjFun"},{"Uniquefunname":"const QObject * getQObject(...)","Funname":"getQObject","Returntype":"const QObject *","Args":"..."},{"Uniquefunname":"const QObject * getQObject(const QObject * obj)","Funname":"getQObject","Returntype":"const QObject *","Args":"const QObject * obj"},{"Uniquefunname":" static quintptr *getVtableOfClass()","Funname":"getVtableOfClass","Returntype":"quintptr *","Args":""},{"Uniquefunname":" static inline quintptr *getVtableOfObject(const void *obj)","Funname":"getVtableOfObject","Returntype":"quintptr *","Args":"const void * obj"},{"Uniquefunname":" static inline int getVtableSize(quintptr **obj)","Funname":"getVtableSize","Returntype":"int","Args":"quintptr ** obj"},{"Uniquefunname":"bool hasVtable(const void * obj)","Funname":"hasVtable","Returntype":"bool","Args":"const void * obj"},{"Uniquefunname":" static Fun originalFun(const typename QtPrivate::FunctionPointer\u003cFun\u003e::Object *obj, Fun fun)","Funname":"originalFun","Returntype":"Fun","Args":"const typename QtPrivate::FunctionPointer\u003cFun\u003e::Object * obj,Fun fun"},{"Uniquefunname":"quintptr originalFun(const void * obj,quintptr functionOffset)","Funname":"originalFun","Returntype":"quintptr","Args":"const void * obj,quintptr functionOffset"},{"Uniquefunname":" overrideVfptrFun(quintptr *vfptr_t1, Fun1 fun1, Fun2 fun2, bool forceWrite)","Funname":"overrideVfptrFun","Returntype":"std","Args":"quintptr * vfptr_t1,Fun1 fun1,Fun2 fun2,bool forceWrite"},{"Uniquefunname":" static bool overrideVfptrFun(Fun1 fun1, Fun2 fun2)","Funname":"overrideVfptrFun","Returntype":"bool","Args":"Fun1 fun1,Fun2 fun2"},{"Uniquefunname":"bool overrideVfptrFun(Fun1 fun1,const typename QtPrivate::FunctionPointer\u003cFun2\u003e::Object * t2,Fun2 fun2)","Funname":"overrideVfptrFun","Returntype":"bool","Args":"Fun1 fun1,const typename QtPrivate::FunctionPointer\u003cFun2\u003e::Object * t2,Fun2 fun2"},{"Uniquefunname":"bool overrideVfptrFun(const typename QtPrivate::FunctionPointer\u003cFun1\u003e::Object * t1,Fun1 fun1,Fun2 fun2)","Funname":"overrideVfptrFun","Returntype":"bool","Args":"const typename QtPrivate::FunctionPointer\u003cFun1\u003e::Object * t1,Fun1 fun1,Fun2 fun2"},{"Uniquefunname":"bool overrideVfptrFun(const typename QtPrivate::FunctionPointer\u003cFun1\u003e::Object * t1,Fun1 fun1,const typename QtPrivate::FunctionPointer\u003cFun2\u003e::Object * t2,Fun2 fun2)","Funname":"overrideVfptrFun","Returntype":"bool","Args":"const typename QtPrivate::FunctionPointer\u003cFun1\u003e::Object * t1,Fun1 fun1,const typename QtPrivate::FunctionPointer\u003cFun2\u003e::Object * t2,Fun2 fun2"},{"Uniquefunname":"bool overrideVfptrFun(quintptr * vfptr_t1,Fun1 fun1,quintptr * vfptr_t2,Fun2 fun2,bool forceWrite)","Funname":"overrideVfptrFun","Returntype":"bool","Args":"quintptr * vfptr_t1,Fun1 fun1,quintptr * vfptr_t2,Fun2 fun2,bool forceWrite"},{"Uniquefunname":"bool resetVfptrFun(const typename QtPrivate::FunctionPointer\u003cFun1\u003e::Object * obj,Fun1 fun)","Funname":"resetVfptrFun","Returntype":"bool","Args":"const typename QtPrivate::FunctionPointer\u003cFun1\u003e::Object * obj,Fun1 fun"},{"Uniquefunname":"quintptr resetVfptrFun(const void * obj,quintptr functionOffset)","Funname":"resetVfptrFun","Returntype":"quintptr","Args":"const void * obj,quintptr functionOffset"},{"Uniquefunname":"void resetVtable(const void * obj)","Funname":"resetVtable","Returntype":"void","Args":"const void * obj"},{"Uniquefunname":"QFunctionPointer resolve(const char * symbol)","Funname":"resolve","Returntype":"QFunctionPointer","Args":"const char * symbol"},{"Uniquefunname":" static inline quintptr toQuintptr(const void *ptr)","Funname":"toQuintptr","Returntype":"quintptr","Args":"const void * ptr"},{"Uniquefunname":" ~_ResetVFun()","Funname":"~_ResetVFun","Returntype":"","Args":""}],"Records":[{"Name":"macro","Fields":["DVTABLEHOOK_H"]},{"Name":"class:DVtableHook::callOriginalFun::_ResetVFun","Fields":["quint16 DVtableHook::callOriginalFun::_ResetVFun::offset","quintptr DVtableHook::callOriginalFun::_ResetVFun::oldFun","quintptr * DVtableHook::callOriginalFun::_ResetVFun::vfptr"]},{"Name":"class:DVtableHook","Fields":["quintptr DVtableHook::fun1_offset","quintptr DVtableHook::fun2_offset","QMap\u003cconst void *,quintptr\u003e DVtableHook::objDestructFun","QMap\u003cconst void *,quintptr * \u003e DVtableHook::objToGhostVfptr","QMap\u003cquintptr **,quintptr * \u003e DVtableHook::objToOriginalVfptr","quintptr * DVtableHook::vfun"]}]} +{"Filepath":"tests/ut_dutil.h","Functions":[{"Uniquefunname":"void SetUp()","Funname":"SetUp","Returntype":"void","Args":""},{"Uniquefunname":"void SetUpTestCase()","Funname":"SetUpTestCase","Returntype":"void","Args":""},{"Uniquefunname":"void TearDown()","Funname":"TearDown","Returntype":"void","Args":""},{"Uniquefunname":"void TearDownTestCase()","Funname":"TearDownTestCase","Returntype":"void","Args":""},{"Uniquefunname":"void ut_DUtil::SetUp()","Funname":"ut_DUtil::SetUp","Returntype":"void","Args":""},{"Uniquefunname":"void ut_DUtil::SetUpTestCase()","Funname":"ut_DUtil::SetUpTestCase","Returntype":"void","Args":""},{"Uniquefunname":"void ut_DUtil::TearDown()","Funname":"ut_DUtil::TearDown","Returntype":"void","Args":""},{"Uniquefunname":"void ut_DUtil::TearDownTestCase()","Funname":"ut_DUtil::TearDownTestCase","Returntype":"void","Args":""}],"Records":null} +{"Filepath":"tests/ut_singleton.h","Functions":[{"Uniquefunname":" MultiSingletonTester(QObject * parent=nullptr)","Funname":"MultiSingletonTester","Returntype":"","Args":"QObject * parent=nullptr"},{"Uniquefunname":" MultiSingletonTester::MultiSingletonTester(QObject * parent=nullptr)","Funname":"MultiSingletonTester::MultiSingletonTester","Returntype":"","Args":"QObject * parent=nullptr"},{"Uniquefunname":"void MultiSingletonTester::run()","Funname":"MultiSingletonTester::run","Returntype":"void","Args":""},{"Uniquefunname":" Singleton(QObject * parent=nullptr)","Funname":"Singleton","Returntype":"","Args":"QObject * parent=nullptr"},{"Uniquefunname":" Singleton::Singleton(QObject * parent=nullptr)","Funname":"Singleton::Singleton","Returntype":"","Args":"QObject * parent=nullptr"},{"Uniquefunname":"void Singleton::test()","Funname":"Singleton::test","Returntype":"void","Args":""},{"Uniquefunname":"void run()","Funname":"run","Returntype":"void","Args":""},{"Uniquefunname":"void test()","Funname":"test","Returntype":"void","Args":""}],"Records":null} diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..63463dc --- /dev/null +++ b/debian/changelog @@ -0,0 +1,23 @@ +dtkcore (5.0.3) unstable; urgency=medium + + * Release 5.0.3 + + -- Deepin Packages Builder Tue, 21 Sep 2019 13:31:03 +0800 + +dtkcore (5.0.0) unstable; urgency=medium + + * Release 5.0.0 + + -- Deepin Packages Builder Tue, 03 Sep 2019 08:47:03 +0800 + +dtkcore (2.0.8) unstable; urgency=medium + + * Release 2.0.8 + + -- Deepin Packages Builder Wed, 02 May 2018 10:52:03 +0800 + +dtkcore (0.3.3-1) unstable; urgency=medium + + * Initial release + + -- Deepin Packages Builder Mon, 10 Oct 2016 16:58:07 +0800 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +9 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..cf0c813 --- /dev/null +++ b/debian/control @@ -0,0 +1,34 @@ +Source: dtkcore +Section: libdevel +Priority: optional +Maintainer: Deepin Packages Builder +Build-Depends: debhelper (>= 9), pkg-config, + qttools5-dev-tools, qtbase5-private-dev, + libgsettings-qt-dev, libgtest-dev, libdtkcommon-dev +Standards-Version: 3.9.8 + +Package: libdtkcore5 +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, lshw, libdtkcommon +Multi-Arch: same +Description: Deepin Tool Kit Core library + DtkCore is base library of Deepin Qt/C++ applications. + . + This package contains the shared libraries. + +Package: libdtkcore5-bin +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, + libdtkcore5( =${binary:Version}) +Description: Deepin Tool Kit Core Utilities + DtkCore is base devel library of Deepin Qt/C++ applications. + . + This package contains the utilities of DtkCore + +Package: libdtkcore-dev +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libdtkcore5( =${binary:Version}), libdtkcommon-dev +Description: Deepin Tool Kit Core Devel library + DtkCore is base devel library of Deepin Qt/C++ applications. + . + This package contains the header files and static libraries of DtkCore diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..7a0c37f --- /dev/null +++ b/debian/copyright @@ -0,0 +1,22 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: dtkcore +Source: https://github.com/linuxdeepin/dtkcore + +Files: * +Copyright: 2017 Deepin Technology Co., Ltd. +License: LGPL-3+ + This package is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + . + This package 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 Lesser General Public License for more details. + . + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see + . + On Debian systems, the complete text of the GNU Lesser General + Public License version 3 can be found in "/usr/share/common-licenses/LGPL-3". diff --git a/debian/libdtkcore-dev.install b/debian/libdtkcore-dev.install new file mode 100644 index 0000000..f1f7613 --- /dev/null +++ b/debian/libdtkcore-dev.install @@ -0,0 +1,5 @@ +usr/lib/*/lib*.so +usr/include +usr/lib/*/pkgconfig/*.pc +usr/lib/*/cmake/*/*.cmake +usr/lib/*/qt5/* diff --git a/debian/libdtkcore5-bin.install b/debian/libdtkcore5-bin.install new file mode 100644 index 0000000..0b8a68c --- /dev/null +++ b/debian/libdtkcore5-bin.install @@ -0,0 +1,2 @@ +usr/lib/*/*/DCore/bin/* +usr/bin/* \ No newline at end of file diff --git a/debian/libdtkcore5.install b/debian/libdtkcore5.install new file mode 100644 index 0000000..3ddde58 --- /dev/null +++ b/debian/libdtkcore5.install @@ -0,0 +1 @@ +usr/lib/*/lib*.so.* diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..7abf4a2 --- /dev/null +++ b/debian/rules @@ -0,0 +1,27 @@ +#!/usr/bin/make -f +DPKG_EXPORT_BUILDFLAGS = 1 +include /usr/share/dpkg/default.mk +export QT_SELECT = qt5 + +DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) + +VERSION = $(DEB_VERSION_UPSTREAM) +_PACK_VER = $(shell echo $(VERSION) | awk -F'[+_~-]' '{print $$1}') +_BUILD_VER = $(shell echo $(VERSION) | awk -F'[+_~-]' '{print $$2}' | sed 's/[^0-9]//g') +ifeq ($(_BUILD_VER),) + CONFIG_VERSION = $(_PACK_VER) +else + CONFIG_VERSION = $(_PACK_VER).$(_BUILD_VER) +endif + +%: + dh $@ --parallel + +override_dh_auto_configure: + dh_auto_configure -- LIB_INSTALL_DIR=/usr/lib/$(DEB_HOST_MULTIARCH) VERSION=$(CONFIG_VERSION) + +#override_dh_auto_test: +# echo "skip auto test" + +override_dh_makeshlibs: + dh_makeshlibs -V "libdtkcore5 (>= $(shell echo $(VERSION) | cut -d '.' -f 1,2))" diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/debian/symbols.amd64 b/debian/symbols.amd64 new file mode 100644 index 0000000..502b661 --- /dev/null +++ b/debian/symbols.amd64 @@ -0,0 +1,909 @@ +libdtkcore.so.5 libdtkcore5 #MINVER# + _Z19qInitResources_utilv@Base 5.0.3 + _Z22qCleanupResources_utilv@Base 5.0.3 + _ZGVZN3Dtk4Core11DLogManager8instanceEvE8instance@Base 5.0.3 + _ZN10QByteArrayD1Ev@Base 5.0.3 + _ZN10QByteArrayD2Ev@Base 5.0.3 + _ZN11DDBusCaller3argI7QStringEES_RKT_@Base 5.0.3 + _ZN11DDBusCaller4callEv@Base 5.0.3 + _ZN11DDBusCallerC1ERK7QStringSt10shared_ptrI9DDBusDataE@Base 5.0.3 + _ZN11DDBusCallerC2ERK7QStringSt10shared_ptrI9DDBusDataE@Base 5.0.3 + _ZN11DDBusCallerD1Ev@Base 5.0.3 + _ZN11DDBusCallerD2Ev@Base 5.0.3 + _ZN11DDBusSender4pathERK7QString@Base 5.0.3 + _ZN11DDBusSender4typeEN15QDBusConnection7BusTypeE@Base 5.0.3 + _ZN11DDBusSender6methodERK7QString@Base 5.0.3 + _ZN11DDBusSender7serviceERK7QString@Base 5.0.3 + _ZN11DDBusSender8propertyERK7QString@Base 5.0.3 + _ZN11DDBusSender9interfaceERK7QString@Base 5.0.3 + _ZN11DDBusSenderC1Ev@Base 5.0.3 + _ZN11DDBusSenderC2Ev@Base 5.0.3 + _ZN12QWeakPointerI7QObjectED1Ev@Base 5.0.3 + _ZN12QWeakPointerI7QObjectED2Ev@Base 5.0.3 + _ZN13DDBusProperty3getEv@Base 5.0.3 + _ZN13DDBusPropertyC1ERK7QStringSt10shared_ptrI9DDBusDataE@Base 5.0.3 + _ZN13DDBusPropertyC2ERK7QStringSt10shared_ptrI9DDBusDataE@Base 5.0.3 + _ZN14QScopedPointerIN3Dtk4Core23GSettingsBackendPrivateE21QScopedPointerDeleterIS2_EED1Ev@Base 5.0.3 + _ZN14QScopedPointerIN3Dtk4Core23GSettingsBackendPrivateE21QScopedPointerDeleterIS2_EED2Ev@Base 5.0.3 + _ZN15QVarLengthArrayIcLi4096EEC1Ei@Base 5.0.3 + _ZN15QVarLengthArrayIcLi4096EEC2Ei@Base 5.0.3 + _ZN3Dtk4Core10doUnescapeER7QStringRK5QHashI5QCharS4_E@Base 5.0.3 + _ZN3Dtk4Core11DLogManager12setLogFormatERK7QString@Base 5.0.3 + _ZN3Dtk4Core11DLogManager14getlogFilePathEv@Base 5.0.3 + _ZN3Dtk4Core11DLogManager14setlogFilePathERK7QString@Base 5.0.3 + _ZN3Dtk4Core11DLogManager19initConsoleAppenderEv@Base 5.0.3 + _ZN3Dtk4Core11DLogManager20registerFileAppenderEv@Base 5.0.3 + _ZN3Dtk4Core11DLogManager23initRollingFileAppenderEv@Base 5.0.3 + _ZN3Dtk4Core11DLogManager23registerConsoleAppenderEv@Base 5.0.3 + _ZN3Dtk4Core11DLogManager8joinPathERK7QStringS4_@Base 5.0.3 + _ZN3Dtk4Core11DLogManagerC1Ev@Base 5.0.3 + _ZN3Dtk4Core11DLogManagerC2Ev@Base 5.0.3 + _ZN3Dtk4Core11DLogManagerD1Ev@Base 5.0.3 + _ZN3Dtk4Core11DLogManagerD2Ev@Base 5.0.3 + _ZN3Dtk4Core11DVtableHook10copyVtableEPPy@Base 5.0.3 + _ZN3Dtk4Core11DVtableHook11originalFunEPKvy@Base 5.0.3 + _ZN3Dtk4Core11DVtableHook11resetVtableEPKv@Base 5.0.3 + _ZN3Dtk4Core11DVtableHook12ensureVtableEPKvSt8functionIFvvEE@Base 5.0.3 + _ZN3Dtk4Core11DVtableHook13resetVfptrFunEPKvy@Base 5.0.3 + _ZN3Dtk4Core11DVtableHook14objDestructFunE@Base 5.0.3 + _ZN3Dtk4Core11DVtableHook15autoCleanVtableEPKv@Base 5.0.3 + _ZN3Dtk4Core11DVtableHook15objToGhostVfptrE@Base 5.0.3 + _ZN3Dtk4Core11DVtableHook16clearGhostVtableEPKv@Base 5.0.3 + _ZN3Dtk4Core11DVtableHook16forceWriteMemoryEPvPKvm@Base 5.0.3 + _ZN3Dtk4Core11DVtableHook18objToOriginalVfptrE@Base 5.0.3 + _ZN3Dtk4Core11DVtableHook19getDestructFunIndexEPPySt8functionIFvvEE@Base 5.0.3 + _ZN3Dtk4Core11DVtableHook7resolveEPKc@Base 5.0.3 + _ZN3Dtk4Core11DVtableHook9hasVtableEPKv@Base 5.0.3 + _ZN3Dtk4Core11unqtifyNameERK7QString@Base 5.0.3 + _ZN3Dtk4Core12DFileWatcher11onFileMovedERK7QStringS4_S4_S4_@Base 5.0.3 + _ZN3Dtk4Core12DFileWatcher11qt_metacallEN11QMetaObject4CallEiPPv@Base 5.0.3 + _ZN3Dtk4Core12DFileWatcher11qt_metacastEPKc@Base 5.0.3 + _ZN3Dtk4Core12DFileWatcher12onFileClosedERK7QStringS4_@Base 5.0.3 + _ZN3Dtk4Core12DFileWatcher13onFileCreatedERK7QStringS4_@Base 5.0.3 + _ZN3Dtk4Core12DFileWatcher13onFileDeletedERK7QStringS4_@Base 5.0.3 + _ZN3Dtk4Core12DFileWatcher14onFileModifiedERK7QStringS4_@Base 5.0.3 + _ZN3Dtk4Core12DFileWatcher16staticMetaObjectE@Base 5.0.3 + _ZN3Dtk4Core12DFileWatcher22onFileAttributeChangedERK7QStringS4_@Base 5.0.3 + _ZN3Dtk4Core12DFileWatcherC1ERK7QStringP7QObject@Base 5.0.3 + _ZN3Dtk4Core12DFileWatcherC2ERK7QStringP7QObject@Base 5.0.3 + _ZN3Dtk4Core12DFileWatcherD0Ev@Base 5.0.3 + _ZN3Dtk4Core12DFileWatcherD1Ev@Base 5.0.3 + _ZN3Dtk4Core12DFileWatcherD2Ev@Base 5.0.3 + _ZN3Dtk4Core12FileAppender11setFileNameERK7QString@Base 5.0.3 + _ZN3Dtk4Core12FileAppender6appendERK9QDateTimeNS0_6Logger8LogLevelEPKciS8_RK7QStringSB_@Base 5.0.3 + _ZN3Dtk4Core12FileAppender8openFileEv@Base 5.0.3 + _ZN3Dtk4Core12FileAppender9closeFileEv@Base 5.0.3 + _ZN3Dtk4Core12FileAppenderC1ERK7QString@Base 5.0.3 + _ZN3Dtk4Core12FileAppenderC2ERK7QString@Base 5.0.3 + _ZN3Dtk4Core12FileAppenderD0Ev@Base 5.0.3 + _ZN3Dtk4Core12FileAppenderD1Ev@Base 5.0.3 + _ZN3Dtk4Core12FileAppenderD2Ev@Base 5.0.3 + _ZN3Dtk4Core13DDesktopEntry10escapeExecER7QString@Base 5.0.3 + _ZN3Dtk4Core13DDesktopEntry11removeEntryERK7QStringS4_@Base 5.0.3 + _ZN3Dtk4Core13DDesktopEntry11setRawValueERK7QStringS4_S4_@Base 5.0.3 + _ZN3Dtk4Core13DDesktopEntry12unescapeExecER7QString@Base 5.0.3 + _ZN3Dtk4Core13DDesktopEntry14setStringValueERK7QStringS4_S4_@Base 5.0.3 + _ZN3Dtk4Core13DDesktopEntry16staticMetaObjectE@Base 5.0.3 + _ZN3Dtk4Core13DDesktopEntry17setLocalizedValueERK7QStringS4_S4_S4_@Base 5.0.3 + _ZN3Dtk4Core13DDesktopEntry6escapeER7QString@Base 5.0.3 + _ZN3Dtk4Core13DDesktopEntry8unescapeER7QStringb@Base 5.0.3 + _ZN3Dtk4Core13DDesktopEntry9setStatusERKNS1_6StatusE@Base 5.0.3 + _ZN3Dtk4Core13DDesktopEntryC1ERK7QString@Base 5.0.3 + _ZN3Dtk4Core13DDesktopEntryC2ERK7QString@Base 5.0.3 + _ZN3Dtk4Core13DDesktopEntryD1Ev@Base 5.0.3 + _ZN3Dtk4Core13DDesktopEntryD2Ev@Base 5.0.3 + _ZN3Dtk4Core13DFileServices10showFolderE4QUrlRK7QString@Base 5.0.3 + _ZN3Dtk4Core13DFileServices10showFolderE7QStringRKS2_@Base 5.0.3 + _ZN3Dtk4Core13DFileServices11showFoldersE5QListI4QUrlERK7QString@Base 5.0.3 + _ZN3Dtk4Core13DFileServices11showFoldersE5QListI7QStringERKS3_@Base 5.0.3 + _ZN3Dtk4Core13DFileServices12errorMessageEv@Base 5.0.3 + _ZN3Dtk4Core13DFileServices12showFileItemE4QUrlRK7QString@Base 5.0.3 + _ZN3Dtk4Core13DFileServices12showFileItemE7QStringRKS2_@Base 5.0.3 + _ZN3Dtk4Core13DFileServices13showFileItemsE5QListI4QUrlERK7QString@Base 5.0.3 + _ZN3Dtk4Core13DFileServices13showFileItemsE5QListI7QStringERKS3_@Base 5.0.3 + _ZN3Dtk4Core13DFileServices21showFileItemPropertieE4QUrlRK7QString@Base 5.0.3 + _ZN3Dtk4Core13DFileServices21showFileItemPropertieE7QStringRKS2_@Base 5.0.3 + _ZN3Dtk4Core13DFileServices22showFileItemPropertiesE5QListI4QUrlERK7QString@Base 5.0.3 + _ZN3Dtk4Core13DFileServices22showFileItemPropertiesE5QListI7QStringERKS3_@Base 5.0.3 + _ZN3Dtk4Core13DFileServices5trashE4QUrl@Base 5.0.3 + _ZN3Dtk4Core13DFileServices5trashE5QListI4QUrlE@Base 5.0.3 + _ZN3Dtk4Core13DFileServices5trashE5QListI7QStringE@Base 5.0.3 + _ZN3Dtk4Core13DFileServices5trashE7QString@Base 5.0.3 + _ZN3Dtk4Core13DSecureStringC1ERK7QString@Base 5.0.3 + _ZN3Dtk4Core13DSecureStringC2ERK7QString@Base 5.0.3 + _ZN3Dtk4Core13DSecureStringD1Ev@Base 5.0.3 + _ZN3Dtk4Core13DSecureStringD2Ev@Base 5.0.3 + _ZN3Dtk4Core13DTrashManager10cleanTrashEv@Base 5.0.3 + _ZN3Dtk4Core13DTrashManager11moveToTrashERK7QStringb@Base 5.0.3 + _ZN3Dtk4Core13DTrashManager8instanceEv@Base 5.0.3 + _ZN3Dtk4Core13DTrashManagerC1Ev@Base 5.0.3 + _ZN3Dtk4Core13DTrashManagerC2Ev@Base 5.0.3 + _ZN3Dtk4Core13DTrashManagerD0Ev@Base 5.0.3 + _ZN3Dtk4Core13DTrashManagerD1Ev@Base 5.0.3 + _ZN3Dtk4Core13DTrashManagerD2Ev@Base 5.0.3 + _ZN3Dtk4Core13LoggerPrivate14globalInstanceE@Base 5.0.3 + _ZN3Dtk4Core13LoggerPrivate18globalInstanceLockE@Base 5.0.3 + _ZN3Dtk4Core14Chinese2PinyinERK7QString@Base 5.0.3 + _ZN3Dtk4Core14DObjectPrivateC1EPNS0_7DObjectE@Base 5.0.3 + _ZN3Dtk4Core14DObjectPrivateC2EPNS0_7DObjectE@Base 5.0.3 + _ZN3Dtk4Core14DObjectPrivateD0Ev@Base 5.0.3 + _ZN3Dtk4Core14DObjectPrivateD1Ev@Base 5.0.3 + _ZN3Dtk4Core14DObjectPrivateD2Ev@Base 5.0.3 + _ZN3Dtk4Core14DRecentManager10removeItemERK7QString@Base 5.0.3 + _ZN3Dtk4Core14DRecentManager11removeItemsERK11QStringList@Base 5.0.3 + _ZN3Dtk4Core14DRecentManager7addItemERK7QStringRNS0_11DRecentDataE@Base 5.0.3 + _ZN3Dtk4Core14DSettingsGroup11qt_metacallEN11QMetaObject4CallEiPPv@Base 5.0.3 + _ZN3Dtk4Core14DSettingsGroup11qt_metacastEPKc@Base 5.0.3 + _ZN3Dtk4Core14DSettingsGroup14setParentGroupE8QPointerIS1_E@Base 5.0.3 + _ZN3Dtk4Core14DSettingsGroup16staticMetaObjectE@Base 5.0.3 + _ZN3Dtk4Core14DSettingsGroup8fromJsonERK7QStringRK11QJsonObject@Base 5.0.3 + _ZN3Dtk4Core14DSettingsGroup9parseJsonERK7QStringRK11QJsonObject@Base 5.0.3 + _ZN3Dtk4Core14DSettingsGroupC1EP7QObject@Base 5.0.3 + _ZN3Dtk4Core14DSettingsGroupC2EP7QObject@Base 5.0.3 + _ZN3Dtk4Core14DSettingsGroupD0Ev@Base 5.0.3 + _ZN3Dtk4Core14DSettingsGroupD1Ev@Base 5.0.3 + _ZN3Dtk4Core14DSettingsGroupD2Ev@Base 5.0.3 + _ZN3Dtk4Core14DStandardPaths14findExecutableERK7QStringRK11QStringList@Base 5.0.3 + _ZN3Dtk4Core14DStandardPaths16writableLocationEN14QStandardPaths16StandardLocationE@Base 5.0.3 + _ZN3Dtk4Core14DStandardPaths17standardLocationsEN14QStandardPaths16StandardLocationE@Base 5.0.3 + _ZN3Dtk4Core14DStandardPaths6locateEN14QStandardPaths16StandardLocationERK7QString6QFlagsINS2_12LocateOptionEE@Base 5.0.3 + _ZN3Dtk4Core14DStandardPaths7setModeENS1_4ModeE@Base 5.0.3 + _ZN3Dtk4Core14DStandardPaths9locateAllEN14QStandardPaths16StandardLocationERK7QString6QFlagsINS2_12LocateOptionEE@Base 5.0.3 + _ZN3Dtk4Core14DTrashManager_D0Ev@Base 5.0.3 + _ZN3Dtk4Core14DTrashManager_D1Ev@Base 5.0.3 + _ZN3Dtk4Core14DTrashManager_D2Ev@Base 5.0.3 + _ZN3Dtk4Core14loggerInstanceEv@Base 5.0.3 + _ZN3Dtk4Core14parentPathListERK7QString@Base 5.0.3 + _ZN3Dtk4Core15ConsoleAppender24ignoreEnvironmentPatternEb@Base 5.0.3 + _ZN3Dtk4Core15ConsoleAppender6appendERK9QDateTimeNS0_6Logger8LogLevelEPKciS8_RK7QStringSB_@Base 5.0.3 + _ZN3Dtk4Core15ConsoleAppenderC1Ev@Base 5.0.3 + _ZN3Dtk4Core15ConsoleAppenderC2Ev@Base 5.0.3 + _ZN3Dtk4Core15ConsoleAppenderD0Ev@Base 5.0.3 + _ZN3Dtk4Core15ConsoleAppenderD1Ev@Base 5.0.3 + _ZN3Dtk4Core15ConsoleAppenderD2Ev@Base 5.0.3 + _ZN3Dtk4Core15DSettingsOption11dataChangedERK7QString8QVariant@Base 5.0.3 + _ZN3Dtk4Core15DSettingsOption11qt_metacallEN11QMetaObject4CallEiPPv@Base 5.0.3 + _ZN3Dtk4Core15DSettingsOption11qt_metacastEPKc@Base 5.0.3 + _ZN3Dtk4Core15DSettingsOption12valueChangedE8QVariant@Base 5.0.3 + _ZN3Dtk4Core15DSettingsOption14setParentGroupE8QPointerINS0_14DSettingsGroupEE@Base 5.0.3 + _ZN3Dtk4Core15DSettingsOption16staticMetaObjectE@Base 5.0.3 + _ZN3Dtk4Core15DSettingsOption7setDataERK7QString8QVariant@Base 5.0.3 + _ZN3Dtk4Core15DSettingsOption8fromJsonERK7QStringRK11QJsonObject@Base 5.0.3 + _ZN3Dtk4Core15DSettingsOption8setValueE8QVariant@Base 5.0.3 + _ZN3Dtk4Core15DSettingsOption9parseJsonERK7QStringRK11QJsonObject@Base 5.0.3 + _ZN3Dtk4Core15DSettingsOptionC1EP7QObject@Base 5.0.3 + _ZN3Dtk4Core15DSettingsOptionC2EP7QObject@Base 5.0.3 + _ZN3Dtk4Core15DSettingsOptionD0Ev@Base 5.0.3 + _ZN3Dtk4Core15DSettingsOptionD1Ev@Base 5.0.3 + _ZN3Dtk4Core15DSettingsOptionD2Ev@Base 5.0.3 + _ZN3Dtk4Core15DSysInfoPrivate13parseInfoFileER5QFile@Base 5.0.3 + _ZN3Dtk4Core15DSysInfoPrivate16ensureDeepinInfoEv@Base 5.0.3 + _ZN3Dtk4Core15DSysInfoPrivate17ensureReleaseInfoEv@Base 5.0.3 + _ZN3Dtk4Core15DSysInfoPrivate18ensureComputerInfoEv@Base 5.0.3 + _ZN3Dtk4Core15DSysInfoPrivateC1Ev@Base 5.0.3 + _ZN3Dtk4Core15DSysInfoPrivateC2Ev@Base 5.0.3 + _ZN3Dtk4Core15QSettingBackend11doSetOptionERK7QStringRK8QVariant@Base 5.0.3 + _ZN3Dtk4Core15QSettingBackend11qt_metacallEN11QMetaObject4CallEiPPv@Base 5.0.3 + _ZN3Dtk4Core15QSettingBackend11qt_metacastEPKc@Base 5.0.3 + _ZN3Dtk4Core15QSettingBackend16staticMetaObjectE@Base 5.0.3 + _ZN3Dtk4Core15QSettingBackend6doSyncEv@Base 5.0.3 + _ZN3Dtk4Core15QSettingBackendC1ERK7QStringP7QObject@Base 5.0.3 + _ZN3Dtk4Core15QSettingBackendC2ERK7QStringP7QObject@Base 5.0.3 + _ZN3Dtk4Core15QSettingBackendD0Ev@Base 5.0.3 + _ZN3Dtk4Core15QSettingBackendD1Ev@Base 5.0.3 + _ZN3Dtk4Core15QSettingBackendD2Ev@Base 5.0.3 + _ZN3Dtk4Core16AbstractAppender15setDetailsLevelENS0_6Logger8LogLevelE@Base 5.0.3 + _ZN3Dtk4Core16AbstractAppender15setDetailsLevelERK7QString@Base 5.0.3 + _ZN3Dtk4Core16AbstractAppender5writeERK9QDateTimeNS0_6Logger8LogLevelEPKciS8_RK7QStringSB_@Base 5.0.3 + _ZN3Dtk4Core16AbstractAppenderC1Ev@Base 5.0.3 + _ZN3Dtk4Core16AbstractAppenderC2Ev@Base 5.0.3 + _ZN3Dtk4Core16AbstractAppenderD0Ev@Base 5.0.3 + _ZN3Dtk4Core16AbstractAppenderD1Ev@Base 5.0.3 + _ZN3Dtk4Core16AbstractAppenderD2Ev@Base 5.0.3 + _ZN3Dtk4Core16DBaseFileWatcher10fileClosedERK4QUrl@Base 5.0.3 + _ZN3Dtk4Core16DBaseFileWatcher11fileDeletedERK4QUrl@Base 5.0.3 + _ZN3Dtk4Core16DBaseFileWatcher11ghostSignalERK4QUrlMS1_FvS4_ES4_@Base 5.0.3 + _ZN3Dtk4Core16DBaseFileWatcher11ghostSignalERK4QUrlMS1_FvS4_S4_ES4_S4_@Base 5.0.3 + _ZN3Dtk4Core16DBaseFileWatcher11qt_metacallEN11QMetaObject4CallEiPPv@Base 5.0.3 + _ZN3Dtk4Core16DBaseFileWatcher11qt_metacastEPKc@Base 5.0.3 + _ZN3Dtk4Core16DBaseFileWatcher11stopWatcherEv@Base 5.0.3 + _ZN3Dtk4Core16DBaseFileWatcher12fileModifiedERK4QUrl@Base 5.0.3 + _ZN3Dtk4Core16DBaseFileWatcher12startWatcherEv@Base 5.0.3 + _ZN3Dtk4Core16DBaseFileWatcher14restartWatcherEv@Base 5.0.3 + _ZN3Dtk4Core16DBaseFileWatcher14subfileCreatedERK4QUrl@Base 5.0.3 + _ZN3Dtk4Core16DBaseFileWatcher16staticMetaObjectE@Base 5.0.3 + _ZN3Dtk4Core16DBaseFileWatcher20fileAttributeChangedERK4QUrl@Base 5.0.3 + _ZN3Dtk4Core16DBaseFileWatcher24setEnabledSubfileWatcherERK4QUrlb@Base 5.0.3 + _ZN3Dtk4Core16DBaseFileWatcher9fileMovedERK4QUrlS4_@Base 5.0.3 + _ZN3Dtk4Core16DBaseFileWatcherC1ERNS0_23DBaseFileWatcherPrivateERK4QUrlP7QObject@Base 5.0.3 + _ZN3Dtk4Core16DBaseFileWatcherC2ERNS0_23DBaseFileWatcherPrivateERK4QUrlP7QObject@Base 5.0.3 + _ZN3Dtk4Core16DBaseFileWatcherD0Ev@Base 5.0.3 + _ZN3Dtk4Core16DBaseFileWatcherD1Ev@Base 5.0.3 + _ZN3Dtk4Core16DBaseFileWatcherD2Ev@Base 5.0.3 + _ZN3Dtk4Core16DSettingsBackend11qt_metacallEN11QMetaObject4CallEiPPv@Base 5.0.3 + _ZN3Dtk4Core16DSettingsBackend11qt_metacastEPKc@Base 5.0.3 + _ZN3Dtk4Core16DSettingsBackend13optionChangedERK7QStringRK8QVariant@Base 5.0.3 + _ZN3Dtk4Core16DSettingsBackend16staticMetaObjectE@Base 5.0.3 + _ZN3Dtk4Core16DSettingsBackend4syncEv@Base 5.0.3 + _ZN3Dtk4Core16DSettingsBackend9setOptionERK7QStringRK8QVariant@Base 5.0.3 + _ZN3Dtk4Core16GSettingsBackend11doSetOptionERK7QStringRK8QVariant@Base 5.0.3 + _ZN3Dtk4Core16GSettingsBackend11qt_metacallEN11QMetaObject4CallEiPPv@Base 5.0.3 + _ZN3Dtk4Core16GSettingsBackend11qt_metacastEPKc@Base 5.0.3 + _ZN3Dtk4Core16GSettingsBackend16staticMetaObjectE@Base 5.0.3 + _ZN3Dtk4Core16GSettingsBackend6doSyncEv@Base 5.0.3 + _ZN3Dtk4Core16GSettingsBackendC1EPNS0_9DSettingsEP7QObject@Base 5.0.3 + _ZN3Dtk4Core16GSettingsBackendC2EPNS0_9DSettingsEP7QObject@Base 5.0.3 + _ZN3Dtk4Core16GSettingsBackendD0Ev@Base 5.0.3 + _ZN3Dtk4Core16GSettingsBackendD1Ev@Base 5.0.3 + _ZN3Dtk4Core16GSettingsBackendD2Ev@Base 5.0.3 + _ZN3Dtk4Core16readLineFromDataERK10QByteArrayRiS4_S4_S4_@Base 5.0.3 + _ZN3Dtk4Core18DDiskSizeFormatter4rateEi@Base 5.0.3 + _ZN3Dtk4Core18DDiskSizeFormatterC1Ev@Base 5.0.3 + _ZN3Dtk4Core18DDiskSizeFormatterC2Ev@Base 5.0.3 + _ZN3Dtk4Core18DFileSystemWatcher10fileClosedERK7QStringS4_NS1_14QPrivateSignalE@Base 5.0.3 + _ZN3Dtk4Core18DFileSystemWatcher10removePathERK7QString@Base 5.0.3 + _ZN3Dtk4Core18DFileSystemWatcher11fileCreatedERK7QStringS4_NS1_14QPrivateSignalE@Base 5.0.3 + _ZN3Dtk4Core18DFileSystemWatcher11fileDeletedERK7QStringS4_NS1_14QPrivateSignalE@Base 5.0.3 + _ZN3Dtk4Core18DFileSystemWatcher11qt_metacallEN11QMetaObject4CallEiPPv@Base 5.0.3 + _ZN3Dtk4Core18DFileSystemWatcher11qt_metacastEPKc@Base 5.0.3 + _ZN3Dtk4Core18DFileSystemWatcher11removePathsERK11QStringList@Base 5.0.3 + _ZN3Dtk4Core18DFileSystemWatcher12fileModifiedERK7QStringS4_NS1_14QPrivateSignalE@Base 5.0.3 + _ZN3Dtk4Core18DFileSystemWatcher16staticMetaObjectE@Base 5.0.3 + _ZN3Dtk4Core18DFileSystemWatcher20fileAttributeChangedERK7QStringS4_NS1_14QPrivateSignalE@Base 5.0.3 + _ZN3Dtk4Core18DFileSystemWatcher7addPathERK7QString@Base 5.0.3 + _ZN3Dtk4Core18DFileSystemWatcher8addPathsERK11QStringList@Base 5.0.3 + _ZN3Dtk4Core18DFileSystemWatcher9fileMovedERK7QStringS4_S4_S4_NS1_14QPrivateSignalE@Base 5.0.3 + _ZN3Dtk4Core18DFileSystemWatcherC1EP7QObject@Base 5.0.3 + _ZN3Dtk4Core18DFileSystemWatcherC1ERK11QStringListP7QObject@Base 5.0.3 + _ZN3Dtk4Core18DFileSystemWatcherC2EP7QObject@Base 5.0.3 + _ZN3Dtk4Core18DFileSystemWatcherC2ERK11QStringListP7QObject@Base 5.0.3 + _ZN3Dtk4Core18DFileSystemWatcherD0Ev@Base 5.0.3 + _ZN3Dtk4Core18DFileSystemWatcherD1Ev@Base 5.0.3 + _ZN3Dtk4Core18DFileSystemWatcherD2Ev@Base 5.0.3 + _ZN3Dtk4Core18DTimeUnitFormatterC1Ev@Base 5.0.3 + _ZN3Dtk4Core18DTimeUnitFormatterC2Ev@Base 5.0.3 + _ZN3Dtk4Core18LoggerTimingHelper5startEPKcz@Base 5.0.3 + _ZN3Dtk4Core18LoggerTimingHelper5startERK7QString@Base 5.0.3 + _ZN3Dtk4Core18LoggerTimingHelperD1Ev@Base 5.0.3 + _ZN3Dtk4Core18LoggerTimingHelperD2Ev@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherManager10fileClosedERK7QString@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherManager11fileDeletedERK7QString@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherManager11qt_metacallEN11QMetaObject4CallEiPPv@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherManager11qt_metacastEPKc@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherManager12fileModifiedERK7QString@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherManager14subfileCreatedERK7QString@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherManager16staticMetaObjectE@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherManager20fileAttributeChangedERK7QString@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherManager3addERK7QString@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherManager6removeERK7QString@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherManager9fileMovedERK7QStringS4_@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherManagerC1EP7QObject@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherManagerC2EP7QObject@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherManagerD0Ev@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherManagerD1Ev@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherManagerD2Ev@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherPrivate10formatPathERK7QString@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherPrivate18_q_handleFileCloseERK7QStringS4_@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherPrivate18_q_handleFileMovedERK7QStringS4_S4_S4_@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherPrivate20_q_handleFileCreatedERK7QStringS4_@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherPrivate20_q_handleFileDeletedERK7QStringS4_@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherPrivate21_q_handleFileModifiedERK7QStringS4_@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherPrivate22filePathToWatcherCountE@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherPrivate29_q_handleFileAttributeChangedERK7QStringS4_@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherPrivate4stopEv@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherPrivate5startEv@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherPrivateD0Ev@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherPrivateD1Ev@Base 5.0.3 + _ZN3Dtk4Core19DFileWatcherPrivateD2Ev@Base 5.0.3 + _ZN3Dtk4Core19RollingFileAppender14removeOldFilesEv@Base 5.0.3 + _ZN3Dtk4Core19RollingFileAppender14setDatePatternENS1_11DatePatternE@Base 5.0.3 + _ZN3Dtk4Core19RollingFileAppender14setDatePatternERK7QString@Base 5.0.3 + _ZN3Dtk4Core19RollingFileAppender16computeFrequencyEv@Base 5.0.3 + _ZN3Dtk4Core19RollingFileAppender16setLogFilesLimitEi@Base 5.0.3 + _ZN3Dtk4Core19RollingFileAppender19computeRollOverTimeEv@Base 5.0.3 + _ZN3Dtk4Core19RollingFileAppender20setDatePatternStringERK7QString@Base 5.0.3 + _ZN3Dtk4Core19RollingFileAppender6appendERK9QDateTimeNS0_6Logger8LogLevelEPKciS8_RK7QStringSB_@Base 5.0.3 + _ZN3Dtk4Core19RollingFileAppender8rollOverEv@Base 5.0.3 + _ZN3Dtk4Core19RollingFileAppenderC1ERK7QString@Base 5.0.3 + _ZN3Dtk4Core19RollingFileAppenderC2ERK7QString@Base 5.0.3 + _ZN3Dtk4Core19RollingFileAppenderD0Ev@Base 5.0.3 + _ZN3Dtk4Core19RollingFileAppenderD1Ev@Base 5.0.3 + _ZN3Dtk4Core19RollingFileAppenderD2Ev@Base 5.0.3 + _ZN3Dtk4Core20DDesktopEntryPrivate20initSectionsFromDataERK10QByteArray@Base 5.0.3 + _ZN3Dtk4Core20DDesktopEntryPrivate3getERK7QStringS4_PS2_@Base 5.0.3 + _ZN3Dtk4Core20DDesktopEntryPrivate3setERK7QStringS4_S4_@Base 5.0.3 + _ZN3Dtk4Core20DDesktopEntryPrivate6removeERK7QStringS4_@Base 5.0.3 + _ZN3Dtk4Core20DDesktopEntryPrivate9fuzzyLoadEv@Base 5.0.3 + _ZN3Dtk4Core20DDesktopEntryPrivateC1ERK7QStringPNS0_13DDesktopEntryE@Base 5.0.3 + _ZN3Dtk4Core20DDesktopEntryPrivateC2ERK7QStringPNS0_13DDesktopEntryE@Base 5.0.3 + _ZN3Dtk4Core20DDesktopEntryPrivateD1Ev@Base 5.0.3 + _ZN3Dtk4Core20DDesktopEntryPrivateD2Ev@Base 5.0.3 + _ZN3Dtk4Core20DDesktopEntrySection23ensureSectionDataParsedEv@Base 5.0.3 + _ZN3Dtk4Core20DDesktopEntrySectionD1Ev@Base 5.0.3 + _ZN3Dtk4Core20DDesktopEntrySectionD2Ev@Base 5.0.3 + _ZN3Dtk4Core20DDesktopEntrySectionaSERKS1_@Base 5.0.3 + _ZN3Dtk4Core20DTrashManagerPrivate15removeFileOrDirERK7QString@Base 5.0.3 + _ZN3Dtk4Core20DTrashManagerPrivate18removeFromIteratorER12QDirIterator@Base 5.0.3 + _ZN3Dtk4Core20DTrashManagerPrivateD0Ev@Base 5.0.3 + _ZN3Dtk4Core20DTrashManagerPrivateD1Ev@Base 5.0.3 + _ZN3Dtk4Core20DTrashManagerPrivateD2Ev@Base 5.0.3 + _ZN3Dtk4Core21DSettingsGroupPrivate9parseJsonERK7QStringRK11QJsonObject@Base 5.0.3 + _ZN3Dtk4Core22AbstractStringAppender16qCleanupFuncinfoEPKc@Base 5.0.3 + _ZN3Dtk4Core22AbstractStringAppender17stripFunctionNameEPKc@Base 5.0.3 + _ZN3Dtk4Core22AbstractStringAppender9setFormatERK7QString@Base 5.0.3 + _ZN3Dtk4Core22AbstractStringAppenderC1Ev@Base 5.0.3 + _ZN3Dtk4Core22AbstractStringAppenderC2Ev@Base 5.0.3 + _ZN3Dtk4Core22AbstractStringAppenderD0Ev@Base 5.0.3 + _ZN3Dtk4Core22AbstractStringAppenderD1Ev@Base 5.0.3 + _ZN3Dtk4Core22AbstractStringAppenderD2Ev@Base 5.0.3 + _ZN3Dtk4Core22DAbstractUnitFormatterC1Ev@Base 5.0.3 + _ZN3Dtk4Core22DAbstractUnitFormatterC2Ev@Base 5.0.3 + _ZN3Dtk4Core22DAbstractUnitFormatterD1Ev@Base 5.0.3 + _ZN3Dtk4Core22DAbstractUnitFormatterD2Ev@Base 5.0.3 + _ZN3Dtk4Core22DSettingsOptionPrivate9parseJsonERK7QStringRK11QJsonObject@Base 5.0.3 + _ZN3Dtk4Core23DBaseFileWatcherPrivate11watcherListE@Base 5.0.3 + _ZN3Dtk4Core23DBaseFileWatcherPrivateC1EPNS0_16DBaseFileWatcherE@Base 5.0.3 + _ZN3Dtk4Core23DBaseFileWatcherPrivateC2EPNS0_16DBaseFileWatcherE@Base 5.0.3 + _ZN3Dtk4Core25DFileSystemWatcherPrivate11removePathsERK11QStringListPS2_S5_@Base 5.0.3 + _ZN3Dtk4Core25DFileSystemWatcherPrivate13onFileChangedERK7QStringb@Base 5.0.3 + _ZN3Dtk4Core25DFileSystemWatcherPrivate18_q_readFromInotifyEv@Base 5.0.3 + _ZN3Dtk4Core25DFileSystemWatcherPrivate18onDirectoryChangedERK7QStringb@Base 5.0.3 + _ZN3Dtk4Core25DFileSystemWatcherPrivate8addPathsERK11QStringListPS2_S5_@Base 5.0.3 + _ZN3Dtk4Core25DFileSystemWatcherPrivateC1EiPNS0_18DFileSystemWatcherE@Base 5.0.3 + _ZN3Dtk4Core25DFileSystemWatcherPrivateC2EiPNS0_18DFileSystemWatcherE@Base 5.0.3 + _ZN3Dtk4Core25DFileSystemWatcherPrivateD0Ev@Base 5.0.3 + _ZN3Dtk4Core25DFileSystemWatcherPrivateD1Ev@Base 5.0.3 + _ZN3Dtk4Core25DFileSystemWatcherPrivateD2Ev@Base 5.0.3 + _ZN3Dtk4Core26DFileWatcherManagerPrivateC1EPNS0_19DFileWatcherManagerE@Base 5.0.3 + _ZN3Dtk4Core26DFileWatcherManagerPrivateC2EPNS0_19DFileWatcherManagerE@Base 5.0.3 + _ZN3Dtk4Core26DFileWatcherManagerPrivateD0Ev@Base 5.0.3 + _ZN3Dtk4Core26DFileWatcherManagerPrivateD1Ev@Base 5.0.3 + _ZN3Dtk4Core26DFileWatcherManagerPrivateD2Ev@Base 5.0.3 + _ZN3Dtk4Core5DUtil13DNotifySender4callEv@Base 5.0.3 + _ZN3Dtk4Core5DUtil13DNotifySender5hintsERK4QMapI7QString8QVariantE@Base 5.0.3 + _ZN3Dtk4Core5DUtil13DNotifySender7actionsERK11QStringList@Base 5.0.3 + _ZN3Dtk4Core5DUtil13DNotifySender7appBodyERK7QString@Base 5.0.3 + _ZN3Dtk4Core5DUtil13DNotifySender7appIconERK7QString@Base 5.0.3 + _ZN3Dtk4Core5DUtil13DNotifySender7appNameERK7QString@Base 5.0.3 + _ZN3Dtk4Core5DUtil13DNotifySender7timeOutEi@Base 5.0.3 + _ZN3Dtk4Core5DUtil13DNotifySender9replaceIdEj@Base 5.0.3 + _ZN3Dtk4Core5DUtil13DNotifySenderC1ERK7QString@Base 5.0.3 + _ZN3Dtk4Core5DUtil13DNotifySenderC2ERK7QString@Base 5.0.3 + _ZN3Dtk4Core5DUtil18DExportedInterface11qt_metacallEN11QMetaObject4CallEiPPv@Base 5.0.3 + _ZN3Dtk4Core5DUtil18DExportedInterface11qt_metacastEPKc@Base 5.0.3 + _ZN3Dtk4Core5DUtil18DExportedInterface14registerActionERK7QStringS5_St8functionIF8QVariantS3_EE@Base 5.0.3 + _ZN3Dtk4Core5DUtil18DExportedInterface16staticMetaObjectE@Base 5.0.3 + _ZN3Dtk4Core5DUtil18DExportedInterfaceC1EP7QObject@Base 5.0.3 + _ZN3Dtk4Core5DUtil18DExportedInterfaceC2EP7QObject@Base 5.0.3 + _ZN3Dtk4Core5DUtil18DExportedInterfaceD0Ev@Base 5.0.3 + _ZN3Dtk4Core5DUtil18DExportedInterfaceD1Ev@Base 5.0.3 + _ZN3Dtk4Core5DUtil18DExportedInterfaceD2Ev@Base 5.0.3 + _ZN3Dtk4Core5DUtil25DExportedInterfacePrivate10actionHelpE7QStringi@Base 5.0.3 + _ZN3Dtk4Core5DUtil25DExportedInterfacePrivateC1EPNS1_18DExportedInterfaceE@Base 5.0.3 + _ZN3Dtk4Core5DUtil25DExportedInterfacePrivateC2EPNS1_18DExportedInterfaceE@Base 5.0.3 + _ZN3Dtk4Core5DUtil25DExportedInterfacePrivateD0Ev@Base 5.0.3 + _ZN3Dtk4Core5DUtil25DExportedInterfacePrivateD1Ev@Base 5.0.3 + _ZN3Dtk4Core5DUtil25DExportedInterfacePrivateD2Ev@Base 5.0.3 + _ZN3Dtk4Core5DUtil31DExportedInterfaceDBusInterface11qt_metacallEN11QMetaObject4CallEiPPv@Base 5.0.3 + _ZN3Dtk4Core5DUtil31DExportedInterfaceDBusInterface11qt_metacastEPKc@Base 5.0.3 + _ZN3Dtk4Core5DUtil31DExportedInterfaceDBusInterface16staticMetaObjectE@Base 5.0.3 + _ZN3Dtk4Core5DUtil31DExportedInterfaceDBusInterface4helpERK7QString@Base 5.0.3 + _ZN3Dtk4Core5DUtil31DExportedInterfaceDBusInterface4listEv@Base 5.0.3 + _ZN3Dtk4Core5DUtil31DExportedInterfaceDBusInterface6invokeE7QStringS3_@Base 5.0.3 + _ZN3Dtk4Core5DUtil31DExportedInterfaceDBusInterfaceC1EPNS1_25DExportedInterfacePrivateE@Base 5.0.3 + _ZN3Dtk4Core5DUtil31DExportedInterfaceDBusInterfaceC2EPNS1_25DExportedInterfacePrivateE@Base 5.0.3 + _ZN3Dtk4Core5DUtil31DExportedInterfaceDBusInterfaceD0Ev@Base 5.0.3 + _ZN3Dtk4Core5DUtil31DExportedInterfaceDBusInterfaceD1Ev@Base 5.0.3 + _ZN3Dtk4Core5DUtil31DExportedInterfaceDBusInterfaceD2Ev@Base 5.0.3 + _ZN3Dtk4Core6Logger11writeAssertEPKciS3_S3_@Base 5.0.3 + _ZN3Dtk4Core6Logger13levelToStringENS1_8LogLevelE@Base 5.0.3 + _ZN3Dtk4Core6Logger14globalInstanceEv@Base 5.0.3 + _ZN3Dtk4Core6Logger15levelFromStringERK7QString@Base 5.0.3 + _ZN3Dtk4Core6Logger16registerAppenderEPNS0_16AbstractAppenderE@Base 5.0.3 + _ZN3Dtk4Core6Logger18setDefaultCategoryERK7QString@Base 5.0.3 + _ZN3Dtk4Core6Logger19logToGlobalInstanceERK7QStringb@Base 5.0.3 + _ZN3Dtk4Core6Logger24registerCategoryAppenderERK7QStringPNS0_16AbstractAppenderE@Base 5.0.3 + _ZN3Dtk4Core6Logger5writeENS1_8LogLevelEPKciS4_S4_@Base 5.0.3 + _ZN3Dtk4Core6Logger5writeENS1_8LogLevelEPKciS4_S4_RK7QString@Base 5.0.3 + _ZN3Dtk4Core6Logger5writeERK9QDateTimeNS1_8LogLevelEPKciS7_S7_RK7QString@Base 5.0.3 + _ZN3Dtk4Core6Logger5writeERK9QDateTimeNS1_8LogLevelEPKciS7_S7_RK7QStringb@Base 5.0.3 + _ZN3Dtk4Core6LoggerC1ERK7QString@Base 5.0.3 + _ZN3Dtk4Core6LoggerC1Ev@Base 5.0.3 + _ZN3Dtk4Core6LoggerC2ERK7QString@Base 5.0.3 + _ZN3Dtk4Core6LoggerC2Ev@Base 5.0.3 + _ZN3Dtk4Core6LoggerD1Ev@Base 5.0.3 + _ZN3Dtk4Core6LoggerD2Ev@Base 5.0.3 + _ZN3Dtk4Core7DObjectC1EPS1_@Base 5.0.3 + _ZN3Dtk4Core7DObjectC1ERNS0_14DObjectPrivateEPS1_@Base 5.0.3 + _ZN3Dtk4Core7DObjectC2EPS1_@Base 5.0.3 + _ZN3Dtk4Core7DObjectC2ERNS0_14DObjectPrivateEPS1_@Base 5.0.3 + _ZN3Dtk4Core7DObjectD0Ev@Base 5.0.3 + _ZN3Dtk4Core7DObjectD1Ev@Base 5.0.3 + _ZN3Dtk4Core7DObjectD2Ev@Base 5.0.3 + _ZN3Dtk4Core8DPathBufC1ERK7QString@Base 5.0.3 + _ZN3Dtk4Core8DPathBufC1Ev@Base 5.0.3 + _ZN3Dtk4Core8DPathBufC2ERK7QString@Base 5.0.3 + _ZN3Dtk4Core8DPathBufC2Ev@Base 5.0.3 + _ZN3Dtk4Core8DSysInfo10deepinTypeEv@Base 5.0.3 + _ZN3Dtk4Core8DSysInfo11productTypeEv@Base 5.0.3 + _ZN3Dtk4Core8DSysInfo12computerNameEv@Base 5.0.3 + _ZN3Dtk4Core8DSysInfo12cpuModelNameEv@Base 5.0.3 + _ZN3Dtk4Core8DSysInfo13deepinEditionEv@Base 5.0.3 + _ZN3Dtk4Core8DSysInfo13deepinVersionEv@Base 5.0.3 + _ZN3Dtk4Core8DSysInfo14productVersionEv@Base 5.0.3 + _ZN3Dtk4Core8DSysInfo14systemDiskSizeEv@Base 5.0.3 + _ZN3Dtk4Core8DSysInfo15deepinCopyrightEv@Base 5.0.3 + _ZN3Dtk4Core8DSysInfo15memoryTotalSizeEv@Base 5.0.3 + _ZN3Dtk4Core8DSysInfo17productTypeStringEv@Base 5.0.3 + _ZN3Dtk4Core8DSysInfo18isCommunityEditionEv@Base 5.0.3 + _ZN3Dtk4Core8DSysInfo19distributionOrgLogoENS1_7OrgTypeENS1_8LogoTypeERK7QString@Base 5.0.3 + _ZN3Dtk4Core8DSysInfo19distributionOrgNameENS1_7OrgTypeERK7QLocale@Base 5.0.3 + _ZN3Dtk4Core8DSysInfo19memoryInstalledSizeEv@Base 5.0.3 + _ZN3Dtk4Core8DSysInfo19operatingSystemNameEv@Base 5.0.3 + _ZN3Dtk4Core8DSysInfo20distributionInfoPathEv@Base 5.0.3 + _ZN3Dtk4Core8DSysInfo21deepinDistributorLogoENS1_8LogoTypeERK7QString@Base 5.0.3 + _ZN3Dtk4Core8DSysInfo21deepinDistributorNameEv@Base 5.0.3 + _ZN3Dtk4Core8DSysInfo21deepinTypeDisplayNameERK7QLocale@Base 5.0.3 + _ZN3Dtk4Core8DSysInfo22distributionOrgWebsiteENS1_7OrgTypeE@Base 5.0.3 + _ZN3Dtk4Core8DSysInfo24deepinDistributorWebsiteEv@Base 5.0.3 + _ZN3Dtk4Core8DSysInfo26deepinDistributionInfoPathEv@Base 5.0.3 + _ZN3Dtk4Core8DSysInfo27distributionInfoSectionNameENS1_7OrgTypeE@Base 5.0.3 + _ZN3Dtk4Core8DSysInfo5isDDEEv@Base 5.0.3 + _ZN3Dtk4Core8DSysInfo8isDeepinEv@Base 5.0.3 + _ZN3Dtk4Core8doEscapeER7QStringRK5QHashI5QCharS4_E@Base 5.0.3 + _ZN3Dtk4Core9DSettings10setBackendEPNS0_16DSettingsBackendE@Base 5.0.3 + _ZN3Dtk4Core9DSettings11qt_metacallEN11QMetaObject4CallEiPPv@Base 5.0.3 + _ZN3Dtk4Core9DSettings11qt_metacastEPKc@Base 5.0.3 + _ZN3Dtk4Core9DSettings12fromJsonFileERK7QString@Base 5.0.3 + _ZN3Dtk4Core9DSettings12valueChangedERK7QStringRK8QVariant@Base 5.0.3 + _ZN3Dtk4Core9DSettings16staticMetaObjectE@Base 5.0.3 + _ZN3Dtk4Core9DSettings4syncEv@Base 5.0.3 + _ZN3Dtk4Core9DSettings5resetEv@Base 5.0.3 + _ZN3Dtk4Core9DSettings8fromJsonERK10QByteArray@Base 5.0.3 + _ZN3Dtk4Core9DSettings9loadValueEv@Base 5.0.3 + _ZN3Dtk4Core9DSettings9parseJsonERK10QByteArray@Base 5.0.3 + _ZN3Dtk4Core9DSettings9setOptionERK7QStringRK8QVariant@Base 5.0.3 + _ZN3Dtk4Core9DSettingsC1EP7QObject@Base 5.0.3 + _ZN3Dtk4Core9DSettingsC2EP7QObject@Base 5.0.3 + _ZN3Dtk4Core9DSettingsD0Ev@Base 5.0.3 + _ZN3Dtk4Core9DSettingsD1Ev@Base 5.0.3 + _ZN3Dtk4Core9DSettingsD2Ev@Base 5.0.3 + _ZN3Dtk4Core9LogDevice8readDataEPcx@Base 5.0.3 + _ZN3Dtk4Core9LogDevice9writeDataEPKcx@Base 5.0.3 + _ZN3Dtk4Core9LogDeviceD0Ev@Base 5.0.3 + _ZN3Dtk4Core9LogDeviceD1Ev@Base 5.0.3 + _ZN3Dtk4Core9LogDeviceD2Ev@Base 5.0.3 + _ZN3Dtk4Core9qtifyNameERK7QString@Base 5.0.3 + _ZN4QMapI7QString5QPairIS0_yEE13detach_helperEv@Base 5.0.3 + _ZN4QMapI7QString5QPairIS0_yEED1Ev@Base 5.0.3 + _ZN4QMapI7QString5QPairIS0_yEED2Ev@Base 5.0.3 + _ZN4QMapI7QString5QPairIS0_yEEixERKS0_@Base 5.0.3 + _ZN4QMapI7QString8QPointerIN3Dtk4Core15DSettingsOptionEEE13detach_helperEv@Base 5.0.3 + _ZN4QMapI7QString8QVariantE6insertERKS0_RKS1_@Base 5.0.3 + _ZN4QMapI7QString8QVariantEC1ERKS2_@Base 5.0.3 + _ZN4QMapI7QString8QVariantEC2ERKS2_@Base 5.0.3 + _ZN4QMapI7QStringN3Dtk4Core20DDesktopEntrySectionEE13detach_helperEv@Base 5.0.3 + _ZN4QMapI7QStringN3Dtk4Core20DDesktopEntrySectionEED1Ev@Base 5.0.3 + _ZN4QMapI7QStringN3Dtk4Core20DDesktopEntrySectionEED2Ev@Base 5.0.3 + _ZN4QMapI7QStringN3Dtk4Core20DDesktopEntrySectionEEixERKS0_@Base 5.0.3 + _ZN4QMapI7QStringPN3Dtk4Core12DFileWatcherEE13detach_helperEv@Base 5.0.3 + _ZN4QMapI7QStringS0_E13detach_helperEv@Base 5.0.3 + _ZN4QMapI7QStringS0_E6removeERKS0_@Base 5.0.3 + _ZN4QMapI7QStringS0_EC1ERKS1_@Base 5.0.3 + _ZN4QMapI7QStringS0_EC2ERKS1_@Base 5.0.3 + _ZN4QMapI7QStringS0_ED1Ev@Base 5.0.3 + _ZN4QMapI7QStringS0_ED2Ev@Base 5.0.3 + _ZN4QMapI7QStringS0_EixERKS0_@Base 5.0.3 + _ZN4QMapI7QStringiE13detach_helperEv@Base 5.0.3 + _ZN4QMapI7QStringiED1Ev@Base 5.0.3 + _ZN4QMapI7QStringiED2Ev@Base 5.0.3 + _ZN4QMapI9QDateTime7QStringED1Ev@Base 5.0.3 + _ZN4QMapI9QDateTime7QStringED2Ev@Base 5.0.3 + _ZN4QMapIPKvPyE13detach_helperEv@Base 5.0.3 + _ZN4QMapIPKvPyED1Ev@Base 5.0.3 + _ZN4QMapIPKvPyED2Ev@Base 5.0.3 + _ZN4QMapIPKvyE13detach_helperEv@Base 5.0.3 + _ZN4QMapIPKvyED1Ev@Base 5.0.3 + _ZN4QMapIPKvyED2Ev@Base 5.0.3 + _ZN4QMapIPPyS0_E13detach_helperEv@Base 5.0.3 + _ZN4QMapIPPyS0_ED1Ev@Base 5.0.3 + _ZN4QMapIPPyS0_ED2Ev@Base 5.0.3 + _ZN4QMapIi7QStringED1Ev@Base 5.0.3 + _ZN4QMapIi7QStringED2Ev@Base 5.0.3 + _ZN5QHashI5QCharS0_E11deleteNode2EPN9QHashData4NodeE@Base 5.0.3 + _ZN5QHashI5QCharS0_E13duplicateNodeEPN9QHashData4NodeEPv@Base 5.0.3 + _ZN5QHashI5QCharS0_E6insertERKS0_S3_@Base 5.0.3 + _ZN5QHashI5QCharS0_ED1Ev@Base 5.0.3 + _ZN5QHashI5QCharS0_ED2Ev@Base 5.0.3 + _ZN5QHashI7QString5QPairISt8functionIF8QVariantS0_EES0_EE11deleteNode2EPN9QHashData4NodeE@Base 5.0.3 + _ZN5QHashI7QString5QPairISt8functionIF8QVariantS0_EES0_EE13duplicateNodeEPN9QHashData4NodeEPv@Base 5.0.3 + _ZN5QHashI7QStringiE11deleteNode2EPN9QHashData4NodeE@Base 5.0.3 + _ZN5QHashI7QStringiE13duplicateNodeEPN9QHashData4NodeEPv@Base 5.0.3 + _ZN5QHashIPN3Dtk4Core16AbstractAppenderE15QHashDummyValueE11deleteNode2EPN9QHashData4NodeE@Base 5.0.3 + _ZN5QHashIPN3Dtk4Core16AbstractAppenderE15QHashDummyValueE13duplicateNodeEPN9QHashData4NodeEPv@Base 5.0.3 + _ZN5QHashIPN3Dtk4Core16AbstractAppenderE15QHashDummyValueED1Ev@Base 5.0.3 + _ZN5QHashIPN3Dtk4Core16AbstractAppenderE15QHashDummyValueED2Ev@Base 5.0.3 + _ZN5QHashIi15QHashDummyValueE11deleteNode2EPN9QHashData4NodeE@Base 5.0.3 + _ZN5QHashIi15QHashDummyValueE13duplicateNodeEPN9QHashData4NodeEPv@Base 5.0.3 + _ZN5QHashIi7QStringE11deleteNode2EPN9QHashData4NodeE@Base 5.0.3 + _ZN5QHashIi7QStringE13duplicateNodeEPN9QHashData4NodeEPv@Base 5.0.3 + _ZN5QHashIi7QStringE5eraseENS1_14const_iteratorE@Base 5.0.3 + _ZN5QHashIi7QStringED1Ev@Base 5.0.3 + _ZN5QHashIi7QStringED2Ev@Base 5.0.3 + _ZN5QHashIj7QStringE11deleteNode2EPN9QHashData4NodeE@Base 5.0.3 + _ZN5QHashIj7QStringE13duplicateNodeEPN9QHashData4NodeEPv@Base 5.0.3 + _ZN5QHashIj7QStringED1Ev@Base 5.0.3 + _ZN5QHashIj7QStringED2Ev@Base 5.0.3 + _ZN5QListI10QByteArrayED1Ev@Base 5.0.3 + _ZN5QListI10QByteArrayED2Ev@Base 5.0.3 + _ZN5QListI4QUrlE13detach_helperEi@Base 5.0.3 + _ZN5QListI4QUrlE18detach_helper_growEii@Base 5.0.3 + _ZN5QListI4QUrlE6appendERKS0_@Base 5.0.3 + _ZN5QListI4QUrlEC1ERKS1_@Base 5.0.3 + _ZN5QListI4QUrlEC2ERKS1_@Base 5.0.3 + _ZN5QListI4QUrlED1Ev@Base 5.0.3 + _ZN5QListI4QUrlED2Ev@Base 5.0.3 + _ZN5QListI5QPairI7QStringiEE13detach_helperEi@Base 5.0.3 + _ZN5QListI5QPairI7QStringiEE18detach_helper_growEii@Base 5.0.3 + _ZN5QListI5QPairI7QStringiEE6appendERKS2_@Base 5.0.3 + _ZN5QListI5QPairI7QStringiEED1Ev@Base 5.0.3 + _ZN5QListI5QPairI7QStringiEED2Ev@Base 5.0.3 + _ZN5QListI5QPairIdiEE18detach_helper_growEii@Base 5.0.3 + _ZN5QListI5QPairIdiEE6appendERKS1_@Base 5.0.3 + _ZN5QListI5QPairIdiEED1Ev@Base 5.0.3 + _ZN5QListI5QPairIdiEED2Ev@Base 5.0.3 + _ZN5QListI7QStringE13detach_helperEi@Base 5.0.3 + _ZN5QListI7QStringE18detach_helper_growEii@Base 5.0.3 + _ZN5QListI7QStringE6appendERKS0_@Base 5.0.3 + _ZN5QListI7QStringE7reserveEi@Base 5.0.3 + _ZN5QListI7QStringE9removeAllERKS0_@Base 5.0.3 + _ZN5QListI7QStringEC1ERKS1_@Base 5.0.3 + _ZN5QListI7QStringEC2ERKS1_@Base 5.0.3 + _ZN5QListI7QStringED1Ev@Base 5.0.3 + _ZN5QListI7QStringED2Ev@Base 5.0.3 + _ZN5QListI8QPointerIN3Dtk4Core14DSettingsGroupEEE13detach_helperEi@Base 5.0.3 + _ZN5QListI8QPointerIN3Dtk4Core14DSettingsGroupEEE18detach_helper_growEii@Base 5.0.3 + _ZN5QListI8QPointerIN3Dtk4Core14DSettingsGroupEEE6appendERKS4_@Base 5.0.3 + _ZN5QListI8QPointerIN3Dtk4Core15DSettingsOptionEEE13detach_helperEi@Base 5.0.3 + _ZN5QListI8QPointerIN3Dtk4Core15DSettingsOptionEEE18detach_helper_growEii@Base 5.0.3 + _ZN5QListI8QPointerIN3Dtk4Core15DSettingsOptionEEE6appendERKS4_@Base 5.0.3 + _ZN5QListI8QPointerIN3Dtk4Core15DSettingsOptionEEED1Ev@Base 5.0.3 + _ZN5QListI8QPointerIN3Dtk4Core15DSettingsOptionEEED2Ev@Base 5.0.3 + _ZN5QListI8QVariantE13detach_helperEi@Base 5.0.3 + _ZN5QListI8QVariantE18detach_helper_growEii@Base 5.0.3 + _ZN5QListI8QVariantE6appendERKS0_@Base 5.0.3 + _ZN5QListI8QVariantEC1ERKS1_@Base 5.0.3 + _ZN5QListI8QVariantEC2ERKS1_@Base 5.0.3 + _ZN5QListI8QVariantED1Ev@Base 5.0.3 + _ZN5QListI8QVariantED2Ev@Base 5.0.3 + _ZN5QListI9QFileInfoE13detach_helperEi@Base 5.0.3 + _ZN5QListI9QFileInfoED1Ev@Base 5.0.3 + _ZN5QListI9QFileInfoED2Ev@Base 5.0.3 + _ZN5QListIN3Dtk4Core8DSysInfo10DeepinTypeEE13detach_helperEi@Base 5.0.3 + _ZN5QListIN3Dtk4Core8DSysInfo10DeepinTypeEE18detach_helper_growEii@Base 5.0.3 + _ZN5QListIN3Dtk4Core8DSysInfo10DeepinTypeEE6appendERKS3_@Base 5.0.3 + _ZN5QListIN3Dtk4Core8DSysInfo10DeepinTypeEED1Ev@Base 5.0.3 + _ZN5QListIN3Dtk4Core8DSysInfo10DeepinTypeEED2Ev@Base 5.0.3 + _ZN5QListIP13inotify_eventE13detach_helperEi@Base 5.0.3 + _ZN5QListIP13inotify_eventE18detach_helper_growEii@Base 5.0.3 + _ZN5QListIP13inotify_eventE6appendERKS1_@Base 5.0.3 + _ZN5QListIP13inotify_eventED1Ev@Base 5.0.3 + _ZN5QListIP13inotify_eventED2Ev@Base 5.0.3 + _ZN5QListIPN3Dtk4Core16AbstractAppenderEE18detach_helper_growEii@Base 5.0.3 + _ZN5QListIPN3Dtk4Core16AbstractAppenderEE6appendERKS3_@Base 5.0.3 + _ZN5QListIPN3Dtk4Core16AbstractAppenderEEC1ERKS4_@Base 5.0.3 + _ZN5QListIPN3Dtk4Core16AbstractAppenderEEC2ERKS4_@Base 5.0.3 + _ZN5QListIPN3Dtk4Core16AbstractAppenderEED1Ev@Base 5.0.3 + _ZN5QListIPN3Dtk4Core16AbstractAppenderEED2Ev@Base 5.0.3 + _ZN5QListIPN3Dtk4Core16DBaseFileWatcherEE13detach_helperEi@Base 5.0.3 + _ZN5QListIPN3Dtk4Core16DBaseFileWatcherEE18detach_helper_growEii@Base 5.0.3 + _ZN5QListIPN3Dtk4Core16DBaseFileWatcherEE6appendERKS3_@Base 5.0.3 + _ZN5QListIPN3Dtk4Core16DBaseFileWatcherEE9removeOneERKS3_@Base 5.0.3 + _ZN5QListIPN3Dtk4Core16DBaseFileWatcherEED1Ev@Base 5.0.3 + _ZN5QListIPN3Dtk4Core16DBaseFileWatcherEED2Ev@Base 5.0.3 + _ZN5QPairISt8functionIF8QVariant7QStringEES2_ED1Ev@Base 5.0.3 + _ZN5QPairISt8functionIF8QVariant7QStringEES2_ED2Ev@Base 5.0.3 + _ZN7QStringC1EPKc@Base 5.0.3 + _ZN7QStringC2EPKc@Base 5.0.3 + _ZN7QStringD1Ev@Base 5.0.3 + _ZN7QStringD2Ev@Base 5.0.3 + _ZN8QMapDataI7QStringN3Dtk4Core20DDesktopEntrySectionEE10createNodeERKS0_RKS3_P8QMapNodeIS0_S3_Eb@Base 5.0.3 + _ZN8QMapDataI7QStringPN3Dtk4Core12DFileWatcherEE7destroyEv@Base 5.0.3 + _ZN8QMapDataI7QStringPN3Dtk4Core16AbstractAppenderEE7destroyEv@Base 5.0.3 + _ZN8QMapDataI7QStringbE7destroyEv@Base 5.0.3 + _ZN8QMapDataI7QStringiE7destroyEv@Base 5.0.3 + _ZN8QMapDataI9QDateTime7QStringE7destroyEv@Base 5.0.3 + _ZN8QMapDataIi7QStringE7destroyEv@Base 5.0.3 + _ZN8QMapNodeI7QString5QPairIS0_yEE14destroySubTreeEv@Base 5.0.3 + _ZN8QMapNodeI7QString8QPointerIN3Dtk4Core14DSettingsGroupEEE14destroySubTreeEv@Base 5.0.3 + _ZN8QMapNodeI7QString8QPointerIN3Dtk4Core15DSettingsOptionEEE14destroySubTreeEv@Base 5.0.3 + _ZN8QMapNodeI7QString8QVariantE14destroySubTreeEv@Base 5.0.3 + _ZN8QMapNodeI7QStringN3Dtk4Core20DDesktopEntrySectionEE14destroySubTreeEv@Base 5.0.3 + _ZN8QMapNodeI7QStringPN3Dtk4Core12DFileWatcherEE14destroySubTreeEv@Base 5.0.3 + _ZN8QMapNodeI7QStringPN3Dtk4Core16AbstractAppenderEE14destroySubTreeEv@Base 5.0.3 + _ZN8QMapNodeI7QStringS0_E14destroySubTreeEv@Base 5.0.3 + _ZN8QMapNodeI7QStringbE14destroySubTreeEv@Base 5.0.3 + _ZN8QMapNodeI7QStringiE14destroySubTreeEv@Base 5.0.3 + _ZN8QMapNodeI9QDateTime7QStringE14destroySubTreeEv@Base 5.0.3 + _ZN8QMapNodeIi7QStringE14destroySubTreeEv@Base 5.0.3 + _ZN9DDBusDataC1Ev@Base 5.0.3 + _ZN9DDBusDataC2Ev@Base 5.0.3 + _ZN9QtPrivate11QSlotObjectIMN3Dtk4Core12DFileWatcherEFvRK7QStringS6_ENS_4ListIJS6_S6_EEEvE4implEiPNS_15QSlotObjectBaseEP7QObjectPPvPb@Base 5.0.3 + _ZN9QtPrivate11QSlotObjectIMN3Dtk4Core12DFileWatcherEFvRK7QStringS6_S6_S6_ENS_4ListIJS6_S6_S6_S6_EEEvE4implEiPNS_15QSlotObjectBaseEP7QObjectPPvPb@Base 5.0.3 + _ZN9QtPrivate11QSlotObjectIMN3Dtk4Core16DSettingsBackendEFvRK7QStringRK8QVariantENS_4ListIJS6_S9_EEEvE4implEiPNS_15QSlotObjectBaseEP7QObjectPPvPb@Base 5.0.3 + _ZN9QtPrivate11QSlotObjectIMN3Dtk4Core16DSettingsBackendEFvvENS_4ListIJEEEvE4implEiPNS_15QSlotObjectBaseEP7QObjectPPvPb@Base 5.0.3 + _ZN9QtPrivate8RefCount3refEv@Base 5.0.3 + _ZNK3Dtk4Core12DFileWatcher10metaObjectEv@Base 5.0.3 + _ZNK3Dtk4Core12FileAppender4sizeEv@Base 5.0.3 + _ZNK3Dtk4Core12FileAppender8fileNameEv@Base 5.0.3 + _ZNK3Dtk4Core13DDesktopEntry11genericNameEv@Base 5.0.3 + _ZNK3Dtk4Core13DDesktopEntry11stringValueERK7QStringS4_S4_@Base 5.0.3 + _ZNK3Dtk4Core13DDesktopEntry14ddeDisplayNameEv@Base 5.0.3 + _ZNK3Dtk4Core13DDesktopEntry14localizedValueERK7QStringRK7QLocaleS4_S4_@Base 5.0.3 + _ZNK3Dtk4Core13DDesktopEntry14localizedValueERK7QStringS4_S4_S4_@Base 5.0.3 + _ZNK3Dtk4Core13DDesktopEntry15stringListValueERK7QStringS4_@Base 5.0.3 + _ZNK3Dtk4Core13DDesktopEntry4keysERK7QString@Base 5.0.3 + _ZNK3Dtk4Core13DDesktopEntry4nameEv@Base 5.0.3 + _ZNK3Dtk4Core13DDesktopEntry4saveEv@Base 5.0.3 + _ZNK3Dtk4Core13DDesktopEntry6statusEv@Base 5.0.3 + _ZNK3Dtk4Core13DDesktopEntry7commentEv@Base 5.0.3 + _ZNK3Dtk4Core13DDesktopEntry8containsERK7QStringS4_@Base 5.0.3 + _ZNK3Dtk4Core13DDesktopEntry8rawValueERK7QStringS4_S4_@Base 5.0.3 + _ZNK3Dtk4Core13DDesktopEntry9allGroupsEb@Base 5.0.3 + _ZNK3Dtk4Core13DTrashManager12trashIsEmptyEv@Base 5.0.3 + _ZNK3Dtk4Core14DSettingsGroup10childGroupERK7QString@Base 5.0.3 + _ZNK3Dtk4Core14DSettingsGroup10metaObjectEv@Base 5.0.3 + _ZNK3Dtk4Core14DSettingsGroup11childGroupsEv@Base 5.0.3 + _ZNK3Dtk4Core14DSettingsGroup11parentGroupEv@Base 5.0.3 + _ZNK3Dtk4Core14DSettingsGroup12childOptionsEv@Base 5.0.3 + _ZNK3Dtk4Core14DSettingsGroup3keyEv@Base 5.0.3 + _ZNK3Dtk4Core14DSettingsGroup4nameEv@Base 5.0.3 + _ZNK3Dtk4Core14DSettingsGroup6optionERK7QString@Base 5.0.3 + _ZNK3Dtk4Core14DSettingsGroup7optionsEv@Base 5.0.3 + _ZNK3Dtk4Core14DSettingsGroup8isHiddenEv@Base 5.0.3 + _ZNK3Dtk4Core15ConsoleAppender6formatEv@Base 5.0.3 + _ZNK3Dtk4Core15DSettingsOption10metaObjectEv@Base 5.0.3 + _ZNK3Dtk4Core15DSettingsOption11parentGroupEv@Base 5.0.3 + _ZNK3Dtk4Core15DSettingsOption12defaultValueEv@Base 5.0.3 + _ZNK3Dtk4Core15DSettingsOption3keyEv@Base 5.0.3 + _ZNK3Dtk4Core15DSettingsOption4dataERK7QString@Base 5.0.3 + _ZNK3Dtk4Core15DSettingsOption4nameEv@Base 5.0.3 + _ZNK3Dtk4Core15DSettingsOption5valueEv@Base 5.0.3 + _ZNK3Dtk4Core15DSettingsOption8canResetEv@Base 5.0.3 + _ZNK3Dtk4Core15DSettingsOption8isHiddenEv@Base 5.0.3 + _ZNK3Dtk4Core15DSettingsOption8viewTypeEv@Base 5.0.3 + _ZNK3Dtk4Core15QSettingBackend10metaObjectEv@Base 5.0.3 + _ZNK3Dtk4Core15QSettingBackend4keysEv@Base 5.0.3 + _ZNK3Dtk4Core15QSettingBackend9getOptionERK7QString@Base 5.0.3 + _ZNK3Dtk4Core16AbstractAppender12detailsLevelEv@Base 5.0.3 + _ZNK3Dtk4Core16DBaseFileWatcher10metaObjectEv@Base 5.0.3 + _ZNK3Dtk4Core16DBaseFileWatcher7fileUrlEv@Base 5.0.3 + _ZNK3Dtk4Core16DSettingsBackend10metaObjectEv@Base 5.0.3 + _ZNK3Dtk4Core16GSettingsBackend10metaObjectEv@Base 5.0.3 + _ZNK3Dtk4Core16GSettingsBackend4keysEv@Base 5.0.3 + _ZNK3Dtk4Core16GSettingsBackend9getOptionERK7QString@Base 5.0.3 + _ZNK3Dtk4Core17CuteMessageLogger5writeEPKcz@Base 5.0.3 + _ZNK3Dtk4Core17CuteMessageLogger5writeERK7QString@Base 5.0.3 + _ZNK3Dtk4Core17CuteMessageLogger5writeEv@Base 5.0.3 + _ZNK3Dtk4Core18DDiskSizeFormatter15unitConvertRateEi@Base 5.0.3 + _ZNK3Dtk4Core18DDiskSizeFormatter7unitMaxEv@Base 5.0.3 + _ZNK3Dtk4Core18DDiskSizeFormatter7unitMinEv@Base 5.0.3 + _ZNK3Dtk4Core18DDiskSizeFormatter7unitStrEi@Base 5.0.3 + _ZNK3Dtk4Core18DFileSystemWatcher10metaObjectEv@Base 5.0.3 + _ZNK3Dtk4Core18DFileSystemWatcher11directoriesEv@Base 5.0.3 + _ZNK3Dtk4Core18DFileSystemWatcher5filesEv@Base 5.0.3 + _ZNK3Dtk4Core18DTimeUnitFormatter15unitConvertRateEi@Base 5.0.3 + _ZNK3Dtk4Core18DTimeUnitFormatter7unitMaxEv@Base 5.0.3 + _ZNK3Dtk4Core18DTimeUnitFormatter7unitMinEv@Base 5.0.3 + _ZNK3Dtk4Core18DTimeUnitFormatter7unitStrEi@Base 5.0.3 + _ZNK3Dtk4Core19DFileWatcherManager10metaObjectEv@Base 5.0.3 + _ZNK3Dtk4Core19RollingFileAppender11datePatternEv@Base 5.0.3 + _ZNK3Dtk4Core19RollingFileAppender13logFilesLimitEv@Base 5.0.3 + _ZNK3Dtk4Core19RollingFileAppender17datePatternStringEv@Base 5.0.3 + _ZNK3Dtk4Core20DDesktopEntryPrivate10isWritableEv@Base 5.0.3 + _ZNK3Dtk4Core20DDesktopEntryPrivate10sectionPosERK7QString@Base 5.0.3 + _ZNK3Dtk4Core20DDesktopEntryPrivate4keysERK7QString@Base 5.0.3 + _ZNK3Dtk4Core20DDesktopEntryPrivate5writeER9QIODevice@Base 5.0.3 + _ZNK3Dtk4Core20DDesktopEntryPrivate8containsERK7QStringS4_@Base 5.0.3 + _ZNK3Dtk4Core20DDesktopEntryPrivate9setStatusERKNS0_13DDesktopEntry6StatusE@Base 5.0.3 + _ZNK3Dtk4Core22AbstractStringAppender15formattedStringERK9QDateTimeNS0_6Logger8LogLevelEPKciS8_RK7QStringSB_@Base 5.0.3 + _ZNK3Dtk4Core22AbstractStringAppender6formatEv@Base 5.0.3 + _ZNK3Dtk4Core22DAbstractUnitFormatter12unitValueMaxEi@Base 5.0.3 + _ZNK3Dtk4Core22DAbstractUnitFormatter12unitValueMinEi@Base 5.0.3 + _ZNK3Dtk4Core22DAbstractUnitFormatter16formatAsUnitListEdi@Base 5.0.3 + _ZNK3Dtk4Core22DAbstractUnitFormatter6formatEdi@Base 5.0.3 + _ZNK3Dtk4Core22DAbstractUnitFormatter8formatAsEdii@Base 5.0.3 + _ZNK3Dtk4Core5DUtil18DExportedInterface10metaObjectEv@Base 5.0.3 + _ZNK3Dtk4Core5DUtil18DExportedInterface6invokeERK7QStringS5_@Base 5.0.3 + _ZNK3Dtk4Core5DUtil31DExportedInterfaceDBusInterface10metaObjectEv@Base 5.0.3 + _ZNK3Dtk4Core6Logger15defaultCategoryEv@Base 5.0.3 + _ZNK3Dtk4Core9DSettings10metaObjectEv@Base 5.0.3 + _ZNK3Dtk4Core9DSettings4keysEv@Base 5.0.3 + _ZNK3Dtk4Core9DSettings4metaEv@Base 5.0.3 + _ZNK3Dtk4Core9DSettings5groupERK7QString@Base 5.0.3 + _ZNK3Dtk4Core9DSettings5valueERK7QString@Base 5.0.3 + _ZNK3Dtk4Core9DSettings6groupsEv@Base 5.0.3 + _ZNK3Dtk4Core9DSettings6optionERK7QString@Base 5.0.3 + _ZNK3Dtk4Core9DSettings7optionsEv@Base 5.0.3 + _ZNK3Dtk4Core9DSettings9getOptionERK7QString@Base 5.0.3 + _ZNK3Dtk4Core9DSettings9groupKeysEv@Base 5.0.3 + _ZNK4QMapI7QString8QPointerIN3Dtk4Core15DSettingsOptionEEE6valuesEv@Base 5.0.3 + _ZNK4QMapI7QStringN3Dtk4Core20DDesktopEntrySectionEE4keysEv@Base 5.0.3 + _ZNK4QMapIi7QStringE6valuesERKi@Base 5.0.3 + _ZNK5QHashI5QCharS0_E8findNodeERKS0_Pj@Base 5.0.3 + _ZNK5QHashI7QString5QPairISt8functionIF8QVariantS0_EES0_EE4keysEv@Base 5.0.3 + _ZNK5QHashI7QString5QPairISt8functionIF8QVariantS0_EES0_EE8findNodeERKS0_Pj@Base 5.0.3 + _ZNK5QHashI7QString5QPairISt8functionIF8QVariantS0_EES0_EE8findNodeERKS0_j@Base 5.0.3 + _ZNK5QHashI7QStringiE8findNodeERKS0_Pj@Base 5.0.3 + _ZNK5QHashI7QStringiE8findNodeERKS0_j@Base 5.0.3 + _ZNK5QHashIPN3Dtk4Core16AbstractAppenderE15QHashDummyValueE8findNodeERKS3_Pj@Base 5.0.3 + _ZNK5QHashIi15QHashDummyValueE8findNodeERKiPj@Base 5.0.3 + _ZNK5QHashIi7QStringE6valuesERKi@Base 5.0.3 + _ZNK5QHashIi7QStringE8findNodeERKiPj@Base 5.0.3 + _ZNK5QHashIj7QStringE8findNodeERKjPj@Base 5.0.3 + _ZNK5QListIPN3Dtk4Core16AbstractAppenderEE5toSetEv@Base 5.0.3 + _ZNK8QMapDataI7QString8QPointerIN3Dtk4Core14DSettingsGroupEEE8findNodeERKS0_@Base 5.0.3 + _ZNK8QMapDataI7QString8QPointerIN3Dtk4Core15DSettingsOptionEEE8findNodeERKS0_@Base 5.0.3 + _ZNK8QMapDataI7QString8QVariantE8findNodeERKS0_@Base 5.0.3 + _ZNK8QMapDataI7QStringN3Dtk4Core20DDesktopEntrySectionEE8findNodeERKS0_@Base 5.0.3 + _ZNK8QMapDataI7QStringPN3Dtk4Core12DFileWatcherEE8findNodeERKS0_@Base 5.0.3 + _ZNK8QMapDataI7QStringPN3Dtk4Core16AbstractAppenderEE8findNodeERKS0_@Base 5.0.3 + _ZNK8QMapDataI7QStringS0_E8findNodeERKS0_@Base 5.0.3 + _ZNK8QMapDataI7QStringiE8findNodeERKS0_@Base 5.0.3 + _ZNK8QMapDataIPKvPyE8findNodeERKS1_@Base 5.0.3 + _ZNK8QMapDataIPKvyE8findNodeERKS1_@Base 5.0.3 + _ZNK8QMapNodeI7QString5QPairIS0_yEE4copyEP8QMapDataIS0_S2_E@Base 5.0.3 + _ZNK8QMapNodeI7QString8QPointerIN3Dtk4Core14DSettingsGroupEEE4copyEP8QMapDataIS0_S5_E@Base 5.0.3 + _ZNK8QMapNodeI7QString8QPointerIN3Dtk4Core15DSettingsOptionEEE4copyEP8QMapDataIS0_S5_E@Base 5.0.3 + _ZNK8QMapNodeI7QString8QVariantE4copyEP8QMapDataIS0_S1_E@Base 5.0.3 + _ZNK8QMapNodeI7QStringN3Dtk4Core20DDesktopEntrySectionEE4copyEP8QMapDataIS0_S3_E@Base 5.0.3 + _ZNK8QMapNodeI7QStringPN3Dtk4Core12DFileWatcherEE4copyEP8QMapDataIS0_S4_E@Base 5.0.3 + _ZNK8QMapNodeI7QStringPN3Dtk4Core16AbstractAppenderEE4copyEP8QMapDataIS0_S4_E@Base 5.0.3 + _ZNK8QMapNodeI7QStringS0_E4copyEP8QMapDataIS0_S0_E@Base 5.0.3 + _ZNK8QMapNodeI7QStringbE4copyEP8QMapDataIS0_bE@Base 5.0.3 + _ZNK8QMapNodeI7QStringiE4copyEP8QMapDataIS0_iE@Base 5.0.3 + _ZNK8QMapNodeI9QDateTime7QStringE4copyEP8QMapDataIS0_S1_E@Base 5.0.3 + _ZNK8QMapNodeIPKvPyE4copyEP8QMapDataIS1_S2_E@Base 5.0.3 + _ZNK8QMapNodeIPKvyE4copyEP8QMapDataIS1_yE@Base 5.0.3 + _ZNK8QMapNodeIPPyS0_E4copyEP8QMapDataIS1_S0_E@Base 5.0.3 + _ZNK8QMapNodeIi7QStringE4copyEP8QMapDataIiS0_E@Base 5.0.3 + _ZNKSt5ctypeIcE8do_widenEc@Base 5.0.3 + _ZNSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE10_M_releaseEv@Base 5.0.3 + _ZNSt23_Sp_counted_ptr_inplaceI9DDBusDataSaIS0_ELN9__gnu_cxx12_Lock_policyE2EE10_M_destroyEv@Base 5.0.3 + _ZNSt23_Sp_counted_ptr_inplaceI9DDBusDataSaIS0_ELN9__gnu_cxx12_Lock_policyE2EE10_M_disposeEv@Base 5.0.3 + _ZNSt23_Sp_counted_ptr_inplaceI9DDBusDataSaIS0_ELN9__gnu_cxx12_Lock_policyE2EE14_M_get_deleterERKSt9type_info@Base 5.0.3 + _ZNSt23_Sp_counted_ptr_inplaceI9DDBusDataSaIS0_ELN9__gnu_cxx12_Lock_policyE2EED0Ev@Base 5.0.3 + _ZNSt23_Sp_counted_ptr_inplaceI9DDBusDataSaIS0_ELN9__gnu_cxx12_Lock_policyE2EED1Ev@Base 5.0.3 + _ZNSt23_Sp_counted_ptr_inplaceI9DDBusDataSaIS0_ELN9__gnu_cxx12_Lock_policyE2EED2Ev@Base 5.0.3 + _ZNSt23_Sp_counted_ptr_inplaceIN3Dtk4Core5DUtil11DNotifyDataESaIS3_ELN9__gnu_cxx12_Lock_policyE2EE10_M_destroyEv@Base 5.0.3 + _ZNSt23_Sp_counted_ptr_inplaceIN3Dtk4Core5DUtil11DNotifyDataESaIS3_ELN9__gnu_cxx12_Lock_policyE2EE10_M_disposeEv@Base 5.0.3 + _ZNSt23_Sp_counted_ptr_inplaceIN3Dtk4Core5DUtil11DNotifyDataESaIS3_ELN9__gnu_cxx12_Lock_policyE2EE14_M_get_deleterERKSt9type_info@Base 5.0.3 + _ZNSt23_Sp_counted_ptr_inplaceIN3Dtk4Core5DUtil11DNotifyDataESaIS3_ELN9__gnu_cxx12_Lock_policyE2EED0Ev@Base 5.0.3 + _ZNSt23_Sp_counted_ptr_inplaceIN3Dtk4Core5DUtil11DNotifyDataESaIS3_ELN9__gnu_cxx12_Lock_policyE2EED1Ev@Base 5.0.3 + _ZNSt23_Sp_counted_ptr_inplaceIN3Dtk4Core5DUtil11DNotifyDataESaIS3_ELN9__gnu_cxx12_Lock_policyE2EED2Ev@Base 5.0.3 + _ZNSt8functionIF8QVariant7QStringEEC1ERKS3_@Base 5.0.3 + _ZNSt8functionIF8QVariant7QStringEEC2ERKS3_@Base 5.0.3 + _ZSt9__find_ifIPK7QStringN9__gnu_cxx5__ops16_Iter_equals_valIS1_EEET_S7_S7_T0_St26random_access_iterator_tag@Base 5.0.3 + _ZTI12QDBusContext@Base 5.0.3 + _ZTIN3Dtk4Core12DFileWatcherE@Base 5.0.3 + _ZTIN3Dtk4Core12FileAppenderE@Base 5.0.3 + _ZTIN3Dtk4Core13DTrashManagerE@Base 5.0.3 + _ZTIN3Dtk4Core14DObjectPrivateE@Base 5.0.3 + _ZTIN3Dtk4Core14DSettingsGroupE@Base 5.0.3 + _ZTIN3Dtk4Core14DTrashManager_E@Base 5.0.3 + _ZTIN3Dtk4Core15ConsoleAppenderE@Base 5.0.3 + _ZTIN3Dtk4Core15DSettingsOptionE@Base 5.0.3 + _ZTIN3Dtk4Core15QSettingBackendE@Base 5.0.3 + _ZTIN3Dtk4Core16AbstractAppenderE@Base 5.0.3 + _ZTIN3Dtk4Core16DBaseFileWatcherE@Base 5.0.3 + _ZTIN3Dtk4Core16DSettingsBackendE@Base 5.0.3 + _ZTIN3Dtk4Core16GSettingsBackendE@Base 5.0.3 + _ZTIN3Dtk4Core18DDiskSizeFormatterE@Base 5.0.3 + _ZTIN3Dtk4Core18DFileSystemWatcherE@Base 5.0.3 + _ZTIN3Dtk4Core18DTimeUnitFormatterE@Base 5.0.3 + _ZTIN3Dtk4Core19DFileWatcherManagerE@Base 5.0.3 + _ZTIN3Dtk4Core19DFileWatcherPrivateE@Base 5.0.3 + _ZTIN3Dtk4Core19RollingFileAppenderE@Base 5.0.3 + _ZTIN3Dtk4Core20DTrashManagerPrivateE@Base 5.0.3 + _ZTIN3Dtk4Core22AbstractStringAppenderE@Base 5.0.3 + _ZTIN3Dtk4Core22DAbstractUnitFormatterE@Base 5.0.3 + _ZTIN3Dtk4Core23DBaseFileWatcherPrivateE@Base 5.0.3 + _ZTIN3Dtk4Core25DFileSystemWatcherPrivateE@Base 5.0.3 + _ZTIN3Dtk4Core26DFileWatcherManagerPrivateE@Base 5.0.3 + _ZTIN3Dtk4Core5DUtil18DExportedInterfaceE@Base 5.0.3 + _ZTIN3Dtk4Core5DUtil25DExportedInterfacePrivateE@Base 5.0.3 + _ZTIN3Dtk4Core5DUtil31DExportedInterfaceDBusInterfaceE@Base 5.0.3 + _ZTIN3Dtk4Core7DObjectE@Base 5.0.3 + _ZTIN3Dtk4Core9DSettingsE@Base 5.0.3 + _ZTIN3Dtk4Core9LogDeviceE@Base 5.0.3 + _ZTISt11_Mutex_baseILN9__gnu_cxx12_Lock_policyE2EE@Base 5.0.3 + _ZTISt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE@Base 5.0.3 + _ZTISt23_Sp_counted_ptr_inplaceI9DDBusDataSaIS0_ELN9__gnu_cxx12_Lock_policyE2EE@Base 5.0.3 + _ZTISt23_Sp_counted_ptr_inplaceIN3Dtk4Core5DUtil11DNotifyDataESaIS3_ELN9__gnu_cxx12_Lock_policyE2EE@Base 5.0.3 + _ZTS12QDBusContext@Base 5.0.3 + _ZTSN3Dtk4Core12DFileWatcherE@Base 5.0.3 + _ZTSN3Dtk4Core12FileAppenderE@Base 5.0.3 + _ZTSN3Dtk4Core13DTrashManagerE@Base 5.0.3 + _ZTSN3Dtk4Core14DObjectPrivateE@Base 5.0.3 + _ZTSN3Dtk4Core14DSettingsGroupE@Base 5.0.3 + _ZTSN3Dtk4Core14DTrashManager_E@Base 5.0.3 + _ZTSN3Dtk4Core15ConsoleAppenderE@Base 5.0.3 + _ZTSN3Dtk4Core15DSettingsOptionE@Base 5.0.3 + _ZTSN3Dtk4Core15QSettingBackendE@Base 5.0.3 + _ZTSN3Dtk4Core16AbstractAppenderE@Base 5.0.3 + _ZTSN3Dtk4Core16DBaseFileWatcherE@Base 5.0.3 + _ZTSN3Dtk4Core16DSettingsBackendE@Base 5.0.3 + _ZTSN3Dtk4Core16GSettingsBackendE@Base 5.0.3 + _ZTSN3Dtk4Core18DDiskSizeFormatterE@Base 5.0.3 + _ZTSN3Dtk4Core18DFileSystemWatcherE@Base 5.0.3 + _ZTSN3Dtk4Core18DTimeUnitFormatterE@Base 5.0.3 + _ZTSN3Dtk4Core19DFileWatcherManagerE@Base 5.0.3 + _ZTSN3Dtk4Core19DFileWatcherPrivateE@Base 5.0.3 + _ZTSN3Dtk4Core19RollingFileAppenderE@Base 5.0.3 + _ZTSN3Dtk4Core20DTrashManagerPrivateE@Base 5.0.3 + _ZTSN3Dtk4Core22AbstractStringAppenderE@Base 5.0.3 + _ZTSN3Dtk4Core22DAbstractUnitFormatterE@Base 5.0.3 + _ZTSN3Dtk4Core23DBaseFileWatcherPrivateE@Base 5.0.3 + _ZTSN3Dtk4Core25DFileSystemWatcherPrivateE@Base 5.0.3 + _ZTSN3Dtk4Core26DFileWatcherManagerPrivateE@Base 5.0.3 + _ZTSN3Dtk4Core5DUtil18DExportedInterfaceE@Base 5.0.3 + _ZTSN3Dtk4Core5DUtil25DExportedInterfacePrivateE@Base 5.0.3 + _ZTSN3Dtk4Core5DUtil31DExportedInterfaceDBusInterfaceE@Base 5.0.3 + _ZTSN3Dtk4Core7DObjectE@Base 5.0.3 + _ZTSN3Dtk4Core9DSettingsE@Base 5.0.3 + _ZTSN3Dtk4Core9LogDeviceE@Base 5.0.3 + _ZTSSt11_Mutex_baseILN9__gnu_cxx12_Lock_policyE2EE@Base 5.0.3 + _ZTSSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE@Base 5.0.3 + _ZTSSt19_Sp_make_shared_tag@Base 5.0.3 + _ZTSSt23_Sp_counted_ptr_inplaceI9DDBusDataSaIS0_ELN9__gnu_cxx12_Lock_policyE2EE@Base 5.0.3 + _ZTSSt23_Sp_counted_ptr_inplaceIN3Dtk4Core5DUtil11DNotifyDataESaIS3_ELN9__gnu_cxx12_Lock_policyE2EE@Base 5.0.3 + _ZTVN3Dtk4Core12DFileWatcherE@Base 5.0.3 + _ZTVN3Dtk4Core12FileAppenderE@Base 5.0.3 + _ZTVN3Dtk4Core13DTrashManagerE@Base 5.0.3 + _ZTVN3Dtk4Core14DObjectPrivateE@Base 5.0.3 + _ZTVN3Dtk4Core14DSettingsGroupE@Base 5.0.3 + _ZTVN3Dtk4Core14DTrashManager_E@Base 5.0.3 + _ZTVN3Dtk4Core15ConsoleAppenderE@Base 5.0.3 + _ZTVN3Dtk4Core15DSettingsOptionE@Base 5.0.3 + _ZTVN3Dtk4Core15QSettingBackendE@Base 5.0.3 + _ZTVN3Dtk4Core16AbstractAppenderE@Base 5.0.3 + _ZTVN3Dtk4Core16DBaseFileWatcherE@Base 5.0.3 + _ZTVN3Dtk4Core16DSettingsBackendE@Base 5.0.3 + _ZTVN3Dtk4Core16GSettingsBackendE@Base 5.0.3 + _ZTVN3Dtk4Core18DDiskSizeFormatterE@Base 5.0.3 + _ZTVN3Dtk4Core18DFileSystemWatcherE@Base 5.0.3 + _ZTVN3Dtk4Core18DTimeUnitFormatterE@Base 5.0.3 + _ZTVN3Dtk4Core19DFileWatcherManagerE@Base 5.0.3 + _ZTVN3Dtk4Core19DFileWatcherPrivateE@Base 5.0.3 + _ZTVN3Dtk4Core19RollingFileAppenderE@Base 5.0.3 + _ZTVN3Dtk4Core20DTrashManagerPrivateE@Base 5.0.3 + _ZTVN3Dtk4Core22AbstractStringAppenderE@Base 5.0.3 + _ZTVN3Dtk4Core22DAbstractUnitFormatterE@Base 5.0.3 + _ZTVN3Dtk4Core23DBaseFileWatcherPrivateE@Base 5.0.3 + _ZTVN3Dtk4Core25DFileSystemWatcherPrivateE@Base 5.0.3 + _ZTVN3Dtk4Core26DFileWatcherManagerPrivateE@Base 5.0.3 + _ZTVN3Dtk4Core5DUtil18DExportedInterfaceE@Base 5.0.3 + _ZTVN3Dtk4Core5DUtil25DExportedInterfacePrivateE@Base 5.0.3 + _ZTVN3Dtk4Core5DUtil31DExportedInterfaceDBusInterfaceE@Base 5.0.3 + _ZTVN3Dtk4Core7DObjectE@Base 5.0.3 + _ZTVN3Dtk4Core9DSettingsE@Base 5.0.3 + _ZTVN3Dtk4Core9LogDeviceE@Base 5.0.3 + _ZTVSt23_Sp_counted_ptr_inplaceI9DDBusDataSaIS0_ELN9__gnu_cxx12_Lock_policyE2EE@Base 5.0.3 + _ZTVSt23_Sp_counted_ptr_inplaceIN3Dtk4Core5DUtil11DNotifyDataESaIS3_ELN9__gnu_cxx12_Lock_policyE2EE@Base 5.0.3 + _ZThn16_N3Dtk4Core12DFileWatcherD0Ev@Base 5.0.3 + _ZThn16_N3Dtk4Core12DFileWatcherD1Ev@Base 5.0.3 + _ZThn16_N3Dtk4Core13DTrashManagerD0Ev@Base 5.0.3 + _ZThn16_N3Dtk4Core13DTrashManagerD1Ev@Base 5.0.3 + _ZThn16_N3Dtk4Core14DTrashManager_D0Ev@Base 5.0.3 + _ZThn16_N3Dtk4Core14DTrashManager_D1Ev@Base 5.0.3 + _ZThn16_N3Dtk4Core16DBaseFileWatcherD0Ev@Base 5.0.3 + _ZThn16_N3Dtk4Core16DBaseFileWatcherD1Ev@Base 5.0.3 + _ZThn16_N3Dtk4Core18DFileSystemWatcherD0Ev@Base 5.0.3 + _ZThn16_N3Dtk4Core18DFileSystemWatcherD1Ev@Base 5.0.3 + _ZThn16_N3Dtk4Core19DFileWatcherManagerD0Ev@Base 5.0.3 + _ZThn16_N3Dtk4Core19DFileWatcherManagerD1Ev@Base 5.0.3 + _ZThn16_N3Dtk4Core5DUtil18DExportedInterfaceD0Ev@Base 5.0.3 + _ZThn16_N3Dtk4Core5DUtil18DExportedInterfaceD1Ev@Base 5.0.3 + _ZZN3Dtk4Core11DLogManager8instanceEvE8instance@Base 5.0.3 + _ZZN9QtPrivate15ConnectionTypesINS_4ListIJRK7QStringRK8QVariantEEELb1EE5typesEvE1t@Base 5.0.3 + _ZZNSt19_Sp_make_shared_tag5_S_tiEvE5__tag@Base 5.0.3 diff --git a/doc/Specification.md b/doc/Specification.md new file mode 100644 index 0000000..94bf3a8 --- /dev/null +++ b/doc/Specification.md @@ -0,0 +1,81 @@ +# Deepin Application Specification {#Specification} + +Every application should keep the rule in this document. + +## 1. Application Information + +Application should set the property Organization-name and Application-name. + +Organization/Application name can contains alphabet, number and other visible ASCII code, BUT space MUST NOT appear in the name. And we do not approve +of no-ASCII code character in the Organization/Application name + +Application can stay Organization-name empty, but it should always set an Application-name. + +## 2. Standard Path + +The log, configure and runtime cache of Application should store in specific path. + +**If Organization-name is empty, "{Organization-name}/" would not appear in path.** + +### 2.1 User Application Standard Path + +As an application run for user session, the Standard path should be: + +````bash +XGD_LOG_HOME_DEEPIN: + Where deepin-user-specific log should be written. + XGD_USER_HOME/.log + +DAPP_CONFIG_HOME: + Where application-specific configurations should be written. + XDG_CONFIG_HOME/{Organization-name}/{Application-name} + +DAPP_LOG_HOME: + Where application-specific log should be written. + XGD_LOG_HOME_DEEPIN/{Organization-name}/{Application-name} + +DAPP_CACHE_HOME: + Where application-specific cache files should be written. + XGD_CACHE_HOME/{Organization-name}/{Application-name} + +DAPP_DATA_HOME: + Where application-specific data files should be written. + $XDG_DATA_HOME/{Organization-name}/{Application-name} + +```` + +Simple example: + +The dde-dock is offcial application of deepin and the standard path will be: + +````bash +DAPP_CONFIG_HOME: $HOME/.config/deepin/dde-dock +DAPP_LOG_HOME: $HOME/.log/deepin/dde-dock +DAPP_CACHE_HOME: $HOME/.cache/deepin/dde-dock +DAPP_DATA_HOME: $HOME/.local/share/deepin/dde-dock +```` + +### 2.2 System Application Standard Path + +Application run as system daemon, or with user with no home directory should place it's file in this standard path: + +````bash +DAPP_CONFIG_SYS: + /etc/{Organization-name}/{Application-name} + +DAPP_LOG_SYS: + /var/log/{Organization-name}/{Application-name} + +DAPP_DATA_SYS: + /usr/share/{Organization-name}/{Application-name} + +DAPP_CACHE_SYS: + /var/cache/{Organization-name}/{Application-name} +```` + + +Refs: + +[XDG Base Directory Specification](https://specifications.freedesktop.org/basedir-spec/basedir-spec-0.8.html) + +[XDG Base Directory support](https://wiki.archlinux.org/index.php/XDG_Base_Directory_support) diff --git a/dtkcore.pro b/dtkcore.pro new file mode 100644 index 0000000..28a097f --- /dev/null +++ b/dtkcore.pro @@ -0,0 +1 @@ +load(dtk_lib) diff --git a/examples/examples.pro b/examples/examples.pro new file mode 100644 index 0000000..984ab9d --- /dev/null +++ b/examples/examples.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS += expintf-example diff --git a/examples/expintf-example/expintf-example.pro b/examples/expintf-example/expintf-example.pro new file mode 100644 index 0000000..5663a98 --- /dev/null +++ b/examples/expintf-example/expintf-example.pro @@ -0,0 +1,16 @@ +TEMPLATE = app +QT += dbus + +SOURCES += \ + $$PWD/main.cpp + +win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../../src/release -ldtkcore +else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../../src/debug -ldtkcore +else:unix: LIBS += -L$$OUT_PWD/../../src -ldtkcore + +INCLUDEPATH += $$PWD/../../src +INCLUDEPATH += $$PWD/../../src/base + +CONFIG(debug, debug|release) { + unix:QMAKE_RPATHDIR += $$OUT_PWD/../../src +} diff --git a/examples/expintf-example/main.cpp b/examples/expintf-example/main.cpp new file mode 100644 index 0000000..5af9bb6 --- /dev/null +++ b/examples/expintf-example/main.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2017 ~ 2019 Deepin Technology Co., Ltd. + * + * Author: Chris Xiong + * + * Maintainer: Chris Xiong + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#include "util/dexportedinterface.h" + +#include +#include +#include +#include + +#include + +//#define ALTERNATE_USAGE + +DCORE_USE_NAMESPACE + +class CustomInterface : public DUtil::DExportedInterface +{ + QVariant invoke(const QString &action, const QString ¶meters) const + { + QJsonDocument d = QJsonDocument::fromJson(parameters.toUtf8()); + if (action == "pow") { + return QVariant(pow(d["a"].toDouble(), d["b"].toDouble())); + } + return QVariant(); + } +}; + +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); + QDBusConnection::sessionBus().registerService("com.deepin.ExpIntfTest"); + +#ifndef ALTERNATE_USAGE + DUtil::DExportedInterface *ei = new DUtil::DExportedInterface(); + ei->registerAction("quit", "quit the application", [&app](QString)->QVariant { + app.quit(); + return QVariant(); + }); + + ei->registerAction("answer", "answer to the ultimate question of life, the universe, and everything", + [](QString)->QVariant {return QVariant(42);}); + + ei->registerAction("sum", "returns the sum of two integers", [](QString p)->QVariant { + QJsonDocument d = QJsonDocument::fromJson(p.toUtf8()); + return QVariant(d["a"].toInt() + d["b"].toInt()); + }); +#else + CustomInterface *cei = new CustomInterface(); + cei->registerAction("pow", "raise a number to a power"); +#endif + + return app.exec(); +} diff --git a/rpm/dtkcore.spec b/rpm/dtkcore.spec new file mode 100644 index 0000000..8645aff --- /dev/null +++ b/rpm/dtkcore.spec @@ -0,0 +1,77 @@ +Name: dtkcore +Version: 5.4.3 +Release: 1%{?dist} +Summary: Deepin tool kit core modules +License: LGPLv3+ +URL: https://github.com/linuxdeepin/dtkcore +%if 0%{?fedora} +Source0: %{url}/archive/%{version}/%{name}-%{version}.tar.gz +%else +Source0: %{name}_%{version}.orig.tar.xz +%endif +BuildRequires: gcc-c++ +BuildRequires: annobin +BuildRequires: pkgconfig(Qt5Core) +BuildRequires: pkgconfig(gsettings-qt) +BuildRequires: gtest-devel + +# since f30 +Obsoletes: deepin-tool-kit <= 0.3.3 +Obsoletes: deepin-tool-kit-devel <= 0.3.3 +Obsoletes: dtksettings <= 0.1.7 +Obsoletes: dtksettings-devel <= 0.1.7 + +%description +Deepin tool kit core modules. + +%package devel +Summary: Development package for %{name} +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: qt5-qtbase-devel%{?_isa} + +%description devel +Header files and libraries for %{name}. + +%prep +%autosetup -p1 + +%build +# help find (and prefer) qt5 utilities, e.g. qmake, lrelease +export PATH=%{_qt5_bindir}:$PATH +%qmake_qt5 PREFIX=%{_prefix} \ + DTK_VERSION=%{version} \ + LIB_INSTALL_DIR=%{_libdir} \ + BIN_INSTALL_DIR=%{_libexecdir}/dtk5 \ + TOOL_INSTALL_DIR=%{_libexecdir}/dtk5 +%make_build + +%install +%make_install INSTALL_ROOT=%{buildroot} + +%files +%doc README.md +%license LICENSE +%{_libdir}/lib%{name}.so.5* +%dir %{_libexecdir}/dtk5/ +%{_libexecdir}/dtk5/dtk-settings +%{_libexecdir}/dtk5/dtk-license.py +%{_libexecdir}/dtk5/dtk-translate.py +%{_libexecdir}/dtk5/deepin-os-release +%{_prefix}/bin/qdbusxml2cpp-fix +%{_datadir}/glib-2.0/schemas/* + +%files devel +%doc doc/Specification.md +%{_includedir}/libdtk-*/ +%{_qt5_archdatadir}/mkspecs/features/*.prf +%{_qt5_archdatadir}/mkspecs/modules/*.pri +%{_libdir}/cmake/Dtk/ +%{_libdir}/cmake/DtkCore/ +%{_libdir}/cmake/DtkCMake/ +%{_libdir}/cmake/DtkTools/ +%{_libdir}/pkgconfig/dtkcore.pc +%{_libdir}/lib%{name}.so + +%changelog +* Thu Jun 11 2020 uoser - 5.2.2.3 +- Update to 5.2.2.3 diff --git a/src/DDesktopEntry b/src/DDesktopEntry new file mode 100644 index 0000000..847127a --- /dev/null +++ b/src/DDesktopEntry @@ -0,0 +1 @@ +#include "ddesktopentry.h" diff --git a/src/DSecureString b/src/DSecureString new file mode 100644 index 0000000..83f6c1a --- /dev/null +++ b/src/DSecureString @@ -0,0 +1 @@ +#include "dsecurestring.h" diff --git a/src/DSysInfo b/src/DSysInfo new file mode 100644 index 0000000..c026f58 --- /dev/null +++ b/src/DSysInfo @@ -0,0 +1 @@ +#include "dsysinfo.h" diff --git a/src/base/DObject b/src/base/DObject new file mode 100644 index 0000000..75fbcb7 --- /dev/null +++ b/src/base/DObject @@ -0,0 +1 @@ +#include "dobject.h" diff --git a/src/base/DObjectPrivate b/src/base/DObjectPrivate new file mode 100644 index 0000000..0c145c8 --- /dev/null +++ b/src/base/DObjectPrivate @@ -0,0 +1 @@ +#include "dobject_p.h" diff --git a/src/base/DSingleton b/src/base/DSingleton new file mode 100644 index 0000000..280d2f9 --- /dev/null +++ b/src/base/DSingleton @@ -0,0 +1 @@ +#include "dsingleton.h" diff --git a/src/base/base.pri b/src/base/base.pri new file mode 100644 index 0000000..fb8de9e --- /dev/null +++ b/src/base/base.pri @@ -0,0 +1,18 @@ +include($$PWD/private/private.pri) + +INCLUDEPATH += $$PWD/base +INCLUDEPATH += $$PWD/private + +HEADERS += \ + $$PWD/dobject.h \ + $$PWD/dsingleton.h + +SOURCES += \ + $$PWD/dobject.cpp + +includes.files += $$PWD/*.h +includes.files += $$PWD/private/*.h +includes.files += \ + $$PWD/DObject \ + $$PWD/DObjectPrivate \ + $$PWD/DSingleton diff --git a/src/base/dobject.cpp b/src/base/dobject.cpp new file mode 100644 index 0000000..778457d --- /dev/null +++ b/src/base/dobject.cpp @@ -0,0 +1,246 @@ +/* + * Copyright (C) 2015 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#include "dobject.h" +#include "private/dobject_p.h" + +DCORE_BEGIN_NAMESPACE + +DObjectPrivate::DObjectPrivate(DObject *qq) + : q_ptr(qq) +{ + +} + +DObjectPrivate::~DObjectPrivate() +{ + +} + +/*! + * \~chinese \file dobject.h + * \~chinese \brief 一些宏的定义 +*/ + +/*! + * \~chinese \def D_DECLARE_PRIVATE(Class) + * + * \~chinese \brief 这个宏一定要放到类的私有区域,它定义了 d_func() 这个函数用于返回私有类的对象, + * \~chinese 这个对象只应该在类的内部使用,另外将私有类声明为公开类的友元类。 + * \~chinese \param Class 公开类的类名 + * \~chinese \sa D_DECLARE_PUBLIC D_D D_DC +*/ + +/*! + * \~chinese \def D_DECLARE_PUBLIC(Class) + * + * \~chinese \brief 这个宏用于私有类中,它定义了 q_func() 这个函数用于返回公开类的对象,另外将公开类 + * \~chinese 声明为私有类的友元类。 + * \~chinese \param Class 公开类的类名 + * \~chinese \sa D_DECLARE_PRIVATE D_Q D_QC +*/ + +/*! + * \~chinese \def D_D(Class) + * + * \~chinese \brief 这个宏用于公开类中,它定义了一个名字为 d 的变量存储 d_func() 的返回值。用于在公开 + * \~chinese 类中需要访问私有类的数据成员的函数中。 + * \~chinese \param Class 公开类的类名 + * \~chinese \sa D_DECLARE_PRVATE D_DC +*/ + +/*! + * \~chinese \def D_DC(Class) + * + * \~chinese \brief 同 D_D,用在公开类加了 const 修饰符的成员函数中。 + * \~chinese \param Class 公开类的类名 + * \~chinese \sa D_DECLARE_PRVATE D_D +*/ + +/*! + * \~chinese \def D_Q(Class) + * + * \~chinese \brief 这个宏用于私有类中,它定义了一个名字为 q 的变量存储 q_func() 的返回值。用于在私有 + * \~chinese 类中需要调用公开类的成员函数时。 + * \~chinese \param Class 公开类的类名 + * \~chinese \sa D_DECLARE_PUBLIC D_QC +*/ + +/*! + * \~chinese \def D_QC(Class) + * + * \~chinese \brief 同 D_Q,用在私有类加了 const 修饰符的成员函数中。 + * \~chinese \param Class 公开类的类名 + * \~chinese \sa D_DECLARE_PUBLIC D_Q +*/ + +/*! + * \~chinese \def D_PRIVATE_SLOT(Func) + * + * \~chinese \brief 同 Q_PRIVATE_SLOT,用在继承了 QObject 的公开类中,在公开类中定一个槽函数,且函数 + * \~chinese 必须在私有类中有实现。用这个方式定义的槽函数无法被直接调用,只能用于 QObject::connect + * \~chinese 使用 SIGNAL 和 SLOT 的方式连接信号,或者使用 QMetaObject::invokeMethod 调用。 + * \~chinese 一般来讲,这个槽函数应该只在类内部使用,外界不应该通过任何方式来调用它。 + * + * \~chinese 例子: + * + * \~chinese a.h + * \code + * class APrivate; + * class A : public DObject + * { + * D_DECLARE_PRIVATE(A) + * public: + * A(); + * + * protected: + * A(APrivate &dd, DObject *parent = nullptr); + * + * private: + * D_PRIVATE_SLOT(void _q_testSlot() const) + * }; + * \endcode + * \~chinese a.cpp + * \code + * class APrivate : public DObjectPrivate + * { + * public: + * D_DECLARE_PUBLIC(A) + * + * APrivate(A *qq) + * : DObjectPrivate(qq) + * { + * QTimer *timer = new QTimer(); + * QObject::connect(timer, SIGNAL(timeout()), qq, SLOT(_q_testSlot())); + * timer->start(1000); + * } + * + * void _q_testSlot() const + * { + * qDebug() << "slot"; + * } + * }; + * + * A::A() + * : DObject(*new APrivate(this)) + * { + * + * } + * + * A::A(APrivate &dd, DObject *parent) + * : DObject(dd, parent) + * { + * + * } + * + * #include "moc_a.cpp" + * \endcode + * \~chinese \param Func 槽函数的完整签名 + * \~chinese \note 添加或更新私有槽之后需要重新手动调用 qmake + * \~chinese \sa D_DECLARE_PUBLIC D_Q +*/ + +/*! + * \~chinese \class DObject + * \~chinese \brief deepin-tool-kit 中所有公开类的祖先类。 + * + * \~chinese 通过和 \ref D_DECLARE_PRIVATE 、\ref D_DECLARE_PUBLIC + * \~chinese 等宏的配合方便派生类中实现 D-Point 结构。虽然 QObject 中已经有了这样的实现结构,但是没有 + * \~chinese 办法在不使用 Qt 私有模块的情况下,在 DTK 库中达到同样的目的。D-Point 结构由“公共接口类” + * \~chinese 和“私有数据类”两部分组成,在 DTK 中,DObjectPrivate 是所有数据类的祖先类。在这种结构下, + * \~chinese 只有 DObject 这个基类中定了一个指向于私有数据类的对象指针,派生类中不会也不应该再定义任何 + * \~chinese 成员变量,派生类中需要添加数据成员时,可以继承 DObjectPrivate,将新的成员变量放到私有类中 + * + * \~chinese 例子: + * + * \~chinese a.h + * \code + * class APrivate; + * class A : public DObject + * { + * D_DECLARE_PRIVATE(A) + * public: + * A(); + * int test() const; + * + * protected: + * A(APrivate &dd, DObject *parent = nullptr); + * }; + * \endcode + * \~chinese a.cpp + * \code + * class APrivate : public DObjectPrivate + * { + * public: + * APrivate(A *qq) + * : DObjectPrivate(qq) + * { + * + * } + * + * D_DECLARE_PUBLIC(A) + * // 此处添加数据成员 + * int data; + * }; + * + * A::A() + * : DObject(*new APrivate(this)) + * { + * + * } + * + * int test() const + * { + * D_D(A); + * + * return d->data; + * } + * + * A::A(APrivate &dd, DObject *parent) + * : DObject(dd, parent) + * { + * + * } + * \endcode + * 一般来讲,DObject 只会用在 DTK 库中定义的类,对于使用 DTK 库的应用程序来说不用关心它的存在 + * \~chinese \sa \href{https://wiki.qt.io/D-Pointer/zh,类的 D-Point 结构} + */ + +/*! + * \~chinese \brief 只有在不需要数据成员的派生类中才会使用 + */ +DObject::DObject(DObject * /*parent = nullptr*/) +{ + +} + +/*! + * \~chinese \brief 在派生类中比较常用的构造函数 + * \~chinese \param dd 私有类对象 + */ +DObject::DObject(DObjectPrivate &dd, DObject * /*parent = nullptr*/): + d_d_ptr(&dd) +{ + +} + +DObject::~DObject() +{ + +} + +DCORE_END_NAMESPACE diff --git a/src/base/dobject.h b/src/base/dobject.h new file mode 100644 index 0000000..d981d40 --- /dev/null +++ b/src/base/dobject.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2015 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef DOBJECT_H +#define DOBJECT_H + +#include + +#include "dtkcore_global.h" + +DCORE_BEGIN_NAMESPACE + +#define D_DECLARE_PRIVATE(Class) Q_DECLARE_PRIVATE_D(qGetPtrHelper(d_d_ptr),Class) +#define D_DECLARE_PUBLIC(Class) Q_DECLARE_PUBLIC(Class) +#define D_D(Class) Q_D(Class) +#define D_Q(Class) Q_Q(Class) +#define D_DC(Class) Q_D(const Class) +#define D_QC(Class) Q_Q(const Class) +#define D_PRIVATE_SLOT(Func) Q_PRIVATE_SLOT(d_func(), Func) + +class DObjectPrivate; + +class LIBDTKCORESHARED_EXPORT DObject +{ +protected: + DObject(DObject *parent = nullptr); + + DObject(DObjectPrivate &dd, DObject *parent = nullptr); + + virtual ~DObject(); + + QScopedPointer d_d_ptr; + + Q_DISABLE_COPY(DObject) + D_DECLARE_PRIVATE(DObject) +}; + +DCORE_END_NAMESPACE + +#endif // DOBJECT_H diff --git a/src/base/dsingleton.h b/src/base/dsingleton.h new file mode 100644 index 0000000..ae15030 --- /dev/null +++ b/src/base/dsingleton.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2016 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef DSINGLETON_H +#define DSINGLETON_H + +#include "dtkcore_global.h" + +DCORE_BEGIN_NAMESPACE + +/*! + * \~english a simple singleton template for std c++ 11 or later. + * + * example: + +``` + class ExampleSingleton : public QObject, public Dtk::DSingleton + { + Q_OBJECT + friend class DSingleton; + }; +``` + + * \note: for Qt, "public DSingleton" must be after QObject. + */ + + +/*! + * \~chinese 通过c++11的特性实现的单例模板 + * + * 使用示例: + +``` + class ExampleSingleton : public QObject, public Dtk::DSingleton + { + Q_OBJECT + friend class DSingleton; + }; +``` + + * \note 对于Qt程序 public DSingleton" 必须在卸载QObject后面出现。 + */ + +template +class LIBDTKCORESHARED_EXPORT DSingleton +{ +public: + static inline T *instance() + { + static T *_instance = new T; + return _instance; + } + +protected: + DSingleton(void) {} + ~DSingleton(void) {} + DSingleton(const DSingleton &) {} + DSingleton &operator= (const DSingleton &) {} +}; + +DCORE_END_NAMESPACE + +#endif // DSINGLETON_H diff --git a/src/base/private/dobject_p.h b/src/base/private/dobject_p.h new file mode 100644 index 0000000..f3213bd --- /dev/null +++ b/src/base/private/dobject_p.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2015 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef DOBJECT_P_H +#define DOBJECT_P_H + +#include "dtkcore_global.h" + +DCORE_BEGIN_NAMESPACE + +class DObject; +class LIBDTKCORESHARED_EXPORT DObjectPrivate +{ +public: + virtual ~DObjectPrivate(); + +protected: + DObjectPrivate(DObject *qq); + + DObject *q_ptr; + + Q_DECLARE_PUBLIC(DObject) +}; + +DCORE_END_NAMESPACE + +#endif // DOBJECT_P_H + diff --git a/src/base/private/private.pri b/src/base/private/private.pri new file mode 100644 index 0000000..5de92e3 --- /dev/null +++ b/src/base/private/private.pri @@ -0,0 +1,2 @@ +HEADERS += \ + $$PWD/dobject_p.h diff --git a/src/ddesktopentry.cpp b/src/ddesktopentry.cpp new file mode 100644 index 0000000..e70e8a7 --- /dev/null +++ b/src/ddesktopentry.cpp @@ -0,0 +1,1047 @@ +/* + * Copyright (C) 2019 Deepin Technology Co., Ltd. + * 2019 Gary Wang + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#include "ddesktopentry.h" + +#include +#include +#include +#include +#include +#include + +DCORE_BEGIN_NAMESPACE + +enum { Space = 0x1, Special = 0x2 }; + +static const char charTraits[256] = { + // Space: '\t', '\n', '\r', ' ' + // Special: '\n', '\r', ';', '=', '\\', '#' + // Please note that '"' is NOT a special character + + 0, 0, 0, 0, 0, 0, 0, 0, 0, Space, Space | Special, 0, 0, Space | Special, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + Space, 0, 0, Special, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Special, 0, Special, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Special, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +bool readLineFromData(const QByteArray &data, int &dataPos, int &lineStart, int &lineLen, int &equalsPos) +{ + int dataLen = data.length(); + + equalsPos = -1; + + lineStart = dataPos; + while (lineStart < dataLen && (charTraits[uint(uchar(data.at(lineStart)))] & Space)) + ++lineStart; + + int i = lineStart; + while (i < dataLen) { + while (!(charTraits[uint(uchar(data.at(i)))] & Special)) { + if (++i == dataLen) + goto break_out_of_outer_loop; + } + + char ch = data.at(i++); + if (ch == '=') { + if (equalsPos == -1) + equalsPos = i - 1; + } else if (ch == '\n' || ch == '\r') { + if (i == lineStart + 1) { + ++lineStart; + } else { + --i; + goto break_out_of_outer_loop; + } + } else if (ch == '\\') { + if (i < dataLen) { + char ch = data.at(i++); + if (i < dataLen) { + char ch2 = data.at(i); + // \n, \r, \r\n, and \n\r are legitimate line terminators in INI files + if ((ch == '\n' && ch2 == '\r') || (ch == '\r' && ch2 == '\n')) + ++i; + } + } + } else if (ch == ';') { + // The multiple values should be separated by a semicolon and the value of the key + // may be optionally terminated by a semicolon. Trailing empty strings must always + // be terminated with a semicolon. Semicolons in these values need to be escaped + // using \; . + // Don't need to do anything here. + } else { + Q_ASSERT(ch == '#'); + + if (i == lineStart + 1) { + char ch; + while (i < dataLen && (((ch = data.at(i)) != '\n') && ch != '\r')) + ++i; + lineStart = i; + } + } + } + +break_out_of_outer_loop: + dataPos = i; + lineLen = i - lineStart; + return lineLen > 0; +} + +QString &doEscape(QString& str, const QHash &repl) +{ + // First we replace slash. + str.replace(QLatin1Char('\\'), QLatin1String("\\\\")); + + QHashIterator i(repl); + while (i.hasNext()) { + i.next(); + if (i.key() != QLatin1Char('\\')) + str.replace(i.key(), QString::fromLatin1("\\\\%1").arg(i.value())); + } + + return str; +} + +QString &doUnescape(QString& str, const QHash &repl) +{ + int n = 0; + while (1) { + n=str.indexOf(QLatin1String("\\"), n); + if (n < 0 || n > str.length() - 2) + break; + + if (repl.contains(str.at(n+1))) { + str.replace(n, 2, repl.value(str.at(n+1))); + } + + n++; + } + + return str; +} + +/*! \internal */ +class DDesktopEntrySection +{ +public: + DDesktopEntrySection() {} + + QString name; + QMap valuesMap; + QByteArray unparsedDatas; + int sectionPos = 99; + + inline operator QString() const { + return QLatin1String("DDesktopEntrySection(") + name + QLatin1String(")"); + } + + QByteArray sectionData() const { + if (unparsedDatas.isEmpty()) { + // construct data and return + QByteArray data; + + data.append(QString("[%1]\n").arg(name)); + + QMap::const_iterator i; + for (i = valuesMap.begin(); i != valuesMap.end(); i++) { + data.append(QString("%1=%2\n").arg(i.key(), i.value())); + } + + return data; + } else { + return unparsedDatas; + } + } + + bool ensureSectionDataParsed() { + if (unparsedDatas.isEmpty()) return true; + + valuesMap.clear(); + + // for readLineFromFileData() + int dataPos = 0; + int lineStart; + int lineLen; + int equalsPos; + + while(readLineFromData(unparsedDatas, dataPos, lineStart, lineLen, equalsPos)) { + if (unparsedDatas.at(lineStart) == '[') continue; // section name already parsed + + if (equalsPos != -1) { + QString key = unparsedDatas.mid(lineStart, equalsPos - lineStart).trimmed(); + QString rawValue = unparsedDatas.mid(equalsPos + 1, lineStart + lineLen - equalsPos - 1).trimmed(); + + valuesMap[key] = rawValue; + } + } + + unparsedDatas.clear(); + + return true; + } + + bool contains(const QString &key) const { + const_cast(this)->ensureSectionDataParsed(); + return valuesMap.contains(key); + } + + QStringList allKeys() const { + const_cast(this)->ensureSectionDataParsed(); + return valuesMap.keys(); + } + + QString get(const QString &key, QString &defaultValue) { + if (this->contains(key)) { + return valuesMap[key]; + } else { + return defaultValue; + } + } + + bool set(const QString &key, const QString &value) { + if (this->contains(key)) { + valuesMap.remove(key); + } + valuesMap[key] = value; + return true; + } + + bool remove(const QString &key) { + if (this->contains(key)) { + valuesMap.remove(key); + return true; + } + return false; + } +}; + +typedef QMap SectionMap; + +class DDesktopEntryPrivate +{ +public: + DDesktopEntryPrivate(const QString &filePath, DDesktopEntry *qq); + ~DDesktopEntryPrivate(); + + bool isWritable() const; + bool fuzzyLoad(); + bool initSectionsFromData(const QByteArray &data); + void setStatus(const DDesktopEntry::Status &newStatus) const; + bool write(QIODevice &device) const; + + int sectionPos(const QString §ionName) const; + bool contains(const QString §ionName, const QString &key) const; + QStringList keys(const QString §ionName) const; + bool get(const QString §ionName, const QString &key, QString *value); + bool set(const QString §ionName, const QString &key, const QString &value); + bool remove(const QString §ionName, const QString &key); + +protected: + QString filePath; + QMutex fileMutex; + SectionMap sectionsMap; + mutable DDesktopEntry::Status status; + +private: + bool __padding[4]; + DDesktopEntry *q_ptr = nullptr; + + Q_DECLARE_PUBLIC(DDesktopEntry) +}; + +DDesktopEntryPrivate::DDesktopEntryPrivate(const QString &filePath, DDesktopEntry *qq) + : filePath(filePath), q_ptr(qq) +{ + fuzzyLoad(); +} + +DDesktopEntryPrivate::~DDesktopEntryPrivate() +{ + +} + +bool DDesktopEntryPrivate::isWritable() const +{ + QFileInfo fileInfo(filePath); + +#ifndef QT_NO_TEMPORARYFILE + if (fileInfo.exists()) { +#endif + QFile file(filePath); + return file.open(QFile::ReadWrite); +#ifndef QT_NO_TEMPORARYFILE + } else { + // Create the directories to the file. + QDir dir(fileInfo.absolutePath()); + if (!dir.exists()) { + if (!dir.mkpath(dir.absolutePath())) + return false; + } + + // we use a temporary file to avoid race conditions + QTemporaryFile file(filePath); + return file.open(); + } +#endif +} + +bool DDesktopEntryPrivate::fuzzyLoad() +{ + QFile file(filePath); + QFileInfo fileInfo(filePath); + + if (fileInfo.exists() && !file.open(QFile::ReadOnly)) { + setStatus(DDesktopEntry::AccessError); + return false; + } + + if (file.isReadable() && file.size() != 0) { + bool ok = false; + QByteArray data = file.readAll(); + + ok = initSectionsFromData(data); + + if (!ok) { + setStatus(DDesktopEntry::FormatError); + return false; + } + } + + return true; +} + +bool DDesktopEntryPrivate::initSectionsFromData(const QByteArray &data) +{ + sectionsMap.clear(); + + QString lastSectionName; + int lastSectionStart = 0; + bool formatOk = true; + int sectionIdx = 0; + // for readLineFromFileData() + int dataPos = 0; + int lineStart; + int lineLen; + int equalsPos; + + auto commitSection = [=](const QString &name, int sectionStartPos, int sectionLength, int sectionIndex) { + DDesktopEntrySection lastSection; + lastSection.name = name; + lastSection.unparsedDatas = data.mid(sectionStartPos, sectionLength); + lastSection.sectionPos = sectionIndex; + sectionsMap[name] = lastSection; + }; + + // TODO: here we only need to find the section start, so things like equalsPos are useless here. + // maybe we can do some optimization here via adding extra argument to readLineFromData(). + while(readLineFromData(data, dataPos, lineStart, lineLen, equalsPos)) { + // qDebug() << "CurrentLine:" << data.mid(lineStart, lineLen); + if (data.at(lineStart) == '[') { + // commit the last section we've ever read before we read the new one. + if (!lastSectionName.isEmpty()) { + commitSection(lastSectionName, lastSectionStart, lineStart - lastSectionStart, sectionIdx); + sectionIdx++; + } + // process section name line + QByteArray sectionName; + int idx = data.indexOf(']', lineStart); + if (idx == -1 || idx >= lineStart + lineLen) { + qWarning() << "Bad desktop file format while reading line:" << data.mid(lineStart, lineLen); + formatOk = false; + sectionName = data.mid(lineStart + 1, lineLen - 1).trimmed(); + } else { + sectionName = data.mid(lineStart + 1, idx - lineStart - 1).trimmed(); + } + lastSectionName = sectionName; + lastSectionStart = lineStart; + } + } + + Q_ASSERT(lineStart == data.length()); + if (!lastSectionName.isEmpty()) { + commitSection(lastSectionName, lastSectionStart, lineStart - lastSectionStart, sectionIdx); + } + + return formatOk; +} + +// Always keep the first meet error status. and allowed clear the status. +void DDesktopEntryPrivate::setStatus(const DDesktopEntry::Status &newStatus) const +{ + if (newStatus == DDesktopEntry::NoError || this->status == DDesktopEntry::NoError) { + this->status = newStatus; + } +} + +bool DDesktopEntryPrivate::write(QIODevice &device) const +{ + Q_Q(const DDesktopEntry); + + QStringList sortedKeys = q->allGroups(true); + + for (const QString &key : sortedKeys) { + qint64 ret = device.write(sectionsMap[key].sectionData()); + if (ret == -1) return false; + } + + return true; +} + +int DDesktopEntryPrivate::sectionPos(const QString §ionName) const +{ + if (sectionsMap.contains(sectionName)) { + return sectionsMap[sectionName].sectionPos; + } + + return -1; +} + +bool DDesktopEntryPrivate::contains(const QString §ionName, const QString &key) const +{ + if (sectionName.isNull() || key.isNull()) { + return false; + } + + if (sectionsMap.contains(sectionName)) { + return sectionsMap[sectionName].contains(key); + } + + return false; +} + +QStringList DDesktopEntryPrivate::keys(const QString §ionName) const +{ + if (sectionName.isNull()) { + return {}; + } + + if (sectionsMap.contains(sectionName)) { + return sectionsMap[sectionName].allKeys(); + } + + return {}; +} + +// return true if we found the value, and set the value to *value +bool DDesktopEntryPrivate::get(const QString §ionName, const QString &key, QString *value) +{ + if (!this->contains(sectionName, key)) { + return false; + } + + if (sectionsMap.contains(sectionName)) { + QString &&result = sectionsMap[sectionName].get(key, *value); + *value = result; + return true; + } + + return false; +} + +bool DDesktopEntryPrivate::set(const QString §ionName, const QString &key, const QString &value) +{ + if (sectionsMap.contains(sectionName)) { + bool result = sectionsMap[sectionName].set(key, value); + return result; + } else { + // create new section. + DDesktopEntrySection newSection; + newSection.name = sectionName; + newSection.set(key, value); + sectionsMap[sectionName] = newSection; + return true; + } + + return false; +} + +bool DDesktopEntryPrivate::remove(const QString §ionName, const QString &key) +{ + if (this->contains(sectionName, key)) { + return sectionsMap[sectionName].remove(key); + } + return false; +} + +/*! + * \class DDesktopEntry + * \brief Handling desktop entry files. + * + * DDesktopEntry provide method for handling XDG desktop entry read and write. The interface + * of this class is similar to QSettings. + * + * For more details about the spec itself, please refer to: + * https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html + */ + +DDesktopEntry::DDesktopEntry(const QString &filePath) noexcept + : d_ptr(new DDesktopEntryPrivate(filePath, this)) +{ + +} + +DDesktopEntry::~DDesktopEntry() +{ + +} + +/*! + * \brief Write back data to the desktop entry file. + * \return true if write success; otherwise returns false. + */ +bool DDesktopEntry::save() const +{ + Q_D(const DDesktopEntry); + + // write to file. + if (d->isWritable()) { + bool ok = false; + bool createFile = false; + QFileInfo fileInfo(d->filePath); + +#if !defined(QT_BOOTSTRAPPED) && QT_CONFIG(temporaryfile) + QSaveFile sf(d->filePath); + sf.setDirectWriteFallback(true); +#else + QFile sf(d->filePath); +#endif + if (!sf.open(QIODevice::WriteOnly)) { + d->setStatus(DDesktopEntry::AccessError); + return false; + } + + ok = d->write(sf); + +#if !defined(QT_BOOTSTRAPPED) && QT_CONFIG(temporaryfile) + if (ok) { + ok = sf.commit(); + } +#endif + + if (ok) { + // If we have created the file, apply the file perms + if (createFile) { + QFile::Permissions perms = fileInfo.permissions() | QFile::ReadOwner | QFile::WriteOwner + | QFile::ReadGroup | QFile::ReadOther; + QFile(d->filePath).setPermissions(perms); + } + return true; + } else { + d->setStatus(DDesktopEntry::AccessError); + return false; + } + } + + return false; +} + +/*! + * \brief Get data parse status + * + * Returns a status code indicating the first error that was met by DDesktopEntry, or QSettings::NoError if no error occurred. + * + * Be aware that DDesktopEntry delays performing some operations. + */ +DDesktopEntry::Status DDesktopEntry::status() const +{ + Q_D(const DDesktopEntry); + return d->status; +} + +/*! + * \brief Get a list of all section keys inside the given \a section. + * + * \return all available section keys. + */ +QStringList DDesktopEntry::keys(const QString §ion) const +{ + Q_D(const DDesktopEntry); + + if (section.isEmpty()) { + qWarning("DDesktopEntry::keys: Empty section name passed"); + return {}; + } + + return d->keys(section); +} + +/*! + * \brief Get a list of all section groups inside the desktop entry. + * + * If \a sorted is set to true, the returned result will keep the order as-is when reading the entry file. + * + * \return all available section groups. + */ +QStringList DDesktopEntry::allGroups(bool sorted) const +{ + Q_D(const DDesktopEntry); + + if (!sorted) { + return d->sectionsMap.keys(); + } else { + using StrIntPair = QPair; + + QStringList keys = d->sectionsMap.keys(); + QList result; + + for (const QString & key : keys) { + result << StrIntPair(key, d->sectionPos(key)); + } + + std::sort(result.begin(), result.end(), [](const StrIntPair& a, const StrIntPair& b) -> bool { + return a.second < b.second; + }); + + keys.clear(); + + for (const StrIntPair& pair : result) { + keys << pair.first; + } + + return keys; + } +} + +/*! + * \brief Check if the desktop entry file have the given \a section contains the given \a key + * + * \return true if the desktop entry contains the \a key in \a section; otherwise returns false. + */ +bool DDesktopEntry::contains(const QString &key, const QString §ion) const +{ + Q_D(const DDesktopEntry); + + if (key.isEmpty() || section.isEmpty()) { + qWarning("DDesktopEntry::contains: Empty key or section passed"); + return false; + } + + return d->contains(section, key); +} + +/*! + * \brief Returns the localized string value of the "Name" key under "Desktop Entry" section. + * + * It's equivalent to calling localizedValue("Name"). + * + * \sa localizedValue(), genericName(), ddeDisplayName() + */ +QString DDesktopEntry::name() const +{ + return localizedValue(QStringLiteral("Name")); +} + +/*! + * \brief Returns the localized string value of the "GenericName" key under "Desktop Entry" section. + * + * It's equivalent to calling localizedValue("GenericName"). It will NOT fallback to "Name" if "GenericName" + * is not existed. + * + * \sa localizedValue(), name(), ddeDisplayName() + */ +QString DDesktopEntry::genericName() const +{ + return localizedValue(QStringLiteral("GenericName")); +} + +/*! + * \brief Display name specially for DDE applications. + * + * This will check "X-Deepin-Vendor" and will return the localized string value of "GenericName" if + * "X-Deepin-Vendor" is "deepin", or it will return the localized string value of "Name". + * + * \sa localizedValue(), name(), genericName() + */ +QString DDesktopEntry::ddeDisplayName() const +{ + QString deepinVendor = stringValue("X-Deepin-Vendor"); + QString genericNameStr = genericName(); + if (deepinVendor == QStringLiteral("deepin") && !genericNameStr.isEmpty()) { + return genericNameStr; + } + + return name(); +} + +/*! + * \brief Returns the localized string value of the "Comment" key under "Desktop Entry" section. + * + * It's equivalent to calling localizedValue("Comment"). + * + * \sa localizedValue() + */ +QString DDesktopEntry::comment() const +{ + return localizedValue(QStringLiteral("Comment")); +} + +/*! + * \brief Returns the raw string value associated with the given \a key in \a section. + * + * If the entry contains no item with the key, the function returns a default-constructed value. + * + * \sa setRawValue(), stringValue(), localizedValue(), stringListValue() + */ +QString DDesktopEntry::rawValue(const QString &key, const QString §ion, const QString &defaultValue) const +{ + Q_D(const DDesktopEntry); + QString result = defaultValue; + if (key.isEmpty() || section.isEmpty()) { + qWarning("DDesktopEntry::value: Empty key or section passed"); + return result; + } + const_cast(d)->get(section, key, &result); // FIXME: better way than const_cast? + return result; +} + +/*! + * \brief Returns the unescaped string value associated with the given \a key in \a section. + * + * If the entry contains no item with the key, the function returns a default-constructed value. + * + * \sa setStringValue(), rawValue(), localizedValue(), stringListValue() + */ +QString DDesktopEntry::stringValue(const QString &key, const QString §ion, const QString &defaultValue) const +{ + QString rawResult = rawValue(key, section, defaultValue); + rawResult = DDesktopEntry::unescape(rawResult); + return rawResult; +} + +/*! + * \brief Returns the localized string value associated with the given \a key and \a localeKey in \a section. + * + * If the given \a localeKey can't be found, it will fallback to "C", if still cannot found, will fallback to the + * key without localeKey. + * + * If the entry contains no item with the key, the function returns a default-constructed value. + * + * \sa setLocalizedValue(), rawValue(), stringValue(), stringListValue() + */ +QString DDesktopEntry::localizedValue(const QString &key, const QString &localeKey, const QString §ion, const QString &defaultValue) const +{ + Q_D(const DDesktopEntry); + QString result = defaultValue; + QString actualLocaleKey = QLatin1String("C"); + if (key.isEmpty() || section.isEmpty()) { + qWarning("DDesktopEntry::localizedValue: Empty key or section passed"); + return result; + } + + QStringList possibleKeys; + + // 此处添加 bcp47Name() 是为了兼容 desktop 文件中的语言长短名解析。 + // 比如芬兰语,有 [fi] 和 [fi_FI] 两种情况,QLocale::name() 对应 fi_FI,QLocale::bcp47Name() 对应 fi。 + if (!localeKey.isEmpty()) { + if (localeKey == "empty") { + possibleKeys << key; + } else if (localeKey == "default") { + possibleKeys << QString("%1[%2]").arg(key, QLocale().name()); + possibleKeys << QString("%1[%2]").arg(key, QLocale().bcp47Name()); + } else if (localeKey == "system") { + possibleKeys << QString("%1[%2]").arg(key, QLocale::system().name()); + possibleKeys << QString("%1[%2]").arg(key, QLocale::system().bcp47Name()); + } else { + possibleKeys << QString("%1[%2]").arg(key, localeKey); + } + } + + if (!actualLocaleKey.isEmpty()) { + possibleKeys << QString("%1[%2]").arg(key, actualLocaleKey); + } + possibleKeys << QString("%1[%2]").arg(key, "C"); + possibleKeys << key; + + for (const QString &oneKey : possibleKeys) { + if (d->contains(section, oneKey)) { + const_cast(d)->get(section, oneKey, &result); + break; + } + } + + return result; +} + +/*! + * \brief Returns the localized string value associated with the given \a key and \a locale in \a section. + * + * If the given \a locale can't be found, it will fallback to "C", if still cannot found, will fallback to the + * key without a locale key. + * + * If the entry contains no item with the key, the function returns a default-constructed value. + * + * \sa setLocalizedValue(), rawValue(), stringValue(), stringListValue() + */ +QString DDesktopEntry::localizedValue(const QString &key, const QLocale &locale, const QString §ion, const QString &defaultValue) const +{ + return localizedValue(key, locale.name(), section, defaultValue); +} + +/*! + * \brief Returns a list of strings associated with the given \a key in the given \a section. + * + * If the entry contains no item with the key, the function returns a empty string list. + * + * \sa setRawValue(), rawValue(), stringValue(), localizedValue() + */ +QStringList DDesktopEntry::stringListValue(const QString &key, const QString §ion) const +{ + Q_D(const DDesktopEntry); + + QString value; + + const_cast(d)->get(section, key, &value); + + if (value.endsWith(';')) { + value = value.left(value.length() - 1); + } + QStringList&& strings = value.split(';'); + + QString combine; + QStringList result; + for (QString oneStr : strings) { + if (oneStr.endsWith('\\')) { + combine = combine + oneStr + ';'; + continue; + } + if (!combine.isEmpty()) { + oneStr = combine + oneStr; + combine.clear(); + } + result << DDesktopEntry::unescape(oneStr, true); + } + + return result; +} + +bool DDesktopEntry::setRawValue(const QString &value, const QString &key, const QString §ion) +{ + Q_D(DDesktopEntry); + if (key.isEmpty() || section.isEmpty()) { + qWarning("DDesktopEntry::setRawValue: Empty key or section passed"); + return false; + } + + bool result = d->set(section, key, value); + return result; +} + +bool DDesktopEntry::setStringValue(const QString &value, const QString &key, const QString §ion) +{ + QString escapedValue = value; + DDesktopEntry::escape(escapedValue); + bool result = setRawValue(escapedValue, key, section); + return result; +} + +bool DDesktopEntry::setLocalizedValue(const QString &value, const QString &localeKey, const QString &key, const QString §ion) +{ + Q_D(DDesktopEntry); + if (key.isEmpty() || section.isEmpty()) { + qWarning("DDesktopEntry::setLocalizedValue: Empty key or section passed"); + return false; + } + + QString actualKey = localeKey.isEmpty() ? key : QString("%1[%2]").arg(key, localeKey); + + bool result = d->set(section, actualKey, value); + return result; +} + +bool DDesktopEntry::removeEntry(const QString &key, const QString §ion) +{ + Q_D(DDesktopEntry); + if (key.isEmpty() || section.isEmpty()) { + qWarning("DDesktopEntry::setLocalizedValue: Empty key or section passed"); + return false; + } + bool result = d->remove(section, key); + return result; +} + +/************************************************ + The escape sequences \s, \n, \t, \r, and \\ are supported for values + of type string and localestring, meaning ASCII space, newline, tab, + carriage return, and backslash, respectively. + ************************************************/ +QString &DDesktopEntry::escape(QString &str) +{ + QHash repl; + repl.insert(QLatin1Char('\n'), QLatin1Char('n')); + repl.insert(QLatin1Char('\t'), QLatin1Char('t')); + repl.insert(QLatin1Char('\r'), QLatin1Char('r')); + + return doEscape(str, repl); +} + +/************************************************ + Quoting must be done by enclosing the argument between double quotes and + escaping the + double quote character, + backtick character ("`"), + dollar sign ("$") and + backslash character ("\") +by preceding it with an additional backslash character. +Implementations must undo quoting before expanding field codes and before +passing the argument to the executable program. + +Note that the general escape rule for values of type string states that the +backslash character can be escaped as ("\\") as well and that this escape +rule is applied before the quoting rule. As such, to unambiguously represent a +literal backslash character in a quoted argument in a desktop entry file +requires the use of four successive backslash characters ("\\\\"). +Likewise, a literal dollar sign in a quoted argument in a desktop entry file +is unambiguously represented with ("\\$"). + ************************************************/ +QString &DDesktopEntry::escapeExec(QString &str) +{ + QHash repl; + // The parseCombinedArgString() splits the string by the space symbols, + // we temporarily replace them on the special characters. + // Replacement will reverse after the splitting. + repl.insert(QLatin1Char('"'), QLatin1Char('"')); // double quote, + repl.insert(QLatin1Char('\''), QLatin1Char('\'')); // single quote ("'"), + repl.insert(QLatin1Char('\\'), QLatin1Char('\\')); // backslash character ("\"), + repl.insert(QLatin1Char('$'), QLatin1Char('$')); // dollar sign ("$"), + + return doEscape(str, repl); +} + +/* + * The escape sequences \s, \n, \t, \r, and \\ are supported for values of type string and localestring, + * meaning ASCII space, newline, tab, carriage return, and backslash, respectively. + * + * Some keys can have multiple values. In such a case, the value of the key is specified as a plural: for + * example, string(s). The multiple values should be separated by a semicolon and the value of the key may + * be optionally terminated by a semicolon. Trailing empty strings must always be terminated with a semicolon. + * Semicolons in these values need to be escaped using \;. + * + * https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#value-types +*/ +QString &DDesktopEntry::unescape(QString &str, bool unescapeSemicolons) +{ + QHash repl; + repl.insert(QLatin1Char('\\'), QLatin1Char('\\')); + repl.insert(QLatin1Char('s'), QLatin1Char(' ')); + repl.insert(QLatin1Char('n'), QLatin1Char('\n')); + repl.insert(QLatin1Char('t'), QLatin1Char('\t')); + repl.insert(QLatin1Char('r'), QLatin1Char('\r')); + + if (unescapeSemicolons) { + repl.insert(QLatin1Char(';'), QLatin1Char(';')); + } + + return doUnescape(str, repl); +} + +/************************************************ + Quoting must be done by enclosing the argument between double quotes and + escaping the + double quote character, + backtick character ("`"), + dollar sign ("$") and + backslash character ("\") +by preceding it with an additional backslash character. +Implementations must undo quoting before expanding field codes and before +passing the argument to the executable program. + +Reserved characters are + space (" "), + tab, + newline, + double quote, + single quote ("'"), + backslash character ("\"), + greater-than sign (">"), + less-than sign ("<"), + tilde ("~"), + vertical bar ("|"), + ampersand ("&"), + semicolon (";"), + dollar sign ("$"), + asterisk ("*"), + question mark ("?"), + hash mark ("#"), + parenthesis ("(") and (")") + backtick character ("`"). + +Note that the general escape rule for values of type string states that the +backslash character can be escaped as ("\\") as well and that this escape +rule is applied before the quoting rule. As such, to unambiguously represent a +literal backslash character in a quoted argument in a desktop entry file +requires the use of four successive backslash characters ("\\\\"). +Likewise, a literal dollar sign in a quoted argument in a desktop entry file +is unambiguously represented with ("\\$"). + ************************************************/ +QString &DDesktopEntry::unescapeExec(QString &str) +{ + unescape(str); + QHash repl; + // The parseCombinedArgString() splits the string by the space symbols, + // we temporarily replace them on the special characters. + // Replacement will reverse after the splitting. + repl.insert(QLatin1Char(' '), 01); // space + repl.insert(QLatin1Char('\t'), 02); // tab + repl.insert(QLatin1Char('\n'), 03); // newline, + + repl.insert(QLatin1Char('"'), QLatin1Char('"')); // double quote, + repl.insert(QLatin1Char('\''), QLatin1Char('\'')); // single quote ("'"), + repl.insert(QLatin1Char('\\'), QLatin1Char('\\')); // backslash character ("\"), + repl.insert(QLatin1Char('>'), QLatin1Char('>')); // greater-than sign (">"), + repl.insert(QLatin1Char('<'), QLatin1Char('<')); // less-than sign ("<"), + repl.insert(QLatin1Char('~'), QLatin1Char('~')); // tilde ("~"), + repl.insert(QLatin1Char('|'), QLatin1Char('|')); // vertical bar ("|"), + repl.insert(QLatin1Char('&'), QLatin1Char('&')); // ampersand ("&"), + repl.insert(QLatin1Char(';'), QLatin1Char(';')); // semicolon (";"), + repl.insert(QLatin1Char('$'), QLatin1Char('$')); // dollar sign ("$"), + repl.insert(QLatin1Char('*'), QLatin1Char('*')); // asterisk ("*"), + repl.insert(QLatin1Char('?'), QLatin1Char('?')); // question mark ("?"), + repl.insert(QLatin1Char('#'), QLatin1Char('#')); // hash mark ("#"), + repl.insert(QLatin1Char('('), QLatin1Char('(')); // parenthesis ("(") + repl.insert(QLatin1Char(')'), QLatin1Char(')')); // parenthesis (")") + repl.insert(QLatin1Char('`'), QLatin1Char('`')); // backtick character ("`"). + + return doUnescape(str, repl); +} + +bool DDesktopEntry::setStatus(const DDesktopEntry::Status &status) +{ + Q_D(DDesktopEntry); + d->setStatus(status); + + return true; +} + +DCORE_END_NAMESPACE diff --git a/src/ddesktopentry.h b/src/ddesktopentry.h new file mode 100644 index 0000000..3053ef9 --- /dev/null +++ b/src/ddesktopentry.h @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2019 Deepin Technology Co., Ltd. + * 2019 Gary Wang + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include + +#include +#include +#include + +DCORE_BEGIN_NAMESPACE + +class DDesktopEntryPrivate; +class LIBDTKCORESHARED_EXPORT DDesktopEntry +{ + Q_GADGET +public: + enum EntryType { + Unknown = 0, //!< Unknown desktop file type. Maybe is invalid. + Application, //!< The file describes application. + Link, //!< The file describes URL. + Directory, //!< The file describes directory settings. + ServiceType, //!< KDE specific type. mentioned in the spec, so listed here too. + Service, //!< KDE specific type. mentioned in the spec, so listed here too. + FSDevice //!< KDE specific type. mentioned in the spec, so listed here too. + }; + Q_ENUM(EntryType) + + enum ValueType { + Unparsed = 0, // Maybe useless, consider remove it? + String, + Strings, + Boolean, + Numeric, + NotExisted = 99 + }; + Q_ENUM(ValueType) + + enum Status { + NoError = 0, //!< No error occurred. + AccessError, //!< An access error occurred (e.g. trying to write to a read-only file). + FormatError //!< A format error occurred (e.g. loading a malformed desktop entry file). + }; + Q_ENUM(Status) + + explicit DDesktopEntry(const QString &filePath) noexcept; + ~DDesktopEntry(); + + bool save() const; + + Status status() const; + QStringList keys(const QString §ion = "Desktop Entry") const; + QStringList allGroups(bool sorted = false) const; + + bool contains(const QString &key, const QString §ion = "Desktop Entry") const; + + QString name() const; + QString genericName() const; + QString ddeDisplayName() const; + QString comment() const; + + QString rawValue(const QString &key, const QString §ion = "Desktop Entry", + const QString &defaultValue = QString()) const; + QString stringValue(const QString &key, const QString §ion = "Desktop Entry", + const QString &defaultValue = QString()) const; + QString localizedValue(const QString &key, const QString &localeKey = "default", + const QString §ion = "Desktop Entry", const QString& defaultValue = QString()) const; + QString localizedValue(const QString &key, const QLocale &locale, + const QString §ion = "Desktop Entry", const QString& defaultValue = QString()) const; + QStringList stringListValue(const QString &key, const QString §ion = "Desktop Entry") const; + + bool setRawValue(const QString &value, const QString &key, const QString& section = "Desktop Entry"); + bool setStringValue(const QString &value, const QString &key, const QString& section = "Desktop Entry"); + bool setLocalizedValue(const QString &value, const QString& localeKey, + const QString &key, const QString& section = "Desktop Entry"); + + bool removeEntry(const QString &key, const QString §ion = "Desktop Entry"); + + static QString &escape(QString &str); + static QString &escapeExec(QString &str); + static QString &unescape(QString &str, bool unescapeSemicolons = false); + static QString &unescapeExec(QString &str); + +protected: + bool setStatus(const Status &status); + +private: + QScopedPointer d_ptr; + + Q_DECLARE_PRIVATE(DDesktopEntry) +}; + +DCORE_END_NAMESPACE diff --git a/src/dsecurestring.cpp b/src/dsecurestring.cpp new file mode 100644 index 0000000..cc5965a --- /dev/null +++ b/src/dsecurestring.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2019 Deepin Technology Co., Ltd. + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ +#include "dsecurestring.h" +#include "dutil.h" + +DCORE_BEGIN_NAMESPACE + +DSecureString::DSecureString(const QString &other) noexcept + : QString(other) +{ +} + +DSecureString::~DSecureString() +{ + DUtil::SecureErase(*this); +} + +DCORE_END_NAMESPACE diff --git a/src/dsecurestring.h b/src/dsecurestring.h new file mode 100644 index 0000000..e5ac5a1 --- /dev/null +++ b/src/dsecurestring.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2019 Deepin Technology Co., Ltd. + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ +#pragma once + +#include +#include + +DCORE_BEGIN_NAMESPACE + +class LIBDTKCORESHARED_EXPORT DSecureString : public QString +{ +public: + using QString::QString; + DSecureString(const QString &other) noexcept; + ~DSecureString(); +}; + +DCORE_END_NAMESPACE diff --git a/src/dsysinfo.cpp b/src/dsysinfo.cpp new file mode 100644 index 0000000..44960ff --- /dev/null +++ b/src/dsysinfo.cpp @@ -0,0 +1,1080 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: zccrs + * + * Maintainer: zccrs + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ +#include "dsysinfo.h" +#include "ddesktopentry.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef Q_OS_LINUX +#include +#include +#include +#endif + +#ifndef OS_VERSION_TEST_FILE +#define OS_VERSION_FILE "/etc/os-version" +#else +#define OS_VERSION_FILE OS_VERSION_TEST_FILE +#endif + +DCORE_BEGIN_NAMESPACE + +class Q_DECL_HIDDEN DSysInfoPrivate +{ +public: + DSysInfoPrivate(); + +#ifdef Q_OS_LINUX + void ensureDeepinInfo(); + bool ensureOsVersion(); + void ensureDistributionInfo(); + bool splitA_BC_DMode(); +#endif + void ensureReleaseInfo(); + void ensureComputerInfo(); + QMap parseInfoFile(QFile &file); + +#ifdef Q_OS_LINUX + DSysInfo::DeepinType deepinType = DSysInfo::DeepinType(-1); + QMap deepinTypeMap; //Type Name with Language + QString deepinVersion; + QString deepinEdition; + QString deepinCopyright; + + QString majorVersion; + QString minorVersion; + struct MinVersion { + enum Type { + A_BC_D, // 专业版 + X_Y_Z, // 家庭版 + A_B_C // 社区版 + }; + MinVersion() + : A(0) + , B(0) + , BC(0) + , C(0) + , D(0) + , X(0) + , Y(0) + , Z(0) + { + } + + uint A, B, BC, C, D; // A-BC-D + uint X, Y, Z; + Type type; + }; + struct OSBuild { + OSBuild():A(0), B(0), C(0), D(0), xyz(100){ + } + uint A, B, C, D, E, xyz; // ABCDE.xyz + }; + + MinVersion minVersion; + OSBuild osBuild; +#endif + + QScopedPointer distributionInfo; + + DSysInfo::ProductType productType = DSysInfo::ProductType(-1); + QString prettyName; + QString productTypeString; + QString productVersion; + + QString computerName; + QString cpuModelName; + qint64 memoryAvailableSize = -1; + qint64 memoryInstalledSize = -1; + qint64 diskSize = 0; +}; + +DSysInfoPrivate::DSysInfoPrivate() +{ + +} + +#ifdef Q_OS_LINUX +void DSysInfoPrivate::ensureDistributionInfo() +{ + if (distributionInfo) + return; + + const QString distributionInfoFile(DSysInfo::distributionInfoPath()); + // Generic DDE distribution info + distributionInfo.reset(new DDesktopEntry(distributionInfoFile)); +} + +bool DSysInfoPrivate::splitA_BC_DMode() +{ + // A-BC-D + bool ok = false; + uint minv = minorVersion.toUInt(&ok); + if (ok) { + minVersion.D = minv % 10; + } else if (minorVersion.length() > 0) { + const QString D = minorVersion.right(1); + if (D.contains(QRegExp("[0-9A-Z]"))) { + // 0-9...A-Z + minVersion.D = 10 + static_cast(D.data()->toLatin1() - 'A'); + } else { + qWarning() << "invalid minorVersion"; + minVersion.D = 0; + } + } + uint minVer = minorVersion.left(3).toUInt(); + minVersion.BC = minVer % 100; + minVer /= 100; + minVersion.A = minVer % 10; + minVersion.type = MinVersion::A_BC_D; + return ok; +} + +void DSysInfoPrivate::ensureDeepinInfo() +{ + if (static_cast(deepinType) >= 0) + return; + + QFile file("/etc/deepin-version"); + + if (!file.open(QFile::ReadOnly)) { + deepinType = DSysInfo::UnknownDeepin; + + return; + } + + char buf[1024]; + int buf_length = 0; + + Q_FOREVER { + buf_length = file.readLine(buf, sizeof(buf)); + + if (buf_length < 0) + break; + + const QByteArray line(buf, buf_length); + const QByteArrayList &list = line.split('='); + + if (list.count() != 2) { + continue; + } + + const auto key_value = qMakePair(list.first().trimmed(), list.last().trimmed()); + + if (key_value.first == "Version") { + deepinVersion = key_value.second; + } else if (line.startsWith("Type")) { + if (key_value.first == "Type") { + deepinTypeMap[QString()] = QString::fromLatin1(key_value.second); + } else if (key_value.first.at(4) == '[' && key_value.first.at(key_value.first.size() - 1) == ']') { + const QByteArray &language = key_value.first.mid(5, key_value.first.size() - 6); + + if (!language.isEmpty()) { + deepinTypeMap[QString::fromLatin1(language)] = QString::fromUtf8(key_value.second); + } + } + } else if (key_value.first == "Edition") { + deepinEdition = QString::fromUtf8(key_value.second); + } else if (key_value.first == "Copyright") { + deepinCopyright = QString::fromUtf8(key_value.second); + } + + if (!deepinTypeMap.isEmpty() && !deepinEdition.isEmpty() && !deepinCopyright.isEmpty()) { + break; + } + } + + file.close(); + + const QString &deepin_type = deepinTypeMap[QString()]; + + if (deepin_type.isEmpty()) { + deepinType = DSysInfo::UnknownDeepin; + } else if (deepin_type == "Desktop") { + deepinType = DSysInfo::DeepinDesktop; + } else if (deepin_type == "Professional") { + deepinType = DSysInfo::DeepinProfessional; + } else if (deepin_type == "Server") { + deepinType = DSysInfo::DeepinServer; + } else if (deepin_type == "Personal") { + deepinType = DSysInfo::DeepinPersonal; + } else { + deepinType = DSysInfo::UnknownDeepin; + } +} + +bool DSysInfoPrivate::ensureOsVersion() +{ +#ifndef OS_VERSION_TEST_FILE // 测试时总是重新读取文件 + if (osBuild.A > 0) + return true; +#endif + + DDesktopEntry entry(OS_VERSION_FILE); + bool ok = false; + + // 先获取版本信息 + // ABCDE.xyz + QString osb = entry.stringValue("OsBuild", "Version"); + QStringList osbs = osb.split("."); + Q_ASSERT(osbs.size() == 2 && osbs.value(0).size() == 5); + uint left = osbs.value(0).trimmed().toUInt(&ok); + Q_ASSERT(ok); + if (ok) { + osBuild.E = left % 10; + left /= 10; + osBuild.D = left % 10; + left /= 10; + osBuild.C = left % 10; // default C is 0 + left /= 10; + osBuild.B = left % 10; + left /= 10; + osBuild.A = left % 10; + } + + // xyz + osBuild.xyz = osbs.value(1).trimmed().toUInt(&ok); + + majorVersion = entry.stringValue("MajorVersion", "Version"); + minorVersion = entry.stringValue("MinorVersion", "Version"); + + switch (osBuild.D) { + case 7: { + // 家庭版使用“完整版本号编码-X.Y.Z”的形式 + const QStringList &versionList = minorVersion.split('.'); + if (versionList.isEmpty()) { + // 如果读取失败直接返回为空 + qWarning() << "no minorVersion"; + return false; + } else if (versionList.length() == 2) { + // Z为0 + minVersion.X = versionList.first().toUInt(); + minVersion.Y = versionList.last().toUInt(); + minVersion.Z = 0; + } else if (versionList.length() == 3) { + // X.Y.Z都存在 + minVersion.X = versionList.at(0).toUInt(); + minVersion.Y = versionList.at(1).toUInt(); + minVersion.Z = versionList.at(2).toUInt(); + } + minVersion.type = MinVersion::X_Y_Z; + } break; + + case 3: { + // 社区版使用“完整版本号编码-A.B.C”的形式 + bool a_bc_dMode = false; + const QStringList &versionList = minorVersion.split('.'); + if (versionList.isEmpty()) { + // 如果读取失败直接返回为空 + qWarning() << "no minorVersion"; + return false; + } else if (versionList.length() == 1) { + QString modeVersion = versionList.first(); + if (modeVersion.length() == 2) { + //A.B.C模式且B C 为0 + minVersion.A = modeVersion.toUInt(); + minVersion.B = 0; + minVersion.C = 0; + } else { + // A_BC_D模式 + splitA_BC_DMode(); + a_bc_dMode = true; + } + } else if (versionList.length() == 2) { + // C为0 + minVersion.A = versionList.first().toUInt(); + minVersion.B = versionList.last().toUInt(); + minVersion.C = 0; + } else if (versionList.length() == 3) { + // A.B.C都存在 + minVersion.A = versionList.at(0).toUInt(); + minVersion.B = versionList.at(1).toUInt(); + minVersion.C = versionList.at(2).toUInt(); + } + + if (!a_bc_dMode) + minVersion.type = MinVersion::A_B_C; + } break; + default: { + // A-BC-D + ok = splitA_BC_DMode(); + } break; + } + return ok; +} + +static QString unquote(const QByteArray &value) +{ + if (value.at(0) == '"' || value.at(0) == '\'') { + return QString::fromLatin1(value.mid(1, value.size() - 2)); + } + + return QString::fromLatin1(value); +} + +static bool readEtcFile(DSysInfoPrivate *info, const char *filename, + const QByteArray &idKey, const QByteArray &versionKey, const QByteArray &prettyNameKey) +{ + + QFile file(QString::fromLatin1(filename)); + + if (!file.open(QIODevice::ReadOnly)) { + return false; + } + + quint8 valid_data_count = 0; + char buf[1024]; + + while (valid_data_count < 3) { + int buf_length = file.readLine(buf, sizeof(buf)); + + if (buf_length < 0) + break; + + const QByteArray line(buf, buf_length - 1); + + if (info->productTypeString.isEmpty() && line.startsWith(idKey)) { + const QByteArray value(line.constData() + idKey.size()); + info->productTypeString = unquote(value); + ++valid_data_count; + continue; + } + + if (info->prettyName.isEmpty() && line.startsWith(prettyNameKey)) { + const QByteArray value(line.constData() + prettyNameKey.size()); + info->prettyName = unquote(value); + ++valid_data_count; + continue; + } + + if (info->productVersion.isEmpty() && line.startsWith(versionKey)) { + const QByteArray value(line.constData() + versionKey.size()); + info->productVersion = unquote(value); + ++valid_data_count; + continue; + } + } + + file.close(); + + return valid_data_count != 0; +} + +static bool readOsRelease(DSysInfoPrivate *info) +{ + if (!readEtcFile(info, "/etc/os-release", "ID=", "VERSION_ID=", "PRETTY_NAME=")) + return readEtcFile(info, "/usr/lib/os-release", "ID=", "VERSION_ID=", "PRETTY_NAME="); + + return true; +} + +static bool readLsbRelease(DSysInfoPrivate *info) +{ + return readEtcFile(info, "/etc/lsb-release", "DISTRIB_ID=", "DISTRIB_RELEASE=", "DISTRIB_DESCRIPTION="); +} +#endif + +void DSysInfoPrivate::ensureReleaseInfo() +{ + if (productType >= 0) { + return; + } + +#ifdef Q_OS_LINUX + readOsRelease(this); + readLsbRelease(this); + + if (productTypeString.isEmpty()) { + productType = DSysInfo::UnknownType; + } else { + switch (productTypeString.at(0).unicode()) { + case 'd': + case 'D': + if (productTypeString.compare("deepin", Qt::CaseInsensitive) == 0) { + productType = DSysInfo::Deepin; + } else if (productTypeString.compare("debian", Qt::CaseInsensitive) == 0) { + productType = DSysInfo::Debian; + } + break; + case 'a': + case 'A': + if (productTypeString.compare("arch", Qt::CaseInsensitive) == 0) + productType = DSysInfo::ArchLinux; + break; + case 'c': + case 'C': + if (productTypeString.compare("centos", Qt::CaseInsensitive) == 0) + productType = DSysInfo::CentOS; + break; + case 'f': + case 'F': + if (productTypeString.compare("fedora", Qt::CaseInsensitive) == 0) + productType = DSysInfo::Fedora; + break; + case 'l': + case 'L': + if (productTypeString.compare("linuxmint", Qt::CaseInsensitive) == 0) + productType = DSysInfo::LinuxMint; + break; + case 'm': + case 'M': + if (productTypeString.compare("manjaro", Qt::CaseInsensitive) == 0) + productType = DSysInfo::Manjaro; + break; + case 'o': + case 'O': + if (productTypeString.compare("opensuse", Qt::CaseInsensitive) == 0) + productType = DSysInfo::openSUSE; + break; + case 's': + case 'S': + if (productTypeString.compare("sailfishos", Qt::CaseInsensitive) == 0) + productType = DSysInfo::SailfishOS; + break; + case 'u': + case 'U': + if (productTypeString.compare("ubuntu", Qt::CaseInsensitive) == 0) { + productType = DSysInfo::Ubuntu; + } else if (productTypeString.compare("uos", Qt::CaseInsensitive) == 0 || productTypeString.compare("UnionTech OS", Qt::CaseInsensitive) == 0) { + productType = DSysInfo::Uos; + } + break; + default: + productType = DSysInfo::UnknownType; + break; + } + } +#endif +} + +void DSysInfoPrivate::ensureComputerInfo() +{ + if (memoryAvailableSize >= 0) + return; + +#ifdef Q_OS_LINUX + struct utsname u; + if (uname(&u) == 0) + computerName = QString::fromLatin1(u.nodename); + + QFile file("/proc/cpuinfo"); + + if (file.open(QFile::ReadOnly)) { + QMap map = parseInfoFile(file); + if (map.contains("Processor")) { + // arm-cpuinfo hw_kirin-cpuinfo + cpuModelName = map.value("Processor"); + } else if (map.contains("model name")) { + // cpuinfo + cpuModelName = map.value("model name"); + } else if (map.contains("cpu model")) { + // loonson3-cpuinfo sw-cpuinfo + cpuModelName = map.value("cpu model"); + } + + file.close(); + } + + memoryAvailableSize = get_phys_pages() * sysconf(_SC_PAGESIZE); + + // Getting Memory Installed Size + // TODO: way to not dept on lshw? + if (!QStandardPaths::findExecutable("lshw").isEmpty()) { + QProcess lshw; + + lshw.start("lshw", {"-c", "memory", "-json", "-sanitize"}, QIODevice::ReadOnly); + + if (!lshw.waitForFinished()) { + return; + } + + const QByteArray &lshwInfoJson = lshw.readAllStandardOutput(); + QJsonArray lshwResultArray = QJsonDocument::fromJson(lshwInfoJson).array(); + if (!lshwResultArray.isEmpty()) { + QJsonValue memoryHwInfo = lshwResultArray.first(); + QString id = memoryHwInfo.toObject().value("id").toString(); + Q_ASSERT(id == "memory"); + memoryInstalledSize = memoryHwInfo.toObject().value("size").toDouble(); // TODO: check "units" is "bytes" ? + } + } + + // Getting Disk Size + const QString &deviceName = QStorageInfo::root().device(); + QProcess lsblk; + + lsblk.start("lsblk", {"-Jlpb", "-oNAME,KNAME,PKNAME,SIZE"}, QIODevice::ReadOnly); + + if (!lsblk.waitForFinished()) { + return; + } + + const QByteArray &diskStatusJson = lsblk.readAllStandardOutput(); + QJsonDocument diskStatus = QJsonDocument::fromJson(diskStatusJson); + QJsonValue diskStatusJsonValue = diskStatus.object().value("blockdevices"); + QMap> deviceParentAndSizeMap; + + if (!diskStatusJsonValue.isUndefined()) { + QJsonArray diskStatusArray = diskStatusJsonValue.toArray(); + QString keyName; + + for (const QJsonValue oneValue : diskStatusArray) { + 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[kname] = QPair(pkname, size); + } + + while (!deviceParentAndSizeMap[keyName].first.isNull()) { + keyName = deviceParentAndSizeMap[keyName].first; + } + + diskSize = deviceParentAndSizeMap[keyName].second; + } +#endif +} + +QMap DSysInfoPrivate::parseInfoFile(QFile &file) +{ + char buf[1024]; + qint64 lineLength = 0; + QMap map; + do { + lineLength = file.readLine(buf, sizeof(buf)); + QString s(buf); + if (s.contains(':')) { + QStringList list = s.split(':'); + if (list.size() == 2) { + map.insert(list.first().trimmed(), list.back().trimmed()); + } + } + } while (lineLength >= 0); + return map; +} + +Q_GLOBAL_STATIC(DSysInfoPrivate, siGlobal) + +QString DSysInfo::operatingSystemName() +{ + siGlobal->ensureReleaseInfo(); + + return siGlobal->prettyName; +} + +#ifdef Q_OS_LINUX +/*! + * \brief Check current distro is Deepin or not. + * \note Uos will also return true. + */ +bool DSysInfo::isDeepin() +{ + siGlobal->ensureReleaseInfo(); + + return productType() == Deepin || productType() == Uos; +} + +bool DSysInfo::isDDE() +{ + siGlobal->ensureDeepinInfo(); + + return siGlobal->deepinType != UnknownDeepin; +} + +DSysInfo::DeepinType DSysInfo::deepinType() +{ + siGlobal->ensureDeepinInfo(); + + return siGlobal->deepinType; +} + +QString DSysInfo::deepinTypeDisplayName(const QLocale &locale) +{ + siGlobal->ensureDeepinInfo(); + + return siGlobal->deepinTypeMap.value(locale.name(), siGlobal->deepinTypeMap.value(QString())); +} + +QString DSysInfo::deepinVersion() +{ + siGlobal->ensureDeepinInfo(); + + return siGlobal->deepinVersion; +} + +QString DSysInfo::deepinEdition() +{ + siGlobal->ensureDeepinInfo(); + + return siGlobal->deepinEdition; +} + +QString DSysInfo::deepinCopyright() +{ + siGlobal->ensureDeepinInfo(); + + return siGlobal->deepinCopyright; +} + +/*! + * \~chinese \brief DSysInfo::osType 系统类型 + * \~chinese \row 显示系统类型【1:桌面】【2:服务器】【3:专用设备】 + * \~chinese \note 根据 osBuild.B 判断 + */ +DSysInfo::UosType DSysInfo::uosType() +{ + siGlobal->ensureOsVersion(); + + UosType ost = UosTypeUnknown; + if ((siGlobal->osBuild.B > UosTypeUnknown && siGlobal->osBuild.B < UosTypeCount)) { + ost = static_cast(siGlobal->osBuild.B); + } + + return ost; +} + +/*! + * \~chinese \brief DSysInfo::osEditionType 版本类型 + * \~chinese \row 显示版本类型 专业版/个人版/社区版... + * \~chinese \note 根据 osBuild.B && osBuild.D + */ +DSysInfo::UosEdition DSysInfo::uosEditionType() +{ + siGlobal->ensureOsVersion(); + UosEdition ospt = UosEditionUnknown; + if (siGlobal->osBuild.B == UosDesktop) { + switch (siGlobal->osBuild.D) { + case 1: + return UosProfessional; + case 2: + case 7: + // 新版本家庭版(7)与旧版本个人版(2)同为Home 不修改旧有逻辑的情况下新增7保证对旧版的适配 + return UosHome; + case 3: + return UosCommunity; + case 4: + return UosMilitary; + case 5: + return UosDeviceEdition; + case 6: + return UosEducation; + default: + break; + } + } else if (siGlobal->osBuild.B == UosServer) { + switch (siGlobal->osBuild.D) { + case 1: + return UosEnterprise; + case 2: + return UosEnterpriseC; + case 3: + return UosEuler; + case 4: + return UosMilitaryS; + case 5: + return UosDeviceEdition; + default: + break; + } + } else if (siGlobal->osBuild.B == UosDevice){ + ospt = UosEnterprise; // os-version 1.4 if B==Device then et=Enterprise + } + + return ospt; +} + +/*! + * \~chinese \brief DSysInfo::osArch 架构信息(使用一个字节的二进制位,从低位到高位) + * \~chinese \row 【0x8 sw64】【0x4 mips64】【0x2 arm64】【0x1 amd64】 + */ +DSysInfo::UosArch DSysInfo::uosArch() +{ + siGlobal->ensureOsVersion(); + + return static_cast(siGlobal->osBuild.E); +} + +static QString getUosVersionValue(const QString &key, const QLocale &locale) +{ + DDesktopEntry entry(OS_VERSION_FILE); + QString localKey = QString("%1[%2]").arg(key, locale.name()); + + return entry.stringValue(localKey, "Version", entry.stringValue(key, "Version")); +} + +/*! + * \~chinese \brief DSysInfo::osProductTypeName 版本名称 + * \~chinese \row ProductType[xx] 项对应的值, 如果找不到对应语言的默认使用 ProductType的值(Desktop/Server/Device) + * \~chinese \param locale 当前系统语言 + */ +QString DSysInfo::uosProductTypeName(const QLocale &locale) +{ + return getUosVersionValue("ProductType", locale); +} + +/*! + * \~chinese \brief DSysInfo::osSystemName 版本名称 + * \~chinese \row SystemName[xx] 项对应的值, 如果找不到对应语言的默认使用 SystemName 的值 Uniontech OS + * \~chinese \param locale 当前系统语言 + */ +QString DSysInfo::uosSystemName(const QLocale &locale) +{ + return getUosVersionValue("SystemName", locale); +} + +/*! + * \~chinese \brief DSysInfo::osEditionName 版本名称 + * \~chinese \row EditionName[xx] 项对应的值, 如果找不到对应语言的默认使用 EditionName 的值(Professional/Home/Community...) + * \~chinese \param locale 当前系统语言 + */ +QString DSysInfo::uosEditionName(const QLocale &locale) +{ + return getUosVersionValue("EditionName", locale); +} + +/*! + * \~chinese \brief DSysInfo::spVersion 阶段版本名称 + * \~chinese \row 小版本号 A-BC-D 中 BC、 A.B.C 中的 B + * \~chinese \row 返回 SP1-SPxx, 如果正式版返回空 + * \~chinese \row X.Y.Z模式下暂不支持返回此版本号 + * \~chinese \note minVersion.BC == 00:正式版本 minVersion.BC | minVersion.B == 01-99:SP1….SP99 + */ +QString DSysInfo::spVersion() +{ + siGlobal->ensureOsVersion(); + switch (siGlobal->minVersion.type) { + case DSysInfoPrivate::MinVersion::A_BC_D: { + if (siGlobal->minVersion.BC > 0) { + return QString("SP%1").arg(siGlobal->minVersion.BC); + } else { + return QString(); // 00 正式版 + } + } + + case DSysInfoPrivate::MinVersion::A_B_C: { + if (siGlobal->minVersion.B > 0) { + return QStringLiteral("SP%1").arg(siGlobal->minVersion.B); + } else { + return {}; + } + } + + case DSysInfoPrivate::MinVersion::X_Y_Z: + qWarning() << "Getting the SP version in this mode is not supported."; + return {}; + } +} + +/*! + * \~chinese \brief DSysInfo::udpateVersion 更新版本名称 + * \~chinese \row 小版本号 A-BC-D 中 D、A.B.C 模式中的 C + * \~chinese \row 返回 update1… update9, 如果正式版返回空 + * \~chinese \row X.Y.Z模式下暂不支持返回此版本号 + * \~chinese \note minVersion.D == 0:正式版本 minVersion.D | minVersion.C == 1-9:update1… update9,updateA...updateZ + */ +QString DSysInfo::udpateVersion() +{ + siGlobal->ensureOsVersion(); + switch (siGlobal->minVersion.type) { + case DSysInfoPrivate::MinVersion::A_BC_D: { + if (siGlobal->minVersion.D > 0) { + uint uv = siGlobal->minVersion.D; + if (uv < 10) { + return QString("update%1").arg(uv); + } else if (uv < 36) { + return QString("update").append(QChar(uv - 10 + 'A')); + } else { + qWarning() << "invalid update versoin"; + break; + } + } else { + break; // 0 正式版 + } + } + + case DSysInfoPrivate::MinVersion::A_B_C: { + if (siGlobal->minVersion.C > 0) { + return QStringLiteral("update%1").arg(siGlobal->minVersion.C); + } else { + break; + } + } + + case DSysInfoPrivate::MinVersion::X_Y_Z: + qWarning() << "Getting the update version in this mode is not supported."; + break; + } + + return {}; +} + +/*! + * \~chinese \brief DSysInfo::majorVersion 主版本号 + * \~chinese \row 主版本号 【20】【23】【25】【26】【29】【30】 + * \~chinese \note 返回 MajorVersion 的值 + */ +QString DSysInfo::majorVersion() +{ + siGlobal->ensureOsVersion(); + return siGlobal->majorVersion; +} + +/*! + * \~chinese \brief DSysInfo::minorVersion 小版本号 + * \~chinese \row 【ABCD】 ·[0-9]{4} + * \~chinese \row【A.B.C】 或者【X.Y.Z】 + * \~chinese \note 返回 MinorVersion 的值 + */ +QString DSysInfo::minorVersion() +{ + siGlobal->ensureOsVersion(); + return siGlobal->minorVersion; +} + +/*! + * \~chinese \brief DSysInfo::buildVersion 小版本号 + * \~chinese \row 系统镜像批次号,按时间顺序(不可回退)从100-999递增 + * \~chinese \note 返回 osBuild.xyz 的值 + */ +QString DSysInfo::buildVersion() +{ + siGlobal->ensureOsVersion(); + return QString::number(siGlobal->osBuild.xyz); +} +#endif + +QString DSysInfo::deepinDistributionInfoPath() +{ + return distributionInfoPath(); +} + +QString DSysInfo::distributionInfoPath() +{ +#ifdef Q_OS_LINUX + return "/usr/share/deepin/distribution.info"; +#else + return QDir(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)).filePath("deepin-distribution.info"); +#endif // Q_OS_LINUX +} + +QString DSysInfo::distributionInfoSectionName(DSysInfo::OrgType type) +{ + switch (type) { + case Distribution: + return "Distribution"; + case Distributor: + return "Distributor"; + case Manufacturer: + return "Manufacturer"; + } + + return QString(); +} + +/*! + * \return the organization name. + * + * use \l type as Distribution to get the name of current deepin distribution itself. + * + * \sa deepinDistributionInfoPath() + */ +QString DSysInfo::distributionOrgName(DSysInfo::OrgType type, const QLocale &locale) +{ +#ifdef Q_OS_LINUX + siGlobal->ensureDistributionInfo(); +#endif + + QString fallback = type == Distribution ? QStringLiteral("Deepin") : QString(); + + return siGlobal->distributionInfo->localizedValue("Name", locale, distributionInfoSectionName(type), fallback); +} + +QString DSysInfo::deepinDistributorName() +{ + return distributionOrgName(Distributor); +} + +/*! + * \return the organization website name and url. + * + * use \l type as Distribution to get the name of current deepin distribution itself. + * + * \sa deepinDistributionInfoPath() + */ +QPair DSysInfo::distributionOrgWebsite(DSysInfo::OrgType type) +{ +#ifdef Q_OS_LINUX + siGlobal->ensureDistributionInfo(); +#endif + + QString fallbackSiteName = type == Distribution ? QStringLiteral("www.deepin.org") : QString(); + QString fallbackSiteUrl = type == Distribution ? QStringLiteral("https://www.deepin.org") : QString(); + + return { + siGlobal->distributionInfo->stringValue("WebsiteName", distributionInfoSectionName(type), fallbackSiteName), + siGlobal->distributionInfo->stringValue("Website", distributionInfoSectionName(type), fallbackSiteUrl), + }; +} + +QPair DSysInfo::deepinDistributorWebsite() +{ + return distributionOrgWebsite(Distributor); +} + +/*! + * \return the obtained organization logo path, or the given \l fallback one if there are no such logo. + * + * use \l type as Distribution to get the logo of current deepin distribution itself. + * + * \sa deepinDistributionInfoPath() + */ +QString DSysInfo::distributionOrgLogo(DSysInfo::OrgType orgType, DSysInfo::LogoType type, const QString &fallback) +{ + DDesktopEntry distributionInfo(distributionInfoPath()); + QString orgSectionName = distributionInfoSectionName(orgType); + + switch (type) { + case Normal: + return distributionInfo.stringValue("Logo", orgSectionName, fallback); + case Light: + return distributionInfo.stringValue("LogoLight", orgSectionName, fallback); + case Symbolic: + return distributionInfo.stringValue("LogoSymbolic", orgSectionName, fallback); + case Transparent: + return distributionInfo.stringValue("LogoTransparent", orgSectionName, fallback); + } + + return QString(); +} + +QString DSysInfo::deepinDistributorLogo(DSysInfo::LogoType type, const QString &fallback) +{ + return distributionOrgLogo(Distributor, type, fallback); +} + +DSysInfo::ProductType DSysInfo::productType() +{ + siGlobal->ensureReleaseInfo(); + + return siGlobal->productType; +} + +QString DSysInfo::productTypeString() +{ + siGlobal->ensureReleaseInfo(); + + return siGlobal->productTypeString; +} + +QString DSysInfo::productVersion() +{ + siGlobal->ensureReleaseInfo(); + + return siGlobal->productVersion; +} + +/*! + * \brief Check if current edition is a community edition + * + * Developer can use this way to check if we need enable or disable features + * for community or enterprise edition. + * + * Current rule: + * - Professional, Server, Personal edition (DeepinType) will be treat as Enterprise edition. + * - Uos (ProductType) will be treat as Enterprise edition. + * + * \return true if it's on a community edition distro/installation + */ +bool DSysInfo::isCommunityEdition() +{ +#ifdef Q_OS_LINUX + DeepinType type = deepinType(); + QList enterpriseTypes { + DeepinProfessional, DeepinServer, DeepinPersonal + }; + + if (enterpriseTypes.contains(type)) { + return false; + } + + if (productType() == Uos) { + return false; + } +#endif // Q_OS_LINUX + + return true; +} + +QString DSysInfo::computerName() +{ + siGlobal->ensureComputerInfo(); + + return siGlobal->computerName; +} + +QString DSysInfo::cpuModelName() +{ + siGlobal->ensureComputerInfo(); + + return siGlobal->cpuModelName; +} + +/*! + * \return the installed memory size + */ +qint64 DSysInfo::memoryInstalledSize() +{ + siGlobal->ensureComputerInfo(); + + return siGlobal->memoryInstalledSize; +} + +/*! + * \return the total available to use memory size + */ +qint64 DSysInfo::memoryTotalSize() +{ + siGlobal->ensureComputerInfo(); + + return siGlobal->memoryAvailableSize; +} + +qint64 DSysInfo::systemDiskSize() +{ + siGlobal->ensureComputerInfo(); + + return siGlobal->diskSize; +} + +DCORE_END_NAMESPACE diff --git a/src/dsysinfo.h b/src/dsysinfo.h new file mode 100644 index 0000000..136652e --- /dev/null +++ b/src/dsysinfo.h @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: zccrs + * + * Maintainer: zccrs + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ +#ifndef DSYSINFO_H +#define DSYSINFO_H + +#include + +#include + +DCORE_BEGIN_NAMESPACE + +class DSysInfoPrivate; +class LIBDTKCORESHARED_EXPORT DSysInfo +{ +public: + enum ProductType { + UnknownType = 0, + Deepin, + ArchLinux, + CentOS, + Debian, + Fedora, + LinuxMint, + Manjaro, + openSUSE, + SailfishOS, + Ubuntu, + Uos + }; + + enum DeepinType { + UnknownDeepin = 0, + DeepinDesktop, + DeepinProfessional, + DeepinServer, + DeepinPersonal + }; + + enum LogoType { + Normal = 0, + Light, + Symbolic, + Transparent + }; + + enum OrgType { + Distribution, //!< distribution itself + Distributor, //!< distributer of the current distribution + Manufacturer //!< manufacturer of the current distribution or device + }; + + enum UosType { + UosTypeUnknown, + UosDesktop, + UosServer, + UosDevice, + + UosTypeCount // must at last + }; + + enum UosEdition { + UosEditionUnknown, + UosProfessional, + UosHome, + UosCommunity, + UosMilitary, + UosEnterprise, + UosEnterpriseC, + UosEuler, + UosMilitaryS, // for Server + UosDeviceEdition, + UosEducation, + + UosEditionCount // must at last + }; + + // 注意:此处架构是从OsBuild获取的系统版本的Arch信息,并不是指硬件的Arch信息 + enum UosArch { + UosArchUnknown, + UosAMD64 = 1 << 0, + UosARM64 = 1 << 1, + UosMIPS64 = 1 << 2, + UosSW64 = 1 << 3 + }; + +#ifdef Q_OS_LINUX + static bool isDeepin(); + static bool isDDE(); + static DeepinType deepinType(); + static QString deepinTypeDisplayName(const QLocale &locale = QLocale::system()); + static QString deepinVersion(); + static QString deepinEdition(); + static QString deepinCopyright(); + + // uos version interface + static UosType uosType(); + static UosEdition uosEditionType(); + static UosArch uosArch(); + static QString uosProductTypeName(const QLocale &locale = QLocale::system()); + static QString uosSystemName(const QLocale &locale = QLocale::system()); + static QString uosEditionName(const QLocale &locale = QLocale::system()); + + static QString spVersion(); // SP1...SP99 + static QString udpateVersion(); // update1...update9 + static QString majorVersion(); + static QString minorVersion(); + static QString buildVersion(); // xyzs +#endif + + Q_DECL_DEPRECATED_X("Use distributionInfoPath() instead") static QString deepinDistributionInfoPath(); + static QString distributionInfoPath(); + static QString distributionInfoSectionName(OrgType type); + + static QString distributionOrgName(OrgType type = Distribution, const QLocale &locale = QLocale::system()); + Q_DECL_DEPRECATED_X("Use deepinDistributionOrgName() instead") static QString deepinDistributorName(); + static QPair distributionOrgWebsite(OrgType type = Distribution); + Q_DECL_DEPRECATED_X("Use deepinDistributionOrgWebsite() instead") static QPair deepinDistributorWebsite(); + static QString distributionOrgLogo(OrgType orgType = Distribution, LogoType type = Normal, const QString & fallback = QString()); + Q_DECL_DEPRECATED_X("Use deepinDistributionOrgLogo() instead") static QString deepinDistributorLogo(LogoType type = Normal, const QString & fallback = QString()); + + static QString operatingSystemName(); + static ProductType productType(); + static QString productTypeString(); + static QString productVersion(); + static bool isCommunityEdition(); + + static QString computerName(); + static QString cpuModelName(); + static qint64 memoryInstalledSize(); + static qint64 memoryTotalSize(); + static qint64 systemDiskSize(); +}; + +DCORE_END_NAMESPACE + +#endif // DSYSINFO_H diff --git a/src/dtkcore_global.cpp b/src/dtkcore_global.cpp new file mode 100644 index 0000000..7512b5c --- /dev/null +++ b/src/dtkcore_global.cpp @@ -0,0 +1,54 @@ +#include "dtkcore_global.h" +#include +#include + +#if (!defined DTK_VERSION) || (!defined DTK_VERSION_STR) +#error "DTK_VERSION or DTK_VERSION_STR not defined!" +#endif + +void doubleLoadCheck() +{ + QFile f("/proc/self/maps"); + if (!f.open(QIODevice::ReadOnly)) + qFatal("%s", f.errorString().toLocal8Bit().data()); + + const QByteArray &data = f.readAll(); + QTextStream ts(data); + QString modulePath; + while (Q_UNLIKELY(!ts.atEnd())) { + const QString line = ts.readLine(); + const QStringList &maps = line.split(' ', QString::SplitBehavior::SkipEmptyParts); + if (Q_UNLIKELY(maps.size() < 6)) + continue; + + QFileInfo info(maps.value(5)); + const QString &infoAbPath = info.absoluteFilePath(); + if (modulePath == infoAbPath || !info.fileName().contains("dtkcore")) + continue; + + if (modulePath.isEmpty()) { + modulePath = infoAbPath; + } else { + // modulePath != infoAbPath + QByteArray msg; + msg += modulePath + " and " + info.absoluteFilePath() + " both loaded"; + qFatal("%s", msg.data()); + } + } +} + +// 在库被加载时就执行此函数 +__attribute__((constructor)) void init() +{ + doubleLoadCheck(); +} + +int dtkVersion() +{ + return DTK_VERSION; +} + +const char *dtkVersionString() +{ + return DTK_VERSION_STR; +} diff --git a/src/dtkcore_global.h b/src/dtkcore_global.h new file mode 100644 index 0000000..7a6ce6e --- /dev/null +++ b/src/dtkcore_global.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2017 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include + +#define DTK_NAMESPACE Dtk + +#if !defined(DTK_NAMESPACE) +# define DTK_BEGIN_NAMESPACE +# define DTK_END_NAMESPACE +# define DTK_USE_NAMESPACE +#else +# define DTK_BEGIN_NAMESPACE namespace DTK_NAMESPACE { +# define DTK_END_NAMESPACE } +# define DTK_USE_NAMESPACE using namespace DTK_NAMESPACE; +#endif + +#define DCORE_NAMESPACE Core +#define DTK_CORE_NAMESPACE DTK_NAMESPACE::DCORE_NAMESPACE + +#if !defined(DCORE_NAMESPACE) +# define DCORE_BEGIN_NAMESPACE +# define DCORE_END_NAMESPACE +# define DCORE_USE_NAMESPACE +#else +# define DCORE_BEGIN_NAMESPACE namespace DTK_NAMESPACE { namespace DCORE_NAMESPACE { +# define DCORE_END_NAMESPACE }} +# define DCORE_USE_NAMESPACE using namespace DTK_CORE_NAMESPACE; +#endif + + +#if defined(DTK_STATIC_LIB) +# define LIBDTKCORESHARED_EXPORT +#else +#if defined(LIBDTKCORE_LIBRARY) +# define LIBDTKCORESHARED_EXPORT Q_DECL_EXPORT +#else +# define LIBDTKCORESHARED_EXPORT Q_DECL_IMPORT +#endif +#endif + +#ifdef D_DEPRECATED_CHECK +#define D_DECL_DEPRECATED_X(text) Q_DECL_HIDDEN +#define D_DECL_DEPRECATED Q_DECL_HIDDEN +#else +#define D_DECL_DEPRECATED Q_DECL_DEPRECATED +#define D_DECL_DEPRECATED_X Q_DECL_DEPRECATED_X +#endif + +#define DTK_VERSION_CHECK(major, minor, patch, build) ((major<<24)|(minor<<16)|(patch<<8)|build) +#define DTK_VERSION DTK_VERSION_CHECK(DTK_VERSION_MAJOR, DTK_VERSION_MINOR, DTK_VERSION_PATCH, DTK_VERSION_BUILD) + +extern "C" { +int LIBDTKCORESHARED_EXPORT dtkVersion(); +const LIBDTKCORESHARED_EXPORT char *dtkVersionString(); +} diff --git a/src/filesystem/DBaseFileWatcher b/src/filesystem/DBaseFileWatcher new file mode 100644 index 0000000..1348031 --- /dev/null +++ b/src/filesystem/DBaseFileWatcher @@ -0,0 +1 @@ +#include "dbasefilewatcher.h" diff --git a/src/filesystem/DFileSystemWatcher b/src/filesystem/DFileSystemWatcher new file mode 100644 index 0000000..97400f2 --- /dev/null +++ b/src/filesystem/DFileSystemWatcher @@ -0,0 +1 @@ +#include "dfilesystemwatcher.h" diff --git a/src/filesystem/DFileWatcher b/src/filesystem/DFileWatcher new file mode 100644 index 0000000..768151a --- /dev/null +++ b/src/filesystem/DFileWatcher @@ -0,0 +1 @@ +#include "dfilewatcher.h" diff --git a/src/filesystem/DFileWatcherManager b/src/filesystem/DFileWatcherManager new file mode 100644 index 0000000..a9f8682 --- /dev/null +++ b/src/filesystem/DFileWatcherManager @@ -0,0 +1 @@ +#include "dfilewatchermanager.h" diff --git a/src/filesystem/DPathBuf b/src/filesystem/DPathBuf new file mode 100644 index 0000000..961c40b --- /dev/null +++ b/src/filesystem/DPathBuf @@ -0,0 +1 @@ +#include "dpathbuf.h" diff --git a/src/filesystem/DStandardPaths b/src/filesystem/DStandardPaths new file mode 100644 index 0000000..9d0b963 --- /dev/null +++ b/src/filesystem/DStandardPaths @@ -0,0 +1 @@ +#include "dstandardpaths.h" diff --git a/src/filesystem/DTrashManager b/src/filesystem/DTrashManager new file mode 100644 index 0000000..e763093 --- /dev/null +++ b/src/filesystem/DTrashManager @@ -0,0 +1 @@ +#include "dtrashmanager.h" diff --git a/src/filesystem/dbasefilewatcher.cpp b/src/filesystem/dbasefilewatcher.cpp new file mode 100644 index 0000000..393c27e --- /dev/null +++ b/src/filesystem/dbasefilewatcher.cpp @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2017 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#include "dbasefilewatcher.h" +#include "private/dbasefilewatcher_p.h" + +#include +#include + +DCORE_BEGIN_NAMESPACE + +QList DBaseFileWatcherPrivate::watcherList; +DBaseFileWatcherPrivate::DBaseFileWatcherPrivate(DBaseFileWatcher *qq) + : DObjectPrivate(qq) +{ + +} + +/*! + \~english \class DBaseFileWatcher + \~english \brief The DBaseFileWatcher class provides an interface for monitoring files and directories for modifications. +*/ + +/*! + \~chinese \class DBaseFileWatcher + \~chinese \brief DBaseFileWatcher 类提供了一系列接口可供监视文件和目录的变动。 +*/ + +DBaseFileWatcher::~DBaseFileWatcher() +{ + stopWatcher(); + DBaseFileWatcherPrivate::watcherList.removeOne(this); +} + +QUrl DBaseFileWatcher::fileUrl() const +{ + Q_D(const DBaseFileWatcher); + + return d->url; +} + +/*! + * \~chinese \brief 开始文件变动监视 + * \~english \brief Let file watcher start watching file changes. + * + * \sa stopWatcher(), restartWatcher() + */ +bool DBaseFileWatcher::startWatcher() +{ + Q_D(DBaseFileWatcher); + + if (d->started) + return true; + + if (d->start()) { + d->started = true; + + return true; + } + + return false; +} + +/*! + * \~chinese \brief 停止文件变动监视 + * \~english \brief Stop watching file changes. + * + * \sa startWatcher(), restartWatcher() + */ +bool DBaseFileWatcher::stopWatcher() +{ + Q_D(DBaseFileWatcher); + + if (!d->started) + return false; + + if (d->stop()) { + d->started = false; + + return true; + } + + return false; +} + +/*! + * \~chinese \brief 重新开始文件变动监视 + * \~english \brief Stop file watcher and then restart it to watching file changes. + * + * \sa startWatcher(), stopWatcher() + */ +bool DBaseFileWatcher::restartWatcher() +{ + bool ok = stopWatcher(); + return ok && startWatcher(); +} + +/*! + * \~chinese \brief 设置是否对 \a subfileUrl 目录启用文件监视 + * \~english \brief Set enable file watcher for \a subfileUrl or not + * + * \~chinese \param subfileUrl 设置所针对的 Url + * \~english \param subfileUrl The given url + * + * \~chinese \param enabled 是否启用文件变动监视 + * \~english \param enabled Enable file change watching or not. + */ +void DBaseFileWatcher::setEnabledSubfileWatcher(const QUrl &subfileUrl, bool enabled) +{ + Q_UNUSED(subfileUrl) + Q_UNUSED(enabled) +} + +/*! + * \~chinese \brief 发送一个信号表示目标目录 \a targetUrl 得到了一个 \a signal 信号,包含参数 \a arg1 。 + * \~english \brief Emit a signal about \a targetUrl got a \a signal with \a arg1 + * + * \~chinese 示例用法: + * \~english Example usage: + * + * \~ \code{.cpp} + * DBaseFileWatcher::ghostSignal(QUrl("bookmark:///"), &DBaseFileWatcher::fileDeleted, QUrl("bookmark:///bookmarkFile1")); + * \endcode + */ +bool DBaseFileWatcher::ghostSignal(const QUrl &targetUrl, DBaseFileWatcher::SignalType1 signal, const QUrl &arg1) +{ + if (!signal) + return false; + + bool ok = false; + + for (DBaseFileWatcher *watcher : DBaseFileWatcherPrivate::watcherList) { + if (watcher->fileUrl() == targetUrl) { + ok = true; + (watcher->*signal)(arg1); + } + } + + return ok; +} + +/*! + * \~chinese \brief 发送一个信号表示目标目录 \a targetUrl 得到了一个 \a signal 信号,包含参数 \a arg1 和 \arg2。 + * \~english \brief Emit a signal about \a targetUrl got a \a signal with \a arg1 and \a arg2 + * + * \~chinese 示例用法: + * \~english Example usage: + * + * \~ \code{.cpp} + * DBaseFileWatcher::ghostSignal(QUrl("bookmark:///"), &DBaseFileWatcher::fileMoved, QUrl("bookmark:///bookmarkFile1"), QUrl("bookmark:///NewNameFile1")); + * \endcode + */ +bool DBaseFileWatcher::ghostSignal(const QUrl &targetUrl, DBaseFileWatcher::SignalType2 signal, const QUrl &arg1, const QUrl &arg2) +{ + if (!signal) + return false; + + bool ok = false; + + for (DBaseFileWatcher *watcher : DBaseFileWatcherPrivate::watcherList) { + if (watcher->fileUrl() == targetUrl) { + ok = true; + (watcher->*signal)(arg1, arg2); + } + } + + return ok; +} + +DBaseFileWatcher::DBaseFileWatcher(DBaseFileWatcherPrivate &dd, + const QUrl &url, QObject *parent) + : QObject(parent) + , DObject(dd) +{ + Q_ASSERT(url.isValid()); + + d_func()->url = url; + DBaseFileWatcherPrivate::watcherList << this; +} + +DCORE_END_NAMESPACE + +#include "moc_dbasefilewatcher.cpp" diff --git a/src/filesystem/dbasefilewatcher.h b/src/filesystem/dbasefilewatcher.h new file mode 100644 index 0000000..e011bd5 --- /dev/null +++ b/src/filesystem/dbasefilewatcher.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2017 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef DBASEFILEWATCHER_H +#define DBASEFILEWATCHER_H + +#include "dtkcore_global.h" +#include "dobject.h" + +#include + +DCORE_BEGIN_NAMESPACE + +class DBaseFileWatcherPrivate; +class LIBDTKCORESHARED_EXPORT DBaseFileWatcher : public QObject, public DObject +{ + Q_OBJECT + +public: + ~DBaseFileWatcher(); + + QUrl fileUrl() const; + + bool startWatcher(); + bool stopWatcher(); + bool restartWatcher(); + + virtual void setEnabledSubfileWatcher(const QUrl &subfileUrl, bool enabled = true); + + using SignalType1 = void(DBaseFileWatcher::*)(const QUrl &); + using SignalType2 = void(DBaseFileWatcher::*)(const QUrl &, const QUrl &); + static bool ghostSignal(const QUrl &targetUrl, SignalType1 signal, const QUrl &arg1); + static bool ghostSignal(const QUrl &targetUrl, SignalType2 signal, const QUrl &arg1, const QUrl &arg2); + +Q_SIGNALS: + void fileDeleted(const QUrl &url); + void fileAttributeChanged(const QUrl &url); + void fileMoved(const QUrl &fromUrl, const QUrl &toUrl); + void subfileCreated(const QUrl &url); + void fileModified(const QUrl &url); + void fileClosed(const QUrl &url); + +protected: + explicit DBaseFileWatcher(DBaseFileWatcherPrivate &dd, const QUrl &url, QObject *parent = 0); + +private: + Q_DISABLE_COPY(DBaseFileWatcher) + D_DECLARE_PRIVATE(DBaseFileWatcher) +}; + +DCORE_END_NAMESPACE + +#endif // DBASEFILEWATCHER_H diff --git a/src/filesystem/dfilesystemwatcher.h b/src/filesystem/dfilesystemwatcher.h new file mode 100644 index 0000000..a8be007 --- /dev/null +++ b/src/filesystem/dfilesystemwatcher.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2017 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef DFILESYSTEMWATCHER_H +#define DFILESYSTEMWATCHER_H + +#include "dtkcore_global.h" +#include "dobject.h" + +#include + +DCORE_BEGIN_NAMESPACE + +class DFileSystemWatcherPrivate; +class LIBDTKCORESHARED_EXPORT DFileSystemWatcher : public QObject, public DObject +{ + Q_OBJECT + D_DECLARE_PRIVATE(DFileSystemWatcher) + +public: + DFileSystemWatcher(QObject *parent = Q_NULLPTR); + DFileSystemWatcher(const QStringList &paths, QObject *parent = Q_NULLPTR); + ~DFileSystemWatcher(); + + bool addPath(const QString &file); + QStringList addPaths(const QStringList &files); + bool removePath(const QString &file); + QStringList removePaths(const QStringList &files); + + QStringList files() const; + QStringList directories() const; + +Q_SIGNALS: + void fileDeleted(const QString &path, const QString &name, QPrivateSignal); + void fileAttributeChanged(const QString &path, const QString &name, QPrivateSignal); + void fileClosed(const QString &path, const QString &name, QPrivateSignal); + void fileMoved(const QString &fromPath, const QString &fromName, + const QString &toPath, const QString &toName, QPrivateSignal); + void fileCreated(const QString &path, const QString &name, QPrivateSignal); + void fileModified(const QString &path, const QString &name, QPrivateSignal); + +private: + Q_PRIVATE_SLOT(d_func(), void _q_readFromInotify()) +}; + +DCORE_END_NAMESPACE + +#endif // DFILESYSTEMWATCHER_H diff --git a/src/filesystem/dfilesystemwatcher_dummy.cpp b/src/filesystem/dfilesystemwatcher_dummy.cpp new file mode 100644 index 0000000..bb2cf51 --- /dev/null +++ b/src/filesystem/dfilesystemwatcher_dummy.cpp @@ -0,0 +1,248 @@ +/* + * Copyright (C) 2017 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#include "dfilesystemwatcher.h" +#include "private/dfilesystemwatcher_dummy_p.h" + +DCORE_BEGIN_NAMESPACE + +DFileSystemWatcherPrivate::DFileSystemWatcherPrivate(int fd, DFileSystemWatcher *qq) + : DObjectPrivate(qq) +{ + +} + +DFileSystemWatcherPrivate::~DFileSystemWatcherPrivate() +{ + +} + +/*! + \class DFileSystemWatcher + \inmodule QtCore + \brief The DFileSystemWatcher class provides an interface for monitoring files and directories for modifications. + \ingroup io + \since 4.2 + \reentrant + + DFileSystemWatcher monitors the file system for changes to files + and directories by watching a list of specified paths. + + Call addPath() to watch a particular file or directory. Multiple + paths can be added using the addPaths() function. Existing paths can + be removed by using the removePath() and removePaths() functions. + + DFileSystemWatcher examines each path added to it. Files that have + been added to the DFileSystemWatcher can be accessed using the + files() function, and directories using the directories() function. + + The fileChanged() signal is emitted when a file has been modified, + renamed or removed from disk. Similarly, the directoryChanged() + signal is emitted when a directory or its contents is modified or + removed. Note that DFileSystemWatcher stops monitoring files once + they have been renamed or removed from disk, and directories once + they have been removed from disk. + + \note On systems running a Linux kernel without inotify support, + file systems that contain watched paths cannot be unmounted. + + \note Windows CE does not support directory monitoring by + default as this depends on the file system driver installed. + + \note The act of monitoring files and directories for + modifications consumes system resources. This implies there is a + limit to the number of files and directories your process can + monitor simultaneously. On all BSD variants, for + example, an open file descriptor is required for each monitored + file. Some system limits the number of open file descriptors to 256 + by default. This means that addPath() and addPaths() will fail if + your process tries to add more than 256 files or directories to + the file system monitor. Also note that your process may have + other file descriptors open in addition to the ones for files + being monitored, and these other open descriptors also count in + the total. OS X uses a different backend and does not + suffer from this issue. + + + \sa QFile, QDir +*/ + + +/*! + Constructs a new file system watcher object with the given \a parent. +*/ +DFileSystemWatcher::DFileSystemWatcher(QObject *parent) + : QObject(parent) + , DObject() +{ + +} + +/*! + Constructs a new file system watcher object with the given \a parent + which monitors the specified \a paths list. +*/ +DFileSystemWatcher::DFileSystemWatcher(const QStringList &paths, QObject *parent) + : DFileSystemWatcher(parent) +{ + addPaths(paths); +} + +/*! + Destroys the file system watcher. +*/ +DFileSystemWatcher::~DFileSystemWatcher() +{ } + +/*! + Adds \a path to the file system watcher if \a path exists. The + path is not added if it does not exist, or if it is already being + monitored by the file system watcher. + + If \a path specifies a directory, the directoryChanged() signal + will be emitted when \a path is modified or removed from disk; + otherwise the fileChanged() signal is emitted when \a path is + modified, renamed or removed. + + If the watch was successful, true is returned. + + Reasons for a watch failure are generally system-dependent, but + may include the resource not existing, access failures, or the + total watch count limit, if the platform has one. + + \note There may be a system dependent limit to the number of + files and directories that can be monitored simultaneously. + If this limit is been reached, \a path will not be monitored, + and false is returned. + + \sa addPaths(), removePath() +*/ +bool DFileSystemWatcher::addPath(const QString &path) +{ + return false; +} + +/*! + Adds each path in \a paths to the file system watcher. Paths are + not added if they not exist, or if they are already being + monitored by the file system watcher. + + If a path specifies a directory, the directoryChanged() signal + will be emitted when the path is modified or removed from disk; + otherwise the fileChanged() signal is emitted when the path is + modified, renamed, or removed. + + The return value is a list of paths that could not be watched. + + Reasons for a watch failure are generally system-dependent, but + may include the resource not existing, access failures, or the + total watch count limit, if the platform has one. + + \note There may be a system dependent limit to the number of + files and directories that can be monitored simultaneously. + If this limit has been reached, the excess \a paths will not + be monitored, and they will be added to the returned QStringList. + + \sa addPath(), removePaths() +*/ +QStringList DFileSystemWatcher::addPaths(const QStringList &paths) +{ + return QStringList(); +} + +/*! + Removes the specified \a path from the file system watcher. + + If the watch is successfully removed, true is returned. + + Reasons for watch removal failing are generally system-dependent, + but may be due to the path having already been deleted, for example. + + \sa removePaths(), addPath() +*/ +bool DFileSystemWatcher::removePath(const QString &path) +{ + return false; +} + +/*! + Removes the specified \a paths from the file system watcher. + + The return value is a list of paths which were not able to be + unwatched successfully. + + Reasons for watch removal failing are generally system-dependent, + but may be due to the path having already been deleted, for example. + + \sa removePath(), addPaths() +*/ +QStringList DFileSystemWatcher::removePaths(const QStringList &paths) +{ + return QStringList(); +} + +/*! + \fn void DFileSystemWatcher::fileChanged(const QString &path) + + This signal is emitted when the file at the specified \a path is + modified, renamed or removed from disk. + + \sa directoryChanged() +*/ + +/*! + \fn void DFileSystemWatcher::directoryChanged(const QString &path) + + This signal is emitted when the directory at a specified \a path + is modified (e.g., when a file is added or deleted) or removed + from disk. Note that if there are several changes during a short + period of time, some of the changes might not Q_EMIT this signal. + However, the last change in the sequence of changes will always + generate this signal. + + \sa fileChanged() +*/ + +/*! + \fn QStringList DFileSystemWatcher::directories() const + + Returns a list of paths to directories that are being watched. + + \sa files() +*/ + +/*! + \fn QStringList DFileSystemWatcher::files() const + + Returns a list of paths to files that are being watched. + + \sa directories() +*/ + +QStringList DFileSystemWatcher::directories() const +{ + return QStringList(); +} + +QStringList DFileSystemWatcher::files() const +{ + return QStringList(); +} + +DCORE_END_NAMESPACE + +#include "moc_dfilesystemwatcher.cpp" diff --git a/src/filesystem/dfilesystemwatcher_linux.cpp b/src/filesystem/dfilesystemwatcher_linux.cpp new file mode 100644 index 0000000..bfddfd3 --- /dev/null +++ b/src/filesystem/dfilesystemwatcher_linux.cpp @@ -0,0 +1,671 @@ +/* + * Copyright (C) 2017 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#include "dfilesystemwatcher.h" +#include "private/dfilesystemwatcher_linux_p.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +DCORE_BEGIN_NAMESPACE + +DFileSystemWatcherPrivate::DFileSystemWatcherPrivate(int fd, DFileSystemWatcher *qq) + : DObjectPrivate(qq) + , inotifyFd(fd) + , notifier(fd, QSocketNotifier::Read, qq) +{ + fcntl(inotifyFd, F_SETFD, FD_CLOEXEC); + qq->connect(¬ifier, SIGNAL(activated(int)), qq, SLOT(_q_readFromInotify())); +} + +DFileSystemWatcherPrivate::~DFileSystemWatcherPrivate() +{ + notifier.setEnabled(false); + Q_FOREACH (int id, pathToID) + inotify_rm_watch(inotifyFd, id < 0 ? -id : id); + + ::close(inotifyFd); +} + +QStringList DFileSystemWatcherPrivate::addPaths(const QStringList &paths, QStringList *files, QStringList *directories) +{ + QStringList p = paths; + QMutableListIterator it(p); + while (it.hasNext()) { + QString path = it.next(); + QFileInfo fi(path); + bool isDir = fi.isDir(); + if (isDir) { + if (directories->contains(path)) + continue; + } else { + if (files->contains(path)) + continue; + } + + int wd = inotify_add_watch(inotifyFd, + QFile::encodeName(path), + (isDir + ? (0 + | IN_ATTRIB + | IN_MOVE + | IN_MOVE_SELF + | IN_CREATE + | IN_DELETE + | IN_DELETE_SELF + | IN_MODIFY + ) + : (0 + | IN_ATTRIB + | IN_CLOSE_WRITE + | IN_MODIFY + | IN_MOVE + | IN_MOVE_SELF + | IN_DELETE_SELF + ))); + if (wd < 0) { + perror("DFileSystemWatcherPrivate::addPaths: inotify_add_watch failed"); + continue; + } + + it.remove(); + + int id = isDir ? -wd : wd; + if (id < 0) { + directories->append(path); + } else { + files->append(path); + } + + pathToID.insert(path, id); + idToPath.insert(id, path); + } + + return p; +} + +QStringList DFileSystemWatcherPrivate::removePaths(const QStringList &paths, QStringList *files, QStringList *directories) +{ + QStringList p = paths; + QMutableListIterator it(p); + while (it.hasNext()) { + QString path = it.next(); + int id = pathToID.take(path); + for (auto hit = idToPath.find(id); hit != idToPath.end() && hit.key() == id; ++hit) { + if (hit.value() == path) { + idToPath.erase(hit); + break; + } + } + + it.remove(); + + if (!idToPath.contains(id)) { + int wd = id < 0 ? -id : id; + //qDebug() << "removing watch for path" << path << "wd" << wd; + inotify_rm_watch(inotifyFd, wd); + } + + if (id < 0) { + directories->removeAll(path); + } else { + files->removeAll(path); + } + } + + return p; +} + +void DFileSystemWatcherPrivate::_q_readFromInotify() +{ + Q_Q(DFileSystemWatcher); +// qDebug() << "QInotifyFileSystemWatcherEngine::readFromInotify"; + + int buffSize = 0; + ioctl(inotifyFd, FIONREAD, (char *) &buffSize); + QVarLengthArray buffer(buffSize); + buffSize = read(inotifyFd, buffer.data(), buffSize); + char *at = buffer.data(); + char * const end = at + buffSize; + + QList eventList; + QMultiHash batch_pathmap; + /// only save event: IN_MOVE_TO + QMultiMap cookieToFilePath; + QMultiMap cookieToFileName; + QSet hasMoveFromByCookie; +#ifdef QT_DEBUG + int exist_count = 0; +#endif + while (at < end) { + inotify_event *event = reinterpret_cast(at); + QStringList paths; + + at += sizeof(inotify_event) + event->len; + + int id = event->wd; + paths = idToPath.values(id); + if (paths.empty()) { + // perhaps a directory? + id = -id; + paths = idToPath.values(id); + if (paths.empty()) + continue; + } + + if (!(event->mask & IN_MOVED_TO) || !hasMoveFromByCookie.contains(event->cookie)) { + auto it = std::find_if(eventList.begin(), eventList.end(), [event](inotify_event *e){ + return event->wd == e->wd && event->mask == e->mask && + event->cookie == e->cookie && + event->len == e->len && + !strcmp(event->name, e->name); + }); + + if (it==eventList.end()) { + eventList.append(event); + } +#ifdef QT_DEBUG + else { + qDebug() << "exist event:" << "event->wd" << event->wd << + "event->mask" << event->mask << + "event->cookie" << event->cookie << "exist counts " << ++exist_count; + } +#endif + const QList bps = batch_pathmap.values(id); + for (auto &path : paths) { + if (!bps.contains(path)) { + batch_pathmap.insert(id, path); + } + } + } + + if (event->mask & IN_MOVED_TO) { + for (auto &path : paths) { + cookieToFilePath.insert(event->cookie, path); + } + cookieToFileName.insert(event->cookie, QString::fromUtf8(event->name)); + } + + if (event->mask & IN_MOVED_FROM) + hasMoveFromByCookie << event->cookie; + } + +// qDebug() << "event count:" << eventList.count(); + + QList::const_iterator it = eventList.constBegin(); + while (it != eventList.constEnd()) { + const inotify_event &event = **it; + ++it; + +// qDebug() << "inotify event, wd" << event.wd << "cookie" << event.cookie << "mask" << hex << event.mask; + + int id = event.wd; + QStringList paths = batch_pathmap.values(id); + + if (paths.empty()) { + id = -id; + paths = batch_pathmap.values(id); + + if (paths.empty()) + continue; + } + const QString &name = QString::fromUtf8(event.name); + + for (auto &path : paths) { +// qDebug() << "event for path" << path; + +// /// TODO: Existence of invalid utf8 characters QFile can not read the file information +// if (event.name != QString::fromLocal8Bit(event.name).toLocal8Bit()) { +// if (event.mask & (IN_CREATE | IN_MOVED_TO)) { +// DFMGlobal::fileNameCorrection(path); +// } +// } + + if ((event.mask & (IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT)) != 0) { + do { + if (event.mask & IN_MOVE_SELF) { + QMap::const_iterator iterator = cookieToFilePath.constBegin(); + + bool isMove = false; + + while (iterator != cookieToFilePath.constEnd()) { + const QString &_path = iterator.value(); + const QString &_name = cookieToFileName.value(iterator.key()); + + if (QFileInfo(_path + QDir::separator() + _name) == QFileInfo(path)) { + isMove = true; + break; + } + + ++iterator; + } + + if (isMove) + break; + } + + /// Keep watcher +// pathToID.remove(path); +// idToPath.remove(id, getPathFromID(id)); +// if (!idToPath.contains(id)) +// inotify_rm_watch(inotifyFd, event.wd); + +// if (id < 0) +// onDirectoryChanged(path, true); +// else +// onFileChanged(path, true); + + Q_EMIT q->fileDeleted(path, QString(), DFileSystemWatcher::QPrivateSignal()); + } while (false); + } else { + if (id < 0) + onDirectoryChanged(path, false); + else + onFileChanged(path, false); + } + + QString filePath = path; + + if (id < 0) { + if (path.endsWith(QDir::separator())) + filePath = path + name; + else + filePath = path + QDir::separator() + name; + } + + if (event.mask & IN_CREATE) { +// qDebug() << "IN_CREATE" << filePath << name; + + if (name.isEmpty()) { + if (pathToID.contains(path)) { + q->removePath(path); + q->addPath(path); + } + } else if (pathToID.contains(filePath)) { + q->removePath(filePath); + q->addPath(filePath); + } + + Q_EMIT q->fileCreated(path, name, DFileSystemWatcher::QPrivateSignal()); + } + + if (event.mask & IN_DELETE) { +// qDebug() << "IN_DELETE" << filePath; + + Q_EMIT q->fileDeleted(path, name, DFileSystemWatcher::QPrivateSignal()); + } + + if (event.mask & IN_MOVED_FROM) { + const QString toName = cookieToFileName.value(event.cookie); + + if (cookieToFilePath.values(event.cookie).empty()) { + Q_EMIT q->fileMoved(path, name, QString(), QString(), DFileSystemWatcher::QPrivateSignal()); + } else { + for (QString &toPath : cookieToFilePath.values(event.cookie)) { +// qDebug() << "IN_MOVED_FROM" << filePath << "to path:" << toPath << "to name:" << toName; + + Q_EMIT q->fileMoved(path, name, toPath, toName, DFileSystemWatcher::QPrivateSignal()); + } + } + } + + if (event.mask & IN_MOVED_TO) { +// qDebug() << "IN_MOVED_TO" << filePath; + + if (!hasMoveFromByCookie.contains(event.cookie)) + Q_EMIT q->fileMoved(QString(), QString(), path, name, DFileSystemWatcher::QPrivateSignal()); + } + + if (event.mask & IN_ATTRIB) { +// qDebug() << "IN_ATTRIB" << event.mask << filePath; + + Q_EMIT q->fileAttributeChanged(path, name, DFileSystemWatcher::QPrivateSignal()); + } + + /*only monitor file close event which is opend by write mode*/ + if (event.mask & IN_CLOSE_WRITE) { +// qDebug() << "IN_CLOSE_WRITE" << event.mask << filePath; + + Q_EMIT q->fileClosed(path, id < 0 ? name : QString(), DFileSystemWatcher::QPrivateSignal()); + } + + if (event.mask & IN_MODIFY) { +// qDebug() << "IN_MODIFY" << event.mask << filePath << name; + + Q_EMIT q->fileModified(path, name, DFileSystemWatcher::QPrivateSignal()); + } + } + } +} + +void DFileSystemWatcherPrivate::onFileChanged(const QString &path, bool removed) +{ + Q_Q(DFileSystemWatcher); + if (!files.contains(path)) { + // the path was removed after a change was detected, but before we delivered the signal + return; + } + if (removed) { + files.removeAll(path); + } +// Q_EMIT q->fileChanged(path, DFileSystemWatcher::QPrivateSignal()); +} + +void DFileSystemWatcherPrivate::onDirectoryChanged(const QString &path, bool removed) +{ + Q_Q(DFileSystemWatcher); + if (!directories.contains(path)) { + // perhaps the path was removed after a change was detected, but before we delivered the signal + return; + } + if (removed) { + directories.removeAll(path); + } +// Q_EMIT q->directoryChanged(path, DFileSystemWatcher::QPrivateSignal()); +} + +/*! + \class DFileSystemWatcher + \inmodule QtCore + \brief The DFileSystemWatcher class provides an interface for monitoring files and directories for modifications. + \ingroup io + \since 4.2 + \reentrant + + DFileSystemWatcher monitors the file system for changes to files + and directories by watching a list of specified paths. + + Call addPath() to watch a particular file or directory. Multiple + paths can be added using the addPaths() function. Existing paths can + be removed by using the removePath() and removePaths() functions. + + DFileSystemWatcher examines each path added to it. Files that have + been added to the DFileSystemWatcher can be accessed using the + files() function, and directories using the directories() function. + + The fileChanged() signal is emitted when a file has been modified, + renamed or removed from disk. Similarly, the directoryChanged() + signal is emitted when a directory or its contents is modified or + removed. Note that DFileSystemWatcher stops monitoring files once + they have been renamed or removed from disk, and directories once + they have been removed from disk. + + \note On systems running a Linux kernel without inotify support, + file systems that contain watched paths cannot be unmounted. + + \note Windows CE does not support directory monitoring by + default as this depends on the file system driver installed. + + \note The act of monitoring files and directories for + modifications consumes system resources. This implies there is a + limit to the number of files and directories your process can + monitor simultaneously. On all BSD variants, for + example, an open file descriptor is required for each monitored + file. Some system limits the number of open file descriptors to 256 + by default. This means that addPath() and addPaths() will fail if + your process tries to add more than 256 files or directories to + the file system monitor. Also note that your process may have + other file descriptors open in addition to the ones for files + being monitored, and these other open descriptors also count in + the total. OS X uses a different backend and does not + suffer from this issue. + + + \sa QFile, QDir +*/ + + +/*! + Constructs a new file system watcher object with the given \a parent. +*/ +DFileSystemWatcher::DFileSystemWatcher(QObject *parent) + : QObject(parent) + , DObject() +{ + int fd = -1; +#ifdef IN_CLOEXEC + fd = inotify_init1(IN_CLOEXEC | O_NONBLOCK); +#endif + if (fd == -1) { + fd = inotify_init1(O_NONBLOCK); + } + + if (fd != -1) + d_d_ptr.reset(new DFileSystemWatcherPrivate(fd, this)); +} + +/*! + Constructs a new file system watcher object with the given \a parent + which monitors the specified \a paths list. +*/ +DFileSystemWatcher::DFileSystemWatcher(const QStringList &paths, QObject *parent) + : DFileSystemWatcher(parent) +{ + addPaths(paths); +} + +/*! + Destroys the file system watcher. +*/ +DFileSystemWatcher::~DFileSystemWatcher() +{ } + +/*! + Adds \a path to the file system watcher if \a path exists. The + path is not added if it does not exist, or if it is already being + monitored by the file system watcher. + + If \a path specifies a directory, the directoryChanged() signal + will be emitted when \a path is modified or removed from disk; + otherwise the fileChanged() signal is emitted when \a path is + modified, renamed or removed. + + If the watch was successful, true is returned. + + Reasons for a watch failure are generally system-dependent, but + may include the resource not existing, access failures, or the + total watch count limit, if the platform has one. + + \note There may be a system dependent limit to the number of + files and directories that can be monitored simultaneously. + If this limit is been reached, \a path will not be monitored, + and false is returned. + + \sa addPaths(), removePath() +*/ +bool DFileSystemWatcher::addPath(const QString &path) +{ + if (path.isEmpty()) { + qWarning("DFileSystemWatcher::addPath: path is empty"); + return true; + } + + QStringList paths = addPaths(QStringList(path)); + return paths.isEmpty(); +} + +/*! + Adds each path in \a paths to the file system watcher. Paths are + not added if they not exist, or if they are already being + monitored by the file system watcher. + + If a path specifies a directory, the directoryChanged() signal + will be emitted when the path is modified or removed from disk; + otherwise the fileChanged() signal is emitted when the path is + modified, renamed, or removed. + + The return value is a list of paths that could not be watched. + + Reasons for a watch failure are generally system-dependent, but + may include the resource not existing, access failures, or the + total watch count limit, if the platform has one. + + \note There may be a system dependent limit to the number of + files and directories that can be monitored simultaneously. + If this limit has been reached, the excess \a paths will not + be monitored, and they will be added to the returned QStringList. + + \sa addPath(), removePaths() +*/ +QStringList DFileSystemWatcher::addPaths(const QStringList &paths) +{ + Q_D(DFileSystemWatcher); + + QStringList p = paths; + QMutableListIterator it(p); + + while (it.hasNext()) { + const QString &path = it.next(); + if (path.isEmpty()) + it.remove(); + } + + if (p.isEmpty()) { + qWarning("DFileSystemWatcher::addPaths: list is empty"); + return QStringList(); + } + + if (d) + p = d->addPaths(p, &d->files, &d->directories); + + return p; +} + +/*! + Removes the specified \a path from the file system watcher. + + If the watch is successfully removed, true is returned. + + Reasons for watch removal failing are generally system-dependent, + but may be due to the path having already been deleted, for example. + + \sa removePaths(), addPath() +*/ +bool DFileSystemWatcher::removePath(const QString &path) +{ + if (path.isEmpty()) { + qWarning("DFileSystemWatcher::removePath: path is empty"); + return true; + } + + QStringList paths = removePaths(QStringList(path)); + return paths.isEmpty(); +} + +/*! + Removes the specified \a paths from the file system watcher. + + The return value is a list of paths which were not able to be + unwatched successfully. + + Reasons for watch removal failing are generally system-dependent, + but may be due to the path having already been deleted, for example. + + \sa removePath(), addPaths() +*/ +QStringList DFileSystemWatcher::removePaths(const QStringList &paths) +{ + Q_D(DFileSystemWatcher); + + QStringList p = paths; + QMutableListIterator it(p); + + while (it.hasNext()) { + const QString &path = it.next(); + if (path.isEmpty()) + it.remove(); + } + + if (p.isEmpty()) { + qWarning("DFileSystemWatcher::removePaths: list is empty"); + return QStringList(); + } + + if (d) + p = d->removePaths(p, &d->files, &d->directories); + + return p; +} + +/*! + \fn void DFileSystemWatcher::fileChanged(const QString &path) + + This signal is emitted when the file at the specified \a path is + modified, renamed or removed from disk. + + \sa directoryChanged() +*/ + +/*! + \fn void DFileSystemWatcher::directoryChanged(const QString &path) + + This signal is emitted when the directory at a specified \a path + is modified (e.g., when a file is added or deleted) or removed + from disk. Note that if there are several changes during a short + period of time, some of the changes might not Q_EMIT this signal. + However, the last change in the sequence of changes will always + generate this signal. + + \sa fileChanged() +*/ + +/*! + \fn QStringList DFileSystemWatcher::directories() const + + Returns a list of paths to directories that are being watched. + + \sa files() +*/ + +/*! + \fn QStringList DFileSystemWatcher::files() const + + Returns a list of paths to files that are being watched. + + \sa directories() +*/ + +QStringList DFileSystemWatcher::directories() const +{ + Q_D(const DFileSystemWatcher); + + if (!d) + return QStringList(); + + return d->directories; +} + +QStringList DFileSystemWatcher::files() const +{ + Q_D(const DFileSystemWatcher); + + if (!d) + return QStringList(); + + return d->files; +} + +DCORE_END_NAMESPACE + +#include "moc_dfilesystemwatcher.cpp" diff --git a/src/filesystem/dfilesystemwatcher_win.cpp b/src/filesystem/dfilesystemwatcher_win.cpp new file mode 100644 index 0000000..826ad25 --- /dev/null +++ b/src/filesystem/dfilesystemwatcher_win.cpp @@ -0,0 +1,248 @@ +/* + * Copyright (C) 2017 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#include "dfilesystemwatcher.h" +#include "private/dfilesystemwatcher_win_p.h" + +DCORE_BEGIN_NAMESPACE + +DFileSystemWatcherPrivate::DFileSystemWatcherPrivate(int fd, DFileSystemWatcher *qq) + : DObjectPrivate(qq) +{ + +} + +DFileSystemWatcherPrivate::~DFileSystemWatcherPrivate() +{ + +} + +/*! + \class DFileSystemWatcher + \inmodule QtCore + \brief The DFileSystemWatcher class provides an interface for monitoring files and directories for modifications. + \ingroup io + \since 4.2 + \reentrant + + DFileSystemWatcher monitors the file system for changes to files + and directories by watching a list of specified paths. + + Call addPath() to watch a particular file or directory. Multiple + paths can be added using the addPaths() function. Existing paths can + be removed by using the removePath() and removePaths() functions. + + DFileSystemWatcher examines each path added to it. Files that have + been added to the DFileSystemWatcher can be accessed using the + files() function, and directories using the directories() function. + + The fileChanged() signal is emitted when a file has been modified, + renamed or removed from disk. Similarly, the directoryChanged() + signal is emitted when a directory or its contents is modified or + removed. Note that DFileSystemWatcher stops monitoring files once + they have been renamed or removed from disk, and directories once + they have been removed from disk. + + \note On systems running a Linux kernel without inotify support, + file systems that contain watched paths cannot be unmounted. + + \note Windows CE does not support directory monitoring by + default as this depends on the file system driver installed. + + \note The act of monitoring files and directories for + modifications consumes system resources. This implies there is a + limit to the number of files and directories your process can + monitor simultaneously. On all BSD variants, for + example, an open file descriptor is required for each monitored + file. Some system limits the number of open file descriptors to 256 + by default. This means that addPath() and addPaths() will fail if + your process tries to add more than 256 files or directories to + the file system monitor. Also note that your process may have + other file descriptors open in addition to the ones for files + being monitored, and these other open descriptors also count in + the total. OS X uses a different backend and does not + suffer from this issue. + + + \sa QFile, QDir +*/ + + +/*! + Constructs a new file system watcher object with the given \a parent. +*/ +DFileSystemWatcher::DFileSystemWatcher(QObject *parent) + : QObject(parent) + , DObject() +{ + +} + +/*! + Constructs a new file system watcher object with the given \a parent + which monitors the specified \a paths list. +*/ +DFileSystemWatcher::DFileSystemWatcher(const QStringList &paths, QObject *parent) + : DFileSystemWatcher(parent) +{ + addPaths(paths); +} + +/*! + Destroys the file system watcher. +*/ +DFileSystemWatcher::~DFileSystemWatcher() +{ } + +/*! + Adds \a path to the file system watcher if \a path exists. The + path is not added if it does not exist, or if it is already being + monitored by the file system watcher. + + If \a path specifies a directory, the directoryChanged() signal + will be emitted when \a path is modified or removed from disk; + otherwise the fileChanged() signal is emitted when \a path is + modified, renamed or removed. + + If the watch was successful, true is returned. + + Reasons for a watch failure are generally system-dependent, but + may include the resource not existing, access failures, or the + total watch count limit, if the platform has one. + + \note There may be a system dependent limit to the number of + files and directories that can be monitored simultaneously. + If this limit is been reached, \a path will not be monitored, + and false is returned. + + \sa addPaths(), removePath() +*/ +bool DFileSystemWatcher::addPath(const QString &path) +{ + return false; +} + +/*! + Adds each path in \a paths to the file system watcher. Paths are + not added if they not exist, or if they are already being + monitored by the file system watcher. + + If a path specifies a directory, the directoryChanged() signal + will be emitted when the path is modified or removed from disk; + otherwise the fileChanged() signal is emitted when the path is + modified, renamed, or removed. + + The return value is a list of paths that could not be watched. + + Reasons for a watch failure are generally system-dependent, but + may include the resource not existing, access failures, or the + total watch count limit, if the platform has one. + + \note There may be a system dependent limit to the number of + files and directories that can be monitored simultaneously. + If this limit has been reached, the excess \a paths will not + be monitored, and they will be added to the returned QStringList. + + \sa addPath(), removePaths() +*/ +QStringList DFileSystemWatcher::addPaths(const QStringList &paths) +{ + return QStringList(); +} + +/*! + Removes the specified \a path from the file system watcher. + + If the watch is successfully removed, true is returned. + + Reasons for watch removal failing are generally system-dependent, + but may be due to the path having already been deleted, for example. + + \sa removePaths(), addPath() +*/ +bool DFileSystemWatcher::removePath(const QString &path) +{ + return false; +} + +/*! + Removes the specified \a paths from the file system watcher. + + The return value is a list of paths which were not able to be + unwatched successfully. + + Reasons for watch removal failing are generally system-dependent, + but may be due to the path having already been deleted, for example. + + \sa removePath(), addPaths() +*/ +QStringList DFileSystemWatcher::removePaths(const QStringList &paths) +{ + return QStringList(); +} + +/*! + \fn void DFileSystemWatcher::fileChanged(const QString &path) + + This signal is emitted when the file at the specified \a path is + modified, renamed or removed from disk. + + \sa directoryChanged() +*/ + +/*! + \fn void DFileSystemWatcher::directoryChanged(const QString &path) + + This signal is emitted when the directory at a specified \a path + is modified (e.g., when a file is added or deleted) or removed + from disk. Note that if there are several changes during a short + period of time, some of the changes might not Q_EMIT this signal. + However, the last change in the sequence of changes will always + generate this signal. + + \sa fileChanged() +*/ + +/*! + \fn QStringList DFileSystemWatcher::directories() const + + Returns a list of paths to directories that are being watched. + + \sa files() +*/ + +/*! + \fn QStringList DFileSystemWatcher::files() const + + Returns a list of paths to files that are being watched. + + \sa directories() +*/ + +QStringList DFileSystemWatcher::directories() const +{ + return QStringList(); +} + +QStringList DFileSystemWatcher::files() const +{ + return QStringList(); +} + +DCORE_END_NAMESPACE + +#include "moc_dfilesystemwatcher.cpp" diff --git a/src/filesystem/dfilewatcher.cpp b/src/filesystem/dfilewatcher.cpp new file mode 100644 index 0000000..fb06711 --- /dev/null +++ b/src/filesystem/dfilewatcher.cpp @@ -0,0 +1,295 @@ +/* + * Copyright (C) 2017 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#include "dfilewatcher.h" +#include "private/dbasefilewatcher_p.h" + +#include "dfilesystemwatcher.h" + +#include +#include + +DCORE_BEGIN_NAMESPACE + +static QString joinFilePath(const QString &path, const QString &name) +{ + if (path.endsWith(QDir::separator())) + return path + name; + + return path + QDir::separator() + name; +} + +class DFileWatcherPrivate : DBaseFileWatcherPrivate +{ +public: + DFileWatcherPrivate(DFileWatcher *qq) + : DBaseFileWatcherPrivate(qq) {} + + bool start() Q_DECL_OVERRIDE; + bool stop() Q_DECL_OVERRIDE; + + void _q_handleFileDeleted(const QString &path, const QString &parentPath); + void _q_handleFileAttributeChanged(const QString &path, const QString &parentPath); + void _q_handleFileMoved(const QString &from, const QString &fromParent, const QString &to, const QString &toParent); + void _q_handleFileCreated(const QString &path, const QString &parentPath); + void _q_handleFileModified(const QString &path, const QString &parentPath); + void _q_handleFileClose(const QString &path, const QString &parentPath); + + static QString formatPath(const QString &path); + + QString path; + QStringList watchFileList; + + static QMap filePathToWatcherCount; + + Q_DECLARE_PUBLIC(DFileWatcher) +}; + +QMap DFileWatcherPrivate::filePathToWatcherCount; +Q_GLOBAL_STATIC(DFileSystemWatcher, watcher_file_private) + +QStringList parentPathList(const QString &path) +{ + QStringList list; + QDir dir(path); + + list << path; + + while (dir.cdUp()) { + list << dir.absolutePath(); + } + + return list; +} + +bool DFileWatcherPrivate::start() +{ + Q_Q(DFileWatcher); + + started = true; + + Q_FOREACH (const QString &path, parentPathList(this->path)) { + if (watchFileList.contains(path)) + continue; + + if (filePathToWatcherCount.value(path, -1) <= 0) { + if (!watcher_file_private->addPath(path)) { + qWarning() << Q_FUNC_INFO << "start watch failed, file path =" << path; + q->stopWatcher(); + started = false; + return false; + } + } + + watchFileList << path; + filePathToWatcherCount[path] = filePathToWatcherCount.value(path, 0) + 1; + } + + q->connect(watcher_file_private, &DFileSystemWatcher::fileDeleted, + q, &DFileWatcher::onFileDeleted); + q->connect(watcher_file_private, &DFileSystemWatcher::fileAttributeChanged, + q, &DFileWatcher::onFileAttributeChanged); + q->connect(watcher_file_private, &DFileSystemWatcher::fileMoved, + q, &DFileWatcher::onFileMoved); + q->connect(watcher_file_private, &DFileSystemWatcher::fileCreated, + q, &DFileWatcher::onFileCreated); + q->connect(watcher_file_private, &DFileSystemWatcher::fileModified, + q, &DFileWatcher::onFileModified); + q->connect(watcher_file_private, &DFileSystemWatcher::fileClosed, + q, &DFileWatcher::onFileClosed); + + return true; +} + +bool DFileWatcherPrivate::stop() +{ + Q_Q(DFileWatcher); + + q->disconnect(watcher_file_private, 0, q, 0); + + bool ok = true; + + Q_FOREACH (const QString &path, watchFileList) { + int count = filePathToWatcherCount.value(path, 0); + + --count; + + if (count <= 0) { + filePathToWatcherCount.remove(path); + watchFileList.removeOne(path); + ok = ok && watcher_file_private->removePath(path); + } else { + filePathToWatcherCount[path] = count; + } + } + + return ok; +} + +void DFileWatcherPrivate::_q_handleFileDeleted(const QString &path, const QString &parentPath) +{ + if (path != this->path && parentPath != this->path) + return; + + Q_Q(DFileWatcher); + + Q_EMIT q->fileDeleted(QUrl::fromLocalFile(path)); +} + +void DFileWatcherPrivate::_q_handleFileAttributeChanged(const QString &path, const QString &parentPath) +{ + if (path != this->path && parentPath != this->path) + return; + + Q_Q(DFileWatcher); + + Q_EMIT q->fileAttributeChanged(QUrl::fromLocalFile(path)); +} + +void DFileWatcherPrivate::_q_handleFileMoved(const QString &from, const QString &fromParent, const QString &to, const QString &toParent) +{ + Q_Q(DFileWatcher); + + if ((fromParent == this->path && toParent == this->path) || from == this->path) { + Q_EMIT q->fileMoved(QUrl::fromLocalFile(from), QUrl::fromLocalFile(to)); + } else if (fromParent == this->path) { + Q_EMIT q->fileDeleted(QUrl::fromLocalFile(from)); + } else if (watchFileList.contains(from)) { + Q_EMIT q->fileDeleted(url); + } else if (toParent == this->path) { + Q_EMIT q->subfileCreated(QUrl::fromLocalFile(to)); + } +} + +void DFileWatcherPrivate::_q_handleFileCreated(const QString &path, const QString &parentPath) +{ + if (path != this->path && parentPath != this->path) + return; + + Q_Q(DFileWatcher); + + Q_EMIT q->subfileCreated(QUrl::fromLocalFile(path)); +} + +void DFileWatcherPrivate::_q_handleFileModified(const QString &path, const QString &parentPath) +{ + if (path != this->path && parentPath != this->path) + return; + + Q_Q(DFileWatcher); + + Q_EMIT q->fileModified(QUrl::fromLocalFile(path)); +} + +void DFileWatcherPrivate::_q_handleFileClose(const QString &path, const QString &parentPath) +{ + if (path != this->path && parentPath != this->path) + return; + + Q_Q(DFileWatcher); + + Q_EMIT q->fileClosed(QUrl::fromLocalFile(path)); +} + +QString DFileWatcherPrivate::formatPath(const QString &path) +{ + QString p = QFileInfo(path).absoluteFilePath(); + + if (p.endsWith(QDir::separator())) + p.chop(1); + + return p.isEmpty() ? path : p; +} + +/*! + \~english \class DFileWatcher + \~english \brief The DFileWatcher class provides an implemention of DBaseFileWatcher for monitoring files and directories for modifications. +*/ + +/*! + \~chinese \class DFileWatcher + \~chinese \brief DFileWatcher 类提供了对 DBaseFileWatcher 接口的实现,可供监视文件和目录的变动。 +*/ + +DFileWatcher::DFileWatcher(const QString &filePath, QObject *parent) + : DBaseFileWatcher(*new DFileWatcherPrivate(this), QUrl::fromLocalFile(filePath), parent) +{ + d_func()->path = DFileWatcherPrivate::formatPath(filePath); +} + +void DFileWatcher::onFileDeleted(const QString &path, const QString &name) +{ + if (name.isEmpty()) + d_func()->_q_handleFileDeleted(path, QString()); + else + d_func()->_q_handleFileDeleted(joinFilePath(path, name), path); +} + +void DFileWatcher::onFileAttributeChanged(const QString &path, const QString &name) +{ + if (name.isEmpty()) + d_func()->_q_handleFileAttributeChanged(path, QString()); + else + d_func()->_q_handleFileAttributeChanged(joinFilePath(path, name), path); +} + +void DFileWatcher::onFileMoved(const QString &from, const QString &fname, const QString &to, const QString &tname) +{ + QString fromPath, fpPath; + QString toPath, tpPath; + + if (fname.isEmpty()) { + fromPath = from; + } else { + fromPath = joinFilePath(from, fname); + fpPath = from; + } + + if (tname.isEmpty()) { + toPath = to; + } else { + toPath = joinFilePath(to, tname); + tpPath = to; + } + + d_func()->_q_handleFileMoved(fromPath, fpPath, toPath, tpPath); +} + +void DFileWatcher::onFileCreated(const QString &path, const QString &name) +{ + d_func()->_q_handleFileCreated(joinFilePath(path, name), path); +} + +void DFileWatcher::onFileModified(const QString &path, const QString &name) +{ + if (name.isEmpty()) + d_func()->_q_handleFileModified(path, QString()); + else + d_func()->_q_handleFileModified(joinFilePath(path, name), path); +} + +void DFileWatcher::onFileClosed(const QString &path, const QString &name) +{ + if (name.isEmpty()) + d_func()->_q_handleFileClose(path, QString()); + else + d_func()->_q_handleFileClose(joinFilePath(path, name), path); +} + +DCORE_END_NAMESPACE + +#include "moc_dfilewatcher.cpp" diff --git a/src/filesystem/dfilewatcher.h b/src/filesystem/dfilewatcher.h new file mode 100644 index 0000000..ba893a3 --- /dev/null +++ b/src/filesystem/dfilewatcher.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2017 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef DFILEWATCHER_H +#define DFILEWATCHER_H + +#include "dbasefilewatcher.h" + +DCORE_BEGIN_NAMESPACE + +class DFileWatcherPrivate; +class LIBDTKCORESHARED_EXPORT DFileWatcher : public DBaseFileWatcher +{ + Q_OBJECT + +public: + explicit DFileWatcher(const QString &filePath, QObject *parent = 0); + +private Q_SLOTS: + void onFileDeleted(const QString &path, const QString &name); + void onFileAttributeChanged(const QString &path, const QString &name); + void onFileMoved(const QString &fromPath, const QString &fromName, + const QString &toPath, const QString &toName); + void onFileCreated(const QString &path, const QString &name); + void onFileModified(const QString &path, const QString &name); + void onFileClosed(const QString &path, const QString &name); + +private: + D_DECLARE_PRIVATE(DFileWatcher) +}; + +DCORE_END_NAMESPACE + +#endif // DFILEWATCHER_H diff --git a/src/filesystem/dfilewatchermanager.cpp b/src/filesystem/dfilewatchermanager.cpp new file mode 100644 index 0000000..128a40f --- /dev/null +++ b/src/filesystem/dfilewatchermanager.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2017 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#include "dfilewatchermanager.h" +#include "dfilewatcher.h" +#include "base/private/dobject_p.h" + +#include +#include + +DCORE_BEGIN_NAMESPACE + +class DFileWatcherManagerPrivate : public DObjectPrivate +{ +public: + DFileWatcherManagerPrivate(DFileWatcherManager *qq); + + QMap watchersMap; + + D_DECLARE_PUBLIC(DFileWatcherManager) +}; + +DFileWatcherManagerPrivate::DFileWatcherManagerPrivate(DFileWatcherManager *qq) + : DObjectPrivate(qq) +{ + +} + +/*! + \~english \class DFileWatcherManager + \~english \brief The DFileWatcherManager class can help you manage file watchers and get signal when file got changed. +*/ + +/*! + \~chinese \class DFileWatcherManager + \~chinese \brief DFileWatcherManager 类可以帮助管理一系列 DFileWatcher 文件监视器,并在文件变动时发送信号通知。 +*/ + +DFileWatcherManager::DFileWatcherManager(QObject *parent) + : QObject(parent) + , DObject(*new DFileWatcherManagerPrivate(this)) +{ + +} + +DFileWatcherManager::~DFileWatcherManager() +{ + +} + +/*! + * \~chinese \brief 为路径 \a filePatch 创建 DFileWatcher 并将其添加到 DFileWatcherManager 中. + * \~english \brief Add file watcher for \a filePatch to the file watcher manager. + * + * \~chinese \return 被创建并添加到 DFileWatcherManager 的 DFileWatcher + * \~english \return The file watcher which got created and added into the file watcher manager. + */ +DFileWatcher *DFileWatcherManager::add(const QString &filePath) +{ + Q_D(DFileWatcherManager); + + DFileWatcher *watcher = d->watchersMap.value(filePath); + + if (watcher) { + return watcher; + } + + watcher = new DFileWatcher(filePath, this); + + connect(watcher, &DFileWatcher::fileAttributeChanged, this, [this](const QUrl & url) { + Q_EMIT fileAttributeChanged(url.toLocalFile()); + }); + connect(watcher, &DFileWatcher::fileClosed, this, [this](const QUrl & url) { + Q_EMIT fileClosed(url.toLocalFile()); + }); + connect(watcher, &DFileWatcher::fileDeleted, this, [this](const QUrl & url) { + Q_EMIT fileDeleted(url.toLocalFile()); + }); + connect(watcher, &DFileWatcher::fileModified, this, [this](const QUrl & url) { + Q_EMIT fileModified(url.toLocalFile()); + }); + connect(watcher, &DFileWatcher::fileMoved, this, [this](const QUrl & fromUrl, const QUrl & toUrl) { + Q_EMIT fileMoved(fromUrl.toLocalFile(), toUrl.toLocalFile()); + }); + connect(watcher, &DFileWatcher::subfileCreated, this, [this](const QUrl & url) { + Q_EMIT subfileCreated(url.toLocalFile()); + }); + + d->watchersMap[filePath] = watcher; + watcher->startWatcher(); + + return watcher; +} + +/*! + * \~chinese \brief 从当前 DFileWatcherManager 中移除监视 \a filePath 的 DFileWatcher. + * \~english \brief Remove file watcher for \a filePatch from the file watcher manager. + */ +void DFileWatcherManager::remove(const QString &filePath) +{ + Q_D(DFileWatcherManager); + + DFileWatcher *watcher = d->watchersMap.take(filePath); + + if (watcher) { + watcher->deleteLater(); + } +} + +DCORE_END_NAMESPACE diff --git a/src/filesystem/dfilewatchermanager.h b/src/filesystem/dfilewatchermanager.h new file mode 100644 index 0000000..4021495 --- /dev/null +++ b/src/filesystem/dfilewatchermanager.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2017 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef DFILEWATCHERMANAGER_H +#define DFILEWATCHERMANAGER_H + +#include "dtkcore_global.h" +#include "dobject.h" + +#include + +DCORE_BEGIN_NAMESPACE + +class DFileWatcher; + +class DFileWatcherManagerPrivate; +class LIBDTKCORESHARED_EXPORT DFileWatcherManager : public QObject, public DObject +{ + Q_OBJECT + +public: + explicit DFileWatcherManager(QObject *parent = 0); + ~DFileWatcherManager(); + + DFileWatcher *add(const QString &filePath); + void remove(const QString &filePath); + +Q_SIGNALS: + void fileDeleted(const QString &filePath); + void fileAttributeChanged(const QString &filePath); + void fileMoved(const QString &fromFilePath, const QString &toFilePath); + void subfileCreated(const QString &filePath); + void fileModified(const QString &filePath); + void fileClosed(const QString &filePath); + +private: + QScopedPointer d_ptr; + + D_DECLARE_PRIVATE(DFileWatcherManager) + Q_DISABLE_COPY(DFileWatcherManager) +}; + +DCORE_END_NAMESPACE + +#endif // DFILEWATCHERMANAGER_H diff --git a/src/filesystem/dpathbuf.cpp b/src/filesystem/dpathbuf.cpp new file mode 100644 index 0000000..c36195d --- /dev/null +++ b/src/filesystem/dpathbuf.cpp @@ -0,0 +1,36 @@ +#include "dpathbuf.h" + +/*! + * \~english \class Dtk::Core::DPathBuf + * \brief Dtk::Core::DPathBuf cat path friendly and supoort multiplatform. + */ + +/*! + * \~chinese \class Dtk::Core::DPathBuf + * \brief Dtk::Core::DPathBuf是一个用于跨平台拼接路径的辅助类。 + * 它能够方便的写出链式结构的路径拼接代码。 +``` +DPathBuf logPath(QStandardPaths::standardLocations(QStandardPaths::HomeLocation).first()); +logPath = logPath / ".cache" / "deepin" / "deepin-test-dtk" / "deepin-test-dtk.log"; +``` + */ + + +DCORE_BEGIN_NAMESPACE + +/*! + * \brief Create Dtk::Core::DPathBuf from string. + * \param path + */ +DPathBuf::DPathBuf(const QString &path) +{ + m_path = QDir(path).absolutePath(); +} + +DPathBuf::DPathBuf() + : DPathBuf(QString()) +{ + +} + +DCORE_END_NAMESPACE diff --git a/src/filesystem/dpathbuf.h b/src/filesystem/dpathbuf.h new file mode 100644 index 0000000..23a8697 --- /dev/null +++ b/src/filesystem/dpathbuf.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2017 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include + +#include "dtkcore_global.h" + +DCORE_BEGIN_NAMESPACE + +class LIBDTKCORESHARED_EXPORT DPathBuf +{ +public: + DPathBuf(); + DPathBuf(const QString &path); + + /*! + * \brief join path with operator / + * \param p is subpath + * \return a new DPathBuf with subpath p + */ + DPathBuf operator/(const QString &p) const + { + return DPathBuf(m_path + "/" + p); + } + + /*! + * \brief join path to self with operator /= + * \param p is subpath to join + * \return self object + */ + DPathBuf &operator/=(const QString &p) + { + return join(p); + } + + /*! + * \brief join path with operator / + * \param p is subpath + * \return a new DPathBuf with subpath p + * \sa Dtk::Core::DPathBuf::operator/(const QString &p) const + */ + DPathBuf operator/(const char *p) const + { + return operator /(QString(p)); + } + + /*! + * \brief join path to self with operator /= + * \param p is subpath to join + * \return self object + * \sa Dtk::Core::DPathBuf::operator/=(const QString &p) + */ + DPathBuf &operator/=(const char *p) + { + return operator /=(QString(p)); + } + + /*! + * \brief join add subpath p to self + * \param p is subpath to join + * \return slef object with subpath joined + */ + DPathBuf &join(const QString &p) + { + m_path += "/" + p; + m_path = QDir(m_path).absolutePath(); + return *this; + } + + /*! + * \brief toString export native separators format string. + * \return string with native separators + */ + QString toString() const + { + return QDir::toNativeSeparators(m_path); + } + +private: + QString m_path; +}; + +DCORE_END_NAMESPACE diff --git a/src/filesystem/dstandardpaths.cpp b/src/filesystem/dstandardpaths.cpp new file mode 100644 index 0000000..4177a9e --- /dev/null +++ b/src/filesystem/dstandardpaths.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2017 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#include "dstandardpaths.h" + +#include + +DCORE_BEGIN_NAMESPACE + +class DSnapStandardPathsPrivate +{ +public: + inline static QString writableLocation(QStandardPaths::StandardLocation /*type*/) + { + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + return env.value("SNAP_USER_COMMON"); + } + + inline static QStringList standardLocations(QStandardPaths::StandardLocation type) + { + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + + switch (type) { + case QStandardPaths::GenericDataLocation: { + QString snapRoot = env.value("SNAP"); + QString genericDataDir = snapRoot + "/usr/share/"; + return QStringList() << genericDataDir; + } + default: + break; + } + + return QStringList() << env.value("SNAP_USER_COMMON"); + } + +private: + DSnapStandardPathsPrivate(); + ~DSnapStandardPathsPrivate(); + Q_DISABLE_COPY(DSnapStandardPathsPrivate) +}; + + +/*! + * \~chinese \class Dtk::Core::DStandardPaths + * \brief DStandardPaths提供兼容Snap/Dtk标准的路径模式。DStandardPaths实现了Qt的QStandardPaths主要接口。 + * \sa QStandardPaths + * + * \enum DStandardPaths::Mode + * \brief DStandardPaths支持的路径产生模式。 + * \var DStandardPaths::Mode DStandardPaths::Auto + * \brief 和Qt标准的行为表现一致。 + * \var DStandardPaths::Mode DStandardPaths::Snap + * \brief 读取SNAP相关的环境变量,支持将配置存储在SNAP对应目录。 + * \var DStandardPaths::Mode DStandardPaths::Test + * \brief 和Qt标准的行为表现一致,但是会开启测试模式,参考QStandardPaths::setTestModeEnabled。 + */ + + +static DStandardPaths::Mode s_mode = DStandardPaths::Auto; + +QString DStandardPaths::writableLocation(QStandardPaths::StandardLocation type) +{ + switch (s_mode) { + case Auto: + case Test: + return QStandardPaths::writableLocation(type); + case Snap: + return DSnapStandardPathsPrivate::writableLocation(type); + } + return QStandardPaths::writableLocation(type); +} + +QStringList DStandardPaths::standardLocations(QStandardPaths::StandardLocation type) +{ + switch (s_mode) { + case Auto: + case Test: + return QStandardPaths::standardLocations(type); + case Snap: + return DSnapStandardPathsPrivate::standardLocations(type); + } + return QStandardPaths::standardLocations(type); +} + +QString DStandardPaths::locate(QStandardPaths::StandardLocation type, const QString &fileName, QStandardPaths::LocateOptions options) +{ + return QStandardPaths::locate(type, fileName, options); +} + +QStringList DStandardPaths::locateAll(QStandardPaths::StandardLocation type, const QString &fileName, QStandardPaths::LocateOptions options) +{ + return QStandardPaths::locateAll(type, fileName, options); +} + +QString DStandardPaths::findExecutable(const QString &executableName, const QStringList &paths) +{ + return QStandardPaths::findExecutable(executableName, paths); +} + +void DStandardPaths::setMode(DStandardPaths::Mode mode) +{ + s_mode = mode; + QStandardPaths::setTestModeEnabled(mode == Test); +} + +DCORE_END_NAMESPACE diff --git a/src/filesystem/dstandardpaths.h b/src/filesystem/dstandardpaths.h new file mode 100644 index 0000000..5323fe4 --- /dev/null +++ b/src/filesystem/dstandardpaths.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2017 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef DTK_CORE_FILESYSTEM_DSTANDARDPATHS_H +#define DTK_CORE_FILESYSTEM_DSTANDARDPATHS_H + +#include + +#include "dtkcore_global.h" + +DCORE_BEGIN_NAMESPACE + +class DStandardPathsPrivate; +class LIBDTKCORESHARED_EXPORT DStandardPaths +{ +public: + enum Mode { + Auto, + Snap, + Test, + }; + + static QString writableLocation(QStandardPaths::StandardLocation type); + static QStringList standardLocations(QStandardPaths::StandardLocation type); + + static QString locate(QStandardPaths::StandardLocation type, const QString &fileName, QStandardPaths::LocateOptions options = QStandardPaths::LocateFile); + static QStringList locateAll(QStandardPaths::StandardLocation type, const QString &fileName, QStandardPaths::LocateOptions options = QStandardPaths::LocateFile); + static QString findExecutable(const QString &executableName, const QStringList &paths = QStringList()); + static void setMode(Mode mode); + +private: + DStandardPaths(); + ~DStandardPaths(); + Q_DISABLE_COPY(DStandardPaths) +}; + +DCORE_END_NAMESPACE + +#endif // DTK_CORE_FILESYSTEM_DSTANDARDPATHS_H diff --git a/src/filesystem/dtrashmanager.h b/src/filesystem/dtrashmanager.h new file mode 100644 index 0000000..d2c031e --- /dev/null +++ b/src/filesystem/dtrashmanager.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2017 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef DTRASHMANAGER_H +#define DTRASHMANAGER_H + +#include +#include + +#include + +DCORE_BEGIN_NAMESPACE + +class DTrashManagerPrivate; +class LIBDTKCORESHARED_EXPORT DTrashManager : public QObject, public DObject +{ +public: + static DTrashManager *instance(); + + bool trashIsEmpty() const; + bool cleanTrash(); + bool moveToTrash(const QString &filePath, bool followSymlink = false); + +protected: + DTrashManager(); + +private: + D_DECLARE_PRIVATE(DTrashManager) +}; + +DCORE_END_NAMESPACE + +#endif // DTRASHMANAGER_H diff --git a/src/filesystem/dtrashmanager_dummy.cpp b/src/filesystem/dtrashmanager_dummy.cpp new file mode 100644 index 0000000..054b7d7 --- /dev/null +++ b/src/filesystem/dtrashmanager_dummy.cpp @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2017 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#include "dtrashmanager.h" + +#include "DObjectPrivate" + +#include +#include +#include +#include +#include + +DCORE_BEGIN_NAMESPACE + +class DTrashManager_ : public DTrashManager {}; +Q_GLOBAL_STATIC(DTrashManager_, globalTrashManager) + +static QString getNotExistsFileName(const QString &fileName, const QString &targetPath) +{ + QByteArray name = fileName.toUtf8(); + + int index = name.lastIndexOf('.'); + QByteArray suffix; + + if (index >= 0) + { + suffix = name.mid(index); + } + + if (suffix.size() > 200) + { + suffix = suffix.left(200); + } + + name.chop(suffix.size()); + name = name.left(200 - suffix.size()); + + while (QFile::exists(targetPath + "/" + name + suffix)) + { + name = QCryptographicHash::hash(name, QCryptographicHash::Md5).toHex(); + } + + return QString::fromUtf8(name + suffix); +} + +static bool renameFile(const QFileInfo &fileInfo, const QString &target, QString *errorString = NULL) +{ + if (fileInfo.isFile() || fileInfo.isSymLink()) + { + QFile file(fileInfo.filePath()); + + if (!file.rename(target)) + { + if (errorString) + { + *errorString = file.errorString(); + } + + return false; + } + + return true; + } + else + { + QDirIterator iterator(fileInfo.filePath(), + QDir::AllEntries | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System); + + while (iterator.hasNext()) + { + iterator.next(); + + const QString newFile = iterator.filePath().replace(0, fileInfo.filePath().length(), target); + + if (!QDir().mkpath(QFileInfo(newFile).path())) + { + if (errorString) + { + *errorString = QString("Make the %1 path is failed").arg(QFileInfo(newFile).path()); + } + + return false; + } + + if (!renameFile(iterator.fileInfo(), newFile, errorString)) + { + return false; + } + } + + if (!QDir().rmdir(fileInfo.filePath())) + { + if (errorString) + { + *errorString = QString("Cannot remove the %1 dir").arg(fileInfo.filePath()); + } + + return false; + } + } + + return true; +} + +class DTrashManagerPrivate : public DTK_CORE_NAMESPACE::DObjectPrivate +{ +public: + DTrashManagerPrivate(DTrashManager *q_ptr) + : DObjectPrivate(q_ptr) {} + + D_DECLARE_PUBLIC(DTrashManager) +}; + +DTrashManager *DTrashManager::instance() +{ + return globalTrashManager; +} + +bool DTrashManager::trashIsEmpty() const +{ + return false; +} + +bool DTrashManager::cleanTrash() +{ + return false; +} + +bool DTrashManager::moveToTrash(const QString &filePath, bool followSymlink) +{ + return false; +} + +DTrashManager::DTrashManager() + : QObject() + , DObject(*new DTrashManagerPrivate(this)) +{ + +} + +DCORE_END_NAMESPACE diff --git a/src/filesystem/dtrashmanager_linux.cpp b/src/filesystem/dtrashmanager_linux.cpp new file mode 100644 index 0000000..38446a5 --- /dev/null +++ b/src/filesystem/dtrashmanager_linux.cpp @@ -0,0 +1,260 @@ +/* + * Copyright (C) 2017 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#include "dtrashmanager.h" +#include "dstandardpaths.h" +#include "private/dobject_p.h" + +#include +#include +#include +#include +#include + +#define TRASH_PATH \ + DStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/Trash" +#define TRASH_INFO_PATH TRASH_PATH"/info" +#define TRASH_FILES_PATH TRASH_PATH"/files" + +DCORE_BEGIN_NAMESPACE + +class DTrashManager_ : public DTrashManager {}; +Q_GLOBAL_STATIC(DTrashManager_, globalTrashManager) + +static QString getNotExistsFileName(const QString &fileName, const QString &targetPath) +{ + QByteArray name = fileName.toUtf8(); + + int index = name.lastIndexOf('.'); + QByteArray suffix; + + if (index >= 0) { + suffix = name.mid(index); + } + + if (suffix.size() > 200) { + suffix = suffix.left(200); + } + + name.chop(suffix.size()); + name = name.left(200 - suffix.size()); + + while (QFile::exists(targetPath + "/" + name + suffix)) { + name = QCryptographicHash::hash(name, QCryptographicHash::Md5).toHex(); + } + + return QString::fromUtf8(name + suffix); +} + +static bool writeTrashInfo(const QString &fileBaseName, const QString &sourceFilePath, const QDateTime &datetime, QString *errorString = NULL) +{ + QFile metadata(TRASH_INFO_PATH"/" + fileBaseName + ".trashinfo"); + + if (metadata.exists()) { + if (errorString) { + *errorString = QString("The %1 file is exists").arg(metadata.fileName()); + } + + return false; + } + + if (!metadata.open(QIODevice::WriteOnly)) { + if (errorString) { + *errorString = metadata.errorString(); + } + + return false; + } + + QByteArray data; + + data.append("[Trash Info]\n"); + data.append("Path=").append(sourceFilePath.toUtf8().toPercentEncoding("/")).append("\n"); + data.append("DeletionDate=").append(datetime.toString(Qt::ISODate)).append("\n"); + + qint64 size = metadata.write(data); + metadata.close(); + + if (size <= 0) { + if (errorString) { + *errorString = metadata.errorString(); + } + + return false; + } + + return true; +} + +static bool renameFile(const QFileInfo &fileInfo, const QString &target, QString *errorString = NULL) +{ + if (fileInfo.isFile() || fileInfo.isSymLink()) { + QFile file(fileInfo.filePath()); + + if (!file.rename(target)) { + if (errorString) { + *errorString = file.errorString(); + } + + return false; + } + + return true; + } else { + QDirIterator iterator(fileInfo.filePath(), + QDir::AllEntries | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System); + + while (iterator.hasNext()) { + iterator.next(); + + const QString newFile = iterator.filePath().replace(0, fileInfo.filePath().length(), target); + + if (!QDir().mkpath(QFileInfo(newFile).path())) { + if (errorString) { + *errorString = QString("Make the %1 path is failed").arg(QFileInfo(newFile).path()); + } + + return false; + } + + if (!renameFile(iterator.fileInfo(), newFile, errorString)) { + return false; + } + } + + if (!QDir().rmdir(fileInfo.filePath())) { + if (errorString) { + *errorString = QString("Cannot remove the %1 dir").arg(fileInfo.filePath()); + } + + return false; + } + } + + return true; +} + +class DTrashManagerPrivate : public DTK_CORE_NAMESPACE::DObjectPrivate +{ +public: + DTrashManagerPrivate(DTrashManager *q_ptr) + : DObjectPrivate(q_ptr) {} + + static bool removeFileOrDir(const QString &path); + static bool removeFromIterator(QDirIterator &iter); + + D_DECLARE_PUBLIC(DTrashManager) +}; + +DTrashManager *DTrashManager::instance() +{ + return globalTrashManager; +} + +bool DTrashManager::trashIsEmpty() const +{ + QDirIterator iterator(TRASH_INFO_PATH, +// QStringList() << "*.trashinfo", + QDir::Files | QDir::NoDotAndDotDot | QDir::Hidden); + + return !iterator.hasNext(); +} + +bool DTrashManager::cleanTrash() +{ + QDirIterator iterator_info(TRASH_INFO_PATH, + QDir::Files | QDir::NoDotAndDotDot | QDir::Hidden); + + QDirIterator iterator_files(TRASH_FILES_PATH, + QDir::AllEntries | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System, + QDirIterator::Subdirectories); + + return DTrashManagerPrivate::removeFromIterator(iterator_info) && + DTrashManagerPrivate::removeFromIterator(iterator_files); +} + +bool DTrashManager::moveToTrash(const QString &filePath, bool followSymlink) +{ + QFileInfo fileInfo(filePath); + + if (!fileInfo.exists() && (followSymlink || !fileInfo.isSymLink())) { + return false; + } + + QDir trashDir(TRASH_FILES_PATH); + QStorageInfo storageInfo(fileInfo.filePath()); + QStorageInfo trashStorageInfo(trashDir); + + if (storageInfo != trashStorageInfo) { + return false; + } + + if (!trashDir.mkpath(TRASH_INFO_PATH)) { + return false; + } + + if (!trashDir.mkpath(TRASH_FILES_PATH)) { + return false; + } + + if (followSymlink && fileInfo.isSymLink()) { + fileInfo.setFile(fileInfo.symLinkTarget()); + } + + const QString &fileName = getNotExistsFileName(fileInfo.fileName(), TRASH_FILES_PATH); + + if (!writeTrashInfo(fileName, fileInfo.filePath(), QDateTime::currentDateTime())) { + return false; + } + + const QString &newFilePath = TRASH_FILES_PATH"/" + fileName; + + return renameFile(fileInfo, newFilePath); +} + +DTrashManager::DTrashManager() + : QObject() + , DObject(*new DTrashManagerPrivate(this)) +{ + +} + +bool DTrashManagerPrivate::removeFileOrDir(const QString &path) +{ + QFileInfo fileInfo(path); + if (fileInfo.isDir() && !fileInfo.isSymLink()) { + QDir dir(path); + return dir.removeRecursively(); + } else { + return QFile::remove(path); + } +} + +bool DTrashManagerPrivate::removeFromIterator(QDirIterator &iter) +{ + bool ok = true; + while (iter.hasNext()) { + QString nextPath = iter.next(); +// qDebug() << iter.fileName() << iterator_info.filePath(); + if (!DTrashManagerPrivate::removeFileOrDir(nextPath)) { + ok = false; + } + } + return ok; +} + +DCORE_END_NAMESPACE diff --git a/src/filesystem/filesystem.pri b/src/filesystem/filesystem.pri new file mode 100644 index 0000000..d97756d --- /dev/null +++ b/src/filesystem/filesystem.pri @@ -0,0 +1,43 @@ +include($$PWD/private/private.pri) + +INCLUDEPATH += $$PWD/../base + +HEADERS += \ + $$PWD/dbasefilewatcher.h \ + $$PWD/dfilesystemwatcher.h \ + $$PWD/dfilewatcher.h \ + $$PWD/dfilewatchermanager.h \ + $$PWD/dpathbuf.h \ + $$PWD/dstandardpaths.h \ + $$PWD/dtrashmanager.h + +SOURCES += \ + $$PWD/dbasefilewatcher.cpp \ + $$PWD/dfilewatcher.cpp \ + $$PWD/dfilewatchermanager.cpp \ + $$PWD/dstandardpaths.cpp \ + $$PWD/dpathbuf.cpp + +linux { + SOURCES += \ + $$PWD/dfilesystemwatcher_linux.cpp \ + $$PWD/dtrashmanager_linux.cpp +} else:win* { + SOURCES += \ + $$PWD/dfilesystemwatcher_win.cpp \ + $$PWD/dtrashmanager_dummy.cpp +} else { + SOURCES += \ + $$PWD/dfilesystemwatcher_dummy.cpp \ + $$PWD/dtrashmanager_dummy.cpp +} + +includes.files += $$PWD/*.h +includes.files += \ + $$PWD/DFileWatcher \ + $$PWD/DBaseFileWatcher \ + $$PWD/DFileSystemWatcher \ + $$PWD/DFileWatcherManager \ + $$PWD/DPathBuf \ + $$PWD/DStandardPaths \ + $$PWD/DTrashManager diff --git a/src/filesystem/private/dbasefilewatcher_p.h b/src/filesystem/private/dbasefilewatcher_p.h new file mode 100644 index 0000000..f200e94 --- /dev/null +++ b/src/filesystem/private/dbasefilewatcher_p.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2017 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef DBASEFILEWATCHER_P_H +#define DBASEFILEWATCHER_P_H + +#include "base/private/dobject_p.h" + +#include + +DCORE_BEGIN_NAMESPACE + +class DBaseFileWatcher; +class DBaseFileWatcherPrivate : public DObjectPrivate +{ +public: + DBaseFileWatcherPrivate(DBaseFileWatcher *qq); + + virtual bool start() = 0; + virtual bool stop() = 0; + + QUrl url; + bool started = false; + static QList watcherList; + + D_DECLARE_PUBLIC(DBaseFileWatcher) +}; + +DCORE_END_NAMESPACE + +#endif // DBASEFILEWATCHER_P_H diff --git a/src/filesystem/private/dfilesystemwatcher_dummy_p.h b/src/filesystem/private/dfilesystemwatcher_dummy_p.h new file mode 100644 index 0000000..ed97dd6 --- /dev/null +++ b/src/filesystem/private/dfilesystemwatcher_dummy_p.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2017 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef DFILESYSTEMWATCHER_WIN_P_H +#define DFILESYSTEMWATCHER_WIN_P_H + +#include "base/private/dobject_p.h" + +DCORE_BEGIN_NAMESPACE + +class DFileSystemWatcher; +class DFileSystemWatcherPrivate : public DObjectPrivate +{ + Q_DECLARE_PUBLIC(DFileSystemWatcher) + +public: + DFileSystemWatcherPrivate(int fd, DFileSystemWatcher *qq); + ~DFileSystemWatcherPrivate(); + + // private slots + void _q_readFromInotify(); +}; + +void DFileSystemWatcherPrivate::_q_readFromInotify() +{ + +} + +DCORE_END_NAMESPACE + +#endif // DFILESYSTEMWATCHER_WIN_P_H diff --git a/src/filesystem/private/dfilesystemwatcher_linux_p.h b/src/filesystem/private/dfilesystemwatcher_linux_p.h new file mode 100644 index 0000000..103c307 --- /dev/null +++ b/src/filesystem/private/dfilesystemwatcher_linux_p.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2017 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef DFILESYSTEMWATCHER_P_H +#define DFILESYSTEMWATCHER_P_H + +#include "base/private/dobject_p.h" + +#include +#include +#include + +DCORE_BEGIN_NAMESPACE + +class DFileSystemWatcher; +class DFileSystemWatcherPrivate : public DObjectPrivate +{ + Q_DECLARE_PUBLIC(DFileSystemWatcher) + +public: + DFileSystemWatcherPrivate(int fd, DFileSystemWatcher *qq); + ~DFileSystemWatcherPrivate(); + + QStringList addPaths(const QStringList &paths, QStringList *files, QStringList *directories); + QStringList removePaths(const QStringList &paths, QStringList *files, QStringList *directories); + + QStringList files, directories; + int inotifyFd; + QHash pathToID; + QMultiHash idToPath; + QSocketNotifier notifier; + + // private slots + void _q_readFromInotify(); + +private: + void onFileChanged(const QString &path, bool removed); + void onDirectoryChanged(const QString &path, bool removed); +}; + +DCORE_END_NAMESPACE + +#endif // DFILESYSTEMWATCHER_P_H diff --git a/src/filesystem/private/dfilesystemwatcher_win_p.h b/src/filesystem/private/dfilesystemwatcher_win_p.h new file mode 100644 index 0000000..ed97dd6 --- /dev/null +++ b/src/filesystem/private/dfilesystemwatcher_win_p.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2017 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef DFILESYSTEMWATCHER_WIN_P_H +#define DFILESYSTEMWATCHER_WIN_P_H + +#include "base/private/dobject_p.h" + +DCORE_BEGIN_NAMESPACE + +class DFileSystemWatcher; +class DFileSystemWatcherPrivate : public DObjectPrivate +{ + Q_DECLARE_PUBLIC(DFileSystemWatcher) + +public: + DFileSystemWatcherPrivate(int fd, DFileSystemWatcher *qq); + ~DFileSystemWatcherPrivate(); + + // private slots + void _q_readFromInotify(); +}; + +void DFileSystemWatcherPrivate::_q_readFromInotify() +{ + +} + +DCORE_END_NAMESPACE + +#endif // DFILESYSTEMWATCHER_WIN_P_H diff --git a/src/filesystem/private/private.pri b/src/filesystem/private/private.pri new file mode 100644 index 0000000..b31875f --- /dev/null +++ b/src/filesystem/private/private.pri @@ -0,0 +1,10 @@ +HEADERS += \ + $$PWD/dbasefilewatcher_p.h + +linux { + HEADERS += \ + $$PWD/dfilesystemwatcher_linux_p.h +} else:win* { + HEADERS += \ + $$PWD/dfilesystemwatcher_win_p.h +} diff --git a/src/log/AbstractAppender.cpp b/src/log/AbstractAppender.cpp new file mode 100644 index 0000000..2d01cf7 --- /dev/null +++ b/src/log/AbstractAppender.cpp @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2017 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + + // Local +#include "AbstractAppender.h" + +// Qt +#include + +DCORE_BEGIN_NAMESPACE + +/** + * \class AbstractAppender + * + * \brief The AbstractAppender class provides an abstract base class for writing a log entries. + * + * The AbstractAppender class is the base interface class for all log appenders that could be used with Logger. + * + * AbstractAppender provides a common implementation for the thread safe, mutex-protected logging of application + * messages, such as ConsoleAppender, FileAppender or something else. AbstractAppender is abstract and can not be + * instantiated, but you can use any of its subclasses or create a custom log appender at your choice. + * + * Appenders are the logical devices that is aimed to be attached to Logger object by calling + * Logger::registerAppender(). On each log record call from the application Logger object sequentially calls write() + * function on all the appenders registered in it. + * + * You can subclass AbstractAppender to implement a logging target of any kind you like. It may be the external logging + * subsystem (for example, syslog in *nix), XML file, SQL database entries, D-Bus messages or anything else you can + * imagine. + * + * For the simple non-structured plain text logging (for example, to a plain text file or to the console output) you may + * like to subclass the AbstractStringAppender instead of AbstractAppender, which will give you a more convenient way to + * control the format of the log output. + * + * \sa AbstractStringAppender + * \sa Logger::registerAppender() + */ + + +//! Constructs a AbstractAppender object. +AbstractAppender::AbstractAppender() + : m_detailsLevel(Logger::Debug) +{} + + +//! Destructs the AbstractAppender object. +AbstractAppender::~AbstractAppender() +{} + + +//! Returns the current details level of appender. +/** + * Log records with a log level lower than a current detailsLevel() will be silently ignored by appender and would not + * be sent to its append() function. + * + * It provides additional logging flexibility, allowing you to set the different severity levels for different types + * of logs. + * + * \note This function is thread safe. + * + * \sa setDetailsLevel() + * \sa Logger::LogLevel + */ +Logger::LogLevel AbstractAppender::detailsLevel() const +{ + QMutexLocker locker(&m_detailsLevelMutex); + return m_detailsLevel; +} + + +//! Sets the current details level of appender. +/** + * Default details level is Logger::Debug + * + * \note This function is thread safe. + * + * \sa detailsLevel() + * \sa Logger::LogLevel + */ +void AbstractAppender::setDetailsLevel(Logger::LogLevel level) +{ + QMutexLocker locker(&m_detailsLevelMutex); + m_detailsLevel = level; +} + + + +//! Sets the current details level of appender +/** + * This function is provided for convenience, it behaves like an above function. + * + * \sa detailsLevel() + * \sa Logger::LogLevel + */ +void AbstractAppender::setDetailsLevel(const QString& level) +{ + setDetailsLevel(Logger::levelFromString(level)); +} + + +//! Tries to write the log record to this logger +/** + * This is the function called by Logger object to write a log message to the appender. + * + * \note This function is thread safe. + * + * \sa Logger::write() + * \sa detailsLevel() + */ +void AbstractAppender::write(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, int line, + const char* function, const QString& category, const QString& message) +{ + if (logLevel >= detailsLevel()) + { + QMutexLocker locker(&m_writeMutex); + append(timeStamp, logLevel, file, line, function, category, message); + } +} + + +/** + * \fn virtual void AbstractAppender::append(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, + * int line, const char* function, const QString& message) + * + * \brief Writes the log record to the logger instance + * + * This function is called every time when user tries to write a message to this AbstractAppender instance using + * the write() function. Write function works as proxy and transfers only the messages with log level more or equal + * to the current logLevel(). + * + * Overload this function when you are implementing a custom appender. + * + * \note This function is not needed to be thread safe because it is never called directly by Logger object. The + * write() function works as a proxy and protects this function from concurrent access. + * + * \sa Logger::write() + */ + +DCORE_END_NAMESPACE diff --git a/src/log/AbstractAppender.h b/src/log/AbstractAppender.h new file mode 100644 index 0000000..91e9479 --- /dev/null +++ b/src/log/AbstractAppender.h @@ -0,0 +1,52 @@ +/* + Copyright (c) 2010 Boris Moiseev (cyberbobs at gmail dot com) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1 + as published by the Free Software Foundation and appearing in the file + LICENSE.LGPL included in the packaging of this file. + + 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 Lesser General Public License for more details. +*/ +#ifndef ABSTRACTAPPENDER_H +#define ABSTRACTAPPENDER_H + +// Local +#include "CuteLogger_global.h" +#include + +// Qt +#include + +DCORE_BEGIN_NAMESPACE + +class CUTELOGGERSHARED_EXPORT AbstractAppender +{ +public: + AbstractAppender(); + virtual ~AbstractAppender(); + + Logger::LogLevel detailsLevel() const; + void setDetailsLevel(Logger::LogLevel level); + void setDetailsLevel(const QString &level); + + void write(const QDateTime &timeStamp, Logger::LogLevel logLevel, const char *file, int line, const char *function, + const QString &category, const QString &message); + +protected: + virtual void append(const QDateTime &timeStamp, Logger::LogLevel logLevel, const char *file, int line, + const char *function, const QString &category, const QString &message) = 0; + +private: + QMutex m_writeMutex; + + Logger::LogLevel m_detailsLevel; + mutable QMutex m_detailsLevelMutex; +}; + +DCORE_END_NAMESPACE + +#endif // ABSTRACTAPPENDER_H diff --git a/src/log/AbstractStringAppender.cpp b/src/log/AbstractStringAppender.cpp new file mode 100644 index 0000000..e040eef --- /dev/null +++ b/src/log/AbstractStringAppender.cpp @@ -0,0 +1,464 @@ +/* + Copyright (c) 2010 Boris Moiseev (cyberbobs at gmail dot com) Nikolay Matyunin (matyunin.n at gmail dot com) + + Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1 + as published by the Free Software Foundation and appearing in the file + LICENSE.LGPL included in the packaging of this file. + + 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 Lesser General Public License for more details. +*/ +// Local +#include "AbstractStringAppender.h" + +// Qt +#include +#include +#include +#include +#include +#include + +DCORE_BEGIN_NAMESPACE + +/** + * \class AbstractStringAppender + * + * \brief The AbstractStringAppender class provides a convenient base for appenders working with plain text formatted + * logs. + * + * AbstractSringAppender is the simple extension of the AbstractAppender class providing the convenient way to create + * custom log appenders working with a plain text formatted log targets. + * + * It have the formattedString() protected function that formats the logging arguments according to a format set with + * setFormat(). + * + * This class can not be directly instantiated because it contains pure virtual function inherited from AbstractAppender + * class. + * + * For more detailed description of customizing the log output format see the documentation on the setFormat() function. + */ + + +const char formattingMarker = '%'; + + +//! Constructs a new string appender object +AbstractStringAppender::AbstractStringAppender() + : m_format(QLatin1String("%{time}{yyyy-MM-ddTHH:mm:ss.zzz} [%{type:-7}] <%{function}> %{message}\n")) +{} + + +//! Returns the current log format string. +/** + * The default format is set to "%{time}{yyyy-MM-ddTHH:mm:ss.zzz} [%{type:-7}] <%{function}> %{message}\n". You can set a different log record + * format using the setFormat() function. + * + * \sa setFormat(const QString&) + */ +QString AbstractStringAppender::format() const +{ + QReadLocker locker(&m_formatLock); + return m_format; +} + + +//! Sets the logging format for writing strings to the log target with this appender. +/** + * The string format seems to be very common to those developers who have used a standard sprintf function. + * + * Log output format is a simple QString with the special markers (starting with % sign) which will be replaced with + * it's internal meaning when writing a log record. + * + * Controlling marker begins with the percent sign (%) which is followed by the command inside {} brackets + * (the command describes, what will be put to log record instead of marker). + * Optional field width argument may be specified right after the command (through the colon symbol before the closing bracket) + * Some commands requires an additional formatting argument (in the second {} brackets). + * + * Field width argument works almost identically to the \c QString::arg() \c fieldWidth argument (and uses it + * internally). For example, \c "%{type:-7}" will be replaced with the left padded debug level of the message + * (\c "Debug ") or something. For the more detailed description of it you may consider to look to the Qt + * Reference Documentation. + * + * Supported marker commands are: + * \arg \c %{time} - timestamp. You may specify your custom timestamp format using the second {} brackets after the marker, + * timestamp format here will be similar to those used in QDateTime::toString() function. For example, + * "%{time}{dd-MM-yyyy, HH:mm}" may be replaced with "17-12-2010, 20:17" depending on current date and time. + * The default format used here is "HH:mm:ss.zzz". + * \arg \c %{type} - Log level. Possible log levels are shown in the Logger::LogLevel enumerator. + * \arg \c %{Type} - Uppercased log level. + * \arg \c %{typeOne} - One letter log level. + * \arg \c %{TypeOne} - One uppercase letter log level. + * \arg \c %{File} - Full source file name (with path) of the file that requested log recording. Uses the \c __FILE__ + * preprocessor macro. + * \arg \c %{file} - Short file name (with stripped path). + * \arg \c %{line} - Line number in the source file. Uses the \c __LINE__ preprocessor macro. + * \arg \c %{Function} - Name of function that called on of the LOG_* macros. Uses the \c Q_FUNC_INFO macro provided with + * Qt. + * \arg \c %{function} - Similar to the %{Function}, but the function name is stripped using stripFunctionName + * \arg \c %{message} - The log message sent by the caller. + * \arg \c %{category} - The log category. + * \arg \c %{appname} - Application name (returned by QCoreApplication::applicationName() function). + * \arg \c %{pid} - Application pid (returned by QCoreApplication::applicationPid() function). + * \arg \c %{threadid} - ID of current thread. + * \arg \c %% - Convinient marker that is replaced with the single \c % mark. + * + * \note Format doesn't add \c '\\n' to the end of the format line. Please consider adding it manually. + * + * \sa format() + * \sa stripFunctionName() + * \sa Logger::LogLevel + */ +void AbstractStringAppender::setFormat(const QString& format) +{ + QWriteLocker locker(&m_formatLock); + m_format = format; +} + + +//! Strips the long function signature (as added by Q_FUNC_INFO macro) +/** + * The string processing drops the returning type, arguments and template parameters of function. It is definitely + * useful for enchancing the log output readability. + * \return stripped function name + */ +QString AbstractStringAppender::stripFunctionName(const char* name) +{ + return QString::fromLatin1(qCleanupFuncinfo(name)); +} + + +// The function was backported from Qt5 sources (qlogging.h) +QByteArray AbstractStringAppender::qCleanupFuncinfo(const char* name) +{ + QByteArray info(name); + + // Strip the function info down to the base function name + // note that this throws away the template definitions, + // the parameter types (overloads) and any const/volatile qualifiers. + if (info.isEmpty()) + return info; + + int pos; + + // skip trailing [with XXX] for templates (gcc) + pos = info.size() - 1; + if (info.endsWith(']')) { + while (--pos) { + if (info.at(pos) == '[') + info.truncate(pos); + } + } + + bool hasLambda = false; + QRegExp lambdaRegex("::"); + int lambdaIndex = lambdaRegex.indexIn(QString::fromLatin1(info)); + if (lambdaIndex != -1) + { + hasLambda = true; + info.remove(lambdaIndex, lambdaRegex.matchedLength()); + } + + // operator names with '(', ')', '<', '>' in it + static const char operator_call[] = "operator()"; + static const char operator_lessThan[] = "operator<"; + static const char operator_greaterThan[] = "operator>"; + static const char operator_lessThanEqual[] = "operator<="; + static const char operator_greaterThanEqual[] = "operator>="; + + // canonize operator names + info.replace("operator ", "operator"); + + // remove argument list + Q_FOREVER { + int parencount = 0; + pos = info.lastIndexOf(')'); + if (pos == -1) { + // Don't know how to parse this function name + return info; + } + + // find the beginning of the argument list + --pos; + ++parencount; + while (pos && parencount) { + if (info.at(pos) == ')') + ++parencount; + else if (info.at(pos) == '(') + --parencount; + --pos; + } + if (parencount != 0) + return info; + + info.truncate(++pos); + + if (info.at(pos - 1) == ')') { + if (info.indexOf(operator_call) == pos - (int)strlen(operator_call)) + break; + + // this function returns a pointer to a function + // and we matched the arguments of the return type's parameter list + // try again + info.remove(0, info.indexOf('(')); + info.chop(1); + continue; + } else { + break; + } + } + + if (hasLambda) + info.append("::lambda"); + + // find the beginning of the function name + int parencount = 0; + int templatecount = 0; + --pos; + + // make sure special characters in operator names are kept + if (pos > -1) { + switch (info.at(pos)) { + case ')': + if (info.indexOf(operator_call) == pos - (int)strlen(operator_call) + 1) + pos -= 2; + break; + case '<': + if (info.indexOf(operator_lessThan) == pos - (int)strlen(operator_lessThan) + 1) + --pos; + break; + case '>': + if (info.indexOf(operator_greaterThan) == pos - (int)strlen(operator_greaterThan) + 1) + --pos; + break; + case '=': { + int operatorLength = (int)strlen(operator_lessThanEqual); + if (info.indexOf(operator_lessThanEqual) == pos - operatorLength + 1) + pos -= 2; + else if (info.indexOf(operator_greaterThanEqual) == pos - operatorLength + 1) + pos -= 2; + break; + } + default: + break; + } + } + + while (pos > -1) { + if (parencount < 0 || templatecount < 0) + return info; + + char c = info.at(pos); + if (c == ')') + ++parencount; + else if (c == '(') + --parencount; + else if (c == '>') + ++templatecount; + else if (c == '<') + --templatecount; + else if (c == ' ' && templatecount == 0 && parencount == 0) + break; + + --pos; + } + info = info.mid(pos + 1); + + // remove trailing '*', '&' that are part of the return argument + while ((info.at(0) == '*') + || (info.at(0) == '&')) + info = info.mid(1); + + // we have the full function name now. + // clean up the templates + while ((pos = info.lastIndexOf('>')) != -1) { + if (!info.contains('<')) + break; + + // find the matching close + int end = pos; + templatecount = 1; + --pos; + while (pos && templatecount) { + register char c = info.at(pos); + if (c == '>') + ++templatecount; + else if (c == '<') + --templatecount; + --pos; + } + ++pos; + info.remove(pos, end - pos + 1); + } + + return info; +} + + +//! Returns the string to record to the logging target, formatted according to the format(). +/** + * \sa format() + * \sa setFormat(const QString&) + */ +QString AbstractStringAppender::formattedString(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, + int line, const char* function, const QString& category, const QString& message) const +{ + QString f = format(); + const int size = f.size(); + + QString result; + + int i = 0; + while (i < f.size()) + { + QChar c = f.at(i); + + // We will silently ignore the broken % marker at the end of string + if (c != QLatin1Char(formattingMarker) || (i + 2) >= size) + { + result.append(c); + } + else + { + i += 2; + QChar currentChar = f.at(i); + QString command; + int fieldWidth = 0; + + if (currentChar.isLetter()) + { + command.append(currentChar); + int j = 1; + while ((i + j) < size && f.at(i + j).isLetter()) + { + command.append(f.at(i+j)); + j++; + } + + i+=j; + currentChar = f.at(i); + + // Check for the padding instruction + if (currentChar == QLatin1Char(':')) + { + currentChar = f.at(++i); + if (currentChar.isDigit() || currentChar.category() == QChar::Punctuation_Dash) + { + int j = 1; + while ((i + j) < size && f.at(i + j).isDigit()) + j++; + fieldWidth = f.mid(i, j).toInt(); + + i += j; + } + } + } + + // Log record chunk to insert instead of formatting instruction + QString chunk; + + // Time stamp + if (command == QLatin1String("time")) + { + if (f.at(i + 1) == QLatin1Char('{')) + { + int j = 1; + while ((i + 2 + j) < size && f.at(i + 2 + j) != QLatin1Char('}')) + j++; + + if ((i + 2 + j) < size) + { + chunk = timeStamp.toString(f.mid(i + 2, j)); + + i += j; + i += 2; + } + } + + if (chunk.isNull()) + chunk = timeStamp.toString(QLatin1String("HH:mm:ss.zzz")); + } + + // Log level + else if (command == QLatin1String("type")) + chunk = Logger::levelToString(logLevel); + + // Uppercased log level + else if (command == QLatin1String("Type")) + chunk = Logger::levelToString(logLevel).toUpper(); + + // One letter log level + else if (command == QLatin1String("typeOne")) + chunk = Logger::levelToString(logLevel).left(1).toLower(); + + // One uppercase letter log level + else if (command == QLatin1String("TypeOne")) + chunk = Logger::levelToString(logLevel).left(1).toUpper(); + + // Filename + else if (command == QLatin1String("File")) + chunk = QLatin1String(file); + + // Filename without a path + else if (command == QLatin1String("file")) + chunk = QString(QLatin1String(file)).section('/', -1); + + // Source line number + else if (command == QLatin1String("line")) + chunk = QString::number(line); + + // Function name, as returned by Q_FUNC_INFO + else if (command == QLatin1String("Function")) + chunk = QString::fromLatin1(function); + + // Stripped function name + else if (command == QLatin1String("function")) + chunk = stripFunctionName(function); + + // Log message + else if (command == QLatin1String("message")) + chunk = message; + + else if (command == QLatin1String("category")) + chunk = category; + + // Application pid + else if (command == QLatin1String("pid")) + chunk = QString::number(QCoreApplication::applicationPid()); + + // Application name + else if (command == QLatin1String("appname")) + chunk = QCoreApplication::applicationName(); + + // Thread ID (duplicates Qt5 threadid debbuging way) + else if (command == QLatin1String("threadid")) + chunk = QLatin1String("0x") + QString::number(qlonglong(QThread::currentThread()->currentThread()), 16); + + // We simply replace the double formatting marker (%) with one + else if (command == QString(formattingMarker)) + chunk = QLatin1Char(formattingMarker); + + // Do not process any unknown commands + else + { + chunk = QString(formattingMarker); + chunk.append(command); + } + + if (!chunk.isEmpty() && chunk != "0") { + result.append(QString(QLatin1String("%1")).arg(chunk, fieldWidth)); + } + } + + ++i; + } + + return result; +} + +DCORE_END_NAMESPACE diff --git a/src/log/AbstractStringAppender.h b/src/log/AbstractStringAppender.h new file mode 100644 index 0000000..b79f194 --- /dev/null +++ b/src/log/AbstractStringAppender.h @@ -0,0 +1,49 @@ +/* + Copyright (c) 2010 Boris Moiseev (cyberbobs at gmail dot com) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1 + as published by the Free Software Foundation and appearing in the file + LICENSE.LGPL included in the packaging of this file. + + 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 Lesser General Public License for more details. +*/ +#ifndef ABSTRACTSTRINGAPPENDER_H +#define ABSTRACTSTRINGAPPENDER_H + +// Local +#include "CuteLogger_global.h" +#include + +// Qt +#include + +DCORE_BEGIN_NAMESPACE + +class CUTELOGGERSHARED_EXPORT AbstractStringAppender : public AbstractAppender +{ + public: + AbstractStringAppender(); + + virtual QString format() const; + void setFormat(const QString&); + + static QString stripFunctionName(const char*); + + protected: + QString formattedString(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, int line, + const char* function, const QString& category, const QString& message) const; + + private: + static QByteArray qCleanupFuncinfo(const char*); + + QString m_format; + mutable QReadWriteLock m_formatLock; +}; + +DCORE_END_NAMESPACE + +#endif // ABSTRACTSTRINGAPPENDER_H diff --git a/src/log/ConsoleAppender.cpp b/src/log/ConsoleAppender.cpp new file mode 100644 index 0000000..417e888 --- /dev/null +++ b/src/log/ConsoleAppender.cpp @@ -0,0 +1,67 @@ +/* + Copyright (c) 2010 Boris Moiseev (cyberbobs at gmail dot com) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1 + as published by the Free Software Foundation and appearing in the file + LICENSE.LGPL included in the packaging of this file. + + 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 Lesser General Public License for more details. +*/ +// Local +#include "ConsoleAppender.h" + +// STL +#include + +DCORE_BEGIN_NAMESPACE + +/** + * \class ConsoleAppender + * + * \brief ConsoleAppender is the simple appender that writes the log records to the std::cerr output stream. + * + * ConsoleAppender uses "[%{type:-7}] <%{function}> %{message}\n" as a default output format. It is similar to the + * AbstractStringAppender but doesn't show a timestamp. + * + * You can modify ConsoleAppender output format without modifying your code by using \c QT_MESSAGE_PATTERN environment + * variable. If you need your application to ignore this environment variable you can call + * ConsoleAppender::ignoreEnvironmentPattern(true) + */ + + +ConsoleAppender::ConsoleAppender() + : AbstractStringAppender(), + m_ignoreEnvPattern(false) +{ + setFormat("[%{type:-7}] <%{function}> %{message}\n"); +} + + +QString ConsoleAppender::format() const +{ + const QString envPattern = QString::fromLocal8Bit(qgetenv("QT_MESSAGE_PATTERN")); + return (m_ignoreEnvPattern || envPattern.isEmpty()) ? AbstractStringAppender::format() : (envPattern + "\n"); +} + + +void ConsoleAppender::ignoreEnvironmentPattern(bool ignore) +{ + m_ignoreEnvPattern = ignore; +} + + +//! Writes the log record to the std::cerr stream. +/** + * \sa AbstractStringAppender::format() + */ +void ConsoleAppender::append(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, int line, + const char* function, const QString& category, const QString& message) +{ + std::cerr << qPrintable(formattedString(timeStamp, logLevel, file, line, function, category, message)); +} + +DCORE_END_NAMESPACE diff --git a/src/log/ConsoleAppender.h b/src/log/ConsoleAppender.h new file mode 100644 index 0000000..26fe8e5 --- /dev/null +++ b/src/log/ConsoleAppender.h @@ -0,0 +1,39 @@ +/* + Copyright (c) 2010 Boris Moiseev (cyberbobs at gmail dot com) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1 + as published by the Free Software Foundation and appearing in the file + LICENSE.LGPL included in the packaging of this file. + + 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 Lesser General Public License for more details. +*/ +#ifndef CONSOLEAPPENDER_H +#define CONSOLEAPPENDER_H + +#include "CuteLogger_global.h" +#include + +DCORE_BEGIN_NAMESPACE + +class CUTELOGGERSHARED_EXPORT ConsoleAppender : public AbstractStringAppender +{ + public: + ConsoleAppender(); + virtual QString format() const; + void ignoreEnvironmentPattern(bool ignore); + + protected: + virtual void append(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, int line, + const char* function, const QString& category, const QString& message); + + private: + bool m_ignoreEnvPattern; +}; + +DCORE_END_NAMESPACE + +#endif // CONSOLEAPPENDER_H diff --git a/src/log/CuteLogger_global.h b/src/log/CuteLogger_global.h new file mode 100644 index 0000000..aefc915 --- /dev/null +++ b/src/log/CuteLogger_global.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2017 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef CUTELOGGER_GLOBAL_H +#define CUTELOGGER_GLOBAL_H + +#include "dtkcore_global.h" + +#if defined(CUTELOGGER_LIBRARY) +# define CUTELOGGERSHARED_EXPORT Q_DECL_EXPORT +#else +#if defined(Q_OS_WIN32) +# define CUTELOGGERSHARED_EXPORT +#else +# define CUTELOGGERSHARED_EXPORT Q_DECL_IMPORT +#endif +#endif + +#endif // CUTELOGGER_GLOBAL_H diff --git a/src/log/DLog b/src/log/DLog new file mode 100644 index 0000000..774c2fc --- /dev/null +++ b/src/log/DLog @@ -0,0 +1,8 @@ +#include "CuteLogger_global.h" +#include "RollingFileAppender.h" +#include "Logger.h" +#include "LogManager.h" +#include "FileAppender.h" +#include "ConsoleAppender.h" +#include "AbstractStringAppender.h" +#include "AbstractAppender.h" diff --git a/src/log/FileAppender.cpp b/src/log/FileAppender.cpp new file mode 100644 index 0000000..b26273d --- /dev/null +++ b/src/log/FileAppender.cpp @@ -0,0 +1,112 @@ +/* + Copyright (c) 2010 Boris Moiseev (cyberbobs at gmail dot com) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1 + as published by the Free Software Foundation and appearing in the file + LICENSE.LGPL included in the packaging of this file. + + 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 Lesser General Public License for more details. +*/ +// Local +#include "FileAppender.h" + +// STL +#include + +DCORE_BEGIN_NAMESPACE + +/** + * \class FileAppender + * + * \brief Simple appender that writes the log records to the plain text file. + */ + + +//! Constructs the new file appender assigned to file with the given name. +FileAppender::FileAppender(const QString& fileName) +{ + setFileName(fileName); +} + + +FileAppender::~FileAppender() +{ + closeFile(); +} + + +//! Returns the name set by setFileName() or to the FileAppender constructor. +/** + * \sa setFileName() + */ +QString FileAppender::fileName() const +{ + QMutexLocker locker(&m_logFileMutex); + return m_logFile.fileName(); +} + + +//! Sets the name of the file. The name can have no path, a relative path, or an absolute path. +/** + * \sa fileName() + */ +void FileAppender::setFileName(const QString& s) +{ + QMutexLocker locker(&m_logFileMutex); + if (m_logFile.isOpen()) + m_logFile.close(); + + m_logFile.setFileName(s); +} + +qint64 FileAppender::size() const +{ + return m_logFile.size(); +} + + +bool FileAppender::openFile() +{ + bool isOpen = m_logFile.isOpen(); + if (!isOpen) + { + isOpen = m_logFile.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text); + if (isOpen) + m_logStream.setDevice(&m_logFile); + else + std::cerr << " Cannot open the log file " << qPrintable(m_logFile.fileName()) << std::endl; + } + return isOpen; +} + + +//! Write the log record to the file. +/** + * \sa fileName() + * \sa AbstractStringAppender::format() + */ +void FileAppender::append(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, int line, + const char* function, const QString& category, const QString& message) +{ + QMutexLocker locker(&m_logFileMutex); + + if (openFile()) + { + m_logStream << formattedString(timeStamp, logLevel, file, line, function, category, message); + m_logStream.flush(); + m_logFile.flush(); + } +} + + +void FileAppender::closeFile() +{ + QMutexLocker locker(&m_logFileMutex); + m_logFile.close(); +} + +DCORE_END_NAMESPACE diff --git a/src/log/FileAppender.h b/src/log/FileAppender.h new file mode 100644 index 0000000..c122580 --- /dev/null +++ b/src/log/FileAppender.h @@ -0,0 +1,52 @@ +/* + Copyright (c) 2010 Boris Moiseev (cyberbobs at gmail dot com) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1 + as published by the Free Software Foundation and appearing in the file + LICENSE.LGPL included in the packaging of this file. + + 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 Lesser General Public License for more details. +*/ +#ifndef FILEAPPENDER_H +#define FILEAPPENDER_H + +// Logger +#include "CuteLogger_global.h" +#include + +// Qt +#include +#include + +DCORE_BEGIN_NAMESPACE + +class CUTELOGGERSHARED_EXPORT FileAppender : public AbstractStringAppender +{ + public: + FileAppender(const QString& fileName = QString()); + ~FileAppender(); + + QString fileName() const; + void setFileName(const QString&); + + qint64 size() const; + + protected: + virtual void append(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, int line, + const char* function, const QString& category, const QString& message); + bool openFile(); + void closeFile(); + + private: + QFile m_logFile; + QTextStream m_logStream; + mutable QMutex m_logFileMutex; +}; + +DCORE_END_NAMESPACE + +#endif // FILEAPPENDER_H diff --git a/src/log/LICENSE b/src/log/LICENSE new file mode 100644 index 0000000..9cecc1d --- /dev/null +++ b/src/log/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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 + (at your option) 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 . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/src/log/LogManager.cpp b/src/log/LogManager.cpp new file mode 100644 index 0000000..8f90fe7 --- /dev/null +++ b/src/log/LogManager.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2017 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#include "LogManager.h" +#include +#include +#include + +DCORE_BEGIN_NAMESPACE + +/** + * \class DLogManager + * + * \brief DLogManager is the deepin user application log manager + */ + +DLogManager::DLogManager() +{ +#if !defined(QT_DEBUG) && !defined(QT_MESSAGELOGCONTEXT) + m_format = "%{time}{yyyy-MM-dd, HH:mm:ss.zzz} %{message}\n"; +#else + m_format = "%{time}{yyyy-MM-dd, HH:mm:ss.zzz} [%{type:-7}] [%{file:-20} %{function:-35} %{line}] %{message}\n"; +#endif +} + +void DLogManager::initConsoleAppender(){ + m_consoleAppender = new ConsoleAppender; + m_consoleAppender->setFormat(m_format); + logger->registerAppender(m_consoleAppender); +} + +void DLogManager::initRollingFileAppender(){ + m_rollingFileAppender = new RollingFileAppender(getlogFilePath()); + m_rollingFileAppender->setFormat(m_format); + m_rollingFileAppender->setLogFilesLimit(5); + m_rollingFileAppender->setDatePattern(RollingFileAppender::DailyRollover); + logger->registerAppender(m_rollingFileAppender); +} + +//! Registers the appender to write the log records to the Console +/** + * \sa registerFileAppender + */ +void DLogManager::registerConsoleAppender(){ + DLogManager::instance()->initConsoleAppender(); +} + +//! Registers the appender to write the log records to the file +/** + * \sa getlogFilePath + * \sa registerConsoleAppender + */ +void DLogManager::registerFileAppender() { + DLogManager::instance()->initRollingFileAppender(); +} + +//! Return the path file log storage +/** + * \~chinese \brief DLogManager::getlogFilePath 获取日志文件路径 + * \~chinese \brief 默认日志路径是 ~/.cache/organizationName/applicationName.log + * \~chinese \brief 如果获取 HOME 环境变量失败将不写日志 + * \sa registerFileAppender + */ +QString DLogManager::getlogFilePath() +{ + // 不再构造时去设置默认logpath(且mkdir), 而在getlogPath时再去判断是否设置默认值 + // 修复设置了日志路径还是会在默认的位置创建目录的问题 + if (DLogManager::instance()->m_logPath.isEmpty()) { + if (QDir::homePath() == QDir::rootPath()) { + qWarning() << "unable to locate the cache directory." + << "logfile path is empty, the log will not be written.\r\n" + << (qgetenv("HOME").isEmpty() ? "the HOME environment variable not set" : ""); + return QString(); + } + + QString cachePath = QStandardPaths::standardLocations(QStandardPaths::CacheLocation).at(0); + if (!QDir(cachePath).exists()) { + QDir(cachePath).mkpath(cachePath); + } + DLogManager::instance()->m_logPath = DLogManager::instance()->joinPath(cachePath, QString("%1.log").arg(qApp->applicationName())); + } + + return QDir::toNativeSeparators(DLogManager::instance()->m_logPath); +} + +/*! + * \~chinese \brief DLogManager::setlogFilePath 设置日志文件路径 + * \~chinese \param logFilePath 日志文件路径 + * \~chinese \brief 如果设置的文件路进不是文件路径将什么都不做,输出一条警告 + */ +void DLogManager::setlogFilePath(const QString &logFilePath) +{ + QFileInfo info(logFilePath); + if (info.exists() && !info.isFile()) + qWarning() << "invalid file path:" << logFilePath << " is not a file"; + else + DLogManager::instance()->m_logPath = logFilePath; +} + +void DLogManager::setLogFormat(const QString &format) +{ + //m_format = "%{time}{yyyy-MM-dd, HH:mm:ss.zzz} [%{type:-7}] [%{file:-20} %{function:-35} %{line}] %{message}\n"; + DLogManager::instance()->m_format = format; +} + +QString DLogManager::joinPath(const QString &path, const QString &fileName){ + QString separator(QDir::separator()); + return QString("%1%2%3").arg(path, separator, fileName); +} + +DLogManager::~DLogManager() +{ + +} + +DCORE_END_NAMESPACE diff --git a/src/log/LogManager.h b/src/log/LogManager.h new file mode 100644 index 0000000..5f54903 --- /dev/null +++ b/src/log/LogManager.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2017 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef LOGMANAGER_H +#define LOGMANAGER_H + +#include + +#include "CuteLogger_global.h" + +DCORE_BEGIN_NAMESPACE + +class ConsoleAppender; +class RollingFileAppender; + +class LIBDTKCORESHARED_EXPORT DLogManager +{ +public: + static void registerConsoleAppender(); + static void registerFileAppender(); + + static QString getlogFilePath(); + + /*! + * \brief setlogFilePath will change log file path of registerFileAppender + * \param logFilePath is the full path of file appender log + */ + static void setlogFilePath(const QString& logFilePath); + + static void setLogFormat(const QString& format); + +private: + QString m_format; + QString m_logPath; + ConsoleAppender* m_consoleAppender; + RollingFileAppender* m_rollingFileAppender; + + void initConsoleAppender(); + void initRollingFileAppender(); + QString joinPath(const QString& path, const QString& fileName); + + inline static DLogManager* instance(){ + static DLogManager instance; + return &instance; + } + explicit DLogManager(); + ~DLogManager(); + DLogManager(const DLogManager &); + DLogManager & operator = (const DLogManager &); +}; + +DCORE_END_NAMESPACE + +#endif // LOGMANAGER_H diff --git a/src/log/Logger.cpp b/src/log/Logger.cpp new file mode 100644 index 0000000..df5c359 --- /dev/null +++ b/src/log/Logger.cpp @@ -0,0 +1,1060 @@ +/* + Copyright (c) 2012 Boris Moiseev (cyberbobs at gmail dot com) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1 + as published by the Free Software Foundation and appearing in the file + LICENSE.LGPL included in the packaging of this file. + + 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 Lesser General Public License for more details. +*/ +// Local +#include "Logger.h" +#include "AbstractAppender.h" +#include "AbstractStringAppender.h" + +// Qt +#include +#include +#include +#include +#include +#include + +#if defined(Q_OS_ANDROID) +# include +# include +#endif + +// STL +#include + +DCORE_BEGIN_NAMESPACE + +/** + * \file Logger.h + * \brief A file containing the description of Logger class and and additional useful macros for logging + */ + +/** + * \def logger + * + * \brief Macro returning the current instance of Logger object + * + * If you haven't created a local Logger object it returns the same value as the Logger::globalInstance() functions. + * This macro is a recommended way to get an access to the Logger instance used in current class. + * + * Example: + * \code + * ConsoleAppender* consoleAppender = new ConsoleAppender; + * logger->registerAppender(consoleAppender); + * \endcode + * + * \sa Dtk::Logger::globalInstance() + */ + + +/** + * \def dTrace + * + * \brief Writes the trace log record + * + * This macro is the convenient way to call Logger::write(). It uses the common preprocessor macros \c __FILE__, + * \c __LINE__ and the standard Qt \c Q_FUNC_INFO macros to automatically determine the needed parameters to call + * Logger::write(). + * + * \note This and other (dInfo() etc...) macros uses the variadic macro arguments to give convenient usage form for + * the different versions of Logger::write() (using the QString or const char* argument or returning the QDebug class + * instance). Not all compilers will support this. Please, consider reviewing your compiler documentation to ensure + * it support __VA_ARGS__ macro. + * + * \sa Dtk::Logger::LogLevel + * \sa Dtk::Logger::write() + */ + + +/** + * \def dDebug + * + * \brief Writes the debug log record + * + * This macro records the debug log record using the Logger::write() function. It works similar to the dTrace() + * macro. + * + * \sa dTrace() + * \sa Dtk::Logger::LogLevel + * \sa Dtk::Logger::write() + */ + + +/** + * \def dInfo + * + * \brief Writes the info log record + * + * This macro records the info log record using the Logger::write() function. It works similar to the dTrace() + * macro. + * + * \sa dTrace() + * \sa Dtk::Logger::LogLevel + * \sa Dtk::Logger::write() + */ + + +/** + * \def dWarning + * + * \brief Write the warning log record + * + * This macro records the warning log record using the Logger::write() function. It works similar to the dTrace() + * macro. + * + * \sa dTrace() + * \sa Dtk::Logger::LogLevel + * \sa Dtk::Logger::write() + */ + + +/** + * \def dError + * + * \brief Write the error log record + * This macro records the error log record using the Logger::write() function. It works similar to the dTrace() + * macro. + * + * \sa dTrace() + * \sa Dtk::Logger::LogLevel + * \sa Dtk::Logger::write() + */ + + +/** + * \def dFatal + * + * \brief Write the fatal log record + * + * This macro records the fatal log record using the Logger::write() function. It works similar to the dTrace() + * macro. + * + * \note Recording of the log record using the Logger::Fatal log level will lead to calling the STL abort() + * function, which will interrupt the running of your software and begin the writing of the core dump. + * + * \sa dTrace() + * \sa Dtk::Logger::LogLevel + * \sa Dtk::Logger::write() + */ + + +/** + * \def dCTrace(category) + * + * \brief Writes the trace log record to the specific category + * + * This macro is the similar to the dTrace() macro, but has a category parameter + * to write only to the category appenders (registered using Logger::registerCategoryAppender() method). + * + * \param category category name string + * + * \sa dTrace() + * \sa Dtk::Logger::LogLevel + * \sa Dtk::Logger::registerCategoryAppender() + * \sa Dtk::Logger::write() + * \sa dCategory(), dGlobalCategory() + */ + + +/** + * \def dCDebug + * + * \brief Writes the debug log record to the specific category + * + * This macro records the debug log record using the Logger::write() function. It works similar to the dCTrace() + * macro. + * + * \sa dCTrace() + */ + + +/** + * \def dCInfo + * + * \brief Writes the info log record to the specific category + * + * This macro records the info log record using the Logger::write() function. It works similar to the dCTrace() + * macro. + * + * \sa dCTrace() + */ + + +/** + * \def dCWarning + * + * \brief Writes the warning log record to the specific category + * + * This macro records the warning log record using the Logger::write() function. It works similar to the dCTrace() + * macro. + * + * \sa dCTrace() + */ + + +/** + * \def dCError + * + * \brief Writes the error log record to the specific category + * + * This macro records the error log record using the Logger::write() function. It works similar to the dCTrace() + * macro. + * + * \sa dCTrace() + */ + + +/** + * \def dCFatal + * + * \brief Write the fatal log record to the specific category + * + * This macro records the fatal log record using the Logger::write() function. It works similar to the dCTrace() + * macro. + * + * \note Recording of the log record using the Logger::Fatal log level will lead to calling the STL abort() + * function, which will interrupt the running of your software and begin the writing of the core dump. + * + * \sa dCTrace() + */ + + +/** + * \def dCategory(category) + * + * \brief Create logger instance inside your custom class to log all messages to the specified category + * + * This macro is used to pass all log messages inside your custom class to the specific category. + * You must include this macro inside your class declaration (similarly to the Q_OBJECT macro). + * Internally, this macro redefines loggerInstance() function, creates the local Logger object inside your class and + * sets the default category to the specified parameter. + * + * Thus, any call to loggerInstance() (for example, inside dTrace() macro) will return the local Logger object, + * so any logging message will be directed to the default category. + * + * \note This macro does not register any appender to the newly created logger instance. You should register + * logger appenders manually, inside your class. + * + * Usage example: + * \code + * class CustomClass : public QObject + * { + * Q_OBJECT + * dCategory("custom_category") + * ... + * }; + * + * CustomClass::CustomClass(QObject* parent) : QObject(parent) + * { + * logger->registerAppender(new FileAppender("custom_category_log")); + * dTrace() << "Trace to the custom category log"; + * } + * \endcode + * + * \sa Dtk::Logger::write() + * \sa dTrace + * \sa Dtk::Logger::registerCategoryAppender() + * \sa Dtk::Logger::setDefaultCategory() + * \sa dGlobalCategory + */ + + +/** + * \def dGlobalCategory(category) + * + * \brief Create logger instance inside your custom class to log all messages both to the specified category and to + * the global logger instance. + * + * This macro is similar to dCategory(), but also passes all log messages to the global logger instance appenders. + * It is equal to defining the local category logger using dCategory macro and calling: + * \code logger->logToGlobalInstance(logger->defaultCategory(), true); \endcode + * + * \sa dCategory + * \sa Dtk::Logger::logToGlobalInstance() + * \sa Dtk::Logger::defaultCategory() + * \sa Dtk::Logger::registerCategoryAppender() + * \sa Dtk::Logger::write() + */ + + + +/** + * \def dAssert + * + * \brief Check the assertion + * + * This macro is a convenient and recommended to use way to call Logger::writeAssert() function. It uses the + * preprocessor macros (as the dDebug() does) to fill the necessary arguments of the Logger::writeAssert() call. It + * also uses undocumented but rather mature and stable \c qt_noop() function (which does nothing) when the assertion + * is true. + * + * Example: + * \code + * bool b = checkSomething(); + * ... + * dAssert(b == true); + * \endcode + * + * \sa Dtk::Logger::writeAssert() + */ + + +/** + * \def dTraceTime + * + * \brief Logs the processing time of current function / code block + * + * This macro automagically measures the function or code of block execution time and outputs it as a Logger::Trace + * level log record. + * + * Example: + * \code + * int foo() + * { + * dTraceTime(); + * ... // Do some long operations + * return 0; + * } // Outputs: Function foo finished in