aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsaturneric <[email protected]>2024-07-29 19:29:56 +0000
committersaturneric <[email protected]>2024-07-29 19:29:56 +0000
commitfa90ec4b5315b9e70a44a9625c143ce253f0e885 (patch)
tree8ffa82e33522de03974d6d0289aa831b4fd6ebdf
parentfix: correct urls at appdata.xml (diff)
parentMerge branch 'develop' of github.com:saturneric/GpgFrontend into develop (diff)
downloadGpgFrontend-fa90ec4b5315b9e70a44a9625c143ce253f0e885.tar.gz
GpgFrontend-fa90ec4b5315b9e70a44a9625c143ce253f0e885.zip
Merge branch 'develop'
-rw-r--r--.github/workflows/codeql-analysis.yml17
-rw-r--r--.github/workflows/doxygen-genration.yml3
-rw-r--r--.github/workflows/release-qt5.yml63
-rw-r--r--.github/workflows/release.yml165
-rw-r--r--.gitignore1
-rw-r--r--.gitmodules6
-rw-r--r--CMakeLists.txt552
-rw-r--r--README.md35
-rw-r--r--cmake/FlagsOverrides.cmake4
-rw-r--r--gpgfrontend.qrc1
m---------modules0
-rw-r--r--resource/lfs/icons/filter.pngbin0 -> 4328 bytes
-rw-r--r--resource/lfs/locale/ts/GpgFrontend.de_DE.ts1466
-rw-r--r--resource/lfs/locale/ts/GpgFrontend.zh_CN.ts1464
-rw-r--r--src/CMakeLists.txt993
-rw-r--r--src/GpgFrontendContext.h5
-rw-r--r--src/app.cpp23
-rw-r--r--src/cmd.cpp46
-rw-r--r--src/cmd.h2
-rw-r--r--src/core/CMakeLists.txt113
-rw-r--r--src/core/GpgConstants.h8
-rw-r--r--src/core/GpgCoreInit.cpp62
-rw-r--r--src/core/GpgFrontendCore.cpp2
-rw-r--r--src/core/GpgFrontendCore.h8
-rw-r--r--src/core/function/ArchiveFileOperator.cpp79
-rw-r--r--src/core/function/CacheManager.cpp15
-rw-r--r--src/core/function/CoreSignalStation.h6
-rw-r--r--src/core/function/DataObjectOperator.cpp20
-rw-r--r--src/core/function/GlobalSettingStation.cpp12
-rw-r--r--src/core/function/GlobalSettingStation.h2
-rw-r--r--src/core/function/KeyPackageOperator.cpp16
-rw-r--r--src/core/function/LoggerManager.cpp155
-rw-r--r--src/core/function/LoggerManager.h65
-rw-r--r--src/core/function/SecureMemoryAllocator.cpp32
-rw-r--r--src/core/function/SecureMemoryAllocator.h1
-rw-r--r--src/core/function/basic/ChannelObject.cpp2
-rw-r--r--src/core/function/basic/GpgFunctionObject.cpp17
-rw-r--r--src/core/function/basic/SingletonStorage.cpp26
-rw-r--r--src/core/function/basic/SingletonStorageCollection.cpp15
-rw-r--r--src/core/function/gpg/GpgAdvancedOperator.cpp62
-rw-r--r--src/core/function/gpg/GpgBasicOperator.cpp12
-rw-r--r--src/core/function/gpg/GpgCommandExecutor.cpp88
-rw-r--r--src/core/function/gpg/GpgContext.cpp152
-rw-r--r--src/core/function/gpg/GpgContext.h4
-rw-r--r--src/core/function/gpg/GpgFileOpera.cpp42
-rw-r--r--src/core/function/gpg/GpgKeyGetter.cpp45
-rw-r--r--src/core/function/gpg/GpgKeyGetter.h8
-rw-r--r--src/core/function/gpg/GpgKeyImportExporter.cpp26
-rw-r--r--src/core/function/gpg/GpgKeyManager.cpp152
-rw-r--r--src/core/function/gpg/GpgKeyManager.h2
-rw-r--r--src/core/function/gpg/GpgKeyOpera.cpp96
-rw-r--r--src/core/function/gpg/GpgUIDOperator.cpp10
-rw-r--r--src/core/model/DataObject.h4
-rw-r--r--src/core/model/GFDataExchanger.cpp20
-rw-r--r--src/core/model/GpgDecryptResult.cpp6
-rw-r--r--src/core/model/GpgEncryptResult.cpp6
-rw-r--r--src/core/model/GpgGenKeyInfo.cpp28
-rw-r--r--src/core/model/GpgKeyTableModel.cpp172
-rw-r--r--src/core/model/GpgKeyTableModel.h216
-rw-r--r--src/core/model/GpgKeyTableProxyModel.cpp179
-rw-r--r--src/core/model/GpgKeyTableProxyModel.h94
-rw-r--r--src/core/model/GpgSignResult.cpp6
-rw-r--r--src/core/model/SettingsObject.cpp5
-rw-r--r--src/core/module/Event.cpp50
-rw-r--r--src/core/module/Event.h16
-rw-r--r--src/core/module/GlobalModuleContext.cpp81
-rw-r--r--src/core/module/GlobalRegisterTable.cpp32
-rw-r--r--src/core/module/GlobalRegisterTableTreeModel.h7
-rw-r--r--src/core/module/Module.cpp59
-rw-r--r--src/core/module/Module.h2
-rw-r--r--src/core/module/ModuleInit.cpp29
-rw-r--r--src/core/module/ModuleInit.h6
-rw-r--r--src/core/module/ModuleManager.cpp45
-rw-r--r--src/core/module/ModuleManager.h22
-rw-r--r--src/core/thread/FileReadTask.cpp9
-rw-r--r--src/core/thread/Task.cpp38
-rw-r--r--src/core/thread/TaskRunner.cpp19
-rw-r--r--src/core/typedef/GpgTypedef.h2
-rw-r--r--src/core/utils/AsyncUtils.cpp16
-rw-r--r--src/core/utils/BuildInfoUtils.cpp7
-rw-r--r--src/core/utils/BuildInfoUtils.h7
-rw-r--r--src/core/utils/CommonUtils.cpp4
-rw-r--r--src/core/utils/CommonUtils.h8
-rw-r--r--src/core/utils/GpgUtils.cpp25
-rw-r--r--src/core/utils/IOUtils.cpp29
-rw-r--r--src/core/utils/LocalizedUtils.cpp2
-rw-r--r--src/core/utils/LogUtils.cpp59
-rw-r--r--src/core/utils/LogUtils.h155
-rw-r--r--src/init.cpp40
-rw-r--r--src/init.h7
-rw-r--r--src/main.cpp36
-rw-r--r--src/module/mods/gpg_info/CMakeLists.txt76
-rw-r--r--src/module/mods/gpg_info/GFModuleExport.h42
-rw-r--r--src/module/mods/gpg_info/GnuPGInfoGatheringModule.cpp526
-rw-r--r--src/module/mods/gpg_info/GpgInfo.cpp79
-rw-r--r--src/module/mods/gpg_info/GpgInfo.h88
-rw-r--r--src/module/mods/gpg_info/QtLoggerFmt.h68
-rw-r--r--src/module/mods/ver_check/CMakeLists.txt76
-rw-r--r--src/module/mods/ver_check/GFModuleExport.h42
-rw-r--r--src/module/mods/ver_check/QtLoggerFmt.h68
-rw-r--r--src/module/mods/ver_check/SoftwareVersion.cpp100
-rw-r--r--src/module/mods/ver_check/SoftwareVersion.h83
-rw-r--r--src/module/mods/ver_check/VersionCheckTask.cpp171
-rw-r--r--src/module/mods/ver_check/VersionCheckTask.h89
-rw-r--r--src/module/mods/ver_check/VersionCheckingModule.cpp164
-rw-r--r--src/module/sdk/GFSDKBuildInfo.h36
-rw-r--r--src/module/sdk/GFSDKLog.cpp47
-rw-r--r--src/module/sdk/GFSDKUI.cpp27
-rw-r--r--src/pinentry/CMakeLists.txt62
-rw-r--r--src/pinentry/accessibility.cpp44
-rw-r--r--src/pinentry/accessibility.h40
-rw-r--r--src/pinentry/capslock/capslock.cpp41
-rw-r--r--src/pinentry/capslock/capslock.h77
-rw-r--r--src/pinentry/capslock/capslock_unix.cpp137
-rw-r--r--src/pinentry/capslock/capslock_win.cpp26
-rw-r--r--src/pinentry/pinentry.cpp570
-rw-r--r--src/pinentry/pinentry.h339
-rw-r--r--src/pinentry/pinentry_debug.cpp31
-rw-r--r--src/pinentry/pinentry_debug.h28
-rw-r--r--src/pinentry/pinentryconfirm.cpp123
-rw-r--r--src/pinentry/pinentryconfirm.h63
-rw-r--r--src/pinentry/pinentrydialog.cpp634
-rw-r--r--src/pinentry/pinentrydialog.h170
-rw-r--r--src/pinentry/pinlineedit.cpp204
-rw-r--r--src/pinentry/pinlineedit.h60
-rw-r--r--src/pinentry/qti18n.cpp93
-rw-r--r--src/pinentry/secmem++.h91
-rw-r--r--src/sdk/CMakeLists.txt (renamed from src/module/CMakeLists.txt)35
-rw-r--r--src/sdk/GFSDK.h (renamed from src/module/sdk/GFSDK.h)0
-rw-r--r--src/sdk/GFSDKBasic.cpp (renamed from src/module/sdk/GFSDKBasic.cpp)32
-rw-r--r--src/sdk/GFSDKBasic.h (renamed from src/module/sdk/GFSDKBasic.h)27
-rw-r--r--src/sdk/GFSDKBuildInfo.h.in (renamed from src/module/sdk/GFSDKBuildInfo.h.in)0
-rw-r--r--src/sdk/GFSDKExport.h (renamed from src/module/sdk/GFSDKExport.h)0
-rw-r--r--src/sdk/GFSDKExtra.cpp (renamed from src/module/sdk/GFSDKExtra.cpp)13
-rw-r--r--src/sdk/GFSDKExtra.h (renamed from src/module/sdk/GFSDKExtra.h)0
-rw-r--r--src/sdk/GFSDKGpg.cpp (renamed from src/module/sdk/GFSDKGpg.cpp)0
-rw-r--r--src/sdk/GFSDKGpg.h (renamed from src/module/sdk/GFSDKGpg.h)0
-rw-r--r--src/sdk/GFSDKLog.cpp (renamed from src/main.h)21
-rw-r--r--src/sdk/GFSDKLog.h (renamed from src/module/sdk/GFSDKLog.h)0
-rw-r--r--src/sdk/GFSDKModule.cpp (renamed from src/module/sdk/GFSDKModule.cpp)55
-rw-r--r--src/sdk/GFSDKModule.h (renamed from src/module/sdk/GFSDKModule.h)5
-rw-r--r--src/sdk/GFSDKUI.cpp71
-rw-r--r--src/sdk/GFSDKUI.h46
-rw-r--r--src/sdk/GFSDKUtils.cpp (renamed from src/module/sdk/GFSDKUtils.cpp)0
-rw-r--r--src/sdk/GFSDKUtils.h (renamed from src/module/sdk/GFSDKUtils.h)0
-rw-r--r--src/sdk/private/CommonUtils.cpp103
-rw-r--r--src/sdk/private/CommonUtils.h (renamed from src/module/mods/gpg_info/GnuPGInfoGatheringModule.h)64
-rw-r--r--src/test/CMakeLists.txt25
-rw-r--r--src/test/GpgFrontendTest.cpp11
-rw-r--r--src/test/GpgFrontendTest.h15
-rw-r--r--src/ui/CMakeLists.txt44
-rw-r--r--src/ui/GpgFrontendApplication.cpp6
-rw-r--r--src/ui/GpgFrontendUI.cpp (renamed from src/module/sdk/GFSDKUI.h)4
-rw-r--r--src/ui/GpgFrontendUI.h17
-rw-r--r--src/ui/GpgFrontendUIInit.cpp51
-rw-r--r--src/ui/GpgFrontendUIInit.h7
-rw-r--r--src/ui/UIModuleManager.cpp104
-rw-r--r--src/ui/UIModuleManager.h104
-rw-r--r--src/ui/UserInterfaceUtils.cpp76
-rw-r--r--src/ui/UserInterfaceUtils.h15
-rw-r--r--src/ui/dialog/GeneralDialog.cpp39
-rw-r--r--src/ui/dialog/SignersPicker.cpp21
-rw-r--r--src/ui/dialog/Wizard.cpp2
-rw-r--r--src/ui/dialog/controller/GnuPGControllerDialog.cpp15
-rw-r--r--src/ui/dialog/controller/ModuleControllerDialog.cpp27
-rw-r--r--src/ui/dialog/help/AboutDialog.cpp160
-rw-r--r--src/ui/dialog/help/AboutDialog.h41
-rw-r--r--src/ui/dialog/help/GnupgTab.cpp336
-rw-r--r--src/ui/dialog/help/GnupgTab.h65
-rw-r--r--src/ui/dialog/import_export/KeyServerImportDialog.cpp9
-rw-r--r--src/ui/dialog/import_export/KeyUploadDialog.cpp4
-rw-r--r--src/ui/dialog/key_generate/KeygenDialog.cpp4
-rw-r--r--src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp4
-rw-r--r--src/ui/dialog/keypair_details/KeyPairOperaTab.cpp171
-rw-r--r--src/ui/dialog/keypair_details/KeyPairOperaTab.h12
-rw-r--r--src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp9
-rw-r--r--src/ui/dialog/keypair_details/KeyPairUIDTab.cpp2
-rw-r--r--src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp8
-rw-r--r--src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp15
-rw-r--r--src/ui/dialog/settings/SettingsAppearance.cpp7
-rw-r--r--src/ui/dialog/settings/SettingsDialog.cpp5
-rw-r--r--src/ui/dialog/settings/SettingsGeneral.cpp10
-rw-r--r--src/ui/dialog/settings/SettingsKeyServer.cpp3
-rw-r--r--src/ui/function/GenerateRevokeCertification.cpp13
-rw-r--r--src/ui/function/RaisePinentry.cpp122
-rw-r--r--src/ui/function/RaisePinentry.h60
-rw-r--r--src/ui/function/SetOwnerTrustLevel.cpp3
-rw-r--r--src/ui/main_window/GeneralMainWindow.cpp45
-rw-r--r--src/ui/main_window/KeyMgmt.cpp48
-rw-r--r--src/ui/main_window/MainWindow.cpp37
-rw-r--r--src/ui/main_window/MainWindow.h5
-rw-r--r--src/ui/main_window/MainWindowFileSlotFunction.cpp6
-rw-r--r--src/ui/main_window/MainWindowGpgOperaFunction.cpp8
-rw-r--r--src/ui/main_window/MainWindowSlotFunction.cpp28
-rw-r--r--src/ui/main_window/MainWindowSlotUI.cpp19
-rw-r--r--src/ui/main_window/MainWindowUI.cpp27
-rw-r--r--src/ui/struct/UIMountPoint.h (renamed from src/module/mods/ver_check/VersionCheckingModule.h)54
-rw-r--r--src/ui/thread/KeyServerImportTask.cpp7
-rw-r--r--src/ui/thread/ListedKeyServerTestTask.cpp3
-rw-r--r--src/ui/thread/ProxyConnectionTestTask.cpp4
-rw-r--r--src/ui/widgets/FilePage.cpp1
-rw-r--r--src/ui/widgets/FileTreeView.cpp24
-rw-r--r--src/ui/widgets/GRTTreeView.cpp2
-rw-r--r--src/ui/widgets/HelpPage.cpp7
-rw-r--r--src/ui/widgets/InfoBoardWidget.cpp2
-rw-r--r--src/ui/widgets/KeyList.cpp637
-rw-r--r--src/ui/widgets/KeyList.h208
-rw-r--r--src/ui/widgets/KeyTable.cpp149
-rw-r--r--src/ui/widgets/KeyTable.h176
-rw-r--r--src/ui/widgets/PlainTextEditorPage.cpp4
-rw-r--r--src/ui/widgets/TextEdit.cpp18
-rw-r--r--third_party/CMakeLists.txt26
m---------third_party/mimalloc0
m---------third_party/spdlog0
-rw-r--r--ui/GeneralSettings.ui7
-rw-r--r--ui/GnuPGInfo.ui163
-rw-r--r--ui/KeyList.ui17
-rw-r--r--ui/ModuleControllerDialog.ui2
218 files changed, 5920 insertions, 10296 deletions
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index f420374d..9ff1d59b 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -15,15 +15,12 @@ on:
push:
branches: [ main ]
pull_request:
- # The branches below must be a subset of the branches above
branches: [ main ]
schedule:
- cron: '19 14 * * 2'
env:
- # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Debug
- EXECUTABLE_OUTPUT_PATH: ./
jobs:
analyze:
@@ -38,9 +35,6 @@ jobs:
fail-fast: false
matrix:
language: [ 'cpp' ]
- # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
- # Learn more:
- # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
steps:
- name: Checkout repository
@@ -49,15 +43,10 @@ jobs:
lfs: 'false'
submodules: recursive
- # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
- # If you wish to specify custom queries, you can do so here or in a config file.
- # By default, queries listed here will override any specified in a config file.
- # Prefix the list here with "+" to use these queries and those in the config file.
- # queries: ./path/to/local/query, your-org/your-repo/queries@main
- name: Install Dependence
run: |
@@ -97,13 +86,13 @@ jobs:
- name: Install Qt
uses: jurplel/install-qt-action@v3
with:
- version: '6.5.3'
+ version: '6.7.2'
cache: 'true'
- name: Configure CMake && Build GpgFrontend
run: |
- cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DGPGFRONTEND_BUILD_TYPE_TEST_UI=ON
+ cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DGPGFRONTEND_BUILD_TYPE_STABLE=ON
cmake --build ${{github.workspace}}/build --config {{$env.BUILD_TYPE}} -- -v
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v2
+ uses: github/codeql-action/analyze@v3
diff --git a/.github/workflows/doxygen-genration.yml b/.github/workflows/doxygen-genration.yml
index ddb2723f..c23da8d2 100644
--- a/.github/workflows/doxygen-genration.yml
+++ b/.github/workflows/doxygen-genration.yml
@@ -4,8 +4,7 @@ on:
push:
branches: [ main, 'develop' ]
paths-ignore:
- - 'resource/locale/template/**'
- - 'manual/**'
+ - 'resource/lfs/locale/**'
- '**.md'
jobs:
diff --git a/.github/workflows/release-qt5.yml b/.github/workflows/release-qt5.yml
index f65408e8..5dbd2fab 100644
--- a/.github/workflows/release-qt5.yml
+++ b/.github/workflows/release-qt5.yml
@@ -4,20 +4,17 @@ on:
push:
branches: [ main, 'develop' ]
paths-ignore:
- - 'resource/locale/**'
- - 'manual/**'
+ - 'resource/lfs/locale/**'
- '**.md'
pull_request:
branches: [ main, 'develop' ]
paths-ignore:
- - 'resource/locale/**'
- - 'manual/**'
+ - 'resource/lfs/locale/**'
- '**.md'
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
- EXECUTABLE_OUTPUT_PATH: ./
jobs:
build:
@@ -54,8 +51,9 @@ jobs:
run: |
pacman --noconfirm -S --needed mingw-w64-x86_64-gcc mingw-w64-x86_64-make mingw-w64-x86_64-cmake autoconf
pacman --noconfirm -S --needed make texinfo automake
- pacman --noconfirm -S --needed mingw-w64-x86_64-qt5 libintl msys2-runtime-devel gettext-devel
+ pacman --noconfirm -S --needed mingw-w64-x86_64-qt5 mingw-w64-x86_64-angleproject libintl msys2-runtime-devel gettext-devel
pacman --noconfirm -S --needed mingw-w64-x86_64-ninja mingw-w64-x86_64-gnupg mingw-w64-x86_64-libarchive
+ pacman --noconfirm -S --needed mingw-w64-x86_64-gtest
if: matrix.os == 'windows-2019'
- name: Install Dependence (Linux)
@@ -122,7 +120,7 @@ jobs:
- name: Build GpgME (Windows)
shell: msys2 {0}
run: |
- git clone --depth 1 --branch gpgme-1.18.0 git://git.gnupg.org/gpgme.git ${{github.workspace}}/third_party/gpgme
+ git clone --depth 1 --branch fix/1.18.0 https://git.bktus.com/GpgFrontend/gpgme.git ${{github.workspace}}/third_party/gpgme
cd ${{github.workspace}}/third_party/gpgme
./autogen.sh
./configure --enable-maintainer-mode --enable-languages=cpp --disable-gpg-test && make -j4
@@ -140,6 +138,34 @@ jobs:
cd ${{github.workspace}}
if: matrix.os == 'ubuntu-20.04'
+ - name: Build mimalloc (Linux)
+ run: |
+ cd ${{github.workspace}}/third_party/mimalloc
+ mkdir build && cd build
+ cmake -G Ninja -DMI_SECURE=ON ..
+ ninja
+ sudo ninja install
+ if: matrix.os == 'ubuntu-20.04'
+
+ - name: Build mimalloc (Windows)
+ shell: msys2 {0}
+ run: |
+ cd $(echo "/${{github.workspace}}" | sed 's/\\/\//g' | sed 's/://')
+ cd third_party/mimalloc
+ mkdir build && cd build
+ cmake -G Ninja -DMI_SECURE=ON -DCMAKE_INSTALL_PREFIX=$MSYSTEM_PREFIX .. && ninja
+ ninja install
+ if: matrix.os == 'windows-2019'
+
+ - name: Build googletest (Linux)
+ run: |
+ cd ${{github.workspace}}/third_party/googletest
+ mkdir build && cd build
+ cmake -G Ninja -DBUILD_SHARED_LIBS=ON ..
+ ninja
+ sudo ninja install
+ if: matrix.os == 'ubuntu-20.04'
+
- name: Configure CMake & Build Binary(Windows)
shell: msys2 {0}
run: |
@@ -162,19 +188,32 @@ jobs:
cd ${{github.workspace}}/build/final-artifact
wget -c -nv https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage
chmod u+x linuxdeployqt-continuous-x86_64.AppImage
- ./linuxdeployqt-continuous-x86_64.AppImage ${{github.workspace}}/build/artifacts/AppDir/usr/share/applications/*.desktop -no-translations -extra-plugins=iconengines,platformthemes/libqgtk3.so -appimage -executable-dir=${{github.workspace}}/build/artifacts/AppDir/usr/plugins/mods/
+ ./linuxdeployqt-continuous-x86_64.AppImage ${{github.workspace}}/build/artifacts/AppDir/usr/share/applications/*.desktop -no-translations -extra-plugins=iconengines -appimage
+ echo "BUILD_TYPE_LOWER=${BUILD_TYPE,,}" >> ${GITHUB_ENV}
+ echo "SHORT_SHA=`echo ${GITHUB_SHA} | cut -c1-8`" >> ${GITHUB_ENV}
if: matrix.os == 'ubuntu-20.04'
+
+
+ - name: Copy Modules & Package (Windows)
+ shell: msys2 {0}
+ run: |
+ cd $(echo "/${{github.workspace}}" | sed 's/\\/\//g' | sed 's/://')
+ cd build
+ windeployqt --no-translations --force ./artifacts/GpgFrontend.exe
+ echo "BUILD_TYPE_LOWER=${BUILD_TYPE,,}" >> ${GITHUB_ENV}
+ echo "SHORT_SHA=`echo ${GITHUB_SHA} | cut -c1-8`" >> ${GITHUB_ENV}
+ if: matrix.os == 'windows-2019'
- name: Upload Artifact(Linux)
- uses: actions/upload-artifact@master
+ uses: actions/upload-artifact@v4
with:
- name: gpgfrontend-${{matrix.os}}-${{env.BUILD_TYPE}}-${{ github.sha }}
+ name: gpgfrontend-${{matrix.os}}-${{env.BUILD_TYPE_LOWER}}-${{ env.SHORT_SHA }}
path: ${{github.workspace}}/build/final-artifact/Gpg_Frontend*.AppImage*
if: matrix.os == 'ubuntu-20.04'
- name: Upload Artifact(Windows)
- uses: actions/upload-artifact@master
+ uses: actions/upload-artifact@v4
with:
- name: gpgfrontend-${{matrix.os}}-${{env.BUILD_TYPE}}-${{ github.sha }}
+ name: gpgfrontend-${{matrix.os}}--${{env.BUILD_TYPE_LOWER}}-${{ env.SHORT_SHA }}
path: ${{github.workspace}}/build/artifacts/*
if: matrix.os == 'windows-2019'
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 611b0333..18d41b8c 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -4,26 +4,23 @@ on:
push:
branches: [ main, 'develop' ]
paths-ignore:
- - 'resource/locale/**'
- - 'manual/**'
+ - 'resource/lfs/locale/**'
- '**.md'
pull_request:
branches: [ main, 'develop' ]
paths-ignore:
- - 'resource/locale/**'
- - 'manual/**'
+ - 'resource/lfs/locale/**'
- '**.md'
env:
- # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
+ # Customize the CMake build type here (Release, Debug, etc.)
BUILD_TYPE: Release
- EXECUTABLE_OUTPUT_PATH: ./
jobs:
build:
strategy:
matrix:
- os: [ 'ubuntu-20.04', 'macos-11', 'macos-12', 'windows-2019' ]
+ os: [ 'ubuntu-20.04', 'macos-13', 'macos-12', "macos-14", 'windows-2019' ]
runs-on: ${{ matrix.os }}
continue-on-error: true
steps:
@@ -31,7 +28,7 @@ jobs:
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- if: matrix.os == 'windows-2019' || matrix.os == 'macos-11' || matrix.os == 'macos-12'
+ if: matrix.os == 'windows-2019' || matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'
- uses: actions/checkout@v4
with:
@@ -60,8 +57,8 @@ jobs:
PP_PATH=$RUNNER_TEMP/${{secrets.GPGFRONTEND_XOCDE_PROVISIONING_PROFILE_UUID}}.provisionprofile
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
- echo -n "${{secrets.MACOS_CERTIFICATE}}" | base64 --decode --output $CERTIFICATE_PATH
- echo -n "${{secrets.GPGFRONTEND_XOCDE_PROVISIONING_PROFILE_DATA}}" | base64 --decode --output $PP_PATH
+ echo -n "${{secrets.MACOS_CERTIFICATE}}" | base64 --decode -o $CERTIFICATE_PATH
+ echo -n "${{secrets.GPGFRONTEND_XOCDE_PROVISIONING_PROFILE_DATA}}" | base64 --decode -o $PP_PATH
security create-keychain -p gpgfrontend build.keychain
security default-keychain -s build.keychain
@@ -72,21 +69,21 @@ jobs:
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
- if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
+ if: matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'
- name: Install Qt6
uses: jurplel/install-qt-action@v3
with:
- version: '6.5.3'
+ version: '6.7.2'
cache: 'true'
- if: matrix.os == 'ubuntu-20.04' || matrix.os == 'macos-11' || matrix.os == 'macos-12'
+ if: matrix.os == 'ubuntu-20.04' || matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'
- name: Install Dependence (macOS)
run: |
brew install cmake autoconf automake texinfo gettext openssl@3
- brew install ninja libarchive gpgme
+ brew install ninja libarchive gpgme googletest
brew link openssl@3 --force
- if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
+ if: matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'
- name: Set up MinGW (Windows)
uses: msys2/setup-msys2@v2
@@ -100,14 +97,9 @@ jobs:
run: |
pacman --noconfirm -S --needed mingw-w64-x86_64-gcc mingw-w64-x86_64-make mingw-w64-x86_64-cmake autoconf
pacman --noconfirm -S --needed make texinfo automake
- pacman --noconfirm -S --needed libintl msys2-runtime-devel gettext-devel
+ pacman --noconfirm -S --needed mingw-w64-x86_64-qt6 mingw-w64-x86_64-icu libintl msys2-runtime-devel gettext-devel
pacman --noconfirm -S --needed mingw-w64-x86_64-ninja mingw-w64-x86_64-gnupg mingw-w64-x86_64-libarchive
- wget https://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-icu-73.2-1-any.pkg.tar.zst
- wget https://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-qt6-base-6.5.3-1-any.pkg.tar.zst
- wget https://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-qt6-5compat-6.5.3-1-any.pkg.tar.zst
- wget https://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-qt6-svg-6.5.3-1-any.pkg.tar.zst
- wget https://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-qt6-tools-6.5.3-1-any.pkg.tar.zst
- pacman --noconfirm -U *.pkg.tar.zst
+ pacman --noconfirm -S --needed mingw-w64-x86_64-gtest
if: matrix.os == 'windows-2019'
- name: Build gpg-error (Linux)
@@ -165,7 +157,7 @@ jobs:
- name: Build GpgME (Windows)
shell: msys2 {0}
run: |
- git clone --depth 1 --branch gpgme-1.18.0 git://git.gnupg.org/gpgme.git ${{github.workspace}}/third_party/gpgme
+ git clone --depth 1 --branch fix/1.18.0 https://git.bktus.com/GpgFrontend/gpgme.git ${{github.workspace}}/third_party/gpgme
cd ${{github.workspace}}/third_party/gpgme
./autogen.sh
./configure --enable-maintainer-mode --enable-languages=cpp --disable-gpg-test && make -j4
@@ -173,19 +165,68 @@ jobs:
cd ${{github.workspace}}
if: matrix.os == 'windows-2019'
- - name: Build GpgFrontend (Linux)
- # Build your GpgFrontend with the given configuration
+ - name: Build mimalloc (Linux)
run: |
- cmake -B ${{github.workspace}}/build -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
- cmake --build ${{github.workspace}}/build --config {{$env.BUILD_TYPE}} -- -v
+ cd ${{github.workspace}}/third_party/mimalloc
+ mkdir build && cd build
+ cmake -G Ninja -DMI_SECURE=ON ..
+ ninja
+ sudo ninja install
if: matrix.os == 'ubuntu-20.04'
- - name: Build Integrated Modules (macOS)
- # Build your GpgFrontend with the given configuration
+ - name: Build mimalloc (Windows)
+ shell: msys2 {0}
+ run: |
+ cd $(echo "/${{github.workspace}}" | sed 's/\\/\//g' | sed 's/://')
+ cd third_party/mimalloc
+ mkdir build && cd build
+ cmake -G Ninja -DMI_SECURE=ON -DCMAKE_INSTALL_PREFIX=$MSYSTEM_PREFIX .. && ninja
+ ninja install
+ if: matrix.os == 'windows-2019'
+
+ - name: Build googletest (Linux)
+ run: |
+ cd ${{github.workspace}}/third_party/googletest
+ mkdir build && cd build
+ cmake -G Ninja -DBUILD_SHARED_LIBS=ON ..
+ ninja
+ sudo ninja install
+ if: matrix.os == 'ubuntu-20.04'
+
+ - name: Build & Install Full SDK
run: |
- cmake -B ${{github.workspace}}/build-mods -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DGPGFRONTEND_BUILD_MODS_ONLY=On
- cmake --build ${{github.workspace}}/build-mods --config {{$env.BUILD_TYPE}} -- -v
- if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
+ cmake -B ${{github.workspace}}/build-full-sdk -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DGPGFRONTEND_BUILD_TYPE_FULL_SDK=ON
+ cmake --build ${{github.workspace}}/build-full-sdk --config {{$env.BUILD_TYPE}} -- -v
+ sudo cmake --install ${{github.workspace}}/build-full-sdk --config {{$env.BUILD_TYPE}}
+ if: matrix.os == 'ubuntu-20.04' || matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'
+
+ - name: Build & Install Full SDK (Windows)
+ shell: msys2 {0}
+ run: |
+ cd $(echo "/${{github.workspace}}" | sed 's/\\/\//g' | sed 's/://')
+ mkdir build-full-sdk && cd build-full-sdk
+ cmake -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DGPGFRONTEND_BUILD_TYPE_FULL_SDK=ON -DCMAKE_INSTALL_PREFIX=$MSYSTEM_PREFIX ..
+ cmake --build . --config ${{env.BUILD_TYPE}} -- -j 4
+ cmake --install . --config {{$env.BUILD_TYPE}}
+ if: matrix.os == 'windows-2019'
+
+ - name: Build Integrated Modules
+ run: |
+ cmake -S ${{github.workspace}}/modules -B ${{github.workspace}}/modules/build -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/modules/build/artifacts
+ cmake --build ${{github.workspace}}/modules/build --config {{$env.BUILD_TYPE}} -- -v
+ cmake --install ${{github.workspace}}/modules/build --config {{$env.BUILD_TYPE}}
+ if: matrix.os == 'ubuntu-20.04' || matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'
+
+ - name: Build Integrated Modules (Windows)
+ shell: msys2 {0}
+ run: |
+ cd $(echo "/${{github.workspace}}" | sed 's/\\/\//g' | sed 's/://')
+ cd modules
+ mkdir build && cd build
+ cmake -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DGPGFRONTEND_BUILD_TYPE_STABLE=ON -DCMAKE_INSTALL_PREFIX=./artifacts ..
+ cmake --build . --config ${{env.BUILD_TYPE}} -- -j 4
+ cmake --install . --config {{$env.BUILD_TYPE}}
+ if: matrix.os == 'windows-2019'
- name: Build & Export GpgFrontend (macOS)
# Build your GpgFrontend with the given configuration
@@ -205,14 +246,15 @@ jobs:
xcodebuild -exportArchive -archivePath ${{github.workspace}}/build/GpgFrontend.xcarchive \
-exportOptionsPlist ${{github.workspace}}/build/ExportOptions.plist \
-exportPath ${{github.workspace}}/build/package/
- if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
+ if: matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'
- name: Copy Modules into Bundle & Deploy Qt & Code Sign (macOS)
run: |
- cmake -E copy_directory ${{github.workspace}}/build-mods/artifacts/mods ${{github.workspace}}/build/package/GpgFrontend.app/Contents/PlugIns/mods
+ codesign -s "${{secrets.GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}}" -f --deep --options=runtime --timestamp ${{github.workspace}}/modules/build/artifacts/modules/*
+ cmake -E copy_directory ${{github.workspace}}/modules/build/artifacts/modules ${{github.workspace}}/build/package/GpgFrontend.app/Contents/Modules
macdeployqt ${{github.workspace}}/build/package/GpgFrontend.app -verbose=2 -appstore-compliant -always-overwrite
- codesign -s "${{secrets.GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}}" -f --deep --options=runtime ${{github.workspace}}/build/package/GpgFrontend.app
- if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
+ codesign -s "${{secrets.GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}}" -f --deep --options=runtime --timestamp ${{github.workspace}}/build/package/GpgFrontend.app
+ if: matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'
- name: Package & Sign App Bundle (macOS)
run: |
@@ -227,7 +269,7 @@ jobs:
${{github.workspace}}/build/final-artifact/GpgFrontend-${{env.sha_short}}-x86_64.dmg
mv ${{github.workspace}}/build/GpgFrontend.app.zip \
${{github.workspace}}/build/GpgFrontend-${{env.sha_short}}-x86_64.zip
- if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
+ if: matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'
- name: Notarize Release Build (macOS)
run: |
@@ -236,43 +278,68 @@ jobs:
--team-id ${{secrets.APPLE_DEVELOPER_TEAM_ID}} \
--password ${{secrets.APPLE_DEVELOPER_ID_SECRET}} \
${{github.workspace}}/build/GpgFrontend-${{env.sha_short}}-x86_64.zip
- if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
+ echo "BUILD_TYPE_LOWER=$(echo ${BUILD_TYPE} | tr '[:upper:]' '[:lower:]')" >> ${GITHUB_ENV}
+ echo "SHORT_SHA=`echo ${GITHUB_SHA} | cut -c1-8`" >> ${GITHUB_ENV}
+ if: matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'
+
+ - name: Build GpgFrontend (Linux)
+ # Build your GpgFrontend with the given configuration
+ run: |
+ cmake -B ${{github.workspace}}/build -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DDGPGFRONTEND_BUILD_TYPE_ONLY_APPLICATION=ON
+ cmake --build ${{github.workspace}}/build --config {{$env.BUILD_TYPE}} -- -v
+ if: matrix.os == 'ubuntu-20.04'
- - name: Package App Image (Linux)
+ - name: Copy Modules & Package App Image (Linux)
run: |
+ cmake -E copy_directory ${{github.workspace}}/modules/build/artifacts/modules ${{github.workspace}}/build/artifacts/AppDir/usr/modules
mkdir ${{github.workspace}}/build/final-artifact
cd ${{github.workspace}}/build/final-artifact
wget -c -nv https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage
chmod u+x linuxdeployqt-continuous-x86_64.AppImage
- ./linuxdeployqt-continuous-x86_64.AppImage ${{github.workspace}}/build/artifacts/AppDir/usr/share/applications/*.desktop -no-translations -extra-plugins=iconengines,platformthemes/libqgtk3.so -appimage -executable-dir=${{github.workspace}}/build/artifacts/AppDir/usr/plugins/mods/
+ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
+ ./linuxdeployqt-continuous-x86_64.AppImage ${{github.workspace}}/build/artifacts/AppDir/usr/share/applications/*.desktop -no-translations -extra-plugins=iconengines -appimage -executable-dir=${{github.workspace}}/build/artifacts/AppDir/usr/modules/
+ echo "BUILD_TYPE_LOWER=${BUILD_TYPE,,}" >> ${GITHUB_ENV}
+ echo "SHORT_SHA=`echo ${GITHUB_SHA} | cut -c1-8`" >> ${GITHUB_ENV}
if: matrix.os == 'ubuntu-20.04'
- - name: Configure CMake & Build Binary(Windows)
+ - name: Configure CMake & Build Application (Windows)
shell: msys2 {0}
run: |
cd $(echo "/${{github.workspace}}" | sed 's/\\/\//g' | sed 's/://')
mkdir build && cd build
- cmake -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DGPGFRONTEND_BUILD_TYPE_STABLE=ON ..
+ cmake -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DGPGFRONTEND_BUILD_TYPE_ONLY_APPLICATION=ON ..
cmake --build . --config ${{env.BUILD_TYPE}} -- -j 4
if: matrix.os == 'windows-2019'
+
+ - name: Copy Modules & Package (Windows)
+ shell: msys2 {0}
+ run: |
+ cd $(echo "/${{github.workspace}}" | sed 's/\\/\//g' | sed 's/://')
+ mkdir -p build/artifacts/modules
+ cp -r modules/build/artifacts/bin/* build/artifacts/modules
+ cd build
+ windeployqt-qt6 --no-translations --force ./artifacts/GpgFrontend.exe
+ echo "BUILD_TYPE_LOWER=${BUILD_TYPE,,}" >> ${GITHUB_ENV}
+ echo "SHORT_SHA=`echo ${GITHUB_SHA} | cut -c1-8`" >> ${GITHUB_ENV}
+ if: matrix.os == 'windows-2019'
- - name: Upload Artifact(Linux)
+ - name: Upload Artifact (Linux)
uses: actions/upload-artifact@master
with:
- name: gpgfrontend-${{matrix.os}}-${{env.BUILD_TYPE}}-${{ github.sha }}
+ name: gpgfrontend-${{matrix.os}}-${{env.BUILD_TYPE_LOWER}}-${{env.SHORT_SHA}}
path: ${{github.workspace}}/build/final-artifact/Gpg_Frontend*.AppImage*
if: matrix.os == 'ubuntu-20.04'
- - name: Upload Artifact(macOS)
+ - name: Upload Artifact (macOS)
uses: actions/upload-artifact@master
with:
- name: gpgfrontend-${{matrix.os}}-${{env.BUILD_TYPE}}-${{ github.sha }}
+ name: gpgfrontend-${{matrix.os}}-${{env.BUILD_TYPE_LOWER}}-${{env.SHORT_SHA}}
path: ${{github.workspace}}/build/final-artifact/*
- if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
+ if: matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'
- - name: Upload Artifact(Windows)
+ - name: Upload Artifact (Windows)
uses: actions/upload-artifact@master
with:
- name: gpgfrontend-${{matrix.os}}-${{env.BUILD_TYPE}}-${{ github.sha }}
+ name: gpgfrontend-${{matrix.os}}-${{env.BUILD_TYPE_LOWER}}-${{env.SHORT_SHA}}
path: ${{github.workspace}}/build/artifacts/*
if: matrix.os == 'windows-2019'
diff --git a/.gitignore b/.gitignore
index 2355efd0..4ec64539 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@ src/GpgFrontendBuildInfo.h
src/GpgFrontendBuildInstallInfo.h
src/core/GpgFrontendCoreExport.h
src/ui/GpgFrontendUIExport.h
+src/sdk/GFSDKBuildInfo.h
docs/
# gettext
diff --git a/.gitmodules b/.gitmodules
index 6d7f2301..884e10f7 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,9 +1,6 @@
[submodule "third_party/qt-aes"]
path = third_party/qt-aes
url = https://github.com/bricke/Qt-AES.git
-[submodule "third_party/spdlog"]
- path = third_party/spdlog
- url = https://github.com/gabime/spdlog.git
[submodule "third_party/mimalloc"]
path = third_party/mimalloc
url = https://github.com/microsoft/mimalloc.git
@@ -16,3 +13,6 @@
[submodule "third_party/qttranslations"]
path = third_party/qttranslations
url = https://github.com/qt/qttranslations.git
+[submodule "modules"]
+ path = modules
+ url = https://github.com/saturneric/GpgFrontend-Modules.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5c3a4f88..259457a1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -26,19 +26,20 @@
cmake_minimum_required(VERSION 3.16)
message(STATUS "Current Generator: ${CMAKE_GENERATOR}")
+
if(CMAKE_GENERATOR STREQUAL "Xcode")
- set(CMAKE_USER_MAKE_RULES_OVERRIDE "${CMAKE_SOURCE_DIR}/cmake/FlagsOverridesXcode.cmake")
- set(XCODE_BUILD 1)
+ set(CMAKE_USER_MAKE_RULES_OVERRIDE "${CMAKE_SOURCE_DIR}/cmake/FlagsOverridesXcode.cmake")
+ set(XCODE_BUILD 1)
else()
- set(CMAKE_USER_MAKE_RULES_OVERRIDE "${CMAKE_SOURCE_DIR}/cmake/FlagsOverrides.cmake")
+ set(CMAKE_USER_MAKE_RULES_OVERRIDE "${CMAKE_SOURCE_DIR}/cmake/FlagsOverrides.cmake")
endif()
# define project
-project(GpgFrontend
- VERSION 2.1.3
- DESCRIPTION "GpgFrontend is a free, open-source, robust yet user-friendly, compact and cross-platform tool for OpenPGP encryption."
- HOMEPAGE_URL "https://gpgfrontend.bktus.com"
- LANGUAGES CXX)
+project(GpgFrontend
+ VERSION 2.1.4
+ DESCRIPTION "GpgFrontend is a free, open-source, robust yet user-friendly, compact and cross-platform tool for OpenPGP encryption."
+ HOMEPAGE_URL "https://gpgfrontend.bktus.com"
+ LANGUAGES CXX)
# show cmake version
message(STATUS "GpgFrontend Build Configuration Started CMAKE Version ${CMAKE_VERSION}")
@@ -54,21 +55,27 @@ include(CheckCXXSourceCompiles)
# generate compile_commands.json
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
-# options
+# build type options
option(GPGFRONTEND_BUILD_TYPE_TEST_CORE
- "Only compile the core and generate the unit test program" OFF)
+ "Only compile the core and generate the unit test program" OFF)
option(GPGFRONTEND_BUILD_TYPE_TEST_CORE_AND_COVERAGE
- "Compile only the core and generate unit test programs that can evaluate test coverage" OFF)
+ "Compile only the core and generate unit test programs that can evaluate test coverage" OFF)
option(GPGFRONTEND_BUILD_TYPE_TEST_UI
- "Only generate a graphical interface with basic functions" OFF)
+ "Only generate a graphical interface with basic functions" OFF)
option(GPGFRONTEND_BUILD_TYPE_TEST_ALL
- "Generate a graphical interface with all functions" OFF)
+ "Generate a graphical interface with all functions" OFF)
option(GPGFRONTEND_BUILD_TYPE_STABLE
- "Generate release version" ON)
+ "Generate release version" ON)
+option(GPGFRONTEND_BUILD_TYPE_FULL_SDK "Build and install all headers and libs exclude application" OFF)
+option(GPGFRONTEND_BUILD_TYPE_ONLY_SDK "Build and install sdk headers and libs" OFF)
+option(GPGFRONTEND_BUILD_TYPE_ONLY_APPLICATION "Generate a usable SDK" OFF)
+
+# function or mode options
option(GPGFRONTEND_QT5_BUILD "Swith to Qt5 building mode" OFF)
option(GPGFRONTEND_GENERATE_LINUX_INSTALL_SOFTWARE "Generate an installable version" OFF)
-option(GPGFRONTEND_BUILD_MODS_ONLY "Build Modules Only" OFF)
+option(GPGFRONTEND_ENABLE_ASAN "Enable ASAN" OFF)
+# xcode options
option(GPGFRONTEND_XCODE_TEAM_ID "GpgFrontend Apple Team ID" "NONE")
option(GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY "GpgFrontend Signing Certificate" "NONE")
option(GPGFRONTEND_XOCDE_APPID "GpgFrontend Apple AppID" "NONE")
@@ -76,100 +83,122 @@ option(GPGFRONTEND_XOCDE_PROVISIONING_PROFILE_UUID "GpgFrontend ProvisioningProf
option(GPGFRONTEND_XOCDE_ENABLE_SANDBOX "Enable SandBox For Xcode Build" OFF)
# analyse options
-if (GPGFRONTEND_BUILD_TYPE_TEST_CORE)
- set(CMAKE_BUILD_TYPE "Debug")
- set(GPGFRONTEND_BUILD_CONFIG "test_core")
-endif ()
-
-if (GPGFRONTEND_BUILD_TYPE_TEST_CORE_AND_COVERAGE)
- set(CMAKE_BUILD_TYPE "Debug")
- set(GPGFRONTEND_BUILD_CONFIG "test_core_coverage")
-endif ()
-
-if (GPGFRONTEND_BUILD_TYPE_TEST_UI)
- set(CMAKE_BUILD_TYPE "Debug")
- set(GPGFRONTEND_BUILD_CONFIG "test_ui")
-endif ()
-
-if (GPGFRONTEND_BUILD_TYPE_TEST_ALL)
- set(CMAKE_BUILD_TYPE "Debug")
- set(GPGFRONTEND_BUILD_CONFIG "test_all")
-endif ()
+if(GPGFRONTEND_BUILD_TYPE_TEST_CORE)
+ set(CMAKE_BUILD_TYPE "Debug")
+ set(GPGFRONTEND_BUILD_CONFIG "test_core")
+endif()
+
+if(GPGFRONTEND_BUILD_TYPE_TEST_CORE_AND_COVERAGE)
+ set(CMAKE_BUILD_TYPE "Debug")
+ set(GPGFRONTEND_BUILD_CONFIG "test_core_coverage")
+endif()
+
+if(GPGFRONTEND_BUILD_TYPE_TEST_UI)
+ set(CMAKE_BUILD_TYPE "Debug")
+ set(GPGFRONTEND_BUILD_CONFIG "test_ui")
+endif()
+
+if(GPGFRONTEND_BUILD_TYPE_TEST_ALL)
+ set(CMAKE_BUILD_TYPE "Debug")
+ set(GPGFRONTEND_BUILD_CONFIG "test_all")
+endif()
# Specify compilation mode
message(STATUS "Switch Build Configure STABLE_BUILD_APPLICATION")
set(STABLE_BUILD_APPLICATION 1)
# stable features
-if (GPGFRONTEND_BUILD_TYPE_STABLE)
+if(GPGFRONTEND_BUILD_TYPE_STABLE)
+ set(GPGFRONTEND_BUILD_TYPE_TEST_CORE 0)
+ set(GPGFRONTEND_BUILD_TYPE_TEST_CORE_AND_COVERAGE 0)
+ set(GPGFRONTEND_BUILD_TYPE_TEST_UI 0)
+ set(GPGFRONTEND_BUILD_TYPE_TEST_ALL 0)
+ unset(GPGFRONTEND_BUILD_CONFIG)
+
+ set(STABLE_BUILD_APPLICATION 1)
+endif()
- set(GPGFRONTEND_BUILD_TYPE_TEST_CORE 0)
- set(GPGFRONTEND_BUILD_TYPE_TEST_CORE_AND_COVERAGE 0)
- set(GPGFRONTEND_BUILD_TYPE_TEST_UI 0)
- set(GPGFRONTEND_BUILD_TYPE_TEST_ALL 0)
- unset(GPGFRONTEND_BUILD_CONFIG)
+# linux package build
+if(GPGFRONTEND_GENERATE_LINUX_INSTALL_SOFTWARE)
+ set(GPGFRONTEND_BUILD_TYPE_TEST_CORE 0)
+ set(GPGFRONTEND_BUILD_TYPE_TEST_CORE_AND_COVERAGE 0)
+ set(GPGFRONTEND_BUILD_TYPE_TEST_UI 0)
+ set(GPGFRONTEND_BUILD_TYPE_TEST_ALL 0)
+ unset(GPGFRONTEND_BUILD_CONFIG)
+
+ set(LINUX_INSTALL_SOFTWARE 1)
+endif()
- set(STABLE_BUILD_APPLICATION 1)
-endif ()
+if(GPGFRONTEND_BUILD_TYPE_FULL_SDK)
+ set(GPGFRONTEND_BUILD_TYPE_TEST_CORE 0)
+ set(GPGFRONTEND_BUILD_TYPE_TEST_CORE_AND_COVERAGE 0)
+ set(GPGFRONTEND_BUILD_TYPE_TEST_UI 0)
+ set(GPGFRONTEND_BUILD_TYPE_TEST_ALL 0)
+ unset(GPGFRONTEND_BUILD_CONFIG)
-# linux package build
-if (GPGFRONTEND_GENERATE_LINUX_INSTALL_SOFTWARE)
-
- set(GPGFRONTEND_BUILD_TYPE_TEST_CORE 0)
- set(GPGFRONTEND_BUILD_TYPE_TEST_CORE_AND_COVERAGE 0)
- set(GPGFRONTEND_BUILD_TYPE_TEST_UI 0)
- set(GPGFRONTEND_BUILD_TYPE_TEST_ALL 0)
- unset(GPGFRONTEND_BUILD_CONFIG)
-
- set(LINUX_INSTALL_SOFTWARE 1)
-endif ()
-
-if (GPGFRONTEND_BUILD_MODS_ONLY)
- set(GPGFRONTEND_BUILD_TYPE_TEST_CORE 0)
- set(GPGFRONTEND_BUILD_TYPE_TEST_CORE_AND_COVERAGE 0)
- set(GPGFRONTEND_BUILD_TYPE_TEST_UI 0)
- set(GPGFRONTEND_BUILD_TYPE_TEST_ALL 0)
- unset(GPGFRONTEND_BUILD_CONFIG)
-
- set(STABLE_BUILD_APPLICATION 0)
- set(BUILD_MODS_ONLY 1)
+ set(STABLE_BUILD_APPLICATION 0)
+ set(STABLE_BUILD_FULL_SDK 1)
+endif()
+
+if(GPGFRONTEND_BUILD_TYPE_ONLY_SDK)
+ set(GPGFRONTEND_BUILD_TYPE_TEST_CORE 0)
+ set(GPGFRONTEND_BUILD_TYPE_TEST_CORE_AND_COVERAGE 0)
+ set(GPGFRONTEND_BUILD_TYPE_TEST_UI 0)
+ set(GPGFRONTEND_BUILD_TYPE_TEST_ALL 0)
+ unset(GPGFRONTEND_BUILD_CONFIG)
+
+ set(STABLE_BUILD_APPLICATION 0)
+ set(STABLE_BUILD_ONLY_SDK 1)
+endif()
+
+if(GPGFRONTEND_BUILD_TYPE_ONLY_APPLICATION)
+ set(GPGFRONTEND_BUILD_TYPE_TEST_CORE 0)
+ set(GPGFRONTEND_BUILD_TYPE_TEST_CORE_AND_COVERAGE 0)
+ set(GPGFRONTEND_BUILD_TYPE_TEST_UI 0)
+ set(GPGFRONTEND_BUILD_TYPE_TEST_ALL 0)
+ unset(GPGFRONTEND_BUILD_CONFIG)
+
+ set(STABLE_BUILD_APPLICATION 0)
+ set(STABLE_BUILD_ONLY_APPLICATION 1)
endif()
# C++
# options for ccache
find_program(CCACHE_FOUND ccache)
+
if(CCACHE_FOUND)
- set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
- set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
+ set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
+ set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
endif(CCACHE_FOUND)
# detect compiler
-if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
- # using clang
- if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0)
- message(FATAL_ERROR "Clang version must be at least 9.0!")
- endif()
- message(STATUS "Build System Using Compiler CLANG, VERSION: ${CMAKE_CXX_COMPILER_VERSION}")
- set(USING_COMPILER_CLANG 1)
-
-elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
- # using gcc
- if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0)
- message(FATAL_ERROR "GCC version must be at least 8.0!")
- endif()
- message(STATUS "Build System Using Compiler GCC, VERSION: ${CMAKE_CXX_COMPILER_VERSION}")
- set(USING_COMPILER_GCC 1)
-
-elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
- # using Intel C++
- message(FATAL_ERROR "Intel C++ is not supported.")
-
-elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
- # using Visual Studio C++
- message(FATAL_ERROR "MSVC is not supported.")
-endif ()
-
+if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+ # using clang
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0)
+ message(FATAL_ERROR "Clang version must be at least 9.0!")
+ endif()
+
+ message(STATUS "Build System Using Compiler CLANG, VERSION: ${CMAKE_CXX_COMPILER_VERSION}")
+ set(USING_COMPILER_CLANG 1)
+
+elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+ # using gcc
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0)
+ message(FATAL_ERROR "GCC version must be at least 8.0!")
+ endif()
+
+ message(STATUS "Build System Using Compiler GCC, VERSION: ${CMAKE_CXX_COMPILER_VERSION}")
+ set(USING_COMPILER_GCC 1)
+
+elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
+ # using Intel C++
+ message(FATAL_ERROR "Intel C++ is not supported.")
+
+elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
+ # using Visual Studio C++
+ message(FATAL_ERROR "MSVC is not supported.")
+endif()
# Using Standard C++-17 (Consider compatibility)
set(CMAKE_CXX_STANDARD 17)
@@ -182,29 +211,41 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# Check Env Variables Before Configuring
+if(NOT CMAKE_BUILD_TYPE)
+ set(CMAKE_BUILD_TYPE "Release")
+endif()
-if (NOT CMAKE_BUILD_TYPE)
- set(CMAKE_BUILD_TYPE "Release")
-endif ()
-
-if (CMAKE_BUILD_TYPE STREQUAL "Release")
- add_compile_definitions(RELEASE)
+if(CMAKE_BUILD_TYPE STREQUAL "Release")
+ add_compile_definitions(RELEASE)
else()
- add_compile_definitions(DEBUG)
+ add_compile_definitions(DEBUG)
endif()
# use xcode archive build at macos release at default
-if (CMAKE_BUILD_TYPE STREQUAL "Release" AND APPLE)
- set(GPGFRONTEND_GENERATE_LINUX_INSTALL_SOFTWARE 0)
- set(LINUX_INSTALL_SOFTWARE 0)
+if(CMAKE_BUILD_TYPE STREQUAL "Release" AND APPLE)
+ set(GPGFRONTEND_GENERATE_LINUX_INSTALL_SOFTWARE 0)
+ set(LINUX_INSTALL_SOFTWARE 0)
- set(GPGFRONTEND_BUILD_TYPE_TEST_CORE 0)
- set(GPGFRONTEND_BUILD_TYPE_TEST_CORE_AND_COVERAGE 0)
- set(GPGFRONTEND_BUILD_TYPE_TEST_UI 0)
- set(GPGFRONTEND_BUILD_TYPE_TEST_ALL 0)
+ set(GPGFRONTEND_BUILD_TYPE_TEST_CORE 0)
+ set(GPGFRONTEND_BUILD_TYPE_TEST_CORE_AND_COVERAGE 0)
+ set(GPGFRONTEND_BUILD_TYPE_TEST_UI 0)
+ set(GPGFRONTEND_BUILD_TYPE_TEST_ALL 0)
- unset(GPGFRONTEND_BUILD_CONFIG)
-endif ()
+ unset(GPGFRONTEND_BUILD_CONFIG)
+endif()
+
+# if enable ASAN
+if(GPGFRONTEND_ENABLE_ASAN)
+ # check compiler
+ if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+ message(FATAL_ERROR "Use GPGFRONTEND_ENABLE_ASAN only when using the clang compiler.")
+ endif()
+
+ add_compile_options(-fsanitize=address -fsanitize-recover=address)
+ add_link_options(-fsanitize=address -fsanitize-recover=address)
+
+ set(ENABLE_ASAN 1)
+endif()
set(AppName GpgFrontend)
@@ -212,22 +253,23 @@ set(AppName GpgFrontend)
set(GIT_COMMIT_HASH "")
set(GIT_BRANCH_NAME "")
find_package(Git QUIET)
-if (GIT_FOUND)
- execute_process(
- COMMAND ${GIT_EXECUTABLE} log -1 --pretty=format:%H
- OUTPUT_VARIABLE GIT_COMMIT_HASH
- OUTPUT_STRIP_TRAILING_WHITESPACE
- ERROR_QUIET
- WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
- )
- execute_process(
- COMMAND ${GIT_EXECUTABLE} symbolic-ref --short -q HEAD
- OUTPUT_VARIABLE GIT_BRANCH_NAME
- OUTPUT_STRIP_TRAILING_WHITESPACE
- ERROR_QUIET
- WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
- )
-endif ()
+
+if(GIT_FOUND)
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} log -1 --pretty=format:%H
+ OUTPUT_VARIABLE GIT_COMMIT_HASH
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ )
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} symbolic-ref --short -q HEAD
+ OUTPUT_VARIABLE GIT_BRANCH_NAME
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ )
+endif()
set(BUILD_VERSION ${PROJECT_VERSION}_${CMAKE_SYSTEM}_${CMAKE_SYSTEM_PROCESSOR}_${CMAKE_BUILD_TYPE})
set(GIT_VERSION ${GIT_BRANCH_NAME}_${GIT_COMMIT_HASH})
@@ -242,132 +284,127 @@ message(STATUS "GpgFrontend Build Version ${BUILD_VERSION}")
message(STATUS "GpgFrontend Git Repo Version ${GIT_VERSION}")
# support for dymatic libraries
-include (GenerateExportHeader)
+include(GenerateExportHeader)
# Windows
-IF (MINGW)
- message(STATUS "GpgFrontend Configuration For OS Platform Microsoft Windows")
- message(STATUS "Build Environment MINGW")
-
- set(OS_PLATFORM 0)
- add_definitions(-DWINDOWS)
-
- include_directories(
- ${CMAKE_CURRENT_SOURCE_DIR}/src
- ${CMAKE_CURRENT_SOURCE_DIR}/third_party
- /mingw64/include
- )
- link_directories(
- ${CMAKE_SOURCE_DIR}/lib/mingw
- /mingw64/lib
- )
+IF(MINGW)
+ message(STATUS "GpgFrontend Configuration For OS Platform Microsoft Windows")
+ message(STATUS "Build Environment MINGW")
+
+ set(OS_PLATFORM 0)
+ add_definitions(-DWINDOWS)
+
+ include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}/src
+ ${CMAKE_CURRENT_SOURCE_DIR}/third_party
+ /mingw64/include
+ )
+ link_directories(
+ ${CMAKE_SOURCE_DIR}/lib/mingw
+ /mingw64/lib
+ )
+
+ # Http Request User Agent
+ set(HTTP_REQUEST_USER_AGENT "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0")
+endif()
- # Http Request User Agent
- set(HTTP_REQUEST_USER_AGENT "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0")
+# macOS
+if(APPLE)
+ message(STATUS "GpgFrontend Configuration For OS Platform MacOS")
-endif ()
+ set(OS_PLATFORM 1)
+ ADD_DEFINITIONS(-DMACOS)
-# macOS
-if (APPLE)
- message(STATUS "GpgFrontend Configuration For OS Platform MacOS")
-
- set(OS_PLATFORM 1)
- ADD_DEFINITIONS(-DMACOS)
-
- if (XCODE_BUILD)
- set(XCODE_CODE_SIGN_IDENTITY "\"${XCODE_CODE_SIGN_IDENTITY}\"")
- message(STATUS "XCODE_CODE_SIGN_IDENTITY ${XCODE_CODE_SIGN_IDENTITY}")
- if (APPLE_SANDBOX)
- add_compile_definitions(APPLE_SANDBOX)
- endif ()
- endif ()
-
- include_directories(
- ${CMAKE_CURRENT_SOURCE_DIR}/src
- ${CMAKE_CURRENT_SOURCE_DIR}/third_party
- /usr/local/include
- /opt/homebrew/include
- )
- link_directories(
- /usr/local/lib
- /opt/homebrew/lib
- )
-
- # Http Request User Agent
- set(HTTP_REQUEST_USER_AGENT "Mozilla/5.0 (Macintosh; Intel Mac OS X 14.3; rv:123.0) Gecko/20100101 Firefox/123.0")
-
-endif ()
-
-if (UNIX AND NOT APPLE)
- set(LINUX TRUE)
-endif ()
-
-if (LINUX)
-
- message(STATUS "GpgFrontend Configuration For OS Platform Linux")
-
- set(OS_PLATFORM 2)
- add_compile_definitions(LINUX)
-
- # Get Env Info
- find_program(UNAME_PROGRAM uname)
- if(UNAME_PROGRAM)
- execute_process(COMMAND ${UNAME_PROGRAM} OUTPUT_VARIABLE SYSTEM_NAME OUTPUT_STRIP_TRAILING_WHITESPACE)
- endif()
+ if(XCODE_BUILD)
+ set(XCODE_CODE_SIGN_IDENTITY "\"${XCODE_CODE_SIGN_IDENTITY}\"")
+ message(STATUS "XCODE_CODE_SIGN_IDENTITY ${XCODE_CODE_SIGN_IDENTITY}")
- if(USING_COMPILER_CLANG)
- add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-stdlib=libstdc++>)
+ if(APPLE_SANDBOX)
+ add_compile_definitions(APPLE_SANDBOX)
endif()
+ endif()
+
+ include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}/src
+ ${CMAKE_CURRENT_SOURCE_DIR}/third_party
+ /usr/local/include
+ /opt/homebrew/include
+ )
+ link_directories(
+ /usr/local/lib
+ /opt/homebrew/lib
+ )
+
+ # Http Request User Agent
+ set(HTTP_REQUEST_USER_AGENT "Mozilla/5.0 (Macintosh; Intel Mac OS X 14.3; rv:123.0) Gecko/20100101 Firefox/123.0")
+endif()
- if(SYSTEM_NAME STREQUAL "FreeBSD")
- message(STATUS "FreeBSD BOX")
- add_compile_definitions(FREEBSD)
- set(FREEBSD TRUE)
- endif()
+if(UNIX AND NOT APPLE)
+ set(LINUX TRUE)
+endif()
- include_directories(
- ${CMAKE_CURRENT_SOURCE_DIR}/src
- ${CMAKE_CURRENT_SOURCE_DIR}/third_party
- /usr/include
- /usr/local/include
- )
- link_directories(${CMAKE_CURRENT_SOURCE_DIR}/lib/)
- link_directories(
- /lib/
- /usr/lib/
- /usr/local/lib/
- )
-
- # Http Request User Agent
- set(HTTP_REQUEST_USER_AGENT "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:123.0) Gecko/20100101 Firefox/123.0")
-
-endif ()
-
-if (LINUX_INSTALL_SOFTWARE)
- message(STATUS "Linux Install Traget ${CMAKE_INSTALL_PREFIX}")
- include(GNUInstallDirs)
- set(APP_INSTALL_FLAG LINUX_INSTALL)
- add_compile_definitions(LINUX_INSTALL_BUILD)
-else ()
- set(APP_INSTALL_FLAG BUNDLE)
-endif ()
-
-if (GPGFRONTEND_QT5_BUILD)
-
- add_compile_definitions(QT5_BUILD)
-
- # Introduce Qt
- # Support Qt version: 5.15.x
- find_package(Qt5 5.15 COMPONENTS Core Widgets PrintSupport Network LinguistTools REQUIRED)
+if(LINUX)
+ message(STATUS "GpgFrontend Configuration For OS Platform Linux")
+
+ set(OS_PLATFORM 2)
+ add_compile_definitions(LINUX)
+
+ # Get Env Info
+ find_program(UNAME_PROGRAM uname)
+
+ if(UNAME_PROGRAM)
+ execute_process(COMMAND ${UNAME_PROGRAM} OUTPUT_VARIABLE SYSTEM_NAME OUTPUT_STRIP_TRAILING_WHITESPACE)
+ endif()
+
+ if(USING_COMPILER_CLANG)
+ add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-stdlib=libstdc++>)
+ endif()
+
+ if(SYSTEM_NAME STREQUAL "FreeBSD")
+ message(STATUS "FreeBSD BOX")
+ add_compile_definitions(FREEBSD)
+ set(FREEBSD TRUE)
+ endif()
+
+ include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}/src
+ ${CMAKE_CURRENT_SOURCE_DIR}/third_party
+ /usr/include
+ /usr/local/include
+ )
+ link_directories(${CMAKE_CURRENT_SOURCE_DIR}/lib/)
+ link_directories(
+ /lib/
+ /usr/lib/
+ /usr/local/lib/
+ )
+
+ # Http Request User Agent
+ set(HTTP_REQUEST_USER_AGENT "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:123.0) Gecko/20100101 Firefox/123.0")
+endif()
+if(LINUX_INSTALL_SOFTWARE)
+ message(STATUS "Linux Install Traget ${CMAKE_INSTALL_PREFIX}")
+ include(GNUInstallDirs)
+ set(APP_INSTALL_FLAG LINUX_INSTALL)
+ add_compile_definitions(LINUX_INSTALL_BUILD)
else()
+ set(APP_INSTALL_FLAG BUNDLE)
+endif()
+
+if(GPGFRONTEND_QT5_BUILD)
+ add_compile_definitions(QT5_BUILD)
- add_compile_definitions(QT6_BUILD)
+ # Introduce Qt
+ # Support Qt version: 5.15.x
+ find_package(Qt5 5.15 COMPONENTS Core Widgets PrintSupport Network LinguistTools REQUIRED)
- # Introduce Qt
- # Support Qt version: 6.x
- find_package(Qt6 6 COMPONENTS Core Widgets PrintSupport Network LinguistTools REQUIRED)
+else()
+ add_compile_definitions(QT6_BUILD)
+ # Introduce Qt
+ # Support Qt version: 6.x
+ find_package(Qt6 6 COMPONENTS Core Widgets PrintSupport Network LinguistTools REQUIRED)
endif()
# Qt configuration
@@ -378,28 +415,43 @@ set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC_OPTIONS "--compress;9")
set(CMAKE_AUTOUIC_SEARCH_PATHS ${CMAKE_AUTOUIC_SEARCH_PATHS} ${CMAKE_SOURCE_DIR}/ui)
-if (STABLE_BUILD_APPLICATION)
- message("[+] Build Stable Application")
- set(BUILD_CORE 1)
- set(BUILD_UI 1)
- set(BUILD_MODULE 1)
- set(BUILD_TEST 1)
- set(BUILD_APPLICATION 1)
- set(SUPPORT_MULTI_LANG 1)
-elseif (BUILD_MODS_ONLY)
- message("[+] Build Mods")
- set(BUILD_CORE 1)
- set(BUILD_MODULE 1)
-endif ()
+if(STABLE_BUILD_APPLICATION)
+ message("[*] Build Stable Application")
+ set(BUILD_CORE 1)
+ set(BUILD_UI 1)
+ set(BUILD_TEST 1)
+ set(BUILD_SDK 1)
+ set(BUILD_APPLICATION 1)
+ set(SUPPORT_MULTI_LANG 1)
+elseif(STABLE_BUILD_ONLY_SDK)
+ message("[*] Build SDK")
+ set(BUILD_CORE 1)
+ set(BUILD_UI 1)
+ set(BUILD_SDK 1)
+elseif(STABLE_BUILD_FULL_SDK)
+ message("[*] Build All Headers and Libs (SDK fully build)")
+ set(BUILD_CORE 1)
+ set(BUILD_UI 1)
+ set(BUILD_TEST 1)
+ set(BUILD_SDK 1)
+elseif(GPGFRONTEND_BUILD_TYPE_ONLY_APPLICATION)
+ message("[*] Build executable only")
+ set(BUILD_CORE 0)
+ set(BUILD_UI 0)
+ set(BUILD_TEST 0)
+ set(BUILD_SDK 0)
+ set(BUILD_APPLICATION 1)
+ set(SUPPORT_MULTI_LANG 1)
+endif()
# For instance in order to select the highest version one
SET(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
-if (SUPPORT_MULTI_LANG)
- add_compile_definitions(SUPPORT_MULTI_LANG)
-endif ()
+if(SUPPORT_MULTI_LANG)
+ add_compile_definitions(SUPPORT_MULTI_LANG)
+endif()
# Output Env Variables
message(STATUS "Build Type: ${CMAKE_BUILD_TYPE}")
diff --git a/README.md b/README.md
index 57cddc6e..67851e15 100644
--- a/README.md
+++ b/README.md
@@ -33,6 +33,7 @@ GpgFrontend is **PERMANENTLY FREE** of charge. However, you can support us by
- [Developer Document](#developer-document)
- [Language Support](#language-support)
- [Supported Languages](#supported-languages)
+ - [Modules](#modules)
- [Contact](#contact)
- [Contributing \& Bugs Report](#contributing--bugs-report)
- [Project Maintainer](#project-maintainer)
@@ -42,7 +43,10 @@ GpgFrontend is **PERMANENTLY FREE** of charge. However, you can support us by
## User Manual
GpgFrontend provides documentations on its main features. If you want to know how to install, please
-read the [User Manual](https://www.gpgfrontend.bktus.com/#/quick-start) instead of README.
+read the [User Manual](https://www.gpgfrontend.bktus.com/overview/glance) instead of README.
+
+The code for the user manual is maintained in [this
+repository](https://github.com/saturneric/GpgFrontend-Manual.git).
## Developer Document
@@ -51,11 +55,14 @@ latest develop code. [Developer Document](https://doxygen.gpgfrontend.bktus.com)
will help you understand the source code and get involved more quickly in the
process of contributing to open source.
+The code for the developer documentations is maintained in [this
+repository](https://github.com/saturneric/GpgFrontend-Doxygen.git).
+
## Language Support
If you find an error in any of the translations or need to add a new one, we
welcome you to [join our translation
-work](https://www.gpgfrontend.bktus.com/#/contribute/translate-interface).
+work](https://www.gpgfrontend.bktus.com/appendix/translate-interface).
### Supported Languages
@@ -69,16 +76,32 @@ GpgFrontend currently supports an array of languages including:
Contributors: [SHOW](TRANSLATORS)
+## Modules
+
+GpgFrontend supports extensive module development, allowing users to customize
+their experience. Modules can encapsulate functionality, enabling users to
+enable or disable features as needed. Users can refer to existing module code
+for guidance and are encouraged to contribute to the [Module
+Repository](https://github.com/saturneric/GpgFrontend-Modules.git) to reach a
+broader audience.
+
+As the development is still in its infancy, there are not enough modules and
+many API interfaces have not been stabilized. So the discussion is open for the
+development of new modules and the introduction of API interfaces.
+
## Contact
-Please refer to [HERE](https://www.gpgfrontend.bktus.com/contact) for my contact details.
+Please refer to [HERE](https://www.gpgfrontend.bktus.com/overview/contact) for my contact details.
### Contributing & Bugs Report
-Feel free to dive in! [Open an issue](https://github.com/saturneric/GpgFrontend/issues/new) or submit PRs if you prefer
-to use GitHub. For anonymous users, Git patches can be delivered by [mail](mailto:[email protected]).
+Feel free to dive in! [Open an
+issue](https://github.com/saturneric/GpgFrontend/issues/new) or submit PRs if
+you prefer to use GitHub. For anonymous users, Git patches can be delivered by
+[mail](mailto:[email protected]). If you don't have a GitHub account or prefer not
+to register, you are welcome to communicate with me via email at
-[Contributing Guide](https://www.gpgfrontend.bktus.com/#/contribute/contribute)
+[Contributing Guide](https://www.gpgfrontend.bktus.com/appendix/contribute)
### Project Maintainer
diff --git a/cmake/FlagsOverrides.cmake b/cmake/FlagsOverrides.cmake
index 8696c810..6c5c994c 100644
--- a/cmake/FlagsOverrides.cmake
+++ b/cmake/FlagsOverrides.cmake
@@ -1,11 +1,11 @@
SET (CMAKE_C_FLAGS "-Wall -std=c11")
-SET (CMAKE_C_FLAGS_DEBUG "-g -fsanitize=address -fsanitize-recover=address")
+SET (CMAKE_C_FLAGS_DEBUG "-g")
SET (CMAKE_C_FLAGS_MINSIZERE "-Os -DNDEBUG")
SET (CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG")
SET (CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g")
SET (CMAKE_CXX_FLAGS "-Wall -std=c++17")
-SET (CMAKE_CXX_FLAGS_DEBUG "-g -fsanitize=address -fsanitize-recover=address")
+SET (CMAKE_CXX_FLAGS_DEBUG "-g")
SET (CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG")
SET (CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g") \ No newline at end of file
diff --git a/gpgfrontend.qrc b/gpgfrontend.qrc
index e311ed6a..a04c1819 100644
--- a/gpgfrontend.qrc
+++ b/gpgfrontend.qrc
@@ -97,6 +97,7 @@
<file alias="key.png">resource/lfs/icons/key.png</file>
<file alias="stairs.png">resource/lfs/icons/stairs.png</file>
<file alias="detail.png">resource/lfs/icons/detail.png</file>
+ <file alias="filter.png">resource/lfs/icons/filter.png</file>
</qresource>
<qresource prefix="/test/key">
<file alias="pv1.key">resource/lfs/test/data/pv1.key</file>
diff --git a/modules b/modules
new file mode 160000
+Subproject 0bad8ba3e6b7574cba25ad11bf425f15700657e
diff --git a/resource/lfs/icons/filter.png b/resource/lfs/icons/filter.png
new file mode 100644
index 00000000..a8480b48
--- /dev/null
+++ b/resource/lfs/icons/filter.png
Binary files differ
diff --git a/resource/lfs/locale/ts/GpgFrontend.de_DE.ts b/resource/lfs/locale/ts/GpgFrontend.de_DE.ts
index fea99d0c..07450b89 100644
--- a/resource/lfs/locale/ts/GpgFrontend.de_DE.ts
+++ b/resource/lfs/locale/ts/GpgFrontend.de_DE.ts
@@ -146,6 +146,64 @@
</message>
</context>
<context>
+ <name>GpgFrontend::GpgKeyTableModel</name>
+ <message>
+ <location filename="../../../../src/core/model/GpgKeyTableModel.cpp" line="39"/>
+ <source>Select</source>
+ <translation type="unfinished">Auswählen</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/core/model/GpgKeyTableModel.cpp" line="39"/>
+ <source>Type</source>
+ <translation type="unfinished">Typ</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/core/model/GpgKeyTableModel.cpp" line="39"/>
+ <source>Name</source>
+ <translation type="unfinished">Name</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/core/model/GpgKeyTableModel.cpp" line="40"/>
+ <source>Email Address</source>
+ <translation type="unfinished">E-Mail-Addresse</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/core/model/GpgKeyTableModel.cpp" line="40"/>
+ <source>Usage</source>
+ <translation type="unfinished">Verwendungszweck</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/core/model/GpgKeyTableModel.cpp" line="40"/>
+ <source>Trust</source>
+ <translation type="unfinished">Vertrauen</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/core/model/GpgKeyTableModel.cpp" line="41"/>
+ <source>Key ID</source>
+ <translation type="unfinished">Schlüssel-ID</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/core/model/GpgKeyTableModel.cpp" line="41"/>
+ <source>Create Date</source>
+ <translation type="unfinished">Erstellungsdatum</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/core/model/GpgKeyTableModel.cpp" line="41"/>
+ <source>Algorithm</source>
+ <translation type="unfinished">Algorithmus</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/core/model/GpgKeyTableModel.cpp" line="42"/>
+ <source>Subkey(s)</source>
+ <translation type="unfinished">Unterschlüssel(e)</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/core/model/GpgKeyTableModel.cpp" line="42"/>
+ <source>Comment</source>
+ <translation type="unfinished">Kommentar</translation>
+ </message>
+</context>
+<context>
<name>GpgFrontend::GpgSignResultAnalyse</name>
<message>
<location filename="../../../../src/core/function/result_analyse/GpgSignResultAnalyse.cpp" line="43"/>
@@ -560,6 +618,14 @@
</message>
</context>
<context>
+ <name>GpgFrontend::UI</name>
+ <message>
+ <location filename="../../../../src/ui/dialog/settings/SettingsDialog.cpp" line="123"/>
+ <source>System Default</source>
+ <translation type="unfinished">Systemstandard</translation>
+ </message>
+</context>
+<context>
<name>GpgFrontend::UI::AboutDialog</name>
<message>
<location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="41"/>
@@ -572,19 +638,22 @@
<translation type="unfinished">Über GpgFrontend</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="51"/>
+ <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="58"/>
+ <source>Unnamed</source>
+ <translation type="unfinished">Unbenannt</translation>
+ </message>
+ <message>
<source>GnuPG</source>
- <translation type="unfinished">GnuPG</translation>
+ <translation type="obsolete">GnuPG</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="54"/>
+ <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="49"/>
<source>Translators</source>
<translation type="unfinished">Übersetzer</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="58"/>
<source>Update</source>
- <translation type="unfinished">Aktualisieren</translation>
+ <translation type="obsolete">Aktualisieren</translation>
</message>
</context>
<context>
@@ -747,12 +816,12 @@
<context>
<name>GpgFrontend::UI::CommonUtils</name>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="186"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="185"/>
<source>GnuPG Context Loading Failed</source>
<translation type="unfinished">Laden des GnuPG-Kontexts fehlgeschlagen</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="188"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="187"/>
<source>Gnupg(gpg) is not installed correctly, please follow &lt;a href=&apos;https://www.gpgfrontend.bktus.com/#/faq?id=how-to-deal-with-39env-loading-failed39&apos;&gt;this notes&lt;/a&gt; in FAQ to install Gnupg and then open GpgFrontend. &lt;br /&gt;Or, you can open GnuPG Controller to set a custom GnuPG which GpgFrontend should use. Then, GpgFrontend will restart. &lt;br /&gt;&lt;br /&gt;Breif Reason: %1</source>
<translation>Gnupg(gpg) ist nicht korrekt installiert, bitte folgen Sie dieser &lt;a href=&apos;https://www.gpgfrontend.bktus.com/#/faq?id=how-to-deal-with-39env-loading-failed39&apos;&gt;Anleitung&lt;/a&gt; (nur in Englisch) in den FAQ, um Gnupg zu installieren und dann GpgFrontend zu öffnen. &lt;br /&gt;Alternativ können Sie den GnuPG Controller öffnen und ein benutzerspezifisches GnuPG für die Nutzung mit GpgFrontend auszuwählen. GpgFrontend muss dann neu gestartet werden. &lt;br /&gt;&lt;br /&gt;Grund %1</translation>
</message>
@@ -761,29 +830,29 @@
<translation type="obsolete">Keine Schlüssel zum Importieren gefunden</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="450"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="441"/>
<source>Timeout</source>
<translation type="unfinished">Zeitablauf</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="251"/>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="382"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="248"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="378"/>
<source>Success</source>
<translation type="unfinished">Erfolg</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="252"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="249"/>
<source>Gpg Operation succeed.</source>
<translation>Gpg-Verarbeitung erfolgreich.</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="262"/>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="374"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="259"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="370"/>
<source>Failure</source>
<translation type="unfinished">Fehler</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="263"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="260"/>
<source>Gpg Operation failed.
Error code: %1
@@ -796,14 +865,14 @@ Quelle: %2
Beschrei: %3</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="288"/>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="295"/>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="502"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="285"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="292"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="493"/>
<source>Error</source>
<translation type="unfinished">Fehler</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="280"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="277"/>
<source>Open Key</source>
<translation type="unfinished">Schlüssel öffnen</translation>
</message>
@@ -812,87 +881,87 @@ Beschrei: %3</translation>
<translation type="obsolete">Schlüsseldateien</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="281"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="278"/>
<source>Keyring files</source>
<translation type="unfinished">Schlüsselbunddateien</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="289"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="286"/>
<source>Cannot open this file. Please make sure that this is a regular file and it&apos;s readable.</source>
<translation type="unfinished">Kann diese Datei nicht öffnen. Bitte stellen Sie sicher, dass es sich um eine reguläre, lesbare Datei handelt.</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="296"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="293"/>
<source>The target file is too large for a keyring.</source>
<translation>Die Zieldatei ist zu groß für einen Schlüsselring.</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="302"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="299"/>
<source>File Open Failed</source>
<translation type="unfinished">Datei konnte nicht geöffnet werden</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="303"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="300"/>
<source>Failed to open file: </source>
<translation type="unfinished">Datei konnte nicht geöffnet werden: </translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="355"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="351"/>
<source>Processing</source>
<translation type="unfinished">In Bearbeitung</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="375"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="371"/>
<source>Failed to execute command.</source>
<translation type="unfinished">Fehler beim Ausführen des Befehls.</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="383"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="379"/>
<source>Succeed in executing command.</source>
<translation type="unfinished">Befehl erfolgreich ausgeführt.</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="385"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="381"/>
<source>Warning</source>
<translation type="unfinished">Warnung</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="386"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="382"/>
<source>Finished executing command.</source>
<translation type="unfinished">Ausführung des Befehls abgeschlossen.</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="407"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="402"/>
<source>Default Keyserver Not Found</source>
<translation type="unfinished">Standard-Keyserver nicht gefunden</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="408"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="403"/>
<source>Cannot read default keyserver from your settings, please set a default keyserver first</source>
<translation type="unfinished">Der Standard-Keyserver kann nicht aus Ihren Einstellungen gelesen werden, bitte legen Sie zuerst einen Standard-Keyserver fest</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="447"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="438"/>
<source>Key Not Found</source>
<translation type="unfinished">Schlüssel nicht gefunden</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="453"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="444"/>
<source>Key Server Not Found</source>
<translation type="unfinished">Schlüsselserver nicht gefunden</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="456"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="447"/>
<source>Connection Error</source>
<translation type="unfinished">Verbindungsfehler</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="467"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="458"/>
<source>The key has been updated</source>
<translation type="unfinished">Der Schlüssel wurde aktualisiert</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="469"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="460"/>
<source>No need to update the key</source>
<translation type="unfinished">Keine Notwendigkeit, den Schlüssel zu aktualisieren</translation>
</message>
@@ -1094,128 +1163,128 @@ Beschrei: %3</translation>
<context>
<name>GpgFrontend::UI::FileTreeView</name>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="92"/>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="105"/>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="168"/>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="214"/>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="236"/>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="277"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="88"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="101"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="159"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="204"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="225"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="266"/>
<source>Error</source>
<translation type="unfinished">Fehler</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="93"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="89"/>
<source>The path is not exists, unprivileged or unreachable.</source>
<translation type="unfinished">Der Pfad ist nicht vorhanden, nicht privilegiert oder nicht erreichbar.</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="106"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="102"/>
<source>The file is unprivileged or unreachable.</source>
<translation type="unfinished">Die Datei ist nicht privilegiert oder nicht erreichbar.</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="159"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="152"/>
<source>Warning</source>
<translation type="unfinished">Warnung</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="160"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="153"/>
<source>Are you sure you want to delete it?</source>
<translation type="unfinished">Möchten Sie es wirklich löschen?</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="169"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="160"/>
<source>Unable to delete the file or folder.</source>
<translation type="unfinished">Die Datei oder der Ordner kann nicht gelöscht werden.</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="178"/>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="191"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="169"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="182"/>
<source>Make New Directory</source>
<translation type="unfinished">Neues Verzeichnis erstellen</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="179"/>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="192"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="170"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="183"/>
<source>Directory Name</source>
<translation type="unfinished">Verzeichnisname</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="206"/>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="228"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="197"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="218"/>
<source>Create Empty File</source>
<translation type="unfinished">Leere Datei erstellen</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="206"/>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="228"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="197"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="218"/>
<source>Filename (you can given extension)</source>
<translation type="unfinished">Dateiname (Sie können die Erweiterung angeben)</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="215"/>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="237"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="205"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="226"/>
<source>Unable to create the file.</source>
<translation type="unfinished">Die Datei kann nicht erstellt werden.</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="269"/>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="300"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="258"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="289"/>
<source>Rename</source>
<translation type="unfinished">Umbenennen</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="269"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="258"/>
<source>New Filename</source>
<translation type="unfinished">Neuer Dateiname</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="278"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="267"/>
<source>Unable to rename the file or folder.</source>
<translation type="unfinished">Die Datei oder der Ordner kann nicht umbenannt werden.</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="295"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="284"/>
<source>Open</source>
<translation type="unfinished">Öffnen</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="305"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="294"/>
<source>Delete</source>
<translation type="unfinished">Löschen</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="310"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="299"/>
<source>Calculate Hash</source>
<translation type="unfinished">Hash berechnen</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="315"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="304"/>
<source>Directory</source>
<translation type="unfinished">Verzeichnis</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="320"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="309"/>
<source>File</source>
<translation type="unfinished">Datei</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="325"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="314"/>
<source>Compress...</source>
<translation type="unfinished">Komprimieren...</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="332"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="321"/>
<source>Open with Default System Application</source>
<translation type="unfinished">Mit der Standardsystemanwendung öffnen</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="337"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="326"/>
<source>New</source>
<translation type="unfinished">Neu</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="395"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="382"/>
<source>Calculating</source>
<translation type="unfinished">Berechnen</translation>
</message>
@@ -1262,53 +1331,58 @@ Beschrei: %3</translation>
</message>
<message>
<location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="56"/>
+ <source>Disable loading of all modules (including integrated modules)</source>
+ <translation type="unfinished">Deaktivieren des Ladens aller Module (einschließlich integrierter Module)</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="58"/>
<source>Language</source>
<translation type="unfinished">Sprache</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="58"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="60"/>
<source>NOTE</source>
<translation type="unfinished">HINWEIS</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="58"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="60"/>
<source>: </source>
<translation type="unfinished">: </translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="59"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="61"/>
<source>GpgFrontend will restart automatically if you change the language!</source>
<translation type="unfinished">GpgFrontend wird automatisch neu gestartet, wenn die Sprache geändert wird!</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="61"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="63"/>
<source>Data</source>
<translation type="unfinished">Daten</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="63"/>
- <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="81"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="65"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="83"/>
<source>Clear All Log (Total Size: %1)</source>
<translation type="unfinished">Gesamtes Protokoll löschen (Gesamtgröße: %1)</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="66"/>
- <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="95"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="68"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="97"/>
<source>Clear All Data Objects (Total Size: %1)</source>
<translation type="unfinished">Alle Datenobjekte löschen (Gesamtgröße: %1)</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="69"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="71"/>
<source>Reveal in File Explorer</source>
<translation>Im Datei-Explorer öffnen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="88"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="90"/>
<source>Confirm</source>
<translation type="unfinished">Bestätigen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="89"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="91"/>
<source>Are you sure you want to clear all data objects?
This will result in loss of all cached form positions, statuses, key servers, etc.</source>
<translation type="unfinished">Sind Sie sicher, dass Sie alle Datenobjekte löschen möchten? Dies führt zum Verlust aller zwischengespeicherten Formularpositionen, Status, Schlüsselserver usw.</translation>
@@ -1396,19 +1470,19 @@ This will result in loss of all cached form positions, statuses, key servers, et
</message>
<message>
<location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="100"/>
- <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="120"/>
+ <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="117"/>
<source>Open Directory</source>
<translation type="unfinished">Verzeichnis öffnen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="173"/>
+ <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="167"/>
<source>GnuPG Controller</source>
<translation type="unfinished">GnuPG-Controller</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="364"/>
- <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="371"/>
- <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="383"/>
+ <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="349"/>
+ <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="356"/>
+ <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="368"/>
<source>Illegal GnuPG Path</source>
<translation type="unfinished">Unzulässiger GnuPG-Pfad</translation>
</message>
@@ -1417,22 +1491,22 @@ This will result in loss of all cached form positions, statuses, key servers, et
<translation type="obsolete">Der Ziel-GnuPG-Pfad ist leer.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="365"/>
+ <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="350"/>
<source>Target GnuPG Path is not an exists readable directory.</source>
<translation type="unfinished">Der Ziel-GnuPG-Pfad ist kein lesbares Verzeichnis.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="372"/>
+ <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="357"/>
<source>Target GnuPG Path is not an absolute path.</source>
<translation type="unfinished">Der Ziel-GnuPG-Pfad ist kein absoluter Pfad.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="384"/>
+ <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="369"/>
<source>Target GnuPG Path contains no &quot;gpgconf&quot; executable.</source>
<translation type="unfinished">Der Ziel-GnuPG-Pfad enthält keine ausführbare Datei „gpgconf“.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="397"/>
+ <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="382"/>
<source>Illegal GnuPG Key Database Path</source>
<translation type="unfinished">Unzulässiger GnuPG-Schlüsseldatenbankpfad</translation>
</message>
@@ -1441,7 +1515,7 @@ This will result in loss of all cached form positions, statuses, key servers, et
<translation type="obsolete">Der Zielpfad für die GnuPG-Schlüsseldatenbank ist leer.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="398"/>
+ <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="383"/>
<source>Target GnuPG Key Database Path is not an exists readable directory.</source>
<translation type="unfinished">Der Zielpfad für die GnuPG-Schlüsseldatenbank ist kein lesbares Verzeichnis.</translation>
</message>
@@ -1449,84 +1523,68 @@ This will result in loss of all cached form positions, statuses, key servers, et
<context>
<name>GpgFrontend::UI::GnupgTab</name>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="46"/>
<source>Name</source>
- <translation type="unfinished">Name</translation>
+ <translation type="obsolete">Name</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="46"/>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="92"/>
<source>Description</source>
- <translation type="unfinished">Beschreibung</translation>
+ <translation type="obsolete">Beschreibung</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="46"/>
<source>Version</source>
- <translation type="unfinished">Version</translation>
+ <translation type="obsolete">Version</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="47"/>
<source>Checksum</source>
- <translation type="unfinished">Prüfsumme</translation>
+ <translation type="obsolete">Prüfsumme</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="47"/>
<source>Binary Path</source>
- <translation type="unfinished">Binärer Pfad</translation>
+ <translation type="obsolete">Binärer Pfad</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="49"/>
<source>Components</source>
- <translation type="unfinished">Komponenten</translation>
+ <translation type="obsolete">Komponenten</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="50"/>
<source>Directories</source>
- <translation type="unfinished">Verzeichnisse</translation>
+ <translation type="obsolete">Verzeichnisse</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="51"/>
<source>Options</source>
- <translation type="unfinished">Optionen</translation>
+ <translation type="obsolete">Optionen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="70"/>
<source>Directory Type</source>
- <translation type="unfinished">Verzeichnis Typ</translation>
+ <translation type="obsolete">Verzeichnis Typ</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="70"/>
<source>Path</source>
- <translation type="unfinished">Pfad</translation>
+ <translation type="obsolete">Pfad</translation>
</message>
<message>
<source>Configurations</source>
<translation type="obsolete">Konfigurationen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="91"/>
<source>Component</source>
- <translation>Komponente</translation>
+ <translation type="vanished">Komponente</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="91"/>
<source>Group</source>
- <translation>Gruppe</translation>
+ <translation type="vanished">Gruppe</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="91"/>
<source>Key</source>
- <translation type="unfinished">Schlüssel</translation>
+ <translation type="obsolete">Schlüssel</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="92"/>
<source>Default Value</source>
- <translation>Standardwert</translation>
+ <translation type="vanished">Standardwert</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="93"/>
<source>Value</source>
- <translation type="unfinished">Wert</translation>
+ <translation type="obsolete">Wert</translation>
</message>
</context>
<context>
@@ -1570,22 +1628,22 @@ This will result in loss of all cached form positions, statuses, key servers, et
<translation type="unfinished">Klar</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/InfoBoardWidget.cpp" line="167"/>
+ <location filename="../../../../src/ui/widgets/InfoBoardWidget.cpp" line="166"/>
<source>Save Information Board&apos;s Content</source>
<translation type="unfinished">Inhalt der Informationstafel speichern</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/InfoBoardWidget.cpp" line="167"/>
+ <location filename="../../../../src/ui/widgets/InfoBoardWidget.cpp" line="166"/>
<source>Text (*.txt)</source>
<translation>Text (*.txt)</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/InfoBoardWidget.cpp" line="176"/>
+ <location filename="../../../../src/ui/widgets/InfoBoardWidget.cpp" line="174"/>
<source>Error</source>
<translation type="unfinished">Fehler</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/InfoBoardWidget.cpp" line="177"/>
+ <location filename="../../../../src/ui/widgets/InfoBoardWidget.cpp" line="175"/>
<source>The file path is not exists, unprivileged or unreachable.</source>
<translation type="unfinished">Dateipfad nicht vorhanden oder erreichbar oder Sie besitzen nicht ausreichende Rechte.</translation>
</message>
@@ -1593,37 +1651,37 @@ This will result in loss of all cached form positions, statuses, key servers, et
<context>
<name>GpgFrontend::UI::InfoTab</name>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="102"/>
+ <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="99"/>
<source>GpgFrontend is an easy-to-use, compact, cross-platform, and installation-free GnuPG Frontend.It visualizes most of the common operations of GnuPG.GpgFrontend is licensed under the GPLv3</source>
<translation>GpgFrontend ist ein benutzerfreundliches, kompaktes, plattformübergreifendes und installationsfreies GnuPG-Frontend. Es visualisiert die meisten gängigen Operationen von GnuPG. GpgFrontend ist unter der GPLv3 lizenziert.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="108"/>
+ <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="105"/>
<source>Developer:</source>
<translation type="unfinished">Entwickler:</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="109"/>
+ <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="106"/>
<source>If you have any questions or suggestions, raise an issue at</source>
<translation type="unfinished">Wenn Sie Fragen oder Anregungen haben, wenden Sie sich an</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="112"/>
+ <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="109"/>
<source>or send a mail to my mailing list at</source>
<translation type="unfinished">oder senden Sie eine Mail an meine Mailingliste an</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="114"/>
+ <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="111"/>
<source>Built with Qt</source>
<translation type="unfinished">Mit Qt erstellt</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="115"/>
+ <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="112"/>
<source>and</source>
<translation type="unfinished">und</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="116"/>
+ <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="113"/>
<source>Built at</source>
<translation type="unfinished">Erstellt am</translation>
</message>
@@ -1778,47 +1836,47 @@ This will result in loss of all cached form positions, statuses, key servers, et
<translation type="unfinished">Authentifizierung</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="436"/>
+ <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="432"/>
<source>Name</source>
<translation type="unfinished">Name</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="437"/>
+ <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="433"/>
<source>Email Address</source>
<translation type="unfinished">E-Mail-Addresse</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="438"/>
+ <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="434"/>
<source>Comment</source>
<translation type="unfinished">Kommentar</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="439"/>
+ <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="435"/>
<source>Expiration Date</source>
<translation type="unfinished">Ablaufdatum</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="440"/>
+ <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="436"/>
<source>Never Expire</source>
<translation type="unfinished">Nie ablaufen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="441"/>
+ <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="437"/>
<source>KeySize (in Bit)</source>
<translation type="unfinished">Schlüsselgröße (in Bit)</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="442"/>
+ <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="438"/>
<source>Key Type</source>
<translation type="unfinished">Schlüsselart</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="443"/>
+ <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="439"/>
<source>Non Pass Phrase</source>
<translation type="unfinished">Nicht-Passphrase</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="456"/>
+ <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="452"/>
<source>Basic Information</source>
<translation type="unfinished">Grundlegende Informationen</translation>
</message>
@@ -1968,132 +2026,140 @@ This will result in loss of all cached form positions, statuses, key servers, et
<context>
<name>GpgFrontend::UI::KeyList</name>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="99"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="220"/>
<source>Refresh</source>
<translation type="unfinished">Aktualisierung</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="101"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="222"/>
<source>Refresh the key list to synchronize changes.</source>
<translation type="unfinished">Aktualisieren Sie die Schlüsselliste, um Änderungen zu synchronisieren.</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="102"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="223"/>
<source>Sync Public Key</source>
<translation type="unfinished">Öffentlichen Schlüssel synchronisieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="104"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="225"/>
<source>Sync public key with your default keyserver.</source>
<translation type="unfinished">Den öffentlichen Schlüssel mit Ihrem Standard-Schlüsselserver synchronisieren.</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="105"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="226"/>
<source>Uncheck ALL</source>
<translation type="unfinished">Alle abwählen</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="107"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="228"/>
<source>Cancel all checked items in the current tab at once.</source>
<translation type="unfinished">Alle markierten Elemente in der aktuellen Registerkarte auf einmal abbrechen.</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="108"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="229"/>
<source>Check ALL</source>
<translation type="unfinished">ALLE überprüfen</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="110"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="231"/>
<source>Check all items in the current tab at once</source>
<translation type="unfinished">Alle Elemente im aktuellen Tab gleichzeitig überprüfen</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="111"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="232"/>
<source>Search for keys...</source>
<translation type="unfinished">Suche nach Schlüsseln...</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="170"/>
<source>Select</source>
- <translation type="unfinished">Auswählen</translation>
+ <translation type="obsolete">Auswählen</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="170"/>
<source>Type</source>
- <translation type="unfinished">Typ</translation>
+ <translation type="obsolete">Typ</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="170"/>
<source>Name</source>
- <translation type="unfinished">Name</translation>
+ <translation type="obsolete">Name</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="170"/>
<source>Email Address</source>
- <translation type="unfinished">E-Mail-Addresse</translation>
+ <translation type="obsolete">E-Mail-Addresse</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="171"/>
<source>Usage</source>
- <translation type="unfinished">Verwendungszweck</translation>
+ <translation type="obsolete">Verwendungszweck</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="171"/>
<source>Trust</source>
- <translation type="unfinished">Vertrauen</translation>
+ <translation type="obsolete">Vertrauen</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="171"/>
<source>Finger Print</source>
- <translation type="unfinished">Fingerabdruck</translation>
+ <translation type="obsolete">Fingerabdruck</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="171"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="74"/>
<source>Key ID</source>
<translation type="unfinished">Schlüssel-ID</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="186"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="85"/>
+ <source>Algorithm</source>
+ <translation type="unfinished">Algorithmus</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="96"/>
+ <source>Owner Trust</source>
+ <translation type="unfinished">Vertrauen des Eigentümers</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="108"/>
+ <source>Create Date</source>
+ <translation type="unfinished">Erstellungsdatum</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="263"/>
<source>Refreshing Key List...</source>
<translation type="unfinished">Schlüsselliste wird aktualisiert...</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="374"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="431"/>
<source>Import Keys</source>
<translation type="unfinished">Schlüssel importieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="376"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="433"/>
<source>You&apos;ve dropped something on the table.</source>
<translation type="unfinished">Sie haben etwas in der Tabelle abgelegt.</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="377"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="434"/>
<source>GpgFrontend will now try to import key(s).</source>
<translation type="unfinished">GpgFrontend wird nun versuchen, Schlüssel zu importieren.</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="380"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="437"/>
<source>Always import without bothering.</source>
<translation type="unfinished">Immer ohne Nachfrage inportieren.</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="475"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="270"/>
<source>Key List Refreshed.</source>
<translation type="unfinished">Schlüsselliste aktualisiert.</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="510"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="550"/>
<source>Syncing Key List...</source>
<translation type="unfinished">Schlüsselliste wird synchronisiert...</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="518"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="556"/>
<source>Sync [%1/%2] %3 %4</source>
<translation type="unfinished">Synchronisieren [%1/%2] %3 %4</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="528"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="566"/>
<source>Key List Sync Done.</source>
<translation type="unfinished">Synchronisierung der Schlüsselliste abgeschlossen.</translation>
</message>
@@ -2106,205 +2172,205 @@ This will result in loss of all cached form positions, statuses, key servers, et
<translation type="unfinished">Alle</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="61"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="62"/>
<source>Only Public Key</source>
<translation type="unfinished">Nur öffentlicher Schlüssel</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="71"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="69"/>
<source>Has Private Key</source>
<translation type="unfinished">Hat privaten Schlüssel</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="81"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="76"/>
<source>No Primary Key</source>
<translation type="unfinished">Kein Primärschlüssel</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="90"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="85"/>
<source>Revoked</source>
<translation type="unfinished">Widerrufen</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="98"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="92"/>
<source>Expired</source>
<translation type="unfinished">Abgelaufen</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="123"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="116"/>
<source>KeyPair Management</source>
<translation type="unfinished">Schlüsselpaar-Verwaltung</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="144"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="137"/>
<source>Open</source>
<translation type="unfinished">Öffnen</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="146"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="139"/>
<source>Open Key File</source>
<translation type="unfinished">Schlüsseldatei öffnen</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="150"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="153"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="143"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="146"/>
<source>Close</source>
<translation type="unfinished">Schließen</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="156"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="149"/>
<source>New Keypair</source>
<translation type="unfinished">Neues Schlüsselpaar</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="159"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="152"/>
<source>Generate KeyPair</source>
<translation type="unfinished">Schlüsselpaar erstellen</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="163"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="156"/>
<source>New Subkey</source>
<translation type="unfinished">Neuer Unterschlüssel</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="167"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="160"/>
<source>Generate Subkey For Selected KeyPair</source>
<translation type="unfinished">Unterschlüssel für ausgewähltes Schlüsselpaar erstellen</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="171"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="265"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="164"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="258"/>
<source>File</source>
<translation type="unfinished">Datei</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="173"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="166"/>
<source>Import New Key From File</source>
<translation type="unfinished">Neuen Schlüssel aus Datei importieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="177"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="170"/>
<source>Clipboard</source>
<translation type="unfinished">Zwischenablage</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="181"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="174"/>
<source>Import New Key From Clipboard</source>
<translation type="unfinished">Neuen Schlüssel aus der Zwischenablage importieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="192"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="185"/>
<source>Keyserver</source>
<translation type="unfinished">Schlüsselserver</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="196"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="189"/>
<source>Import New Key From Keyserver</source>
<translation type="unfinished">Neuen Schlüssel vom Schlüsselserver importieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="202"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="536"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="195"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="529"/>
<source>Key Package</source>
<translation type="unfinished">Schlüsselpaket</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="205"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="198"/>
<source>Import Key(s) From a Key Package</source>
<translation type="unfinished">Schlüssel aus einem Schlüsselpaket importieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="209"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="202"/>
<source>Export To Clipboard</source>
<translation type="unfinished">In die Zwischenablage exportieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="213"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="206"/>
<source>Export Checked Key(s) To Clipboard</source>
<translation>Ausgewählte(n) Schlüssel in Zwischenablage exportiert</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="217"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="210"/>
<source>Export As Key Package</source>
<translation type="unfinished">Als Schlüsselpaket exportieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="220"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="213"/>
<source>Export Checked Key(s) To a Key Package</source>
<translation type="unfinished">Geprüfte(n) Schlüssel in ein Schlüsselpaket exportieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="224"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="217"/>
<source>Export As OpenSSH</source>
<translation type="unfinished">Als OpenSSH exportieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="227"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="220"/>
<source>Export Checked Key As OpenSSH Format to File</source>
<translation>Ausgewählten Schlüssel im OpenSSH Format in Datei exportiert</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="231"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="224"/>
<source>Delete Selected Key(s)</source>
<translation type="unfinished">Ausgewählte(n) Schlüssel löschen</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="233"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="226"/>
<source>Delete the Selected keys</source>
<translation type="unfinished">Die ausgewählten Schlüssel löschen</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="237"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="230"/>
<source>Delete Checked Key(s)</source>
<translation type="unfinished">Geprüfte(n) Schlüssel löschen</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="239"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="232"/>
<source>Delete the Checked keys</source>
<translation type="unfinished">Die markierten Schlüssel löschen</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="244"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="237"/>
<source>Show Key Details</source>
<translation type="unfinished">Schlüsseldetails anzeigen</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="246"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="239"/>
<source>Show Details for this Key</source>
<translation type="unfinished">Details zu diesem Schlüssel anzeigen</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="250"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="252"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="243"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="245"/>
<source>Set Owner Trust Level</source>
<translation type="unfinished">Vertrauensstufe des Eigentümers festlegen</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="269"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="289"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="262"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="282"/>
<source>Key</source>
<translation type="unfinished">Schlüssel</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="270"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="263"/>
<source>Generate Key</source>
<translation type="unfinished">Schlüssel erstellen</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="274"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="302"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="267"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="295"/>
<source>Import Key</source>
<translation type="unfinished">Schlüssel importieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="280"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="310"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="311"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="273"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="303"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="304"/>
<source>Export Key</source>
<translation>Schlüssel exportieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="301"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="294"/>
<source>Import key</source>
<translation type="unfinished">Schlüssel importieren</translation>
</message>
@@ -2313,160 +2379,160 @@ This will result in loss of all cached form positions, statuses, key servers, et
<translation type="vanished">Schlüssel exportieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="344"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="337"/>
<source>Deleting Keys</source>
<translation type="unfinished">Schlüssel löschen</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="345"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="338"/>
<source>Are you sure that you want to delete the following keys?</source>
<translation type="unfinished">Möchten Sie die folgenden Schlüssel wirklich löschen?</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="347"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="340"/>
<source>The action can not be undone.</source>
<translation type="unfinished">Die Aktion kann nicht rückgängig gemacht werden.</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="363"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="412"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="424"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="452"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="491"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="502"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="515"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="545"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="553"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="569"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="577"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="593"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="356"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="405"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="417"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="445"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="484"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="495"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="508"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="538"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="546"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="562"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="570"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="585"/>
<source>Error</source>
<translation type="unfinished">Fehler</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="363"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="452"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="356"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="445"/>
<source>Key Not Found.</source>
<translation type="unfinished">Schlüssel nicht gefunden.</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="374"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="387"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="470"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="476"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="367"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="380"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="463"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="469"/>
<source>Forbidden</source>
<translation type="unfinished">Verboten</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="375"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="388"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="368"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="381"/>
<source>Please check some keys before doing this operation.</source>
<translation type="unfinished">Bitte wählen Sie mindestens einen Schlüssel aus, bevor Sie diesen Vorgang ausführen.</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="380"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="528"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="373"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="521"/>
<source>key(s) exported</source>
<translation type="unfinished">Schlüssel exportiert</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="404"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="483"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="397"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="476"/>
<source>Exporting</source>
<translation>Exportiere</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="413"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="425"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="492"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="503"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="406"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="418"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="485"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="496"/>
<source>Unknown error occurred</source>
<translation>Unbekannter Fehler ist aufgetreten</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="446"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="456"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="439"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="449"/>
<source>Invalid Operation</source>
<translation type="unfinished">Ungültige Operation</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="447"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="440"/>
<source>Please select one KeyPair before doing this operation.</source>
<translation type="unfinished">Bitte wählen Sie ein Schlüsselpaar aus, bevor Sie diesen Vorgang ausführen.</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="457"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="450"/>
<source>If a key pair does not have a private key then it will not be able to generate sub-keys.</source>
<translation type="unfinished">Wenn ein Schlüsselpaar keinen privaten Schlüssel hat, kann es keine Unterschlüssel generieren.</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="471"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="464"/>
<source>Please check a key before performing this operation.</source>
<translation>Bitte wählen Sie einen Schlüssel aus, bevor Sie diesen Vorgang starten.</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="477"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="470"/>
<source>This operation accepts just a single key.</source>
<translation>Dieser Vorgang kann nur für einen einzelnen Schlüssel ausgeführt werden.</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="516"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="509"/>
<source>This key may not be able to export as OpenSSH format. Please check the key-size of the subkey(s) used to sign.</source>
<translation type="unfinished">Dieser Schlüssel kann möglicherweise nicht im OpenSSH-Format exportiert werden. Bitte überprüfen Sie die Schlüsselgröße der zum Signieren verwendeten Unterschlüssel.</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="523"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="516"/>
<source>Export OpenSSH Key To File</source>
<translation type="unfinished">OpenSSH-Schlüssel in eine Datei exportieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="524"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="517"/>
<source>OpenSSH Public Key Files</source>
<translation type="unfinished">OpenSSH-Dateien mit öffentlichem Schlüssel</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="536"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="529"/>
<source>Import Key Package</source>
<translation type="unfinished">Schlüsselpaket importieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="546"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="570"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="539"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="563"/>
<source>Cannot open this file. Please make sure that this is a regular file and it&apos;s readable.</source>
<translation type="unfinished">Kann diese Datei nicht öffnen. Bitte stellen Sie sicher, dass es sich um eine reguläre, lesbare Datei handelt.</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="554"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="547"/>
<source>The target file is too large for a key package.</source>
<translation type="unfinished">Die Zieldatei ist zu groß für ein Schlüsselpaket.</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="559"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="552"/>
<source>Import Key Package Passphrase File</source>
<translation type="unfinished">Schlüsselpaket-Passphrasendatei importieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="560"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="553"/>
<source>Key Package Passphrase File</source>
<translation type="unfinished">Schlüsselpaket-Passphrasendatei</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="578"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="571"/>
<source>The target file is too large for a key package passphrase.</source>
<translation type="unfinished">Die Zieldatei ist zu groß für eine Schlüsselpaket-Passphrase.</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="584"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="576"/>
<source>Importing</source>
<translation type="unfinished">Importieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="600"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="592"/>
<source>key(s) imported</source>
<translation type="unfinished">Schlüssel importiert</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="594"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="586"/>
<source>An error occur in importing key package.</source>
<translation type="unfinished">Beim Importieren des Schlüsselpakets ist ein Fehler aufgetreten.</translation>
</message>
@@ -2670,256 +2736,317 @@ This will result in loss of all cached form positions, statuses, key servers, et
<context>
<name>GpgFrontend::UI::KeyPairOperaTab</name>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="53"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="54"/>
<source>General Operations</source>
<translation type="unfinished">Allgemeine Vorgänge</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="59"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="60"/>
<source>Export Public Key</source>
<translation type="unfinished">Öffentlichen Schlüssel exportieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="65"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="66"/>
<source>Export Private Key</source>
<translation type="unfinished">Privaten Schlüssel exportieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="72"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="73"/>
<source>Modify Expiration Datetime (Primary Key)</source>
<translation type="unfinished">Ablaufdatum/Uhrzeit ändern (Primärschlüssel)</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="75"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="76"/>
<source>Modify Password</source>
<translation type="unfinished">Passwort verändern</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="93"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="94"/>
<source>Key Server Operation (Pubkey)</source>
<translation type="unfinished">Betrieb des Schlüsselservers (Pubkey)</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="177"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="199"/>
<source>Generate Revoke Certificate</source>
<translation type="unfinished">Widerrufszertifikat erstellen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="107"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="118"/>
<source>Modify TOFU Policy</source>
<translation type="unfinished">TOFU-Richtlinie ändern</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="101"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="102"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="558"/>
+ <source>Import A Paper Key</source>
+ <translation type="unfinished">Importieren eines Papierschlüssels</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="112"/>
<source>Revoke Certificate Operation</source>
<translation type="unfinished">Zertifikat widerrufen Operation</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="114"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="125"/>
<source>Set Owner Trust Level</source>
<translation type="unfinished">Vertrauensstufe des Eigentümers festlegen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="138"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="149"/>
<source>Upload Key Pair to Key Server</source>
<translation type="unfinished">Schlüsselpaar auf Schlüsselserver hochladen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="146"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="157"/>
<source>Sync Key Pair From Key Server</source>
<translation type="unfinished">Schlüsselpaar vom Schlüsselserver synchronisieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="161"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="172"/>
<source>Export Full Secret Key</source>
<translation type="unfinished">Vollständigen geheimen Schlüssel exportieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="167"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="178"/>
<source>Export Shortest Secret Key</source>
<translation type="unfinished">Kürzesten geheimen Schlüssel exportieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="182"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="184"/>
+ <source>Export Secret Key As A Paper Key</source>
+ <translation type="unfinished">Geheimen Schlüssel als Papierschlüssel exportieren</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="204"/>
<source>Import Revoke Certificate</source>
<translation type="unfinished">Zertifikat importieren widerrufen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="209"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="255"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="298"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="231"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="277"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="320"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="505"/>
<source>Export Key To File</source>
<translation type="unfinished">Schlüssel in Datei exportieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="210"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="256"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="299"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="232"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="278"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="321"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="506"/>
<source>Key Files</source>
<translation type="unfinished">Schlüsseldateien</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="215"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="261"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="304"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="237"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="283"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="326"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="529"/>
<source>Export Error</source>
<translation type="unfinished">Exportfehler</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="216"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="262"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="305"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="238"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="284"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="327"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="530"/>
<source>Couldn&apos;t open %1 for writing</source>
<translation type="unfinished">%1 konnte nicht zum Schreiben geöffnet werden</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="224"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="246"/>
<source>Exporting short private Key</source>
<translation type="unfinished">Exportieren eines kurzen privaten Schlüssels</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="225"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="272"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="247"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="294"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="474"/>
<source>You are about to export your</source>
<translation type="unfinished">Sie sind dabei, Ihre . zu exportieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="226"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="273"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="248"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="295"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="475"/>
<source> PRIVATE KEY </source>
<translation type="unfinished"> PRIVATEN SCHLÜSSEL </translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="227"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="274"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="249"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="296"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="476"/>
<source>This is NOT your Public Key, so DON&apos;T give it away.</source>
<translation type="unfinished">Dies ist NICHT Ihr öffentlicher Schlüssel, also geben Sie ihn NICHT weiter.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="228"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="250"/>
<source>Do you REALLY want to export your PRIVATE KEY in a Minimum Size?</source>
<translation type="unfinished">Möchten Sie WIRKLICH Ihren PRIVATEN SCHLÜSSEL in einer Mindestgröße exportieren?</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="231"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="253"/>
<source>For OpenPGP keys it removes all signatures except for the latest self-signatures.</source>
<translation type="unfinished">Bei OpenPGP-Schlüsseln werden alle Signaturen mit Ausnahme der neuesten Eigensignaturen entfernt.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="271"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="293"/>
<source>Exporting private Key</source>
<translation type="unfinished">Exportieren des privaten Schlüssels</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="275"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="297"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="482"/>
<source>Do you REALLY want to export your PRIVATE KEY?</source>
<translation type="unfinished">Möchten Sie WIRKLICH Ihren PRIVATEN SCHLÜSSEL exportieren?</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="329"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="412"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="351"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="433"/>
<source>Revocation Certificates</source>
<translation type="unfinished">Widerrufszertifikate</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="340"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="362"/>
<source>Generate revocation certificate</source>
<translation>Widerrufszertifikat erstellen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="361"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="371"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="383"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="392"/>
<source>Policy Auto</source>
<translation type="unfinished">Richtlinie Auto</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="361"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="373"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="383"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="394"/>
<source>Policy Good</source>
<translation type="unfinished">Richtlinie gut</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="361"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="375"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="383"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="396"/>
<source>Policy Bad</source>
<translation type="unfinished">Richtlinie schlecht</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="362"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="377"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="384"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="398"/>
<source>Policy Ask</source>
<translation type="unfinished">Richtlinie fragen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="362"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="379"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="384"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="400"/>
<source>Policy Unknown</source>
<translation type="unfinished">Richtlinie unbekannt</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="366"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="388"/>
<source>Modify TOFU Policy(Default is Auto)</source>
<translation type="unfinished">TOFU-Richtlinie ändern (Standard ist Auto)</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="367"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="389"/>
<source>Policy for the Key Pair:</source>
<translation type="unfinished">Richtlinie für das Schlüsselpaar:</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="384"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="405"/>
<source>Not Successful</source>
<translation type="unfinished">Nicht erfolgreich</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="385"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="406"/>
<source>Modify TOFU policy not successfully.</source>
<translation type="unfinished">Ändern der TOFU-Richtlinie nicht erfolgreich.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="399"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="411"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="420"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="432"/>
<source>Import Key Revocation Certificate</source>
<translation type="unfinished">Schlüssel-Widerrufs-Zertifikat importieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="400"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="421"/>
<source>You are about to import the</source>
<translation type="unfinished">Sie sind dabei, das</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="401"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="422"/>
<source>REVOCATION CERTIFICATE</source>
<translation type="unfinished">Schlüssel-Widerrufs-Zertifikat importieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="402"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="423"/>
<source>A successful import will result in the key being irreversibly revoked.</source>
<translation type="unfinished">Ein erfolgreicher Import führt dazu, dass der Schlüssel unwiderruflich widerrufen wird.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="404"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="425"/>
<source>Do you REALLY want to execute this operation?</source>
<translation type="unfinished">Wollen Sie diesen Vorgang WIRKLICH durchführen?</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="420"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="429"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="442"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="441"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="450"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="459"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="522"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="567"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="575"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="583"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="601"/>
<source>Error</source>
<translation type="unfinished">Fehler</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="421"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="443"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="442"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="460"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="568"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="584"/>
<source>Cannot open this file. Please make sure that this is a regular file and it&apos;s readable.</source>
<translation type="unfinished">Kann diese Datei nicht öffnen. Bitte stellen Sie sicher, dass es sich um eine reguläre, lesbare Datei handelt.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="430"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="451"/>
<source>The target file is too large for a key revocation certificate.</source>
<translation type="unfinished">Die Zieldatei ist zu groß für ein Schlüsselwiderrufszertifikat.</translation>
</message>
+ <message>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="473"/>
+ <source>Exporting private key as a Paper key</source>
+ <translation type="unfinished">Privaten Schlüssel als Papierschlüssel exportieren</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="477"/>
+ <source>A PaperKey is a human-readable printout of your private key, which can be used to recover your key if you lose access to your digital copy. </source>
+ <translation type="unfinished">Ein PaperKey ist ein von Menschen lesbarer Ausdruck Ihres privaten Schlüssels, mit dem Sie Ihren Schlüssel wiederherstellen können, wenn Sie den Zugriff auf Ihre digitale Kopie verlieren. </translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="481"/>
+ <source>Keep it in a safe place.</source>
+ <translation type="unfinished">Bewahren Sie es an einem sicheren Ort auf.</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="523"/>
+ <source>An error occurred trying to generate Paper Key.</source>
+ <translation type="unfinished">Beim Versuch, einen Papierschlüssel zu erzeugen, ist ein Fehler aufgetreten.</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="602"/>
+ <source>An error occurred trying to recover the Paper Key back to the private key.</source>
+ <translation type="unfinished">Beim Versuch, den Papierschlüssel in den privaten Schlüssel zurückzuverwandeln, ist ein Fehler aufgetreten.</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="559"/>
+ <source>Paper Key File</source>
+ <translation type="unfinished">Papier-Schlüsseldatei</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="576"/>
+ <source>The target file is too large for a paper key keyring.</source>
+ <translation type="unfinished">Die Zieldatei ist zu groß für einen Papierschlüsselanhänger.</translation>
+ </message>
</context>
<context>
<name>GpgFrontend::UI::KeyPairSubkeyTab</name>
@@ -3015,57 +3142,57 @@ This will result in loss of all cached form positions, statuses, key servers, et
<translation type="unfinished">Ablaufdatum</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="203"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="200"/>
<source>Never Expire</source>
<translation type="unfinished">Nie ablaufen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="240"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="235"/>
<source>Never Expires</source>
<translation type="unfinished">Läuft nie ab</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="262"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="257"/>
<source>Certificate</source>
<translation type="unfinished">Zertifikat</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="264"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="259"/>
<source>Encrypt</source>
<translation type="unfinished">Verschlüsseln</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="265"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="260"/>
<source>Sign</source>
<translation type="unfinished">Unterschreiben</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="266"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="261"/>
<source>Auth</source>
<translation type="unfinished">Authentifizieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="271"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="266"/>
<source>Exists</source>
<translation type="unfinished">Existiert</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="272"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="267"/>
<source>Not Exists</source>
<translation type="unfinished">Existiert nicht</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="275"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="270"/>
<source>Yes</source>
<translation type="unfinished">Ja</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="275"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="270"/>
<source>No</source>
<translation type="unfinished">Nein</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="304"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="299"/>
<source>Edit Expire Date</source>
<translation type="unfinished">Ablaufdatum bearbeiten</translation>
</message>
@@ -3135,154 +3262,154 @@ This will result in loss of all cached form positions, statuses, key servers, et
<translation>Ablaufdatum</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="240"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="239"/>
<source>TOFU %1</source>
<translation type="unfinished">TOFU %1</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="288"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="287"/>
<source>Never Expires</source>
<translation type="unfinished">Läuft nie ab</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="305"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="364"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="484"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="498"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="541"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="550"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="304"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="363"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="482"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="496"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="539"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="548"/>
<source>Invalid Operation</source>
<translation type="unfinished">Ungültige Operation</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="306"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="365"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="305"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="364"/>
<source>Please select one or more UIDs before doing this operation.</source>
<translation type="unfinished">Bitte wählen Sie eine oder mehrere UIDs aus, bevor Sie diesen Vorgang ausführen.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="328"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="327"/>
<source>Sign Selected UID(s)</source>
<translation type="unfinished">Ausgewählte UID(s) signieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="331"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="330"/>
<source>Delete Selected UID(s)</source>
<translation type="unfinished">Ausgewählte UID(s) löschen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="351"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="350"/>
<source>Successful Operation</source>
<translation type="unfinished">Erfolgreiche Durchführung</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="352"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="351"/>
<source>Successfully added a new UID.</source>
<translation type="unfinished">Erfolgreich eine neue UID hinzugefügt.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="354"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="389"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="423"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="519"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="571"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="353"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="387"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="421"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="517"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="569"/>
<source>Operation Failed</source>
<translation type="unfinished">Vorgang fehlgeschlagen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="355"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="424"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="520"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="572"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="354"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="422"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="518"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="570"/>
<source>An error occurred during the operation.</source>
<translation type="unfinished">Während des Vorgangs ist ein Fehler aufgetreten.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="376"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="375"/>
<source>Deleting UIDs</source>
<translation type="unfinished">UIDs löschen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="379"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="378"/>
<source>Are you sure that you want to delete the following UIDs?</source>
<translation type="unfinished">Möchten Sie die folgenden UIDs wirklich löschen?</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="381"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="417"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="514"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="566"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="380"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="415"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="512"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="564"/>
<source>The action can not be undone.</source>
<translation type="unfinished">Die Aktion kann nicht rückgängig gemacht werden.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="390"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="388"/>
<source>An error occurred during the delete %1 operation.</source>
<translation type="unfinished">Beim Löschen von %1 ist ein Fehler aufgetreten.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="414"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="412"/>
<source>Set Primary UID</source>
<translation type="unfinished">Primäre UID festlegen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="415"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="413"/>
<source>Are you sure that you want to set the Primary UID to?</source>
<translation type="unfinished">Sind Sie sicher, dass Sie die primäre UID auf festlegen möchten?</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="455"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="453"/>
<source>Set As Primary</source>
<translation type="unfinished">Als primär festlegen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="458"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="456"/>
<source>Sign UID</source>
<translation type="unfinished">UID unterschreiben</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="461"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="459"/>
<source>Delete UID</source>
<translation type="unfinished">UID löschen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="485"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="499"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="483"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="497"/>
<source>Please select one UID before doing this operation.</source>
<translation type="unfinished">Bitte eine UID auswählen, bevor dieser Vorgang ausgeführt wird.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="509"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="507"/>
<source>Deleting UID</source>
<translation type="unfinished">UID löschen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="512"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="510"/>
<source>Are you sure that you want to delete the following uid?</source>
<translation type="unfinished">Möchten Sie die folgende UID wirklich löschen?</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="530"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="528"/>
<source>Delete(Revoke) Key Signature</source>
<translation type="unfinished">Schlüsselsignatur löschen (widerrufen)</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="542"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="540"/>
<source>Please select one Key Signature before doing this operation.</source>
<translation type="unfinished">Bitte wählen Sie eine Schlüsselsignatur, bevor Sie diesen Vorgang ausführen.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="551"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="549"/>
<source>To delete the signature, you need to have its corresponding public key in the local database.</source>
<translation type="unfinished">Um die Signatur zu löschen, müssen Sie den entsprechenden öffentlichen Schlüssel in der lokalen Datenbank haben.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="561"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="559"/>
<source>Deleting Key Signature</source>
<translation type="unfinished">Schlüsselsignatur löschen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="563"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="561"/>
<source>Are you sure that you want to delete the following signature?</source>
<translation type="unfinished">Möchten Sie die folgende Signatur wirklich löschen?</translation>
</message>
@@ -3321,9 +3448,13 @@ This will result in loss of all cached form positions, statuses, key servers, et
<translation type="unfinished">Schlüsselserver</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="113"/>
<source>Import Keys from Keyserver</source>
- <translation type="unfinished">Schlüssel vom Schlüsselserver importieren</translation>
+ <translation type="obsolete">Schlüssel vom Schlüsselserver importieren</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="113"/>
+ <source>Import Keys from key server</source>
+ <translation type="unfinished">Importieren von Schlüsseln vom Schlüsselserver</translation>
</message>
<message>
<location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="153"/>
@@ -3351,77 +3482,77 @@ This will result in loss of all cached form positions, statuses, key servers, et
<translation type="unfinished">Text ist leer.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="223"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="219"/>
<source>Not Key Found</source>
<translation type="unfinished">Schlüssel nicht gefunden</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="226"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="222"/>
<source>Timeout</source>
<translation type="unfinished">Zeitablauf</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="229"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="225"/>
<source>Key Server Not Found</source>
<translation type="unfinished">Schlüsselserver nicht gefunden</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="232"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="228"/>
<source>Connection Error</source>
<translation type="unfinished">Verbindungsfehler</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="241"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="237"/>
<source>Too many responses from keyserver!</source>
<translation type="unfinished">Zu viele Antworten vom Schlüsselserver!</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="253"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="249"/>
<source>No keys found, input may be kexId, retrying search with 0x.</source>
<translation type="unfinished">Keine Schlüssel gefunden, Eingabe kann kexId sein, versuche es mit 0x erneut.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="263"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="259"/>
<source>No keys found containing the search string!</source>
<translation type="unfinished">Keine Schlüssel gefunden, die den Suchbegriff enthalten!</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="270"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="266"/>
<source>Insufficiently specific search string!</source>
<translation type="unfinished">Unzureichend spezifischer Suchbegriff!</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="305"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="301"/>
<source>revoked</source>
<translation type="unfinished">widerrufen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="308"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="304"/>
<source>disabled</source>
<translation type="unfinished">deaktiviert</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="353"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="349"/>
<source>%1 keys found. Double click a key to import it.</source>
<translation type="unfinished">%1 Schlüssel gefunden. Doppelklicken Sie auf einen Schlüssel, um ihn zu importieren.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="374"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="370"/>
<source>Warning</source>
<translation type="unfinished">Warnung</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="375"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="371"/>
<source>Please select one KeyPair before doing this operation.</source>
<translation type="unfinished">Bitte wählen Sie ein Schlüsselpaar aus, bevor Sie diesen Vorgang ausführen.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="422"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="417"/>
<source>Key Imported</source>
<translation type="unfinished">Schlüssel importiert</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="433"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="428"/>
<source>Processing ...</source>
<translation>Verarbeite ...</translation>
</message>
@@ -3429,27 +3560,27 @@ This will result in loss of all cached form positions, statuses, key servers, et
<context>
<name>GpgFrontend::UI::KeyServerImportTask</name>
<message>
- <location filename="../../../../src/ui/thread/KeyServerImportTask.cpp" line="79"/>
+ <location filename="../../../../src/ui/thread/KeyServerImportTask.cpp" line="78"/>
<source>Key not found in the Keyserver.</source>
<translation>Schlüssel auf dem Schlüsselserver nicht gefunden.</translation>
</message>
<message>
- <location filename="../../../../src/ui/thread/KeyServerImportTask.cpp" line="82"/>
+ <location filename="../../../../src/ui/thread/KeyServerImportTask.cpp" line="81"/>
<source>Network connection timeout.</source>
<translation>Netzwerkverbindungs-Timeout</translation>
</message>
<message>
- <location filename="../../../../src/ui/thread/KeyServerImportTask.cpp" line="85"/>
+ <location filename="../../../../src/ui/thread/KeyServerImportTask.cpp" line="84"/>
<source>Cannot resolve the address of target key server.</source>
<translation>Kann die Adresse des gewählten Schlüsselservers nicht auflösen.</translation>
</message>
<message>
- <location filename="../../../../src/ui/thread/KeyServerImportTask.cpp" line="88"/>
+ <location filename="../../../../src/ui/thread/KeyServerImportTask.cpp" line="87"/>
<source>General connection error occurred.</source>
<translation>Allgemeiner Verbindungsfehler ist aufgetreten.</translation>
</message>
<message>
- <location filename="../../../../src/ui/thread/KeyServerImportTask.cpp" line="94"/>
+ <location filename="../../../../src/ui/thread/KeyServerImportTask.cpp" line="93"/>
<source>Success</source>
<translation type="unfinished">Erfolg</translation>
</message>
@@ -3457,80 +3588,93 @@ This will result in loss of all cached form positions, statuses, key servers, et
<context>
<name>GpgFrontend::UI::KeySetExpireDateDialog</name>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="81"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="73"/>
<source>Success</source>
<translation type="unfinished">Erfolg</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="82"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="74"/>
<source>The expire date of the key pair has been updated.</source>
<translation type="unfinished">Das Ablaufdatum des Schlüsselpaars wurde aktualisiert.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="91"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="83"/>
<source>Failure</source>
<translation type="unfinished">Fehler</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="92"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="84"/>
<source>Failed to update the expire date of the key pair.</source>
<translation type="unfinished">Das Ablaufdatum des Schlüsselpaars konnte nicht aktualisiert werden.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="136"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="128"/>
<source>Modified Expiration Date (Local Time)</source>
<translation type="unfinished">Geändertes Ablaufdatum (Ortszeit)</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="137"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="129"/>
<source>Tips: For the sake of security, the key is valid for up to two years. If you are an expert user, please unlock it for a longer time in the settings.</source>
<translation type="unfinished">Tipps: Aus Sicherheitsgründen ist der Schlüssel bis zu zwei Jahre gültig. Wenn Sie ein erfahrener Benutzer sind, entsperren Sie es bitte für längere Zeit in den Einstellungen.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="141"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="133"/>
<source>No Expiration</source>
<translation type="unfinished">Nicht ablaufend</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="142"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="134"/>
<source>Modified Expiration Date</source>
<translation type="unfinished">Geändertes Ablaufdatum</translation>
</message>
</context>
<context>
+ <name>GpgFrontend::UI::KeyTable</name>
+ <message>
+ <location filename="../../../../src/ui/widgets/KeyTable.cpp" line="83"/>
+ <source>Error</source>
+ <translation type="unfinished">Fehler</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/widgets/KeyTable.cpp" line="83"/>
+ <source>Key Not Found.</source>
+ <translation type="unfinished">Schlüssel nicht gefunden.</translation>
+ </message>
+</context>
+<context>
<name>GpgFrontend::UI::KeyUIDSignDialog</name>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="46"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="50"/>
<source>Signers</source>
<translation type="unfinished">Unterzeichner</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="80"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="83"/>
<source>Expire Date</source>
<translation type="unfinished">Ablaufdatum</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="90"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="93"/>
<source>Sign For Key&apos;s UID(s)</source>
<translation type="unfinished">Für die UID(s) des Schlüssels unterschreiben</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="114"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="113"/>
<source>Unsuccessful Operation</source>
<translation type="unfinished">Fehlgeschlagener Vorgang</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="115"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="114"/>
<source>Signature operation failed for UID %1</source>
<translation type="unfinished">Signaturvorgang für UID %1 fehlgeschlagen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="120"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="119"/>
<source>Operation Complete</source>
<translation type="unfinished">Vorgang abgeschlossen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="121"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="120"/>
<source>The signature operation of the UID is complete</source>
<translation type="unfinished">Der Signaturvorgang der UID ist abgeschlossen</translation>
</message>
@@ -3553,37 +3697,37 @@ This will result in loss of all cached form positions, statuses, key servers, et
<translation>Unbekannter Fehler ist aufgetreten</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="150"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="148"/>
<source>Key Not Found</source>
<translation type="unfinished">Schlüssel nicht gefunden</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="153"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="151"/>
<source>Timeout</source>
<translation type="unfinished">Zeitablauf</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="156"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="154"/>
<source>Key Server Not Found</source>
<translation type="unfinished">Schlüsselserver nicht gefunden</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="159"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="157"/>
<source>Connection Error</source>
<translation type="unfinished">Verbindungsfehler</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="161"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="159"/>
<source>Upload Failed</source>
<translation>Hochladen fehlgeschlagen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="165"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="163"/>
<source>Upload Success</source>
<translation type="unfinished">Erfolgreich hochgeladen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="166"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="164"/>
<source>Upload Public Key Successfully</source>
<translation type="unfinished">Öffentlichen Schlüssel erfolgreich hochgeladen</translation>
</message>
@@ -3652,67 +3796,67 @@ This will result in loss of all cached form positions, statuses, key servers, et
<translation type="unfinished">Als Standard einstellen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="143"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="142"/>
<source>Insecure keyserver address</source>
<translation type="unfinished">Unsichere Keyserver-Adresse</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="144"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="143"/>
<source>For security reasons, using HTTP as the communication protocol with the key server is not recommended. It is recommended to use HTTPS.</source>
<translation type="unfinished">Aus Sicherheitsgründen wird die Verwendung von HTTP als Kommunikationsprotokoll mit dem Schlüsselserver nicht empfohlen. Es wird empfohlen, HTTPS zu verwenden.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="152"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="151"/>
<source>Warning</source>
<translation type="unfinished">Warnung</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="153"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="152"/>
<source>You may not use HTTPS or HTTP as the protocol for communicating with the key server, which may not be wrong. But please check the address you entered again to make sure it is correct. Are you sure that want to add it into the keyserver list?</source>
<translation type="unfinished">Sie könnten HTTP oder HTTPS für die Verbindung zum Schlüsselserver nutzen, was nicht unbedingt falsch ist. Aber es ist aus Sicherheitsgründen nicht empfohlen. Bitte prüfen Sie die eingegebene Adresse noch einmal, um sicher zu sein, dass sie korrekt ist. Sind Sie sicher, dass Sie sie zur Liste der Schlüsselserver hinzufügen möchten?</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="200"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="197"/>
<source>true</source>
<translation type="unfinished">wahr</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="201"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="198"/>
<source>false</source>
<translation type="unfinished">falsch</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="206"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="203"/>
<source>unknown</source>
<translation type="unfinished">unbekannt</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="220"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="217"/>
<source>Set TCP Timeout</source>
<translation type="unfinished">TCP-Zeitüberschreitung einstellen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="221"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="218"/>
<source>timeout(ms): </source>
<translation>Timeout (ms):</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="245"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="242"/>
<source>Reachable</source>
<translation type="unfinished">Erreichbar</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="248"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="245"/>
<source>Not Reachable</source>
<translation type="unfinished">Nicht erreichbar</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="260"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="257"/>
<source>Test Key Server Connection...</source>
<translation type="unfinished">Schlüsselserververbindung testen…</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="261"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="258"/>
<source>This test only tests the network connectivity of the key server. Passing the test does not mean that the key server is functionally available.</source>
<translation type="unfinished">Dieser Test testet nur die Netzwerkkonnektivität des Schlüsselservers. Das Bestehen des Tests bedeutet nicht, dass der Schlüsselserver funktionsfähig ist.</translation>
</message>
@@ -3740,35 +3884,35 @@ This will result in loss of all cached form positions, statuses, key servers, et
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="216"/>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="260"/>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="279"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="297"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="311"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="329"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="347"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="361"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="380"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="435"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="454"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="490"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="509"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="537"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="577"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="614"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="640"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="680"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="718"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="744"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="752"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="776"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="813"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="823"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="848"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="296"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="310"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="328"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="345"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="359"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="378"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="433"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="452"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="488"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="504"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="532"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="572"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="609"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="635"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="675"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="713"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="739"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="747"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="771"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="808"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="817"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="842"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="74"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="121"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="177"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="210"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="246"/>
- <location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="322"/>
- <location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="368"/>
+ <location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="314"/>
+ <location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="360"/>
<location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="97"/>
<location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="121"/>
<location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="141"/>
@@ -3776,8 +3920,8 @@ This will result in loss of all cached form positions, statuses, key servers, et
<location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="170"/>
<location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="183"/>
<location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="198"/>
- <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="248"/>
- <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="256"/>
+ <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="249"/>
+ <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="257"/>
<source>Error</source>
<translation type="unfinished">Fehler</translation>
</message>
@@ -3785,13 +3929,13 @@ This will result in loss of all cached form positions, statuses, key servers, et
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="50"/>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="165"/>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="280"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="330"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="381"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="455"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="538"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="641"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="745"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="814"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="329"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="379"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="453"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="533"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="636"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="740"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="809"/>
<source>Cannot read from file: %1</source>
<translation>Kann Datei nicht lesen: %1</translation>
</message>
@@ -3804,25 +3948,25 @@ This will result in loss of all cached form positions, statuses, key servers, et
<message>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="66"/>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="181"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="288"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="338"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="416"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="584"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="687"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="758"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="829"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="287"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="336"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="414"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="579"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="682"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="753"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="823"/>
<source>Warning</source>
<translation type="unfinished">Warnung</translation>
</message>
<message>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="75"/>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="190"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="298"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="348"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="578"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="681"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="753"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="824"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="297"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="346"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="573"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="676"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="748"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="818"/>
<source>Cannot write to file: %1</source>
<translation>Kann in Datei nicht schreiben: %</translation>
</message>
@@ -3850,29 +3994,29 @@ This will result in loss of all cached form positions, statuses, key servers, et
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="146"/>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="217"/>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="261"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="312"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="362"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="436"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="510"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="615"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="719"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="777"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="849"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="311"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="360"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="434"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="505"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="610"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="714"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="772"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="843"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="75"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="122"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="178"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="211"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="247"/>
- <location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="323"/>
- <location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="369"/>
+ <location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="315"/>
+ <location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="361"/>
<source>Unknown error occurred</source>
<translation>Unbekannter Fehler ist aufgetreten</translation>
</message>
<message>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="126"/>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="241"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="559"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="662"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="554"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="657"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="279"/>
<source>Invalid KeyPair</source>
<translation type="unfinished">Ungültiges Schlüsselpaar</translation>
@@ -3880,8 +4024,8 @@ This will result in loss of all cached form positions, statuses, key servers, et
<message>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="127"/>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="242"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="560"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="663"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="555"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="658"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="280"/>
<source>The selected keypair cannot be used for encryption.</source>
<translation type="unfinished">Das ausgewählte Schlüsselpaar kann nicht zur Verschlüsselung verwendet werden.</translation>
@@ -3889,8 +4033,8 @@ This will result in loss of all cached form positions, statuses, key servers, et
<message>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="128"/>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="243"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="561"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="664"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="556"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="659"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="103"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="159"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="281"/>
@@ -3914,117 +4058,117 @@ This will result in loss of all cached form positions, statuses, key servers, et
<translation>Archivierung und Verschlüsselung</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="289"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="339"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="585"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="688"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="288"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="337"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="580"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="683"/>
<source>The target file already exists, do you need to overwrite it?</source>
<translation type="unfinished">Die Zieldatei existiert bereits, wollen Sie sie überschreiben?</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="303"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="302"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="202"/>
<source>Decrypting</source>
<translation type="unfinished">Entschlüsseln</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="353"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="351"/>
<source>Decrypting &amp; Extrating</source>
<translation>Entschlüsselung und Extraktion</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="390"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="548"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="651"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="388"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="543"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="646"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="147"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="267"/>
<source>No Key Checked</source>
<translation type="unfinished">Kein Schlüssel ausgewählt</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="391"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="549"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="652"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="389"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="544"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="647"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="148"/>
<source>Please check the key in the key toolbox on the right.</source>
<translation type="unfinished">Bitte wählen Sie den Schlüssel in der Schlüssel-Toolbox auf der rechten Seite.</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="398"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="396"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="100"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="156"/>
<source>Invalid Operation</source>
<translation type="unfinished">Ungültige Operation</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="399"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="397"/>
<source>The selected key contains a key that does not actually have a sign usage.</source>
<translation type="unfinished">Der ausgewählte Schlüssel enthält einen Schlüssel, der keine Signierfunktion hat.</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="401"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="399"/>
<source>for example the Following Key:</source>
<translation type="unfinished">zum Beispiel der folgende Schlüssel:</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="417"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="415"/>
<source>The signature file &quot;%1&quot; exists, do you need to overwrite it?</source>
<translation type="unfinished">Die Signaturdatei &quot;%1&quot; existiert, wollen Sie sie überschreiben?</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="426"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="424"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="168"/>
<source>Signing</source>
<translation type="unfinished">Unterzeichnen</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="475"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="473"/>
<source>File to be Verified</source>
<translation>Zu verifizierende Datei</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="476"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="474"/>
<source>Please provide An ABSOLUTE Path
If Data And Signature is COMBINED within a single file, KEEP THIS EMPTY: </source>
<translation>Bitte geben Sie einen ABSOLUTEN Pfad an.
Fals Daten und Signatur in einer Datei COMBINIERT sind, LASSEN SIE DIES LEER: </translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="491"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="489"/>
<source>Please select the appropriate origin file or signature file. Ensure that both are in this directory.</source>
<translation type="unfinished">Bitte wählen Sie die entsprechende Ursprungsdatei oder Signaturdatei aus. Stellen Sie sicher, dass sich beide in diesem Verzeichnis befinden.</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="500"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="495"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="237"/>
<source>Verifying</source>
<translation type="unfinished">Verifizierung</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="603"/>
- <location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="310"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="598"/>
+ <location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="302"/>
<source>Encrypting and Signing</source>
<translation type="unfinished">Verschlüsseln und Signieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="706"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="701"/>
<source>Archiving &amp; Encrypting &amp; Signing</source>
<translation>Archivierung &amp; Verschlüsselung &amp; Signierung</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="759"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="830"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="754"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="824"/>
<source>The output file %1 already exists, do you need to overwrite it?</source>
<translation type="unfinished">Die Ausgabedatei %1 existiert bereits, wollen Sie sie überschreiben?</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="768"/>
- <location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="358"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="763"/>
+ <location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="350"/>
<source>Decrypting and Verifying</source>
<translation type="unfinished">Entschlüsseln und Verifizieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="839"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="833"/>
<source>Decrypting &amp; Verifying &amp; Extracting</source>
<translation>Entschlüsselung &amp; Verifizierung &amp; Extraktion</translation>
</message>
@@ -4079,43 +4223,43 @@ Fals Daten und Signatur in einer Datei COMBINIERT sind, LASSEN SIE DIES LEER: </
<translation type="unfinished">当地时间</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="249"/>
+ <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="250"/>
<source>Cannot open this file. Please make sure that this is a regular file and it&apos;s readable.</source>
<translation>Kann diese Datei nicht öffnen. Bitte stellen Sie sicher, dass es sich um eine reguläre, lesbare Datei handelt.</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="257"/>
+ <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="258"/>
<source>Cannot open this file. The file is TOO LARGE (&gt;1MB) for GpgFrontend Text Editor.</source>
<translation>Kann diese Datei nicht öffen. DIe Datei ist ZU GROSS (&gt;1MB) für den GpgFrontend Texteditor.</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="298"/>
+ <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="292"/>
<source>GpgFrontend Upgradeable (New Version: %1).</source>
<translation type="unfinished">GpgFrontend kann aktualisiert werden (neue Version: %1).</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="302"/>
+ <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="296"/>
<location filename="../../../../src/ui/main_window/MainWindowUI.cpp" line="448"/>
<source>Update</source>
<translation type="unfinished">Aktualisieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="308"/>
+ <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="302"/>
<source>Withdrawn Version</source>
<translation type="unfinished">Zurückgezogene Version</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="310"/>
+ <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="304"/>
<source>This version(%1) may have been withdrawn by the developer due to serious problems. Please stop using this version immediately and use the latest stable version.</source>
<translation type="unfinished">Diese Version (%1) wurde möglicherweise vom Entwickler aufgrund schwerwiegender Probleme zurückgezogen. Bitte beenden Sie die Verwendung dieser Version sofort und verwenden Sie die neueste stabile Version.</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="315"/>
+ <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="309"/>
<source>You can download the latest stable version(%1) on Github Releases Page.&lt;br/&gt;</source>
<translation type="unfinished">Sie können die neueste stabile Version (%1) auf der Github-Release-Seite herunterladen.&lt;br/&gt;</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="320"/>
+ <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="314"/>
<source>This maybe a BETA Version (Latest Stable Version: %1).</source>
<translation type="unfinished">Dies ist möglicherweise eine BETA-Version (Neueste stabile Version: %1).</translation>
</message>
@@ -4774,17 +4918,17 @@ Fals Daten und Signatur in einer Datei COMBINIERT sind, LASSEN SIE DIES LEER: </
<translation type="unfinished">Favorit</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowUI.cpp" line="726"/>
+ <location filename="../../../../src/ui/main_window/MainWindowUI.cpp" line="727"/>
<source>Only Public Key</source>
<translation type="unfinished">Nur öffentlicher Schlüssel</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowUI.cpp" line="736"/>
+ <location filename="../../../../src/ui/main_window/MainWindowUI.cpp" line="734"/>
<source>Has Private Key</source>
<translation type="unfinished">Hat privaten Schlüssel</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowUI.cpp" line="750"/>
+ <location filename="../../../../src/ui/main_window/MainWindowUI.cpp" line="745"/>
<source>Information Board</source>
<translation type="unfinished">Informationstafel</translation>
</message>
@@ -4833,89 +4977,89 @@ Fals Daten und Signatur in einer Datei COMBINIERT sind, LASSEN SIE DIES LEER: </
</message>
<message>
<location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="84"/>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="184"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="195"/>
<source>Enable Auto Activate</source>
<translation type="unfinished">Automatisches Aktivieren aktivieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="133"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="144"/>
<source>BASIC INFO</source>
<translation type="unfinished">GRUNDINFO</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="135"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="146"/>
<source>ID</source>
<translation type="unfinished">ID</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="137"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="148"/>
<source>Version</source>
<translation type="unfinished">Version</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="139"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="150"/>
<source>SDK Version</source>
<translation type="unfinished">SDK-Version</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="141"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="152"/>
<source>Qt ENV Version</source>
<translation type="unfinished">Qt ENV Version</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="143"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="154"/>
<source>Hash</source>
<translation type="unfinished">Hash</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="144"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="155"/>
<source>Path</source>
<translation type="unfinished">Pfad</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="148"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="159"/>
<source>Auto Activate</source>
<translation type="unfinished">Automatisch aktivieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="149"/>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="151"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="160"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="162"/>
<source>True</source>
<translation type="unfinished">Wahr</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="149"/>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="151"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="160"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="162"/>
<source>False</source>
<translation type="unfinished">Falsch</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="150"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="161"/>
<source>Active</source>
<translation type="unfinished">Aktiv</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="155"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="166"/>
<source>METADATA</source>
<translation type="unfinished">METADATEN</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="171"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="182"/>
<source>Listening Event</source>
<translation type="unfinished">Anhören von Veranstaltungen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="180"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="191"/>
<source>Deactivate</source>
<translation type="unfinished">Deaktivieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="181"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="192"/>
<source>Activate</source>
<translation type="unfinished">Aktivieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="183"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="194"/>
<source>Disable Auto Activate</source>
<translation type="unfinished">Automatisches Aktivieren deaktivieren</translation>
</message>
@@ -5043,7 +5187,7 @@ Fals Daten und Signatur in einer Datei COMBINIERT sind, LASSEN SIE DIES LEER: </
</message>
<message>
<location filename="../../../../src/ui/widgets/PlainTextEditorPage.cpp" line="63"/>
- <location filename="../../../../src/ui/widgets/PlainTextEditorPage.cpp" line="196"/>
+ <location filename="../../../../src/ui/widgets/PlainTextEditorPage.cpp" line="194"/>
<source>%1 character(s)</source>
<translation type="unfinished">%1 Zeichen</translation>
</message>
@@ -5098,14 +5242,12 @@ Fals Daten und Signatur in einer Datei COMBINIERT sind, LASSEN SIE DIES LEER: </
<translation type="vanished">PIN wiederholen:</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/RaisePinentry.cpp" line="68"/>
<source>Show passphrase</source>
- <translation>Passwortphrase anzeigen</translation>
+ <translation type="vanished">Passwortphrase anzeigen</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/RaisePinentry.cpp" line="68"/>
<source>Hide passphrase</source>
- <translation>Passwortphrase verbergen</translation>
+ <translation type="vanished">Passwortphrase verbergen</translation>
</message>
<message>
<source>Given PIN was wrong. Please retry.</source>
@@ -5116,48 +5258,40 @@ Fals Daten und Signatur in einer Datei COMBINIERT sind, LASSEN SIE DIES LEER: </
<translation type="vanished">PIN:</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/RaisePinentry.cpp" line="67"/>
<source>Repeat Passphrase:</source>
- <translation>Passphrase wiederholen:</translation>
+ <translation type="vanished">Passphrase wiederholen:</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/RaisePinentry.cpp" line="71"/>
<source>Given Passphrase was wrong. Please retry.</source>
- <translation>Die angegebene Passphrase war falsch. Bitte versuchen Sie es erneut.</translation>
+ <translation type="vanished">Die angegebene Passphrase war falsch. Bitte versuchen Sie es erneut.</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/RaisePinentry.cpp" line="74"/>
<source>Passphrase:</source>
- <translation>Passphrase:</translation>
+ <translation type="vanished">Passphrase:</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/RaisePinentry.cpp" line="84"/>
<source>Passphrases do not match</source>
- <translation>Passwortphrasen stimmen nicht überein</translation>
+ <translation type="vanished">Passwortphrasen stimmen nicht überein</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/RaisePinentry.cpp" line="87"/>
<source>Caps Lock is on</source>
- <translation>Feststelltaste ist eingeschaltet</translation>
+ <translation type="vanished">Feststelltaste ist eingeschaltet</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/RaisePinentry.cpp" line="91"/>
<source>Bundled Pinentry</source>
- <translation>Eingabe Passphrase</translation>
+ <translation type="vanished">Eingabe Passphrase</translation>
</message>
<message>
<source>Buddled Pinentry</source>
<translation type="vanished">Pineingabe</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/RaisePinentry.cpp" line="95"/>
<source>Confirm</source>
- <translation>Bestätigen</translation>
+ <translation type="vanished">Bestätigen</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/RaisePinentry.cpp" line="96"/>
<source>Cancel</source>
- <translation>Abbrechen</translation>
+ <translation type="vanished">Abbrechen</translation>
</message>
</context>
<context>
@@ -5169,31 +5303,31 @@ Fals Daten und Signatur in einer Datei COMBINIERT sind, LASSEN SIE DIES LEER: </
</message>
<message>
<location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="49"/>
- <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="67"/>
+ <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="66"/>
<source>Undefined</source>
<translation type="unfinished">Undefiniert</translation>
</message>
<message>
<location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="49"/>
- <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="65"/>
+ <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="64"/>
<source>Never</source>
<translation type="unfinished">Niemals</translation>
</message>
<message>
<location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="49"/>
- <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="63"/>
+ <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="62"/>
<source>Marginal</source>
<translation type="unfinished">Geringfügig</translation>
</message>
<message>
<location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="50"/>
- <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="61"/>
+ <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="60"/>
<source>Full</source>
<translation type="unfinished">Voll</translation>
</message>
<message>
<location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="50"/>
- <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="59"/>
+ <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="58"/>
<source>Ultimate</source>
<translation type="unfinished">Ultimativ</translation>
</message>
@@ -5208,22 +5342,22 @@ Fals Daten und Signatur in einer Datei COMBINIERT sind, LASSEN SIE DIES LEER: </
<translation type="unfinished">Vertrauen für das Schlüsselpaar:</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="73"/>
+ <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="72"/>
<source>Warning</source>
<translation type="unfinished">Warnung</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="75"/>
+ <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="74"/>
<source>Owner Trust Level cannot set to Unknown level, automately changing it into Undefined level.</source>
<translation type="unfinished">Die Vertrauensstufe des Eigentümers kann nicht auf „Unbekannt“ gesetzt werden, setze automatisch die Stufe „Undefiniert“.</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="83"/>
+ <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="82"/>
<source>Failed</source>
<translation type="unfinished">Gescheitert</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="84"/>
+ <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="83"/>
<source>Modify Owner Trust Level failed.</source>
<translation type="unfinished">Das Ändern der Vertrauensstufe des Eigentümers ist fehlgeschlagen.</translation>
</message>
@@ -5261,9 +5395,8 @@ Fals Daten und Signatur in einer Datei COMBINIERT sind, LASSEN SIE DIES LEER: </
<translation type="unfinished">Einstellung</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsDialog.cpp" line="124"/>
<source>System Default</source>
- <translation type="unfinished">Systemstandard</translation>
+ <translation type="obsolete">Systemstandard</translation>
</message>
</context>
<context>
@@ -5279,27 +5412,27 @@ Fals Daten und Signatur in einer Datei COMBINIERT sind, LASSEN SIE DIES LEER: </
<translation type="unfinished">Abbrechen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/SignersPicker.cpp" line="49"/>
+ <location filename="../../../../src/ui/dialog/SignersPicker.cpp" line="52"/>
<source>Signers</source>
<translation type="unfinished">Unterzeichner</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/SignersPicker.cpp" line="57"/>
+ <location filename="../../../../src/ui/dialog/SignersPicker.cpp" line="60"/>
<source>Select Signer(s)</source>
<translation type="unfinished">Unterzeichner auswählen</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/SignersPicker.cpp" line="61"/>
+ <location filename="../../../../src/ui/dialog/SignersPicker.cpp" line="63"/>
<source>Please select one or more private keys you use for signing.</source>
<translation type="unfinished">Bitte wählen Sie einen oder mehrere private Schlüssel aus, die Sie zum Signieren verwenden.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/SignersPicker.cpp" line="63"/>
+ <location filename="../../../../src/ui/dialog/SignersPicker.cpp" line="64"/>
<source>If no key is selected, the default key will be used for signing.</source>
<translation type="unfinished">Wenn kein Schlüssel ausgewählt ist, wird der Standardschlüssel zum Signieren verwendet.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/SignersPicker.cpp" line="73"/>
+ <location filename="../../../../src/ui/dialog/SignersPicker.cpp" line="74"/>
<source>Signers Picker</source>
<translation>Signierungswähler</translation>
</message>
@@ -5449,54 +5582,54 @@ Fals Daten und Signatur in einer Datei COMBINIERT sind, LASSEN SIE DIES LEER: </
<translation type="unfinished">Verzeichnis öffnen</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="143"/>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="203"/>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="422"/>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="459"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="142"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="202"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="421"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="458"/>
<source>Warning</source>
<translation type="unfinished">Warnung</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="144"/>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="204"/>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="423"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="143"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="203"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="422"/>
<source>Cannot read file %1:
%2.</source>
<translation type="unfinished">Kann Datei %1 nicht lesen:
%2.</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="152"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="151"/>
<source>Open file</source>
<translation type="unfinished">Datei öffnen</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="221"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="220"/>
<source>Save file</source>
<translation type="unfinished">Datei speichern</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="282"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="281"/>
<source>Unsaved document</source>
<translation type="unfinished">Nicht gespeichertes Dokument</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="283"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="282"/>
<source>The document &quot;%1&quot; has been modified. Do you want to save your changes?</source>
<translation type="unfinished">Das Dokument &quot;%1&quot; wurde geändert. Wollen Sie Ihre Änderungen speichern?</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="286"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="285"/>
<source>Note:</source>
<translation type="unfinished">Notiz:</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="287"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="286"/>
<source>If you don&apos;t save these files, all changes are lost.</source>
<translation type="unfinished">Wenn Sie diese Dateien nicht speichern, gehen alle Änderungen verloren.</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="459"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="458"/>
<source>No document to print</source>
<translation>Kein Dokument für Ausdruck</translation>
</message>
@@ -5504,7 +5637,7 @@ Fals Daten und Signatur in einer Datei COMBINIERT sind, LASSEN SIE DIES LEER: </
<context>
<name>GpgFrontend::UI::TranslatorsTab</name>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="145"/>
+ <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="142"/>
<source>If you think there are any problems with the translation, why not participate in the translation work? If you want to participate, please read the document or contact me via email.</source>
<translation type="unfinished">Wenn Sie der Meinung sind, dass es Probleme mit der Übersetzung gibt, warum beteiligen Sie sich nicht an der Übersetzungsarbeit? Wenn Sie teilnehmen möchten, lesen Sie bitte das Dokument oder kontaktieren Sie mich per E-Mail.</translation>
</message>
@@ -5512,65 +5645,48 @@ Fals Daten und Signatur in einer Datei COMBINIERT sind, LASSEN SIE DIES LEER: </
<context>
<name>GpgFrontend::UI::UpdateTab</name>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="163"/>
<source>It is recommended that you always check the version of GpgFrontend and upgrade to the latest version.</source>
- <translation type="unfinished">Es wird empfohlen, immer die Version von GpgFrontend zu überprüfen und auf die neueste Version zu aktualisieren.</translation>
+ <translation type="obsolete">Es wird empfohlen, immer die Version von GpgFrontend zu überprüfen und auf die neueste Version zu aktualisieren.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="166"/>
<source>New versions not only represent new features, but also often represent functional and security fixes.</source>
- <translation type="unfinished">Neue Versionen beinhalten nicht nur neue Funktionen, sondern stellen oft auch Funktions- und Sicherheitskorrekturen dar.</translation>
+ <translation type="obsolete">Neue Versionen beinhalten nicht nur neue Funktionen, sondern stellen oft auch Funktions- und Sicherheitskorrekturen dar.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="172"/>
<source>Current Version</source>
- <translation type="unfinished">Aktuelle Version</translation>
+ <translation type="obsolete">Aktuelle Version</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="173"/>
<source>: </source>
- <translation type="unfinished">: </translation>
+ <translation type="obsolete">: </translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="248"/>
<source>Latest Version From Github</source>
- <translation type="unfinished">Neueste Version von Github</translation>
+ <translation type="obsolete">Neueste Version von Github</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="254"/>
<source>The current version is less than the latest version on github.</source>
- <translation type="unfinished">Die aktuelle Versionsnunmmer ist kleiner als die neueste Version auf github.</translation>
+ <translation type="obsolete">Die aktuelle Versionsnunmmer ist kleiner als die neueste Version auf github.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="256"/>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="267"/>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="279"/>
<source>Please click</source>
- <translation type="unfinished">Bitte klicken Sie</translation>
+ <translation type="obsolete">Bitte klicken Sie</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="259"/>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="270"/>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="282"/>
<source>Here</source>
- <translation type="unfinished">Hier</translation>
+ <translation type="obsolete">Hier</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="259"/>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="270"/>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="282"/>
<source>to download the latest stable version.</source>
- <translation type="unfinished">um die neueste stabile Version herunterzuladen.</translation>
+ <translation type="obsolete">um die neueste stabile Version herunterzuladen.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="265"/>
<source>This version has serious problems and has been withdrawn. Please stop using it immediately.</source>
- <translation type="unfinished">Diese Version hat ernsthafte Probleme und wurde zurückgezogen. Bitte hören Sie sofort auf, sie zu verwenden.</translation>
+ <translation type="obsolete">Diese Version hat ernsthafte Probleme und wurde zurückgezogen. Bitte hören Sie sofort auf, sie zu verwenden.</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="276"/>
<source>This version has not been released yet, it may be a beta version. If you are not a tester and care about version stability, please do not use this version.</source>
- <translation type="unfinished">Diese Version wurde noch nicht veröffentlicht, möglicherweise handelt es sich um eine Beta-Version. Wenn Sie kein Tester sind und Ihnen Stabilität der Version wichtig ist, verwenden Sie diese Version bitte nicht.</translation>
+ <translation type="obsolete">Diese Version wurde noch nicht veröffentlicht, möglicherweise handelt es sich um eine Beta-Version. Wenn Sie kein Tester sind und Ihnen Stabilität der Version wichtig ist, verwenden Sie diese Version bitte nicht.</translation>
</message>
</context>
<context>
@@ -5806,39 +5922,43 @@ Fals Daten und Signatur in einer Datei COMBINIERT sind, LASSEN SIE DIES LEER: </
<context>
<name>QCoreApplication</name>
<message>
- <location filename="../../../../src/cmd.cpp" line="47"/>
+ <location filename="../../../../src/cmd.cpp" line="50"/>
<source>This is free software; see the source for copying conditions.</source>
<translation type="unfinished">Dies ist freie Software. Beachten Sie den Quellcode für die Kopierbedingungen.</translation>
</message>
<message>
- <location filename="../../../../src/cmd.cpp" line="52"/>
+ <location filename="../../../../src/cmd.cpp" line="55"/>
<source>Build DateTime: </source>
<translation type="unfinished">Build DateTime: </translation>
</message>
<message>
- <location filename="../../../../src/cmd.cpp" line="54"/>
+ <location filename="../../../../src/cmd.cpp" line="57"/>
<source>Build Version: </source>
<translation type="unfinished">Build Version: </translation>
</message>
<message>
- <location filename="../../../../src/cmd.cpp" line="56"/>
+ <location filename="../../../../src/cmd.cpp" line="59"/>
<source>Source Code Version: </source>
<translation type="unfinished">Sourcecode Version: </translation>
</message>
<message>
- <location filename="../../../../src/core/GpgCoreInit.cpp" line="303"/>
+ <location filename="../../../../src/core/GpgCoreInit.cpp" line="283"/>
<source>GpgME initiation failed</source>
<translation>GpgME-Initiation fehlgeschlagen</translation>
</message>
<message>
- <location filename="../../../../src/core/GpgCoreInit.cpp" line="409"/>
+ <location filename="../../../../src/core/GpgCoreInit.cpp" line="378"/>
<source>GpgME Context initiation failed</source>
<translation>GpgME-Kontext-Initiation fehlgeschlagen</translation>
</message>
<message>
- <location filename="../../../../src/core/GpgCoreInit.cpp" line="418"/>
+ <location filename="../../../../src/core/GpgCoreInit.cpp" line="387"/>
+ <source>Gpg Key Database initiation failed</source>
+ <translation type="unfinished">Initiierung der Gpg-Schlüsseldatenbank fehlgeschlagen</translation>
+ </message>
+ <message>
<source>Gpg Key Detabase initiation failed</source>
- <translation>Gpg Key Detabase initiation fehlgeschlagen</translation>
+ <translation type="vanished">Gpg Key Detabase initiation fehlgeschlagen</translation>
</message>
<message>
<location filename="../../../../src/core/utils/IOUtils.cpp" line="89"/>
@@ -5847,7 +5967,7 @@ Fals Daten und Signatur in einer Datei COMBINIERT sind, LASSEN SIE DIES LEER: </
</message>
<message>
<location filename="../../../../src/core/utils/IOUtils.cpp" line="90"/>
- <location filename="../../../../src/core/utils/IOUtils.cpp" line="125"/>
+ <location filename="../../../../src/core/utils/IOUtils.cpp" line="122"/>
<source>Filename</source>
<translation>Dateiname</translation>
</message>
@@ -5855,10 +5975,10 @@ Fals Daten und Signatur in einer Datei COMBINIERT sind, LASSEN SIE DIES LEER: </
<location filename="../../../../src/core/utils/IOUtils.cpp" line="90"/>
<location filename="../../../../src/core/utils/IOUtils.cpp" line="95"/>
<location filename="../../../../src/core/utils/IOUtils.cpp" line="99"/>
- <location filename="../../../../src/core/utils/IOUtils.cpp" line="104"/>
- <location filename="../../../../src/core/utils/IOUtils.cpp" line="110"/>
- <location filename="../../../../src/core/utils/IOUtils.cpp" line="116"/>
- <location filename="../../../../src/core/utils/IOUtils.cpp" line="125"/>
+ <location filename="../../../../src/core/utils/IOUtils.cpp" line="103"/>
+ <location filename="../../../../src/core/utils/IOUtils.cpp" line="108"/>
+ <location filename="../../../../src/core/utils/IOUtils.cpp" line="113"/>
+ <location filename="../../../../src/core/utils/IOUtils.cpp" line="122"/>
<source>: </source>
<translation type="unfinished">: </translation>
</message>
@@ -5869,37 +5989,37 @@ Fals Daten und Signatur in einer Datei COMBINIERT sind, LASSEN SIE DIES LEER: </
<translation>Dateigröße</translation>
</message>
<message>
- <location filename="../../../../src/core/utils/IOUtils.cpp" line="123"/>
+ <location filename="../../../../src/core/utils/IOUtils.cpp" line="120"/>
<source>Error: cannot read target file</source>
<translation>Fehler: Zieldatei kann nicht gelesen werden</translation>
</message>
<message>
- <location filename="../../../../src/core/utils/IOUtils.cpp" line="156"/>
+ <location filename="../../../../src/core/utils/IOUtils.cpp" line="153"/>
<source>target path doesn&apos;t exists</source>
<translation type="unfinished">Zielpfad existiert nicht</translation>
</message>
<message>
- <location filename="../../../../src/core/utils/IOUtils.cpp" line="162"/>
+ <location filename="../../../../src/core/utils/IOUtils.cpp" line="159"/>
<source>do NOT have permission to write path</source>
<translation type="unfinished">habe KEINE Schreibberechtigung für den Pfad</translation>
</message>
<message>
- <location filename="../../../../src/core/utils/IOUtils.cpp" line="168"/>
+ <location filename="../../../../src/core/utils/IOUtils.cpp" line="165"/>
<source>do NOT have permission to read/write file</source>
<translation type="unfinished">habe KEINE Lese-/Schreibberechtigung für die Datei</translation>
</message>
<message>
- <location filename="../../../../src/core/utils/IOUtils.cpp" line="171"/>
+ <location filename="../../../../src/core/utils/IOUtils.cpp" line="168"/>
<source>Success</source>
<translation>erfolgreich</translation>
</message>
<message>
- <location filename="../../../../src/ui/GpgFrontendUIInit.cpp" line="56"/>
+ <location filename="../../../../src/ui/GpgFrontendUIInit.cpp" line="58"/>
<source>Loading Gnupg Info...</source>
<translation type="unfinished">Gnupg-Info wird geladen...</translation>
</message>
<message>
- <location filename="../../../../src/ui/GpgFrontendUIInit.cpp" line="57"/>
+ <location filename="../../../../src/ui/GpgFrontendUIInit.cpp" line="59"/>
<source>If this process is too slow, please set the key server address appropriately in the gnupg configuration file (depending on the network situation in your country or region).</source>
<translation type="unfinished">Sollte dieser Vorgang zu langsam sein, stellen Sie bitte die Keyserver-Adresse entsprechend in der gnupg-Konfigurationsdatei ein (abhängig von der Netzwerksituation in Ihrem Land oder Ihrer Region).</translation>
</message>
@@ -5919,12 +6039,12 @@ Fals Daten und Signatur in einer Datei COMBINIERT sind, LASSEN SIE DIES LEER: </
<translation type="unfinished">Es gibt lokal keinen öffentlichen Zielschlüsselinhalt für GpgFrontend, um genügend Informationen über diese Signatur zu sammeln. Möchten Sie jetzt den öffentlichen Schlüssel vom Keyserver importieren?</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="486"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="528"/>
<source>Sync All Public Key</source>
<translation type="unfinished">Alle öffentlichen Schlüssel synchronisieren</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="487"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="529"/>
<source>You have not checked any public keys that you want to synchronize, do you want to synchronize all local public keys from the key server?</source>
<translation type="unfinished">Sie haben keine öffentlichen Schlüssel angekreuzt, die Sie synchronisieren möchten. Möchten Sie alle lokalen öffentlichen Schlüssel mit dem Schlüsselserver synchronisieren?</translation>
</message>
diff --git a/resource/lfs/locale/ts/GpgFrontend.zh_CN.ts b/resource/lfs/locale/ts/GpgFrontend.zh_CN.ts
index 9ef9da83..c5f18144 100644
--- a/resource/lfs/locale/ts/GpgFrontend.zh_CN.ts
+++ b/resource/lfs/locale/ts/GpgFrontend.zh_CN.ts
@@ -146,6 +146,64 @@
</message>
</context>
<context>
+ <name>GpgFrontend::GpgKeyTableModel</name>
+ <message>
+ <location filename="../../../../src/core/model/GpgKeyTableModel.cpp" line="39"/>
+ <source>Select</source>
+ <translation type="unfinished">选择</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/core/model/GpgKeyTableModel.cpp" line="39"/>
+ <source>Type</source>
+ <translation type="unfinished">类型</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/core/model/GpgKeyTableModel.cpp" line="39"/>
+ <source>Name</source>
+ <translation type="unfinished">姓名</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/core/model/GpgKeyTableModel.cpp" line="40"/>
+ <source>Email Address</source>
+ <translation type="unfinished">电子邮件地址</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/core/model/GpgKeyTableModel.cpp" line="40"/>
+ <source>Usage</source>
+ <translation type="unfinished">用法</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/core/model/GpgKeyTableModel.cpp" line="40"/>
+ <source>Trust</source>
+ <translation type="unfinished">信任</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/core/model/GpgKeyTableModel.cpp" line="41"/>
+ <source>Key ID</source>
+ <translation type="unfinished">密钥ID</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/core/model/GpgKeyTableModel.cpp" line="41"/>
+ <source>Create Date</source>
+ <translation type="unfinished">创建时间</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/core/model/GpgKeyTableModel.cpp" line="41"/>
+ <source>Algorithm</source>
+ <translation type="unfinished">算法</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/core/model/GpgKeyTableModel.cpp" line="42"/>
+ <source>Subkey(s)</source>
+ <translation type="unfinished">子密钥</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/core/model/GpgKeyTableModel.cpp" line="42"/>
+ <source>Comment</source>
+ <translation type="unfinished">注释</translation>
+ </message>
+</context>
+<context>
<name>GpgFrontend::GpgSignResultAnalyse</name>
<message>
<location filename="../../../../src/core/function/result_analyse/GpgSignResultAnalyse.cpp" line="43"/>
@@ -556,6 +614,14 @@
</message>
</context>
<context>
+ <name>GpgFrontend::UI</name>
+ <message>
+ <location filename="../../../../src/ui/dialog/settings/SettingsDialog.cpp" line="123"/>
+ <source>System Default</source>
+ <translation type="unfinished">系统默认</translation>
+ </message>
+</context>
+<context>
<name>GpgFrontend::UI::AboutDialog</name>
<message>
<location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="41"/>
@@ -568,19 +634,22 @@
<translation type="unfinished">关于 GpgFrontend</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="51"/>
+ <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="58"/>
+ <source>Unnamed</source>
+ <translation type="unfinished">未命名</translation>
+ </message>
+ <message>
<source>GnuPG</source>
- <translation type="unfinished">GnuPG</translation>
+ <translation type="obsolete">GnuPG</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="54"/>
+ <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="49"/>
<source>Translators</source>
<translation type="unfinished">翻译贡献者</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="58"/>
<source>Update</source>
- <translation type="unfinished">更新</translation>
+ <translation type="obsolete">更新</translation>
</message>
</context>
<context>
@@ -743,12 +812,12 @@
<context>
<name>GpgFrontend::UI::CommonUtils</name>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="186"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="185"/>
<source>GnuPG Context Loading Failed</source>
<translation type="unfinished">GnuPG 上下文加载失败</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="188"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="187"/>
<source>Gnupg(gpg) is not installed correctly, please follow &lt;a href=&apos;https://www.gpgfrontend.bktus.com/#/faq?id=how-to-deal-with-39env-loading-failed39&apos;&gt;this notes&lt;/a&gt; in FAQ to install Gnupg and then open GpgFrontend. &lt;br /&gt;Or, you can open GnuPG Controller to set a custom GnuPG which GpgFrontend should use. Then, GpgFrontend will restart. &lt;br /&gt;&lt;br /&gt;Breif Reason: %1</source>
<translation type="unfinished">Gnupg(gpg) 未正确安装,请按照常见问题中的 &lt;a href=&apos;https://www.gpgfrontend.bktus.com/#/faq?id=how-to-deal-with-39env-loading-failed39&apos;&gt;this notes&lt;/a&gt; 安装 Gnupg,然后打开 GpgFrontend。&lt;br /&gt;或者,您可以打开 GnuPG Controller 设置 GpgFrontend 应使用的自定义 GnuPG。然后,GpgFrontend 将重新启动。 &lt;br /&gt;&lt;br /&gt;错误原因:%1</translation>
</message>
@@ -757,29 +826,29 @@
<translation type="obsolete">找不到要导入的密钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="450"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="441"/>
<source>Timeout</source>
<translation type="unfinished">超时</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="251"/>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="382"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="248"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="378"/>
<source>Success</source>
<translation type="unfinished">成功</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="252"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="249"/>
<source>Gpg Operation succeed.</source>
<translation type="unfinished">Gpg 操作成功。</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="262"/>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="374"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="259"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="370"/>
<source>Failure</source>
<translation type="unfinished">失败</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="263"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="260"/>
<source>Gpg Operation failed.
Error code: %1
@@ -792,14 +861,14 @@ Description: %3</source>
说明: %3</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="288"/>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="295"/>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="502"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="285"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="292"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="493"/>
<source>Error</source>
<translation type="unfinished">错误</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="280"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="277"/>
<source>Open Key</source>
<translation type="unfinished">打开密钥</translation>
</message>
@@ -808,87 +877,87 @@ Description: %3</source>
<translation type="obsolete">密钥文件</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="281"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="278"/>
<source>Keyring files</source>
<translation type="unfinished">密钥圈文件</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="289"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="286"/>
<source>Cannot open this file. Please make sure that this is a regular file and it&apos;s readable.</source>
<translation type="unfinished">无法打开此文件。请确保这是一个普通文件,并且有读取权限。</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="296"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="293"/>
<source>The target file is too large for a keyring.</source>
<translation>目标文件对于一个密钥来说太大。</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="302"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="299"/>
<source>File Open Failed</source>
<translation>文件打开失败</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="303"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="300"/>
<source>Failed to open file: </source>
<translation>打开文件失败: </translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="355"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="351"/>
<source>Processing</source>
<translation>处理中</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="375"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="371"/>
<source>Failed to execute command.</source>
<translation>执行命令失败。</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="383"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="379"/>
<source>Succeed in executing command.</source>
<translation>成功执行命令。</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="385"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="381"/>
<source>Warning</source>
<translation>警告</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="386"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="382"/>
<source>Finished executing command.</source>
<translation>命令执行完毕。</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="407"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="402"/>
<source>Default Keyserver Not Found</source>
<translation>未找到默认密钥服务器</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="408"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="403"/>
<source>Cannot read default keyserver from your settings, please set a default keyserver first</source>
<translation>无法从您的设置中读取默认密钥服务器,请先设置默认密钥服务器</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="447"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="438"/>
<source>Key Not Found</source>
<translation>未找到密钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="453"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="444"/>
<source>Key Server Not Found</source>
<translation>未找到密钥服务器</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="456"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="447"/>
<source>Connection Error</source>
<translation>连接错误</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="467"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="458"/>
<source>The key has been updated</source>
<translation>密钥已更新</translation>
</message>
<message>
- <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="469"/>
+ <location filename="../../../../src/ui/UserInterfaceUtils.cpp" line="460"/>
<source>No need to update the key</source>
<translation>无需更新密钥</translation>
</message>
@@ -1090,128 +1159,128 @@ Description: %3</source>
<context>
<name>GpgFrontend::UI::FileTreeView</name>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="92"/>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="105"/>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="168"/>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="214"/>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="236"/>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="277"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="88"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="101"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="159"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="204"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="225"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="266"/>
<source>Error</source>
<translation type="unfinished">错误</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="93"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="89"/>
<source>The path is not exists, unprivileged or unreachable.</source>
<translation type="unfinished">该路径不存在、没有特权或无法访问。</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="106"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="102"/>
<source>The file is unprivileged or unreachable.</source>
<translation type="unfinished">该目录不存在,或者您的权限不足。</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="159"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="152"/>
<source>Warning</source>
<translation type="unfinished">警告</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="160"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="153"/>
<source>Are you sure you want to delete it?</source>
<translation type="unfinished">你确定要删除吗?</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="169"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="160"/>
<source>Unable to delete the file or folder.</source>
<translation type="unfinished">无法删除文件或文件夹。</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="178"/>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="191"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="169"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="182"/>
<source>Make New Directory</source>
<translation type="unfinished">新建目录</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="179"/>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="192"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="170"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="183"/>
<source>Directory Name</source>
<translation type="unfinished">目录名称</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="206"/>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="228"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="197"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="218"/>
<source>Create Empty File</source>
<translation type="unfinished">创建空文件</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="206"/>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="228"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="197"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="218"/>
<source>Filename (you can given extension)</source>
<translation type="unfinished">文件名(您可以指定扩展名)</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="215"/>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="237"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="205"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="226"/>
<source>Unable to create the file.</source>
<translation type="unfinished">无法创建文件。</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="269"/>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="300"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="258"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="289"/>
<source>Rename</source>
<translation type="unfinished">改名</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="269"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="258"/>
<source>New Filename</source>
<translation type="unfinished">新文件名</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="278"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="267"/>
<source>Unable to rename the file or folder.</source>
<translation type="unfinished">无法重命名文件或文件夹。</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="295"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="284"/>
<source>Open</source>
<translation type="unfinished">打开</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="305"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="294"/>
<source>Delete</source>
<translation type="unfinished">删除</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="310"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="299"/>
<source>Calculate Hash</source>
<translation type="unfinished">计算哈希值</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="315"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="304"/>
<source>Directory</source>
<translation type="unfinished">目录</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="320"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="309"/>
<source>File</source>
<translation type="unfinished">文件</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="325"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="314"/>
<source>Compress...</source>
<translation type="unfinished">压缩...</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="332"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="321"/>
<source>Open with Default System Application</source>
<translation type="unfinished">使用默认系统应用程序打开</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="337"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="326"/>
<source>New</source>
<translation type="unfinished">新建</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="395"/>
+ <location filename="../../../../src/ui/widgets/FileTreeView.cpp" line="382"/>
<source>Calculating</source>
<translation type="unfinished">计算中</translation>
</message>
@@ -1258,53 +1327,58 @@ Description: %3</source>
</message>
<message>
<location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="56"/>
+ <source>Disable loading of all modules (including integrated modules)</source>
+ <translation type="unfinished">禁止加载所有的模组(包括被集成模组)</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="58"/>
<source>Language</source>
<translation type="unfinished">语言</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="58"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="60"/>
<source>NOTE</source>
<translation type="unfinished">提示</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="58"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="60"/>
<source>: </source>
<translation>: </translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="59"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="61"/>
<source>GpgFrontend will restart automatically if you change the language!</source>
<translation>如果您更改语言,GpgFrontend 将自动重启!</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="61"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="63"/>
<source>Data</source>
<translation>数据</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="63"/>
- <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="81"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="65"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="83"/>
<source>Clear All Log (Total Size: %1)</source>
<translation>清除所有日志(总大小:%1)</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="66"/>
- <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="95"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="68"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="97"/>
<source>Clear All Data Objects (Total Size: %1)</source>
<translation>清除所有数据对象(总大小:%1)</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="69"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="71"/>
<source>Reveal in File Explorer</source>
<translation>在文件资源管理器中显示</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="88"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="90"/>
<source>Confirm</source>
<translation>确认</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="89"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsGeneral.cpp" line="91"/>
<source>Are you sure you want to clear all data objects?
This will result in loss of all cached form positions, statuses, key servers, etc.</source>
<translation>您确定要清除所有数据对象吗?这将导致所有缓存的页面位置、状态、密钥服务器等丢失。</translation>
@@ -1392,19 +1466,19 @@ This will result in loss of all cached form positions, statuses, key servers, et
</message>
<message>
<location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="100"/>
- <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="120"/>
+ <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="117"/>
<source>Open Directory</source>
<translation>打开目录</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="173"/>
+ <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="167"/>
<source>GnuPG Controller</source>
<translation>GnuPG 控制器</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="364"/>
- <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="371"/>
- <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="383"/>
+ <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="349"/>
+ <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="356"/>
+ <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="368"/>
<source>Illegal GnuPG Path</source>
<translation>非法 GnuPG 路径</translation>
</message>
@@ -1413,22 +1487,22 @@ This will result in loss of all cached form positions, statuses, key servers, et
<translation type="obsolete">目标 GnuPG 路径为空。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="365"/>
+ <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="350"/>
<source>Target GnuPG Path is not an exists readable directory.</source>
<translation>目标 GnuPG 路径不是现有的可读目录。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="372"/>
+ <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="357"/>
<source>Target GnuPG Path is not an absolute path.</source>
<translation>目标 GnuPG 路径不是绝对路径。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="384"/>
+ <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="369"/>
<source>Target GnuPG Path contains no &quot;gpgconf&quot; executable.</source>
<translation>目标 GnuPG 路径不包含“gpgconf”可执行文件。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="397"/>
+ <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="382"/>
<source>Illegal GnuPG Key Database Path</source>
<translation>非法的 GnuPG 密钥数据库路径</translation>
</message>
@@ -1437,7 +1511,7 @@ This will result in loss of all cached form positions, statuses, key servers, et
<translation type="obsolete">目标 GnuPG 密钥数据库路径为空。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="398"/>
+ <location filename="../../../../src/ui/dialog/controller/GnuPGControllerDialog.cpp" line="383"/>
<source>Target GnuPG Key Database Path is not an exists readable directory.</source>
<translation>目标 GnuPG 密钥数据库路径不是现有的可读目录。</translation>
</message>
@@ -1445,84 +1519,68 @@ This will result in loss of all cached form positions, statuses, key servers, et
<context>
<name>GpgFrontend::UI::GnupgTab</name>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="46"/>
<source>Name</source>
- <translation>名称</translation>
+ <translation type="vanished">名称</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="46"/>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="92"/>
<source>Description</source>
- <translation>描述</translation>
+ <translation type="vanished">描述</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="46"/>
<source>Version</source>
- <translation>版本</translation>
+ <translation type="vanished">版本</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="47"/>
<source>Checksum</source>
- <translation>校验和</translation>
+ <translation type="vanished">校验和</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="47"/>
<source>Binary Path</source>
- <translation>二进制路径</translation>
+ <translation type="vanished">二进制路径</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="49"/>
<source>Components</source>
- <translation>组件</translation>
+ <translation type="vanished">组件</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="50"/>
<source>Directories</source>
- <translation>目录</translation>
+ <translation type="vanished">目录</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="51"/>
<source>Options</source>
- <translation>参数</translation>
+ <translation type="vanished">参数</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="70"/>
<source>Directory Type</source>
- <translation>目录类型</translation>
+ <translation type="vanished">目录类型</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="70"/>
<source>Path</source>
- <translation>路径</translation>
+ <translation type="vanished">路径</translation>
</message>
<message>
<source>Configurations</source>
<translation type="obsolete">配置</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="91"/>
<source>Component</source>
- <translation>组件</translation>
+ <translation type="vanished">组件</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="91"/>
<source>Group</source>
- <translation>组</translation>
+ <translation type="vanished">组</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="91"/>
<source>Key</source>
- <translation>键</translation>
+ <translation type="vanished">键</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="92"/>
<source>Default Value</source>
- <translation>默认值</translation>
+ <translation type="vanished">默认值</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/GnupgTab.cpp" line="93"/>
<source>Value</source>
- <translation>值</translation>
+ <translation type="vanished">值</translation>
</message>
</context>
<context>
@@ -1566,22 +1624,22 @@ This will result in loss of all cached form positions, statuses, key servers, et
<translation>清空面板</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/InfoBoardWidget.cpp" line="167"/>
+ <location filename="../../../../src/ui/widgets/InfoBoardWidget.cpp" line="166"/>
<source>Save Information Board&apos;s Content</source>
<translation>保存信息面板的内容</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/InfoBoardWidget.cpp" line="167"/>
+ <location filename="../../../../src/ui/widgets/InfoBoardWidget.cpp" line="166"/>
<source>Text (*.txt)</source>
<translation>文本文件 (*.txt)</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/InfoBoardWidget.cpp" line="176"/>
+ <location filename="../../../../src/ui/widgets/InfoBoardWidget.cpp" line="174"/>
<source>Error</source>
<translation>错误</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/InfoBoardWidget.cpp" line="177"/>
+ <location filename="../../../../src/ui/widgets/InfoBoardWidget.cpp" line="175"/>
<source>The file path is not exists, unprivileged or unreachable.</source>
<translation>文件路径不存在、无特权或无法访问。</translation>
</message>
@@ -1589,37 +1647,37 @@ This will result in loss of all cached form positions, statuses, key servers, et
<context>
<name>GpgFrontend::UI::InfoTab</name>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="102"/>
+ <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="99"/>
<source>GpgFrontend is an easy-to-use, compact, cross-platform, and installation-free GnuPG Frontend.It visualizes most of the common operations of GnuPG.GpgFrontend is licensed under the GPLv3</source>
<translation type="unfinished">GpgFrontend 是一个易于使用、紧凑、跨平台、免安装的 GnuPG 前端。它将 GnuPG 的大部分常用操作可视化。GpgFrontend 是在 GPLv3 下授权的</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="108"/>
+ <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="105"/>
<source>Developer:</source>
<translation type="unfinished">开发者:</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="109"/>
+ <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="106"/>
<source>If you have any questions or suggestions, raise an issue at</source>
<translation type="unfinished">如果您有任何问题或建议,请在以下位置提出问题</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="112"/>
+ <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="109"/>
<source>or send a mail to my mailing list at</source>
<translation type="unfinished">或发送邮件到我的邮件列表</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="114"/>
+ <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="111"/>
<source>Built with Qt</source>
<translation type="unfinished">用 Qt 构建</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="115"/>
+ <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="112"/>
<source>and</source>
<translation type="unfinished">和</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="116"/>
+ <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="113"/>
<source>Built at</source>
<translation type="unfinished">构建于</translation>
</message>
@@ -1774,47 +1832,47 @@ This will result in loss of all cached form positions, statuses, key servers, et
<translation type="unfinished">验证</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="436"/>
+ <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="432"/>
<source>Name</source>
<translation type="unfinished">姓名</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="437"/>
+ <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="433"/>
<source>Email Address</source>
<translation type="unfinished">电子邮件地址</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="438"/>
+ <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="434"/>
<source>Comment</source>
<translation type="unfinished">注释</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="439"/>
+ <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="435"/>
<source>Expiration Date</source>
<translation type="unfinished">截止日期</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="440"/>
+ <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="436"/>
<source>Never Expire</source>
<translation type="unfinished">永不过期</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="441"/>
+ <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="437"/>
<source>KeySize (in Bit)</source>
<translation type="unfinished">密钥大小(以位为单位)</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="442"/>
+ <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="438"/>
<source>Key Type</source>
<translation type="unfinished">密钥类型</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="443"/>
+ <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="439"/>
<source>Non Pass Phrase</source>
<translation type="unfinished">不设置密码</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="456"/>
+ <location filename="../../../../src/ui/dialog/key_generate/KeygenDialog.cpp" line="452"/>
<source>Basic Information</source>
<translation type="unfinished">基本信息</translation>
</message>
@@ -1964,132 +2022,140 @@ This will result in loss of all cached form positions, statuses, key servers, et
<context>
<name>GpgFrontend::UI::KeyList</name>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="99"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="220"/>
<source>Refresh</source>
<translation type="unfinished">刷新</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="101"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="222"/>
<source>Refresh the key list to synchronize changes.</source>
<translation type="unfinished">刷新密钥列表以同步更改。</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="102"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="223"/>
<source>Sync Public Key</source>
<translation type="unfinished">同步公钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="104"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="225"/>
<source>Sync public key with your default keyserver.</source>
<translation type="unfinished">将公钥与您的默认密钥服务器同步。</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="105"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="226"/>
<source>Uncheck ALL</source>
<translation type="unfinished">全不选</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="107"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="228"/>
<source>Cancel all checked items in the current tab at once.</source>
<translation type="unfinished">一次性取消选中当前选项卡中所有的项目。</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="108"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="229"/>
<source>Check ALL</source>
<translation type="unfinished">全选</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="110"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="231"/>
<source>Check all items in the current tab at once</source>
<translation type="unfinished">一次性选中当前选项卡中的所有项目</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="111"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="232"/>
<source>Search for keys...</source>
<translation type="unfinished">搜索钥匙...</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="170"/>
<source>Select</source>
- <translation type="unfinished">选择</translation>
+ <translation type="obsolete">选择</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="170"/>
<source>Type</source>
- <translation type="unfinished">类型</translation>
+ <translation type="obsolete">类型</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="170"/>
<source>Name</source>
- <translation type="unfinished">姓名</translation>
+ <translation type="obsolete">姓名</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="170"/>
<source>Email Address</source>
- <translation type="unfinished">电子邮件地址</translation>
+ <translation type="obsolete">电子邮件地址</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="171"/>
<source>Usage</source>
- <translation type="unfinished">用法</translation>
+ <translation type="obsolete">用法</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="171"/>
<source>Trust</source>
- <translation type="unfinished">信任</translation>
+ <translation type="obsolete">信任</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="171"/>
<source>Finger Print</source>
- <translation type="unfinished">指纹</translation>
+ <translation type="obsolete">指纹</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="171"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="74"/>
<source>Key ID</source>
<translation type="unfinished">密钥编号</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="186"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="85"/>
+ <source>Algorithm</source>
+ <translation type="unfinished">算法</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="96"/>
+ <source>Owner Trust</source>
+ <translation type="unfinished">信任级别</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="108"/>
+ <source>Create Date</source>
+ <translation type="unfinished">创建时间</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="263"/>
<source>Refreshing Key List...</source>
<translation type="unfinished">正在刷新密钥列表...</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="374"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="431"/>
<source>Import Keys</source>
<translation type="unfinished">导入密钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="376"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="433"/>
<source>You&apos;ve dropped something on the table.</source>
<translation type="unfinished">你把东西掉在桌子上了。</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="377"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="434"/>
<source>GpgFrontend will now try to import key(s).</source>
<translation type="unfinished">GpgFrontend 现在将尝试导入密钥。</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="380"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="437"/>
<source>Always import without bothering.</source>
<translation type="unfinished">始终导入而无需打扰。</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="475"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="270"/>
<source>Key List Refreshed.</source>
<translation type="unfinished">密钥列表已刷新。</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="510"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="550"/>
<source>Syncing Key List...</source>
<translation type="unfinished">正在同步密钥列表...</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="518"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="556"/>
<source>Sync [%1/%2] %3 %4</source>
<translation type="unfinished">同步 [%1/%2] %3 %4</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="528"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="566"/>
<source>Key List Sync Done.</source>
<translation type="unfinished">密钥列表同步完成。</translation>
</message>
@@ -2102,363 +2168,363 @@ This will result in loss of all cached form positions, statuses, key servers, et
<translation type="unfinished">全部</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="61"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="62"/>
<source>Only Public Key</source>
<translation type="unfinished">只有公钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="71"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="69"/>
<source>Has Private Key</source>
<translation type="unfinished">有私钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="81"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="76"/>
<source>No Primary Key</source>
<translation type="unfinished">无主密钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="90"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="85"/>
<source>Revoked</source>
<translation type="unfinished">已吊销</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="98"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="92"/>
<source>Expired</source>
<translation type="unfinished">已到期</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="123"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="116"/>
<source>KeyPair Management</source>
<translation type="unfinished">密钥对管理</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="144"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="137"/>
<source>Open</source>
<translation type="unfinished">打开</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="146"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="139"/>
<source>Open Key File</source>
<translation type="unfinished">打开密钥文件</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="150"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="153"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="143"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="146"/>
<source>Close</source>
<translation type="unfinished">关闭</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="156"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="149"/>
<source>New Keypair</source>
<translation type="unfinished">新密钥对</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="159"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="152"/>
<source>Generate KeyPair</source>
<translation type="unfinished">生成密钥对</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="163"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="156"/>
<source>New Subkey</source>
<translation type="unfinished">新子密钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="167"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="160"/>
<source>Generate Subkey For Selected KeyPair</source>
<translation type="unfinished">为选定的密钥对生成子密钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="171"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="265"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="164"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="258"/>
<source>File</source>
<translation type="unfinished">文件</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="173"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="166"/>
<source>Import New Key From File</source>
<translation type="unfinished">从文件导入新密钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="177"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="170"/>
<source>Clipboard</source>
<translation type="unfinished">剪贴板</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="181"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="174"/>
<source>Import New Key From Clipboard</source>
<translation type="unfinished">从剪贴板导入新密钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="192"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="185"/>
<source>Keyserver</source>
<translation type="unfinished">密钥服务器</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="196"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="189"/>
<source>Import New Key From Keyserver</source>
<translation type="unfinished">从密钥服务器导入新密钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="202"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="536"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="195"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="529"/>
<source>Key Package</source>
<translation type="unfinished">密钥包</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="205"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="198"/>
<source>Import Key(s) From a Key Package</source>
<translation type="unfinished">从密钥包导入密钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="209"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="202"/>
<source>Export To Clipboard</source>
<translation type="unfinished">导出到剪贴板</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="213"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="206"/>
<source>Export Checked Key(s) To Clipboard</source>
<translation type="unfinished">将选中的密钥导出到剪贴板</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="217"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="210"/>
<source>Export As Key Package</source>
<translation type="unfinished">导出为密钥包</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="220"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="213"/>
<source>Export Checked Key(s) To a Key Package</source>
<translation type="unfinished">将勾选的密钥导出到密钥包</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="224"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="217"/>
<source>Export As OpenSSH</source>
<translation type="unfinished">导出为OpenSSH密钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="227"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="220"/>
<source>Export Checked Key As OpenSSH Format to File</source>
<translation type="unfinished">将校验过的密钥导出为 OpenSSH 格式文件</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="231"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="224"/>
<source>Delete Selected Key(s)</source>
<translation type="unfinished">删除这些选定的密钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="233"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="226"/>
<source>Delete the Selected keys</source>
<translation type="unfinished">删除这个选定的密钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="237"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="230"/>
<source>Delete Checked Key(s)</source>
<translation type="unfinished">删除选中的密钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="239"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="232"/>
<source>Delete the Checked keys</source>
<translation type="unfinished">删除选中的密钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="244"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="237"/>
<source>Show Key Details</source>
<translation type="unfinished">显示密钥细节</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="246"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="239"/>
<source>Show Details for this Key</source>
<translation type="unfinished">显示此密钥的详细信息</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="250"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="252"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="243"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="245"/>
<source>Set Owner Trust Level</source>
<translation type="unfinished">设置所有者信任级别</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="269"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="289"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="262"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="282"/>
<source>Key</source>
<translation type="unfinished">密钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="270"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="263"/>
<source>Generate Key</source>
<translation type="unfinished">生成密钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="274"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="302"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="267"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="295"/>
<source>Import Key</source>
<translation type="unfinished">导入密钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="280"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="310"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="311"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="273"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="303"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="304"/>
<source>Export Key</source>
<translation type="unfinished">导出密钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="301"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="294"/>
<source>Import key</source>
<translation type="unfinished">导入密钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="344"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="337"/>
<source>Deleting Keys</source>
<translation type="unfinished">删除密钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="345"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="338"/>
<source>Are you sure that you want to delete the following keys?</source>
<translation type="unfinished">您确定要删除以下密钥吗?</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="347"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="340"/>
<source>The action can not be undone.</source>
<translation type="unfinished">该操作无法撤消。</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="363"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="412"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="424"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="452"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="491"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="502"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="515"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="545"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="553"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="569"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="577"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="593"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="356"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="405"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="417"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="445"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="484"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="495"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="508"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="538"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="546"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="562"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="570"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="585"/>
<source>Error</source>
<translation type="unfinished">错误</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="363"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="452"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="356"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="445"/>
<source>Key Not Found.</source>
<translation type="unfinished">未找到密钥。</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="374"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="387"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="470"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="476"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="367"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="380"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="463"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="469"/>
<source>Forbidden</source>
<translation type="unfinished">操作被禁止</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="375"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="388"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="368"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="381"/>
<source>Please check some keys before doing this operation.</source>
<translation type="unfinished">请在执行此操作之前勾选一些密钥。</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="380"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="528"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="373"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="521"/>
<source>key(s) exported</source>
<translation type="unfinished">导出的密钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="404"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="483"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="397"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="476"/>
<source>Exporting</source>
<translation type="unfinished">导出中</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="413"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="425"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="492"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="503"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="406"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="418"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="485"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="496"/>
<source>Unknown error occurred</source>
<translation type="unfinished">发生了未知错误</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="446"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="456"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="439"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="449"/>
<source>Invalid Operation</source>
<translation type="unfinished">无效操作</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="447"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="440"/>
<source>Please select one KeyPair before doing this operation.</source>
<translation type="unfinished">请在执行此操作前选择一个钥对。</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="457"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="450"/>
<source>If a key pair does not have a private key then it will not be able to generate sub-keys.</source>
<translation type="unfinished">如果密钥对没有私钥,那么它将无法生成子密钥。</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="471"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="464"/>
<source>Please check a key before performing this operation.</source>
<translation type="unfinished">请在执行此操作前勾选一个密钥。</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="477"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="470"/>
<source>This operation accepts just a single key.</source>
<translation type="unfinished">此操作只接受单个密钥。</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="516"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="509"/>
<source>This key may not be able to export as OpenSSH format. Please check the key-size of the subkey(s) used to sign.</source>
<translation type="unfinished">此密钥可能无法导出为 OpenSSH 格式。请检查用于签名的子密钥的密钥大小。</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="523"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="516"/>
<source>Export OpenSSH Key To File</source>
<translation type="unfinished">将 OpenSSH 密钥导出到文件</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="524"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="517"/>
<source>OpenSSH Public Key Files</source>
<translation type="unfinished">OpenSSH 公钥文件</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="536"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="529"/>
<source>Import Key Package</source>
<translation type="unfinished">导入密钥包</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="546"/>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="570"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="539"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="563"/>
<source>Cannot open this file. Please make sure that this is a regular file and it&apos;s readable.</source>
<translation type="unfinished">无法打开此文件。请确保这是一个普通文件,并且有读取权限。</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="554"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="547"/>
<source>The target file is too large for a key package.</source>
<translation type="unfinished">目标文件对于密钥包来说太大。</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="559"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="552"/>
<source>Import Key Package Passphrase File</source>
<translation type="unfinished">导入密钥包口令文件</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="560"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="553"/>
<source>Key Package Passphrase File</source>
<translation type="unfinished">密钥包口令文件</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="578"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="571"/>
<source>The target file is too large for a key package passphrase.</source>
<translation type="unfinished">目标文件对于密钥包口令来说太大。</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="584"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="576"/>
<source>Importing</source>
<translation type="unfinished">导入中</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="600"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="592"/>
<source>key(s) imported</source>
<translation type="unfinished">导入的密钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="594"/>
+ <location filename="../../../../src/ui/main_window/KeyMgmt.cpp" line="586"/>
<source>An error occur in importing key package.</source>
<translation type="unfinished">导入密钥包出错。</translation>
</message>
@@ -2662,256 +2728,317 @@ This will result in loss of all cached form positions, statuses, key servers, et
<context>
<name>GpgFrontend::UI::KeyPairOperaTab</name>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="53"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="54"/>
<source>General Operations</source>
<translation>一般操作</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="59"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="60"/>
<source>Export Public Key</source>
<translation>导出公钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="65"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="66"/>
<source>Export Private Key</source>
<translation>导出私钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="72"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="73"/>
<source>Modify Expiration Datetime (Primary Key)</source>
<translation>修改到期日期时间(主密钥)</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="75"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="76"/>
<source>Modify Password</source>
<translation>修改密码</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="93"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="94"/>
<source>Key Server Operation (Pubkey)</source>
<translation>密钥服务器操作(公钥)</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="177"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="199"/>
<source>Generate Revoke Certificate</source>
<translation>生成吊销证书</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="107"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="118"/>
<source>Modify TOFU Policy</source>
<translation>修改TOFU策略</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="101"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="102"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="558"/>
+ <source>Import A Paper Key</source>
+ <translation type="unfinished">导入纸密钥</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="112"/>
<source>Revoke Certificate Operation</source>
<translation>吊销证书操作</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="114"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="125"/>
<source>Set Owner Trust Level</source>
<translation>设置所有者信任级别</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="138"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="149"/>
<source>Upload Key Pair to Key Server</source>
<translation>上传密钥对到密钥服务器</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="146"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="157"/>
<source>Sync Key Pair From Key Server</source>
<translation>从密钥服务器同步密钥对</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="161"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="172"/>
<source>Export Full Secret Key</source>
<translation>导出完整私钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="167"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="178"/>
<source>Export Shortest Secret Key</source>
<translation>导出最短私钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="182"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="184"/>
+ <source>Export Secret Key As A Paper Key</source>
+ <translation type="unfinished">将私钥导出为纸密钥</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="204"/>
<source>Import Revoke Certificate</source>
<translation>导入吊销证书</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="209"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="255"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="298"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="231"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="277"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="320"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="505"/>
<source>Export Key To File</source>
<translation>将密钥导出到文件</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="210"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="256"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="299"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="232"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="278"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="321"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="506"/>
<source>Key Files</source>
<translation>密钥文件</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="215"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="261"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="304"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="237"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="283"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="326"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="529"/>
<source>Export Error</source>
<translation>导出错误</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="216"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="262"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="305"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="238"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="284"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="327"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="530"/>
<source>Couldn&apos;t open %1 for writing</source>
<translation>无法打开 %1 进行写入</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="224"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="246"/>
<source>Exporting short private Key</source>
<translation>导出短私钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="225"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="272"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="247"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="294"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="474"/>
<source>You are about to export your</source>
<translation>您即将导出您的</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="226"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="273"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="248"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="295"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="475"/>
<source> PRIVATE KEY </source>
<translation> 私钥 </translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="227"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="274"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="249"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="296"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="476"/>
<source>This is NOT your Public Key, so DON&apos;T give it away.</source>
<translation>这不是你的公钥,所以不要把它给别人。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="228"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="250"/>
<source>Do you REALLY want to export your PRIVATE KEY in a Minimum Size?</source>
<translation>您真的想以最小尺寸导出您的私钥吗?</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="231"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="253"/>
<source>For OpenPGP keys it removes all signatures except for the latest self-signatures.</source>
<translation>对于 OpenPGP 密钥,它会删除除最新的自签名之外的所有签名。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="271"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="293"/>
<source>Exporting private Key</source>
<translation>导出私钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="275"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="297"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="482"/>
<source>Do you REALLY want to export your PRIVATE KEY?</source>
<translation>你真的想导出你的私钥吗?</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="329"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="412"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="351"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="433"/>
<source>Revocation Certificates</source>
<translation>吊销证书</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="340"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="362"/>
<source>Generate revocation certificate</source>
<translation>生成撤吊销证书</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="361"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="371"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="383"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="392"/>
<source>Policy Auto</source>
<translation>策略:自动</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="361"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="373"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="383"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="394"/>
<source>Policy Good</source>
<translation>策略:正常</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="361"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="375"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="383"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="396"/>
<source>Policy Bad</source>
<translation>策略:异常</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="362"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="377"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="384"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="398"/>
<source>Policy Ask</source>
<translation>策略:询问</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="362"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="379"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="384"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="400"/>
<source>Policy Unknown</source>
<translation>策略:未知</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="366"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="388"/>
<source>Modify TOFU Policy(Default is Auto)</source>
<translation>修改TOFU策略(默认为自动)</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="367"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="389"/>
<source>Policy for the Key Pair:</source>
<translation>密钥对策略:</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="384"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="405"/>
<source>Not Successful</source>
<translation>失败</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="385"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="406"/>
<source>Modify TOFU policy not successfully.</source>
<translation>修改 TOFU 策略失败。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="399"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="411"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="420"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="432"/>
<source>Import Key Revocation Certificate</source>
<translation>导入密钥吊销证书</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="400"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="421"/>
<source>You are about to import the</source>
<translation>您将导入</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="401"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="422"/>
<source>REVOCATION CERTIFICATE</source>
<translation>吊销证书</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="402"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="423"/>
<source>A successful import will result in the key being irreversibly revoked.</source>
<translation>导入成功后,密钥将被不可逆转地吊销。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="404"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="425"/>
<source>Do you REALLY want to execute this operation?</source>
<translation>您真的想执行这个操作吗?</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="420"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="429"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="442"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="441"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="450"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="459"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="522"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="567"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="575"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="583"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="601"/>
<source>Error</source>
<translation>错误</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="421"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="443"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="442"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="460"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="568"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="584"/>
<source>Cannot open this file. Please make sure that this is a regular file and it&apos;s readable.</source>
<translation>无法打开此文件。请确保这是一个普通文件,并且有读取权限。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="430"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="451"/>
<source>The target file is too large for a key revocation certificate.</source>
<translation>目标文件对于一个密钥吊销证书来说太大了。</translation>
</message>
+ <message>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="473"/>
+ <source>Exporting private key as a Paper key</source>
+ <translation type="unfinished">将私钥导出为纸密钥</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="477"/>
+ <source>A PaperKey is a human-readable printout of your private key, which can be used to recover your key if you lose access to your digital copy. </source>
+ <translation type="unfinished">纸密钥是私人密钥的人工可读打印件,如果丢失了密钥的数字版本,可以用它来恢复密钥。</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="481"/>
+ <source>Keep it in a safe place.</source>
+ <translation type="unfinished">请妥善保管。</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="523"/>
+ <source>An error occurred trying to generate Paper Key.</source>
+ <translation type="unfinished">尝试生成纸密钥时发生错误。</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="602"/>
+ <source>An error occurred trying to recover the Paper Key back to the private key.</source>
+ <translation type="unfinished">用纸密钥恢复私钥时发生了错误。</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="559"/>
+ <source>Paper Key File</source>
+ <translation type="unfinished">纸密钥文件</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairOperaTab.cpp" line="576"/>
+ <source>The target file is too large for a paper key keyring.</source>
+ <translation type="unfinished">目标文件对于一个纸密钥文件来说太大了。</translation>
+ </message>
</context>
<context>
<name>GpgFrontend::UI::KeyPairSubkeyTab</name>
@@ -3007,57 +3134,57 @@ This will result in loss of all cached form positions, statuses, key servers, et
<translation type="unfinished">到期日期</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="203"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="200"/>
<source>Never Expire</source>
<translation type="unfinished">永不过期</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="240"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="235"/>
<source>Never Expires</source>
<translation type="unfinished">永不过期</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="262"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="257"/>
<source>Certificate</source>
<translation type="unfinished">证书</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="264"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="259"/>
<source>Encrypt</source>
<translation type="unfinished">加密</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="265"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="260"/>
<source>Sign</source>
<translation type="unfinished">签名</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="266"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="261"/>
<source>Auth</source>
<translation type="unfinished">认证</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="271"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="266"/>
<source>Exists</source>
<translation type="unfinished">存在</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="272"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="267"/>
<source>Not Exists</source>
<translation type="unfinished">不存在</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="275"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="270"/>
<source>Yes</source>
<translation type="unfinished">是</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="275"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="270"/>
<source>No</source>
<translation type="unfinished">否</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="304"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp" line="299"/>
<source>Edit Expire Date</source>
<translation type="unfinished">编辑到期日期</translation>
</message>
@@ -3127,154 +3254,154 @@ This will result in loss of all cached form positions, statuses, key servers, et
<translation type="unfinished">过期时间</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="240"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="239"/>
<source>TOFU %1</source>
<translation type="unfinished">TOFU %1</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="288"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="287"/>
<source>Never Expires</source>
<translation type="unfinished">永不过期</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="305"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="364"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="484"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="498"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="541"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="550"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="304"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="363"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="482"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="496"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="539"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="548"/>
<source>Invalid Operation</source>
<translation type="unfinished">无效操作</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="306"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="365"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="305"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="364"/>
<source>Please select one or more UIDs before doing this operation.</source>
<translation type="unfinished">请在执行此操作前选择一个或多个 UID。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="328"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="327"/>
<source>Sign Selected UID(s)</source>
<translation type="unfinished">签署选定的 UID</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="331"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="330"/>
<source>Delete Selected UID(s)</source>
<translation type="unfinished">删除选定的 UID</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="351"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="350"/>
<source>Successful Operation</source>
<translation type="unfinished">操作成功</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="352"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="351"/>
<source>Successfully added a new UID.</source>
<translation type="unfinished">成功添加了新的 UID。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="354"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="389"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="423"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="519"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="571"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="353"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="387"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="421"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="517"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="569"/>
<source>Operation Failed</source>
<translation type="unfinished">操作失败</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="355"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="424"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="520"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="572"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="354"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="422"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="518"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="570"/>
<source>An error occurred during the operation.</source>
<translation type="unfinished">操作过程中发生错误。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="376"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="375"/>
<source>Deleting UIDs</source>
<translation type="unfinished">删除 UID</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="379"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="378"/>
<source>Are you sure that you want to delete the following UIDs?</source>
<translation type="unfinished">您确定要删除以下 UID 吗?</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="381"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="417"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="514"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="566"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="380"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="415"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="512"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="564"/>
<source>The action can not be undone.</source>
<translation type="unfinished">该操作无法撤消。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="390"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="388"/>
<source>An error occurred during the delete %1 operation.</source>
<translation type="unfinished">删除 %1 操作期间出错。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="414"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="412"/>
<source>Set Primary UID</source>
<translation type="unfinished">设置主 UID</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="415"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="413"/>
<source>Are you sure that you want to set the Primary UID to?</source>
<translation type="unfinished">您确定要将主 UID 设置为吗?</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="455"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="453"/>
<source>Set As Primary</source>
<translation type="unfinished">设为主要</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="458"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="456"/>
<source>Sign UID</source>
<translation type="unfinished">签署 UID</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="461"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="459"/>
<source>Delete UID</source>
<translation type="unfinished">删除 UID</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="485"/>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="499"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="483"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="497"/>
<source>Please select one UID before doing this operation.</source>
<translation type="unfinished">请在执行此操作前选择一个 UID。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="509"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="507"/>
<source>Deleting UID</source>
<translation type="unfinished">删除 UID</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="512"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="510"/>
<source>Are you sure that you want to delete the following uid?</source>
<translation type="unfinished">您确定要删除以下 UID 吗?</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="530"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="528"/>
<source>Delete(Revoke) Key Signature</source>
<translation type="unfinished">删除(撤销)密钥签名</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="542"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="540"/>
<source>Please select one Key Signature before doing this operation.</source>
<translation type="unfinished">请在执行此操作前选择一个密钥签名。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="551"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="549"/>
<source>To delete the signature, you need to have its corresponding public key in the local database.</source>
<translation type="unfinished">要删除签名,您需要在本地数据库中有其对应的公钥。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="561"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="559"/>
<source>Deleting Key Signature</source>
<translation type="unfinished">删除密钥签名</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="563"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyPairUIDTab.cpp" line="561"/>
<source>Are you sure that you want to delete the following signature?</source>
<translation type="unfinished">您确定要删除以下签名吗?</translation>
</message>
@@ -3313,8 +3440,12 @@ This will result in loss of all cached form positions, statuses, key servers, et
<translation type="unfinished">密钥服务器</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="113"/>
<source>Import Keys from Keyserver</source>
+ <translation type="obsolete">从密钥服务器导入密钥</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="113"/>
+ <source>Import Keys from key server</source>
<translation type="unfinished">从密钥服务器导入密钥</translation>
</message>
<message>
@@ -3343,77 +3474,77 @@ This will result in loss of all cached form positions, statuses, key servers, et
<translation type="unfinished">文字为空。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="223"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="219"/>
<source>Not Key Found</source>
<translation type="unfinished">未找到密钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="226"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="222"/>
<source>Timeout</source>
<translation type="unfinished">超时</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="229"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="225"/>
<source>Key Server Not Found</source>
<translation type="unfinished">未找到密钥服务器</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="232"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="228"/>
<source>Connection Error</source>
<translation type="unfinished">连接错误</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="241"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="237"/>
<source>Too many responses from keyserver!</source>
<translation type="unfinished">来自密钥服务器的响应太多!</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="253"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="249"/>
<source>No keys found, input may be kexId, retrying search with 0x.</source>
<translation type="unfinished">未找到密钥,输入可能是 kexId,正在使用 0x 重试。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="263"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="259"/>
<source>No keys found containing the search string!</source>
<translation type="unfinished">未找到包含搜索字符串的密钥!</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="270"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="266"/>
<source>Insufficiently specific search string!</source>
<translation type="unfinished">不够具体的搜索字符串!</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="305"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="301"/>
<source>revoked</source>
<translation type="unfinished">撤销</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="308"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="304"/>
<source>disabled</source>
<translation type="unfinished">被禁用</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="353"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="349"/>
<source>%1 keys found. Double click a key to import it.</source>
<translation type="unfinished">找到 %1 个密钥。双击一个密钥来导入它。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="374"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="370"/>
<source>Warning</source>
<translation type="unfinished">警告</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="375"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="371"/>
<source>Please select one KeyPair before doing this operation.</source>
<translation type="unfinished">请在执行此操作前选择一个钥对。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="422"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="417"/>
<source>Key Imported</source>
<translation type="unfinished">密钥导入成功</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="433"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyServerImportDialog.cpp" line="428"/>
<source>Processing ...</source>
<translation type="unfinished">处理中 ......</translation>
</message>
@@ -3421,27 +3552,27 @@ This will result in loss of all cached form positions, statuses, key servers, et
<context>
<name>GpgFrontend::UI::KeyServerImportTask</name>
<message>
- <location filename="../../../../src/ui/thread/KeyServerImportTask.cpp" line="79"/>
+ <location filename="../../../../src/ui/thread/KeyServerImportTask.cpp" line="78"/>
<source>Key not found in the Keyserver.</source>
<translation type="unfinished">密钥服务器中找不到密钥。</translation>
</message>
<message>
- <location filename="../../../../src/ui/thread/KeyServerImportTask.cpp" line="82"/>
+ <location filename="../../../../src/ui/thread/KeyServerImportTask.cpp" line="81"/>
<source>Network connection timeout.</source>
<translation type="unfinished">网络连接错误。</translation>
</message>
<message>
- <location filename="../../../../src/ui/thread/KeyServerImportTask.cpp" line="85"/>
+ <location filename="../../../../src/ui/thread/KeyServerImportTask.cpp" line="84"/>
<source>Cannot resolve the address of target key server.</source>
<translation type="unfinished">网络连接超时。</translation>
</message>
<message>
- <location filename="../../../../src/ui/thread/KeyServerImportTask.cpp" line="88"/>
+ <location filename="../../../../src/ui/thread/KeyServerImportTask.cpp" line="87"/>
<source>General connection error occurred.</source>
<translation type="unfinished">出现一般连接错误。</translation>
</message>
<message>
- <location filename="../../../../src/ui/thread/KeyServerImportTask.cpp" line="94"/>
+ <location filename="../../../../src/ui/thread/KeyServerImportTask.cpp" line="93"/>
<source>Success</source>
<translation type="unfinished">成功</translation>
</message>
@@ -3449,80 +3580,93 @@ This will result in loss of all cached form positions, statuses, key servers, et
<context>
<name>GpgFrontend::UI::KeySetExpireDateDialog</name>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="81"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="73"/>
<source>Success</source>
<translation type="unfinished">成功</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="82"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="74"/>
<source>The expire date of the key pair has been updated.</source>
<translation type="unfinished">密钥对的到期日期已更新。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="91"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="83"/>
<source>Failure</source>
<translation type="unfinished">失败</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="92"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="84"/>
<source>Failed to update the expire date of the key pair.</source>
<translation type="unfinished">无法更新密钥对的过期日期。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="136"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="128"/>
<source>Modified Expiration Date (Local Time)</source>
<translation type="unfinished">修改到期日期(本地时间)</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="137"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="129"/>
<source>Tips: For the sake of security, the key is valid for up to two years. If you are an expert user, please unlock it for a longer time in the settings.</source>
<translation type="unfinished">温馨提示:为安全起见,密钥有效期最长为两年。如果您是专家用户,请在设置中解锁更长的时间。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="141"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="133"/>
<source>No Expiration</source>
<translation type="unfinished">无有效期</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="142"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp" line="134"/>
<source>Modified Expiration Date</source>
<translation type="unfinished">修改到期日</translation>
</message>
</context>
<context>
+ <name>GpgFrontend::UI::KeyTable</name>
+ <message>
+ <location filename="../../../../src/ui/widgets/KeyTable.cpp" line="83"/>
+ <source>Error</source>
+ <translation type="unfinished">错误</translation>
+ </message>
+ <message>
+ <location filename="../../../../src/ui/widgets/KeyTable.cpp" line="83"/>
+ <source>Key Not Found.</source>
+ <translation type="unfinished">未找到密钥。</translation>
+ </message>
+</context>
+<context>
<name>GpgFrontend::UI::KeyUIDSignDialog</name>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="46"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="50"/>
<source>Signers</source>
<translation type="unfinished">签名者</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="80"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="83"/>
<source>Expire Date</source>
<translation type="unfinished">到期日期</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="90"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="93"/>
<source>Sign For Key&apos;s UID(s)</source>
<translation type="unfinished">为密钥的 UID 签名</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="114"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="113"/>
<source>Unsuccessful Operation</source>
<translation type="unfinished">不成功的操作</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="115"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="114"/>
<source>Signature operation failed for UID %1</source>
<translation type="unfinished">UID %1 的签名操作失败</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="120"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="119"/>
<source>Operation Complete</source>
<translation type="unfinished">操作完成</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="121"/>
+ <location filename="../../../../src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp" line="120"/>
<source>The signature operation of the UID is complete</source>
<translation type="unfinished">UID的签名操作完成</translation>
</message>
@@ -3545,37 +3689,37 @@ This will result in loss of all cached form positions, statuses, key servers, et
<translation type="unfinished">发生未知错误</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="150"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="148"/>
<source>Key Not Found</source>
<translation type="unfinished">未找到密钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="153"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="151"/>
<source>Timeout</source>
<translation type="unfinished">超时</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="156"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="154"/>
<source>Key Server Not Found</source>
<translation type="unfinished">未找到密钥服务器</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="159"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="157"/>
<source>Connection Error</source>
<translation type="unfinished">连接错误</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="161"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="159"/>
<source>Upload Failed</source>
<translation type="unfinished">上传失败</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="165"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="163"/>
<source>Upload Success</source>
<translation type="unfinished">上传成功</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="166"/>
+ <location filename="../../../../src/ui/dialog/import_export/KeyUploadDialog.cpp" line="164"/>
<source>Upload Public Key Successfully</source>
<translation type="unfinished">上传公钥成功</translation>
</message>
@@ -3644,67 +3788,67 @@ This will result in loss of all cached form positions, statuses, key servers, et
<translation type="unfinished">设为默认</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="143"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="142"/>
<source>Insecure keyserver address</source>
<translation type="unfinished">不安全的密钥服务器地址</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="144"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="143"/>
<source>For security reasons, using HTTP as the communication protocol with the key server is not recommended. It is recommended to use HTTPS.</source>
<translation type="unfinished">出于安全原因,不建议使用 HTTP 作为与密钥服务器的通信协议。建议使用HTTPS。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="152"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="151"/>
<source>Warning</source>
<translation type="unfinished">警告</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="153"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="152"/>
<source>You may not use HTTPS or HTTP as the protocol for communicating with the key server, which may not be wrong. But please check the address you entered again to make sure it is correct. Are you sure that want to add it into the keyserver list?</source>
<translation type="unfinished">通常不会使用HTTPS或HTTP作为与密钥服务器通信的协议。当然,您可能需要这么做。但是,烦请您再次检查您输入的地址。您确定要将其添加到密钥服务器列表中吗?</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="200"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="197"/>
<source>true</source>
<translation type="unfinished">是</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="201"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="198"/>
<source>false</source>
<translation type="unfinished">错误的</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="206"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="203"/>
<source>unknown</source>
<translation type="unfinished">未知</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="220"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="217"/>
<source>Set TCP Timeout</source>
<translation type="unfinished">设置 TCP 超时</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="221"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="218"/>
<source>timeout(ms): </source>
<translation>超时时间(毫秒): </translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="245"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="242"/>
<source>Reachable</source>
<translation type="unfinished">正常</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="248"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="245"/>
<source>Not Reachable</source>
<translation type="unfinished">离线</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="260"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="257"/>
<source>Test Key Server Connection...</source>
<translation type="unfinished">测试密钥服务器连通性...</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="261"/>
+ <location filename="../../../../src/ui/dialog/settings/SettingsKeyServer.cpp" line="258"/>
<source>This test only tests the network connectivity of the key server. Passing the test does not mean that the key server is functionally available.</source>
<translation type="unfinished">本测试仅测试密钥服务器的网络连通性。通过测试并不意味着密钥服务器在功能上可用。</translation>
</message>
@@ -3732,35 +3876,35 @@ This will result in loss of all cached form positions, statuses, key servers, et
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="216"/>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="260"/>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="279"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="297"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="311"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="329"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="347"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="361"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="380"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="435"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="454"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="490"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="509"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="537"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="577"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="614"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="640"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="680"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="718"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="744"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="752"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="776"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="813"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="823"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="848"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="296"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="310"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="328"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="345"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="359"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="378"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="433"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="452"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="488"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="504"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="532"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="572"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="609"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="635"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="675"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="713"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="739"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="747"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="771"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="808"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="817"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="842"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="74"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="121"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="177"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="210"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="246"/>
- <location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="322"/>
- <location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="368"/>
+ <location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="314"/>
+ <location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="360"/>
<location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="97"/>
<location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="121"/>
<location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="141"/>
@@ -3768,8 +3912,8 @@ This will result in loss of all cached form positions, statuses, key servers, et
<location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="170"/>
<location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="183"/>
<location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="198"/>
- <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="248"/>
- <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="256"/>
+ <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="249"/>
+ <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="257"/>
<source>Error</source>
<translation type="unfinished">错误</translation>
</message>
@@ -3777,13 +3921,13 @@ This will result in loss of all cached form positions, statuses, key servers, et
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="50"/>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="165"/>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="280"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="330"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="381"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="455"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="538"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="641"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="745"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="814"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="329"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="379"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="453"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="533"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="636"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="740"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="809"/>
<source>Cannot read from file: %1</source>
<translation type="unfinished">无法读取文件:%1</translation>
</message>
@@ -3796,25 +3940,25 @@ This will result in loss of all cached form positions, statuses, key servers, et
<message>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="66"/>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="181"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="288"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="338"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="416"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="584"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="687"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="758"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="829"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="287"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="336"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="414"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="579"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="682"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="753"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="823"/>
<source>Warning</source>
<translation type="unfinished">警告</translation>
</message>
<message>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="75"/>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="190"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="298"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="348"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="578"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="681"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="753"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="824"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="297"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="346"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="573"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="676"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="748"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="818"/>
<source>Cannot write to file: %1</source>
<translation type="unfinished">无法写入文件:%1</translation>
</message>
@@ -3842,29 +3986,29 @@ This will result in loss of all cached form positions, statuses, key servers, et
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="146"/>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="217"/>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="261"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="312"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="362"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="436"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="510"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="615"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="719"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="777"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="849"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="311"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="360"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="434"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="505"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="610"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="714"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="772"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="843"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="75"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="122"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="178"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="211"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="247"/>
- <location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="323"/>
- <location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="369"/>
+ <location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="315"/>
+ <location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="361"/>
<source>Unknown error occurred</source>
<translation type="unfinished">发生了未知错误</translation>
</message>
<message>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="126"/>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="241"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="559"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="662"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="554"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="657"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="279"/>
<source>Invalid KeyPair</source>
<translation type="unfinished">无效的密钥对</translation>
@@ -3872,8 +4016,8 @@ This will result in loss of all cached form positions, statuses, key servers, et
<message>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="127"/>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="242"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="560"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="663"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="555"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="658"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="280"/>
<source>The selected keypair cannot be used for encryption.</source>
<translation type="unfinished">所选的密钥对不能用于加密。</translation>
@@ -3881,8 +4025,8 @@ This will result in loss of all cached form positions, statuses, key servers, et
<message>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="128"/>
<location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="243"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="561"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="664"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="556"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="659"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="103"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="159"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="281"/>
@@ -3906,117 +4050,117 @@ This will result in loss of all cached form positions, statuses, key servers, et
<translation type="unfinished">正在打包并进行加密</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="289"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="339"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="585"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="688"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="288"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="337"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="580"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="683"/>
<source>The target file already exists, do you need to overwrite it?</source>
<translation type="unfinished">目标文件已经存在,是否需要覆盖?</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="303"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="302"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="202"/>
<source>Decrypting</source>
<translation type="unfinished">解密</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="353"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="351"/>
<source>Decrypting &amp; Extrating</source>
<translation type="unfinished">正在进行解密并解包</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="390"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="548"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="651"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="388"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="543"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="646"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="147"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="267"/>
<source>No Key Checked</source>
<translation type="unfinished">未勾选任何密钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="391"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="549"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="652"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="389"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="544"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="647"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="148"/>
<source>Please check the key in the key toolbox on the right.</source>
<translation type="unfinished">请勾选右侧密钥工具箱中的密钥。</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="398"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="396"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="100"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="156"/>
<source>Invalid Operation</source>
<translation type="unfinished">无效操作</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="399"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="397"/>
<source>The selected key contains a key that does not actually have a sign usage.</source>
<translation type="unfinished">所选密钥包含一个实际上没有符号用法的密钥。</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="401"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="399"/>
<source>for example the Following Key:</source>
<translation type="unfinished">例如以下密钥:</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="417"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="415"/>
<source>The signature file &quot;%1&quot; exists, do you need to overwrite it?</source>
<translation type="unfinished">签名文件“%1”存在,是否需要覆盖?</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="426"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="424"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="168"/>
<source>Signing</source>
<translation type="unfinished">签名</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="475"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="473"/>
<source>File to be Verified</source>
<translation type="unfinished">被验证的文件</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="476"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="474"/>
<source>Please provide An ABSOLUTE Path
If Data And Signature is COMBINED within a single file, KEEP THIS EMPTY: </source>
<translation>请提供绝对路径
如果确认数据和签名都在一个文件中,请置空: </translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="491"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="489"/>
<source>Please select the appropriate origin file or signature file. Ensure that both are in this directory.</source>
<translation type="unfinished">请选择合适的源文件或签名文件。确保两者都在此目录中。</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="500"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="495"/>
<location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="237"/>
<source>Verifying</source>
<translation type="unfinished">验证</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="603"/>
- <location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="310"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="598"/>
+ <location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="302"/>
<source>Encrypting and Signing</source>
<translation type="unfinished">加密和签名</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="706"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="701"/>
<source>Archiving &amp; Encrypting &amp; Signing</source>
<translation type="unfinished">正在进行打包、加密及签名操作</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="759"/>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="830"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="754"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="824"/>
<source>The output file %1 already exists, do you need to overwrite it?</source>
<translation type="unfinished">输出文件 %1 已经存在,是否需要覆盖?</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="768"/>
- <location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="358"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="763"/>
+ <location filename="../../../../src/ui/main_window/MainWindowGpgOperaFunction.cpp" line="350"/>
<source>Decrypting and Verifying</source>
<translation type="unfinished">解密和验证</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="839"/>
+ <location filename="../../../../src/ui/main_window/MainWindowFileSlotFunction.cpp" line="833"/>
<source>Decrypting &amp; Verifying &amp; Extracting</source>
<translation type="unfinished">正在进行解包、解密及验证操作</translation>
</message>
@@ -4067,43 +4211,43 @@ If Data And Signature is COMBINED within a single file, KEEP THIS EMPTY: </sourc
<translation type="unfinished">当地时间</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="249"/>
+ <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="250"/>
<source>Cannot open this file. Please make sure that this is a regular file and it&apos;s readable.</source>
<translation type="unfinished">无法打开此文件。请确保这是一个普通文件,并且有读取权限。</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="257"/>
+ <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="258"/>
<source>Cannot open this file. The file is TOO LARGE (&gt;1MB) for GpgFrontend Text Editor.</source>
<translation type="unfinished">无法打开此文件。文件对于 GpgFrontend 文本编辑器来说过大(&gt;1MB)。</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="298"/>
+ <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="292"/>
<source>GpgFrontend Upgradeable (New Version: %1).</source>
<translation type="unfinished">GpgFrontend 可升级(新版本:%1)。</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="302"/>
+ <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="296"/>
<location filename="../../../../src/ui/main_window/MainWindowUI.cpp" line="448"/>
<source>Update</source>
<translation type="unfinished">更新</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="308"/>
+ <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="302"/>
<source>Withdrawn Version</source>
<translation type="unfinished">被召回的版本</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="310"/>
+ <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="304"/>
<source>This version(%1) may have been withdrawn by the developer due to serious problems. Please stop using this version immediately and use the latest stable version.</source>
<translation type="unfinished">由于严重问题,此版本(%1) 可能已被开发人员召回。请立即停止使用此版本并使用最新的稳定版。</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="315"/>
+ <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="309"/>
<source>You can download the latest stable version(%1) on Github Releases Page.&lt;br/&gt;</source>
<translation type="unfinished">您可以在 Github Releases Page 上下载最新的稳定版 (%1)。&lt;br/&gt;</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="320"/>
+ <location filename="../../../../src/ui/main_window/MainWindowSlotFunction.cpp" line="314"/>
<source>This maybe a BETA Version (Latest Stable Version: %1).</source>
<translation type="unfinished">这可能是 BETA 版本(最新稳定版:%1)。</translation>
</message>
@@ -4762,17 +4906,17 @@ If Data And Signature is COMBINED within a single file, KEEP THIS EMPTY: </sourc
<translation type="unfinished">最喜欢的</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowUI.cpp" line="726"/>
+ <location filename="../../../../src/ui/main_window/MainWindowUI.cpp" line="727"/>
<source>Only Public Key</source>
<translation type="unfinished">只有公钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowUI.cpp" line="736"/>
+ <location filename="../../../../src/ui/main_window/MainWindowUI.cpp" line="734"/>
<source>Has Private Key</source>
<translation type="unfinished">有私钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/main_window/MainWindowUI.cpp" line="750"/>
+ <location filename="../../../../src/ui/main_window/MainWindowUI.cpp" line="745"/>
<source>Information Board</source>
<translation type="unfinished">信息面板</translation>
</message>
@@ -4821,89 +4965,89 @@ If Data And Signature is COMBINED within a single file, KEEP THIS EMPTY: </sourc
</message>
<message>
<location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="84"/>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="184"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="195"/>
<source>Enable Auto Activate</source>
<translation type="unfinished">开启自动启用</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="133"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="144"/>
<source>BASIC INFO</source>
<translation type="unfinished">基本信息</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="135"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="146"/>
<source>ID</source>
<translation type="unfinished">ID</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="137"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="148"/>
<source>Version</source>
<translation type="unfinished">版本</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="139"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="150"/>
<source>SDK Version</source>
<translation type="unfinished">SDK 版本</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="141"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="152"/>
<source>Qt ENV Version</source>
<translation type="unfinished">Qt 环境版本</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="143"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="154"/>
<source>Hash</source>
<translation type="unfinished">哈希</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="144"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="155"/>
<source>Path</source>
<translation type="unfinished">路径</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="148"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="159"/>
<source>Auto Activate</source>
<translation type="unfinished">自动启用</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="149"/>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="151"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="160"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="162"/>
<source>True</source>
<translation type="unfinished">开</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="149"/>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="151"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="160"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="162"/>
<source>False</source>
<translation type="unfinished">关</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="150"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="161"/>
<source>Active</source>
<translation type="unfinished">启用状态</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="155"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="166"/>
<source>METADATA</source>
<translation type="unfinished">元数据</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="171"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="182"/>
<source>Listening Event</source>
<translation type="unfinished">监听事件</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="180"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="191"/>
<source>Deactivate</source>
<translation type="unfinished">禁用</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="181"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="192"/>
<source>Activate</source>
<translation type="unfinished">启用</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="183"/>
+ <location filename="../../../../src/ui/dialog/controller/ModuleControllerDialog.cpp" line="194"/>
<source>Disable Auto Activate</source>
<translation type="unfinished">关闭自动启用</translation>
</message>
@@ -5031,7 +5175,7 @@ If Data And Signature is COMBINED within a single file, KEEP THIS EMPTY: </sourc
</message>
<message>
<location filename="../../../../src/ui/widgets/PlainTextEditorPage.cpp" line="63"/>
- <location filename="../../../../src/ui/widgets/PlainTextEditorPage.cpp" line="196"/>
+ <location filename="../../../../src/ui/widgets/PlainTextEditorPage.cpp" line="194"/>
<source>%1 character(s)</source>
<translation type="unfinished">%1 个字符</translation>
</message>
@@ -5086,14 +5230,12 @@ If Data And Signature is COMBINED within a single file, KEEP THIS EMPTY: </sourc
<translation type="vanished">重复密码:</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/RaisePinentry.cpp" line="68"/>
<source>Show passphrase</source>
- <translation type="unfinished">显示密码</translation>
+ <translation type="obsolete">显示密码</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/RaisePinentry.cpp" line="68"/>
<source>Hide passphrase</source>
- <translation type="unfinished">隐藏密码</translation>
+ <translation type="obsolete">隐藏密码</translation>
</message>
<message>
<source>Given PIN was wrong. Please retry.</source>
@@ -5104,48 +5246,40 @@ If Data And Signature is COMBINED within a single file, KEEP THIS EMPTY: </sourc
<translation type="obsolete">密码:</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/RaisePinentry.cpp" line="67"/>
<source>Repeat Passphrase:</source>
- <translation type="unfinished">重新输入密码:</translation>
+ <translation type="obsolete">重新输入密码:</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/RaisePinentry.cpp" line="71"/>
<source>Given Passphrase was wrong. Please retry.</source>
- <translation type="unfinished">密码错误。请重试。</translation>
+ <translation type="obsolete">密码错误。请重试。</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/RaisePinentry.cpp" line="74"/>
<source>Passphrase:</source>
- <translation type="unfinished">密码:</translation>
+ <translation type="obsolete">密码:</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/RaisePinentry.cpp" line="84"/>
<source>Passphrases do not match</source>
- <translation type="unfinished">密码不匹配</translation>
+ <translation type="obsolete">密码不匹配</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/RaisePinentry.cpp" line="87"/>
<source>Caps Lock is on</source>
- <translation type="unfinished">大写锁定已开启</translation>
+ <translation type="obsolete">大写锁定已开启</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/RaisePinentry.cpp" line="91"/>
<source>Bundled Pinentry</source>
- <translation type="unfinished">集成Pinentry</translation>
+ <translation type="obsolete">集成Pinentry</translation>
</message>
<message>
<source>Buddled Pinentry</source>
<translation type="obsolete">集成Pinentry</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/RaisePinentry.cpp" line="95"/>
<source>Confirm</source>
- <translation type="unfinished">确认</translation>
+ <translation type="obsolete">确认</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/RaisePinentry.cpp" line="96"/>
<source>Cancel</source>
- <translation type="unfinished">取消</translation>
+ <translation type="obsolete">取消</translation>
</message>
</context>
<context>
@@ -5157,31 +5291,31 @@ If Data And Signature is COMBINED within a single file, KEEP THIS EMPTY: </sourc
</message>
<message>
<location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="49"/>
- <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="67"/>
+ <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="66"/>
<source>Undefined</source>
<translation type="unfinished">不明确</translation>
</message>
<message>
<location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="49"/>
- <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="65"/>
+ <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="64"/>
<source>Never</source>
<translation type="unfinished">绝不</translation>
</message>
<message>
<location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="49"/>
- <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="63"/>
+ <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="62"/>
<source>Marginal</source>
<translation type="unfinished">边缘</translation>
</message>
<message>
<location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="50"/>
- <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="61"/>
+ <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="60"/>
<source>Full</source>
<translation type="unfinished">完全</translation>
</message>
<message>
<location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="50"/>
- <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="59"/>
+ <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="58"/>
<source>Ultimate</source>
<translation type="unfinished">终极</translation>
</message>
@@ -5196,22 +5330,22 @@ If Data And Signature is COMBINED within a single file, KEEP THIS EMPTY: </sourc
<translation type="unfinished">对密钥对的信任:</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="73"/>
+ <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="72"/>
<source>Warning</source>
<translation type="unfinished">警告</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="75"/>
+ <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="74"/>
<source>Owner Trust Level cannot set to Unknown level, automately changing it into Undefined level.</source>
<translation type="unfinished">所有者信任级别无法设置为未知级别,会自动将其更改为未定义级别。</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="83"/>
+ <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="82"/>
<source>Failed</source>
<translation type="unfinished">失败</translation>
</message>
<message>
- <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="84"/>
+ <location filename="../../../../src/ui/function/SetOwnerTrustLevel.cpp" line="83"/>
<source>Modify Owner Trust Level failed.</source>
<translation type="unfinished">修改所有者信任级别失败。</translation>
</message>
@@ -5249,9 +5383,8 @@ If Data And Signature is COMBINED within a single file, KEEP THIS EMPTY: </sourc
<translation type="unfinished">偏好</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/settings/SettingsDialog.cpp" line="124"/>
<source>System Default</source>
- <translation type="unfinished">系统默认</translation>
+ <translation type="obsolete">系统默认</translation>
</message>
</context>
<context>
@@ -5267,27 +5400,27 @@ If Data And Signature is COMBINED within a single file, KEEP THIS EMPTY: </sourc
<translation type="unfinished">取消</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/SignersPicker.cpp" line="49"/>
+ <location filename="../../../../src/ui/dialog/SignersPicker.cpp" line="52"/>
<source>Signers</source>
<translation type="unfinished">签名者</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/SignersPicker.cpp" line="57"/>
+ <location filename="../../../../src/ui/dialog/SignersPicker.cpp" line="60"/>
<source>Select Signer(s)</source>
<translation type="unfinished">选择签名者</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/SignersPicker.cpp" line="61"/>
+ <location filename="../../../../src/ui/dialog/SignersPicker.cpp" line="63"/>
<source>Please select one or more private keys you use for signing.</source>
<translation type="unfinished">请选择您用于签名的一个或多个私钥。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/SignersPicker.cpp" line="63"/>
+ <location filename="../../../../src/ui/dialog/SignersPicker.cpp" line="64"/>
<source>If no key is selected, the default key will be used for signing.</source>
<translation type="unfinished">如果未选择密钥,则将使用默认密钥进行签名。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/SignersPicker.cpp" line="73"/>
+ <location filename="../../../../src/ui/dialog/SignersPicker.cpp" line="74"/>
<source>Signers Picker</source>
<translation type="unfinished">签署人选择界面</translation>
</message>
@@ -5437,54 +5570,54 @@ If Data And Signature is COMBINED within a single file, KEEP THIS EMPTY: </sourc
<translation type="unfinished">打开目录</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="143"/>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="203"/>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="422"/>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="459"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="142"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="202"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="421"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="458"/>
<source>Warning</source>
<translation type="unfinished">警告</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="144"/>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="204"/>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="423"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="143"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="203"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="422"/>
<source>Cannot read file %1:
%2.</source>
<translation type="unfinished">无法读取文件 %1:
%2。</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="152"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="151"/>
<source>Open file</source>
<translation type="unfinished">打开文件</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="221"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="220"/>
<source>Save file</source>
<translation type="unfinished">保存存档</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="282"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="281"/>
<source>Unsaved document</source>
<translation type="unfinished">未保存的文件</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="283"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="282"/>
<source>The document &quot;%1&quot; has been modified. Do you want to save your changes?</source>
<translation type="unfinished">文档“%1”已被修改。是否要保存更改?</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="286"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="285"/>
<source>Note:</source>
<translation type="unfinished">笔记:</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="287"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="286"/>
<source>If you don&apos;t save these files, all changes are lost.</source>
<translation type="unfinished">如果您不保存这些文件,所有更改都将丢失。</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="459"/>
+ <location filename="../../../../src/ui/widgets/TextEdit.cpp" line="458"/>
<source>No document to print</source>
<translation type="unfinished">没有要打印的文件</translation>
</message>
@@ -5492,7 +5625,7 @@ If Data And Signature is COMBINED within a single file, KEEP THIS EMPTY: </sourc
<context>
<name>GpgFrontend::UI::TranslatorsTab</name>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="145"/>
+ <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="142"/>
<source>If you think there are any problems with the translation, why not participate in the translation work? If you want to participate, please read the document or contact me via email.</source>
<translation type="unfinished">如果觉得翻译有问题,何不参与翻译工作呢?如果您想参加,请阅读文档或通过电子邮件与我联系。</translation>
</message>
@@ -5500,65 +5633,48 @@ If Data And Signature is COMBINED within a single file, KEEP THIS EMPTY: </sourc
<context>
<name>GpgFrontend::UI::UpdateTab</name>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="163"/>
<source>It is recommended that you always check the version of GpgFrontend and upgrade to the latest version.</source>
- <translation type="unfinished">建议您经常检查 GpgFrontend 的版本更新。</translation>
+ <translation type="obsolete">建议您经常检查 GpgFrontend 的版本更新。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="166"/>
<source>New versions not only represent new features, but also often represent functional and security fixes.</source>
- <translation type="unfinished">新版本不仅代表新功能,而且通常代表功能和安全修复。</translation>
+ <translation type="obsolete">新版本不仅代表新功能,而且通常代表功能和安全修复。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="172"/>
<source>Current Version</source>
- <translation type="unfinished">当前版本</translation>
+ <translation type="obsolete">当前版本</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="173"/>
<source>: </source>
- <translation>: </translation>
+ <translation type="vanished">: </translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="248"/>
<source>Latest Version From Github</source>
- <translation type="unfinished">来自 Github 的最新版本</translation>
+ <translation type="obsolete">来自 Github 的最新版本</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="254"/>
<source>The current version is less than the latest version on github.</source>
- <translation type="unfinished">当前版本低于github上的最新版本。</translation>
+ <translation type="obsolete">当前版本低于github上的最新版本。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="256"/>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="267"/>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="279"/>
<source>Please click</source>
- <translation type="unfinished">请点击</translation>
+ <translation type="obsolete">请点击</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="259"/>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="270"/>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="282"/>
<source>Here</source>
- <translation type="unfinished">这里</translation>
+ <translation type="obsolete">这里</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="259"/>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="270"/>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="282"/>
<source>to download the latest stable version.</source>
- <translation type="unfinished">来下载最新的稳定版本。</translation>
+ <translation type="obsolete">来下载最新的稳定版本。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="265"/>
<source>This version has serious problems and has been withdrawn. Please stop using it immediately.</source>
- <translation>此版本存在严重问题,已经被召回。请立即停止使用。</translation>
+ <translation type="vanished">此版本存在严重问题,已经被召回。请立即停止使用。</translation>
</message>
<message>
- <location filename="../../../../src/ui/dialog/help/AboutDialog.cpp" line="276"/>
<source>This version has not been released yet, it may be a beta version. If you are not a tester and care about version stability, please do not use this version.</source>
- <translation type="unfinished">此版本尚未发布,可能是测试版。如果您不是测试人员并且关心版本稳定性,请不要使用此版本。</translation>
+ <translation type="obsolete">此版本尚未发布,可能是测试版。如果您不是测试人员并且关心版本稳定性,请不要使用此版本。</translation>
</message>
</context>
<context>
@@ -5794,32 +5910,32 @@ If Data And Signature is COMBINED within a single file, KEEP THIS EMPTY: </sourc
<context>
<name>QCoreApplication</name>
<message>
- <location filename="../../../../src/cmd.cpp" line="47"/>
+ <location filename="../../../../src/cmd.cpp" line="50"/>
<source>This is free software; see the source for copying conditions.</source>
<translation type="unfinished">此为自由软件。关于版权信息,请参阅源代码中的版权文件。</translation>
</message>
<message>
- <location filename="../../../../src/cmd.cpp" line="52"/>
+ <location filename="../../../../src/cmd.cpp" line="55"/>
<source>Build DateTime: </source>
<translation>构建时间: </translation>
</message>
<message>
- <location filename="../../../../src/cmd.cpp" line="54"/>
+ <location filename="../../../../src/cmd.cpp" line="57"/>
<source>Build Version: </source>
<translation>构建版本: </translation>
</message>
<message>
- <location filename="../../../../src/cmd.cpp" line="56"/>
+ <location filename="../../../../src/cmd.cpp" line="59"/>
<source>Source Code Version: </source>
<translation>源代码版本: </translation>
</message>
<message>
- <location filename="../../../../src/ui/GpgFrontendUIInit.cpp" line="56"/>
+ <location filename="../../../../src/ui/GpgFrontendUIInit.cpp" line="58"/>
<source>Loading Gnupg Info...</source>
<translation type="unfinished">正在加载 Gnupg 信息...</translation>
</message>
<message>
- <location filename="../../../../src/ui/GpgFrontendUIInit.cpp" line="57"/>
+ <location filename="../../../../src/ui/GpgFrontendUIInit.cpp" line="59"/>
<source>If this process is too slow, please set the key server address appropriately in the gnupg configuration file (depending on the network situation in your country or region).</source>
<translation type="unfinished">如果此过程太慢,请在 gnupg 配置文件中适当设置密钥服务器地址(取决于您所在国家或地区的网络情况)。</translation>
</message>
@@ -5845,7 +5961,7 @@ If Data And Signature is COMBINED within a single file, KEEP THIS EMPTY: </sourc
</message>
<message>
<location filename="../../../../src/core/utils/IOUtils.cpp" line="90"/>
- <location filename="../../../../src/core/utils/IOUtils.cpp" line="125"/>
+ <location filename="../../../../src/core/utils/IOUtils.cpp" line="122"/>
<source>Filename</source>
<translation type="unfinished">文件名</translation>
</message>
@@ -5853,10 +5969,10 @@ If Data And Signature is COMBINED within a single file, KEEP THIS EMPTY: </sourc
<location filename="../../../../src/core/utils/IOUtils.cpp" line="90"/>
<location filename="../../../../src/core/utils/IOUtils.cpp" line="95"/>
<location filename="../../../../src/core/utils/IOUtils.cpp" line="99"/>
- <location filename="../../../../src/core/utils/IOUtils.cpp" line="104"/>
- <location filename="../../../../src/core/utils/IOUtils.cpp" line="110"/>
- <location filename="../../../../src/core/utils/IOUtils.cpp" line="116"/>
- <location filename="../../../../src/core/utils/IOUtils.cpp" line="125"/>
+ <location filename="../../../../src/core/utils/IOUtils.cpp" line="103"/>
+ <location filename="../../../../src/core/utils/IOUtils.cpp" line="108"/>
+ <location filename="../../../../src/core/utils/IOUtils.cpp" line="113"/>
+ <location filename="../../../../src/core/utils/IOUtils.cpp" line="122"/>
<source>: </source>
<translation>: </translation>
</message>
@@ -5867,52 +5983,56 @@ If Data And Signature is COMBINED within a single file, KEEP THIS EMPTY: </sourc
<translation type="unfinished">文件大小</translation>
</message>
<message>
- <location filename="../../../../src/core/utils/IOUtils.cpp" line="123"/>
+ <location filename="../../../../src/core/utils/IOUtils.cpp" line="120"/>
<source>Error: cannot read target file</source>
<translation type="unfinished">错误:无法读取目标文件</translation>
</message>
<message>
- <location filename="../../../../src/core/utils/IOUtils.cpp" line="156"/>
+ <location filename="../../../../src/core/utils/IOUtils.cpp" line="153"/>
<source>target path doesn&apos;t exists</source>
<translation type="unfinished">目标路径不存在</translation>
</message>
<message>
- <location filename="../../../../src/core/utils/IOUtils.cpp" line="162"/>
+ <location filename="../../../../src/core/utils/IOUtils.cpp" line="159"/>
<source>do NOT have permission to write path</source>
<translation type="unfinished">缺少写入路径的权限</translation>
</message>
<message>
- <location filename="../../../../src/core/utils/IOUtils.cpp" line="168"/>
+ <location filename="../../../../src/core/utils/IOUtils.cpp" line="165"/>
<source>do NOT have permission to read/write file</source>
<translation type="unfinished">缺少读写文件的权限</translation>
</message>
<message>
- <location filename="../../../../src/core/utils/IOUtils.cpp" line="171"/>
+ <location filename="../../../../src/core/utils/IOUtils.cpp" line="168"/>
<source>Success</source>
<translation type="unfinished">成功</translation>
</message>
<message>
- <location filename="../../../../src/core/GpgCoreInit.cpp" line="303"/>
+ <location filename="../../../../src/core/GpgCoreInit.cpp" line="283"/>
<source>GpgME initiation failed</source>
<translation type="unfinished">GpgME初始化失败</translation>
</message>
<message>
- <location filename="../../../../src/core/GpgCoreInit.cpp" line="409"/>
+ <location filename="../../../../src/core/GpgCoreInit.cpp" line="378"/>
<source>GpgME Context initiation failed</source>
<translation type="unfinished">GpgME上下文初始化失败</translation>
</message>
<message>
- <location filename="../../../../src/core/GpgCoreInit.cpp" line="418"/>
+ <location filename="../../../../src/core/GpgCoreInit.cpp" line="387"/>
+ <source>Gpg Key Database initiation failed</source>
+ <translation type="unfinished">Gpg密钥数据库初始化失败</translation>
+ </message>
+ <message>
<source>Gpg Key Detabase initiation failed</source>
- <translation type="unfinished">密钥数据库初始化失败</translation>
+ <translation type="obsolete">密钥数据库初始化失败</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="486"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="528"/>
<source>Sync All Public Key</source>
<translation type="unfinished">同步所有公钥</translation>
</message>
<message>
- <location filename="../../../../src/ui/widgets/KeyList.cpp" line="487"/>
+ <location filename="../../../../src/ui/widgets/KeyList.cpp" line="529"/>
<source>You have not checked any public keys that you want to synchronize, do you want to synchronize all local public keys from the key server?</source>
<translation type="unfinished">您没有选中任何要同步的公钥,是否要从密钥服务器同步所有本地公钥?</translation>
</message>
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c416e681..28f30f13 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -23,6 +23,7 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
+#
if(APPLE)
add_compile_definitions("_GNU_SOURCE")
endif()
@@ -31,480 +32,562 @@ endif()
find_package(Gpgme REQUIRED)
# Introduce OpenSSL
-if (APPLE)
- # Define possible OpenSSL directories
- set(OPENSSL_DIR_CANDIDATES
- /usr/local/opt/openssl@3
- /opt/homebrew/opt/openssl@3
- )
-
- # Find the valid OpenSSL directory
- foreach(DIR IN LISTS OPENSSL_DIR_CANDIDATES)
- if(IS_DIRECTORY "${DIR}" OR EXISTS "${DIR}")
- set(OPENSSL_ROOT_DIR "${DIR}")
- break() # Stop loop once a valid directory is found
- endif()
- endforeach()
-
- # If not found, throw an error or warning
- if(NOT OPENSSL_ROOT_DIR)
- message(FATAL_ERROR "OpenSSL not found in the standard directories. Please install it or set OPENSSL_ROOT_DIR manually.")
+if(APPLE)
+ # Define possible OpenSSL directories
+ set(OPENSSL_DIR_CANDIDATES
+ /usr/local/opt/openssl@3
+ /opt/homebrew/opt/openssl@3
+ )
+
+ # Find the valid OpenSSL directory
+ foreach(DIR IN LISTS OPENSSL_DIR_CANDIDATES)
+ if(IS_DIRECTORY "${DIR}" OR EXISTS "${DIR}")
+ set(OPENSSL_ROOT_DIR "${DIR}")
+ break() # Stop loop once a valid directory is found
endif()
+ endforeach()
+
+ # If not found, throw an error or warning
+ if(NOT OPENSSL_ROOT_DIR)
+ message(FATAL_ERROR "OpenSSL not found in the standard directories. Please install it or set OPENSSL_ROOT_DIR manually.")
+ endif()
endif()
find_package(OpenSSL REQUIRED)
+# mimalloc
+if(NOT APPLE)
+ find_package(mimalloc REQUIRED)
+endif()
+
# Set Build Information
configure_file(${CMAKE_SOURCE_DIR}/src/GpgFrontend.h.in ${CMAKE_SOURCE_DIR}/src/GpgFrontend.h @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/src/GpgFrontendBuildInfo.h.in ${CMAKE_SOURCE_DIR}/src/GpgFrontendBuildInfo.h @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/src/GpgFrontendBuildInstallInfo.h.in ${CMAKE_SOURCE_DIR}/src/GpgFrontendBuildInstallInfo.h @ONLY)
-configure_file(${CMAKE_SOURCE_DIR}/src/module/sdk/GFSDKBuildInfo.h.in ${CMAKE_SOURCE_DIR}/src/module/sdk/GFSDKBuildInfo.h @ONLY)
-if (APPLE)
- configure_file(${CMAKE_SOURCE_DIR}/resource/plist/ExportOptions.plist.in ${CMAKE_BINARY_DIR}/ExportOptions.plist @ONLY)
-endif ()
+configure_file(${CMAKE_SOURCE_DIR}/src/sdk/GFSDKBuildInfo.h.in ${CMAKE_SOURCE_DIR}/src/sdk/GFSDKBuildInfo.h @ONLY)
+
+if(APPLE)
+ configure_file(${CMAKE_SOURCE_DIR}/resource/plist/ExportOptions.plist.in ${CMAKE_BINARY_DIR}/ExportOptions.plist @ONLY)
+endif()
# Set Runtime Output Directory
-if (NOT XCODE_BUILD)
- # Set Binary Output Path
- set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/artifacts)
-else ()
- # Set Binary Output Path
- set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE})
-endif ()
+if(NOT XCODE_BUILD)
+ # Set Binary Output Path
+ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/artifacts)
+else()
+ # Set Binary Output Path
+ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE})
+endif()
-# configure for output path and resources
-if (BUILD_APPLICATION)
- aux_source_directory(. BASE_SOURCE)
- set(APP_ICON_RESOURCE_WINDOWS "${CMAKE_SOURCE_DIR}/gpgfrontend.rc")
- set_property(SOURCE gpgfrontend.rc APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_SOURCE_DIR}/gpgfrontend.ico)
-endif ()
-
-if (BUILD_CORE)
- # core depends pinentry
- message("[+] Build Pinentry")
- add_subdirectory(pinentry)
-
- message("[+] Build Core")
- add_subdirectory(core)
-endif ()
-
-if (BUILD_UI)
- message("[+] Build UI")
- add_subdirectory(ui)
-endif ()
-
-if (BUILD_MODULE)
- message("[+] Build Module")
- add_subdirectory(module)
-endif ()
+# Print modules
+if(BUILD_CORE)
+ message("[+] Build Core")
+ add_subdirectory(core)
+endif()
+
+if(BUILD_UI)
+ message("[+] Build UI")
+ add_subdirectory(ui)
+endif()
+
+if(BUILD_SDK)
+ message("[+] Build SDK")
+ add_subdirectory(sdk)
+endif()
# build to test gpgfrontend core
-if (BUILD_TEST)
- include(CTest)
- enable_testing()
- add_subdirectory(test)
-endif ()
-
-if (BUILD_APPLICATION)
- # Set Resource Output Path
- if (${CMAKE_BUILD_TYPE} STREQUAL "Release")
- if (APPLE)
- set(RESOURCE_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Resources)
- elseif (LINUX AND NOT LINUX_INSTALL_SOFTWARE)
- file(MAKE_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir)
- file(COPY ${CMAKE_SOURCE_DIR}/resource/lfs/hicolor DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir/usr/share/icons)
- file(COPY ${CMAKE_SOURCE_DIR}/resource/appstream/com.bktus.gpgfrontend.metainfo.xml DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir/usr/share/metainfo FOLLOW_SYMLINK_CHAIN)
- file(COPY ${CMAKE_SOURCE_DIR}/resource/appstream/com.bktus.gpgfrontend.desktop DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir/usr/share/applications FOLLOW_SYMLINK_CHAIN)
- file(COPY ${CMAKE_SOURCE_DIR}/resource/lfs/pixmaps/com.bktus.gpgfrontend.png DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir FOLLOW_SYMLINK_CHAIN)
- set(RESOURCE_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir/usr/share)
- else ()
- set(RESOURCE_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
- endif ()
- else ()
- set(RESOURCE_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
- endif ()
-endif ()
-
-if (BUILD_APPLICATION)
- if (${CMAKE_BUILD_TYPE} STREQUAL "Release")
- if (APPLE)
- set(GPGFRONTEND_MACOS_ICON ${CMAKE_SOURCE_DIR}/gpgfrontend.icns)
- set_source_files_properties(${GPGFRONTEND_MACOS_ICON} PROPERTIES
- MACOSX_PACKAGE_LOCATION "Resources")
- elseif (LINUX AND NOT LINUX_INSTALL_SOFTWARE)
- file(REMOVE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir/usr/bin/${AppName})
- endif ()
- endif ()
-endif ()
-
-if (BUILD_APPLICATION)
- # Copy Utils Files
- if (MINGW)
- message(STATUS "Copying Dependent DLL For Windows Runtime Env")
-
- set(ALL_RUNTIME_DEP_PATH_LIST "")
-
- # get mingw bin path
- find_file(_libGccDllPath NAMES libgcc_s_seh-1.dll NO_CACHE REQUIRED)
- cmake_path(GET _libGccDllPath PARENT_PATH _libDllBinPath)
-
- # find libicu*.dll
- unset(_libDllPath)
- file(GLOB _libDllPath "${_libDllBinPath}/libicu[a-z]*[0-9][0-9].dll")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
-
- unset(_libDllPath)
- file(GLOB _libDllPath "${_libDllBinPath}/libassuan*.dll")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
-
- unset(_libDllPath)
- file(GLOB _libDllPath "${_libDllBinPath}/libbz*.dll")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
-
- unset(_libDllPath)
- file(GLOB _libDllPath "${_libDllBinPath}/libcrypto-*.dll")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
-
- unset(_libDllPath)
- file(GLOB _libDllPath "${_libDllBinPath}/libexpat-*.dll")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
-
- unset(_libDllPath)
- file(GLOB _libDllPath "${_libDllBinPath}/libfreetype-*.dll")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
-
- unset(_libDllPath)
- file(GLOB _libDllPath "${_libDllBinPath}/libgcc_s_seh-*.dll")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
-
- unset(_libDllPath)
- file(GLOB _libDllPath "${_libDllBinPath}/libglib-*.dll")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
-
- unset(_libDllPath)
- file(GLOB _libDllPath "${_libDllBinPath}/libgpg-error*.dll")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
-
- unset(_libDllPath)
- file(GLOB _libDllPath "${_libDllBinPath}/libgpgme*.dll")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
-
- unset(_libDllPath)
- file(GLOB _libDllPath "${_libDllBinPath}/libgraphite2.dll")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
-
- unset(_libDllPath)
- file(GLOB _libDllPath "${_libDllBinPath}/libharfbuzz-*.dll")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
-
- unset(_libDllPath)
- file(GLOB _libDllPath "${_libDllBinPath}/libiconv-*.dll")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
-
- unset(_libDllPath)
- file(GLOB _libDllPath "${_libDllBinPath}/libintl-*.dll")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
-
- unset(_libDllPath)
- file(GLOB _libDllPath "${_libDllBinPath}/liblz4.dll")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
-
- unset(_libDllPath)
- file(GLOB _libDllPath "${_libDllBinPath}/liblzma-*.dll")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
-
- unset(_libDllPath)
- file(GLOB _libDllPath "${_libDllBinPath}/libpcre-*.dll")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
-
- unset(_libDllPath)
- file(GLOB _libDllPath "${_libDllBinPath}/libpcre2-*.dll")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
-
- unset(_libDllPath)
- file(GLOB _libDllPath "${_libDllBinPath}/libpng*-*.dll")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
-
- unset(_libDllPath)
- file(GLOB _libDllPath "${_libDllBinPath}/libstdc++-*.dll")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
-
- unset(_libDllPath)
- file(GLOB _libDllPath "${_libDllBinPath}/libwinpthread-*.dll")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
-
- unset(_libDllPath)
- file(GLOB _libDllPath "${_libDllBinPath}/zlib*.dll")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
-
- unset(_libDllPath)
- file(GLOB _libDllPath "${_libDllBinPath}/libb2-*.dll")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
-
- # openssl
- unset(_libDllPath)
- file(GLOB _libDllPath "${_libDllBinPath}/libssl-*.dll")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
-
- unset(_libDllPath)
- file(GLOB _libDllPath "${_libDllBinPath}/libcrypto-*.dll")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
-
- unset(_libDllPath)
- file(GLOB _libDllPath "${_libDllBinPath}/libxml2-*.dll")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
-
- # /mingw64/libexec
- execute_process(
- COMMAND cygpath -m /mingw64/libexec
- OUTPUT_VARIABLE MSYS64_LIBEXEC_PATH
- OUTPUT_STRIP_TRAILING_WHITESPACE
- )
-
- # gpgme-w32spawn.exe
- unset(_libExEPath)
- file(GLOB _libExEPath "${MSYS64_LIBEXEC_PATH}/gpgme-*.exe")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libExEPath})
-
- unset(_libExEPath)
- file(GLOB _libExEPath "${_libDllBinPath}/gpgme-*.exe")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libExEPath})
-
- set(ALL_RUNTIME_DLL_FILES "")
-
- if(GPGFRONTEND_QT5_BUILD)
- list(APPEND ALL_RUNTIME_DLL_FILES "Qt5Core.dll;Qt5Gui.dll;Qt5Network.dll;Qt5PrintSupport.dll;Qt5Svg.dll;Qt5Widgets.dll;libbrotlicommon.dll;libbrotlidec.dll;libdouble-conversion.dll;libzstd.dll;libmd4c.dll;")
- else()
- list(APPEND ALL_RUNTIME_DLL_FILES "Qt6Core.dll;Qt6Core5Compat.dll;Qt6Gui.dll;Qt6Network.dll;Qt6PrintSupport.dll;Qt6Svg.dll;Qt6Widgets.dll;libbrotlicommon.dll;libbrotlidec.dll;libdouble-conversion.dll;libzstd.dll;libmd4c.dll;")
- endif()
-
- # find the other dlls
- foreach (_dllFileName ${ALL_RUNTIME_DLL_FILES})
- message(STATUS "DLL FILE ${_dllFileName}")
- list(APPEND ALL_DLL_NAME ${_dllFileName})
- unset(_runtimeDllLocalPath)
-
- find_file(_runtimeDllLocalPath NAMES ${_dllFileName} NO_CACHE REQUIRED)
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_runtimeDllLocalPath})
- message(STATUS "DLL ${_dllFileName} Path is ${_runtimeDllLocalPath}")
- endforeach()
-
- message(STATUS "All Runtime Dependencies Path ${ALL_RUNTIME_DEP_PATH_LIST}")
-
- # copy dependencies to release path
- foreach (_dllRuntimeFilePath ${ALL_RUNTIME_DEP_PATH_LIST})
- file(COPY ${_dllRuntimeFilePath} DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
- endforeach()
-
- endif ()
-endif ()
-
-if (BUILD_APPLICATION)
- set(RESOURCE_FILES ${CMAKE_SOURCE_DIR}/gpgfrontend.qrc ${APP_ICON_RESOURCE_WINDOWS} ${QON_QM_FILES})
- add_custom_target(resources ALL DEPENDS ${RESOURCE_FILES})
-endif ()
-
-if (BUILD_APPLICATION)
- if (${CMAKE_BUILD_TYPE} STREQUAL "Release")
- if (MINGW)
- add_executable(${AppName} WIN32 ${BASE_SOURCE} ${RESOURCE_FILES})
- # include qt dependencies
- if(NOT Qt6_DIR)
- add_custom_command(TARGET ${AppName} POST_BUILD
- COMMAND windeployqt --force ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${AppName}.exe)
- else()
- add_custom_command(TARGET ${AppName} POST_BUILD
- COMMAND windeployqt-qt6.exe --force ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${AppName}.exe)
- endif()
- elseif (LINUX AND NOT LINUX_INSTALL_SOFTWARE)
- add_executable(${AppName} ${BASE_SOURCE} ${RESOURCE_FILES})
-
- add_custom_command(TARGET ${AppName} POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir/usr/bin"
- COMMAND ${CMAKE_COMMAND} -E rename "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${AppName}" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir/usr/bin/${AppName}"
- COMMENT "Copying Binary into App Image"
- )
-
- add_custom_command(TARGET ${AppName} POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir/usr/plugins"
- COMMENT "Complement to build the required architecture"
- )
-
- add_custom_command(TARGET ${AppName} POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir/usr/plugins/mods"
- COMMAND ${CMAKE_COMMAND} -E rename "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mods" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir/usr/plugins/mods"
- COMMENT "Copying Mods into App Image"
- )
-
- # app bundle packing using xcode
- elseif (APPLE AND XCODE_BUILD)
- # standard app bundle packing
- add_executable(${AppName} MACOSX_BUNDLE ${GPGFRONTEND_MACOS_ICON} ${BASE_SOURCE} ${RESOURCE_FILES})
-
- set_target_properties(${AppName} PROPERTIES
- BUNDLE True
- MACOSX_BUNDLE_GUI_IDENTIFIER com.bktus.gpgfrontend
- MACOSX_BUNDLE_BUNDLE_NAME ${AppName}
- MACOSX_BUNDLE_LONG_VERSION_STRING ${BUILD_VERSION}
- MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION}
- MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
- MACOSX_BUNDLE_COPYRIGHT "GPL-3.0"
- MACOSX_BUNDLE_INFO_STRING "An OpenPGP Crypto Tool"
- MACOSX_BUNDLE_ICON_FILE "gpgfrontend.icns"
- MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/resource/plist/MacOSXBundleInfo.plist.in)
-
- # option for sandbox mode, still under test
- if(GPGFRONTEND_XOCDE_ENABLE_SANDBOX)
- message(STATUS "Build Application With App Sandbox")
- set(CUSTOM_ATTRIBUTE_ENABLE_APP_SANDBOX "Yes")
- add_custom_command(TARGET ${AppName} POST_BUILD
- COMMAND /bin/cp -rf ${CMAKE_SOURCE_DIR}/resource/lfs/macOS/GnuPG ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_BUILD_TYPE}/${AppName}.app/Contents/
- WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
- COMMENT "Copying Buddled GnuPG into App Bundle Resource")
- set_target_properties(${AppName} PROPERTIES
- XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_SOURCE_DIR}/resource/entitlements/GpgFrontend.entitlements")
- else()
- message(STATUS "Build Application Without App Sandbox")
- set(CUSTOM_ATTRIBUTE_ENABLE_APP_SANDBOX "No")
- endif()
-
- set_target_properties(${AppName} PROPERTIES
- XCODE_ATTRIBUTE_INSTALL_PATH "$(LOCAL_APPS_DIR)"
- XCODE_ATTRIBUTE_SKIP_INSTALL "No"
- XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS "--deep --entitlements ${CMAKE_SOURCE_DIR}/resource/plist/entitlement.plist"
- XCODE_ATTRIBUTE_ENABLE_APP_SANDBOX "${CUSTOM_ATTRIBUTE_ENABLE_APP_SANDBOX}"
- XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME "Yes"
- XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}")
- elseif(LINUX AND LINUX_INSTALL_SOFTWARE)
- add_executable(${AppName} ${BASE_SOURCE} ${RESOURCE_FILES})
- else ()
- message(FATAL_ERROR "cannot find a defined method to release application.")
- endif ()
- else ()
- # if the status is debug
- add_executable(${AppName} ${BASE_SOURCE} ${RESOURCE_FILES})
- if(MINGW)
- # include qt dependencies
- if(NOT Qt6_DIR)
- add_custom_command(TARGET ${AppName} POST_BUILD
- COMMAND windeployqt --force ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${AppName}.exe)
- else()
- add_custom_command(TARGET ${AppName} POST_BUILD
- COMMAND windeployqt-qt6.exe --force ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${AppName}.exe)
- endif()
- endif()
- endif ()
-
- # Make app build with resources
- add_dependencies(${AppName} resources)
-
- # using c++ standard 17
- target_compile_features(${AppName} PUBLIC cxx_std_17)
-
-endif ()
+if(BUILD_TEST)
+ include(CTest)
+ enable_testing()
+ add_subdirectory(test)
+endif()
-# link options for GpgFrontend
-if (BUILD_APPLICATION)
- target_link_libraries(${AppName} gpgfrontend_ui gpgfrontend_test)
- if (MINGW)
- message(STATUS "Link Application Library For MINGW")
- target_link_libraries(${AppName} crypto)
- elseif (APPLE)
- message(STATUS "Link Application Library For macOS")
- else ()
- message(STATUS "Link Application Library For Linux")
- target_link_libraries(${AppName} crypto pthread)
- endif ()
-endif ()
+# configure for output path and resources
+if(BUILD_APPLICATION)
+ aux_source_directory(. BASE_SOURCE)
+ set(APP_ICON_RESOURCE_WINDOWS "${CMAKE_SOURCE_DIR}/gpgfrontend.rc")
+ set_property(SOURCE gpgfrontend.rc APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_SOURCE_DIR}/gpgfrontend.ico)
+endif()
-# add i18n support
-if (BUILD_APPLICATION)
- set(LOCALE_TS_PATH ${CMAKE_SOURCE_DIR}/resource/lfs/locale/ts)
- set(TS_FILES "${LOCALE_TS_PATH}/GpgFrontend.en_US.ts"
- "${LOCALE_TS_PATH}/GpgFrontend.de_DE.ts"
- "${LOCALE_TS_PATH}/GpgFrontend.fr_FR.ts"
- "${LOCALE_TS_PATH}/GpgFrontend.zh_CN.ts"
- "${LOCALE_TS_PATH}/GpgFrontend.zh_TW.ts"
- "${LOCALE_TS_PATH}/GpgFrontend.it_IT.ts")
- file(GLOB_RECURSE ALL_SOURCE_FILES RELACTIVE ${CMAKE_SOURCE_DIR}/src/*.cpp)
-
- if(GPGFRONTEND_QT5_BUILD)
- # TODO
- qt5_add_translation(GF_TRANSLATIONS_QM ${TS_FILES})
- message(STATUS "GF_TRANSLATIONS_QM ${GF_TRANSLATIONS_QM}")
-
- set(GF_QM_TRANSLATIONS_RESOURCE_FILE "${CMAKE_CURRENT_BINARY_DIR}/i18n.qrc")
- file(WRITE ${GF_QM_TRANSLATIONS_RESOURCE_FILE} "<!DOCTYPE RCC>\n<RCC version=\"1.0\">\n <qresource prefix=\"i18n\">\n")
- foreach(QM_FILE ${GF_TRANSLATIONS_QM})
- file(RELATIVE_PATH QM_FILENAME ${CMAKE_CURRENT_BINARY_DIR} ${QM_FILE})
- file(APPEND ${GF_QM_TRANSLATIONS_RESOURCE_FILE} " <file alias=\"${QM_FILENAME}\">${QM_FILE}</file>\n")
- endforeach()
- file(APPEND ${GF_QM_TRANSLATIONS_RESOURCE_FILE} " </qresource>\n</RCC>\n")
- qt5_add_resources(GF_I18N_RESOURCES ${GF_QM_TRANSLATIONS_RESOURCE_FILE})
-
- file(GLOB QT_TRANSLATIONS_TS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/third_party/qttranslations/translations/*.ts)
- list(FILTER QT_TRANSLATIONS_TS INCLUDE REGEX ".*(qt|qtbase)_.*\.ts$")
- qt5_add_translation(QT_TRANSLATIONS_QM ${QT_TRANSLATIONS_TS})
-
- set(QT_QM_TRANSLATIONS_RESOURCE_FILE "${CMAKE_CURRENT_BINARY_DIR}/qt_i18n.qrc")
- file(WRITE ${QT_QM_TRANSLATIONS_RESOURCE_FILE} "<!DOCTYPE RCC>\n<RCC version=\"1.0\">\n <qresource prefix=\"qt_i18n\">\n")
- foreach(QM_FILE ${QT_TRANSLATIONS_QM})
- file(RELATIVE_PATH QM_FILENAME ${CMAKE_CURRENT_BINARY_DIR} ${QM_FILE})
- file(APPEND ${QT_QM_TRANSLATIONS_RESOURCE_FILE} " <file alias=\"${QM_FILENAME}\">${QM_FILE}</file>\n")
- endforeach()
- file(APPEND ${QT_QM_TRANSLATIONS_RESOURCE_FILE} " </qresource>\n</RCC>\n")
- qt5_add_resources(GF_I18N_RESOURCES ${QT_QM_TRANSLATIONS_RESOURCE_FILE})
-
- message(STATUS "GF_I18N_RESOURCES ${GF_I18N_RESOURCES}")
-
- target_sources(${AppName} PRIVATE ${GF_I18N_RESOURCES})
+if(BUILD_APPLICATION)
+ # Set Resource Output Path
+ if(${CMAKE_BUILD_TYPE} STREQUAL "Release")
+ if(APPLE)
+ set(RESOURCE_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Resources)
+ elseif(LINUX AND NOT LINUX_INSTALL_SOFTWARE)
+ file(MAKE_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir)
+ file(COPY ${CMAKE_SOURCE_DIR}/resource/lfs/hicolor DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir/usr/share/icons)
+ file(COPY ${CMAKE_SOURCE_DIR}/resource/appstream/com.bktus.gpgfrontend.metainfo.xml DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir/usr/share/metainfo FOLLOW_SYMLINK_CHAIN)
+ file(COPY ${CMAKE_SOURCE_DIR}/resource/appstream/com.bktus.gpgfrontend.desktop DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir/usr/share/applications FOLLOW_SYMLINK_CHAIN)
+ file(COPY ${CMAKE_SOURCE_DIR}/resource/lfs/pixmaps/com.bktus.gpgfrontend.png DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir FOLLOW_SYMLINK_CHAIN)
+ set(RESOURCE_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir/usr/share)
else()
- qt_add_translations(${AppName}
- RESOURCE_PREFIX "/i18n"
- TS_FILES ${TS_FILES}
- SOURCES ${ALL_SOURCE_FILES}
- INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/src)
- file(GLOB QT_TRANSLATIONS_TS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/third_party/qttranslations/translations/*.ts)
- list(FILTER QT_TRANSLATIONS_TS INCLUDE REGEX ".*(qt|qtbase)_.*\.ts$")
- add_custom_target(qttranslations ALL)
- qt_add_lrelease(qttranslations
- TS_FILES ${QT_TRANSLATIONS_TS}
- QM_FILES_OUTPUT_VARIABLE QT_TRANSLATIONS_QM)
- qt_add_resources(${AppName} "qttranslations"
- PREFIX "/i18n_qt"
- BASE ${CMAKE_CURRENT_BINARY_DIR}
- FILES ${QT_TRANSLATIONS_QM})
+ set(RESOURCE_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
endif()
+ else()
+ set(RESOURCE_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
+ endif()
+endif()
+if(BUILD_APPLICATION)
+ if(${CMAKE_BUILD_TYPE} STREQUAL "Release")
+ if(APPLE)
+ set(GPGFRONTEND_MACOS_ICON ${CMAKE_SOURCE_DIR}/gpgfrontend.icns)
+ set_source_files_properties(${GPGFRONTEND_MACOS_ICON} PROPERTIES
+ MACOSX_PACKAGE_LOCATION "Resources")
+ elseif(LINUX AND NOT LINUX_INSTALL_SOFTWARE)
+ file(REMOVE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir/usr/bin/${AppName})
+ endif()
+ endif()
+endif()
+
+if(BUILD_APPLICATION AND MINGW)
+ message(STATUS "Copying Dependent DLL For Windows Runtime Env")
+
+ # all dep dll list
+ set(ALL_RUNTIME_DEP_PATH_LIST "")
+
+ # /mingw64/libexec
+ execute_process(
+ COMMAND cygpath -m /mingw64/bin
+ OUTPUT_VARIABLE MSYS64_BIN_PATH
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+
+ # find libicu*.dll
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/libicu[a-z]*[0-9][0-9].dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/libassuan*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/libbz*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/libcrypto-*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/libexpat-*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/libfreetype-*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/libgcc_s_seh-*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/libglib-*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/libgpg-error*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/libgpgme*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/libgraphite2.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/libharfbuzz-*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/libiconv-*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/libintl-*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/liblz4.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/liblzma-*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/libpcre-*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/libpcre2-*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/libpng*-*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/libstdc++-*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/libwinpthread-*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/zlib*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/libb2-*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ # openssl
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/libssl-*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/libcrypto-*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/libxml2-*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ # /mingw64/libexec
+ execute_process(
+ COMMAND cygpath -m /mingw64/libexec
+ OUTPUT_VARIABLE MSYS64_LIBEXEC_PATH
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+
+ # gpgme-w32spawn.exe
+ unset(_libExEPath)
+ file(GLOB _libExEPath "${MSYS64_LIBEXEC_PATH}/gpgme-*.exe")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libExEPath})
+
+ unset(_libExEPath)
+ file(GLOB _libExEPath "${MSYS64_BIN_PATH}/gpgme-*.exe")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libExEPath})
+
+ # add gpgfrontend libraries
+ if(STABLE_BUILD_ONLY_APPLICATION)
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/libgpgfrontend_*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/libmimalloc*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/mimalloc*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/libarchive*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${MSYS64_BIN_PATH}/libgtest*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+ endif()
+
+ # dll with only name
+ set(ALL_RUNTIME_DLL_FILES "")
+
+ if(GPGFRONTEND_QT5_BUILD)
+ list(APPEND ALL_RUNTIME_DLL_FILES "Qt5Core.dll;Qt5Gui.dll;Qt5Network.dll;Qt5PrintSupport.dll;Qt5Svg.dll;Qt5Widgets.dll;libbrotlicommon.dll;libbrotlidec.dll;libdouble-conversion.dll;libzstd.dll;libmd4c.dll;")
+ else()
+ list(APPEND ALL_RUNTIME_DLL_FILES "Qt6Core.dll;Qt6Core5Compat.dll;Qt6Gui.dll;Qt6Network.dll;Qt6PrintSupport.dll;Qt6Svg.dll;Qt6Widgets.dll;libbrotlicommon.dll;libbrotlidec.dll;libdouble-conversion.dll;libzstd.dll;libmd4c.dll;")
+ endif()
+
+ # find the other dlls
+ foreach(_dllFileName ${ALL_RUNTIME_DLL_FILES})
+ message(STATUS "DLL FILE ${_dllFileName}")
+ list(APPEND ALL_DLL_NAME ${_dllFileName})
+ unset(_runtimeDllLocalPath)
+
+ find_file(_runtimeDllLocalPath NAMES ${_dllFileName} NO_CACHE REQUIRED)
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_runtimeDllLocalPath})
+ message(STATUS "DLL: ${_dllFileName} , ITS Full Path is ${_runtimeDllLocalPath}")
+ endforeach()
+
+ message(STATUS "All the Application Runtime Dependencies Path: ${ALL_RUNTIME_DEP_PATH_LIST}")
+
+ # copy dependencies to release path
+ foreach(_dllRuntimeFilePath ${ALL_RUNTIME_DEP_PATH_LIST})
+ file(COPY ${_dllRuntimeFilePath} DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
+ endforeach()
+endif()
+
+if(BUILD_APPLICATION)
+ set(RESOURCE_FILES ${CMAKE_SOURCE_DIR}/gpgfrontend.qrc ${APP_ICON_RESOURCE_WINDOWS} ${QON_QM_FILES})
+ add_custom_target(resources ALL DEPENDS ${RESOURCE_FILES})
+endif()
+
+if(BUILD_APPLICATION)
+ if(${CMAKE_BUILD_TYPE} STREQUAL "Release")
+ if(MINGW)
+ add_executable(${AppName} WIN32 ${BASE_SOURCE} ${RESOURCE_FILES})
+ elseif(LINUX AND NOT LINUX_INSTALL_SOFTWARE)
+ add_executable(${AppName} ${BASE_SOURCE} ${RESOURCE_FILES})
+
+ add_custom_command(TARGET ${AppName} POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir/usr/bin"
+ COMMAND ${CMAKE_COMMAND} -E rename "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${AppName}" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir/usr/bin/${AppName}"
+ COMMENT "Copying Binary into App Image"
+ )
+
+ # app bundle packing using xcode
+ elseif(APPLE AND XCODE_BUILD)
+ # standard app bundle packing
+ add_executable(${AppName} MACOSX_BUNDLE ${GPGFRONTEND_MACOS_ICON} ${BASE_SOURCE} ${RESOURCE_FILES})
+
+ set_target_properties(${AppName} PROPERTIES
+ BUNDLE True
+ MACOSX_BUNDLE_GUI_IDENTIFIER com.bktus.gpgfrontend
+ MACOSX_BUNDLE_BUNDLE_NAME ${AppName}
+ MACOSX_BUNDLE_LONG_VERSION_STRING ${BUILD_VERSION}
+ MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION}
+ MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
+ MACOSX_BUNDLE_COPYRIGHT "GPL-3.0"
+ MACOSX_BUNDLE_INFO_STRING "An OpenPGP Crypto Tool"
+ MACOSX_BUNDLE_ICON_FILE "gpgfrontend.icns"
+ MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/resource/plist/MacOSXBundleInfo.plist.in)
+
+ # option for sandbox mode, still under test
+ if(GPGFRONTEND_XOCDE_ENABLE_SANDBOX)
+ message(STATUS "Build Application With App Sandbox")
+ set(CUSTOM_ATTRIBUTE_ENABLE_APP_SANDBOX "Yes")
+ add_custom_command(TARGET ${AppName} POST_BUILD
+ COMMAND /bin/cp -rf ${CMAKE_SOURCE_DIR}/resource/lfs/macOS/GnuPG ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_BUILD_TYPE}/${AppName}.app/Contents/
+ WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
+ COMMENT "Copying Buddled GnuPG into App Bundle Resource")
+ set_target_properties(${AppName} PROPERTIES
+ XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_SOURCE_DIR}/resource/entitlements/GpgFrontend.entitlements")
+ else()
+ message(STATUS "Build Application Without App Sandbox")
+ set(CUSTOM_ATTRIBUTE_ENABLE_APP_SANDBOX "No")
+ endif()
+
+ set_target_properties(${AppName} PROPERTIES
+ XCODE_ATTRIBUTE_INSTALL_PATH "$(LOCAL_APPS_DIR)"
+ XCODE_ATTRIBUTE_SKIP_INSTALL "No"
+ XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS "--deep --entitlements ${CMAKE_SOURCE_DIR}/resource/plist/entitlement.plist"
+ XCODE_ATTRIBUTE_ENABLE_APP_SANDBOX "${CUSTOM_ATTRIBUTE_ENABLE_APP_SANDBOX}"
+ XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME "Yes"
+ XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}")
+ elseif(LINUX AND LINUX_INSTALL_SOFTWARE)
+ add_executable(${AppName} ${BASE_SOURCE} ${RESOURCE_FILES})
+ else()
+ message(FATAL_ERROR "cannot find a defined method to release application.")
+ endif()
+ else()
+ # if the status is debug
+ add_executable(${AppName} ${BASE_SOURCE} ${RESOURCE_FILES})
+
+ if(MINGW)
+ # include qt dependencies
+ if(NOT Qt6_DIR)
+ add_custom_command(TARGET ${AppName} POST_BUILD
+ COMMAND windeployqt --force ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${AppName}.exe)
+ else()
+ add_custom_command(TARGET ${AppName} POST_BUILD
+ COMMAND windeployqt-qt6.exe --force ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${AppName}.exe)
+ endif()
+ endif()
+ endif()
+
+ # Make app build with resources
+ add_dependencies(${AppName} resources)
+
+ # using c++ standard 17
+ target_compile_features(${AppName} PUBLIC cxx_std_17)
+endif()
+
+if(STABLE_BUILD_ONLY_APPLICATION)
+ message(STATUS "Application Headers Search Path: ${CMAKE_INSTALL_PREFIX}/include/gpgfrontend")
+ target_include_directories(${AppName} PUBLIC "${CMAKE_INSTALL_PREFIX}/include/gpgfrontend")
+
+ # link qt
+ if(GPGFRONTEND_QT5_BUILD)
+ target_link_libraries(${AppName} Qt5::Core Qt5::Widgets)
+ else()
+ target_link_libraries(${AppName} Qt6::Core Qt6::Widgets)
+ endif()
+endif()
+
+# link options for GpgFrontend
+if(BUILD_APPLICATION)
+ target_link_libraries(${AppName} gpgfrontend_core gpgfrontend_ui gpgfrontend_test)
+
+ if(MINGW)
+ message(STATUS "Link Application Library For MINGW")
+ target_link_libraries(${AppName} crypto)
+ elseif(APPLE)
+ message(STATUS "Link Application Library For macOS")
+ else()
+ message(STATUS "Link Application Library For Linux")
+ target_link_libraries(${AppName} crypto pthread)
+ endif()
+endif()
+
+# add i18n support
+if(BUILD_APPLICATION)
+ set(LOCALE_TS_PATH ${CMAKE_SOURCE_DIR}/resource/lfs/locale/ts)
+ set(TS_FILES "${LOCALE_TS_PATH}/GpgFrontend.en_US.ts"
+ "${LOCALE_TS_PATH}/GpgFrontend.de_DE.ts"
+ "${LOCALE_TS_PATH}/GpgFrontend.fr_FR.ts"
+ "${LOCALE_TS_PATH}/GpgFrontend.zh_CN.ts"
+ "${LOCALE_TS_PATH}/GpgFrontend.zh_TW.ts"
+ "${LOCALE_TS_PATH}/GpgFrontend.it_IT.ts")
+ file(GLOB_RECURSE ALL_SOURCE_FILES RELACTIVE ${CMAKE_SOURCE_DIR}/src/*.cpp)
+
+ if(GPGFRONTEND_QT5_BUILD)
+ # TODO
+ qt5_add_translation(GF_TRANSLATIONS_QM ${TS_FILES})
+ message(STATUS "GF_TRANSLATIONS_QM ${GF_TRANSLATIONS_QM}")
+
+ set(GF_QM_TRANSLATIONS_RESOURCE_FILE "${CMAKE_CURRENT_BINARY_DIR}/i18n.qrc")
+ file(WRITE ${GF_QM_TRANSLATIONS_RESOURCE_FILE} "<!DOCTYPE RCC>\n<RCC version=\"1.0\">\n <qresource prefix=\"i18n\">\n")
+
+ foreach(QM_FILE ${GF_TRANSLATIONS_QM})
+ file(RELATIVE_PATH QM_FILENAME ${CMAKE_CURRENT_BINARY_DIR} ${QM_FILE})
+ file(APPEND ${GF_QM_TRANSLATIONS_RESOURCE_FILE} " <file alias=\"${QM_FILENAME}\">${QM_FILE}</file>\n")
+ endforeach()
+
+ file(APPEND ${GF_QM_TRANSLATIONS_RESOURCE_FILE} " </qresource>\n</RCC>\n")
+ qt5_add_resources(GF_I18N_RESOURCES ${GF_QM_TRANSLATIONS_RESOURCE_FILE})
+
+ file(GLOB QT_TRANSLATIONS_TS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/third_party/qttranslations/translations/*.ts)
+ list(FILTER QT_TRANSLATIONS_TS INCLUDE REGEX ".*(qt|qtbase)_.*\.ts$")
+ qt5_add_translation(QT_TRANSLATIONS_QM ${QT_TRANSLATIONS_TS})
+
+ set(QT_QM_TRANSLATIONS_RESOURCE_FILE "${CMAKE_CURRENT_BINARY_DIR}/qt_i18n.qrc")
+ file(WRITE ${QT_QM_TRANSLATIONS_RESOURCE_FILE} "<!DOCTYPE RCC>\n<RCC version=\"1.0\">\n <qresource prefix=\"qt_i18n\">\n")
+
+ foreach(QM_FILE ${QT_TRANSLATIONS_QM})
+ file(RELATIVE_PATH QM_FILENAME ${CMAKE_CURRENT_BINARY_DIR} ${QM_FILE})
+ file(APPEND ${QT_QM_TRANSLATIONS_RESOURCE_FILE} " <file alias=\"${QM_FILENAME}\">${QM_FILE}</file>\n")
+ endforeach()
+
+ file(APPEND ${QT_QM_TRANSLATIONS_RESOURCE_FILE} " </qresource>\n</RCC>\n")
+ qt5_add_resources(GF_I18N_RESOURCES ${QT_QM_TRANSLATIONS_RESOURCE_FILE})
+
+ message(STATUS "GF_I18N_RESOURCES ${GF_I18N_RESOURCES}")
+
+ target_sources(${AppName} PRIVATE ${GF_I18N_RESOURCES})
+ else()
+ add_custom_target(gftranslations ALL)
+
+ qt_add_lrelease(gftranslations
+ TS_FILES ${TS_FILES}
+ QM_FILES_OUTPUT_VARIABLE GF_TRANSLATIONS_QM)
+ qt_add_resources(${AppName} "gftranslations"
+ PREFIX "/i18n"
+ BASE ${CMAKE_CURRENT_BINARY_DIR}
+ FILES ${GF_TRANSLATIONS_QM})
+
+ add_custom_target(qttranslations ALL)
+
+ file(GLOB QT_TRANSLATIONS_TS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/third_party/qttranslations/translations/*.ts)
+ list(FILTER QT_TRANSLATIONS_TS INCLUDE REGEX ".*(qt|qtbase)_.*\.ts$")
+ qt_add_lrelease(qttranslations
+ TS_FILES ${QT_TRANSLATIONS_TS}
+ QM_FILES_OUTPUT_VARIABLE QT_TRANSLATIONS_QM)
+ qt_add_resources(${AppName} "qttranslations"
+ PREFIX "/i18n_qt"
+ BASE ${CMAKE_CURRENT_BINARY_DIR}
+ FILES ${QT_TRANSLATIONS_QM})
+ endif()
endif()
# if building linux package
-if (LINUX AND LINUX_INSTALL_SOFTWARE)
- include(GNUInstallDirs)
- set(GPGFRONTEND_INSTALL_LIBRARIES
- mimalloc
- spdlog
- gpgfrontend_core
- gpgfrontend_ui
- gpgfrontend_test
- gpgfrontend_pinentry
- gpgfrontend_module_sdk)
-
- message(STATUS "GpgFrontend Install Libraries: ${GPGFRONTEND_INSTALL_LIBRARIES}")
- install(TARGETS ${AppName} ${GPGFRONTEND_INSTALL_LIBRARIES}
- EXPORT GpgFrontendTargets
- RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}
- LIBRARY DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}
- ARCHIVE DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR})
-
- install(FILES ${CMAKE_SOURCE_DIR}/TRANSLATORS
- DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/${AppName}/)
- install(FILES ${CMAKE_SOURCE_DIR}/resource/appstream/com.bktus.gpgfrontend.appdata.xml
- DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/metainfo/)
- install(FILES ${CMAKE_SOURCE_DIR}/resource/appstream/com.bktus.gpgfrontend.desktop
- DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/applications/)
- install(DIRECTORY ${CMAKE_SOURCE_DIR}/resource/lfs/pixmaps/
- DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/pixmaps/)
- install(DIRECTORY ${CMAKE_SOURCE_DIR}/resource/lfs/hicolor/
- DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/icons/hicolor/)
-endif ()
+if(LINUX AND LINUX_INSTALL_SOFTWARE)
+ include(GNUInstallDirs)
+
+ if(STABLE_BUILD_ONLY_APPLICATION)
+ set(GPGFRONTEND_INSTALL_LIBRARIES "")
+ else()
+ set(GPGFRONTEND_INSTALL_LIBRARIES
+ gpgfrontend_core
+ gpgfrontend_ui
+ gpgfrontend_test
+ gpgfrontend_module_sdk)
+ endif()
+
+ message(STATUS "GpgFrontend Install Libraries: ${GPGFRONTEND_INSTALL_LIBRARIES}")
+ install(TARGETS ${AppName} ${GPGFRONTEND_INSTALL_LIBRARIES}
+ EXPORT GpgFrontendTargets
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
+
+ install(FILES ${CMAKE_SOURCE_DIR}/TRANSLATORS
+ DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${AppName}/)
+ install(FILES ${CMAKE_SOURCE_DIR}/resource/appstream/com.bktus.gpgfrontend.appdata.xml
+ DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/metainfo/)
+ install(FILES ${CMAKE_SOURCE_DIR}/resource/appstream/com.bktus.gpgfrontend.desktop
+ DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications/)
+ install(DIRECTORY ${CMAKE_SOURCE_DIR}/resource/lfs/pixmaps/
+ DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pixmaps/)
+ install(DIRECTORY ${CMAKE_SOURCE_DIR}/resource/lfs/hicolor/
+ DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/)
+endif()
+
+# if only build sdk
+if(STABLE_BUILD_ONLY_SDK)
+ include(GNUInstallDirs)
+ set(GPGFRONTEND_SDK_INSTALL_LIBRARIES
+ gpgfrontend_module_sdk)
+
+ install(TARGETS ${GPGFRONTEND_SDK_INSTALL_LIBRARIES}
+ EXPORT GpgFrontendTargets
+ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
+endif()
+
+# if build full sdk
+if(STABLE_BUILD_FULL_SDK)
+ include(GNUInstallDirs)
+
+ set(GPGFRONTEND_SDK_INSTALL_LIBRARIES
+ gpgfrontend_core
+ gpgfrontend_ui
+ gpgfrontend_test
+ gpgfrontend_module_sdk)
+
+ install(TARGETS ${GPGFRONTEND_SDK_INSTALL_LIBRARIES}
+ EXPORT GpgFrontendTargets
+ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
+
+ install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/core"
+ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/gpgfrontend"
+ FILES_MATCHING
+ PATTERN "*.h"
+ )
+
+ install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/ui"
+ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/gpgfrontend"
+ FILES_MATCHING
+ PATTERN "*.h"
+ )
+
+ install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/test"
+ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/gpgfrontend"
+ FILES_MATCHING
+ PATTERN "*.h"
+ )
+endif() \ No newline at end of file
diff --git a/src/GpgFrontendContext.h b/src/GpgFrontendContext.h
index 00bbcfbe..9dd805b7 100644
--- a/src/GpgFrontendContext.h
+++ b/src/GpgFrontendContext.h
@@ -28,6 +28,10 @@
#pragma once
+#include <qapplication.h>
+
+#include <memory>
+
namespace GpgFrontend {
struct GpgFrontendContext;
@@ -38,7 +42,6 @@ using GFCxtSPtr = std::shared_ptr<GpgFrontendContext>;
struct GpgFrontendContext {
int argc;
char** argv;
- spdlog::level::level_enum log_level;
bool gather_external_gnupg_info;
bool load_default_gpg_context;
diff --git a/src/app.cpp b/src/app.cpp
index 9aa72894..4e67a0d6 100644
--- a/src/app.cpp
+++ b/src/app.cpp
@@ -34,7 +34,6 @@
// main
#include "init.h"
-#include "main.h"
namespace GpgFrontend {
@@ -50,20 +49,18 @@ constexpr int kCrashCode = ~0; ///<
auto StartApplication(const GFCxtWPtr& p_ctx) -> int {
GFCxtSPtr ctx = p_ctx.lock();
if (ctx == nullptr) {
- GF_MAIN_LOG_ERROR("cannot get gpgfrontend context.");
+ qWarning("cannot get gpgfrontend context.");
return -1;
}
auto* app = ctx->GetApp();
if (app == nullptr) {
- GF_MAIN_LOG_ERROR("cannot get qapplication from gpgfrontend context.");
+ qWarning("cannot get QApplication from gpgfrontend context.");
return -1;
}
- GF_MAIN_LOG_DEBUG("start running gui application");
-
/**
- * internationalisation. loop to restart main window
+ * internationalization. loop to restart main window
* with changed translation when settings change.
*/
int return_from_event_loop_code;
@@ -71,7 +68,7 @@ auto StartApplication(const GFCxtWPtr& p_ctx) -> int {
do {
// refresh locale settings
- if (restart_count > 0) InitLocale();
+ InitLocale();
// after that load ui totally
GpgFrontend::UI::InitGpgFrontendUI(app);
@@ -79,13 +76,8 @@ auto StartApplication(const GFCxtWPtr& p_ctx) -> int {
// finally create main window
return_from_event_loop_code = GpgFrontend::UI::RunGpgFrontendUI(app);
- GF_MAIN_LOG_DEBUG("try to destroy modules system and core");
-
restart_count++;
- GF_MAIN_LOG_DEBUG(
- "restart loop refresh, event loop code: {}, restart count: {}",
- return_from_event_loop_code, restart_count);
} while (return_from_event_loop_code == GpgFrontend::kRestartCode &&
restart_count < 99);
@@ -94,17 +86,10 @@ auto StartApplication(const GFCxtWPtr& p_ctx) -> int {
// then shutdown the core
GpgFrontend::DestroyGpgFrontendCore();
- GF_MAIN_LOG_DEBUG("core and modules system destroyed");
-
- // log for debug
- GF_MAIN_LOG_INFO("GpgFrontend is about to exit.");
// deep restart mode
if (return_from_event_loop_code == GpgFrontend::kDeepRestartCode ||
return_from_event_loop_code == kCrashCode) {
- // log for debug
- GF_MAIN_LOG_DEBUG(
- "deep restart or cash loop status caught, restart a new application");
QProcess::startDetached(qApp->arguments()[0], qApp->arguments());
};
diff --git a/src/cmd.cpp b/src/cmd.cpp
index d41b6de0..06222431 100644
--- a/src/cmd.cpp
+++ b/src/cmd.cpp
@@ -28,13 +28,16 @@
#include "cmd.h"
-#include "core/utils/BuildInfoUtils.h"
-#include "main.h"
+#include <qdatetime.h>
+#include <qglobal.h>
+#include <qloggingcategory.h>
+#include <qstring.h>
+#include <qtextstream.h>
-// std
-#include <iostream>
+#include "core/utils/BuildInfoUtils.h"
// GpgFrontend
+
#include "GpgFrontendContext.h"
#include "test/GpgFrontendTest.h"
@@ -42,7 +45,7 @@ namespace GpgFrontend {
auto PrintVersion() -> int {
QTextStream stream(stdout);
- stream << PROJECT_NAME << " " << GetProjectVersion() << '\n';
+ stream << GetProjectName() << " " << GetProjectVersion() << '\n';
stream << "Copyright (©) 2021 Saturneric <[email protected]>" << '\n'
<< QCoreApplication::tr(
"This is free software; see the source for copying conditions.")
@@ -60,30 +63,29 @@ auto PrintVersion() -> int {
return 0;
}
-auto ParseLogLevel(const QString& log_level) -> spdlog::level::level_enum {
- if (log_level == "trace") {
- return spdlog::level::trace;
- }
+auto ParseLogLevel(const QString& log_level) -> int {
if (log_level == "debug") {
- return spdlog::level::debug;
- }
- if (log_level == "info") {
- return spdlog::level::info;
+ QLoggingCategory::setFilterRules(
+ "core.debug=true\nui.debug=true\ntest.debug=true\nmodule.debug=true");
+ } else if (log_level == "info") {
+ QLoggingCategory::setFilterRules(
+ "*.debug=false\ncore.info=true\nui.info=true\ntest.info="
+ "true\nmodule.info=true");
+ } else if (log_level == "warning") {
+ QLoggingCategory::setFilterRules("*.debug=false\n*.info=false\n");
+ } else if (log_level == "critical") {
+ QLoggingCategory::setFilterRules(
+ "*.debug=false\n*.info=false\n*.warning=false\n");
+ } else {
+ qWarning() << "unknown log level: " << log_level;
}
- if (log_level == "warn") {
- return spdlog::level::warn;
- }
- if (log_level == "error") {
- return spdlog::level::err;
- }
-
- return spdlog::level::info;
+ return 0;
}
auto RunTest(const GFCxtWPtr& p_ctx) -> int {
GpgFrontend::GFCxtSPtr const ctx = p_ctx.lock();
if (ctx == nullptr) {
- GF_MAIN_LOG_ERROR("cannot get gpgfrontend context for test running");
+ qWarning("cannot get gpgfrontend context for test running");
return -1;
}
diff --git a/src/cmd.h b/src/cmd.h
index 061926dc..e987b39a 100644
--- a/src/cmd.h
+++ b/src/cmd.h
@@ -36,7 +36,7 @@ namespace GpgFrontend {
auto PrintVersion() -> int;
-auto ParseLogLevel(const QString& level) -> spdlog::level::level_enum;
+auto ParseLogLevel(const QString& level) -> int;
auto RunTest(const GFCxtWPtr&) -> int;
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index cedbe69a..d5b213ca 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -23,7 +23,7 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
-
+# gather source files
aux_source_directory(./function/result_analyse CORE_SOURCE)
aux_source_directory(./function/basic CORE_SOURCE)
aux_source_directory(./function/gpg CORE_SOURCE)
@@ -40,24 +40,24 @@ aux_source_directory(. CORE_SOURCE)
# define libgpgfrontend_core
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
+
add_library(gpgfrontend_core SHARED ${CORE_SOURCE})
+
+# generate headers
set(_export_file "${CMAKE_CURRENT_SOURCE_DIR}/GpgFrontendCoreExport.h")
generate_export_header(gpgfrontend_core EXPORT_FILE_NAME "${_export_file}")
+# compile definitions
+target_compile_definitions(gpgfrontend_core PUBLIC GF_CORE)
+
+# mimalloc (except apple macos)
if(NOT APPLE)
- target_link_libraries(gpgfrontend_core PUBLIC mimalloc)
- if(MINGW)
- set_target_properties(mimalloc
- PROPERTIES
- LIBRARY_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
- RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
- )
- endif()
+ target_link_libraries(gpgfrontend_core PUBLIC mimalloc)
endif()
# qt-aes
target_sources(gpgfrontend_core PRIVATE
- ${CMAKE_SOURCE_DIR}/third_party/qt-aes/qaesencryption.cpp)
+ ${CMAKE_SOURCE_DIR}/third_party/qt-aes/qaesencryption.cpp)
# encoding detect library
aux_source_directory(${CMAKE_SOURCE_DIR}/third_party/encoding-detect ENCODING_DETECT_SOURCE_CODE)
@@ -65,44 +65,27 @@ target_sources(gpgfrontend_core PUBLIC ${ENCODING_DETECT_SOURCE_CODE})
# link gnupg libraries
target_link_libraries(gpgfrontend_core PUBLIC gpgme assuan gpg-error)
+
# link openssl
target_link_libraries(gpgfrontend_core PUBLIC OpenSSL::SSL OpenSSL::Crypto)
-if (MINGW)
- # for uuid ability in mingw
- target_link_libraries(gpgfrontend_core PUBLIC bcrypt)
-endif ()
-# spdlog
-target_link_libraries(gpgfrontend_core PRIVATE spdlog)
if(MINGW)
- set_target_properties(spdlog
- PROPERTIES
- LIBRARY_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
- RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
- )
+ # for uuid ability in mingw
+ target_link_libraries(gpgfrontend_core PUBLIC bcrypt)
endif()
# configure libarchive
-if(NOT MINGW)
- if(APPLE)
- if(EXISTS "/usr/local/opt/libarchive/include")
- set(LibArchive_INCLUDE_DIR "/usr/local/opt/libarchive/include")
- else()
- set(LibArchive_INCLUDE_DIR "/opt/homebrew/opt/libarchive/include")
- endif()
- endif()
- find_package(LibArchive REQUIRED)
- target_include_directories(gpgfrontend_core PRIVATE ${LibArchive_INCLUDE_DIR})
-else()
- if(MINGW)
- set_target_properties(archive
- PROPERTIES
- LIBRARY_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
- RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
- )
- endif()
+if(APPLE)
+ if(EXISTS "/usr/local/opt/libarchive/include")
+ set(LibArchive_INCLUDE_DIR "/usr/local/opt/libarchive/include")
+ else()
+ set(LibArchive_INCLUDE_DIR "/opt/homebrew/opt/libarchive/include")
+ endif()
endif()
+find_package(LibArchive REQUIRED)
+target_include_directories(gpgfrontend_core PRIVATE ${LibArchive_INCLUDE_DIR})
+
# link libarchive
target_link_libraries(gpgfrontend_core PRIVATE archive)
@@ -116,30 +99,38 @@ endif()
# set up pch
target_precompile_headers(gpgfrontend_core
- PUBLIC ${CMAKE_SOURCE_DIR}/src/GpgFrontend.h
- PUBLIC GpgFrontendCore.h
- PUBLIC GpgConstants.h)
+ PUBLIC ${CMAKE_SOURCE_DIR}/src/GpgFrontend.h
+ PUBLIC GpgFrontendCore.h
+ PUBLIC GpgConstants.h)
# using std c++ 17
target_compile_features(gpgfrontend_core PUBLIC cxx_std_17)
+if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
+ # lib output path
+ set_target_properties(gpgfrontend_core PROPERTIES
+ LIBRARY_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/lib
+ RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/lib)
+endif()
+
# link for different platforms
-if (MINGW)
- message(STATUS "Link GPG Static Library For MINGW")
- target_link_libraries(gpgfrontend_core PUBLIC wsock32)
-elseif (APPLE)
- message(STATUS "Link GPG Static Library For macOS")
- if (XCODE_BUILD)
- set_target_properties(gpgfrontend_core
- PROPERTIES
- ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
- LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
- LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
- XCODE_ATTRIBUTE_SKIP_INSTALL "Yes"
- XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}")
- endif ()
-else ()
- # linux
- message(STATUS "Link GPG Static Library For Unix")
- target_link_libraries(gpgfrontend_core PUBLIC pthread dl)
-endif ()
+if(MINGW)
+ message(STATUS "Link GPG Static Library For MINGW")
+ target_link_libraries(gpgfrontend_core PUBLIC wsock32)
+elseif(APPLE)
+ message(STATUS "Link GPG Static Library For macOS")
+
+ if(XCODE_BUILD)
+ set_target_properties(gpgfrontend_core
+ PROPERTIES
+ ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
+ LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
+ LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
+ XCODE_ATTRIBUTE_SKIP_INSTALL "Yes"
+ XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}")
+ endif()
+else()
+ # linux
+ message(STATUS "Link GPG Static Library For Unix")
+ target_link_libraries(gpgfrontend_core PUBLIC pthread dl)
+endif()
diff --git a/src/core/GpgConstants.h b/src/core/GpgConstants.h
index 91d5f1ef..1165db78 100644
--- a/src/core/GpgConstants.h
+++ b/src/core/GpgConstants.h
@@ -53,9 +53,13 @@ constexpr const char* PGP_PRIVATE_KEY_BEGIN =
"-----BEGIN PGP PRIVATE KEY BLOCK-----"; ///<
// MODULE ID
-const QString kGnuPGInfoGatheringModuleID =
+constexpr const char* kGnuPGInfoGatheringModuleID =
"com.bktus.gpgfrontend.module.gnupg_info_gathering";
-const QString kVersionCheckingModuleID =
+constexpr const char* kVersionCheckingModuleID =
"com.bktus.gpgfrontend.module.version_checking";
+constexpr const char* kPinentryModuleID =
+ "com.bktus.gpgfrontend.module.pinentry";
+constexpr const char* kPaperKeyModuleID =
+ "com.bktus.gpgfrontend.module.paper_key";
} // namespace GpgFrontend
diff --git a/src/core/GpgCoreInit.cpp b/src/core/GpgCoreInit.cpp
index 2952d6e4..4e1b64e1 100644
--- a/src/core/GpgCoreInit.cpp
+++ b/src/core/GpgCoreInit.cpp
@@ -78,7 +78,6 @@ auto SearchGpgconfPath(const QList<QString>& candidate_paths) -> QString {
auto SearchKeyDatabasePath(const QList<QString>& candidate_paths) -> QString {
for (const auto& path : candidate_paths) {
- GF_CORE_LOG_DEBUG("searh for candidate key database path: {}", path);
if (VerifyKeyDatabasePath(QFileInfo(path))) {
return path;
}
@@ -97,8 +96,6 @@ auto InitGpgME(const QString& gpgconf_path, const QString& gnupg_path) -> bool {
#endif
if (!gnupg_path.isEmpty()) {
- GF_CORE_LOG_DEBUG("gpgme set engine info, gpgconf path: {}, gnupg path: {}",
- gpgconf_path, gnupg_path);
CheckGpgError(gpgme_set_engine_info(GPGME_PROTOCOL_GPGCONF,
gpgconf_path.toUtf8(), nullptr));
CheckGpgError(gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP,
@@ -121,15 +118,6 @@ auto InitGpgME(const QString& gpgconf_path, const QString& gnupg_path) -> bool {
continue;
}
- GF_CORE_LOG_DEBUG(
- "gpg context engine info: {} {} {} {}",
- gpgme_get_protocol_name(engine_info->protocol),
- QString(engine_info->file_name == nullptr ? "null"
- : engine_info->file_name),
- QString(engine_info->home_dir == nullptr ? "null"
- : engine_info->home_dir),
- QString(engine_info->version ? "null" : engine_info->version));
-
switch (engine_info->protocol) {
case GPGME_PROTOCOL_OpenPGP:
find_openpgp = true;
@@ -183,12 +171,11 @@ auto InitGpgME(const QString& gpgconf_path, const QString& gnupg_path) -> bool {
const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
"core", "gpgme.ctx.gnupg_version", QString{"0.0.0"});
- GF_CORE_LOG_DEBUG("got gnupg version from rt: {}", gnupg_version);
// conditional check: only support gpg 2.1.x now
if (!(GFCompareSoftwareVersion(gnupg_version, "2.1.0") >= 0 && find_gpgconf &&
find_openpgp && find_cms)) {
- GF_CORE_LOG_ERROR("gpgme env check failed, abort");
+ qCWarning(core, "gpgme env check failed, abort");
return false;
}
@@ -249,8 +236,8 @@ auto DetectGpgConfPath() -> QString {
#endif
if (!VerifyGpgconfPath(QFileInfo(gnupg_install_fs_path))) {
- GF_CORE_LOG_ERROR("core loaded custom gpgconf path is illegal: {}",
- gnupg_install_fs_path);
+ qCWarning(core) << "core loaded custom gpgconf path is illegal: "
+ << gnupg_install_fs_path;
gnupg_install_fs_path = "";
}
}
@@ -260,15 +247,11 @@ auto DetectGpgConfPath() -> QString {
#ifdef MACOS
gnupg_install_fs_path = SearchGpgconfPath(
{"/usr/local/bin/gpgconf", "/opt/homebrew/bin/gpgconf"});
- GF_CORE_LOG_DEBUG("core loaded searched gpgconf path: {}",
- gnupg_install_fs_path);
#endif
#ifdef WINDOWS
gnupg_install_fs_path =
SearchGpgconfPath({"C:/Program Files (x86)/gnupg/bin"});
- GF_CORE_LOG_DEBUG("core loaded searched gpgconf path: {}",
- gnupg_install_fs_path);
#endif
}
@@ -289,13 +272,10 @@ void InitGpgFrontendCore(CoreInitArgs args) {
Module::UpsertRTValue("core", "env.state.basic", 0);
Module::UpsertRTValue("core", "env.state.all", 0);
- // initialize locale environment
- GF_CORE_LOG_DEBUG("locale: {}", setlocale(LC_CTYPE, nullptr));
-
auto gpgconf_install_fs_path = DetectGpgConfPath();
auto gnupg_install_fs_path = DetectGnuPGPath(gpgconf_install_fs_path);
- GF_CORE_LOG_INFO("detected gpgconf path: {}", gpgconf_install_fs_path);
- GF_CORE_LOG_INFO("detected gnupg path: {}", gnupg_install_fs_path);
+ qCInfo(core) << "detected gpgconf path: " << gpgconf_install_fs_path;
+ qCInfo(core) << "detected gnupg path: " << gnupg_install_fs_path;
// initialize library gpgme
if (!InitGpgME(gpgconf_install_fs_path, gnupg_install_fs_path)) {
@@ -334,11 +314,6 @@ void InitGpgFrontendCore(CoreInitArgs args) {
QString::fromLocal8Bit(qgetenv("container")) != "flatpak")
.toBool();
- GF_CORE_LOG_DEBUG("core loaded if use custom key databse path: {}",
- use_custom_key_database_path);
- GF_CORE_LOG_DEBUG("core loaded custom key databse path: {}",
- custom_key_database_path);
-
// check key database path
QString key_database_fs_path;
// user defined
@@ -346,21 +321,17 @@ void InitGpgFrontendCore(CoreInitArgs args) {
!custom_key_database_path.isEmpty()) {
key_database_fs_path = custom_key_database_path;
if (VerifyKeyDatabasePath(QFileInfo(key_database_fs_path))) {
- GF_CORE_LOG_ERROR(
- "core loaded custom gpg key database is illegal: {}",
- key_database_fs_path);
+ qCWarning(core)
+ << "core loaded custom gpg key database is illegal: "
+ << key_database_fs_path;
} else {
use_custom_key_database_path = true;
- GF_CORE_LOG_DEBUG("core loaded custom gpg key database path: {}",
- key_database_fs_path);
}
} else {
#if defined(LINUX) || defined(MACOS)
use_custom_key_database_path = true;
key_database_fs_path =
SearchKeyDatabasePath({QDir::home().path() + "/.gnupg"});
- GF_CORE_LOG_DEBUG("core loaded searched key database path: {}",
- key_database_fs_path);
#endif
}
@@ -377,13 +348,11 @@ void InitGpgFrontendCore(CoreInitArgs args) {
if (dir_info.exists() && dir_info.isDir() &&
dir_info.isReadable() && dir_info.isWritable()) {
args.db_path = dir_info.absoluteFilePath();
- GF_CORE_LOG_INFO("using key database path: {}",
- args.db_path);
} else {
- GF_CORE_LOG_ERROR(
- "custom key database path: {}, is not point to "
- "an accessible directory",
- key_database_fs_path);
+ qCWarning(core)
+ << "custom key database path: " << key_database_fs_path
+ << ", is not point to "
+ "an accessible directory";
}
}
@@ -404,7 +373,7 @@ void InitGpgFrontendCore(CoreInitArgs args) {
// exit if failed
if (!ctx.Good()) {
- GF_CORE_LOG_ERROR("default gnupg context init error, abort");
+ qCWarning(core, "default gnupg context init error, abort");
CoreSignalStation::GetInstance()->SignalBadGnupgEnv(
QCoreApplication::tr("GpgME Context initiation failed"));
return -1;
@@ -415,11 +384,12 @@ void InitGpgFrontendCore(CoreInitArgs args) {
if (args.load_default_gpg_context) {
if (!GpgKeyGetter::GetInstance().FlushKeyCache()) {
CoreSignalStation::GetInstance()->SignalBadGnupgEnv(
- QCoreApplication::tr("Gpg Key Detabase initiation failed"));
+ QCoreApplication::tr("Gpg Key Database initiation failed"));
};
}
- GF_CORE_LOG_DEBUG(
+ qCDebug(
+ core,
"basic env checking finished, including gpgme, ctx, and key infos");
Module::UpsertRTValue("core", "env.state.basic", 1);
diff --git a/src/core/GpgFrontendCore.cpp b/src/core/GpgFrontendCore.cpp
index 82ed09f4..ab589abc 100644
--- a/src/core/GpgFrontendCore.cpp
+++ b/src/core/GpgFrontendCore.cpp
@@ -27,3 +27,5 @@
*/
#include "core/GpgFrontendCore.h"
+
+Q_LOGGING_CATEGORY(core, "core") \ No newline at end of file
diff --git a/src/core/GpgFrontendCore.h b/src/core/GpgFrontendCore.h
index f07824cf..0310804c 100644
--- a/src/core/GpgFrontendCore.h
+++ b/src/core/GpgFrontendCore.h
@@ -30,3 +30,11 @@
// Qt
#include <QtCore>
+
+// declare area of core
+#ifdef GF_CORE
+
+// declare logging category
+Q_DECLARE_LOGGING_CATEGORY(core)
+
+#endif \ No newline at end of file
diff --git a/src/core/function/ArchiveFileOperator.cpp b/src/core/function/ArchiveFileOperator.cpp
index 475ef434..0df1a284 100644
--- a/src/core/function/ArchiveFileOperator.cpp
+++ b/src/core/function/ArchiveFileOperator.cpp
@@ -46,14 +46,14 @@ auto CopyData(struct archive *ar, struct archive *aw) -> int {
r = archive_read_data_block(ar, &buff, &size, &offset);
if (r == ARCHIVE_EOF) return (ARCHIVE_OK);
if (r != ARCHIVE_OK) {
- GF_CORE_LOG_ERROR("archive_read_data_block() failed: {}",
- archive_error_string(ar));
+ qCWarning(core) << "archive_read_data_block() failed: "
+ << archive_error_string(ar);
return (r);
}
r = archive_write_data_block(aw, buff, size, offset);
if (r != ARCHIVE_OK) {
- GF_CORE_LOG_ERROR("archive_write_data_block() failed: {}",
- archive_error_string(aw));
+ qCWarning(core) << "archive_write_data_block() failed: "
+ << archive_error_string(aw);
return (r);
}
}
@@ -113,8 +113,8 @@ void ArchiveFileOperator::NewArchive2DataExchanger(
#endif
if (r != ARCHIVE_OK) {
- GF_CORE_LOG_ERROR("archive_read_disk_open() failed: {}, abort...",
- archive_error_string(disk));
+ qCWarning(core, "archive_read_disk_open() failed: %s, abort...",
+ archive_error_string(disk));
archive_read_free(disk);
archive_write_free(archive);
return -1;
@@ -125,8 +125,9 @@ void ArchiveFileOperator::NewArchive2DataExchanger(
r = archive_read_next_header2(disk, entry);
if (r == ARCHIVE_EOF) break;
if (r != ARCHIVE_OK) {
- GF_CORE_LOG_ERROR(
- "archive_read_next_header2() failed, ret: {}, explain: {}", r,
+ qCWarning(
+ core,
+ "archive_read_next_header2() failed, ret: %d, explain: %s", r,
archive_error_string(disk));
ret = -1;
break;
@@ -143,11 +144,8 @@ void ArchiveFileOperator::NewArchive2DataExchanger(
#endif
QFile file(source_path);
-#ifdef QT5_BUILD
+
if (file.open(QIODevice::ReadOnly)) {
-#else
- if (file.open(QIODeviceBase::ReadOnly)) {
-#endif
// turn absolute path to relative path
auto relativ_path_name = base_path.relativeFilePath(source_path);
archive_entry_set_pathname(entry, relativ_path_name.toUtf8());
@@ -164,17 +162,17 @@ void ArchiveFileOperator::NewArchive2DataExchanger(
r = archive_write_header(archive, entry);
if (r < ARCHIVE_OK) {
- GF_CORE_LOG_ERROR(
- "archive_write_header() failed, ret: {}, explain: {} ", r,
- archive_error_string(archive));
+ qCWarning(core,
+ "archive_write_header() failed, ret: %d, explain: %s",
+ r, archive_error_string(archive));
continue;
}
if (r == ARCHIVE_FATAL) {
- GF_CORE_LOG_ERROR(
- "archive_write_header() failed, ret: {}, explain: {}, "
- "abort ...",
- r, archive_error_string(archive));
+ qCWarning(core,
+ "archive_write_header() failed, ret: %d, explain: %s, "
+ "abort ...",
+ r, archive_error_string(archive));
ret = -1;
break;
}
@@ -201,7 +199,6 @@ void ArchiveFileOperator::NewArchive2DataExchanger(
void ArchiveFileOperator::ExtractArchiveFromDataExchanger(
std::shared_ptr<GFDataExchanger> ex, const QString &target_path,
const OperationCallback &cb) {
- GF_CORE_LOG_INFO("target path: {}", target_path);
RunIOOperaAsync(
[=](const DataObjectPtr &data_object) -> GFError {
auto *archive = archive_read_new();
@@ -209,17 +206,17 @@ void ArchiveFileOperator::ExtractArchiveFromDataExchanger(
auto r = archive_read_support_filter_all(archive);
if (r != ARCHIVE_OK) {
- GF_CORE_LOG_ERROR(
- "archive_read_support_filter_all(), ret: {}, reason: {}", r,
- archive_error_string(archive));
+ qCWarning(core,
+ "archive_read_support_filter_all(), ret: %d, reason: %s", r,
+ archive_error_string(archive));
return r;
}
r = archive_read_support_format_all(archive);
if (r != ARCHIVE_OK) {
- GF_CORE_LOG_ERROR(
- "archive_read_support_format_all(), ret: {}, reason: {}", r,
- archive_error_string(archive));
+ qCWarning(core,
+ "archive_read_support_format_all(), ret: %d, reason: %s", r,
+ archive_error_string(archive));
return r;
}
@@ -230,16 +227,16 @@ void ArchiveFileOperator::ExtractArchiveFromDataExchanger(
nullptr);
if (r != ARCHIVE_OK) {
- GF_CORE_LOG_ERROR("archive_read_open(), ret: {}, reason: {}", r,
- archive_error_string(archive));
+ qCWarning(core, "archive_read_open(), ret: %d, reason: %s", r,
+ archive_error_string(archive));
return r;
}
r = archive_write_disk_set_options(ext, 0);
if (r != ARCHIVE_OK) {
- GF_CORE_LOG_ERROR(
- "archive_write_disk_set_options(), ret: {}, reason: {}", r,
- archive_error_string(archive));
+ qCWarning(core,
+ "archive_write_disk_set_options(), ret: %d, reason: %s", r,
+ archive_error_string(archive));
return r;
}
@@ -248,8 +245,8 @@ void ArchiveFileOperator::ExtractArchiveFromDataExchanger(
r = archive_read_next_header(archive, &entry);
if (r == ARCHIVE_EOF) break;
if (r != ARCHIVE_OK) {
- GF_CORE_LOG_ERROR("archive_read_next_header(), ret: {}, reason: {}",
- r, archive_error_string(archive));
+ qCWarning(core, "archive_read_next_header(), ret: %d, reason: %s",
+ r, archive_error_string(archive));
break;
}
@@ -267,8 +264,8 @@ void ArchiveFileOperator::ExtractArchiveFromDataExchanger(
r = archive_write_header(ext, entry);
if (r != ARCHIVE_OK) {
- GF_CORE_LOG_ERROR("archive_write_header(), ret: {}, reason: {}", r,
- archive_error_string(archive));
+ qCWarning(core, "archive_write_header(), ret: %d, reason: %s", r,
+ archive_error_string(archive));
} else {
r = CopyData(archive, ext);
}
@@ -276,13 +273,13 @@ void ArchiveFileOperator::ExtractArchiveFromDataExchanger(
r = archive_read_free(archive);
if (r != ARCHIVE_OK) {
- GF_CORE_LOG_ERROR("archive_read_free(), ret: {}, reason: {}", r,
- archive_error_string(archive));
+ qCWarning(core, "archive_read_free(), ret: %d, reason: %s", r,
+ archive_error_string(archive));
}
r = archive_write_free(ext);
if (r != ARCHIVE_OK) {
- GF_CORE_LOG_ERROR("archive_read_free(), ret: {}, reason: {}", r,
- archive_error_string(archive));
+ qCWarning(core, "archive_read_free(), ret: %d, reason: %s", r,
+ archive_error_string(archive));
}
return 0;
@@ -302,8 +299,8 @@ void ArchiveFileOperator::ListArchive(const QString &archive_path) {
10240); // Note 1
if (r != ARCHIVE_OK) return;
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
- GF_CORE_LOG_DEBUG("File: {}", archive_entry_pathname(entry));
- GF_CORE_LOG_DEBUG("File Path: {}", archive_entry_pathname(entry));
+ qCDebug(core, core, "File: %s", archive_entry_pathname(entry));
+ qCDebug(core, core, "File Path: %s", archive_entry_pathname(entry));
archive_read_data_skip(a); // Note 2
}
r = archive_read_free(a); // Note 3
diff --git a/src/core/function/CacheManager.cpp b/src/core/function/CacheManager.cpp
index 719c962d..e71936fe 100644
--- a/src/core/function/CacheManager.cpp
+++ b/src/core/function/CacheManager.cpp
@@ -107,7 +107,6 @@ class CacheManager::Impl : public QObject {
durable_cache_storage_.insert(key, value);
if (!key_storage_.contains(key)) {
- GF_CORE_LOG_DEBUG("register new key of cache", key);
key_storage_.push_back(key);
}
@@ -126,8 +125,8 @@ class CacheManager::Impl : public QObject {
return {};
}
- auto LoadDurableCache(const QString& key, QJsonDocument default_value)
- -> QJsonDocument {
+ auto LoadDurableCache(const QString& key,
+ QJsonDocument default_value) -> QJsonDocument {
auto data_object_key = get_data_object_key(key);
if (!durable_cache_storage_.exists(key)) {
durable_cache_storage_.insert(
@@ -165,9 +164,10 @@ class CacheManager::Impl : public QObject {
*
*/
void slot_flush_cache_storage() {
+ qCDebug(core, "write cache to file system...");
+
for (const auto& cache : durable_cache_storage_.mirror()) {
auto key = get_data_object_key(cache.first);
- GF_CORE_LOG_TRACE("save cache into filesystem, key {}", key);
GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(
key, QJsonDocument(cache.second));
}
@@ -215,7 +215,7 @@ class CacheManager::Impl : public QObject {
*
*/
void load_all_cache_storage() {
- GF_CORE_LOG_DEBUG("start to load all cache from file system");
+ qCDebug(core, "start to load all cache from file system");
auto stored_data =
GpgFrontend::DataObjectOperator::GetInstance().GetDataObject(drk_key_);
@@ -258,9 +258,8 @@ auto CacheManager::LoadDurableCache(const QString& key) -> QJsonDocument {
return p_->LoadDurableCache(key);
}
-auto CacheManager::LoadDurableCache(const QString& key,
- QJsonDocument default_value)
- -> QJsonDocument {
+auto CacheManager::LoadDurableCache(
+ const QString& key, QJsonDocument default_value) -> QJsonDocument {
return p_->LoadDurableCache(key, std::move(default_value));
}
diff --git a/src/core/function/CoreSignalStation.h b/src/core/function/CoreSignalStation.h
index 8827c803..5c19f3b0 100644
--- a/src/core/function/CoreSignalStation.h
+++ b/src/core/function/CoreSignalStation.h
@@ -62,12 +62,6 @@ class GPGFRONTEND_CORE_EXPORT CoreSignalStation : public QObject {
* @brief
*
*/
- void SignalUserInputPassphraseCallback(QSharedPointer<GpgPassphraseContext>);
-
- /**
- * @brief
- *
- */
void SignalBadGnupgEnv(QString);
/**
diff --git a/src/core/function/DataObjectOperator.cpp b/src/core/function/DataObjectOperator.cpp
index cbf21f8e..dbf92cd1 100644
--- a/src/core/function/DataObjectOperator.cpp
+++ b/src/core/function/DataObjectOperator.cpp
@@ -36,7 +36,6 @@
namespace GpgFrontend {
void DataObjectOperator::init_app_secure_key() {
- GF_CORE_LOG_INFO("initializing application secure key...");
WriteFile(app_secure_key_path_,
PassphraseGenerator::GetInstance().Generate(256).toUtf8());
QFile::setPermissions(app_secure_key_path_,
@@ -50,8 +49,8 @@ DataObjectOperator::DataObjectOperator(int channel)
QByteArray key;
if (!ReadFile(app_secure_key_path_, key)) {
- GF_CORE_LOG_ERROR("failed to read app secure key file: {}",
- app_secure_key_path_);
+ qCWarning(core) << "failed to read app secure key file: "
+ << app_secure_key_path_;
// unsafe mode
key = {};
}
@@ -85,8 +84,6 @@ auto DataObjectOperator::SaveDataObj(const QString& key,
QAESEncryption(QAESEncryption::AES_256, QAESEncryption::ECB,
QAESEncryption::Padding::ISO)
.encode(value.toJson(), hash_key_);
- GF_CORE_LOG_TRACE("saving data object {} to disk {} , size: {} bytes",
- hash_obj_key, target_obj_path, encoded_data.size());
// recreate if not exists
if (!QDir(app_data_objs_path_).exists()) {
@@ -94,7 +91,7 @@ auto DataObjectOperator::SaveDataObj(const QString& key,
}
if (!WriteFile(target_obj_path, encoded_data)) {
- GF_CORE_LOG_ERROR("failed to write data object to disk: {}", key);
+ qCWarning(core) << "failed to write data object to disk: " << key;
}
return key.isEmpty() ? hash_obj_key : QString();
}
@@ -102,20 +99,19 @@ auto DataObjectOperator::SaveDataObj(const QString& key,
auto DataObjectOperator::GetDataObject(const QString& key)
-> std::optional<QJsonDocument> {
try {
- GF_CORE_LOG_TRACE("try to get data object from disk, key: {}", key);
auto hash_obj_key = QCryptographicHash::hash(hash_key_ + key.toUtf8(),
QCryptographicHash::Sha256)
.toHex();
const auto obj_path = app_data_objs_path_ + "/" + hash_obj_key;
if (!QFileInfo(obj_path).exists()) {
- GF_CORE_LOG_WARN("data object not found from disk, key: {}", key);
+ qCWarning(core) << "data object not found from disk, key: " << key;
return {};
}
QByteArray encoded_data;
if (!ReadFile(obj_path, encoded_data)) {
- GF_CORE_LOG_ERROR("failed to read data object from disk, key: {}", key);
+ qCWarning(core) << "failed to read data object from disk, key: " << key;
return {};
}
@@ -124,11 +120,11 @@ auto DataObjectOperator::GetDataObject(const QString& key)
auto decoded_data =
encryption.removePadding(encryption.decode(encoded_data, hash_key_));
- GF_CORE_LOG_TRACE("data object has been decoded, key: {}, data: {}", key,
- decoded_data);
+
return QJsonDocument::fromJson(decoded_data);
} catch (...) {
- GF_CORE_LOG_ERROR("failed to get data object, caught exception: {}", key);
+ qCWarning(core) << "failed to get data object:" << key
+ << " caught exception.";
return {};
}
}
diff --git a/src/core/function/GlobalSettingStation.cpp b/src/core/function/GlobalSettingStation.cpp
index 45ab11f9..e123f249 100644
--- a/src/core/function/GlobalSettingStation.cpp
+++ b/src/core/function/GlobalSettingStation.cpp
@@ -40,13 +40,11 @@ class GlobalSettingStation::Impl {
*
*/
explicit Impl() noexcept {
- GF_CORE_LOG_INFO("app path: {}", GetAppDir());
- GF_CORE_LOG_INFO("app working path: {}", working_path_);
+ qCInfo(core) << "app path: " << GetAppDir();
+ qCInfo(core) << "app working path: " << working_path_;
auto portable_file_path = working_path_ + "/PORTABLE.txt";
if (QFileInfo(portable_file_path).exists()) {
- GF_CORE_LOG_INFO(
- "dectected portable mode, reconfiguring config and data path...");
Module::UpsertRTValue("core", "env.state.portable", 1);
app_data_path_ = working_path_;
@@ -56,11 +54,11 @@ class GlobalSettingStation::Impl {
portable_mode_ = true;
}
- GF_CORE_LOG_INFO("app data path: {}", app_data_path_);
- GF_CORE_LOG_INFO("app log path: {}", app_log_path_);
+ qCInfo(core) << "app data path: " << app_data_path_;
+ qCInfo(core) << "app log path: " << app_log_path_;
#ifdef WINDOWS
- GF_CORE_LOG_INFO("app config path: {}", app_config_path_);
+ qCInfo(core) << "app config path: " << app_config_path_;
#endif
#ifdef WINDOWS
diff --git a/src/core/function/GlobalSettingStation.h b/src/core/function/GlobalSettingStation.h
index c907bdb5..d3287ac2 100644
--- a/src/core/function/GlobalSettingStation.h
+++ b/src/core/function/GlobalSettingStation.h
@@ -28,6 +28,8 @@
#pragma once
+#include <qsettings.h>
+
#include "core/function/basic/GpgFunctionObject.h"
namespace GpgFrontend {
diff --git a/src/core/function/KeyPackageOperator.cpp b/src/core/function/KeyPackageOperator.cpp
index d185b0ef..d4642cf7 100644
--- a/src/core/function/KeyPackageOperator.cpp
+++ b/src/core/function/KeyPackageOperator.cpp
@@ -28,6 +28,7 @@
#include "KeyPackageOperator.h"
+#include <qglobal.h>
#include <qt-aes/qaesencryption.h>
#include "core/function/KeyPackageOperator.h"
@@ -44,7 +45,7 @@ namespace GpgFrontend {
auto KeyPackageOperator::GeneratePassphrase(const QString& phrase_path,
QString& phrase) -> bool {
phrase = PassphraseGenerator::GetInstance().Generate(256);
- GF_CORE_LOG_DEBUG("generated passphrase: {} bytes", phrase.size());
+ qCDebug(core, "generated passphrase: %lld bytes", phrase.size());
return WriteFile(phrase_path, phrase.toUtf8());
}
@@ -53,13 +54,11 @@ void KeyPackageOperator::GenerateKeyPackage(const QString& key_package_path,
const KeyArgsList& keys,
QString& phrase, bool secret,
const OperationCallback& cb) {
- GF_CORE_LOG_DEBUG("generating key package: {}", key_package_name);
-
GpgKeyImportExporter::GetInstance().ExportAllKeys(
keys, secret, true, [=](GpgError err, const DataObjectPtr& data_obj) {
if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
- GF_LOG_ERROR("export keys error, reason: {}",
- DescribeGpgErrCode(err).second);
+ qCWarning(core) << "export keys error, reason: "
+ << DescribeGpgErrCode(err).second;
cb(-1, data_obj);
return;
}
@@ -78,7 +77,6 @@ void KeyPackageOperator::GenerateKeyPackage(const QString& key_package_path,
QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
QAESEncryption::Padding::ISO);
auto encoded_data = encryption.encode(data, hash_key);
- GF_CORE_LOG_DEBUG("writing key package, name: {}", key_package_name);
cb(WriteFile(key_package_path, encoded_data) ? 0 : -1,
TransferParams());
@@ -91,20 +89,18 @@ void KeyPackageOperator::ImportKeyPackage(const QString& key_package_path,
const OperationCallback& cb) {
RunOperaAsync(
[=](const DataObjectPtr& data_object) -> GFError {
- GF_CORE_LOG_DEBUG("importing key package: {}", key_package_path);
-
QByteArray encrypted_data;
ReadFile(key_package_path, encrypted_data);
if (encrypted_data.isEmpty()) {
- GF_CORE_LOG_ERROR("failed to read key package: {}", key_package_path);
+ qCWarning(core) << "failed to read key package: " << key_package_path;
return -1;
};
QByteArray passphrase;
ReadFile(phrase_path, passphrase);
if (passphrase.size() != 256) {
- GF_CORE_LOG_ERROR("passphrase size mismatch: {}", phrase_path);
+ qCWarning(core) << "passphrase size mismatch: " << phrase_path;
return -1;
}
diff --git a/src/core/function/LoggerManager.cpp b/src/core/function/LoggerManager.cpp
deleted file mode 100644
index c7088128..00000000
--- a/src/core/function/LoggerManager.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric <[email protected]>
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend 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.
- *
- * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric <[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#include "LoggerManager.h"
-
-#include <spdlog/async.h>
-#include <spdlog/common.h>
-#include <spdlog/sinks/rotating_file_sink.h>
-#include <spdlog/sinks/stdout_color_sinks.h>
-
-#include "core/function/GlobalSettingStation.h"
-
-namespace GpgFrontend {
-
-std::shared_ptr<spdlog::logger> LoggerManager::default_logger = nullptr;
-spdlog::level::level_enum LoggerManager::default_log_level =
- spdlog::level::debug;
-
-LoggerManager::LoggerManager(int channel)
- : SingletonFunctionObject<LoggerManager>(channel) {
- spdlog::init_thread_pool(1024, 2);
- spdlog::flush_every(std::chrono::seconds(5));
-}
-
-LoggerManager::~LoggerManager() {
-#ifdef WINDOWS
- // Under VisualStudio, this must be called before main finishes to workaround
- // a known VS issue
- spdlog::drop_all();
- spdlog::shutdown();
-#endif
-
- if (default_logger) default_logger = nullptr;
-}
-
-auto LoggerManager::GetLogger(const QString& id)
- -> std::shared_ptr<spdlog::logger> {
- auto m_it = logger_map_.find(id);
- if (m_it == logger_map_.end()) return GetDefaultLogger();
- return m_it->second;
-}
-
-auto LoggerManager::RegisterAsyncLogger(const QString& id,
- spdlog::level::level_enum level)
- -> std::shared_ptr<spdlog::logger> {
- // get the log directory
- auto log_file_path =
- GlobalSettingStation::GetInstance().GetLogDir() + "/" + id + ".log";
-
- // sinks
- std::vector<spdlog::sink_ptr> sinks;
- sinks.push_back(GpgFrontend::SecureCreateSharedObject<
- spdlog::sinks::stderr_color_sink_mt>());
- sinks.push_back(GpgFrontend::SecureCreateSharedObject<
- spdlog::sinks::rotating_file_sink_mt>(
- log_file_path.toUtf8().constData(), 1048576 * 32, 8));
-
- // logger
- auto logger = GpgFrontend::SecureCreateSharedObject<spdlog::async_logger>(
- id.toStdString(), begin(sinks), end(sinks), spdlog::thread_pool());
- logger->set_pattern(
- "[%H:%M:%S.%e] [T:%t] [%=6n] %^[%=8l]%$ [%s:%#] [%!] -> %v (+%ius)");
-
- // set the level of logger
- logger->set_level(level);
-
- // flush policy
-#ifdef DEBUG
- logger->flush_on(spdlog::level::trace);
-#else
- logger->flush_on(spdlog::level::err);
-#endif
-
- logger_map_[id] = logger;
- return logger;
-}
-
-auto LoggerManager::RegisterSyncLogger(const QString& id,
- spdlog::level::level_enum level)
- -> std::shared_ptr<spdlog::logger> {
- // get the log directory
- auto log_file_path =
- GlobalSettingStation::GetInstance().GetLogDir() + "/" + id + ".log";
-
- // sinks
- std::vector<spdlog::sink_ptr> sinks;
- sinks.push_back(GpgFrontend::SecureCreateSharedObject<
- spdlog::sinks::stderr_color_sink_mt>());
- sinks.push_back(GpgFrontend::SecureCreateSharedObject<
- spdlog::sinks::rotating_file_sink_mt>(
- log_file_path.toUtf8().constData(), 1048576 * 32, 8));
-
- // logger
- auto logger = GpgFrontend::SecureCreateSharedObject<spdlog::logger>(
- id.toStdString(), begin(sinks), end(sinks));
- logger->set_pattern(
- "[%H:%M:%S.%e] [T:%t] [%=6n] %^[%=8l]%$ [%s:%#] [%!] -> %v (+%ius)");
-
- // set the level of logger
- logger->set_level(level);
-
- logger_map_[id] = logger;
- return logger;
-}
-
-auto LoggerManager::GetDefaultLogger() -> std::shared_ptr<spdlog::logger> {
- if (default_logger == nullptr) {
- // sinks
- std::vector<spdlog::sink_ptr> sinks;
- sinks.push_back(GpgFrontend::SecureCreateSharedObject<
- spdlog::sinks::stderr_color_sink_mt>());
-
- // logger
- auto logger = GpgFrontend::SecureCreateSharedObject<spdlog::logger>(
- "default", begin(sinks), end(sinks));
- logger->set_pattern(
- "[%H:%M:%S.%e] [T:%t] [%=6n] %^[%=8l]%$ [%s:%#] [%!] -> %v (+%ius)");
-
- // set the level of logger
- logger->set_level(default_log_level);
- spdlog::set_default_logger(logger);
- default_logger = logger;
- }
- return default_logger;
-}
-
-void LoggerManager::SetDefaultLogLevel(spdlog::level::level_enum level) {
- default_log_level = level;
-}
-} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/LoggerManager.h b/src/core/function/LoggerManager.h
deleted file mode 100644
index 78fecc3c..00000000
--- a/src/core/function/LoggerManager.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric <[email protected]>
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend 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.
- *
- * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric <[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#pragma once
-
-#include "core/function/basic/GpgFunctionObject.h"
-
-namespace spdlog {
-class logger;
-}
-
-namespace GpgFrontend {
-
-class GPGFRONTEND_CORE_EXPORT LoggerManager
- : public SingletonFunctionObject<LoggerManager> {
- public:
- explicit LoggerManager(int channel);
-
- ~LoggerManager() override;
-
- auto RegisterAsyncLogger(const QString& id, spdlog::level::level_enum)
- -> std::shared_ptr<spdlog::logger>;
-
- auto RegisterSyncLogger(const QString& id, spdlog::level::level_enum)
- -> std::shared_ptr<spdlog::logger>;
-
- auto GetLogger(const QString& id) -> std::shared_ptr<spdlog::logger>;
-
- static auto GetDefaultLogger() -> std::shared_ptr<spdlog::logger>;
-
- static void SetDefaultLogLevel(spdlog::level::level_enum);
-
- private:
- static spdlog::level::level_enum default_log_level;
- static std::shared_ptr<spdlog::logger> default_logger;
-
- std::map<QString, std::shared_ptr<spdlog::logger>> logger_map_;
-};
-
-} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/SecureMemoryAllocator.cpp b/src/core/function/SecureMemoryAllocator.cpp
index fccd09fe..651e4085 100644
--- a/src/core/function/SecureMemoryAllocator.cpp
+++ b/src/core/function/SecureMemoryAllocator.cpp
@@ -28,36 +28,40 @@
#include "SecureMemoryAllocator.h"
-#if !defined(MACOS) && defined(DEBUG)
+#ifndef MACOS
+
#include <mimalloc.h>
-#endif
namespace GpgFrontend {
auto SecureMemoryAllocator::Allocate(std::size_t size) -> void* {
-#if !defined(MACOS) && defined(DEBUG)
auto* addr = mi_malloc(size);
-#else
- auto* addr = malloc(size);
-#endif
return addr;
}
auto SecureMemoryAllocator::Reallocate(void* ptr, std::size_t size) -> void* {
-#if !defined(MACOS) && defined(DEBUG)
auto* addr = mi_realloc(ptr, size);
+ return addr;
+}
+
+void SecureMemoryAllocator::Deallocate(void* p) { mi_free(p); }
+
#else
+
+namespace GpgFrontend {
+
+auto SecureMemoryAllocator::Allocate(std::size_t size) -> void* {
+ auto* addr = malloc(size);
+ return addr;
+}
+
+auto SecureMemoryAllocator::Reallocate(void* ptr, std::size_t size) -> void* {
auto* addr = realloc(ptr, size);
-#endif
return addr;
}
-void SecureMemoryAllocator::Deallocate(void* p) {
-#if !defined(MACOS) && defined(DEBUG)
- mi_free(p);
-#else
- free(p);
+void SecureMemoryAllocator::Deallocate(void* p) { free(p); }
+
#endif
-}
} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/SecureMemoryAllocator.h b/src/core/function/SecureMemoryAllocator.h
index e86d54d6..77295f53 100644
--- a/src/core/function/SecureMemoryAllocator.h
+++ b/src/core/function/SecureMemoryAllocator.h
@@ -29,7 +29,6 @@
#pragma once
#include "core/GpgFrontendCoreExport.h"
-#include "core/utils/LogUtils.h"
namespace GpgFrontend {
diff --git a/src/core/function/basic/ChannelObject.cpp b/src/core/function/basic/ChannelObject.cpp
index 18449ddb..1d9d60b5 100644
--- a/src/core/function/basic/ChannelObject.cpp
+++ b/src/core/function/basic/ChannelObject.cpp
@@ -39,7 +39,7 @@ ChannelObject::ChannelObject(int channel, QString type)
#ifdef DEBUG
ChannelObject::~ChannelObject() noexcept {
- // using iostream instead of spdlog bacause at this time spdlog may have
+ // using iostream instead of log bacause at this time log object may have
// already been destroyed.
QTextStream(stdout) << "releasing channel object: " << this->type_
<< Qt::endl;
diff --git a/src/core/function/basic/GpgFunctionObject.cpp b/src/core/function/basic/GpgFunctionObject.cpp
index e9e444f1..2e531c15 100644
--- a/src/core/function/basic/GpgFunctionObject.cpp
+++ b/src/core/function/basic/GpgFunctionObject.cpp
@@ -44,8 +44,8 @@ std::mutex g_function_object_mutex_map_lock;
std::map<size_t, FunctionObjectTypeLockInfo> g_function_object_mutex_map;
namespace GpgFrontend {
-auto GetGlobalFunctionObjectChannelLock(const std::type_info& type, int channel)
- -> std::mutex& {
+auto GetGlobalFunctionObjectChannelLock(const std::type_info& type,
+ int channel) -> std::mutex& {
std::lock_guard<std::mutex> lock_guard(g_function_object_mutex_map_lock);
auto& channel_map = g_function_object_mutex_map[type.hash_code()];
return channel_map.channel_lock_map[channel];
@@ -64,24 +64,17 @@ auto GetGlobalFunctionObjectTypeLock(const std::type_info& type)
* @param channel
* @return T&
*/
-auto GetChannelObjectInstance(const std::type_info& type, int channel)
- -> ChannelObject* {
- GF_DEFAULT_LOG_TRACE("try to get instance of type: {} at channel: {}",
- type.name(), channel);
-
+auto GetChannelObjectInstance(const std::type_info& type,
+ int channel) -> ChannelObject* {
// lock this channel
std::lock_guard<std::mutex> guard(
GetGlobalFunctionObjectChannelLock(type, channel));
auto* p_storage =
SingletonStorageCollection::GetInstance(false)->GetSingletonStorage(type);
- GF_DEFAULT_LOG_TRACE("get singleton storage result, p_storage: {}",
- static_cast<void*>(p_storage));
auto* p_pbj =
static_cast<ChannelObject*>(p_storage->FindObjectInChannel(channel));
- GF_DEFAULT_LOG_TRACE("find channel object result, channel {}, p_pbj: {}",
- channel, static_cast<void*>(p_pbj));
return p_pbj;
}
@@ -95,8 +88,6 @@ auto CreateChannelObjectInstance(const std::type_info& type, int channel,
auto* p_storage =
SingletonStorageCollection::GetInstance(false)->GetSingletonStorage(type);
- GF_DEFAULT_LOG_TRACE("create channel object, channel {}, type: {}", channel,
- type.name());
// do create object of this channel
return p_storage->SetObjectInChannel(channel, std::move(channel_object));
diff --git a/src/core/function/basic/SingletonStorage.cpp b/src/core/function/basic/SingletonStorage.cpp
index eab71e0f..fd583820 100644
--- a/src/core/function/basic/SingletonStorage.cpp
+++ b/src/core/function/basic/SingletonStorage.cpp
@@ -53,8 +53,7 @@ class SingletonStorage::Impl {
std::shared_lock<std::shared_mutex> lock(instances_mutex_);
ins_it = instances_map_.find(channel);
if (ins_it == instances_map_.end()) {
- GF_DEFAULT_LOG_TRACE("cannot find channel object, channel: {}",
- channel);
+ qCDebug(core, "cannot find channel object, channel: %d", channel);
return nullptr;
}
return ins_it->second.get();
@@ -72,14 +71,14 @@ class SingletonStorage::Impl {
auto SetObjectInChannel(int channel, ChannelObjectPtr p_obj)
-> GpgFrontend::ChannelObject* {
- GF_DEFAULT_LOG_TRACE(
- "set channel object, type: {} in channel: {}, address: {}",
- typeid(p_obj.get()).name(), channel, static_cast<void*>(p_obj.get()));
+ qCDebug(core, "set channel object, type: %s in channel: %d, address: %p",
+ typeid(p_obj.get()).name(), channel,
+ static_cast<void*>(p_obj.get()));
assert(p_obj != nullptr);
if (p_obj == nullptr) {
- GF_DEFAULT_LOG_ERROR(
- "cannot set a nullptr as a channel obejct of channel: {}", channel);
+ qCWarning(core, "cannot set a nullptr as a channel object of channel: %d",
+ channel);
return nullptr;
}
@@ -87,17 +86,16 @@ class SingletonStorage::Impl {
auto* raw_obj = p_obj.get();
{
- GF_DEFAULT_LOG_TRACE(
- "register channel object to instances map, "
- "channel: {}, address: {}",
- channel, static_cast<void*>(p_obj.get()));
+ qCDebug(core,
+ "register channel object to instances map, "
+ "channel: %d, address: %p",
+ channel, static_cast<void*>(p_obj.get()));
std::unique_lock<std::shared_mutex> lock(instances_mutex_);
instances_map_[channel] = std::move(p_obj);
}
- GF_DEFAULT_LOG_TRACE(
- "set channel: {} success, current channel object address: {}", channel,
- static_cast<void*>(raw_obj));
+ qCDebug(core, "set channel: %d success, current channel object address: %p",
+ channel, static_cast<void*>(raw_obj));
return raw_obj;
}
diff --git a/src/core/function/basic/SingletonStorageCollection.cpp b/src/core/function/basic/SingletonStorageCollection.cpp
index c22b5242..1eee087a 100644
--- a/src/core/function/basic/SingletonStorageCollection.cpp
+++ b/src/core/function/basic/SingletonStorageCollection.cpp
@@ -49,9 +49,9 @@ class SingletonStorageCollection::Impl {
static auto GetInstance(bool force_refresh) -> SingletonStorageCollection* {
if (force_refresh || global_instance == nullptr) {
global_instance = SecureCreateUniqueObject<SingletonStorageCollection>();
- GF_DEFAULT_LOG_TRACE(
- "a new global singleton storage collection created, address: {}",
- static_cast<void*>(global_instance.get()));
+ qCDebug(core,
+ "a new global singleton storage collection created, address: %p",
+ static_cast<void*>(global_instance.get()));
}
return global_instance.get();
}
@@ -80,10 +80,6 @@ class SingletonStorageCollection::Impl {
}
if (ins_it == storages_map_.end()) {
auto storage = SecureCreateUniqueObject<SingletonStorage>();
- GF_DEFAULT_LOG_TRACE(
- "hash: {} created, singleton storage address: {} type_name: {}",
- hash, static_cast<void*>(storage.get()), type_id.name());
-
{
std::unique_lock<std::shared_mutex> lock(storages_mutex_);
storages_map_.insert({hash, std::move(storage)});
@@ -110,8 +106,9 @@ auto GpgFrontend::SingletonStorageCollection::GetInstance(bool force_refresh)
}
void SingletonStorageCollection::Destroy() {
- GF_DEFAULT_LOG_TRACE(
- "global singleton storage collection is about to destroy, address: {}",
+ qCDebug(
+ core,
+ "global singleton storage collection is about to destroy, address: %p",
static_cast<void*>(global_instance.get()));
return SingletonStorageCollection::Impl::Destroy();
}
diff --git a/src/core/function/gpg/GpgAdvancedOperator.cpp b/src/core/function/gpg/GpgAdvancedOperator.cpp
index cb8fec00..18b38460 100644
--- a/src/core/function/gpg/GpgAdvancedOperator.cpp
+++ b/src/core/function/gpg/GpgAdvancedOperator.cpp
@@ -39,10 +39,9 @@ void GpgFrontend::GpgAdvancedOperator::ClearGpgPasswordCache(
OperationCallback cb) {
const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
"core", "gpgme.ctx.gpgconf_path", QString{});
- GF_CORE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path);
if (gpgconf_path.isEmpty()) {
- GF_CORE_LOG_ERROR("cannot get valid gpgconf path from rt, abort.");
+ qCWarning(core, "cannot get valid gpgconf path from rt, abort.");
cb(-1, TransferParams());
return;
}
@@ -51,7 +50,6 @@ void GpgFrontend::GpgAdvancedOperator::ClearGpgPasswordCache(
{gpgconf_path, QStringList{"--reload", "gpg-agent"},
[=](int exit_code, const QString & /*p_out*/,
const QString & /*p_err*/) {
- GF_CORE_LOG_DEBUG("gpgconf reload exit code: {}", exit_code);
cb(exit_code == 0 ? 0 : -1, TransferParams());
}});
}
@@ -60,10 +58,9 @@ void GpgFrontend::GpgAdvancedOperator::ReloadGpgComponents(
OperationCallback cb) {
const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
"core", "gpgme.ctx.gpgconf_path", QString{});
- GF_CORE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path);
if (gpgconf_path.isEmpty()) {
- GF_CORE_LOG_ERROR("cannot get valid gpgconf path from rt, abort.");
+ qCWarning(core, "cannot get valid gpgconf path from rt, abort.");
cb(-1, TransferParams());
return;
}
@@ -71,7 +68,7 @@ void GpgFrontend::GpgAdvancedOperator::ReloadGpgComponents(
GpgFrontend::GpgCommandExecutor::ExecuteSync(
{gpgconf_path, QStringList{"--reload"},
[=](int exit_code, const QString &, const QString &) {
- GF_CORE_LOG_DEBUG("gpgconf reload exit code: {}", exit_code);
+ qCDebug(core, "gpgconf reload exit code: %d", exit_code);
cb(exit_code == 0 ? 0 : -1, TransferParams());
}});
}
@@ -79,59 +76,53 @@ void GpgFrontend::GpgAdvancedOperator::ReloadGpgComponents(
void GpgFrontend::GpgAdvancedOperator::KillAllGpgComponents() {
const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
"core", "gpgme.ctx.gpgconf_path", QString{});
- GF_CORE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path);
if (gpgconf_path.isEmpty()) {
- GF_CORE_LOG_ERROR("cannot get valid gpgconf path from rt, abort.");
+ qCWarning(core, "cannot get valid gpgconf path from rt, abort.");
return;
}
GpgFrontend::GpgCommandExecutor::ExecuteSync(
{gpgconf_path, QStringList{"--verbose", "--kill", "all"},
[=](int exit_code, const QString &p_out, const QString &p_err) {
- GF_CORE_LOG_DEBUG("gpgconf --kill all command got exit code: {}",
- exit_code);
bool success = true;
if (exit_code != 0) {
success = false;
- GF_CORE_LOG_ERROR(
- "gpgconf execute error, process stderr: {}, process stdout: {}",
- p_err, p_out);
+ qCWarning(core) << "gpgconf execute error, process stderr: " << p_err
+ << ", process stdout: " << p_out;
return;
}
- GF_CORE_LOG_DEBUG("gpgconf --kill --all execute result: {}", success);
+ qCDebug(core, "gpgconf --kill --all execute result: %d", success);
}});
}
void GpgFrontend::GpgAdvancedOperator::RestartGpgComponents() {
const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
"core", "gpgme.ctx.gpgconf_path", QString{});
- GF_CORE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path);
if (gpgconf_path.isEmpty()) {
- GF_CORE_LOG_ERROR("cannot get valid gpgconf path from rt, abort.");
+ qCWarning(core, "cannot get valid gpgconf path from rt, abort.");
return;
}
GpgFrontend::GpgCommandExecutor::ExecuteSync(
{gpgconf_path, QStringList{"--verbose", "--kill", "all"},
[=](int exit_code, const QString &p_out, const QString &p_err) {
- GF_CORE_LOG_DEBUG("gpgconf --kill all command got exit code: {}",
- exit_code);
+ qCDebug(core, "gpgconf --kill all command got exit code: %d",
+ exit_code);
bool success = true;
if (exit_code != 0) {
success = false;
- GF_CORE_LOG_ERROR(
- "gpgconf execute error, process stderr: {}, process stdout: {}",
- p_err, p_out);
+ qCWarning(core) << "gpgconf execute error, process stderr: " << p_err
+ << ", process stdout: " << p_out;
return;
}
- GF_CORE_LOG_DEBUG("gpgconf --kill --all execute result: {}", success);
+ qCDebug(core, "gpgconf --kill --all execute result: %d", success);
if (!success) {
- GF_CORE_LOG_ERROR(
- "restart all component after core initilized failed");
+ qCWarning(core,
+ "restart all component after core initilized failed");
Module::UpsertRTValue(
"core", "gpg_advanced_operator.restart_gpg_components", false);
return;
@@ -150,10 +141,9 @@ void GpgFrontend::GpgAdvancedOperator::RestartGpgComponents() {
void GpgFrontend::GpgAdvancedOperator::ResetConfigures(OperationCallback cb) {
const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
"core", "gpgme.ctx.gpgconf_path", QString{});
- GF_CORE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path);
if (gpgconf_path.isEmpty()) {
- GF_CORE_LOG_ERROR("cannot get valid gpgconf path from rt, abort.");
+ qCWarning(core, "cannot get valid gpgconf path from rt, abort.");
cb(-1, TransferParams());
return;
}
@@ -161,7 +151,7 @@ void GpgFrontend::GpgAdvancedOperator::ResetConfigures(OperationCallback cb) {
GpgFrontend::GpgCommandExecutor::ExecuteSync(
{gpgconf_path, QStringList{"--apply-defaults"},
[=](int exit_code, const QString &, const QString &) {
- GF_CORE_LOG_DEBUG("gpgconf apply-defaults exit code: {}", exit_code);
+ qCDebug(core, "gpgconf apply-defaults exit code: %d", exit_code);
cb(exit_code == 0 ? 0 : -1, TransferParams());
}});
}
@@ -174,14 +164,12 @@ void GpgFrontend::GpgAdvancedOperator::StartGpgAgent(OperationCallback cb) {
const auto gpg_agent_path = Module::RetrieveRTValueTypedOrDefault<>(
kGnuPGInfoGatheringModuleID, "gnupg.gpg_agent_path", QString{});
- GF_CORE_LOG_DEBUG("got gnupg agent path from rt: {}", gpg_agent_path);
const auto home_path = Module::RetrieveRTValueTypedOrDefault<>(
kGnuPGInfoGatheringModuleID, "gnupg.home_path", QString{});
- GF_CORE_LOG_DEBUG("got gnupg home path from rt: {}", home_path);
if (gpg_agent_path.isEmpty()) {
- GF_CORE_LOG_ERROR("cannot get valid gpg agent path from rt, abort.");
+ qCWarning(core, "cannot get valid gpg agent path from rt, abort.");
cb(-1, TransferParams());
return;
}
@@ -189,7 +177,7 @@ void GpgFrontend::GpgAdvancedOperator::StartGpgAgent(OperationCallback cb) {
GpgFrontend::GpgCommandExecutor::ExecuteSync(
{gpg_agent_path, QStringList{"--homedir", home_path, "--daemon"},
[=](int exit_code, const QString &, const QString &) {
- GF_CORE_LOG_DEBUG("gpgconf daemon exit code: {}", exit_code);
+ qCDebug(core, "gpgconf daemon exit code: %d", exit_code);
cb(exit_code >= 0 ? 0 : -1, TransferParams());
}});
}
@@ -202,14 +190,12 @@ void GpgFrontend::GpgAdvancedOperator::StartDirmngr(OperationCallback cb) {
const auto dirmngr_path = Module::RetrieveRTValueTypedOrDefault<>(
kGnuPGInfoGatheringModuleID, "gnupg.dirmngr_path", QString{});
- GF_CORE_LOG_DEBUG("got gnupg dirmngr path from rt: {}", dirmngr_path);
const auto home_path = Module::RetrieveRTValueTypedOrDefault<>(
kGnuPGInfoGatheringModuleID, "gnupg.home_path", QString{});
- GF_CORE_LOG_DEBUG("got gnupg home path from rt: {}", home_path);
if (dirmngr_path.isEmpty()) {
- GF_CORE_LOG_ERROR("cannot get valid dirmngr path from rt, abort.");
+ qCWarning(core, "cannot get valid dirmngr path from rt, abort.");
cb(-1, TransferParams());
return;
}
@@ -217,7 +203,7 @@ void GpgFrontend::GpgAdvancedOperator::StartDirmngr(OperationCallback cb) {
GpgFrontend::GpgCommandExecutor::ExecuteSync(
{dirmngr_path, QStringList{"--homedir", home_path, "--daemon"},
[=](int exit_code, const QString &, const QString &) {
- GF_CORE_LOG_DEBUG("gpgconf daemon exit code: {}", exit_code);
+ qCDebug(core, "gpgconf daemon exit code: %d", exit_code);
cb(exit_code >= 0 ? 0 : -1, TransferParams());
}});
}
@@ -230,14 +216,12 @@ void GpgFrontend::GpgAdvancedOperator::StartKeyBoxd(OperationCallback cb) {
const auto keyboxd_path = Module::RetrieveRTValueTypedOrDefault<>(
kGnuPGInfoGatheringModuleID, "gnupg.keyboxd_path", QString{});
- GF_CORE_LOG_DEBUG("got gnupg keyboxd path from rt: {}", keyboxd_path);
const auto home_path = Module::RetrieveRTValueTypedOrDefault<>(
kGnuPGInfoGatheringModuleID, "gnupg.home_path", QString{});
- GF_CORE_LOG_DEBUG("got gnupg home path from rt: {}", home_path);
if (keyboxd_path.isEmpty()) {
- GF_CORE_LOG_ERROR("cannot get valid keyboxd path from rt, abort.");
+ qCWarning(core, "cannot get valid keyboxd path from rt, abort.");
cb(-1, TransferParams());
return;
}
@@ -245,7 +229,7 @@ void GpgFrontend::GpgAdvancedOperator::StartKeyBoxd(OperationCallback cb) {
GpgFrontend::GpgCommandExecutor::ExecuteSync(
{keyboxd_path, QStringList{"--homedir", home_path, "--daemon"},
[=](int exit_code, const QString &, const QString &) {
- GF_CORE_LOG_DEBUG("gpgconf daemon exit code: {}", exit_code);
+ qCDebug(core, "gpgconf daemon exit code: %d", exit_code);
cb(exit_code >= 0 ? 0 : -1, TransferParams());
}});
}
diff --git a/src/core/function/gpg/GpgBasicOperator.cpp b/src/core/function/gpg/GpgBasicOperator.cpp
index 8b62aad0..d7106a33 100644
--- a/src/core/function/gpg/GpgBasicOperator.cpp
+++ b/src/core/function/gpg/GpgBasicOperator.cpp
@@ -251,10 +251,9 @@ void GpgBasicOperator::Sign(const KeyArgsList& signers,
cb, "gpgme_op_sign", "2.1.0");
}
-auto GpgBasicOperator::SignSync(const KeyArgsList& signers,
- const GFBuffer& in_buffer, GpgSignMode mode,
- bool ascii)
- -> std::tuple<GpgError, DataObjectPtr> {
+auto GpgBasicOperator::SignSync(
+ const KeyArgsList& signers, const GFBuffer& in_buffer, GpgSignMode mode,
+ bool ascii) -> std::tuple<GpgError, DataObjectPtr> {
return RunGpgOperaSync(
[=](const DataObjectPtr& data_object) -> GpgError {
if (signers.empty()) return GPG_ERR_CANCELED;
@@ -391,15 +390,14 @@ void GpgBasicOperator::SetSigners(const KeyArgsList& signers, bool ascii) {
gpgme_signers_clear(ctx);
for (const GpgKey& key : signers) {
- GF_CORE_LOG_DEBUG("key fpr: {}", key.GetFingerprint());
+ qCDebug(core) << "signer's key fpr: " << key.GetFingerprint();
if (key.IsHasActualSigningCapability()) {
- GF_CORE_LOG_DEBUG("signer");
auto error = gpgme_signers_add(ctx, gpgme_key_t(key));
CheckGpgError(error);
}
}
if (signers.size() != gpgme_signers_count(ctx_.DefaultContext()))
- GF_CORE_LOG_DEBUG("not all signers added");
+ qCDebug(core, "not all signers added");
}
auto GpgBasicOperator::GetSigners(bool ascii) -> std::unique_ptr<KeyArgsList> {
diff --git a/src/core/function/gpg/GpgCommandExecutor.cpp b/src/core/function/gpg/GpgCommandExecutor.cpp
index 66c18ae1..5e0f3826 100644
--- a/src/core/function/gpg/GpgCommandExecutor.cpp
+++ b/src/core/function/gpg/GpgCommandExecutor.cpp
@@ -27,6 +27,8 @@
*/
#include "GpgCommandExecutor.h"
+#include <qglobal.h>
+
#include "core/model/DataObject.h"
#include "core/module/Module.h"
#include "core/thread/Task.h"
@@ -41,18 +43,14 @@ auto BuildTaskFromExecCtx(const GpgCommandExecutor::ExecuteContext &context)
const auto &interact_function = context.int_func;
const auto &cmd_executor_callback = context.cb_func;
- const QString joined_argument = arguments.join(" ");
-
- GF_CORE_LOG_DEBUG("building task: called cmd {} arguments size: {}", cmd,
- arguments.size());
-
Thread::Task::TaskCallback result_callback =
- [cmd, joined_argument](int /*rtn*/, const DataObjectPtr &data_object) {
- GF_CORE_LOG_DEBUG(
- "data object args count of cmd executor result callback: {}",
- data_object->GetObjectSize());
+ [cmd](int /*rtn*/, const DataObjectPtr &data_object) {
+ qCDebug(core,
+ "data object args count of cmd executor result callback: %ld",
+ data_object->GetObjectSize());
+
if (!data_object->Check<int, QString, GpgCommandExecutorCallback>()) {
- GF_CORE_LOG_ERROR("data object checking failed");
+ qCWarning(core, "data object checking failed");
return;
}
@@ -61,22 +59,17 @@ auto BuildTaskFromExecCtx(const GpgCommandExecutor::ExecuteContext &context)
auto callback =
ExtractParams<GpgCommandExecutorCallback>(data_object, 2);
- // call callback
- GF_CORE_LOG_DEBUG(
- "calling custom callback from caller of cmd {} {}, "
- "exit_code: {}",
- cmd, joined_argument, exit_code);
callback(exit_code, process_stdout, {});
};
Thread::Task::TaskRunnable runner =
- [joined_argument](const DataObjectPtr &data_object) -> int {
- GF_CORE_LOG_DEBUG("process runner called, data object size: {}",
- data_object->GetObjectSize());
+ [](const DataObjectPtr &data_object) -> int {
+ qCDebug(core, "process runner called, data object size: %lu",
+ data_object->GetObjectSize());
if (!data_object->Check<QString, QStringList, GpgCommandExecutorInteractor,
GpgCommandExecutorCallback>()) {
- GF_CORE_LOG_ERROR("data object checking failed");
+ qCWarning(core, "data object checking failed");
return -1;
}
@@ -86,6 +79,7 @@ auto BuildTaskFromExecCtx(const GpgCommandExecutor::ExecuteContext &context)
auto interact_func =
ExtractParams<GpgCommandExecutorInteractor>(data_object, 2);
auto callback = ExtractParams<GpgCommandExecutorCallback>(data_object, 3);
+ const QString joined_argument = arguments.join(" ");
// create process
auto *cmd_process = new QProcess();
@@ -106,26 +100,23 @@ auto BuildTaskFromExecCtx(const GpgCommandExecutor::ExecuteContext &context)
QObject::connect(
cmd_process, &QProcess::started, [cmd, joined_argument]() -> void {
- GF_CORE_LOG_DEBUG(
- "\n== Process Execute Started ==\nCommand: {}\nArguments: "
- "{}\n========================",
- cmd, joined_argument);
+ qCDebug(core) << "\n== Process Execute Started ==\nCommand: " << cmd
+ << "\nArguments: " << joined_argument
+ << " \n========================";
});
QObject::connect(
cmd_process, &QProcess::readyReadStandardOutput,
[interact_func, cmd_process]() { interact_func(cmd_process); });
- QObject::connect(
- cmd_process, &QProcess::errorOccurred,
- [=](QProcess::ProcessError error) {
- GF_CORE_LOG_ERROR(
- "caught error while executing command: {} {}, error: {}", cmd,
- joined_argument, error);
- });
+ QObject::connect(cmd_process, &QProcess::errorOccurred,
+ [=](QProcess::ProcessError error) {
+ qCWarning(core)
+ << "caught error while executing command: " << cmd
+ << joined_argument << ", error:" << error;
+ });
- GF_CORE_LOG_DEBUG(
- "\n== Process Execute Ready ==\nCommand: {}\nArguments: "
- "{}\n========================",
- cmd, joined_argument);
+ qCDebug(core) << "\n== Process Execute Ready ==\nCommand: " << cmd
+ << "\nArguments: " << joined_argument
+ << "\n========================";
cmd_process->start();
cmd_process->waitForFinished();
@@ -133,15 +124,13 @@ auto BuildTaskFromExecCtx(const GpgCommandExecutor::ExecuteContext &context)
QString process_stdout = cmd_process->readAllStandardOutput();
int exit_code = cmd_process->exitCode();
- GF_CORE_LOG_DEBUG(
- "\n==== Process Execution Summary ====\n"
- "Command: {}\n"
- "Arguments: {}\n"
- "Exit Code: {}\n"
- "---- Standard Output ----\n"
- "{}\n"
- "===============================",
- cmd, joined_argument, exit_code, process_stdout);
+ qCDebug(core) << "\n==== Process Execution Summary ====\n"
+ << "Command: " << cmd << "\n"
+ << "Arguments: " << joined_argument << "\n"
+ << "Exit Code: " << exit_code << "\n"
+ << "---- Standard Output ----\n"
+ << process_stdout << "\n"
+ << "===============================";
cmd_process->close();
cmd_process->deleteLater();
@@ -177,7 +166,7 @@ void GpgCommandExecutor::ExecuteSync(ExecuteContext context) {
// to arvoid dead lock issue we need to check if current thread is the same as
// target thread. if it is, we can't call exec() because it will block the
// current thread.
- GF_CORE_LOG_TRACE("blocking until gpg command finish...");
+ qCDebug(core, "blocking until gpg command finish...");
// block until task finished
// this is to keep reference vaild until task finished
looper.exec();
@@ -185,9 +174,6 @@ void GpgCommandExecutor::ExecuteSync(ExecuteContext context) {
void GpgCommandExecutor::ExecuteConcurrentlyAsync(ExecuteContexts contexts) {
for (auto &context : contexts) {
- const auto &cmd = context.cmd;
- GF_CORE_LOG_INFO("gpg concurrently called cmd {}", cmd);
-
Thread::Task *task = BuildTaskFromExecCtx(context);
if (context.task_runner != nullptr) {
@@ -208,15 +194,15 @@ void GpgCommandExecutor::ExecuteConcurrentlySync(ExecuteContexts contexts) {
for (auto &context : contexts) {
const auto &cmd = context.cmd;
- GF_CORE_LOG_DEBUG("gpg concurrently called cmd: {}", cmd);
+ qCDebug(core) << "gpg concurrently called cmd: " << cmd;
Thread::Task *task = BuildTaskFromExecCtx(context);
QObject::connect(task, &Thread::Task::SignalTaskEnd, [&]() {
--remaining_tasks;
- GF_CORE_LOG_DEBUG("remaining tasks: {}", remaining_tasks);
+ qCDebug(core, "remaining tasks: %lld", remaining_tasks);
if (remaining_tasks <= 0) {
- GF_CORE_LOG_DEBUG("no remaining task, quit");
+ qCDebug(core, "no remaining task, quit");
looper.quit();
}
});
@@ -232,7 +218,7 @@ void GpgCommandExecutor::ExecuteConcurrentlySync(ExecuteContexts contexts) {
target_task_runner->PostTask(task);
}
- GF_CORE_LOG_TRACE("blocking until concurrent gpg commands finish...");
+ qCDebug(core, "blocking until concurrent gpg commands finish...");
// block until task finished
// this is to keep reference vaild until task finished
looper.exec();
diff --git a/src/core/function/gpg/GpgContext.cpp b/src/core/function/gpg/GpgContext.cpp
index 7dec318e..75e97e0c 100644
--- a/src/core/function/gpg/GpgContext.cpp
+++ b/src/core/function/gpg/GpgContext.cpp
@@ -32,6 +32,7 @@
#include <gpgme.h>
#include <cassert>
+#include <cstddef>
#include <mutex>
#include "core/function/CoreSignalStation.h"
@@ -77,8 +78,8 @@ class GpgContext::Impl {
[[nodiscard]] auto Good() const -> bool { return good_; }
- auto SetPassphraseCb(const gpgme_ctx_t &ctx, gpgme_passphrase_cb_t cb)
- -> bool {
+ auto SetPassphraseCb(const gpgme_ctx_t &ctx,
+ gpgme_passphrase_cb_t cb) -> bool {
if (gpgme_get_pinentry_mode(ctx) != GPGME_PINENTRY_MODE_LOOPBACK) {
if (CheckGpgError(gpgme_set_pinentry_mode(
ctx, GPGME_PINENTRY_MODE_LOOPBACK)) != GPG_ERR_NO_ERROR) {
@@ -92,31 +93,24 @@ class GpgContext::Impl {
static auto TestPassphraseCb(void *opaque, const char *uid_hint,
const char *passphrase_info, int last_was_bad,
int fd) -> gpgme_error_t {
- size_t res;
-#ifdef QT5_BUILD
- QString pass_qstr = "abcdefg\n";
- QByteArray pass = pass_qstr.toUtf8();
-#else
- QString pass = "abcdefg\n";
-#endif
-
- auto passpahrase_size = pass.size();
- size_t off = 0;
-
- do {
-#ifdef QT5_BUILD
- const char *p_pass = pass.data();
- res = gpgme_io_write(fd, &p_pass[off], passpahrase_size - off);
-#else
- res = gpgme_io_write(fd, &pass[off], passpahrase_size - off);
-#endif
- if (res > 0) off += res;
- } while (res > 0 && off != passpahrase_size);
+ QString passphrase = "abcdefg";
+ auto pass_bytes = passphrase.toLatin1();
+ auto pass_size = pass_bytes.size();
+ const auto *p_pass_bytes = pass_bytes.constData();
+
+ ssize_t res = 0;
+ if (pass_size > 0) {
+ ssize_t off = 0;
+ ssize_t ret = 0;
+ do {
+ ret = gpgme_io_write(fd, &p_pass_bytes[off], pass_size - off);
+ if (ret > 0) off += ret;
+ } while (ret > 0 && off != pass_size);
+ res = off;
+ }
res += gpgme_io_write(fd, "\n", 1);
- return res == passpahrase_size + 1
- ? 0
- : gpgme_error_from_errno(GPG_ERR_CANCELED);
+ return res == pass_size + 1 ? 0 : gpgme_error_from_errno(GPG_ERR_CANCELED);
}
static auto CustomPassphraseCb(void *hook, const char *uid_hint,
@@ -130,47 +124,54 @@ class GpgContext::Impl {
passphrase_info != nullptr ? passphrase_info : "",
prev_was_bad != 0, ask_for_new));
- GF_CORE_LOG_DEBUG(
- "custom passphrase cb called, uid: {}, info: {}, last_was_bad: {}",
- uid_hint == nullptr ? "<empty>" : QString{uid_hint},
- passphrase_info == nullptr ? "<empty>" : QString{passphrase_info},
- prev_was_bad);
+ qCDebug(core) << "custom passphrase cb called, uid: "
+ << (uid_hint == nullptr ? "<empty>" : QString{uid_hint})
+ << ", info: "
+ << (passphrase_info == nullptr ? "<empty>"
+ : QString{passphrase_info})
+ << ", last_was_bad: " << prev_was_bad;
QEventLoop looper;
- QObject::connect(CoreSignalStation::GetInstance(),
- &CoreSignalStation::SignalUserInputPassphraseCallback,
- &looper, &QEventLoop::quit);
+ QString passphrase = "";
+
+ Module::TriggerEvent(
+ "REQUEST_PIN_ENTRY",
+ {{"uid_hint", uid_hint != nullptr ? uid_hint : ""},
+ {"passphrase_info", passphrase_info != nullptr ? passphrase_info : ""},
+ {"prev_was_bad", (prev_was_bad != 0) ? "1" : "0"},
+ {"ask_for_new", ask_for_new ? "1" : "0"}},
+ [&passphrase, &looper](Module::EventIdentifier i,
+ Module::Event::ListenerIdentifier ei,
+ Module::Event::Params p) {
+ passphrase = p["passphrase"];
+ looper.quit();
+ });
- emit CoreSignalStation::GetInstance()->SignalNeedUserInputPassphrase(
- context);
looper.exec();
-
ResetCacheValue("PinentryContext");
- auto passphrase = context->GetPassphrase().toStdString();
- auto passpahrase_size = passphrase.size();
- GF_CORE_LOG_DEBUG("get passphrase from pinentry size: {}",
- passpahrase_size);
-
- size_t res = 0;
- if (passpahrase_size > 0) {
- size_t off = 0;
+
+ auto pass_bytes = passphrase.toLatin1();
+ auto pass_size = pass_bytes.size();
+ const auto *p_pass_bytes = pass_bytes.constData();
+
+ ssize_t res = 0;
+ if (pass_size > 0) {
+ ssize_t off = 0;
+ ssize_t ret = 0;
do {
- res = gpgme_io_write(fd, &passphrase[off], passpahrase_size - off);
- if (res > 0) off += res;
- } while (res > 0 && off != passpahrase_size);
+ ret = gpgme_io_write(fd, &p_pass_bytes[off], pass_size - off);
+ if (ret > 0) off += ret;
+ } while (ret > 0 && off != pass_size);
+ res = off;
}
res += gpgme_io_write(fd, "\n", 1);
-
- GF_CORE_LOG_DEBUG("custom passphrase cd is about to return, res: {}", res);
- return res == passpahrase_size + 1
- ? 0
- : gpgme_error_from_errno(GPG_ERR_CANCELED);
+ return res == pass_size + 1 ? 0 : gpgme_error_from_errno(GPG_ERR_CANCELED);
}
- static auto TestStatusCb(void *hook, const char *keyword, const char *args)
- -> gpgme_error_t {
- GF_CORE_LOG_DEBUG("keyword {}", keyword);
+ static auto TestStatusCb(void *hook, const char *keyword,
+ const char *args) -> gpgme_error_t {
+ qCDebug(core, "keyword %s", keyword);
return GPG_ERR_NO_ERROR;
}
@@ -188,10 +189,11 @@ class GpgContext::Impl {
const auto gpgme_version = Module::RetrieveRTValueTypedOrDefault<>(
"core", "gpgme.version", QString{"0.0.0"});
- GF_CORE_LOG_DEBUG("got gpgme version version from rt: {}", gpgme_version);
+ qCDebug(core) << "got gpgme version version from rt: " << gpgme_version;
if (gpgme_get_keylist_mode(ctx) == 0) {
- GF_CORE_LOG_ERROR(
+ qCWarning(
+ core,
"ctx is not a valid pointer, reported by gpgme_get_keylist_mode");
return false;
}
@@ -210,8 +212,8 @@ class GpgContext::Impl {
const auto database_path = Module::RetrieveRTValueTypedOrDefault<>(
"core", "gpgme.ctx.database_path", QString{});
- GF_CORE_LOG_DEBUG("ctx set engine info, db path: {}, app path: {}",
- database_path, app_path);
+ qCDebug(core) << "ctx set engine info, db path: " << database_path
+ << ", app path: " << app_path;
auto app_path_buffer = app_path.toUtf8();
auto database_path_buffer = database_path.toUtf8();
@@ -232,23 +234,22 @@ class GpgContext::Impl {
assert(ctx != nullptr);
if (args.custom_gpgconf && !args.custom_gpgconf_path.isEmpty()) {
- GF_CORE_LOG_DEBUG("set custom gpgconf path: {}",
- args.custom_gpgconf_path);
+ qCDebug(core) << "set custom gpgconf path: " << args.custom_gpgconf_path;
auto err =
gpgme_ctx_set_engine_info(ctx, GPGME_PROTOCOL_GPGCONF,
args.custom_gpgconf_path.toUtf8(), nullptr);
if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
- GF_CORE_LOG_ERROR("set gpg context engine info error: {}",
- DescribeGpgErrCode(err).second);
+ qCWarning(core) << "set gpg context engine info error: "
+ << DescribeGpgErrCode(err).second;
return false;
}
}
// set context offline mode
- GF_CORE_LOG_DEBUG("gpg context: offline mode: {}", args_.offline_mode);
- GF_CORE_LOG_DEBUG("gpg context: auto import missing key: {}",
- args_.auto_import_missing_key);
+ qCDebug(core, "gpg context: offline mode: %d", args_.offline_mode);
+ qCDebug(core, "gpg context: auto import missing key: %d",
+ args_.auto_import_missing_key);
gpgme_set_offline(ctx, args_.offline_mode ? 1 : 0);
// set option auto import missing key
@@ -260,19 +261,20 @@ class GpgContext::Impl {
}
if (!set_ctx_key_list_mode(ctx)) {
- GF_CORE_LOG_DEBUG("set ctx key list mode failed");
+ qCDebug(core, "set ctx key list mode failed");
return false;
}
// for unit test
if (args_.test_mode) {
if (!SetPassphraseCb(ctx, TestPassphraseCb)) {
- GF_CORE_LOG_ERROR("set passphrase cb failed, test");
+ qCWarning(core, "set passphrase cb failed, test");
return false;
};
- } else if (!args_.use_pinentry) {
+ } else if (!args_.use_pinentry &&
+ Module::IsModuleActivate(kPinentryModuleID)) {
if (!SetPassphraseCb(ctx, CustomPassphraseCb)) {
- GF_CORE_LOG_DEBUG("set passphrase cb failed, custom");
+ qCDebug(core, "set passphrase cb failed, custom");
return false;
}
}
@@ -283,7 +285,7 @@ class GpgContext::Impl {
}
if (!set_ctx_openpgp_engine_info(ctx)) {
- GF_CORE_LOG_ERROR("set gpgme context openpgp engine info failed");
+ qCWarning(core, "set gpgme context openpgp engine info failed");
return false;
}
@@ -293,15 +295,15 @@ class GpgContext::Impl {
auto binary_ctx_initialize(const GpgContextInitArgs &args) -> bool {
gpgme_ctx_t p_ctx;
if (auto err = CheckGpgError(gpgme_new(&p_ctx)); err != GPG_ERR_NO_ERROR) {
- GF_CORE_LOG_ERROR("get new gpg context error: {}",
- DescribeGpgErrCode(err).second);
+ qCWarning(core) << "get new gpg context error: "
+ << DescribeGpgErrCode(err).second;
return false;
}
assert(p_ctx != nullptr);
binary_ctx_ref_ = p_ctx;
if (!common_ctx_initialize(binary_ctx_ref_, args)) {
- GF_CORE_LOG_ERROR("get new ctx failed, binary");
+ qCWarning(core, "get new ctx failed, binary");
return false;
}
@@ -312,7 +314,7 @@ class GpgContext::Impl {
auto default_ctx_initialize(const GpgContextInitArgs &args) -> bool {
gpgme_ctx_t p_ctx;
if (CheckGpgError(gpgme_new(&p_ctx)) != GPG_ERR_NO_ERROR) {
- GF_CORE_LOG_ERROR("get new ctx failed, default");
+ qCWarning(core, "get new ctx failed, default");
return false;
}
assert(p_ctx != nullptr);
diff --git a/src/core/function/gpg/GpgContext.h b/src/core/function/gpg/GpgContext.h
index 2a8f6fdd..0fcf3e43 100644
--- a/src/core/function/gpg/GpgContext.h
+++ b/src/core/function/gpg/GpgContext.h
@@ -40,7 +40,7 @@ namespace GpgFrontend {
*
*/
struct GpgContextInitArgs {
- QString db_path = {}; ///<
+ QString db_path; ///<
bool test_mode = false; ///<
bool offline_mode = false; ///<
@@ -63,7 +63,7 @@ class GPGFRONTEND_CORE_EXPORT GpgContext
explicit GpgContext(GpgContextInitArgs args, int channel);
- virtual ~GpgContext() override;
+ ~GpgContext();
[[nodiscard]] auto Good() const -> bool;
diff --git a/src/core/function/gpg/GpgFileOpera.cpp b/src/core/function/gpg/GpgFileOpera.cpp
index ad506c4a..9ada4afa 100644
--- a/src/core/function/gpg/GpgFileOpera.cpp
+++ b/src/core/function/gpg/GpgFileOpera.cpp
@@ -69,10 +69,9 @@ void GpgFileOpera::EncryptFile(const KeyArgsList& keys, const QString& in_path,
cb, "gpgme_op_encrypt", "2.1.0");
}
-auto GpgFileOpera::EncryptFileSync(const KeyArgsList& keys,
- const QString& in_path, bool ascii,
- const QString& out_path)
- -> std::tuple<GpgError, DataObjectPtr> {
+auto GpgFileOpera::EncryptFileSync(
+ const KeyArgsList& keys, const QString& in_path, bool ascii,
+ const QString& out_path) -> std::tuple<GpgError, DataObjectPtr> {
return RunGpgOperaSync(
[=](const DataObjectPtr& data_object) -> GpgError {
std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
@@ -111,7 +110,7 @@ void GpgFileOpera::EncryptDirectory(const KeyArgsList& keys,
GpgData data_in(ex);
GpgData data_out(out_path, false);
- GF_CORE_LOG_DEBUG("encrypt directory start");
+ qCDebug(core, "encrypt directory start");
auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
auto err = CheckGpgError(gpgme_op_encrypt(ctx, recipients.data(),
@@ -119,15 +118,14 @@ void GpgFileOpera::EncryptDirectory(const KeyArgsList& keys,
data_in, data_out));
data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx))});
- GF_CORE_LOG_DEBUG("encrypt directory finished, err: {}", err);
+ qCDebug(core, "encrypt directory finished, err: %d", err);
return err;
},
cb, "gpgme_op_encrypt", "2.1.0");
ArchiveFileOperator::NewArchive2DataExchanger(
in_path, ex, [=](GFError err, const DataObjectPtr&) {
- GF_CORE_LOG_DEBUG("new archive 2 data exchanger operation, err: {}",
- err);
+ qCDebug(core, "new archive 2 data exchanger operation, err: %d", err);
if (decltype(ex) p_ex = w_ex.lock(); err < 0 && p_ex != nullptr) {
ex->CloseWrite();
}
@@ -176,8 +174,8 @@ void GpgFileOpera::DecryptArchive(const QString& in_path,
ArchiveFileOperator::ExtractArchiveFromDataExchanger(
ex, out_path, [](GFError err, const DataObjectPtr&) {
- GF_CORE_LOG_DEBUG(
- "extract archive from data exchanger operation, err: {}", err);
+ qCDebug(core, "extract archive from data exchanger operation, err: %d",
+ err);
});
RunGpgOperaAsync(
@@ -331,11 +329,10 @@ void GpgFileOpera::EncryptSignFile(const KeyArgsList& keys,
cb, "gpgme_op_encrypt_sign", "2.1.0");
}
-auto GpgFileOpera::EncryptSignFileSync(const KeyArgsList& keys,
- const KeyArgsList& signer_keys,
- const QString& in_path, bool ascii,
- const QString& out_path)
- -> std::tuple<GpgError, DataObjectPtr> {
+auto GpgFileOpera::EncryptSignFileSync(
+ const KeyArgsList& keys, const KeyArgsList& signer_keys,
+ const QString& in_path, bool ascii,
+ const QString& out_path) -> std::tuple<GpgError, DataObjectPtr> {
return RunGpgOperaSync(
[=](const DataObjectPtr& data_object) -> GpgError {
GpgError err;
@@ -399,7 +396,7 @@ void GpgFileOpera::EncryptSignDirectory(const KeyArgsList& keys,
ArchiveFileOperator::NewArchive2DataExchanger(
in_path, ex, [=](GFError err, const DataObjectPtr&) {
- GF_CORE_LOG_DEBUG("new archive 2 fd operation, err: {}", err);
+ qCDebug(core, "new archive 2 fd operation, err: %d", err);
if (decltype(ex) p_ex = w_ex.lock(); err < 0 && p_ex != nullptr) {
ex->CloseWrite();
}
@@ -459,7 +456,7 @@ void GpgFileOpera::DecryptVerifyArchive(const QString& in_path,
ArchiveFileOperator::ExtractArchiveFromDataExchanger(
ex, out_path, [](GFError err, const DataObjectPtr&) {
- GF_CORE_LOG_DEBUG("extract archive from ex operation, err: {}", err);
+ qCDebug(core, "extract archive from ex operation, err: %d", err);
});
RunGpgOperaAsync(
@@ -545,19 +542,18 @@ void GpgFileOpera::EncryptDerectorySymmetric(const QString& in_path, bool ascii,
ArchiveFileOperator::NewArchive2DataExchanger(
in_path, ex, [=](GFError err, const DataObjectPtr&) {
- GF_CORE_LOG_DEBUG("new archive 2 fd operation, err: {}", err);
+ qCDebug(core, "new archive 2 fd operation, err: %d", err);
});
}
-auto GpgFileOpera::EncryptDerectorySymmetricSync(const QString& in_path,
- bool ascii,
- const QString& out_path)
- -> std::tuple<GpgError, DataObjectPtr> {
+auto GpgFileOpera::EncryptDerectorySymmetricSync(
+ const QString& in_path, bool ascii,
+ const QString& out_path) -> std::tuple<GpgError, DataObjectPtr> {
auto ex = std::make_shared<GFDataExchanger>(kDataExchangerSize);
ArchiveFileOperator::NewArchive2DataExchanger(
in_path, ex, [=](GFError err, const DataObjectPtr&) {
- GF_CORE_LOG_DEBUG("new archive 2 fd operation, err: {}", err);
+ qCDebug(core, "new archive 2 fd operation, err: %d", err);
});
return RunGpgOperaSync(
diff --git a/src/core/function/gpg/GpgKeyGetter.cpp b/src/core/function/gpg/GpgKeyGetter.cpp
index 4a35d3cd..8b78b754 100644
--- a/src/core/function/gpg/GpgKeyGetter.cpp
+++ b/src/core/function/gpg/GpgKeyGetter.cpp
@@ -42,9 +42,7 @@ namespace GpgFrontend {
class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
public:
explicit Impl(int channel)
- : SingletonFunctionObject<GpgKeyGetter::Impl>(channel) {
- GF_CORE_LOG_DEBUG("called channel: {}", channel);
- }
+ : SingletonFunctionObject<GpgKeyGetter::Impl>(channel) {}
auto GetKey(const QString& fpr, bool use_cache) -> GpgKey {
// find in cache first
@@ -56,7 +54,8 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
gpgme_key_t p_key = nullptr;
gpgme_get_key(ctx_.DefaultContext(), fpr.toUtf8(), &p_key, 1);
if (p_key == nullptr) {
- GF_CORE_LOG_WARN("GpgKeyGetter GetKey Private _p_key Null fpr", fpr);
+ qCWarning(core) << "GpgKeyGetter GetKey Private _p_key Null, fpr: "
+ << fpr;
return GetPubkey(fpr, true);
}
return GpgKey(std::move(p_key));
@@ -72,7 +71,7 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
gpgme_key_t p_key = nullptr;
gpgme_get_key(ctx_.DefaultContext(), fpr.toUtf8(), &p_key, 0);
if (p_key == nullptr)
- GF_CORE_LOG_WARN("GpgKeyGetter GetKey _p_key Null", fpr);
+ qCWarning(core) << "GpgKeyGetter GetKey _p_key Null, fpr: " << fpr;
return GpgKey(std::move(p_key));
}
@@ -92,9 +91,23 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
return keys_list;
}
- auto FlushKeyCache() -> bool {
- GF_CORE_LOG_DEBUG("flush key channel called, channel: {}", GetChannel());
+ auto FetchGpgKeyList() -> GpgKeyList {
+ if (keys_search_cache_.empty()) {
+ FlushKeyCache();
+ }
+ auto keys_list = GpgKeyList{};
+ {
+ // get the lock
+ std::lock_guard<std::mutex> lock(keys_cache_mutex_);
+ for (const auto& key : keys_cache_) {
+ keys_list.push_back(key);
+ }
+ }
+ return keys_list;
+ }
+
+ auto FlushKeyCache() -> bool {
// clear the keys cache
keys_cache_.clear();
keys_search_cache_.clear();
@@ -129,17 +142,12 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
}
}
- GF_CORE_LOG_DEBUG("flush key channel cache address: {} object address: {}",
- static_cast<void*>(&keys_search_cache_),
- static_cast<void*>(this));
-
// for debug
assert(CheckGpgError2ErrCode(err, GPG_ERR_EOF) == GPG_ERR_EOF);
err = gpgme_op_keylist_end(ctx_.DefaultContext());
assert(CheckGpgError2ErrCode(err, GPG_ERR_EOF) == GPG_ERR_NO_ERROR);
- GF_CORE_LOG_DEBUG("flush key channel done, channel: {}", GetChannel());
return true;
}
@@ -165,6 +173,11 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
return keys_copy;
}
+ auto GetGpgKeyTableModel() -> QSharedPointer<GpgKeyTableModel> {
+ return SecureCreateQSharedObject<GpgKeyTableModel>(FetchGpgKeyList(),
+ nullptr);
+ }
+
private:
/**
* @brief Get the gpgme context object
@@ -218,9 +231,7 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
GpgKeyGetter::GpgKeyGetter(int channel)
: SingletonFunctionObject<GpgKeyGetter>(channel),
- p_(SecureCreateUniqueObject<Impl>(channel)) {
- GF_CORE_LOG_DEBUG("called channel: {}", channel);
-}
+ p_(SecureCreateUniqueObject<Impl>(channel)) {}
GpgKeyGetter::~GpgKeyGetter() = default;
@@ -248,4 +259,8 @@ auto GpgKeyGetter::GetKeysCopy(const KeyListPtr& keys) -> KeyListPtr {
auto GpgKeyGetter::FetchKey() -> KeyLinkListPtr { return p_->FetchKey(); }
+auto GpgKeyGetter::GetGpgKeyTableModel() -> QSharedPointer<GpgKeyTableModel> {
+ return p_->GetGpgKeyTableModel();
+}
+
} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgKeyGetter.h b/src/core/function/gpg/GpgKeyGetter.h
index 91138623..2c4c0706 100644
--- a/src/core/function/gpg/GpgKeyGetter.h
+++ b/src/core/function/gpg/GpgKeyGetter.h
@@ -29,6 +29,7 @@
#pragma once
#include "core/function/basic/GpgFunctionObject.h"
+#include "core/model/GpgKeyTableModel.h"
#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
@@ -106,6 +107,13 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
*/
auto GetKeysCopy(const KeyLinkListPtr& keys) -> KeyLinkListPtr;
+ /**
+ * @brief
+ *
+ * @return GpgKeyTableModel
+ */
+ auto GetGpgKeyTableModel() -> QSharedPointer<GpgKeyTableModel>;
+
private:
class Impl;
SecureUniquePtr<Impl> p_;
diff --git a/src/core/function/gpg/GpgKeyImportExporter.cpp b/src/core/function/gpg/GpgKeyImportExporter.cpp
index ef8cb112..b9875131 100644
--- a/src/core/function/gpg/GpgKeyImportExporter.cpp
+++ b/src/core/function/gpg/GpgKeyImportExporter.cpp
@@ -49,11 +49,11 @@ auto GpgKeyImportExporter::ImportKey(const GFBuffer& in_buffer)
if (in_buffer.Empty()) return {};
GpgData data_in(in_buffer);
- auto err = CheckGpgError(gpgme_op_import(ctx_.DefaultContext(), data_in));
+ auto err = CheckGpgError(gpgme_op_import(ctx_.BinaryContext(), data_in));
if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
gpgme_import_result_t result;
- result = gpgme_op_import_result(ctx_.DefaultContext());
+ result = gpgme_op_import_result(ctx_.BinaryContext());
gpgme_import_status_t status = result->imports;
auto import_info = SecureCreateSharedObject<GpgImportInformation>(result);
while (status != nullptr) {
@@ -91,11 +91,8 @@ auto GpgKeyImportExporter::ExportKey(const GpgKey& key, bool secret, bool ascii,
GpgData data_out;
auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
auto err = gpgme_op_export_keys(ctx, keys_array.data(), mode, data_out);
- if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
+ if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {err, {}};
- GF_CORE_LOG_DEBUG(
- "operation of exporting a key finished, ascii: {}, read_bytes: {}", ascii,
- gpgme_data_seek(data_out, 0, SEEK_END));
return {err, data_out.Read2GFBuffer()};
}
@@ -125,11 +122,7 @@ void GpgKeyImportExporter::ExportKeys(const KeyArgsList& keys, bool secret,
GpgData data_out;
auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
auto err = gpgme_op_export_keys(ctx, keys_array.data(), mode, data_out);
- if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
-
- GF_CORE_LOG_DEBUG(
- "operation of exporting keys finished, ascii: {}, read_bytes: {}",
- ascii, gpgme_data_seek(data_out, 0, SEEK_END));
+ if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return err;
data_object->Swap({data_out.Read2GFBuffer()});
return err;
@@ -159,11 +152,8 @@ void GpgKeyImportExporter::ExportAllKeys(const KeyArgsList& keys, bool secret,
GpgData data_out;
auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
auto err = gpgme_op_export_keys(ctx, keys_array.data(), mode, data_out);
- if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
+ if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return err;
- GF_CORE_LOG_DEBUG(
- "operation of exporting keys finished, ascii: {}, read_bytes: {}",
- ascii, gpgme_data_seek(data_out, 0, SEEK_END));
auto buffer = data_out.Read2GFBuffer();
if (secret) {
@@ -173,12 +163,8 @@ void GpgKeyImportExporter::ExportAllKeys(const KeyArgsList& keys, bool secret,
GpgData data_out_secret;
auto err = gpgme_op_export_keys(ctx, keys_array.data(), mode,
data_out_secret);
- if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
+ if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return err;
- GF_CORE_LOG_DEBUG(
- "operation of exporting secret keys finished, "
- "ascii: {}, read_bytes: {}",
- ascii, gpgme_data_seek(data_out_secret, 0, SEEK_END));
buffer.Append(data_out_secret.Read2GFBuffer());
}
diff --git a/src/core/function/gpg/GpgKeyManager.cpp b/src/core/function/gpg/GpgKeyManager.cpp
index b5efe141..93a864ca 100644
--- a/src/core/function/gpg/GpgKeyManager.cpp
+++ b/src/core/function/gpg/GpgKeyManager.cpp
@@ -73,10 +73,9 @@ auto GpgFrontend::GpgKeyManager::RevSign(
return true;
}
-auto GpgFrontend::GpgKeyManager::SetExpire(const GpgFrontend::GpgKey& key,
- std::unique_ptr<GpgSubKey>& subkey,
- std::unique_ptr<QDateTime>& expires)
- -> bool {
+auto GpgFrontend::GpgKeyManager::SetExpire(
+ const GpgFrontend::GpgKey& key, std::unique_ptr<GpgSubKey>& subkey,
+ std::unique_ptr<QDateTime>& expires) -> bool {
unsigned long expires_time = 0;
if (expires != nullptr) expires_time = expires->toSecsSinceEpoch();
@@ -95,81 +94,83 @@ auto GpgFrontend::GpgKeyManager::SetExpire(const GpgFrontend::GpgKey& key,
auto GpgFrontend::GpgKeyManager::SetOwnerTrustLevel(const GpgKey& key,
int trust_level) -> bool {
if (trust_level < 0 || trust_level > 5) {
- GF_CORE_LOG_ERROR("illegal owner trust level: {}", trust_level);
+ qCWarning(core, "illegal owner trust level: %d", trust_level);
}
- AutomatonNextStateHandler next_state_handler = [](AutomatonState state,
- QString status,
- QString args) {
- GF_CORE_LOG_DEBUG("next_state_handler state: {}, gpg_status: {}, args: {}",
- state, status, args);
- auto tokens = args.split(' ');
+ AutomatonNextStateHandler next_state_handler =
+ [](AutomatonState state, QString status, QString args) {
+ qCDebug(core) << "next_state_handler state: "
+ << static_cast<unsigned int>(state)
+ << ", gpg_status: " << status << ", args: " << args;
- switch (state) {
- case AS_START:
- if (status == "GET_LINE" && args == "keyedit.prompt") {
- return AS_COMMAND;
- }
- return AS_ERROR;
- case AS_COMMAND:
- if (status == "GET_LINE" && args == "edit_ownertrust.value") {
- return AS_VALUE;
- }
- return AS_ERROR;
- case AS_VALUE:
- if (status == "GET_LINE" && args == "keyedit.prompt") {
- return AS_QUIT;
- } else if (status == "GET_BOOL" &&
- args == "edit_ownertrust.set_ultimate.okay") {
- return AS_REALLY_ULTIMATE;
- }
- return AS_ERROR;
- case AS_REALLY_ULTIMATE:
- if (status == "GET_LINE" && args == "keyedit.prompt") {
- return AS_QUIT;
- }
- return AS_ERROR;
- case AS_QUIT:
- if (status == "GET_LINE" && args == "keyedit.save.okay") {
- return AS_SAVE;
- }
- return AS_ERROR;
- case AS_ERROR:
- if (status == "GET_LINE" && args == "keyedit.prompt") {
- return AS_QUIT;
- }
- return AS_ERROR;
- default:
- return AS_ERROR;
- };
- };
+ auto tokens = args.split(' ');
- AutomatonActionHandler action_handler =
- [trust_level](AutomatonHandelStruct& handler, AutomatonState state) {
- GF_CORE_LOG_DEBUG("action_handler state: {}", state);
switch (state) {
+ case AS_START:
+ if (status == "GET_LINE" && args == "keyedit.prompt") {
+ return AS_COMMAND;
+ }
+ return AS_ERROR;
case AS_COMMAND:
- return QString("trust");
+ if (status == "GET_LINE" && args == "edit_ownertrust.value") {
+ return AS_VALUE;
+ }
+ return AS_ERROR;
case AS_VALUE:
- handler.SetSuccess(true);
- return QString::number(trust_level);
+ if (status == "GET_LINE" && args == "keyedit.prompt") {
+ return AS_QUIT;
+ } else if (status == "GET_BOOL" &&
+ args == "edit_ownertrust.set_ultimate.okay") {
+ return AS_REALLY_ULTIMATE;
+ }
+ return AS_ERROR;
case AS_REALLY_ULTIMATE:
- handler.SetSuccess(true);
- return QString("Y");
+ if (status == "GET_LINE" && args == "keyedit.prompt") {
+ return AS_QUIT;
+ }
+ return AS_ERROR;
case AS_QUIT:
- return QString("quit");
- case AS_SAVE:
- handler.SetSuccess(true);
- return QString("Y");
- case AS_START:
+ if (status == "GET_LINE" && args == "keyedit.save.okay") {
+ return AS_SAVE;
+ }
+ return AS_ERROR;
case AS_ERROR:
- return QString("");
+ if (status == "GET_LINE" && args == "keyedit.prompt") {
+ return AS_QUIT;
+ }
+ return AS_ERROR;
default:
- return QString("");
- }
- return QString("");
+ return AS_ERROR;
+ };
};
+ AutomatonActionHandler action_handler = [trust_level](
+ AutomatonHandelStruct& handler,
+ AutomatonState state) {
+ qCDebug(core, "action_handler state: %d", static_cast<unsigned int>(state));
+ switch (state) {
+ case AS_COMMAND:
+ return QString("trust");
+ case AS_VALUE:
+ handler.SetSuccess(true);
+ return QString::number(trust_level);
+ case AS_REALLY_ULTIMATE:
+ handler.SetSuccess(true);
+ return QString("Y");
+ case AS_QUIT:
+ return QString("quit");
+ case AS_SAVE:
+ handler.SetSuccess(true);
+ return QString("Y");
+ case AS_START:
+ case AS_ERROR:
+ return QString("");
+ default:
+ return QString("");
+ }
+ return QString("");
+ };
+
auto key_fpr = key.GetFingerprint();
AutomatonHandelStruct handel_struct(key_fpr);
handel_struct.SetHandler(next_state_handler, action_handler);
@@ -185,21 +186,19 @@ auto GpgFrontend::GpgKeyManager::SetOwnerTrustLevel(const GpgKey& key,
auto GpgFrontend::GpgKeyManager::interactor_cb_fnc(void* handle,
const char* status,
- const char* args, int fd)
- -> gpgme_error_t {
+ const char* args,
+ int fd) -> gpgme_error_t {
auto* handle_struct = static_cast<AutomatonHandelStruct*>(handle);
QString status_s = status;
QString args_s = args;
- GF_CORE_LOG_DEBUG(
- "cb start status: {}, args: {}, fd: {}, handle struct state: {}",
- status_s, args_s, fd, handle_struct->CuurentStatus());
if (status_s == "KEY_CONSIDERED") {
auto tokens = QString(args).split(' ');
if (tokens.empty() || tokens[0] != handle_struct->KeyFpr()) {
- GF_CORE_LOG_ERROR("handle struct key fpr {} mismatch token: {}, exit...",
- handle_struct->KeyFpr(), tokens[0]);
+ qCWarning(core) << "handle struct key fpr " << handle_struct->KeyFpr()
+ << "mismatch token: " << tokens[0] << ", exit...";
+
return -1;
}
@@ -207,13 +206,13 @@ auto GpgFrontend::GpgKeyManager::interactor_cb_fnc(void* handle,
}
if (status_s == "GOT_IT" || status_s.isEmpty()) {
- GF_CORE_LOG_DEBUG("status GOT_IT, continue...");
+ qCDebug(core, "status GOT_IT, continue...");
return 0;
}
AutomatonState next_state = handle_struct->NextState(status_s, args_s);
if (next_state == AS_ERROR) {
- GF_CORE_LOG_DEBUG("handle struct next state caught error, skipping...");
+ qCDebug(core, "handle struct next state caught error, skipping...");
return GPG_ERR_FALSE;
}
@@ -224,8 +223,7 @@ auto GpgFrontend::GpgKeyManager::interactor_cb_fnc(void* handle,
// set state and preform action
handle_struct->SetStatus(next_state);
Command cmd = handle_struct->Action();
- GF_CORE_LOG_DEBUG("handle struct action done, next state: {}, action cmd: {}",
- next_state, cmd);
+
if (!cmd.isEmpty()) {
auto btye_array = cmd.toUtf8();
gpgme_io_write(fd, btye_array, btye_array.size());
diff --git a/src/core/function/gpg/GpgKeyManager.h b/src/core/function/gpg/GpgKeyManager.h
index 8b4d41b2..85dc6be5 100644
--- a/src/core/function/gpg/GpgKeyManager.h
+++ b/src/core/function/gpg/GpgKeyManager.h
@@ -105,7 +105,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager
AS_ERROR,
AS_QUIT,
};
-
+
struct AutomatonHandelStruct;
using AutomatonActionHandler =
diff --git a/src/core/function/gpg/GpgKeyOpera.cpp b/src/core/function/gpg/GpgKeyOpera.cpp
index 14d58a10..0205ea2f 100644
--- a/src/core/function/gpg/GpgKeyOpera.cpp
+++ b/src/core/function/gpg/GpgKeyOpera.cpp
@@ -61,7 +61,7 @@ void GpgKeyOpera::DeleteKeys(KeyIdArgsListPtr key_ids) {
GPGME_DELETE_ALLOW_SECRET | GPGME_DELETE_FORCE));
assert(gpg_err_code(err) == GPG_ERR_NO_ERROR);
} else {
- GF_CORE_LOG_WARN("GpgKeyOpera DeleteKeys get key failed", tmp);
+ qCWarning(core) << "GpgKeyOpera DeleteKeys get key failed: " << tmp;
}
}
}
@@ -113,14 +113,12 @@ void GpgKeyOpera::GenerateRevokeCert(const GpgKey& key,
output_path, "--gen-revoke", key.GetFingerprint()},
[=](int exit_code, const QString& p_out, const QString& p_err) {
if (exit_code != 0) {
- GF_CORE_LOG_ERROR(
- "gnupg gen revoke execute error, process stderr: {}, process "
- "stdout: {}",
- p_err, p_out);
+ qCWarning(core) << "gnupg gen revoke execute error, process stderr: "
+ << p_err << ", process stdout: " << p_out;
} else {
- GF_CORE_LOG_DEBUG(
- "gnupg gen revoke exit_code: {}, process stdout size: {}",
- exit_code, p_out.size());
+ qCDebug(core,
+ "gnupg gen revoke exit_code: %d, process stdout size: %lld",
+ exit_code, p_out.size());
}
},
nullptr,
@@ -128,7 +126,6 @@ void GpgKeyOpera::GenerateRevokeCert(const GpgKey& key,
// Code From Gpg4Win
while (proc->canReadLine()) {
const QString line = QString::fromUtf8(proc->readLine()).trimmed();
- GF_CORE_LOG_DEBUG("line: {}", line);
if (line == QLatin1String("[GNUPG:] GET_BOOL gen_revoke.okay")) {
proc->write("y\n");
} else if (line == QLatin1String("[GNUPG:] GET_LINE "
@@ -162,8 +159,8 @@ void GpgKeyOpera::GenerateKey(const std::shared_ptr<GenKeyInfo>& params,
auto userid = params->GetUserid();
auto algo = params->GetAlgo() + params->GetKeySizeStr();
- GF_CORE_LOG_DEBUG("params: {} {}", params->GetAlgo(),
- params->GetKeySizeStr());
+ qCDebug(core) << "params: " << params->GetAlgo()
+ << params->GetKeySizeStr();
unsigned long expires =
QDateTime::currentDateTime().secsTo(params->GetExpireTime());
@@ -178,8 +175,9 @@ void GpgKeyOpera::GenerateKey(const std::shared_ptr<GenKeyInfo>& params,
if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
- GF_CORE_LOG_DEBUG("key generation args: {} {} {} {}", userid, algo,
- expires, flags);
+ qCDebug(core) << "key generation args: " << userid << algo << expires
+ << flags;
+
err = gpgme_op_createkey(ctx.DefaultContext(), userid.toUtf8(),
algo.toUtf8(), 0, expires, nullptr, flags);
@@ -202,8 +200,8 @@ auto GpgKeyOpera::GenerateKeySync(const std::shared_ptr<GenKeyInfo>& params)
auto userid = params->GetUserid();
auto algo = params->GetAlgo() + params->GetKeySizeStr();
- GF_CORE_LOG_DEBUG("params: {} {}", params->GetAlgo(),
- params->GetKeySizeStr());
+ qCDebug(core) << "params: " << params->GetAlgo()
+ << params->GetKeySizeStr();
unsigned long expires =
QDateTime::currentDateTime().secsTo(params->GetExpireTime());
@@ -218,8 +216,9 @@ auto GpgKeyOpera::GenerateKeySync(const std::shared_ptr<GenKeyInfo>& params)
if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
- GF_CORE_LOG_DEBUG("key generation args: {} {} {} {}", userid, algo,
- expires, flags);
+ qCDebug(core) << "key generation args: " << userid << algo << expires
+ << flags;
+
err = gpgme_op_createkey(ctx.DefaultContext(), userid.toUtf8(),
algo.toUtf8(), 0, expires, nullptr, flags);
@@ -242,8 +241,8 @@ void GpgKeyOpera::GenerateSubkey(const GpgKey& key,
[key, &ctx = ctx_, params](const DataObjectPtr& data_object) -> GpgError {
if (!params->IsSubKey()) return GPG_ERR_CANCELED;
- GF_CORE_LOG_DEBUG("generate subkey algo {}, key size {}",
- params->GetAlgo(), params->GetKeySizeStr());
+ qCDebug(core) << "generate subkey algo: " << params->GetAlgo()
+ << "key size: " << params->GetKeySizeStr();
auto algo = params->GetAlgo() + params->GetKeySizeStr();
unsigned long expires =
@@ -257,8 +256,9 @@ void GpgKeyOpera::GenerateSubkey(const GpgKey& key,
if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
- GF_CORE_LOG_DEBUG("subkey generation args: {} {} {} {}", key.GetId(),
- algo, expires, flags);
+ qCDebug(core) << "subkey generation args: " << key.GetId() << algo
+ << expires << flags;
+
auto err = gpgme_op_createsubkey(ctx.DefaultContext(),
static_cast<gpgme_key_t>(key),
algo.toUtf8(), 0, expires, flags);
@@ -281,8 +281,8 @@ auto GpgKeyOpera::GenerateSubkeySync(const GpgKey& key,
[key, &ctx = ctx_, params](const DataObjectPtr& data_object) -> GpgError {
if (!params->IsSubKey()) return GPG_ERR_CANCELED;
- GF_CORE_LOG_DEBUG("generate subkey algo {} key size {}",
- params->GetAlgo(), params->GetKeySizeStr());
+ qCDebug(core) << "generate subkey algo: " << params->GetAlgo()
+ << " key size: " << params->GetKeySizeStr();
auto algo = params->GetAlgo() + params->GetKeySizeStr();
unsigned long expires =
@@ -296,8 +296,7 @@ auto GpgKeyOpera::GenerateSubkeySync(const GpgKey& key,
if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
- GF_CORE_LOG_DEBUG("args: {} {} {} {}", key.GetId(), algo, expires,
- flags);
+ qCDebug(core) << " args: " << key.GetId() << algo << expires << flags;
auto err = gpgme_op_createsubkey(ctx.DefaultContext(),
static_cast<gpgme_key_t>(key),
@@ -337,8 +336,9 @@ void GpgKeyOpera::GenerateKeyWithSubkey(
if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
- GF_CORE_LOG_DEBUG("key generation args: {}", userid, algo, expires,
- flags);
+ qCDebug(core) << "key generation args: " << userid << algo << expires
+ << flags;
+
err = gpgme_op_createkey(ctx.DefaultContext(), userid, algo, 0, expires,
nullptr, flags);
@@ -358,16 +358,11 @@ void GpgKeyOpera::GenerateKeyWithSubkey(
auto key =
GpgKeyGetter::GetInstance().GetKey(genkey_result.GetFingerprint());
if (!key.IsGood()) {
- GF_CORE_LOG_ERROR("cannot get key which has been generate, fpr: {}",
- genkey_result.GetFingerprint());
+ qCWarning(core) << "cannot get key which has been generate, fpr: "
+ << genkey_result.GetFingerprint();
return err;
}
- GF_CORE_LOG_DEBUG(
- "try to generate subkey of key: {}, algo {} key size {}",
- key.GetId(), subkey_params->GetAlgo(),
- subkey_params->GetKeySizeStr());
-
algo = (subkey_params->GetAlgo() + subkey_params->GetKeySizeStr())
.toUtf8();
expires =
@@ -380,8 +375,8 @@ void GpgKeyOpera::GenerateKeyWithSubkey(
if (subkey_params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
if (subkey_params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
- GF_CORE_LOG_DEBUG("subkey generation args: {} {} {} {}", key.GetId(),
- algo, expires, flags);
+ qCDebug(core) << "subkey generation args: " << key.GetId() << algo
+ << expires << flags;
err = gpgme_op_createsubkey(ctx.DefaultContext(),
static_cast<gpgme_key_t>(key), algo, 0,
@@ -422,8 +417,9 @@ auto GpgKeyOpera::GenerateKeyWithSubkeySync(
if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
- GF_CORE_LOG_DEBUG("key generation args: {}", userid, algo, expires,
- flags);
+ qCDebug(core) << "key generation args: " << userid << algo << expires
+ << flags;
+
err = gpgme_op_createkey(ctx.DefaultContext(), userid, algo, 0, expires,
nullptr, flags);
@@ -443,15 +439,14 @@ auto GpgKeyOpera::GenerateKeyWithSubkeySync(
auto key =
GpgKeyGetter::GetInstance().GetKey(genkey_result.GetFingerprint());
if (!key.IsGood()) {
- GF_CORE_LOG_ERROR("cannot get key which has been generate, fpr: {}",
- genkey_result.GetFingerprint());
+ qCWarning(core) << "cannot get key which has been generate, fpr: "
+ << genkey_result.GetFingerprint();
return err;
}
- GF_CORE_LOG_DEBUG(
- "try to generate subkey of key: {}, algo {} key size {}",
- key.GetId(), subkey_params->GetAlgo(),
- subkey_params->GetKeySizeStr());
+ qCDebug(core) << "try to generate subkey of key: " << key.GetId()
+ << ", algo :" << subkey_params->GetAlgo()
+ << ", key size: " << subkey_params->GetKeySizeStr();
algo = (subkey_params->GetAlgo() + subkey_params->GetKeySizeStr())
.toUtf8();
@@ -465,8 +460,8 @@ auto GpgKeyOpera::GenerateKeyWithSubkeySync(
if (subkey_params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
if (subkey_params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
- GF_CORE_LOG_DEBUG("subkey generation args: {} {} {} {}", key.GetId(),
- algo, expires, flags);
+ qCDebug(core) << "subkey generation args: " << key.GetId() << algo
+ << expires << flags;
err = gpgme_op_createsubkey(ctx.DefaultContext(),
static_cast<gpgme_key_t>(key), algo, 0,
@@ -495,15 +490,14 @@ void GpgKeyOpera::ModifyPassword(const GpgKey& key,
callback, "gpgme_op_passwd", "2.0.15");
}
-auto GpgKeyOpera::ModifyTOFUPolicy(const GpgKey& key,
- gpgme_tofu_policy_t tofu_policy)
- -> GpgError {
+auto GpgKeyOpera::ModifyTOFUPolicy(
+ const GpgKey& key, gpgme_tofu_policy_t tofu_policy) -> GpgError {
const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
"core", "gpgme.ctx.gnupg_version", QString{"2.0.0"});
- GF_CORE_LOG_DEBUG("got gnupg version from rt: {}", gnupg_version);
+ qCDebug(core) << "got gnupg version from rt: " << gnupg_version;
if (GFCompareSoftwareVersion(gnupg_version, "2.1.10") < 0) {
- GF_CORE_LOG_ERROR("operator not support");
+ qCWarning(core, "operator not support");
return GPG_ERR_NOT_SUPPORTED;
}
diff --git a/src/core/function/gpg/GpgUIDOperator.cpp b/src/core/function/gpg/GpgUIDOperator.cpp
index 6c0373de..4477dd2f 100644
--- a/src/core/function/gpg/GpgUIDOperator.cpp
+++ b/src/core/function/gpg/GpgUIDOperator.cpp
@@ -48,17 +48,17 @@ auto GpgUIDOperator::RevUID(const GpgKey& key, const QString& uid) -> bool {
return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
-auto GpgUIDOperator::SetPrimaryUID(const GpgKey& key, const QString& uid)
- -> bool {
+auto GpgUIDOperator::SetPrimaryUID(const GpgKey& key,
+ const QString& uid) -> bool {
auto err = CheckGpgError(gpgme_op_set_uid_flag(
ctx_.DefaultContext(), static_cast<gpgme_key_t>(key), uid.toUtf8(),
"primary", nullptr));
return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
auto GpgUIDOperator::AddUID(const GpgKey& key, const QString& name,
- const QString& comment, const QString& email)
- -> bool {
- GF_CORE_LOG_DEBUG("new uuid: {} {} {}", name, comment, email);
+ const QString& comment,
+ const QString& email) -> bool {
+ qCDebug(core) << "new uuid:" << name << comment << email;
return AddUID(key, QString("%1(%2)<%3>").arg(name).arg(comment).arg(email));
}
diff --git a/src/core/model/DataObject.h b/src/core/model/DataObject.h
index 6b41a051..28678ca3 100644
--- a/src/core/model/DataObject.h
+++ b/src/core/model/DataObject.h
@@ -70,10 +70,6 @@ class GPGFRONTEND_CORE_EXPORT DataObject {
for (size_t i = 0; i < type_list.size(); ++i) {
if (std::type_index(*type_list[i]) !=
std::type_index((*this)[i].type())) {
- GF_CORE_LOG_ERROR(
- "value of index {} in data object is type: {}, "
- "not expected type: {}",
- i, ((*this)[i]).type().name(), type_list[i]->name());
return false;
}
}
diff --git a/src/core/model/GFDataExchanger.cpp b/src/core/model/GFDataExchanger.cpp
index abf79c6b..c0da517d 100644
--- a/src/core/model/GFDataExchanger.cpp
+++ b/src/core/model/GFDataExchanger.cpp
@@ -28,8 +28,6 @@
#include "GFDataExchanger.h"
-#include "core/utils/LogUtils.h"
-
namespace GpgFrontend {
auto GFDataExchanger::Write(const std::byte* buffer, size_t size) -> ssize_t {
@@ -40,16 +38,22 @@ auto GFDataExchanger::Write(const std::byte* buffer, size_t size) -> ssize_t {
std::unique_lock<std::mutex> lock(mutex_);
try {
for (size_t i = 0; i < size; i++) {
- if (queue_.size() == queue_max_size_) not_empty_.notify_all();
- not_full_.wait(lock,
- [=] { return queue_.size() < queue_max_size_ || close_; });
+ if (queue_.size() == static_cast<unsigned long>(queue_max_size_)) {
+ not_empty_.notify_all();
+ }
+
+ not_full_.wait(lock, [=] {
+ return queue_.size() < static_cast<unsigned long>(queue_max_size_) ||
+ close_;
+ });
if (close_) return -1;
queue_.push(buffer[i]);
write_bytes++;
}
} catch (...) {
- GF_CORE_LOG_ERROR(
+ qCWarning(
+ core,
"gf data exchanger caught exception when it writes to queue, abort...");
}
@@ -72,7 +76,9 @@ auto GFDataExchanger::Read(std::byte* buffer, size_t size) -> ssize_t {
read_bytes++;
}
- if (queue_.size() < queue_max_size_) not_full_.notify_all();
+ if (queue_.size() < static_cast<unsigned long>(queue_max_size_)) {
+ not_full_.notify_all();
+ }
return read_bytes;
}
diff --git a/src/core/model/GpgDecryptResult.cpp b/src/core/model/GpgDecryptResult.cpp
index 3568bfd9..57a83656 100644
--- a/src/core/model/GpgDecryptResult.cpp
+++ b/src/core/model/GpgDecryptResult.cpp
@@ -55,9 +55,9 @@ auto GpgDecryptResult::Recipients() -> std::vector<GpgRecipient> {
try {
result.emplace_back(reci);
} catch (...) {
- GF_CORE_LOG_ERROR(
- "caught exception when processing invalid_recipients, "
- "maybe nullptr of fpr");
+ qCWarning(core,
+ "caught exception when processing invalid_recipients, "
+ "maybe nullptr of fpr");
}
}
return result;
diff --git a/src/core/model/GpgEncryptResult.cpp b/src/core/model/GpgEncryptResult.cpp
index 843cf7eb..7017432b 100644
--- a/src/core/model/GpgEncryptResult.cpp
+++ b/src/core/model/GpgEncryptResult.cpp
@@ -55,9 +55,9 @@ auto GpgEncryptResult::InvalidRecipients()
try {
result.emplace_back(QString{invalid_key->fpr}, invalid_key->reason);
} catch (...) {
- GF_CORE_LOG_ERROR(
- "caught exception when processing invalid_recipients, "
- "maybe nullptr of fpr");
+ qCWarning(core,
+ "caught exception when processing invalid_recipients, "
+ "maybe nullptr of fpr");
}
}
return result;
diff --git a/src/core/model/GpgGenKeyInfo.cpp b/src/core/model/GpgGenKeyInfo.cpp
index d7daa852..47451253 100644
--- a/src/core/model/GpgGenKeyInfo.cpp
+++ b/src/core/model/GpgGenKeyInfo.cpp
@@ -30,13 +30,10 @@
#include <cassert>
-#include "core/utils/LogUtils.h"
-
namespace GpgFrontend {
void GenKeyInfo::SetAlgo(const QString &t_algo_args) {
auto algo_args = t_algo_args.toLower();
- GF_CORE_LOG_DEBUG("set algo args: {}", algo_args);
// reset all options
reset_options();
@@ -74,6 +71,28 @@ void GenKeyInfo::SetAlgo(const QString &t_algo_args) {
suggest_max_key_size_ = 3072;
suggest_size_addition_step_ = 1024;
SetKeyLength(2048);
+ } else if (algo_args == "elg") {
+ /**
+ * Algorithm (DSA) as a government standard for digital signatures.
+ * Originally, it supported key lengths between 512 and 1024 bits.
+ * Recently, NIST has declared 512-bit keys obsolete:
+ * now, DSA is available in 1024, 2048 and 3072-bit lengths.
+ */
+ SetAllowEncryption(true);
+
+ SetAllowAuthentication(false);
+ allow_change_authentication_ = false;
+
+ SetAllowSigning(false);
+ allow_change_signing_ = false;
+
+ SetAllowCertification(false);
+ allow_change_certification_ = false;
+
+ suggest_min_key_size_ = 1024;
+ suggest_max_key_size_ = 4096;
+ suggest_size_addition_step_ = 1024;
+ SetKeyLength(3072);
} else if (algo_args == "ed25519") {
/**
@@ -105,7 +124,7 @@ void GenKeyInfo::SetAlgo(const QString &t_algo_args) {
suggest_size_addition_step_ = -1;
SetKeyLength(-1);
} else {
- SPDLOG_ERROR("unsupported genkey algo arguments: {}", algo_args);
+ qCWarning(core) << "unsupported genkey algo arguments: " << algo_args;
return;
}
@@ -189,6 +208,7 @@ auto GenKeyInfo::GetSupportedSubkeyAlgo()
static const std::vector<GenKeyInfo::KeyGenAlgo> kSupportSubkeyAlgo = {
{"RSA", "", "RSA"},
{"DSA", "", "DSA"},
+ {"ELG-E", "", "ELG"},
{"ECDSA", "", "ED25519"},
{"ECDH", "", "CV25519"},
{"ECDH NIST P-256", "", "NISTP256"},
diff --git a/src/core/model/GpgKeyTableModel.cpp b/src/core/model/GpgKeyTableModel.cpp
new file mode 100644
index 00000000..e2a4fe37
--- /dev/null
+++ b/src/core/model/GpgKeyTableModel.cpp
@@ -0,0 +1,172 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend 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.
+ *
+ * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgKeyTableModel.h"
+
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/model/GpgKey.h"
+
+namespace GpgFrontend {
+
+GpgKeyTableModel::GpgKeyTableModel(GpgKeyList keys, QObject *parent)
+ : QAbstractTableModel(parent),
+ buffered_keys_(keys),
+ column_headers_({tr("Select"), tr("Type"), tr("Name"),
+ tr("Email Address"), tr("Usage"), tr("Trust"),
+ tr("Key ID"), tr("Create Date"), tr("Algorithm"),
+ tr("Subkey(s)"), tr("Comment")}),
+ key_check_state_(buffered_keys_.size()) {}
+
+auto GpgKeyTableModel::rowCount(const QModelIndex & /*parent*/) const -> int {
+ return static_cast<int>(buffered_keys_.size());
+}
+
+auto GpgKeyTableModel::columnCount(const QModelIndex & /*parent*/) const
+ -> int {
+ return 11;
+}
+
+auto GpgKeyTableModel::data(const QModelIndex &index, int role) const
+ -> QVariant {
+ if (!index.isValid() || buffered_keys_.empty()) return {};
+
+ if (role == Qt::TextAlignmentRole) {
+ return Qt::AlignCenter;
+ }
+
+ if (role == Qt::CheckStateRole) {
+ if (index.column() == 0) {
+ return key_check_state_[index.row()] ? Qt::Checked : Qt::Unchecked;
+ }
+ return {};
+ }
+
+ const auto &key = buffered_keys_.at(index.row());
+
+ switch (index.column()) {
+ case 0: {
+ return index.row();
+ }
+ case 1: {
+ QString type_sym;
+ type_sym += key.IsPrivateKey() ? "pub/sec" : "pub";
+ if (key.IsPrivateKey() && !key.IsHasMasterKey()) type_sym += "#";
+ if (key.IsHasCardKey()) type_sym += "^";
+ return type_sym;
+ }
+ case 2: {
+ return key.GetName();
+ }
+ case 3: {
+ return key.GetEmail();
+ }
+ case 4: {
+ QString usage_sym;
+ if (key.IsHasActualCertificationCapability()) usage_sym += "C";
+ if (key.IsHasActualEncryptionCapability()) usage_sym += "E";
+ if (key.IsHasActualSigningCapability()) usage_sym += "S";
+ if (key.IsHasActualAuthenticationCapability()) usage_sym += "A";
+ return usage_sym;
+ }
+ case 5: {
+ return key.GetOwnerTrust();
+ }
+ case 6: {
+ return key.GetId();
+ }
+ case 7: {
+ return key.GetCreateTime();
+ }
+ case 8: {
+ return key.GetKeyAlgo();
+ }
+ case 9: {
+ return static_cast<int>(key.GetSubKeys()->size());
+ }
+ case 10: {
+ return key.GetComment();
+ }
+ default:
+ return {};
+ }
+}
+
+auto GpgKeyTableModel::headerData(int section, Qt::Orientation orientation,
+ int role) const -> QVariant {
+ if (role != Qt::DisplayRole) return {};
+
+ if (orientation == Qt::Horizontal) {
+ return column_headers_[section];
+ }
+
+ return {};
+}
+
+auto GpgKeyTableModel::flags(const QModelIndex &index) const -> Qt::ItemFlags {
+ if (!index.isValid()) return Qt::NoItemFlags;
+
+ if (index.column() == 0) {
+ return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled;
+ }
+
+ return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
+}
+
+auto GpgKeyTableModel::setData(const QModelIndex &index, const QVariant &value,
+ int role) -> bool {
+ if (!index.isValid()) return false;
+
+ if (index.column() == 0 && role == Qt::CheckStateRole) {
+ key_check_state_[index.row()] = (value == Qt::Checked);
+ emit dataChanged(index, index);
+ return true;
+ }
+
+ return false;
+}
+
+auto GpgKeyTableModel::GetAllKeyIds() -> GpgKeyIDList {
+ GpgKeyIDList keys;
+ for (auto &key : buffered_keys_) {
+ keys.push_back(key.GetId());
+ }
+ return keys;
+}
+
+auto GpgKeyTableModel::GetKeyIDByRow(int row) const -> QString {
+ if (buffered_keys_.size() <= row) return {};
+
+ return buffered_keys_[row].GetId();
+}
+
+auto GpgKeyTableModel::IsPrivateKeyByRow(int row) const -> bool {
+ if (buffered_keys_.size() <= row) return false;
+ return buffered_keys_[row].IsPrivateKey();
+}
+
+} // namespace GpgFrontend
diff --git a/src/core/model/GpgKeyTableModel.h b/src/core/model/GpgKeyTableModel.h
new file mode 100644
index 00000000..50640a9f
--- /dev/null
+++ b/src/core/model/GpgKeyTableModel.h
@@ -0,0 +1,216 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend 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.
+ *
+ * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+/**
+ * @brief
+ *
+ */
+#include "core/model/GpgKey.h"
+#include "core/typedef/GpgTypedef.h"
+
+namespace GpgFrontend {
+
+enum class GpgKeyTableColumn : unsigned int {
+ kNONE = 0,
+ kTYPE = 1 << 0,
+ kNAME = 1 << 1,
+ kEMAIL_ADDRESS = 1 << 2,
+ kUSAGE = 1 << 3,
+ kKEY_ID = 1 << 4,
+ kOWNER_TRUST = 1 << 5,
+ kCREATE_DATE = 1 << 6,
+ kALGO = 1 << 7,
+ kSUBKEYS_NUMBER = 1 << 8,
+ kCOMMENT = 1 << 9,
+ kALL = ~0U
+};
+
+inline auto operator|(GpgKeyTableColumn lhs,
+ GpgKeyTableColumn rhs) -> GpgKeyTableColumn {
+ using T = std::underlying_type_t<GpgKeyTableColumn>;
+ return static_cast<GpgKeyTableColumn>(static_cast<T>(lhs) |
+ static_cast<T>(rhs));
+}
+
+inline auto operator|=(GpgKeyTableColumn &lhs,
+ GpgKeyTableColumn rhs) -> GpgKeyTableColumn & {
+ lhs = lhs | rhs;
+ return lhs;
+}
+
+inline auto operator&(GpgKeyTableColumn lhs,
+ GpgKeyTableColumn rhs) -> GpgKeyTableColumn {
+ using T = std::underlying_type_t<GpgKeyTableColumn>;
+ return static_cast<GpgKeyTableColumn>(static_cast<T>(lhs) &
+ static_cast<T>(rhs));
+}
+
+inline auto operator&=(GpgKeyTableColumn &lhs,
+ GpgKeyTableColumn rhs) -> GpgKeyTableColumn & {
+ lhs = lhs & rhs;
+ return lhs;
+}
+
+inline auto operator~(GpgKeyTableColumn hs) -> GpgKeyTableColumn {
+ using T = std::underlying_type_t<GpgKeyTableColumn>;
+ return static_cast<GpgKeyTableColumn>(~static_cast<T>(hs));
+}
+
+enum class GpgKeyTableDisplayMode : unsigned int {
+ kNONE = 0,
+ kPUBLIC_KEY = 1 << 0,
+ kPRIVATE_KEY = 1 << 1,
+ kFAVORITES = 1 << 2,
+ kALL = ~0U
+};
+
+inline auto operator|(GpgKeyTableDisplayMode lhs,
+ GpgKeyTableDisplayMode rhs) -> GpgKeyTableDisplayMode {
+ using T = std::underlying_type_t<GpgKeyTableDisplayMode>;
+ return static_cast<GpgKeyTableDisplayMode>(static_cast<T>(lhs) |
+ static_cast<T>(rhs));
+}
+
+inline auto operator|=(GpgKeyTableDisplayMode &lhs,
+ GpgKeyTableDisplayMode rhs) -> GpgKeyTableDisplayMode & {
+ lhs = lhs | rhs;
+ return lhs;
+}
+
+inline auto operator&(GpgKeyTableDisplayMode lhs,
+ GpgKeyTableDisplayMode rhs) -> bool {
+ using T = std::underlying_type_t<GpgKeyTableDisplayMode>;
+ return (static_cast<T>(lhs) & static_cast<T>(rhs)) != 0;
+}
+
+class GPGFRONTEND_CORE_EXPORT GpgKeyTableModel : public QAbstractTableModel {
+ Q_OBJECT
+ public:
+ /**
+ * @brief Construct a new Gpg Key Table Model object
+ *
+ * @param keys
+ * @param parent
+ */
+ explicit GpgKeyTableModel(GpgKeyList keys, QObject *parent = nullptr);
+
+ /**
+ * @brief
+ *
+ * @param parent
+ * @return int
+ */
+ [[nodiscard]] auto rowCount(const QModelIndex &parent) const -> int override;
+
+ /**
+ * @brief
+ *
+ * @param parent
+ * @return int
+ */
+ [[nodiscard]] auto columnCount(const QModelIndex &parent) const
+ -> int override;
+
+ /**
+ * @brief
+ *
+ * @param index
+ * @param role
+ * @return QVariant
+ */
+ [[nodiscard]] auto data(const QModelIndex &index,
+ int role) const -> QVariant override;
+
+ /**
+ * @brief
+ *
+ * @param section
+ * @param orientation
+ * @param role
+ * @return QVariant
+ */
+ [[nodiscard]] auto headerData(int section, Qt::Orientation orientation,
+ int role) const -> QVariant override;
+
+ /**
+ * @brief Set the Data object
+ *
+ * @param index
+ * @param value
+ * @param role
+ * @return true
+ * @return false
+ */
+ auto setData(const QModelIndex &index, const QVariant &value,
+ int role) -> bool override;
+
+ /**
+ * @brief
+ *
+ * @param index
+ * @return Qt::ItemFlags
+ */
+ [[nodiscard]] auto flags(const QModelIndex &index) const
+ -> Qt::ItemFlags override;
+
+ /**
+ * @brief Get the All Key Ids object
+ *
+ * @return auto
+ */
+ auto GetAllKeyIds() -> GpgKeyIDList;
+
+ /**
+ * @brief Get the Key ID By Row object
+ *
+ * @return QString
+ */
+ [[nodiscard]] auto GetKeyIDByRow(int row) const -> QString;
+
+ /**
+ * @brief
+ *
+ * @param row
+ * @return true
+ * @return false
+ */
+ [[nodiscard]] auto IsPrivateKeyByRow(int row) const -> bool;
+
+ private:
+ GpgKeyList buffered_keys_;
+ QStringList column_headers_;
+#ifdef QT5_BUILD
+ QVector<bool> key_check_state_;
+#else
+ QList<bool> key_check_state_;
+#endif
+};
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgKeyTableProxyModel.cpp b/src/core/model/GpgKeyTableProxyModel.cpp
new file mode 100644
index 00000000..aebe06ef
--- /dev/null
+++ b/src/core/model/GpgKeyTableProxyModel.cpp
@@ -0,0 +1,179 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend 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.
+ *
+ * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgKeyTableProxyModel.h"
+
+#include <utility>
+
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/model/CacheObject.h"
+#include "core/model/GpgKey.h"
+
+namespace GpgFrontend {
+
+GpgKeyTableProxyModel::GpgKeyTableProxyModel(
+ QSharedPointer<GpgKeyTableModel> model, GpgKeyTableDisplayMode display_mode,
+ GpgKeyTableColumn columns, KeyFilter filter, QObject *parent)
+ : QSortFilterProxyModel(parent),
+ model_(std::move(model)),
+ display_mode_(display_mode),
+ filter_columns_(columns),
+ custom_filter_(std::move(filter)) {
+ setSourceModel(model_.get());
+
+ connect(this, &GpgKeyTableProxyModel::SignalFavoritesChanged, this,
+ &GpgKeyTableProxyModel::slot_update_favorites);
+ connect(this, &GpgKeyTableProxyModel::SignalColumnTypeChange, this,
+ &GpgKeyTableProxyModel::slot_update_column_type);
+
+ emit SignalFavoritesChanged();
+}
+
+auto GpgKeyTableProxyModel::filterAcceptsRow(
+ int source_row, const QModelIndex &sourceParent) const -> bool {
+ auto index = sourceModel()->index(source_row, 6, sourceParent);
+ auto key_id = sourceModel()->data(index).toString();
+ auto key = GpgKeyGetter::GetInstance().GetKey(key_id);
+
+ if (!(display_mode_ & GpgKeyTableDisplayMode::kPRIVATE_KEY) &&
+ key.IsPrivateKey()) {
+ return false;
+ }
+
+ if (!(display_mode_ & GpgKeyTableDisplayMode::kPUBLIC_KEY) &&
+ !key.IsPrivateKey()) {
+ return false;
+ }
+
+ if (!custom_filter_(key)) return false;
+
+ if (display_mode_ & GpgKeyTableDisplayMode::kFAVORITES &&
+ !favorite_fingerprints_.contains(key.GetFingerprint())) {
+ return false;
+ }
+
+ if (filter_keywords_.isEmpty()) return true;
+
+ QStringList infos;
+ for (int column = 0; column < sourceModel()->columnCount(); ++column) {
+ auto index = sourceModel()->index(source_row, column, sourceParent);
+ infos << sourceModel()->data(index).toString();
+
+ const auto uids = key.GetUIDs();
+ for (const auto &uid : *uids) {
+ infos << uid.GetUID();
+ }
+ }
+
+ return std::any_of(infos.cbegin(), infos.cend(), [&](const QString &info) {
+ return info.contains(filter_keywords_, Qt::CaseInsensitive);
+ });
+
+ return false;
+}
+
+auto GpgKeyTableProxyModel::filterAcceptsColumn(
+ int sourceColumn, const QModelIndex &sourceParent) const -> bool {
+ switch (sourceColumn) {
+ case 0: {
+ return true;
+ }
+ case 1: {
+ return (filter_columns_ & GpgKeyTableColumn::kTYPE) !=
+ GpgKeyTableColumn::kNONE;
+ }
+ case 2: {
+ return (filter_columns_ & GpgKeyTableColumn::kNAME) !=
+ GpgKeyTableColumn::kNONE;
+ }
+ case 3: {
+ return (filter_columns_ & GpgKeyTableColumn::kEMAIL_ADDRESS) !=
+ GpgKeyTableColumn::kNONE;
+ }
+ case 4: {
+ return (filter_columns_ & GpgKeyTableColumn::kUSAGE) !=
+ GpgKeyTableColumn::kNONE;
+ }
+ case 5: {
+ return (filter_columns_ & GpgKeyTableColumn::kOWNER_TRUST) !=
+ GpgKeyTableColumn::kNONE;
+ }
+ case 6: {
+ return (filter_columns_ & GpgKeyTableColumn::kKEY_ID) !=
+ GpgKeyTableColumn::kNONE;
+ }
+ case 7: {
+ return (filter_columns_ & GpgKeyTableColumn::kCREATE_DATE) !=
+ GpgKeyTableColumn::kNONE;
+ }
+ case 8: {
+ return (filter_columns_ & GpgKeyTableColumn::kALGO) !=
+ GpgKeyTableColumn::kNONE;
+ }
+ case 9: {
+ return (filter_columns_ & GpgKeyTableColumn::kSUBKEYS_NUMBER) !=
+ GpgKeyTableColumn::kNONE;
+ }
+ case 10: {
+ return (filter_columns_ & GpgKeyTableColumn::kCOMMENT) !=
+ GpgKeyTableColumn::kNONE;
+ }
+ default:
+ return false;
+ }
+}
+
+void GpgKeyTableProxyModel::SetSearchKeywords(const QString &keywords) {
+ this->filter_keywords_ = keywords;
+ invalidateFilter();
+}
+
+void GpgKeyTableProxyModel::slot_update_favorites() {
+ // load cache
+ auto json_data = CacheObject("favourite_key_pair");
+ if (!json_data.isArray()) return;
+
+ auto key_fprs = json_data.array();
+ for (const auto &key_fpr : key_fprs) {
+ if (key_fpr.isString()) favorite_fingerprints_.append(key_fpr.toString());
+ }
+
+ invalidateFilter();
+}
+
+void GpgKeyTableProxyModel::slot_update_column_type(
+ GpgKeyTableColumn filter_columns) {
+ filter_columns_ = filter_columns;
+#ifdef QT5_BUILD
+ invalidateFilter();
+#else
+ invalidateColumnsFilter();
+#endif
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgKeyTableProxyModel.h b/src/core/model/GpgKeyTableProxyModel.h
new file mode 100644
index 00000000..657b40cf
--- /dev/null
+++ b/src/core/model/GpgKeyTableProxyModel.h
@@ -0,0 +1,94 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend 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.
+ *
+ * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/model/GpgKeyTableModel.h"
+
+namespace GpgFrontend {
+
+class GPGFRONTEND_CORE_EXPORT GpgKeyTableProxyModel
+ : public QSortFilterProxyModel {
+ Q_OBJECT
+ public:
+ using KeyFilter = std::function<bool(const GpgKey &)>;
+
+ explicit GpgKeyTableProxyModel(QSharedPointer<GpgKeyTableModel> model,
+ GpgKeyTableDisplayMode display_mode,
+ GpgKeyTableColumn columns, KeyFilter filter,
+ QObject *parent);
+
+ void SetSearchKeywords(const QString &keywords);
+
+ protected:
+ [[nodiscard]] auto filterAcceptsRow(int sourceRow,
+ const QModelIndex &sourceParent) const
+ -> bool override;
+
+ [[nodiscard]] auto filterAcceptsColumn(int sourceColumn,
+ const QModelIndex &sourceParent) const
+ -> bool override;
+
+ signals:
+
+ /**
+ * @brief
+ *
+ */
+ void SignalFavoritesChanged();
+
+ /**
+ * @brief
+ *
+ */
+ void SignalColumnTypeChange(GpgKeyTableColumn);
+
+ private slots:
+
+ /**
+ * @brief
+ *
+ */
+ void slot_update_favorites();
+
+ /**
+ * @brief
+ *
+ */
+ void slot_update_column_type(GpgKeyTableColumn);
+
+ private:
+ QSharedPointer<GpgKeyTableModel> model_;
+ GpgKeyTableDisplayMode display_mode_;
+ GpgKeyTableColumn filter_columns_;
+ QString filter_keywords_;
+ QList<QString> favorite_fingerprints_;
+ KeyFilter custom_filter_;
+};
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgSignResult.cpp b/src/core/model/GpgSignResult.cpp
index 4a0e5f35..50f6cfb7 100644
--- a/src/core/model/GpgSignResult.cpp
+++ b/src/core/model/GpgSignResult.cpp
@@ -55,9 +55,9 @@ auto GpgSignResult::InvalidSigners()
try {
result.emplace_back(QString{invalid_key->fpr}, invalid_key->reason);
} catch (...) {
- GF_CORE_LOG_ERROR(
- "caught exception when processing invalid_signers, "
- "maybe nullptr of fpr");
+ qCWarning(core,
+ "caught exception when processing invalid_signers, "
+ "maybe nullptr of fpr");
}
}
return result;
diff --git a/src/core/model/SettingsObject.cpp b/src/core/model/SettingsObject.cpp
index 09824f12..48eb65ff 100644
--- a/src/core/model/SettingsObject.cpp
+++ b/src/core/model/SettingsObject.cpp
@@ -35,20 +35,17 @@ namespace GpgFrontend {
SettingsObject::SettingsObject(QString settings_name)
: settings_name_(std::move(settings_name)) {
try {
- GF_CORE_LOG_DEBUG("loading settings from: {}", this->settings_name_);
auto json_optional =
DataObjectOperator::GetInstance().GetDataObject(settings_name_);
if (json_optional.has_value() && json_optional->isObject()) {
- GF_CORE_LOG_DEBUG("settings object: {} loaded.", settings_name_);
QJsonObject::operator=(json_optional.value().object());
} else {
- GF_CORE_LOG_DEBUG("settings object: {} not found.", settings_name_);
QJsonObject::operator=({});
}
} catch (std::exception& e) {
- GF_CORE_LOG_ERROR("load setting object error: {}", e.what());
+ qCWarning(core) << "load setting object error: {}" << e.what();
}
}
diff --git a/src/core/module/Event.cpp b/src/core/module/Event.cpp
index 4b0b989b..6d39d7ba 100644
--- a/src/core/module/Event.cpp
+++ b/src/core/module/Event.cpp
@@ -34,21 +34,17 @@ namespace GpgFrontend::Module {
class Event::Impl {
public:
- Impl(QString event_id, std::initializer_list<ParameterInitializer> params,
- EventCallback callback)
+ Impl(QString event_id, Params params, EventCallback callback)
: event_identifier_(std::move(event_id)),
callback_(std::move(callback)),
callback_thread_(QThread::currentThread()) {
- for (const auto& param : params) {
- AddParameter(param);
- }
- GF_CORE_LOG_DEBUG("create event {}", event_identifier_);
+ data_.insert(params);
}
auto operator[](const QString& key) const -> std::optional<ParameterValue> {
auto it_data = data_.find(key);
if (it_data != data_.end()) {
- return it_data->second;
+ return it_data.value();
}
return std::nullopt;
}
@@ -82,21 +78,17 @@ class Event::Impl {
}
void ExecuteCallback(ListenerIdentifier listener_id,
- const DataObjectPtr& data_object) {
- GF_CORE_LOG_DEBUG("try to execute callback for event {} with listener {}",
- event_identifier_, listener_id);
+ const Params& data_object) {
if (callback_) {
- GF_CORE_LOG_DEBUG("executing callback for event {} with listener {}",
- event_identifier_, listener_id);
if (!QMetaObject::invokeMethod(
callback_thread_,
[callback = callback_, event_identifier = event_identifier_,
listener_id, data_object]() {
callback(event_identifier, listener_id, data_object);
})) {
- GF_CORE_LOG_ERROR(
- "failed to invoke callback for event {} with listener {}",
- event_identifier_, listener_id);
+ qCWarning(core) << "failed to invoke callback for event: "
+ << event_identifier_
+ << " with listener:" << listener_id;
}
}
}
@@ -112,7 +104,22 @@ class Event::Impl {
GFModuleEventParam* p_param;
int index = 0;
- for (const auto& data : data_) {
+
+#ifdef QT5_BUILD
+ for (auto it = data_.keyValueBegin(); it != data_.keyValueEnd(); ++it) {
+ p_param = static_cast<GFModuleEventParam*>(
+ SecureMalloc(sizeof(GFModuleEventParam)));
+ if (index++ == 0) event->params = p_param;
+
+ p_param->name = GFStrDup(it->first);
+ p_param->value = GFStrDup(it->second);
+ p_param->next = nullptr;
+
+ if (l_param != nullptr) l_param->next = p_param;
+ l_param = p_param;
+ }
+#else
+ for (const auto& data : data_.asKeyValueRange()) {
p_param = static_cast<GFModuleEventParam*>(
SecureMalloc(sizeof(GFModuleEventParam)));
if (index++ == 0) event->params = p_param;
@@ -124,6 +131,7 @@ class Event::Impl {
if (l_param != nullptr) l_param->next = p_param;
l_param = p_param;
}
+#endif
return event;
}
@@ -131,14 +139,12 @@ class Event::Impl {
private:
EventIdentifier event_identifier_;
EventTriggerIdentifier trigger_uuid_ = QUuid::createUuid().toString();
- std::map<QString, QString> data_;
+ QMap<QString, QString> data_;
EventCallback callback_;
QThread* callback_thread_ = nullptr; ///<
};
-Event::Event(const QString& event_id,
- std::initializer_list<ParameterInitializer> params,
- EventCallback callback)
+Event::Event(const QString& event_id, Params params, EventCallback callback)
: p_(SecureCreateUniqueObject<Impl>(event_id, params,
std::move(callback))) {}
@@ -170,8 +176,8 @@ void Event::AddParameter(const QString& key, const QString& value) {
p_->AddParameter(key, value);
}
-void Event::ExecuteCallback(ListenerIdentifier l_id, DataObjectPtr d_o) {
- p_->ExecuteCallback(std::move(l_id), d_o);
+void Event::ExecuteCallback(ListenerIdentifier l_id, const Params& param) {
+ p_->ExecuteCallback(std::move(l_id), param);
}
auto Event::ToModuleEvent() -> GFModuleEvent* { return p_->ToModuleEvent(); }
diff --git a/src/core/module/Event.h b/src/core/module/Event.h
index b629caae..64c35592 100644
--- a/src/core/module/Event.h
+++ b/src/core/module/Event.h
@@ -34,7 +34,7 @@
#include "core/GpgFrontendCore.h"
#include "core/model/DataObject.h"
-#include "module/sdk/GFSDKModule.h"
+#include "sdk/GFSDKModule.h"
namespace GpgFrontend::Module {
@@ -50,16 +50,16 @@ class GPGFRONTEND_CORE_EXPORT Event {
using ParameterValue = std::any;
using EventIdentifier = QString;
using ListenerIdentifier = QString;
+ using Params = QMap<QString, QString>;
+
using EventCallback =
- std::function<void(EventIdentifier, ListenerIdentifier, DataObjectPtr)>;
+ std::function<void(EventIdentifier, ListenerIdentifier, Params)>;
struct ParameterInitializer {
QString key;
QString value;
};
- explicit Event(const QString&,
- std::initializer_list<ParameterInitializer> = {},
- EventCallback = nullptr);
+ explicit Event(const QString&, Params = {}, EventCallback = nullptr);
~Event();
@@ -81,7 +81,7 @@ class GPGFRONTEND_CORE_EXPORT Event {
void AddParameter(const QString& key, const QString& value);
- void ExecuteCallback(ListenerIdentifier, DataObjectPtr);
+ void ExecuteCallback(ListenerIdentifier, const Params&);
auto ToModuleEvent() -> GFModuleEvent*;
@@ -91,10 +91,8 @@ class GPGFRONTEND_CORE_EXPORT Event {
};
template <typename... Args>
-auto MakeEvent(const EventIdentifier& event_id, Args&&... args,
+auto MakeEvent(const EventIdentifier& event_id, const Event::Params& params,
Event::EventCallback e_cb) -> EventReference {
- std::initializer_list<Event::ParameterInitializer> params = {
- Event::ParameterInitializer{std::forward<Args>(args)}...};
return GpgFrontend::SecureCreateSharedObject<Event>(event_id, params, e_cb);
}
diff --git a/src/core/module/GlobalModuleContext.cpp b/src/core/module/GlobalModuleContext.cpp
index e67e48f9..c35e5229 100644
--- a/src/core/module/GlobalModuleContext.cpp
+++ b/src/core/module/GlobalModuleContext.cpp
@@ -54,8 +54,8 @@ class GlobalModuleContext::Impl {
// Search for the module in the register table.
auto module_info_opt = search_module_register_table(module_id);
if (!module_info_opt.has_value()) {
- GF_CORE_LOG_ERROR("cannot find module id {} at register table",
- module_id);
+ qCWarning(core) << "cannot find module id " << module_id
+ << " at register table";
return nullptr;
}
@@ -67,11 +67,11 @@ class GlobalModuleContext::Impl {
auto module_info_opt =
search_module_register_table(module->GetModuleIdentifier());
if (!module_info_opt.has_value()) {
- GF_CORE_LOG_ERROR(
- "cannot find module id {} at register table, fallbacking to "
- "default "
- "channel",
- module->GetModuleIdentifier());
+ qCWarning(core) << "cannot find module id "
+ << module->GetModuleIdentifier()
+ << " at register table, fallback to "
+ "default channel";
+
return GetDefaultChannel(module);
}
@@ -99,20 +99,17 @@ class GlobalModuleContext::Impl {
}
auto RegisterModule(const ModulePtr& module, bool integrated_module) -> bool {
- GF_CORE_LOG_DEBUG("attempting to register module: {}",
- module->GetModuleIdentifier());
// Check if the module is null or already registered.
if (module == nullptr ||
module_register_table_.find(module->GetModuleIdentifier()) !=
module_register_table_.end()) {
- GF_CORE_LOG_ERROR(
- "module is null or have already registered this module");
+ qCWarning(core, "module is null or have already registered this module");
return false;
}
if (module->Register() != 0) {
- GF_CORE_LOG_ERROR("register module {} failed",
- module->GetModuleIdentifier());
+ qCWarning(core) << "register module " << module->GetModuleIdentifier()
+ << " failed";
return false;
}
@@ -132,19 +129,15 @@ class GlobalModuleContext::Impl {
// Register the module with its identifier.
module_register_table_[module->GetModuleIdentifier()] = register_info;
- GF_CORE_LOG_DEBUG("successfully registered module: {}",
- module->GetModuleIdentifier());
return true;
}
auto ActiveModule(ModuleIdentifier module_id) -> bool {
- GF_CORE_LOG_DEBUG("attempting to activate module: {}", module_id);
-
// Search for the module in the register table.
auto module_info_opt = search_module_register_table(module_id);
if (!module_info_opt.has_value()) {
- GF_CORE_LOG_ERROR("cannot find module id {} at register table",
- module_id);
+ qCWarning(core) << "cannot find module id " << module_id
+ << " at register table";
return false;
}
@@ -153,9 +146,8 @@ class GlobalModuleContext::Impl {
// try to get module from module info
auto module = module_info->module;
if (module == nullptr) {
- GF_CORE_LOG_ERROR(
- "module id {} at register table is releated to a null module",
- module_id);
+ qCWarning(core) << "module id:" << module_id
+ << " at register table is related to a null module";
return false;
}
@@ -165,19 +157,15 @@ class GlobalModuleContext::Impl {
module_info->activate = true;
}
- GF_CORE_LOG_DEBUG("module activation status: {}", module_info->activate);
return module_info->activate;
}
auto ListenEvent(ModuleIdentifier module_id, EventIdentifier event) -> bool {
- GF_CORE_LOG_DEBUG("module: {} is attempting to listen to event {}",
- module_id, event);
-
// module -> event
auto module_info_opt = search_module_register_table(module_id);
if (!module_info_opt.has_value()) {
- GF_CORE_LOG_ERROR("cannot find module id {} at register table",
- module_id);
+ qCWarning(core) << "cannot find module id" << module_id
+ << "at register table";
return false;
}
@@ -186,7 +174,6 @@ class GlobalModuleContext::Impl {
if (met_it == module_events_table_.end()) {
module_events_table_[event] = std::unordered_set<ModuleIdentifier>();
met_it = module_events_table_.find(event);
- GF_CORE_LOG_DEBUG("new event {} of module system created", event);
}
module_info_opt.value()->listening_event_ids.push_back(event);
@@ -204,14 +191,14 @@ class GlobalModuleContext::Impl {
// search for the module in the register table.
auto module_info_opt = search_module_register_table(module_id);
if (!module_info_opt.has_value()) {
- GF_CORE_LOG_ERROR("cannot find module id {} at register table",
- module_id);
+ qCWarning(core) << "cannot find module id " << module_id
+ << " at register table";
return false;
}
auto module_info = module_info_opt.value();
- // activate the module if it is not already deactive.
- if (module_info->activate && (module_info->module->Deactive() == 0)) {
+ // activate the module if it is not already Deactivate.
+ if (module_info->activate && (module_info->module->Deactivate() == 0)) {
for (const auto& event_ids : module_info->listening_event_ids) {
auto& modules = module_events_table_[event_ids];
if (auto it = modules.find(module_id); it != modules.end()) {
@@ -228,15 +215,13 @@ class GlobalModuleContext::Impl {
auto TriggerEvent(const EventReference& event) -> bool {
auto event_id = event->GetIdentifier();
- GF_CORE_LOG_DEBUG("attempting to trigger event: {}", event_id);
// Find the set of listeners associated with the given event in the table
auto met_it = module_events_table_.find(event_id);
if (met_it == module_events_table_.end()) {
// Log a warning if the event is not registered and nobody is listening
- GF_CORE_LOG_WARN(
- "event {} is not listening by anyone and not registered as well",
- event_id);
+ qCInfo(core) << "event: " << event_id
+ << " is not listening by anyone and not registered as well.";
return false;
}
@@ -246,15 +231,10 @@ class GlobalModuleContext::Impl {
// Check if the set of listeners is empty
if (listeners_set.empty()) {
// Log a warning if nobody is listening to this event
- GF_CORE_LOG_WARN("event {} is not listening by anyone",
- event->GetIdentifier());
+ qCInfo(core) << "event: " << event_id << " is not listening by anyone";
return false;
}
- // Log the number of listeners for this event
- GF_CORE_LOG_DEBUG("event {}'s current listeners size: {}",
- event->GetIdentifier(), listeners_set.size());
-
// register trigger id index table
module_on_triggering_events_table_[event->GetTriggerIdentifier()] = event;
@@ -265,8 +245,8 @@ class GlobalModuleContext::Impl {
// Log an error if the module is not found in the registration table
if (!module_info_opt.has_value()) {
- GF_CORE_LOG_ERROR("cannot find module id {} at register table",
- listener_module_id);
+ qCWarning(core) << "cannot find module id: " << listener_module_id
+ << " at register table";
continue;
}
@@ -274,11 +254,6 @@ class GlobalModuleContext::Impl {
auto module_info = module_info_opt.value();
auto module = module_info->module;
- GF_CORE_LOG_DEBUG(
- "module {} is listening to event {}, activate state: {}",
- module_info->module->GetModuleIdentifier(), event->GetIdentifier(),
- module_info->activate);
-
// Check if the module is activated
if (!module_info->activate) continue;
@@ -289,9 +264,9 @@ class GlobalModuleContext::Impl {
[listener_module_id, event_id](int code, DataObjectPtr) {
if (code < 0) {
// Log an error if the module execution fails
- GF_CORE_LOG_ERROR(
- "module {} execution failed of event {}: exec return code {}",
- listener_module_id, event_id, code);
+ qCWarning(core) << "module " << listener_module_id
+ << "execution failed of event " << event_id
+ << ": exec return code: " << code;
}
};
diff --git a/src/core/module/GlobalRegisterTable.cpp b/src/core/module/GlobalRegisterTable.cpp
index bac51d85..c19a9131 100644
--- a/src/core/module/GlobalRegisterTable.cpp
+++ b/src/core/module/GlobalRegisterTable.cpp
@@ -126,8 +126,8 @@ class GlobalRegisterTable::Impl {
return rtn;
}
- auto ListenPublish(QObject* o, const Namespace& n, const Key& k, LPCallback c)
- -> bool {
+ auto ListenPublish(QObject* o, const Namespace& n, const Key& k,
+ LPCallback c) -> bool {
if (o == nullptr) return false;
return QObject::connect(parent_, &GlobalRegisterTable::SignalPublish, o,
[n, k, c](const Namespace& pn, const Key& pk,
@@ -138,7 +138,7 @@ class GlobalRegisterTable::Impl {
}) == nullptr;
}
- auto RootRTNode() -> RTNode* { return root_node_.get(); }
+ auto RootRTNode() -> RTNodePtr { return root_node_; }
private:
std::shared_mutex lock_;
@@ -165,8 +165,8 @@ class GlobalRegisterTableTreeModel::Impl {
return 4;
}
- [[nodiscard]] auto Data(const QModelIndex& index, int role) const
- -> QVariant {
+ [[nodiscard]] auto Data(const QModelIndex& index,
+ int role) const -> QVariant {
if (!index.isValid()) return {};
if (role == Qt::DisplayRole) {
@@ -232,8 +232,8 @@ class GlobalRegisterTableTreeModel::Impl {
return tr("<UNSUPPORTED>");
}
- [[nodiscard]] auto Index(int row, int column, const QModelIndex& parent) const
- -> QModelIndex {
+ [[nodiscard]] auto Index(int row, int column,
+ const QModelIndex& parent) const -> QModelIndex {
if (!parent_->hasIndex(row, column, parent)) return {};
auto* parent_node = !parent.isValid()
@@ -292,8 +292,8 @@ auto GlobalRegisterTable::PublishKV(Namespace n, Key k, std::any v) -> bool {
return p_->PublishKV(n, k, v);
}
-auto GlobalRegisterTable::LookupKV(Namespace n, Key v)
- -> std::optional<std::any> {
+auto GlobalRegisterTable::LookupKV(Namespace n,
+ Key v) -> std::optional<std::any> {
return p_->LookupKV(n, v);
}
@@ -302,14 +302,15 @@ auto GlobalRegisterTable::ListenPublish(QObject* o, Namespace n, Key k,
return p_->ListenPublish(o, n, k, c);
}
-auto GlobalRegisterTable::ListChildKeys(Namespace n, Key k)
- -> std::vector<Key> {
+auto GlobalRegisterTable::ListChildKeys(Namespace n,
+ Key k) -> std::vector<Key> {
return p_->ListChildKeys(n, k);
}
GlobalRegisterTableTreeModel::GlobalRegisterTableTreeModel(
- GlobalRegisterTable* grt)
- : p_(SecureCreateUniqueObject<Impl>(this, grt->p_.get())) {}
+ GlobalRegisterTable* grt, QObject* parent)
+ : QAbstractItemModel(parent),
+ p_(SecureCreateUniqueObject<Impl>(this, grt->p_.get())) {}
auto GlobalRegisterTableTreeModel::rowCount(const QModelIndex& parent) const
-> int {
@@ -326,9 +327,8 @@ auto GlobalRegisterTableTreeModel::data(const QModelIndex& index,
return p_->Data(index, role);
}
-auto GlobalRegisterTableTreeModel::index(int row, int column,
- const QModelIndex& parent) const
- -> QModelIndex {
+auto GlobalRegisterTableTreeModel::index(
+ int row, int column, const QModelIndex& parent) const -> QModelIndex {
return p_->Index(row, column, parent);
}
diff --git a/src/core/module/GlobalRegisterTableTreeModel.h b/src/core/module/GlobalRegisterTableTreeModel.h
index fe4242a2..b7d56cc1 100644
--- a/src/core/module/GlobalRegisterTableTreeModel.h
+++ b/src/core/module/GlobalRegisterTableTreeModel.h
@@ -34,15 +34,16 @@ namespace GpgFrontend::Module {
class GPGFRONTEND_CORE_EXPORT GlobalRegisterTableTreeModel
: public QAbstractItemModel {
public:
- explicit GlobalRegisterTableTreeModel(GlobalRegisterTable *grt);
+ explicit GlobalRegisterTableTreeModel(GlobalRegisterTable *grt,
+ QObject *parent);
[[nodiscard]] auto rowCount(const QModelIndex &parent) const -> int override;
[[nodiscard]] auto columnCount(const QModelIndex &parent) const
-> int override;
- [[nodiscard]] auto data(const QModelIndex &index, int role) const
- -> QVariant override;
+ [[nodiscard]] auto data(const QModelIndex &index,
+ int role) const -> QVariant override;
[[nodiscard]] auto index(int row, int column, const QModelIndex &parent) const
-> QModelIndex override;
diff --git a/src/core/module/Module.cpp b/src/core/module/Module.cpp
index 9c875fce..78a8810f 100644
--- a/src/core/module/Module.cpp
+++ b/src/core/module/Module.cpp
@@ -31,7 +31,7 @@
#include "core/module/GlobalModuleContext.h"
#include "core/utils/CommonUtils.h"
#include "core/utils/IOUtils.h"
-#include "module/sdk/GFSDKModule.h"
+#include "sdk/GFSDKModule.h"
#include "utils/BuildInfoUtils.h"
namespace GpgFrontend::Module {
@@ -59,9 +59,9 @@ class Module::Impl {
*required_symbol.pointer =
reinterpret_cast<void*>(module_library.resolve(required_symbol.name));
if (*required_symbol.pointer == nullptr) {
- GF_CORE_LOG_WARN(
- "illegal module: {}, reason: cannot load symbol: {}, abort...",
- module_library.fileName(), required_symbol.name);
+ qCWarning(core) << "illegal module: " << module_library.fileName()
+ << ", reason cannot load symbol: "
+ << required_symbol.name << ", abort...";
return;
}
}
@@ -72,39 +72,38 @@ class Module::Impl {
qt_env_ver_ = GFUnStrDup(get_qt_ver_api_());
if (!module_identifier_regex_exp_.match(identifier_).hasMatch()) {
- GF_CORE_LOG_WARN(
- "illegal module: {}, reasson invalid module id, abort...",
- identifier_);
+ qCWarning(core) << "illegal module: " << identifier_
+ << ", reason invalid module id, abort...";
return;
}
if (!module_version_regex_exp_.match(version_).hasMatch()) {
- GF_CORE_LOG_WARN(
- "illegal module: {}, reasson invalid version: {}, abort...",
- identifier_, version_);
+ qCWarning(core) << "illegal module: " << identifier_
+ << ", reason invalid version: " << version_
+ << ", abort...";
return;
}
if (!module_version_regex_exp_.match(gf_sdk_ver_).hasMatch()) {
- GF_CORE_LOG_WARN(
- "illegal module: {}, reasson invalid sdk version: {}, abort...",
- identifier_, gf_sdk_ver_);
+ qCWarning(core) << "illegal module: " << identifier_
+ << ", reason invalid sdk version: " << gf_sdk_ver_
+ << ", abort...";
return;
}
if (GFCompareSoftwareVersion(gf_sdk_ver_, GetProjectVersion()) > 0) {
- GF_CORE_LOG_WARN(
- "uncompatible module: {}, sdk version: {} greater than "
- "current sdk version: {}, abort...",
- identifier_, gf_sdk_ver_, GetProjectVersion());
+ qCWarning(core) << "uncompatible module: " << identifier_
+ << ", reason sdk version: " << gf_sdk_ver_
+ << "current sdk version: " << GetProjectVersion()
+ << ", abort...";
return;
}
auto qt_env_ver_regex_match = module_version_regex_exp_.match(qt_env_ver_);
if (!qt_env_ver_regex_match.hasMatch()) {
- GF_CORE_LOG_WARN(
- "illegal module: {}, reasson invalid qt env version: {}, abort...",
- identifier_, qt_env_ver_);
+ qCWarning(core) << "illegal module: " << identifier_
+ << ", reason invalid qt env version: " << qt_env_ver_
+ << ", abort...";
return;
}
@@ -113,19 +112,13 @@ class Module::Impl {
if (qt_env_ver_major != QString::number(QT_VERSION_MAJOR) + "." ||
qt_env_ver_minor != QString::number(QT_VERSION_MINOR) + ".") {
- GF_CORE_LOG_WARN(
- "uncompatible module: {}, qt version: {} is not binary uncompatible "
- "with application's qt env version: {}, abort...",
- identifier_, qt_env_ver_, QString::fromUtf8(QT_VERSION_STR));
+ qCWarning(core) << "uncompatible module: " << identifier_
+ << ", reason sdk version: " << qt_env_ver_
+ << "current sdk version: "
+ << QString::fromUtf8(QT_VERSION_STR) << ", abort...";
return;
}
- GF_CORE_LOG_INFO(
- "module loaded, id: {}, version: {}, "
- "sdk version: {}, qt env version: {}, hash: {}, path: {}",
- identifier_, version_, gf_sdk_ver_, qt_env_ver_, module_hash_,
- module_library_path_);
-
::GFModuleMetaData* p_meta_data = get_metadata_api_();
while (p_meta_data != nullptr) {
@@ -159,7 +152,7 @@ class Module::Impl {
return -1;
}
- auto Deactive() -> int {
+ auto Deactivate() -> int {
if (good_ && deactivate_api_ != nullptr) return deactivate_api_();
return -1;
}
@@ -255,7 +248,7 @@ class Module::Impl {
{"GFRegisterModule", reinterpret_cast<void**>(&register_api_)},
{"GFActiveModule", reinterpret_cast<void**>(&activate_api_)},
{"GFExecuteModule", reinterpret_cast<void**>(&execute_api_)},
- {"GFDeactiveModule", reinterpret_cast<void**>(&deactivate_api_)},
+ {"GFDeactivateModule", reinterpret_cast<void**>(&deactivate_api_)},
{"GFUnregisterModule", reinterpret_cast<void**>(&unregister_api_)},
};
@@ -286,7 +279,7 @@ auto Module::Exec(EventReference event) -> int {
return p_->Exec(std::move(event));
}
-auto Module::Deactive() -> int { return p_->Deactive(); }
+auto Module::Deactivate() -> int { return p_->Deactivate(); }
auto Module::UnRegister() -> int { return p_->UnRegister(); }
diff --git a/src/core/module/Module.h b/src/core/module/Module.h
index c332d455..e609d64e 100644
--- a/src/core/module/Module.h
+++ b/src/core/module/Module.h
@@ -61,7 +61,7 @@ class GPGFRONTEND_CORE_EXPORT Module : public QObject {
virtual auto Exec(EventReference) -> int;
- virtual auto Deactive() -> int;
+ virtual auto Deactivate() -> int;
virtual auto UnRegister() -> int;
diff --git a/src/core/module/ModuleInit.cpp b/src/core/module/ModuleInit.cpp
index ceb5987e..dc001798 100644
--- a/src/core/module/ModuleInit.cpp
+++ b/src/core/module/ModuleInit.cpp
@@ -39,11 +39,8 @@
namespace GpgFrontend::Module {
void LoadModuleFromPath(const QString& mods_path, bool integrated) {
- for (const auto& module_library_name :
- QDir(mods_path).entryList(QStringList() << "*.so"
- << "*.dll"
- << "*.dylib",
- QDir::Files)) {
+ for (const auto& module_library_name : QDir(mods_path).entryList(
+ QStringList() << "*.so" << "*.dll" << "*.dylib", QDir::Files)) {
ModuleManager::GetInstance().LoadModule(
mods_path + "/" + module_library_name, integrated);
}
@@ -54,34 +51,30 @@ auto LoadIntegratedMods() -> bool {
#if defined(MACOS) && defined(RELEASE)
// App Bundle
- auto mods_path = exec_binary_path + "/../PlugIns/mods";
+ auto mods_path = exec_binary_path + "/../Modules";
#else
// Debug Or Windows Platform
- auto mods_path = exec_binary_path + "/mods";
+ auto mods_path = exec_binary_path + "/modules";
#endif
// AppImage
if (!qEnvironmentVariable("APPIMAGE").isEmpty()) {
- mods_path = qEnvironmentVariable("APPDIR") + "/usr/plugins/mods";
+ mods_path = qEnvironmentVariable("APPDIR") + "/usr/modules";
}
// Flatpak
if (!qEnvironmentVariable("container").isEmpty()) {
- mods_path = "/app/lib/mods";
+ mods_path = "/app/modules";
}
- GF_CORE_LOG_DEBUG("try loading integrated modules at path: {} ...",
- mods_path);
if (!QDir(mods_path).exists()) {
- GF_CORE_LOG_WARN(
- "integrated module directory at path {} not found, abort...",
- mods_path);
+ qCWarning(core) << "integrated module directory at path: " << mods_path
+ << " not found, abort...";
return false;
}
LoadModuleFromPath(mods_path, true);
- GF_CORE_LOG_DEBUG("load integrated modules done.");
return true;
}
@@ -89,16 +82,14 @@ auto LoadExternalMods() -> bool {
auto mods_path =
GpgFrontend::GlobalSettingStation::GetInstance().GetModulesDir();
- GF_CORE_LOG_DEBUG("try loading external modules at path: {} ...", mods_path);
if (!QDir(mods_path).exists()) {
- GF_CORE_LOG_WARN("external module directory at path {} not found, abort...",
- mods_path);
+ qCWarning(core) << "external module directory at path " << mods_path
+ << " not found, abort...";
return false;
}
LoadModuleFromPath(mods_path, false);
- GF_CORE_LOG_DEBUG("load integrated modules done.");
return true;
}
diff --git a/src/core/module/ModuleInit.h b/src/core/module/ModuleInit.h
index e7e86f0f..c4f121ba 100644
--- a/src/core/module/ModuleInit.h
+++ b/src/core/module/ModuleInit.h
@@ -28,15 +28,11 @@
#pragma once
-#include <spdlog/spdlog.h>
-
#include "core/GpgFrontendCoreExport.h"
namespace GpgFrontend::Module {
-struct ModuleInitArgs {
- spdlog::level::level_enum log_level;
-};
+struct ModuleInitArgs {};
/**
* @brief init the module library
diff --git a/src/core/module/ModuleManager.cpp b/src/core/module/ModuleManager.cpp
index d07ca989..d575d40c 100644
--- a/src/core/module/ModuleManager.cpp
+++ b/src/core/module/ModuleManager.cpp
@@ -31,6 +31,7 @@
#include <memory>
#include <utility>
+#include "core/function/GlobalSettingStation.h"
#include "core/function/SecureMemoryAllocator.h"
#include "core/function/basic/GpgFunctionObject.h"
#include "core/model/SettingsObject.h"
@@ -54,25 +55,31 @@ class ModuleManager::Impl {
auto LoadAndRegisterModule(const QString& module_library_path,
bool integrated_module) -> void {
+ // give user ability to give up all modules
+ auto disable_loading_all_modules =
+ GlobalSettingStation::GetInstance()
+ .GetSettings()
+ .value("basic/disable_loading_all_modules", false)
+ .toBool();
+ if (disable_loading_all_modules) return;
+
Thread::TaskRunnerGetter::GetInstance()
.GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default)
->PostTask(new Thread::Task(
[=](GpgFrontend::DataObjectPtr) -> int {
QLibrary module_library(module_library_path);
if (!module_library.load()) {
- GF_CORE_LOG_WARN(
- "module manager failed to load module, "
- "reason: broken library: {} ",
- module_library.fileName());
+ qCWarning(core) << "module manager failed to load module: "
+ << module_library.fileName()
+ << ", reason: " << module_library.errorString();
return -1;
}
auto module = SecureCreateSharedObject<Module>(module_library);
if (!module->IsGood()) {
- GF_CORE_LOG_WARN(
- "module manager failed to load module, "
- "reason: illegal module: {}",
- module_library.fileName());
+ qCWarning(core) << "module manager failed to load module, "
+ "reason: illegal module: "
+ << module_library.fileName();
return -1;
}
@@ -172,7 +179,7 @@ class ModuleManager::Impl {
__func__, nullptr));
}
- void DeactiveModule(const ModuleIdentifier& identifier) {
+ void DeactivateModule(const ModuleIdentifier& identifier) {
Thread::TaskRunnerGetter::GetInstance()
.GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default)
->PostTask(new Thread::Task(
@@ -231,13 +238,13 @@ auto UpsertRTValue(const QString& namespace_, const QString& key,
std::any(value));
}
-auto ListenRTPublishEvent(QObject* o, Namespace n, Key k, LPCallback c)
- -> bool {
+auto ListenRTPublishEvent(QObject* o, Namespace n, Key k,
+ LPCallback c) -> bool {
return ModuleManager::GetInstance().ListenRTPublish(o, n, k, c);
}
-auto ListRTChildKeys(const QString& namespace_, const QString& key)
- -> std::vector<Key> {
+auto ListRTChildKeys(const QString& namespace_,
+ const QString& key) -> std::vector<Key> {
return ModuleManager::GetInstance().ListRTChildKeys(namespace_, key);
}
@@ -283,8 +290,8 @@ void ModuleManager::ActiveModule(ModuleIdentifier id) {
return p_->ActiveModule(id);
}
-void ModuleManager::DeactiveModule(ModuleIdentifier id) {
- return p_->DeactiveModule(id);
+void ModuleManager::DeactivateModule(ModuleIdentifier id) {
+ return p_->DeactivateModule(id);
}
auto ModuleManager::GetTaskRunner(ModuleIdentifier id)
@@ -296,8 +303,8 @@ auto ModuleManager::UpsertRTValue(Namespace n, Key k, std::any v) -> bool {
return p_->UpsertRTValue(n, k, v);
}
-auto ModuleManager::RetrieveRTValue(Namespace n, Key k)
- -> std::optional<std::any> {
+auto ModuleManager::RetrieveRTValue(Namespace n,
+ Key k) -> std::optional<std::any> {
return p_->RetrieveRTValue(n, k);
}
@@ -306,8 +313,8 @@ auto ModuleManager::ListenRTPublish(QObject* o, Namespace n, Key k,
return p_->ListenPublish(o, n, k, c);
}
-auto ModuleManager::ListRTChildKeys(const QString& n, const QString& k)
- -> std::vector<Key> {
+auto ModuleManager::ListRTChildKeys(const QString& n,
+ const QString& k) -> std::vector<Key> {
return p_->ListRTChildKeys(n, k);
}
diff --git a/src/core/module/ModuleManager.h b/src/core/module/ModuleManager.h
index ea2d88cb..9f7fab18 100644
--- a/src/core/module/ModuleManager.h
+++ b/src/core/module/ModuleManager.h
@@ -28,7 +28,6 @@
#pragma once
-#include <mutex>
#include <vector>
#include "core/function/SecureMemoryAllocator.h"
@@ -88,7 +87,7 @@ class GPGFRONTEND_CORE_EXPORT ModuleManager
void ActiveModule(ModuleIdentifier);
- void DeactiveModule(ModuleIdentifier);
+ void DeactivateModule(ModuleIdentifier);
auto GetTaskRunner(ModuleIdentifier) -> std::optional<TaskRunnerPtr>;
@@ -123,10 +122,10 @@ void RegisterAndActivateModule(Args&&... args) {
}
template <typename... Args>
-void TriggerEvent(const EventIdentifier& event_id, Args&&... args,
+void TriggerEvent(const EventIdentifier& event_id,
+ const Event::Params& params = {},
Event::EventCallback e_cb = nullptr) {
- ModuleManager::GetInstance().TriggerEvent(
- std::move(MakeEvent(event_id, std::forward<Args>(args)..., e_cb)));
+ ModuleManager::GetInstance().TriggerEvent(MakeEvent(event_id, params, e_cb));
}
/**
@@ -166,13 +165,12 @@ auto GPGFRONTEND_CORE_EXPORT ListenRTPublishEvent(QObject*, Namespace, Key,
* @param key
* @return std::vector<Key>
*/
-auto GPGFRONTEND_CORE_EXPORT ListRTChildKeys(const QString& namespace_,
- const QString& key)
- -> std::vector<Key>;
+auto GPGFRONTEND_CORE_EXPORT ListRTChildKeys(
+ const QString& namespace_, const QString& key) -> std::vector<Key>;
template <typename T>
-auto RetrieveRTValueTyped(const QString& namespace_, const QString& key)
- -> std::optional<T> {
+auto RetrieveRTValueTyped(const QString& namespace_,
+ const QString& key) -> std::optional<T> {
auto any_value =
ModuleManager::GetInstance().RetrieveRTValue(namespace_, key);
if (any_value && any_value->type() == typeid(T)) {
@@ -183,8 +181,8 @@ auto RetrieveRTValueTyped(const QString& namespace_, const QString& key)
template <typename T>
auto RetrieveRTValueTypedOrDefault(const QString& namespace_,
- const QString& key, const T& defaultValue)
- -> T {
+ const QString& key,
+ const T& defaultValue) -> T {
auto any_value =
ModuleManager::GetInstance().RetrieveRTValue(namespace_, key);
if (any_value && any_value->type() == typeid(T)) {
diff --git a/src/core/thread/FileReadTask.cpp b/src/core/thread/FileReadTask.cpp
index 49a3f540..78cd99e9 100644
--- a/src/core/thread/FileReadTask.cpp
+++ b/src/core/thread/FileReadTask.cpp
@@ -41,17 +41,15 @@ FileReadTask::FileReadTask(QString path)
auto FileReadTask::Run() -> int {
if (QFileInfo(read_file_path_).isFile()) {
- GF_CORE_LOG_DEBUG("read open file: {}", read_file_path_);
-
target_file_.setFileName(read_file_path_);
target_file_.open(QIODevice::ReadOnly);
if (!(target_file_.isOpen() && target_file_.isReadable())) {
- GF_CORE_LOG_ERROR("file not open or not readable");
+ qCWarning(core, "file not open or not readable");
if (target_file_.isOpen()) target_file_.close();
return -1;
}
- GF_CORE_LOG_DEBUG("started reading: {}", read_file_path_);
+
slot_read_bytes();
} else {
emit SignalFileBytesReadEnd();
@@ -64,10 +62,8 @@ void FileReadTask::slot_read_bytes() {
if (QByteArray read_buffer;
!target_file_.atEnd() &&
(read_buffer = target_file_.read(kBufferSize)).size() > 0) {
- GF_CORE_LOG_DEBUG("io thread read bytes: {}", read_buffer.size());
emit SignalFileBytesRead(std::move(read_buffer));
} else {
- GF_CORE_LOG_DEBUG("io thread read bytes end");
emit SignalFileBytesReadEnd();
// announce finish task
emit SignalTaskShouldEnd(0);
@@ -75,7 +71,6 @@ void FileReadTask::slot_read_bytes() {
}
FileReadTask::~FileReadTask() {
- GF_CORE_LOG_DEBUG("close file: {}", read_file_path_);
if (target_file_.isOpen()) target_file_.close();
}
diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp
index dc0cfe94..14818aca 100644
--- a/src/core/thread/Task.cpp
+++ b/src/core/thread/Task.cpp
@@ -38,7 +38,6 @@ class Task::Impl {
public:
Impl(Task *parent, QString name)
: parent_(parent), uuid_(generate_uuid()), name_(std::move(name)) {
- GF_CORE_LOG_TRACE("task {} created", GetFullID());
init();
}
@@ -51,8 +50,6 @@ class Task::Impl {
callback_([](int, const DataObjectPtr &) {}),
callback_thread_(QThread::currentThread()),
data_object_(std::move(data_object)) {
- GF_CORE_LOG_TRACE("task {} created with runnable, callback_thread_: {}",
- GetFullID(), static_cast<void *>(callback_thread_));
init();
}
@@ -65,13 +62,10 @@ class Task::Impl {
callback_(std::move(callback)),
callback_thread_(QThread::currentThread()),
data_object_(std::move(data_object)) {
- GF_CORE_LOG_TRACE(
- "task {} created with runnable and callback, callback_thread_: {}",
- GetFullID(), static_cast<void *>(callback_thread_));
init();
}
- ~Impl() { GF_CORE_LOG_TRACE("task {} destroyed", GetFullID()); }
+ ~Impl() = default;
/**
* @brief
@@ -95,13 +89,7 @@ class Task::Impl {
* @return int
*/
auto Run() -> int {
- GF_CORE_LOG_TRACE("task {} is in classical runnable and callback mode",
- GetFullID());
-
if (runnable_) return runnable_(data_object_);
-
- GF_CORE_LOG_WARN("no runnable in task, do callback operation, task: {}",
- GetFullID());
return 0;
}
@@ -137,9 +125,6 @@ class Task::Impl {
DataObjectPtr data_object_ = nullptr; ///<
void init() {
- GF_CORE_LOG_TRACE("task {} created, parent: {}, impl: {}", name_,
- static_cast<void *>(parent_), static_cast<void *>(this));
-
//
HoldOnLifeCycle(false);
@@ -156,17 +141,11 @@ class Task::Impl {
SetRTN(rtn);
try {
if (callback_) {
- GF_CORE_LOG_TRACE(
- "task callback {} is starting with runnerable rtn: {}",
- GetFullID(), rtn);
-
callback_(rtn_, data_object_);
- GF_CORE_LOG_TRACE("task callback {} finished, rtn: {}",
- GetFullID(), rtn);
}
} catch (...) {
- GF_CORE_LOG_ERROR("task {} callback caught exception, rtn: {}",
- GetFullID(), rtn);
+ qCWarning(core) << "task: {}, " << GetFullID()
+ << "callback caught exception, rtn: " << rtn;
}
emit parent_->SignalTaskEnd();
});
@@ -214,11 +193,7 @@ void Task::SafelyRun() { emit SignalRun(); }
int Task::Run() { return p_->Run(); }
-void Task::run() {
- GF_CORE_LOG_TRACE("interface run() of task {} was called by thread: {}",
- GetFullID(), QThread::currentThread()->currentThreadId());
- this->SafelyRun();
-}
+void Task::run() { this->SafelyRun(); }
Task::TaskHandler::TaskHandler(Task *task) : task_(task) {}
@@ -238,14 +213,11 @@ auto Task::TaskHandler::GetTask() -> Task * {
void Task::slot_exception_safe_run() noexcept {
auto rtn = p_->GetRTN();
try {
- GF_CORE_LOG_TRACE("task runnable {} is starting...", GetFullID());
-
// Run() will set rtn by itself
rtn = this->Run();
- GF_CORE_LOG_TRACE("task runnable {} finished, rtn: {}", GetFullID());
} catch (...) {
- GF_CORE_LOG_ERROR("exception was caught at task: {}", GetFullID());
+ qCWarning(core) << "exception was caught at task: {}" << GetFullID();
}
// raise signal to anounce after runnable returned
diff --git a/src/core/thread/TaskRunner.cpp b/src/core/thread/TaskRunner.cpp
index 8e381384..0837b7b8 100644
--- a/src/core/thread/TaskRunner.cpp
+++ b/src/core/thread/TaskRunner.cpp
@@ -38,21 +38,19 @@ class TaskRunner::Impl : public QThread {
void PostTask(Task* task) {
if (task == nullptr) {
- GF_CORE_LOG_ERROR("task posted is null");
+ qCWarning(core, "task posted is null");
return;
}
task->setParent(nullptr);
task->moveToThread(this);
- GF_CORE_LOG_TRACE("runner starts task: {} at thread: {}", task->GetFullID(),
- this->currentThreadId());
task->SafelyRun();
}
auto RegisterTask(const QString& name, const Task::TaskRunnable& runnerable,
- const Task::TaskCallback& cb, DataObjectPtr params)
- -> Task::TaskHandler {
+ const Task::TaskCallback& cb,
+ DataObjectPtr params) -> Task::TaskHandler {
auto* raw_task = new Task(runnerable, name, std::move(params), cb);
raw_task->setParent(nullptr);
raw_task->moveToThread(this);
@@ -65,9 +63,6 @@ class TaskRunner::Impl : public QThread {
pending_tasks_.remove(raw_task->GetFullID());
});
- GF_CORE_LOG_TRACE("runner starts task: {} at thread: {}",
- raw_task->GetFullID(), this->currentThreadId());
-
return Task::TaskHandler(raw_task);
}
@@ -78,7 +73,7 @@ class TaskRunner::Impl : public QThread {
void PostConcurrentTask(Task* task) {
if (task == nullptr) {
- GF_CORE_LOG_ERROR("task posted is null");
+ qCWarning(core, "task posted is null");
return;
}
@@ -93,8 +88,6 @@ class TaskRunner::Impl : public QThread {
concurrent_thread->start();
- GF_CORE_LOG_TRACE("runner starts task concurrenctly: {}",
- task->GetFullID());
task->SafelyRun();
}
@@ -143,8 +136,8 @@ auto TaskRunner::IsRunning() -> bool { return p_->isRunning(); }
auto TaskRunner::RegisterTask(const QString& name,
const Task::TaskRunnable& runnable,
- const Task::TaskCallback& cb, DataObjectPtr p_pbj)
- -> Task::TaskHandler {
+ const Task::TaskCallback& cb,
+ DataObjectPtr p_pbj) -> Task::TaskHandler {
return p_->RegisterTask(name, runnable, cb, p_pbj);
}
} // namespace GpgFrontend::Thread
diff --git a/src/core/typedef/GpgTypedef.h b/src/core/typedef/GpgTypedef.h
index 599c5c59..730bd4ee 100644
--- a/src/core/typedef/GpgTypedef.h
+++ b/src/core/typedef/GpgTypedef.h
@@ -58,6 +58,8 @@ using GpgKeyLinkList = std::list<GpgKey>; ///<
using KeyLinkListPtr = std::unique_ptr<GpgKeyLinkList>; ///<
using KeyPtr = std::unique_ptr<GpgKey>; ///<
using KeyPtrArgsList = const std::initializer_list<KeyPtr>; ///<
+using GpgKeyList = QList<GpgKey>; ///<
+using GpgKeyIDList = QList<QString>; ///<
using GpgSignMode = gpgme_sig_mode_t;
diff --git a/src/core/utils/AsyncUtils.cpp b/src/core/utils/AsyncUtils.cpp
index 3c007fb6..7d746bbc 100644
--- a/src/core/utils/AsyncUtils.cpp
+++ b/src/core/utils/AsyncUtils.cpp
@@ -42,12 +42,10 @@ auto RunGpgOperaAsync(const GpgOperaRunnable& runnable,
-> Thread::Task::TaskHandler {
const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
"core", "gpgme.ctx.gnupg_version", minial_version);
- GF_CORE_LOG_DEBUG("got gnupg version from rt: {}, operation: {}",
- gnupg_version, operation);
if (GFCompareSoftwareVersion(gnupg_version, minial_version) < 0) {
- GF_CORE_LOG_ERROR("operaton {} not support for gnupg version: {}",
- operation, gnupg_version);
+ qCWarning(core) << "operation" << operation
+ << " not support for gnupg version: " << gnupg_version;
callback(GPG_ERR_NOT_SUPPORTED, TransferParams());
return Thread::Task::TaskHandler(nullptr);
}
@@ -82,12 +80,10 @@ auto RunGpgOperaSync(const GpgOperaRunnable& runnable, const QString& operation,
-> std::tuple<GpgError, DataObjectPtr> {
const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
"core", "gpgme.ctx.gnupg_version", minial_version);
- GF_CORE_LOG_DEBUG("got gnupg version from rt: {}, operation: {}",
- gnupg_version, operation);
if (GFCompareSoftwareVersion(gnupg_version, minial_version) < 0) {
- GF_CORE_LOG_ERROR("operaton {} not support for gnupg version: {}",
- operation, gnupg_version);
+ qCWarning(core) << "operation" << operation
+ << " not support for gnupg version: " << gnupg_version;
return {GPG_ERR_NOT_SUPPORTED, TransferParams()};
}
@@ -125,8 +121,8 @@ auto RunIOOperaAsync(const OperaRunnable& runnable,
}
auto RunOperaAsync(const OperaRunnable& runnable,
- const OperationCallback& callback, const QString& operation)
- -> Thread::Task::TaskHandler {
+ const OperationCallback& callback,
+ const QString& operation) -> Thread::Task::TaskHandler {
auto handler =
Thread::TaskRunnerGetter::GetInstance()
.GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default)
diff --git a/src/core/utils/BuildInfoUtils.cpp b/src/core/utils/BuildInfoUtils.cpp
index a7d914ef..65a0b43a 100644
--- a/src/core/utils/BuildInfoUtils.cpp
+++ b/src/core/utils/BuildInfoUtils.cpp
@@ -5,9 +5,12 @@
namespace GpgFrontend {
+auto GetProjectName() -> QString { return {PROJECT_NAME}; }
+
auto GetProjectVersion() -> QString {
- return QString("v") + VERSION_MAJOR + "." + VERSION_MINOR + "." +
- VERSION_PATCH;
+ return (QStringList{} << "v" << VERSION_MAJOR << "." << VERSION_MINOR << "."
+ << VERSION_PATCH)
+ .join("");
}
auto GetProjectBuildVersion() -> QString { return BUILD_VERSION; }
diff --git a/src/core/utils/BuildInfoUtils.h b/src/core/utils/BuildInfoUtils.h
index 07b0bb21..dfc9efe3 100644
--- a/src/core/utils/BuildInfoUtils.h
+++ b/src/core/utils/BuildInfoUtils.h
@@ -37,6 +37,13 @@ namespace GpgFrontend {
*
* @return QString
*/
+auto GPGFRONTEND_CORE_EXPORT GetProjectName() -> QString;
+
+/**
+ * @brief
+ *
+ * @return QString
+ */
auto GPGFRONTEND_CORE_EXPORT GetProjectVersion() -> QString;
/**
diff --git a/src/core/utils/CommonUtils.cpp b/src/core/utils/CommonUtils.cpp
index d1704312..941ea39f 100644
--- a/src/core/utils/CommonUtils.cpp
+++ b/src/core/utils/CommonUtils.cpp
@@ -82,13 +82,13 @@ auto GFStrDup(const QString& str) -> char* {
return c_str;
}
-auto GPGFRONTEND_CORE_EXPORT GFUnStrDup(char* str) -> QString {
+auto GFUnStrDup(char* str) -> QString {
auto qt_str = QString::fromUtf8(str);
SecureFree(static_cast<void*>(const_cast<char*>(str)));
return qt_str;
}
-auto GPGFRONTEND_CORE_EXPORT GFUnStrDup(const char* str) -> QString {
+auto GFUnStrDup(const char* str) -> QString {
return GFUnStrDup(const_cast<char*>(str));
}
diff --git a/src/core/utils/CommonUtils.h b/src/core/utils/CommonUtils.h
index 6ef38fad..bd546a11 100644
--- a/src/core/utils/CommonUtils.h
+++ b/src/core/utils/CommonUtils.h
@@ -48,21 +48,21 @@ auto GPGFRONTEND_CORE_EXPORT BeautifyFingerprint(QString fingerprint)
* @param b
* @return int
*/
-auto GPGFRONTEND_CORE_EXPORT GFCompareSoftwareVersion(const QString& a,
- const QString& b) -> int;
+auto GPGFRONTEND_CORE_EXPORT GFCompareSoftwareVersion(const QString &a,
+ const QString &b) -> int;
/**
* @brief
*
* @return char*
*/
-auto GPGFRONTEND_CORE_EXPORT GFStrDup(const QString&) -> char*;
+auto GFStrDup(const QString &) -> char *;
/**
* @brief
*
* @return QString
*/
-auto GPGFRONTEND_CORE_EXPORT GFUnStrDup(const char*) -> QString;
+auto GFUnStrDup(const char *) -> QString;
} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/utils/GpgUtils.cpp b/src/core/utils/GpgUtils.cpp
index 0d00b13e..1d81b272 100644
--- a/src/core/utils/GpgUtils.cpp
+++ b/src/core/utils/GpgUtils.cpp
@@ -50,9 +50,9 @@ auto GetGpgmeErrorString(gpgme_error_t err) -> QString {
auto CheckGpgError(GpgError err) -> GpgError {
auto err_code = gpg_err_code(err);
if (err_code != GPG_ERR_NO_ERROR) {
- GF_CORE_LOG_ERROR(
- "gpg operation failed [error code: {}], source: {} description: {}",
- err_code, gpgme_strsource(err), GetGpgmeErrorString(err));
+ qCWarning(core) << "gpg operation failed [error code: " << err_code
+ << "], source: " << gpgme_strsource(err)
+ << " description: " << GetGpgmeErrorString(err);
}
return err_code;
}
@@ -61,13 +61,15 @@ auto CheckGpgError2ErrCode(GpgError err, GpgError predict) -> GpgErrorCode {
auto err_code = gpg_err_code(err);
if (err_code != gpg_err_code(predict)) {
if (err_code == GPG_ERR_NO_ERROR) {
- GF_CORE_LOG_WARN("[Warning {}] Source: {} description: {} predict: {}",
- gpg_err_code(err), gpgme_strsource(err),
- GetGpgmeErrorString(err), GetGpgmeErrorString(predict));
+ qCInfo(core) << "[Warning " << gpg_err_code(err)
+ << "] Source: " << gpgme_strsource(err)
+ << " description: " << GetGpgmeErrorString(err)
+ << " predict: " << GetGpgmeErrorString(predict);
} else {
- GF_CORE_LOG_ERROR("[Error {}] Source: {} description: {} predict: {}",
- gpg_err_code(err), gpgme_strsource(err),
- GetGpgmeErrorString(err), GetGpgmeErrorString(predict));
+ qCWarning(core) << "[Error " << gpg_err_code(err)
+ << "] Source: " << gpgme_strsource(err)
+ << " description: " << GetGpgmeErrorString(err)
+ << " predict: " << GetGpgmeErrorString(predict);
}
}
return err_code;
@@ -79,8 +81,9 @@ auto DescribeGpgErrCode(GpgError err) -> GpgErrorDesc {
auto CheckGpgError(GpgError err, const QString& /*comment*/) -> GpgError {
if (gpg_err_code(err) != GPG_ERR_NO_ERROR) {
- GF_CORE_LOG_WARN("[Error {}] Source: {} description: {}", gpg_err_code(err),
- gpgme_strsource(err), GetGpgmeErrorString(err));
+ qCWarning(core) << "[Error " << gpg_err_code(err)
+ << "] Source: " << gpgme_strsource(err)
+ << " description: " << GetGpgmeErrorString(err);
}
return err;
}
diff --git a/src/core/utils/IOUtils.cpp b/src/core/utils/IOUtils.cpp
index 0be11755..409cff19 100644
--- a/src/core/utils/IOUtils.cpp
+++ b/src/core/utils/IOUtils.cpp
@@ -49,7 +49,7 @@ auto GetFileChecksum(const QString& file_name,
auto ReadFile(const QString& file_name, QByteArray& data) -> bool {
QFile file(file_name);
if (!file.open(QIODevice::ReadOnly)) {
- GF_CORE_LOG_ERROR("failed to open file: {}", file_name);
+ qCWarning(core) << "failed to open file: " << file_name;
return false;
}
data = file.readAll();
@@ -60,7 +60,7 @@ auto ReadFile(const QString& file_name, QByteArray& data) -> bool {
auto WriteFile(const QString& file_name, const QByteArray& data) -> bool {
QFile file(file_name);
if (!file.open(QIODevice::WriteOnly)) {
- GF_CORE_LOG_ERROR("failed to open file for writing: {}", file_name);
+ qCWarning(core) << "failed to open file for writing: " << file_name;
return false;
}
file.write(data);
@@ -100,20 +100,17 @@ auto CalculateHash(const QString& file_path) -> QString {
<< Qt::endl;
// md5
- ss << "- "
- << "MD5" << QCoreApplication::tr(": ")
+ ss << "- " << "MD5" << QCoreApplication::tr(": ")
<< GetFileChecksum(file_path, QCryptographicHash::Md5).toHex()
<< Qt::endl;
// sha1
- ss << "- "
- << "SHA1" << QCoreApplication::tr(": ")
+ ss << "- " << "SHA1" << QCoreApplication::tr(": ")
<< GetFileChecksum(file_path, QCryptographicHash::Sha1).toHex()
<< Qt::endl;
// sha1
- ss << "- "
- << "SHA256" << QCoreApplication::tr(": ")
+ ss << "- " << "SHA256" << QCoreApplication::tr(": ")
<< GetFileChecksum(file_path, QCryptographicHash::Sha256).toHex()
<< Qt::endl;
@@ -147,8 +144,8 @@ auto CreateTempFileAndWriteData(const GFBuffer& data) -> QString {
return temp_file;
}
-auto TargetFilePreCheck(const QString& path, bool read)
- -> std::tuple<bool, QString> {
+auto TargetFilePreCheck(const QString& path,
+ bool read) -> std::tuple<bool, QString> {
QFileInfo const file_info(path);
if (read) {
@@ -184,16 +181,16 @@ auto CalculateBinaryChacksum(const QString& path) -> QString {
// check file info and access rights
QFileInfo info(path);
if (!info.exists() || !info.isFile() || !info.isReadable()) {
- GF_CORE_LOG_ERROR("get info for file {} error, exists: {}", info.filePath(),
- info.exists());
+ qCWarning(core) << "get info for file: " << info.filePath()
+ << " error, exists: " << info.exists();
return {};
}
// open and read file
QFile f(info.filePath());
if (!f.open(QIODevice::ReadOnly)) {
- GF_CORE_LOG_ERROR("open {} to calculate checksum error: {}",
- path.toStdString(), f.errorString().toStdString());
+ qCWarning(core) << "open " << path
+ << "to calculate checksum error: " << f.errorString();
return {};
}
@@ -204,8 +201,8 @@ auto CalculateBinaryChacksum(const QString& path) -> QString {
while (!f.atEnd()) {
QByteArray const buffer = f.read(buffer_size);
if (buffer.isEmpty()) {
- GF_CORE_LOG_ERROR("error reading file {} during checksum calculation",
- path.toStdString());
+ qCWarning(core) << "error reading file: " << path
+ << " during checksum calculation";
return {};
}
hash_sha.addData(buffer);
diff --git a/src/core/utils/LocalizedUtils.cpp b/src/core/utils/LocalizedUtils.cpp
index e5c9b434..f38b004b 100644
--- a/src/core/utils/LocalizedUtils.cpp
+++ b/src/core/utils/LocalizedUtils.cpp
@@ -28,8 +28,6 @@
#include "LocalizedUtils.h"
-#include "core/utils/LogUtils.h"
-
namespace GpgFrontend {
auto GetLocalizedDateByTimestamp(time_t timestamp) -> QString {
diff --git a/src/core/utils/LogUtils.cpp b/src/core/utils/LogUtils.cpp
deleted file mode 100644
index fbf0c8d3..00000000
--- a/src/core/utils/LogUtils.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric <[email protected]>
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend 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.
- *
- * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric <[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#include "LogUtils.h"
-
-#include "core/function/LoggerManager.h"
-
-namespace GpgFrontend {
-
-auto GetDefaultLogger() -> std::shared_ptr<spdlog::logger> {
- return LoggerManager::GetDefaultLogger();
-}
-
-auto GetCoreLogger() -> std::shared_ptr<spdlog::logger> {
- return LoggerManager::GetInstance().GetLogger("core");
-}
-
-auto GetLogger(const QString& id) -> std::shared_ptr<spdlog::logger> {
- return LoggerManager::GetInstance().GetLogger(id);
-}
-
-void SetDefaultLogLevel(spdlog::level::level_enum level) {
- return LoggerManager::SetDefaultLogLevel(level);
-}
-
-void RegisterAsyncLogger(const QString& id, spdlog::level::level_enum level) {
- LoggerManager::GetInstance().RegisterAsyncLogger(id, level);
-}
-
-void RegisterSyncLogger(const QString& id, spdlog::level::level_enum level) {
- LoggerManager::GetInstance().RegisterSyncLogger(id, level);
-}
-
-} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/utils/LogUtils.h b/src/core/utils/LogUtils.h
deleted file mode 100644
index e8dc6f3b..00000000
--- a/src/core/utils/LogUtils.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric <[email protected]>
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend 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.
- *
- * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric <[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#pragma once
-
-// spdlog library configuration
-#undef SPDLOG_ACTIVE_LEVEL
-#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_TRACE
-#include <spdlog/spdlog.h>
-
-// logger fmt
-#include "core/GpgFrontendCoreExport.h"
-
-template <>
-struct fmt::formatter<QString> {
- // Parses format specifications.
- constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
- return ctx.begin();
- }
-
- // Formats the QString qstr and writes it to the output.
- template <typename FormatContext>
- auto format(const QString& qstr, FormatContext& ctx) const
- -> decltype(ctx.out()) {
- // Convert QString to UTF-8 QString (to handle Unicode characters
- // correctly)
- QByteArray utf8_array = qstr.toUtf8();
- return fmt::format_to(ctx.out(), "{}", utf8_array.constData());
- }
-};
-
-template <>
-struct fmt::formatter<QByteArray> {
- // Parses format specifications.
- constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
- return ctx.begin();
- }
-
- // Formats the QString qstr and writes it to the output.
- template <typename FormatContext>
- auto format(const QByteArray& qarray, FormatContext& ctx) const
- -> decltype(ctx.out()) {
- // Convert QString to UTF-8 QString (to handle Unicode characters
- // correctly)
- return fmt::format_to(ctx.out(), "{}", qarray.constData());
- }
-};
-
-namespace GpgFrontend {
-
-/**
- * @brief
- *
- * @return std::shared_ptr<spdlog::logger>
- */
-auto GPGFRONTEND_CORE_EXPORT GetDefaultLogger()
- -> std::shared_ptr<spdlog::logger>;
-
-/**
- * @brief
- *
- * @return std::shared_ptr<spdlog::logger>
- */
-auto GPGFRONTEND_CORE_EXPORT GetCoreLogger() -> std::shared_ptr<spdlog::logger>;
-
-/**
- * @brief
- *
- * @return std::shared_ptr<spdlog::logger>
- */
-auto GPGFRONTEND_CORE_EXPORT GetLogger(const QString&)
- -> std::shared_ptr<spdlog::logger>;
-
-/**
- * @brief Set the Default Log Level object
- *
- * @return auto
- */
-void GPGFRONTEND_CORE_EXPORT SetDefaultLogLevel(spdlog::level::level_enum);
-
-/**
- * @brief
- *
- * @return auto
- */
-void GPGFRONTEND_CORE_EXPORT RegisterAsyncLogger(const QString&,
- spdlog::level::level_enum);
-
-/**
- * @brief
- *
- * @return auto
- */
-void GPGFRONTEND_CORE_EXPORT RegisterSyncLogger(const QString&,
- spdlog::level::level_enum);
-
-} // namespace GpgFrontend
-
-#define GF_DEFAULT_LOG_TRACE(...) \
- SPDLOG_LOGGER_TRACE(GpgFrontend::GetDefaultLogger(), __VA_ARGS__)
-#define GF_DEFAULT_LOG_DEBUG(...) \
- SPDLOG_LOGGER_DEBUG(GpgFrontend::GetDefaultLogger(), __VA_ARGS__)
-#define GF_DEFAULT_LOG_INFO(...) \
- SPDLOG_LOGGER_INFO(GpgFrontend::GetDefaultLogger(), __VA_ARGS__)
-#define GF_DEFAULT_LOG_WARN(...) \
- SPDLOG_LOGGER_WARN(GpgFrontend::GetDefaultLogger(), __VA_ARGS__)
-#define GF_DEFAULT_LOG_ERROR(...) \
- SPDLOG_LOGGER_ERROR(GpgFrontend::GetDefaultLogger(), __VA_ARGS__)
-
-#define GF_CORE_LOG_TRACE(...) \
- SPDLOG_LOGGER_TRACE(GpgFrontend::GetCoreLogger(), __VA_ARGS__)
-#define GF_CORE_LOG_DEBUG(...) \
- SPDLOG_LOGGER_DEBUG(GpgFrontend::GetCoreLogger(), __VA_ARGS__)
-#define GF_CORE_LOG_INFO(...) \
- SPDLOG_LOGGER_INFO(GpgFrontend::GetCoreLogger(), __VA_ARGS__)
-#define GF_CORE_LOG_WARN(...) \
- SPDLOG_LOGGER_WARN(GpgFrontend::GetCoreLogger(), __VA_ARGS__)
-#define GF_CORE_LOG_ERROR(...) \
- SPDLOG_LOGGER_ERROR(GpgFrontend::GetCoreLogger(), __VA_ARGS__)
-
-#define GF_LOG_TRACE(ID, ...) \
- SPDLOG_LOGGER_TRACE(GpgFrontend::GetLogger(ID), __VA_ARGS__)
-#define GF_LOG_DEBUG(ID, ...) \
- SPDLOG_LOGGER_DEBUG(GpgFrontend::GetLogger(ID), __VA_ARGS__)
-#define GF_LOG_INFO(ID, ...) \
- SPDLOG_LOGGER_INFO(GpgFrontend::GetLogger(ID), __VA_ARGS__)
-#define GF_LOG_WARN(ID, ...) \
- SPDLOG_LOGGER_WARN(GpgFrontend::GetLogger(ID), __VA_ARGS__)
-#define GF_LOG_ERROR(ID, ...) \
- SPDLOG_LOGGER_ERROR(GpgFrontend::GetLogger(ID), __VA_ARGS__)
diff --git a/src/init.cpp b/src/init.cpp
index da89be1f..666d6701 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -33,12 +33,10 @@
#include "core/function/gpg/GpgAdvancedOperator.h"
#include "core/module/ModuleInit.h"
#include "core/thread/TaskRunnerGetter.h"
-#include "core/utils/LogUtils.h"
#include "ui/GpgFrontendUIInit.h"
// main
#include "GpgFrontendContext.h"
-#include "main.h"
namespace GpgFrontend {
@@ -54,22 +52,6 @@ int setenv(const char *name, const char *value, int overwrite) {
}
#endif
-void InitLoggingSystem(const GFCxtSPtr &ctx) {
-#ifdef DEBUG
- RegisterSyncLogger("core", ctx->log_level);
- RegisterSyncLogger("main", ctx->log_level);
- RegisterSyncLogger("module", ctx->log_level);
- RegisterSyncLogger("ui", ctx->log_level);
- RegisterSyncLogger("test", ctx->log_level);
-#else
- RegisterAsyncLogger("core", ctx->log_level);
- RegisterAsyncLogger("main", ctx->log_level);
- RegisterAsyncLogger("module", ctx->log_level);
- RegisterAsyncLogger("ui", ctx->log_level);
- RegisterAsyncLogger("test", ctx->log_level);
-#endif
-}
-
void InitGlobalPathEnv() {
// read settings
bool use_custom_gnupg_install_path =
@@ -87,13 +69,12 @@ void InitGlobalPathEnv() {
// add custom gnupg install path into env $PATH
if (use_custom_gnupg_install_path && !custom_gnupg_install_path.isEmpty()) {
QString path_value = getenv("PATH");
- GF_MAIN_LOG_DEBUG("Current System PATH: {}", path_value);
+
setenv("PATH",
(QDir(custom_gnupg_install_path).absolutePath() + ":" + path_value)
.toUtf8(),
1);
QString modified_path_value = getenv("PATH");
- GF_MAIN_LOG_DEBUG("Modified System PATH: {}", modified_path_value);
}
if (GlobalSettingStation::GetInstance()
@@ -102,7 +83,6 @@ void InitGlobalPathEnv() {
.toBool()) {
qputenv("GPGME_DEBUG",
QString("9:%1").arg(QDir::currentPath() + "/gpgme.log").toUtf8());
- GF_CORE_LOG_DEBUG("GPGME_DEBUG ENV: {}", qgetenv("GPGME_DEBUG"));
}
}
@@ -112,19 +92,11 @@ void InitGlobalBasicEnv(const GFCxtWPtr &p_ctx, bool gui_mode) {
return;
}
- // init default locale of application
- InitLocale();
-
- // initialize logging system
- SetDefaultLogLevel(ctx->log_level);
- InitLoggingSystem(ctx);
-
// change path to search for related
InitGlobalPathEnv();
// should load module system first
Module::ModuleInitArgs module_init_args;
- module_init_args.log_level = ctx->log_level;
Module::LoadGpgFrontendModules(module_init_args);
// then preload ui
@@ -149,12 +121,16 @@ void InitLocale() {
// read from settings file
auto lang = settings.value("basic/lang").toString();
- GF_UI_LOG_INFO("current system default locale: {}", QLocale().name());
- GF_UI_LOG_INFO("locale settings from config: {}", lang);
+ qInfo() << "current system default locale: " << QLocale().name();
+ qInfo() << "locale settings from config: " << lang;
auto target_locale =
lang.trimmed().isEmpty() ? QLocale::system() : QLocale(lang);
- GF_UI_LOG_INFO("application's target locale: {}", target_locale.name());
+ qInfo() << "application's target locale: " << target_locale.name();
+
+ // initialize locale environment
+ qDebug("locale info: %s",
+ setlocale(LC_CTYPE, target_locale.amText().toUtf8()));
QLocale::setDefault(target_locale);
}
diff --git a/src/init.h b/src/init.h
index 218889ff..770eee61 100644
--- a/src/init.h
+++ b/src/init.h
@@ -33,13 +33,6 @@
namespace GpgFrontend {
/**
- * @brief
- *
- * @param args
- */
-void InitLoggingSystem(const GFCxtSPtr &);
-
-/**
* @brief init global PATH env
*
*/
diff --git a/src/main.cpp b/src/main.cpp
index a99f3e30..e2690f4f 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -30,14 +30,18 @@
* \mainpage GpgFrontend Develop Document Main Page
*/
+#include <qcommandlineparser.h>
+#include <qloggingcategory.h>
+
+//
#include "GpgFrontendContext.h"
+#include "core/utils/MemoryUtils.h"
+
+//
#include "app.h"
#include "cmd.h"
#include "init.h"
-//
-#include "core/utils/MemoryUtils.h"
-
/**
*
* @param argc
@@ -45,15 +49,31 @@
* @return
*/
auto main(int argc, char* argv[]) -> int {
+ // initialize qt resources
+ Q_INIT_RESOURCE(gpgfrontend);
+
GpgFrontend::GFCxtSPtr const ctx =
GpgFrontend::SecureCreateSharedObject<GpgFrontend::GpgFrontendContext>(
argc, argv);
ctx->InitApplication();
- auto rtn = 0;
+#ifdef RELEASE
+ QLoggingCategory::setFilterRules("*.debug=false\n*.info=false\n");
+ qSetMessagePattern(
+ "[%{time yyyyMMdd h:mm:ss.zzz}] [%{category}] "
+ "[%{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-"
+ "critical}C%{endif}%{if-fatal}F%{endif}] [%{threadid}] - "
+ "%{message}");
+#else
+ QLoggingCategory::setFilterRules("*.debug=false");
+ qSetMessagePattern(
+ "[%{time yyyyMMdd h:mm:ss.zzz}] [%{category}] "
+ "[%{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-"
+ "critical}C%{endif}%{if-fatal}F%{endif}] [%{threadid}] %{file}:%{line} - "
+ "%{message}");
+#endif
- // initialize qt resources
- Q_INIT_RESOURCE(gpgfrontend);
+ auto rtn = 0;
QCommandLineParser parser;
parser.addHelpOption();
@@ -67,14 +87,12 @@ auto main(int argc, char* argv[]) -> int {
parser.process(*ctx->GetApp());
- ctx->log_level = spdlog::level::info;
-
if (parser.isSet("v")) {
return GpgFrontend::PrintVersion();
}
if (parser.isSet("l")) {
- ctx->log_level = GpgFrontend::ParseLogLevel(parser.value("l"));
+ GpgFrontend::ParseLogLevel(parser.value("l"));
}
if (parser.isSet("t")) {
diff --git a/src/module/mods/gpg_info/CMakeLists.txt b/src/module/mods/gpg_info/CMakeLists.txt
deleted file mode 100644
index 6660f5cb..00000000
--- a/src/module/mods/gpg_info/CMakeLists.txt
+++ /dev/null
@@ -1,76 +0,0 @@
-# Copyright (C) 2021 Saturneric <[email protected]>
-#
-# This file is part of GpgFrontend.
-#
-# GpgFrontend 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.
-#
-# GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
-#
-# The initial version of the source code is inherited from
-# the gpg4usb project, which is under GPL-3.0-or-later.
-#
-# All the source code of GpgFrontend was modified and released by
-# Saturneric <[email protected]> starting on May 12, 2021.
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-# com.bktus.gpgfrontend.module.integrated.gnupg_info_gathering
-
-aux_source_directory(. INTEGRATED_MODULE_SOURCE)
-
-# define libgpgfrontend_module
-add_library(mod_gpg_info SHARED ${INTEGRATED_MODULE_SOURCE})
-set(_export_file "${CMAKE_CURRENT_SOURCE_DIR}/GFModuleExport.h")
-generate_export_header(mod_gpg_info
- BASE_NAME "GF_MODULE"
- EXPORT_FILE_NAME "${_export_file}")
-
-target_include_directories(mod_gpg_info PRIVATE
- ${CMAKE_SOURCE_DIR}/third_party/spdlog/include)
-
-# set output directory
-set_target_properties(mod_gpg_info PROPERTIES
- LIBRARY_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mods
- RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mods)
-
-if (XCODE_BUILD)
- set_target_properties(mod_gpg_info
- PROPERTIES
- ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
- LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
- RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
- XCODE_ATTRIBUTE_SKIP_INSTALL "Yes"
- XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}")
-endif ()
-
-if (LINUX AND LINUX_INSTALL_SOFTWARE)
- install(TARGETS mod_gpg_info
- LIBRARY DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/mods/")
-endif()
-
-# link sdk
-target_link_libraries(mod_gpg_info PRIVATE
- gpgfrontend_module_sdk)
-
-if(GPGFRONTEND_QT5_BUILD)
- # link Qt core
- target_link_libraries(mod_gpg_info PRIVATE Qt5::Core)
-else()
- # link Qt core
- target_link_libraries(mod_gpg_info PRIVATE Qt6::Core)
-endif()
-
-# property
-set_property(TARGET mod_gpg_info PROPERTY AUTOMOC ON)
-
-# using std c++ 17
-target_compile_features(mod_gpg_info PRIVATE cxx_std_17) \ No newline at end of file
diff --git a/src/module/mods/gpg_info/GFModuleExport.h b/src/module/mods/gpg_info/GFModuleExport.h
deleted file mode 100644
index a1fc1053..00000000
--- a/src/module/mods/gpg_info/GFModuleExport.h
+++ /dev/null
@@ -1,42 +0,0 @@
-
-#ifndef GF_MODULE_EXPORT_H
-#define GF_MODULE_EXPORT_H
-
-#ifdef GF_MODULE_STATIC_DEFINE
-# define GF_MODULE_EXPORT
-# define GF_MODULE_NO_EXPORT
-#else
-# ifndef GF_MODULE_EXPORT
-# ifdef mod_gpg_info_EXPORTS
- /* We are building this library */
-# define GF_MODULE_EXPORT __attribute__((visibility("default")))
-# else
- /* We are using this library */
-# define GF_MODULE_EXPORT __attribute__((visibility("default")))
-# endif
-# endif
-
-# ifndef GF_MODULE_NO_EXPORT
-# define GF_MODULE_NO_EXPORT __attribute__((visibility("hidden")))
-# endif
-#endif
-
-#ifndef GF_MODULE_DEPRECATED
-# define GF_MODULE_DEPRECATED __attribute__ ((__deprecated__))
-#endif
-
-#ifndef GF_MODULE_DEPRECATED_EXPORT
-# define GF_MODULE_DEPRECATED_EXPORT GF_MODULE_EXPORT GF_MODULE_DEPRECATED
-#endif
-
-#ifndef GF_MODULE_DEPRECATED_NO_EXPORT
-# define GF_MODULE_DEPRECATED_NO_EXPORT GF_MODULE_NO_EXPORT GF_MODULE_DEPRECATED
-#endif
-
-#if 0 /* DEFINE_NO_DEPRECATED */
-# ifndef GF_MODULE_NO_DEPRECATED
-# define GF_MODULE_NO_DEPRECATED
-# endif
-#endif
-
-#endif /* GF_MODULE_EXPORT_H */
diff --git a/src/module/mods/gpg_info/GnuPGInfoGatheringModule.cpp b/src/module/mods/gpg_info/GnuPGInfoGatheringModule.cpp
deleted file mode 100644
index 8d400c89..00000000
--- a/src/module/mods/gpg_info/GnuPGInfoGatheringModule.cpp
+++ /dev/null
@@ -1,526 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric <[email protected]>
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend 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.
- *
- * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric <[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#include "GnuPGInfoGatheringModule.h"
-
-#include <GFSDKBasic.h>
-#include <GFSDKBuildInfo.h>
-#include <GFSDKLog.h>
-#include <spdlog/spdlog.h>
-
-// qt
-#include <QCryptographicHash>
-#include <QFileInfo>
-#include <QJsonDocument>
-#include <QString>
-
-// c++
-#include <optional>
-
-#include "GpgInfo.h"
-
-template <>
-struct fmt::formatter<QString> {
- // Parses format specifications.
- constexpr auto parse(format_parse_context &ctx) -> decltype(ctx.begin()) {
- return ctx.begin();
- }
-
- // Formats the QString qstr and writes it to the output.
- template <typename FormatContext>
- auto format(const QString &qstr, FormatContext &ctx) const
- -> decltype(ctx.out()) {
- // Convert QString to UTF-8 QString (to handle Unicode characters
- // correctly)
- QByteArray utf8_array = qstr.toUtf8();
- return fmt::format_to(ctx.out(), "{}", utf8_array.constData());
- }
-};
-
-template <>
-struct fmt::formatter<QByteArray> {
- // Parses format specifications.
- constexpr auto parse(format_parse_context &ctx) -> decltype(ctx.begin()) {
- return ctx.begin();
- }
-
- // Formats the QString qstr and writes it to the output.
- template <typename FormatContext>
- auto format(const QByteArray &qarray, FormatContext &ctx) const
- -> decltype(ctx.out()) {
- // Convert QString to UTF-8 QString (to handle Unicode characters
- // correctly)
- return fmt::format_to(ctx.out(), "{}", qarray.constData());
- }
-};
-
-extern auto CalculateBinaryChacksum(const QString &path)
- -> std::optional<QString>;
-
-extern void GetGpgComponentInfos(void *, int, const char *, const char *);
-
-extern void GetGpgDirectoryInfos(void *, int, const char *, const char *);
-
-extern void GetGpgOptionInfos(void *, int, const char *, const char *);
-
-using Context = struct {
- QString gpgme_version;
- QString gpgconf_path;
- GpgComponentInfo component_info;
-};
-
-auto GFGetModuleGFSDKVersion() -> const char * {
- return GFModuleStrDup(GF_SDK_VERSION_STR);
-}
-
-auto GFGetModuleQtEnvVersion() -> const char * {
- return GFModuleStrDup(QT_VERSION_STR);
-}
-
-auto GFGetModuleID() -> const char * {
- return GFModuleStrDup("com.bktus.gpgfrontend.module.gnupg_info_gathering");
-}
-
-auto GFGetModuleVersion() -> const char * { return GFModuleStrDup("1.0.0"); }
-
-auto GFGetModuleMetaData() -> GFModuleMetaData * {
- auto *p_meta = static_cast<GFModuleMetaData *>(
- GFAllocateMemory(sizeof(GFModuleMetaData)));
- auto *h_meta = p_meta;
-
- p_meta->key = "Name";
- p_meta->value = "GatherGnupgInfo";
- p_meta->next = static_cast<GFModuleMetaData *>(
- GFAllocateMemory(sizeof(GFModuleMetaData)));
- p_meta = p_meta->next;
-
- p_meta->key = "Description";
- p_meta->value = "Try gathering gnupg informations";
- p_meta->next = static_cast<GFModuleMetaData *>(
- GFAllocateMemory(sizeof(GFModuleMetaData)));
- p_meta = p_meta->next;
-
- p_meta->key = "Author";
- p_meta->value = "Saturneric";
- p_meta->next = nullptr;
- return h_meta;
-}
-
-auto GFRegisterModule() -> int {
- GFModuleLogDebug("gnupg info gathering module registering");
- return 0;
-}
-
-auto GFActiveModule() -> int {
- GFModuleLogDebug("gnupg info gathering module activating");
- GFModuleListenEvent(GFGetModuleID(),
- GFModuleStrDup("REQUEST_GATHERING_GNUPG_INFO"));
- return 0;
-}
-
-auto GFExecuteModule(GFModuleEvent *event) -> int {
- GFModuleLogDebug(
- fmt::format("gnupg info gathering module executing, event id: {}",
- event->id)
- .c_str());
-
- GFModuleLogDebug("start to load extra info at module gnupginfogathering...");
-
- const auto *const gpgme_version = GFModuleRetrieveRTValueOrDefault(
- GFModuleStrDup("core"), GFModuleStrDup("gpgme.version"),
- GFModuleStrDup("0.0.0"));
- GFModuleLogDebug(
- fmt::format("got gpgme version from rt: {}", gpgme_version).c_str());
-
- const auto *const gpgconf_path = GFModuleRetrieveRTValueOrDefault(
- GFModuleStrDup("core"), GFModuleStrDup("gpgme.ctx.gpgconf_path"),
- GFModuleStrDup(""));
- GFModuleLogDebug(
- fmt::format("got gpgconf path from rt: {}", gpgconf_path).c_str());
-
- auto context = Context{gpgme_version, gpgconf_path};
-
- // get all components
- const char *argv[] = {GFModuleStrDup("--list-components")};
- GFExecuteCommandSync(gpgconf_path, 1, argv, GetGpgComponentInfos, &context);
- GFModuleLogDebug("load gnupg component info done.");
-
-#ifdef QT5_BUILD
- QVector<GFCommandExecuteContext> exec_contexts;
-#else
- QList<GFCommandExecuteContext> exec_contexts;
-#endif
-
- const char **argv_0 =
- static_cast<const char **>(GFAllocateMemory(sizeof(const char *)));
- argv_0[0] = GFModuleStrDup("--list-dirs");
-
- exec_contexts.push_back(
- {gpgconf_path, 1, argv_0, GetGpgDirectoryInfos, nullptr});
-
- char **components_c_array;
- int ret = GFModuleListRTChildKeys(
- GFGetModuleID(), GFModuleStrDup("gnupg.components"), &components_c_array);
- if (components_c_array == nullptr || ret == 0) return -1;
-
- QStringList components;
- auto *p_a = components_c_array;
- for (int i = 0; i < ret; i++) components.append(QString::fromUtf8(p_a[i]));
-
- for (const auto &component : components) {
- const auto *component_info_json = GFModuleRetrieveRTValueOrDefault(
- GFGetModuleID(),
- GFModuleStrDup(QString("gnupg.components.%1").arg(component).toUtf8()),
- nullptr);
-
- if (component_info_json == nullptr) continue;
-
- auto jsonlized_component_info =
- QJsonDocument::fromJson(component_info_json);
- assert(jsonlized_component_info.isObject());
-
- auto component_info = GpgComponentInfo(jsonlized_component_info.object());
- GFModuleLogDebug(fmt::format("gpgconf check options ready, "
- "component: {}",
- component_info.name)
- .c_str());
-
- if (component_info.name == "gpgme" || component_info.name == "gpgconf") {
- continue;
- }
-
- auto *context = new (GFAllocateMemory(sizeof(Context)))
- Context{gpgme_version, gpgconf_path, component_info};
-
- const char **argv_0 =
- static_cast<const char **>(GFAllocateMemory(sizeof(const char *) * 2));
- argv_0[0] = GFModuleStrDup("--list-options"),
- argv_0[1] = GFModuleStrDup(component_info.name.toUtf8());
- exec_contexts.push_back(
- {gpgconf_path, 2, argv_0, GetGpgOptionInfos, context});
- }
-
- GFExecuteCommandBatchSync(static_cast<int32_t>(exec_contexts.size()),
- exec_contexts.constData());
- GFModuleUpsertRTValueBool(GFGetModuleID(),
- GFModuleStrDup("gnupg.gathering_done"), 1);
-
- char **event_argv =
- static_cast<char **>(GFAllocateMemory(sizeof(char **) * 1));
- event_argv[0] = GFModuleStrDup("0");
-
- GFModuleTriggerModuleEventCallback(event, GFGetModuleID(), 1, event_argv);
-
- GFModuleLogDebug("gnupg external info gathering done");
- return 0;
-}
-
-auto GFDeactiveModule() -> int { return 0; }
-
-auto GFUnregisterModule() -> int {
- GFModuleLogDebug("gnupg info gathering module unregistering");
- return 0;
-}
-
-auto CalculateBinaryChacksum(const QString &path) -> std::optional<QString> {
- // check file info and access rights
- QFileInfo info(path);
- if (!info.exists() || !info.isFile() || !info.isReadable()) {
- GFModuleLogError(fmt::format("get info for file {} error, exists: {}",
- info.filePath(), info.exists())
- .c_str());
- return {};
- }
-
- // open and read file
- QFile f(info.filePath());
- if (!f.open(QIODevice::ReadOnly)) {
- GFModuleLogError(fmt::format("open {} to calculate checksum error: {}",
- path.toStdString(),
- f.errorString().toStdString())
- .c_str());
- return {};
- }
-
- QCryptographicHash hash_sha(QCryptographicHash::Sha256);
-
- // read data by chunks
- const qint64 buffer_size = 8192; // Define a suitable buffer size
- while (!f.atEnd()) {
- QByteArray const buffer = f.read(buffer_size);
- if (buffer.isEmpty()) {
- GFModuleLogError(fmt::format("error reading file {} during "
- "checksum calculation",
- path.toStdString())
- .c_str());
- return {};
- }
- hash_sha.addData(buffer);
- }
-
- // close the file
- f.close();
-
- // return the first 6 characters of the SHA-256 hash
- // of the file
- return QString(hash_sha.result().toHex()).left(6);
-}
-
-void GetGpgComponentInfos(void *data, int exit_code, const char *out,
- const char *err) {
- auto *context = reinterpret_cast<Context *>(data);
- auto p_out = QString::fromUtf8(out);
- auto p_err = QString::fromUtf8(err);
-
- GFModuleLogDebug(fmt::format("gpgconf components exit_code: {} "
- "process stdout size: {}",
- exit_code, p_out.size())
- .c_str());
-
- if (exit_code != 0) {
- GFModuleLogError(fmt::format("gpgconf execute error, process "
- "stderr: {}, "
- "process stdout: {}",
- p_err, p_out)
- .c_str());
- return;
- }
-
- std::vector<GpgComponentInfo> component_infos;
- GpgComponentInfo c_i_gpgme;
- c_i_gpgme.name = "gpgme";
- c_i_gpgme.desc = "GPG Made Easy";
- c_i_gpgme.version = context->gpgme_version;
- c_i_gpgme.path = "Embedded In";
- c_i_gpgme.binary_checksum = "/";
-
- GpgComponentInfo c_i_gpgconf;
- c_i_gpgconf.name = "gpgconf";
- c_i_gpgconf.desc = "GPG Configure";
- c_i_gpgconf.version = "/";
- c_i_gpgconf.path = context->gpgconf_path;
- auto gpgconf_binary_checksum = CalculateBinaryChacksum(context->gpgconf_path);
- c_i_gpgconf.binary_checksum =
- (gpgconf_binary_checksum.has_value() ? gpgconf_binary_checksum.value()
- : QString("/"));
-
- component_infos.push_back(c_i_gpgme);
- component_infos.push_back(c_i_gpgconf);
-
- auto const jsonlized_gpgme_component_info = c_i_gpgme.Json();
- auto const jsonlized_gpgconf_component_info = c_i_gpgconf.Json();
- GFModuleUpsertRTValue(
- GFGetModuleID(), GFModuleStrDup("gnupg.components.gpgme"),
- GFModuleStrDup(QJsonDocument(jsonlized_gpgme_component_info).toJson()));
- GFModuleUpsertRTValue(
- GFGetModuleID(), GFModuleStrDup("gnupg.components.gpgconf"),
- GFModuleStrDup(QJsonDocument(jsonlized_gpgconf_component_info).toJson()));
-
- auto line_split_list = p_out.split("\n");
-
- for (const auto &line : line_split_list) {
- auto info_split_list = line.split(":");
-
- if (info_split_list.size() != 3) continue;
-
- auto component_name = info_split_list[0].trimmed();
- auto component_desc = info_split_list[1].trimmed();
- auto component_path = info_split_list[2].trimmed();
-
-#ifdef WINDOWS
- // replace some special substrings on windows
- // platform
- component_path.replace("%3a", ":");
-#endif
-
- auto binary_checksum = CalculateBinaryChacksum(component_path);
-
- GFModuleLogDebug(
- fmt::format("gnupg component name: {} desc: "
- "{} checksum: {} path: {} ",
- component_name, component_desc,
- binary_checksum.has_value() ? binary_checksum.value() : "/",
- component_path)
- .c_str());
-
- QString version = "/";
-
- if (component_name == "gpg") {
- version = GFModuleRetrieveRTValueOrDefault(
- GFModuleStrDup("core"), GFModuleStrDup("gpgme.ctx.gnupg_version"),
- GFModuleStrDup("2.0.0"));
- }
- if (component_name == "gpg-agent") {
- GFModuleUpsertRTValue(GFGetModuleID(),
- GFModuleStrDup("gnupg.gpg_agent_path"),
- GFModuleStrDup(QString(component_path).toUtf8()));
- }
- if (component_name == "dirmngr") {
- GFModuleUpsertRTValue(GFGetModuleID(),
- GFModuleStrDup("gnupg.dirmngr_path"),
- GFModuleStrDup(QString(component_path).toUtf8()));
- }
- if (component_name == "keyboxd") {
- GFModuleUpsertRTValue(GFGetModuleID(),
- GFModuleStrDup("gnupg.keyboxd_path"),
- GFModuleStrDup(QString(component_path).toUtf8()));
- }
-
- {
- GpgComponentInfo c_i;
- c_i.name = component_name;
- c_i.desc = component_desc;
- c_i.version = version;
- c_i.path = component_path;
- c_i.binary_checksum =
- (binary_checksum.has_value() ? binary_checksum.value()
- : QString("/"));
-
- auto const jsonlized_component_info = c_i.Json();
- GFModuleUpsertRTValue(
- GFGetModuleID(),
- GFModuleStrDup(
- QString("gnupg.components.%1").arg(component_name).toUtf8()),
- GFModuleStrDup(QJsonDocument(jsonlized_component_info).toJson()));
-
- component_infos.push_back(c_i);
- }
-
- GFModuleLogDebug("load gnupg component info actually done.");
- }
-}
-
-void GetGpgDirectoryInfos(void *, int exit_code, const char *out,
- const char *err) {
- if (exit_code != 0) return;
-
- auto p_out = QString::fromUtf8(out);
- auto p_err = QString::fromUtf8(err);
- auto line_split_list = p_out.split("\n");
-
- for (const auto &line : line_split_list) {
- auto info_split_list = line.split(":");
- GFModuleLogDebug(fmt::format("gpgconf direcrotries info line: "
- "{} info size: {}",
- line, info_split_list.size())
- .c_str());
-
- if (info_split_list.size() != 2) continue;
-
- auto configuration_name = info_split_list[0].trimmed();
- auto configuration_value = info_split_list[1].trimmed();
-
-#ifdef WINDOWS
- // replace some special substrings on windows
- // platform
- configuration_value.replace("%3a", ":");
-#endif
-
- // record gnupg home path
- if (configuration_name == "homedir") {
- GFModuleUpsertRTValue(GFGetModuleID(), GFModuleStrDup("gnupg.home_path"),
- GFModuleStrDup(configuration_value.toUtf8()));
- }
-
- GFModuleUpsertRTValue(
- GFGetModuleID(),
- GFModuleStrDup(
- QString("gnupg.dirs.%1").arg(configuration_name).toUtf8()),
- GFModuleStrDup(configuration_value.toUtf8()));
- }
-}
-
-void GetGpgOptionInfos(void *data, int exit_code, const char *out,
- const char *err) {
- if (exit_code != 0) return;
-
- auto p_out = QString::fromUtf8(out);
- auto p_err = QString::fromUtf8(err);
- auto *context = reinterpret_cast<Context *>(data);
- auto component_name = context->component_info.name;
-
- GFModuleLogDebug(fmt::format("gpgconf {} avaliable options "
- "exit_code: {} process stdout "
- "size: {} ",
- component_name, exit_code, p_out.size())
- .c_str());
-
- std::vector<GpgOptionsInfo> options_infos;
-
- auto line_split_list = p_out.split("\n");
-
- for (const auto &line : line_split_list) {
- auto info_split_list = line.split(":");
-
- GFModuleLogDebug(fmt::format("component {} avaliable options "
- "line: {} info size: {}",
- component_name, line, info_split_list.size())
- .c_str());
-
- if (info_split_list.size() < 10) continue;
-
- // The format of each line is:
- // name:flags:level:description:type:alt-type:argname:default:argdef:value
-
- auto option_name = info_split_list[0].trimmed();
- auto option_flags = info_split_list[1].trimmed();
- auto option_level = info_split_list[2].trimmed();
- auto option_desc = info_split_list[3].trimmed();
- auto option_type = info_split_list[4].trimmed();
- auto option_alt_type = info_split_list[5].trimmed();
- auto option_argname = info_split_list[6].trimmed();
- auto option_default = info_split_list[7].trimmed();
- auto option_argdef = info_split_list[8].trimmed();
- auto option_value = info_split_list[9].trimmed();
-
- GpgOptionsInfo info;
- info.name = option_name;
- info.flags = option_flags;
- info.level = option_level;
- info.description = option_desc;
- info.type = option_type;
- info.alt_type = option_alt_type;
- info.argname = option_argname;
- info.default_value = option_default;
- info.argdef = option_argdef;
- info.value = option_value;
-
- auto const jsonlized_option_info = info.Json();
- GFModuleUpsertRTValue(
- GFGetModuleID(),
- GFModuleStrDup(QString("gnupg.components.%1.options.%2")
- .arg(component_name)
- .arg(option_name)
- .toUtf8()),
- GFModuleStrDup(QJsonDocument(jsonlized_option_info).toJson()));
- options_infos.push_back(info);
- }
-
- context->~Context();
- GFFreeMemory(context);
-}
diff --git a/src/module/mods/gpg_info/GpgInfo.cpp b/src/module/mods/gpg_info/GpgInfo.cpp
deleted file mode 100644
index 680f4a8a..00000000
--- a/src/module/mods/gpg_info/GpgInfo.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric <[email protected]>
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend 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.
- *
- * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric <[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#include "GpgInfo.h"
-
-GpgOptionsInfo::GpgOptionsInfo(const QJsonObject &j) {
- if (const auto v = j["name"]; v.isString()) name = v.toString();
- if (const auto v = j["flags"]; v.isString()) flags = v.toString();
- if (const auto v = j["level"]; v.isString()) level = v.toString();
- if (const auto v = j["description"]; v.isString()) description = v.toString();
- if (const auto v = j["type"]; v.isString()) type = v.toString();
- if (const auto v = j["alt_type"]; v.isString()) alt_type = v.toString();
- if (const auto v = j["argname"]; v.isString()) argname = v.toString();
- if (const auto v = j["default_value"]; v.isString()) {
- default_value = v.toString();
- }
- if (const auto v = j["argdef"]; v.isString()) argdef = v.toString();
- if (const auto v = j["value"]; v.isString()) value = v.toString();
-}
-
-auto GpgOptionsInfo::Json() const -> QJsonObject {
- QJsonObject j;
- j["name"] = name;
- j["flags"] = flags;
- j["level"] = level;
- j["description"] = description;
- j["type"] = type;
- j["alt_type"] = alt_type;
- j["argname"] = argname;
- j["default_value"] = default_value;
- j["argdef"] = argdef;
- j["value"] = value;
- return j;
-}
-
-auto GpgComponentInfo::Json() const -> QJsonObject {
- QJsonObject j;
- j["name"] = name;
- j["desc"] = desc;
- j["version"] = version;
- j["path"] = path;
- j["binary_checksum"] = binary_checksum;
- return j;
-}
-
-GpgComponentInfo::GpgComponentInfo(const QJsonObject &j) {
- if (const auto v = j["name"]; v.isString()) name = v.toString();
- if (const auto v = j["desc"]; v.isString()) desc = v.toString();
- if (const auto v = j["version"]; v.isString()) version = v.toString();
- if (const auto v = j["path"]; v.isString()) path = v.toString();
- if (const auto v = j["binary_checksum"]; v.isString()) {
- binary_checksum = v.toString();
- }
-}
diff --git a/src/module/mods/gpg_info/GpgInfo.h b/src/module/mods/gpg_info/GpgInfo.h
deleted file mode 100644
index 1aacc207..00000000
--- a/src/module/mods/gpg_info/GpgInfo.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric <[email protected]>
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend 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.
- *
- * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric <[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#pragma once
-
-#include <QJsonObject>
-#include <QString>
-#include <map>
-
-/**
- * @brief Use to record some info about gnupg
- *
- */
-class GpgInfo {
- public:
- QString GnuPGHomePath; ///< value of ---homedir
-
- std::map<QString, std::vector<QString>> ComponentsInfo; ///<
- std::map<QString, std::vector<QString>> ConfigurationsInfo; ///<
- std::map<QString, std::vector<QString>> OptionsInfo; ///<
- std::map<QString, std::vector<QString>> AvailableOptionsInfo; ///<
-};
-
-/**
- * @brief Use to record some info about gnupg components
- *
- */
-struct GpgComponentInfo {
- QString name;
- QString desc;
- QString version;
- QString path;
- QString binary_checksum;
-
- GpgComponentInfo() = default;
-
- explicit GpgComponentInfo(const QJsonObject &j);
-
- [[nodiscard]] auto Json() const -> QJsonObject;
-};
-
-/**
- * The format of each line is:
- * name:flags:level:description:type:alt-type:argname:default:argdef:value
- */
-struct GpgOptionsInfo {
- QString name;
- QString flags;
- QString level;
- QString description;
- QString type;
- QString alt_type;
- QString argname;
- QString default_value;
- QString argdef;
- QString value;
-
- GpgOptionsInfo() = default;
-
- explicit GpgOptionsInfo(const QJsonObject &j);
-
- [[nodiscard]] auto Json() const -> QJsonObject;
-};
diff --git a/src/module/mods/gpg_info/QtLoggerFmt.h b/src/module/mods/gpg_info/QtLoggerFmt.h
deleted file mode 100644
index 23997465..00000000
--- a/src/module/mods/gpg_info/QtLoggerFmt.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric <[email protected]>
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend 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.
- *
- * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric <[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#pragma once
-
-#include <spdlog/spdlog.h>
-
-#include <QString>
-
-template <>
-struct fmt::formatter<QString> {
- // Parses format specifications.
- constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
- return ctx.begin();
- }
-
- // Formats the QString qstr and writes it to the output.
- template <typename FormatContext>
- auto format(const QString& qstr, FormatContext& ctx) const
- -> decltype(ctx.out()) {
- // Convert QString to UTF-8 QString (to handle Unicode characters
- // correctly)
- QByteArray utf8_array = qstr.toUtf8();
- return fmt::format_to(ctx.out(), "{}", utf8_array.constData());
- }
-};
-
-template <>
-struct fmt::formatter<QByteArray> {
- // Parses format specifications.
- constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
- return ctx.begin();
- }
-
- // Formats the QString qstr and writes it to the output.
- template <typename FormatContext>
- auto format(const QByteArray& qarray, FormatContext& ctx) const
- -> decltype(ctx.out()) {
- // Convert QString to UTF-8 QString (to handle Unicode characters
- // correctly)
- return fmt::format_to(ctx.out(), "{}", qarray.constData());
- }
-};
diff --git a/src/module/mods/ver_check/CMakeLists.txt b/src/module/mods/ver_check/CMakeLists.txt
deleted file mode 100644
index b07a499a..00000000
--- a/src/module/mods/ver_check/CMakeLists.txt
+++ /dev/null
@@ -1,76 +0,0 @@
-# Copyright (C) 2021 Saturneric <[email protected]>
-#
-# This file is part of GpgFrontend.
-#
-# GpgFrontend 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.
-#
-# GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
-#
-# The initial version of the source code is inherited from
-# the gpg4usb project, which is under GPL-3.0-or-later.
-#
-# All the source code of GpgFrontend was modified and released by
-# Saturneric <[email protected]> starting on May 12, 2021.
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-# com.bktus.gpgfrontend.module.integrated.version_checking
-
-aux_source_directory(. INTEGRATED_MODULE_SOURCE)
-
-# define libgpgfrontend_module
-add_library(mod_ver_check SHARED ${INTEGRATED_MODULE_SOURCE})
-set(_export_file "${CMAKE_CURRENT_SOURCE_DIR}/GFModuleExport.h")
-generate_export_header(mod_ver_check
- BASE_NAME "GF_MODULE"
- EXPORT_FILE_NAME "${_export_file}")
-
-target_include_directories(mod_ver_check PRIVATE
- ${CMAKE_SOURCE_DIR}/third_party/spdlog/include)
-
-# set output directory
-set_target_properties(mod_ver_check PROPERTIES
- LIBRARY_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mods
- RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mods)
-
-if (XCODE_BUILD)
- set_target_properties(mod_ver_check
- PROPERTIES
- ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
- LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
- RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
- XCODE_ATTRIBUTE_SKIP_INSTALL "Yes"
- XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}")
-endif ()
-
-if (LINUX AND LINUX_INSTALL_SOFTWARE)
- install(TARGETS mod_ver_check
- LIBRARY DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/mods/")
-endif()
-
-# link sdk
-target_link_libraries(mod_ver_check PRIVATE
- gpgfrontend_module_sdk)
-
-if(GPGFRONTEND_QT5_BUILD)
- # link Qt
- target_link_libraries(mod_ver_check PUBLIC Qt5::Core Qt5::Network)
-else()
- # link Qt
- target_link_libraries(mod_ver_check PUBLIC Qt6::Core Qt6::Network)
-endif()
-
-# property
-set_property(TARGET mod_ver_check PROPERTY AUTOMOC ON)
-
-# using std c++ 17
-target_compile_features(mod_ver_check PRIVATE cxx_std_17) \ No newline at end of file
diff --git a/src/module/mods/ver_check/GFModuleExport.h b/src/module/mods/ver_check/GFModuleExport.h
deleted file mode 100644
index ce663b5f..00000000
--- a/src/module/mods/ver_check/GFModuleExport.h
+++ /dev/null
@@ -1,42 +0,0 @@
-
-#ifndef GF_MODULE_EXPORT_H
-#define GF_MODULE_EXPORT_H
-
-#ifdef GF_MODULE_STATIC_DEFINE
-# define GF_MODULE_EXPORT
-# define GF_MODULE_NO_EXPORT
-#else
-# ifndef GF_MODULE_EXPORT
-# ifdef mod_ver_check_EXPORTS
- /* We are building this library */
-# define GF_MODULE_EXPORT __attribute__((visibility("default")))
-# else
- /* We are using this library */
-# define GF_MODULE_EXPORT __attribute__((visibility("default")))
-# endif
-# endif
-
-# ifndef GF_MODULE_NO_EXPORT
-# define GF_MODULE_NO_EXPORT __attribute__((visibility("hidden")))
-# endif
-#endif
-
-#ifndef GF_MODULE_DEPRECATED
-# define GF_MODULE_DEPRECATED __attribute__ ((__deprecated__))
-#endif
-
-#ifndef GF_MODULE_DEPRECATED_EXPORT
-# define GF_MODULE_DEPRECATED_EXPORT GF_MODULE_EXPORT GF_MODULE_DEPRECATED
-#endif
-
-#ifndef GF_MODULE_DEPRECATED_NO_EXPORT
-# define GF_MODULE_DEPRECATED_NO_EXPORT GF_MODULE_NO_EXPORT GF_MODULE_DEPRECATED
-#endif
-
-#if 0 /* DEFINE_NO_DEPRECATED */
-# ifndef GF_MODULE_NO_DEPRECATED
-# define GF_MODULE_NO_DEPRECATED
-# endif
-#endif
-
-#endif /* GF_MODULE_EXPORT_H */
diff --git a/src/module/mods/ver_check/QtLoggerFmt.h b/src/module/mods/ver_check/QtLoggerFmt.h
deleted file mode 100644
index 23997465..00000000
--- a/src/module/mods/ver_check/QtLoggerFmt.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric <[email protected]>
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend 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.
- *
- * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric <[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#pragma once
-
-#include <spdlog/spdlog.h>
-
-#include <QString>
-
-template <>
-struct fmt::formatter<QString> {
- // Parses format specifications.
- constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
- return ctx.begin();
- }
-
- // Formats the QString qstr and writes it to the output.
- template <typename FormatContext>
- auto format(const QString& qstr, FormatContext& ctx) const
- -> decltype(ctx.out()) {
- // Convert QString to UTF-8 QString (to handle Unicode characters
- // correctly)
- QByteArray utf8_array = qstr.toUtf8();
- return fmt::format_to(ctx.out(), "{}", utf8_array.constData());
- }
-};
-
-template <>
-struct fmt::formatter<QByteArray> {
- // Parses format specifications.
- constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
- return ctx.begin();
- }
-
- // Formats the QString qstr and writes it to the output.
- template <typename FormatContext>
- auto format(const QByteArray& qarray, FormatContext& ctx) const
- -> decltype(ctx.out()) {
- // Convert QString to UTF-8 QString (to handle Unicode characters
- // correctly)
- return fmt::format_to(ctx.out(), "{}", qarray.constData());
- }
-};
diff --git a/src/module/mods/ver_check/SoftwareVersion.cpp b/src/module/mods/ver_check/SoftwareVersion.cpp
deleted file mode 100644
index cd864195..00000000
--- a/src/module/mods/ver_check/SoftwareVersion.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric <[email protected]>
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend 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.
- *
- * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric <[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#include "SoftwareVersion.h"
-
-#include <GFSDKBasic.h>
-#include <GFSDKExtra.h>
-#include <GFSDKLog.h>
-#include <spdlog/spdlog.h>
-
-#include <QString>
-
-template <>
-struct fmt::formatter<QString> {
- // Parses format specifications.
- constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
- return ctx.begin();
- }
-
- // Formats the QString qstr and writes it to the output.
- template <typename FormatContext>
- auto format(const QString& qstr, FormatContext& ctx) const
- -> decltype(ctx.out()) {
- // Convert QString to UTF-8 QString (to handle Unicode characters
- // correctly)
- QByteArray utf8_array = qstr.toUtf8();
- return fmt::format_to(ctx.out(), "{}", utf8_array.constData());
- }
-};
-
-template <>
-struct fmt::formatter<QByteArray> {
- // Parses format specifications.
- constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
- return ctx.begin();
- }
-
- // Formats the QString qstr and writes it to the output.
- template <typename FormatContext>
- auto format(const QByteArray& qarray, FormatContext& ctx) const
- -> decltype(ctx.out()) {
- // Convert QString to UTF-8 QString (to handle Unicode characters
- // correctly)
- return fmt::format_to(ctx.out(), "{}", qarray.constData());
- }
-};
-
-auto SoftwareVersion::NeedUpgrade() const -> bool {
- GFModuleLogDebug(
- fmt::format(
- "compair version current {} latest {}, result {}", current_version,
- latest_version,
- GFCompareSoftwareVersion(GFModuleStrDup(current_version.toUtf8()),
- GFModuleStrDup(latest_version.toUtf8())))
- .c_str());
-
- GFModuleLogDebug(fmt::format("load done: {}, pre-release: {}, draft: {}",
- loading_done,
- latest_prerelease_version_from_remote,
- latest_draft_from_remote)
- .c_str());
- return loading_done && !latest_prerelease_version_from_remote &&
- !latest_draft_from_remote &&
- GFCompareSoftwareVersion(GFModuleStrDup(current_version.toUtf8()),
- GFModuleStrDup(latest_version.toUtf8())) < 0;
-}
-
-auto SoftwareVersion::VersionWithdrawn() const -> bool {
- return loading_done && !current_version_publish_in_remote &&
- current_version_is_a_prerelease && !current_version_is_drafted;
-}
-
-auto SoftwareVersion::CurrentVersionReleased() const -> bool {
- return loading_done && current_version_publish_in_remote;
-} \ No newline at end of file
diff --git a/src/module/mods/ver_check/SoftwareVersion.h b/src/module/mods/ver_check/SoftwareVersion.h
deleted file mode 100644
index 6b05d413..00000000
--- a/src/module/mods/ver_check/SoftwareVersion.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric <[email protected]>
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend 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.
- *
- * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric <[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#pragma once
-
-#include <QString>
-
-/**
- * @brief
- *
- */
-struct SoftwareVersion {
- QString latest_version; ///<
- QString current_version; ///<
- bool latest_prerelease_version_from_remote = false; ///<
- bool latest_draft_from_remote = false; ///<
- bool current_version_is_a_prerelease = false; ///<
- bool current_version_is_drafted = false; ///<
- bool loading_done = false; ///<
- bool current_version_publish_in_remote = false; ///<
- QString publish_date; ///<
- QString release_note; ///<
-
- /**
- * @brief
- *
- * @return true
- * @return false
- */
- [[nodiscard]] auto InfoValid() const -> bool { return loading_done; }
-
- /**
- * @brief
- *
- * @return true
- * @return false
- */
- [[nodiscard]] auto NeedUpgrade() const -> bool;
-
- /**
- * @brief
- *
- * @return true
- * @return false
- */
- [[nodiscard]] auto VersionWithdrawn() const -> bool;
-
- /**
- * @brief
- *
- * @return true
- * @return false
- */
- [[nodiscard]] auto CurrentVersionReleased() const -> bool;
-
- private:
- static auto version_compare(const QString& a, const QString& b) -> int;
-};
diff --git a/src/module/mods/ver_check/VersionCheckTask.cpp b/src/module/mods/ver_check/VersionCheckTask.cpp
deleted file mode 100644
index 5ea9c48e..00000000
--- a/src/module/mods/ver_check/VersionCheckTask.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric <[email protected]>
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend 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.
- *
- * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric <[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#include "VersionCheckTask.h"
-
-#include <GFSDKBasic.h>
-#include <GFSDKExtra.h>
-#include <GFSDKLog.h>
-
-#include <QMetaType>
-#include <QtNetwork>
-
-VersionCheckTask::VersionCheckTask()
- : network_manager_(new QNetworkAccessManager(this)),
- current_version_(GFProjectVersion()) {
- qRegisterMetaType<SoftwareVersion>("SoftwareVersion");
- version_.current_version = current_version_;
-}
-
-auto VersionCheckTask::Run() -> int {
- GFModuleLogDebug(
- fmt::format("current project version: {}", current_version_).c_str());
- QString latest_version_url =
- "https://api.github.com/repos/saturneric/gpgfrontend/releases/latest";
-
- QNetworkRequest latest_request(latest_version_url);
- latest_request.setHeader(QNetworkRequest::UserAgentHeader,
- GFHttpRequestUserAgent());
-
- latest_reply_ = network_manager_->get(latest_request);
- connect(latest_reply_, &QNetworkReply::finished, this,
- &VersionCheckTask::slot_parse_latest_version_info);
- return 0;
-}
-
-void VersionCheckTask::slot_parse_latest_version_info() {
- if (latest_reply_ == nullptr) {
- version_.latest_version = current_version_;
- version_.loading_done = false;
- } else if (latest_reply_->error() != QNetworkReply::NoError) {
- GFModuleLogError(fmt::format("latest version request error: ",
- latest_reply_->errorString())
- .c_str());
- version_.latest_version = current_version_;
- } else {
- latest_reply_bytes_ = latest_reply_->readAll();
- auto latest_reply_json = QJsonDocument::fromJson(latest_reply_bytes_);
-
- if (latest_reply_json.isObject()) {
- QString latest_version = latest_reply_json["tag_name"].toString();
-
- QRegularExpression re(R"(^[vV](\d+\.)?(\d+\.)?(\*|\d+))");
- auto version_match = re.match(latest_version);
- if (version_match.hasMatch()) {
- latest_version = version_match.captured(0);
- GFModuleLogInfo(fmt::format("latest released version from github: {}",
- latest_version)
- .c_str());
- } else {
- latest_version = current_version_;
- GFModuleLogWarn(
- fmt::format("latest version unknown, set to current version: {}",
- current_version_)
- .c_str());
- }
-
- bool prerelease = latest_reply_json["prerelease"].toBool();
- bool draft = latest_reply_json["draft"].toBool();
- auto publish_date = latest_reply_json["published_at"].toString();
- auto release_note = latest_reply_json["body"].toString();
- version_.latest_version = latest_version;
- version_.latest_prerelease_version_from_remote = prerelease;
- version_.latest_draft_from_remote = draft;
- version_.publish_date = publish_date;
- version_.release_note = release_note;
- } else {
- GFModuleLogWarn(fmt::format("cannot parse data got from github: {}",
- latest_reply_bytes_)
- .c_str());
- }
- }
-
- if (latest_reply_ != nullptr) {
- latest_reply_->deleteLater();
- }
-
- try {
- QString current_version_url =
- "https://api.github.com/repos/saturneric/gpgfrontend/releases/tags/" +
- current_version_;
- GFModuleLogDebug(
- fmt::format("current version info query url: {}", current_version_url)
- .c_str());
-
- QNetworkRequest current_request(current_version_url);
- current_request.setHeader(QNetworkRequest::UserAgentHeader,
- GFHttpRequestUserAgent());
-
- current_reply_ = network_manager_->get(current_request);
-
- connect(current_reply_, &QNetworkReply::finished, this,
- &VersionCheckTask::slot_parse_current_version_info);
- } catch (...) {
- GFModuleLogError("current version request create error");
- }
-}
-
-void VersionCheckTask::slot_parse_current_version_info() {
- if (current_reply_ == nullptr) {
- // loading done
- version_.loading_done = false;
-
- } else if (current_reply_->error() != QNetworkReply::NoError) {
- GFModuleLogError(fmt::format("current version request network error: {}",
- current_reply_->errorString())
- .c_str());
-
- // loading done
- version_.loading_done = true;
- version_.current_version_publish_in_remote = false;
- } else {
- version_.current_version_publish_in_remote = true;
- current_reply_bytes_ = current_reply_->readAll();
- auto current_reply_json = QJsonDocument::fromJson(current_reply_bytes_);
-
- if (current_reply_json.isObject()) {
- bool current_prerelease = current_reply_json["prerelease"].toBool();
- bool current_draft = current_reply_json["draft"].toBool();
- version_.latest_prerelease_version_from_remote = current_prerelease;
- version_.latest_draft_from_remote = current_draft;
- // loading done
- version_.loading_done = true;
- } else {
- GFModuleLogWarn(fmt::format("cannot parse data got from github: {}",
- current_reply_bytes_)
- .c_str());
- }
- }
-
- GFModuleLogDebug(fmt::format("current version parse done: {}",
- version_.current_version_publish_in_remote)
- .c_str());
-
- if (current_reply_ != nullptr) current_reply_->deleteLater();
- emit SignalUpgradeVersion(version_);
-}
diff --git a/src/module/mods/ver_check/VersionCheckTask.h b/src/module/mods/ver_check/VersionCheckTask.h
deleted file mode 100644
index df801570..00000000
--- a/src/module/mods/ver_check/VersionCheckTask.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric <[email protected]>
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend 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.
- *
- * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric <[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#pragma once
-
-#include <core/thread/Task.h>
-
-#include "SoftwareVersion.h"
-
-class QNetworkReply;
-class QNetworkAccessManager;
-
-/**
- * @brief
- *
- */
-class VersionCheckTask : public QObject {
- Q_OBJECT
- public:
- /**
- * @brief Construct a new Version Check Thread object
- *
- */
- VersionCheckTask();
-
- /**
- * @brief
- *
- * @return int
- */
- auto Run() -> int;
-
- signals:
-
- /**
- * @brief
- *
- * @param version
- */
- void SignalUpgradeVersion(SoftwareVersion version);
-
- private slots:
-
- /**
- * @brief
- *
- */
- void slot_parse_latest_version_info();
-
- /**
- * @brief
- *
- */
- void slot_parse_current_version_info();
-
- private:
- QByteArray latest_reply_bytes_; ///<
- QByteArray current_reply_bytes_; ///<
- QNetworkReply* latest_reply_ = nullptr; ///< latest version info reply
- QNetworkReply* current_reply_ = nullptr; ///< current version info reply
- QNetworkAccessManager* network_manager_; ///<
- QString current_version_;
- SoftwareVersion version_;
-};
diff --git a/src/module/mods/ver_check/VersionCheckingModule.cpp b/src/module/mods/ver_check/VersionCheckingModule.cpp
deleted file mode 100644
index 35d3b82e..00000000
--- a/src/module/mods/ver_check/VersionCheckingModule.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric <[email protected]>
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend 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.
- *
- * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric <[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#include "VersionCheckingModule.h"
-
-#include <GFSDKBasic.h>
-#include <GFSDKBuildInfo.h>
-#include <GFSDKExtra.h>
-#include <GFSDKLog.h>
-#include <spdlog/spdlog.h>
-
-#include <QMetaType>
-#include <QtNetwork>
-
-#include "SoftwareVersion.h"
-#include "VersionCheckTask.h"
-
-extern void VersionCheckDone(const SoftwareVersion& version);
-
-auto GFGetModuleGFSDKVersion() -> const char* {
- return GFModuleStrDup(GF_SDK_VERSION_STR);
-}
-
-auto GFGetModuleQtEnvVersion() -> const char* {
- return GFModuleStrDup(QT_VERSION_STR);
-}
-
-auto GFGetModuleID() -> const char* {
- return GFModuleStrDup("com.bktus.gpgfrontend.module.version_checking");
-}
-
-auto GFGetModuleVersion() -> const char* { return GFModuleStrDup("1.0.0"); }
-
-auto GFGetModuleMetaData() -> GFModuleMetaData* {
- auto* p_meta = static_cast<GFModuleMetaData*>(
- GFAllocateMemory(sizeof(GFModuleMetaData)));
- auto* h_meta = p_meta;
-
- p_meta->key = "Name";
- p_meta->value = "VersionChecking";
- p_meta->next = static_cast<GFModuleMetaData*>(
- GFAllocateMemory(sizeof(GFModuleMetaData)));
- p_meta = p_meta->next;
-
- p_meta->key = "Description";
- p_meta->value = "Try checking gpgfrontend version";
- p_meta->next = static_cast<GFModuleMetaData*>(
- GFAllocateMemory(sizeof(GFModuleMetaData)));
- p_meta = p_meta->next;
-
- p_meta->key = "Author";
- p_meta->value = "Saturneric";
- p_meta->next = nullptr;
-
- return h_meta;
-}
-
-auto GFRegisterModule() -> int {
- GFModuleLogInfo("version checking module registering");
- return 0;
-}
-
-auto GFActiveModule() -> int {
- GFModuleLogInfo("version checking module activating");
-
- GFModuleListenEvent(GFGetModuleID(), GFModuleStrDup("APPLICATION_LOADED"));
- GFModuleListenEvent(GFGetModuleID(),
- GFModuleStrDup("CHECK_APPLICATION_VERSION"));
- return 0;
-}
-
-auto GFExecuteModule(GFModuleEvent* event) -> int {
- GFModuleLogInfo(
- fmt::format("version checking module executing, event id: {}", event->id)
- .c_str());
-
- auto* task = new VersionCheckTask();
- QObject::connect(
- task, &VersionCheckTask::SignalUpgradeVersion, QThread::currentThread(),
- [event](const SoftwareVersion& version) {
- VersionCheckDone(version);
-
- char** event_argv =
- static_cast<char**>(GFAllocateMemory(sizeof(char**) * 1));
- event_argv[0] = GFModuleStrDup("0");
-
- GFModuleTriggerModuleEventCallback(event, GFGetModuleID(), 1,
- event_argv);
- });
- QObject::connect(task, &VersionCheckTask::SignalUpgradeVersion, task,
- &QObject::deleteLater);
- task->Run();
-
- return 0;
-}
-
-auto GFDeactiveModule() -> int { return 0; }
-
-auto GFUnregisterModule() -> int { return 0; }
-
-void VersionCheckDone(const SoftwareVersion& version) {
- GFModuleLogDebug("filling software information info in rt...");
-
- GFModuleUpsertRTValue(GFGetModuleID(),
- GFModuleStrDup("version.current_version"),
- GFModuleStrDup(version.current_version.toUtf8()));
- GFModuleUpsertRTValue(GFGetModuleID(),
- GFModuleStrDup("version.latest_version"),
- GFModuleStrDup(version.latest_version.toUtf8()));
- GFModuleUpsertRTValueBool(
- GFGetModuleID(), GFModuleStrDup("version.current_version_is_drafted"),
- version.current_version_is_drafted ? 1 : 0);
- GFModuleUpsertRTValueBool(
- GFGetModuleID(),
- GFModuleStrDup("version.current_version_is_a_prerelease"),
- version.current_version_is_a_prerelease ? 1 : 0);
- GFModuleUpsertRTValueBool(
- GFGetModuleID(),
- GFModuleStrDup("version.current_version_publish_in_remote"),
- version.current_version_publish_in_remote ? 1 : 0);
- GFModuleUpsertRTValueBool(
- GFGetModuleID(),
- GFModuleStrDup("version.latest_prerelease_version_from_remote"),
- version.latest_prerelease_version_from_remote ? 1 : 0);
- GFModuleUpsertRTValueBool(GFGetModuleID(),
- GFModuleStrDup("version.need_upgrade"),
- version.NeedUpgrade() ? 1 : 0);
- GFModuleUpsertRTValueBool(GFGetModuleID(),
- GFModuleStrDup("version.current_version_released"),
- version.CurrentVersionReleased() ? 1 : 0);
- GFModuleUpsertRTValueBool(
- GFGetModuleID(), GFModuleStrDup("version.current_a_withdrawn_version"),
- version.VersionWithdrawn() ? 1 : 0);
- GFModuleUpsertRTValueBool(GFGetModuleID(),
- GFModuleStrDup("version.loading_done"),
- version.loading_done ? 1 : 0);
-
- GFModuleLogDebug("software information filled in rt");
-}
diff --git a/src/module/sdk/GFSDKBuildInfo.h b/src/module/sdk/GFSDKBuildInfo.h
deleted file mode 100644
index a64d95c5..00000000
--- a/src/module/sdk/GFSDKBuildInfo.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric <[email protected]>
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend 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.
- *
- * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric <[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#pragma once
-
-#define GF_SDK_VERSION_MAJOR "2"
-#define GF_SDK_VERSION_MINOR "1"
-#define GF_SDK_VERSION_PATCH "3"
-
-#define GF_SDK_VERSION_STR \
- GF_SDK_VERSION_MAJOR "." GF_SDK_VERSION_MINOR "." GF_SDK_VERSION_PATCH
diff --git a/src/module/sdk/GFSDKLog.cpp b/src/module/sdk/GFSDKLog.cpp
deleted file mode 100644
index 603cc325..00000000
--- a/src/module/sdk/GFSDKLog.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric <[email protected]>
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend 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.
- *
- * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric <[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#include "GFSDKLog.h"
-
-#include "core/utils/LogUtils.h"
-
-#define MODULE_LOG_TRACE(...) GF_LOG_TRACE("module", __VA_ARGS__)
-#define MODULE_LOG_DEBUG(...) GF_LOG_DEBUG("module", __VA_ARGS__)
-#define MODULE_LOG_INFO(...) GF_LOG_INFO("module", __VA_ARGS__)
-#define MODULE_LOG_WARN(...) GF_LOG_WARN("module", __VA_ARGS__)
-#define MODULE_LOG_ERROR(...) GF_LOG_ERROR("module", __VA_ARGS__)
-
-void GFModuleLogTrace(const char* l) { MODULE_LOG_TRACE(l); }
-
-void GFModuleLogDebug(const char* l) { MODULE_LOG_DEBUG(l); }
-
-void GFModuleLogInfo(const char* l) { MODULE_LOG_INFO(l); }
-
-void GFModuleLogWarn(const char* l) { MODULE_LOG_WARN(l); }
-
-void GFModuleLogError(const char* l) { MODULE_LOG_ERROR(l); }
diff --git a/src/module/sdk/GFSDKUI.cpp b/src/module/sdk/GFSDKUI.cpp
deleted file mode 100644
index 63859763..00000000
--- a/src/module/sdk/GFSDKUI.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric <[email protected]>
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend 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.
- *
- * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric <[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */ \ No newline at end of file
diff --git a/src/pinentry/CMakeLists.txt b/src/pinentry/CMakeLists.txt
deleted file mode 100644
index cce5fcfb..00000000
--- a/src/pinentry/CMakeLists.txt
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright (C) 2021 Saturneric <[email protected]>
-#
-# This file is part of GpgFrontend.
-#
-# GpgFrontend 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.
-#
-# GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
-#
-# The initial version of the source code is inherited from
-# the gpg4usb project, which is under GPL-3.0-or-later.
-#
-# All the source code of GpgFrontend was modified and released by
-# Saturneric <[email protected]> starting on May 12, 2021.
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-aux_source_directory(. PINENTRY_SOURCE)
-
-# capslock
-list(APPEND PINENTRY_SOURCE "capslock/capslock.cpp")
-if (MINGW)
- list(APPEND PINENTRY_SOURCE "capslock/capslock_win.cpp")
-else()
- list(APPEND PINENTRY_SOURCE "capslock/capslock_unix.cpp")
-endif()
-
-add_library(gpgfrontend_pinentry SHARED ${PINENTRY_SOURCE})
-
-target_link_libraries(gpgfrontend_pinentry PUBLIC gpgfrontend_core)
-
-if(GPGFRONTEND_QT5_BUILD)
- # link Qt core
- target_link_libraries(gpgfrontend_pinentry PUBLIC Qt5::Widgets)
-else()
- # link Qt core
- target_link_libraries(gpgfrontend_pinentry PUBLIC Qt6::Widgets)
-endif()
-
-if (XCODE_BUILD)
- set_target_properties(gpgfrontend_pinentry
- PROPERTIES
- ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
- LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
- LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
- XCODE_ATTRIBUTE_SKIP_INSTALL "Yes"
- XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}")
-endif ()
-
-# spdlog
-target_link_libraries(gpgfrontend_pinentry PRIVATE spdlog)
-
-# using std c++ 17
-target_compile_features(gpgfrontend_pinentry PUBLIC cxx_std_17)
diff --git a/src/pinentry/accessibility.cpp b/src/pinentry/accessibility.cpp
deleted file mode 100644
index f139832a..00000000
--- a/src/pinentry/accessibility.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/* accessibility.cpp - Helpers for making pinentry accessible
- * Copyright (C) 2021 g10 Code GmbH
- *
- * Software engineering by Ingo Klöcker <[email protected]>
- *
- * 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 2 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 <https://www.gnu.org/licenses/>.
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include "accessibility.h"
-
-#include <QString>
-#include <QWidget>
-
-namespace Accessibility {
-
-void setDescription(QWidget *w, const QString &text) {
- if (w) {
-#ifndef QT_NO_ACCESSIBILITY
- w->setAccessibleDescription(text);
-#endif
- }
-}
-
-void setName(QWidget *w, const QString &text) {
- if (w) {
-#ifndef QT_NO_ACCESSIBILITY
- w->setAccessibleName(text);
-#endif
- }
-}
-
-} // namespace Accessibility
diff --git a/src/pinentry/accessibility.h b/src/pinentry/accessibility.h
deleted file mode 100644
index 9ef912d6..00000000
--- a/src/pinentry/accessibility.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* accessibility.h - Helpers for making pinentry accessible
- * Copyright (C) 2021 g10 Code GmbH
- *
- * Software engineering by Ingo Klöcker <[email protected]>
- *
- * 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 2 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 <https://www.gnu.org/licenses/>.
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#ifndef __PINENTRY_QT_ACCESSIBILITY_H__
-#define __PINENTRY_QT_ACCESSIBILITY_H__
-
-class QString;
-class QWidget;
-
-namespace Accessibility
-{
-
-/* Wrapper for QWidget::setAccessibleDescription which does nothing if
- QT_NO_ACCESSIBILITY is defined. */
-void setDescription(QWidget *w, const QString &text);
-
-/* Wrapper for QWidget::setAccessibleName which does nothing if
- QT_NO_ACCESSIBILITY is defined. */
-void setName(QWidget *w, const QString &text);
-
-} // namespace Accessibility
-
-#endif // __PINENTRY_QT_ACCESSIBILITY_H__
diff --git a/src/pinentry/capslock/capslock.cpp b/src/pinentry/capslock/capslock.cpp
deleted file mode 100644
index a730c220..00000000
--- a/src/pinentry/capslock/capslock.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/* capslock.cpp - Helper to check whether Caps Lock is on
- * Copyright (C) 2021 g10 Code GmbH
- *
- * Software engineering by Ingo Klöcker <[email protected]>
- *
- * 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 2 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 <https://www.gnu.org/licenses/>.
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include <QDebug>
-#include <QGuiApplication>
-
-#include "capslock.h"
-
-CapsLockWatcher::Private::Private(CapsLockWatcher *q) : q{q} {
-#ifdef PINENTRY_QT_WAYLAND
- if (qApp->platformName() == QLatin1String("wayland")) {
- watchWayland();
- }
-#endif
-}
-
-CapsLockWatcher::CapsLockWatcher(QObject *parent)
- : QObject{parent}, d{new Private{this}} {
- if (qApp->platformName() == QLatin1String("wayland")) {
-#ifndef PINENTRY_QT_WAYLAND
- qWarning() << "CapsLockWatcher was compiled without support for Wayland";
-#endif
- }
-}
diff --git a/src/pinentry/capslock/capslock.h b/src/pinentry/capslock/capslock.h
deleted file mode 100644
index 138f88cc..00000000
--- a/src/pinentry/capslock/capslock.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/* capslock.h - Helper to check whether Caps Lock is on
- * Copyright (C) 2021 g10 Code GmbH
- *
- * Software engineering by Ingo Klöcker <[email protected]>
- *
- * 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 2 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 <https://www.gnu.org/licenses/>.
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#ifndef __PINENTRY_QT_CAPSLOCK_H__
-#define __PINENTRY_QT_CAPSLOCK_H__
-
-#include <QObject>
-#include <memory>
-
-enum class LockState { Unknown = -1, Off, On };
-
-LockState capsLockState();
-
-#ifdef PINENTRY_QT_WAYLAND
-namespace KWayland {
-namespace Client {
-class Registry;
-class Seat;
-} // namespace Client
-} // namespace KWayland
-#endif
-
-class CapsLockWatcher : public QObject {
- Q_OBJECT
-
- public:
- explicit CapsLockWatcher(QObject *parent = nullptr);
-
- Q_SIGNALS:
- void stateChanged(bool locked);
-
- private:
- class Private;
- std::unique_ptr<Private> d;
-};
-
-class CapsLockWatcher::Private {
- public:
- explicit Private(CapsLockWatcher *);
-#ifdef PINENTRY_QT_WAYLAND
- void watchWayland();
-#endif
-
- private:
-#ifdef PINENTRY_QT_WAYLAND
- void registry_seatAnnounced(quint32, quint32);
- void seat_hasKeyboardChanged(bool);
- void keyboard_modifiersChanged(quint32);
-#endif
-
- private:
- CapsLockWatcher *const q;
-
-#ifdef PINENTRY_QT_WAYLAND
- KWayland::Client::Registry *registry = nullptr;
- KWayland::Client::Seat *seat = nullptr;
-#endif
-};
-
-#endif // __PINENTRY_QT_CAPSLOCK_H__
diff --git a/src/pinentry/capslock/capslock_unix.cpp b/src/pinentry/capslock/capslock_unix.cpp
deleted file mode 100644
index e4f4cd17..00000000
--- a/src/pinentry/capslock/capslock_unix.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/* capslock_unix.cpp - Helper to check whether Caps Lock is on
- * Copyright (C) 2021 g10 Code GmbH
- *
- * Software engineering by Ingo Klöcker <[email protected]>
- *
- * 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 2 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 <https://www.gnu.org/licenses/>.
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "capslock.h"
-
-#ifdef PINENTRY_QT_WAYLAND
-#include <KWayland/Client/connection_thread.h>
-#include <KWayland/Client/keyboard.h>
-#include <KWayland/Client/registry.h>
-#include <KWayland/Client/seat.h>
-#endif
-
-#include <QGuiApplication>
-
-#ifdef PINENTRY_QT_X11
-#include <X11/XKBlib.h>
-
-#include <QX11Info>
-#undef Status
-#endif
-
-#include <QDebug>
-
-#ifdef PINENTRY_QT_WAYLAND
-using namespace KWayland::Client;
-#endif
-
-#ifdef PINENTRY_QT_WAYLAND
-static bool watchingWayland = false;
-#endif
-
-LockState capsLockState() {
- static bool reportUnsupportedPlatform = true;
-#ifdef PINENTRY_QT_X11
- if (qApp->platformName() == QLatin1String("xcb")) {
- unsigned int state;
- XkbGetIndicatorState(QX11Info::display(), XkbUseCoreKbd, &state);
- return (state & 0x01) == 1 ? LockState::On : LockState::Off;
- }
-#endif
-#ifdef PINENTRY_QT_WAYLAND
- if (qApp->platformName() == QLatin1String("wayland")) {
- if (!watchingWayland && reportUnsupportedPlatform) {
- qDebug() << "Use CapsLockWatcher for checking for Caps Lock on Wayland";
- }
- } else
-#endif
- if (reportUnsupportedPlatform) {
- qWarning() << "Checking for Caps Lock not possible on unsupported platform:"
- << qApp->platformName();
- }
- reportUnsupportedPlatform = false;
- return LockState::Unknown;
-}
-
-#ifdef PINENTRY_QT_WAYLAND
-void CapsLockWatcher::Private::watchWayland() {
- watchingWayland = true;
- auto connection = ConnectionThread::fromApplication(q);
- if (!connection) {
- qWarning() << "Failed to get connection to Wayland server from QPA";
- return;
- }
- registry = new Registry{q};
- registry->create(connection);
- if (!registry->isValid()) {
- qWarning() << "Failed to create valid KWayland registry";
- return;
- }
- registry->setup();
-
- connect(registry, &Registry::seatAnnounced, q,
- [this](quint32 name, quint32 version) {
- registry_seatAnnounced(name, version);
- });
-}
-
-void CapsLockWatcher::Private::registry_seatAnnounced(quint32 name,
- quint32 version) {
- Q_ASSERT(registry);
- seat = registry->createSeat(name, version, q);
- if (!seat->isValid()) {
- qWarning() << "Failed to create valid KWayland seat";
- return;
- }
-
- connect(seat, &Seat::hasKeyboardChanged, q,
- [this](bool hasKeyboard) { seat_hasKeyboardChanged(hasKeyboard); });
-}
-
-void CapsLockWatcher::Private::seat_hasKeyboardChanged(bool hasKeyboard) {
- Q_ASSERT(seat);
-
- if (!hasKeyboard) {
- qDebug() << "Seat has no keyboard";
- return;
- }
-
- auto keyboard = seat->createKeyboard(q);
- if (!keyboard->isValid()) {
- qWarning() << "Failed to create valid KWayland keyboard";
- return;
- }
-
- connect(keyboard, &Keyboard::modifiersChanged, q,
- [this](quint32, quint32, quint32 locked, quint32) {
- keyboard_modifiersChanged(locked);
- });
-}
-
-void CapsLockWatcher::Private::keyboard_modifiersChanged(quint32 locked) {
- const bool capsLockIsLocked = (locked & 2u) != 0;
- qDebug() << "Caps Lock is locked:" << capsLockIsLocked;
- Q_EMIT q->stateChanged(capsLockIsLocked);
-}
-#endif
diff --git a/src/pinentry/capslock/capslock_win.cpp b/src/pinentry/capslock/capslock_win.cpp
deleted file mode 100644
index 46bc7043..00000000
--- a/src/pinentry/capslock/capslock_win.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/* capslock_win.cpp - Helper to check whether Caps Lock is on
- * Copyright (C) 2021 g10 Code GmbH
- *
- * Software engineering by Ingo Klöcker <[email protected]>
- *
- * 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 2 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 <https://www.gnu.org/licenses/>.
- * SPDX-License-Identifier: GPL-2.0+
- */
-#include <windows.h>
-
-#include "capslock.h"
-
-LockState capsLockState() {
- return (GetKeyState(VK_CAPITAL) & 1) ? LockState::On : LockState::Off;
-}
diff --git a/src/pinentry/pinentry.cpp b/src/pinentry/pinentry.cpp
deleted file mode 100644
index 5f233f5d..00000000
--- a/src/pinentry/pinentry.cpp
+++ /dev/null
@@ -1,570 +0,0 @@
-/* pinentry.c - The PIN entry support library
- * Copyright (C) 2002, 2003, 2007, 2008, 2010, 2015, 2016, 2021 g10 Code GmbH
- *
- * This file is part of PINENTRY.
- *
- * PINENTRY 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 2 of the License, or
- * (at your option) any later version.
- *
- * PINENTRY 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 <https://www.gnu.org/licenses/>.
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifndef WINDOWS
-#include <errno.h>
-#endif
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-#ifndef WINDOWS
-#include <sys/utsname.h>
-#endif
-#ifndef WINDOWS
-#include <locale.h>
-#endif
-#include <limits.h>
-#ifdef WINDOWS
-#include <windows.h>
-#endif
-
-#include <assuan.h>
-
-#include "core/utils/MemoryUtils.h"
-#include "pinentry.h"
-
-#ifdef WINDOWS
-#define getpid() GetCurrentProcessId()
-#endif
-
-/* Keep the name of our program here. */
-static char this_pgmname[50];
-
-struct pinentry pinentry;
-
-static const char *flavor_flag;
-
-/* Because gtk_init removes the --display arg from the command lines
- * and our command line parser is called after gtk_init (so that it
- * does not see gtk specific options) we don't have a way to get hold
- * of the --display option. Our solution is to remember --display in
- * the call to pinentry_have_display and set it then in our
- * parser. */
-static char *remember_display;
-
-static void pinentry_reset(int use_defaults) {
- /* GPG Agent sets these options once when it starts the pinentry.
- Don't reset them. */
- int grab = pinentry.grab;
- char *ttyname = pinentry.ttyname;
- char *ttytype = pinentry.ttytype_l;
- char *ttyalert = pinentry.ttyalert;
- char *lc_ctype = pinentry.lc_ctype;
- char *lc_messages = pinentry.lc_messages;
- int allow_external_password_cache = pinentry.allow_external_password_cache;
- char *default_ok = pinentry.default_ok;
- char *default_cancel = pinentry.default_cancel;
- char *default_prompt = pinentry.default_prompt;
- char *default_pwmngr = pinentry.default_pwmngr;
- char *default_cf_visi = pinentry.default_cf_visi;
- char *default_tt_visi = pinentry.default_tt_visi;
- char *default_tt_hide = pinentry.default_tt_hide;
- char *default_capshint = pinentry.default_capshint;
- char *touch_file = pinentry.touch_file;
- unsigned long owner_pid = pinentry.owner_pid;
- int owner_uid = pinentry.owner_uid;
- char *owner_host = pinentry.owner_host;
- int constraints_enforce = pinentry.constraints_enforce;
- char *constraints_hint_short = pinentry.constraints_hint_short;
- char *constraints_hint_long = pinentry.constraints_hint_long;
- char *constraints_error_title = pinentry.constraints_error_title;
-
- /* These options are set from the command line. Don't reset
- them. */
- int debug = pinentry.debug;
- char *display = pinentry.display;
- int parent_wid = pinentry.parent_wid;
-
- pinentry_color_t color_fg = pinentry.color_fg;
- int color_fg_bright = pinentry.color_fg_bright;
- pinentry_color_t color_bg = pinentry.color_bg;
- pinentry_color_t color_so = pinentry.color_so;
- int color_so_bright = pinentry.color_so_bright;
- pinentry_color_t color_ok = pinentry.color_ok;
- int color_ok_bright = pinentry.color_ok_bright;
- pinentry_color_t color_qualitybar = pinentry.color_qualitybar;
- int color_qualitybar_bright = pinentry.color_qualitybar_bright;
-
- int timeout = pinentry.timeout;
-
- char *invisible_char = pinentry.invisible_char;
-
- /* Free any allocated memory. */
- if (use_defaults) {
- free(pinentry.ttyname);
- free(pinentry.ttytype_l);
- free(pinentry.ttyalert);
- free(pinentry.lc_ctype);
- free(pinentry.lc_messages);
- free(pinentry.default_ok);
- free(pinentry.default_cancel);
- free(pinentry.default_prompt);
- free(pinentry.default_pwmngr);
- free(pinentry.default_cf_visi);
- free(pinentry.default_tt_visi);
- free(pinentry.default_tt_hide);
- free(pinentry.default_capshint);
- free(pinentry.touch_file);
- free(pinentry.owner_host);
- free(pinentry.display);
- free(pinentry.constraints_hint_short);
- free(pinentry.constraints_hint_long);
- free(pinentry.constraints_error_title);
- }
-
- free(pinentry.title);
- free(pinentry.description);
- free(pinentry.error);
- free(pinentry.prompt);
- free(pinentry.ok);
- free(pinentry.notok);
- free(pinentry.cancel);
- GpgFrontend::SecureFree(pinentry.pin);
- free(pinentry.repeat_passphrase);
- free(pinentry.repeat_error_string);
- free(pinentry.quality_bar);
- free(pinentry.quality_bar_tt);
- free(pinentry.formatted_passphrase_hint);
- free(pinentry.keyinfo);
- free(pinentry.specific_err_info);
-
- /* Reset the pinentry structure. */
- memset(&pinentry, 0, sizeof(pinentry));
-
- /* Restore options without a default we want to preserve. */
- pinentry.invisible_char = invisible_char;
-
- /* Restore other options or set defaults. */
-
- if (use_defaults) {
- /* Pinentry timeout in seconds. */
- pinentry.timeout = 60;
-
- /* Global grab. */
- pinentry.grab = 1;
-
- pinentry.color_fg = PINENTRY_COLOR_DEFAULT;
- pinentry.color_fg_bright = 0;
- pinentry.color_bg = PINENTRY_COLOR_DEFAULT;
- pinentry.color_so = PINENTRY_COLOR_DEFAULT;
- pinentry.color_so_bright = 0;
- pinentry.color_ok = PINENTRY_COLOR_DEFAULT;
- pinentry.color_ok_bright = 0;
- pinentry.color_qualitybar = PINENTRY_COLOR_DEFAULT;
- pinentry.color_qualitybar_bright = 0;
-
- pinentry.owner_uid = -1;
- } else /* Restore the options. */
- {
- pinentry.grab = grab;
- pinentry.ttyname = ttyname;
- pinentry.ttytype_l = ttytype;
- pinentry.ttyalert = ttyalert;
- pinentry.lc_ctype = lc_ctype;
- pinentry.lc_messages = lc_messages;
- pinentry.allow_external_password_cache = allow_external_password_cache;
- pinentry.default_ok = default_ok;
- pinentry.default_cancel = default_cancel;
- pinentry.default_prompt = default_prompt;
- pinentry.default_pwmngr = default_pwmngr;
- pinentry.default_cf_visi = default_cf_visi;
- pinentry.default_tt_visi = default_tt_visi;
- pinentry.default_tt_hide = default_tt_hide;
- pinentry.default_capshint = default_capshint;
- pinentry.touch_file = touch_file;
- pinentry.owner_pid = owner_pid;
- pinentry.owner_uid = owner_uid;
- pinentry.owner_host = owner_host;
- pinentry.constraints_enforce = constraints_enforce;
- pinentry.constraints_hint_short = constraints_hint_short;
- pinentry.constraints_hint_long = constraints_hint_long;
- pinentry.constraints_error_title = constraints_error_title;
-
- pinentry.debug = debug;
- pinentry.display = display;
- pinentry.parent_wid = parent_wid;
-
- pinentry.color_fg = color_fg;
- pinentry.color_fg_bright = color_fg_bright;
- pinentry.color_bg = color_bg;
- pinentry.color_so = color_so;
- pinentry.color_so_bright = color_so_bright;
- pinentry.color_ok = color_ok;
- pinentry.color_ok_bright = color_ok_bright;
- pinentry.color_qualitybar = color_qualitybar;
- pinentry.color_qualitybar_bright = color_qualitybar_bright;
-
- pinentry.timeout = timeout;
- }
-}
-
-static gpg_error_t pinentry_assuan_reset_handler(assuan_context_t ctx,
- char *line) {
- (void)ctx;
- (void)line;
-
- pinentry_reset(0);
-
- return 0;
-}
-
-/* Return a malloced copy of the commandline for PID. If this is not
- * possible NULL is returned. */
-#ifndef WINDOWS
-static char *get_cmdline(unsigned long pid) {
- char buffer[200];
- FILE *fp;
- size_t i, n;
-
- snprintf(buffer, sizeof buffer, "/proc/%lu/cmdline", pid);
-
- fp = fopen(buffer, "rb");
- if (!fp) return NULL;
- n = fread(buffer, 1, sizeof buffer - 1, fp);
- if (n < sizeof buffer - 1 && ferror(fp)) {
- /* Some error occurred. */
- fclose(fp);
- return NULL;
- }
- fclose(fp);
- if (n == 0) return NULL;
- /* Arguments are delimited by Nuls. We should do proper quoting but
- * that can be a bit complicated, thus we simply replace the Nuls by
- * spaces. */
- for (i = 0; i < n; i++)
- if (!buffer[i] && i < n - 1) buffer[i] = ' ';
- buffer[i] = 0; /* Make sure the last byte is the string terminator. */
-
- return strdup(buffer);
-}
-#endif /*!WINDOWS*/
-
-/* Atomically ask the kernel for information about process PID.
- * Return a malloc'ed copy of the process name as long as the process
- * uid matches UID. If it cannot determine that the process has uid
- * UID, it returns NULL.
- *
- * This is not as informative as get_cmdline, but it verifies that the
- * process does belong to the user in question.
- */
-#ifndef WINDOWS
-static char *get_pid_name_for_uid(unsigned long pid, int uid) {
- char buffer[400];
- FILE *fp;
- size_t end, n;
- char *uidstr;
-
- snprintf(buffer, sizeof buffer, "/proc/%lu/status", pid);
-
- fp = fopen(buffer, "rb");
- if (!fp) return NULL;
- n = fread(buffer, 1, sizeof buffer - 1, fp);
- if (n < sizeof buffer - 1 && ferror(fp)) {
- /* Some error occurred. */
- fclose(fp);
- return NULL;
- }
- fclose(fp);
- if (n == 0) return NULL;
- buffer[n] = 0;
- /* Fixme: Is it specified that "Name" is always the first line? For
- * robustness I would prefer to have a real parser here. -wk */
- if (strncmp(buffer, "Name:\t", 6)) return NULL;
- end = strcspn(buffer + 6, "\n") + 6;
- buffer[end] = 0;
-
- /* check that uid matches what we expect */
- uidstr = strstr(buffer + end + 1, "\nUid:\t");
- if (!uidstr) return NULL;
- if (atoi(uidstr + 6) != uid) return NULL;
-
- return strdup(buffer + 6);
-}
-#endif /*!WINDOWS*/
-
-const char *pinentry_get_pgmname(void) { return this_pgmname; }
-
-/* Return a malloced string with the title. The caller mus free the
- * string. If no title is available or the title string has an error
- * NULL is returned. */
-char *pinentry_get_title(pinentry_t pe) {
- char *title;
-
- if (pe->title) title = strdup(pe->title);
-#ifndef WINDOWS
- else if (pe->owner_pid) {
- char buf[200];
- struct utsname utsbuf;
- char *pidname = NULL;
- char *cmdline = NULL;
-
- if (pe->owner_host && !uname(&utsbuf) &&
- !strcmp(utsbuf.nodename, pe->owner_host)) {
- pidname = get_pid_name_for_uid(pe->owner_pid, pe->owner_uid);
- if (pidname) cmdline = get_cmdline(pe->owner_pid);
- }
-
- if (pe->owner_host && (cmdline || pidname))
- snprintf(buf, sizeof buf, "[%lu]@%s (%s)", pe->owner_pid, pe->owner_host,
- cmdline ? cmdline : pidname);
- else if (pe->owner_host)
- snprintf(buf, sizeof buf, "[%lu]@%s", pe->owner_pid, pe->owner_host);
- else
- snprintf(buf, sizeof buf, "[%lu] <unknown host>", pe->owner_pid);
- free(pidname);
- free(cmdline);
- title = strdup(buf);
- }
-#endif /*!WINDOWS*/
- else
- title = strdup(this_pgmname);
-
- return title;
-}
-
-/* Run a quality inquiry for PASSPHRASE of LENGTH. (We need LENGTH
- because not all backends might be able to return a proper
- C-string.). Returns: A value between -100 and 100 to give an
- estimate of the passphrase's quality. Negative values are use if
- the caller won't even accept that passphrase. Note that we expect
- just one data line which should not be escaped in any represent a
- numeric signed decimal value. Extra data is currently ignored but
- should not be send at all. */
-int pinentry_inq_quality(const QString &passphrase) {
- int score = 0;
-
- score += std::min(40, static_cast<int>(passphrase.length()) * 2);
-
- bool has_upper = false;
- bool has_lower = false;
- bool has_digit = false;
- bool has_special = false;
- for (const auto ch : passphrase) {
- if (ch.isUpper()) has_upper = true;
- if (ch.isLower()) has_lower = true;
- if (ch.isDigit()) has_digit = true;
- if (!ch.isLetterOrNumber()) has_special = true;
- }
-
- int const variety_count =
- static_cast<int>(has_upper) + static_cast<int>(has_lower) +
- static_cast<int>(has_digit) + static_cast<int>(has_special);
- score += variety_count * 10;
-
- for (auto i = 0; i < passphrase.length() - 1; ++i) {
- if (passphrase[i] == passphrase[i + 1]) {
- score -= 5;
- }
- }
-
- QHash<QChar, int> char_count;
- for (const auto ch : passphrase) {
- char_count[ch]++;
- }
- for (auto &p : char_count) {
- if (p > 1) {
- score -= (p - 1) * 3;
- }
- }
-
- QString const lower_password = passphrase.toLower();
- if (lower_password.contains("password") ||
- lower_password.contains("123456")) {
- score -= 30;
- }
-
- return std::max(-100, std::min(100, score));
-}
-
-/* Run a genpin inquiry */
-char *pinentry_inq_genpin(pinentry_t pin) {
- assuan_context_t ctx = (assuan_context_t)pin->ctx_assuan;
- const char prefix[] = "INQUIRE GENPIN";
- char *line;
- size_t linelen;
- int gotvalue = 0;
- char *value = NULL;
- int rc;
-
- if (!ctx) return 0; /* Can't run the callback. */
-
- rc = assuan_write_line(ctx, prefix);
- if (rc) {
- fprintf(stderr, "ASSUAN WRITE LINE failed: rc=%d\n", rc);
- return 0;
- }
-
- for (;;) {
- do {
- rc = assuan_read_line(ctx, &line, &linelen);
- if (rc) {
- fprintf(stderr, "ASSUAN READ LINE failed: rc=%d\n", rc);
- free(value);
- return 0;
- }
- } while (*line == '#' || !linelen);
- if (line[0] == 'E' && line[1] == 'N' && line[2] == 'D' &&
- (!line[3] || line[3] == ' '))
- break; /* END command received*/
- if (line[0] == 'C' && line[1] == 'A' && line[2] == 'N' &&
- (!line[3] || line[3] == ' '))
- break; /* CAN command received*/
- if (line[0] == 'E' && line[1] == 'R' && line[2] == 'R' &&
- (!line[3] || line[3] == ' '))
- break; /* ERR command received*/
- if (line[0] != 'D' || line[1] != ' ' || linelen < 3 || gotvalue) continue;
- gotvalue = 1;
- value = strdup(line + 2);
- }
-
- return value;
-}
-
-/* Try to make room for at least LEN bytes in the pinentry. Returns
- new buffer on success and 0 on failure or when the old buffer is
- sufficient. */
-char *pinentry_setbufferlen(pinentry_t pin, int len) {
- char *newp;
-
- if (pin->pin_len)
- assert(pin->pin);
- else
- assert(!pin->pin);
-
- if (len < 2048) len = 2048;
-
- if (len <= pin->pin_len) return pin->pin;
-
- newp = GpgFrontend::SecureReallocAsType<char>(pin->pin, len);
- if (newp) {
- pin->pin = newp;
- pin->pin_len = len;
- } else {
- GpgFrontend::SecureFree(pin->pin);
- pin->pin = 0;
- pin->pin_len = 0;
- }
- return newp;
-}
-
-static void pinentry_setbuffer_clear(pinentry_t pin) {
- if (!pin->pin) {
- assert(pin->pin_len == 0);
- return;
- }
-
- assert(pin->pin_len > 0);
-
- GpgFrontend::SecureFree(pin->pin);
- pin->pin = NULL;
- pin->pin_len = 0;
-}
-
-static struct assuan_malloc_hooks assuan_malloc_hooks = {
- GpgFrontend::SecureMalloc, GpgFrontend::SecureRealloc,
- GpgFrontend::SecureFree};
-
-/* Simple test to check whether DISPLAY is set or the option --display
- was given. Used to decide whether the GUI or curses should be
- initialized. */
-int pinentry_have_display(int argc, char **argv) {
- int found = 0;
-
- for (; argc; argc--, argv++) {
- if (!strcmp(*argv, "--display")) {
- if (argv[1] && !remember_display) {
- remember_display = strdup(argv[1]);
- if (!remember_display) {
-#ifndef WINDOWS
- fprintf(stderr, "%s: %s\n", this_pgmname, strerror(errno));
-#endif
- exit(EXIT_FAILURE);
- }
- }
- found = 1;
- break;
- } else if (!strncmp(*argv, "--display=", 10)) {
- if (!remember_display) {
- remember_display = strdup(*argv + 10);
- if (!remember_display) {
-#ifndef WINDOWS
- fprintf(stderr, "%s: %s\n", this_pgmname, strerror(errno));
-#endif
- exit(EXIT_FAILURE);
- }
- }
- found = 1;
- break;
- }
- }
-
-#ifndef WINDOWS
- {
- const char *s;
- s = getenv("DISPLAY");
- if (s && *s) found = 1;
- }
-#endif
-
- return found;
-}
-
-/* Set the optional flag used with getinfo. */
-void pinentry_set_flavor_flag(const char *string) { flavor_flag = string; }
-
-/* Note, that it is sufficient to allocate the target string D as
- long as the source string S, i.e.: strlen(s)+1; */
-static void strcpy_escaped(char *d, const char *s) {
- while (*s) {
- if (*s == '%' && s[1] && s[2]) {
- s++;
- *d++ = xtoi_2(s);
- s += 2;
- } else
- *d++ = *s++;
- }
- *d = 0;
-}
-
-/* Return a staically allocated string with information on the mode,
- * uid, and gid of DEVICE. On error "?" is returned if DEVICE is
- * NULL, "-" is returned. */
-static const char *device_stat_string(const char *device) {
-#ifdef HAVE_STAT
- static char buf[40];
- struct stat st;
-
- if (!device || !*device) return "-";
-
- if (stat(device, &st)) return "?"; /* Error */
- snprintf(buf, sizeof buf, "%lo/%lu/%lu", (unsigned long)st.st_mode,
- (unsigned long)st.st_uid, (unsigned long)st.st_gid);
- return buf;
-#else
- return "-";
-#endif
-} \ No newline at end of file
diff --git a/src/pinentry/pinentry.h b/src/pinentry/pinentry.h
deleted file mode 100644
index 143a8855..00000000
--- a/src/pinentry/pinentry.h
+++ /dev/null
@@ -1,339 +0,0 @@
-/* pinentry.h - The interface for the PIN entry support library.
- * Copyright (C) 2002, 2003, 2010, 2015, 2021 g10 Code GmbH
- *
- * This file is part of PINENTRY.
- *
- * PINENTRY 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 2 of the License, or
- * (at your option) any later version.
- *
- * PINENTRY 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 <https://www.gnu.org/licenses/>.
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#ifndef PINENTRY_H
-#define PINENTRY_H
-
-#include <cstdint>
-
-#ifdef __cplusplus
-extern "C" {
-#if 0
-}
-#endif
-#endif
-
-typedef enum {
- PINENTRY_COLOR_NONE,
- PINENTRY_COLOR_DEFAULT,
- PINENTRY_COLOR_BLACK,
- PINENTRY_COLOR_RED,
- PINENTRY_COLOR_GREEN,
- PINENTRY_COLOR_YELLOW,
- PINENTRY_COLOR_BLUE,
- PINENTRY_COLOR_MAGENTA,
- PINENTRY_COLOR_CYAN,
- PINENTRY_COLOR_WHITE
-} pinentry_color_t;
-
-struct pinentry {
- /* The window title, or NULL. (Assuan: "SETTITLE TITLE".) */
- char *title;
- /* The description to display, or NULL. (Assuan: "SETDESC
- DESC".) */
- char *description;
- /* The error message to display, or NULL. (Assuan: "SETERROR
- MESSAGE".) */
- char *error;
- /* The prompt to display, or NULL. (Assuan: "SETPROMPT
- prompt".) */
- char *prompt;
- /* The OK button text to display, or NULL. (Assuan: "SETOK
- OK".) */
- char *ok;
- /* The Not-OK button text to display, or NULL. This is the text for
- the alternative option shown by the third button. (Assuan:
- "SETNOTOK NOTOK".) */
- char *notok;
- /* The Cancel button text to display, or NULL. (Assuan: "SETCANCEL
- CANCEL".) */
- char *cancel;
-
- /* The buffer to store the secret into. */
- char *pin;
- /* The length of the buffer. */
- int pin_len;
- /* Whether the pin was read from an external cache (1) or entered by
- the user (0). */
- int pin_from_cache;
-
- /* The name of the X display to use if X is available and supported.
- (Assuan: "OPTION display DISPLAY".) */
- char *display;
- /* The name of the terminal node to open if X not available or
- supported. (Assuan: "OPTION ttyname TTYNAME".) */
- char *ttyname;
- /* The type of the terminal. (Assuan: "OPTION ttytype TTYTYPE".) */
- char *ttytype_l;
- /* Set the alert mode (none, beep or flash). */
- char *ttyalert;
- /* The LC_CTYPE value for the terminal. (Assuan: "OPTION lc-ctype
- LC_CTYPE".) */
- char *lc_ctype;
- /* The LC_MESSAGES value for the terminal. (Assuan: "OPTION
- lc-messages LC_MESSAGES".) */
- char *lc_messages;
-
- /* True if debug mode is requested. */
- int debug;
-
- /* The number of seconds before giving up while waiting for user input. */
- int timeout;
-
- /* True if caller should grab the keyboard. (Assuan: "OPTION grab"
- or "OPTION no-grab".) */
- int grab;
-
- /* The PID of the owner or 0 if not known. The owner is the process
- * which actually triggered the the pinentry. For example gpg. */
- unsigned long owner_pid;
-
- /* The numeric uid (user ID) of the owner process or -1 if not
- * known. */
- int owner_uid;
-
- /* The malloced hostname of the owner or NULL. */
- char *owner_host;
-
- /* The window ID of the parent window over which the pinentry window
- should be displayed. (Assuan: "OPTION parent-wid WID".) */
- int parent_wid;
-
- /* The name of an optional file which will be touched after a curses
- entry has been displayed. (Assuan: "OPTION touch-file
- FILENAME".) */
- char *touch_file;
-
- /* The frontend should set this to -1 if the user canceled the
- request, and to the length of the PIN stored in pin
- otherwise. */
- int result;
-
- /* The frontend should set this if the NOTOK button was pressed. */
- int canceled;
-
- /* The frontend should set this to true if an error with the local
- conversion occurred. */
- int locale_err;
-
- /* The frontend should set this to a gpg-error so that commands are
- able to return specific error codes. This is an ugly hack due to
- the fact that pinentry_cmd_handler_t returns the length of the
- passphrase or a negative error code. */
- int specific_err;
-
- /* The frontend may store a string with the error location here. */
- const char *specific_err_loc;
-
- /* The frontend may store a malloced string here to emit an ERROR
- * status code with this extra info along with SPECIFIC_ERR. */
- char *specific_err_info;
-
- /* The frontend should set this to true if the window close button
- has been used. This flag is used in addition to a regular return
- value. */
- int close_button;
-
- /* The caller should set this to true if only one button is
- required. This is useful for notification dialogs where only a
- dismiss button is required. */
- int one_button;
-
- /* Whether this is a CONFIRM pinentry. */
- int confirm;
-
- /* If true a second prompt for the passphrase is shown and the user
- is expected to enter the same passphrase again. Pinentry checks
- that both match. (Assuan: "SETREPEAT".) */
- char *repeat_passphrase;
-
- /* The string to show if a repeated passphrase does not match.
- (Assuan: "SETREPEATERROR ERROR".) */
- char *repeat_error_string;
-
- /* The string to show if a repeated passphrase does match.
- (Assuan: "SETREPEATOK STRING".) */
- char *repeat_ok_string;
-
- /* Set to true if the passphrase has been entered a second time and
- matches the first passphrase. */
- int repeat_okay;
-
- /* If this is not NULL, a passphrase quality indicator is shown.
- There will also be an inquiry back to the caller to get an
- indication of the quality for the passphrase entered so far. The
- string is used as a label for the quality bar. (Assuan:
- "SETQUALITYBAR LABEL".) */
- char *quality_bar;
-
- /* The tooltip to be shown for the qualitybar. Malloced or NULL.
- (Assuan: "SETQUALITYBAR_TT TOOLTIP".) */
- char *quality_bar_tt;
-
- /* If this is not NULL, a generate action should be shown.
- There will be an inquiry back to the caller to get such a
- PIN. generate action. Malloced or NULL.
- (Assuan: "SETGENPIN LABEL" .) */
- char *genpin_label;
-
- /* The tooltip to be shown for the generate action. Malloced or NULL.
- (Assuan: "SETGENPIN_TT TOOLTIP".) */
- char *genpin_tt;
-
- /* Specifies whether passphrase formatting should be enabled.
- (Assuan: "OPTION formatted-passphrase") */
- int formatted_passphrase;
-
- /* A hint to be shown near the passphrase input field if passphrase
- formatting is enabled. Malloced or NULL.
- (Assuan: "OPTION formatted-passphrase-hint=HINT".) */
- char *formatted_passphrase_hint;
-
- /* For the curses pinentry, the color of error messages. */
- pinentry_color_t color_fg;
- int color_fg_bright;
- pinentry_color_t color_bg;
- pinentry_color_t color_so;
- int color_so_bright;
- pinentry_color_t color_ok;
- int color_ok_bright;
- pinentry_color_t color_qualitybar;
- int color_qualitybar_bright;
-
- /* Malloced and i18ned default strings or NULL. These strings may
- include an underscore character to indicate an accelerator key.
- A double underscore represents a plain one. */
- /* (Assuan: "OPTION default-ok OK"). */
- char *default_ok;
- /* (Assuan: "OPTION default-cancel CANCEL"). */
- char *default_cancel;
- /* (Assuan: "OPTION default-prompt PROMPT"). */
- char *default_prompt;
- /* (Assuan: "OPTION default-pwmngr
- SAVE_PASSWORD_WITH_PASSWORD_MANAGER?"). */
- char *default_pwmngr;
- /* (Assuan: "OPTION default-cf-visi
- Do you really want to make your passphrase visible?"). */
- char *default_cf_visi;
- /* (Assuan: "OPTION default-tt-visi
- Make passphrase visible?"). */
- char *default_tt_visi;
- /* (Assuan: "OPTION default-tt-hide
- Hide passphrase"). */
- char *default_tt_hide;
- /* (Assuan: "OPTION default-capshint
- Caps Lock is on"). */
- char *default_capshint;
-
- /* Whether we are allowed to read the password from an external
- cache. (Assuan: "OPTION allow-external-password-cache") */
- int allow_external_password_cache;
-
- /* We only try the cache once. */
- int tried_password_cache;
-
- /* A stable identifier for the key. (Assuan: "SETKEYINFO
- KEYINFO".) */
- char *keyinfo;
-
- /* Whether we may cache the password (according to the user). */
- int may_cache_password;
-
- /* NOTE: If you add any additional fields to this structure, be sure
- to update the initializer in pinentry/pinentry.c!!! */
-
- /* For the quality indicator and genpin we need to do an inquiry.
- Thus we need to save the assuan ctx. */
- void *ctx_assuan;
-
- /* An UTF-8 string with an invisible character used to override the
- default in some pinentries. Only the first character is
- used. */
- char *invisible_char;
-
- /* Whether the passphrase constraints are enforced by gpg-agent.
- (Assuan: "OPTION constraints-enforce") */
- int constraints_enforce;
-
- /* A short translated hint for the user with the constraints for new
- passphrases to be displayed near the passphrase input field.
- Malloced or NULL.
- (Assuan: "OPTION constraints-hint-short=At least 8 characters".) */
- char *constraints_hint_short;
-
- /* A longer translated hint for the user with the constraints for new
- passphrases to be displayed for example as tooltip. Malloced or NULL.
- (Assuan: "OPTION constraints-hint-long=The passphrase must ...".) */
- char *constraints_hint_long;
-
- /* A short translated title for an error dialog informing the user about
- unsatisfied passphrase constraints. Malloced or NULL.
- (Assuan: "OPTION constraints-error-title=Passphrase Not Allowed".) */
- char *constraints_error_title;
-};
-typedef struct pinentry *pinentry_t;
-
-/* The pinentry command handler type processes the pinentry request
- PIN. If PIN->pin is zero, request a confirmation, otherwise a PIN
- entry. On confirmation, the function should return TRUE if
- confirmed, and FALSE otherwise. On PIN entry, the function should
- return -1 if an error occurred or the user cancelled the operation
- and 1 otherwise. */
-typedef int (*pinentry_cmd_handler_t)(pinentry_t pin);
-
-const char *pinentry_get_pgmname(void);
-
-char *pinentry_get_title(pinentry_t pe);
-
-/* Run a quality inquiry for PASSPHRASE of LENGTH. */
-int pinentry_inq_quality(const QString &passphrase);
-
-/* Run a genpin iquriry. Returns a malloced string or NULL */
-char *pinentry_inq_genpin(pinentry_t pin);
-
-/* Try to make room for at least LEN bytes for the pin in the pinentry
- PIN. Returns new buffer on success and 0 on failure. */
-char *pinentry_setbufferlen(pinentry_t pin, int len);
-
-/* Return true if either DISPLAY is set or ARGV contains the string
- "--display". */
-int pinentry_have_display(int argc, char **argv);
-
-/* Parse the command line options. May exit the program if only help
- or version output is requested. */
-void pinentry_parse_opts(int argc, char *argv[]);
-
-/* Set the optional flag used with getinfo. */
-void pinentry_set_flavor_flag(const char *string);
-
-#ifdef WINDOWS
-/* Windows declares sleep as obsolete, but provides a definition for
- _sleep but non for the still existing sleep. */
-#define sleep(a) _sleep((a))
-#endif /*WINDOWS*/
-
-#if 0
-{
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* PINENTRY_H */
diff --git a/src/pinentry/pinentry_debug.cpp b/src/pinentry/pinentry_debug.cpp
deleted file mode 100644
index 9afbcdb3..00000000
--- a/src/pinentry/pinentry_debug.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/* pinentry_debug.h - Logging category for pinentry
- * Copyright (C) 2021 g10 Code GmbH
- *
- * Software engineering by Ingo Klöcker <[email protected]>
- *
- * 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 2 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 <https://www.gnu.org/licenses/>.
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "pinentry_debug.h"
-
-#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
-Q_LOGGING_CATEGORY(PINENTRY_LOG, "gpg.pinentry", QtWarningMsg)
-#else
-Q_LOGGING_CATEGORY(PINENTRY_LOG, "gpg.pinentry")
-#endif
diff --git a/src/pinentry/pinentry_debug.h b/src/pinentry/pinentry_debug.h
deleted file mode 100644
index fc8c808a..00000000
--- a/src/pinentry/pinentry_debug.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* pinentry_debug.h - Logging category for pinentry
- * Copyright (C) 2021 g10 Code GmbH
- *
- * Software engineering by Ingo Klöcker <[email protected]>
- *
- * 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 2 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 <https://www.gnu.org/licenses/>.
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#ifndef __PINENTRY_QT_DEBUG_H__
-#define __PINENTRY_QT_DEBUG_H__
-
-#include <QLoggingCategory>
-
-Q_DECLARE_LOGGING_CATEGORY(PINENTRY_LOG)
-
-#endif // __PINENTRY_QT_DEBUG_H__
diff --git a/src/pinentry/pinentryconfirm.cpp b/src/pinentry/pinentryconfirm.cpp
deleted file mode 100644
index 31d55b5c..00000000
--- a/src/pinentry/pinentryconfirm.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/* pinentryconfirm.cpp - A QMessageBox with a timeout
- *
- * Copyright (C) 2011 Ben Kibbey <[email protected]>
- * Copyright (C) 2022 g10 Code GmbH
- *
- * Software engineering by Ingo Klöcker <[email protected]>
- *
- * 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 2 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 <https://www.gnu.org/licenses/>.
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include "pinentryconfirm.h"
-
-#include <QAbstractButton>
-#include <QApplication>
-#include <QFontMetrics>
-#include <QGridLayout>
-#include <QLabel>
-#include <QSpacerItem>
-
-#include "accessibility.h"
-#include "pinentrydialog.h"
-
-namespace {
-QLabel *messageBoxLabel(QMessageBox *messageBox) {
- return messageBox->findChild<QLabel *>(QStringLiteral("qt_msgbox_label"));
-}
-} // namespace
-
-PinentryConfirm::PinentryConfirm(Icon icon, const QString &title,
- const QString &text, StandardButtons buttons,
- QWidget *parent, Qt::WindowFlags flags)
- : QMessageBox{icon, title, text, buttons, parent, flags} {
- _timer.callOnTimeout(this, &PinentryConfirm::slotTimeout);
-
-#ifndef QT_NO_ACCESSIBILITY
- QAccessible::installActivationObserver(this);
- accessibilityActiveChanged(QAccessible::isActive());
-#endif
-
-#if QT_VERSION >= 0x050000
- /* This is in line with PinentryDialog ctor to have a maximizing
- * animation when opening. */
- if (qApp->platformName() != QLatin1String("wayland")) {
- setWindowState(Qt::WindowMinimized);
- QTimer::singleShot(0, this, [this]() { raiseWindow(this); });
- }
-#else
- activateWindow();
- raise();
-#endif
-}
-
-PinentryConfirm::~PinentryConfirm() {
-#ifndef QT_NO_ACCESSIBILITY
- QAccessible::removeActivationObserver(this);
-#endif
-}
-
-void PinentryConfirm::setTimeout(std::chrono::seconds timeout) {
- _timer.setInterval(timeout);
-}
-
-std::chrono::seconds PinentryConfirm::timeout() const {
- return std::chrono::duration_cast<std::chrono::seconds>(
- _timer.intervalAsDuration());
-}
-
-bool PinentryConfirm::timedOut() const { return _timed_out; }
-
-void PinentryConfirm::showEvent(QShowEvent *event) {
- static bool resized;
- if (!resized) {
- QGridLayout *lay = dynamic_cast<QGridLayout *>(layout());
- if (lay) {
- QSize textSize = fontMetrics().size(Qt::TextExpandTabs, text(),
- fontMetrics().maxWidth());
- QSpacerItem *horizontalSpacer =
- new QSpacerItem(textSize.width() + iconPixmap().width(), 0,
- QSizePolicy::Minimum, QSizePolicy::Expanding);
- lay->addItem(horizontalSpacer, lay->rowCount(), 1, 1,
- lay->columnCount() - 1);
- }
- resized = true;
- }
-
- QMessageBox::showEvent(event);
-
- if (timeout() > std::chrono::milliseconds::zero()) {
- _timer.setSingleShot(true);
- _timer.start();
- }
-}
-
-void PinentryConfirm::slotTimeout() {
- QAbstractButton *b = button(QMessageBox::Cancel);
- _timed_out = true;
-
- if (b) {
- b->animateClick();
- }
-}
-
-#ifndef QT_NO_ACCESSIBILITY
-void PinentryConfirm::accessibilityActiveChanged(bool active) {
- // Allow text label to get focus if accessibility is active
- const auto focusPolicy = active ? Qt::StrongFocus : Qt::ClickFocus;
- if (auto label = messageBoxLabel(this)) {
- label->setFocusPolicy(focusPolicy);
- }
-}
-#endif
diff --git a/src/pinentry/pinentryconfirm.h b/src/pinentry/pinentryconfirm.h
deleted file mode 100644
index 7be7c268..00000000
--- a/src/pinentry/pinentryconfirm.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* pinentryconfirm.h - A QMessageBox with a timeout
- *
- * Copyright (C) 2011 Ben Kibbey <[email protected]>
- * Copyright (C) 2022 g10 Code GmbH
- *
- * Software engineering by Ingo Klöcker <[email protected]>
- *
- * 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 2 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 <https://www.gnu.org/licenses/>.
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#ifndef PINENTRYCONFIRM_H
-#define PINENTRYCONFIRM_H
-
-#include <QAccessible>
-#include <QMessageBox>
-#include <QTimer>
-
-class PinentryConfirm : public QMessageBox
-#ifndef QT_NO_ACCESSIBILITY
- , public QAccessible::ActivationObserver
-#endif
-{
- Q_OBJECT
-public:
- PinentryConfirm(Icon icon, const QString &title, const QString &text,
- StandardButtons buttons = NoButton, QWidget *parent = nullptr,
- Qt::WindowFlags flags = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint);
- ~PinentryConfirm() override;
-
- void setTimeout(std::chrono::seconds timeout);
- std::chrono::seconds timeout() const;
-
- bool timedOut() const;
-
-protected:
- void showEvent(QShowEvent *event) override;
-
-private Q_SLOTS:
- void slotTimeout();
-
-private:
-#ifndef QT_NO_ACCESSIBILITY
- void accessibilityActiveChanged(bool active) override;
-#endif
-
-private:
- QTimer _timer;
- bool _timed_out = false;
-};
-
-#endif
diff --git a/src/pinentry/pinentrydialog.cpp b/src/pinentry/pinentrydialog.cpp
deleted file mode 100644
index d63b0015..00000000
--- a/src/pinentry/pinentrydialog.cpp
+++ /dev/null
@@ -1,634 +0,0 @@
-/* pinentrydialog.cpp - A (not yet) secure Qt 4 dialog for PIN entry.
- * Copyright (C) 2002, 2008 Klarälvdalens Datakonsult AB (KDAB)
- * Copyright 2007 Ingo Klöcker
- * Copyright 2016 Intevation GmbH
- * Copyright (C) 2021, 2022 g10 Code GmbH
- *
- * Written by Steffen Hansen <[email protected]>.
- * Modified by Andre Heinecke <[email protected]>
- * Software engineering by Ingo Klöcker <[email protected]>
- *
- * 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 2 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 <https://www.gnu.org/licenses/>.
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include "pinentrydialog.h"
-
-#include <qnamespace.h>
-
-#include <QAccessible>
-#include <QAction>
-#include <QApplication>
-#include <QCheckBox>
-#include <QDebug>
-#include <QDialogButtonBox>
-#include <QFontMetrics>
-#include <QGridLayout>
-#include <QHBoxLayout>
-#include <QKeyEvent>
-#include <QLabel>
-#include <QLineEdit>
-#include <QMessageBox>
-#include <QPainter>
-#include <QPalette>
-#include <QProgressBar>
-#include <QPushButton>
-#include <QRegularExpression>
-#include <QStyle>
-#include <QVBoxLayout>
-
-#include "accessibility.h"
-#include "capslock/capslock.h"
-#include "core/utils/MemoryUtils.h"
-#include "pinentry.h"
-#include "pinlineedit.h"
-
-void raiseWindow(QWidget *w) {
- w->setWindowState((w->windowState() & ~Qt::WindowMinimized) |
- Qt::WindowActive);
- w->activateWindow();
- w->raise();
-}
-
-auto applicationIconPixmap(const QIcon &overlayIcon) -> QPixmap {
- QPixmap pm = qApp->windowIcon().pixmap(48, 48);
-
- if (!overlayIcon.isNull()) {
- QPainter painter(&pm);
- const int emblem_size = 22;
- painter.drawPixmap(pm.width() - emblem_size, 0,
- overlayIcon.pixmap(emblem_size, emblem_size));
- }
-
- return pm;
-}
-
-void PinEntryDialog::slotTimeout() {
- _timed_out = true;
- reject();
-}
-
-PinEntryDialog::PinEntryDialog(QWidget *parent, const char *name, int timeout,
- bool modal, bool enable_quality_bar,
- const QString &repeatString,
- const QString &visibilityTT,
- const QString &hideTT)
- : QDialog{parent},
- _have_quality_bar{enable_quality_bar},
- mVisibilityTT{visibilityTT},
- mHideTT{hideTT} {
- Q_UNUSED(name)
-
- if (modal) {
- setWindowModality(Qt::ApplicationModal);
- setModal(true);
- }
-
- QPalette red_text_palette;
- red_text_palette.setColor(QPalette::WindowText, Qt::red);
-
- auto *const main_layout = new QVBoxLayout{this};
-
- auto *const hbox = new QHBoxLayout;
-
- _icon = new QLabel(this);
- _icon->setPixmap(applicationIconPixmap());
- hbox->addWidget(_icon, 0, Qt::AlignVCenter | Qt::AlignLeft);
-
- auto *const grid = new QGridLayout;
- int row = 1;
-
- _error = new QLabel{this};
- _error->setTextFormat(Qt::PlainText);
- _error->setTextInteractionFlags(Qt::TextSelectableByMouse);
- _error->setPalette(red_text_palette);
- _error->hide();
- grid->addWidget(_error, row, 1, 1, 2);
-
- row++;
- _desc = new QLabel{this};
- _desc->setTextFormat(Qt::PlainText);
- _desc->setTextInteractionFlags(Qt::TextSelectableByMouse);
- _desc->hide();
- grid->addWidget(_desc, row, 1, 1, 2);
-
- row++;
- mCapsLockHint = new QLabel{this};
- mCapsLockHint->setTextFormat(Qt::PlainText);
- mCapsLockHint->setTextInteractionFlags(Qt::TextSelectableByMouse);
- mCapsLockHint->setPalette(red_text_palette);
- mCapsLockHint->setAlignment(Qt::AlignCenter);
- mCapsLockHint->setVisible(false);
- grid->addWidget(mCapsLockHint, row, 1, 1, 2);
-
- row++;
- {
- _prompt = new QLabel(this);
- _prompt->setTextFormat(Qt::PlainText);
- _prompt->setTextInteractionFlags(Qt::TextSelectableByMouse);
- _prompt->hide();
- grid->addWidget(_prompt, row, 1);
-
- auto *const l = new QHBoxLayout;
- _edit = new PinLineEdit(this);
- _edit->setMaxLength(256);
- _edit->setMinimumWidth(_edit->fontMetrics().averageCharWidth() * 20 + 48);
- _edit->setEchoMode(QLineEdit::Password);
- _prompt->setBuddy(_edit);
- l->addWidget(_edit, 1);
-
- if (!repeatString.isNull()) {
- mGenerateButton = new QPushButton{this};
- mGenerateButton->setIcon(QIcon(QLatin1String(":password-generate.svg")));
- mGenerateButton->setVisible(false);
- l->addWidget(mGenerateButton);
- }
- grid->addLayout(l, row, 2);
- }
-
- /* Set up the show password action */
- const QIcon visibility_icon = QIcon(QLatin1String(":visibility.svg"));
- const QIcon hide_icon = QIcon(QLatin1String(":hint.svg"));
-#if QT_VERSION >= 0x050200
- if (!visibility_icon.isNull() && !hide_icon.isNull()) {
- mVisiActionEdit =
- _edit->addAction(visibility_icon, QLineEdit::TrailingPosition);
- mVisiActionEdit->setVisible(false);
- mVisiActionEdit->setToolTip(mVisibilityTT);
- } else
-#endif
- {
- if (!mVisibilityTT.isNull()) {
- row++;
- mVisiCB = new QCheckBox{mVisibilityTT, this};
- grid->addWidget(mVisiCB, row, 1, 1, 2, Qt::AlignLeft);
- }
- }
-
- row++;
- mConstraintsHint = new QLabel{this};
- mConstraintsHint->setTextFormat(Qt::PlainText);
- mConstraintsHint->setTextInteractionFlags(Qt::TextSelectableByMouse);
- mConstraintsHint->setVisible(false);
- grid->addWidget(mConstraintsHint, row, 2);
-
- row++;
- mFormattedPassphraseHintSpacer = new QLabel{this};
- mFormattedPassphraseHintSpacer->setVisible(false);
- mFormattedPassphraseHint = new QLabel{this};
- mFormattedPassphraseHint->setTextFormat(Qt::PlainText);
- mFormattedPassphraseHint->setTextInteractionFlags(Qt::TextSelectableByMouse);
- mFormattedPassphraseHint->setVisible(false);
- grid->addWidget(mFormattedPassphraseHintSpacer, row, 1);
- grid->addWidget(mFormattedPassphraseHint, row, 2);
-
- if (!repeatString.isNull()) {
- row++;
- auto *repeat_label = new QLabel{this};
- repeat_label->setTextFormat(Qt::PlainText);
- repeat_label->setTextInteractionFlags(Qt::TextSelectableByMouse);
- repeat_label->setText(repeatString);
- grid->addWidget(repeat_label, row, 1);
-
- mRepeat = new PinLineEdit(this);
- mRepeat->setMaxLength(256);
- mRepeat->setEchoMode(QLineEdit::Password);
- repeat_label->setBuddy(mRepeat);
- grid->addWidget(mRepeat, row, 2);
-
- row++;
- mRepeatError = new QLabel{this};
- mRepeatError->setTextFormat(Qt::PlainText);
- mRepeatError->setTextInteractionFlags(Qt::TextSelectableByMouse);
- mRepeatError->setPalette(red_text_palette);
- mRepeatError->hide();
- grid->addWidget(mRepeatError, row, 2);
- }
-
- if (enable_quality_bar) {
- row++;
- _quality_bar_label = new QLabel(this);
- _quality_bar_label->setTextFormat(Qt::PlainText);
- _quality_bar_label->setTextInteractionFlags(Qt::TextSelectableByMouse);
- _quality_bar_label->setAlignment(Qt::AlignVCenter);
- grid->addWidget(_quality_bar_label, row, 1);
-
- _quality_bar = new QProgressBar(this);
- _quality_bar->setAlignment(Qt::AlignCenter);
- _quality_bar_label->setBuddy(_quality_bar);
- grid->addWidget(_quality_bar, row, 2);
- }
-
- hbox->addLayout(grid, 1);
- main_layout->addLayout(hbox);
-
- auto *const buttons = new QDialogButtonBox(this);
- buttons->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
- _ok = buttons->button(QDialogButtonBox::Ok);
- _cancel = buttons->button(QDialogButtonBox::Cancel);
-
- if (style()->styleHint(QStyle::SH_DialogButtonBox_ButtonsHaveIcons)) {
- _ok->setIcon(style()->standardIcon(QStyle::SP_DialogOkButton));
- _cancel->setIcon(style()->standardIcon(QStyle::SP_DialogCancelButton));
- }
-
- main_layout->addStretch(1);
- main_layout->addWidget(buttons);
- main_layout->setSizeConstraint(QLayout::SetFixedSize);
-
- if (timeout > 0) {
- _timer = new QTimer(this);
- connect(_timer, &QTimer::timeout, this, &PinEntryDialog::slotTimeout);
- _timer->start(timeout * 1000);
- }
-
- connect(buttons, &QDialogButtonBox::accepted, this,
- &PinEntryDialog::onAccept);
- connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
- connect(_edit, &QLineEdit::textChanged, this, &PinEntryDialog::updateQuality);
- connect(_edit, &QLineEdit::textChanged, this, &PinEntryDialog::textChanged);
- connect(_edit, &PinLineEdit::backspacePressed, this,
- &PinEntryDialog::onBackspace);
- if (mGenerateButton != nullptr) {
- connect(mGenerateButton, &QPushButton::clicked, this,
- &PinEntryDialog::generatePin);
- }
- if (mVisiActionEdit != nullptr) {
- connect(mVisiActionEdit, &QAction::triggered, this,
- &PinEntryDialog::toggleVisibility);
- }
- if (mVisiCB != nullptr) {
- connect(mVisiCB, &QCheckBox::toggled, this,
- &PinEntryDialog::toggleVisibility);
- }
- if (mRepeat != nullptr) {
- connect(mRepeat, &QLineEdit::textChanged, this,
- &PinEntryDialog::textChanged);
- }
-
- auto *caps_lock_watcher = new CapsLockWatcher{this};
- connect(caps_lock_watcher, &CapsLockWatcher::stateChanged, this,
- [this](bool locked) { mCapsLockHint->setVisible(locked); });
-
- connect(qApp, &QApplication::focusChanged, this,
- &PinEntryDialog::focusChanged);
- connect(qApp, &QApplication::applicationStateChanged, this,
- &PinEntryDialog::checkCapsLock);
- checkCapsLock();
-
- setAttribute(Qt::WA_DeleteOnClose);
- setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
-
- /* This is mostly an issue on Windows where this results
- in the pinentry popping up nicely with an animation and
- comes to front. It is not ifdefed for Windows only since
- window managers on Linux like KWin can also have this
- result in an animation when the pinentry is shown and
- not just popping it up.
- */
- if (qApp->platformName() != QLatin1String("wayland")) {
- setWindowState(Qt::WindowMinimized);
- QTimer::singleShot(0, this, [this]() { raiseWindow(this); });
- } else {
- raiseWindow(this);
- }
-}
-
-void PinEntryDialog::keyPressEvent(QKeyEvent *e) {
- const auto return_pressed =
- (!e->modifiers() &&
- (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return)) ||
- (e->modifiers() & Qt::KeypadModifier && e->key() == Qt::Key_Enter);
- if (return_pressed && _edit->hasFocus() && (mRepeat != nullptr)) {
- // if the user pressed Return in the first input field, then move the
- // focus to the repeat input field and prevent further event processing
- // by QDialog (which would trigger the default button)
- mRepeat->setFocus();
- e->ignore();
- return;
- }
-
- QDialog::keyPressEvent(e);
-}
-
-void PinEntryDialog::keyReleaseEvent(QKeyEvent *event) {
- QDialog::keyReleaseEvent(event);
- checkCapsLock();
-}
-
-void PinEntryDialog::showEvent(QShowEvent *event) {
- QDialog::showEvent(event);
- _edit->setFocus();
-}
-
-void PinEntryDialog::setDescription(const QString &txt) {
- _desc->setVisible(!txt.isEmpty());
- _desc->setText(txt);
- _icon->setPixmap(applicationIconPixmap());
- setError(QString());
-}
-
-QString PinEntryDialog::description() const { return _desc->text(); }
-
-void PinEntryDialog::setError(const QString &txt) {
- if (!txt.isNull()) {
- _icon->setPixmap(
- applicationIconPixmap(QIcon{QStringLiteral(":data-error.svg")}));
- }
- _error->setText(txt);
- _error->setVisible(!txt.isEmpty());
-}
-
-QString PinEntryDialog::error() const { return _error->text(); }
-
-void PinEntryDialog::setPin(const QString &txt) { _edit->setPin(txt); }
-
-QString PinEntryDialog::pin() const { return _edit->pin(); }
-
-void PinEntryDialog::setPrompt(const QString &txt) {
- _prompt->setText(txt);
- _prompt->setVisible(!txt.isEmpty());
- if (txt.contains("PIN")) _disable_echo_allowed = false;
-}
-
-QString PinEntryDialog::prompt() const { return _prompt->text(); }
-
-void PinEntryDialog::setOkText(const QString &txt) {
- _ok->setText(txt);
- _ok->setVisible(!txt.isEmpty());
-}
-
-void PinEntryDialog::setCancelText(const QString &txt) {
- _cancel->setText(txt);
- _cancel->setVisible(!txt.isEmpty());
-}
-
-void PinEntryDialog::setQualityBar(const QString &txt) {
- if (_have_quality_bar) {
- _quality_bar_label->setText(txt);
- }
-}
-
-void PinEntryDialog::setQualityBarTT(const QString &txt) {
- if (_have_quality_bar) {
- _quality_bar->setToolTip(txt);
- }
-}
-
-void PinEntryDialog::setGenpinLabel(const QString &txt) {
- if (mGenerateButton == nullptr) {
- return;
- }
- mGenerateButton->setVisible(!txt.isEmpty());
- if (!txt.isEmpty()) {
- Accessibility::setName(mGenerateButton, txt);
- }
-}
-
-void PinEntryDialog::setGenpinTT(const QString &txt) {
- if (mGenerateButton != nullptr) {
- mGenerateButton->setToolTip(txt);
- }
-}
-
-void PinEntryDialog::setCapsLockHint(const QString &txt) {
- mCapsLockHint->setText(txt);
-}
-
-void PinEntryDialog::setFormattedPassphrase(
- const PinEntryDialog::FormattedPassphraseOptions &options) {
- mFormatPassphrase = options.formatPassphrase;
- mFormattedPassphraseHint->setTextFormat(Qt::RichText);
- mFormattedPassphraseHint->setText(QLatin1String("<html>") +
- options.hint.toHtmlEscaped() +
- QLatin1String("</html>"));
- Accessibility::setName(mFormattedPassphraseHint, options.hint);
- // toggleFormattedPassphrase();
-}
-
-void PinEntryDialog::setConstraintsOptions(const ConstraintsOptions &options) {
- mEnforceConstraints = options.enforce;
- mConstraintsHint->setText(options.shortHint);
- if (!options.longHint.isEmpty()) {
- mConstraintsHint->setToolTip(
- QLatin1String("<html>") +
- options.longHint.toHtmlEscaped().replace(QLatin1String("\n\n"),
- QLatin1String("<br>")) +
- QLatin1String("</html>"));
- Accessibility::setDescription(mConstraintsHint, options.longHint);
- }
- mConstraintsErrorTitle = options.errorTitle;
-
- mConstraintsHint->setVisible(mEnforceConstraints &&
- !options.shortHint.isEmpty());
-}
-
-void PinEntryDialog::toggleFormattedPassphrase() {
- const bool enable_formatting =
- mFormatPassphrase && _edit->echoMode() == QLineEdit::Normal;
- _edit->setFormattedPassphrase(enable_formatting);
- if (mRepeat != nullptr) {
- mRepeat->setFormattedPassphrase(enable_formatting);
- const bool hint_about_to_be_hidden =
- mFormattedPassphraseHint->isVisible() && !enable_formatting;
- if (hint_about_to_be_hidden) {
- // set hint spacer to current height of hint label before hiding the hint
- mFormattedPassphraseHintSpacer->setMinimumHeight(
- mFormattedPassphraseHint->height());
- mFormattedPassphraseHintSpacer->setVisible(true);
- } else if (enable_formatting) {
- mFormattedPassphraseHintSpacer->setVisible(false);
- }
- mFormattedPassphraseHint->setVisible(enable_formatting);
- }
-}
-
-void PinEntryDialog::onBackspace() {
- cancelTimeout();
-
- if (_disable_echo_allowed) {
- _edit->setEchoMode(QLineEdit::NoEcho);
- if (mRepeat != nullptr) {
- mRepeat->setEchoMode(QLineEdit::NoEcho);
- }
- }
-}
-
-void PinEntryDialog::updateQuality(const QString &txt) {
- int length;
- int percent;
- QPalette pal;
-
- _disable_echo_allowed = false;
-
- if (!_have_quality_bar) {
- return;
- }
-
- length = txt.length();
- percent = length != 0 ? pinentry_inq_quality(txt) : 0;
- if (length == 0) {
- _quality_bar->reset();
- } else {
- pal = _quality_bar->palette();
- if (percent < 0) {
- pal.setColor(QPalette::Highlight, QColor("red"));
- percent = -percent;
- } else {
- pal.setColor(QPalette::Highlight, QColor("green"));
- }
- _quality_bar->setPalette(pal);
- _quality_bar->setValue(percent);
- }
-}
-
-void PinEntryDialog::setPinentryInfo(struct pinentry peinfo) {
- _pinentry_info =
- GpgFrontend::SecureCreateUniqueObject<struct pinentry>(peinfo);
-}
-
-void PinEntryDialog::focusChanged(QWidget *old, QWidget *now) {
- // Grab keyboard. It might be a little weird to do it here, but it works!
- // Previously this code was in showEvent, but that did not work in Qt4.
- if (!_pinentry_info || (_pinentry_info->grab != 0)) {
- if (_grabbed && (old != nullptr) && (old == _edit || old == mRepeat)) {
- old->releaseKeyboard();
- _grabbed = false;
- }
- if (!_grabbed && (now != nullptr) && (now == _edit || now == mRepeat)) {
- now->grabKeyboard();
- _grabbed = true;
- }
- }
-}
-
-void PinEntryDialog::textChanged(const QString &text) {
- Q_UNUSED(text);
-
- cancelTimeout();
-
- if ((mVisiActionEdit != nullptr) && sender() == _edit) {
- mVisiActionEdit->setVisible(!_edit->pin().isEmpty());
- }
- if (mGenerateButton != nullptr) {
- mGenerateButton->setVisible(_edit->pin().isEmpty()
-#ifndef QT_NO_ACCESSIBILITY
- && !mGenerateButton->accessibleName().isEmpty()
-#endif
- );
- }
-}
-
-void PinEntryDialog::generatePin() {
- // std::unique_ptr<char> pin{pinentry_inq_genpin(_pinentry_info.get())};
- // if (pin) {
- // if (_edit->echoMode() == QLineEdit::Password) {
- // if (mVisiActionEdit != nullptr) {
- // mVisiActionEdit->trigger();
- // }
- // if (mVisiCB != nullptr) {
- // mVisiCB->setChecked(true);
- // }
- // }
- // const auto pin_str = QString::fromUtf8(pin.get());
- // _edit->setPin(pin_str);
- // mRepeat->setPin(pin_str);
- // // explicitly focus the first input field and select the generated
- // password _edit->setFocus(); _edit->selectAll();
- // }
-}
-
-void PinEntryDialog::toggleVisibility() {
- if (sender() != mVisiCB) {
- if (_edit->echoMode() == QLineEdit::Password) {
- if (mVisiActionEdit != nullptr) {
- mVisiActionEdit->setIcon(QIcon(QLatin1String(":hint.svg")));
- mVisiActionEdit->setToolTip(mHideTT);
- }
- _edit->setEchoMode(QLineEdit::Normal);
- if (mRepeat != nullptr) {
- mRepeat->setEchoMode(QLineEdit::Normal);
- }
- } else {
- if (mVisiActionEdit != nullptr) {
- mVisiActionEdit->setIcon(QIcon(QLatin1String(":visibility.svg")));
- mVisiActionEdit->setToolTip(mVisibilityTT);
- }
- _edit->setEchoMode(QLineEdit::Password);
- if (mRepeat != nullptr) {
- mRepeat->setEchoMode(QLineEdit::Password);
- }
- }
- } else {
- if (mVisiCB->isChecked()) {
- if (mRepeat != nullptr) {
- mRepeat->setEchoMode(QLineEdit::Normal);
- }
- _edit->setEchoMode(QLineEdit::Normal);
- } else {
- if (mRepeat != nullptr) {
- mRepeat->setEchoMode(QLineEdit::Password);
- }
- _edit->setEchoMode(QLineEdit::Password);
- }
- }
- toggleFormattedPassphrase();
-}
-
-QString PinEntryDialog::repeatedPin() const {
- if (mRepeat != nullptr) {
- return mRepeat->pin();
- }
- return QString();
-}
-
-bool PinEntryDialog::timedOut() const { return _timed_out; }
-
-void PinEntryDialog::setRepeatErrorText(const QString &err) {
- if (mRepeatError != nullptr) {
- mRepeatError->setText(err);
- }
-}
-
-void PinEntryDialog::cancelTimeout() {
- if (_timer != nullptr) {
- _timer->stop();
- }
-}
-
-void PinEntryDialog::checkCapsLock() {
- const auto state = capsLockState();
- if (state != LockState::Unknown) {
- mCapsLockHint->setVisible(state == LockState::On);
- }
-}
-
-void PinEntryDialog::onAccept() {
- cancelTimeout();
-
- if ((mRepeat != nullptr) && mRepeat->pin() != _edit->pin()) {
-#ifndef QT_NO_ACCESSIBILITY
- if (QAccessible::isActive()) {
- QMessageBox::information(this, mRepeatError->text(),
- mRepeatError->text());
- } else
-#endif
- {
- mRepeatError->setVisible(true);
- }
- return;
- }
-
- accept();
-}
diff --git a/src/pinentry/pinentrydialog.h b/src/pinentry/pinentrydialog.h
deleted file mode 100644
index 9cc677e5..00000000
--- a/src/pinentry/pinentrydialog.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/* pinentrydialog.h - A (not yet) secure Qt 4 dialog for PIN entry.
- * Copyright (C) 2002, 2008 Klarälvdalens Datakonsult AB (KDAB)
- * Copyright 2007 Ingo Klöcker
- * Copyright 2016 Intevation GmbH
- * Copyright (C) 2021, 2022 g10 Code GmbH
- *
- * Written by Steffen Hansen <[email protected]>.
- * Modified by Andre Heinecke <[email protected]>
- * Software engineering by Ingo Klöcker <[email protected]>
- *
- * 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 2 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 <https://www.gnu.org/licenses/>.
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#ifndef __PINENTRYDIALOG_H__
-#define __PINENTRYDIALOG_H__
-
-#include <QAccessible>
-#include <QDialog>
-#include <QStyle>
-#include <QTimer>
-
-#include "core/function/SecureMemoryAllocator.h"
-#include "pinentry.h"
-
-class QIcon;
-class QLabel;
-class QPushButton;
-class QLineEdit;
-class PinLineEdit;
-class QString;
-class QProgressBar;
-class QCheckBox;
-class QAction;
-
-QPixmap applicationIconPixmap(const QIcon &overlayIcon = {});
-
-void raiseWindow(QWidget *w);
-
-class PinEntryDialog : public QDialog {
- Q_OBJECT
-
- Q_PROPERTY(QString description READ description WRITE setDescription)
- Q_PROPERTY(QString error READ error WRITE setError)
- Q_PROPERTY(QString pin READ pin WRITE setPin)
- Q_PROPERTY(QString prompt READ prompt WRITE setPrompt)
- public:
- struct FormattedPassphraseOptions {
- bool formatPassphrase;
- QString hint;
- };
- struct ConstraintsOptions {
- bool enforce;
- QString shortHint;
- QString longHint;
- QString errorTitle;
- };
-
- explicit PinEntryDialog(QWidget *parent = 0, const char *name = 0,
- int timeout = 0, bool modal = false,
- bool enable_quality_bar = false,
- const QString &repeatString = QString(),
- const QString &visibiltyTT = QString(),
- const QString &hideTT = QString());
-
- void setDescription(const QString &);
- QString description() const;
-
- void setError(const QString &);
- QString error() const;
-
- void setPin(const QString &);
- QString pin() const;
-
- QString repeatedPin() const;
- void setRepeatErrorText(const QString &);
-
- void setPrompt(const QString &);
- QString prompt() const;
-
- void setOkText(const QString &);
- void setCancelText(const QString &);
-
- void setQualityBar(const QString &);
- void setQualityBarTT(const QString &);
-
- void setGenpinLabel(const QString &);
- void setGenpinTT(const QString &);
-
- void setCapsLockHint(const QString &);
-
- void setFormattedPassphrase(const FormattedPassphraseOptions &options);
-
- void setConstraintsOptions(const ConstraintsOptions &options);
-
- void setPinentryInfo(struct pinentry);
-
- bool timedOut() const;
-
- protected Q_SLOTS:
- void updateQuality(const QString &);
- void slotTimeout();
- void textChanged(const QString &);
- void focusChanged(QWidget *old, QWidget *now);
- void toggleVisibility();
- void onBackspace();
- void generatePin();
- void toggleFormattedPassphrase();
-
- protected:
- void keyPressEvent(QKeyEvent *event) override;
- void keyReleaseEvent(QKeyEvent *event) override;
- void showEvent(QShowEvent *event) override;
-
- private Q_SLOTS:
- void cancelTimeout();
- void checkCapsLock();
- void onAccept();
-
- private:
- enum PassphraseCheckResult {
- PassphraseNotChecked = -1,
- PassphraseNotOk = 0,
- PassphraseOk
- };
-
- QLabel *_icon = nullptr;
- QLabel *_desc = nullptr;
- QLabel *_error = nullptr;
- QLabel *_prompt = nullptr;
- QLabel *_quality_bar_label = nullptr;
- QProgressBar *_quality_bar = nullptr;
- PinLineEdit *_edit = nullptr;
- PinLineEdit *mRepeat = nullptr;
- QLabel *mRepeatError = nullptr;
- QPushButton *_ok = nullptr;
- QPushButton *_cancel = nullptr;
- bool _grabbed = false;
- bool _have_quality_bar = false;
- bool _timed_out = false;
- bool _disable_echo_allowed = true;
- bool mEnforceConstraints = false;
- bool mFormatPassphrase = false;
-
- GpgFrontend::SecureUniquePtr<struct pinentry> _pinentry_info = nullptr;
- QTimer *_timer = nullptr;
- QString mVisibilityTT;
- QString mHideTT;
- QAction *mVisiActionEdit = nullptr;
- QPushButton *mGenerateButton = nullptr;
- QCheckBox *mVisiCB = nullptr;
- QLabel *mFormattedPassphraseHint = nullptr;
- QLabel *mFormattedPassphraseHintSpacer = nullptr;
- QLabel *mCapsLockHint = nullptr;
- QLabel *mConstraintsHint = nullptr;
- QString mConstraintsErrorTitle;
-};
-
-#endif // __PINENTRYDIALOG_H__
diff --git a/src/pinentry/pinlineedit.cpp b/src/pinentry/pinlineedit.cpp
deleted file mode 100644
index 9d172b56..00000000
--- a/src/pinentry/pinlineedit.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-/* pinlineedit.cpp - Modified QLineEdit widget.
- * Copyright (C) 2018 Damien Goutte-Gattat
- * Copyright (C) 2021 g10 Code GmbH
- *
- * Software engineering by Ingo Klöcker <[email protected]>
- *
- * 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 2 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 <https://www.gnu.org/licenses/>.
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include "pinlineedit.h"
-
-#include <QClipboard>
-#include <QGuiApplication>
-#include <QKeyEvent>
-
-static const int FormattedPassphraseGroupSize = 5;
-static const QChar FormattedPassphraseSeparator = QChar::Nbsp;
-
-namespace {
-struct Selection {
- bool empty() const { return start < 0 || start >= end; }
- int length() const { return empty() ? 0 : end - start; }
-
- int start;
- int end;
-};
-} // namespace
-
-class PinLineEdit::Private {
- PinLineEdit *const q;
-
- public:
- Private(PinLineEdit *q) : q{q} {}
-
- QString formatted(QString text) const {
- const int dashCount = text.size() / FormattedPassphraseGroupSize;
- text.reserve(text.size() + dashCount);
- for (int i = FormattedPassphraseGroupSize; i < text.size();
- i += FormattedPassphraseGroupSize + 1) {
- text.insert(i, FormattedPassphraseSeparator);
- }
- return text;
- }
-
- Selection formattedSelection(Selection selection) const {
- if (selection.empty()) {
- return selection;
- }
- return {selection.start + selection.start / FormattedPassphraseGroupSize,
- selection.end + (selection.end - 1) / FormattedPassphraseGroupSize};
- }
-
- QString unformatted(QString text) const {
- for (int i = FormattedPassphraseGroupSize; i < text.size();
- i += FormattedPassphraseGroupSize) {
- text.remove(i, 1);
- }
- return text;
- }
-
- Selection unformattedSelection(Selection selection) const {
- if (selection.empty()) {
- return selection;
- }
- return {
- selection.start - selection.start / (FormattedPassphraseGroupSize + 1),
- selection.end - selection.end / (FormattedPassphraseGroupSize + 1)};
- }
-
- void copyToClipboard() {
- if (q->echoMode() != QLineEdit::Normal) {
- return;
- }
-
- QString text = q->selectedText();
- if (mFormattedPassphrase) {
- text.remove(FormattedPassphraseSeparator);
- }
- if (!text.isEmpty()) {
- QGuiApplication::clipboard()->setText(text);
- }
- }
-
- int selectionEnd() {
-#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
- return q->selectionEnd();
-#else
- return q->selectionStart() + q->selectedText().size();
-#endif
- }
-
- public:
- bool mFormattedPassphrase = false;
-};
-
-PinLineEdit::PinLineEdit(QWidget *parent)
- : QLineEdit(parent), d{new Private{this}} {
- connect(this, SIGNAL(textEdited(QString)), this, SLOT(textEdited()));
-}
-
-PinLineEdit::~PinLineEdit() = default;
-
-void PinLineEdit::setFormattedPassphrase(bool on) {
- if (on == d->mFormattedPassphrase) {
- return;
- }
- d->mFormattedPassphrase = on;
- Selection selection{selectionStart(), d->selectionEnd()};
- if (d->mFormattedPassphrase) {
- setText(d->formatted(text()));
- selection = d->formattedSelection(selection);
- } else {
- setText(d->unformatted(text()));
- selection = d->unformattedSelection(selection);
- }
- if (!selection.empty()) {
- setSelection(selection.start, selection.length());
- }
-}
-
-void PinLineEdit::copy() const { d->copyToClipboard(); }
-
-void PinLineEdit::cut() {
- if (hasSelectedText()) {
- copy();
- del();
- }
-}
-
-void PinLineEdit::setPin(const QString &pin) {
- setText(d->mFormattedPassphrase ? d->formatted(pin) : pin);
-}
-
-QString PinLineEdit::pin() const {
- if (d->mFormattedPassphrase) {
- return d->unformatted(text());
- } else {
- return text();
- }
-}
-
-void PinLineEdit::keyPressEvent(QKeyEvent *e) {
- if (e == QKeySequence::Copy) {
- copy();
- return;
- } else if (e == QKeySequence::Cut) {
- if (!isReadOnly() && hasSelectedText()) {
- copy();
- del();
- }
- return;
- } else if (e == QKeySequence::DeleteEndOfLine) {
- if (!isReadOnly()) {
- setSelection(cursorPosition(), text().size());
- copy();
- del();
- }
- return;
- } else if (e == QKeySequence::DeleteCompleteLine) {
- if (!isReadOnly()) {
- setSelection(0, text().size());
- copy();
- del();
- }
- return;
- }
-
- QLineEdit::keyPressEvent(e);
-
- if (e->key() == Qt::Key::Key_Backspace) {
- emit backspacePressed();
- }
-}
-
-void PinLineEdit::textEdited() {
- if (!d->mFormattedPassphrase) {
- return;
- }
- auto currentText = text();
- // first calculate the cursor position in the reformatted text; the cursor
- // is put left of the separators, so that backspace works as expected
- auto cursorPos = cursorPosition();
- cursorPos -= QStringView{currentText}.left(cursorPos).count(
- FormattedPassphraseSeparator);
- cursorPos += std::max(cursorPos - 1, 0) / FormattedPassphraseGroupSize;
- // then reformat the text
- currentText.remove(FormattedPassphraseSeparator);
- currentText = d->formatted(currentText);
- // finally, set reformatted text and updated cursor position
- setText(currentText);
- setCursorPosition(cursorPos);
-}
diff --git a/src/pinentry/pinlineedit.h b/src/pinentry/pinlineedit.h
deleted file mode 100644
index 72ac85a5..00000000
--- a/src/pinentry/pinlineedit.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* pinlineedit.h - Modified QLineEdit widget.
- * Copyright (C) 2018 Damien Goutte-Gattat
- * Copyright (C) 2021 g10 Code GmbH
- *
- * Software engineering by Ingo Klöcker <[email protected]>
- *
- * 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 2 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 <https://www.gnu.org/licenses/>.
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#ifndef _PINLINEEDIT_H_
-#define _PINLINEEDIT_H_
-
-#include <QLineEdit>
-
-class PinLineEdit : public QLineEdit {
- Q_OBJECT
-
- public:
- explicit PinLineEdit(QWidget *parent = nullptr);
- ~PinLineEdit() override;
-
- void setPin(const QString &pin);
- QString pin() const;
-
- public Q_SLOTS:
- void setFormattedPassphrase(bool on);
- void copy() const;
- void cut();
-
- Q_SIGNALS:
- void backspacePressed();
-
- protected:
- void keyPressEvent(QKeyEvent *) override;
-
- private:
- using QLineEdit::setText;
- using QLineEdit::text;
-
- private Q_SLOTS:
- void textEdited();
-
- private:
- class Private;
- std::unique_ptr<Private> d;
-};
-
-#endif // _PINLINEEDIT_H_
diff --git a/src/pinentry/qti18n.cpp b/src/pinentry/qti18n.cpp
deleted file mode 100644
index 198e6cc4..00000000
--- a/src/pinentry/qti18n.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/* qti18n.cpp - Load qt translations for pinentry.
- * Copyright 2021 g10 Code GmbH
- * SPDX-FileCopyrightText: 2015 Lukáš Tinkl <[email protected]>
- * SPDX-FileCopyrightText: 2021 Ingo Klöcker <[email protected]>
- *
- * Copied from k18n under the terms of LGPLv2 or later.
- *
- * 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 2 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 <https://www.gnu.org/licenses/>.
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include <QCoreApplication>
-#include <QDebug>
-#include <QLibraryInfo>
-#include <QLocale>
-#include <QTranslator>
-
-static bool loadCatalog(const QString &catalog, const QLocale &locale) {
- auto translator = new QTranslator(QCoreApplication::instance());
-
- if (!translator->load(locale, catalog, QString(),
- QLatin1String(":/i18n_qt"))) {
- qDebug() << "Loading the" << catalog << "catalog failed for locale"
- << locale;
- delete translator;
- return false;
- }
- QCoreApplication::instance()->installTranslator(translator);
- return true;
-}
-
-static bool loadCatalog(const QString &catalog, const QLocale &locale,
- const QLocale &fallbackLocale) {
- // try to load the catalog for locale
- if (loadCatalog(catalog, locale)) {
- return true;
- }
- // if this fails, then try the fallback locale (if it's different from locale)
- if (fallbackLocale != locale) {
- return loadCatalog(catalog, fallbackLocale);
- }
- return false;
-}
-
-// load global Qt translation, needed in KDE e.g. by lots of builtin dialogs
-// (QColorDialog, QFontDialog) that we use
-static void loadTranslation(const QString &localeName,
- const QString &fallbackLocaleName) {
- const QLocale locale{localeName};
- const QLocale fallbackLocale{fallbackLocaleName};
- // first, try to load the qt_ meta catalog
- if (loadCatalog(QStringLiteral("qt_"), locale, fallbackLocale)) {
- return;
- }
- // if loading the meta catalog failed, then try loading the four catalogs
- // it depends on, i.e. qtbase, qtscript, qtmultimedia, qtxmlpatterns,
- // separately
- const auto catalogs = {
- QStringLiteral("qtbase_"),
- /* QStringLiteral("qtscript_"),
- QStringLiteral("qtmultimedia_"),
- QStringLiteral("qtxmlpatterns_"), */
- };
- for (const auto &catalog : catalogs) {
- loadCatalog(catalog, locale, fallbackLocale);
- }
-}
-
-static void load() {
- // The way Qt translation system handles plural forms makes it necessary to
- // have a translation file which contains only plural forms for `en`. That's
- // why we load the `en` translation unconditionally, then load the
- // translation for the current locale to overload it.
- loadCatalog(QStringLiteral("qt_"), QLocale{QStringLiteral("en")});
-
- const QLocale locale = QLocale::system();
- if (locale.name() != QStringLiteral("en")) {
- loadTranslation(locale.name(), locale.bcp47Name());
- }
-}
-
-Q_COREAPP_STARTUP_FUNCTION(load)
diff --git a/src/pinentry/secmem++.h b/src/pinentry/secmem++.h
deleted file mode 100644
index 116da880..00000000
--- a/src/pinentry/secmem++.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* STL allocator for secmem
- * Copyright (C) 2008 Marc Mutz <[email protected]>
- *
- * 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 2 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 <https://www.gnu.org/licenses/>.
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#ifndef __SECMEM_SECMEMPP_H__
-#define __SECMEM_SECMEMPP_H__
-
-#include "../secmem/secmem.h"
-#include <cstddef>
-
-namespace secmem {
-
- template <typename T>
- class alloc {
- public:
- // type definitions:
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef T* pointer;
- typedef const T* const_pointer;
- typedef T& reference;
- typedef const T& const_reference;
- typedef T value_type;
-
- // rebind
- template <typename U>
- struct rebind {
- typedef alloc<U> other;
- };
-
- // address
- pointer address( reference value ) const {
- return &value;
- }
- const_pointer address( const_reference value ) const {
- return &value;
- }
-
- // (trivial) ctors and dtors
- alloc() {}
- alloc( const alloc & ) {}
- template <typename U> alloc( const alloc<U> & ) {}
- // copy ctor is ok
- ~alloc() {}
-
- // de/allocation
- size_type max_size() const {
- return secmem_get_max_size();
- }
-
- pointer allocate( size_type n, void * =0 ) {
- return static_cast<pointer>( secmem_malloc( n * sizeof(T) ) );
- }
-
- void deallocate( pointer p, size_type ) {
- secmem_free( p );
- }
-
- // de/construct
- void construct( pointer p, const T & value ) {
- void * loc = p;
- new (loc)T(value);
- }
- void destruct( pointer p ) {
- p->~T();
- }
- };
-
- // equality comparison
- template <typename T1,typename T2>
- bool operator==( const alloc<T1> &, const alloc<T2> & ) { return true; }
- template <typename T1, typename T2>
- bool operator!=( const alloc<T1> &, const alloc<T2> & ) { return false; }
-
-}
-
-#endif /* __SECMEM_SECMEMPP_H__ */
diff --git a/src/module/CMakeLists.txt b/src/sdk/CMakeLists.txt
index 8d894b00..5f1dc65a 100644
--- a/src/module/CMakeLists.txt
+++ b/src/sdk/CMakeLists.txt
@@ -27,19 +27,30 @@ set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
# define libgpgfrontend_module_sdk
-aux_source_directory(sdk MODULE_SDK_SOURCE)
+aux_source_directory(. MODULE_SDK_SOURCE)
+aux_source_directory(private MODULE_SDK_SOURCE)
add_library(gpgfrontend_module_sdk SHARED ${MODULE_SDK_SOURCE})
-set(_export_file_sdk "${CMAKE_CURRENT_SOURCE_DIR}/sdk/GFSDKExport.h")
+set(_export_file_sdk "${CMAKE_CURRENT_SOURCE_DIR}/GFSDKExport.h")
generate_export_header(gpgfrontend_module_sdk EXPORT_FILE_NAME "${_export_file_sdk}")
target_include_directories(gpgfrontend_module_sdk PRIVATE
- ${CMAKE_CURRENT_BINARY_DIR}/gpgfrontend_module_sdk_autogen/include
- ${CMAKE_SOURCE_DIR}/third_party/spdlog/include)
+ ${CMAKE_CURRENT_BINARY_DIR}/gpgfrontend_module_sdk_autogen/include)
target_include_directories(gpgfrontend_module_sdk PUBLIC sdk)
# link module system
-target_link_libraries(gpgfrontend_module_sdk PRIVATE gpgfrontend_core)
+target_link_libraries(gpgfrontend_module_sdk PRIVATE gpgfrontend_core gpgfrontend_ui)
+
+# sdk export headers
+file(GLOB _headerPath "${CMAKE_CURRENT_SOURCE_DIR}/*.h")
+set_target_properties(gpgfrontend_module_sdk PROPERTIES PUBLIC_HEADER "${_headerPath}")
+
+if (${CMAKE_BUILD_TYPE} STREQUAL "Debug")
+ # lib output path
+ set_target_properties(gpgfrontend_module_sdk PROPERTIES
+ LIBRARY_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/lib
+ RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/lib)
+endif()
if (XCODE_BUILD)
set_target_properties(gpgfrontend_module_sdk
@@ -49,16 +60,4 @@ if (XCODE_BUILD)
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
XCODE_ATTRIBUTE_SKIP_INSTALL "Yes"
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}")
-endif ()
-
-# tracking modules
-set(all_integrated_module_libraries "")
-file(GLOB children LIST_DIRECTORIES true "mods/*")
-foreach(child ${children})
- if(IS_DIRECTORY ${child})
- get_filename_component(dirName ${child} NAME)
- add_subdirectory("mods/${dirName}")
-
- list(APPEND all_integrated_module_libraries ${dirName})
- endif()
-endforeach() \ No newline at end of file
+endif () \ No newline at end of file
diff --git a/src/module/sdk/GFSDK.h b/src/sdk/GFSDK.h
index 77e019af..77e019af 100644
--- a/src/module/sdk/GFSDK.h
+++ b/src/sdk/GFSDK.h
diff --git a/src/module/sdk/GFSDKBasic.cpp b/src/sdk/GFSDKBasic.cpp
index 4d8af6c8..8b884c84 100644
--- a/src/module/sdk/GFSDKBasic.cpp
+++ b/src/sdk/GFSDKBasic.cpp
@@ -31,29 +31,32 @@
#include "core/function/SecureMemoryAllocator.h"
#include "core/function/gpg/GpgCommandExecutor.h"
#include "core/utils/BuildInfoUtils.h"
-#include "core/utils/CommonUtils.h"
+#include "sdk/private/CommonUtils.h"
+#include "ui/GpgFrontendUIInit.h"
auto GFAllocateMemory(uint32_t size) -> void* {
return GpgFrontend::SecureMemoryAllocator::Allocate(size);
}
+auto GFReallocateMemory(void* ptr, uint32_t size) -> void* {
+ return GpgFrontend::SecureMemoryAllocator::Reallocate(ptr, size);
+}
+
void GFFreeMemory(void* ptr) {
return GpgFrontend::SecureMemoryAllocator::Deallocate(ptr);
}
auto GFProjectVersion() -> const char* {
- return GpgFrontend::GFStrDup(GpgFrontend::GetProjectVersion());
+ return GFStrDup(GpgFrontend::GetProjectVersion());
}
-auto GFQtEnvVersion() -> const char* {
- return GpgFrontend::GFStrDup(QT_VERSION_STR);
-}
+auto GFQtEnvVersion() -> const char* { return GFStrDup(QT_VERSION_STR); }
void GFExecuteCommandSync(const char* cmd, int32_t argc, const char** argv,
GFCommandExeucteCallback cb, void* data) {
QStringList args;
for (int i = 0; i < argc; i++) {
- args.append(GpgFrontend::GFUnStrDup(argv[i]));
+ args.append(GFUnStrDup(argv[i]));
}
GpgFrontend::GpgCommandExecutor::ExecuteContext const context{
@@ -74,7 +77,7 @@ void GFExecuteCommandBatchSync(int32_t context_size,
QStringList args;
const char** argv = exec_context.argv;
for (int j = 0; j < exec_context.argc; j++) {
- args.append(GpgFrontend::GFUnStrDup(argv[j]));
+ args.append(GFUnStrDup(argv[j]));
}
contexts.append(
@@ -94,7 +97,7 @@ auto StrlenSafe(const char* str, size_t max_len) -> size_t {
return end - str;
}
-auto GPGFRONTEND_MODULE_SDK_EXPORT GFModuleStrDup(const char* src) -> char* {
+auto GFModuleStrDup(const char* src) -> char* {
auto len = StrlenSafe(src, kGfStrlenMax);
if (len > kGfStrlenMax) return nullptr;
@@ -103,4 +106,15 @@ auto GPGFRONTEND_MODULE_SDK_EXPORT GFModuleStrDup(const char* src) -> char* {
dst[len] = '\0';
return dst;
-} \ No newline at end of file
+}
+
+auto GFAppActiveLocale() -> char* { return GFStrDup(QLocale().name()); }
+
+auto GFAppRegisterTranslator(char* data, int size) -> int {
+ auto b = QByteArray(data, size);
+ QMetaObject::invokeMethod(QApplication::instance()->thread(), [b]() {
+ GpgFrontend::UI::InstallTranslatorFromQMData(b);
+ });
+ GFFreeMemory(data);
+ return 0;
+}
diff --git a/src/module/sdk/GFSDKBasic.h b/src/sdk/GFSDKBasic.h
index 07ff6ed7..93392857 100644
--- a/src/module/sdk/GFSDKBasic.h
+++ b/src/sdk/GFSDKBasic.h
@@ -59,6 +59,16 @@ auto GPGFRONTEND_MODULE_SDK_EXPORT GFAllocateMemory(uint32_t size) -> void*;
/**
* @brief
*
+ * @param ptr
+ * @param size
+ * @return void*
+ */
+auto GPGFRONTEND_MODULE_SDK_EXPORT GFReallocateMemory(void* ptr,
+ uint32_t size) -> void*;
+
+/**
+ * @brief
+ *
* @return const char*
*/
auto GPGFRONTEND_MODULE_SDK_EXPORT GFProjectVersion() -> const char*;
@@ -104,4 +114,21 @@ void GPGFRONTEND_MODULE_SDK_EXPORT GFExecuteCommandBatchSync(
* @return char*
*/
auto GPGFRONTEND_MODULE_SDK_EXPORT GFModuleStrDup(const char*) -> char*;
+
+/**
+ * @brief
+ *
+ * @return char*
+ */
+auto GPGFRONTEND_MODULE_SDK_EXPORT GFAppActiveLocale() -> char*;
+
+/**
+ * @brief
+ *
+ * @param data
+ * @param size
+ * @return auto
+ */
+auto GPGFRONTEND_MODULE_SDK_EXPORT GFAppRegisterTranslator(char* data,
+ int size) -> int;
} \ No newline at end of file
diff --git a/src/module/sdk/GFSDKBuildInfo.h.in b/src/sdk/GFSDKBuildInfo.h.in
index 508c35d4..508c35d4 100644
--- a/src/module/sdk/GFSDKBuildInfo.h.in
+++ b/src/sdk/GFSDKBuildInfo.h.in
diff --git a/src/module/sdk/GFSDKExport.h b/src/sdk/GFSDKExport.h
index a62168bc..a62168bc 100644
--- a/src/module/sdk/GFSDKExport.h
+++ b/src/sdk/GFSDKExport.h
diff --git a/src/module/sdk/GFSDKExtra.cpp b/src/sdk/GFSDKExtra.cpp
index bbfa8575..00e734da 100644
--- a/src/module/sdk/GFSDKExtra.cpp
+++ b/src/sdk/GFSDKExtra.cpp
@@ -28,15 +28,16 @@
#include "GFSDKExtra.h"
-#include "core/utils/BuildInfoUtils.h"
-#include "core/utils/CommonUtils.h"
+#include <core/utils/BuildInfoUtils.h>
+#include <core/utils/CommonUtils.h>
+
+#include "sdk/private/CommonUtils.h"
auto GFCompareSoftwareVersion(const char *current_version,
const char *latest_version) -> int {
- return GpgFrontend::GFCompareSoftwareVersion(
- GpgFrontend::GFUnStrDup(current_version),
- GpgFrontend::GFUnStrDup(latest_version));
+ return GpgFrontend::GFCompareSoftwareVersion(GFUnStrDup(current_version),
+ GFUnStrDup(latest_version));
}
auto GFHttpRequestUserAgent() -> const char * {
- return GpgFrontend::GFStrDup(GpgFrontend::GetHttpRequestUserAgent());
+ return GFStrDup(GpgFrontend::GetHttpRequestUserAgent());
} \ No newline at end of file
diff --git a/src/module/sdk/GFSDKExtra.h b/src/sdk/GFSDKExtra.h
index 3d7f4226..3d7f4226 100644
--- a/src/module/sdk/GFSDKExtra.h
+++ b/src/sdk/GFSDKExtra.h
diff --git a/src/module/sdk/GFSDKGpg.cpp b/src/sdk/GFSDKGpg.cpp
index 63859763..63859763 100644
--- a/src/module/sdk/GFSDKGpg.cpp
+++ b/src/sdk/GFSDKGpg.cpp
diff --git a/src/module/sdk/GFSDKGpg.h b/src/sdk/GFSDKGpg.h
index 8823bfc5..8823bfc5 100644
--- a/src/module/sdk/GFSDKGpg.h
+++ b/src/sdk/GFSDKGpg.h
diff --git a/src/main.h b/src/sdk/GFSDKLog.cpp
index a394e676..bc1ce7b8 100644
--- a/src/main.h
+++ b/src/sdk/GFSDKLog.cpp
@@ -26,13 +26,18 @@
*
*/
-#pragma once
+#include "GFSDKLog.h"
-#include "core/utils/LogUtils.h"
-#include "core/utils/MemoryUtils.h"
+#include <qglobal.h>
-#define GF_MAIN_LOG_TRACE(...) GF_LOG_TRACE("main", __VA_ARGS__)
-#define GF_MAIN_LOG_DEBUG(...) GF_LOG_DEBUG("main", __VA_ARGS__)
-#define GF_MAIN_LOG_INFO(...) GF_LOG_INFO("main", __VA_ARGS__)
-#define GF_MAIN_LOG_WARN(...) GF_LOG_WARN("main", __VA_ARGS__)
-#define GF_MAIN_LOG_ERROR(...) GF_LOG_ERROR("main", __VA_ARGS__) \ No newline at end of file
+Q_LOGGING_CATEGORY(module, "module")
+
+void GFModuleLogTrace(const char* l) { qCDebug(module) << QString(l); }
+
+void GFModuleLogDebug(const char* l) { qCDebug(module) << QString(l); }
+
+void GFModuleLogInfo(const char* l) { qCInfo(module) << QString(l); }
+
+void GFModuleLogWarn(const char* l) { qCWarning(module) << QString(l); }
+
+void GFModuleLogError(const char* l) { qCCritical(module) << QString(l); }
diff --git a/src/module/sdk/GFSDKLog.h b/src/sdk/GFSDKLog.h
index 77e019af..77e019af 100644
--- a/src/module/sdk/GFSDKLog.h
+++ b/src/sdk/GFSDKLog.h
diff --git a/src/module/sdk/GFSDKModule.cpp b/src/sdk/GFSDKModule.cpp
index 00594488..996c9985 100644
--- a/src/module/sdk/GFSDKModule.cpp
+++ b/src/sdk/GFSDKModule.cpp
@@ -29,70 +29,69 @@
#include "GFSDKModule.h"
#include <core/module/ModuleManager.h>
-#include <core/utils/CommonUtils.h>
+#include <sdk/private/CommonUtils.h>
#include "GFSDKBasic.h"
void GFModuleListenEvent(const char *module_id, const char *event_id) {
return GpgFrontend::Module::ModuleManager::GetInstance().ListenEvent(
- GpgFrontend::GFUnStrDup(module_id).toLower(),
- GpgFrontend::GFUnStrDup(event_id).toUpper());
+ GFUnStrDup(module_id).toLower(), GFUnStrDup(event_id).toUpper());
}
auto GFModuleRetrieveRTValueOrDefault(const char *namespace_, const char *key,
const char *default_value) -> const
char * {
- return GpgFrontend::GFStrDup(
- GpgFrontend::Module::RetrieveRTValueTypedOrDefault(
- GpgFrontend::GFUnStrDup(namespace_), GpgFrontend::GFUnStrDup(key),
- GpgFrontend::GFUnStrDup(default_value)));
+ return GFStrDup(GpgFrontend::Module::RetrieveRTValueTypedOrDefault(
+ GFUnStrDup(namespace_), GFUnStrDup(key), GFUnStrDup(default_value)));
}
void GFModuleUpsertRTValue(const char *namespace_, const char *key,
const char *vaule) {
- GpgFrontend::Module::UpsertRTValue(
- GpgFrontend::GFUnStrDup(namespace_).toLower(),
- GpgFrontend::GFUnStrDup(key).toLower(), GpgFrontend::GFUnStrDup(vaule));
+ GpgFrontend::Module::UpsertRTValue(GFUnStrDup(namespace_).toLower(),
+ GFUnStrDup(key).toLower(),
+ GFUnStrDup(vaule));
}
void GFModuleUpsertRTValueBool(const char *namespace_, const char *key,
int value) {
- GpgFrontend::Module::UpsertRTValue(
- GpgFrontend::GFUnStrDup(namespace_).toLower(),
- GpgFrontend::GFUnStrDup(key).toLower(), value != 0);
+ GpgFrontend::Module::UpsertRTValue(GFUnStrDup(namespace_).toLower(),
+ GFUnStrDup(key).toLower(), value != 0);
}
auto GFModuleListRTChildKeys(const char *namespace_, const char *key,
char ***child_keys) -> int32_t {
*child_keys = nullptr;
auto keys = GpgFrontend::Module::ListRTChildKeys(
- GpgFrontend::GFUnStrDup(namespace_).toLower(),
- GpgFrontend::GFUnStrDup(key).toLower());
+ GFUnStrDup(namespace_).toLower(), GFUnStrDup(key).toLower());
if (keys.empty()) return 0;
*child_keys =
static_cast<char **>(GFAllocateMemory(sizeof(char **) * keys.size()));
- for (int i = 0; i < keys.size(); i++) {
- (*child_keys)[i] = GpgFrontend::GFStrDup(keys[i]);
+ for (decltype(keys.size()) i = 0; i < keys.size(); i++) {
+ (*child_keys)[i] = GFStrDup(keys[i]);
}
return static_cast<int32_t>(keys.size());
}
void GFModuleTriggerModuleEventCallback(GFModuleEvent *module_event,
- const char *module_id, int argc,
- char **argv) {
- auto data_object = GpgFrontend::TransferParams();
- for (int i = 0; i < argc; i++) {
- data_object->AppendObject(GpgFrontend::GFUnStrDup(argv[i]));
- }
-
+ const char *module_id,
+ GFModuleEventParam *p_argv) {
+ auto argv = ConvertEventParamsToMap(p_argv);
auto event = GpgFrontend::Module::ModuleManager::GetInstance().SearchEvent(
- GpgFrontend::GFUnStrDup(module_event->trigger_id).toLower());
+ GFUnStrDup(module_event->trigger_id).toLower());
if (!event) return;
- event.value()->ExecuteCallback(GpgFrontend::GFUnStrDup(module_id),
- data_object);
-} \ No newline at end of file
+ event.value()->ExecuteCallback(GFUnStrDup(module_id), argv);
+}
+
+auto GFModuleRetrieveRTValueOrDefaultBool(const char *namespace_,
+ const char *key,
+ int default_value) -> const int {
+ return static_cast<const int>(
+ GpgFrontend::Module::RetrieveRTValueTypedOrDefault(
+ GFUnStrDup(namespace_), GFUnStrDup(key),
+ static_cast<bool>(default_value)));
+}
diff --git a/src/module/sdk/GFSDKModule.h b/src/sdk/GFSDKModule.h
index 67c1f492..821e3122 100644
--- a/src/module/sdk/GFSDKModule.h
+++ b/src/sdk/GFSDKModule.h
@@ -79,6 +79,9 @@ auto GPGFRONTEND_MODULE_SDK_EXPORT GFModuleRetrieveRTValueOrDefault(
const char *namespace_, const char *key, const char *default_value) -> const
char *;
+auto GPGFRONTEND_MODULE_SDK_EXPORT GFModuleRetrieveRTValueOrDefaultBool(
+ const char *namespace_, const char *key, int default_value) -> const int;
+
void GPGFRONTEND_MODULE_SDK_EXPORT GFModuleUpsertRTValue(const char *namespace_,
const char *key,
const char *vaule);
@@ -90,5 +93,5 @@ auto GPGFRONTEND_MODULE_SDK_EXPORT GFModuleListRTChildKeys(
const char *namespace_, const char *key, char ***child_keys) -> int32_t;
void GPGFRONTEND_MODULE_SDK_EXPORT GFModuleTriggerModuleEventCallback(
- GFModuleEvent *event, const char *module_id, int argc, char **argv);
+ GFModuleEvent *event, const char *module_id, GFModuleEventParam *argv);
}; \ No newline at end of file
diff --git a/src/sdk/GFSDKUI.cpp b/src/sdk/GFSDKUI.cpp
new file mode 100644
index 00000000..a48f306a
--- /dev/null
+++ b/src/sdk/GFSDKUI.cpp
@@ -0,0 +1,71 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend 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.
+ *
+ * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GFSDKUI.h"
+
+#include <core/utils/CommonUtils.h>
+
+#include <QMap>
+#include <QString>
+
+#include "sdk/private/CommonUtils.h"
+#include "ui/UIModuleManager.h"
+
+auto MetaDataArrayToQMap(MetaData** meta_data_array, int size)
+ -> QMap<QString, QString> {
+ QMap<QString, QString> map;
+
+ for (int i = 0; i < size; ++i) {
+ QString const key = GFUnStrDup(meta_data_array[i]->key);
+ QString const value = GFUnStrDup(meta_data_array[i]->value);
+ map.insert(key, value);
+
+ GpgFrontend::SecureFree(meta_data_array[i]);
+ }
+
+ GpgFrontend::SecureFree(meta_data_array);
+ return map;
+}
+
+auto GFUIMountEntry(const char* id, MetaData** meta_data_array,
+ int meta_data_array_size, EntryFactory factory) -> int {
+ if (id == nullptr || factory == nullptr) return -1;
+
+ auto meta_data = MetaDataArrayToQMap(meta_data_array, meta_data_array_size);
+ auto qid = GFUnStrDup(id);
+
+ QMetaObject::invokeMethod(
+ QApplication::instance()->thread(), [qid, meta_data, factory]() -> int {
+ return GpgFrontend::UI::UIModuleManager::GetInstance().MountEntry(
+ qid, meta_data, factory)
+ ? 0
+ : -1;
+ });
+
+ return 0;
+}
diff --git a/src/sdk/GFSDKUI.h b/src/sdk/GFSDKUI.h
new file mode 100644
index 00000000..ba9a3490
--- /dev/null
+++ b/src/sdk/GFSDKUI.h
@@ -0,0 +1,46 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend 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.
+ *
+ * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "GFSDKExport.h"
+
+extern "C" {
+
+using EntryFactory = void* (*)(const char*);
+
+struct MetaData {
+ const char* key;
+ const char* value;
+};
+
+auto GPGFRONTEND_MODULE_SDK_EXPORT GFUIMountEntry(const char* id,
+ MetaData** meta_data_array,
+ int meta_data_array_size,
+ EntryFactory factory) -> int;
+} \ No newline at end of file
diff --git a/src/module/sdk/GFSDKUtils.cpp b/src/sdk/GFSDKUtils.cpp
index fcb510e3..fcb510e3 100644
--- a/src/module/sdk/GFSDKUtils.cpp
+++ b/src/sdk/GFSDKUtils.cpp
diff --git a/src/module/sdk/GFSDKUtils.h b/src/sdk/GFSDKUtils.h
index 7d72e9ee..7d72e9ee 100644
--- a/src/module/sdk/GFSDKUtils.h
+++ b/src/sdk/GFSDKUtils.h
diff --git a/src/sdk/private/CommonUtils.cpp b/src/sdk/private/CommonUtils.cpp
new file mode 100644
index 00000000..31092a3e
--- /dev/null
+++ b/src/sdk/private/CommonUtils.cpp
@@ -0,0 +1,103 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend 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.
+ *
+ * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "CommonUtils.h"
+
+#include <core/utils/MemoryUtils.h>
+
+#include <cstring>
+
+#include "GFSDKModule.h"
+
+auto GFStrDup(const QString& str) -> char* {
+ auto utf8_str = str.toUtf8();
+ auto* c_str = static_cast<char*>(
+ GpgFrontend::SecureMalloc((utf8_str.size() + 1) * sizeof(char)));
+
+ memcpy(c_str, utf8_str.constData(), utf8_str.size());
+ c_str[utf8_str.size()] = '\0';
+ return c_str;
+}
+
+auto GFUnStrDup(char* str) -> QString {
+ auto qt_str = QString::fromUtf8(str);
+ GpgFrontend::SecureFree(static_cast<void*>(const_cast<char*>(str)));
+ return qt_str;
+}
+
+auto GFUnStrDup(const char* str) -> QString {
+ return GFUnStrDup(const_cast<char*>(str));
+}
+
+auto CharArrayToQMap(char** char_array, int size) -> QMap<QString, QString> {
+ QMap<QString, QString> map;
+ for (int i = 0; i < size; i += 2) {
+ QString const key = GFUnStrDup(char_array[i]);
+ QString const value = QString::fromUtf8(char_array[i + 1]);
+ map.insert(key, value);
+ }
+ return map;
+}
+
+auto QMapToCharArray(const QMap<QString, QString>& map, int& size) -> char** {
+ size = map.size() * 2;
+ char** char_array = new char*[size];
+
+ int index = 0;
+ for (auto it = map.begin(); it != map.end(); ++it) {
+ QByteArray const key = it.key().toUtf8();
+ QByteArray const value = it.value().toUtf8();
+
+ char_array[index] = new char[key.size() + 1];
+ std::strcpy(char_array[index], key.constData());
+ index++;
+
+ char_array[index] = new char[value.size() + 1];
+ std::strcpy(char_array[index], value.constData());
+ index++;
+ }
+
+ return char_array;
+}
+
+auto ConvertEventParamsToMap(GFModuleEventParam* params)
+ -> QMap<QString, QString> {
+ QMap<QString, QString> param_map;
+ GFModuleEventParam* current = params;
+ GFModuleEventParam* last;
+
+ while (current != nullptr) {
+ param_map[current->name] = GFUnStrDup(current->value);
+
+ last = current;
+ current = current->next;
+ GpgFrontend::SecureFree(last);
+ }
+
+ return param_map;
+} \ No newline at end of file
diff --git a/src/module/mods/gpg_info/GnuPGInfoGatheringModule.h b/src/sdk/private/CommonUtils.h
index 35ee4ac3..514bcd5d 100644
--- a/src/module/mods/gpg_info/GnuPGInfoGatheringModule.h
+++ b/src/sdk/private/CommonUtils.h
@@ -28,29 +28,53 @@
#pragma once
-#include <GFSDKModule.h>
+struct GFModuleEventParam;
-#include "GFModuleExport.h"
-
-extern "C" {
-
-auto GF_MODULE_EXPORT GFGetModuleGFSDKVersion() -> const char *;
-
-auto GF_MODULE_EXPORT GFGetModuleQtEnvVersion() -> const char *;
-
-auto GF_MODULE_EXPORT GFGetModuleID() -> const char *;
-
-auto GF_MODULE_EXPORT GFGetModuleVersion() -> const char *;
-
-auto GF_MODULE_EXPORT GFGetModuleMetaData() -> GFModuleMetaData *;
+/**
+ * @brief
+ *
+ * @return char*
+ */
+auto GFStrDup(const QString &) -> char *;
-auto GF_MODULE_EXPORT GFRegisterModule() -> int;
+/**
+ * @brief
+ *
+ * @param str
+ * @return QString
+ */
+auto GFUnStrDup(char *str) -> QString;
-auto GF_MODULE_EXPORT GFActiveModule() -> int;
+/**
+ * @brief
+ *
+ * @return QString
+ */
+auto GFUnStrDup(const char *) -> QString;
-auto GF_MODULE_EXPORT GFExecuteModule(GFModuleEvent *) -> int;
+/**
+ * @brief
+ *
+ * @param char_array
+ * @param size
+ * @return QMap<QString, QString>
+ */
+auto CharArrayToQMap(char **char_array, int size) -> QMap<QString, QString>;
-auto GF_MODULE_EXPORT GFDeactiveModule() -> int;
+/**
+ * @brief
+ *
+ * @param map
+ * @param size
+ * @return char**
+ */
+auto QMapToCharArray(const QMap<QString, QString> &map, int &size) -> char **;
-auto GF_MODULE_EXPORT GFUnregisterModule() -> int;
-};
+/**
+ * @brief
+ *
+ * @param params
+ * @return QMap<QString, QString>
+ */
+auto ConvertEventParamsToMap(GFModuleEventParam *params)
+ -> QMap<QString, QString>; \ No newline at end of file
diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt
index f23cc928..9179f3c0 100644
--- a/src/test/CMakeLists.txt
+++ b/src/test/CMakeLists.txt
@@ -28,16 +28,22 @@
aux_source_directory(./core TEST_SOURCE)
aux_source_directory(. TEST_SOURCE)
+# define test library
add_library(gpgfrontend_test SHARED ${TEST_SOURCE})
+# generate headers
set(_export_file "${CMAKE_CURRENT_SOURCE_DIR}/GpgFrontendTestExport.h")
generate_export_header(gpgfrontend_test EXPORT_FILE_NAME "${_export_file}")
+# compile definitions
+target_compile_definitions(gpgfrontend_test PUBLIC GF_TEST)
+
+# link options
target_link_libraries(gpgfrontend_test PRIVATE gtest)
+
target_link_libraries(gpgfrontend_test PRIVATE gpgfrontend_core)
-target_link_libraries(gpgfrontend_test PRIVATE spdlog)
-if (XCODE_BUILD)
+if(XCODE_BUILD)
set_target_properties(gpgfrontend_test
PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
@@ -45,14 +51,13 @@ if (XCODE_BUILD)
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
XCODE_ATTRIBUTE_SKIP_INSTALL "Yes"
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}")
-endif ()
-
-if(MINGW)
- set_target_properties(gtest
- PROPERTIES
- LIBRARY_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
- RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
- )
+endif()
+
+if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
+ # lib output path
+ set_target_properties(gpgfrontend_test PROPERTIES
+ LIBRARY_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/lib
+ RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/lib)
endif()
add_test(AllTestsInGpgFrontend gpgfrontend_test)
diff --git a/src/test/GpgFrontendTest.cpp b/src/test/GpgFrontendTest.cpp
index 95b4179a..2ad7ada7 100644
--- a/src/test/GpgFrontendTest.cpp
+++ b/src/test/GpgFrontendTest.cpp
@@ -29,6 +29,7 @@
#include "GpgFrontendTest.h"
#include <gtest/gtest.h>
+#include <qglobal.h>
#include "core/GpgConstants.h"
#include "core/function/GlobalSettingStation.h"
@@ -37,6 +38,8 @@
#include "core/function/gpg/GpgKeyImportExporter.h"
#include "core/utils/IOUtils.h"
+Q_LOGGING_CATEGORY(test, "test")
+
namespace GpgFrontend::Test {
auto GenerateRandomString(size_t length) -> QString {
@@ -56,8 +59,6 @@ auto GenerateRandomString(size_t length) -> QString {
void ConfigureGpgContext() {
auto db_path = QDir(QDir::tempPath() + "/" + GenerateRandomString(12));
- GF_TEST_LOG_DEBUG("setting up new database path for test case: {}",
- db_path.path());
if (db_path.exists()) db_path.rmdir(".");
db_path.mkpath(".");
@@ -84,7 +85,7 @@ void ImportPrivateKeys(const QString& data_path, QSettings settings) {
GpgKeyImportExporter::GetInstance(kGpgFrontendDefaultChannel)
.ImportKey(gf_buffer);
} else {
- GF_TEST_LOG_ERROR("read from key file failed: {}", key_file);
+ qCWarning(test) << "read from key file failed: " << key_file;
}
}
}
@@ -95,8 +96,8 @@ void SetupGlobalTestEnv() {
auto test_config_path = test_path + "/conf/test.ini";
auto test_data_path = test_path + "/data";
- GF_TEST_LOG_INFO("test config file path: {}", test_config_path);
- GF_TEST_LOG_INFO("test data file path: {}", test_data_path);
+ qCInfo(test) << "test config file path: " << test_config_path;
+ qCInfo(test) << "test data file path: " << test_data_path;
ImportPrivateKeys(test_data_path,
QSettings(test_config_path, QSettings::IniFormat));
diff --git a/src/test/GpgFrontendTest.h b/src/test/GpgFrontendTest.h
index 405eee90..3c1ecbfd 100644
--- a/src/test/GpgFrontendTest.h
+++ b/src/test/GpgFrontendTest.h
@@ -30,8 +30,13 @@
#include "GpgFrontendTestExport.h"
-// Core
-#include "core/utils/LogUtils.h"
+// declare area of test
+#ifdef GF_TEST
+
+// declare logging category
+Q_DECLARE_LOGGING_CATEGORY(test)
+
+#endif
namespace GpgFrontend::Test {
@@ -42,10 +47,4 @@ struct GpgFrontendContext {
auto GPGFRONTEND_TEST_EXPORT ExecuteAllTestCase(GpgFrontendContext args) -> int;
-#define GF_TEST_LOG_TRACE(...) GF_LOG_TRACE("test", __VA_ARGS__)
-#define GF_TEST_LOG_DEBUG(...) GF_LOG_DEBUG("test", __VA_ARGS__)
-#define GF_TEST_LOG_INFO(...) GF_LOG_INFO("test", __VA_ARGS__)
-#define GF_TEST_LOG_WARN(...) GF_LOG_WARN("test", __VA_ARGS__)
-#define GF_TEST_LOG_ERROR(...) GF_LOG_ERROR("test", __VA_ARGS__)
-
} // namespace GpgFrontend::Test
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
index e6b41b50..4dcaf73f 100644
--- a/src/ui/CMakeLists.txt
+++ b/src/ui/CMakeLists.txt
@@ -23,7 +23,6 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
-
# tracking source files
aux_source_directory(. UI_SOURCE)
aux_source_directory(dialog/keypair_details UI_SOURCE)
@@ -43,46 +42,55 @@ aux_source_directory(function UI_SOURCE)
# define libgpgfrontend_ui
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
+
add_library(gpgfrontend_ui SHARED ${UI_SOURCE})
+
+# generate headers
set(_export_file "${CMAKE_CURRENT_SOURCE_DIR}/GpgFrontendUIExport.h")
generate_export_header(gpgfrontend_ui EXPORT_FILE_NAME "${_export_file}")
+# compile definitions
+target_compile_definitions(gpgfrontend_ui PUBLIC GF_UI)
+
if(GPGFRONTEND_QT5_BUILD)
# link Qt
target_link_libraries(gpgfrontend_ui
- Qt5::Core Qt5::Widgets Qt5::Network Qt5::PrintSupport)
+ Qt5::Core Qt5::Widgets Qt5::Network Qt5::PrintSupport)
else()
# link Qt
target_link_libraries(gpgfrontend_ui
- Qt6::Core Qt6::Widgets Qt6::Network Qt6::PrintSupport)
+ Qt6::Core Qt6::Widgets Qt6::Network Qt6::PrintSupport)
endif()
-
# link gpgfrontend_core
target_link_libraries(gpgfrontend_ui gpgfrontend_core)
-# link buddled pinentry
-target_link_libraries(gpgfrontend_ui gpgfrontend_pinentry)
-
# set up pch
target_precompile_headers(gpgfrontend_ui PUBLIC GpgFrontendUI.h)
# add ui generator include path
target_include_directories(gpgfrontend_ui PUBLIC
- ${CMAKE_CURRENT_BINARY_DIR}/gpgfrontend_ui_autogen/include
- ${CMAKE_SOURCE_DIR}/third_party/spdlog/include)
+ ${CMAKE_CURRENT_BINARY_DIR}/gpgfrontend_ui_autogen/include)
# using std c++ 17
target_compile_features(gpgfrontend_ui PUBLIC cxx_std_17)
+if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
+ # lib output path
+ set_target_properties(gpgfrontend_ui PROPERTIES
+ LIBRARY_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/lib
+ RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/lib)
+endif()
+
# for xcode archive build
-if (XCODE_BUILD)
- set_target_properties(gpgfrontend_ui
- PROPERTIES
- ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
- LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
- LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
- XCODE_ATTRIBUTE_SKIP_INSTALL "Yes"
- XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}")
-endif ()
+if(XCODE_BUILD)
+ set_target_properties(gpgfrontend_ui
+ PROPERTIES
+ ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
+ LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
+ LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
+ XCODE_ATTRIBUTE_SKIP_INSTALL "Yes"
+ XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}")
+endif()
+
target_compile_features(gpgfrontend_ui PUBLIC cxx_std_17) \ No newline at end of file
diff --git a/src/ui/GpgFrontendApplication.cpp b/src/ui/GpgFrontendApplication.cpp
index b3c12de6..3ee7ab7d 100644
--- a/src/ui/GpgFrontendApplication.cpp
+++ b/src/ui/GpgFrontendApplication.cpp
@@ -40,7 +40,7 @@ GpgFrontendApplication::GpgFrontendApplication(int &argc, char *argv[])
#endif
// set the extra information of the build
- GpgFrontendApplication::setApplicationVersion(GetProjectBuildVersion());
+ GpgFrontendApplication::setApplicationVersion(GetProjectVersion());
GpgFrontendApplication::setApplicationName(QString::fromUtf8((PROJECT_NAME)));
GpgFrontendApplication::setApplicationDisplayName(
QString::fromUtf8((PROJECT_NAME)));
@@ -57,7 +57,7 @@ bool GpgFrontendApplication::notify(QObject *receiver, QEvent *event) {
try {
return QApplication::notify(receiver, event);
} catch (const std::exception &ex) {
- GF_UI_LOG_ERROR("exception was caught in notify: {}", ex.what());
+ qCWarning(ui, "exception was caught in notify: {}", ex.what());
QMessageBox::information(
nullptr, tr("Standard Exception Thrown"),
tr("Oops, an standard exception was thrown "
@@ -66,7 +66,7 @@ bool GpgFrontendApplication::notify(QObject *receiver, QEvent *event) {
"be the negligence of the programmer, "
"please report this problem if you can."));
} catch (...) {
- GF_UI_LOG_ERROR("unknown exception was caught in notify");
+ qCWarning(ui, "unknown exception was caught in notify");
QMessageBox::information(
nullptr, tr("Unhandled Exception Thrown"),
tr("Oops, an unhandled exception was thrown "
diff --git a/src/module/sdk/GFSDKUI.h b/src/ui/GpgFrontendUI.cpp
index 0702632a..359eb6d2 100644
--- a/src/module/sdk/GFSDKUI.h
+++ b/src/ui/GpgFrontendUI.cpp
@@ -26,4 +26,6 @@
*
*/
-#pragma once \ No newline at end of file
+#include "GpgFrontendUI.h"
+
+Q_LOGGING_CATEGORY(ui, "ui") \ No newline at end of file
diff --git a/src/ui/GpgFrontendUI.h b/src/ui/GpgFrontendUI.h
index b3115795..a4793672 100644
--- a/src/ui/GpgFrontendUI.h
+++ b/src/ui/GpgFrontendUI.h
@@ -33,16 +33,13 @@
*/
#include <QtWidgets>
-// Core
-#include "GpgFrontend.h"
-#include "core/GpgFrontendCore.h"
-#include "core/utils/LogUtils.h"
-
// UI
#include "ui/GpgFrontendUIExport.h"
-#define GF_UI_LOG_TRACE(...) GF_LOG_TRACE("ui", __VA_ARGS__)
-#define GF_UI_LOG_DEBUG(...) GF_LOG_DEBUG("ui", __VA_ARGS__)
-#define GF_UI_LOG_INFO(...) GF_LOG_INFO("ui", __VA_ARGS__)
-#define GF_UI_LOG_WARN(...) GF_LOG_WARN("ui", __VA_ARGS__)
-#define GF_UI_LOG_ERROR(...) GF_LOG_ERROR("ui", __VA_ARGS__)
+// declare area of ui
+#ifdef GF_UI
+
+// declare logging category
+Q_DECLARE_LOGGING_CATEGORY(ui)
+
+#endif
diff --git a/src/ui/GpgFrontendUIInit.cpp b/src/ui/GpgFrontendUIInit.cpp
index 046c25d7..b779c335 100644
--- a/src/ui/GpgFrontendUIInit.cpp
+++ b/src/ui/GpgFrontendUIInit.cpp
@@ -30,6 +30,7 @@
#include <QtNetwork>
+#include "UIModuleManager.h"
#include "core/GpgConstants.h"
#include "core/function/CoreSignalStation.h"
#include "core/function/GlobalSettingStation.h"
@@ -42,11 +43,12 @@
namespace GpgFrontend::UI {
QList<QTranslator*> registered_translators;
+QList<QByteArray> loaded_qm_datum;
extern void InitUITranslations();
void WaitEnvCheckingProcess() {
- GF_UI_LOG_DEBUG("need to waiting for env checking process");
+ qCDebug(ui, "need to waiting for env checking process");
// create and show loading window before starting the main window
auto* waiting_dialog = new QProgressDialog();
@@ -65,7 +67,6 @@ void WaitEnvCheckingProcess() {
QApplication::connect(CoreSignalStation::GetInstance(),
&CoreSignalStation::SignalGoodGnupgEnv, waiting_dialog,
[=]() {
- GF_UI_LOG_DEBUG("gpg env loaded successfuly");
waiting_dialog->finished(0);
waiting_dialog->deleteLater();
});
@@ -77,19 +78,19 @@ void WaitEnvCheckingProcess() {
&QEventLoop::quit);
QApplication::connect(waiting_dialog, &QProgressDialog::canceled, [=]() {
- GF_UI_LOG_DEBUG("cancel clicked on waiting dialog");
+ qCDebug(ui, "cancel clicked on waiting dialog");
QApplication::quit();
exit(0);
});
auto env_state =
Module::RetrieveRTValueTypedOrDefault<>("core", "env.state.basic", 0);
- GF_UI_LOG_DEBUG("ui is ready to waiting for env initialized, env_state: {}",
- env_state);
+ qCDebug(ui, "ui is ready to waiting for env initialized, env_state: %d",
+ env_state);
// check twice to avoid some unlucky sitations
if (env_state == 1) {
- GF_UI_LOG_DEBUG("env state turned initialized before the looper start");
+ qCDebug(ui, "env state turned initialized before the looper start");
waiting_dialog->finished(0);
waiting_dialog->deleteLater();
return;
@@ -104,7 +105,13 @@ void WaitEnvCheckingProcess() {
looper.exec();
}
-void PreInitGpgFrontendUI() { CommonUtils::GetInstance(); }
+void PreInitGpgFrontendUI() {
+ CommonUtils::GetInstance();
+
+ // declare module ui entry mount points
+ UIModuleManager::GetInstance().DeclareMountPoint("AboutDialogTabs", "QWidget",
+ {});
+}
void InitGpgFrontendUI(QApplication* /*app*/) {
// init locale
@@ -151,8 +158,6 @@ void InitGpgFrontendUI(QApplication* /*app*/) {
settings.value("proxy/username", QString{}).toString();
QString const proxy_password =
settings.value("proxy/password", QString{}).toString();
- GF_UI_LOG_DEBUG("proxy settings: type {}, host {}, port: {}", proxy_type,
- proxy_host, proxy_port);
QNetworkProxy::ProxyType proxy_type_qt = QNetworkProxy::NoProxy;
if (proxy_type == "HTTP") {
@@ -181,7 +186,7 @@ void InitGpgFrontendUI(QApplication* /*app*/) {
QNetworkProxy::setApplicationProxy(proxy);
} catch (...) {
- GF_UI_LOG_ERROR("setting operation error: proxy setings");
+ qCWarning(ui, "setting operation error: proxy setings");
// no proxy by default
QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy);
}
@@ -202,7 +207,7 @@ auto RunGpgFrontendUI(QApplication* app) -> int {
// pre-check, if application need to restart
if (CommonUtils::GetInstance()->isApplicationNeedRestart()) {
- GF_UI_LOG_DEBUG("application need to restart, before main window init");
+ qCDebug(ui, "application need to restart, before main window init.");
return kDeepRestartCode;
}
@@ -210,7 +215,6 @@ auto RunGpgFrontendUI(QApplication* app) -> int {
main_window->Init();
// show main windows
- GF_UI_LOG_DEBUG("main window is ready to show");
main_window->show();
// start the main event loop
@@ -228,13 +232,11 @@ void InitUITranslations() {
QCoreApplication::removeTranslator(translator);
}
registered_translators.clear();
+ loaded_qm_datum.clear();
auto* translator = new QTranslator(QCoreApplication::instance());
if (translator->load(QLocale(), QLatin1String("qt"), QLatin1String("_"),
QLatin1String(":/i18n_qt"), QLatin1String(".qm"))) {
- GF_UI_LOG_DEBUG("load qt translation file done, locale: {}",
- QLocale().name());
-
QCoreApplication::installTranslator(translator);
registered_translators.append(translator);
}
@@ -242,8 +244,6 @@ void InitUITranslations() {
translator = new QTranslator(QCoreApplication::instance());
if (translator->load(QLocale(), QLatin1String("qtbase"), QLatin1String("_"),
QLatin1String(":/i18n_qt"), QLatin1String(".qm"))) {
- GF_UI_LOG_DEBUG("load qtbase translation file done, locale: {}",
- QLocale().name());
QCoreApplication::installTranslator(translator);
registered_translators.append(translator);
}
@@ -252,11 +252,24 @@ void InitUITranslations() {
if (translator->load(QLocale(), QLatin1String(PROJECT_NAME),
QLatin1String("."), QLatin1String(":/i18n"),
QLatin1String(".qm"))) {
- GF_UI_LOG_DEBUG("load target translation file done, locale: {}",
- QLocale().name());
QCoreApplication::installTranslator(translator);
registered_translators.append(translator);
}
}
+auto InstallTranslatorFromQMData(const QByteArray& data) -> bool {
+ auto* translator = new QTranslator(QCoreApplication::instance());
+
+ if (translator->load(reinterpret_cast<uchar*>(const_cast<char*>(data.data())),
+ data.size())) {
+ QCoreApplication::installTranslator(translator);
+ registered_translators.append(translator);
+ loaded_qm_datum.append(data);
+
+ return true;
+ }
+
+ return false;
+}
+
} // namespace GpgFrontend::UI
diff --git a/src/ui/GpgFrontendUIInit.h b/src/ui/GpgFrontendUIInit.h
index fd62f3f6..686b3558 100644
--- a/src/ui/GpgFrontendUIInit.h
+++ b/src/ui/GpgFrontendUIInit.h
@@ -55,4 +55,11 @@ void GPGFRONTEND_UI_EXPORT DestroyGpgFrontendUI();
*/
auto GPGFRONTEND_UI_EXPORT RunGpgFrontendUI(QApplication *) -> int;
+/**
+ * @brief
+ *
+ */
+auto GPGFRONTEND_UI_EXPORT InstallTranslatorFromQMData(const QByteArray &data)
+ -> bool;
+
}; // namespace GpgFrontend::UI
diff --git a/src/ui/UIModuleManager.cpp b/src/ui/UIModuleManager.cpp
new file mode 100644
index 00000000..1e08010d
--- /dev/null
+++ b/src/ui/UIModuleManager.cpp
@@ -0,0 +1,104 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend 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.
+ *
+ * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "UIModuleManager.h"
+
+#include <utility>
+
+#include "core/module/ModuleManager.h"
+
+namespace GpgFrontend::UI {
+
+UIModuleManager::UIModuleManager(int channel)
+ : SingletonFunctionObject<UIModuleManager>(channel) {}
+
+UIModuleManager::~UIModuleManager() = default;
+
+auto UIModuleManager::DeclareMountPoint(
+ const QString& id, const QString& entry_type,
+ QMap<QString, QVariant> meta_data_desc) -> bool {
+ if (id.isEmpty() || mount_points_.contains(id)) return false;
+
+ UIMountPoint point;
+ point.id = id;
+ point.entry_type = entry_type;
+ point.meta_data_desc = std::move(meta_data_desc);
+
+ mount_points_[id] = point;
+
+ auto grt_key = QString("mount_points.%1").arg(id);
+ GpgFrontend::Module::UpsertRTValue(
+ "ui", grt_key, QString(QJsonDocument(point.ToJson()).toJson()));
+
+ return true;
+}
+
+auto UIModuleManager::MountEntry(const QString& id,
+ QMap<QString, QString> meta_data,
+ EntryFactory factory) -> bool {
+ if (id.isEmpty() || !mount_points_.contains(id)) return false;
+
+ if (factory == nullptr) return false;
+
+ MountedUIEntry m_entry;
+ m_entry.id_ = id;
+
+#ifdef QT5_BUILD
+ for (auto it = meta_data.keyValueBegin(); it != meta_data.keyValueEnd();
+ ++it) {
+ meta_data[it->first] = QApplication::translate("GTrC", it->second.toUtf8());
+ }
+#else
+ for (const auto& meta : meta_data.asKeyValueRange()) {
+ meta_data[meta.first] =
+ QApplication::translate("GTrC", meta.second.toUtf8());
+ }
+#endif
+
+ m_entry.meta_data_ = std::move(meta_data);
+ m_entry.factory_ = factory;
+
+ mounted_entries_[id].append(m_entry);
+ return true;
+}
+
+auto UIModuleManager::QueryMountedEntries(QString id) -> QList<MountedUIEntry> {
+ if (id.isEmpty() || !mount_points_.contains(id)) return {};
+ return mounted_entries_[id];
+}
+
+auto MountedUIEntry::GetWidget() const -> QWidget* {
+ return qobject_cast<QWidget*>(static_cast<QObject*>(factory_(id_.toUtf8())));
+}
+
+auto MountedUIEntry::GetMetaDataByDefault(
+ const QString& key, QString default_value) const -> QString {
+ if (!meta_data_.contains(key)) return default_value;
+ return meta_data_[key];
+}
+} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/UIModuleManager.h b/src/ui/UIModuleManager.h
new file mode 100644
index 00000000..88096578
--- /dev/null
+++ b/src/ui/UIModuleManager.h
@@ -0,0 +1,104 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend 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.
+ *
+ * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "GpgFrontendUIExport.h"
+#include "core/function/basic/GpgFunctionObject.h"
+#include "sdk/GFSDKUI.h"
+#include "ui/struct/UIMountPoint.h"
+
+namespace GpgFrontend::UI {
+
+struct MountedUIEntry {
+ QString id_;
+ QMap<QString, QString> meta_data_;
+ EntryFactory factory_;
+
+ MountedUIEntry() = default;
+
+ [[nodiscard]] auto GetWidget() const -> QWidget*;
+
+ [[nodiscard]] auto GetMetaDataByDefault(const QString& key,
+ QString default_value) const
+ -> QString;
+};
+
+class GPGFRONTEND_UI_EXPORT UIModuleManager
+ : public SingletonFunctionObject<UIModuleManager> {
+ public:
+ /**
+ * @brief Construct a new UIModuleManager object
+ *
+ * @param channel
+ */
+ explicit UIModuleManager(int channel);
+
+ /**
+ * @brief Destroy the UIModuleManager object
+ *
+ */
+ virtual ~UIModuleManager() override;
+ /**
+ * @brief
+ *
+ * @param id
+ * @param entry_type
+ * @param metadata_desc
+ * @return true
+ * @return false
+ */
+ auto DeclareMountPoint(const QString& id, const QString& entry_type,
+ QMap<QString, QVariant> meta_data_desc) -> bool;
+
+ /**
+ * @brief
+ *
+ * @param id
+ * @param meta_data
+ * @param entry
+ * @return true
+ * @return false
+ */
+ auto MountEntry(const QString& id, QMap<QString, QString> meta_data,
+ EntryFactory factory) -> bool;
+
+ /**
+ * @brief
+ *
+ * @param id
+ * @return QList<MountedUIEntry>
+ */
+ auto QueryMountedEntries(QString id) -> QList<MountedUIEntry>;
+
+ private:
+ QMap<QString, UIMountPoint> mount_points_;
+ QMap<QString, QList<MountedUIEntry>> mounted_entries_;
+};
+
+} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/UserInterfaceUtils.cpp b/src/ui/UserInterfaceUtils.cpp
index 806ceb9e..8f50636b 100644
--- a/src/ui/UserInterfaceUtils.cpp
+++ b/src/ui/UserInterfaceUtils.cpp
@@ -80,7 +80,6 @@ void ImportUnknownKeyFromKeyserver(
auto key_ids = std::make_unique<KeyIdArgsList>();
auto *signature = verify_result.GetSignatures();
while (signature != nullptr) {
- GF_UI_LOG_DEBUG("signature fpr: {}", signature->fpr);
key_ids->push_back(signature->fpr);
signature = signature->next;
}
@@ -232,8 +231,6 @@ void CommonUtils::WaitForOpera(QWidget *parent,
QTimer::singleShot(64, parent, [=]() {
opera([dialog]() {
if (dialog != nullptr) {
- GF_UI_LOG_DEBUG("called operating waiting cb, dialog: {}",
- static_cast<void *>(dialog));
dialog->close();
dialog->accept();
}
@@ -267,7 +264,7 @@ void CommonUtils::RaiseFailureMessageBox(QWidget *parent, GpgError err) {
.arg(desc.second));
}
-void CommonUtils::SlotImportKeys(QWidget *parent, const QString &in_buffer) {
+void CommonUtils::SlotImportKeys(QWidget *parent, const QByteArray &in_buffer) {
auto info =
GpgKeyImportExporter::GetInstance().ImportKey(GFBuffer(in_buffer));
emit SignalKeyStatusUpdated();
@@ -313,7 +310,7 @@ void CommonUtils::SlotImportKeyFromKeyServer(QWidget *parent) {
void CommonUtils::SlotImportKeyFromClipboard(QWidget *parent) {
QClipboard *cb = QApplication::clipboard();
- SlotImportKeys(parent, cb->text(QClipboard::Clipboard));
+ SlotImportKeys(parent, cb->text(QClipboard::Clipboard).toLatin1());
}
void CommonUtils::SlotExecuteCommand(
@@ -328,18 +325,17 @@ void CommonUtils::SlotExecuteCommand(
&QEventLoop::quit);
connect(cmd_process, &QProcess::errorOccurred, &looper, &QEventLoop::quit);
connect(cmd_process, &QProcess::started,
- []() -> void { GF_UI_LOG_DEBUG("process started"); });
+ []() -> void { qCDebug(ui, "process started"); });
connect(cmd_process, &QProcess::readyReadStandardOutput,
[interact_func, cmd_process]() { interact_func(cmd_process); });
connect(cmd_process, &QProcess::errorOccurred, this,
- [=]() -> void { GF_UI_LOG_ERROR("error in process"); });
+ [=]() -> void { qCWarning(ui, "error in process"); });
connect(cmd_process,
qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this,
[=](int, QProcess::ExitStatus status) {
- if (status == QProcess::NormalExit)
- GF_UI_LOG_DEBUG("succeed in executing command: {}", cmd);
- else
- GF_UI_LOG_WARN("error in executing command: {}", cmd);
+ if (status != QProcess::NormalExit) {
+ qCWarning(ui) << "error in executing command: " << cmd;
+ }
});
cmd_process->setProgram(cmd);
@@ -365,11 +361,11 @@ void CommonUtils::SlotExecuteGpgCommand(
&WaitingDialog::deleteLater);
connect(gpg_process, &QProcess::errorOccurred, &looper, &QEventLoop::quit);
connect(gpg_process, &QProcess::started,
- []() -> void { GF_UI_LOG_DEBUG("gpg process started"); });
+ []() -> void { qCDebug(ui, "gpg process started"); });
connect(gpg_process, &QProcess::readyReadStandardOutput,
[interact_func, gpg_process]() { interact_func(gpg_process); });
connect(gpg_process, &QProcess::errorOccurred, this, [=]() -> void {
- GF_UI_LOG_ERROR("Error in Process");
+ qCWarning(ui, "Error in Process");
dialog->close();
QMessageBox::critical(nullptr, tr("Failure"),
tr("Failed to execute command."));
@@ -388,7 +384,6 @@ void CommonUtils::SlotExecuteGpgCommand(
const auto app_path = Module::RetrieveRTValueTypedOrDefault<>(
"core", "gpgme.ctx.app_path", QString{});
- GF_UI_LOG_DEBUG("got gnupg app path from rt: {}", app_path);
gpg_process->setProgram(app_path);
gpg_process->setArguments(arguments);
@@ -409,8 +404,6 @@ void CommonUtils::SlotImportKeyFromKeyServer(
"please set a default keyserver first"));
return;
}
- GF_UI_LOG_DEBUG("set target key server to default Key Server: {}",
- target_keyserver);
auto *thread = QThread::create([target_keyserver, key_ids, callback]() {
QUrl target_keyserver_url(target_keyserver);
@@ -426,8 +419,6 @@ void CommonUtils::SlotImportKeyFromKeyServer(
target_keyserver_url.host() +
"/pks/lookup?op=get&search=0x" + key_id + "&options=mr");
- GF_UI_LOG_DEBUG("request url: {}", req_url.toString());
-
// Waiting for reply
auto request = QNetworkRequest(req_url);
request.setHeader(QNetworkRequest::UserAgentHeader,
@@ -498,21 +489,19 @@ void CommonUtils::slot_update_key_from_server_finished(
bool success, QString err_msg, QByteArray buffer,
std::shared_ptr<GpgImportInformation> info) {
if (!success) {
- GF_UI_LOG_ERROR("get err from reply: {}", buffer);
+ qCWarning(ui) << "get err from reply: " << buffer;
QMessageBox::critical(nullptr, tr("Error"), err_msg);
return;
}
// refresh the key database
- emit UISignalStation::GetInstance()->SignalKeyDatabaseRefresh();
+ emit UISignalStation::GetInstance() -> SignalKeyDatabaseRefresh();
// show details
(new KeyImportDetailDialog(std::move(info), this))->exec();
}
void CommonUtils::SlotRestartApplication(int code) {
- GF_UI_LOG_DEBUG("application need restart, code: {}", code);
-
if (code == 0) {
std::exit(0);
} else {
@@ -529,34 +518,41 @@ auto CommonUtils::KeyExistsinFavouriteList(const GpgKey &key) -> bool {
auto json_data = CacheObject("favourite_key_pair");
if (!json_data.isArray()) json_data.setArray(QJsonArray());
- auto key_array = json_data.array();
- return std::find(key_array.begin(), key_array.end(), key.GetFingerprint()) !=
- key_array.end();
+ auto key_fpr_array = json_data.array();
+ return std::find(key_fpr_array.begin(), key_fpr_array.end(),
+ key.GetFingerprint()) != key_fpr_array.end();
}
void CommonUtils::AddKey2Favourtie(const GpgKey &key) {
- auto json_data = CacheObject("favourite_key_pair");
- QJsonArray key_array;
- if (json_data.isArray()) key_array = json_data.array();
+ {
+ auto json_data = CacheObject("favourite_key_pair");
+ QJsonArray key_array;
+ if (json_data.isArray()) key_array = json_data.array();
+
+ key_array.push_back(key.GetFingerprint());
+ json_data.setArray(key_array);
+ }
- key_array.push_back(key.GetFingerprint());
- json_data.setArray(key_array);
+ emit SignalFavoritesChanged();
}
void CommonUtils::RemoveKeyFromFavourite(const GpgKey &key) {
- auto json_data = CacheObject("favourite_key_pair");
- QJsonArray key_array;
- if (json_data.isArray()) key_array = json_data.array();
-
- QString fingerprint = key.GetFingerprint();
- QJsonArray new_key_array;
- for (auto &&item : key_array) {
- if (item.isString() && item.toString() != fingerprint) {
- new_key_array.append(item);
+ {
+ auto json_data = CacheObject("favourite_key_pair");
+ QJsonArray key_array;
+ if (json_data.isArray()) key_array = json_data.array();
+
+ auto fingerprint = key.GetFingerprint();
+ QJsonArray new_key_array;
+ for (auto &&item : key_array) {
+ if (item.isString() && item.toString() != fingerprint) {
+ new_key_array.append(item);
+ }
}
+ json_data.setArray(new_key_array);
}
- json_data.setArray(new_key_array);
+ emit SignalFavoritesChanged();
}
/**
diff --git a/src/ui/UserInterfaceUtils.h b/src/ui/UserInterfaceUtils.h
index 304ba37b..4f42db8c 100644
--- a/src/ui/UserInterfaceUtils.h
+++ b/src/ui/UserInterfaceUtils.h
@@ -63,8 +63,8 @@ void show_verify_details(QWidget* parent, InfoBoardWidget* info_board,
* @param parent
* @param verify_res
*/
-void ImportUnknownKeyFromKeyserver(
- QWidget* parent, const GpgVerifyResultAnalyse& verify_res);
+void ImportUnknownKeyFromKeyserver(QWidget* parent,
+ const GpgVerifyResultAnalyse& verify_res);
/**
* @brief
@@ -135,7 +135,7 @@ class CommonUtils : public QWidget {
*
* @return CommonUtils*
*/
- static CommonUtils* GetInstance();
+ static auto GetInstance() -> CommonUtils*;
/**
* @brief
@@ -214,14 +214,21 @@ class CommonUtils : public QWidget {
*/
void SignalRestartApplication(int);
+ /**
+ * @brief
+ *
+ */
+ void SignalFavoritesChanged();
+
public slots:
+
/**
* @brief
*
* @param parent
* @param in_buffer
*/
- void SlotImportKeys(QWidget* parent, const QString& in_buffer);
+ void SlotImportKeys(QWidget* parent, const QByteArray& in_buffer);
/**
* @brief
diff --git a/src/ui/dialog/GeneralDialog.cpp b/src/ui/dialog/GeneralDialog.cpp
index 2015322f..91ede794 100644
--- a/src/ui/dialog/GeneralDialog.cpp
+++ b/src/ui/dialog/GeneralDialog.cpp
@@ -52,21 +52,14 @@ void GpgFrontend::UI::GeneralDialog::slot_restore_settings() noexcept {
if (window_state.window_save) {
int x = window_state.x;
int y = window_state.y;
- GF_UI_LOG_DEBUG("stored dialog pos, x: {}, y: {}", x, y);
QPoint relative_pos = {x, y};
QPoint pos = parent_rect_.topLeft() + relative_pos;
- GF_UI_LOG_DEBUG("relative dialog pos, x: {}, y: {}", relative_pos.x(),
- relative_pos.y());
int width = window_state.width;
int height = window_state.height;
- GF_UI_LOG_DEBUG("stored dialog size, width: {}, height: {}", width,
- height);
QRect target_rect = {pos.x(), pos.y(), width, height};
- GF_UI_LOG_DEBUG("dialog stored target rect, width: {}, height: {}", width,
- height);
// check for valid
if (width > 0 && height > 0 && screen_rect_.contains(target_rect)) {
@@ -76,7 +69,7 @@ void GpgFrontend::UI::GeneralDialog::slot_restore_settings() noexcept {
}
} catch (...) {
- GF_UI_LOG_ERROR("error at restoring settings");
+ qCWarning(ui, "error at restoring settings");
}
}
@@ -86,14 +79,8 @@ void GpgFrontend::UI::GeneralDialog::slot_save_settings() noexcept {
update_rect_cache();
- GF_UI_LOG_DEBUG("dialog pos, x: {}, y: {}", rect_.x(), rect_.y());
- GF_UI_LOG_DEBUG("dialog size, width: {}, height: {}", rect_.width(),
- rect_.height());
-
// window position relative to parent
auto relative_pos = rect_.topLeft() - parent_rect_.topLeft();
- GF_UI_LOG_DEBUG("store dialog pos, x: {}, y: {}", relative_pos.x(),
- relative_pos.y());
WindowStateSO window_state;
window_state.x = relative_pos.x();
@@ -105,18 +92,13 @@ void GpgFrontend::UI::GeneralDialog::slot_save_settings() noexcept {
general_windows_state.Store(window_state.Json());
} catch (...) {
- GF_UI_LOG_ERROR("general dialog: {}, caught exception", name_);
+ qCWarning(ui) << "general dialog: " << name_ << ", caught exception";
}
}
void GpgFrontend::UI::GeneralDialog::setPosCenterOfScreen() {
update_rect_cache();
- int screen_width = screen_rect_.width();
- int screen_height = screen_rect_.height();
- GF_UI_LOG_DEBUG("dialog current screen available geometry", screen_width,
- screen_height);
-
// update rect of current dialog
rect_ = this->geometry();
this->move(screen_rect_.center() -
@@ -131,16 +113,6 @@ void GpgFrontend::UI::GeneralDialog::movePosition2CenterOfParent() {
// update cache
update_rect_cache();
- // log for debug
- GF_UI_LOG_DEBUG("parent pos x: {} y: {}", parent_rect_.x(), parent_rect_.y());
- GF_UI_LOG_DEBUG("parent size width: {}, height: {}", parent_rect_.width(),
- parent_rect_.height());
- GF_UI_LOG_DEBUG("parent center pos x: {}, y: {}", parent_rect_.center().x(),
- parent_rect_.center().y());
- GF_UI_LOG_DEBUG("dialog pos x: {} y: {}", rect_.x(), rect_.y());
- GF_UI_LOG_DEBUG("dialog size width: {} height: {}", rect_.width(),
- rect_.height());
-
if (parent_rect_.topLeft() != QPoint{0, 0} &&
parent_rect_.size() != QSize{0, 0}) {
if (rect_.width() <= 0) rect_.setWidth(100);
@@ -149,10 +121,6 @@ void GpgFrontend::UI::GeneralDialog::movePosition2CenterOfParent() {
QPoint target_position =
parent_rect_.center() - QPoint(rect_.width() / 2, rect_.height() / 2);
- GF_UI_LOG_DEBUG(
- "update position to parent's center, target pos, x:{}, y: {}",
- target_position.x(), target_position.y());
-
this->move(target_position);
} else {
setPosCenterOfScreen();
@@ -207,9 +175,6 @@ auto GpgFrontend::UI::GeneralDialog::isRectRestored() -> bool {
*
*/
void GpgFrontend::UI::GeneralDialog::showEvent(QShowEvent *event) {
- GF_UI_LOG_DEBUG("General Dialog named {} is about to show, caught show event",
- name_);
-
// default position strategy
if (!isRectRestored()) movePosition2CenterOfParent();
diff --git a/src/ui/dialog/SignersPicker.cpp b/src/ui/dialog/SignersPicker.cpp
index 9c342cc7..7152bc6e 100644
--- a/src/ui/dialog/SignersPicker.cpp
+++ b/src/ui/dialog/SignersPicker.cpp
@@ -44,22 +44,23 @@ SignersPicker::SignersPicker(QWidget* parent)
connect(cancel_button, &QPushButton::clicked, this, &QDialog::reject);
/*Setup KeyList*/
- key_list_ = new KeyList(0U, this);
- key_list_->AddListGroupTab(
- tr("Signers"), "signers", KeyListRow::ONLY_SECRET_KEY,
- KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage,
- [](const GpgKey& key, const KeyTable&) -> bool {
- return key.IsHasActualSigningCapability();
- });
+ key_list_ =
+ new KeyList(KeyMenuAbility::kCOLUMN_FILTER | KeyMenuAbility::kSEARCH_BAR,
+ GpgKeyTableColumn::kNAME | GpgKeyTableColumn::kEMAIL_ADDRESS |
+ GpgKeyTableColumn::kKEY_ID | GpgKeyTableColumn::kUSAGE,
+ this);
+ key_list_->AddListGroupTab(tr("Signers"), "signers",
+ GpgKeyTableDisplayMode::kPRIVATE_KEY,
+ [](const GpgKey& key) -> bool {
+ return key.IsHasActualSigningCapability();
+ });
key_list_->SlotRefresh();
auto* vbox2 = new QVBoxLayout();
vbox2->addWidget(new QLabel(tr("Select Signer(s)") + ": "));
vbox2->addWidget(key_list_);
vbox2->addWidget(new QLabel(
- QString(
- tr("Please select one or more private keys you use for signing.")) +
- "\n" +
+ tr("Please select one or more private keys you use for signing.") + "\n" +
tr("If no key is selected, the default key will be used for signing.")));
vbox2->addWidget(confirm_button);
vbox2->addWidget(cancel_button);
diff --git a/src/ui/dialog/Wizard.cpp b/src/ui/dialog/Wizard.cpp
index e65366dd..cb43c966 100644
--- a/src/ui/dialog/Wizard.cpp
+++ b/src/ui/dialog/Wizard.cpp
@@ -60,7 +60,7 @@ void Wizard::slot_wizard_accepted() {
auto settings = GlobalSettingStation::GetInstance().GetSettings();
settings.setValue("wizard/show_wizard", false);
} catch (...) {
- GF_UI_LOG_ERROR("setting operation error");
+ qCWarning(ui, "setting operation error");
}
if (field("openHelp").toBool()) {
emit SignalOpenHelp("docu.html#content");
diff --git a/src/ui/dialog/controller/GnuPGControllerDialog.cpp b/src/ui/dialog/controller/GnuPGControllerDialog.cpp
index 1874e255..b09b7280 100644
--- a/src/ui/dialog/controller/GnuPGControllerDialog.cpp
+++ b/src/ui/dialog/controller/GnuPGControllerDialog.cpp
@@ -100,9 +100,6 @@ GnuPGControllerDialog::GnuPGControllerDialog(QWidget* parent)
this, tr("Open Directory"), {},
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
- GF_UI_LOG_DEBUG("key database path selected: {}",
- selected_custom_key_database_path);
-
custom_key_database_path_ = selected_custom_key_database_path;
// announce the restart
@@ -120,9 +117,6 @@ GnuPGControllerDialog::GnuPGControllerDialog(QWidget* parent)
this, tr("Open Directory"), {},
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
- GF_UI_LOG_DEBUG("gnupg install path selected: {}",
- selected_custom_gnupg_install_path);
-
custom_gnupg_path_ = selected_custom_gnupg_install_path;
// announce the restart
@@ -177,8 +171,6 @@ GnuPGControllerDialog::GnuPGControllerDialog(QWidget* parent)
void GnuPGControllerDialog::SlotAccept() {
apply_settings();
- GF_UI_LOG_DEBUG("gnupg controller apply done");
- GF_UI_LOG_DEBUG("restart needed: {}", get_restart_needed());
if (get_restart_needed() != 0) {
emit SignalRestartNeeded(get_restart_needed());
}
@@ -198,8 +190,6 @@ void GnuPGControllerDialog::slot_update_custom_key_database_path_label(
.GetSettings()
.value("gnupg/custom_key_database_path")
.toString();
- GF_UI_LOG_DEBUG("selected_custom_key_database_path from settings: {}",
- custom_key_database_path);
custom_key_database_path_ = custom_key_database_path;
}
@@ -217,7 +207,6 @@ void GnuPGControllerDialog::slot_update_custom_key_database_path_label(
if (ui_->currentKeyDatabasePathLabel->text().isEmpty()) {
const auto database_path = Module::RetrieveRTValueTypedOrDefault<>(
"core", "gpgme.ctx.database_path", QString{});
- GF_UI_LOG_DEBUG("got gpgme.ctx.database_path from rt: {}", database_path);
ui_->currentKeyDatabasePathLabel->setText(database_path);
}
}
@@ -236,8 +225,6 @@ void GnuPGControllerDialog::slot_update_custom_gnupg_install_path_label(
.GetSettings()
.value("gnupg/custom_gnupg_install_path")
.toString();
- GF_UI_LOG_DEBUG("custom_gnupg_install_path from settings: {}",
- custom_gnupg_install_path);
custom_gnupg_path_ = custom_gnupg_install_path;
}
@@ -256,7 +243,6 @@ void GnuPGControllerDialog::slot_update_custom_gnupg_install_path_label(
if (ui_->currentCustomGnuPGInstallPathLabel->text().isEmpty()) {
const auto gnupg_path = Module::RetrieveRTValueTypedOrDefault<>(
"core", "gpgme.ctx.app_path", QString{});
- GF_UI_LOG_DEBUG("got gnupg home path from rt: {}", gnupg_path);
auto dir = QFileInfo(gnupg_path).path();
ui_->currentCustomGnuPGInstallPathLabel->setText(dir);
}
@@ -351,7 +337,6 @@ auto GnuPGControllerDialog::get_restart_needed() const -> int {
}
void GnuPGControllerDialog::slot_set_restart_needed(int mode) {
- GF_UI_LOG_INFO("announce restart needed, mode: {}", mode);
this->restart_mode_ = mode;
}
diff --git a/src/ui/dialog/controller/ModuleControllerDialog.cpp b/src/ui/dialog/controller/ModuleControllerDialog.cpp
index 4c727b48..e7c0d5fe 100644
--- a/src/ui/dialog/controller/ModuleControllerDialog.cpp
+++ b/src/ui/dialog/controller/ModuleControllerDialog.cpp
@@ -62,14 +62,14 @@ ModuleControllerDialog::ModuleControllerDialog(QWidget* parent)
connect(ui_->moduleListView, &ModuleListView::SignalSelectModule, this,
&ModuleControllerDialog::slot_load_module_details);
- connect(ui_->activateOrDeactiveButton, &QPushButton::clicked, this, [=]() {
+ connect(ui_->activateOrDeactivateButton, &QPushButton::clicked, this, [=]() {
auto module_id = ui_->moduleListView->GetCurrentModuleID();
if (module_id.isEmpty()) return;
if (!module_manager_->IsModuleActivated(module_id)) {
module_manager_->ActiveModule(module_id);
} else {
- module_manager_->DeactiveModule(module_id);
+ module_manager_->DeactivateModule(module_id);
}
QTimer::singleShot(1000, [=]() { slot_load_module_details(module_id); });
@@ -93,19 +93,32 @@ ModuleControllerDialog::ModuleControllerDialog(QWidget* parent)
Module::TriggerEvent(event_id);
});
+ connect(ui_->pushButton_4, &QPushButton::clicked, this, []() {
+
+ });
+
connect(ui_->showModsDirButton, &QPushButton::clicked, this, [=]() {
QDesktopServices::openUrl(QUrl::fromLocalFile(
GlobalSettingStation::GetInstance().GetModulesDir()));
});
#ifdef RELEASE
- ui_->tabWidget->setTabEnabled(2, false);
+ ui_->tabWidget->setTabVisible(2, false);
#endif
+
+ // give user ability to give up all modules
+ auto disable_loading_all_modules =
+ GlobalSettingStation::GetInstance()
+ .GetSettings()
+ .value("basic/disable_loading_all_modules", false)
+ .toBool();
+ if (disable_loading_all_modules) {
+ ui_->tabWidget->setTabEnabled(0, false);
+ }
}
void ModuleControllerDialog::slot_load_module_details(
Module::ModuleIdentifier module_id) {
- GF_UI_LOG_DEBUG("loading module details, module id: {}", module_id);
auto module = module_manager_->SearchModule(module_id);
SettingsObject so(QString("module.%1.so").arg(module_id));
ModuleSO module_so(so);
@@ -122,8 +135,6 @@ void ModuleControllerDialog::slot_load_module_details(
module_so.module_id = module_id;
module_so.module_hash = module->GetModuleHash();
module_so.auto_activate = false;
- GF_UI_LOG_DEBUG("reseting module settings object, module id: {}",
- module_id);
so.Store(module_so.ToJson());
}
@@ -177,8 +188,8 @@ void ModuleControllerDialog::slot_load_module_details(
}
ui_->moduleInfoTextBrowser->setText(buffer);
- ui_->activateOrDeactiveButton->setText(if_activated ? tr("Deactivate")
- : tr("Activate"));
+ ui_->activateOrDeactivateButton->setText(if_activated ? tr("Deactivate")
+ : tr("Activate"));
ui_->autoActivateButton->setText(module_so.auto_activate
? tr("Disable Auto Activate")
: tr("Enable Auto Activate"));
diff --git a/src/ui/dialog/help/AboutDialog.cpp b/src/ui/dialog/help/AboutDialog.cpp
index 0735ddba..14cb76ad 100644
--- a/src/ui/dialog/help/AboutDialog.cpp
+++ b/src/ui/dialog/help/AboutDialog.cpp
@@ -32,7 +32,7 @@
#include "core/module/ModuleManager.h"
#include "core/utils/BuildInfoUtils.h"
-#include "ui/dialog/help/GnupgTab.h"
+#include "ui/UIModuleManager.h"
namespace GpgFrontend::UI {
@@ -46,20 +46,18 @@ AboutDialog::AboutDialog(const QString& default_tab_name, QWidget* parent)
tab_widget->addTab(info_tab, tr("About GpgFrontend"));
- if (Module::IsModuleActivate(kGnuPGInfoGatheringModuleID)) {
- auto* gnupg_tab = new GnupgTab();
- tab_widget->addTab(gnupg_tab, tr("GnuPG"));
- }
-
tab_widget->addTab(translators_tab, tr("Translators"));
- if (Module::IsModuleActivate(kVersionCheckingModuleID)) {
- auto* update_tab = new UpdateTab();
- tab_widget->addTab(update_tab, tr("Update"));
- }
+ auto entries =
+ UIModuleManager::GetInstance().QueryMountedEntries("AboutDialogTabs");
- connect(tab_widget, &QTabWidget::currentChanged, this,
- [&](int index) { GF_UI_LOG_DEBUG("current index: {}", index); });
+ for (const auto& entry : entries) {
+ auto* widget = entry.GetWidget();
+ if (widget != nullptr) {
+ tab_widget->addTab(widget,
+ entry.GetMetaDataByDefault("TabTitle", tr("Unnamed")));
+ }
+ }
int default_index = 0;
for (int i = 0; i < tab_widget->count(); i++) {
@@ -90,15 +88,14 @@ void AboutDialog::showEvent(QShowEvent* ev) { QDialog::showEvent(ev); }
InfoTab::InfoTab(QWidget* parent) : QWidget(parent) {
const auto gpgme_version = Module::RetrieveRTValueTypedOrDefault<>(
"core", "gpgme.version", QString{"2.0.0"});
- GF_UI_LOG_DEBUG("got gpgme version from rt: {}", gpgme_version);
auto pixmap = QPixmap(":/icons/gpgfrontend_logo.png");
pixmap = pixmap.scaled(128, 128);
auto text =
"<center><h2>" + qApp->applicationName() + "</h2></center>" +
- "<center><b>" + "v" + qApp->applicationVersion() + "</b></center>" +
- "<center>" + GetProjectBuildGitVersion() + "</center>" + "<br><center>" +
+ "<center><b>" + GetProjectVersion() + "</b></center>" + "<center>" +
+ GetProjectBuildGitVersion() + "</center>" + "<br><center>" +
tr("GpgFrontend is an easy-to-use, compact, cross-platform, "
"and installation-free GnuPG Frontend."
"It visualizes most of the common operations of GnuPG."
@@ -152,137 +149,4 @@ TranslatorsTab::TranslatorsTab(QWidget* parent) : QWidget(parent) {
setLayout(main_layout);
}
-UpdateTab::UpdateTab(QWidget* parent) : QWidget(parent) {
- auto* layout = new QGridLayout();
-
- current_version_ = GetProjectVersion();
-
- auto* tips_label = new QLabel();
- tips_label->setText(
- "<center>" +
- tr("It is recommended that you always check the version "
- "of GpgFrontend and upgrade to the latest version.") +
- "</center><center>" +
- tr("New versions not only represent new features, but "
- "also often represent functional and security fixes.") +
- "</center>");
- tips_label->setWordWrap(true);
-
- current_version_label_ = new QLabel();
- current_version_label_->setText("<center>" + tr("Current Version") +
- tr(": ") + "<b>" + current_version_ +
- "</b></center>");
- current_version_label_->setWordWrap(true);
-
- latest_version_label_ = new QLabel();
- latest_version_label_->setWordWrap(true);
-
- upgrade_label_ = new QLabel();
- upgrade_label_->setWordWrap(true);
- upgrade_label_->setOpenExternalLinks(true);
- upgrade_label_->setHidden(true);
-
- pb_ = new QProgressBar();
- pb_->setRange(0, 0);
- pb_->setTextVisible(false);
-
- layout->addWidget(tips_label, 1, 0, 1, -1);
- layout->addWidget(current_version_label_, 2, 0, 1, -1);
- layout->addWidget(latest_version_label_, 3, 0, 1, -1);
- layout->addWidget(upgrade_label_, 4, 0, 1, -1);
- layout->addWidget(pb_, 5, 0, 1, -1);
- layout->addItem(
- new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Fixed), 2, 1,
- 1, 1);
-
- setLayout(layout);
-}
-
-void UpdateTab::showEvent(QShowEvent* event) {
- QWidget::showEvent(event);
- GF_UI_LOG_DEBUG("loading version loading info from rt");
-
- auto is_loading_done = Module::RetrieveRTValueTypedOrDefault<>(
- kVersionCheckingModuleID, "version.loading_done", false);
-
- if (!is_loading_done) {
- Module::ListenRTPublishEvent(
- this, kVersionCheckingModuleID, "version.loading_done",
- [=](Module::Namespace, Module::Key, int, std::any) {
- GF_UI_LOG_DEBUG(
- "version_checking module version.loading_done changed, calling "
- "slot version upgrade");
- this->slot_show_version_status();
- });
- Module::TriggerEvent("CHECK_APPLICATION_VERSION");
- } else {
- slot_show_version_status();
- }
-}
-
-void UpdateTab::slot_show_version_status() {
- GF_UI_LOG_DEBUG("loading version info from rt");
- this->pb_->setHidden(true);
-
- auto is_loading_done = Module::RetrieveRTValueTypedOrDefault<>(
- kVersionCheckingModuleID, "version.loading_done", false);
-
- if (!is_loading_done) {
- GF_UI_LOG_DEBUG("version info loading haven't been done yet.");
- return;
- }
-
- auto is_need_upgrade = Module::RetrieveRTValueTypedOrDefault<>(
- kVersionCheckingModuleID, "version.need_upgrade", false);
-
- auto is_current_a_withdrawn_version = Module::RetrieveRTValueTypedOrDefault<>(
- kVersionCheckingModuleID, "version.current_a_withdrawn_version", false);
-
- auto is_current_version_released = Module::RetrieveRTValueTypedOrDefault<>(
- kVersionCheckingModuleID, "version.current_version_released", false);
-
- auto latest_version = Module::RetrieveRTValueTypedOrDefault<>(
- kVersionCheckingModuleID, "version.latest_version", QString{});
-
- latest_version_label_->setText("<center><b>" +
- tr("Latest Version From Github") + ": " +
- latest_version + "</b></center>");
-
- if (is_need_upgrade) {
- upgrade_label_->setText(
- "<center>" +
- tr("The current version is less than the latest version on "
- "github.") +
- "</center><center>" + tr("Please click") +
- " <a "
- "href=\"https://www.gpgfrontend.bktus.com/#/downloads\">" +
- tr("Here") + "</a> " + tr("to download the latest stable version.") +
- "</center>");
- upgrade_label_->show();
- } else if (is_current_a_withdrawn_version) {
- upgrade_label_->setText(
- "<center>" +
- tr("This version has serious problems and has been withdrawn. "
- "Please stop using it immediately.") +
- "</center><center>" + tr("Please click") +
- " <a "
- "href=\"https://github.com/saturneric/GpgFrontend/releases\">" +
- tr("Here") + "</a> " + tr("to download the latest stable version.") +
- "</center>");
- upgrade_label_->show();
- } else if (!is_current_version_released) {
- upgrade_label_->setText(
- "<center>" +
- tr("This version has not been released yet, it may be a beta "
- "version. If you are not a tester and care about version "
- "stability, please do not use this version.") +
- "</center><center>" + tr("Please click") +
- " <a "
- "href=\"https://www.gpgfrontend.bktus.com/#/downloads\">" +
- tr("Here") + "</a> " + tr("to download the latest stable version.") +
- "</center>");
- upgrade_label_->show();
- }
-}
-
} // namespace GpgFrontend::UI
diff --git a/src/ui/dialog/help/AboutDialog.h b/src/ui/dialog/help/AboutDialog.h
index 6d152afb..0b9ca5ae 100644
--- a/src/ui/dialog/help/AboutDialog.h
+++ b/src/ui/dialog/help/AboutDialog.h
@@ -66,47 +66,6 @@ class TranslatorsTab : public QWidget {
};
/**
- * @brief Class containing the main tab of about dialog
- *
- */
-class UpdateTab : public QWidget {
- Q_OBJECT
-
- QLabel* current_version_label_; ///<
- QLabel* latest_version_label_; ///<
- QLabel* upgrade_label_; ///<
- QProgressBar* pb_; ///<
- QString current_version_; ///<
-
- public:
- /**
- * @brief Construct a new Update Tab object
- *
- * @param parent
- */
- explicit UpdateTab(QWidget* parent = nullptr);
-
- protected:
- void showEvent(QShowEvent* event) override;
-
- private slots:
- /**
- * @brief
- *
- * @param version
- */
- void slot_show_version_status();
-
- signals:
- /**
- * @brief
- *
- * @param data
- */
- void SignalReplyFromUpdateServer(QByteArray data);
-};
-
-/**
* @brief Class for handling the about dialog
*
*/
diff --git a/src/ui/dialog/help/GnupgTab.cpp b/src/ui/dialog/help/GnupgTab.cpp
deleted file mode 100644
index ac018def..00000000
--- a/src/ui/dialog/help/GnupgTab.cpp
+++ /dev/null
@@ -1,336 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric <[email protected]>
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend 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.
- *
- * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric <[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-//
-// Created by eric on 2022/7/23.
-//
-
-#include "GnupgTab.h"
-
-#include "core/module/ModuleManager.h"
-#include "ui_GnuPGInfo.h"
-
-namespace GpgFrontend::UI {
-
-GnupgTab::GnupgTab(QWidget* parent)
- : QWidget(parent),
- ui_(GpgFrontend::SecureCreateSharedObject<Ui_GnuPGInfo>()) {
- ui_->setupUi(this);
-
- QStringList components_column_titles;
- components_column_titles << tr("Name") << tr("Description") << tr("Version")
- << tr("Checksum") << tr("Binary Path");
-
- ui_->tabWidget->setTabText(0, tr("Components"));
- ui_->tabWidget->setTabText(1, tr("Directories"));
- ui_->tabWidget->setTabText(2, tr("Options"));
-
- ui_->componentDetailsTable->setColumnCount(components_column_titles.length());
- ui_->componentDetailsTable->setHorizontalHeaderLabels(
- components_column_titles);
- ui_->componentDetailsTable->horizontalHeader()->setStretchLastSection(false);
- ui_->componentDetailsTable->setSelectionBehavior(
- QAbstractItemView::SelectRows);
-
- // table items not editable
- ui_->componentDetailsTable->setEditTriggers(
- QAbstractItemView::NoEditTriggers);
-
- // no focus (rectangle around table items)
- // may be it should focus on whole row
- ui_->componentDetailsTable->setFocusPolicy(Qt::NoFocus);
- ui_->componentDetailsTable->setAlternatingRowColors(true);
-
- QStringList directories_column_titles;
- directories_column_titles << tr("Directory Type") << tr("Path");
-
- ui_->directoriesDetailsTable->setColumnCount(
- static_cast<int>(directories_column_titles.length()));
- ui_->directoriesDetailsTable->setHorizontalHeaderLabels(
- directories_column_titles);
- ui_->directoriesDetailsTable->horizontalHeader()->setStretchLastSection(
- false);
- ui_->directoriesDetailsTable->setSelectionBehavior(
- QAbstractItemView::SelectRows);
-
- // table items not editable
- ui_->directoriesDetailsTable->setEditTriggers(
- QAbstractItemView::NoEditTriggers);
-
- // no focus (rectangle around table items)
- // may be it should focus on whole row
- ui_->directoriesDetailsTable->setFocusPolicy(Qt::NoFocus);
- ui_->directoriesDetailsTable->setAlternatingRowColors(true);
-
- QStringList options_column_titles;
- options_column_titles << tr("Component") << tr("Group") << tr("Key")
- << tr("Description") << tr("Default Value")
- << tr("Value");
-
- ui_->optionDetailsTable->setColumnCount(options_column_titles.length());
- ui_->optionDetailsTable->setHorizontalHeaderLabels(options_column_titles);
- ui_->optionDetailsTable->horizontalHeader()->setStretchLastSection(false);
- ui_->optionDetailsTable->setSelectionBehavior(QAbstractItemView::SelectRows);
-
- // table items not editable
- ui_->optionDetailsTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
-
- // no focus (rectangle around table items)
- // may be it should focus on whole row
- ui_->optionDetailsTable->setFocusPolicy(Qt::NoFocus);
- ui_->optionDetailsTable->setAlternatingRowColors(true);
-
- if (Module::RetrieveRTValueTypedOrDefault(
- "ui", "env.state.gnupg_info_gathering", 0) == 1) {
- process_software_info();
- } else {
- gather_gnupg_info();
- }
-}
-
-void GnupgTab::process_software_info() {
- const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
- "core", "gpgme.ctx.gnupg_version", QString{"2.0.0"});
- GF_UI_LOG_DEBUG("got gnupg version from rt: {}", gnupg_version);
-
- ui_->gnupgVersionLabel->setText(
- QString::fromStdString(fmt::format("Version: {}", gnupg_version)));
-
- auto components =
- Module::ListRTChildKeys(kGnuPGInfoGatheringModuleID, "gnupg.components");
- GF_UI_LOG_DEBUG("got gnupg components from rt, size: {}", components.size());
-
- ui_->componentDetailsTable->setRowCount(components.size());
-
- int row = 0;
- for (auto& component : components) {
- auto component_info_json_bytes = Module::RetrieveRTValueTypedOrDefault(
- kGnuPGInfoGatheringModuleID,
- QString("gnupg.components.%1").arg(component), QString{});
- GF_UI_LOG_DEBUG("got gnupg component {} info from rt", component);
-
- auto component_info_json =
- QJsonDocument::fromJson(component_info_json_bytes.toUtf8());
- if (!component_info_json.isObject()) {
- GF_UI_LOG_WARN("illegal gnupg component info, json: {}",
- QString(component_info_json_bytes));
- continue;
- }
-
- auto component_info = component_info_json.object();
- if (!component_info.contains("name")) {
- GF_UI_LOG_WARN(
- "illegal gnupg component info. it doesn't have a name, json: {}",
- QString(component_info_json_bytes));
- continue;
- }
-
- auto* tmp0 = new QTableWidgetItem(component_info["name"].toString());
- tmp0->setTextAlignment(Qt::AlignCenter);
- ui_->componentDetailsTable->setItem(row, 0, tmp0);
-
- auto* tmp1 = new QTableWidgetItem(component_info["desc"].toString());
- tmp1->setTextAlignment(Qt::AlignCenter);
- ui_->componentDetailsTable->setItem(row, 1, tmp1);
-
- auto* tmp2 = new QTableWidgetItem(component_info["version"].toString());
- tmp2->setTextAlignment(Qt::AlignCenter);
- ui_->componentDetailsTable->setItem(row, 2, tmp2);
-
- auto* tmp3 =
- new QTableWidgetItem(component_info["binary_checksum"].toString());
- tmp3->setTextAlignment(Qt::AlignCenter);
- ui_->componentDetailsTable->setItem(row, 3, tmp3);
-
- auto* tmp4 = new QTableWidgetItem(component_info["path"].toString());
- tmp4->setTextAlignment(Qt::AlignLeft);
- ui_->componentDetailsTable->setItem(row, 4, tmp4);
-
- row++;
- }
-
- ui_->componentDetailsTable->resizeColumnsToContents();
-
- auto directories = Module::ListRTChildKeys(kGnuPGInfoGatheringModuleID,
- QString("gnupg.dirs"));
-
- ui_->directoriesDetailsTable->setRowCount(
- static_cast<int>(directories.size()));
-
- row = 0;
- for (auto& dir : directories) {
- const auto dir_path = Module::RetrieveRTValueTypedOrDefault(
- kGnuPGInfoGatheringModuleID, QString("gnupg.dirs.%1").arg(dir),
- QString{});
-
- if (dir_path.isEmpty()) continue;
-
- auto* tmp0 = new QTableWidgetItem(dir);
- tmp0->setTextAlignment(Qt::AlignCenter);
- ui_->directoriesDetailsTable->setItem(row, 0, tmp0);
-
- auto* tmp1 = new QTableWidgetItem(dir_path);
- tmp1->setTextAlignment(Qt::AlignCenter);
- ui_->directoriesDetailsTable->setItem(row, 1, tmp1);
-
- row++;
- }
-
- ui_->directoriesDetailsTable->resizeColumnsToContents();
-
- // calculate the total row number of configuration table
- row = 0;
- for (auto& component : components) {
- auto options = Module::ListRTChildKeys(
- kGnuPGInfoGatheringModuleID,
- QString("gnupg.components.%1.options").arg(component));
- for (auto& option : options) {
- const auto option_info_json =
- QJsonDocument::fromJson(Module::RetrieveRTValueTypedOrDefault(
- kGnuPGInfoGatheringModuleID,
- QString("gnupg.components.%1.options.%2")
- .arg(component)
- .arg(option),
- QString{})
- .toUtf8());
-
- if (!option_info_json.isObject()) continue;
-
- auto option_info = option_info_json.object();
- if (!option_info.contains("name") || option_info["flags"] == "1") {
- continue;
- }
- row++;
- }
- }
-
- ui_->optionDetailsTable->setRowCount(row);
-
- row = 0;
- QString configuration_group;
- for (auto& component : components) {
- auto options = Module::ListRTChildKeys(
- kGnuPGInfoGatheringModuleID,
- QString("gnupg.components.%1.options").arg(component));
-
- for (auto& option : options) {
- auto option_info_json_bytes = Module::RetrieveRTValueTypedOrDefault(
- kGnuPGInfoGatheringModuleID,
- QString("gnupg.components.%1.options.%2").arg(component).arg(option),
- QString{});
- GF_UI_LOG_DEBUG("got gnupg component's option {} info from rt, info: {}",
- component, option_info_json_bytes);
-
- auto option_info_json =
- QJsonDocument::fromJson(option_info_json_bytes.toUtf8());
-
- if (!option_info_json.isObject()) {
- GF_UI_LOG_WARN("illegal gnupg option info, json: {}",
- QString(option_info_json_bytes));
- continue;
- }
-
- auto option_info = option_info_json.object();
- if (!option_info.contains("name")) {
- GF_UI_LOG_WARN(
- "illegal gnupg configuation info. it doesn't have a name, json: {}",
- QString(option_info_json_bytes));
- continue;
- }
-
- if (option_info["flags"] == "1") {
- configuration_group = option_info["name"].toString();
- continue;
- }
-
- auto* tmp0 = new QTableWidgetItem(component);
- tmp0->setTextAlignment(Qt::AlignCenter);
- ui_->optionDetailsTable->setItem(row, 0, tmp0);
-
- auto* tmp1 = new QTableWidgetItem(configuration_group);
- tmp1->setTextAlignment(Qt::AlignCenter);
- ui_->optionDetailsTable->setItem(row, 1, tmp1);
-
- auto* tmp2 = new QTableWidgetItem(option_info["name"].toString());
- tmp2->setTextAlignment(Qt::AlignCenter);
- ui_->optionDetailsTable->setItem(row, 2, tmp2);
-
- auto* tmp3 = new QTableWidgetItem(option_info["description"].toString());
-
- tmp3->setTextAlignment(Qt::AlignLeft);
- ui_->optionDetailsTable->setItem(row, 3, tmp3);
-
- auto* tmp4 =
- new QTableWidgetItem(option_info["default_value"].toString());
- tmp4->setTextAlignment(Qt::AlignLeft);
- ui_->optionDetailsTable->setItem(row, 4, tmp4);
-
- auto* tmp5 = new QTableWidgetItem(option_info["value"].toString());
- tmp5->setTextAlignment(Qt::AlignLeft);
- ui_->optionDetailsTable->setItem(row, 5, tmp5);
-
- row++;
- }
- }
-
- ui_->loadProgressBar->hide();
- ui_->tabWidget->setDisabled(false);
-}
-
-void GnupgTab::gather_gnupg_info() {
- // if gnupg_info_gathering module activated
- if (Module::IsModuleActivate(kGnuPGInfoGatheringModuleID)) {
- GF_CORE_LOG_DEBUG(
- "module gnupg_info_gathering is activated, "
- "loading external gnupg info...");
-
- ui_->loadProgressBar->show();
- ui_->tabWidget->setDisabled(true);
-
- // gather external gnupg info
- Module::TriggerEvent(
- "REQUEST_GATHERING_GNUPG_INFO",
- [=](const Module::EventIdentifier& /*e*/,
- const Module::Event::ListenerIdentifier& l_id, DataObjectPtr o) {
- GF_CORE_LOG_DEBUG(
- "received event REQUEST_GATHERING_GNUPG_INFO callback "
- "from module: {}",
- l_id);
-
- if (l_id == kGnuPGInfoGatheringModuleID) {
- Module::UpsertRTValue("ui", "env.state.gnupg_info_gathering", 1);
-
- // gnupg info gathering process finished
- GF_CORE_LOG_INFO("gnupg information gathering finished");
- process_software_info();
- }
- });
- }
-}
-
-} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/dialog/help/GnupgTab.h b/src/ui/dialog/help/GnupgTab.h
deleted file mode 100644
index 60abd048..00000000
--- a/src/ui/dialog/help/GnupgTab.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric <[email protected]>
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend 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.
- *
- * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric <[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-//
-// Created by eric on 2022/7/23.
-//
-
-#pragma once
-
-#include "core/function/gpg/GpgContext.h"
-#include "ui/GpgFrontendUI.h"
-
-class Ui_GnuPGInfo;
-namespace GpgFrontend::UI {
-class GnupgTab : public QWidget {
- Q_OBJECT
- public:
- /**
- * @brief Construct a new Info Tab object
- *
- * @param parent
- */
- explicit GnupgTab(QWidget* parent = nullptr);
-
- private:
- std::shared_ptr<Ui_GnuPGInfo> ui_; ///<
-
- /**
- * @brief
- *
- */
- void process_software_info();
-
- /**
- * @brief
- *
- */
- void gather_gnupg_info();
-};
-} // namespace GpgFrontend::UI
diff --git a/src/ui/dialog/import_export/KeyServerImportDialog.cpp b/src/ui/dialog/import_export/KeyServerImportDialog.cpp
index 575a97e4..af00549d 100644
--- a/src/ui/dialog/import_export/KeyServerImportDialog.cpp
+++ b/src/ui/dialog/import_export/KeyServerImportDialog.cpp
@@ -110,7 +110,7 @@ KeyServerImportDialog::KeyServerImportDialog(QWidget* parent)
main_layout->addLayout(buttons_layout, 6, 0, 1, 3);
this->setLayout(main_layout);
- this->setWindowTitle(tr("Import Keys from Keyserver"));
+ this->setWindowTitle(tr("Import Keys from key server"));
this->setModal(true);
movePosition2CenterOfParent();
@@ -132,7 +132,7 @@ auto KeyServerImportDialog::create_combo_box() -> QComboBox* {
}
combo_box->setCurrentText(key_server.GetTargetServer());
} catch (...) {
- GF_UI_LOG_ERROR("setting operation error", "server_list", "default_server");
+ qCWarning(ui, "setting operation error server_list default_server");
}
return combo_box;
@@ -208,16 +208,12 @@ void KeyServerImportDialog::slot_search() {
void KeyServerImportDialog::slot_search_finished(
QNetworkReply::NetworkError error, QByteArray buffer) {
- GF_UI_LOG_DEBUG("search result {} {}", error, buffer.size());
-
keys_table_->clearContents();
keys_table_->setRowCount(0);
auto stream = QTextStream(buffer);
if (error != QNetworkReply::NoError) {
- GF_UI_LOG_DEBUG("error from reply: {}", error);
-
switch (error) {
case QNetworkReply::ContentNotFoundError:
set_message(tr("Not Key Found"), true);
@@ -414,7 +410,6 @@ void KeyServerImportDialog::slot_import_finished(
set_loading(false);
if (!success) {
- GF_UI_LOG_ERROR("error from reply: {}", buffer);
set_message(err_msg, true);
return;
}
diff --git a/src/ui/dialog/import_export/KeyUploadDialog.cpp b/src/ui/dialog/import_export/KeyUploadDialog.cpp
index 7ab34c49..ed408bab 100644
--- a/src/ui/dialog/import_export/KeyUploadDialog.cpp
+++ b/src/ui/dialog/import_export/KeyUploadDialog.cpp
@@ -74,7 +74,7 @@ void KeyUploadDialog::SlotUpload() {
if (CheckGpgError(err) == GPG_ERR_USER_1 || data_obj == nullptr ||
!data_obj->Check<GFBuffer>()) {
- GF_CORE_LOG_ERROR("data object checking failed");
+ qCWarning(ui, "data object checking failed");
QMessageBox::critical(this, tr("Error"),
tr("Unknown error occurred"));
// Done
@@ -139,11 +139,9 @@ void KeyUploadDialog::slot_upload_finished() {
this->close();
QByteArray response = reply->readAll();
- GF_UI_LOG_DEBUG("upload response: {}", response);
auto error = reply->error();
if (error != QNetworkReply::NoError) {
- GF_UI_LOG_DEBUG("error from reply: {}", reply->errorString());
QString message;
switch (error) {
case QNetworkReply::ContentNotFoundError:
diff --git a/src/ui/dialog/key_generate/KeygenDialog.cpp b/src/ui/dialog/key_generate/KeygenDialog.cpp
index 7585d6f0..cbaebb13 100644
--- a/src/ui/dialog/key_generate/KeygenDialog.cpp
+++ b/src/ui/dialog/key_generate/KeygenDialog.cpp
@@ -257,16 +257,12 @@ void KeyGenDialog::slot_authentication_box_changed(int state) {
}
void KeyGenDialog::slot_activated_key_type(int index) {
- GF_UI_LOG_DEBUG("key type index changed: {}", index);
-
// check
assert(gen_key_info_->GetSupportedKeyAlgo().size() >
static_cast<size_t>(index));
const auto [name, key_algo, subkey_algo] =
gen_key_info_->GetSupportedKeyAlgo()[index];
- GF_UI_LOG_DEBUG("target key algo changed, name: {}, key: {}, subkey: {}",
- name, key_algo, subkey_algo);
assert(!key_algo.isEmpty());
gen_key_info_->SetAlgo(key_algo);
diff --git a/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp b/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp
index eecf2a1d..25da4291 100644
--- a/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp
+++ b/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp
@@ -305,7 +305,7 @@ void SubkeyGenerateDialog::slot_key_gen_accept() {
CommonUtils::RaiseMessageBox(this, err);
if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
emit UISignalStation::GetInstance()
- ->SignalKeyDatabaseRefresh();
+ -> SignalKeyDatabaseRefresh();
}
});
});
@@ -358,8 +358,6 @@ void SubkeyGenerateDialog::slot_authentication_box_changed(int state) {
}
void SubkeyGenerateDialog::slot_activated_key_type(int index) {
- GF_UI_LOG_DEBUG("key type index changed: {}", index);
-
// check
assert(gen_key_info_->GetSupportedSubkeyAlgo().size() >
static_cast<size_t>(index));
diff --git a/src/ui/dialog/keypair_details/KeyPairOperaTab.cpp b/src/ui/dialog/keypair_details/KeyPairOperaTab.cpp
index 74f827aa..08564bec 100644
--- a/src/ui/dialog/keypair_details/KeyPairOperaTab.cpp
+++ b/src/ui/dialog/keypair_details/KeyPairOperaTab.cpp
@@ -34,6 +34,7 @@
#include "core/function/gpg/GpgKeyImportExporter.h"
#include "core/function/gpg/GpgKeyOpera.h"
#include "core/model/GpgKey.h"
+#include "core/module/ModuleManager.h"
#include "core/typedef/GpgTypedef.h"
#include "core/utils/GpgUtils.h"
#include "core/utils/IOUtils.h"
@@ -96,6 +97,16 @@ KeyPairOperaTab::KeyPairOperaTab(const QString& key_id, QWidget* parent)
key_server_opera_button->setDisabled(forbid_all_gnupg_connection);
advance_h_box_layout->addWidget(key_server_opera_button);
+ if (Module::IsModuleActivate(kPaperKeyModuleID)) {
+ if (!m_key_.IsPrivateKey() || !m_key_.IsHasMasterKey()) {
+ auto* import_paper_key_button = new QPushButton(tr("Import A Paper Key"));
+ import_paper_key_button->setStyleSheet("text-align:center;");
+ connect(import_paper_key_button, &QPushButton::clicked, this,
+ &KeyPairOperaTab::slot_import_paper_key);
+ vbox_p_k->addWidget(import_paper_key_button);
+ }
+ }
+
if (m_key_.IsPrivateKey() && m_key_.IsHasMasterKey()) {
auto* revoke_cert_opera_button =
new QPushButton(tr("Revoke Certificate Operation"));
@@ -168,6 +179,17 @@ void KeyPairOperaTab::CreateOperaMenu() {
connect(export_shortest_secret_key, &QAction::triggered, this,
&KeyPairOperaTab::slot_export_short_private_key);
+ if (Module::IsModuleActivate(kPaperKeyModuleID)) {
+ auto* export_secret_key_as_paper_key =
+ new QAction(tr("Export Secret Key As A Paper Key"), this);
+ connect(export_secret_key_as_paper_key, &QAction::triggered, this,
+ &KeyPairOperaTab::slot_export_paper_key);
+ if (!m_key_.IsPrivateKey()) {
+ export_secret_key_as_paper_key->setDisabled(true);
+ }
+ secret_key_export_opera_menu_->addAction(export_secret_key_as_paper_key);
+ }
+
secret_key_export_opera_menu_->addAction(export_full_secret_key);
secret_key_export_opera_menu_->addAction(export_shortest_secret_key);
@@ -366,7 +388,6 @@ void KeyPairOperaTab::slot_modify_tofu_policy() {
this, tr("Modify TOFU Policy(Default is Auto)"),
tr("Policy for the Key Pair:"), items, 0, false, &ok);
if (ok && !item.isEmpty()) {
- GF_UI_LOG_DEBUG("selected policy: {}", item);
gpgme_tofu_policy_t tofu_policy = GPGME_TOFU_POLICY_AUTO;
if (item == tr("Policy Auto")) {
tofu_policy = GPGME_TOFU_POLICY_AUTO;
@@ -433,11 +454,115 @@ void KeyPairOperaTab::slot_import_revoke_cert() {
QFile rev_file(rev_file_info.absoluteFilePath());
-#ifdef QT5_BUILD
if (!rev_file.open(QIODevice::ReadOnly)) {
+ QMessageBox::critical(
+ this, tr("Error"),
+ tr("Cannot open this file. Please make sure that this "
+ "is a regular file and it's readable."));
+ return;
+ }
+
+ emit UISignalStation::GetInstance() -> SignalKeyRevoked(m_key_.GetId());
+ CommonUtils::GetInstance()->SlotImportKeys(nullptr, rev_file.readAll());
+}
+
+void KeyPairOperaTab::slot_export_paper_key() {
+ if (!Module::IsModuleActivate(kPaperKeyModuleID)) return;
+
+ int ret = QMessageBox::information(
+ this, tr("Exporting private key as a Paper key"),
+ "<h3>" + tr("You are about to export your") + "<font color=\"red\">" +
+ tr(" PRIVATE KEY ") + "</font>!</h3>\n" +
+ tr("This is NOT your Public Key, so DON'T give it away.") + "<br />" +
+ tr("A PaperKey is a human-readable printout of your private key, "
+ "which can be used to recover your key if you lose access to "
+ "your "
+ "digital copy. ") +
+ "<br />" + tr("Keep it in a safe place.") + "<br />" +
+ tr("Do you REALLY want to export your PRIVATE KEY?"),
+ QMessageBox::Cancel | QMessageBox::Ok);
+
+ // export key, if ok was clicked
+ if (ret == QMessageBox::Ok) {
+ auto [err, gf_buffer] = GpgKeyImportExporter::GetInstance().ExportKey(
+ m_key_, true, false, true);
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ CommonUtils::RaiseMessageBox(this, err);
+ return;
+ }
+
+ // generate a file name
+#ifndef WINDOWS
+ auto file_string = m_key_.GetName() + "<" + m_key_.GetEmail() + ">(" +
+ m_key_.GetId() + ")_paper_key.txt";
+#else
+ auto file_string = m_key_.GetName() + "[" + m_key_.GetEmail() + "](" +
+ m_key_.GetId() + ")_paper_key.txt";
+#endif
+ std::replace(file_string.begin(), file_string.end(), ' ', '_');
+
+ auto file_name = QFileDialog::getSaveFileName(
+ this, tr("Export Key To File"), file_string,
+ tr("Key Files") + " (*.txt);;All Files (*)");
+
+ if (file_name.isEmpty()) return;
+
+ Module::TriggerEvent(
+ "REQUEST_TRANS_KEY_2_PAPER_KEY",
+ {
+ {"secret_key", QString(gf_buffer.ConvertToQByteArray().toBase64())},
+ },
+ [this, file_name](Module::EventIdentifier i,
+ Module::Event::ListenerIdentifier ei,
+ Module::Event::Params p) {
+ qCDebug(ui) << "REQUEST_TRANS_KEY_2_PAPER_KEY callback: " << i << ei;
+
+ if (p["ret"] != "0" || p["paper_key"].isEmpty()) {
+ QMessageBox::critical(
+ this, tr("Error"),
+ tr("An error occurred trying to generate Paper Key."));
+ return;
+ }
+
+ if (!WriteFile(file_name, p["paper_key"].toLatin1())) {
+ QMessageBox::critical(
+ this, tr("Export Error"),
+ tr("Couldn't open %1 for writing").arg(file_name));
+ return;
+ }
+ });
+ }
+}
+
+void KeyPairOperaTab::slot_import_paper_key() {
+ if (!Module::IsModuleActivate(kPaperKeyModuleID)) return;
+
+ auto [err, gf_buffer] =
+ GpgKeyImportExporter::GetInstance().ExportKey(m_key_, false, false, true);
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ CommonUtils::RaiseMessageBox(this, err);
+ return;
+ }
+
+ // generate a file name
+#ifndef WINDOWS
+ auto file_string = m_key_.GetName() + "<" + m_key_.GetEmail() + ">(" +
+ m_key_.GetId() + ")_paper_key.txt";
#else
- if (!rev_file.open(QIODeviceBase::ReadOnly)) {
+ auto file_string = m_key_.GetName() + "[" + m_key_.GetEmail() + "](" +
+ m_key_.GetId() + ")_paper_key.txt";
#endif
+ std::replace(file_string.begin(), file_string.end(), ' ', '_');
+
+ auto file_name = QFileDialog::getOpenFileName(
+ this, tr("Import A Paper Key"), file_string,
+ tr("Paper Key File") + " (*.txt);;All Files (*)");
+
+ if (file_name.isEmpty()) return;
+
+ QFileInfo file_info(file_name);
+
+ if (!file_info.isFile() || !file_info.isReadable()) {
QMessageBox::critical(
this, tr("Error"),
tr("Cannot open this file. Please make sure that this "
@@ -445,7 +570,43 @@ void KeyPairOperaTab::slot_import_revoke_cert() {
return;
}
- emit UISignalStation::GetInstance()->SignalKeyRevoked(m_key_.GetId());
- CommonUtils::GetInstance()->SlotImportKeys(nullptr, rev_file.readAll());
+ if (file_info.size() > static_cast<qint64>(1024 * 1024)) {
+ QMessageBox::critical(
+ this, tr("Error"),
+ tr("The target file is too large for a paper key keyring."));
+ return;
+ }
+
+ auto [succ, gf_in_buff] = ReadFileGFBuffer(file_name);
+ if (!succ) {
+ QMessageBox::critical(
+ this, tr("Error"),
+ tr("Cannot open this file. Please make sure that this "
+ "is a regular file and it's readable."));
+ return;
+ }
+
+ Module::TriggerEvent(
+ "REQUEST_TRANS_PAPER_KEY_2_KEY",
+ {
+ {"public_key", QString(gf_buffer.ConvertToQByteArray().toBase64())},
+ {"paper_key_secrets",
+ QString(gf_in_buff.ConvertToQByteArray().toBase64())},
+ },
+ [this](Module::EventIdentifier i, Module::Event::ListenerIdentifier ei,
+ Module::Event::Params p) {
+ qCDebug(ui) << "REQUEST_TRANS_PAPER_KEY_2_KEY callback: " << i << ei;
+
+ if (p["ret"] != "0" || p["secret_key"].isEmpty()) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("An error occurred trying to recover the "
+ "Paper Key back to the private key."));
+ return;
+ }
+
+ CommonUtils::GetInstance()->SlotImportKeys(
+ this, QByteArray::fromBase64(p["secret_key"].toLatin1()));
+ });
}
+
} // namespace GpgFrontend::UI
diff --git a/src/ui/dialog/keypair_details/KeyPairOperaTab.h b/src/ui/dialog/keypair_details/KeyPairOperaTab.h
index 22c94957..27bc7400 100644
--- a/src/ui/dialog/keypair_details/KeyPairOperaTab.h
+++ b/src/ui/dialog/keypair_details/KeyPairOperaTab.h
@@ -126,6 +126,18 @@ class KeyPairOperaTab : public QWidget {
*/
void slot_import_revoke_cert();
+ /**
+ * @brief
+ *
+ */
+ void slot_export_paper_key();
+
+ /**
+ * @brief
+ *
+ */
+ void slot_import_paper_key();
+
private:
GpgKey m_key_; ///<
QMenu* key_server_opera_menu_{}; ///<
diff --git a/src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp b/src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp
index 2a9a4c96..1d463aad 100644
--- a/src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp
+++ b/src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp
@@ -175,9 +175,6 @@ void KeyPairSubkeyTab::slot_refresh_subkey_list() {
this->buffered_subkeys_.push_back(std::move(sub_key));
}
- GF_UI_LOG_DEBUG("buffered_subkeys_ refreshed size",
- this->buffered_subkeys_.size());
-
subkey_list_->setRowCount(buffered_subkeys_.size());
for (const auto& subkeys : buffered_subkeys_) {
@@ -211,12 +208,10 @@ void KeyPairSubkeyTab::slot_refresh_subkey_list() {
}
}
- GF_UI_LOG_DEBUG("subkey_list_ item {} refreshed", row);
-
row++;
}
- GF_UI_LOG_DEBUG("subkey_list_ refreshed");
+ qCDebug(ui, "subkey_list_ refreshed");
if (subkey_list_->rowCount() > 0) {
subkey_list_->selectRow(0);
@@ -309,8 +304,6 @@ void KeyPairSubkeyTab::create_subkey_opera_menu() {
}
void KeyPairSubkeyTab::slot_edit_subkey() {
- GF_UI_LOG_DEBUG("fpr {}", get_selected_subkey().GetFingerprint());
-
auto* dialog = new KeySetExpireDateDialog(
key_.GetId(), get_selected_subkey().GetFingerprint(), this);
dialog->show();
diff --git a/src/ui/dialog/keypair_details/KeyPairUIDTab.cpp b/src/ui/dialog/keypair_details/KeyPairUIDTab.cpp
index 47cae8c1..5b0a8271 100644
--- a/src/ui/dialog/keypair_details/KeyPairUIDTab.cpp
+++ b/src/ui/dialog/keypair_details/KeyPairUIDTab.cpp
@@ -228,7 +228,6 @@ void KeyPairUIDTab::slot_refresh_tofu_info() {
continue;
}
auto tofu_infos = uid.GetTofuInfos();
- GF_UI_LOG_DEBUG("tofu info size: {}", tofu_infos->size());
if (tofu_infos->empty()) {
tofu_tabs_->hide();
} else {
@@ -383,7 +382,6 @@ void KeyPairUIDTab::slot_del_uid() {
if (ret == QMessageBox::Yes) {
for (const auto& uid : *selected_uids) {
- GF_UI_LOG_DEBUG("uid: {}", uid);
if (!GpgUIDOperator::GetInstance().RevUID(m_key_, uid)) {
QMessageBox::critical(
nullptr, tr("Operation Failed"),
diff --git a/src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp b/src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp
index 43fb6f3b..9ab1350c 100644
--- a/src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp
+++ b/src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp
@@ -58,18 +58,10 @@ KeySetExpireDateDialog::KeySetExpireDateDialog(const KeyId& key_id,
}
void KeySetExpireDateDialog::slot_confirm() {
- GF_UI_LOG_DEBUG("confirm called, date: {}, time: {}",
- ui_->dateEdit->date().toString(),
- ui_->timeEdit->time().toString());
auto datetime = QDateTime(ui_->dateEdit->date(), ui_->timeEdit->time());
std::unique_ptr<QDateTime> expires = nullptr;
if (ui_->noExpirationCheckBox->checkState() == Qt::Unchecked) {
expires = std::make_unique<QDateTime>(datetime.toLocalTime());
-
- GF_UI_LOG_DEBUG("keyid: {}", m_key_.GetId(), m_subkey_,
- expires->toSecsSinceEpoch());
- } else {
- GF_UI_LOG_DEBUG("keyid: {}", m_key_.GetId(), m_subkey_, "Non Expired");
}
auto err = GpgKeyOpera::GetInstance().SetExpire(m_key_, m_subkey_, expires);
diff --git a/src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp b/src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp
index a56a7fc7..07c7b688 100644
--- a/src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp
+++ b/src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp
@@ -41,11 +41,14 @@ KeyUIDSignDialog::KeyUIDSignDialog(const GpgKey& key, UIDArgsListPtr uid,
m_uids_(std::move(uid)),
m_key_(key) {
const auto key_id = m_key_.GetId();
- m_key_list_ = new KeyList(KeyMenuAbility::NONE, this);
+ m_key_list_ =
+ new KeyList(KeyMenuAbility::kCOLUMN_FILTER | KeyMenuAbility::kSEARCH_BAR,
+ GpgKeyTableColumn::kNAME | GpgKeyTableColumn::kEMAIL_ADDRESS |
+ GpgKeyTableColumn::kKEY_ID,
+ this);
m_key_list_->AddListGroupTab(
- tr("Signers"), "signers", KeyListRow::ONLY_SECRET_KEY,
- KeyListColumn::NAME | KeyListColumn::EmailAddress,
- [key_id](const GpgKey& key, const KeyTable&) -> bool {
+ tr("Signers"), "signers", GpgKeyTableDisplayMode::kPRIVATE_KEY,
+ [key_id](const GpgKey& key) -> bool {
return !(key.IsDisabled() || !key.IsHasCertificationCapability() ||
!key.IsHasMasterKey() || key.IsExpired() || key.IsRevoked() ||
key_id == key.GetId());
@@ -101,13 +104,9 @@ void KeyUIDSignDialog::slot_sign_key(bool clicked) {
// Set Signers
auto key_ids = m_key_list_->GetChecked();
auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
-
- GF_UI_LOG_DEBUG("key info got");
auto expires = std::make_unique<QDateTime>(expires_edit_->dateTime());
- GF_UI_LOG_DEBUG("sign start");
for (const auto& uid : *m_uids_) {
- GF_UI_LOG_DEBUG("sign uid: {}", uid);
// Sign For mKey
if (!GpgKeyManager::GetInstance().SignKey(m_key_, *keys, uid, expires)) {
QMessageBox::critical(
diff --git a/src/ui/dialog/settings/SettingsAppearance.cpp b/src/ui/dialog/settings/SettingsAppearance.cpp
index f09f9823..6f9961c0 100644
--- a/src/ui/dialog/settings/SettingsAppearance.cpp
+++ b/src/ui/dialog/settings/SettingsAppearance.cpp
@@ -141,16 +141,9 @@ void AppearanceTab::SetSettings() {
auto target_theme_index = ui_->themeComboBox->findText(theme);
if (theme.isEmpty() || target_theme_index == -1) {
#ifdef QT5_BUILD
- GF_UI_LOG_DEBUG(
- "There is not valid theme found from settings, "
- "using current theme (qt5): {}",
- QApplication::style()->metaObject()->className());
ui_->themeComboBox->setCurrentIndex(ui_->themeComboBox->findText(
QApplication::style()->metaObject()->className()));
#else
- GF_UI_LOG_DEBUG(
- "There is not valid theme found from settings, using current theme: {}",
- QApplication::style()->name());
ui_->themeComboBox->setCurrentIndex(
ui_->themeComboBox->findText(QApplication::style()->name()));
#endif
diff --git a/src/ui/dialog/settings/SettingsDialog.cpp b/src/ui/dialog/settings/SettingsDialog.cpp
index 70b8c7b0..4d80ced2 100644
--- a/src/ui/dialog/settings/SettingsDialog.cpp
+++ b/src/ui/dialog/settings/SettingsDialog.cpp
@@ -89,7 +89,7 @@ SettingsDialog::SettingsDialog(QWidget* parent)
connect(this, &SettingsDialog::SignalRestartNeeded,
qobject_cast<MainWindow*>(parent), &MainWindow::SlotSetRestartNeeded);
- this->setMinimumSize(480, 680);
+ this->setMinimumWidth(500);
this->adjustSize();
this->show();
}
@@ -112,7 +112,6 @@ void SettingsDialog::SlotAccept() {
key_server_tab_->ApplySettings();
network_tab_->ApplySettings();
- GF_UI_LOG_DEBUG("ui restart status: {}", restart_mode_);
if (restart_mode_ != kNonRestartCode) {
emit SignalRestartNeeded(restart_mode_);
}
@@ -125,8 +124,6 @@ auto SettingsDialog::ListLanguages() -> QHash<QString, QString> {
auto filenames = QDir(QLatin1String(":/i18n")).entryList();
for (const auto& file : filenames) {
- GF_UI_LOG_DEBUG("get locale from locale directory: {}", file);
-
auto start = file.indexOf('.') + 1;
auto end = file.lastIndexOf('.');
if (start < 0 || end < 0 || start >= end) continue;
diff --git a/src/ui/dialog/settings/SettingsGeneral.cpp b/src/ui/dialog/settings/SettingsGeneral.cpp
index 9764b747..6167ea01 100644
--- a/src/ui/dialog/settings/SettingsGeneral.cpp
+++ b/src/ui/dialog/settings/SettingsGeneral.cpp
@@ -52,6 +52,8 @@ GeneralTab::GeneralTab(QWidget* parent)
tr("Enable to use longer key expiration date."));
ui_->importConfirmationCheckBox->setText(
tr("Import files dropped on the Key List without confirmation."));
+ ui_->disableLoadingModulesCheckBox->setText(
+ tr("Disable loading of all modules (including integrated modules)"));
ui_->langBox->setTitle(tr("Language"));
ui_->langNoteLabel->setText(
@@ -129,9 +131,13 @@ void GeneralTab::SetSettings() {
ui_->importConfirmationCheckBox->setCheckState(
confirm_import_keys ? Qt::Checked : Qt::Unchecked);
+ auto disable_loading_all_modules =
+ settings.value("basic/disable_loading_all_modules", false).toBool();
+ ui_->disableLoadingModulesCheckBox->setCheckState(
+ disable_loading_all_modules ? Qt::Checked : Qt::Unchecked);
+
auto lang_key = settings.value("basic/lang").toString();
auto lang_value = lang_.value(lang_key);
- GF_UI_LOG_DEBUG("lang settings current: {}", lang_value);
if (!lang_.empty()) {
ui_->langSelectBox->setCurrentIndex(
ui_->langSelectBox->findText(lang_value));
@@ -152,6 +158,8 @@ void GeneralTab::ApplySettings() {
ui_->restoreTextEditorPageCheckBox->isChecked());
settings.setValue("basic/confirm_import_keys",
ui_->importConfirmationCheckBox->isChecked());
+ settings.setValue("basic/disable_loading_all_modules",
+ ui_->disableLoadingModulesCheckBox->isChecked());
settings.setValue("basic/lang", lang_.key(ui_->langSelectBox->currentText()));
}
diff --git a/src/ui/dialog/settings/SettingsKeyServer.cpp b/src/ui/dialog/settings/SettingsKeyServer.cpp
index fb6e624c..d3e4578c 100644
--- a/src/ui/dialog/settings/SettingsKeyServer.cpp
+++ b/src/ui/dialog/settings/SettingsKeyServer.cpp
@@ -78,7 +78,6 @@ KeyserverTab::KeyserverTab(QWidget* parent)
connect(ui_->keyServerListTable, &QTableWidget::itemChanged,
[=](QTableWidgetItem* item) {
- GF_UI_LOG_DEBUG("item edited: {}", item->column());
if (item->column() != 1) return;
const auto row_size = ui_->keyServerListTable->rowCount();
// Update Actions
@@ -180,8 +179,6 @@ void KeyserverTab::ApplySettings() {
}
void KeyserverTab::slot_refresh_table() {
- GF_UI_LOG_INFO("start refreshing key server table");
-
ui_->keyServerListTable->blockSignals(true);
ui_->keyServerListTable->setRowCount(key_server_str_list_.size());
diff --git a/src/ui/function/GenerateRevokeCertification.cpp b/src/ui/function/GenerateRevokeCertification.cpp
index 9f8afcff..f9b655a3 100644
--- a/src/ui/function/GenerateRevokeCertification.cpp
+++ b/src/ui/function/GenerateRevokeCertification.cpp
@@ -48,14 +48,12 @@ auto GenerateRevokeCertification::Exec(const GpgKey& key,
output_path, "--gen-revoke", key.GetFingerprint()},
[=](int exit_code, const QString& p_out, const QString& p_err) {
if (exit_code != 0) {
- GF_UI_LOG_ERROR(
- "gnupg gen revoke execute error, process stderr: {}, process "
- "stdout: {}",
- p_err, p_out);
+ qCWarning(ui) << "gnupg gen revoke execute error, process stderr: "
+ << p_err << ", process stdout: " << p_out;
} else {
- GF_UI_LOG_DEBUG(
- "gnupg gen revoke exit_code: {}, process stdout size: {}",
- exit_code, p_out.size());
+ qCDebug(ui,
+ "gnupg gen revoke exit_code: %d, process stdout size: %lld",
+ exit_code, p_out.size());
}
},
nullptr,
@@ -63,7 +61,6 @@ auto GenerateRevokeCertification::Exec(const GpgKey& key,
// Code From Gpg4Win
while (proc->canReadLine()) {
const QString line = QString::fromUtf8(proc->readLine()).trimmed();
- GF_UI_LOG_DEBUG("line: {}", line);
if (line == QLatin1String("[GNUPG:] GET_BOOL gen_revoke.okay")) {
proc->write("y\n");
} else if (line == QLatin1String("[GNUPG:] GET_LINE "
diff --git a/src/ui/function/RaisePinentry.cpp b/src/ui/function/RaisePinentry.cpp
deleted file mode 100644
index 7c68d67c..00000000
--- a/src/ui/function/RaisePinentry.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric <[email protected]>
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend 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.
- *
- * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric <[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#include "RaisePinentry.h"
-
-#include "core/function/CoreSignalStation.h"
-#include "core/model/GpgPassphraseContext.h"
-#include "core/utils/CacheUtils.h"
-#include "pinentry/pinentrydialog.h"
-
-namespace GpgFrontend::UI {
-
-auto FindTopMostWindow(QWidget* fallback) -> QWidget* {
- QList<QWidget*> top_widgets = QApplication::topLevelWidgets();
- foreach (QWidget* widget, top_widgets) {
- if (widget->isActiveWindow()) {
- GF_UI_LOG_TRACE("find a topmost widget, address: {}",
- static_cast<void*>(widget));
- return widget;
- }
- }
- return fallback;
-}
-
-RaisePinentry::RaisePinentry(QWidget* parent,
- QSharedPointer<GpgPassphraseContext> context)
- : QWidget(parent), context_(std::move(context)) {}
-
-auto RaisePinentry::Exec() -> int {
- GF_UI_LOG_DEBUG(
- "setting pinetry's arguments, context uids: {}, passphrase info: {}, "
- "prev_was_bad: {}",
- context_->GetUidsInfo(), context_->GetPassphraseInfo(),
- context_->IsPreWasBad());
-
- bool ask_for_new = context_->IsAskForNew() &&
- context_->GetPassphraseInfo().isEmpty() &&
- context_->GetUidsInfo().isEmpty();
-
- auto* pinentry =
- new PinEntryDialog(FindTopMostWindow(this), 0, 15, true, ask_for_new,
- ask_for_new ? tr("Repeat Passphrase:") : QString(),
- tr("Show passphrase"), tr("Hide passphrase"));
-
- if (context_->IsPreWasBad()) {
- pinentry->setError(tr("Given Passphrase was wrong. Please retry."));
- }
-
- pinentry->setPrompt(tr("Passphrase:"));
-
- if (!context_->GetUidsInfo().isEmpty()) {
- pinentry->setDescription(QString("Please provide Passphrase of Key:\n%1\n")
- .arg(context_->GetUidsInfo()));
- }
-
- struct pinentry pinentry_info;
- pinentry->setPinentryInfo(pinentry_info);
-
- pinentry->setRepeatErrorText(tr("Passphrases do not match"));
- pinentry->setGenpinLabel(QString(""));
- pinentry->setGenpinTT(QString(""));
- pinentry->setCapsLockHint(tr("Caps Lock is on"));
- pinentry->setFormattedPassphrase({false, QString()});
- pinentry->setConstraintsOptions({false, QString(), QString(), QString()});
-
- pinentry->setWindowTitle(tr("Bundled Pinentry"));
-
- /* If we reuse the same dialog window. */
- pinentry->setPin(QString());
- pinentry->setOkText(tr("Confirm"));
- pinentry->setCancelText(tr("Cancel"));
-
- GF_UI_LOG_DEBUG("buddled pinentry is ready to start...");
- connect(pinentry, &PinEntryDialog::finished, this,
- [pinentry, this](int result) {
- bool ret = result != 0;
- GF_UI_LOG_DEBUG("buddled pinentry finished, ret: {}", ret);
-
- if (!ret) {
- emit CoreSignalStation::GetInstance()
- ->SignalUserInputPassphraseCallback({});
- return -1;
- }
-
- auto pin = pinentry->pin().toUtf8();
-
- context_->SetPassphrase(pin);
- emit CoreSignalStation::GetInstance()
- ->SignalUserInputPassphraseCallback(context_);
- return 0;
- });
- connect(pinentry, &PinEntryDialog::finished, this, &QWidget::deleteLater);
-
- pinentry->open();
- return 0;
-}
-} // namespace GpgFrontend::UI
diff --git a/src/ui/function/RaisePinentry.h b/src/ui/function/RaisePinentry.h
deleted file mode 100644
index 40175dfd..00000000
--- a/src/ui/function/RaisePinentry.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric <[email protected]>
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend 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.
- *
- * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric <[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#pragma once
-
-#include "ui/GpgFrontendUI.h"
-
-namespace GpgFrontend {
-class GpgPassphraseContext;
-}
-
-namespace GpgFrontend::UI {
-
-class RaisePinentry : public QWidget {
- Q_OBJECT
- public:
- /**
- * @brief Construct a new Raise Pinentry object
- *
- * @param parent
- */
- explicit RaisePinentry(QWidget *parent, QSharedPointer<GpgPassphraseContext>);
-
- /**
- * @brief
- *
- * @return int
- */
- auto Exec() -> int;
-
- private:
- QSharedPointer<GpgPassphraseContext> context_;
-};
-
-} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/function/SetOwnerTrustLevel.cpp b/src/ui/function/SetOwnerTrustLevel.cpp
index 87f4cb61..29697eaa 100644
--- a/src/ui/function/SetOwnerTrustLevel.cpp
+++ b/src/ui/function/SetOwnerTrustLevel.cpp
@@ -54,7 +54,6 @@ auto SetOwnerTrustLevel::Exec(const QString& key_id) -> bool {
key.GetOwnerTrustLevel(), false, &ok);
if (ok && !item.isEmpty()) {
- GF_UI_LOG_DEBUG("selected owner trust policy: {}", item);
int trust_level = 0; // Unknown Level
if (item == tr("Ultimate")) {
trust_level = 5;
@@ -86,7 +85,7 @@ auto SetOwnerTrustLevel::Exec(const QString& key_id) -> bool {
}
// update key database and refresh ui
- emit UISignalStation::GetInstance()->SignalKeyDatabaseRefresh();
+ emit UISignalStation::GetInstance() -> SignalKeyDatabaseRefresh();
return true;
}
diff --git a/src/ui/main_window/GeneralMainWindow.cpp b/src/ui/main_window/GeneralMainWindow.cpp
index 3d662332..9ea13836 100644
--- a/src/ui/main_window/GeneralMainWindow.cpp
+++ b/src/ui/main_window/GeneralMainWindow.cpp
@@ -45,10 +45,7 @@ GpgFrontend::UI::GeneralMainWindow::GeneralMainWindow(QString name,
GpgFrontend::UI::GeneralMainWindow::~GeneralMainWindow() = default;
void GpgFrontend::UI::GeneralMainWindow::closeEvent(QCloseEvent *event) {
- GF_UI_LOG_DEBUG("main window close event caught, event type: {}",
- event->type());
slot_save_settings();
-
QMainWindow::closeEvent(event);
}
@@ -56,16 +53,13 @@ void GpgFrontend::UI::GeneralMainWindow::slot_restore_settings() noexcept {
try {
WindowStateSO window_state(SettingsObject(name_ + "_state"));
- GF_UI_LOG_DEBUG("restore main window state: {}",
- window_state.window_state_data);
-
if (!window_state.window_state_data.isEmpty()) {
// state sets pos & size of dock-widgets
this->restoreState(
QByteArray::fromBase64(window_state.window_state_data.toUtf8()));
}
- this->setMinimumSize(640, 480);
+ this->setMinimumSize(800, 600);
// restore window size & location
if (window_state.window_save) {
@@ -73,9 +67,6 @@ void GpgFrontend::UI::GeneralMainWindow::slot_restore_settings() noexcept {
size_ = {window_state.width, window_state.height};
if (this->parent() != nullptr) {
- GF_UI_LOG_DEBUG("parent address: {}",
- static_cast<void *>(this->parent()));
-
QPoint parent_pos = {0, 0};
QSize parent_size = {0, 0};
@@ -91,12 +82,6 @@ void GpgFrontend::UI::GeneralMainWindow::slot_restore_settings() noexcept {
parent_size = parent_window->size();
}
- GF_UI_LOG_DEBUG("parent pos x: {} y: {}", parent_pos.x(),
- parent_pos.y());
-
- GF_UI_LOG_DEBUG("parent size width: {} height: {}", parent_size.width(),
- parent_size.height());
-
if (parent_pos != QPoint{0, 0}) {
QPoint const parent_center{parent_pos.x() + parent_size.width() / 2,
parent_pos.y() + parent_size.height() / 2};
@@ -106,8 +91,8 @@ void GpgFrontend::UI::GeneralMainWindow::slot_restore_settings() noexcept {
}
}
- if (size_.width() < 640) size_.setWidth(640);
- if (size_.height() < 480) size_.setHeight(480);
+ if (size_.width() < 800) size_.setWidth(800);
+ if (size_.height() < 600) size_.setHeight(600);
this->move(pos_);
this->resize(size_);
@@ -127,13 +112,12 @@ void GpgFrontend::UI::GeneralMainWindow::slot_restore_settings() noexcept {
icon_style_ = toolButtonStyle();
} catch (...) {
- GF_UI_LOG_ERROR("general main window: {}, caught exception", name_);
+ qCWarning(ui) << "general main window: " << name_ << ", caught exception";
}
}
void GpgFrontend::UI::GeneralMainWindow::slot_save_settings() noexcept {
try {
- GF_UI_LOG_DEBUG("save main window state, name: {}", name_);
SettingsObject general_windows_state(name_ + "_state");
// update geo of current dialog
@@ -150,7 +134,7 @@ void GpgFrontend::UI::GeneralMainWindow::slot_save_settings() noexcept {
general_windows_state.Store(window_state.Json());
} catch (...) {
- GF_UI_LOG_ERROR("general main window: {}, caught exception", name_);
+ qCWarning(ui) << "general main window: " << name_ << ", caught exception";
}
}
@@ -158,11 +142,6 @@ void GeneralMainWindow::setPosCenterOfScreen() {
// update cache
update_rect_cache();
- int screen_width = screen_rect_.width();
- int screen_height = screen_rect_.height();
- GF_UI_LOG_DEBUG("dialog current screen available geometry", screen_width,
- screen_height);
-
// update rect of current dialog
rect_ = this->geometry();
this->move(screen_rect_.center() -
@@ -173,16 +152,6 @@ void GeneralMainWindow::movePosition2CenterOfParent() {
// update cache
update_rect_cache();
- // log for debug
- GF_UI_LOG_DEBUG("parent pos x: {} y: {}", parent_rect_.x(), parent_rect_.y());
- GF_UI_LOG_DEBUG("parent size width: {}, height: {}", parent_rect_.width(),
- parent_rect_.height());
- GF_UI_LOG_DEBUG("parent center pos x: {}, y: {}", parent_rect_.center().x(),
- parent_rect_.center().y());
- GF_UI_LOG_DEBUG("dialog pos x: {} y: {}", rect_.x(), rect_.y());
- GF_UI_LOG_DEBUG("dialog size width: {} height: {}", rect_.width(),
- rect_.height());
-
if (parent_rect_.topLeft() != QPoint{0, 0} &&
parent_rect_.size() != QSize{0, 0}) {
if (rect_.width() <= 0) rect_.setWidth(100);
@@ -191,10 +160,6 @@ void GeneralMainWindow::movePosition2CenterOfParent() {
QPoint target_position =
parent_rect_.center() - QPoint(rect_.width() / 2, rect_.height() / 2);
- GF_UI_LOG_DEBUG(
- "update position to parent's center, target pos, x:{}, y: {}",
- target_position.x(), target_position.y());
-
this->move(target_position);
} else {
setPosCenterOfScreen();
diff --git a/src/ui/main_window/KeyMgmt.cpp b/src/ui/main_window/KeyMgmt.cpp
index afc6129c..09746140 100644
--- a/src/ui/main_window/KeyMgmt.cpp
+++ b/src/ui/main_window/KeyMgmt.cpp
@@ -52,55 +52,48 @@ namespace GpgFrontend::UI {
KeyMgmt::KeyMgmt(QWidget* parent)
: GeneralMainWindow("key_management", parent) {
/* the list of Keys available*/
- key_list_ = new KeyList(KeyMenuAbility::ALL, this);
+ key_list_ = new KeyList(KeyMenuAbility::kALL, GpgKeyTableColumn::kALL, this);
key_list_->AddListGroupTab(tr("All"), "all",
- KeyListRow::SECRET_OR_PUBLIC_KEY);
+ GpgKeyTableDisplayMode::kPUBLIC_KEY |
+ GpgKeyTableDisplayMode::kPRIVATE_KEY);
key_list_->AddListGroupTab(
tr("Only Public Key"), "only_public_key",
- KeyListRow::SECRET_OR_PUBLIC_KEY,
- KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
- KeyListColumn::Usage | KeyListColumn::Validity,
- [](const GpgKey& key, const KeyTable&) -> bool {
+ GpgKeyTableDisplayMode::kPUBLIC_KEY, [](const GpgKey& key) -> bool {
return !key.IsPrivateKey() &&
!(key.IsRevoked() || key.IsDisabled() || key.IsExpired());
});
key_list_->AddListGroupTab(
tr("Has Private Key"), "has_private_key",
- KeyListRow::SECRET_OR_PUBLIC_KEY,
- KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
- KeyListColumn::Usage | KeyListColumn::Validity,
- [](const GpgKey& key, const KeyTable&) -> bool {
+ GpgKeyTableDisplayMode::kPRIVATE_KEY, [](const GpgKey& key) -> bool {
return key.IsPrivateKey() &&
!(key.IsRevoked() || key.IsDisabled() || key.IsExpired());
});
key_list_->AddListGroupTab(
- tr("No Primary Key"), "no_primary_key", KeyListRow::SECRET_OR_PUBLIC_KEY,
- KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
- KeyListColumn::Usage | KeyListColumn::Validity,
- [](const GpgKey& key, const KeyTable&) -> bool {
+ tr("No Primary Key"), "no_primary_key",
+ GpgKeyTableDisplayMode::kPUBLIC_KEY |
+ GpgKeyTableDisplayMode::kPRIVATE_KEY,
+ [](const GpgKey& key) -> bool {
return !key.IsHasMasterKey() &&
!(key.IsRevoked() || key.IsDisabled() || key.IsExpired());
});
key_list_->AddListGroupTab(
- tr("Revoked"), "revoked", KeyListRow::SECRET_OR_PUBLIC_KEY,
- KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
- KeyListColumn::Usage | KeyListColumn::Validity,
- [](const GpgKey& key, const KeyTable&) -> bool {
- return key.IsRevoked();
- });
+ tr("Revoked"), "revoked",
+ GpgKeyTableDisplayMode::kPUBLIC_KEY |
+ GpgKeyTableDisplayMode::kPRIVATE_KEY,
+
+ [](const GpgKey& key) -> bool { return key.IsRevoked(); });
key_list_->AddListGroupTab(
- tr("Expired"), "expired", KeyListRow::SECRET_OR_PUBLIC_KEY,
- KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
- KeyListColumn::Usage | KeyListColumn::Validity,
- [](const GpgKey& key, const KeyTable&) -> bool {
- return key.IsExpired();
- });
+ tr("Expired"), "expired",
+ GpgKeyTableDisplayMode::kPUBLIC_KEY |
+ GpgKeyTableDisplayMode::kPRIVATE_KEY,
+
+ [](const GpgKey& key) -> bool { return key.IsExpired(); });
setCentralWidget(key_list_);
key_list_->SetDoubleClickedAction(
@@ -420,7 +413,7 @@ void KeyMgmt::SlotExportKeyToClipboard() {
}
if (data_obj == nullptr || !data_obj->Check<GFBuffer>()) {
- GF_CORE_LOG_ERROR("data object checking failed");
+ qCWarning(ui, "data object checking failed");
QMessageBox::critical(this, tr("Error"),
tr("Unknown error occurred"));
return;
@@ -579,7 +572,6 @@ void KeyMgmt::SlotImportKeyPackage() {
return;
}
- GF_UI_LOG_INFO("importing key package: {}", key_package_file_name);
CommonUtils::WaitForOpera(
this, tr("Importing"), [=](const OperaWaitingHd& op_hd) {
KeyPackageOperator::ImportKeyPackage(
diff --git a/src/ui/main_window/MainWindow.cpp b/src/ui/main_window/MainWindow.cpp
index c50cfc5e..3106f226 100644
--- a/src/ui/main_window/MainWindow.cpp
+++ b/src/ui/main_window/MainWindow.cpp
@@ -43,12 +43,8 @@
namespace GpgFrontend::UI {
MainWindow::MainWindow() : GeneralMainWindow("main_window") {
- this->setMinimumSize(1200, 700);
+ this->setMinimumSize(1200, 870);
this->setWindowTitle(qApp->applicationName());
-
- connect(CoreSignalStation::GetInstance(),
- &CoreSignalStation::SignalNeedUserInputPassphrase, this,
- &MainWindow::SlotRaisePinentry);
}
void MainWindow::Init() noexcept {
@@ -61,10 +57,14 @@ void MainWindow::Init() noexcept {
setCentralWidget(edit_);
/* the list of Keys available*/
- m_key_list_ =
- new KeyList(KeyMenuAbility::REFRESH | KeyMenuAbility::UNCHECK_ALL |
- KeyMenuAbility::SEARCH_BAR,
- this);
+ m_key_list_ = new KeyList(
+ KeyMenuAbility::kREFRESH | KeyMenuAbility::kCHECK_ALL |
+ KeyMenuAbility::kUNCHECK_ALL | KeyMenuAbility::kCOLUMN_FILTER |
+ KeyMenuAbility::kSEARCH_BAR,
+ GpgKeyTableColumn::kTYPE | GpgKeyTableColumn::kNAME |
+ GpgKeyTableColumn::kKEY_ID | GpgKeyTableColumn::kEMAIL_ADDRESS |
+ GpgKeyTableColumn::kUSAGE | GpgKeyTableColumn::kOWNER_TRUST,
+ this);
info_board_ = new InfoBoardWidget(this);
@@ -132,9 +132,9 @@ void MainWindow::Init() noexcept {
Module::ListenRTPublishEvent(
this, kVersionCheckingModuleID, "version.loading_done",
[=](Module::Namespace, Module::Key, int, std::any) {
- GF_UI_LOG_DEBUG(
- "version-checking version.loading_done changed, calling slot "
- "version upgrade");
+ qCDebug(ui,
+ "version-checking version.loading_done changed, calling slot "
+ "version upgrade");
this->slot_version_upgrade_notify();
});
@@ -151,7 +151,7 @@ void MainWindow::Init() noexcept {
if (show_wizard) slot_start_wizard();
} catch (...) {
- GF_UI_LOG_ERROR(tr("Critical error occur while loading GpgFrontend."));
+ qCWarning(ui) << tr("Critical error occur while loading GpgFrontend.");
QMessageBox::critical(
nullptr, tr("Loading Failed"),
tr("Critical error occur while loading GpgFrontend."));
@@ -161,8 +161,6 @@ void MainWindow::Init() noexcept {
}
void MainWindow::restore_settings() {
- GF_UI_LOG_DEBUG("restore settings for main windows");
-
KeyServerSO key_server(SettingsObject("key_server"));
if (key_server.server_list.empty()) key_server.ResetDefaultServerList();
if (key_server.default_server < 0) key_server.default_server = 0;
@@ -177,8 +175,6 @@ void MainWindow::restore_settings() {
prohibit_update_checking_ =
settings.value("network/prohibit_update_check").toBool();
-
- GF_UI_LOG_DEBUG("settings restored");
}
void MainWindow::recover_editor_unsaved_pages_from_cache() {
@@ -189,9 +185,6 @@ void MainWindow::recover_editor_unsaved_pages_from_cache() {
return;
}
- GF_UI_LOG_DEBUG("plan ot recover unsaved page from cache, page array: {}",
- json_data.toJson());
-
bool first = true;
auto unsaved_page_array = json_data.array();
@@ -207,10 +200,6 @@ void MainWindow::recover_editor_unsaved_pages_from_cache() {
auto title = unsaved_page_json["title"].toString();
auto content = unsaved_page_json["content"].toString();
- GF_UI_LOG_DEBUG(
- "recovering unsaved page from cache, page title: {}, content size",
- title, content.size());
-
if (first) {
edit_->SlotCloseTab();
first = false;
diff --git a/src/ui/main_window/MainWindow.h b/src/ui/main_window/MainWindow.h
index f53a4a03..b253a667 100644
--- a/src/ui/main_window/MainWindow.h
+++ b/src/ui/main_window/MainWindow.h
@@ -233,11 +233,6 @@ class MainWindow : public GeneralMainWindow {
*/
void SlotSetRestartNeeded(int);
- /**
- * @details Open a new tab for path
- */
- void SlotRaisePinentry(QSharedPointer<GpgPassphraseContext>);
-
private slots:
/**
diff --git a/src/ui/main_window/MainWindowFileSlotFunction.cpp b/src/ui/main_window/MainWindowFileSlotFunction.cpp
index bc3accfa..3d151ce6 100644
--- a/src/ui/main_window/MainWindowFileSlotFunction.cpp
+++ b/src/ui/main_window/MainWindowFileSlotFunction.cpp
@@ -282,7 +282,6 @@ void MainWindow::SlotFileDecrypt(const QString& path) {
}
auto out_path = SetExtensionOfOutputFile(path, kDECRYPT, true);
- GF_UI_LOG_DEBUG("file decrypt target output path: {}", out_path);
if (QFileInfo(out_path).exists()) {
auto ret = QMessageBox::warning(
this, tr("Warning"),
@@ -332,7 +331,6 @@ void MainWindow::SlotArchiveDecrypt(const QString& path) {
}
auto out_path = SetExtensionOfOutputFileForArchive(path, kDECRYPT, true);
- GF_UI_LOG_DEBUG("archive decrypt target output path: {}", out_path);
if (QFileInfo(out_path).exists()) {
auto ret = QMessageBox::warning(
this, tr("Warning"),
@@ -493,9 +491,6 @@ void MainWindow::SlotFileVerify(const QString& path) {
return;
}
- GF_UI_LOG_DEBUG("verification data file path: {}", data_file_path);
- GF_UI_LOG_DEBUG("verification signature file path: {}", sign_file_path);
-
CommonUtils::WaitForOpera(
this, tr("Verifying"), [=](const OperaWaitingHd& op_hd) {
GpgFileOpera::GetInstance().VerifyFile(
@@ -817,7 +812,6 @@ void MainWindow::SlotArchiveDecryptVerify(const QString& path) {
auto out_path =
SetExtensionOfOutputFileForArchive(path, kDECRYPT_VERIFY, true);
- GF_UI_LOG_INFO("out_path: {}", out_path);
check_result = TargetFilePreCheck(out_path, false);
if (!std::get<0>(check_result)) {
QMessageBox::critical(this, tr("Error"),
diff --git a/src/ui/main_window/MainWindowGpgOperaFunction.cpp b/src/ui/main_window/MainWindowGpgOperaFunction.cpp
index 3cef497d..d197e336 100644
--- a/src/ui/main_window/MainWindowGpgOperaFunction.cpp
+++ b/src/ui/main_window/MainWindowGpgOperaFunction.cpp
@@ -295,14 +295,6 @@ void MainWindow::SlotEncryptSign() {
auto signer_key_ids = signers_picker->GetCheckedSigners();
auto signer_keys = GpgKeyGetter::GetInstance().GetKeys(signer_key_ids);
- for (const auto& key : *keys) {
- GF_UI_LOG_DEBUG("keys {}", key.GetEmail());
- }
-
- for (const auto& signer : *signer_keys) {
- GF_UI_LOG_DEBUG("signers {}", signer.GetEmail());
- }
-
// data to transfer into task
auto buffer = GFBuffer(edit_->CurTextPage()->GetTextPage()->toPlainText());
diff --git a/src/ui/main_window/MainWindowSlotFunction.cpp b/src/ui/main_window/MainWindowSlotFunction.cpp
index 7d50b85a..f1754be7 100644
--- a/src/ui/main_window/MainWindowSlotFunction.cpp
+++ b/src/ui/main_window/MainWindowSlotFunction.cpp
@@ -63,14 +63,14 @@ void MainWindow::slot_append_selected_keys() {
auto key_ids = m_key_list_->GetSelected();
if (key_ids->empty()) {
- GF_UI_LOG_ERROR("no key is selected to export");
+ qCWarning(ui, "no key is selected to export");
return;
}
auto key = GpgKeyGetter::GetInstance().GetKey(key_ids->front());
if (!key.IsGood()) {
- GF_UI_LOG_ERROR("selected key for exporting is invalid, key id: {}",
- key_ids->front());
+ qCWarning(ui) << "selected key for exporting is invalid, key id: "
+ << key_ids->front();
return;
}
@@ -88,7 +88,7 @@ void MainWindow::slot_append_keys_create_datetime() {
auto key_ids = m_key_list_->GetSelected();
if (key_ids->empty()) {
- GF_UI_LOG_ERROR("no key is selected");
+ qCWarning(ui, "no key is selected");
return;
}
@@ -112,7 +112,7 @@ void MainWindow::slot_append_keys_expire_datetime() {
auto key_ids = m_key_list_->GetSelected();
if (key_ids->empty()) {
- GF_UI_LOG_ERROR("no key is selected");
+ qCWarning(ui, "no key is selected");
return;
}
@@ -204,8 +204,9 @@ void MainWindow::slot_add_key_2_favourite() {
if (key_ids->empty()) return;
auto key = GpgKeyGetter::GetInstance().GetKey(key_ids->front());
- CommonUtils::GetInstance()->AddKey2Favourtie(key);
+ if (!key.IsGood()) return;
+ CommonUtils::GetInstance()->AddKey2Favourtie(key);
emit SignalUIRefresh();
}
@@ -263,15 +264,14 @@ void MainWindow::SlotOpenFile(const QString& path) {
}
void MainWindow::slot_version_upgrade_notify() {
- GF_UI_LOG_DEBUG(
+ qCDebug(
+ ui,
"slot version upgrade notify called, checking version info from rt...");
+
auto is_loading_done = Module::RetrieveRTValueTypedOrDefault<>(
kVersionCheckingModuleID, "version.loading_done", false);
-
- GF_UI_LOG_DEBUG("checking version info from rt, is loading done state: {}",
- is_loading_done);
if (!is_loading_done) {
- GF_UI_LOG_ERROR("invalid version info from rt, loading hasn't done yet");
+ qCWarning(ui, "invalid version info from rt, loading hasn't done yet");
return;
}
@@ -287,12 +287,6 @@ void MainWindow::slot_version_upgrade_notify() {
auto latest_version = Module::RetrieveRTValueTypedOrDefault<>(
kVersionCheckingModuleID, "version.latest_version", QString{});
- GF_UI_LOG_DEBUG(
- "got version info from rt, need upgrade: {}, with drawn: {}, "
- "current version released: {}",
- is_need_upgrade, is_current_a_withdrawn_version,
- is_current_version_released);
-
if (is_need_upgrade) {
statusBar()->showMessage(
tr("GpgFrontend Upgradeable (New Version: %1).").arg(latest_version),
diff --git a/src/ui/main_window/MainWindowSlotUI.cpp b/src/ui/main_window/MainWindowSlotUI.cpp
index 39ceedc6..1fc4eb5c 100644
--- a/src/ui/main_window/MainWindowSlotUI.cpp
+++ b/src/ui/main_window/MainWindowSlotUI.cpp
@@ -33,7 +33,6 @@
#include "core/model/SettingsObject.h"
#include "ui/UserInterfaceUtils.h"
#include "ui/dialog/Wizard.h"
-#include "ui/function/RaisePinentry.h"
#include "ui/main_window/KeyMgmt.h"
#include "ui/struct/settings_object/AppearanceSO.h"
#include "ui/widgets/TextEdit.h"
@@ -53,7 +52,7 @@ void MainWindow::slot_start_wizard() {
void MainWindow::slot_import_key_from_edit() {
if (edit_->TabCount() == 0 || edit_->SlotCurPageTextEdit() == nullptr) return;
CommonUtils::GetInstance()->SlotImportKeys(
- this, edit_->CurTextPage()->GetTextPage()->toPlainText());
+ this, edit_->CurTextPage()->GetTextPage()->toPlainText().toLatin1());
}
void MainWindow::slot_open_key_management() {
@@ -98,7 +97,6 @@ void MainWindow::slot_disable_tab_actions(int number) {
add_pgp_header_act_->setDisabled(disable);
if (edit_->CurFilePage() != nullptr) {
- GF_UI_LOG_DEBUG("edit current page is file page");
auto* file_page = edit_->CurFilePage();
emit file_page->SignalCurrentTabChanged();
}
@@ -109,9 +107,6 @@ void MainWindow::slot_open_settings_dialog() {
connect(dialog, &SettingsDialog::finished, this, [&]() -> void {
AppearanceSO appearance(SettingsObject("general_settings_state"));
- GF_UI_LOG_DEBUG("tool bar icon_size: {}, {}",
- appearance.tool_bar_icon_width,
- appearance.tool_bar_icon_height);
this->setToolButtonStyle(appearance.tool_bar_button_style);
import_button_->setToolButtonStyle(appearance.tool_bar_button_style);
@@ -182,14 +177,10 @@ void MainWindow::slot_cut_pgp_header() {
edit_->SlotFillTextEditWithText(content.trimmed());
}
-void MainWindow::SlotSetRestartNeeded(int mode) {
- GF_UI_LOG_DEBUG("restart mode: {}", mode);
- this->restart_mode_ = mode;
-}
+void MainWindow::SlotSetRestartNeeded(int mode) { this->restart_mode_ = mode; }
void MainWindow::SlotUpdateCryptoMenuStatus(unsigned int type) {
MainWindow::CryptoMenu::OperationType opera_type = type;
- GF_UI_LOG_DEBUG("update crypto menu status, type: {}", opera_type);
// refresh status to disable all
verify_act_->setDisabled(true);
@@ -220,10 +211,4 @@ void MainWindow::SlotUpdateCryptoMenuStatus(unsigned int type) {
}
}
-void MainWindow::SlotRaisePinentry(
- QSharedPointer<GpgPassphraseContext> context) {
- auto* function = new RaisePinentry(this, context);
- function->Exec();
-}
-
} // namespace GpgFrontend::UI
diff --git a/src/ui/main_window/MainWindowUI.cpp b/src/ui/main_window/MainWindowUI.cpp
index 8b611152..c1189fa2 100644
--- a/src/ui/main_window/MainWindowUI.cpp
+++ b/src/ui/main_window/MainWindowUI.cpp
@@ -707,37 +707,32 @@ void MainWindow::create_dock_windows() {
addDockWidget(Qt::RightDockWidgetArea, key_list_dock_);
m_key_list_->AddListGroupTab(
- tr("Default"), "default", KeyListRow::SECRET_OR_PUBLIC_KEY,
- KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
- KeyListColumn::Usage | KeyListColumn::Validity,
- [](const GpgKey& key, const KeyTable&) -> bool {
+ tr("Default"), "default",
+ GpgKeyTableDisplayMode::kPUBLIC_KEY |
+ GpgKeyTableDisplayMode::kPRIVATE_KEY,
+ [](const GpgKey& key) -> bool {
return !(key.IsRevoked() || key.IsDisabled() || key.IsExpired());
});
m_key_list_->AddListGroupTab(
- tr("Favourite"), "favourite", KeyListRow::SECRET_OR_PUBLIC_KEY,
- KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
- KeyListColumn::Usage | KeyListColumn::Validity,
- [](const GpgKey& key, const KeyTable&) -> bool {
+ tr("Favourite"), "favourite",
+ GpgKeyTableDisplayMode::kPUBLIC_KEY |
+ GpgKeyTableDisplayMode::kPRIVATE_KEY |
+ GpgKeyTableDisplayMode::kFAVORITES,
+ [](const GpgKey& key) -> bool {
return CommonUtils::GetInstance()->KeyExistsinFavouriteList(key);
});
m_key_list_->AddListGroupTab(
tr("Only Public Key"), "only_public_key",
- KeyListRow::SECRET_OR_PUBLIC_KEY,
- KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
- KeyListColumn::Usage | KeyListColumn::Validity,
- [](const GpgKey& key, const KeyTable&) -> bool {
+ GpgKeyTableDisplayMode::kPUBLIC_KEY, [](const GpgKey& key) -> bool {
return !key.IsPrivateKey() &&
!(key.IsRevoked() || key.IsDisabled() || key.IsExpired());
});
m_key_list_->AddListGroupTab(
tr("Has Private Key"), "has_private_key",
- KeyListRow::SECRET_OR_PUBLIC_KEY,
- KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
- KeyListColumn::Usage | KeyListColumn::Validity,
- [](const GpgKey& key, const KeyTable&) -> bool {
+ GpgKeyTableDisplayMode::kPRIVATE_KEY, [](const GpgKey& key) -> bool {
return key.IsPrivateKey() &&
!(key.IsRevoked() || key.IsDisabled() || key.IsExpired());
});
diff --git a/src/module/mods/ver_check/VersionCheckingModule.h b/src/ui/struct/UIMountPoint.h
index 35ee4ac3..61ac83c6 100644
--- a/src/module/mods/ver_check/VersionCheckingModule.h
+++ b/src/ui/struct/UIMountPoint.h
@@ -28,29 +28,31 @@
#pragma once
-#include <GFSDKModule.h>
-
-#include "GFModuleExport.h"
-
-extern "C" {
-
-auto GF_MODULE_EXPORT GFGetModuleGFSDKVersion() -> const char *;
-
-auto GF_MODULE_EXPORT GFGetModuleQtEnvVersion() -> const char *;
-
-auto GF_MODULE_EXPORT GFGetModuleID() -> const char *;
-
-auto GF_MODULE_EXPORT GFGetModuleVersion() -> const char *;
-
-auto GF_MODULE_EXPORT GFGetModuleMetaData() -> GFModuleMetaData *;
-
-auto GF_MODULE_EXPORT GFRegisterModule() -> int;
-
-auto GF_MODULE_EXPORT GFActiveModule() -> int;
-
-auto GF_MODULE_EXPORT GFExecuteModule(GFModuleEvent *) -> int;
-
-auto GF_MODULE_EXPORT GFDeactiveModule() -> int;
-
-auto GF_MODULE_EXPORT GFUnregisterModule() -> int;
-};
+struct UIMountPoint {
+ QString id;
+ QString entry_type;
+ QMap<QString, QVariant> meta_data_desc;
+
+ UIMountPoint() = default;
+
+ explicit UIMountPoint(const QJsonObject& j) {
+ if (const auto v = j["id"]; v.isDouble()) {
+ id = v.toString();
+ }
+ if (const auto v = j["entry_type"]; v.isDouble()) {
+ entry_type = v.toString();
+ }
+ if (const auto v = j["meta_data_desc"]; v.isDouble()) {
+ meta_data_desc = v.toVariant().toMap();
+ }
+ }
+
+ [[nodiscard]] auto ToJson() const -> QJsonObject {
+ QJsonObject j;
+ j["id"] = id;
+ j["entry_type"] = entry_type;
+ j["meta_data_desc"] = QJsonObject::fromVariantMap(meta_data_desc);
+
+ return j;
+ }
+}; \ No newline at end of file
diff --git a/src/ui/thread/KeyServerImportTask.cpp b/src/ui/thread/KeyServerImportTask.cpp
index 8bcb2eab..e3662db2 100644
--- a/src/ui/thread/KeyServerImportTask.cpp
+++ b/src/ui/thread/KeyServerImportTask.cpp
@@ -44,8 +44,6 @@ GpgFrontend::UI::KeyServerImportTask::KeyServerImportTask(
if (keyserver_url_.isEmpty()) {
KeyServerSO key_server(SettingsObject("general_settings_state"));
keyserver_url_ = key_server.GetTargetServer();
- GF_UI_LOG_DEBUG("key server import task sets key server url: {}",
- keyserver_url_);
}
}
@@ -71,8 +69,9 @@ void GpgFrontend::UI::KeyServerImportTask::dealing_reply_from_server() {
auto buffer = reply_->readAll();
if (network_reply != QNetworkReply::NoError) {
- GF_UI_LOG_ERROR("key import error, message from key server reply: ",
- buffer);
+ qCWarning(ui) << "key import error, message from key server reply: "
+ << buffer;
+
QString err_msg;
switch (network_reply) {
case QNetworkReply::ContentNotFoundError:
diff --git a/src/ui/thread/ListedKeyServerTestTask.cpp b/src/ui/thread/ListedKeyServerTestTask.cpp
index 5f7e2dca..1d492735 100644
--- a/src/ui/thread/ListedKeyServerTestTask.cpp
+++ b/src/ui/thread/ListedKeyServerTestTask.cpp
@@ -48,7 +48,6 @@ auto GpgFrontend::UI::ListedKeyServerTestTask::Run() -> int {
size_t index = 0;
for (const auto& url : urls_) {
auto key_url = QUrl{url};
- GF_UI_LOG_DEBUG("key server request: {}", key_url.host());
auto request = QNetworkRequest(key_url);
request.setHeader(QNetworkRequest::UserAgentHeader,
@@ -59,12 +58,10 @@ auto GpgFrontend::UI::ListedKeyServerTestTask::Run() -> int {
connect(network_reply, &QNetworkReply::finished, this,
[this, index, network_reply]() {
- GF_UI_LOG_DEBUG("key server domain reply: {}", urls_[index]);
this->slot_process_network_reply(index, network_reply);
});
connect(timer, &QTimer::timeout, this, [this, index, network_reply]() {
- GF_UI_LOG_DEBUG("timeout for key server: {}", urls_[index]);
if (network_reply->isRunning()) {
network_reply->abort();
this->slot_process_network_reply(index, network_reply);
diff --git a/src/ui/thread/ProxyConnectionTestTask.cpp b/src/ui/thread/ProxyConnectionTestTask.cpp
index c1d2f3e6..7d2c496f 100644
--- a/src/ui/thread/ProxyConnectionTestTask.cpp
+++ b/src/ui/thread/ProxyConnectionTestTask.cpp
@@ -51,12 +51,10 @@ auto GpgFrontend::UI::ProxyConnectionTestTask::Run() -> int {
connect(network_reply, &QNetworkReply::finished, this,
[this, network_reply]() {
- GF_UI_LOG_DEBUG("key server domain reply: {} received", url_);
this->slot_process_network_reply(network_reply);
});
connect(timer, &QTimer::timeout, this, [this, network_reply]() {
- GF_UI_LOG_DEBUG("timeout for key server: {}", url_);
if (network_reply->isRunning()) {
network_reply->abort();
this->slot_process_network_reply(network_reply);
@@ -70,8 +68,6 @@ auto GpgFrontend::UI::ProxyConnectionTestTask::Run() -> int {
void GpgFrontend::UI::ProxyConnectionTestTask::slot_process_network_reply(
QNetworkReply* reply) {
auto buffer = reply->readAll();
- GF_UI_LOG_DEBUG("key server domain reply: {}, buffer size: {}", url_,
- buffer.size());
if (reply->error() == QNetworkReply::NoError && !buffer.isEmpty()) {
result_ = "Reachable";
diff --git a/src/ui/widgets/FilePage.cpp b/src/ui/widgets/FilePage.cpp
index d99bfc53..f44aa12b 100644
--- a/src/ui/widgets/FilePage.cpp
+++ b/src/ui/widgets/FilePage.cpp
@@ -117,7 +117,6 @@ void FilePage::SlotGoPath() {
}
void FilePage::keyPressEvent(QKeyEvent* event) {
- GF_UI_LOG_DEBUG("file page notices key press by user: {}", event->key());
if (ui_->pathEdit->hasFocus() &&
(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)) {
SlotGoPath();
diff --git a/src/ui/widgets/FileTreeView.cpp b/src/ui/widgets/FileTreeView.cpp
index de22ec83..b9ffbd27 100644
--- a/src/ui/widgets/FileTreeView.cpp
+++ b/src/ui/widgets/FileTreeView.cpp
@@ -63,12 +63,9 @@ FileTreeView::FileTreeView(QWidget* parent, const QString& target_path)
void FileTreeView::selectionChanged(const QItemSelection& selected,
const QItemSelection& deselected) {
QTreeView::selectionChanged(selected, deselected);
- GF_UI_LOG_DEBUG(
- "file tree view selected changed, selected: {}, deselected: {}",
- selected.size(), deselected.size());
+
if (!selected.indexes().empty()) {
selected_path_ = dir_model_->filePath(selected.indexes().first());
- GF_UI_LOG_DEBUG("file tree view selected target path: {}", selected_path_);
emit SignalSelectedChanged(selected_path_);
} else {
selected_path_ = QString();
@@ -83,7 +80,6 @@ void FileTreeView::SlotGoPath(const QString& target_path) {
auto file_info = QFileInfo(target_path);
if (file_info.isDir() && file_info.isReadable() && file_info.isExecutable()) {
current_path_ = file_info.absoluteFilePath();
- GF_UI_LOG_DEBUG("file tree view set target path: {}", current_path_);
this->setRootIndex(dir_model_->index(file_info.filePath()));
dir_model_->setRootPath(file_info.filePath());
slot_adjust_column_widths();
@@ -116,7 +112,6 @@ void FileTreeView::SlotUpLevel() {
auto target_path = dir_model_->fileInfo(current_root).absoluteFilePath();
if (auto parent_path = QDir(target_path); parent_path.cdUp()) {
target_path = parent_path.absolutePath();
- GF_UI_LOG_DEBUG("file tree view go parent path: {}", target_path);
this->SlotGoPath(target_path);
}
current_path_ = target_path;
@@ -145,9 +140,7 @@ auto FileTreeView::GetPathByClickPoint(const QPoint& point) -> QString {
return {};
}
- auto index_path = dir_model_->fileInfo(index).absoluteFilePath();
- GF_UI_LOG_DEBUG("file tree view right click on: {}", index_path);
- return index_path;
+ return dir_model_->fileInfo(index).absoluteFilePath();
}
auto FileTreeView::GetSelectedPath() -> QString { return selected_path_; }
@@ -162,8 +155,6 @@ auto FileTreeView::SlotDeleteSelectedItem() -> void {
if (ret == QMessageBox::Cancel) return;
- GF_UI_LOG_DEBUG("delete item: {}", data.toString());
-
if (!dir_model_->remove(index)) {
QMessageBox::critical(this, tr("Error"),
tr("Unable to delete the file or folder."));
@@ -207,7 +198,6 @@ void FileTreeView::SlotTouch() {
QLineEdit::Normal, new_file_name, &ok);
if (ok && !new_file_name.isEmpty()) {
auto file_path = root_path + "/" + new_file_name;
- GF_UI_LOG_DEBUG("new file path: {}", file_path);
QFile new_file(file_path);
if (!new_file.open(QIODevice::WriteOnly | QIODevice::NewOnly)) {
@@ -229,7 +219,6 @@ void FileTreeView::SlotTouchBelowAtSelectedItem() {
QLineEdit::Normal, new_file_name, &ok);
if (ok && !new_file_name.isEmpty()) {
auto file_path = root_path + "/" + new_file_name;
- GF_UI_LOG_DEBUG("new file path: {}", file_path);
QFile new_file(file_path);
if (!new_file.open(QIODevice::WriteOnly | QIODevice::NewOnly)) {
@@ -272,7 +261,7 @@ void FileTreeView::SlotRenameSelectedItem() {
if (ok && !text.isEmpty()) {
auto file_info = QFileInfo(selected_path_);
auto new_name_path = file_info.absolutePath() + "/" + text;
- GF_UI_LOG_DEBUG("new filename path: {}", new_name_path);
+
if (!QDir().rename(file_info.absoluteFilePath(), new_name_path)) {
QMessageBox::critical(this, tr("Error"),
tr("Unable to rename the file or folder."));
@@ -355,8 +344,6 @@ void FileTreeView::slot_show_custom_context_menu(const QPoint& point) {
auto target_path = this->GetPathByClickPoint(point);
auto select_path = GetSelectedPath();
- GF_UI_LOG_DEBUG("file tree view, target path: {}, select path: {}",
- target_path, select_path);
if (target_path.isEmpty() && !select_path.isEmpty()) {
target_path = select_path;
}
@@ -404,8 +391,9 @@ void FileTreeView::slot_calculate_hash() {
return;
}
auto result = ExtractParams<QString>(data_object, 0);
- emit UISignalStation::GetInstance()->SignalRefreshInfoBoard(
- result, InfoBoardStatus::INFO_ERROR_OK);
+ emit UISignalStation::GetInstance()
+ -> SignalRefreshInfoBoard(result,
+ InfoBoardStatus::INFO_ERROR_OK);
},
"calculate_file_hash");
});
diff --git a/src/ui/widgets/GRTTreeView.cpp b/src/ui/widgets/GRTTreeView.cpp
index 09d7dcf0..b52f6881 100644
--- a/src/ui/widgets/GRTTreeView.cpp
+++ b/src/ui/widgets/GRTTreeView.cpp
@@ -35,7 +35,7 @@ namespace GpgFrontend::UI {
GRTTreeView::GRTTreeView(QWidget* parent) : QTreeView(parent) {
setModel(new Module::GlobalRegisterTableTreeModel(
- Module::ModuleManager::GetInstance().GRT()));
+ Module::ModuleManager::GetInstance().GRT(), this));
connect(model(), &QFileSystemModel::layoutChanged, this,
&GRTTreeView::slot_adjust_column_widths);
diff --git a/src/ui/widgets/HelpPage.cpp b/src/ui/widgets/HelpPage.cpp
index 78169944..cf56564c 100644
--- a/src/ui/widgets/HelpPage.cpp
+++ b/src/ui/widgets/HelpPage.cpp
@@ -28,6 +28,8 @@
#include "ui/widgets/HelpPage.h"
+#include "core/function/GlobalSettingStation.h"
+
namespace GpgFrontend::UI {
HelpPage::HelpPage(const QString& path, QWidget* parent) : QWidget(parent) {
@@ -64,7 +66,10 @@ auto HelpPage::localized_help(const QUrl& url) -> QUrl {
QStringList fileparts = filename.split(".");
// QSettings settings;
- QString lang = QSettings().value("int/lang", QLocale().name()).toString();
+ QString lang = GlobalSettingStation::GetInstance()
+ .GetSettings()
+ .value("int/lang", QLocale().name())
+ .toString();
if (lang.isEmpty()) {
lang = QLocale().name();
}
diff --git a/src/ui/widgets/InfoBoardWidget.cpp b/src/ui/widgets/InfoBoardWidget.cpp
index 425e6ccd..10b8ad83 100644
--- a/src/ui/widgets/InfoBoardWidget.cpp
+++ b/src/ui/widgets/InfoBoardWidget.cpp
@@ -115,7 +115,6 @@ void InfoBoardWidget::AssociateTabWidget(QTabWidget* tab) {
void InfoBoardWidget::AddOptionalAction(const QString& name,
const std::function<void()>& action) {
- GF_UI_LOG_DEBUG("add option action: {}", name);
auto* action_button = new QPushButton(name);
auto* layout = new QHBoxLayout();
layout->setContentsMargins(5, 0, 5, 0);
@@ -165,7 +164,6 @@ void InfoBoardWidget::slot_copy() {
void InfoBoardWidget::slot_save() {
auto file_path = QFileDialog::getSaveFileName(
this, tr("Save Information Board's Content"), {}, tr("Text (*.txt)"));
- GF_UI_LOG_DEBUG("file path: {}", file_path);
if (file_path.isEmpty()) return;
QFile file(file_path);
diff --git a/src/ui/widgets/KeyList.cpp b/src/ui/widgets/KeyList.cpp
index be79a6fd..6ddf62a3 100644
--- a/src/ui/widgets/KeyList.cpp
+++ b/src/ui/widgets/KeyList.cpp
@@ -29,7 +29,7 @@
#include "ui/widgets/KeyList.h"
#include <cstddef>
-#include <mutex>
+#include <utility>
#include "core/function/GlobalSettingStation.h"
#include "core/function/gpg/GpgKeyGetter.h"
@@ -40,27 +40,143 @@
namespace GpgFrontend::UI {
-KeyList::KeyList(KeyMenuAbility::AbilityType menu_ability, QWidget* parent)
+KeyList::KeyList(KeyMenuAbility menu_ability,
+ GpgKeyTableColumn fixed_columns_filter, QWidget* parent)
: QWidget(parent),
ui_(GpgFrontend::SecureCreateSharedObject<Ui_KeyList>()),
- menu_ability_(menu_ability) {
+ menu_ability_(menu_ability),
+ model_(GpgKeyGetter::GetInstance().GetGpgKeyTableModel()),
+ fixed_columns_filter_(fixed_columns_filter),
+ global_column_filter_(static_cast<GpgKeyTableColumn>(
+ GlobalSettingStation::GetInstance()
+ .GetSettings()
+ .value("keys/global_columns_filter",
+ static_cast<unsigned int>(GpgKeyTableColumn::kALL))
+ .toUInt())) {
init();
}
void KeyList::init() {
ui_->setupUi(this);
- ui_->menuWidget->setHidden(menu_ability_ == 0U);
+ ui_->menuWidget->setHidden(menu_ability_ == KeyMenuAbility::kNONE);
ui_->refreshKeyListButton->setHidden(~menu_ability_ &
- KeyMenuAbility::REFRESH);
- ui_->syncButton->setHidden(~menu_ability_ & KeyMenuAbility::SYNC_PUBLIC_KEY);
- ui_->uncheckButton->setHidden(~menu_ability_ & KeyMenuAbility::UNCHECK_ALL);
- ui_->searchBarEdit->setHidden(~menu_ability_ & KeyMenuAbility::SEARCH_BAR);
+ KeyMenuAbility::kREFRESH);
+ ui_->syncButton->setHidden(~menu_ability_ & KeyMenuAbility::kSYNC_PUBLIC_KEY);
+ ui_->checkALLButton->setHidden(~menu_ability_ & KeyMenuAbility::kCHECK_ALL);
+ ui_->uncheckButton->setHidden(~menu_ability_ & KeyMenuAbility::kUNCHECK_ALL);
+ ui_->columnTypeButton->setHidden(~menu_ability_ &
+ KeyMenuAbility::kCOLUMN_FILTER);
+ ui_->searchBarEdit->setHidden(~menu_ability_ & KeyMenuAbility::kSEARCH_BAR);
+
+ auto* column_type_menu = new QMenu(this);
+
+ key_id_column_action_ = new QAction(tr("Key ID"), this);
+ key_id_column_action_->setCheckable(true);
+ key_id_column_action_->setChecked(
+ (global_column_filter_ & GpgKeyTableColumn::kKEY_ID) !=
+ GpgKeyTableColumn::kNONE);
+ connect(key_id_column_action_, &QAction::toggled, this, [=](bool checked) {
+ UpdateKeyTableColumnType(
+ checked ? global_column_filter_ | GpgKeyTableColumn::kKEY_ID
+ : global_column_filter_ & ~GpgKeyTableColumn::kKEY_ID);
+ });
+
+ algo_column_action_ = new QAction(tr("Algorithm"), this);
+ algo_column_action_->setCheckable(true);
+ algo_column_action_->setChecked(
+ (global_column_filter_ & GpgKeyTableColumn::kALGO) !=
+ GpgKeyTableColumn::kNONE);
+ connect(algo_column_action_, &QAction::toggled, this, [=](bool checked) {
+ UpdateKeyTableColumnType(
+ checked ? global_column_filter_ | GpgKeyTableColumn::kALGO
+ : global_column_filter_ & ~GpgKeyTableColumn::kALGO);
+ });
+
+ owner_trust_column_action_ = new QAction(tr("Owner Trust"), this);
+ owner_trust_column_action_->setCheckable(true);
+ owner_trust_column_action_->setChecked(
+ (global_column_filter_ & GpgKeyTableColumn::kOWNER_TRUST) !=
+ GpgKeyTableColumn::kNONE);
+ connect(
+ owner_trust_column_action_, &QAction::toggled, this, [=](bool checked) {
+ UpdateKeyTableColumnType(
+ checked ? global_column_filter_ | GpgKeyTableColumn::kOWNER_TRUST
+ : global_column_filter_ & ~GpgKeyTableColumn::kOWNER_TRUST);
+ });
+
+ create_date_column_action_ = new QAction(tr("Create Date"), this);
+ create_date_column_action_->setCheckable(true);
+ create_date_column_action_->setChecked(
+ (global_column_filter_ & GpgKeyTableColumn::kCREATE_DATE) !=
+ GpgKeyTableColumn::kNONE);
+ connect(
+ create_date_column_action_, &QAction::toggled, this, [=](bool checked) {
+ UpdateKeyTableColumnType(
+ checked ? global_column_filter_ | GpgKeyTableColumn::kCREATE_DATE
+ : global_column_filter_ & ~GpgKeyTableColumn::kCREATE_DATE);
+ });
+
+ subkeys_number_column_action_ = new QAction("Subkey(s)", this);
+ subkeys_number_column_action_->setCheckable(true);
+ subkeys_number_column_action_->setChecked(
+ (global_column_filter_ & GpgKeyTableColumn::kSUBKEYS_NUMBER) !=
+ GpgKeyTableColumn::kNONE);
+ connect(
+ subkeys_number_column_action_, &QAction::toggled, this,
+ [=](bool checked) {
+ UpdateKeyTableColumnType(
+ checked
+ ? global_column_filter_ | GpgKeyTableColumn::kSUBKEYS_NUMBER
+ : global_column_filter_ & ~GpgKeyTableColumn::kSUBKEYS_NUMBER);
+ });
+
+ comment_column_action_ = new QAction("Comment", this);
+ comment_column_action_->setCheckable(true);
+ comment_column_action_->setChecked(
+ (global_column_filter_ & GpgKeyTableColumn::kCOMMENT) !=
+ GpgKeyTableColumn::kNONE);
+ connect(comment_column_action_, &QAction::toggled, this, [=](bool checked) {
+ UpdateKeyTableColumnType(
+ checked ? global_column_filter_ | GpgKeyTableColumn::kCOMMENT
+ : global_column_filter_ & ~GpgKeyTableColumn::kCOMMENT);
+ });
+
+ if ((fixed_columns_filter_ & GpgKeyTableColumn::kKEY_ID) !=
+ GpgKeyTableColumn::kNONE) {
+ column_type_menu->addAction(key_id_column_action_);
+ }
+
+ if ((fixed_columns_filter_ & GpgKeyTableColumn::kALGO) !=
+ GpgKeyTableColumn::kNONE) {
+ column_type_menu->addAction(algo_column_action_);
+ }
+ if ((fixed_columns_filter_ & GpgKeyTableColumn::kCREATE_DATE) !=
+ GpgKeyTableColumn::kNONE) {
+ column_type_menu->addAction(create_date_column_action_);
+ }
+
+ if ((fixed_columns_filter_ & GpgKeyTableColumn::kOWNER_TRUST) !=
+ GpgKeyTableColumn::kNONE) {
+ column_type_menu->addAction(owner_trust_column_action_);
+ }
+
+ if ((fixed_columns_filter_ & GpgKeyTableColumn::kSUBKEYS_NUMBER) !=
+ GpgKeyTableColumn::kNONE) {
+ column_type_menu->addAction(subkeys_number_column_action_);
+ }
+
+ if ((fixed_columns_filter_ & GpgKeyTableColumn::kCOMMENT) !=
+ GpgKeyTableColumn::kNONE) {
+ column_type_menu->addAction(comment_column_action_);
+ }
+
+ ui_->columnTypeButton->setMenu(column_type_menu);
ui_->keyGroupTab->clear();
popup_menu_ = new QMenu(this);
- bool forbid_all_gnupg_connection =
+ auto forbid_all_gnupg_connection =
GlobalSettingStation::GetInstance()
.GetSettings()
.value("network/forbid_all_gnupg_connection", false)
@@ -93,6 +209,11 @@ void KeyList::init() {
connect(this, &KeyList::SignalRefreshStatusBar,
UISignalStation::GetInstance(),
&UISignalStation::SignalRefreshStatusBar);
+ connect(this, &KeyList::SignalColumnTypeChange, this, [=]() {
+ GlobalSettingStation::GetInstance().GetSettings().setValue(
+ "keys/global_columns_filter",
+ static_cast<unsigned int>(global_column_filter_));
+ });
setAcceptDrops(true);
@@ -112,120 +233,72 @@ void KeyList::init() {
}
void KeyList::AddListGroupTab(const QString& name, const QString& id,
- KeyListRow::KeyType selectType,
- KeyListColumn::InfoType infoType,
- const KeyTable::KeyTableFilter filter) {
- GF_UI_LOG_DEBUG("add list group tab: {}", name);
-
- auto* key_list = new QTableWidget(this);
- if (m_key_list_ == nullptr) {
- m_key_list_ = key_list;
- }
- key_list->setObjectName(id);
- ui_->keyGroupTab->addTab(key_list, name);
- m_key_tables_.emplace_back(key_list, selectType, infoType, filter);
- m_key_tables_.back().SetMenuAbility(menu_ability_);
-
- key_list->setColumnCount(8);
- key_list->horizontalHeader()->setSectionResizeMode(
- QHeaderView::ResizeToContents);
- key_list->verticalHeader()->hide();
- key_list->setShowGrid(false);
- key_list->sortByColumn(2, Qt::AscendingOrder);
- key_list->setSelectionBehavior(QAbstractItemView::SelectRows);
- key_list->setSelectionMode(QAbstractItemView::SingleSelection);
-
- // table items not editable
- key_list->setEditTriggers(QAbstractItemView::NoEditTriggers);
- // no focus (rectangle around table items)
- // maybe it should focus on whole row
- key_list->setFocusPolicy(Qt::NoFocus);
-
- key_list->setAlternatingRowColors(true);
-
- // Hidden Column For Purpose
- if ((infoType & KeyListColumn::TYPE) == 0U) {
- key_list->setColumnHidden(1, true);
- }
- if ((infoType & KeyListColumn::NAME) == 0U) {
- key_list->setColumnHidden(2, true);
- }
- if ((infoType & KeyListColumn::EmailAddress) == 0U) {
- key_list->setColumnHidden(3, true);
- }
- if ((infoType & KeyListColumn::Usage) == 0U) {
- key_list->setColumnHidden(4, true);
- }
- if ((infoType & KeyListColumn::Validity) == 0U) {
- key_list->setColumnHidden(5, true);
- }
- if ((infoType & KeyListColumn::KeyID) == 0U) {
- key_list->setColumnHidden(6, true);
- }
- if ((infoType & KeyListColumn::FingerPrint) == 0U) {
- key_list->setColumnHidden(7, true);
- }
+ GpgKeyTableDisplayMode display_mode,
+ GpgKeyTableProxyModel::KeyFilter search_filter,
+ GpgKeyTableColumn custom_columns_filter) {
+ auto* key_table =
+ new KeyTable(this, model_, display_mode, custom_columns_filter,
+ std::move(search_filter));
- QStringList labels;
- labels << tr("Select") << tr("Type") << tr("Name") << tr("Email Address")
- << tr("Usage") << tr("Trust") << tr("Key ID") << tr("Finger Print");
+ key_table->setObjectName(id);
+ ui_->keyGroupTab->addTab(key_table, name);
- key_list->setHorizontalHeaderLabels(labels);
- key_list->horizontalHeader()->setStretchLastSection(false);
+ connect(this, &KeyList::SignalColumnTypeChange, key_table,
+ &KeyTable::SignalColumnTypeChange);
- connect(key_list, &QTableWidget::doubleClicked, this,
- &KeyList::slot_double_clicked);
+ UpdateKeyTableColumnType(global_column_filter_);
}
void KeyList::SlotRefresh() {
- GF_UI_LOG_DEBUG("refresh, address: {}", static_cast<void*>(this));
-
ui_->refreshKeyListButton->setDisabled(true);
ui_->syncButton->setDisabled(true);
+ model_ = GpgKeyGetter::GetInstance().GetGpgKeyTableModel();
+
+ for (int i = 0; i < ui_->keyGroupTab->count(); i++) {
+ auto* key_table = qobject_cast<KeyTable*>(ui_->keyGroupTab->widget(i));
+ key_table->RefreshModel(model_);
+ }
+
emit SignalRefreshStatusBar(tr("Refreshing Key List..."), 3000);
- this->buffered_keys_list_ = GpgKeyGetter::GetInstance().FetchKey();
- this->slot_refresh_ui();
+ this->model_ = GpgKeyGetter::GetInstance().GetGpgKeyTableModel();
+
+ this->SlotRefreshUI();
}
void KeyList::SlotRefreshUI() {
- GF_UI_LOG_DEBUG("refresh, address: {}", static_cast<void*>(this));
- this->slot_refresh_ui();
+ emit SignalRefreshStatusBar(tr("Key List Refreshed."), 1000);
+ ui_->refreshKeyListButton->setDisabled(false);
+ ui_->syncButton->setDisabled(false);
}
auto KeyList::GetChecked(const KeyTable& key_table) -> KeyIdArgsListPtr {
auto ret = std::make_unique<KeyIdArgsList>();
- for (int i = 0; i < key_table.key_list_->rowCount(); i++) {
- if (key_table.key_list_->item(i, 0)->checkState() == Qt::Checked) {
- ret->push_back(key_table.buffered_keys_[i].GetId());
+ for (int i = 0; i < key_table.GetRowCount(); i++) {
+ if (key_table.IsRowChecked(i)) {
+ ret->push_back(key_table.GetKeyIdByRow(i));
}
}
return ret;
}
auto KeyList::GetChecked() -> KeyIdArgsListPtr {
- auto* key_list =
- qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget());
- const auto& buffered_keys =
- m_key_tables_[ui_->keyGroupTab->currentIndex()].buffered_keys_;
+ auto* key_table = qobject_cast<KeyTable*>(ui_->keyGroupTab->currentWidget());
auto ret = std::make_unique<KeyIdArgsList>();
- for (int i = 0; i < key_list->rowCount(); i++) {
- if (key_list->item(i, 0)->checkState() == Qt::Checked) {
- ret->push_back(buffered_keys[i].GetId());
+ for (int i = 0; i < key_table->GetRowCount(); i++) {
+ if (key_table->IsRowChecked(i)) {
+ ret->push_back(key_table->GetKeyIdByRow(i));
}
}
return ret;
}
auto KeyList::GetAllPrivateKeys() -> KeyIdArgsListPtr {
- auto* key_list =
- qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget());
- const auto& buffered_keys =
- m_key_tables_[ui_->keyGroupTab->currentIndex()].buffered_keys_;
+ auto* key_table = qobject_cast<KeyTable*>(ui_->keyGroupTab->currentWidget());
auto ret = std::make_unique<KeyIdArgsList>();
- for (int i = 0; i < key_list->rowCount(); i++) {
- if ((key_list->item(i, 1) != nullptr) && buffered_keys[i].IsPrivateKey()) {
- ret->push_back(buffered_keys[i].GetId());
+ for (int i = 0; i < key_table->GetRowCount(); i++) {
+ if (key_table->IsPrivateKeyByRow(i)) {
+ ret->push_back(key_table->GetKeyIdByRow(i));
}
}
return ret;
@@ -235,16 +308,11 @@ auto KeyList::GetCheckedPrivateKey() -> KeyIdArgsListPtr {
auto ret = std::make_unique<KeyIdArgsList>();
if (ui_->keyGroupTab->size().isEmpty()) return ret;
- auto* key_list =
- qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget());
- const auto& buffered_keys =
- m_key_tables_[ui_->keyGroupTab->currentIndex()].buffered_keys_;
-
- for (int i = 0; i < key_list->rowCount(); i++) {
- if ((key_list->item(i, 0)->checkState() == Qt::Checked) &&
- ((key_list->item(i, 1)) != nullptr) &&
- buffered_keys[i].IsPrivateKey()) {
- ret->push_back(buffered_keys[i].GetId());
+ auto* key_table = qobject_cast<KeyTable*>(ui_->keyGroupTab->currentWidget());
+
+ for (int i = 0; i < key_table->GetRowCount(); i++) {
+ if (key_table->IsRowChecked(i) && key_table->IsPrivateKeyByRow(i)) {
+ ret->push_back(key_table->GetKeyIdByRow(i));
}
}
return ret;
@@ -254,16 +322,11 @@ auto KeyList::GetCheckedPublicKey() -> KeyIdArgsListPtr {
auto ret = std::make_unique<KeyIdArgsList>();
if (ui_->keyGroupTab->size().isEmpty()) return ret;
- auto* key_list =
- qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget());
- const auto& buffered_keys =
- m_key_tables_[ui_->keyGroupTab->currentIndex()].buffered_keys_;
-
- for (int i = 0; i < key_list->rowCount(); i++) {
- if ((key_list->item(i, 0)->checkState() == Qt::Checked) &&
- ((key_list->item(i, 1)) != nullptr) &&
- !buffered_keys[i].IsPrivateKey()) {
- ret->push_back(buffered_keys[i].GetId());
+ auto* key_table = qobject_cast<KeyTable*>(ui_->keyGroupTab->currentWidget());
+
+ for (int i = 0; i < key_table->GetRowCount(); i++) {
+ if (key_table->IsRowChecked(i) && key_table->IsPublicKeyByRow(i)) {
+ ret->push_back(key_table->GetKeyIdByRow(i));
}
}
return ret;
@@ -272,52 +335,43 @@ auto KeyList::GetCheckedPublicKey() -> KeyIdArgsListPtr {
void KeyList::SetChecked(const KeyIdArgsListPtr& keyIds,
const KeyTable& key_table) {
if (!keyIds->empty()) {
- for (int i = 0; i < key_table.key_list_->rowCount(); i++) {
+ for (int i = 0; i < key_table.GetRowCount(); i++) {
if (std::find(keyIds->begin(), keyIds->end(),
- key_table.buffered_keys_[i].GetId()) != keyIds->end()) {
- key_table.key_list_->item(i, 0)->setCheckState(Qt::Checked);
- }
- }
- }
-}
-
-void KeyList::SetChecked(KeyIdArgsListPtr key_ids) {
- auto* key_list =
- qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget());
- if (key_list == nullptr) return;
- if (!m_key_tables_.empty()) {
- for (auto& key_table : m_key_tables_) {
- if (key_table.key_list_ == key_list) {
- key_table.SetChecked(std::move(key_ids));
- break;
+ key_table.GetKeyIdByRow(i)) != keyIds->end()) {
+ key_table.SetRowChecked(i);
}
}
}
}
-KeyIdArgsListPtr KeyList::GetSelected() {
+auto KeyList::GetSelected() -> KeyIdArgsListPtr {
auto ret = std::make_unique<KeyIdArgsList>();
if (ui_->keyGroupTab->size().isEmpty()) return ret;
- auto* key_list =
- qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget());
- const auto& buffered_keys =
- m_key_tables_[ui_->keyGroupTab->currentIndex()].buffered_keys_;
+ auto* key_table = qobject_cast<KeyTable*>(ui_->keyGroupTab->currentWidget());
+ if (key_table == nullptr) {
+ qCWarning(ui, "fail to get current key table, nullptr");
+ return ret;
+ }
- for (int i = 0; i < key_list->rowCount(); i++) {
- if (key_list->item(i, 0)->isSelected()) {
- ret->push_back(buffered_keys[i].GetId());
- }
+ QItemSelectionModel* select = key_table->selectionModel();
+ for (auto index : select->selectedRows()) {
+ ret->push_back(key_table->GetKeyIdByRow(index.row()));
+ }
+
+ if (ret->empty()) {
+ qCWarning(ui, "nothing is selected at key list");
}
return ret;
}
[[maybe_unused]] auto KeyList::ContainsPrivateKeys() -> bool {
if (ui_->keyGroupTab->size().isEmpty()) return false;
- m_key_list_ = qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget());
+ auto* key_table =
+ qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget());
- for (int i = 0; i < m_key_list_->rowCount(); i++) {
- if (m_key_list_->item(i, 1) != nullptr) {
+ for (int i = 0; i < key_table->rowCount(); i++) {
+ if (key_table->item(i, 1) != nullptr) {
return true;
}
}
@@ -326,21 +380,24 @@ KeyIdArgsListPtr KeyList::GetSelected() {
void KeyList::SetColumnWidth(int row, int size) {
if (ui_->keyGroupTab->size().isEmpty()) return;
- m_key_list_ = qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget());
-
- m_key_list_->setColumnWidth(row, size);
+ auto* key_table = qobject_cast<KeyTable*>(ui_->keyGroupTab->currentWidget());
+ key_table->setColumnWidth(row, size);
}
void KeyList::contextMenuEvent(QContextMenuEvent* event) {
- if (ui_->keyGroupTab->size().isEmpty()) return;
- m_key_list_ = qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget());
+ if (ui_->keyGroupTab->count() == 0) return;
+ auto* key_table = qobject_cast<KeyTable*>(ui_->keyGroupTab->currentWidget());
+
+ if (key_table == nullptr) {
+ qCDebug(ui, "m_key_list_ is nullptr, key group tab number: %d",
+ ui_->keyGroupTab->count());
+ return;
+ }
QString current_tab_widget_obj_name =
ui_->keyGroupTab->widget(ui_->keyGroupTab->currentIndex())->objectName();
- GF_UI_LOG_DEBUG("current tab widget object name: {}",
- current_tab_widget_obj_name);
if (current_tab_widget_obj_name == "favourite") {
- QList<QAction*> actions = popup_menu_->actions();
+ auto actions = popup_menu_->actions();
for (QAction* action : actions) {
if (action->data().toString() == "remove_key_from_favourtie_action") {
action->setVisible(true);
@@ -349,7 +406,7 @@ void KeyList::contextMenuEvent(QContextMenuEvent* event) {
}
}
} else {
- QList<QAction*> actions = popup_menu_->actions();
+ auto actions = popup_menu_->actions();
for (QAction* action : actions) {
if (action->data().toString() == "remove_key_from_favourtie_action") {
action->setVisible(false);
@@ -359,7 +416,7 @@ void KeyList::contextMenuEvent(QContextMenuEvent* event) {
}
}
- if (m_key_list_->selectedItems().length() > 0) {
+ if (key_table->GetRowSelected() >= 0) {
popup_menu_->exec(event->globalPos());
}
}
@@ -379,7 +436,7 @@ void KeyList::dropEvent(QDropEvent* event) {
// "always import keys"-CheckBox
auto* check_box = new QCheckBox(tr("Always import without bothering."));
- bool confirm_import_keys = GlobalSettingStation::GetInstance()
+ auto confirm_import_keys = GlobalSettingStation::GetInstance()
.GetSettings()
.value("basic/confirm_import_keys", true)
.toBool();
@@ -411,14 +468,14 @@ void KeyList::dropEvent(QDropEvent* event) {
QFile file;
file.setFileName(tmp.toLocalFile());
if (!file.open(QIODevice::ReadOnly)) {
- GF_UI_LOG_ERROR("couldn't open file: {}", tmp.toString());
+ qCWarning(ui) << "couldn't open file: " << tmp.toString();
}
- QByteArray in_buffer = file.readAll();
+ auto in_buffer = file.readAll();
this->import_keys(in_buffer);
file.close();
}
} else {
- QByteArray in_buffer(event->mimeData()->text().toUtf8());
+ auto in_buffer(event->mimeData()->text().toUtf8());
this->import_keys(in_buffer);
}
}
@@ -435,11 +492,11 @@ void KeyList::import_keys(const QByteArray& in_buffer) {
void KeyList::slot_double_clicked(const QModelIndex& index) {
if (ui_->keyGroupTab->size().isEmpty()) return;
- const auto& buffered_keys =
- m_key_tables_[ui_->keyGroupTab->currentIndex()].buffered_keys_;
+
+ auto* key_table = qobject_cast<KeyTable*>(ui_->keyGroupTab->currentWidget());
if (m_action_ != nullptr) {
- const auto key =
- GpgKeyGetter::GetInstance().GetKey(buffered_keys[index.row()].GetId());
+ const auto key = GpgKeyGetter::GetInstance().GetKey(
+ key_table->GetKeyIdByRow(index.row()));
m_action_(key, this);
}
}
@@ -451,30 +508,15 @@ void KeyList::SetDoubleClickedAction(
auto KeyList::GetSelectedKey() -> QString {
if (ui_->keyGroupTab->size().isEmpty()) return {};
- const auto& buffered_keys =
- m_key_tables_[ui_->keyGroupTab->currentIndex()].buffered_keys_;
- for (int i = 0; i < m_key_list_->rowCount(); i++) {
- if (m_key_list_->item(i, 0)->isSelected()) {
- return buffered_keys[i].GetId();
- }
- }
- return {};
-}
+ auto* key_table = qobject_cast<KeyTable*>(ui_->keyGroupTab->currentWidget());
-void KeyList::slot_refresh_ui() {
- GF_UI_LOG_DEBUG("refresh: {}", static_cast<void*>(buffered_keys_list_.get()));
- if (buffered_keys_list_ != nullptr) {
- std::lock_guard<std::mutex> guard(buffered_key_list_mutex_);
+ QItemSelectionModel* select = key_table->selectionModel();
- for (auto& key_table : m_key_tables_) {
- key_table.Refresh(
- GpgKeyGetter::GetInstance().GetKeysCopy(buffered_keys_list_));
- }
- }
- emit SignalRefreshStatusBar(tr("Key List Refreshed."), 1000);
- ui_->refreshKeyListButton->setDisabled(false);
- ui_->syncButton->setDisabled(false);
+ auto selected_rows = select->selectedRows();
+ if (selected_rows.empty()) return {};
+
+ return key_table->GetKeyIdByRow(selected_rows.first().row());
}
void KeyList::slot_sync_with_key_server() {
@@ -490,14 +532,12 @@ void KeyList::slot_sync_with_key_server() {
QMessageBox::Yes | QMessageBox::No);
if (reply == QMessageBox::No) return;
- {
- std::lock_guard<std::mutex> guard(buffered_key_list_mutex_);
- for (const auto& key : *buffered_keys_list_) {
- if (!(key.IsPrivateKey() && key.IsHasMasterKey())) {
- key_ids.push_back(key.GetId());
- }
- }
+
+ auto all_key_ids = model_->GetAllKeyIds();
+ for (auto& key_id : all_key_ids) {
+ key_ids.push_back(key_id);
}
+
} else {
key_ids = *checked_public_keys;
}
@@ -511,8 +551,6 @@ void KeyList::slot_sync_with_key_server() {
CommonUtils::SlotImportKeyFromKeyServer(
key_ids, [=](const QString& key_id, const QString& status,
size_t current_index, size_t all_index) {
- GF_UI_LOG_DEBUG("import key: {} {} {} {}", key_id, status,
- current_index, all_index);
auto key = GpgKeyGetter::GetInstance().GetKey(key_id);
auto status_str = tr("Sync [%1/%2] %3 %4")
@@ -535,226 +573,31 @@ void KeyList::filter_by_keyword() {
auto keyword = ui_->searchBarEdit->text();
keyword = keyword.trimmed();
- GF_UI_LOG_DEBUG("get new keyword of search bar: {}", keyword);
- for (auto& table : m_key_tables_) {
+ for (int i = 0; i < ui_->keyGroupTab->count(); i++) {
+ auto* key_table = qobject_cast<KeyTable*>(ui_->keyGroupTab->widget(i));
// refresh arguments
- table.SetFilterKeyword(keyword.toLower());
- table.SetMenuAbility(menu_ability_);
+ key_table->SetFilterKeyword(keyword.toLower());
}
+
// refresh ui
SlotRefreshUI();
}
void KeyList::uncheck_all() {
- auto* key_list =
- qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget());
- if (key_list == nullptr) return;
- if (!m_key_tables_.empty()) {
- for (auto& key_table : m_key_tables_) {
- if (key_table.key_list_ == key_list) {
- key_table.UncheckALL();
- break;
- }
- }
- }
+ auto* key_table = qobject_cast<KeyTable*>(ui_->keyGroupTab->currentWidget());
+ if (key_table == nullptr) return;
+ key_table->UncheckAll();
}
void KeyList::check_all() {
- auto* key_list =
- qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget());
- if (key_list == nullptr) return;
- if (!m_key_tables_.empty()) {
- for (auto& key_table : m_key_tables_) {
- if (key_table.key_list_ == key_list) {
- key_table.CheckALL();
- break;
- }
- }
- }
-}
-
-KeyIdArgsListPtr& KeyTable::GetChecked() {
- if (checked_key_ids_ == nullptr) {
- checked_key_ids_ = std::make_unique<KeyIdArgsList>();
- }
- auto& ret = checked_key_ids_;
- for (size_t i = 0; i < buffered_keys_.size(); i++) {
- auto key_id = buffered_keys_[i].GetId();
- if (key_list_->item(i, 0)->checkState() == Qt::Checked &&
- std::find(ret->begin(), ret->end(), key_id) == ret->end()) {
- ret->push_back(key_id);
- }
- }
- return ret;
-}
-
-void KeyTable::SetChecked(KeyIdArgsListPtr key_ids) {
- checked_key_ids_ = std::move(key_ids);
-}
-
-void KeyTable::Refresh(KeyLinkListPtr m_keys) {
- auto& checked_key_list = GetChecked();
- // while filling the table, sort enabled causes errors
-
- key_list_->setSortingEnabled(false);
- key_list_->clearContents();
-
- // Optimization for copy
- KeyLinkListPtr keys = nullptr;
- if (m_keys == nullptr) {
- keys = GpgKeyGetter::GetInstance().FetchKey();
- } else {
- keys = std::move(m_keys);
- }
-
- auto it = keys->begin();
- int row_count = 0;
-
- while (it != keys->end()) {
- // filter by search bar's keyword
- if (ability_ & KeyMenuAbility::SEARCH_BAR && !keyword_.isEmpty()) {
- QStringList infos;
- infos << it->GetName().toLower() << it->GetEmail().toLower()
- << it->GetComment().toLower() << it->GetFingerprint().toLower();
-
- auto subkeys = it->GetSubKeys();
- for (const auto& subkey : *subkeys) {
- infos << subkey.GetFingerprint().toLower() << subkey.GetID().toLower();
- }
-
- if (infos.filter(keyword_.toLower()).isEmpty()) {
- it = keys->erase(it);
- continue;
- }
- }
-
- if (filter_ != nullptr) {
- if (!filter_(*it, *this)) {
- it = keys->erase(it);
- continue;
- }
- }
-
- if (select_type_ == KeyListRow::ONLY_SECRET_KEY && !it->IsPrivateKey()) {
- it = keys->erase(it);
- continue;
- }
- row_count++;
- it++;
- }
-
- key_list_->setRowCount(row_count);
-
- int row_index = 0;
- it = keys->begin();
-
- buffered_keys_.clear();
-
- while (it != keys->end()) {
- auto* tmp0 = new QTableWidgetItem(QString::number(row_index));
- tmp0->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled |
- Qt::ItemIsSelectable);
- tmp0->setTextAlignment(Qt::AlignCenter);
- tmp0->setCheckState(Qt::Unchecked);
- key_list_->setItem(row_index, 0, tmp0);
-
- QString type_str;
- QTextStream type_steam(&type_str);
- if (it->IsPrivateKey()) {
- type_steam << "pub/sec";
- } else {
- type_steam << "pub";
- }
-
- if (it->IsPrivateKey() && !it->IsHasMasterKey()) {
- type_steam << "#";
- }
-
- if (it->IsHasCardKey()) {
- type_steam << "^";
- }
-
- auto* tmp1 = new QTableWidgetItem(type_str);
- key_list_->setItem(row_index, 1, tmp1);
-
- auto* tmp2 = new QTableWidgetItem(it->GetName());
- key_list_->setItem(row_index, 2, tmp2);
- auto* tmp3 = new QTableWidgetItem(it->GetEmail());
- key_list_->setItem(row_index, 3, tmp3);
-
- QString usage;
- QTextStream usage_steam(&usage);
-
- if (it->IsHasActualCertificationCapability()) usage_steam << "C";
- if (it->IsHasActualEncryptionCapability()) usage_steam << "E";
- if (it->IsHasActualSigningCapability()) usage_steam << "S";
- if (it->IsHasActualAuthenticationCapability()) usage_steam << "A";
-
- auto* temp_usage = new QTableWidgetItem(usage);
- temp_usage->setTextAlignment(Qt::AlignCenter);
- key_list_->setItem(row_index, 4, temp_usage);
-
- auto* temp_validity = new QTableWidgetItem(it->GetOwnerTrust());
- temp_validity->setTextAlignment(Qt::AlignCenter);
- key_list_->setItem(row_index, 5, temp_validity);
-
- auto* temp_id = new QTableWidgetItem(it->GetId());
- temp_id->setTextAlignment(Qt::AlignCenter);
- key_list_->setItem(row_index, 6, temp_id);
-
- auto* temp_fpr = new QTableWidgetItem(it->GetFingerprint());
- temp_fpr->setTextAlignment(Qt::AlignCenter);
- key_list_->setItem(row_index, 7, temp_fpr);
-
- QFont font = tmp2->font();
-
- // strike out expired keys
- if (it->IsExpired() || it->IsRevoked()) font.setStrikeOut(true);
- if (it->IsPrivateKey()) font.setBold(true);
-
- tmp0->setFont(font);
- temp_usage->setFont(font);
- temp_fpr->setFont(font);
- temp_validity->setFont(font);
- tmp1->setFont(font);
- tmp2->setFont(font);
- tmp3->setFont(font);
- temp_id->setFont(font);
-
- // move to buffered keys
- buffered_keys_.emplace_back(std::move(*it));
-
- it++;
- ++row_index;
- }
-
- if (!checked_key_list->empty()) {
- for (int i = 0; i < key_list_->rowCount(); i++) {
- if (std::find(checked_key_list->begin(), checked_key_list->end(),
- buffered_keys_[i].GetId()) != checked_key_list->end()) {
- key_list_->item(i, 0)->setCheckState(Qt::Checked);
- }
- }
- }
-}
-
-void KeyTable::UncheckALL() const {
- for (int i = 0; i < key_list_->rowCount(); i++) {
- key_list_->item(i, 0)->setCheckState(Qt::Unchecked);
- }
+ auto* key_table = qobject_cast<KeyTable*>(ui_->keyGroupTab->currentWidget());
+ if (key_table == nullptr) return;
+ key_table->CheckAll();
}
-void KeyTable::CheckALL() const {
- for (int i = 0; i < key_list_->rowCount(); i++) {
- key_list_->item(i, 0)->setCheckState(Qt::Checked);
- }
-}
-
-void KeyTable::SetMenuAbility(KeyMenuAbility::AbilityType ability) {
- this->ability_ = ability;
+void KeyList::UpdateKeyTableColumnType(GpgKeyTableColumn column_type) {
+ global_column_filter_ = column_type;
+ emit SignalColumnTypeChange(fixed_columns_filter_ & global_column_filter_);
}
-void KeyTable::SetFilterKeyword(QString keyword) {
- this->keyword_ = std::move(keyword);
-}
} // namespace GpgFrontend::UI
diff --git a/src/ui/widgets/KeyList.h b/src/ui/widgets/KeyList.h
index 1761fb23..cbad6812 100644
--- a/src/ui/widgets/KeyList.h
+++ b/src/ui/widgets/KeyList.h
@@ -28,7 +28,7 @@
#pragma once
-#include "core/model/GpgKey.h"
+#include "ui/widgets/KeyTable.h"
class Ui_KeyList;
@@ -38,126 +38,39 @@ namespace GpgFrontend::UI {
* @brief
*
*/
-struct KeyListRow {
- using KeyType = unsigned int;
-
- static const KeyType SECRET_OR_PUBLIC_KEY = 0; ///<
- static const KeyType ONLY_SECRET_KEY = 1; ///<
+enum class KeyMenuAbility : unsigned int {
+ kNONE = 0,
+ kREFRESH = 1 << 0,
+ kSYNC_PUBLIC_KEY = 1 << 1,
+ kUNCHECK_ALL = 1 << 2,
+ kCHECK_ALL = 1 << 3,
+ kCOLUMN_FILTER = 1 << 4,
+ kSEARCH_BAR = 1 << 5,
+
+ kALL = ~0U
};
-/**
- * @brief
- *
- */
-struct KeyListColumn {
- using InfoType = unsigned int;
-
- static constexpr InfoType ALL = ~0; ///<
- static constexpr InfoType TYPE = 1 << 0; ///<
- static constexpr InfoType NAME = 1 << 1; ///<
- static constexpr InfoType EmailAddress = 1 << 2; ///<
- static constexpr InfoType Usage = 1 << 3; ///<
- static constexpr InfoType Validity = 1 << 4; ///<
- static constexpr InfoType FingerPrint = 1 << 5; ///<
- static constexpr InfoType KeyID = 1 << 6; ///<
-};
+inline auto operator|(KeyMenuAbility lhs, KeyMenuAbility rhs)
+ -> KeyMenuAbility {
+ using T = std::underlying_type_t<KeyMenuAbility>;
+ return static_cast<KeyMenuAbility>(static_cast<T>(lhs) | static_cast<T>(rhs));
+}
-/**
- * @brief
- *
- */
-struct KeyMenuAbility {
- using AbilityType = unsigned int;
-
- static constexpr AbilityType ALL = ~0; ///<
- static constexpr AbilityType NONE = 0; ///<
- static constexpr AbilityType REFRESH = 1 << 0; ///<
- static constexpr AbilityType SYNC_PUBLIC_KEY = 1 << 1; ///<
- static constexpr AbilityType UNCHECK_ALL = 1 << 3; ///<
- static constexpr AbilityType CHECK_ALL = 1 << 5; ///<
- static constexpr AbilityType SEARCH_BAR = 1 << 6; ///<
-};
+inline auto operator|=(KeyMenuAbility& lhs, KeyMenuAbility rhs)
+ -> KeyMenuAbility& {
+ lhs = lhs | rhs;
+ return lhs;
+}
-/**
- * @brief
- *
- */
-struct KeyTable {
- using KeyTableFilter = std::function<bool(const GpgKey&, const KeyTable&)>;
-
- QTableWidget* key_list_; ///<
- KeyListRow::KeyType select_type_; ///<
- KeyListColumn::InfoType info_type_; ///<
- std::vector<GpgKey> buffered_keys_; ///<
- KeyTableFilter filter_; ///<
- KeyIdArgsListPtr checked_key_ids_; ///<
- KeyMenuAbility::AbilityType ability_; ///<
- QString keyword_; ///<
+inline auto operator&(KeyMenuAbility lhs, KeyMenuAbility rhs) -> bool {
+ using T = std::underlying_type_t<KeyMenuAbility>;
+ return (static_cast<T>(lhs) & static_cast<T>(rhs)) != 0;
+}
- /**
- * @brief Construct a new Key Table object
- *
- * @param _key_list
- * @param _select_type
- * @param _info_type
- * @param _filter
- */
- KeyTable(
- QTableWidget* _key_list, KeyListRow::KeyType _select_type,
- KeyListColumn::InfoType _info_type,
- KeyTableFilter _filter = [](const GpgKey&, const KeyTable&) -> bool {
- return true;
- })
- : key_list_(_key_list),
- select_type_(_select_type),
- info_type_(_info_type),
- filter_(std::move(_filter)) {}
-
- /**
- * @brief
- *
- * @param m_keys
- */
- void Refresh(KeyLinkListPtr m_keys = nullptr);
-
- /**
- * @brief Get the Checked object
- *
- * @return KeyIdArgsListPtr&
- */
- KeyIdArgsListPtr& GetChecked();
-
- /**
- * @brief
- *
- */
- void UncheckALL() const;
-
- /**
- * @brief
- *
- */
- void CheckALL() const;
-
- /**
- * @brief Set the Checked object
- *
- * @param key_ids
- */
- void SetChecked(KeyIdArgsListPtr key_ids);
-
- /**
- * @brief
- *
- */
- void SetMenuAbility(KeyMenuAbility::AbilityType ability);
-
- /**
- * @brief
- *
- */
- void SetFilterKeyword(QString keyword);
-};
+inline auto operator~(KeyMenuAbility hs) -> KeyMenuAbility {
+ using T = std::underlying_type_t<GpgKeyTableColumn>;
+ return static_cast<KeyMenuAbility>(~static_cast<T>(hs));
+}
/**
* @brief
@@ -173,8 +86,10 @@ class KeyList : public QWidget {
* @param menu_ability
* @param parent
*/
- explicit KeyList(KeyMenuAbility::AbilityType menu_ability,
- QWidget* parent = nullptr);
+ explicit KeyList(
+ KeyMenuAbility menu_ability,
+ GpgKeyTableColumn fixed_column_filter = GpgKeyTableColumn::kALL,
+ QWidget* parent = nullptr);
/**
* @brief
@@ -186,10 +101,11 @@ class KeyList : public QWidget {
*/
void AddListGroupTab(
const QString& name, const QString& id,
- KeyListRow::KeyType selectType = KeyListRow::SECRET_OR_PUBLIC_KEY,
- KeyListColumn::InfoType infoType = KeyListColumn::ALL,
- KeyTable::KeyTableFilter filter =
- [](const GpgKey&, const KeyTable&) -> bool { return true; });
+ GpgKeyTableDisplayMode display_mode =
+ GpgKeyTableDisplayMode::kPRIVATE_KEY,
+ GpgKeyTableProxyModel::KeyFilter search_filter =
+ [](const GpgKey&) -> bool { return true; },
+ GpgKeyTableColumn custom_columns_filter = GpgKeyTableColumn::kALL);
/**
* @brief Set the Double Clicked Action object
@@ -259,17 +175,10 @@ class KeyList : public QWidget {
/**
* @brief Set the Checked object
*
- * @param key_ids
- */
- void SetChecked(KeyIdArgsListPtr key_ids);
-
- /**
- * @brief Set the Checked object
- *
* @param keyIds
* @param key_table
*/
- static void SetChecked(const KeyIdArgsListPtr& keyIds,
+ static void SetChecked(const KeyIdArgsListPtr& key_ids,
const KeyTable& key_table);
/**
@@ -294,6 +203,12 @@ class KeyList : public QWidget {
*/
[[maybe_unused]] auto ContainsPrivateKeys() -> bool;
+ /**
+ * @brief
+ *
+ */
+ void UpdateKeyTableColumnType(GpgKeyTableColumn);
+
signals:
/**
* @brief
@@ -309,6 +224,14 @@ class KeyList : public QWidget {
*/
void SignalRefreshDatabase();
+ signals:
+
+ /**
+ * @brief
+ *
+ */
+ void SignalColumnTypeChange(GpgKeyTableColumn);
+
public slots:
/**
@@ -335,7 +258,7 @@ class KeyList : public QWidget {
*
* @param inBuffer
*/
- void import_keys(const QByteArray& inBuffer);
+ void import_keys(const QByteArray& in_buffer);
/**
* @brief
@@ -355,15 +278,20 @@ class KeyList : public QWidget {
*/
void filter_by_keyword();
- std::mutex buffered_key_list_mutex_; ///<
-
std::shared_ptr<Ui_KeyList> ui_; ///<
- QTableWidget* m_key_list_{}; ///<
- std::vector<KeyTable> m_key_tables_; ///<
QMenu* popup_menu_{}; ///<
- GpgFrontend::KeyLinkListPtr buffered_keys_list_; ///<
std::function<void(const GpgKey&, QWidget*)> m_action_ = nullptr; ///<
- KeyMenuAbility::AbilityType menu_ability_ = KeyMenuAbility::ALL; ///<
+ KeyMenuAbility menu_ability_ = KeyMenuAbility::kALL; ///<
+ QSharedPointer<GpgKeyTableModel> model_;
+ GpgKeyTableColumn fixed_columns_filter_;
+ GpgKeyTableColumn global_column_filter_;
+
+ QAction* key_id_column_action_;
+ QAction* algo_column_action_;
+ QAction* create_date_column_action_;
+ QAction* owner_trust_column_action_;
+ QAction* subkeys_number_column_action_;
+ QAction* comment_column_action_;
private slots:
@@ -378,12 +306,6 @@ class KeyList : public QWidget {
* @brief
*
*/
- void slot_refresh_ui();
-
- /**
- * @brief
- *
- */
void slot_sync_with_key_server();
protected:
diff --git a/src/ui/widgets/KeyTable.cpp b/src/ui/widgets/KeyTable.cpp
new file mode 100644
index 00000000..1ba44232
--- /dev/null
+++ b/src/ui/widgets/KeyTable.cpp
@@ -0,0 +1,149 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend 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.
+ *
+ * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "ui/widgets/KeyTable.h"
+
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "ui/UserInterfaceUtils.h"
+#include "ui/dialog/keypair_details/KeyDetailsDialog.h"
+
+namespace GpgFrontend::UI {
+
+auto KeyTable::GetChecked() const -> KeyIdArgsListPtr {
+ auto ret = std::make_unique<KeyIdArgsList>();
+ for (decltype(GetRowCount()) i = 0; i < GetRowCount(); i++) {
+ if (IsRowChecked(i)) ret->push_back(GetKeyIdByRow(i));
+ }
+ return ret;
+}
+
+KeyTable::KeyTable(QWidget* parent, QSharedPointer<GpgKeyTableModel> model,
+ GpgKeyTableDisplayMode select_type,
+ GpgKeyTableColumn column_filter,
+ GpgKeyTableProxyModel::KeyFilter filter)
+ : QTableView(parent),
+ model_(std::move(model)),
+ proxy_model_(model_, select_type, column_filter, std::move(filter), this),
+ column_filter_(column_filter) {
+ setModel(&proxy_model_);
+
+ verticalHeader()->hide();
+ horizontalHeader()->setStretchLastSection(false);
+ setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+
+ setShowGrid(false);
+ sortByColumn(2, Qt::AscendingOrder);
+ setSelectionBehavior(QAbstractItemView::SelectRows);
+ setSelectionMode(QAbstractItemView::SingleSelection);
+
+ // table items not editable
+ setEditTriggers(QAbstractItemView::NoEditTriggers);
+
+ setFocusPolicy(Qt::NoFocus);
+ setAlternatingRowColors(true);
+ setSortingEnabled(true);
+
+ connect(CommonUtils::GetInstance(), &CommonUtils::SignalFavoritesChanged,
+ &proxy_model_, &GpgKeyTableProxyModel::SignalFavoritesChanged);
+ connect(this, &KeyTable::SignalColumnTypeChange, this,
+ [=](GpgKeyTableColumn global_column_filter) {
+ emit(&proxy_model_)
+ ->SignalColumnTypeChange(column_filter_ & global_column_filter);
+ });
+ connect(this, &QTableView::doubleClicked, this,
+ [this](const QModelIndex& index) {
+ auto key =
+ GpgKeyGetter::GetInstance().GetKey(GetKeyIdByRow(index.row()));
+ if (!key.IsGood()) {
+ QMessageBox::critical(this, tr("Error"), tr("Key Not Found."));
+ return;
+ }
+ new KeyDetailsDialog(key, this);
+ });
+}
+
+void KeyTable::SetFilterKeyword(const QString& keyword) {
+ proxy_model_.SetSearchKeywords(keyword);
+}
+
+void KeyTable::RefreshModel(QSharedPointer<GpgKeyTableModel> model) {
+ model_ = std::move(model);
+ proxy_model_.setSourceModel(model_.get());
+}
+
+auto KeyTable::IsRowChecked(int row) const -> bool {
+ auto index = model()->index(row, 0);
+ return index.data(Qt::CheckStateRole).toInt() == Qt::Checked;
+}
+
+auto KeyTable::GetRowCount() const -> int { return model()->rowCount(); }
+
+auto KeyTable::GetKeyIdByRow(int row) const -> QString {
+ if (row < 0 || row >= model()->rowCount()) return {};
+ auto origin_row = model()->index(row, 0).data().toInt();
+ return model_->GetKeyIDByRow(origin_row);
+}
+
+auto KeyTable::IsPrivateKeyByRow(int row) const -> bool {
+ if (row < 0 || row >= model()->rowCount()) return false;
+ auto origin_row = model()->index(row, 0).data().toInt();
+ return model_->IsPrivateKeyByRow(origin_row);
+}
+
+auto KeyTable::IsPublicKeyByRow(int row) const -> bool {
+ if (row < 0 || row >= model()->rowCount()) return false;
+ auto origin_row = model()->index(row, 0).data().toInt();
+ return !model_->IsPrivateKeyByRow(origin_row);
+}
+
+void KeyTable::SetRowChecked(int row) const {
+ if (row < 0 || row >= model()->rowCount()) return;
+ model()->setData(model()->index(row, 0), Qt::Checked, Qt::CheckStateRole);
+}
+
+void KeyTable::CheckAll() {
+ for (int row = 0; row < model()->rowCount(); ++row) {
+ auto index = model()->index(row, 0);
+ model()->setData(index, Qt::Checked, Qt::CheckStateRole);
+ }
+}
+
+void KeyTable::UncheckAll() {
+ for (int row = 0; row < model()->rowCount(); ++row) {
+ auto index = model()->index(row, 0);
+ model()->setData(index, Qt::Unchecked, Qt::CheckStateRole);
+ }
+}
+
+[[nodiscard]] auto KeyTable::GetRowSelected() const -> int {
+ auto selected_indexes = selectedIndexes();
+ if (selected_indexes.empty()) return -1;
+
+ return selected_indexes.first().row();
+}
+} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/widgets/KeyTable.h b/src/ui/widgets/KeyTable.h
new file mode 100644
index 00000000..4ec8f687
--- /dev/null
+++ b/src/ui/widgets/KeyTable.h
@@ -0,0 +1,176 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend 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.
+ *
+ * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/model/GpgKey.h"
+#include "core/model/GpgKeyTableModel.h"
+#include "core/model/GpgKeyTableProxyModel.h"
+
+namespace GpgFrontend::UI {
+
+/**
+ * @brief
+ *
+ */
+struct KeyTable : public QTableView {
+ Q_OBJECT
+ public:
+ using KeyTableFilter = std::function<bool(const GpgKey&, const KeyTable&)>;
+
+ /**
+ * @brief Construct a new Key Table object
+ *
+ * @param _key_list
+ * @param _select_type
+ * @param _info_type
+ * @param _filter
+ */
+ KeyTable(
+ QWidget* parent, QSharedPointer<GpgKeyTableModel> model,
+ GpgKeyTableDisplayMode _select_type, GpgKeyTableColumn _info_type,
+ GpgKeyTableProxyModel::KeyFilter _filter = [](const GpgKey&) -> bool {
+ return true;
+ });
+
+ /**
+ * @brief
+ *
+ * @param model
+ */
+ void RefreshModel(QSharedPointer<GpgKeyTableModel> model);
+
+ /**
+ * @brief Get the Checked object
+ *
+ * @return KeyIdArgsListPtr&
+ */
+ [[nodiscard]] auto GetChecked() const -> KeyIdArgsListPtr;
+
+ /**
+ * @brief
+ *
+ */
+ void UncheckALL() const;
+
+ /**
+ * @brief
+ *
+ */
+ void CheckALL() const;
+
+ /**
+ * @brief
+ *
+ */
+ void SetFilterKeyword(const QString& keyword);
+
+ /**
+ * @brief
+ *
+ * @param row
+ * @return true
+ * @return false
+ */
+ [[nodiscard]] auto IsRowChecked(int row) const -> bool;
+
+ /**
+ * @brief Set the Row Checked object
+ *
+ * @param row
+ */
+ void SetRowChecked(int row) const;
+
+ /**
+ * @brief Set the Row Checked object
+ *
+ * @param row
+ */
+ [[nodiscard]] auto GetRowSelected() const -> int;
+
+ /**
+ * @brief Get the Row Count object
+ *
+ * @return auto
+ */
+ [[nodiscard]] auto GetRowCount() const -> int;
+
+ /**
+ * @brief Get the Key Id By Row object
+ *
+ * @param row
+ * @return QString
+ */
+ [[nodiscard]] auto GetKeyIdByRow(int row) const -> QString;
+
+ /**
+ * @brief
+ *
+ * @param row
+ * @return true
+ * @return false
+ */
+ [[nodiscard]] auto IsPublicKeyByRow(int row) const -> bool;
+
+ /**
+ * @brief
+ *
+ * @param row
+ * @return true
+ * @return false
+ */
+ [[nodiscard]] auto IsPrivateKeyByRow(int row) const -> bool;
+
+ /**
+ * @brief
+ *
+ */
+ void CheckAll();
+
+ /**
+ * @brief
+ *
+ */
+ void UncheckAll();
+
+ signals:
+
+ /**
+ * @brief
+ *
+ */
+ void SignalColumnTypeChange(GpgKeyTableColumn);
+
+ private:
+ QSharedPointer<GpgKeyTableModel> model_;
+ GpgKeyTableProxyModel proxy_model_;
+
+ GpgKeyTableColumn column_filter_;
+};
+
+} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/widgets/PlainTextEditorPage.cpp b/src/ui/widgets/PlainTextEditorPage.cpp
index 874bbf3b..57910f9d 100644
--- a/src/ui/widgets/PlainTextEditorPage.cpp
+++ b/src/ui/widgets/PlainTextEditorPage.cpp
@@ -164,7 +164,7 @@ void PlainTextEditorPage::ReadFile() {
[=]() { emit read_task->SignalTaskShouldEnd(0); });
connect(read_task, &FileReadTask::SignalFileBytesReadEnd, this, [=]() {
// set the UI
- GF_UI_LOG_DEBUG("signal file bytes read end rised");
+ qCDebug(ui, "signal file bytes read end rised");
this->read_done_ = true;
text_page->setEnabled(true);
text_page->document()->setModified(false);
@@ -186,8 +186,6 @@ auto BinaryToString(const QByteArray &source) -> QString {
}
void PlainTextEditorPage::slot_insert_text(QByteArray bytes_data) {
- GF_UI_LOG_TRACE("inserting data read to editor, data size: {}",
- bytes_data.size());
read_bytes_ += bytes_data.size();
// insert the text to the text page
diff --git a/src/ui/widgets/TextEdit.cpp b/src/ui/widgets/TextEdit.cpp
index a0dba5f5..9cecfb38 100644
--- a/src/ui/widgets/TextEdit.cpp
+++ b/src/ui/widgets/TextEdit.cpp
@@ -120,7 +120,6 @@ void TextEdit::SlotNewFileTab() {
void TextEdit::SlotOpenFile(const QString& path) {
QFile file(path);
- GF_UI_LOG_DEBUG("main window editor is opening file at path: {}", path);
auto result = file.open(QIODevice::ReadOnly | QIODevice::Text);
if (result) {
auto* page = new PlainTextEditorPage(path);
@@ -510,7 +509,6 @@ QHash<int, QString> TextEdit::UnsavedDocuments() const {
if (ep != nullptr && ep->ReadDone() &&
ep->GetTextPage()->document()->isModified()) {
QString doc_name = tab_widget_->tabText(i);
- GF_UI_LOG_DEBUG("unsaved: {}", doc_name);
// remove * before name of modified doc
doc_name.remove(0, 2);
@@ -601,8 +599,8 @@ void TextEdit::slot_file_page_path_changed(const QString& path) const {
}
tab_widget_->setTabText(index, m_path);
- emit UISignalStation::GetInstance()->SignalMainWindowlUpdateBasicalOperaMenu(
- 0);
+ emit UISignalStation::GetInstance()
+ -> SignalMainWindowlUpdateBasicalOperaMenu(0);
}
void TextEdit::slot_save_status_to_cache_for_revovery() {
@@ -614,17 +612,11 @@ void TextEdit::slot_save_status_to_cache_for_revovery() {
bool restore_text_editor_page =
settings.value("basic/restore_text_editor_page", false).toBool();
if (!restore_text_editor_page) {
- GF_UI_LOG_DEBUG("restore_text_editor_page is false, ignoring...");
+ qCDebug(ui, "restore_text_editor_page is false, ignoring...");
return;
}
int tab_count = tab_widget_->count();
- GF_UI_LOG_DEBUG(
- "restore_text_editor_page is true, pan to save pages, current tabs "
- "count: "
- "{}",
- tab_count);
-
std::vector<std::tuple<int, QString, QString>> unsaved_pages;
for (int i = 0; i < tab_count; i++) {
@@ -643,9 +635,7 @@ void TextEdit::slot_save_status_to_cache_for_revovery() {
continue;
}
- auto raw_text = document->toRawText();
- GF_UI_LOG_DEBUG("unsaved page index: {}, tab title: {}", i, tab_title);
- unsaved_pages.emplace_back(i, tab_title, raw_text);
+ unsaved_pages.emplace_back(i, tab_title, document->toRawText());
}
CacheObject cache("editor_unsaved_pages");
diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt
index 534d71da..3139ce66 100644
--- a/third_party/CMakeLists.txt
+++ b/third_party/CMakeLists.txt
@@ -23,25 +23,9 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
-
-# json
-set(JSON_BuildTests OFF CACHE INTERNAL "")
-
-add_subdirectory(spdlog EXCLUDE_FROM_ALL)
-
-if (MINGW)
- add_subdirectory(libarchive EXCLUDE_FROM_ALL)
-endif()
-
-# not working at macOS
-if (NOT APPLE)
- set(MI_SECURE ON)
- if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
- # set(MI_TRACK_VALGRIND ON)
- set(MI_TRACK_ASAN ON)
- endif()
+# ASAN checking
+if(ENABLE_ASAN AND NOT APPLE AND ${CMAKE_BUILD_TYPE} STREQUAL "Debug")
+ # set(MI_TRACK_VALGRIND ON)
+ set(MI_TRACK_ASAN ON)
add_subdirectory(mimalloc EXCLUDE_FROM_ALL)
-endif()
-
-set(INSTALL_GTEST OFF)
-add_subdirectory(googletest EXCLUDE_FROM_ALL) \ No newline at end of file
+endif() \ No newline at end of file
diff --git a/third_party/mimalloc b/third_party/mimalloc
-Subproject 43ce4bd7fd34bcc730c1c7471c9999559741548
+Subproject 8c532c32c3c96e5ba1f2283e032f69ead8add00
diff --git a/third_party/spdlog b/third_party/spdlog
deleted file mode 160000
-Subproject eb3220622e73a4889eee355ffa37972b3cac3df
diff --git a/ui/GeneralSettings.ui b/ui/GeneralSettings.ui
index a19626f5..78f3bb6a 100644
--- a/ui/GeneralSettings.ui
+++ b/ui/GeneralSettings.ui
@@ -65,6 +65,13 @@
</property>
</widget>
</item>
+ <item>
+ <widget class="QCheckBox" name="disableLoadingModulesCheckBox">
+ <property name="text">
+ <string>Disable loading of all modules (including integrated modules)</string>
+ </property>
+ </widget>
+ </item>
</layout>
</item>
</layout>
diff --git a/ui/GnuPGInfo.ui b/ui/GnuPGInfo.ui
deleted file mode 100644
index 63e746a5..00000000
--- a/ui/GnuPGInfo.ui
+++ /dev/null
@@ -1,163 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>GnuPGInfo</class>
- <widget class="QWidget" name="GnuPGInfo">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>535</width>
- <height>568</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>GnuPG Info</string>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,0,0">
- <property name="spacing">
- <number>0</number>
- </property>
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QLabel" name="label">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
- </property>
- <property name="pixmap">
- <pixmap resource="../gpgfrontend.qrc">:/icons/gnupg.png</pixmap>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- <property name="margin">
- <number>10</number>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="gnupgVersionLabel">
- <property name="text">
- <string>Version</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- <property name="margin">
- <number>5</number>
- </property>
- </widget>
- </item>
- <item>
- <widget class="Line" name="line">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QTabWidget" name="tabWidget">
- <property name="tabShape">
- <enum>QTabWidget::Rounded</enum>
- </property>
- <property name="currentIndex">
- <number>0</number>
- </property>
- <property name="tabBarAutoHide">
- <bool>false</bool>
- </property>
- <widget class="QWidget" name="tab">
- <attribute name="title">
- <string>Components</string>
- </attribute>
- <layout class="QGridLayout" name="gridLayout_3">
- <item row="0" column="0">
- <widget class="QTableWidget" name="componentDetailsTable">
- <property name="sizeAdjustPolicy">
- <enum>QAbstractScrollArea::AdjustToContents</enum>
- </property>
- <property name="autoScrollMargin">
- <number>16</number>
- </property>
- <property name="editTriggers">
- <set>QAbstractItemView::NoEditTriggers</set>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QProgressBar" name="loadProgressBar">
- <property name="maximum">
- <number>0</number>
- </property>
- <property name="value">
- <number>-1</number>
- </property>
- <property name="textVisible">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="tab_2">
- <attribute name="title">
- <string>Directories</string>
- </attribute>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="0">
- <widget class="QTableWidget" name="directoriesDetailsTable">
- <property name="sizeAdjustPolicy">
- <enum>QAbstractScrollArea::AdjustToContents</enum>
- </property>
- <property name="editTriggers">
- <set>QAbstractItemView::NoEditTriggers</set>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="tab_3">
- <attribute name="title">
- <string>Options</string>
- </attribute>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="QTableWidget" name="optionDetailsTable"/>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- <resources>
- <include location="../gpgfrontend.qrc"/>
- </resources>
- <connections/>
-</ui>
diff --git a/ui/KeyList.ui b/ui/KeyList.ui
index afccdcf6..618b44fd 100644
--- a/ui/KeyList.ui
+++ b/ui/KeyList.ui
@@ -93,6 +93,23 @@
</widget>
</item>
<item>
+ <widget class="QToolButton" name="columnTypeButton">
+ <property name="acceptDrops">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../gpgfrontend.qrc">
+ <normaloff>:/icons/filter.png</normaloff>:/icons/filter.png</iconset>
+ </property>
+ <property name="popupMode">
+ <enum>QToolButton::InstantPopup</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
diff --git a/ui/ModuleControllerDialog.ui b/ui/ModuleControllerDialog.ui
index 97dd1397..910a3de8 100644
--- a/ui/ModuleControllerDialog.ui
+++ b/ui/ModuleControllerDialog.ui
@@ -111,7 +111,7 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
- <widget class="QPushButton" name="activateOrDeactiveButton">
+ <widget class="QPushButton" name="activateOrDeactivateButton">
<property name="enabled">
<bool>true</bool>
</property>