aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSaturn&Eric <[email protected]>2023-02-25 11:49:54 +0000
committerGitHub <[email protected]>2023-02-25 11:49:54 +0000
commitaf1cd680f2496629026ba27707cef2afd860f5f9 (patch)
tree78e78450893e98b8828cc41010e377c1561e5f34
parentfix: improve manual (diff)
parentfeat: use aqt to install qt in ci build (diff)
downloadGpgFrontend-af1cd680f2496629026ba27707cef2afd860f5f9.tar.gz
GpgFrontend-af1cd680f2496629026ba27707cef2afd860f5f9.zip
Merge pull request #91 from saturneric/dev/2.0.10/main
Develop 2.1.0.1
-rw-r--r--.gitattributes1
-rw-r--r--.github/workflows/debug.yml25
-rw-r--r--.github/workflows/release-deb-package.yml17
-rw-r--r--.github/workflows/release.yml37
-rw-r--r--.gitmodules6
-rw-r--r--CMakeLists.txt37
-rw-r--r--GpgFrontend.entitlements14
-rw-r--r--README.md8
-rwxr-xr-xresource/lfs/macOS/GnuPG/agent/gpg-agent3
-rwxr-xr-xresource/lfs/macOS/GnuPG/bin/gpgconf3
-rwxr-xr-xresource/lfs/macOS/GnuPG/bin/gpgconf-original3
-rwxr-xr-xresource/lfs/macOS/GnuPG/dirmngr/dirmngr3
-rwxr-xr-xresource/lfs/macOS/GnuPG/g10/gpg3
-rwxr-xr-xresource/lfs/macOS/GnuPG/kbx/keyboxd3
-rw-r--r--resource/lfs/macOS/GnuPG/libs/libassuan.0.dylib3
-rw-r--r--resource/lfs/macOS/GnuPG/libs/libgcrypt.20.dylib3
-rw-r--r--resource/lfs/macOS/GnuPG/libs/libgmp.10.dylib3
-rw-r--r--resource/lfs/macOS/GnuPG/libs/libgnutls.30.dylib3
-rw-r--r--resource/lfs/macOS/GnuPG/libs/libgpg-error.0.dylib3
-rw-r--r--resource/lfs/macOS/GnuPG/libs/libhogweed.6.6.dylib3
-rw-r--r--resource/lfs/macOS/GnuPG/libs/libidn2.0.dylib3
-rw-r--r--resource/lfs/macOS/GnuPG/libs/libintl.8.dylib3
-rw-r--r--resource/lfs/macOS/GnuPG/libs/libksba.8.dylib3
-rw-r--r--resource/lfs/macOS/GnuPG/libs/libnettle.8.6.dylib3
-rw-r--r--resource/lfs/macOS/GnuPG/libs/libnpth.0.dylib3
-rw-r--r--resource/lfs/macOS/GnuPG/libs/libp11-kit.0.dylib3
-rw-r--r--resource/lfs/macOS/GnuPG/libs/libreadline.8.2.dylib3
-rw-r--r--resource/lfs/macOS/GnuPG/libs/libtasn1.6.dylib3
-rw-r--r--resource/lfs/macOS/GnuPG/libs/libunistring.5.dylib3
-rw-r--r--resource/lfs/macOS/GnuPG/libs/libusb-1.0.0.dylib3
-rwxr-xr-xresource/lfs/macOS/GnuPG/scd/scdaemon3
-rwxr-xr-xresource/lfs/macOS/GnuPG/sm/gpgsm3
-rwxr-xr-xresource/lfs/macOS/GnuPG/tools/gpg-connect-agent3
-rw-r--r--src/CMakeLists.txt221
-rw-r--r--src/GpgFrontend.h.in5
-rw-r--r--src/before_exit.cpp4
-rw-r--r--src/core/CMakeLists.txt14
-rw-r--r--src/core/GpgConstants.cpp26
-rw-r--r--src/core/GpgContext.cpp381
-rw-r--r--src/core/GpgContext.h51
-rw-r--r--src/core/GpgCoreInit.cpp91
-rw-r--r--src/core/GpgCoreInit.h8
-rw-r--r--src/core/GpgFunctionObject.cpp14
-rw-r--r--src/core/GpgFunctionObject.h23
-rw-r--r--src/core/GpgGenKeyInfo.cpp2
-rw-r--r--src/core/GpgInfo.h26
-rw-r--r--src/core/common/CoreCommonUtil.cpp22
-rw-r--r--src/core/common/CoreCommonUtil.h24
-rw-r--r--src/core/function/ArchiveFileOperator.cpp62
-rw-r--r--src/core/function/CacheManager.cpp66
-rw-r--r--src/core/function/CacheManager.h45
-rw-r--r--src/core/function/CharsetOperator.cpp27
-rw-r--r--src/core/function/CoreSignalStation.cpp39
-rw-r--r--src/core/function/CoreSignalStation.h69
-rw-r--r--src/core/function/DataObjectOperator.cpp30
-rw-r--r--src/core/function/FileOperator.cpp26
-rw-r--r--src/core/function/GlobalSettingStation.cpp42
-rw-r--r--src/core/function/KeyPackageOperator.cpp22
-rw-r--r--src/core/function/gpg/GpgAdvancedOperator.cpp183
-rw-r--r--src/core/function/gpg/GpgAdvancedOperator.h115
-rw-r--r--src/core/function/gpg/GpgBasicOperator.cpp6
-rw-r--r--src/core/function/gpg/GpgCommandExecutor.cpp252
-rw-r--r--src/core/function/gpg/GpgCommandExecutor.h20
-rw-r--r--src/core/function/gpg/GpgKeyGetter.cpp26
-rw-r--r--src/core/function/gpg/GpgKeyImportExporter.cpp35
-rw-r--r--src/core/function/gpg/GpgKeyImportExporter.h12
-rw-r--r--src/core/function/gpg/GpgKeyOpera.cpp87
-rw-r--r--src/core/function/gpg/GpgUIDOperator.cpp2
-rw-r--r--src/core/function/result_analyse/GpgEncryptResultAnalyse.cpp2
-rw-r--r--src/core/function/result_analyse/GpgSignResultAnalyse.cpp8
-rw-r--r--src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp2
-rw-r--r--src/core/thread/CtxCheckTask.cpp5
-rw-r--r--src/core/thread/FileReadTask.cpp20
-rw-r--r--src/core/thread/Task.cpp158
-rw-r--r--src/core/thread/Task.h82
-rw-r--r--src/core/thread/TaskRunner.cpp112
-rw-r--r--src/core/thread/TaskRunner.h18
-rw-r--r--src/core/thread/TaskRunnerGetter.h1
-rw-r--r--src/init.cpp106
-rw-r--r--src/main.cpp61
-rw-r--r--src/signal.cpp7
-rw-r--r--src/ui/CMakeLists.txt12
-rw-r--r--src/ui/GpgFrontendApplication.cpp11
-rw-r--r--src/ui/GpgFrontendUIInit.cpp109
-rw-r--r--src/ui/GpgFrontendUIInit.h12
-rw-r--r--src/ui/SignalStation.h12
-rw-r--r--src/ui/UserInterfaceUtils.cpp114
-rw-r--r--src/ui/UserInterfaceUtils.h27
-rw-r--r--src/ui/dialog/GeneralDialog.cpp33
-rw-r--r--src/ui/dialog/WaitingDialog.cpp6
-rw-r--r--src/ui/dialog/Wizard.cpp6
-rw-r--r--src/ui/dialog/details/VerifyDetailsDialog.cpp4
-rw-r--r--src/ui/dialog/help/AboutDialog.cpp10
-rw-r--r--src/ui/dialog/help/GnupgTab.cpp131
-rw-r--r--src/ui/dialog/help/GnupgTab.h6
-rw-r--r--src/ui/dialog/import_export/KeyImportDetailDialog.cpp2
-rw-r--r--src/ui/dialog/import_export/KeyServerImportDialog.cpp22
-rw-r--r--src/ui/dialog/import_export/KeyUploadDialog.cpp14
-rw-r--r--src/ui/dialog/key_generate/KeygenDialog.cpp47
-rw-r--r--src/ui/dialog/key_generate/KeygenDialog.h1
-rw-r--r--src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp71
-rw-r--r--src/ui/dialog/key_generate/SubkeyGenerateDialog.h2
-rw-r--r--src/ui/dialog/keypair_details/KeyPairDetailTab.cpp21
-rw-r--r--src/ui/dialog/keypair_details/KeyPairOperaTab.cpp4
-rw-r--r--src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp34
-rw-r--r--src/ui/dialog/keypair_details/KeyPairUIDTab.cpp21
-rw-r--r--src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp24
-rw-r--r--src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp14
-rw-r--r--src/ui/dialog/settings/SettingsAdvanced.cpp5
-rw-r--r--src/ui/dialog/settings/SettingsDialog.cpp8
-rw-r--r--src/ui/dialog/settings/SettingsGeneral.cpp182
-rw-r--r--src/ui/dialog/settings/SettingsGeneral.h8
-rw-r--r--src/ui/dialog/settings/SettingsKeyServer.cpp8
-rw-r--r--src/ui/dialog/settings/SettingsNetwork.cpp22
-rw-r--r--src/ui/main_window/GeneralMainWindow.cpp19
-rw-r--r--src/ui/main_window/KeyMgmt.cpp4
-rw-r--r--src/ui/main_window/MainWindow.cpp47
-rw-r--r--src/ui/main_window/MainWindow.h5
-rw-r--r--src/ui/main_window/MainWindowFileSlotFunction.cpp34
-rw-r--r--src/ui/main_window/MainWindowSlotFunction.cpp24
-rw-r--r--src/ui/main_window/MainWindowSlotUI.cpp8
-rw-r--r--src/ui/main_window/MainWindowUI.cpp100
-rw-r--r--src/ui/struct/SettingsObject.cpp22
-rw-r--r--src/ui/struct/SoftwareVersion.cpp72
-rw-r--r--src/ui/struct/SoftwareVersion.h19
-rw-r--r--src/ui/thread/KeyServerImportTask.cpp5
-rw-r--r--src/ui/thread/KeyServerSearchTask.cpp5
-rw-r--r--src/ui/thread/ListedKeyServerTestTask.cpp13
-rw-r--r--src/ui/thread/ProxyConnectionTestThread.cpp8
-rw-r--r--src/ui/thread/VersionCheckTask.cpp41
-rw-r--r--src/ui/widgets/FilePage.cpp26
-rw-r--r--src/ui/widgets/InfoBoardWidget.cpp7
-rw-r--r--src/ui/widgets/KeyList.cpp29
-rw-r--r--src/ui/widgets/PlainTextEditorPage.cpp11
-rw-r--r--src/ui/widgets/TextEdit.cpp95
-rw-r--r--src/ui/widgets/TextEdit.h13
-rw-r--r--third_party/CMakeLists.txt4
m---------third_party/easyloggingpp0
m---------third_party/gpgme0
m---------third_party/json0
m---------third_party/libarchive0
m---------third_party/libassuan0
m---------third_party/libconfig0
m---------third_party/libgpg-error0
m---------third_party/qt-aes0
m---------third_party/spdlog0
-rw-r--r--ui/GeneralSettings.ui141
-rw-r--r--ui/GnuPGInfo.ui83
148 files changed, 3525 insertions, 1193 deletions
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 00000000..44c37b71
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+resource/lfs/** filter=lfs diff=lfs merge=lfs -text
diff --git a/.github/workflows/debug.yml b/.github/workflows/debug.yml
index 26bbcad2..055347f0 100644
--- a/.github/workflows/debug.yml
+++ b/.github/workflows/debug.yml
@@ -23,7 +23,7 @@ jobs:
build:
strategy:
matrix:
- os: [ 'ubuntu-latest', 'macos-10.15', 'macos-11', 'macos-12', 'windows-latest' ]
+ os: [ 'ubuntu-latest', 'macos-11', 'macos-12', 'windows-latest' ]
runs-on: ${{ matrix.os }}
continue-on-error: true
steps:
@@ -32,7 +32,7 @@ jobs:
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- if: matrix.os == 'windows-latest' || matrix.os == 'macos-10.15' || matrix.os == 'macos-11' || matrix.os == 'macos-12'
+ if: matrix.os == 'windows-latest' || matrix.os == 'macos-11' || matrix.os == 'macos-12'
- uses: actions/checkout@v2
with:
@@ -53,12 +53,11 @@ jobs:
- name: Install Dependence (macOS)
run: |
- brew install cmake autoconf automake qt@5 texinfo gettext [email protected]
+ brew install cmake autoconf automake texinfo gettext [email protected]
brew install boost ninja libarchive libconfig gpgme
brew unlink gettext && brew link --force gettext
- brew link qt@5
brew link [email protected] --force
- if: matrix.os == 'macos-10.15' || matrix.os == 'macos-11' || matrix.os == 'macos-12'
+ if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
- name: Build gpg-error (Linux)
run: |
@@ -92,14 +91,16 @@ jobs:
uses: actions/cache@v1
with:
path: ../Qt
- key: ${{ runner.os }}-QtCache
- if: matrix.os == 'ubuntu-latest'
+ key: ${{ runner.os }}-qt-cache-6
+ if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-11' || matrix.os == 'macos-12'
- name: Install Qt
- uses: jurplel/install-qt-action@v2
+ uses: jurplel/install-qt-action@v3
with:
+ version: '6.4.2'
+ modules: 'qt5compat'
cached: ${{ steps.cache-qt.outputs.cache-hit }}
- if: matrix.os == 'ubuntu-latest'
+ if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-11' || matrix.os == 'macos-12'
- name: Set up MinGW (Windows)
uses: msys2/setup-msys2@v2
@@ -113,7 +114,7 @@ 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 mingw-w64-x86_64-libconfig mingw-w64-x86_64-boost automake
- pacman --noconfirm -S --needed mingw-w64-x86_64-qt5 libintl msys2-runtime-devel gettext-devel
+ pacman --noconfirm -S --needed mingw-w64-x86_64-qt6 libintl msys2-runtime-devel gettext-devel
pacman --noconfirm -S --needed mingw-w64-x86_64-ninja mingw-w64-x86_64-gnupg mingw-w64-x86_64-gpgme
pacman --noconfirm -S --needed mingw-w64-x86_64-libarchive mingw-w64-x86_64-icu mingw-w64-x86_64-icu-debug-libs
if: matrix.os == 'windows-latest'
@@ -130,7 +131,7 @@ jobs:
run: |
cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DGPGFRONTEND_BUILD_TYPE_TEST_UI=ON
cmake --build ${{github.workspace}}/build --config {{$env.BUILD_TYPE}} -- -v
- if: matrix.os == 'macos-10.15' || matrix.os == 'macos-11' || matrix.os == 'macos-12'
+ if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
- name: Configure CMake & Build Binary(Windows)
shell: msys2 {0}
@@ -158,7 +159,7 @@ jobs:
with:
name: gpgfrontend-${{matrix.os}}-${{env.BUILD_TYPE}}-${{steps.vars.outputs.sha_short}}
path: ${{github.workspace}}/build/release/*
- if: matrix.os == 'macos-10.15' || matrix.os == 'macos-11' || matrix.os == 'macos-12'
+ if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
- name: Upload Artifact(Windows)
uses: actions/upload-artifact@master
diff --git a/.github/workflows/release-deb-package.yml b/.github/workflows/release-deb-package.yml
index f5aff6a0..63cacb6f 100644
--- a/.github/workflows/release-deb-package.yml
+++ b/.github/workflows/release-deb-package.yml
@@ -36,22 +36,6 @@ jobs:
id: vars
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
- - name: Install Dependence (Ubuntu 18.04)
- run: |
- sudo apt-get update
- sudo apt-get -y install build-essential binutils git autoconf automake gettext texinfo qt5-default
- sudo apt-get -y install gcc-8 g++-8 ninja-build
- sudo apt-get -y install libconfig++-dev libboost-all-dev libarchive-dev libssl-dev
- sudo apt-get -y install gpgsm libxcb-xinerama0 libxcb-icccm4-dev libcups2-dev libdrm-dev libegl1-mesa-dev
- sudo apt-get -y install libgcrypt11-dev libnss3-dev libpci-dev libpulse-dev libudev-dev libxtst-dev gyp
- sudo apt-get -y install libglu1-mesa-dev libfontconfig1-dev libx11-xcb-dev libicu-dev libxcb-image0
- sudo apt-get -y install libglu1-mesa-dev libfontconfig1-dev libx11-xcb-dev libicu-dev libxcb-*
- sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 8
- sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 8
- sudo update-alternatives --set gcc "/usr/bin/gcc-8"
- sudo update-alternatives --set g++ "/usr/bin/g++-8"
- if: matrix.os == 'ubuntu-18.04'
-
- name: Install Dependence (Ubuntu 20.04)
run: |
sudo apt-get update
@@ -103,6 +87,7 @@ jobs:
cd ${{github.workspace}}/build-deb-${{matrix.os}}
ninja package
cd ${{github.workspace}}
+
- name: Upload Artifact(Linux DEB)
uses: actions/upload-artifact@master
with:
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 9b9e8f82..d10dde2a 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -23,7 +23,7 @@ jobs:
build:
strategy:
matrix:
- os: [ 'ubuntu-18.04', 'macos-10.15', 'macos-11', 'macos-12', 'windows-2019' ]
+ os: [ 'ubuntu-18.04', 'macos-11', 'macos-12', 'windows-2019' ]
runs-on: ${{ matrix.os }}
continue-on-error: true
steps:
@@ -31,7 +31,7 @@ jobs:
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- if: matrix.os == 'windows-2019' || matrix.os == 'macos-10.15' || matrix.os == 'macos-11' || matrix.os == 'macos-12'
+ if: matrix.os == 'windows-2019' || matrix.os == 'macos-11' || matrix.os == 'macos-12'
- uses: actions/checkout@v2
with:
@@ -92,16 +92,31 @@ jobs:
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
- if: matrix.os == 'macos-10.15' || matrix.os == 'macos-11' || matrix.os == 'macos-12'
+ if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
+
+ - name: Cache Qt (macOS)
+ id: cache-qt-6
+ uses: actions/cache@v1
+ with:
+ path: ../Qt
+ key: ${{ runner.os }}-qt-cache-6
+ if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
+
+ - name: Install Qt6 (macOS)
+ uses: jurplel/install-qt-action@v3
+ with:
+ version: '6.4.2'
+ modules: 'qt5compat'
+ cached: ${{ steps.cache-qt.outputs.cache-hit }}
+ if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
- name: Install Dependence (macOS)
run: |
- brew install cmake autoconf automake qt@5 texinfo gettext [email protected]
+ brew install cmake autoconf automake texinfo gettext [email protected]
brew install boost ninja libarchive libconfig gpgme
brew unlink gettext && brew link --force gettext
- brew link qt@5
brew link [email protected] --force
- if: matrix.os == 'macos-10.15' || matrix.os == 'macos-11' || matrix.os == 'macos-12'
+ if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
- name: Build gpg-error (Linux)
run: |
@@ -156,7 +171,7 @@ 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 mingw-w64-x86_64-libconfig mingw-w64-x86_64-boost automake
- pacman --noconfirm -S --needed mingw-w64-x86_64-qt5 libintl msys2-runtime-devel gettext-devel mingw-w64-x86_64-gpgme
+ pacman --noconfirm -S --needed mingw-w64-x86_64-qt6 libintl msys2-runtime-devel gettext-devel mingw-w64-x86_64-gpgme
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-icu mingw-w64-x86_64-icu-debug-libs
if: matrix.os == 'windows-2019'
@@ -186,7 +201,7 @@ jobs:
xcodebuild -exportArchive -archivePath ${{github.workspace}}/build/GpgFrontend.xcarchive \
-exportOptionsPlist ${{github.workspace}}/build/ExportOptions.plist \
-exportPath ${{github.workspace}}/build/package/
- if: matrix.os == 'macos-10.15' || matrix.os == 'macos-11' || matrix.os == 'macos-12'
+ if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
- name: Package & Sign App Bundle (macOS)
run: |
@@ -201,7 +216,7 @@ jobs:
${{github.workspace}}/build/artifactOut/GpgFrontend-${{steps.vars.outputs.sha_short}}-x86_64.dmg
mv ${{github.workspace}}/build/GpgFrontend.app.zip \
${{github.workspace}}/build/GpgFrontend-${{steps.vars.outputs.sha_short}}-x86_64.zip
- if: matrix.os == 'macos-10.15' || matrix.os == 'macos-11' || matrix.os == 'macos-12'
+ if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
- name: Notarize Release Build (macOS)
run: |
@@ -210,7 +225,7 @@ jobs:
--primary-bundle-id ${{secrets.GPGFRONTEND_XOCDE_APPID}} \
-u ${{secrets.APPLE_DEVELOPER_ID}} \
-p ${{secrets.APPLE_DEVELOPER_ID_SECRET}}
- if: matrix.os == 'macos-10.15' || matrix.os == 'macos-11' || matrix.os == 'macos-12'
+ if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
- name: Package App Image (Linux)
run: |
@@ -243,7 +258,7 @@ jobs:
with:
name: gpgfrontend-${{matrix.os}}-${{env.BUILD_TYPE}}-${{steps.vars.outputs.sha_short}}
path: ${{github.workspace}}/build/artifactOut/*
- if: matrix.os == 'macos-10.15' || matrix.os == 'macos-11' || matrix.os == 'macos-12'
+ if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
- name: Upload Artifact(Windows)
uses: actions/upload-artifact@master
diff --git a/.gitmodules b/.gitmodules
index f8ddc595..9243d165 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -10,9 +10,6 @@
[submodule "third_party/json"]
path = third_party/json
url = https://git.bktus.com/GpgFrontend/json.git
-[submodule "third_party/easyloggingpp"]
- path = third_party/easyloggingpp
- url = https://git.bktus.com/GpgFrontend/easyloggingpp.git
[submodule "third_party/qt-aes"]
path = third_party/qt-aes
url = https://git.bktus.com/GpgFrontend/Qt-AES.git
@@ -22,3 +19,6 @@
[submodule "third_party/libconfig"]
path = third_party/libconfig
url = https://git.bktus.com/GpgFrontend/libconfig.git
+[submodule "third_party/spdlog"]
+ path = third_party/spdlog
+ url = https://git.bktus.com/GpgFrontend/spdlog.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1f08f440..e2c107ca 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -27,7 +27,7 @@
cmake_minimum_required(VERSION 3.16)
# define project
-project(GpgFrontend VERSION 2.0.10 LANGUAGES CXX)
+project(GpgFrontend VERSION 2.1.0 LANGUAGES CXX)
# show cmake version
message(STATUS "GpgFrontend Build Configuration Started CMAKE Version ${CMAKE_VERSION}")
@@ -63,6 +63,7 @@ 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")
option(GPGFRONTEND_XOCDE_PROVISIONING_PROFILE_UUID "GpgFrontend ProvisioningProfile UUID" "NONE")
+option(GPGFRONTEND_XOCDE_ENABLE_SANDBOX "Enable SandBox For Xcode Build" OFF)
# analyse options
if (GPGFRONTEND_BUILD_TYPE_TEST_CORE)
@@ -443,40 +444,6 @@ endif ()
SET(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)
-# disable myeasylog.log
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DELPP_NO_DEFAULT_LOG_FILE")
-
-# Introduce boost
-if(NOT BOOST_ROOT)
- find_package(Boost COMPONENTS date_time system REQUIRED)
-else()
- find_package(Boost
- COMPONENTS date_time system REQUIRED
- PATHS ${BOOST_ROOT} NO_DEFAULT_PATH)
-endif()
-
-# Introduce OpenSSL
-if(APPLE)
- set(OPENSSL_ROOT_DIR /usr/local/opt/[email protected])
-endif()
-find_package(OpenSSL REQUIRED)
-
-# Introduce Qt
-if (QT5_ENV_SUPPORT)
- # Support Qt version Both 5.12.x and 5.15.x
- find_package(Qt5 5.9 COMPONENTS Core Test Widgets PrintSupport Network REQUIRED)
-
- # Qt configuration
- set(CMAKE_AUTOMOC ON)
- set(CMAKE_AUTORCC ON)
- set(CMAKE_AUTOUIC ON)
-
- set(CMAKE_AUTORCC_OPTIONS "--compress;9")
- set(CMAKE_AUTOUIC_SEARCH_PATHS ${CMAKE_AUTOUIC_SEARCH_PATHS} ${CMAKE_SOURCE_DIR}/ui)
-
-endif ()
-
-
if (SMTP_SUPPORT)
add_compile_definitions(SMTP_SUPPORT)
endif ()
diff --git a/GpgFrontend.entitlements b/GpgFrontend.entitlements
new file mode 100644
index 00000000..637aa6f1
--- /dev/null
+++ b/GpgFrontend.entitlements
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.apple.security.app-sandbox</key>
+ <true/>
+ <key>com.apple.security.files.user-selected.read-write</key>
+ <true/>
+ <key>com.apple.security.network.client</key>
+ <true/>
+ <key>com.apple.security.print</key>
+ <true/>
+</dict>
+</plist>
diff --git a/README.md b/README.md
index 62def591..54a18a2b 100644
--- a/README.md
+++ b/README.md
@@ -217,9 +217,15 @@ $ ./linuxdeployqt-continuous-x86_64.AppImage ../release/gpgfrontend/usr/share/ap
## Languages Support
+<<<<<<< HEAD
+The supported languages are listed here. Some languages use machine translation and have not been verified. If you want
+to join translation and verification work, please refer to [HERE](https://gpgfrontend.pub/#/translate-interface).
+=======
The supported languages are listed here. Some translations use machine translation and have not been verified. If you want
to join translation or verification work, please refer to [HERE](https://gpgfrontend.pub/#/translate-interface).
+> > > > > > > main
+
### Supported Languages
'zh_CN', 'zh_TW', 'zh_HK', 'es_ES', 'fr_FR', 'de_DE', 'pl_PL', 'ru_RU', 'ja_JP', 'it_IT',
@@ -227,7 +233,7 @@ to join translation or verification work, please refer to [HERE](https://gpgfron
'hr_HR', 'cs_CZ', 'da_DK', 'nl_NL', 'et_EE', 'fa_IR', 'fi_FI', 'fr_CA', 'he_IL', 'id_ID',
'lt_LT', 'de_AT', 'de_CH', 'el_GR', 'es_MX', 'iw_IL', 'uk_UA', 'en_US', 'en_GB', 'en_AU',
-Notice: Most translations are generated by Google's automatic translation machine.If you find that a certain translation
+Notice: Most translations are generated by Google's automatic translation machine. If you find that a certain translation
is wrong, you are welcome to join the translation work to provide a more suitable human translation.
## Contract
diff --git a/resource/lfs/macOS/GnuPG/agent/gpg-agent b/resource/lfs/macOS/GnuPG/agent/gpg-agent
new file mode 100755
index 00000000..190c40e2
--- /dev/null
+++ b/resource/lfs/macOS/GnuPG/agent/gpg-agent
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:09ad99b28e3b2db960965f7debf20d5d64867cebc6852d52a853f827dad7c7b5
+size 436544
diff --git a/resource/lfs/macOS/GnuPG/bin/gpgconf b/resource/lfs/macOS/GnuPG/bin/gpgconf
new file mode 100755
index 00000000..f30709d1
--- /dev/null
+++ b/resource/lfs/macOS/GnuPG/bin/gpgconf
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1d433cb8cd39b2e727467452063047005205b4e742e24ffb2b8d2e2c3389c798
+size 88
diff --git a/resource/lfs/macOS/GnuPG/bin/gpgconf-original b/resource/lfs/macOS/GnuPG/bin/gpgconf-original
new file mode 100755
index 00000000..e305b949
--- /dev/null
+++ b/resource/lfs/macOS/GnuPG/bin/gpgconf-original
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:453e1ff371d08aee36b84899582ba68bc275ba8883340ea183f0c82a51bf480c
+size 201552
diff --git a/resource/lfs/macOS/GnuPG/dirmngr/dirmngr b/resource/lfs/macOS/GnuPG/dirmngr/dirmngr
new file mode 100755
index 00000000..944a545a
--- /dev/null
+++ b/resource/lfs/macOS/GnuPG/dirmngr/dirmngr
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:80903d1d7107d87f350790a01fb19a6206cc36d62d50d82865e1ef9c081d443b
+size 581472
diff --git a/resource/lfs/macOS/GnuPG/g10/gpg b/resource/lfs/macOS/GnuPG/g10/gpg
new file mode 100755
index 00000000..92f49d92
--- /dev/null
+++ b/resource/lfs/macOS/GnuPG/g10/gpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d8973db4e183b7b26aed45fc663ff34e2d0ba52b0d3d08bc249294d89a955cf1
+size 1033696
diff --git a/resource/lfs/macOS/GnuPG/kbx/keyboxd b/resource/lfs/macOS/GnuPG/kbx/keyboxd
new file mode 100755
index 00000000..e3675190
--- /dev/null
+++ b/resource/lfs/macOS/GnuPG/kbx/keyboxd
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c66166e8e8efef62e18c67cd2bac0db5d0ba50e6c0eb117fc07369f1bb55d207
+size 305488
diff --git a/resource/lfs/macOS/GnuPG/libs/libassuan.0.dylib b/resource/lfs/macOS/GnuPG/libs/libassuan.0.dylib
new file mode 100644
index 00000000..b1775f54
--- /dev/null
+++ b/resource/lfs/macOS/GnuPG/libs/libassuan.0.dylib
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:243914cefac155f1843f91331d2eb3326154ba5f68a1143b3882b8fc94f13bc4
+size 116640
diff --git a/resource/lfs/macOS/GnuPG/libs/libgcrypt.20.dylib b/resource/lfs/macOS/GnuPG/libs/libgcrypt.20.dylib
new file mode 100644
index 00000000..e1a31ac4
--- /dev/null
+++ b/resource/lfs/macOS/GnuPG/libs/libgcrypt.20.dylib
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:cc444590a050499a5f516284b43cedeba243822729b3c593ac458ca5a509a710
+size 842032
diff --git a/resource/lfs/macOS/GnuPG/libs/libgmp.10.dylib b/resource/lfs/macOS/GnuPG/libs/libgmp.10.dylib
new file mode 100644
index 00000000..829aea2b
--- /dev/null
+++ b/resource/lfs/macOS/GnuPG/libs/libgmp.10.dylib
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ed2249f92c4386a97513991642ee9eb6af041c646e3c9fdab2ac4c6f468fefec
+size 486352
diff --git a/resource/lfs/macOS/GnuPG/libs/libgnutls.30.dylib b/resource/lfs/macOS/GnuPG/libs/libgnutls.30.dylib
new file mode 100644
index 00000000..55330b13
--- /dev/null
+++ b/resource/lfs/macOS/GnuPG/libs/libgnutls.30.dylib
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ddc00b098c8a5c43fcba2524d9c9a0cb323fd1f77e6b64a809927ebcf14f542c
+size 1948912
diff --git a/resource/lfs/macOS/GnuPG/libs/libgpg-error.0.dylib b/resource/lfs/macOS/GnuPG/libs/libgpg-error.0.dylib
new file mode 100644
index 00000000..16479414
--- /dev/null
+++ b/resource/lfs/macOS/GnuPG/libs/libgpg-error.0.dylib
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ac9396f90299bd5952399c5428ed41b285e1b35d97ff90ee7917f17b314df746
+size 178496
diff --git a/resource/lfs/macOS/GnuPG/libs/libhogweed.6.6.dylib b/resource/lfs/macOS/GnuPG/libs/libhogweed.6.6.dylib
new file mode 100644
index 00000000..e76bc3ae
--- /dev/null
+++ b/resource/lfs/macOS/GnuPG/libs/libhogweed.6.6.dylib
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e6581f0ae342f40ac50f205bbfb3cb3b639eeebad4aa10f0892aab4e2c42f1db
+size 300160
diff --git a/resource/lfs/macOS/GnuPG/libs/libidn2.0.dylib b/resource/lfs/macOS/GnuPG/libs/libidn2.0.dylib
new file mode 100644
index 00000000..1e6338ba
--- /dev/null
+++ b/resource/lfs/macOS/GnuPG/libs/libidn2.0.dylib
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:308f59ceaa30199b39fdcb63080f86c0135beb744a0f73d89155bc94ed44ac1f
+size 259536
diff --git a/resource/lfs/macOS/GnuPG/libs/libintl.8.dylib b/resource/lfs/macOS/GnuPG/libs/libintl.8.dylib
new file mode 100644
index 00000000..ed4dfc46
--- /dev/null
+++ b/resource/lfs/macOS/GnuPG/libs/libintl.8.dylib
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c55333e6fa8832b6f8a0276bfce9a50cecee95af2515e9d2fbde04074cfdbc5e
+size 111216
diff --git a/resource/lfs/macOS/GnuPG/libs/libksba.8.dylib b/resource/lfs/macOS/GnuPG/libs/libksba.8.dylib
new file mode 100644
index 00000000..20a0ceb5
--- /dev/null
+++ b/resource/lfs/macOS/GnuPG/libs/libksba.8.dylib
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e1604bb672c6a414b5c2dc2e3a5fc1a26554c74ec0790cf66c622d594466f04a
+size 267344
diff --git a/resource/lfs/macOS/GnuPG/libs/libnettle.8.6.dylib b/resource/lfs/macOS/GnuPG/libs/libnettle.8.6.dylib
new file mode 100644
index 00000000..5da22375
--- /dev/null
+++ b/resource/lfs/macOS/GnuPG/libs/libnettle.8.6.dylib
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:952c262111a35af64debcdcac6d38e9bf794b4602e6661625345b8f74813382d
+size 315664
diff --git a/resource/lfs/macOS/GnuPG/libs/libnpth.0.dylib b/resource/lfs/macOS/GnuPG/libs/libnpth.0.dylib
new file mode 100644
index 00000000..8b17220c
--- /dev/null
+++ b/resource/lfs/macOS/GnuPG/libs/libnpth.0.dylib
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e01272a5843b3abf78ecd0862a09d6648c7217c31fc1eccac23f380e4f84d1ee
+size 56464
diff --git a/resource/lfs/macOS/GnuPG/libs/libp11-kit.0.dylib b/resource/lfs/macOS/GnuPG/libs/libp11-kit.0.dylib
new file mode 100644
index 00000000..6a974b2f
--- /dev/null
+++ b/resource/lfs/macOS/GnuPG/libs/libp11-kit.0.dylib
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1df14b9fd115d317087f606a312f3095082e3286da21801f4f5ac41449f1babd
+size 1022832
diff --git a/resource/lfs/macOS/GnuPG/libs/libreadline.8.2.dylib b/resource/lfs/macOS/GnuPG/libs/libreadline.8.2.dylib
new file mode 100644
index 00000000..232ff1a9
--- /dev/null
+++ b/resource/lfs/macOS/GnuPG/libs/libreadline.8.2.dylib
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b1c19c68716d6098eff03f3d2bb62d312b9ebcca44c7b51ccc67d6cd3329b1ed
+size 295968
diff --git a/resource/lfs/macOS/GnuPG/libs/libtasn1.6.dylib b/resource/lfs/macOS/GnuPG/libs/libtasn1.6.dylib
new file mode 100644
index 00000000..22bc919e
--- /dev/null
+++ b/resource/lfs/macOS/GnuPG/libs/libtasn1.6.dylib
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:57c57b889d791ffca6f3c128dc6396de707086c11d1067a7c92b9e55cff49950
+size 125328
diff --git a/resource/lfs/macOS/GnuPG/libs/libunistring.5.dylib b/resource/lfs/macOS/GnuPG/libs/libunistring.5.dylib
new file mode 100644
index 00000000..7fc15150
--- /dev/null
+++ b/resource/lfs/macOS/GnuPG/libs/libunistring.5.dylib
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c9f775e184335cc6bbb7e2b702f14054ac38672c4cd1648e12cedf4f2a4cd0e3
+size 1849472
diff --git a/resource/lfs/macOS/GnuPG/libs/libusb-1.0.0.dylib b/resource/lfs/macOS/GnuPG/libs/libusb-1.0.0.dylib
new file mode 100644
index 00000000..569c5bdd
--- /dev/null
+++ b/resource/lfs/macOS/GnuPG/libs/libusb-1.0.0.dylib
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1e35b0eb52d44b464970aa671113f87089c4b540933437d2bf0dac8fcfc38fba
+size 161040
diff --git a/resource/lfs/macOS/GnuPG/scd/scdaemon b/resource/lfs/macOS/GnuPG/scd/scdaemon
new file mode 100755
index 00000000..ba7d6de6
--- /dev/null
+++ b/resource/lfs/macOS/GnuPG/scd/scdaemon
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1dd2a6bdf916e99dfbf6d662941661805de38f78bcf3522a9813fc430bede78e
+size 555632
diff --git a/resource/lfs/macOS/GnuPG/sm/gpgsm b/resource/lfs/macOS/GnuPG/sm/gpgsm
new file mode 100755
index 00000000..784b56ba
--- /dev/null
+++ b/resource/lfs/macOS/GnuPG/sm/gpgsm
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9e660da5cdf99a0ff9be44326332a7d901b41a05136f279beb26dd81b4155555
+size 550544
diff --git a/resource/lfs/macOS/GnuPG/tools/gpg-connect-agent b/resource/lfs/macOS/GnuPG/tools/gpg-connect-agent
new file mode 100755
index 00000000..882568b5
--- /dev/null
+++ b/resource/lfs/macOS/GnuPG/tools/gpg-connect-agent
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2b696f753532e0ff1c149c6e0e4b602982aa3715f31456d448b1ee3dfacbb06b
+size 202832
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e00f9b60..4ec07d66 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -24,6 +24,40 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
+# Introduce boost
+if(NOT BOOST_ROOT)
+ find_package(Boost COMPONENTS date_time system REQUIRED)
+else()
+ find_package(Boost
+ COMPONENTS date_time system REQUIRED
+ PATHS ${BOOST_ROOT} NO_DEFAULT_PATH)
+endif()
+
+# Introduce OpenSSL
+if(APPLE)
+ set(OPENSSL_ROOT_DIR /usr/local/opt/[email protected])
+endif()
+find_package(OpenSSL REQUIRED)
+
+# Introduce Qt
+if (QT5_ENV_SUPPORT)
+ # Support Qt version: 6.x, 5.12.x and 5.15.x
+ find_package(Qt6 6.3 COMPONENTS Core Test Widgets PrintSupport Network Core5Compat)
+ if(NOT Qt6_DIR)
+ find_package(Qt5 5.9 COMPONENTS Core Test Widgets PrintSupport Network REQUIRED)
+ else()
+ add_definitions(-DGPGFRONTEND_GUI_QT6)
+ endif()
+
+ # Qt configuration
+ set(CMAKE_AUTOMOC ON)
+ set(CMAKE_AUTORCC ON)
+ set(CMAKE_AUTOUIC ON)
+
+ set(CMAKE_AUTORCC_OPTIONS "--compress;9")
+ set(CMAKE_AUTOUIC_SEARCH_PATHS ${CMAKE_AUTOUIC_SEARCH_PATHS} ${CMAKE_SOURCE_DIR}/ui)
+endif ()
+
# configure for output path and resources
if (APPLICATION_BUILD)
aux_source_directory(. BASE_SOURCE)
@@ -160,14 +194,148 @@ if (APPLICATION_BUILD)
# Copy Utils Files
if (MINGW)
message(STATUS "Copying Dependent DLL For Windows Runtime Env")
- file(COPY ${CMAKE_SOURCE_DIR}/resource/utils/lib/ DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
- file(COPY ${CMAKE_SOURCE_DIR}/resource/utils/gpgme/ DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
- file(COPY ${CMAKE_SOURCE_DIR}/resource/utils/bearer DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
- file(COPY ${CMAKE_SOURCE_DIR}/resource/utils/iconengines DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
- file(COPY ${CMAKE_SOURCE_DIR}/resource/utils/imageformats DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
- file(COPY ${CMAKE_SOURCE_DIR}/resource/utils/printsupport DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
- file(COPY ${CMAKE_SOURCE_DIR}/resource/utils/platforms DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
- file(COPY ${CMAKE_SOURCE_DIR}/resource/utils/openssl/ DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
+
+ 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}/libconfig++-*.dll")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
+
+ unset(_libDllPath)
+ file(GLOB _libDllPath "${_libDllBinPath}/libarchive-*.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})
+
+ # gpgme-w32spawn.exe
+ unset(_libExEPath)
+ file(GLOB _libExEPath "${_libDllBinPath}/gpgme-w32spawn.exe")
+ list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libExEPath})
+
+ set(ALL_RUNTIME_DLL_FILES "")
+ 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;")
+ # 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 ()
@@ -183,8 +351,16 @@ if (APPLICATION_BUILD)
if (${CMAKE_BUILD_TYPE} STREQUAL "Release")
if (MINGW)
add_executable(${AppName} WIN32 ${BASE_SOURCE} ${RESOURCE_FILES} ${QT5_MOCS})
- # custom app bundle packing
+ # 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 (APPLE AND NOT XCODE_BUILD)
+ # custom app bundle packing
add_executable(${AppName} MACOSX_BUNDLE ${ICON_RESOURCE} ${BASE_SOURCE} ${RESOURCE_FILES} ${QT5_MOCS})
set_target_properties(${AppName} PROPERTIES
BUNDLE True
@@ -214,6 +390,7 @@ if (APPLICATION_BUILD)
COMMENT "Complement to build the required architecture")
# app bundle packing using xcode
elseif (APPLE AND XCODE_BUILD)
+ # standard app bundle packing
add_executable(${AppName} MACOSX_BUNDLE ${ICON_RESOURCE} ${BASE_SOURCE} ${RESOURCE_FILES} ${QT5_MOCS})
set_target_properties(${AppName} PROPERTIES
BUNDLE True
@@ -239,19 +416,43 @@ if (APPLICATION_BUILD)
COMMAND macdeployqt ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_BUILD_TYPE}/${AppName}.app
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
COMMENT "Resolving Qt Dependency")
+
+ # option for sandbox mode, still under test
+ if(GPGFRONTEND_XOCDE_ENABLE_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")
+ else()
+ 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 "No"
+ XCODE_ATTRIBUTE_ENABLE_APP_SANDBOX "${CUSTOM_ATTRIBUTE_ENABLE_APP_SANDBOX}"
XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME "Yes"
+ XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_SOURCE_DIR}/GpgFrontend.entitlements"
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}"
)
else ()
add_executable(${AppName} ${BASE_SOURCE} ${RESOURCE_FILES} ${QT5_MOCS})
endif ()
else ()
+ # if the status is debug
add_executable(${AppName} ${BASE_SOURCE} ${RESOURCE_FILES} ${QT5_MOCS})
+ 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
diff --git a/src/GpgFrontend.h.in b/src/GpgFrontend.h.in
index 78ab6e6a..f441fb8f 100644
--- a/src/GpgFrontend.h.in
+++ b/src/GpgFrontend.h.in
@@ -57,9 +57,8 @@
// logging system
-#define ELPP_DEFAULT_LOGGING_FLAGS 8192
-#include <easylogging++.h>
-
+#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_TRACE
+#include <spdlog/spdlog.h>
// build info
#define PROJECT_NAME "@CMAKE_PROJECT_NAME@"
diff --git a/src/before_exit.cpp b/src/before_exit.cpp
index f13649db..31c56354 100644
--- a/src/before_exit.cpp
+++ b/src/before_exit.cpp
@@ -32,4 +32,6 @@
* @brief Actions performed before exiting the application
*
*/
-void before_exit() { LOG(INFO) << "called"; }
+void before_exit() {
+
+}
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 0282b58c..22a0b88a 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -46,11 +46,6 @@ if (NOT LINUX)
target_link_libraries(gpgfrontend_core PUBLIC config++ intl)
endif ()
-# easyloggingpp
-target_include_directories(gpgfrontend_core PUBLIC
- ${CMAKE_SOURCE_DIR}/third_party/easyloggingpp/src)
-target_sources(gpgfrontend_core PUBLIC
- ${CMAKE_SOURCE_DIR}/third_party/easyloggingpp/src/easylogging++.cc)
# qt-aes
target_sources(gpgfrontend_core PRIVATE
${CMAKE_SOURCE_DIR}/third_party/qt-aes/qaesencryption.cpp)
@@ -82,6 +77,9 @@ if (MINGW)
target_link_libraries(gpgfrontend_core PUBLIC bcrypt)
endif ()
+# spdlog
+target_link_libraries(gpgfrontend_core PRIVATE spdlog)
+
# link libarchive
target_link_libraries(gpgfrontend_core PRIVATE archive)
@@ -89,7 +87,11 @@ target_link_libraries(gpgfrontend_core PRIVATE archive)
target_link_libraries(gpgfrontend_core
PUBLIC nlohmann_json::nlohmann_json)
# link Qt core
-target_link_libraries(gpgfrontend_core PUBLIC Qt5::Core)
+if(Qt6_DIR)
+ target_link_libraries(gpgfrontend_core PUBLIC Qt6::Core)
+else()
+ target_link_libraries(gpgfrontend_core PUBLIC Qt5::Core)
+endif()
# set up pch
target_precompile_headers(gpgfrontend_core
diff --git a/src/core/GpgConstants.cpp b/src/core/GpgConstants.cpp
index ff783872..35e485d4 100644
--- a/src/core/GpgConstants.cpp
+++ b/src/core/GpgConstants.cpp
@@ -53,9 +53,8 @@ const char* GpgFrontend::GpgConstants::GPG_FRONTEND_SHORT_CRYPTO_HEAD =
gpgme_error_t GpgFrontend::check_gpg_error(gpgme_error_t err) {
if (gpg_err_code(err) != GPG_ERR_NO_ERROR) {
- LOG(ERROR) << "[" << _("Error") << gpg_err_code(err) << "]" << _("Source: ")
- << gpgme_strsource(err) << _("Description: ")
- << gpgme_strerror(err);
+ SPDLOG_ERROR("[error: {}] source: {} description: {}", gpg_err_code(err),
+ gpgme_strsource(err), gpgme_strerror(err));
}
return err;
}
@@ -65,14 +64,13 @@ gpg_err_code_t GpgFrontend::check_gpg_error_2_err_code(gpgme_error_t err,
auto err_code = gpg_err_code(err);
if (err_code != gpg_err_code(predict)) {
if (err_code == GPG_ERR_NO_ERROR)
- LOG(WARNING) << "[" << _("Warning") << gpg_err_code(err) << "]"
- << _("Source: ") << gpgme_strsource(err)
- << _("Description: ") << gpgme_strerror(err) << _("Predict")
- << gpgme_strerror(err);
+ SPDLOG_WARN("[Warning {}] Source: {} description: {} predict: {}",
+ gpg_err_code(err), gpgme_strsource(err), gpgme_strerror(err),
+ gpgme_strerror(err));
else
- LOG(ERROR) << "[" << _("Error") << gpg_err_code(err) << "]"
- << _("Source: ") << gpgme_strsource(err) << _("Description: ")
- << gpgme_strerror(err) << _("Predict") << gpgme_strerror(err);
+ SPDLOG_ERROR("[Error {}] Source: {} description: {} predict: {}",
+ gpg_err_code(err), gpgme_strsource(err), gpgme_strerror(err),
+ gpgme_strerror(err));
}
return err_code;
}
@@ -80,9 +78,9 @@ gpg_err_code_t GpgFrontend::check_gpg_error_2_err_code(gpgme_error_t err,
gpgme_error_t GpgFrontend::check_gpg_error(gpgme_error_t err,
const std::string& comment) {
if (gpg_err_code(err) != GPG_ERR_NO_ERROR) {
- LOG(ERROR) << "[" << _("Error") << gpg_err_code(err) << "]" << _("Source: ")
- << gpgme_strsource(err) << _("Description: ")
- << gpgme_strerror(err);
+ SPDLOG_WARN("[Error {}] Source: {} description: {} predict: {}",
+ gpg_err_code(err), gpgme_strsource(err), gpgme_strerror(err),
+ gpgme_strerror(err));
}
return err;
}
@@ -201,6 +199,6 @@ GpgFrontend::GpgGenKeyResult GpgFrontend::_new_result(
}
void GpgFrontend::_result_ref_deletor::operator()(void* _result) {
- DLOG(INFO) << _("Called") << _result;
+ SPDLOG_TRACE("gpgme unref {}", _result);
if (_result != nullptr) gpgme_result_unref(_result);
}
diff --git a/src/core/GpgContext.cpp b/src/core/GpgContext.cpp
index 7ebd9fa9..a5213134 100644
--- a/src/core/GpgContext.cpp
+++ b/src/core/GpgContext.cpp
@@ -30,12 +30,19 @@
#include <gpg-error.h>
#include <gpgme.h>
+#include <unistd.h>
-#include <functional>
+#include <mutex>
+#include <shared_mutex>
#include <string>
-#include <utility>
-#include "GpgConstants.h"
+#include "core/GpgConstants.h"
+#include "core/GpgModel.h"
+#include "core/common/CoreCommonUtil.h"
+#include "core/function/CoreSignalStation.h"
+#include "core/function/gpg/GpgCommandExecutor.h"
+#include "core/thread/TaskRunnerGetter.h"
+#include "thread/Task.h"
#ifdef _WIN32
#include <windows.h>
@@ -55,7 +62,7 @@ GpgContext::GpgContext(const GpgContextInitArgs &args) : args_(args) {
if (_first) {
/* Initialize the locale environment. */
- LOG(INFO) << "locale" << setlocale(LC_CTYPE, nullptr);
+ SPDLOG_DEBUG("locale: {}", setlocale(LC_CTYPE, nullptr));
info_.GpgMEVersion = gpgme_check_version(nullptr);
gpgme_set_locale(nullptr, LC_CTYPE, setlocale(LC_CTYPE, nullptr));
#ifdef LC_MESSAGES
@@ -87,15 +94,14 @@ GpgContext::GpgContext(const GpgContextInitArgs &args) : args_(args) {
continue;
}
- LOG(INFO) << gpgme_get_protocol_name(engine_info->protocol)
- << std::string(engine_info->file_name == nullptr
- ? "null"
- : engine_info->file_name)
- << std::string(engine_info->home_dir == nullptr
- ? "null"
- : engine_info->home_dir)
- << std::string(engine_info->version ? "null"
- : engine_info->version);
+ SPDLOG_DEBUG(
+ "gpg context engine info: {} {} {} {}",
+ gpgme_get_protocol_name(engine_info->protocol),
+ std::string(engine_info->file_name == nullptr ? "null"
+ : engine_info->file_name),
+ std::string(engine_info->home_dir == nullptr ? "null"
+ : engine_info->home_dir),
+ std::string(engine_info->version ? "null" : engine_info->version));
switch (engine_info->protocol) {
case GPGME_PROTOCOL_OpenPGP:
@@ -137,7 +143,7 @@ GpgContext::GpgContext(const GpgContextInitArgs &args) : args_(args) {
auto err = gpgme_ctx_set_engine_info(_ctx_ref.get(), GPGME_PROTOCOL_OpenPGP,
info_.AppPath.c_str(),
info_.DatabasePath.c_str());
- LOG(INFO) << "ctx set custom key db path:" << info_.DatabasePath;
+ SPDLOG_DEBUG("ctx set custom key db path: {}", info_.DatabasePath);
assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
}
@@ -149,20 +155,28 @@ GpgContext::GpgContext(const GpgContextInitArgs &args) : args_(args) {
if (!check_passed) {
this->good_ = false;
- LOG(ERROR) << "Env check failed";
+ SPDLOG_ERROR("env check failed");
return;
} else {
- LOG(INFO) << "gnupg version" << info_.GnupgVersion;
- init_ctx();
+ // async, init context
+ Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_GPG)
+ ->PostTask(new Thread::Task(
+ [=](Thread::Task::DataObjectPtr) -> int {
+ post_init_ctx();
+ return 0;
+ },
+ "post_init_ctx"));
+
good_ = true;
}
}
-void GpgContext::init_ctx() {
+void GpgContext::post_init_ctx() {
// Set Independent Database
if (info_.GnupgVersion <= "2.0.0" && args_.independent_database) {
info_.DatabasePath = args_.db_path;
- LOG(INFO) << "custom key db path" << info_.DatabasePath;
+ SPDLOG_DEBUG("custom key db path {}", info_.DatabasePath);
auto err = gpgme_ctx_set_engine_info(_ctx_ref.get(), GPGME_PROTOCOL_OpenPGP,
info_.AppPath.c_str(),
info_.DatabasePath.c_str());
@@ -198,10 +212,18 @@ void GpgContext::init_ctx() {
// for unit test
if (args_.test_mode) {
- LOG(INFO) << "test mode";
if (info_.GnupgVersion >= "2.1.0") SetPassphraseCb(test_passphrase_cb);
gpgme_set_status_cb(*this, test_status_cb, nullptr);
}
+
+ // preload info
+ auto &info = GetInfo();
+
+ // listen passphrase input event
+ SetPassphraseCb(custom_passphrase_cb);
+ connect(this, &GpgContext::SignalNeedUserInputPassphrase,
+ CoreSignalStation::GetInstance(),
+ &CoreSignalStation::SignalNeedUserInputPassphrase);
}
bool GpgContext::good() const { return good_; }
@@ -213,7 +235,7 @@ void GpgContext::SetPassphraseCb(gpgme_passphrase_cb_t cb) const {
}
gpgme_set_passphrase_cb(*this, cb, nullptr);
} else {
- LOG(ERROR) << "Not supported for gnupg version" << info_.GnupgVersion;
+ SPDLOG_ERROR("not supported for gnupg version: {}", info_.GnupgVersion);
}
}
@@ -234,12 +256,327 @@ gpgme_error_t GpgContext::test_passphrase_cb(void *opaque, const char *uid_hint,
return off == pass_len ? 0 : gpgme_error_from_errno(errno);
}
+gpgme_error_t GpgContext::custom_passphrase_cb(void *opaque,
+ const char *uid_hint,
+ const char *passphrase_info,
+ int last_was_bad, int fd) {
+ SPDLOG_DEBUG("custom passphrase cb called, bad times: {}", last_was_bad);
+
+ if (last_was_bad > 3) {
+ SPDLOG_WARN("failure_counts is over three times");
+ return gpgme_error_from_errno(GPG_ERR_CANCELED);
+ }
+
+ std::string passphrase =
+ CoreCommonUtil::GetInstance()->GetTempCacheValue("__key_passphrase");
+ // no pawword is an error situation
+ if (passphrase.empty()) {
+ // user input passphrase
+ SPDLOG_DEBUG("might need user to input passparase");
+ passphrase = GpgContext::GetInstance().need_user_input_passphrase();
+ if (passphrase.empty()) {
+ gpgme_io_write(fd, "\n", 1);
+ return gpgme_error_from_errno(GPG_ERR_CANCELED);
+ }
+ }
+
+ // the user must at least write a newline character before returning from the
+ // callback.
+ passphrase = passphrase.append("\n");
+ auto passpahrase_size = passphrase.size();
+
+ size_t off = 0, res = 0;
+ do {
+ res = gpgme_io_write(fd, &passphrase[off], passpahrase_size - off);
+ if (res > 0) off += res;
+ } while (res > 0 && off != passpahrase_size);
+
+ return off == passpahrase_size ? 0 : gpgme_error_from_errno(GPG_ERR_CANCELED);
+}
+
gpgme_error_t GpgContext::test_status_cb(void *hook, const char *keyword,
const char *args) {
- LOG(INFO) << "keyword" << keyword;
+ SPDLOG_DEBUG("keyword {}", keyword);
return GPG_ERR_NO_ERROR;
}
+std::string GpgContext::need_user_input_passphrase() {
+ emit SignalNeedUserInputPassphrase();
+
+ std::string final_passphrase;
+ bool input_done = false;
+ SPDLOG_DEBUG("loop start to wait from user");
+ auto connection =
+ connect(CoreSignalStation::GetInstance(),
+ &CoreSignalStation::SignalUserInputPassphraseDone, this,
+ [&](QString passphrase) {
+ SPDLOG_DEBUG("SignalUserInputPassphraseDone emitted");
+ final_passphrase = passphrase.toStdString();
+ input_done = true;
+ });
+ while (!input_done) {
+ QCoreApplication::processEvents(QEventLoop::AllEvents, 800);
+ }
+ disconnect(connection);
+
+ SPDLOG_DEBUG("lopper end");
+ return final_passphrase;
+}
+
+const GpgInfo &GpgContext::GetInfo(bool refresh) {
+ if (!extend_info_loaded_ || refresh) {
+ // try lock
+ std::unique_lock lock(preload_lock_);
+
+ // check twice
+ if (extend_info_loaded_ && !refresh) return info_;
+
+ SPDLOG_DEBUG("start to load extra info");
+
+ // get all components
+ GpgCommandExecutor::GetInstance().Execute(
+ info_.GpgConfPath, {"--list-components"},
+ [=](int exit_code, const std::string &p_out, const std::string &p_err) {
+ SPDLOG_DEBUG(
+ "gpgconf components exit_code: {} process stdout size: {}",
+ exit_code, p_out.size());
+
+ if (exit_code != 0) {
+ SPDLOG_ERROR(
+ "gpgconf execute error, process stderr: {} ,process stdout: "
+ "{}",
+ p_err, p_out);
+ return;
+ }
+
+ auto &components_info = info_.ComponentsInfo;
+ components_info["gpgme"] = {"GPG Made Easy", info_.GpgMEVersion,
+ _("Embedded In"), "/"};
+
+ auto gpgconf_binary_checksum =
+ check_binary_chacksum(info_.GpgConfPath);
+ components_info["gpgconf"] = {"GPG Configure", "/", info_.GpgConfPath,
+ gpgconf_binary_checksum.has_value()
+ ? gpgconf_binary_checksum.value()
+ : "/"};
+
+ std::vector<std::string> line_split_list;
+ boost::split(line_split_list, p_out, boost::is_any_of("\n"));
+
+ for (const auto &line : line_split_list) {
+ std::vector<std::string> info_split_list;
+ boost::split(info_split_list, line, boost::is_any_of(":"));
+
+ if (info_split_list.size() != 3) continue;
+
+ auto component_name = info_split_list[0];
+ auto component_desc = info_split_list[1];
+ auto component_path = info_split_list[2];
+ auto binary_checksum = check_binary_chacksum(component_path);
+
+ SPDLOG_DEBUG(
+ "gnupg component name: {} desc: {} checksum: {} path: {} ",
+ component_name, component_desc,
+ binary_checksum.has_value() ? binary_checksum.value() : "/",
+ component_path);
+
+ std::string version = "/";
+
+ if (component_name == "gpg") {
+ version = info_.GnupgVersion;
+ }
+ if (component_name == "gpg-agent") {
+ info_.GpgAgentPath = info_split_list[2];
+ }
+ if (component_name == "dirmngr") {
+ info_.DirmngrPath = info_split_list[2];
+ }
+ if (component_name == "keyboxd") {
+ info_.KeyboxdPath = info_split_list[2];
+ }
+
+ {
+ // try lock
+ std::unique_lock lock(info_.Lock);
+ // add component info to list
+ components_info[component_name] = {
+ component_desc, version, component_path,
+ binary_checksum.has_value() ? binary_checksum.value() : "/"};
+ }
+ }
+ });
+
+ SPDLOG_DEBUG("start to get dirs info");
+
+ GpgCommandExecutor::GetInstance().ExecuteConcurrently(
+ info_.GpgConfPath, {"--list-dirs"},
+ [=](int exit_code, const std::string &p_out, const std::string &p_err) {
+ SPDLOG_DEBUG(
+ "gpgconf configurations exit_code: {} process stdout size: {}",
+ exit_code, p_out.size());
+
+ if (exit_code != 0) {
+ SPDLOG_ERROR(
+ "gpgconf execute error, process stderr: {} process stdout: "
+ "{}",
+ p_err, p_out);
+ return;
+ }
+
+ auto &configurations_info = info_.ConfigurationsInfo;
+
+ std::vector<std::string> line_split_list;
+ boost::split(line_split_list, p_out, boost::is_any_of("\n"));
+
+ for (const auto &line : line_split_list) {
+ std::vector<std::string> info_split_list;
+ boost::split(info_split_list, line, boost::is_any_of(":"));
+ SPDLOG_DEBUG("gpgconf info line: {} info size: {}", line,
+ info_split_list.size());
+
+ if (info_split_list.size() != 2) continue;
+
+ // record gnupg home path
+ if (info_split_list[0] == "homedir") {
+ info_.GnuPGHomePath = info_split_list[1];
+ }
+
+ auto configuration_name = info_split_list[0];
+ {
+ // try lock
+ std::unique_lock lock(info_.Lock);
+ configurations_info[configuration_name] = {info_split_list[1]};
+ }
+ }
+ });
+
+ SPDLOG_DEBUG("start to get components info");
+
+ for (const auto &component : info_.ComponentsInfo) {
+ SPDLOG_DEBUG("gpgconf check options ready", "component", component.first);
+
+ if (component.first == "gpgme" || component.first == "gpgconf") continue;
+
+ GpgCommandExecutor::GetInstance().ExecuteConcurrently(
+ info_.GpgConfPath, {"--check-options", component.first},
+ [=](int exit_code, const std::string &p_out,
+ const std::string &p_err) {
+ SPDLOG_DEBUG(
+ "gpgconf {} options exit_code: {} process stdout "
+ "size: {} ",
+ component.first, exit_code, p_out.size());
+
+ if (exit_code != 0) {
+ SPDLOG_ERROR(
+ "gpgconf {} options execute error, process "
+ "stderr: {} , process stdout:",
+ component.first, p_err, p_out);
+ return;
+ }
+
+ auto &options_info = info_.OptionsInfo;
+
+ std::vector<std::string> line_split_list;
+ boost::split(line_split_list, p_out, boost::is_any_of("\n"));
+
+ for (const auto &line : line_split_list) {
+ std::vector<std::string> info_split_list;
+ boost::split(info_split_list, line, boost::is_any_of(":"));
+
+ SPDLOG_DEBUG("component {} options line: {} info size: {}",
+ component.first, line, info_split_list.size());
+
+ if (info_split_list.size() != 6) continue;
+
+ auto configuration_name = info_split_list[0];
+ {
+ // try lock
+ std::unique_lock lock(info_.Lock);
+ options_info[configuration_name] = {
+ info_split_list[1], info_split_list[2], info_split_list[3],
+ info_split_list[4], info_split_list[5]};
+ }
+ }
+ });
+ }
+
+ SPDLOG_DEBUG("start to get avaliable component options info");
+
+ for (const auto &component : info_.ComponentsInfo) {
+ SPDLOG_DEBUG("gpgconf list options ready", "component", component.first);
+
+ if (component.first == "gpgme" || component.first == "gpgconf") continue;
+
+ GpgCommandExecutor::GetInstance().ExecuteConcurrently(
+ info_.GpgConfPath, {"--list-options", component.first},
+ [=](int exit_code, const std::string &p_out,
+ const std::string &p_err) {
+ SPDLOG_DEBUG(
+ "gpgconf {} avaliable options exit_code: {} process stdout "
+ "size: {} ",
+ component.first, exit_code, p_out.size());
+
+ if (exit_code != 0) {
+ SPDLOG_ERROR(
+ "gpgconf {} avaliable options execute error, process stderr: "
+ "{} , process stdout:",
+ component.first, p_err, p_out);
+ return;
+ }
+
+ auto &available_options_info = info_.AvailableOptionsInfo;
+
+ std::vector<std::string> line_split_list;
+ boost::split(line_split_list, p_out, boost::is_any_of("\n"));
+
+ for (const auto &line : line_split_list) {
+ std::vector<std::string> info_split_list;
+ boost::split(info_split_list, line, boost::is_any_of(":"));
+
+ SPDLOG_DEBUG(
+ "component {} avaliable options line: {} info size: {}",
+ component.first, line, info_split_list.size());
+
+ if (info_split_list.size() != 10) continue;
+
+ auto configuration_name = info_split_list[0];
+ {
+ // try lock
+ std::unique_lock lock(info_.Lock);
+ available_options_info[configuration_name] = {
+ info_split_list[1], info_split_list[2], info_split_list[3],
+ info_split_list[4], info_split_list[5], info_split_list[6],
+ info_split_list[7], info_split_list[8], info_split_list[9]};
+ }
+ }
+ });
+ }
+ extend_info_loaded_ = true;
+ }
+
+ // ensure nothing is changing now
+ std::shared_lock lock(preload_lock_);
+ return info_;
+}
+
+std::optional<std::string> GpgContext::check_binary_chacksum(
+ std::filesystem::path path) {
+ QFile f(QString::fromStdString(path.u8string()));
+ if (!f.open(QFile::ReadOnly)) return {};
+
+ // read all data from file
+ auto buffer = f.readAll();
+ f.close();
+
+ auto hash_md5 = QCryptographicHash(QCryptographicHash::Md5);
+ // md5
+ hash_md5.addData(buffer);
+ auto md5 = hash_md5.result().toHex().toStdString();
+ SPDLOG_DEBUG("md5 {}", md5);
+
+ return md5.substr(0, 6);
+}
+
void GpgContext::_ctx_ref_deleter::operator()(gpgme_ctx_t _ctx) {
if (_ctx != nullptr) gpgme_release(_ctx);
}
diff --git a/src/core/GpgContext.h b/src/core/GpgContext.h
index e1f1bda4..384271a6 100644
--- a/src/core/GpgContext.h
+++ b/src/core/GpgContext.h
@@ -29,6 +29,9 @@
#ifndef __SGPGMEPP_CONTEXT_H__
#define __SGPGMEPP_CONTEXT_H__
+#include <optional>
+#include <string>
+
#include "GpgConstants.h"
#include "GpgFunctionObject.h"
#include "GpgInfo.h"
@@ -57,7 +60,9 @@ struct GpgContextInitArgs {
*
*/
class GPGFRONTEND_CORE_EXPORT GpgContext
- : public SingletonFunctionObject<GpgContext> {
+ : public QObject,
+ public SingletonFunctionObject<GpgContext> {
+ Q_OBJECT
public:
/**
* @brief Construct a new Gpg Context object
@@ -92,7 +97,7 @@ class GPGFRONTEND_CORE_EXPORT GpgContext
*
* @return const GpgInfo&
*/
- [[nodiscard]] const GpgInfo& GetInfo() const { return info_; }
+ [[nodiscard]] const GpgInfo& GetInfo(bool refresh = false);
/**
* @brief
@@ -102,14 +107,29 @@ class GPGFRONTEND_CORE_EXPORT GpgContext
operator gpgme_ctx_t() const { return _ctx_ref.get(); }
private:
- GpgInfo info_; ///<
- GpgContextInitArgs args_; ///<
+ GpgInfo info_{}; ///<
+ GpgContextInitArgs args_{}; ///<
+ bool extend_info_loaded_ = false;
+ std::shared_mutex preload_lock_{};
/**
* @brief
*
*/
- void init_ctx();
+ void post_init_ctx();
+
+ /**
+ * @brief
+ *
+ * @return std::string
+ */
+ std::string need_user_input_passphrase();
+
+ /**
+ * @brief Construct a new std::check component existence object
+ *
+ */
+ std::optional<std::string> check_binary_chacksum(std::filesystem::path);
/**
* @brief
@@ -124,6 +144,13 @@ class GPGFRONTEND_CORE_EXPORT GpgContext
CtxRefHandler _ctx_ref = nullptr; ///<
bool good_ = true; ///<
+ signals:
+ /**
+ * @brief
+ *
+ */
+ void SignalNeedUserInputPassphrase();
+
public:
/**
* @brief
@@ -142,6 +169,20 @@ class GPGFRONTEND_CORE_EXPORT GpgContext
/**
* @brief
*
+ * @param opaque
+ * @param uid_hint
+ * @param passphrase_info
+ * @param last_was_bad
+ * @param fd
+ * @return gpgme_error_t
+ */
+ static gpgme_error_t custom_passphrase_cb(void* opaque, const char* uid_hint,
+ const char* passphrase_info,
+ int last_was_bad, int fd);
+
+ /**
+ * @brief
+ *
* @param hook
* @param keyword
* @param args
diff --git a/src/core/GpgCoreInit.cpp b/src/core/GpgCoreInit.cpp
index 9ccc693d..840b2b87 100644
--- a/src/core/GpgCoreInit.cpp
+++ b/src/core/GpgCoreInit.cpp
@@ -25,15 +25,17 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-
#include "GpgCoreInit.h"
+#include <spdlog/async.h>
+#include <spdlog/common.h>
+#include <spdlog/sinks/rotating_file_sink.h>
+#include <spdlog/sinks/stdout_color_sinks.h>
+
#include "GpgFunctionObject.h"
#include "core/GpgContext.h"
#include "core/function/GlobalSettingStation.h"
-
-// init easyloggingpp library
-INITIALIZE_EASYLOGGINGPP
+#include "function/gpg/GpgAdvancedOperator.h"
namespace GpgFrontend {
@@ -41,40 +43,51 @@ namespace GpgFrontend {
* @brief setup logging system and do proper initialization
*
*/
-void InitLoggingSystem() {
+void InitCoreLoggingSystem() {
using namespace boost::posix_time;
using namespace boost::gregorian;
- el::Loggers::addFlag(el::LoggingFlag::AutoSpacing);
- el::Loggers::addFlag(el::LoggingFlag::ColoredTerminalOutput);
- el::Loggers::addFlag(el::LoggingFlag::StrictLogFileSizeCheck);
- el::Configurations defaultConf;
- defaultConf.setToDefault();
-
- // apply settings
- defaultConf.setGlobally(el::ConfigurationType::Format,
- "%datetime %level [core] {%func} -> %msg");
-
- // apply settings no written to file
- defaultConf.setGlobally(el::ConfigurationType::ToFile, "false");
-
- // set the logger
- el::Loggers::reconfigureLogger("default", defaultConf);
-
// get the log directory
- auto logfile_path = (GlobalSettingStation::GetInstance().GetLogDir() /
- to_iso_string(second_clock::local_time()));
+ auto logfile_path =
+ (GlobalSettingStation::GetInstance().GetLogDir() / "core");
logfile_path.replace_extension(".log");
- defaultConf.setGlobally(el::ConfigurationType::Filename,
- logfile_path.u8string());
-
- // apply settings written to file
- defaultConf.setGlobally(el::ConfigurationType::ToFile, "true");
- // set the logger
- el::Loggers::reconfigureLogger("default", defaultConf);
+ // sinks
+ std::vector<spdlog::sink_ptr> sinks;
+ sinks.push_back(std::make_shared<spdlog::sinks::stderr_color_sink_mt>());
+ sinks.push_back(std::make_shared<spdlog::sinks::rotating_file_sink_mt>(
+ logfile_path.u8string(), 1048576 * 32, 8));
+
+ // thread pool
+ spdlog::init_thread_pool(1024, 2);
+
+ // logger
+ auto core_logger = std::make_shared<spdlog::async_logger>(
+ "core", begin(sinks), end(sinks), spdlog::thread_pool());
+ core_logger->set_pattern(
+ "[%H:%M:%S.%e] [T:%t] [%=4n] %^[%=8l]%$ [%s:%#] [%!] -> %v (+%ius)");
+
+#ifdef DEBUG
+ core_logger->set_level(spdlog::level::trace);
+#else
+ core_logger->set_level(spdlog::level::info);
+#endif
+
+ // flush policy
+ core_logger->flush_on(spdlog::level::err);
+ spdlog::flush_every(std::chrono::seconds(5));
+
+ // register it as default logger
+ spdlog::set_default_logger(core_logger);
+}
- LOG(INFO) << _("log file path") << logfile_path;
+void ShutdownCoreLoggingSystem() {
+#ifdef WINDOWS
+ // Under VisualStudio, this must be called before main finishes to workaround
+ // a known VS issue
+ spdlog::drop_all();
+ spdlog::shutdown();
+#endif
}
void ResetGpgFrontendCore() { reset_gpgfrontend_core(); }
@@ -89,12 +102,11 @@ void init_gpgfrontend_core() {
use_custom_key_database_path =
settings.lookup("general.use_custom_key_database_path");
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error")
- << _("use_custom_key_database_path");
+ SPDLOG_ERROR("setting operation error: use_custom_key_database_path");
}
- LOG(INFO) << "core loaded if use custom key databse path: "
- << use_custom_key_database_path;
+ SPDLOG_DEBUG("core loaded if use custom key databse path: {}",
+ use_custom_key_database_path);
std::string custom_key_database_path;
try {
@@ -104,11 +116,11 @@ void init_gpgfrontend_core() {
settings.lookup("general.custom_key_database_path"));
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error") << _("custom_key_database_path");
+ SPDLOG_ERROR("setting operation error: custom_key_database_path");
}
- LOG(INFO) << "core loaded custom key databse path: "
- << custom_key_database_path;
+ SPDLOG_DEBUG("core loaded custom key databse path: {}",
+ custom_key_database_path);
// init default channel
GpgFrontend::GpgContext::CreateInstance(
@@ -136,6 +148,9 @@ void init_gpgfrontend_core() {
return std::unique_ptr<ChannelObject>(new GpgContext(args));
});
+
+ // try to restart all components
+ GpgFrontend::GpgAdvancedOperator::GetInstance().RestartGpgComponents();
}
void reset_gpgfrontend_core() { SingletonStorageCollection::GetInstance(true); }
diff --git a/src/core/GpgCoreInit.h b/src/core/GpgCoreInit.h
index 77942b56..41e04d60 100644
--- a/src/core/GpgCoreInit.h
+++ b/src/core/GpgCoreInit.h
@@ -37,7 +37,13 @@ namespace GpgFrontend {
* @brief
*
*/
-void GPGFRONTEND_CORE_EXPORT InitLoggingSystem();
+void GPGFRONTEND_CORE_EXPORT InitCoreLoggingSystem();
+
+/**
+ * @brief
+ *
+ */
+void GPGFRONTEND_CORE_EXPORT ShutdownCoreLoggingSystem();
/**
* @brief
diff --git a/src/core/GpgFunctionObject.cpp b/src/core/GpgFunctionObject.cpp
index 6ff83d72..0ddc290c 100644
--- a/src/core/GpgFunctionObject.cpp
+++ b/src/core/GpgFunctionObject.cpp
@@ -34,8 +34,6 @@
#include <mutex>
#include <shared_mutex>
-#include "easylogging++.h"
-
void GpgFrontend::ChannelObject::SetChannel(int channel) {
this->channel_ = channel;
}
@@ -79,8 +77,8 @@ std::vector<int> GpgFrontend::SingletonStorage::GetAllChannelId() {
GpgFrontend::ChannelObject* GpgFrontend::SingletonStorage::SetObjectInChannel(
int channel, std::unique_ptr<ChannelObject> p_obj) {
{
- LOG(TRACE) << "set channel:" << channel
- << "instance address:" << &instances_map_;
+ SPDLOG_TRACE("set channel: {} instance address: {}", channel,
+ static_cast<void*>(&instances_map_));
assert(p_obj != nullptr);
if (p_obj == nullptr) return nullptr;
@@ -111,9 +109,8 @@ GpgFrontend::SingletonStorageCollection::GetSingletonStorage(
std::unique_lock<std::shared_mutex> lock(storages_mutex_);
storages_map_.insert({hash, std::make_unique<SingletonStorage>()});
}
- LOG(TRACE) << "hash:" << hash << "created"
- << "storage address:" << &storages_map_
- << "type_name : " << type_id.name();
+ SPDLOG_TRACE("hash: {} created, storage address: {} type_name: {}", hash,
+ static_cast<void*>(&storages_map_), type_id.name());
continue;
} else {
return _it->second.get();
@@ -128,7 +125,8 @@ GpgFrontend::SingletonStorageCollection::GetInstance(
if (force_refresh || instance == nullptr) {
instance = new SingletonStorageCollection();
- LOG(INFO) << "new single storage collection created: " << instance;
+ SPDLOG_DEBUG("new single storage collection created: {}",
+ static_cast<void*>(instance));
}
return instance;
diff --git a/src/core/GpgFunctionObject.h b/src/core/GpgFunctionObject.h
index 56d0ab22..9b8c2aa3 100644
--- a/src/core/GpgFunctionObject.h
+++ b/src/core/GpgFunctionObject.h
@@ -29,6 +29,8 @@
#ifndef GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H
#define GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H
+#include <mutex>
+
#include "GpgConstants.h"
namespace GpgFrontend {
@@ -169,16 +171,33 @@ class SingletonFunctionObject : public ChannelObject {
*/
static T& GetInstance(
int channel = GpgFrontend::GPGFRONTEND_DEFAULT_CHANNEL) {
+ static std::mutex g_channel_mutex_map_lock;
+ static std::map<int, std::mutex> g_channel_mutex_map;
+
+ {
+ std::lock_guard<std::mutex> guard(g_channel_mutex_map_lock);
+ if (g_channel_mutex_map.find(channel) == g_channel_mutex_map.end()) {
+ g_channel_mutex_map[channel];
+ }
+ }
+
static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value,
"T not derived from SingletonFunctionObject<T>");
- auto p_storage =
+ auto* p_storage =
SingletonStorageCollection::GetInstance(false)->GetSingletonStorage(
typeid(T));
-
auto* _p_pbj = (T*)(p_storage->FindObjectInChannel(channel));
if (_p_pbj == nullptr) {
+ // lock this channel
+ std::lock_guard<std::mutex> guard(g_channel_mutex_map[channel]);
+
+ // double check
+ if ((_p_pbj = (T*)(p_storage->FindObjectInChannel(channel))) != nullptr)
+ return *_p_pbj;
+
+ // do create object of this channel
auto new_obj = std::unique_ptr<ChannelObject>(new T(channel));
return *(T*)(p_storage->SetObjectInChannel(channel, std::move(new_obj)));
} else {
diff --git a/src/core/GpgGenKeyInfo.cpp b/src/core/GpgGenKeyInfo.cpp
index f9065529..290c93c2 100644
--- a/src/core/GpgGenKeyInfo.cpp
+++ b/src/core/GpgGenKeyInfo.cpp
@@ -38,7 +38,7 @@
void GpgFrontend::GenKeyInfo::SetAlgo(
const GpgFrontend::GenKeyInfo::KeyGenAlgo &m_algo) {
- LOG(INFO) << "set algo name" << m_algo.first;
+ SPDLOG_DEBUG("set algo name: {}", m_algo.first);
// Check algo if supported
std::string algo_args = m_algo.second;
if (standalone_) {
diff --git a/src/core/GpgInfo.h b/src/core/GpgInfo.h
index d0453b9f..f4415af1 100644
--- a/src/core/GpgInfo.h
+++ b/src/core/GpgInfo.h
@@ -29,6 +29,7 @@
#ifndef GPGFRONTEND_ZH_CN_TS_GPGINFO_H
#define GPGFRONTEND_ZH_CN_TS_GPGINFO_H
+#include <mutex>
#include <string>
namespace GpgFrontend {
@@ -38,13 +39,26 @@ namespace GpgFrontend {
*/
class GpgInfo {
public:
- std::string AppPath; ///< executable binary path of gnupg
- std::string DatabasePath; ///<
- std::string GnupgVersion; ///<
- std::string GpgConfPath; ///<
- std::string AssuanPath; ///<
- std::string CMSPath; ///<
+ std::string GnupgVersion; ///< version of gnupg
std::string GpgMEVersion; ///<
+
+ std::string AppPath; ///< executable binary path of gnupg
+ std::string DatabasePath; ///< key database path
+ std::string GpgConfPath; ///< executable binary path of gpgconf
+ std::string AssuanPath; ///< executable binary path of assuan
+ std::string CMSPath; ///< executable binary path of cms
+ std::string GpgAgentPath; ///< executable binary path of gpg-agent
+ std::string DirmngrPath; ///< executable binary path of dirmgr
+ std::string KeyboxdPath; ///< executable binary path of keyboxd
+
+ std::string GnuPGHomePath; ///< value of ---homedir
+
+ std::map<std::string, std::vector<std::string>> ComponentsInfo; ///<
+ std::map<std::string, std::vector<std::string>> ConfigurationsInfo; ///<
+ std::map<std::string, std::vector<std::string>> OptionsInfo; ///<
+ std::map<std::string, std::vector<std::string>> AvailableOptionsInfo; ///<
+
+ std::shared_mutex Lock;
};
} // namespace GpgFrontend
diff --git a/src/core/common/CoreCommonUtil.cpp b/src/core/common/CoreCommonUtil.cpp
index 3b2b4007..93cad60a 100644
--- a/src/core/common/CoreCommonUtil.cpp
+++ b/src/core/common/CoreCommonUtil.cpp
@@ -26,15 +26,33 @@
#include "CoreCommonUtil.h"
+#include <string>
+
namespace GpgFrontend {
std::unique_ptr<CoreCommonUtil> CoreCommonUtil::instance_ = nullptr; ///<
-CoreCommonUtil *CoreCommonUtil::GetInstance() {
- LOG(INFO) << "called";
+CoreCommonUtil* CoreCommonUtil::GetInstance() {
if (instance_ == nullptr) {
instance_ = std::make_unique<CoreCommonUtil>();
}
return instance_.get();
}
+
+void CoreCommonUtil::SetTempCacheValue(const std::string& key,
+ const std::string& value) {
+ temp_cache_[key] = value;
+}
+
+std::string CoreCommonUtil::GetTempCacheValue(const std::string& key) {
+ std::string temp_cache_value;
+ std::swap(temp_cache_value, temp_cache_[key]);
+ return temp_cache_value;
+}
+
+void CoreCommonUtil::ResetTempCacheValue(const std::string& key) {
+ std::string temp_cache_value;
+ std::swap(temp_cache_value, temp_cache_[key]);
+}
+
} // namespace GpgFrontend
diff --git a/src/core/common/CoreCommonUtil.h b/src/core/common/CoreCommonUtil.h
index 3762c4f0..58bb4d40 100644
--- a/src/core/common/CoreCommonUtil.h
+++ b/src/core/common/CoreCommonUtil.h
@@ -27,6 +27,8 @@
#ifndef GPGFRONTEND_CORECOMMONUTIL_H
#define GPGFRONTEND_CORECOMMONUTIL_H
+#include <string>
+
#include "core/GpgFrontendCore.h"
namespace GpgFrontend {
@@ -46,6 +48,27 @@ class GPGFRONTEND_CORE_EXPORT CoreCommonUtil : public QObject {
*/
CoreCommonUtil() = default;
+ /**
+ * @brief set a temp cache under a certain key
+ *
+ */
+ void SetTempCacheValue(const std::string &, const std::string &);
+
+ /**
+ * @brief after get the temp cache, its value will be imediately ease in
+ * storage
+ *
+ * @return std::string
+ */
+ std::string GetTempCacheValue(const std::string &);
+
+ /**
+ * @brief imediately ease temp cache in storage
+ *
+ * @return std::string
+ */
+ void ResetTempCacheValue(const std::string &);
+
signals:
/**
@@ -56,6 +79,7 @@ class GPGFRONTEND_CORE_EXPORT CoreCommonUtil : public QObject {
private:
static std::unique_ptr<CoreCommonUtil> instance_; ///<
+ std::map<std::string, std::string> temp_cache_; //<
};
} // namespace GpgFrontend
diff --git a/src/core/function/ArchiveFileOperator.cpp b/src/core/function/ArchiveFileOperator.cpp
index 64c7389e..04c9326f 100644
--- a/src/core/function/ArchiveFileOperator.cpp
+++ b/src/core/function/ArchiveFileOperator.cpp
@@ -38,14 +38,14 @@ int copy_data(struct archive *ar, struct archive *aw) {
r = archive_read_data_block(ar, &buff, &size, &offset);
if (r == ARCHIVE_EOF) return (ARCHIVE_OK);
if (r != ARCHIVE_OK) {
- LOG(ERROR) << "archive_read_data_block() failed: "
- << archive_error_string(ar);
+ SPDLOG_ERROR("archive_read_data_block() failed: {}",
+ archive_error_string(ar));
return (r);
}
r = archive_write_data_block(aw, buff, size, offset);
if (r != ARCHIVE_OK) {
- LOG(ERROR) << "archive_write_data_block() failed: "
- << archive_error_string(aw);
+ SPDLOG_ERROR("archive_write_data_block() failed: {}",
+ archive_error_string(aw));
return (r);
}
}
@@ -55,7 +55,7 @@ void GpgFrontend::ArchiveFileOperator::CreateArchive(
const std::filesystem::path &base_path,
const std::filesystem::path &archive_path, int compress,
const std::vector<std::filesystem::path> &files) {
- LOG(INFO) << "CreateArchive: " << archive_path.u8string();
+ SPDLOG_DEBUG("CreateArchive: {}", archive_path.u8string());
auto current_base_path_backup = QDir::currentPath();
QDir::setCurrent(base_path.u8string().c_str());
@@ -74,7 +74,7 @@ void GpgFrontend::ArchiveFileOperator::CreateArchive(
ssize_t len;
int fd;
- LOG(INFO) << "compress: " << compress;
+ SPDLOG_DEBUG("compress: {}", compress);
a = archive_write_new();
switch (compress) {
@@ -119,7 +119,7 @@ void GpgFrontend::ArchiveFileOperator::CreateArchive(
#endif
int r;
- LOG(INFO) << "reading file: " << file.u8string();
+ SPDLOG_DEBUG("reading file: {}", file.u8string());
#ifdef WINDOWS
r = archive_read_disk_open_w(disk, file.wstring().c_str());
@@ -127,11 +127,11 @@ void GpgFrontend::ArchiveFileOperator::CreateArchive(
r = archive_read_disk_open(disk, file.u8string().c_str());
#endif
- LOG(INFO) << "read file done: " << file.u8string();
+ SPDLOG_DEBUG("read file done: {}", file.u8string());
if (r != ARCHIVE_OK) {
- LOG(ERROR) << "archive_read_disk_open() failed: "
- << archive_error_string(disk);
+ SPDLOG_ERROR("{archive_read_disk_open() failed: {}",
+ archive_error_string(disk));
throw std::runtime_error("archive_read_disk_open() failed");
}
@@ -143,8 +143,8 @@ void GpgFrontend::ArchiveFileOperator::CreateArchive(
if (r == ARCHIVE_EOF) break;
if (r != ARCHIVE_OK) {
- LOG(ERROR) << "archive_read_next_header2() failed: "
- << archive_error_string(disk);
+ SPDLOG_ERROR("archive_read_next_header2() failed: {}",
+ archive_error_string(disk));
throw std::runtime_error("archive_read_next_header2() failed");
}
archive_read_disk_descend(disk);
@@ -158,14 +158,14 @@ void GpgFrontend::ArchiveFileOperator::CreateArchive(
auto entry_path = std::string(archive_entry_pathname_utf8(entry));
#endif
- LOG(INFO) << "Adding: " << archive_entry_pathname_utf8(entry) << "size"
- << archive_entry_size(entry) << " bytes"
- << "file type" << archive_entry_filetype(entry);
+ SPDLOG_DEBUG("Adding: {} size: {} bytes: {} file type: {}",
+ archive_entry_pathname_utf8(entry),
+ archive_entry_size(entry), archive_entry_filetype(entry));
r = archive_write_header(a, entry);
if (r < ARCHIVE_OK) {
- LOG(ERROR) << "archive_write_header() failed: "
- << archive_error_string(a);
+ SPDLOG_ERROR("archive_write_header() failed: {}",
+ archive_error_string(a));
throw std::runtime_error("archive_write_header() failed");
}
if (r == ARCHIVE_FATAL) throw std::runtime_error("archive fatal");
@@ -193,7 +193,7 @@ void GpgFrontend::ArchiveFileOperator::CreateArchive(
void GpgFrontend::ArchiveFileOperator::ExtractArchive(
const std::filesystem::path &archive_path,
const std::filesystem::path &base_path) {
- LOG(INFO) << "ExtractArchive: " << archive_path.u8string();
+ SPDLOG_DEBUG("ExtractArchive: {}", archive_path.u8string());
auto current_base_path_backup = QDir::currentPath();
QDir::setCurrent(base_path.u8string().c_str());
@@ -228,7 +228,7 @@ void GpgFrontend::ArchiveFileOperator::ExtractArchive(
auto filename = archive_path.u8string();
if (!filename.empty() && filename == u8"-") {
- LOG(ERROR) << "cannot read from stdin";
+ SPDLOG_ERROR("cannot read from stdin");
}
#ifdef WINDOWS
if (archive_read_open_filename_w(a, archive_path.wstring().c_str(), 10240) !=
@@ -237,29 +237,29 @@ void GpgFrontend::ArchiveFileOperator::ExtractArchive(
if (archive_read_open_filename(a, archive_path.u8string().c_str(), 10240) !=
ARCHIVE_OK) {
#endif
- LOG(ERROR) << "archive_read_open_filename() failed: "
- << archive_error_string(a);
+ SPDLOG_ERROR("archive_read_open_filename() failed: {}",
+ archive_error_string(a));
throw std::runtime_error("archive_read_open_filename() failed");
}
for (;;) {
r = archive_read_next_header(a, &entry);
if (r == ARCHIVE_EOF) break;
if (r != ARCHIVE_OK) {
- LOG(ERROR) << "archive_read_next_header() failed: "
- << archive_error_string(a);
+ SPDLOG_ERROR("archive_read_next_header() failed: {}",
+ archive_error_string(a));
throw std::runtime_error("archive_read_next_header() failed");
}
- LOG(INFO) << "Extracting: " << archive_entry_pathname(entry) << "size"
- << archive_entry_size(entry) << " bytes"
- << "file type" << archive_entry_filetype(entry);
+ SPDLOG_DEBUG("Adding: {} size: {} bytes: {} file type: {}",
+ archive_entry_pathname_utf8(entry), archive_entry_size(entry),
+ archive_entry_filetype(entry));
r = archive_write_header(ext, entry);
if (r != ARCHIVE_OK) {
- LOG(ERROR) << "archive_write_header() failed: "
- << archive_error_string(ext);
+ SPDLOG_ERROR("archive_write_header() failed: {}",
+ archive_error_string(ext));
} else {
r = copy_data(a, ext);
if (r != ARCHIVE_OK) {
- LOG(ERROR) << "copy_data() failed: " << archive_error_string(ext);
+ SPDLOG_ERROR("copy_data() failed: {}", archive_error_string(ext));
}
}
}
@@ -285,8 +285,8 @@ void GpgFrontend::ArchiveFileOperator::ListArchive(
10240); // Note 1
if (r != ARCHIVE_OK) return;
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
- LOG(INFO) << "File: " << archive_entry_pathname(entry);
- LOG(INFO) << "File Path: " << archive_entry_pathname(entry);
+ SPDLOG_DEBUG("File: {}", archive_entry_pathname(entry));
+ SPDLOG_DEBUG("File Path: {}", 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
new file mode 100644
index 00000000..a20b8003
--- /dev/null
+++ b/src/core/function/CacheManager.cpp
@@ -0,0 +1,66 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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 "CacheManager.h"
+
+#include <algorithm>
+
+#include "function/DataObjectOperator.h"
+#include "nlohmann/json_fwd.hpp"
+#include "spdlog/spdlog.h"
+
+void GpgFrontend::CacheManager::SaveCache(std::string key,
+ const nlohmann::json &value) {
+ auto stored_data =
+ GpgFrontend::DataObjectOperator::GetInstance().GetDataObject(
+ "__cache_data_list");
+
+ // get cache data list from file system
+ nlohmann::json cache_data_list;
+ if (stored_data.has_value()) {
+ cache_data_list = std::move(stored_data.value());
+ }
+
+ if (!cache_data_list.is_array()) {
+ cache_data_list.clear();
+ }
+
+ if (GpgFrontend::DataObjectOperator::GetInstance()
+ .SaveDataObj(key, value)
+ .empty()) {
+ return;
+ }
+
+ if (std::find(cache_data_list.begin(), cache_data_list.end(), key) ==
+ cache_data_list.end()) {
+ cache_data_list.push_back(key);
+ }
+
+ GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(
+ "__cache_data_list", cache_data_list);
+}
diff --git a/src/core/function/CacheManager.h b/src/core/function/CacheManager.h
new file mode 100644
index 00000000..e489182f
--- /dev/null
+++ b/src/core/function/CacheManager.h
@@ -0,0 +1,45 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef GPGFRONTEND_CACHEMANAGER_H
+#define GPGFRONTEND_CACHEMANAGER_H
+
+namespace GpgFrontend {
+
+class CacheManager {
+ public:
+ static void SaveCache(std::string key, const nlohmann::json &value);
+
+ static nlohmann::json LoadCache(std::string name);
+
+ static void ClearAllCache();
+};
+
+} // namespace GpgFrontend
+
+#endif
diff --git a/src/core/function/CharsetOperator.cpp b/src/core/function/CharsetOperator.cpp
index 81c23388..0e40e317 100644
--- a/src/core/function/CharsetOperator.cpp
+++ b/src/core/function/CharsetOperator.cpp
@@ -28,6 +28,7 @@
#include "core/function/CharsetOperator.h"
+#include <spdlog/spdlog.h>
#include <unicode/ucnv.h>
#include <unicode/ucsdet.h>
#include <unicode/ustring.h>
@@ -37,8 +38,6 @@
#include <memory>
#include <string>
-#include "easylogging++.h"
-
GpgFrontend::CharsetOperator::CharsetInfo GpgFrontend::CharsetOperator::Detect(
const std::string &buffer) {
const UCharsetMatch *ucm;
@@ -47,17 +46,17 @@ GpgFrontend::CharsetOperator::CharsetInfo GpgFrontend::CharsetOperator::Detect(
status = U_ZERO_ERROR;
if (U_FAILURE(status)) {
- LOG(ERROR) << "Failed to open charset detector: " << u_errorName(status);
+ SPDLOG_ERROR("failed to open charset detector: {}", u_errorName(status));
return {"unknown", "unknown", 0};
}
- LOG(INFO) << "Detecting charset buffer:" << buffer.size() << "bytes";
+ SPDLOG_DEBUG("detecting charset buffer: {} bytes", buffer.size());
status = U_ZERO_ERROR;
ucsdet_setText(csd, buffer.data(), buffer.size(), &status);
if (U_FAILURE(status)) {
- LOG(ERROR) << "Failed to set text to charset detector: "
- << u_errorName(status);
+ SPDLOG_ERROR("failed to set text to charset detector: {}",
+ u_errorName(status));
return {"unknown", "unknown", 0};
}
@@ -78,7 +77,7 @@ GpgFrontend::CharsetOperator::CharsetInfo GpgFrontend::CharsetOperator::Detect(
const char *language = ucsdet_getLanguage(ucm, &status);
if (U_FAILURE(status)) return {name, "unknown", confidence};
- LOG(INFO) << "Detected charset: " << name << language << confidence;
+ SPDLOG_DEBUG("Detected charset: {} {} {}", name, language, confidence);
return {name, language, confidence};
}
@@ -89,14 +88,14 @@ bool GpgFrontend::CharsetOperator::Convert2Utf8(const std::string &buffer,
const auto from_encode = std::string("utf-8");
const auto to_encode = from_charset_name;
- LOG(INFO) << "Converting buffer:" << buffer.size();
+ SPDLOG_DEBUG("Converting buffer: {}", buffer.size());
// test if the charset is supported
UConverter *conv = ucnv_open(from_encode.c_str(), &status);
ucnv_close(conv);
if (U_FAILURE(status)) {
- LOG(ERROR) << "Failed to open converter: " << u_errorName(status) << ":"
- << from_encode;
+ SPDLOG_ERROR("failed to open converter: {}, from encode: {}",
+ u_errorName(status), from_encode);
return false;
}
@@ -104,8 +103,8 @@ bool GpgFrontend::CharsetOperator::Convert2Utf8(const std::string &buffer,
conv = ucnv_open(to_encode.c_str(), &status);
ucnv_close(conv);
if (U_FAILURE(status)) {
- LOG(ERROR) << "Failed to open converter: " << u_errorName(status) << ":"
- << to_encode;
+ SPDLOG_ERROR("failed to open converter: {}, to encode: {}",
+ u_errorName(status), to_encode);
return false;
}
@@ -127,10 +126,10 @@ bool GpgFrontend::CharsetOperator::Convert2Utf8(const std::string &buffer,
}
if (U_FAILURE(status)) {
- LOG(ERROR) << "Failed to convert to utf-8: " << u_errorName(status);
+ SPDLOG_ERROR("failed to convert to utf-8: {}", u_errorName(status));
return false;
}
- LOG(INFO) << "Converted buffer:" << out_buffer.size() << "bytes";
+ SPDLOG_DEBUG("converted buffer: {} bytes", out_buffer.size());
return true;
} \ No newline at end of file
diff --git a/src/core/function/CoreSignalStation.cpp b/src/core/function/CoreSignalStation.cpp
new file mode 100644
index 00000000..f78d417b
--- /dev/null
+++ b/src/core/function/CoreSignalStation.cpp
@@ -0,0 +1,39 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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 "core/function/CoreSignalStation.h"
+
+std::unique_ptr<GpgFrontend::CoreSignalStation>
+ GpgFrontend::CoreSignalStation::_instance = nullptr;
+
+GpgFrontend::CoreSignalStation* GpgFrontend::CoreSignalStation::GetInstance() {
+ if (_instance == nullptr) {
+ _instance = std::make_unique<CoreSignalStation>();
+ }
+ return _instance.get();
+}
diff --git a/src/core/function/CoreSignalStation.h b/src/core/function/CoreSignalStation.h
new file mode 100644
index 00000000..7497cab7
--- /dev/null
+++ b/src/core/function/CoreSignalStation.h
@@ -0,0 +1,69 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef GPGFRONTEND_CORESIGNALSTATION_H
+#define GPGFRONTEND_CORESIGNALSTATION_H
+
+#include "core/GpgFrontendCore.h"
+
+namespace GpgFrontend {
+
+/**
+ * @brief
+ *
+ */
+class GPGFRONTEND_CORE_EXPORT CoreSignalStation : public QObject {
+ Q_OBJECT
+ static std::unique_ptr<CoreSignalStation> _instance;
+
+ public:
+ /**
+ * @brief Get the Instance object
+ *
+ * @return SignalStation*
+ */
+ static CoreSignalStation* GetInstance();
+
+ signals:
+
+ /**
+ * @brief
+ *
+ */
+ void SignalUserInputPassphraseDone(QString passparase);
+
+ /**
+ * @brief
+ *
+ */
+ void SignalNeedUserInputPassphrase();
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_CORESIGNALSTATION_H
diff --git a/src/core/function/DataObjectOperator.cpp b/src/core/function/DataObjectOperator.cpp
index 2744c448..180cef30 100644
--- a/src/core/function/DataObjectOperator.cpp
+++ b/src/core/function/DataObjectOperator.cpp
@@ -36,7 +36,7 @@
#include "core/function/PassphraseGenerator.h"
void GpgFrontend::DataObjectOperator::init_app_secure_key() {
- LOG(INFO) << "Initializing application secure key";
+ SPDLOG_DEBUG("initializing application secure key");
FileOperator::WriteFileStd(app_secure_key_path_,
PassphraseGenerator::GetInstance().Generate(256));
std::filesystem::permissions(
@@ -54,13 +54,13 @@ GpgFrontend::DataObjectOperator::DataObjectOperator(int channel)
std::string key;
if (!FileOperator::ReadFileStd(app_secure_key_path_.u8string(), key)) {
- LOG(FATAL) << _("Failed to read app secure key file")
- << app_secure_key_path_;
- throw std::runtime_error(_("Failed to read app secure key file"));
+ SPDLOG_ERROR("failed to read app secure key file: {}",
+ app_secure_key_path_.u8string());
+ throw std::runtime_error("failed to read app secure key file");
}
hash_key_ = QCryptographicHash::hash(QByteArray::fromStdString(key),
QCryptographicHash::Sha256);
- LOG(INFO) << "App secure key loaded" << hash_key_.size() << "bytes";
+ SPDLOG_DEBUG("app secure key loaded {} bytes", hash_key_.size());
if (!exists(app_data_objs_path_)) create_directory(app_data_objs_path_);
}
@@ -93,8 +93,8 @@ std::string GpgFrontend::DataObjectOperator::SaveDataObj(
auto encoded =
encryption.encode(QByteArray::fromStdString(to_string(value)), hash_key_);
- LOG(INFO) << _("Saving data object") << _hash_obj_key << "to" << obj_path
- << encoded.size() << "bytes";
+ SPDLOG_DEBUG("saving data object {} to {} , size: {} bytes", _hash_obj_key,
+ obj_path.u8string(), encoded.size());
FileOperator::WriteFileStd(obj_path.u8string(), encoded.toStdString());
@@ -104,7 +104,7 @@ std::string GpgFrontend::DataObjectOperator::SaveDataObj(
std::optional<nlohmann::json> GpgFrontend::DataObjectOperator::GetDataObject(
const std::string& _key) {
try {
- LOG(INFO) << _("Get data object") << _key;
+ SPDLOG_DEBUG("get data object {}", _key);
auto _hash_obj_key =
QCryptographicHash::hash(hash_key_ + QByteArray::fromStdString(_key),
QCryptographicHash::Sha256)
@@ -114,33 +114,33 @@ std::optional<nlohmann::json> GpgFrontend::DataObjectOperator::GetDataObject(
const auto obj_path = app_data_objs_path_ / _hash_obj_key;
if (!std::filesystem::exists(obj_path)) {
- LOG(ERROR) << _("Data object not found") << _key;
+ SPDLOG_ERROR("data object not found :{}", _key);
return {};
}
std::string buffer;
if (!FileOperator::ReadFileStd(obj_path.u8string(), buffer)) {
- LOG(ERROR) << _("Failed to read data object") << _key;
+ SPDLOG_ERROR("failed to read data object: {}", _key);
return {};
}
- LOG(INFO) << _("Data object found") << _key;
+ SPDLOG_DEBUG("data object found {}", _key);
auto encoded = QByteArray::fromStdString(buffer);
QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
QAESEncryption::Padding::ISO);
- LOG(INFO) << _("Decrypting data object") << encoded.size()
- << hash_key_.size();
+ SPDLOG_DEBUG("decrypting data object {} , hash key size: {}",
+ encoded.size(), hash_key_.size());
auto decoded =
encryption.removePadding(encryption.decode(encoded, hash_key_));
- LOG(INFO) << _("Data object decoded") << _key;
+ SPDLOG_DEBUG("data object decoded: {}", _key);
return nlohmann::json::parse(decoded.toStdString());
} catch (...) {
- LOG(ERROR) << _("Failed to get data object") << _key;
+ SPDLOG_ERROR("failed to get data object: {}", _key);
return {};
}
}
diff --git a/src/core/function/FileOperator.cpp b/src/core/function/FileOperator.cpp
index fcbdb91c..41552246 100644
--- a/src/core/function/FileOperator.cpp
+++ b/src/core/function/FileOperator.cpp
@@ -32,7 +32,7 @@ bool GpgFrontend::FileOperator::ReadFile(const QString& file_name,
QByteArray& data) {
QFile file(file_name);
if (!file.open(QIODevice::ReadOnly)) {
- LOG(ERROR) << "failed to open file" << file_name.toStdString();
+ SPDLOG_ERROR("failed to open file: {}", file_name.toStdString());
return false;
}
data = file.readAll();
@@ -44,7 +44,7 @@ bool GpgFrontend::FileOperator::WriteFile(const QString& file_name,
const QByteArray& data) {
QFile file(file_name);
if (!file.open(QIODevice::WriteOnly)) {
- LOG(ERROR) << "failed to open file" << file_name.toStdString();
+ SPDLOG_ERROR("failed to open file: {}", file_name.toStdString());
return false;
}
file.write(data);
@@ -84,33 +84,33 @@ std::string GpgFrontend::FileOperator::CalculateHash(
<< file_path.filename().u8string().c_str() << std::endl;
QFile f(info.filePath());
- f.open(QFile::ReadOnly);
- auto buffer = f.readAll();
- ss << " " << _("file size(bytes)") << _(": ") << buffer.size()
- << std::endl;
- f.close();
if (f.open(QFile::ReadOnly)) {
- auto hash_md5 = QCryptographicHash(QCryptographicHash::Md5);
+ // read all data
+ auto buffer = f.readAll();
+ ss << " " << _("file size(bytes)") << _(": ") << buffer.size()
+ << std::endl;
+
// md5
+ auto hash_md5 = QCryptographicHash(QCryptographicHash::Md5);
hash_md5.addData(buffer);
auto md5 = hash_md5.result().toHex().toStdString();
- LOG(INFO) << "md5" << md5;
+ SPDLOG_DEBUG("md5 {}", md5);
ss << " "
<< "md5" << _(": ") << md5 << std::endl;
- auto hash_sha1 = QCryptographicHash(QCryptographicHash::Sha1);
// sha1
+ auto hash_sha1 = QCryptographicHash(QCryptographicHash::Sha1);
hash_sha1.addData(buffer);
auto sha1 = hash_sha1.result().toHex().toStdString();
- LOG(INFO) << "sha1" << sha1;
+ SPDLOG_DEBUG("sha1 {}", sha1);
ss << " "
<< "sha1" << _(": ") << sha1 << std::endl;
- auto hash_sha256 = QCryptographicHash(QCryptographicHash::Sha256);
// sha1
+ auto hash_sha256 = QCryptographicHash(QCryptographicHash::Sha256);
hash_sha256.addData(buffer);
auto sha256 = hash_sha256.result().toHex().toStdString();
- LOG(INFO) << "sha256" << sha256;
+ SPDLOG_DEBUG("sha256 {}", sha256);
ss << " "
<< "sha256" << _(": ") << sha256 << std::endl;
diff --git a/src/core/function/GlobalSettingStation.cpp b/src/core/function/GlobalSettingStation.cpp
index 7231ac9e..79c47408 100644
--- a/src/core/function/GlobalSettingStation.cpp
+++ b/src/core/function/GlobalSettingStation.cpp
@@ -34,12 +34,12 @@ void GpgFrontend::GlobalSettingStation::SyncSettings() noexcept {
using namespace libconfig;
try {
ui_cfg_.writeFile(ui_config_path_.u8string().c_str());
- LOG(INFO) << _("Updated ui configuration successfully written to")
- << ui_config_path_;
+ SPDLOG_DEBUG("updated ui configuration successfully written to {}",
+ ui_config_path_.u8string());
} catch (const FileIOException &fioex) {
- LOG(ERROR) << _("I/O error while writing ui configuration file")
- << ui_config_path_;
+ SPDLOG_ERROR("i/o error while writing ui configuration file: {}",
+ ui_config_path_.u8string());
}
}
@@ -48,14 +48,12 @@ GpgFrontend::GlobalSettingStation::GlobalSettingStation(int channel) noexcept
using namespace std::filesystem;
using namespace libconfig;
- el::Loggers::addFlag(el::LoggingFlag::AutoSpacing);
-
- LOG(INFO) << _("App Path") << app_path_;
- LOG(INFO) << _("App Configure Path") << app_configure_path_;
- LOG(INFO) << _("App Data Path") << app_data_path_;
- LOG(INFO) << _("App Log Path") << app_log_path_;
- LOG(INFO) << _("App Locale Path") << app_locale_path_;
- LOG(INFO) << _("App Conf Path") << ui_config_path_;
+ SPDLOG_INFO("app path: {}", app_path_.u8string());
+ SPDLOG_INFO("app configure path: {}", app_configure_path_.u8string());
+ SPDLOG_INFO("app data path: {}", app_data_path_.u8string());
+ SPDLOG_INFO("app log path: {}", app_log_path_.u8string());
+ SPDLOG_INFO("app locale path: {}", app_locale_path_.u8string());
+ SPDLOG_INFO("app conf path: {}", ui_config_path_.u8string());
if (!is_directory(app_configure_path_)) create_directory(app_configure_path_);
@@ -68,24 +66,24 @@ GpgFrontend::GlobalSettingStation::GlobalSettingStation(int channel) noexcept
if (!exists(ui_config_path_)) {
try {
this->ui_cfg_.writeFile(ui_config_path_.u8string().c_str());
- LOG(INFO) << _("UserInterface configuration successfully written to")
- << ui_config_path_;
+ SPDLOG_DEBUG("user interface configuration successfully written to {}",
+ ui_config_path_.u8string());
} catch (const FileIOException &fioex) {
- LOG(ERROR)
- << _("I/O error while writing UserInterface configuration file")
- << ui_config_path_;
+ SPDLOG_DEBUG(
+ "i/o error while writing UserInterface configuration file {}",
+ ui_config_path_.u8string());
}
} else {
try {
this->ui_cfg_.readFile(ui_config_path_.u8string().c_str());
- LOG(INFO) << _("UserInterface configuration successfully read from")
- << ui_config_path_;
+ SPDLOG_DEBUG("user interface configuration successfully read from {}",
+ ui_config_path_.u8string());
} catch (const FileIOException &fioex) {
- LOG(ERROR) << _("I/O error while reading UserInterface configure file");
+ SPDLOG_ERROR("i/o error while reading UserInterface configure file");
} catch (const ParseException &pex) {
- LOG(ERROR) << _("Parse error at ") << pex.getFile() << ":"
- << pex.getLine() << " - " << pex.getError();
+ SPDLOG_ERROR("parse error at {} : {} - {}", pex.getFile(), pex.getLine(),
+ pex.getError());
}
}
}
diff --git a/src/core/function/KeyPackageOperator.cpp b/src/core/function/KeyPackageOperator.cpp
index 3779c64b..5c917ab8 100644
--- a/src/core/function/KeyPackageOperator.cpp
+++ b/src/core/function/KeyPackageOperator.cpp
@@ -39,7 +39,7 @@ namespace GpgFrontend {
bool KeyPackageOperator::GeneratePassphrase(
const std::filesystem::path& phrase_path, std::string& phrase) {
phrase = PassphraseGenerator::GetInstance().Generate(256);
- LOG(INFO) << "Generated passphrase: " << phrase.size() << " bytes";
+ SPDLOG_DEBUG("generated passphrase: {} bytes", phrase.size());
return FileOperator::WriteFileStd(phrase_path, phrase);
}
@@ -47,12 +47,12 @@ bool KeyPackageOperator::GenerateKeyPackage(
const std::filesystem::path& key_package_path,
const std::string& key_package_name, KeyIdArgsListPtr& key_ids,
std::string& phrase, bool secret) {
- LOG(INFO) << "Generating key package: " << key_package_name;
+ SPDLOG_DEBUG("generating key package: {}", key_package_name);
ByteArrayPtr key_export_data = nullptr;
- if (!GpgKeyImportExporter::GetInstance().ExportKeys(key_ids, key_export_data,
- secret)) {
- LOG(ERROR) << "Failed to export keys";
+ if (!GpgKeyImportExporter::GetInstance().ExportAllKeys(
+ key_ids, key_export_data, secret)) {
+ SPDLOG_ERROR("failed to export keys");
return false;
}
@@ -64,7 +64,7 @@ bool KeyPackageOperator::GenerateKeyPackage(
QAESEncryption::Padding::ISO);
auto encoded = encryption.encode(data, hash_key);
- LOG(INFO) << "Writing key package: " << key_package_name;
+ SPDLOG_DEBUG("writing key package: {}", key_package_name);
return FileOperator::WriteFileStd(key_package_path, encoded.toStdString());
}
@@ -72,21 +72,21 @@ bool KeyPackageOperator::ImportKeyPackage(
const std::filesystem::path& key_package_path,
const std::filesystem::path& phrase_path,
GpgFrontend::GpgImportInformation& import_info) {
- LOG(INFO) << "Importing key package: " << key_package_path.u8string();
+ SPDLOG_DEBUG("importing key package: {]", key_package_path.u8string());
std::string encrypted_data;
FileOperator::ReadFileStd(key_package_path, encrypted_data);
if (encrypted_data.empty()) {
- LOG(ERROR) << "Failed to read key package: " << key_package_path.u8string();
+ SPDLOG_ERROR("failed to read key package: {}", key_package_path.u8string());
return false;
};
std::string passphrase;
FileOperator::ReadFileStd(phrase_path, passphrase);
- LOG(INFO) << "Passphrase: " << passphrase.size() << " bytes";
+ SPDLOG_DEBUG("passphrase: {} bytes", passphrase.size());
if (passphrase.size() != 256) {
- LOG(ERROR) << "Failed to read passphrase: " << phrase_path.u8string();
+ SPDLOG_ERROR("failed to read passphrase: {}", phrase_path.u8string());
return false;
}
@@ -100,7 +100,7 @@ bool KeyPackageOperator::ImportKeyPackage(
auto decoded = encryption.removePadding(encryption.decode(encoded, hash_key));
auto key_data = QByteArray::fromBase64(decoded);
- LOG(INFO) << "key data" << key_data.size();
+ SPDLOG_DEBUG("key data size: {}", key_data.size());
if (!key_data.startsWith(GpgConstants::PGP_PUBLIC_KEY_BEGIN) &&
!key_data.startsWith(GpgConstants::PGP_PRIVATE_KEY_BEGIN)) {
return false;
diff --git a/src/core/function/gpg/GpgAdvancedOperator.cpp b/src/core/function/gpg/GpgAdvancedOperator.cpp
new file mode 100644
index 00000000..2a3bba42
--- /dev/null
+++ b/src/core/function/gpg/GpgAdvancedOperator.cpp
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2023. Saturneric
+ *
+ * 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 07.01.2023.
+//
+
+#include "GpgAdvancedOperator.h"
+
+#include "core/function/gpg/GpgCommandExecutor.h"
+#include "spdlog/spdlog.h"
+
+GpgFrontend::GpgAdvancedOperator::GpgAdvancedOperator(int channel)
+ : SingletonFunctionObject(channel) {}
+
+bool GpgFrontend::GpgAdvancedOperator::ClearGpgPasswordCache() {
+ bool success = false;
+ GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
+ ctx_.GetInfo().GpgConfPath, {"--reload", "gpg-agent"},
+ [&](int exit_code, const std::string &p_out, const std::string &p_err) {
+ if (exit_code == 0) {
+ SPDLOG_DEBUG("gpgconf reload exit code: {}", exit_code);
+ success = true;
+ }
+ });
+ return success;
+}
+
+bool GpgFrontend::GpgAdvancedOperator::ReloadGpgComponents() {
+ bool success = false;
+ GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
+ ctx_.GetInfo().GpgConfPath, {"--reload"},
+ [&](int exit_code, const std::string &p_out, const std::string &p_err) {
+ if (exit_code == 0) {
+ success = true;
+ } else {
+ SPDLOG_ERROR(
+ "gpgconf execute error, process stderr: {}, process stdout: {}",
+ p_err, p_out);
+ return;
+ }
+ });
+ return success;
+}
+
+bool GpgFrontend::GpgAdvancedOperator::RestartGpgComponents() {
+ bool success = false;
+
+ GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
+ ctx_.GetInfo().GpgConfPath, {"--verbose", "--kill", "all"},
+ [&](int exit_code, const std::string &p_out, const std::string &p_err) {
+ if (exit_code == 0) {
+ success = true;
+ return;
+ } else {
+ SPDLOG_ERROR(
+ "gpgconf execute error, process stderr: {}, process stdout: {}",
+ p_err, p_out);
+ return;
+ }
+ });
+
+ if (!success) return false;
+
+ success &= StartGpgAgent();
+
+ success &= StartDirmngr();
+
+ success &= StartKeyBoxd();
+
+ return success;
+}
+
+bool GpgFrontend::GpgAdvancedOperator::ResetConfigures() {
+ bool success = false;
+ GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
+ ctx_.GetInfo().GpgConfPath, {"--apply-defaults"},
+ [&](int exit_code, const std::string &p_out, const std::string &p_err) {
+ if (exit_code == 0) {
+ success = true;
+ } else {
+ SPDLOG_ERROR(
+ "gpgconf execute error, process stderr: {}, process stdout: {}",
+ p_err, p_out);
+ return;
+ }
+ });
+
+ return success;
+}
+
+bool GpgFrontend::GpgAdvancedOperator::StartGpgAgent() {
+ bool success = false;
+ GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
+ ctx_.GetInfo().GpgAgentPath,
+ {"--homedir", ctx_.GetInfo().GnuPGHomePath, "--daemon"},
+ [&](int exit_code, const std::string &p_out, const std::string &p_err) {
+ if (exit_code == 0) {
+ success = true;
+ SPDLOG_INFO("start gpg-agent successfully");
+ } else if (exit_code == 2) {
+ success = true;
+ SPDLOG_INFO("gpg-agent already started");
+ } else {
+ SPDLOG_ERROR(
+ "gpg-agent execute error, process stderr: {}, process stdout: {}",
+ p_err, p_out);
+ return;
+ }
+ });
+
+ return success;
+}
+
+bool GpgFrontend::GpgAdvancedOperator::StartDirmngr() {
+ bool success = false;
+ GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
+ ctx_.GetInfo().DirmngrPath,
+ {"--homedir", ctx_.GetInfo().GnuPGHomePath, "--daemon"},
+ [&](int exit_code, const std::string &p_out, const std::string &p_err) {
+ if (exit_code == 0) {
+ success = true;
+ SPDLOG_INFO("start dirmngr successfully");
+ } else if (exit_code == 2) {
+ success = true;
+ SPDLOG_INFO("dirmngr already started");
+ } else {
+ SPDLOG_ERROR(
+ "dirmngr execute error, process stderr: {}, process stdout: {}",
+ p_err, p_out);
+ return;
+ }
+ });
+
+ return success;
+}
+
+bool GpgFrontend::GpgAdvancedOperator::StartKeyBoxd() {
+ bool success = false;
+ GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
+ ctx_.GetInfo().KeyboxdPath,
+ {"--homedir", ctx_.GetInfo().GnuPGHomePath, "--daemon"},
+ [&](int exit_code, const std::string &p_out, const std::string &p_err) {
+ if (exit_code == 0) {
+ success = true;
+ SPDLOG_INFO("start keyboxd successfully");
+ } else if (exit_code == 2) {
+ success = true;
+ SPDLOG_INFO("keyboxd already started");
+ } else {
+ SPDLOG_ERROR(
+ "keyboxd execute error, process stderr: {}, process stdout: {}",
+ p_err, p_out);
+ return;
+ }
+ });
+
+ return success;
+}
diff --git a/src/core/function/gpg/GpgAdvancedOperator.h b/src/core/function/gpg/GpgAdvancedOperator.h
new file mode 100644
index 00000000..5325020a
--- /dev/null
+++ b/src/core/function/gpg/GpgAdvancedOperator.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2023. Saturneric
+ *
+ * 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 07.01.2023.
+//
+
+#ifndef GPGFRONTEND_GPGADVANCEDOPERATOR_H
+#define GPGFRONTEND_GPGADVANCEDOPERATOR_H
+
+#include "core/GpgConstants.h"
+#include "core/GpgContext.h"
+#include "core/GpgFunctionObject.h"
+
+namespace GpgFrontend {
+
+class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
+ : public SingletonFunctionObject<GpgAdvancedOperator> {
+ public:
+ /**
+ * @brief Construct a new Basic Operator object
+ *
+ * @param channel Channel corresponding to the context
+ */
+ explicit GpgAdvancedOperator(
+ int channel = SingletonFunctionObject::GetDefaultChannel());
+
+ /**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+ bool ClearGpgPasswordCache();
+
+ /**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+ bool ReloadGpgComponents();
+
+ /**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+ bool RestartGpgComponents();
+
+ /**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+ bool ResetConfigures();
+
+ /**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+ bool StartGpgAgent();
+
+ /**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+ bool StartDirmngr();
+
+ /**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+ bool StartKeyBoxd();
+
+ private:
+ GpgContext& ctx_ = GpgContext::GetInstance(
+ SingletonFunctionObject::GetChannel()); ///< Corresponding context
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_GPGADVANCEDOPERATOR_H
diff --git a/src/core/function/gpg/GpgBasicOperator.cpp b/src/core/function/gpg/GpgBasicOperator.cpp
index 93075c7c..71f84907 100644
--- a/src/core/function/gpg/GpgBasicOperator.cpp
+++ b/src/core/function/gpg/GpgBasicOperator.cpp
@@ -178,15 +178,15 @@ gpgme_error_t GpgFrontend::GpgBasicOperator::EncryptSign(
void GpgFrontend::GpgBasicOperator::SetSigners(KeyArgsList& signers) {
gpgme_signers_clear(ctx_);
for (const GpgKey& key : signers) {
- DLOG(INFO) << "key" << key.GetFingerprint();
+ SPDLOG_DEBUG("key fpr: {}", key.GetFingerprint());
if (key.IsHasActualSigningCapability()) {
- DLOG(INFO) << "signer";
+ SPDLOG_DEBUG("signer");
auto error = gpgme_signers_add(ctx_, gpgme_key_t(key));
check_gpg_error(error);
}
}
if (signers.size() != gpgme_signers_count(ctx_))
- DLOG(INFO) << "No All Signers Added";
+ SPDLOG_DEBUG("not all signers added");
}
std::unique_ptr<GpgFrontend::KeyArgsList>
diff --git a/src/core/function/gpg/GpgCommandExecutor.cpp b/src/core/function/gpg/GpgCommandExecutor.cpp
index 2292ed0e..86c47c60 100644
--- a/src/core/function/gpg/GpgCommandExecutor.cpp
+++ b/src/core/function/gpg/GpgCommandExecutor.cpp
@@ -27,41 +27,245 @@
*/
#include "GpgCommandExecutor.h"
+#include "GpgFunctionObject.h"
+#include "core/thread/TaskRunnerGetter.h"
+
GpgFrontend::GpgCommandExecutor::GpgCommandExecutor(int channel)
: SingletonFunctionObject<GpgCommandExecutor>(channel) {}
-#ifndef WINDOWS
-#include <boost/asio.hpp>
-#endif
+void GpgFrontend::GpgCommandExecutor::Execute(
+ std::string cmd, std::vector<std::string> arguments,
+ std::function<void(int, std::string, std::string)> callback,
+ std::function<void(QProcess *)> interact_func) {
+ SPDLOG_DEBUG("called cmd {} arguments size: {}", cmd, arguments.size());
-#ifndef WINDOWS
+ Thread::Task::TaskCallback result_callback =
+ [](int rtn, Thread::Task::DataObjectPtr data_object) {
+ SPDLOG_DEBUG("data object use count: {}", data_object.use_count());
+ if (data_object->GetObjectSize() != 4)
+ throw std::runtime_error("invalid data object size");
-using boost::process::async_pipe;
+ auto exit_code = data_object->PopObject<int>();
+ auto process_stdout = data_object->PopObject<std::string>();
+ auto process_stderr = data_object->PopObject<std::string>();
+ auto callback = data_object->PopObject<
+ std::function<void(int, std::string, std::string)>>();
-void GpgFrontend::GpgCommandExecutor::Execute(
- StringArgsRef arguments,
- const std::function<void(async_pipe& in, async_pipe& out)>& interact_func) {
- using namespace boost::process;
+ // call callback
+ callback(exit_code, process_stdout, process_stderr);
+ };
+
+ Thread::Task::TaskRunnable runner =
+ [](GpgFrontend::Thread::Task::DataObjectPtr data_object) -> int {
+ SPDLOG_DEBUG("process runner called, data object size: {}",
+ data_object->GetObjectSize());
+
+ if (data_object->GetObjectSize() != 4)
+ throw std::runtime_error("invalid data object size");
+
+ // get arguments
+ auto cmd = data_object->PopObject<std::string>();
+ SPDLOG_DEBUG("get cmd: {}", cmd);
+ auto arguments = data_object->PopObject<std::vector<std::string>>();
+ auto interact_func =
+ data_object->PopObject<std::function<void(QProcess *)>>();
+
+ auto *cmd_process = new QProcess();
+ cmd_process->setProcessChannelMode(QProcess::MergedChannels);
+
+ QObject::connect(cmd_process, &QProcess::started,
+ []() -> void { SPDLOG_DEBUG("process started"); });
+ QObject::connect(
+ cmd_process, &QProcess::readyReadStandardOutput,
+ [interact_func, cmd_process]() { interact_func(cmd_process); });
+ QObject::connect(cmd_process, &QProcess::errorOccurred,
+ [=](QProcess::ProcessError error) {
+ SPDLOG_ERROR("error in executing command: {} error: {}",
+ cmd, error);
+ });
+ QObject::connect(
+ cmd_process, qOverload<int, QProcess::ExitStatus>(&QProcess::finished),
+ [=](int, QProcess::ExitStatus status) {
+ if (status == QProcess::NormalExit)
+ SPDLOG_DEBUG(
+ "proceess finished, succeed in executing command: {}, exit "
+ "status: {}",
+ cmd, status);
+ else
+ SPDLOG_ERROR(
+ "proceess finished, error in executing command: {}, exit "
+ "status: {}",
+ cmd, status);
+ });
+
+ cmd_process->setProgram(QString::fromStdString(cmd));
- boost::asio::io_service ios;
+ QStringList q_arguments;
+ for (const auto &argument : arguments)
+ q_arguments.append(QString::fromStdString(argument));
+ cmd_process->setArguments(q_arguments);
- std::vector<char> buf;
+ SPDLOG_DEBUG("process execute ready, cmd: {} {}", cmd,
+ q_arguments.join(" ").toStdString());
- async_pipe in_pipe_stream(ios);
- async_pipe out_pipe_stream(ios);
+ cmd_process->start();
+ cmd_process->waitForFinished();
- child child_process(ctx_.GetInfo().AppPath.c_str(), arguments,
- std_out > in_pipe_stream, std_in < out_pipe_stream);
+ std::string process_stdout =
+ cmd_process->readAllStandardOutput().toStdString(),
+ process_stderr =
+ cmd_process->readAllStandardError().toStdString();
+ int exit_code = cmd_process->exitCode();
- boost::asio::async_read(
- in_pipe_stream, boost::asio::buffer(buf),
- [&](const boost::system::error_code& ec, std::size_t size) {
- interact_func(in_pipe_stream, out_pipe_stream);
- });
+ cmd_process->close();
+ cmd_process->deleteLater();
- ios.run();
- child_process.wait();
- child_process.exit_code();
+ // transfer result
+ SPDLOG_DEBUG("runner append object");
+ data_object->AppendObject(std::move(process_stderr));
+ data_object->AppendObject(std::move(process_stdout));
+ data_object->AppendObject(std::move(exit_code));
+ SPDLOG_DEBUG("runner append object done");
+
+ return 0;
+ };
+
+ // data transfer into task
+ auto data_object = std::make_shared<Thread::Task::DataObject>();
+ SPDLOG_DEBUG("executor append object");
+ data_object->AppendObject(std::move(callback));
+ data_object->AppendObject(std::move(interact_func));
+ data_object->AppendObject(std::move(arguments));
+ data_object->AppendObject(std::move(std::string{cmd}));
+ SPDLOG_DEBUG("executor append object done");
+
+ auto *process_task = new GpgFrontend::Thread::Task(
+ std::move(runner), fmt::format("Execute/{}", cmd), data_object,
+ std::move(result_callback));
+
+ QEventLoop looper;
+ QObject::connect(process_task, &Thread::Task::SignalTaskEnd, &looper,
+ &QEventLoop::quit);
+
+ GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_External_Process)
+ ->PostTask(process_task);
+
+ // block until task finished
+ // this is to keep reference vaild until task finished
+ looper.exec();
}
-#endif
+void GpgFrontend::GpgCommandExecutor::ExecuteConcurrently(
+ std::string cmd, std::vector<std::string> arguments,
+ std::function<void(int, std::string, std::string)> callback,
+ std::function<void(QProcess *)> interact_func) {
+ SPDLOG_DEBUG("called cmd {} arguments size: {}", cmd, arguments.size());
+
+ Thread::Task::TaskCallback result_callback =
+ [](int rtn, Thread::Task::DataObjectPtr data_object) {
+ if (data_object->GetObjectSize() != 4)
+ throw std::runtime_error("invalid data object size");
+
+ auto exit_code = data_object->PopObject<int>();
+ auto process_stdout = data_object->PopObject<std::string>();
+ auto process_stderr = data_object->PopObject<std::string>();
+ auto callback = data_object->PopObject<
+ std::function<void(int, std::string, std::string)>>();
+
+ // call callback
+ callback(exit_code, process_stdout, process_stderr);
+ };
+
+ Thread::Task::TaskRunnable runner =
+ [](GpgFrontend::Thread::Task::DataObjectPtr data_object) -> int {
+ SPDLOG_DEBUG("process runner called, data object size: {}",
+ data_object->GetObjectSize());
+
+ if (data_object->GetObjectSize() != 4)
+ throw std::runtime_error("invalid data object size");
+
+ SPDLOG_DEBUG("runner pop object");
+ // get arguments
+ auto cmd = data_object->PopObject<std::string>();
+ auto arguments = data_object->PopObject<std::vector<std::string>>();
+ auto interact_func =
+ data_object->PopObject<std::function<void(QProcess *)>>();
+ SPDLOG_DEBUG("runner pop object done");
+
+ auto *cmd_process = new QProcess();
+ cmd_process->setProcessChannelMode(QProcess::MergedChannels);
+
+ QObject::connect(cmd_process, &QProcess::started,
+ []() -> void { SPDLOG_DEBUG("process started"); });
+ QObject::connect(
+ cmd_process, &QProcess::readyReadStandardOutput,
+ [interact_func, cmd_process]() { interact_func(cmd_process); });
+ QObject::connect(cmd_process, &QProcess::errorOccurred,
+ [=](QProcess::ProcessError error) {
+ SPDLOG_ERROR("error in executing command: {} error: {}",
+ cmd, error);
+ });
+ QObject::connect(
+ cmd_process, qOverload<int, QProcess::ExitStatus>(&QProcess::finished),
+ [=](int, QProcess::ExitStatus status) {
+ if (status == QProcess::NormalExit)
+ SPDLOG_DEBUG(
+ "proceess finished, succeed in executing command: {}, exit "
+ "status: {}",
+ cmd, status);
+ else
+ SPDLOG_ERROR(
+ "proceess finished, error in executing command: {}, exit "
+ "status: {}",
+ cmd, status);
+ });
+
+ cmd_process->setProgram(QString::fromStdString(cmd));
+ cmd_process->setProcessChannelMode(QProcess::SeparateChannels);
+
+ QStringList q_arguments;
+ for (const auto &argument : arguments)
+ q_arguments.append(QString::fromStdString(argument));
+ cmd_process->setArguments(q_arguments);
+
+ SPDLOG_DEBUG("process start ready, cmd: {} {}", cmd,
+ q_arguments.join(" ").toStdString());
+
+ cmd_process->start();
+ cmd_process->waitForFinished();
+
+ std::string process_stdout =
+ cmd_process->readAllStandardOutput().toStdString(),
+ process_stderr =
+ cmd_process->readAllStandardError().toStdString();
+ int exit_code = cmd_process->exitCode();
+
+ cmd_process->close();
+ cmd_process->deleteLater();
+
+ // transfer result
+ SPDLOG_DEBUG("runner append object");
+ data_object->AppendObject(std::move(process_stderr));
+ data_object->AppendObject(std::move(process_stdout));
+ data_object->AppendObject(std::move(exit_code));
+ SPDLOG_DEBUG("runner append object done");
+
+ return 0;
+ };
+
+ // data transfer into task
+ auto data_object = std::make_shared<Thread::Task::DataObject>();
+ data_object->AppendObject(std::move(callback));
+ data_object->AppendObject(std::move(interact_func));
+ data_object->AppendObject(std::move(arguments));
+ data_object->AppendObject(std::move(std::string{cmd}));
+
+ auto *process_task = new GpgFrontend::Thread::Task(
+ std::move(runner), fmt::format("ExecuteConcurrently/{}", cmd),
+ data_object, std::move(result_callback), false);
+
+ GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_External_Process)
+ ->PostTask(process_task);
+}
diff --git a/src/core/function/gpg/GpgCommandExecutor.h b/src/core/function/gpg/GpgCommandExecutor.h
index 40ee22df..da0e7a8b 100644
--- a/src/core/function/gpg/GpgCommandExecutor.h
+++ b/src/core/function/gpg/GpgCommandExecutor.h
@@ -35,6 +35,7 @@
#include "core/GpgContext.h"
#include "core/GpgFunctionObject.h"
+#include "core/thread/Task.h"
namespace GpgFrontend {
@@ -53,19 +54,22 @@ class GPGFRONTEND_CORE_EXPORT GpgCommandExecutor
explicit GpgCommandExecutor(
int channel = SingletonFunctionObject::GetDefaultChannel());
-#ifndef WINDOWS
-
/**
- * @brief Excuting an order
+ * @brief Excuting a command
*
* @param arguments Command parameters
* @param interact_func Command answering function
*/
- void Execute(StringArgsRef arguments,
- const std::function<void(boost::process::async_pipe &in,
- boost::process::async_pipe &out)>
- &interact_func);
-#endif
+ void Execute(
+ std::string cmd, std::vector<std::string> arguments,
+ std::function<void(int, std::string, std::string)> callback =
+ [](int, std::string, std::string) {},
+ std::function<void(QProcess *)> interact_func = [](QProcess *) {});
+
+ void ExecuteConcurrently(
+ std::string cmd, std::vector<std::string> arguments,
+ std::function<void(int, std::string, std::string)> callback,
+ std::function<void(QProcess *)> interact_func = [](QProcess *) {});
private:
GpgContext &ctx_ = GpgContext::GetInstance(
diff --git a/src/core/function/gpg/GpgKeyGetter.cpp b/src/core/function/gpg/GpgKeyGetter.cpp
index 571e8797..a8e685e0 100644
--- a/src/core/function/gpg/GpgKeyGetter.cpp
+++ b/src/core/function/gpg/GpgKeyGetter.cpp
@@ -35,19 +35,15 @@
#include <utility>
#include "GpgConstants.h"
-#include "easylogging++.h"
#include "model/GpgKey.h"
GpgFrontend::GpgKeyGetter::GpgKeyGetter(int channel)
: SingletonFunctionObject<GpgKeyGetter>(channel) {
- LOG(INFO) << "called"
- << "channel:" << channel;
+ SPDLOG_DEBUG("called channel: {}", channel);
}
GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetKey(const std::string& fpr,
bool use_cache) {
- LOG(INFO) << "called";
-
// find in cache first
if (use_cache) {
auto key = get_key_in_cache(fpr);
@@ -57,7 +53,7 @@ GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetKey(const std::string& fpr,
gpgme_key_t _p_key = nullptr;
gpgme_get_key(ctx_, fpr.c_str(), &_p_key, 1);
if (_p_key == nullptr) {
- DLOG(WARNING) << "GpgKeyGetter GetKey Private _p_key Null fpr" << fpr;
+ SPDLOG_WARN("GpgKeyGetter GetKey Private _p_key Null fpr", fpr);
return GetPubkey(fpr);
} else {
return GpgKey(std::move(_p_key));
@@ -74,8 +70,7 @@ GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetPubkey(const std::string& fpr,
gpgme_key_t _p_key = nullptr;
gpgme_get_key(ctx_, fpr.c_str(), &_p_key, 0);
- if (_p_key == nullptr)
- DLOG(WARNING) << "GpgKeyGetter GetKey _p_key Null" << fpr;
+ if (_p_key == nullptr) SPDLOG_WARN("GpgKeyGetter GetKey _p_key Null", fpr);
return GpgKey(std::move(_p_key));
}
@@ -83,21 +78,19 @@ GpgFrontend::KeyLinkListPtr GpgFrontend::GpgKeyGetter::FetchKey() {
// get the lock
std::lock_guard<std::mutex> lock(keys_cache_mutex_);
- LOG(INFO) << "GpgKeyGetter FetchKey"
- << "channel id:" << GetChannel();
+ SPDLOG_DEBUG("channel id: {}", GetChannel());
auto keys_list = std::make_unique<GpgKeyLinkList>();
for (const auto& [key, value] : keys_cache_) {
- LOG(INFO) << "FetchKey Id:" << value.GetId();
+ SPDLOG_DEBUG("fetch key id: {}", value.GetId());
keys_list->push_back(value.Copy());
}
return keys_list;
}
void GpgFrontend::GpgKeyGetter::FlushKeyCache() {
- LOG(INFO) << "called"
- << "channel id: " << GetChannel();
+ SPDLOG_DEBUG("called channel id: {}", GetChannel());
// clear the keys cache
keys_cache_.clear();
@@ -125,13 +118,14 @@ void GpgFrontend::GpgKeyGetter::FlushKeyCache() {
gpg_key = GetKey(gpg_key.GetId(), false);
}
- LOG(INFO) << "LoadKey Fpr:" << gpg_key.GetFingerprint()
- << "Id:" << gpg_key.GetId();
+ SPDLOG_DEBUG("load key fpr: {} id: {}", gpg_key.GetFingerprint(),
+ gpg_key.GetId());
keys_cache_.insert({gpg_key.GetId(), std::move(gpg_key)});
}
}
- LOG(INFO) << "cache address:" << &keys_cache_ << "object address" << this;
+ SPDLOG_DEBUG("cache address: {} object address: {}",
+ static_cast<void*>(&keys_cache_), static_cast<void*>(this));
// for debug
assert(check_gpg_error_2_err_code(err, GPG_ERR_EOF) == GPG_ERR_EOF);
diff --git a/src/core/function/gpg/GpgKeyImportExporter.cpp b/src/core/function/gpg/GpgKeyImportExporter.cpp
index 206282ae..01349c94 100644
--- a/src/core/function/gpg/GpgKeyImportExporter.cpp
+++ b/src/core/function/gpg/GpgKeyImportExporter.cpp
@@ -28,6 +28,8 @@
#include "GpgKeyImportExporter.h"
+#include <memory>
+
#include "GpgConstants.h"
#include "GpgKeyGetter.h"
@@ -91,8 +93,8 @@ bool GpgFrontend::GpgKeyImportExporter::ExportKeys(KeyIdArgsListPtr& uid_list,
delete[] keys_array;
- DLOG(INFO) << "exportKeys read_bytes"
- << gpgme_data_seek(data_out, 0, SEEK_END);
+ SPDLOG_DEBUG("export keys read_bytes: {}",
+ gpgme_data_seek(data_out, 0, SEEK_END));
auto temp_out_buffer = data_out.Read2Buffer();
@@ -116,6 +118,25 @@ bool GpgFrontend::GpgKeyImportExporter::ExportKeys(const KeyArgsList& keys,
}
/**
+ * Export all the keys both private and public keys
+ * @param uid_list key ids
+ * @param out_buffer output byte array
+ * @return if success
+ */
+bool GpgFrontend::GpgKeyImportExporter::ExportAllKeys(
+ KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer, bool secret) const {
+ bool result = true;
+ result = ExportKeys(uid_list, out_buffer, false) & result;
+
+ ByteArrayPtr temp_buffer;
+ if (secret) {
+ result = ExportKeys(uid_list, temp_buffer, true) & result;
+ }
+ out_buffer->append(*temp_buffer);
+ return result;
+}
+
+/**
* Export the secret key of a key pair(including subkeys)
* @param key target key pair
* @param outBuffer output byte array
@@ -123,7 +144,7 @@ bool GpgFrontend::GpgKeyImportExporter::ExportKeys(const KeyArgsList& keys,
*/
bool GpgFrontend::GpgKeyImportExporter::ExportSecretKey(
const GpgKey& key, ByteArrayPtr& out_buffer) const {
- DLOG(INFO) << "Export Secret Key" << key.GetId().c_str();
+ SPDLOG_DEBUG("export secret key: {}", key.GetId().c_str());
gpgme_key_t target_key[2] = {gpgme_key_t(key), nullptr};
@@ -144,8 +165,8 @@ bool GpgFrontend::GpgKeyImportExporter::ExportKey(
GpgData data_out;
auto err = gpgme_op_export(ctx_, key.GetId().c_str(), 0, data_out);
- DLOG(INFO) << "exportKeys read_bytes"
- << gpgme_data_seek(data_out, 0, SEEK_END);
+ SPDLOG_DEBUG("export keys read_bytes: {}",
+ gpgme_data_seek(data_out, 0, SEEK_END));
auto temp_out_buffer = data_out.Read2Buffer();
std::swap(out_buffer, temp_out_buffer);
@@ -159,7 +180,7 @@ bool GpgFrontend::GpgKeyImportExporter::ExportKeyOpenSSH(
auto err = gpgme_op_export(ctx_, key.GetId().c_str(), GPGME_EXPORT_MODE_SSH,
data_out);
- DLOG(INFO) << "read_bytes" << gpgme_data_seek(data_out, 0, SEEK_END);
+ SPDLOG_DEBUG("read_bytes: {}", gpgme_data_seek(data_out, 0, SEEK_END));
auto temp_out_buffer = data_out.Read2Buffer();
std::swap(out_buffer, temp_out_buffer);
@@ -173,7 +194,7 @@ bool GpgFrontend::GpgKeyImportExporter::ExportSecretKeyShortest(
auto err = gpgme_op_export(ctx_, key.GetId().c_str(),
GPGME_EXPORT_MODE_MINIMAL, data_out);
- DLOG(INFO) << "read_bytes" << gpgme_data_seek(data_out, 0, SEEK_END);
+ SPDLOG_DEBUG("read_bytes: {}", gpgme_data_seek(data_out, 0, SEEK_END));
auto temp_out_buffer = data_out.Read2Buffer();
std::swap(out_buffer, temp_out_buffer);
diff --git a/src/core/function/gpg/GpgKeyImportExporter.h b/src/core/function/gpg/GpgKeyImportExporter.h
index 7603c17d..6e90f436 100644
--- a/src/core/function/gpg/GpgKeyImportExporter.h
+++ b/src/core/function/gpg/GpgKeyImportExporter.h
@@ -132,6 +132,18 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyImportExporter
/**
* @brief
*
+ * @param keys
+ * @param outBuffer
+ * @param secret
+ * @return true
+ * @return false
+ */
+ bool ExportAllKeys(KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer,
+ bool secret) const;
+
+ /**
+ * @brief
+ *
* @param key
* @param out_buffer
* @return true
diff --git a/src/core/function/gpg/GpgKeyOpera.cpp b/src/core/function/gpg/GpgKeyOpera.cpp
index 0839c132..0d715ba7 100644
--- a/src/core/function/gpg/GpgKeyOpera.cpp
+++ b/src/core/function/gpg/GpgKeyOpera.cpp
@@ -59,7 +59,7 @@ void GpgFrontend::GpgKeyOpera::DeleteKeys(
GPGME_DELETE_ALLOW_SECRET | GPGME_DELETE_FORCE));
assert(gpg_err_code(err) == GPG_ERR_NO_ERROR);
} else {
- LOG(WARNING) << "GpgKeyOpera DeleteKeys get key failed" << tmp;
+ SPDLOG_WARN("GpgKeyOpera DeleteKeys get key failed", tmp);
}
}
}
@@ -84,7 +84,7 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::SetExpire(
to_time_t(*expires) - system_clock::to_time_t(system_clock::now());
}
- LOG(INFO) << key.GetId() << subkey_fpr << expires_time;
+ SPDLOG_DEBUG(key.GetId(), subkey_fpr, expires_time);
GpgError err;
if (key.GetFingerprint() == subkey_fpr || subkey_fpr.empty())
@@ -103,59 +103,7 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::SetExpire(
* @return the process doing this job
*/
void GpgFrontend::GpgKeyOpera::GenerateRevokeCert(
- const GpgKey& key, const std::string& output_file_name) {
- auto args = std::vector<std::string>{"--no-tty",
- "--command-fd",
- "0",
- "--status-fd",
- "1",
- "-o",
- output_file_name,
- "--gen-revoke",
- key.GetFingerprint()};
-
- using boost::asio::async_write;
- using boost::process::async_pipe;
-#ifndef WINDOWS
- GpgCommandExecutor::GetInstance().Execute(
- args, [](async_pipe& in, async_pipe& out) -> void {
- // boost::asio::streambuf buff;
- // boost::asio::read_until(in, buff, '\n');
- //
- // std::istream is(&buff);
- //
- // while (!is.eof()) {
- // std::string line;
- // is >> line;
- // LOG(INFO) << "line" << line;
- // boost::algorithm::trim(line);
- // if (line == std::string("[GNUPG:] GET_BOOL
- // gen_revoke.okay")) {
- //
- // } else if (line ==
- // std::string(
- // "[GNUPG:] GET_LINE
- // ask_revocation_reason.code")) {
- //
- // } else if (line ==
- // std::string(
- // "[GNUPG:] GET_LINE
- // ask_revocation_reason.text")) {
- //
- // } else if (line ==
- // std::string("[GNUPG:] GET_BOOL
- // openfile.overwrite.okay")) {
- //
- // } else if (line ==
- // std::string(
- // "[GNUPG:] GET_BOOL
- // ask_revocation_reason.okay")) {
- //
- // }
- // }
- });
-#endif
-}
+ const GpgKey& key, const std::string& output_file_name) {}
/**
* Generate a new key pair
@@ -168,7 +116,7 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateKey(
const char* userid = userid_utf8.c_str();
auto algo_utf8 = params->GetAlgo() + params->GetKeySizeStr();
- LOG(INFO) << "params" << params->GetAlgo() << params->GetKeySizeStr();
+ SPDLOG_DEBUG("params: {} {}", params->GetAlgo(), params->GetKeySizeStr());
const char* algo = algo_utf8.c_str();
unsigned long expires = 0;
@@ -181,9 +129,9 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateKey(
GpgError err;
- LOG(INFO) << "ctx version" << ctx_.GetInfo().GnupgVersion;
+ SPDLOG_DEBUG("ctx version, {}", ctx_.GetInfo(false).GnupgVersion);
- if (ctx_.GetInfo().GnupgVersion >= "2.1.0") {
+ if (ctx_.GetInfo(false).GnupgVersion >= "2.1.0") {
unsigned int flags = 0;
if (!params->IsSubKey()) flags |= GPGME_CREATE_CERT;
@@ -193,7 +141,7 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateKey(
if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
- LOG(INFO) << "args: " << userid << algo << expires << flags;
+ SPDLOG_DEBUG("args: {}", userid, algo, expires, flags);
err = gpgme_op_createkey(ctx_, userid, algo, 0, expires, nullptr, flags);
@@ -222,7 +170,7 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateKey(
ss << "</GnupgKeyParms>";
- DLOG(INFO) << "params" << std::endl << ss.str();
+ SPDLOG_DEBUG("params: {}", ss.str());
err = gpgme_op_genkey(ctx_, ss.str().c_str(), nullptr, nullptr);
}
@@ -245,9 +193,8 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateSubkey(
const GpgKey& key, const std::unique_ptr<GenKeyInfo>& params) {
if (!params->IsSubKey()) return GPG_ERR_CANCELED;
- LOG(INFO) << "generate subkey"
- << "algo" << params->GetAlgo() << "key size"
- << params->GetKeySizeStr();
+ SPDLOG_DEBUG("generate subkey algo {} key size {}", params->GetAlgo(),
+ params->GetKeySizeStr());
auto algo_utf8 = (params->GetAlgo() + params->GetKeySizeStr());
const char* algo = algo_utf8.c_str();
@@ -265,11 +212,9 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateSubkey(
if (params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
if (params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
+ if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
- flags |= GPGME_CREATE_NOPASSWD;
-
- LOG(INFO) << "GpgFrontend::GpgKeyOpera::GenerateSubkey Args: " << key.GetId()
- << algo << expires << flags;
+ SPDLOG_DEBUG("args: {} {} {} {}", key.GetId(), algo, expires, flags);
auto err =
gpgme_op_createsubkey(ctx_, gpgme_key_t(key), algo, 0, expires, flags);
@@ -278,8 +223,8 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateSubkey(
GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::ModifyPassword(
const GpgFrontend::GpgKey& key) {
- if (ctx_.GetInfo().GnupgVersion < "2.0.15") {
- LOG(ERROR) << _("operator not support");
+ if (ctx_.GetInfo(false).GnupgVersion < "2.0.15") {
+ SPDLOG_ERROR("operator not support");
return GPG_ERR_NOT_SUPPORTED;
}
auto err = gpgme_op_passwd(ctx_, gpgme_key_t(key), 0);
@@ -287,8 +232,8 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::ModifyPassword(
}
GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::ModifyTOFUPolicy(
const GpgFrontend::GpgKey& key, gpgme_tofu_policy_t tofu_policy) {
- if (ctx_.GetInfo().GnupgVersion < "2.1.10") {
- LOG(ERROR) << _("operator not support");
+ if (ctx_.GetInfo(false).GnupgVersion < "2.1.10") {
+ SPDLOG_ERROR("operator not support");
return GPG_ERR_NOT_SUPPORTED;
}
auto err = gpgme_op_tofu_policy(ctx_, gpgme_key_t(key), tofu_policy);
diff --git a/src/core/function/gpg/GpgUIDOperator.cpp b/src/core/function/gpg/GpgUIDOperator.cpp
index 33c29fa4..7e7a711e 100644
--- a/src/core/function/gpg/GpgUIDOperator.cpp
+++ b/src/core/function/gpg/GpgUIDOperator.cpp
@@ -65,7 +65,7 @@ bool GpgFrontend::GpgUIDOperator::AddUID(const GpgFrontend::GpgKey& key,
const std::string& name,
const std::string& comment,
const std::string& email) {
- LOG(INFO) << "GpgFrontend::UidOperator::AddUID" << name << comment << email;
+ SPDLOG_DEBUG("new uuid: {} {} {}", name, comment, email);
auto uid = boost::format("%1%(%2%)<%3%>") % name % comment % email;
return AddUID(key, uid.str());
}
diff --git a/src/core/function/result_analyse/GpgEncryptResultAnalyse.cpp b/src/core/function/result_analyse/GpgEncryptResultAnalyse.cpp
index 9b3b9700..21d37eab 100644
--- a/src/core/function/result_analyse/GpgEncryptResultAnalyse.cpp
+++ b/src/core/function/result_analyse/GpgEncryptResultAnalyse.cpp
@@ -33,7 +33,7 @@ GpgFrontend::GpgEncryptResultAnalyse::GpgEncryptResultAnalyse(
: error_(error), result_(std::move(result)) {}
void GpgFrontend::GpgEncryptResultAnalyse::do_analyse() {
- LOG(INFO) << _("Start Encrypt Result Analyse");
+ SPDLOG_DEBUG("start encrypt result analyse");
stream_ << "[#] " << _("Encrypt Operation") << " ";
diff --git a/src/core/function/result_analyse/GpgSignResultAnalyse.cpp b/src/core/function/result_analyse/GpgSignResultAnalyse.cpp
index a47b8e3e..e4d1354f 100644
--- a/src/core/function/result_analyse/GpgSignResultAnalyse.cpp
+++ b/src/core/function/result_analyse/GpgSignResultAnalyse.cpp
@@ -35,7 +35,7 @@ GpgFrontend::GpgSignResultAnalyse::GpgSignResultAnalyse(GpgError error,
: error_(error), result_(std::move(result)) {}
void GpgFrontend::GpgSignResultAnalyse::do_analyse() {
- LOG(INFO) << _("Start Sign Result Analyse");
+ SPDLOG_DEBUG("start sign result analyse");
stream_ << "[#] " << _("Sign Operation") << " ";
@@ -49,14 +49,14 @@ void GpgFrontend::GpgSignResultAnalyse::do_analyse() {
if (result_ != nullptr &&
(result_->signatures != nullptr || result_->invalid_signers != nullptr)) {
- LOG(INFO) << _("Sign Result Analyse Getting Result");
+ SPDLOG_DEBUG("sign result analyse getting result");
stream_ << "------------>" << std::endl;
auto new_sign = result_->signatures;
while (new_sign != nullptr) {
stream_ << "[>]" << _("New Signature") << ": " << std::endl;
- LOG(INFO) << _("Signers Fingerprint") << ": " << new_sign->fpr;
+ SPDLOG_DEBUG("signers fingerprint: ", new_sign->fpr);
stream_ << " " << _("Sign Mode") << ": ";
if (new_sign->type == GPGME_SIG_MODE_NORMAL)
@@ -92,7 +92,7 @@ void GpgFrontend::GpgSignResultAnalyse::do_analyse() {
new_sign = new_sign->next;
}
- LOG(INFO) << _("Sign Result Analyse Getting Invalid Signer");
+ SPDLOG_DEBUG("sign result analyse getting invalid signer");
auto invalid_signer = result_->invalid_signers;
diff --git a/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp b/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp
index 79eb5282..b19db5b2 100644
--- a/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp
+++ b/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp
@@ -39,7 +39,7 @@ GpgFrontend::GpgVerifyResultAnalyse::GpgVerifyResultAnalyse(
: error_(error), result_(std::move(result)) {}
void GpgFrontend::GpgVerifyResultAnalyse::do_analyse() {
- LOG(INFO) << _("started");
+ SPDLOG_DEBUG("started");
stream_ << "[#] " << _("Verify Operation") << " ";
diff --git a/src/core/thread/CtxCheckTask.cpp b/src/core/thread/CtxCheckTask.cpp
index 997dd341..9735fcaa 100644
--- a/src/core/thread/CtxCheckTask.cpp
+++ b/src/core/thread/CtxCheckTask.cpp
@@ -30,8 +30,9 @@
#include "core/GpgCoreInit.h"
#include "core/common/CoreCommonUtil.h"
#include "core/function/gpg/GpgKeyGetter.h"
+#include "thread/Task.h"
-GpgFrontend::Thread::CtxCheckTask::CtxCheckTask() {
+GpgFrontend::Thread::CtxCheckTask::CtxCheckTask() : Task("ctx_check_task") {
connect(this, &CtxCheckTask::SignalGnupgNotInstall,
CoreCommonUtil::GetInstance(),
&CoreCommonUtil::SignalGnupgNotInstall);
@@ -48,4 +49,6 @@ void GpgFrontend::Thread::CtxCheckTask::Run() {
// Try flushing key cache
else
GpgFrontend::GpgKeyGetter::GetInstance().FlushKeyCache();
+
+ SPDLOG_DEBUG("ctx check task runnable done");
}
diff --git a/src/core/thread/FileReadTask.cpp b/src/core/thread/FileReadTask.cpp
index 3a235390..73954d28 100644
--- a/src/core/thread/FileReadTask.cpp
+++ b/src/core/thread/FileReadTask.cpp
@@ -26,11 +26,9 @@
#include "core/thread/FileReadTask.h"
-#include <utility>
-
namespace GpgFrontend::UI {
-FileReadTask::FileReadTask(std::string path) {
+FileReadTask::FileReadTask(std::string path) : Task("file_read_task") {
connect(this, &FileReadTask::SignalFileBytesReadNext, this,
&FileReadTask::read_bytes);
@@ -48,18 +46,18 @@ void FileReadTask::Run() {
SetFinishAfterRun(false);
if (is_regular_file(read_file_path_)) {
- LOG(INFO) << "read open file" << read_file_path_;
+ SPDLOG_DEBUG("read open file: {}", read_file_path_.u8string());
target_file_.setFileName(
QString::fromStdString(read_file_path_.u8string()));
target_file_.open(QIODevice::ReadOnly);
if (!(target_file_.isOpen() && target_file_.isReadable())) {
- LOG(ERROR) << "file not open or not readable";
+ SPDLOG_ERROR("file not open or not readable");
if (target_file_.isOpen()) target_file_.close();
return;
}
- LOG(INFO) << "started reading" << read_file_path_;
+ SPDLOG_DEBUG("started reading: {}", read_file_path_.u8string());
read_bytes();
} else {
emit SignalFileBytesReadEnd();
@@ -70,18 +68,18 @@ void FileReadTask::read_bytes() {
QByteArray read_buffer;
if (!target_file_.atEnd() &&
(read_buffer = target_file_.read(buffer_size_)).size() > 0) {
- LOG(INFO) << "read bytes" << read_buffer.size();
+ SPDLOG_DEBUG("read bytes: {}", read_buffer.size());
emit SignalFileBytesRead(std::move(read_buffer));
} else {
- LOG(INFO) << "read bytes end";
+ SPDLOG_DEBUG("read bytes end");
emit SignalFileBytesReadEnd();
- // finish task
- emit SignalTaskFinished();
+ // announce finish task
+ emit SignalTaskRunnableEnd(0);
}
}
FileReadTask::~FileReadTask() {
- LOG(INFO) << "close file" << read_file_path_;
+ SPDLOG_DEBUG("close file: {}", read_file_path_.u8string());
if (target_file_.isOpen()) target_file_.close();
}
diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp
index 6b1a27a1..f3c6ae86 100644
--- a/src/core/thread/Task.cpp
+++ b/src/core/thread/Task.cpp
@@ -34,86 +34,159 @@
#include <utility>
#include "core/thread/TaskRunner.h"
-#include "easylogging++.h"
-GpgFrontend::Thread::Task::Task() : uuid_(generate_uuid()) {
- LOG(TRACE) << "Task" << uuid_ << "created";
+const std::string GpgFrontend::Thread::Task::DEFAULT_TASK_NAME = "default-task";
+
+GpgFrontend::Thread::Task::Task(std::string name)
+ : uuid_(generate_uuid()), name_(name) {
+ SPDLOG_TRACE("task {}/ created", GetFullID());
init();
}
-GpgFrontend::Thread::Task::Task(TaskCallback callback,
- DataObjectPtr data_object)
+GpgFrontend::Thread::Task::Task(TaskRunnable runnable, std::string name,
+ DataObjectPtr data_object, bool sequency)
: uuid_(generate_uuid()),
- callback_(std::move(callback)),
+ name_(name),
+ runnable_(std::move(runnable)),
+ callback_(std::move([](int, const std::shared_ptr<DataObject> &) {})),
callback_thread_(QThread::currentThread()),
- data_object_(data_object) {
- LOG(TRACE) << "Task" << uuid_ << "created with callback"
- << "callback_thread_: " << callback_thread_;
+ data_object_(data_object),
+ sequency_(sequency) {
+ SPDLOG_TRACE("task {} created with runnable, callback_thread_: {}",
+ GetFullID(), static_cast<void *>(callback_thread_));
init();
}
-GpgFrontend::Thread::Task::Task(TaskRunnable runnable, TaskCallback callback,
- DataObjectPtr data_object)
+GpgFrontend::Thread::Task::Task(TaskRunnable runnable, std::string name,
+ DataObjectPtr data_object,
+ TaskCallback callback, bool sequency)
: uuid_(generate_uuid()),
+ name_(name),
runnable_(std::move(runnable)),
callback_(std::move(callback)),
callback_thread_(QThread::currentThread()),
- data_object_(data_object) {
+ data_object_(data_object),
+ sequency_(sequency) {
init();
- LOG(TRACE) << "Task" << uuid_ << "created with runnable and callback"
- << "callback_thread_: " << callback_thread_;
+ SPDLOG_TRACE(
+ "task {} created with runnable and callback, callback_thread_: {}",
+ GetFullID(), static_cast<void *>(callback_thread_));
}
GpgFrontend::Thread::Task::~Task() {
- LOG(TRACE) << "Task" << uuid_ << "destroyed";
+ SPDLOG_TRACE("task {} destroyed", GetFullID());
+}
+
+/**
+ * @brief
+ *
+ * @return std::string
+ */
+std::string GpgFrontend::Thread::Task::GetFullID() const {
+ return uuid_ + "/" + name_;
}
std::string GpgFrontend::Thread::Task::GetUUID() const { return uuid_; }
-void GpgFrontend::Thread::Task::SetFinishAfterRun(bool finish_after_run) {
- this->finish_after_run_ = finish_after_run;
+bool GpgFrontend::Thread::Task::GetSequency() const { return sequency_; }
+
+void GpgFrontend::Thread::Task::SetFinishAfterRun(
+ bool run_callback_after_runnable_finished) {
+ this->run_callback_after_runnable_finished_ =
+ run_callback_after_runnable_finished;
}
void GpgFrontend::Thread::Task::SetRTN(int rtn) { this->rtn_ = rtn; }
void GpgFrontend::Thread::Task::init() {
- connect(this, &Task::SignalTaskFinished, this, &Task::before_finish_task);
+ // after runnable finished, running callback
+ connect(this, &Task::SignalTaskRunnableEnd, this,
+ &Task::slot_task_run_callback);
}
-void GpgFrontend::Thread::Task::before_finish_task() {
- LOG(TRACE) << "Task" << uuid_ << "finished";
+void GpgFrontend::Thread::Task::slot_task_run_callback(int rtn) {
+ SPDLOG_TRACE("task runnable {} finished, rtn: {}", GetFullID(), rtn);
+ // set return value
+ this->SetRTN(rtn);
+
try {
if (callback_) {
- bool if_invoke = QMetaObject::invokeMethod(
- callback_thread_,
- [callback = callback_, rtn = rtn_, data_object = data_object_]() {
- callback(rtn, data_object);
- });
- if (!if_invoke) {
- LOG(ERROR) << "failed to invoke callback";
+ if (callback_thread_ == QThread::currentThread()) {
+ SPDLOG_DEBUG("callback thread is the same thread");
+ if (!QMetaObject::invokeMethod(callback_thread_,
+ [callback = callback_, rtn = rtn_,
+ data_object = data_object_, this]() {
+ callback(rtn, data_object);
+ // do cleaning work
+ emit SignalTaskEnd();
+ })) {
+ SPDLOG_ERROR("failed to invoke callback");
+ }
+ // just finished, let callack thread to raise SignalTaskEnd
+ return;
+ } else {
+ // waiting for callback to finish
+ if (!QMetaObject::invokeMethod(
+ callback_thread_,
+ [callback = callback_, rtn = rtn_,
+ data_object = data_object_]() { callback(rtn, data_object); },
+ Qt::BlockingQueuedConnection)) {
+ SPDLOG_ERROR("failed to invoke callback");
+ }
}
}
} catch (std::exception &e) {
- LOG(ERROR) << "exception caught: " << e.what();
+ SPDLOG_ERROR("exception caught: {}", e.what());
} catch (...) {
- LOG(ERROR) << "unknown exception caught";
+ SPDLOG_ERROR("unknown exception caught");
}
- emit SignalTaskPostFinishedDone();
+
+ // raise signal, announcing this task come to an end
+ SPDLOG_DEBUG("task {}, starting calling signal SignalTaskEnd", GetFullID());
+ emit SignalTaskEnd();
}
void GpgFrontend::Thread::Task::run() {
- LOG(TRACE) << "Task" << uuid_ << "started";
- Run();
- if (finish_after_run_) emit SignalTaskFinished();
+ SPDLOG_TRACE("task {} starting", GetFullID());
+
+ // build runnable package for running
+ auto runnable_package = [=, id = GetFullID()]() {
+ SPDLOG_DEBUG("task {} runnable start runing", id);
+ // Run() will set rtn by itself
+ Run();
+ // raise signal to anounce after runnable returned
+ if (run_callback_after_runnable_finished_) emit SignalTaskRunnableEnd(rtn_);
+ };
+
+ if (thread() != QThread::currentThread()) {
+ SPDLOG_DEBUG("task running thread is not object living thread");
+ // if running sequently
+ if (sequency_) {
+ // running in another thread, blocking until returned
+ if (!QMetaObject::invokeMethod(thread(), runnable_package,
+ Qt::BlockingQueuedConnection)) {
+ SPDLOG_ERROR("qt invoke method failed");
+ }
+ } else {
+ // running in another thread, non-blocking
+ if (!QMetaObject::invokeMethod(thread(), runnable_package)) {
+ SPDLOG_ERROR("qt invoke method failed");
+ }
+ }
+ } else {
+ if (!QMetaObject::invokeMethod(this, runnable_package)) {
+ SPDLOG_ERROR("qt invoke method failed");
+ }
+ }
}
+void GpgFrontend::Thread::Task::SlotRun() { run(); }
+
void GpgFrontend::Thread::Task::Run() {
if (runnable_) {
- bool if_invoke = QMetaObject::invokeMethod(
- this, [=]() { return runnable_(data_object_); }, &rtn_);
- if (!if_invoke) {
- LOG(ERROR) << "Qt invokeMethod failed";
- }
+ SetRTN(runnable_(data_object_));
+ } else {
+ SPDLOG_WARN("no runnable in task, do callback operation");
}
}
@@ -126,8 +199,8 @@ GpgFrontend::Thread::Task::DataObject::get_heap_ptr(size_t bytes_size) {
GpgFrontend::Thread::Task::DataObject::~DataObject() {
if (!data_objects_.empty())
- LOG(WARNING) << "data_objects_ is not empty"
- << "address:" << this;
+ SPDLOG_WARN("data_objects_ is not empty",
+ "address:", static_cast<void *>(this));
while (!data_objects_.empty()) {
free_heap_ptr(data_objects_.top());
data_objects_.pop();
@@ -139,8 +212,9 @@ size_t GpgFrontend::Thread::Task::DataObject::GetObjectSize() {
}
void GpgFrontend::Thread::Task::DataObject::free_heap_ptr(Destructor *ptr) {
- DLOG(TRACE) << "p_obj: " << ptr->p_obj << "destructor: " << ptr->destroy
- << "DataObject:" << this;
+ SPDLOG_TRACE("p_obj: {} data object: {}",
+ static_cast<const void *>(ptr->p_obj),
+ static_cast<void *>(this));
if (ptr->destroy != nullptr) {
ptr->destroy(ptr->p_obj);
}
diff --git a/src/core/thread/Task.h b/src/core/thread/Task.h
index c94baea6..ce354697 100644
--- a/src/core/thread/Task.h
+++ b/src/core/thread/Task.h
@@ -50,6 +50,8 @@ class GPGFRONTEND_CORE_EXPORT Task : public QObject, public QRunnable {
using TaskRunnable = std::function<int(DataObjectPtr)>; ///<
using TaskCallback = std::function<void(int, DataObjectPtr)>; ///<
+ static const std::string DEFAULT_TASK_NAME;
+
friend class TaskRunner;
/**
@@ -78,9 +80,10 @@ class GPGFRONTEND_CORE_EXPORT Task : public QObject, public QRunnable {
*/
template <typename T>
void AppendObject(T &&obj) {
- DLOG(TRACE) << "called:" << this;
+ SPDLOG_TRACE("append object: {}", static_cast<void *>(this));
auto *obj_dstr = this->get_heap_ptr(sizeof(T));
- auto *ptr_heap = new ((void *)obj_dstr->p_obj) T(std::move(obj));
+ new ((void *)obj_dstr->p_obj) T(std::forward<T>(obj));
+
if (std::is_class_v<T>) {
auto destructor = [](const void *x) {
static_cast<const T *>(x)->~T();
@@ -89,7 +92,8 @@ class GPGFRONTEND_CORE_EXPORT Task : public QObject, public QRunnable {
} else {
obj_dstr->destroy = nullptr;
}
- data_objects_.push(std::move(obj_dstr));
+
+ data_objects_.push(obj_dstr);
}
/**
@@ -100,11 +104,11 @@ class GPGFRONTEND_CORE_EXPORT Task : public QObject, public QRunnable {
*/
template <typename T>
void AppendObject(T *obj) {
- DLOG(TRACE) << "called:" << this;
+ SPDLOG_TRACE("called: {}", static_cast<void *>(this));
auto *obj_dstr = this->get_heap_ptr(sizeof(T));
auto *ptr_heap = new ((void *)obj_dstr->p_obj) T(std::move(*obj));
if (std::is_class_v<T>) {
- LOG(TRACE) << "is class";
+ SPDLOG_TRACE("is class");
auto destructor = [](const void *x) {
static_cast<const T *>(x)->~T();
};
@@ -123,7 +127,7 @@ class GPGFRONTEND_CORE_EXPORT Task : public QObject, public QRunnable {
*/
template <typename T>
T PopObject() {
- DLOG(TRACE) << "called:" << this;
+ SPDLOG_TRACE("pop object: {}", static_cast<void *>(this));
if (data_objects_.empty()) throw std::runtime_error("No object to pop");
auto *obj_dstr = data_objects_.top();
auto *heap_ptr = (T *)obj_dstr->p_obj;
@@ -162,24 +166,25 @@ class GPGFRONTEND_CORE_EXPORT Task : public QObject, public QRunnable {
* @brief Construct a new Task object
*
*/
- Task();
+ Task(std::string name = DEFAULT_TASK_NAME);
/**
* @brief Construct a new Task object
*
* @param callback The callback function to be executed.
*/
- Task(TaskCallback callback, DataObjectPtr data_object = nullptr);
+ explicit Task(TaskRunnable runnable, std::string name = DEFAULT_TASK_NAME,
+ DataObjectPtr data_object = nullptr, bool sequency = true);
/**
* @brief Construct a new Task object
*
* @param runnable
*/
- Task(
- TaskRunnable runnable,
- TaskCallback callback = [](int, std::shared_ptr<DataObject>) {},
- DataObjectPtr data = nullptr);
+ explicit Task(
+ TaskRunnable runnable, std::string name, DataObjectPtr data,
+ TaskCallback callback = [](int, const std::shared_ptr<DataObject> &) {},
+ bool sequency = true);
/**
* @brief Destroy the Task object
@@ -200,18 +205,40 @@ class GPGFRONTEND_CORE_EXPORT Task : public QObject, public QRunnable {
*/
std::string GetUUID() const;
- signals:
/**
* @brief
*
+ * @return std::string
*/
- void SignalTaskFinished();
+ std::string GetFullID() const;
/**
* @brief
*
+ * @return std::string
+ */
+ bool GetSequency() const;
+
+ public slots:
+
+ /**
+ * @brief
+ *
+ */
+ void SlotRun();
+
+ signals:
+ /**
+ * @brief announce runnable finished
+ *
+ */
+ void SignalTaskRunnableEnd(int rtn);
+
+ /**
+ * @brief runnable and callabck all finished
+ *
*/
- void SignalTaskPostFinishedDone();
+ void SignalTaskEnd();
protected:
/**
@@ -230,37 +257,40 @@ class GPGFRONTEND_CORE_EXPORT Task : public QObject, public QRunnable {
private:
const std::string uuid_;
- TaskCallback callback_; ///<
- TaskRunnable runnable_; ///<
- bool finish_after_run_ = true; ///<
- int rtn_ = 0; ///<
- QThread *callback_thread_ = nullptr; ///<
- DataObjectPtr data_object_ = nullptr; ///<
+ const std::string name_;
+ const bool sequency_ = true; ///< must run in the same thread
+ TaskCallback callback_; ///<
+ TaskRunnable runnable_; ///<
+ bool run_callback_after_runnable_finished_ = true; ///<
+ int rtn_ = 0; ///<
+ QThread *callback_thread_ = nullptr; ///<
+ DataObjectPtr data_object_ = nullptr; ///<
/**
* @brief
*
*/
- void before_finish_task();
+ void init();
/**
* @brief
*
*/
- void init();
+ virtual void run() override;
/**
* @brief
*
+ * @return std::string
*/
- virtual void run() override;
+ static std::string generate_uuid();
+ private slots:
/**
* @brief
*
- * @return std::string
*/
- static std::string generate_uuid();
+ void slot_task_run_callback(int rtn);
};
} // namespace GpgFrontend::Thread
diff --git a/src/core/thread/TaskRunner.cpp b/src/core/thread/TaskRunner.cpp
index f70b2d4c..461d5fb5 100644
--- a/src/core/thread/TaskRunner.cpp
+++ b/src/core/thread/TaskRunner.cpp
@@ -26,32 +26,24 @@
#include "core/thread/TaskRunner.h"
-#include <exception>
-
#include "core/thread/Task.h"
-#include "easylogging++.h"
+#include "spdlog/spdlog.h"
GpgFrontend::Thread::TaskRunner::TaskRunner() = default;
GpgFrontend::Thread::TaskRunner::~TaskRunner() = default;
void GpgFrontend::Thread::TaskRunner::PostTask(Task* task) {
- std::string uuid = task->GetUUID();
- LOG(TRACE) << "Post Task" << uuid;
+ if (task == nullptr) {
+ SPDLOG_ERROR("task posted is null");
+ return;
+ }
+
+ SPDLOG_TRACE("post task: {}", task->GetFullID());
- if (task == nullptr) return;
task->setParent(nullptr);
task->moveToThread(this);
- connect(task, &Task::SignalTaskPostFinishedDone, this, [&, uuid]() {
- auto it = pending_tasks_.find(uuid);
- if (it == pending_tasks_.end()) {
- return;
- } else {
- it->second->deleteLater();
- pending_tasks_.erase(it);
- }
- });
{
std::lock_guard<std::mutex> lock(tasks_mutex_);
tasks.push(task);
@@ -59,16 +51,20 @@ void GpgFrontend::Thread::TaskRunner::PostTask(Task* task) {
quit();
}
-void GpgFrontend::Thread::TaskRunner::run() {
- LOG(TRACE) << "called"
- << "thread id:" << QThread::currentThreadId();
+void GpgFrontend::Thread::TaskRunner::PostScheduleTask(Task* task,
+ size_t seconds) {
+ if (task == nullptr) return;
+ // TODO
+}
+
+[[noreturn]] void GpgFrontend::Thread::TaskRunner::run() {
+ SPDLOG_TRACE("task runner runing, thread id: {}", QThread::currentThreadId());
while (true) {
- LOG(TRACE) << "TaskRunner: A new cycle start";
if (tasks.empty()) {
- LOG(TRACE) << "TaskRunner: No tasks to run, trapping into event loop...";
+ SPDLOG_TRACE("no tasks to run, trapping into event loop...");
exec();
} else {
- LOG(TRACE) << "TaskRunner: Task queue size:" << tasks.size();
+ SPDLOG_TRACE("start to run task(s), queue size: {}", tasks.size());
Task* task = nullptr;
{
@@ -79,26 +75,72 @@ void GpgFrontend::Thread::TaskRunner::run() {
}
if (task != nullptr) {
- // Run the task
- LOG(TRACE) << "TaskRunner: Running Task" << task->GetUUID();
try {
+ // triger
+ SPDLOG_TRACE("running task {}, sequency: {}", task->GetFullID(),
+ task->GetSequency());
+
+ // when a signal SignalTaskEnd raise, do unregister work
+ connect(task, &Task::SignalTaskEnd, this, [this, task]() {
+ unregister_finished_task(task->GetUUID());
+ });
+
+ if (!task->GetSequency()) {
+ // if it need to run concurrently, we should create a new thread to
+ // run it.
+ auto* concurrent_thread = new QThread(nullptr);
+ task->setParent(nullptr);
+ task->moveToThread(concurrent_thread);
+ // start thread
+ concurrent_thread->start();
+
+ connect(task, &Task::SignalTaskEnd, concurrent_thread,
+ &QThread::quit);
+ // concurrent thread is responsible for deleting the task
+ connect(concurrent_thread, &QThread::finished, task,
+ &Task::deleteLater);
+ }
+
+ // run the task
task->run();
} catch (const std::exception& e) {
- LOG(ERROR) << "TaskRunner: Exception in Task" << task->GetUUID()
- << "Exception: " << e.what();
-
- // destroy the task, remove the task from the pending tasks
- task->deleteLater();
- pending_tasks_.erase(task->GetUUID());
+ SPDLOG_ERROR("task runner: exception in task {}, exception: {}",
+ task->GetFullID(), e.what());
+ // if any exception caught, destroy the task, remove the task from the
+ // pending tasks
+ unregister_finished_task(task->GetUUID());
} catch (...) {
- LOG(ERROR) << "TaskRunner: Unknwon Exception in Task"
- << task->GetUUID();
-
- // destroy the task, remove the task from the pending tasks
- task->deleteLater();
- pending_tasks_.erase(task->GetUUID());
+ SPDLOG_ERROR("task runner: unknown exception in task: {}",
+ task->GetFullID());
+ // if any exception caught, destroy the task, remove the task from the
+ // pending tasks
+ unregister_finished_task(task->GetUUID());
}
}
}
}
}
+
+/**
+ * @brief
+ *
+ */
+void GpgFrontend::Thread::TaskRunner::unregister_finished_task(
+ std::string task_uuid) {
+ SPDLOG_DEBUG("cleaning task {}", task_uuid);
+ // search in map
+ auto pending_task = pending_tasks_.find(task_uuid);
+ if (pending_task == pending_tasks_.end()) {
+ SPDLOG_ERROR("cannot find task in pending list: {}", task_uuid);
+ return;
+ } else {
+ std::lock_guard<std::mutex> lock(tasks_mutex_);
+ // if thread runs sequenctly, that means the thread is living in this
+ // thread, so we can delete it. Or, its living thread need to delete it.
+ if (pending_task->second->GetSequency())
+ pending_task->second->deleteLater();
+ pending_tasks_.erase(pending_task);
+ }
+
+ SPDLOG_DEBUG("clean task {} done", task_uuid);
+}
diff --git a/src/core/thread/TaskRunner.h b/src/core/thread/TaskRunner.h
index f18efca6..35cd1a30 100644
--- a/src/core/thread/TaskRunner.h
+++ b/src/core/thread/TaskRunner.h
@@ -27,6 +27,7 @@
#ifndef GPGFRONTEND_TASKRUNNER_H
#define GPGFRONTEND_TASKRUNNER_H
+#include <cstddef>
#include <mutex>
#include <queue>
@@ -55,7 +56,7 @@ class GPGFRONTEND_CORE_EXPORT TaskRunner : public QThread {
* @brief
*
*/
- void run() override;
+ [[noreturn]] void run() override;
public slots:
@@ -66,10 +67,25 @@ class GPGFRONTEND_CORE_EXPORT TaskRunner : public QThread {
*/
void PostTask(Task* task);
+ /**
+ * @brief
+ *
+ * @param task
+ * @param seconds
+ */
+ void PostScheduleTask(Task* task, size_t seconds);
+
private:
std::queue<Task*> tasks; ///< The task queue
std::map<std::string, Task*> pending_tasks_; ///< The pending tasks
std::mutex tasks_mutex_; ///< The task queue mutex
+ QThreadPool thread_pool_{this}; ///< run non-sequency task
+
+ /**
+ * @brief
+ *
+ */
+ void unregister_finished_task(std::string);
};
} // namespace GpgFrontend::Thread
diff --git a/src/core/thread/TaskRunnerGetter.h b/src/core/thread/TaskRunnerGetter.h
index afbf63af..80b25c3e 100644
--- a/src/core/thread/TaskRunnerGetter.h
+++ b/src/core/thread/TaskRunnerGetter.h
@@ -41,6 +41,7 @@ class GPGFRONTEND_CORE_EXPORT TaskRunnerGetter
kTaskRunnerType_GPG,
kTaskRunnerType_IO,
kTaskRunnerType_Network,
+ kTaskRunnerType_External_Process,
};
TaskRunnerGetter(int channel = SingletonFunctionObject::GetDefaultChannel());
diff --git a/src/init.cpp b/src/init.cpp
index c872170e..80c34800 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -26,21 +26,103 @@
*
*/
+#include <spdlog/async.h>
+#include <spdlog/common.h>
+#include <spdlog/sinks/rotating_file_sink.h>
+#include <spdlog/sinks/stdout_color_sinks.h>
+
+#include <filesystem>
+
#include "GpgFrontend.h"
#include "GpgFrontendBuildInfo.h"
#include "core/function/GlobalSettingStation.h"
+#ifdef WINDOWS
+int setenv(const char *name, const char *value, int overwrite)
+{
+ if(!overwrite) {
+ int errcode = 0;
+ size_t envsize = 0;
+ errcode = getenv_s(&envsize, NULL, 0, name);
+ if(errcode || envsize) return errcode;
+ }
+ return _putenv_s(name, value);
+}
+#endif
+
void init_logging_system() {
- el::Loggers::addFlag(el::LoggingFlag::AutoSpacing);
- el::Configurations defaultConf;
- defaultConf.setToDefault();
-
- // apply settings
- defaultConf.setGlobally(el::ConfigurationType::Format,
- "%datetime %level [main] %func %msg");
- // apply settings no written to file
- defaultConf.setGlobally(el::ConfigurationType::ToFile, "false");
-
- // set the logger
- el::Loggers::reconfigureLogger("default", defaultConf);
+ using namespace boost::posix_time;
+ using namespace boost::gregorian;
+
+ // sinks
+ std::vector<spdlog::sink_ptr> sinks;
+ sinks.push_back(std::make_shared<spdlog::sinks::stderr_color_sink_mt>());
+
+ // thread pool
+ spdlog::init_thread_pool(1024, 2);
+
+ // logger
+ auto main_logger = std::make_shared<spdlog::async_logger>(
+ "main", begin(sinks), end(sinks), spdlog::thread_pool());
+ main_logger->set_pattern(
+ "[%H:%M:%S.%e] [T:%t] [%=4n] %^[%=8l]%$ [%s:%#] [%!] -> %v (+%ius)");
+
+#ifdef DEBUG
+ main_logger->set_level(spdlog::level::trace);
+#else
+ main_logger->set_level(spdlog::level::info);
+#endif
+
+ // flush policy
+ main_logger->flush_on(spdlog::level::err);
+ spdlog::flush_every(std::chrono::seconds(5));
+
+ // register it as default logger
+ spdlog::set_default_logger(main_logger);
+}
+
+void shutdown_logging_system() {
+#ifdef WINDOWS
+ // Under VisualStudio, this must be called before main finishes to workaround
+ // a known VS issue
+ spdlog::drop_all();
+ spdlog::shutdown();
+#endif
+}
+
+void init_global_path_env() {
+ auto& settings =
+ GpgFrontend::GlobalSettingStation::GetInstance().GetUISettings();
+
+ bool use_custom_gnupg_install_path = false;
+ try {
+ use_custom_gnupg_install_path =
+ settings.lookup("general.use_custom_gnupg_install_path");
+ } catch (...) {
+ SPDLOG_ERROR("setting operation error: use_custom_gnupg_install_path");
+ }
+
+ // read from settings file
+ std::string custom_gnupg_install_path;
+ try {
+ custom_gnupg_install_path = static_cast<std::string>(
+ settings.lookup("general.custom_gnupg_install_path"));
+
+ } catch (...) {
+ SPDLOG_ERROR("setting operation error: custom_gnupg_install_path");
+ }
+
+ // add custom gnupg install path into env $PATH
+ if (use_custom_gnupg_install_path && !custom_gnupg_install_path.empty()) {
+ std::string path_value = getenv("PATH");
+ SPDLOG_DEBUG("PATH: {}", path_value);
+ setenv(
+ "PATH",
+ ((std::filesystem::path{custom_gnupg_install_path} / "bin").u8string() +
+ ":" + path_value)
+ .c_str(),
+ 1);
+ std::string modified_path_value = getenv("PATH");
+ SPDLOG_DEBUG("Modified PATH: {}", modified_path_value);
+ }
}
diff --git a/src/main.cpp b/src/main.cpp
index 5f2ba02e..98c02a0e 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -33,18 +33,17 @@
#include <csetjmp>
#include <csignal>
#include <cstddef>
+#include <cstdlib>
+#include <string>
#include "core/GpgConstants.h"
#include "core/GpgCoreInit.h"
+#include "core/function/GlobalSettingStation.h"
+#include "spdlog/spdlog.h"
#include "ui/GpgFrontendApplication.h"
#include "ui/GpgFrontendUIInit.h"
/**
- * \brief initialize the easylogging++ library.
- */
-INITIALIZE_EASYLOGGINGPP
-
-/**
* \brief Store the jump buff and make it possible to recover from a crash.
*/
#ifdef FREEBSD
@@ -75,6 +74,18 @@ extern void before_exit();
extern void init_logging_system();
/**
+ * @brief initialize the logging system.
+ *
+ */
+extern void shutdown_logging_system();
+
+/**
+ * @brief init global PATH env
+ *
+ */
+extern void init_global_path_env();
+
+/**
*
* @param argc
* @param argv
@@ -98,11 +109,17 @@ int main(int argc, char* argv[]) {
auto* app =
GpgFrontend::UI::GpgFrontendApplication::GetInstance(argc, argv, true);
- // init the logging system
+ // init the logging system for main
init_logging_system();
// init the logging system for core
- GpgFrontend::InitLoggingSystem();
+ GpgFrontend::InitCoreLoggingSystem();
+
+ // init the logging system for ui
+ GpgFrontend::UI::InitUILoggingSystem();
+
+ // change path to search for related
+ init_global_path_env();
/**
* internationalisation. loop to restart main window
@@ -124,7 +141,7 @@ int main(int argc, char* argv[]) {
// create main window
return_from_event_loop_code = GpgFrontend::UI::RunGpgFrontendUI(app);
} else {
- LOG(ERROR) << "recover from a crash";
+ SPDLOG_ERROR("recover from a crash");
// when signal is caught, restart the main window
auto* message_box = new QMessageBox(
QMessageBox::Critical, _("A serious error has occurred"),
@@ -137,16 +154,38 @@ int main(int argc, char* argv[]) {
return_from_event_loop_code = CRASH_CODE;
}
- LOG(INFO) << "loop refresh";
+ SPDLOG_DEBUG("restart loop refresh, event loop code: {}",
+ return_from_event_loop_code);
} while (return_from_event_loop_code == RESTART_CODE);
- // reset core
- GpgFrontend::ResetGpgFrontendCore();
+ if (return_from_event_loop_code == DEEP_RESTART_CODE ||
+ return_from_event_loop_code == CRASH_CODE) {
+ // reset core
+ GpgFrontend::ResetGpgFrontendCore();
+ // log for debug
+ SPDLOG_DEBUG("deep restart or cash loop refresh");
+ } else {
+ // log for debug
+ SPDLOG_DEBUG("need to close application, event loop code: {}",
+ return_from_event_loop_code);
+ }
// deep restart mode
} while (return_from_event_loop_code == DEEP_RESTART_CODE ||
return_from_event_loop_code == CRASH_CODE);
+
+ // shutdown the logging system for ui
+ GpgFrontend::UI::ShutdownUILoggingSystem();
+
+ // shutdown the logging system for core
+ GpgFrontend::ShutdownCoreLoggingSystem();
+
+
+
+ // log for debug
+ SPDLOG_INFO("GpgFrontend about to exit.");
+
// exit the program
return return_from_event_loop_code;
}
diff --git a/src/signal.cpp b/src/signal.cpp
index bd4cfdb1..da4dfb39 100644
--- a/src/signal.cpp
+++ b/src/signal.cpp
@@ -43,7 +43,8 @@ extern jmp_buf recover_env;
*/
void handle_signal(int sig) {
static int _repeat_handle_num = 1, last_sig = sig;
- LOG(INFO) << "signal caught" << sig;
+ // SPDLOG_DEBUG("signal caught {}", sig);
+ std::cout << "signal caught" << sig;
if (last_sig == sig)
_repeat_handle_num++;
@@ -51,8 +52,8 @@ void handle_signal(int sig) {
_repeat_handle_num = 1, last_sig = sig;
if (_repeat_handle_num > 3) {
- LOG(INFO) << "The same signal appears three times, execute the termination "
- "operation. ";
+ std::cout << "The same signal appears three times,"
+ << "execute the termination operation." << sig;
exit(-1);
}
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
index 24158e27..176a406e 100644
--- a/src/ui/CMakeLists.txt
+++ b/src/ui/CMakeLists.txt
@@ -46,8 +46,13 @@ set(_export_file "${CMAKE_CURRENT_SOURCE_DIR}/GpgFrontendUIExport.h")
generate_export_header(gpgfrontend_ui EXPORT_FILE_NAME "${_export_file}")
# link Qt
-target_link_libraries(gpgfrontend_ui
- Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core)
+if(Qt6_DIR)
+ target_link_libraries(gpgfrontend_ui
+ Qt6::Network Qt6::PrintSupport Qt6::Widgets Qt6::Test Qt6::Core5Compat Qt6::Core)
+else()
+ target_link_libraries(gpgfrontend_ui
+ Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core)
+endif()
# link gpgfrontend_core
target_link_libraries(gpgfrontend_ui
@@ -58,7 +63,8 @@ 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_CURRENT_BINARY_DIR}/gpgfrontend_ui_autogen/include
+ ${CMAKE_SOURCE_DIR}/third_party/spdlog/include)
# using std c++ 17
target_compile_features(gpgfrontend_ui PUBLIC cxx_std_17)
diff --git a/src/ui/GpgFrontendApplication.cpp b/src/ui/GpgFrontendApplication.cpp
index b1c5beed..1b2bb9ad 100644
--- a/src/ui/GpgFrontendApplication.cpp
+++ b/src/ui/GpgFrontendApplication.cpp
@@ -26,6 +26,8 @@
#include "ui/GpgFrontendApplication.h"
+#include <QTextCodec>
+
#include "GpgFrontendBuildInfo.h"
namespace GpgFrontend::UI {
@@ -36,11 +38,6 @@ GpgFrontendApplication::GpgFrontendApplication(int &argc, char *argv[])
this->setWindowIcon(QIcon(":gpgfrontend.png"));
#endif
-#ifdef MACOS
- // support retina screen
- this->setAttribute(Qt::AA_UseHighDpiPixmaps);
-#endif
-
// set the extra information of the build
this->setApplicationVersion(BUILD_VERSION);
this->setApplicationName(PROJECT_NAME);
@@ -75,7 +72,7 @@ bool GpgFrontendApplication::notify(QObject *receiver, QEvent *event) {
try {
app_done = QApplication::notify(receiver, event);
} catch (const std::exception &ex) {
- LOG(INFO) << "Exception caught in notify: " << ex.what();
+ SPDLOG_ERROR("exception caught in notify: {}", ex.what());
QMessageBox::information(nullptr, _("Standard Exception Thrown"),
_("Oops, an standard exception was thrown "
"during the running of the "
@@ -83,7 +80,7 @@ bool GpgFrontendApplication::notify(QObject *receiver, QEvent *event) {
"be the negligence of the programmer, "
"please report this problem if you can."));
} catch (...) {
- LOG(INFO) << "Unknown exception caught in notify";
+ SPDLOG_ERROR("unknown exception caught in notify");
QMessageBox::information(
nullptr, _("Unhandled Exception Thrown"),
_("Oops, an unhandled exception was thrown "
diff --git a/src/ui/GpgFrontendUIInit.cpp b/src/ui/GpgFrontendUIInit.cpp
index 5cbca31b..6e41f81f 100644
--- a/src/ui/GpgFrontendUIInit.cpp
+++ b/src/ui/GpgFrontendUIInit.cpp
@@ -28,6 +28,11 @@
#include "GpgFrontendUIInit.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"
#include "core/thread/CtxCheckTask.h"
#include "core/thread/TaskRunnerGetter.h"
@@ -39,18 +44,12 @@
#include "core/function/GlobalSettingStation.h"
#endif
-// init easyloggingpp library
-INITIALIZE_EASYLOGGINGPP
-
namespace GpgFrontend::UI {
extern void init_logging_system();
extern void init_locale();
void InitGpgFrontendUI(QApplication* app) {
- // init logging system
- init_logging_system();
-
// init locale
init_locale();
@@ -88,15 +87,15 @@ void InitGpgFrontendUI(QApplication* app) {
waiting_dialog_label->setWordWrap(true);
waiting_dialog->setLabel(waiting_dialog_label);
waiting_dialog->resize(420, 120);
- app->connect(init_ctx_task, &Thread::CtxCheckTask::SignalTaskFinished,
+ app->connect(init_ctx_task, &Thread::CtxCheckTask::SignalTaskEnd,
waiting_dialog, [=]() {
- LOG(INFO) << "Gpg context loaded";
+ SPDLOG_DEBUG("gpg context loaded");
waiting_dialog->finished(0);
waiting_dialog->deleteLater();
});
app->connect(waiting_dialog, &QProgressDialog::canceled, [=]() {
- LOG(INFO) << "cancel clicked";
+ SPDLOG_DEBUG("cancel clicked");
app->quit();
exit(0);
});
@@ -108,8 +107,8 @@ void InitGpgFrontendUI(QApplication* app) {
// new local event looper
QEventLoop looper;
- app->connect(init_ctx_task, &Thread::CtxCheckTask::SignalTaskFinished,
- &looper, &QEventLoop::quit);
+ app->connect(init_ctx_task, &Thread::CtxCheckTask::SignalTaskEnd, &looper,
+ &QEventLoop::quit);
// start the thread to load the gpg context
Thread::TaskRunnerGetter::GetInstance().GetTaskRunner()->PostTask(
@@ -123,46 +122,56 @@ int RunGpgFrontendUI(QApplication* app) {
// create main window and show it
auto main_window = std::make_unique<GpgFrontend::UI::MainWindow>();
main_window->Init();
- LOG(INFO) << "Main window inited";
+ SPDLOG_DEBUG("main window inited");
main_window->show();
// start the main event loop
return app->exec();
}
-void init_logging_system() {
+void InitUILoggingSystem() {
using namespace boost::posix_time;
using namespace boost::gregorian;
- el::Loggers::addFlag(el::LoggingFlag::AutoSpacing);
- el::Loggers::addFlag(el::LoggingFlag::ColoredTerminalOutput);
- el::Loggers::addFlag(el::LoggingFlag::StrictLogFileSizeCheck);
-
- el::Configurations defaultConf;
- defaultConf.setToDefault();
+ // get the log directory
+ auto logfile_path = (GlobalSettingStation::GetInstance().GetLogDir() / "ui");
+ logfile_path.replace_extension(".log");
- // apply settings
- defaultConf.setGlobally(el::ConfigurationType::Format,
- "%datetime %level [ui] {%func} -> %msg");
+ // sinks
+ std::vector<spdlog::sink_ptr> sinks;
+ sinks.push_back(std::make_shared<spdlog::sinks::stderr_color_sink_mt>());
+ sinks.push_back(std::make_shared<spdlog::sinks::rotating_file_sink_mt>(
+ logfile_path.u8string(), 1048576 * 32, 32));
- // apply settings no written to file
- defaultConf.setGlobally(el::ConfigurationType::ToFile, "false");
+ // thread pool
+ spdlog::init_thread_pool(1024, 2);
- // apply settings
- el::Loggers::reconfigureLogger("default", defaultConf)->reconfigure();
+ // logger
+ auto ui_logger = std::make_shared<spdlog::async_logger>(
+ "ui", begin(sinks), end(sinks), spdlog::thread_pool());
+ ui_logger->set_pattern(
+ "[%H:%M:%S.%e] [T:%t] [%=4n] %^[%=8l]%$ [%s:%#] [%!] -> %v (+%ius)");
- // get the log directory
- auto logfile_path = (GlobalSettingStation::GetInstance().GetLogDir() /
- to_iso_string(second_clock::local_time()));
- logfile_path.replace_extension(".log");
- defaultConf.setGlobally(el::ConfigurationType::Filename,
- logfile_path.u8string());
+#ifdef DEBUG
+ ui_logger->set_level(spdlog::level::trace);
+#else
+ ui_logger->set_level(spdlog::level::info);
+#endif
- // apply settings written to file
- defaultConf.setGlobally(el::ConfigurationType::ToFile, "false");
+ // flush policy
+ ui_logger->flush_on(spdlog::level::err);
+ spdlog::flush_every(std::chrono::seconds(5));
- el::Loggers::reconfigureLogger("default", defaultConf);
+ // register it as default logger
+ spdlog::set_default_logger(ui_logger);
+}
- LOG(INFO) << _("log file path") << logfile_path;
+void ShutdownUILoggingSystem() {
+#ifdef WINDOWS
+ // Under VisualStudio, this must be called before main finishes to workaround
+ // a known VS issue
+ spdlog::drop_all();
+ spdlog::shutdown();
+#endif
}
/**
@@ -187,20 +196,20 @@ void init_locale() {
// sync the settings to the file
GpgFrontend::GlobalSettingStation::GetInstance().SyncSettings();
- LOG(INFO) << "current system locale" << setlocale(LC_ALL, nullptr);
+ SPDLOG_DEBUG("current system locale: {}", setlocale(LC_ALL, nullptr));
// read from settings file
std::string lang;
if (!general.lookupValue("lang", lang)) {
- LOG(ERROR) << _("could not read properly from configure file");
+ SPDLOG_ERROR(_("could not read properly from configure file"));
};
- LOG(INFO) << "lang from settings" << lang;
- LOG(INFO) << "project name" << PROJECT_NAME;
- LOG(INFO) << "locales path"
- << GpgFrontend::GlobalSettingStation::GetInstance()
+ SPDLOG_DEBUG("lang from settings: {}", lang);
+ SPDLOG_DEBUG("project name: {}", PROJECT_NAME);
+ SPDLOG_DEBUG("locales path: {}",
+ GpgFrontend::GlobalSettingStation::GetInstance()
.GetLocaleDir()
- .c_str();
+ .u8string());
#ifndef WINDOWS
if (!lang.empty()) {
@@ -208,14 +217,14 @@ void init_locale() {
// set LC_ALL
auto* locale_name = setlocale(LC_ALL, lc.c_str());
- if (locale_name == nullptr) LOG(WARNING) << "set LC_ALL failed" << lc;
+ if (locale_name == nullptr) SPDLOG_WARN("set LC_ALL failed, lc: {}", lc);
auto language = getenv("LANGUAGE");
// set LANGUAGE
std::string language_env = language == nullptr ? "en" : language;
language_env.insert(0, lang + ":");
- LOG(INFO) << "language env" << language_env;
+ SPDLOG_DEBUG("language env: {}", language_env);
if (setenv("LANGUAGE", language_env.c_str(), 1)) {
- LOG(WARNING) << "set LANGUAGE failed" << language_env;
+ SPDLOG_WARN("set LANGUAGE {} failed", language_env);
};
}
#else
@@ -224,16 +233,16 @@ void init_locale() {
// set LC_ALL
auto* locale_name = setlocale(LC_ALL, lc.c_str());
- if (locale_name == nullptr) LOG(WARNING) << "set LC_ALL failed" << lc;
+ if (locale_name == nullptr) SPDLOG_WARN("set LC_ALL failed, lc: {}", lc);
auto language = getenv("LANGUAGE");
// set LANGUAGE
std::string language_env = language == nullptr ? "en" : language;
language_env.insert(0, lang + ":");
language_env.insert(0, "LANGUAGE=");
- LOG(INFO) << "language env" << language_env;
+ SPDLOG_DEBUG("language env: {}", language_env);
if (putenv(language_env.c_str())) {
- LOG(WARNING) << "set LANGUAGE failed" << language_env;
+ SPDLOG_WARN("set LANGUAGE {} failed", language_env);
};
}
#endif
@@ -246,4 +255,4 @@ void init_locale() {
textdomain(PROJECT_NAME);
}
-} // namespace GpgFrontend::UI \ No newline at end of file
+} // namespace GpgFrontend::UI
diff --git a/src/ui/GpgFrontendUIInit.h b/src/ui/GpgFrontendUIInit.h
index 9b490c0f..0e68aa57 100644
--- a/src/ui/GpgFrontendUIInit.h
+++ b/src/ui/GpgFrontendUIInit.h
@@ -40,6 +40,18 @@ namespace GpgFrontend::UI {
void GPGFRONTEND_UI_EXPORT InitGpgFrontendUI(QApplication *);
/**
+ * @brief
+ *
+ */
+void GPGFRONTEND_UI_EXPORT InitUILoggingSystem();
+
+/**
+ * @brief
+ *
+ */
+void GPGFRONTEND_UI_EXPORT ShutdownUILoggingSystem();
+
+/**
* @brief run main window
*/
int GPGFRONTEND_UI_EXPORT RunGpgFrontendUI(QApplication *);
diff --git a/src/ui/SignalStation.h b/src/ui/SignalStation.h
index eb7b3f74..48651f1b 100644
--- a/src/ui/SignalStation.h
+++ b/src/ui/SignalStation.h
@@ -79,6 +79,18 @@ class SignalStation : public QObject {
* @param timeout
*/
void SignalRefreshStatusBar(const QString& message, int timeout);
+
+ /**
+ * @brief
+ *
+ */
+ void SignalUserInputPassphraseDone(QString passparase);
+
+ /**
+ * @brief
+ *
+ */
+ void SignalNeedUserInputPassphrase();
};
} // namespace GpgFrontend::UI
diff --git a/src/ui/UserInterfaceUtils.cpp b/src/ui/UserInterfaceUtils.cpp
index f2659e9d..f944e037 100644
--- a/src/ui/UserInterfaceUtils.cpp
+++ b/src/ui/UserInterfaceUtils.cpp
@@ -28,17 +28,19 @@
#include "UserInterfaceUtils.h"
+#include <string>
#include <utility>
#include <vector>
#include "core/common/CoreCommonUtil.h"
+#include "core/function/CoreSignalStation.h"
#include "core/function/FileOperator.h"
#include "core/function/GlobalSettingStation.h"
#include "core/function/gpg/GpgKeyGetter.h"
#include "core/thread/Task.h"
#include "core/thread/TaskRunner.h"
#include "core/thread/TaskRunnerGetter.h"
-#include "easylogging++.h"
+#include "spdlog/spdlog.h"
#include "ui/SignalStation.h"
#include "ui/dialog/WaitingDialog.h"
#include "ui/struct/SettingsObject.h"
@@ -72,7 +74,7 @@ void import_unknown_key_from_keyserver(
auto key_ids = std::make_unique<KeyIdArgsList>();
auto *signature = verify_res.GetSignatures();
while (signature != nullptr) {
- LOG(INFO) << "signature fpr" << signature->fpr;
+ SPDLOG_DEBUG("signature fpr: {}", signature->fpr);
key_ids->push_back(signature->fpr);
signature = signature->next;
}
@@ -103,8 +105,6 @@ void process_result_analyse(TextEdit *edit, InfoBoardWidget *info_board,
void process_result_analyse(TextEdit *edit, InfoBoardWidget *info_board,
const GpgResultAnalyse &result_analyse_a,
const GpgResultAnalyse &result_analyse_b) {
- LOG(INFO) << "process_result_analyse Started";
-
info_board->AssociateTabWidget(edit->tab_widget_);
refresh_info_board(
@@ -120,15 +120,15 @@ void process_operation(QWidget *parent, const std::string &waiting_title,
auto *dialog =
new WaitingDialog(QString::fromStdString(waiting_title), parent);
- auto *process_task =
- new Thread::Task(std::move(func), std::move(callback), data_object);
+ auto *process_task = new Thread::Task(std::move(func), waiting_title,
+ data_object, std::move(callback));
- QApplication::connect(process_task, &Thread::Task::SignalTaskFinished, dialog,
+ QApplication::connect(process_task, &Thread::Task::SignalTaskEnd, dialog,
&QDialog::close);
QEventLoop looper;
- QApplication::connect(process_task, &Thread::Task::SignalTaskFinished,
- &looper, &QEventLoop::quit);
+ QApplication::connect(process_task, &Thread::Task::SignalTaskEnd, &looper,
+ &QEventLoop::quit);
// post process task to task runner
Thread::TaskRunnerGetter::GetInstance()
@@ -148,8 +148,6 @@ CommonUtils *CommonUtils::GetInstance() {
}
CommonUtils::CommonUtils() : QWidget(nullptr) {
- LOG(INFO) << "common utils created";
-
connect(CoreCommonUtil::GetInstance(), &CoreCommonUtil::SignalGnupgNotInstall,
this, &CommonUtils::SignalGnupgNotInstall);
connect(this, &CommonUtils::SignalKeyStatusUpdated,
@@ -158,6 +156,9 @@ CommonUtils::CommonUtils() : QWidget(nullptr) {
connect(this, &CommonUtils::SignalKeyDatabaseRefreshDone,
SignalStation::GetInstance(),
&SignalStation::SignalKeyDatabaseRefreshDone);
+ connect(this, &CommonUtils::SignalUserInputPassphraseDone,
+ CoreSignalStation::GetInstance(),
+ &CoreSignalStation::SignalUserInputPassphraseDone);
// directly connect to SignalKeyStatusUpdated
// to avoid the delay of signal emitting
@@ -166,6 +167,10 @@ CommonUtils::CommonUtils() : QWidget(nullptr) {
&SignalStation::SignalKeyDatabaseRefresh, this,
&CommonUtils::slot_update_key_status);
+ connect(CoreSignalStation::GetInstance(),
+ &CoreSignalStation::SignalNeedUserInputPassphrase, this,
+ &CommonUtils::slot_popup_passphrase_input_dialog);
+
connect(this, &CommonUtils::SignalGnupgNotInstall, this, []() {
QMessageBox::critical(
nullptr, _("ENV Loading Failed"),
@@ -213,6 +218,38 @@ void CommonUtils::SlotImportKeyFromClipboard(QWidget *parent) {
cb->text(QClipboard::Clipboard).toUtf8().toStdString());
}
+void CommonUtils::SlotExecuteCommand(
+ const std::string &cmd, const QStringList &arguments,
+ const std::function<void(QProcess *)> &interact_func) {
+ QEventLoop looper;
+ auto *cmd_process = new QProcess(&looper);
+ cmd_process->setProcessChannelMode(QProcess::MergedChannels);
+
+ connect(cmd_process,
+ qOverload<int, QProcess::ExitStatus>(&QProcess::finished), &looper,
+ &QEventLoop::quit);
+ connect(cmd_process, &QProcess::errorOccurred, &looper, &QEventLoop::quit);
+ connect(cmd_process, &QProcess::started,
+ []() -> void { SPDLOG_DEBUG("process started"); });
+ connect(cmd_process, &QProcess::readyReadStandardOutput,
+ [interact_func, cmd_process]() { interact_func(cmd_process); });
+ connect(cmd_process, &QProcess::errorOccurred, this,
+ [=]() -> void { SPDLOG_ERROR("error in process"); });
+ connect(cmd_process,
+ qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this,
+ [=](int, QProcess::ExitStatus status) {
+ if (status == QProcess::NormalExit)
+ SPDLOG_DEBUG("succeed in executing command: {}", cmd);
+ else
+ SPDLOG_WARN("error in executing command: {}", cmd);
+ });
+
+ cmd_process->setProgram(QString::fromStdString(cmd));
+ cmd_process->setArguments(arguments);
+ cmd_process->start();
+ looper.exec();
+}
+
void CommonUtils::SlotExecuteGpgCommand(
const QStringList &arguments,
const std::function<void(QProcess *)> &interact_func) {
@@ -230,11 +267,11 @@ void CommonUtils::SlotExecuteGpgCommand(
&WaitingDialog::deleteLater);
connect(gpg_process, &QProcess::errorOccurred, &looper, &QEventLoop::quit);
connect(gpg_process, &QProcess::started,
- []() -> void { LOG(ERROR) << "Gpg Process Started Success"; });
+ []() -> void { SPDLOG_DEBUG("gpg process started"); });
connect(gpg_process, &QProcess::readyReadStandardOutput,
[interact_func, gpg_process]() { interact_func(gpg_process); });
connect(gpg_process, &QProcess::errorOccurred, this, [=]() -> void {
- LOG(ERROR) << "Error in Process";
+ SPDLOG_ERROR("Error in Process");
dialog->close();
QMessageBox::critical(nullptr, _("Failure"),
_("Failed to execute command."));
@@ -251,7 +288,8 @@ void CommonUtils::SlotExecuteGpgCommand(
_("Finished executing command."));
});
- gpg_process->setProgram(GpgContext::GetInstance().GetInfo().AppPath.c_str());
+ gpg_process->setProgram(
+ GpgContext::GetInstance().GetInfo(false).AppPath.c_str());
gpg_process->setArguments(arguments);
gpg_process->start();
looper.exec();
@@ -283,10 +321,10 @@ void CommonUtils::SlotImportKeyFromKeyServer(
target_keyserver =
key_server_list[target_key_server_index].get<std::string>();
- LOG(INFO) << _("Set target Key Server to default Key Server")
- << target_keyserver;
+ SPDLOG_DEBUG("set target key server to default Key Server: {}",
+ target_keyserver);
} catch (...) {
- LOG(ERROR) << _("Cannot read default_keyserver From Settings");
+ SPDLOG_ERROR(_("Cannot read default_keyserver From Settings"));
QMessageBox::critical(
nullptr, _("Default Keyserver Not Found"),
_("Cannot read default keyserver from your settings, "
@@ -307,7 +345,7 @@ void CommonUtils::SlotImportKeyFromKeyServer(
target_keyserver_url.scheme() + "://" + target_keyserver_url.host() +
"/pks/lookup?op=get&search=0x" + key_id.c_str() + "&options=mr");
- LOG(INFO) << "request url" << req_url.toString().toStdString();
+ SPDLOG_DEBUG("request url: {}", req_url.toString().toStdString());
// Waiting for reply
QNetworkReply *reply = network_manager->get(QNetworkRequest(req_url));
@@ -360,21 +398,39 @@ void CommonUtils::SlotImportKeyFromKeyServer(
}
void CommonUtils::slot_update_key_status() {
- LOG(INFO) << "called";
-
- auto refresh_task = new Thread::Task([](Thread::Task::DataObjectPtr) -> int {
- // flush key cache for all GpgKeyGetter Intances.
- for (const auto &channel_id : GpgKeyGetter::GetAllChannelId()) {
- GpgKeyGetter::GetInstance(channel_id).FlushKeyCache();
- }
- return 0;
- });
- connect(refresh_task, &Thread::Task::SignalTaskFinished, this,
- &CommonUtils::SignalKeyDatabaseRefreshDone);
+ auto refresh_task = new Thread::Task(
+ [](Thread::Task::DataObjectPtr) -> int {
+ // flush key cache for all GpgKeyGetter Intances.
+ for (const auto &channel_id : GpgKeyGetter::GetAllChannelId()) {
+ GpgKeyGetter::GetInstance(channel_id).FlushKeyCache();
+ }
+ return 0;
+ },
+ "update_key_database_task");
+ connect(refresh_task, &Thread::Task::SignalTaskEnd, this,
+ &CommonUtils::SignalKeyDatabaseRefreshDone,
+ Qt::BlockingQueuedConnection);
// post the task to the default task runner
Thread::TaskRunnerGetter::GetInstance().GetTaskRunner()->PostTask(
refresh_task);
}
+void CommonUtils::slot_popup_passphrase_input_dialog() {
+ auto *dialog = new QInputDialog(QApplication::activeWindow(), Qt::Dialog);
+ dialog->setModal(true);
+ dialog->setWindowTitle(_("Password Input Dialog"));
+ dialog->setInputMode(QInputDialog::TextInput);
+ dialog->setTextEchoMode(QLineEdit::Password);
+ dialog->setLabelText(_("Please Input The Password"));
+ dialog->resize(500, 80);
+ dialog->exec();
+
+ QString password = dialog->textValue();
+ dialog->deleteLater();
+
+ // send signal
+ emit SignalUserInputPassphraseDone(password);
+}
+
} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/UserInterfaceUtils.h b/src/ui/UserInterfaceUtils.h
index bcfa28d2..7761de7b 100644
--- a/src/ui/UserInterfaceUtils.h
+++ b/src/ui/UserInterfaceUtils.h
@@ -163,6 +163,18 @@ class CommonUtils : public QWidget {
*/
void SignalKeyDatabaseRefreshDone();
+ /**
+ * @brief
+ *
+ */
+ void SignalNeedUserInputPassphrase();
+
+ /**
+ * @brief
+ *
+ */
+ void SignalUserInputPassphraseDone(QString passphrase);
+
public slots:
/**
* @brief
@@ -214,6 +226,15 @@ class CommonUtils : public QWidget {
const QStringList& arguments,
const std::function<void(QProcess*)>& interact_func);
+ /**
+ * @brief
+ *
+ * @param arguments
+ * @param interact_func
+ */
+ void SlotExecuteCommand(const std::string& cmd, const QStringList& arguments,
+ const std::function<void(QProcess*)>& interact_func);
+
private slots:
/**
@@ -222,6 +243,12 @@ class CommonUtils : public QWidget {
*/
void slot_update_key_status();
+ /**
+ * @brief
+ *
+ */
+ void slot_popup_passphrase_input_dialog();
+
private:
static std::unique_ptr<CommonUtils> instance_; ///<
};
diff --git a/src/ui/dialog/GeneralDialog.cpp b/src/ui/dialog/GeneralDialog.cpp
index 6fd2f32c..9367aa44 100644
--- a/src/ui/dialog/GeneralDialog.cpp
+++ b/src/ui/dialog/GeneralDialog.cpp
@@ -39,8 +39,6 @@ GpgFrontend::UI::GeneralDialog::~GeneralDialog() = default;
void GpgFrontend::UI::GeneralDialog::slot_restore_settings() noexcept {
try {
- LOG(INFO) << name_ << _("Called");
-
SettingsObject general_windows_state(name_ + "_dialog_state");
bool window_save = general_windows_state.Check("window_save", true);
@@ -60,8 +58,6 @@ void GpgFrontend::UI::GeneralDialog::slot_restore_settings() noexcept {
size_ = {width, height};
if (this->parent() != nullptr) {
- LOG(INFO) << "parent address" << this->parent();
-
QPoint parent_pos = {0, 0};
QSize parent_size = {0, 0};
@@ -83,14 +79,13 @@ void GpgFrontend::UI::GeneralDialog::slot_restore_settings() noexcept {
parent_size = parent_window->size();
}
- LOG(INFO) << "parent pos x:" << parent_pos.x()
- << "y:" << parent_pos.y();
+ SPDLOG_DEBUG("parent pos x: {} y: {}", parent_pos.x(), parent_pos.y());
- LOG(INFO) << "parent size width:" << parent_size.width()
- << "height:" << parent_size.height();
+ SPDLOG_DEBUG("parent size width: {} height: {}", parent_size.width(),
+ parent_size.height());
- LOG(INFO) << "this dialog size width:" << size_.width()
- << "height:" << size_.height();
+ SPDLOG_DEBUG("this dialog size width: {} height: {}", size_.width(),
+ size_.height());
if (parent_pos != QPoint{0, 0}) {
QPoint parent_center{parent_pos.x() + parent_size.width() / 2,
@@ -110,14 +105,12 @@ void GpgFrontend::UI::GeneralDialog::slot_restore_settings() noexcept {
}
} catch (...) {
- LOG(ERROR) << name_ << "error";
+ SPDLOG_ERROR(name_, "error");
}
}
void GpgFrontend::UI::GeneralDialog::slot_save_settings() noexcept {
try {
- LOG(INFO) << name_ << _("Called");
-
SettingsObject general_windows_state(name_ + "_dialog_state");
// window position and size
@@ -132,7 +125,7 @@ void GpgFrontend::UI::GeneralDialog::slot_save_settings() noexcept {
general_windows_state["window_save"] = true;
} catch (...) {
- LOG(ERROR) << name_ << "error";
+ SPDLOG_ERROR(name_, "error");
}
}
@@ -142,8 +135,8 @@ void GpgFrontend::UI::GeneralDialog::setPosCenterOfScreen() {
int screen_width = geo.width();
int screen_height = geo.height();
- LOG(INFO) << "primary screen available geometry" << screen_width
- << screen_height;
+ SPDLOG_DEBUG("primary screen available geometry", screen_width,
+ screen_height);
pos_ = QPoint((screen_width - QWidget::width()) / 2,
(screen_height - QWidget::height()) / 2);
@@ -155,13 +148,13 @@ void GpgFrontend::UI::GeneralDialog::setPosCenterOfScreen() {
*
*/
void GpgFrontend::UI::GeneralDialog::movePosition2CenterOfParent() {
- LOG(INFO) << "parent pos x:" << parent_pos_.x() << "y:" << parent_pos_.y();
+ SPDLOG_DEBUG("parent pos x: {} y: {}", parent_pos_.x(), parent_pos_.y());
- LOG(INFO) << "parent size width:" << parent_size_.width()
- << "height:" << parent_size_.height();
+ SPDLOG_DEBUG("parent size width: {}", parent_size_.width(),
+ "height:", parent_size_.height());
if (parent_pos_ != QPoint{0, 0} && parent_size_ != QSize{0, 0}) {
- LOG(INFO) << "update current dialog position now";
+ SPDLOG_DEBUG("update current dialog position now");
QPoint parent_center{parent_pos_.x() + parent_size_.width() / 2,
parent_pos_.y() + parent_size_.height() / 2};
diff --git a/src/ui/dialog/WaitingDialog.cpp b/src/ui/dialog/WaitingDialog.cpp
index a4412e57..afdd55b8 100644
--- a/src/ui/dialog/WaitingDialog.cpp
+++ b/src/ui/dialog/WaitingDialog.cpp
@@ -57,8 +57,8 @@ WaitingDialog::WaitingDialog(const QString& title, QWidget* parent)
int screen_width = geo.width();
int screen_height = geo.height();
- LOG(INFO) << "primary screen available geometry" << screen_width
- << screen_height;
+ SPDLOG_DEBUG("primary screen available geometry: {} {}", screen_width,
+ screen_height);
auto pos = QPoint((screen_width - QWidget::width()) / 2,
(screen_height - QWidget::height()) / 2);
@@ -67,7 +67,7 @@ WaitingDialog::WaitingDialog(const QString& title, QWidget* parent)
} else {
auto pos = QPoint(parent->x() + (parent->width() - QWidget::width()) / 2,
parent->y() + (parent->height() - QWidget::height()) / 2);
- LOG(INFO) << "pos" << pos.x() << pos.y();
+ SPDLOG_DEBUG("pos: {} {}", pos.x(), pos.y());
this->move(pos);
}
diff --git a/src/ui/dialog/Wizard.cpp b/src/ui/dialog/Wizard.cpp
index 0f051874..57aefcfb 100644
--- a/src/ui/dialog/Wizard.cpp
+++ b/src/ui/dialog/Wizard.cpp
@@ -52,7 +52,7 @@ Wizard::Wizard(QWidget* parent) : QWizard(parent) {
try {
next_page_id = settings.lookup("wizard.next_page");
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error");
+ SPDLOG_ERROR("setting operation error");
}
setStartId(next_page_id);
@@ -60,7 +60,6 @@ Wizard::Wizard(QWidget* parent) : QWizard(parent) {
}
void Wizard::slot_wizard_accepted() {
- LOG(INFO) << _("Called");
// Don't show is mapped to show -> negation
try {
auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
@@ -75,7 +74,7 @@ void Wizard::slot_wizard_accepted() {
}
GlobalSettingStation::GetInstance().SyncSettings();
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error");
+ SPDLOG_ERROR("setting operation error");
}
if (field("openHelp").toBool()) {
emit SignalOpenHelp("docu.html#content");
@@ -223,7 +222,6 @@ KeyGenPage::KeyGenPage(QWidget* parent) : QWizardPage(parent) {
int KeyGenPage::nextId() const { return Wizard::Page_Conclusion; }
void KeyGenPage::slot_generate_key_dialog() {
- LOG(INFO) << "Try Opening KeyGenDialog";
(new KeyGenDialog(this))->show();
wizard()->next();
}
diff --git a/src/ui/dialog/details/VerifyDetailsDialog.cpp b/src/ui/dialog/details/VerifyDetailsDialog.cpp
index d2af4ee1..307d404a 100644
--- a/src/ui/dialog/details/VerifyDetailsDialog.cpp
+++ b/src/ui/dialog/details/VerifyDetailsDialog.cpp
@@ -65,7 +65,11 @@ void VerifyDetailsDialog::slot_refresh() {
// Get timestamp of signature of current text
QDateTime timestamp;
+#ifdef GPGFRONTEND_GUI_QT6
+ timestamp.setSecsSinceEpoch(sign->timestamp);
+#else
timestamp.setTime_t(sign->timestamp);
+#endif
// Set the title widget depending on sign status
if (gpg_err_code(sign->status) == GPG_ERR_BAD_SIGNATURE) {
diff --git a/src/ui/dialog/help/AboutDialog.cpp b/src/ui/dialog/help/AboutDialog.cpp
index 6b6e4356..3cf6c2a2 100644
--- a/src/ui/dialog/help/AboutDialog.cpp
+++ b/src/ui/dialog/help/AboutDialog.cpp
@@ -52,7 +52,7 @@ AboutDialog::AboutDialog(int defaultIndex, QWidget* parent)
tab_widget->addTab(update_tab_, _("Update"));
connect(tab_widget, &QTabWidget::currentChanged, this,
- [&](int index) { LOG(INFO) << "Current Index" << index; });
+ [&](int index) { SPDLOG_DEBUG("current index: {}", index); });
if (defaultIndex < tab_widget->count() && defaultIndex >= 0) {
tab_widget->setCurrentIndex(defaultIndex);
@@ -66,7 +66,7 @@ AboutDialog::AboutDialog(int defaultIndex, QWidget* parent)
mainLayout->addWidget(buttonBox);
setLayout(mainLayout);
- this->resize(450, 580);
+ this->resize(550, 650);
this->setMinimumWidth(450);
this->show();
}
@@ -95,7 +95,9 @@ InfoTab::InfoTab(QWidget* parent) : QWidget(parent) {
_("or send a mail to my mailing list at") + " <a " +
"href=\"mailto:[email protected]\">[email protected]</a>." + "<br><br> " +
_("Built with Qt") + " " + qVersion() + " " + _("and GPGME") + " " +
- GpgFrontend::GpgContext::GetInstance().GetInfo().GpgMEVersion.c_str() +
+ GpgFrontend::GpgContext::GetInstance()
+ .GetInfo(false)
+ .GpgMEVersion.c_str() +
"<br>" + _("Built at") + " " + BUILD_TIMESTAMP + "</center>");
auto* layout = new QGridLayout();
@@ -201,7 +203,7 @@ UpdateTab::UpdateTab(QWidget* parent) : QWidget(parent) {
void UpdateTab::getLatestVersion() {
this->pb_->setHidden(false);
- LOG(INFO) << _("try to get latest version");
+ SPDLOG_DEBUG("try to get latest version");
auto* version_task = new VersionCheckTask();
diff --git a/src/ui/dialog/help/GnupgTab.cpp b/src/ui/dialog/help/GnupgTab.cpp
index 9d783367..2758cbe1 100644
--- a/src/ui/dialog/help/GnupgTab.cpp
+++ b/src/ui/dialog/help/GnupgTab.cpp
@@ -31,103 +31,104 @@
#include "GnupgTab.h"
-#include "easylogging++.h"
+#include <shared_mutex>
+
+#include "ui/UserInterfaceUtils.h"
#include "ui_GnuPGInfo.h"
GpgFrontend::UI::GnupgTab::GnupgTab(QWidget* parent)
- : QWidget(parent),
- ui_(std::make_shared<Ui_GnuPGInfo>()),
- gpgconf_process_(new QProcess(this)) {
- GpgContext& ctx = GpgContext::GetInstance();
- auto info = ctx.GetInfo();
-
+ : QWidget(parent), ui_(std::make_shared<Ui_GnuPGInfo>()) {
ui_->setupUi(this);
- QStringList column_titles;
- column_titles << _("Name") << _("Description") << _("Version") << _("Path");
+ QStringList components_column_titles;
+ components_column_titles << _("Name") << _("Description") << _("Version")
+ << _("Checksum") << _("Path");
+
+ ui_->componentDetailsTable->setColumnCount(components_column_titles.length());
+ ui_->componentDetailsTable->setHorizontalHeaderLabels(
+ components_column_titles);
+ ui_->componentDetailsTable->horizontalHeader()->setStretchLastSection(false);
+ ui_->componentDetailsTable->setSelectionBehavior(
+ QAbstractItemView::SelectRows);
+
+ QStringList configurations_column_titles;
+ configurations_column_titles << _("Name") << _("Path");
- ui_->conponentDetailsTable->setColumnCount(column_titles.length());
- ui_->conponentDetailsTable->setHorizontalHeaderLabels(column_titles);
- ui_->conponentDetailsTable->horizontalHeader()->setStretchLastSection(false);
- ui_->conponentDetailsTable->setSelectionBehavior(
+ ui_->configurationDetailsTable->setColumnCount(
+ configurations_column_titles.length());
+ ui_->configurationDetailsTable->setHorizontalHeaderLabels(
+ configurations_column_titles);
+ ui_->configurationDetailsTable->horizontalHeader()->setStretchLastSection(
+ false);
+ ui_->configurationDetailsTable->setSelectionBehavior(
QAbstractItemView::SelectRows);
// tableitems not editable
- ui_->conponentDetailsTable->setEditTriggers(
+ ui_->componentDetailsTable->setEditTriggers(
QAbstractItemView::NoEditTriggers);
// no focus (rectangle around tableitems)
// may be it should focus on whole row
- ui_->conponentDetailsTable->setFocusPolicy(Qt::NoFocus);
- ui_->conponentDetailsTable->setAlternatingRowColors(true);
+ ui_->componentDetailsTable->setFocusPolicy(Qt::NoFocus);
+ ui_->componentDetailsTable->setAlternatingRowColors(true);
- gpgconf_process_->start(QString::fromStdString(info.GpgConfPath),
- QStringList() << "--list-components");
-
- connect(gpgconf_process_,
- qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this,
- &GnupgTab::process_components_info);
+ process_software_info();
}
-void GpgFrontend::UI::GnupgTab::process_components_info(
- int exit_code, QProcess::ExitStatus exit_status) {
- LOG(INFO) << "called";
+void GpgFrontend::UI::GnupgTab::process_software_info() {
+ auto& ctx_info = GpgContext::GetInstance().GetInfo();
+
+ ui_->gnupgVersionLabel->setText(QString::fromStdString(
+ fmt::format("Version: {}", ctx_info.GnupgVersion)));
- GpgContext& ctx = GpgContext::GetInstance();
- auto info = ctx.GetInfo();
+ ui_->componentDetailsTable->setRowCount(ctx_info.ComponentsInfo.size());
- std::vector<std::vector<std::string>> components_info = {
- {"gpgme", "GPG Made Easy", info.GpgMEVersion, "/"},
- {"gpgconf", "GPG Configure", "/", info.GpgConfPath},
+ int row = 0;
+ for (const auto& info : ctx_info.ComponentsInfo) {
+ if (info.second.size() != 4) continue;
- };
+ auto* tmp0 = new QTableWidgetItem(QString::fromStdString(info.first));
+ tmp0->setTextAlignment(Qt::AlignCenter);
+ ui_->componentDetailsTable->setItem(row, 0, tmp0);
- if (gpgconf_process_ != nullptr) {
- QString data = gpgconf_process_->readAllStandardOutput();
+ auto* tmp1 = new QTableWidgetItem(QString::fromStdString(info.second[0]));
+ tmp1->setTextAlignment(Qt::AlignCenter);
+ ui_->componentDetailsTable->setItem(row, 1, tmp1);
- std::vector<std::string> line_split_list;
- boost::split(line_split_list, data.toStdString(), boost::is_any_of("\n"));
+ auto* tmp2 = new QTableWidgetItem(QString::fromStdString(info.second[1]));
+ tmp2->setTextAlignment(Qt::AlignCenter);
+ ui_->componentDetailsTable->setItem(row, 2, tmp2);
- for (const auto& line : line_split_list) {
- std::vector<std::string> info_split_list;
- boost::split(info_split_list, line, boost::is_any_of(":"));
- LOG(INFO) << "gpgconf info line" << line << "info size"
- << info_split_list.size();
+ auto* tmp3 = new QTableWidgetItem(QString::fromStdString(info.second[3]));
+ tmp3->setTextAlignment(Qt::AlignCenter);
+ ui_->componentDetailsTable->setItem(row, 3, tmp3);
- if (info_split_list.size() != 3) continue;
+ auto* tmp4 = new QTableWidgetItem(QString::fromStdString(info.second[2]));
+ tmp4->setTextAlignment(Qt::AlignLeft);
+ ui_->componentDetailsTable->setItem(row, 4, tmp4);
- if (info_split_list[0] == "gpg") {
- components_info.push_back({info_split_list[0], info_split_list[1],
- info.GnupgVersion, info_split_list[2]});
- } else {
- components_info.push_back(
- {info_split_list[0], info_split_list[1], "/", info_split_list[2]});
- }
- }
+ row++;
}
- ui_->conponentDetailsTable->setRowCount(components_info.size());
+ ui_->componentDetailsTable->resizeColumnsToContents();
- int row = 0;
- for (const auto& info : components_info) {
- if (info.size() != 4) continue;
+ ui_->configurationDetailsTable->setRowCount(
+ ctx_info.ConfigurationsInfo.size());
+
+ row = 0;
+ for (const auto& info : ctx_info.ConfigurationsInfo) {
+ if (info.second.size() != 1) continue;
- auto* tmp0 = new QTableWidgetItem(QString::fromStdString(info[0]));
+ auto* tmp0 = new QTableWidgetItem(QString::fromStdString(info.first));
tmp0->setTextAlignment(Qt::AlignCenter);
- ui_->conponentDetailsTable->setItem(row, 0, tmp0);
+ ui_->configurationDetailsTable->setItem(row, 0, tmp0);
- auto* tmp1 = new QTableWidgetItem(QString::fromStdString(info[1]));
+ auto* tmp1 = new QTableWidgetItem(QString::fromStdString(info.second[0]));
tmp1->setTextAlignment(Qt::AlignCenter);
- ui_->conponentDetailsTable->setItem(row, 1, tmp1);
-
- auto* tmp2 = new QTableWidgetItem(QString::fromStdString(info[2]));
- tmp2->setTextAlignment(Qt::AlignCenter);
- ui_->conponentDetailsTable->setItem(row, 2, tmp2);
-
- auto* tmp3 = new QTableWidgetItem(QString::fromStdString(info[3]));
- tmp3->setTextAlignment(Qt::AlignLeft);
- ui_->conponentDetailsTable->setItem(row, 3, tmp3);
+ ui_->configurationDetailsTable->setItem(row, 1, tmp1);
row++;
}
+
+ ui_->configurationDetailsTable->resizeColumnsToContents();
}
diff --git a/src/ui/dialog/help/GnupgTab.h b/src/ui/dialog/help/GnupgTab.h
index c143bae3..9195dee0 100644
--- a/src/ui/dialog/help/GnupgTab.h
+++ b/src/ui/dialog/help/GnupgTab.h
@@ -48,11 +48,9 @@ class GnupgTab : public QWidget {
explicit GnupgTab(QWidget* parent = nullptr);
private:
- std::shared_ptr<Ui_GnuPGInfo> ui_;
- QProcess* gpgconf_process_;
+ std::shared_ptr<Ui_GnuPGInfo> ui_; ///<
- private slots:
- void process_components_info(int, QProcess::ExitStatus);
+ void process_software_info();
};
} // namespace GpgFrontend::UI
diff --git a/src/ui/dialog/import_export/KeyImportDetailDialog.cpp b/src/ui/dialog/import_export/KeyImportDetailDialog.cpp
index 31183a34..e9b1af93 100644
--- a/src/ui/dialog/import_export/KeyImportDetailDialog.cpp
+++ b/src/ui/dialog/import_export/KeyImportDetailDialog.cpp
@@ -129,8 +129,6 @@ void KeyImportDetailDialog::create_general_info_box() {
}
void KeyImportDetailDialog::create_keys_table() {
- LOG(INFO) << "KeyImportDetailDialog::create_keys_table() Called";
-
keys_table_ = new QTableWidget(this);
keys_table_->setRowCount(0);
keys_table_->setColumnCount(4);
diff --git a/src/ui/dialog/import_export/KeyServerImportDialog.cpp b/src/ui/dialog/import_export/KeyServerImportDialog.cpp
index 6430a22e..713c5a58 100644
--- a/src/ui/dialog/import_export/KeyServerImportDialog.cpp
+++ b/src/ui/dialog/import_export/KeyServerImportDialog.cpp
@@ -28,6 +28,7 @@
#include "KeyServerImportDialog.h"
+#include <QRegExp>
#include <string>
#include <utility>
@@ -177,8 +178,7 @@ QComboBox* KeyServerImportDialog::create_comboBox() {
comboBox->setCurrentText(default_key_server.c_str());
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error") << "server_list"
- << "default_server";
+ SPDLOG_ERROR("setting operation error", "server_list", "default_server");
}
return comboBox;
@@ -253,8 +253,7 @@ void KeyServerImportDialog::slot_search() {
void KeyServerImportDialog::slot_search_finished(
QNetworkReply::NetworkError error, QByteArray buffer) {
- LOG(INFO) << "Called" << error << buffer.size();
- LOG(INFO) << buffer.toStdString();
+ SPDLOG_DEBUG("search result {} {}", error, buffer.size());
keys_table_->clearContents();
keys_table_->setRowCount(0);
@@ -262,7 +261,7 @@ void KeyServerImportDialog::slot_search_finished(
auto stream = QTextStream(buffer);
if (error != QNetworkReply::NoError) {
- LOG(INFO) << "Error From Reply" << error;
+ SPDLOG_DEBUG("error from reply: {}", error);
switch (error) {
case QNetworkReply::ContentNotFoundError:
@@ -364,8 +363,14 @@ void KeyServerImportDialog::slot_search_finished(
uid->setText(line2[1]);
keys_table_->setItem(row, 0, uid);
}
+#ifdef GPGFRONTEND_GUI_QT6
+ auto* creation_date =
+ new QTableWidgetItem(QDateTime::fromSecsSinceEpoch(line[4].toInt())
+ .toString("dd. MMM. yyyy"));
+#else
auto* creation_date = new QTableWidgetItem(
QDateTime::fromTime_t(line[4].toInt()).toString("dd. MMM. yyyy"));
+#endif
keys_table_->setItem(row, 1, creation_date);
auto* keyid = new QTableWidgetItem(line[1]);
keys_table_->setItem(row, 2, keyid);
@@ -440,8 +445,7 @@ void KeyServerImportDialog::SlotImport(const KeyIdArgsListPtr& keys) {
target_keyserver = default_key_server;
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error") << "server_list"
- << "default_server";
+ SPDLOG_ERROR("setting operation error", "server_list", "default_server");
QMessageBox::critical(
nullptr, _("Default Keyserver Not Found"),
_("Cannot read default keyserver from your settings, "
@@ -470,10 +474,8 @@ void KeyServerImportDialog::SlotImport(std::vector<std::string> key_ids,
void KeyServerImportDialog::slot_import_finished(
QNetworkReply::NetworkError error, QByteArray buffer) {
- LOG(INFO) << _("Called");
-
if (error != QNetworkReply::NoError) {
- LOG(ERROR) << "Error From Reply" << buffer.toStdString();
+ SPDLOG_ERROR("Error From Reply", buffer.toStdString());
if (!m_automatic_) {
switch (error) {
case QNetworkReply::ContentNotFoundError:
diff --git a/src/ui/dialog/import_export/KeyUploadDialog.cpp b/src/ui/dialog/import_export/KeyUploadDialog.cpp
index ad4be0cb..5e05da2d 100644
--- a/src/ui/dialog/import_export/KeyUploadDialog.cpp
+++ b/src/ui/dialog/import_export/KeyUploadDialog.cpp
@@ -41,7 +41,6 @@ KeyUploadDialog::KeyUploadDialog(const KeyIdArgsListPtr& keys_ids,
QWidget* parent)
: GeneralDialog(typeid(KeyUploadDialog).name(), parent),
m_keys_(GpgKeyGetter::GetInstance().GetKeys(keys_ids)) {
-
auto* pb = new QProgressBar();
pb->setRange(0, 0);
pb->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
@@ -71,7 +70,6 @@ void KeyUploadDialog::SlotUpload() {
void KeyUploadDialog::slot_upload_key_to_server(
const GpgFrontend::ByteArray& keys_data) {
-
std::string target_keyserver;
try {
@@ -88,11 +86,11 @@ void KeyUploadDialog::slot_upload_key_to_server(
target_keyserver =
key_server_list[default_key_server_index].get<std::string>();
- LOG(INFO) << _("Set target Key Server to default Key Server")
- << target_keyserver;
+ SPDLOG_DEBUG("set target key server to default key server: {}",
+ target_keyserver);
} catch (...) {
- LOG(ERROR) << _("Cannot read default_keyserver From Settings");
+ SPDLOG_ERROR(_("Cannot read default_keyserver From Settings"));
QMessageBox::critical(nullptr, _("Default Keyserver Not Found"),
_("Cannot read default keyserver from your settings, "
"please set a default keyserver first"));
@@ -139,11 +137,11 @@ void KeyUploadDialog::slot_upload_finished() {
auto* reply = qobject_cast<QNetworkReply*>(sender());
QByteArray response = reply->readAll();
- LOG(INFO) << "Response: " << response.toStdString();
+ SPDLOG_DEBUG("response: {}", response.toStdString());
auto error = reply->error();
if (error != QNetworkReply::NoError) {
- LOG(INFO) << "Error From Reply" << reply->errorString().toStdString();
+ SPDLOG_DEBUG("error from reply: {}", reply->errorString().toStdString());
QString message;
switch (error) {
case QNetworkReply::ContentNotFoundError:
@@ -163,7 +161,7 @@ void KeyUploadDialog::slot_upload_finished() {
} else {
QMessageBox::information(this, _("Upload Success"),
_("Upload Public Key Successfully"));
- LOG(INFO) << "Success while contacting keyserver!";
+ SPDLOG_DEBUG("success while contacting keyserver!");
}
reply->deleteLater();
}
diff --git a/src/ui/dialog/key_generate/KeygenDialog.cpp b/src/ui/dialog/key_generate/KeygenDialog.cpp
index b7ba6369..d6f61215 100644
--- a/src/ui/dialog/key_generate/KeygenDialog.cpp
+++ b/src/ui/dialog/key_generate/KeygenDialog.cpp
@@ -28,6 +28,7 @@
#include "KeygenDialog.h"
+#include "core/common/CoreCommonUtil.h"
#include "core/function/GlobalSettingStation.h"
#include "core/function/gpg/GpgKeyOpera.h"
#include "dialog/WaitingDialog.h"
@@ -46,10 +47,10 @@ KeyGenDialog::KeyGenDialog(QWidget* parent)
bool longer_expiration_date = false;
try {
longer_expiration_date = settings.lookup("general.longer_expiration_date");
- LOG(INFO) << "longer_expiration_date" << longer_expiration_date;
+ SPDLOG_DEBUG("longer_expiration_date: {}", longer_expiration_date);
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error") << _("longer_expiration_date");
+ SPDLOG_ERROR("setting operation error: longer_expiration_date");
}
max_date_time_ = longer_expiration_date
@@ -110,6 +111,10 @@ void KeyGenDialog::slot_key_gen_accept() {
error_stream << " " << _("Expiration time too long.") << std::endl;
}
+ if (passphrase_edit_->isEnabled() && passphrase_edit_->text().size() == 0) {
+ error_stream << " " << _("Password is empty.") << std::endl;
+ }
+
auto err_string = error_stream.str();
if (err_string.empty()) {
@@ -125,8 +130,18 @@ void KeyGenDialog::slot_key_gen_accept() {
if (expire_check_box_->checkState()) {
gen_key_info_->SetNonExpired(true);
} else {
+#ifdef GPGFRONTEND_GUI_QT6
+ gen_key_info_->SetExpireTime(boost::posix_time::from_time_t(
+ date_edit_->dateTime().toSecsSinceEpoch()));
+#else
gen_key_info_->SetExpireTime(
boost::posix_time::from_time_t(date_edit_->dateTime().toTime_t()));
+#endif
+ }
+
+ if (!gen_key_info_->IsNoPassPhrase()) {
+ CoreCommonUtil::GetInstance()->SetTempCacheValue(
+ "__key_passphrase", this->passphrase_edit_->text().toStdString());
}
GpgGenKeyResult result;
@@ -145,7 +160,11 @@ void KeyGenDialog::slot_key_gen_accept() {
dialog->close();
- LOG(INFO) << "generate done";
+ if (!gen_key_info_->IsNoPassPhrase()) {
+ CoreCommonUtil::GetInstance()->ResetTempCacheValue("__key_passphrase");
+ }
+
+ SPDLOG_DEBUG("generate done");
if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) {
auto* msg_box = new QMessageBox((QWidget*)this->parent());
@@ -156,7 +175,7 @@ void KeyGenDialog::slot_key_gen_accept() {
msg_box->setModal(true);
msg_box->open();
- LOG(INFO) << "generate success";
+ SPDLOG_DEBUG("generate success");
emit SignalKeyGenerated();
this->close();
@@ -252,7 +271,7 @@ void KeyGenDialog::slot_authentication_box_changed(int state) {
}
void KeyGenDialog::slot_activated_key_type(int index) {
- qDebug() << "key type index changed " << index;
+ SPDLOG_DEBUG("key type index changed: {}", index);
// check
assert(gen_key_info_->GetSupportedKeyAlgo().size() > index);
@@ -261,8 +280,6 @@ void KeyGenDialog::slot_activated_key_type(int index) {
}
void KeyGenDialog::refresh_widgets_state() {
- qDebug() << "refresh_widgets_state called";
-
if (gen_key_info_->IsAllowEncryption())
key_usage_check_boxes_[0]->setCheckState(Qt::CheckState::Checked);
else
@@ -337,11 +354,8 @@ void KeyGenDialog::set_signal_slot() {
connect(no_pass_phrase_check_box_, &QCheckBox::stateChanged, this,
[this](int state) -> void {
- if (state == 0) {
- gen_key_info_->SetNonPassPhrase(false);
- } else {
- gen_key_info_->SetNonPassPhrase(true);
- }
+ gen_key_info_->SetNonPassPhrase(state != 0);
+ passphrase_edit_->setDisabled(state != 0);
});
}
@@ -356,6 +370,7 @@ QGroupBox* KeyGenDialog::create_basic_info_group_box() {
comment_edit_ = new QLineEdit(this);
key_size_spin_box_ = new QSpinBox(this);
key_type_combo_box_ = new QComboBox(this);
+ passphrase_edit_ = new QLineEdit(this);
for (auto& algo : GenKeyInfo::GetSupportedKeyAlgo()) {
key_type_combo_box_->addItem(QString::fromStdString(algo.first));
@@ -375,6 +390,8 @@ QGroupBox* KeyGenDialog::create_basic_info_group_box() {
expire_check_box_ = new QCheckBox(this);
expire_check_box_->setCheckState(Qt::Unchecked);
+ passphrase_edit_->setEchoMode(QLineEdit::Password);
+
no_pass_phrase_check_box_ = new QCheckBox(this);
no_pass_phrase_check_box_->setCheckState(Qt::Unchecked);
@@ -387,7 +404,8 @@ QGroupBox* KeyGenDialog::create_basic_info_group_box() {
vbox1->addWidget(new QLabel(QString(_("Never Expire")) + ": "), 3, 3);
vbox1->addWidget(new QLabel(QString(_("KeySize (in Bit)")) + ": "), 4, 0);
vbox1->addWidget(new QLabel(QString(_("Key Type")) + ": "), 5, 0);
- vbox1->addWidget(new QLabel(QString(_("Non Pass Phrase")) + ": "), 6, 0);
+ vbox1->addWidget(new QLabel(QString(_("Password")) + ": "), 6, 0);
+ vbox1->addWidget(new QLabel(QString(_("Non Pass Phrase")) + ": "), 6, 3);
vbox1->addWidget(name_edit_, 0, 1, 1, 3);
vbox1->addWidget(email_edit_, 1, 1, 1, 3);
@@ -396,7 +414,8 @@ QGroupBox* KeyGenDialog::create_basic_info_group_box() {
vbox1->addWidget(expire_check_box_, 3, 2);
vbox1->addWidget(key_size_spin_box_, 4, 1);
vbox1->addWidget(key_type_combo_box_, 5, 1);
- vbox1->addWidget(no_pass_phrase_check_box_, 6, 1);
+ vbox1->addWidget(passphrase_edit_, 6, 1);
+ vbox1->addWidget(no_pass_phrase_check_box_, 6, 2);
auto basicInfoGroupBox = new QGroupBox();
basicInfoGroupBox->setLayout(vbox1);
diff --git a/src/ui/dialog/key_generate/KeygenDialog.h b/src/ui/dialog/key_generate/KeygenDialog.h
index baf10dbf..a1d7f39a 100644
--- a/src/ui/dialog/key_generate/KeygenDialog.h
+++ b/src/ui/dialog/key_generate/KeygenDialog.h
@@ -93,6 +93,7 @@ class KeyGenDialog : public GeneralDialog {
QLineEdit* name_edit_{}; ///< Line edit for the keys name
QLineEdit* email_edit_{}; ///< Line edit for the keys email
QLineEdit* comment_edit_{}; ///< Line edit for the keys comment
+ QLineEdit* passphrase_edit_{}; ///<
QSpinBox* key_size_spin_box_{}; ///< Spinbox for the keys size (in bit)
QComboBox* key_type_combo_box_{}; ///< Combobox for Key type
QDateTimeEdit* date_edit_{}; ///< Date edit for expiration date
diff --git a/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp b/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp
index afa768f0..50f38413 100644
--- a/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp
+++ b/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp
@@ -28,11 +28,12 @@
#include <cassert>
+#include "core/common/CoreCommonUtil.h"
#include "core/function/GlobalSettingStation.h"
#include "core/function/gpg/GpgKeyGetter.h"
#include "core/function/gpg/GpgKeyOpera.h"
-#include "dialog/WaitingDialog.h"
#include "ui/SignalStation.h"
+#include "ui/dialog/WaitingDialog.h"
namespace GpgFrontend::UI {
@@ -45,10 +46,10 @@ SubkeyGenerateDialog::SubkeyGenerateDialog(const KeyId& key_id, QWidget* parent)
bool longer_expiration_date = false;
try {
longer_expiration_date = settings.lookup("general.longer_expiration_date");
- LOG(INFO) << "longer_expiration_date" << longer_expiration_date;
+ SPDLOG_DEBUG("longer expiration date: {}", longer_expiration_date);
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error") << _("longer_expiration_date");
+ SPDLOG_ERROR("setting operation error: longer_expiration_date");
}
max_date_time_ = longer_expiration_date
@@ -60,15 +61,20 @@ SubkeyGenerateDialog::SubkeyGenerateDialog(const KeyId& key_id, QWidget* parent)
key_usage_group_box_ = create_key_usage_group_box();
- auto* groupGrid = new QGridLayout(this);
- groupGrid->addWidget(create_basic_info_group_box(), 0, 0);
- groupGrid->addWidget(key_usage_group_box_, 1, 0);
+ auto* group_grid = new QGridLayout(this);
+ group_grid->addWidget(create_basic_info_group_box(), 0, 0);
+ group_grid->addWidget(key_usage_group_box_, 1, 0);
- auto* nameList = new QWidget(this);
- nameList->setLayout(groupGrid);
+ auto* tipps_label = new QLabel(
+ QString(_("Tipps: if the key pair has a passphrase, the subkey's "
+ "passphrase must be equal to it.")));
+ group_grid->addWidget(tipps_label);
+
+ auto* name_list = new QWidget(this);
+ name_list->setLayout(group_grid);
auto* vbox2 = new QVBoxLayout();
- vbox2->addWidget(nameList);
+ vbox2->addWidget(name_list);
vbox2->addWidget(error_label_);
vbox2->addWidget(button_box_);
@@ -121,6 +127,8 @@ QGroupBox* SubkeyGenerateDialog::create_basic_info_group_box() {
error_label_ = new QLabel();
key_size_spin_box_ = new QSpinBox(this);
key_type_combo_box_ = new QComboBox(this);
+ no_pass_phrase_check_box_ = new QCheckBox(this);
+ passphrase_edit_ = new QLineEdit(this);
for (auto& algo : GenKeyInfo::GetSupportedSubkeyAlgo()) {
key_type_combo_box_->addItem(QString::fromStdString(algo.first));
@@ -142,15 +150,19 @@ QGroupBox* SubkeyGenerateDialog::create_basic_info_group_box() {
auto* vbox1 = new QGridLayout;
- vbox1->addWidget(new QLabel(QString(_("Expiration Date")) + ": "), 2, 0);
- vbox1->addWidget(new QLabel(QString(_("Never Expire")) + ": "), 2, 3);
- vbox1->addWidget(new QLabel(QString(_("KeySize (in Bit)")) + ": "), 1, 0);
vbox1->addWidget(new QLabel(QString(_("Key Type")) + ": "), 0, 0);
+ vbox1->addWidget(new QLabel(QString(_("KeySize (in Bit)")) + ": "), 1, 0);
+ vbox1->addWidget(new QLabel(QString(_("Expiration Date")) + ": "), 2, 0);
+ vbox1->addWidget(new QLabel(QString(_("Never Expire"))), 2, 3);
+ vbox1->addWidget(new QLabel(QString(_("Password")) + ": "), 3, 0);
+ vbox1->addWidget(new QLabel(QString(_("Non Pass Phrase"))), 3, 3);
+ vbox1->addWidget(key_type_combo_box_, 0, 1);
+ vbox1->addWidget(key_size_spin_box_, 1, 1);
vbox1->addWidget(date_edit_, 2, 1);
vbox1->addWidget(expire_check_box_, 2, 2);
- vbox1->addWidget(key_size_spin_box_, 1, 1);
- vbox1->addWidget(key_type_combo_box_, 0, 1);
+ vbox1->addWidget(passphrase_edit_, 3, 1);
+ vbox1->addWidget(no_pass_phrase_check_box_, 3, 2);
auto basicInfoGroupBox = new QGroupBox();
basicInfoGroupBox->setLayout(vbox1);
@@ -179,6 +191,12 @@ void SubkeyGenerateDialog::set_signal_slot() {
connect(key_type_combo_box_, qOverload<int>(&QComboBox::currentIndexChanged),
this, &SubkeyGenerateDialog::slot_activated_key_type);
+
+ connect(no_pass_phrase_check_box_, &QCheckBox::stateChanged, this,
+ [this](int state) -> void {
+ gen_key_info_->SetNonPassPhrase(state != 0);
+ passphrase_edit_->setDisabled(state != 0);
+ });
}
void SubkeyGenerateDialog::slot_expire_box_changed() {
@@ -190,8 +208,6 @@ void SubkeyGenerateDialog::slot_expire_box_changed() {
}
void SubkeyGenerateDialog::refresh_widgets_state() {
- LOG(INFO) << "refresh_widgets_state called";
-
if (gen_key_info_->IsAllowEncryption())
key_usage_check_boxes_[0]->setCheckState(Qt::CheckState::Checked);
else
@@ -249,6 +265,10 @@ void SubkeyGenerateDialog::slot_key_gen_accept() {
err_stream << " " << _("Expiration time no more than 2 years.") << " ";
}
+ if (passphrase_edit_->isEnabled() && passphrase_edit_->text().size() == 0) {
+ err_stream << " " << _("Password is empty.") << std::endl;
+ }
+
auto err_string = err_stream.str();
if (err_string.empty()) {
@@ -257,13 +277,24 @@ void SubkeyGenerateDialog::slot_key_gen_accept() {
if (expire_check_box_->checkState()) {
gen_key_info_->SetNonExpired(true);
} else {
+#ifdef GPGFRONTEND_GUI_QT6
+ gen_key_info_->SetExpireTime(boost::posix_time::from_time_t(
+ date_edit_->dateTime().toSecsSinceEpoch()));
+#else
gen_key_info_->SetExpireTime(
boost::posix_time::from_time_t(date_edit_->dateTime().toTime_t()));
+#endif
+ }
+
+ if (!gen_key_info_->IsNoPassPhrase()) {
+ CoreCommonUtil::GetInstance()->SetTempCacheValue(
+ "__key_passphrase", this->passphrase_edit_->text().toStdString());
}
GpgError error;
+ // TODO: remove plain qt thread usage
auto thread = QThread::create([&]() {
- LOG(INFO) << "Thread Started";
+ SPDLOG_DEBUG("thread started");
error = GpgKeyOpera::GetInstance().GenerateSubkey(key_, gen_key_info_);
});
thread->start();
@@ -276,6 +307,10 @@ void SubkeyGenerateDialog::slot_key_gen_accept() {
}
waiting_dialog->close();
+ if (!gen_key_info_->IsNoPassPhrase()) {
+ CoreCommonUtil::GetInstance()->ResetTempCacheValue("__key_passphrase");
+ }
+
if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR) {
auto* msg_box = new QMessageBox((QWidget*)this->parent());
msg_box->setAttribute(Qt::WA_DeleteOnClose);
@@ -338,7 +373,7 @@ void SubkeyGenerateDialog::slot_authentication_box_changed(int state) {
}
void SubkeyGenerateDialog::slot_activated_key_type(int index) {
- qDebug() << "key type index changed " << index;
+ SPDLOG_DEBUG("key type index changed: {}", index);
// check
assert(gen_key_info_->GetSupportedSubkeyAlgo().size() > index);
diff --git a/src/ui/dialog/key_generate/SubkeyGenerateDialog.h b/src/ui/dialog/key_generate/SubkeyGenerateDialog.h
index 1e6608b2..731bb951 100644
--- a/src/ui/dialog/key_generate/SubkeyGenerateDialog.h
+++ b/src/ui/dialog/key_generate/SubkeyGenerateDialog.h
@@ -69,6 +69,8 @@ class SubkeyGenerateDialog : public GeneralDialog {
QComboBox* key_type_combo_box_{}; ///< Combobox for Key tpe
QDateTimeEdit* date_edit_{}; ///< Date edit for expiration date
QCheckBox* expire_check_box_{}; ///< Checkbox, if key should expire
+ QCheckBox* no_pass_phrase_check_box_{}; ///< Checkbox, if key should expire
+ QLineEdit* passphrase_edit_{};
std::vector<QCheckBox*> key_usage_check_boxes_; ///< ENCR, SIGN, CERT, AUTH
QDateTime max_date_time_; ///<
diff --git a/src/ui/dialog/keypair_details/KeyPairDetailTab.cpp b/src/ui/dialog/keypair_details/KeyPairDetailTab.cpp
index b4d2d688..2785603b 100644
--- a/src/ui/dialog/keypair_details/KeyPairDetailTab.cpp
+++ b/src/ui/dialog/keypair_details/KeyPairDetailTab.cpp
@@ -35,8 +35,8 @@
namespace GpgFrontend::UI {
KeyPairDetailTab::KeyPairDetailTab(const std::string& key_id, QWidget* parent)
: QWidget(parent), key_(GpgKeyGetter::GetInstance().GetKey(key_id)) {
- LOG(INFO) << key_.GetEmail() << key_.IsPrivateKey() << key_.IsHasMasterKey()
- << key_.GetSubKeys()->front().IsPrivateKey();
+ SPDLOG_DEBUG(key_.GetEmail(), key_.IsPrivateKey(), key_.IsHasMasterKey(),
+ key_.GetSubKeys()->front().IsPrivateKey());
owner_box_ = new QGroupBox(_("Owner"));
key_box_ = new QGroupBox(_("Primary Key"));
@@ -232,20 +232,35 @@ void KeyPairDetailTab::slot_refresh_key_info() {
if (to_time_t(boost::posix_time::ptime(key_.GetExpireTime())) == 0) {
expire_var_label_->setText(_("Never Expire"));
} else {
+#ifdef GPGFRONTEND_GUI_QT6
+ expire_var_label_->setText(QLocale::system().toString(
+ QDateTime::fromSecsSinceEpoch(to_time_t(key_.GetExpireTime()))));
+#else
expire_var_label_->setText(QLocale::system().toString(
QDateTime::fromTime_t(to_time_t(key_.GetExpireTime()))));
+#endif
}
key_algo_val = key_.GetPublicKeyAlgo();
+#ifdef GPGFRONTEND_GUI_QT6
+ created_var_label_->setText(QLocale::system().toString(
+ QDateTime::fromSecsSinceEpoch(to_time_t(key_.GetCreateTime()))));
+#else
created_var_label_->setText(QLocale::system().toString(
QDateTime::fromTime_t(to_time_t(key_.GetCreateTime()))));
+#endif
if (to_time_t(boost::posix_time::ptime(key_.GetLastUpdateTime())) == 0) {
last_update_var_label_->setText(_("No Data"));
} else {
+#ifdef GPGFRONTEND_GUI_QT6
+ last_update_var_label_->setText(QLocale::system().toString(
+ QDateTime::fromSecsSinceEpoch(to_time_t(key_.GetLastUpdateTime()))));
+#else
last_update_var_label_->setText(QLocale::system().toString(
QDateTime::fromTime_t(to_time_t(key_.GetLastUpdateTime()))));
+#endif
}
key_size_var_label_->setText(key_size_val.c_str());
@@ -269,8 +284,6 @@ void KeyPairDetailTab::slot_refresh_key_info() {
}
void KeyPairDetailTab::slot_refresh_key() {
- LOG(INFO) << _("called");
-
// refresh the key
GpgKey refreshed_key = GpgKeyGetter::GetInstance().GetKey(key_.GetId());
std::swap(this->key_, refreshed_key);
diff --git a/src/ui/dialog/keypair_details/KeyPairOperaTab.cpp b/src/ui/dialog/keypair_details/KeyPairOperaTab.cpp
index 77eba0bc..a1452033 100644
--- a/src/ui/dialog/keypair_details/KeyPairOperaTab.cpp
+++ b/src/ui/dialog/keypair_details/KeyPairOperaTab.cpp
@@ -296,7 +296,7 @@ void KeyPairOperaTab::slot_gen_revoke_cert() {
// Code From Gpg4Win
while (proc->canReadLine()) {
const QString line = QString::fromUtf8(proc->readLine()).trimmed();
- LOG(INFO) << "line" << line.toStdString();
+ SPDLOG_DEBUG("line: {}", line.toStdString());
if (line == QLatin1String("[GNUPG:] GET_BOOL gen_revoke.okay")) {
proc->write("y\n");
} else if (line == QLatin1String("[GNUPG:] GET_LINE "
@@ -336,7 +336,7 @@ void KeyPairOperaTab::slot_modify_tofu_policy() {
this, _("Modify TOFU Policy(Default is Auto)"),
_("Policy for the Key Pair:"), items, 0, false, &ok);
if (ok && !item.isEmpty()) {
- LOG(INFO) << "selected policy" << item.toStdString();
+ SPDLOG_DEBUG("selected policy: {}", item.toStdString());
gpgme_tofu_policy_t tofu_policy = GPGME_TOFU_POLICY_AUTO;
if (item == _("Policy Auto")) {
tofu_policy = GPGME_TOFU_POLICY_AUTO;
diff --git a/src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp b/src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp
index be67e5ca..d1367541 100644
--- a/src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp
+++ b/src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp
@@ -35,8 +35,8 @@ namespace GpgFrontend::UI {
KeyPairSubkeyTab::KeyPairSubkeyTab(const std::string& key_id, QWidget* parent)
: QWidget(parent), key_(GpgKeyGetter::GetInstance().GetKey(key_id)) {
- LOG(INFO) << key_.GetEmail() << key_.IsPrivateKey() << key_.IsHasMasterKey()
- << key_.GetSubKeys()->front().IsPrivateKey();
+ SPDLOG_DEBUG(key_.GetEmail(), key_.IsPrivateKey(), key_.IsHasMasterKey(),
+ key_.GetSubKeys()->front().IsPrivateKey());
create_subkey_list();
create_subkey_opera_menu();
@@ -165,7 +165,6 @@ void KeyPairSubkeyTab::create_subkey_list() {
}
void KeyPairSubkeyTab::slot_refresh_subkey_list() {
- LOG(INFO) << "called";
int row = 0;
subkey_list_->setSelectionMode(QAbstractItemView::SingleSelection);
@@ -177,9 +176,8 @@ void KeyPairSubkeyTab::slot_refresh_subkey_list() {
this->buffered_subkeys_.push_back(std::move(sub_key));
}
- LOG(INFO) << "buffered_subkeys_"
- << "refreshed"
- << "size" << this->buffered_subkeys_.size();
+ SPDLOG_DEBUG("buffered_subkeys_ refreshed size",
+ this->buffered_subkeys_.size());
subkey_list_->setRowCount(buffered_subkeys_.size());
@@ -216,20 +214,16 @@ void KeyPairSubkeyTab::slot_refresh_subkey_list() {
}
}
- LOG(INFO) << "subkey_list_ item" << row << "refreshed";
+ SPDLOG_DEBUG("subkey_list_ item {} refreshed", row);
row++;
}
- LOG(INFO) << "subkey_list_"
- << "refreshed";
+ SPDLOG_DEBUG("subkey_list_ refreshed");
if (subkey_list_->rowCount() > 0) {
subkey_list_->selectRow(0);
}
-
- LOG(INFO) << "slot_refresh_subkey_list"
- << "ended";
}
void KeyPairSubkeyTab::slot_add_subkey() {
@@ -246,10 +240,18 @@ void KeyPairSubkeyTab::slot_refresh_subkey_detail() {
time_t subkey_time_t = boost::posix_time::to_time_t(
boost::posix_time::ptime(subkey.GetExpireTime()));
+#ifdef GPGFRONTEND_GUI_QT6
+ expire_var_label_->setText(
+ subkey_time_t == 0
+ ? _("Never Expires")
+ : QLocale::system().toString(QDateTime::fromSecsSinceEpoch(
+ to_time_t(subkey.GetExpireTime()))));
+#else
expire_var_label_->setText(
subkey_time_t == 0 ? _("Never Expires")
: QLocale::system().toString(QDateTime::fromTime_t(
to_time_t(subkey.GetExpireTime()))));
+#endif
if (subkey_time_t != 0 &&
subkey.GetExpireTime() < boost::posix_time::second_clock::local_time()) {
auto paletteExpired = expire_var_label_->palette();
@@ -262,8 +264,13 @@ void KeyPairSubkeyTab::slot_refresh_subkey_detail() {
}
algorithm_var_label_->setText(QString::fromStdString(subkey.GetPubkeyAlgo()));
+#ifdef GPGFRONTEND_GUI_QT6
+ created_var_label_->setText(QLocale::system().toString(
+ QDateTime::fromSecsSinceEpoch(to_time_t(subkey.GetCreateTime()))));
+#else
created_var_label_->setText(QLocale::system().toString(
QDateTime::fromTime_t(to_time_t(subkey.GetCreateTime()))));
+#endif
std::stringstream usage_steam;
@@ -318,7 +325,7 @@ void KeyPairSubkeyTab::create_subkey_opera_menu() {
}
void KeyPairSubkeyTab::slot_edit_subkey() {
- LOG(INFO) << "Fpr" << get_selected_subkey().GetFingerprint();
+ SPDLOG_DEBUG("fpr {}", get_selected_subkey().GetFingerprint());
auto dialog = new KeySetExpireDateDialog(
key_.GetId(), get_selected_subkey().GetFingerprint(), this);
@@ -344,7 +351,6 @@ const GpgSubKey& KeyPairSubkeyTab::get_selected_subkey() {
return buffered_subkeys_[row];
}
void KeyPairSubkeyTab::slot_refresh_key_info() {
- LOG(INFO) << "called";
key_ = GpgKeyGetter::GetInstance().GetKey(key_.GetId());
}
diff --git a/src/ui/dialog/keypair_details/KeyPairUIDTab.cpp b/src/ui/dialog/keypair_details/KeyPairUIDTab.cpp
index caa4e3be..d55e44d8 100644
--- a/src/ui/dialog/keypair_details/KeyPairUIDTab.cpp
+++ b/src/ui/dialog/keypair_details/KeyPairUIDTab.cpp
@@ -225,7 +225,7 @@ void KeyPairUIDTab::slot_refresh_tofu_info() {
continue;
}
auto tofu_infos = uid.GetTofuInfos();
- LOG(INFO) << "tofu info size" << tofu_infos->size();
+ SPDLOG_DEBUG("tofu info size: {}", tofu_infos->size());
if (tofu_infos->empty()) {
tofu_tabs_->hide();
} else {
@@ -277,17 +277,30 @@ void KeyPairUIDTab::slot_refresh_sig_list() {
new QTableWidgetItem(QString::fromStdString(sig.GetEmail()));
sig_list_->setItem(sigRow, 2, tmp3);
}
-
+#ifdef GPGFRONTEND_GUI_QT6
+ auto* tmp4 = new QTableWidgetItem(QLocale::system().toString(
+ QDateTime::fromSecsSinceEpoch(to_time_t(sig.GetCreateTime()))));
+#else
auto* tmp4 = new QTableWidgetItem(QLocale::system().toString(
QDateTime::fromTime_t(to_time_t(sig.GetCreateTime()))));
+#endif
sig_list_->setItem(sigRow, 3, tmp4);
+#ifdef GPGFRONTEND_GUI_QT6
+ auto* tmp5 = new QTableWidgetItem(
+ boost::posix_time::to_time_t(
+ boost::posix_time::ptime(sig.GetExpireTime())) == 0
+ ? _("Never Expires")
+ : QLocale::system().toString(QDateTime::fromSecsSinceEpoch(
+ to_time_t(sig.GetExpireTime()))));
+#else
auto* tmp5 = new QTableWidgetItem(
boost::posix_time::to_time_t(
boost::posix_time::ptime(sig.GetExpireTime())) == 0
? _("Never Expires")
: QLocale::system().toString(
QDateTime::fromTime_t(to_time_t(sig.GetExpireTime()))));
+#endif
tmp5->setTextAlignment(Qt::AlignCenter);
sig_list_->setItem(sigRow, 4, tmp5);
@@ -382,7 +395,7 @@ void KeyPairUIDTab::slot_del_uid() {
if (ret == QMessageBox::Yes) {
for (const auto& uid : *selected_uids) {
- LOG(INFO) << "KeyPairUIDTab::slot_del_uid UID" << uid;
+ SPDLOG_DEBUG("uid: {}", uid);
if (!GpgUIDOperator::GetInstance().RevUID(m_key_, uid)) {
QMessageBox::critical(
nullptr, _("Operation Failed"),
@@ -574,8 +587,6 @@ void KeyPairUIDTab::slot_del_sign() {
}
}
void KeyPairUIDTab::slot_refresh_key() {
- LOG(INFO) << "called";
-
// refresh the key
GpgKey refreshed_key = GpgKeyGetter::GetInstance().GetKey(m_key_.GetId());
std::swap(this->m_key_, refreshed_key);
diff --git a/src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp b/src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp
index 2c10b895..d09662e1 100644
--- a/src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp
+++ b/src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp
@@ -57,16 +57,23 @@ KeySetExpireDateDialog::KeySetExpireDateDialog(const KeyId& key_id,
}
void KeySetExpireDateDialog::slot_confirm() {
- LOG(INFO) << "Called" << ui_->dateEdit->date().toString().toStdString()
- << ui_->timeEdit->time().toString().toStdString();
+ SPDLOG_DEBUG("called: {} {}", ui_->dateEdit->date().toString().toStdString(),
+ ui_->timeEdit->time().toString().toStdString());
auto datetime = QDateTime(ui_->dateEdit->date(), ui_->timeEdit->time());
std::unique_ptr<boost::posix_time::ptime> expires = nullptr;
if (ui_->noExpirationCheckBox->checkState() == Qt::Unchecked) {
+#ifdef GPGFRONTEND_GUI_QT6
+ expires = std::make_unique<boost::posix_time::ptime>(
+ boost::posix_time::from_time_t(
+ datetime.toLocalTime().toSecsSinceEpoch()));
+#else
expires = std::make_unique<boost::posix_time::ptime>(
boost::posix_time::from_time_t(datetime.toLocalTime().toTime_t()));
- LOG(INFO) << "keyid" << m_key_.GetId() << m_subkey_ << *expires;
+#endif
+ SPDLOG_DEBUG("keyid: {}", m_key_.GetId(), m_subkey_,
+ to_iso_string(*expires));
} else {
- LOG(INFO) << "keyid" << m_key_.GetId() << m_subkey_ << "Non Expired";
+ SPDLOG_DEBUG("keyid: {}", m_key_.GetId(), m_subkey_, "Non Expired");
}
auto err = GpgKeyOpera::GetInstance().SetExpire(m_key_, m_subkey_, expires);
@@ -98,10 +105,10 @@ void KeySetExpireDateDialog::init() {
bool longer_expiration_date = false;
try {
longer_expiration_date = settings.lookup("general.longer_expiration_date");
- LOG(INFO) << "longer_expiration_date" << longer_expiration_date;
+ SPDLOG_DEBUG("longer_expiration_date: {}", longer_expiration_date);
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error") << _("longer_expiration_date");
+ SPDLOG_ERROR("setting operation error: longer_expiration_date");
}
auto max_date_time =
@@ -115,8 +122,13 @@ void KeySetExpireDateDialog::init() {
ui_->dateEdit->setMinimumDateTime(min_date_time);
// set default date time to expire date time
+#ifdef GPGFRONTEND_GUI_QT6
+ auto current_expire_time =
+ QDateTime::fromSecsSinceEpoch(to_time_t(m_key_.GetExpireTime()));
+#else
auto current_expire_time =
QDateTime::fromTime_t(to_time_t(m_key_.GetExpireTime()));
+#endif
ui_->dateEdit->setDateTime(current_expire_time);
ui_->timeEdit->setDateTime(current_expire_time);
diff --git a/src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp b/src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp
index 0f7de587..ca83dbfd 100644
--- a/src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp
+++ b/src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp
@@ -104,19 +104,23 @@ KeyUIDSignDialog::KeyUIDSignDialog(const GpgKey& key, UIDArgsListPtr uid,
}
void KeyUIDSignDialog::slot_sign_key(bool clicked) {
- LOG(INFO) << "Called";
-
// Set Signers
auto key_ids = m_key_list_->GetChecked();
auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
- LOG(INFO) << "Key Info Got";
+ SPDLOG_DEBUG("key info got");
+#ifdef GPGFRONTEND_GUI_QT6
+ auto expires =
+ std::make_unique<boost::posix_time::ptime>(boost::posix_time::from_time_t(
+ expires_edit_->dateTime().toSecsSinceEpoch()));
+#else
auto expires = std::make_unique<boost::posix_time::ptime>(
boost::posix_time::from_time_t(expires_edit_->dateTime().toTime_t()));
+#endif
- LOG(INFO) << "Sign Start";
+ SPDLOG_DEBUG("sign start");
for (const auto& uid : *m_uids_) {
- LOG(INFO) << "Sign UID" << uid;
+ SPDLOG_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/SettingsAdvanced.cpp b/src/ui/dialog/settings/SettingsAdvanced.cpp
index 516d4d02..e10b5dd1 100644
--- a/src/ui/dialog/settings/SettingsAdvanced.cpp
+++ b/src/ui/dialog/settings/SettingsAdvanced.cpp
@@ -60,7 +60,7 @@ void AdvancedTab::SetSettings() {
bool stegano_checked = settings.lookup("advanced.stegano_checked");
if (stegano_checked) stegano_check_box_->setCheckState(Qt::Checked);
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error") << _("stegano_checked");
+ SPDLOG_ERROR("setting operation error: stegano_checked");
}
try {
@@ -69,8 +69,7 @@ void AdvancedTab::SetSettings() {
if (auto_pubkey_exchange_checked)
auto_pubkey_exchange_check_box_->setCheckState(Qt::Checked);
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error")
- << _("auto_pubkey_exchange_checked");
+ SPDLOG_ERROR("setting operation error: auto_pubkey_exchange_checked");
}
}
diff --git a/src/ui/dialog/settings/SettingsDialog.cpp b/src/ui/dialog/settings/SettingsDialog.cpp
index 6737a512..d484207a 100644
--- a/src/ui/dialog/settings/SettingsDialog.cpp
+++ b/src/ui/dialog/settings/SettingsDialog.cpp
@@ -108,19 +108,17 @@ void SettingsDialog::slot_set_restart_needed(int mode) {
}
void SettingsDialog::SlotAccept() {
- LOG(INFO) << "Called";
-
general_tab_->ApplySettings();
appearance_tab_->ApplySettings();
key_server_tab_->ApplySettings();
network_tab_->ApplySettings();
- LOG(INFO) << "apply done";
+ SPDLOG_DEBUG("apply done");
// write settings to filesystem
GlobalSettingStation::GetInstance().SyncSettings();
- LOG(INFO) << "restart needed" << get_restart_needed();
+ SPDLOG_DEBUG("restart needed: {}", get_restart_needed());
if (get_restart_needed()) {
emit SignalRestartNeeded(get_restart_needed());
}
@@ -139,7 +137,7 @@ QHash<QString, QString> SettingsDialog::ListLanguages() {
for (int i = 0; i < file_names.size(); ++i) {
QString locale = file_names[i];
- LOG(INFO) << "locale" << locale.toStdString();
+ SPDLOG_DEBUG("locale: {}", locale.toStdString());
if (locale == "." || locale == "..") continue;
// this works in qt 4.8
diff --git a/src/ui/dialog/settings/SettingsGeneral.cpp b/src/ui/dialog/settings/SettingsGeneral.cpp
index 680ed014..7e48b4e1 100644
--- a/src/ui/dialog/settings/SettingsGeneral.cpp
+++ b/src/ui/dialog/settings/SettingsGeneral.cpp
@@ -43,20 +43,26 @@ GeneralTab::GeneralTab(QWidget* parent)
: QWidget(parent), ui_(std::make_shared<Ui_GeneralSettings>()) {
ui_->setupUi(this);
- ui_->saveCheckedKeysBox->setTitle(_("Save Checked Keys"));
+ ui_->cacheBox->setTitle(_("Cache"));
ui_->saveCheckedKeysCheckBox->setText(
_("Save checked private keys on exit and restore them on next start."));
- ui_->longerKeyExpirationDateBox->setTitle(_("Longer Key Expiration Date"));
+ ui_->clearGpgPasswordCacheCheckBox->setText(
+ "Clear gpg password cache when closing GpgFrontend.");
+
+ ui_->importConfirmationBox->setTitle(_("Operation"));
ui_->longerKeyExpirationDateCheckBox->setText(
- _("Unlock key expiration date setting up to 30 years."));
- ui_->importConfirmationBox->setTitle(_("Confirm drag'n'drop key import"));
+ _("Enable to use longer key expiration date."));
ui_->importConfirmationCheckBox->setText(
_("Import files dropped on the Key List without confirmation."));
- ui_->asciiModeBox->setTitle(_("ASCII Mode"));
- ui_->asciiModeCheckBox->setText(
- _("ASCII encoding is not used when file encrypting and "
- "signing."));
+ ui_->gnupgDatabaseBox->setTitle(_("GnuPG"));
+ ui_->asciiModeCheckBox->setText(_("No ASCII Mode"));
+ ui_->useCustomGnuPGInstallPathCheckBox->setText(_("Use Custom GnuPG"));
+ ui_->useCustomGnuPGInstallPathButton->setText(_("Select GnuPG Path"));
+ ui_->keyDatabseUseCustomCheckBox->setText(
+ _("Use Custom GnuPG Key Database Path"));
+ ui_->customKeyDatabasePathSelectButton->setText(
+ _("Select Key Database Path"));
ui_->langBox->setTitle(_("Language"));
ui_->langNoteLabel->setText(
@@ -77,12 +83,23 @@ GeneralTab::GeneralTab(QWidget* parent)
ui_->customKeyDatabasePathSelectButton->setDisabled(
state != Qt::CheckState::Checked);
// announce the restart
- this->slot_key_databse_path_changed();
+ this->slot_gnupg_stettings_changed();
+ });
+
+ connect(ui_->useCustomGnuPGInstallPathCheckBox, &QCheckBox::stateChanged,
+ this, [=](int state) {
+ ui_->useCustomGnuPGInstallPathButton->setDisabled(
+ state != Qt::CheckState::Checked);
+ // announce the restart
+ this->slot_gnupg_stettings_changed();
});
connect(ui_->keyDatabseUseCustomCheckBox, &QCheckBox::stateChanged, this,
&GeneralTab::slot_update_custom_key_database_path_label);
+ connect(ui_->useCustomGnuPGInstallPathCheckBox, &QCheckBox::stateChanged,
+ this, &GeneralTab::slot_update_custom_gnupg_install_path_label);
+
connect(
ui_->customKeyDatabasePathSelectButton, &QPushButton::clicked, this,
[=]() {
@@ -91,8 +108,8 @@ GeneralTab::GeneralTab(QWidget* parent)
this, _("Open Directory"), {},
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
- LOG(INFO) << "key databse path selected"
- << selected_custom_key_database_path.toStdString();
+ SPDLOG_DEBUG("key databse path selected: {}",
+ selected_custom_key_database_path.toStdString());
if (!selected_custom_key_database_path.isEmpty()) {
auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
@@ -109,7 +126,7 @@ GeneralTab::GeneralTab(QWidget* parent)
}
// announce the restart
- this->slot_key_databse_path_changed();
+ this->slot_gnupg_stettings_changed();
// update ui
this->slot_update_custom_key_database_path_label(
@@ -117,6 +134,39 @@ GeneralTab::GeneralTab(QWidget* parent)
}
});
+ connect(
+ ui_->useCustomGnuPGInstallPathButton, &QPushButton::clicked, this, [=]() {
+ QString selected_custom_gnupg_install_path =
+ QFileDialog::getExistingDirectory(
+ this, _("Open Directory"), {},
+ QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
+
+ SPDLOG_DEBUG("gnupg install path selected: {}",
+ selected_custom_gnupg_install_path.toStdString());
+
+ if (!selected_custom_gnupg_install_path.isEmpty()) {
+ auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
+ auto& general = settings["general"];
+
+ // update settings
+ if (!general.exists("custom_gnupg_install_path"))
+ general.add("custom_gnupg_install_path",
+ libconfig::Setting::TypeString) =
+ selected_custom_gnupg_install_path.toStdString();
+ else {
+ general["custom_gnupg_install_path"] =
+ selected_custom_gnupg_install_path.toStdString();
+ }
+
+ // announce the restart
+ this->slot_gnupg_stettings_changed();
+
+ // update ui
+ this->slot_update_custom_gnupg_install_path_label(
+ this->ui_->useCustomGnuPGInstallPathCheckBox->checkState());
+ }
+ });
+
SetSettings();
}
@@ -132,24 +182,33 @@ void GeneralTab::SetSettings() {
if (save_key_checked)
ui_->saveCheckedKeysCheckBox->setCheckState(Qt::Checked);
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error") << _("save_key_checked");
+ SPDLOG_ERROR("setting operation error: save_key_checked");
+ }
+
+ try {
+ bool clear_gpg_password_cache =
+ settings.lookup("general.clear_gpg_password_cache");
+ if (clear_gpg_password_cache)
+ ui_->clearGpgPasswordCacheCheckBox->setCheckState(Qt::Checked);
+ } catch (...) {
+ SPDLOG_ERROR("setting operation error: clear_gpg_password_cache");
}
try {
bool longer_expiration_date =
settings.lookup("general.longer_expiration_date");
- LOG(INFO) << "longer_expiration_date" << longer_expiration_date;
+ SPDLOG_DEBUG("longer_expiration_date: {}", longer_expiration_date);
if (longer_expiration_date)
ui_->longerKeyExpirationDateCheckBox->setCheckState(Qt::Checked);
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error") << _("longer_expiration_date");
+ SPDLOG_ERROR("setting operation error: longer_expiration_date");
}
#ifdef MULTI_LANG_SUPPORT
try {
std::string lang_key = settings.lookup("general.lang");
QString lang_value = lang_.value(lang_key.c_str());
- LOG(INFO) << "lang settings current" << lang_value.toStdString();
+ SPDLOG_DEBUG("lang settings current: {}", lang_value.toStdString());
if (!lang_.empty()) {
ui_->langSelectBox->setCurrentIndex(
ui_->langSelectBox->findText(lang_value));
@@ -157,27 +216,27 @@ void GeneralTab::SetSettings() {
ui_->langSelectBox->setCurrentIndex(0);
}
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error") << _("lang");
+ SPDLOG_ERROR("setting operation error: lang");
}
#endif
try {
bool confirm_import_keys = settings.lookup("general.confirm_import_keys");
- LOG(INFO) << "confirm_import_keys" << confirm_import_keys;
+ SPDLOG_DEBUG("confirm_import_keys: {}", confirm_import_keys);
if (confirm_import_keys)
ui_->importConfirmationCheckBox->setCheckState(Qt::Checked);
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error") << _("confirm_import_keys");
+ SPDLOG_ERROR("setting operation error: confirm_import_keys");
}
try {
bool non_ascii_when_export =
settings.lookup("general.non_ascii_when_export");
- LOG(INFO) << "non_ascii_when_export" << non_ascii_when_export;
+ SPDLOG_DEBUG("non_ascii_when_export: {}", non_ascii_when_export);
if (non_ascii_when_export)
ui_->asciiModeCheckBox->setCheckState(Qt::Checked);
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error") << _("non_ascii_when_export");
+ SPDLOG_ERROR("setting operation error: non_ascii_when_export");
}
try {
@@ -186,12 +245,23 @@ void GeneralTab::SetSettings() {
if (use_custom_key_database_path)
ui_->keyDatabseUseCustomCheckBox->setCheckState(Qt::Checked);
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error")
- << _("use_custom_key_database_path");
+ SPDLOG_ERROR("setting operation error: use_custom_key_database_path");
}
this->slot_update_custom_key_database_path_label(
ui_->keyDatabseUseCustomCheckBox->checkState());
+
+ try {
+ bool use_custom_gnupg_install_path =
+ settings.lookup("general.use_custom_gnupg_install_path");
+ if (use_custom_gnupg_install_path)
+ ui_->useCustomGnuPGInstallPathCheckBox->setCheckState(Qt::Checked);
+ } catch (...) {
+ SPDLOG_ERROR("setting operation error: use_custom_gnupg_install_path");
+ }
+
+ this->slot_update_custom_gnupg_install_path_label(
+ ui_->useCustomGnuPGInstallPathCheckBox->checkState());
}
/***********************************
@@ -223,6 +293,14 @@ void GeneralTab::ApplySettings() {
general["save_key_checked"] = ui_->saveCheckedKeysCheckBox->isChecked();
}
+ if (!general.exists("clear_gpg_password_cache"))
+ general.add("clear_gpg_password_cache", libconfig::Setting::TypeBoolean) =
+ ui_->clearGpgPasswordCacheCheckBox->isChecked();
+ else {
+ general["clear_gpg_password_cache"] =
+ ui_->saveCheckedKeysCheckBox->isChecked();
+ }
+
if (!general.exists("non_ascii_when_export"))
general.add("non_ascii_when_export", libconfig::Setting::TypeBoolean) =
ui_->asciiModeCheckBox->isChecked();
@@ -256,6 +334,15 @@ void GeneralTab::ApplySettings() {
general["use_custom_key_database_path"] =
ui_->keyDatabseUseCustomCheckBox->isChecked();
}
+
+ if (!general.exists("use_custom_gnupg_install_path"))
+ general.add("use_custom_gnupg_install_path",
+ libconfig::Setting::TypeBoolean) =
+ ui_->useCustomGnuPGInstallPathCheckBox->isChecked();
+ else {
+ general["use_custom_gnupg_install_path"] =
+ ui_->useCustomGnuPGInstallPathCheckBox->isChecked();
+ }
}
#ifdef MULTI_LANG_SUPPORT
@@ -265,7 +352,7 @@ void GeneralTab::slot_language_changed() { emit SignalRestartNeeded(true); }
void GeneralTab::slot_update_custom_key_database_path_label(int state) {
if (state != Qt::CheckState::Checked) {
ui_->currentKeyDatabasePathLabel->setText(QString::fromStdString(
- GpgContext::GetInstance().GetInfo().DatabasePath));
+ GpgContext::GetInstance().GetInfo(false).DatabasePath));
// hide label (not necessary to show the default path)
this->ui_->currentKeyDatabasePathLabel->setHidden(true);
@@ -279,27 +366,58 @@ void GeneralTab::slot_update_custom_key_database_path_label(int state) {
settings.lookup("general.custom_key_database_path"));
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error")
- << _("custom_key_database_path");
+ SPDLOG_ERROR("setting operation error: custom_key_database_path");
}
- LOG(INFO) << "selected_custom_key_database_path from settings"
- << custom_key_database_path;
+ SPDLOG_DEBUG("selected_custom_key_database_path from settings: {}",
+ custom_key_database_path);
// set label value
if (!custom_key_database_path.empty()) {
ui_->currentKeyDatabasePathLabel->setText(
QString::fromStdString(custom_key_database_path));
+ this->ui_->currentKeyDatabasePathLabel->setHidden(false);
} else {
- ui_->currentKeyDatabasePathLabel->setText(
- _("None custom key database path."));
+ this->ui_->currentKeyDatabasePathLabel->setHidden(true);
}
+ }
+}
- this->ui_->currentKeyDatabasePathLabel->setHidden(false);
+void GeneralTab::slot_update_custom_gnupg_install_path_label(int state) {
+ if (state != Qt::CheckState::Checked) {
+ ui_->currentCustomGnuPGInstallPathLabel->setText(QString::fromStdString(
+ GpgContext::GetInstance().GetInfo(false).GnuPGHomePath));
+
+ // hide label (not necessary to show the default path)
+ this->ui_->currentCustomGnuPGInstallPathLabel->setHidden(true);
+ } else {
+ // read from settings file
+ std::string custom_gnupg_install_path;
+ try {
+ auto& settings =
+ GpgFrontend::GlobalSettingStation::GetInstance().GetUISettings();
+ custom_gnupg_install_path = static_cast<std::string>(
+ settings.lookup("general.custom_gnupg_install_path"));
+
+ } catch (...) {
+ SPDLOG_ERROR("setting operation error: custom_gnupg_install_path");
+ }
+
+ SPDLOG_DEBUG("custom_gnupg_install_path from settings: {}",
+ custom_gnupg_install_path);
+
+ // set label value
+ if (!custom_gnupg_install_path.empty()) {
+ ui_->currentCustomGnuPGInstallPathLabel->setText(
+ QString::fromStdString(custom_gnupg_install_path));
+ this->ui_->currentCustomGnuPGInstallPathLabel->setHidden(false);
+ } else {
+ this->ui_->currentCustomGnuPGInstallPathLabel->setHidden(true);
+ }
}
}
-void GeneralTab::slot_key_databse_path_changed() {
+void GeneralTab::slot_gnupg_stettings_changed() {
emit SignalDeepRestartNeeded(true);
}
diff --git a/src/ui/dialog/settings/SettingsGeneral.h b/src/ui/dialog/settings/SettingsGeneral.h
index 4543df7d..ecd2809e 100644
--- a/src/ui/dialog/settings/SettingsGeneral.h
+++ b/src/ui/dialog/settings/SettingsGeneral.h
@@ -109,7 +109,13 @@ class GeneralTab : public QWidget {
* @brief
*
*/
- void slot_key_databse_path_changed();
+ void slot_update_custom_gnupg_install_path_label(int state);
+
+ /**
+ * @brief
+ *
+ */
+ void slot_gnupg_stettings_changed();
#endif
};
diff --git a/src/ui/dialog/settings/SettingsKeyServer.cpp b/src/ui/dialog/settings/SettingsKeyServer.cpp
index 365e19d4..8719ab9a 100644
--- a/src/ui/dialog/settings/SettingsKeyServer.cpp
+++ b/src/ui/dialog/settings/SettingsKeyServer.cpp
@@ -74,7 +74,7 @@ KeyserverTab::KeyserverTab(QWidget* parent)
connect(ui_->keyServerListTable, &QTableWidget::itemChanged,
[=](QTableWidgetItem* item) {
- LOG(INFO) << "item edited" << item->column();
+ SPDLOG_DEBUG("item edited: {}", item->column());
if (item->column() != 1) return;
const auto row_size = ui_->keyServerListTable->rowCount();
// Update Actions
@@ -137,7 +137,7 @@ void KeyserverTab::SetSettings() {
key_server_str_list_.append(default_key_server.c_str());
default_key_server_ = QString::fromStdString(default_key_server);
} catch (const std::exception& e) {
- LOG(ERROR) << "Error reading key-server settings: " << e.what();
+ SPDLOG_ERROR("Error reading key-server settings: ", e.what());
}
}
@@ -188,7 +188,7 @@ void KeyserverTab::ApplySettings() {
}
void KeyserverTab::slot_refresh_table() {
- LOG(INFO) << "Start Refreshing Key Server Table";
+ SPDLOG_INFO("start refreshing key server table");
ui_->keyServerListTable->blockSignals(true);
ui_->keyServerListTable->setRowCount(key_server_str_list_.size());
@@ -273,7 +273,7 @@ void KeyserverTab::slot_test_listed_key_server() {
waiting_dialog->setLabel(waiting_dialog_label);
waiting_dialog->resize(420, 120);
waiting_dialog->setModal(true);
- connect(task, &Thread::Task::SignalTaskFinished, [=]() {
+ connect(task, &Thread::Task::SignalTaskEnd, [=]() {
waiting_dialog->close();
waiting_dialog->deleteLater();
});
diff --git a/src/ui/dialog/settings/SettingsNetwork.cpp b/src/ui/dialog/settings/SettingsNetwork.cpp
index d4edae42..fe3d450e 100644
--- a/src/ui/dialog/settings/SettingsNetwork.cpp
+++ b/src/ui/dialog/settings/SettingsNetwork.cpp
@@ -76,28 +76,28 @@ void GpgFrontend::UI::NetworkTab::SetSettings() {
std::string proxy_host = settings.lookup("proxy.proxy_host");
ui_->proxyServerAddressEdit->setText(proxy_host.c_str());
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error") << _("proxy_host");
+ SPDLOG_ERROR("setting operation error: proxy_host");
}
try {
std::string std_username = settings.lookup("proxy.username");
ui_->usernameEdit->setText(std_username.c_str());
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error") << _("username");
+ SPDLOG_ERROR("setting operation error: username");
}
try {
std::string std_password = settings.lookup("proxy.password");
ui_->passwordEdit->setText(std_password.c_str());
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error") << _("password");
+ SPDLOG_ERROR("setting operation error: password");
}
try {
int port = settings.lookup("proxy.port");
ui_->portSpin->setValue(port);
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error") << _("port");
+ SPDLOG_ERROR("setting operation error: port");
}
ui_->proxyTypeComboBox->setCurrentText("HTTP");
@@ -105,7 +105,7 @@ void GpgFrontend::UI::NetworkTab::SetSettings() {
std::string proxy_type = settings.lookup("proxy.proxy_type");
ui_->proxyTypeComboBox->setCurrentText(proxy_type.c_str());
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error") << _("proxy_type");
+ SPDLOG_ERROR("setting operation error: proxy_type");
}
switch_ui_proxy_type(ui_->proxyTypeComboBox->currentText());
@@ -117,7 +117,7 @@ void GpgFrontend::UI::NetworkTab::SetSettings() {
else
ui_->enableProxyCheckBox->setCheckState(Qt::Unchecked);
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error") << _("proxy_enable");
+ SPDLOG_ERROR("setting operation error: proxy_enable");
}
{
@@ -134,7 +134,7 @@ void GpgFrontend::UI::NetworkTab::SetSettings() {
else
ui_->forbidALLCheckBox->setCheckState(Qt::Unchecked);
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error") << _("forbid_all_connection");
+ SPDLOG_ERROR("setting operation error: forbid_all_connection");
}
ui_->prohibitUpdateCheck->setCheckState(Qt::Unchecked);
@@ -146,13 +146,11 @@ void GpgFrontend::UI::NetworkTab::SetSettings() {
else
ui_->prohibitUpdateCheck->setCheckState(Qt::Unchecked);
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error") << _("prohibit_update_checking");
+ SPDLOG_ERROR("setting operation error: prohibit_update_checking");
}
}
void GpgFrontend::UI::NetworkTab::ApplySettings() {
- LOG(INFO) << "called";
-
auto &settings =
GpgFrontend::GlobalSettingStation::GetInstance().GetUISettings();
@@ -224,8 +222,6 @@ void GpgFrontend::UI::NetworkTab::ApplySettings() {
}
apply_proxy_settings();
-
- LOG(INFO) << "done";
}
void GpgFrontend::UI::NetworkTab::slot_test_proxy_connection_result() {
@@ -270,7 +266,7 @@ void GpgFrontend::UI::NetworkTab::slot_test_proxy_connection_result() {
waiting_dialog->deleteLater();
});
connect(waiting_dialog, &QProgressDialog::canceled, [=]() {
- LOG(INFO) << "cancel clicked";
+ SPDLOG_DEBUG("cancel clicked");
if (thread->isRunning()) thread->terminate();
});
diff --git a/src/ui/main_window/GeneralMainWindow.cpp b/src/ui/main_window/GeneralMainWindow.cpp
index fb42d71a..66255a08 100644
--- a/src/ui/main_window/GeneralMainWindow.cpp
+++ b/src/ui/main_window/GeneralMainWindow.cpp
@@ -47,8 +47,6 @@ void GpgFrontend::UI::GeneralMainWindow::closeEvent(QCloseEvent *event) {
void GpgFrontend::UI::GeneralMainWindow::slot_restore_settings() noexcept {
try {
- LOG(INFO) << name_ << _("Called");
-
SettingsObject general_windows_state(name_ + "_state");
std::string window_state = general_windows_state.Check(
@@ -75,7 +73,7 @@ void GpgFrontend::UI::GeneralMainWindow::slot_restore_settings() noexcept {
size_ = {width, height};
if (this->parent() != nullptr) {
- LOG(INFO) << "parent address" << this->parent();
+ SPDLOG_DEBUG("parent address: {}", static_cast<void *>(this->parent()));
QPoint parent_pos = {0, 0};
QSize parent_size = {0, 0};
@@ -92,11 +90,10 @@ void GpgFrontend::UI::GeneralMainWindow::slot_restore_settings() noexcept {
parent_size = parent_window->size();
}
- LOG(INFO) << "parent pos x:" << parent_pos.x()
- << "y:" << parent_pos.y();
+ SPDLOG_DEBUG("parent pos x: {} y: {}", parent_pos.x(), parent_pos.y());
- LOG(INFO) << "parent size width:" << parent_size.width()
- << "height:" << parent_size.height();
+ SPDLOG_DEBUG("parent size width: {} height: {}", parent_size.width(),
+ parent_size.height());
if (parent_pos != QPoint{0, 0}) {
QPoint parent_center{parent_pos.x() + parent_size.width() / 2,
@@ -116,7 +113,7 @@ void GpgFrontend::UI::GeneralMainWindow::slot_restore_settings() noexcept {
int width = general_settings_state.Check("icon_size").Check("width", 24),
height = general_settings_state.Check("icon_size").Check("height", 24);
- LOG(INFO) << "icon_size" << width << height;
+ SPDLOG_DEBUG("icon size: {} {}", width, height);
icon_size_ = {width, height};
font_size_ = general_settings_state.Check("font_size", 10);
@@ -130,14 +127,12 @@ void GpgFrontend::UI::GeneralMainWindow::slot_restore_settings() noexcept {
icon_style_ = toolButtonStyle();
} catch (...) {
- LOG(ERROR) << name_ << "error";
+ SPDLOG_ERROR(name_, "error");
}
}
void GpgFrontend::UI::GeneralMainWindow::slot_save_settings() noexcept {
try {
- LOG(INFO) << name_ << _("Called");
-
SettingsObject general_windows_state(name_ + "_state");
// window position and size
@@ -166,6 +161,6 @@ void GpgFrontend::UI::GeneralMainWindow::slot_save_settings() noexcept {
general_settings_state["icon_style"] = this->toolButtonStyle();
} catch (...) {
- LOG(ERROR) << name_ << "error";
+ SPDLOG_ERROR(name_, "error");
}
}
diff --git a/src/ui/main_window/KeyMgmt.cpp b/src/ui/main_window/KeyMgmt.cpp
index 9df2b918..9183d9d7 100644
--- a/src/ui/main_window/KeyMgmt.cpp
+++ b/src/ui/main_window/KeyMgmt.cpp
@@ -431,7 +431,7 @@ void KeyMgmt::SlotExportAsOpenSSHFormat() {
}
void KeyMgmt::SlotImportKeyPackage() {
- LOG(INFO) << "Importing key package...";
+ SPDLOG_INFO("Importing key package...");
auto key_package_file_name = QFileDialog::getOpenFileName(
this, _("Import Key Package"), {},
@@ -445,7 +445,7 @@ void KeyMgmt::SlotImportKeyPackage() {
GpgImportInformation info;
- LOG(INFO) << "Importing key package: " << key_package_file_name.toStdString();
+ SPDLOG_INFO("importing key package: {}", key_package_file_name.toStdString());
if (KeyPackageOperator::ImportKeyPackage(key_package_file_name.toStdString(),
key_file_name.toStdString(), info)) {
diff --git a/src/ui/main_window/MainWindow.cpp b/src/ui/main_window/MainWindow.cpp
index b0273d86..fff3ab63 100644
--- a/src/ui/main_window/MainWindow.cpp
+++ b/src/ui/main_window/MainWindow.cpp
@@ -29,6 +29,7 @@
#include "MainWindow.h"
#include "core/function/GlobalSettingStation.h"
+#include "core/function/gpg/GpgAdvancedOperator.h"
#include "ui/SignalStation.h"
#include "ui/UserInterfaceUtils.h"
#include "ui/struct/SettingsObject.h"
@@ -108,7 +109,7 @@ void MainWindow::Init() noexcept {
bool show_wizard = true;
wizard.lookupValue("show_wizard", show_wizard);
- LOG(INFO) << "wizard show_wizard" << show_wizard;
+ SPDLOG_DEBUG("wizard show_wizard: {}", show_wizard);
if (show_wizard) {
slot_start_wizard();
@@ -128,8 +129,31 @@ void MainWindow::Init() noexcept {
->PostTask(version_task);
}
+ // before application exit
+ connect(qApp, &QCoreApplication::aboutToQuit, this, []() {
+ SPDLOG_DEBUG("about to quit process started");
+
+ auto &settings = GlobalSettingStation::GetInstance().GetUISettings();
+ try {
+ bool clear_gpg_password_cache =
+ settings.lookup("general.clear_gpg_password_cache");
+
+ if (clear_gpg_password_cache) {
+ if (GpgFrontend::GpgAdvancedOperator::GetInstance()
+ .ClearGpgPasswordCache()) {
+ SPDLOG_DEBUG("clear gpg password cache done");
+ } else {
+ SPDLOG_ERROR("clear gpg password cache error");
+ }
+ }
+
+ } catch (...) {
+ SPDLOG_ERROR("setting operation error: clear_gpg_password_cache");
+ }
+ });
+
} catch (...) {
- LOG(FATAL) << _("Critical error occur while loading GpgFrontend.");
+ SPDLOG_ERROR(_("Critical error occur while loading GpgFrontend."));
QMessageBox::critical(nullptr, _("Loading Failed"),
_("Critical error occur while loading GpgFrontend."));
QCoreApplication::quit();
@@ -138,10 +162,8 @@ void MainWindow::Init() noexcept {
}
void MainWindow::restore_settings() {
- LOG(INFO) << _("Called");
-
try {
- LOG(INFO) << "restore settings key_server";
+ SPDLOG_DEBUG("restore settings key_server");
SettingsObject key_server_json("key_server");
if (!key_server_json.contains("server_list") ||
@@ -177,7 +199,7 @@ void MainWindow::restore_settings() {
import_button_->setToolButtonStyle(icon_style_);
try {
- LOG(INFO) << "restore settings default_key_checked";
+ SPDLOG_DEBUG("restore settings default_key_checked");
// Checked Keys
SettingsObject default_key_checked("default_key_checked");
@@ -185,13 +207,13 @@ void MainWindow::restore_settings() {
auto key_ids_ptr = std::make_unique<KeyIdArgsList>();
for (auto &it : default_key_checked) {
std::string key_id = it;
- LOG(INFO) << "get checked key id" << key_id;
+ SPDLOG_DEBUG("get checked key id: {}", key_id);
key_ids_ptr->push_back(key_id);
}
m_key_list_->SetChecked(std::move(key_ids_ptr));
}
} catch (...) {
- LOG(ERROR) << "restore default_key_checked failed";
+ SPDLOG_ERROR("restore default_key_checked failed");
}
prohibit_update_checking_ = false;
@@ -199,16 +221,15 @@ void MainWindow::restore_settings() {
prohibit_update_checking_ =
settings.lookup("network.prohibit_update_checking");
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error")
- << _("prohibit_update_checking");
+ SPDLOG_ERROR("setting operation error: prohibit_update_checking");
}
} catch (...) {
- LOG(ERROR) << "cannot resolve settings";
+ SPDLOG_ERROR("cannot resolve settings");
}
GlobalSettingStation::GetInstance().SyncSettings();
- LOG(INFO) << _("settings restored");
+ SPDLOG_DEBUG("settings restored");
}
void MainWindow::save_settings() {
@@ -230,7 +251,7 @@ void MainWindow::save_settings() {
settings["general"].remove("save_key_checked");
}
} catch (...) {
- LOG(ERROR) << "cannot save settings";
+ SPDLOG_ERROR("cannot save settings");
};
GlobalSettingStation::GetInstance().SyncSettings();
diff --git a/src/ui/main_window/MainWindow.h b/src/ui/main_window/MainWindow.h
index 2e24cecd..e32a02ff 100644
--- a/src/ui/main_window/MainWindow.h
+++ b/src/ui/main_window/MainWindow.h
@@ -328,6 +328,7 @@ class MainWindow : public GeneralMainWindow {
QMenu* file_menu_{}; ///< Submenu for file-operations
QMenu* edit_menu_{}; ///< Submenu for text-operations
QMenu* crypt_menu_{}; ///< Submenu for crypt-operations
+ QMenu* gpg_menu_{}; ///< Submenu for help-operations
QMenu* help_menu_{}; ///< Submenu for help-operations
QMenu* key_menu_{}; ///< Submenu for key-operations
QMenu* view_menu_{}; ///< Submenu for view operations
@@ -369,6 +370,10 @@ class MainWindow : public GeneralMainWindow {
QAction* clean_double_line_breaks_act_{}; ///< Action to remove double line
///< breaks
+ QAction* clean_gpg_password_cache_act_{}; ///<
+ QAction* reload_components_act_{}; ///<
+ QAction* restart_components_act_{}; ///<
+
QAction*
append_selected_keys_act_{}; ///< Action to append selected keys to edit
QAction* copy_mail_address_to_clipboard_act_{}; ///< Action to copy mail to
diff --git a/src/ui/main_window/MainWindowFileSlotFunction.cpp b/src/ui/main_window/MainWindowFileSlotFunction.cpp
index 526c27c0..598ba33c 100644
--- a/src/ui/main_window/MainWindowFileSlotFunction.cpp
+++ b/src/ui/main_window/MainWindowFileSlotFunction.cpp
@@ -67,7 +67,7 @@ bool path_pre_check(QWidget* parent, const QString& path) {
*/
bool process_tarball_into_directory(QWidget* parent,
std::filesystem::path& path) {
- LOG(INFO) << "Converting directory into tarball" << path;
+ SPDLOG_DEBUG("converting directory into tarball: {}", path.u8string());
auto selected_dir_path = std::filesystem::path(path);
if (selected_dir_path.extension() != ".tar") {
@@ -81,8 +81,8 @@ bool process_tarball_into_directory(QWidget* parent,
auto target_path = selected_dir_path;
target_path.replace_extension(".tar");
- LOG(INFO) << "base path" << base_path.u8string() << "target archive path"
- << target_path.u8string();
+ SPDLOG_DEBUG("base path: {} target archive path: {]", base_path.u8string(),
+ target_path.u8string());
bool if_error = false;
process_operation(parent, _("Extracting Tarball"),
@@ -101,7 +101,7 @@ bool process_tarball_into_directory(QWidget* parent,
}
path = target_path.u8string().c_str();
} catch (...) {
- LOG(ERROR) << "decompress error";
+ SPDLOG_ERROR("decompress error");
return false;
}
return true;
@@ -125,8 +125,9 @@ bool process_directory_into_tarball(QWidget* parent, QString& path) {
auto target_path = selected_dir_path;
selected_dir_path.replace_extension("");
- LOG(INFO) << "base path" << base_path << "target archive path"
- << target_path << "selected_dir_path" << selected_dir_path;
+ SPDLOG_DEBUG("base path: {} target archive path: {} selected_dir_path: {}",
+ base_path.u8string(), target_path.u8string(),
+ selected_dir_path.u8string());
bool if_error = false;
process_operation(parent, _("Making Tarball"),
@@ -145,7 +146,7 @@ bool process_directory_into_tarball(QWidget* parent, QString& path) {
}
path = target_path.u8string().c_str();
} catch (...) {
- LOG(ERROR) << "compress error";
+ SPDLOG_ERROR("compress error");
return false;
}
return true;
@@ -156,7 +157,7 @@ void MainWindow::SlotFileEncrypt() {
auto path = fileTreeView->GetSelected();
if (!path_pre_check(this, path)) {
- LOG(ERROR) << "path pre check failed";
+ SPDLOG_ERROR("path pre check failed");
return;
}
@@ -172,7 +173,7 @@ void MainWindow::SlotFileEncrypt() {
try {
non_ascii_when_export = settings.lookup("general.non_ascii_when_export");
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error") << _("non_ascii_when_export");
+ SPDLOG_ERROR("setting operation error: non_ascii_when_export");
}
// get file info
@@ -395,7 +396,7 @@ void MainWindow::SlotFileSign() {
try {
non_ascii_when_export = settings.lookup("general.non_ascii_when_export");
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error") << _("non_ascii_when_export");
+ SPDLOG_ERROR("setting operation error: non_ascii_when_export");
}
auto _channel = GPGFRONTEND_DEFAULT_CHANNEL;
@@ -474,7 +475,7 @@ void MainWindow::SlotFileVerify() {
try {
non_ascii_when_export = settings.lookup("general.non_ascii_when_export");
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error") << _("non_ascii_when_export");
+ SPDLOG_ERROR("setting operation error: non_ascii_when_export");
}
auto _channel = GPGFRONTEND_DEFAULT_CHANNEL;
@@ -488,7 +489,8 @@ void MainWindow::SlotFileVerify() {
data_file_path = sign_file_path.parent_path() / sign_file_path.stem();
}
- LOG(INFO) << "sign_file_path" << sign_file_path << sign_file_path.extension();
+ SPDLOG_DEBUG("sign_file_path: {} {}", sign_file_path.u8string(),
+ sign_file_path.extension().u8string());
if (in_path.extension() != ".gpg") {
bool ok;
@@ -511,8 +513,8 @@ void MainWindow::SlotFileVerify() {
return;
}
- DLOG(INFO) << "data path" << data_file_path;
- DLOG(INFO) << "sign path" << sign_file_path;
+ SPDLOG_DEBUG("data path: {}", data_file_path.u8string());
+ SPDLOG_DEBUG("sign path: {}", sign_file_path.u8string());
GpgVerifyResult result = nullptr;
gpgme_error_t error;
@@ -585,7 +587,7 @@ void MainWindow::SlotFileEncryptSign() {
try {
non_ascii_when_export = settings.lookup("general.non_ascii_when_export");
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error") << _("non_ascii_when_export");
+ SPDLOG_ERROR("setting operation error: non_ascii_when_export");
}
// get file info
@@ -697,7 +699,7 @@ void MainWindow::SlotFileDecryptVerify() {
} else {
out_path += ".out";
}
- LOG(INFO) << "out path" << out_path;
+ SPDLOG_DEBUG("out path: {}", out_path.u8string());
if (QFile::exists(out_path.u8string().c_str())) {
auto ret =
diff --git a/src/ui/main_window/MainWindowSlotFunction.cpp b/src/ui/main_window/MainWindowSlotFunction.cpp
index f715046c..6f702e34 100644
--- a/src/ui/main_window/MainWindowSlotFunction.cpp
+++ b/src/ui/main_window/MainWindowSlotFunction.cpp
@@ -36,9 +36,10 @@
#include "core/function/gpg/GpgBasicOperator.h"
#include "core/function/gpg/GpgKeyGetter.h"
#include "core/function/gpg/GpgKeyImportExporter.h"
+#include "dialog/SignersPicker.h"
+#include "spdlog/spdlog.h"
#include "ui/UserInterfaceUtils.h"
#include "ui/dialog/help/AboutDialog.h"
-#include "dialog/SignersPicker.h"
namespace GpgFrontend::UI {
/**
@@ -341,7 +342,7 @@ void MainWindow::slot_verify() {
auto buffer = data_object->PopObject<std::string>();
- LOG(INFO) << "Verify buffer: " << buffer.size();
+ SPDLOG_DEBUG("verify buffer size: {}", buffer.size());
try {
GpgVerifyResult verify_result = nullptr;
@@ -430,11 +431,11 @@ void MainWindow::slot_encrypt_sign() {
auto signer_keys = GpgKeyGetter::GetInstance().GetKeys(signer_key_ids);
for (const auto& key : *keys) {
- LOG(INFO) << "Keys " << key.GetEmail();
+ SPDLOG_DEBUG("keys {}", key.GetEmail());
}
for (const auto& signer : *signer_keys) {
- LOG(INFO) << "Signers " << signer.GetEmail();
+ SPDLOG_DEBUG("signers {}", signer.GetEmail());
}
// data to transfer into task
@@ -486,7 +487,6 @@ void MainWindow::slot_encrypt_sign() {
auto sign_result = data_object->PopObject<GpgSignResult>();
auto tmp = data_object->PopObject<std::unique_ptr<ByteArray>>();
- LOG(INFO) << "GpgResultAnalyse Started";
auto encrypt_result_analyse =
GpgEncryptResultAnalyse(error, std::move(encrypt_result));
auto sign_result_analyse =
@@ -544,7 +544,7 @@ void MainWindow::slot_decrypt_verify() {
data_object->AppendObject(std::move(decrypt_result));
data_object->AppendObject(std::move(error));
} catch (const std::runtime_error& e) {
- LOG(ERROR) << e.what();
+ SPDLOG_ERROR(e.what());
return -1;
}
return 0;
@@ -660,13 +660,17 @@ void MainWindow::upload_key_to_server() {
void MainWindow::SlotOpenFile(QString& path) { edit_->SlotOpenFile(path); }
void MainWindow::slot_version_upgrade(const SoftwareVersion& version) {
- LOG(INFO) << _("Called");
-
- if (!version.InfoVaild()) {
- LOG(INFO) << "Invalid version info";
+ if (!version.InfoValid()) {
+ SPDLOG_ERROR("invalid version info");
return;
}
+ SPDLOG_DEBUG(
+ "version info, need upgrade: {}, with drawn: {}, current version "
+ "released: {}",
+ version.NeedUpgrade(), version.VersionWithDrawn(),
+ version.CurrentVersionReleased());
+
if (version.NeedUpgrade()) {
statusBar()->showMessage(
QString(_("GpgFrontend Upgradeable (New Version: %1)."))
diff --git a/src/ui/main_window/MainWindowSlotUI.cpp b/src/ui/main_window/MainWindowSlotUI.cpp
index 8961a33f..8839df4b 100644
--- a/src/ui/main_window/MainWindowSlotUI.cpp
+++ b/src/ui/main_window/MainWindowSlotUI.cpp
@@ -104,13 +104,11 @@ void MainWindow::slot_open_settings_dialog() {
auto dialog = new SettingsDialog(this);
connect(dialog, &SettingsDialog::finished, this, [&]() -> void {
- LOG(INFO) << "Setting Dialog Finished";
-
SettingsObject general_settings_state("general_settings_state");
int width = general_settings_state.Check("icon_size").Check("width", 24),
height = general_settings_state.Check("icon_size").Check("height", 24);
- LOG(INFO) << "icon_size" << width << height;
+ SPDLOG_DEBUG("icon_size: {} {}", width, height);
general_settings_state.Check("info_font_size", 10);
@@ -184,7 +182,7 @@ void MainWindow::slot_cut_pgp_header() {
}
void MainWindow::SlotSetRestartNeeded(int mode) {
- LOG(INFO) << "restart mode" << mode;
+ SPDLOG_DEBUG("restart mode: {}", mode);
this->restart_needed_ = mode;
}
@@ -192,7 +190,7 @@ int MainWindow::get_restart_needed() const { return this->restart_needed_; }
void MainWindow::SetCryptoMenuStatus(
MainWindow::CryptoMenu::OperationType type) {
- LOG(INFO) << "SetCryptoMenuStatus" << type;
+ SPDLOG_DEBUG("type: {}", type);
// refresh status to disable all
verify_act_->setDisabled(true);
diff --git a/src/ui/main_window/MainWindowUI.cpp b/src/ui/main_window/MainWindowUI.cpp
index 1470b731..b9a01c15 100644
--- a/src/ui/main_window/MainWindowUI.cpp
+++ b/src/ui/main_window/MainWindowUI.cpp
@@ -27,6 +27,7 @@
*/
#include "MainWindow.h"
+#include "core/function/gpg/GpgAdvancedOperator.h"
#include "ui/UserInterfaceUtils.h"
namespace GpgFrontend::UI {
@@ -37,8 +38,11 @@ void MainWindow::create_actions() {
new_tab_act_ = new QAction(_("New"), this);
new_tab_act_->setIcon(QIcon(":misc_doc.png"));
QList<QKeySequence> newTabActShortcutList;
- newTabActShortcutList.append(QKeySequence(Qt::CTRL + Qt::Key_N));
- newTabActShortcutList.append(QKeySequence(Qt::CTRL + Qt::Key_T));
+#ifdef GPGFRONTEND_GUI_QT6
+ newTabActShortcutList.append(QKeySequence(Qt::CTRL | Qt::Key_N));
+ newTabActShortcutList.append(QKeySequence(Qt::CTRL | Qt::Key_T));
+#else
+#endif
new_tab_act_->setShortcuts(newTabActShortcutList);
new_tab_act_->setToolTip(_("Open a new file"));
connect(new_tab_act_, &QAction::triggered, edit_, &TextEdit::SlotNewTab);
@@ -51,7 +55,11 @@ void MainWindow::create_actions() {
browser_act_ = new QAction(_("File Browser"), this);
browser_act_->setIcon(QIcon(":file-browser.png"));
+#ifdef GPGFRONTEND_GUI_QT6
+ browser_act_->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_B));
+#else
browser_act_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_B));
+#endif
browser_act_->setToolTip(_("Open a file browser"));
connect(browser_act_, &QAction::triggered, this,
&MainWindow::slot_open_file_tab);
@@ -164,41 +172,64 @@ void MainWindow::create_actions() {
*/
encrypt_act_ = new QAction(_("Encrypt"), this);
encrypt_act_->setIcon(QIcon(":encrypted.png"));
- encrypt_act_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_E));
+#ifdef GPGFRONTEND_GUI_QT6
+ encrypt_act_->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_E));
+#else
+#endif
encrypt_act_->setToolTip(_("Encrypt Message"));
connect(encrypt_act_, &QAction::triggered, this, &MainWindow::slot_encrypt);
encrypt_sign_act_ = new QAction(_("Encrypt Sign"), this);
encrypt_sign_act_->setIcon(QIcon(":encrypted_signed.png"));
+#ifdef GPGFRONTEND_GUI_QT6
encrypt_sign_act_->setShortcut(
- QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_E));
+ QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_E));
+#else
+ encrypt_act_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_E));
+#endif
encrypt_sign_act_->setToolTip(_("Encrypt and Sign Message"));
connect(encrypt_sign_act_, &QAction::triggered, this,
&MainWindow::slot_encrypt_sign);
decrypt_act_ = new QAction(_("Decrypt"), this);
decrypt_act_->setIcon(QIcon(":decrypted.png"));
- decrypt_act_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_D));
+#ifdef GPGFRONTEND_GUI_QT6
+ decrypt_act_->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_D));
+#else
+ encrypt_act_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_E));
+#endif
decrypt_act_->setToolTip(_("Decrypt Message"));
connect(decrypt_act_, &QAction::triggered, this, &MainWindow::slot_decrypt);
decrypt_verify_act_ = new QAction(_("Decrypt Verify"), this);
decrypt_verify_act_->setIcon(QIcon(":decrypted_verified.png"));
+#ifdef GPGFRONTEND_GUI_QT6
decrypt_verify_act_->setShortcut(
- QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_D));
+ QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_D));
+#else
+ encrypt_act_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_E));
+#endif
decrypt_verify_act_->setToolTip(_("Decrypt and Verify Message"));
connect(decrypt_verify_act_, &QAction::triggered, this,
&MainWindow::slot_decrypt_verify);
sign_act_ = new QAction(_("Sign"), this);
sign_act_->setIcon(QIcon(":signature.png"));
- sign_act_->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_I));
+#ifdef GPGFRONTEND_GUI_QT6
+ sign_act_->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_I));
+#else
+ encrypt_act_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_E));
+#endif
sign_act_->setToolTip(_("Sign Message"));
connect(sign_act_, &QAction::triggered, this, &MainWindow::slot_sign);
verify_act_ = new QAction(_("Verify"), this);
verify_act_->setIcon(QIcon(":verify.png"));
- verify_act_->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_V));
+#ifdef GPGFRONTEND_GUI_QT6
+ verify_act_->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_V));
+#else
+ encrypt_act_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_E));
+#endif
verify_act_->setToolTip(_("Verify Message"));
connect(verify_act_, &QAction::triggered, this, &MainWindow::slot_verify);
@@ -241,6 +272,51 @@ void MainWindow::create_actions() {
connect(open_key_management_act_, &QAction::triggered, this,
&MainWindow::slot_open_key_management);
+ clean_gpg_password_cache_act_ = new QAction(_("Clear Password Cache"), this);
+ clean_gpg_password_cache_act_->setIcon(QIcon(":configure.png"));
+ clean_gpg_password_cache_act_->setToolTip(_("Clear Password Cache of GnuPG"));
+ connect(clean_gpg_password_cache_act_, &QAction::triggered, this, [=]() {
+ if (GpgFrontend::GpgAdvancedOperator::GetInstance()
+ .ClearGpgPasswordCache()) {
+ QMessageBox::information(this, _("Successful Operation"),
+ _("Clear password cache successfully"));
+ } else {
+ QMessageBox::critical(this, _("Failed Operation"),
+ _("Failed to clear password cache of GnuPG"));
+ }
+ });
+
+ reload_components_act_ = new QAction(_("Reload All Components"), this);
+ reload_components_act_->setIcon(QIcon(":configure.png"));
+ reload_components_act_->setToolTip(_("Reload All GnuPG's Components"));
+ connect(reload_components_act_, &QAction::triggered, this, [=]() {
+ if (GpgFrontend::GpgAdvancedOperator::GetInstance().ReloadGpgComponents()) {
+ QMessageBox::information(
+ this, _("Successful Operation"),
+ _("Reload all the GnuPG's components successfully"));
+ } else {
+ QMessageBox::critical(
+ this, _("Failed Operation"),
+ _("Failed to reload all or one of the GnuPG's component(s)"));
+ }
+ });
+
+ restart_components_act_ = new QAction(_("Restart All Components"), this);
+ restart_components_act_->setIcon(QIcon(":configure.png"));
+ restart_components_act_->setToolTip(_("Restart All GnuPG's Components"));
+ connect(restart_components_act_, &QAction::triggered, this, [=]() {
+ if (GpgFrontend::GpgAdvancedOperator::GetInstance()
+ .RestartGpgComponents()) {
+ QMessageBox::information(
+ this, _("Successful Operation"),
+ _("Restart all the GnuPG's components successfully"));
+ } else {
+ QMessageBox::critical(
+ this, _("Failed Operation"),
+ _("Failed to restart all or one of the GnuPG's component(s)"));
+ }
+ });
+
/*
* About Menu
*/
@@ -270,7 +346,7 @@ void MainWindow::create_actions() {
check_update_act_->setIcon(QIcon(":help.png"));
check_update_act_->setToolTip(_("Check for updates"));
connect(check_update_act_, &QAction::triggered, this,
- [=]() { new AboutDialog(2, this); });
+ [=]() { new AboutDialog(3, this); });
start_wizard_act_ = new QAction(_("Open Wizard"), this);
start_wizard_act_->setToolTip(_("Open the wizard"));
@@ -372,6 +448,12 @@ void MainWindow::create_menus() {
import_key_menu_->addAction(import_key_from_key_server_act_);
key_menu_->addAction(open_key_management_act_);
+ gpg_menu_ = menuBar()->addMenu(_("GnuPG"));
+ gpg_menu_->addAction(clean_gpg_password_cache_act_);
+ gpg_menu_->addSeparator();
+ gpg_menu_->addAction(reload_components_act_);
+ gpg_menu_->addAction(restart_components_act_);
+
steganography_menu_ = menuBar()->addMenu(_("Steganography"));
steganography_menu_->addAction(cut_pgp_header_act_);
steganography_menu_->addAction(add_pgp_header_act_);
diff --git a/src/ui/struct/SettingsObject.cpp b/src/ui/struct/SettingsObject.cpp
index 4a9aa7d6..d5230089 100644
--- a/src/ui/struct/SettingsObject.cpp
+++ b/src/ui/struct/SettingsObject.cpp
@@ -32,7 +32,7 @@ nlohmann::json& GpgFrontend::UI::SettingsObject::Check(
const std::string& key, const nlohmann::json& default_value) {
// check if the self null
if (this->nlohmann::json::is_null()) {
- LOG(INFO) << "SettingsObject is null, creating new one";
+ SPDLOG_DEBUG("settings object is null, creating new one");
this->nlohmann::json::operator=(nlohmann::json::object());
}
@@ -41,9 +41,9 @@ nlohmann::json& GpgFrontend::UI::SettingsObject::Check(
this->nlohmann::json::at(key).is_null() ||
this->nlohmann::json::at(key).type_name() !=
default_value.type_name()) {
- LOG(INFO) << "Added missing key: " << key;
+ SPDLOG_DEBUG("added missing key: {}", key);
if (default_value.is_null()) {
- LOG(WARNING) << "Default value is null, using empty object";
+ SPDLOG_WARN("default value is null, using empty object");
this->nlohmann::json::operator[](key) = nlohmann::json::object();
} else {
this->nlohmann::json::operator[](key) = default_value;
@@ -51,7 +51,7 @@ nlohmann::json& GpgFrontend::UI::SettingsObject::Check(
}
return this->nlohmann::json::at(key);
} catch (nlohmann::json::exception& e) {
- LOG(ERROR) << e.what();
+ SPDLOG_ERROR(e.what());
throw e;
}
}
@@ -60,14 +60,14 @@ GpgFrontend::UI::SettingsObject GpgFrontend::UI::SettingsObject::Check(
const std::string& key) {
// check if the self null
if (this->nlohmann::json::is_null()) {
- LOG(INFO) << "SettingsObject is null, creating new one";
+ SPDLOG_DEBUG("settings object is null, creating new one");
this->nlohmann::json::operator=(nlohmann::json::object());
}
if (!nlohmann::json::contains(key) ||
this->nlohmann::json::at(key).is_null() ||
this->nlohmann::json::at(key).type() != nlohmann::json::value_t::object) {
- LOG(INFO) << "Added missing key: " << key;
+ SPDLOG_DEBUG("added missing key: {}", key);
this->nlohmann::json::operator[](key) = nlohmann::json::object();
}
return SettingsObject{nlohmann::json::operator[](key), false};
@@ -76,21 +76,21 @@ GpgFrontend::UI::SettingsObject GpgFrontend::UI::SettingsObject::Check(
GpgFrontend::UI::SettingsObject::SettingsObject(std::string settings_name)
: settings_name_(std::move(settings_name)) {
try {
- LOG(INFO) << "Loading settings from: " << this->settings_name_;
+ SPDLOG_DEBUG("loading settings from: {}", this->settings_name_);
auto _json_optional =
GpgFrontend::DataObjectOperator::GetInstance().GetDataObject(
settings_name_);
if (_json_optional.has_value()) {
- LOG(INFO) << "SettingsObject: " << settings_name_ << " loaded.";
+ SPDLOG_DEBUG("settings object: {} loaded.", settings_name_);
nlohmann::json::operator=(_json_optional.value());
} else {
- LOG(INFO) << "SettingsObject: " << settings_name_ << " not found.";
+ SPDLOG_DEBUG("settings object: {} not found.", settings_name_);
nlohmann::json::operator=({});
}
} catch (std::exception& e) {
- LOG(ERROR) << e.what();
+ SPDLOG_ERROR(e.what());
}
}
@@ -101,4 +101,4 @@ GpgFrontend::UI::SettingsObject::~SettingsObject() {
if (!settings_name_.empty())
GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(settings_name_,
*this);
-}
+} \ No newline at end of file
diff --git a/src/ui/struct/SoftwareVersion.cpp b/src/ui/struct/SoftwareVersion.cpp
index ecccf7c0..6a60cb02 100644
--- a/src/ui/struct/SoftwareVersion.cpp
+++ b/src/ui/struct/SoftwareVersion.cpp
@@ -27,3 +27,75 @@
*/
#include "SoftwareVersion.h"
+
+int GpgFrontend::UI::SoftwareVersion::version_compare(const std::string& a,
+ const std::string& b) {
+ auto temp_a = a, temp_b = b;
+
+ if (!temp_a.empty() && temp_a.front() == 'v') {
+ temp_a = temp_a.erase(0, 1);
+ SPDLOG_DEBUG("real version a: {}", temp_a);
+ }
+
+ if (!temp_b.empty() && temp_b.front() == 'v') {
+ temp_b.erase(0, 1);
+ SPDLOG_DEBUG("real version b: {}", temp_b);
+ }
+
+ // First, split the string.
+ std::vector<std::string> va, vb;
+ boost::split(va, temp_a, boost::is_any_of("."));
+ boost::split(vb, temp_b, boost::is_any_of("."));
+
+ // Compare the numbers step by step, but only as deep as the version
+ // with the least elements allows.
+ const int depth =
+ std::min(static_cast<int>(va.size()), static_cast<int>(vb.size()));
+ int ia = 0, ib = 0;
+ for (int i = 0; i < depth; ++i) {
+ try {
+ ia = boost::lexical_cast<int>(va[i]);
+ ib = boost::lexical_cast<int>(vb[i]);
+ } catch (boost::bad_lexical_cast& ignored) {
+ break;
+ }
+ if (ia != ib) break;
+ }
+
+ // Return the required number.
+ if (ia > ib)
+ return 1;
+ else if (ia < ib)
+ return -1;
+ else {
+ // In case of equal versions, assumes that the version
+ // with the most elements is the highest version.
+ if (va.size() > vb.size())
+ return 1;
+ else if (va.size() < vb.size())
+ return -1;
+ }
+
+ // Everything is equal, return 0.
+ return 0;
+}
+
+bool GpgFrontend::UI::SoftwareVersion::NeedUpgrade() const {
+ SPDLOG_DEBUG("compair version current {} latest {}, result {}",
+ current_version, latest_version,
+ version_compare(current_version, latest_version));
+
+ SPDLOG_DEBUG("load done: {}, pre-release: {}, draft: {}", load_info_done,
+ latest_prerelease, latest_draft);
+ return load_info_done && !latest_prerelease && !latest_draft &&
+ version_compare(current_version, latest_version) < 0;
+}
+
+bool GpgFrontend::UI::SoftwareVersion::VersionWithDrawn() const {
+ return load_info_done && !current_version_found && current_prerelease &&
+ !current_draft;
+}
+
+bool GpgFrontend::UI::SoftwareVersion::CurrentVersionReleased() const {
+ return load_info_done && current_version_found;
+} \ No newline at end of file
diff --git a/src/ui/struct/SoftwareVersion.h b/src/ui/struct/SoftwareVersion.h
index da93f8c6..9d861ef1 100644
--- a/src/ui/struct/SoftwareVersion.h
+++ b/src/ui/struct/SoftwareVersion.h
@@ -54,7 +54,7 @@ struct SoftwareVersion {
* @return true
* @return false
*/
- [[nodiscard]] bool InfoVaild() const { return load_info_done; }
+ [[nodiscard]] bool InfoValid() const { return load_info_done; }
/**
* @brief
@@ -62,10 +62,7 @@ struct SoftwareVersion {
* @return true
* @return false
*/
- [[nodiscard]] bool NeedUpgrade() const {
- return load_info_done && !latest_prerelease && !latest_draft &&
- current_version < latest_version;
- }
+ [[nodiscard]] bool NeedUpgrade() const;
/**
* @brief
@@ -73,10 +70,7 @@ struct SoftwareVersion {
* @return true
* @return false
*/
- [[nodiscard]] bool VersionWithDrawn() const {
- return load_info_done && !current_version_found && current_prerelease &&
- !current_draft;
- }
+ [[nodiscard]] bool VersionWithDrawn() const;
/**
* @brief
@@ -84,9 +78,10 @@ struct SoftwareVersion {
* @return true
* @return false
*/
- [[nodiscard]] bool CurrentVersionReleased() const {
- return load_info_done && current_version_found;
- }
+ [[nodiscard]] bool CurrentVersionReleased() const;
+
+ private:
+ static int version_compare(const std::string& a, const std::string& b);
};
} // namespace GpgFrontend::UI
diff --git a/src/ui/thread/KeyServerImportTask.cpp b/src/ui/thread/KeyServerImportTask.cpp
index bf3e1822..fc6a868c 100644
--- a/src/ui/thread/KeyServerImportTask.cpp
+++ b/src/ui/thread/KeyServerImportTask.cpp
@@ -30,7 +30,8 @@
GpgFrontend::UI::KeyServerImportTask::KeyServerImportTask(
std::string keyserver_url, std::vector<std::string> keyids)
- : keyserver_url_(std::move(keyserver_url)),
+ : Task("key_server_import_task"),
+ keyserver_url_(std::move(keyserver_url)),
keyids_(std::move(keyids)),
manager_(new QNetworkAccessManager(this)) {}
@@ -59,6 +60,6 @@ void GpgFrontend::UI::KeyServerImportTask::dealing_reply_from_server() {
emit SignalKeyServerImportResult(network_reply, buffer);
if (result_count_++ == keyids_.size() - 1) {
- emit SignalTaskFinished();
+ emit SignalTaskRunnableEnd(0);
}
} \ No newline at end of file
diff --git a/src/ui/thread/KeyServerSearchTask.cpp b/src/ui/thread/KeyServerSearchTask.cpp
index 0090e79d..863a4ca3 100644
--- a/src/ui/thread/KeyServerSearchTask.cpp
+++ b/src/ui/thread/KeyServerSearchTask.cpp
@@ -30,7 +30,8 @@
GpgFrontend::UI::KeyServerSearchTask::KeyServerSearchTask(
std::string keyserver_url, std::string search_string)
- : keyserver_url_(std::move(keyserver_url)),
+ : Task("key_server_search_task"),
+ keyserver_url_(std::move(keyserver_url)),
search_string_(std::move(search_string)),
manager_(new QNetworkAccessManager(this)) {}
@@ -55,5 +56,5 @@ void GpgFrontend::UI::KeyServerSearchTask::dealing_reply_from_server() {
buffer = reply_->readAll();
}
emit SignalKeyServerSearchResult(network_reply, buffer);
- emit SignalTaskFinished();
+ emit SignalTaskRunnableEnd(0);
}
diff --git a/src/ui/thread/ListedKeyServerTestTask.cpp b/src/ui/thread/ListedKeyServerTestTask.cpp
index 9d4ca74d..914cd3d6 100644
--- a/src/ui/thread/ListedKeyServerTestTask.cpp
+++ b/src/ui/thread/ListedKeyServerTestTask.cpp
@@ -30,7 +30,8 @@
GpgFrontend::UI::ListedKeyServerTestTask::ListedKeyServerTestTask(
const QStringList& urls, int timeout, QWidget* parent)
- : urls_(urls),
+ : Task("listed_key_server_test_task"),
+ urls_(urls),
timeout_(timeout),
network_manager_(new QNetworkAccessManager(this)),
result_(urls_.size(), kTestResultType_Error) {
@@ -44,20 +45,20 @@ void GpgFrontend::UI::ListedKeyServerTestTask::run() {
size_t index = 0;
for (const auto& url : urls_) {
auto key_url = QUrl{url};
- LOG(INFO) << "key server request: " << key_url.host().toStdString();
+ SPDLOG_DEBUG("key server request: {}", key_url.host().toStdString());
auto* network_reply = network_manager_->get(QNetworkRequest{key_url});
auto* timer = new QTimer(this);
connect(network_reply, &QNetworkReply::finished, this,
[this, index, network_reply]() {
- LOG(INFO) << "key server domain reply"
- << urls_[index].toStdString();
+ SPDLOG_DEBUG("key server domain reply: {}",
+ urls_[index].toStdString());
this->slot_process_network_reply(index, network_reply);
});
connect(timer, &QTimer::timeout, this, [this, index, network_reply]() {
- LOG(INFO) << "timeout for key server" << urls_[index].toStdString();
+ SPDLOG_DEBUG("timeout for key server: {}", urls_[index].toStdString());
if (network_reply->isRunning()) {
network_reply->abort();
this->slot_process_network_reply(index, network_reply);
@@ -83,6 +84,6 @@ void GpgFrontend::UI::ListedKeyServerTestTask::slot_process_network_reply(
if (++result_count_ == urls_.size()) {
emit SignalKeyServerListTestResult(result_);
- emit SignalTaskFinished();
+ emit SignalTaskRunnableEnd(0);
}
}
diff --git a/src/ui/thread/ProxyConnectionTestThread.cpp b/src/ui/thread/ProxyConnectionTestThread.cpp
index 062f4774..8b113453 100644
--- a/src/ui/thread/ProxyConnectionTestThread.cpp
+++ b/src/ui/thread/ProxyConnectionTestThread.cpp
@@ -31,13 +31,13 @@ void GpgFrontend::UI::ProxyConnectionTestThread::run() {
auto proxies_list = QNetworkProxyFactory::systemProxyForQuery(npq);
if (proxies_list.isEmpty()) {
- LOG(INFO) << "no proxy applied";
+ SPDLOG_DEBUG("no proxy applied");
} else {
- LOG(INFO) << "proxies list hostname"
- << proxies_list.front().hostName().toStdString();
+ SPDLOG_DEBUG("proxies list hostname: {}",
+ proxies_list.front().hostName().toStdString());
}
- LOG(INFO) << "proxies list size" << proxies_list.size();
+ SPDLOG_DEBUG("proxies list size: {}", proxies_list.size());
auto manager = std::make_unique<QNetworkAccessManager>(nullptr);
QNetworkRequest url_request;
diff --git a/src/ui/thread/VersionCheckTask.cpp b/src/ui/thread/VersionCheckTask.cpp
index 7de3b511..e9490e1c 100644
--- a/src/ui/thread/VersionCheckTask.cpp
+++ b/src/ui/thread/VersionCheckTask.cpp
@@ -36,7 +36,8 @@
namespace GpgFrontend::UI {
VersionCheckTask::VersionCheckTask()
- : network_manager_(new QNetworkAccessManager(this)),
+ : Task("version_check_task"),
+ network_manager_(new QNetworkAccessManager(this)),
current_version_(std::string("v") + std::to_string(VERSION_MAJOR) + "." +
std::to_string(VERSION_MINOR) + "." +
std::to_string(VERSION_PATCH)) {
@@ -49,7 +50,7 @@ void VersionCheckTask::Run() {
try {
using namespace nlohmann;
- LOG(INFO) << "current version" << current_version_;
+ SPDLOG_DEBUG("current version: {}", current_version_);
std::string latest_version_url =
"https://api.github.com/repos/saturneric/gpgfrontend/releases/latest";
@@ -63,7 +64,8 @@ void VersionCheckTask::Run() {
version_.load_info_done = true;
} catch (...) {
- emit SignalTaskFinished();
+ SPDLOG_ERROR("unknown error occurred");
+ emit SignalTaskRunnableEnd(-1);
}
}
@@ -73,7 +75,7 @@ void VersionCheckTask::slot_parse_latest_version_info() {
try {
if (latest_reply_ == nullptr ||
latest_reply_->error() != QNetworkReply::NoError) {
- LOG(ERROR) << "latest version request error";
+ SPDLOG_ERROR("latest version request error");
version_.latest_version = current_version_;
} else {
latest_reply_bytes_ = latest_reply_->readAll();
@@ -83,16 +85,16 @@ void VersionCheckTask::slot_parse_latest_version_info() {
std::string latest_version = latest_reply_json["tag_name"];
- LOG(INFO) << "latest version from Github" << latest_version;
+ SPDLOG_INFO("latest version from Github: {}", latest_version);
QRegularExpression re(R"(^[vV](\d+\.)?(\d+\.)?(\*|\d+))");
auto version_match = re.match(latest_version.c_str());
if (version_match.hasMatch()) {
latest_version = version_match.captured(0).toStdString();
- LOG(INFO) << "latest version matched" << latest_version;
+ SPDLOG_DEBUG("latest version matched: {}", latest_version);
} else {
latest_version = current_version_;
- LOG(WARNING) << "latest version unknown";
+ SPDLOG_WARN("latest version unknown");
}
bool prerelease = latest_reply_json["prerelease"],
@@ -106,7 +108,7 @@ void VersionCheckTask::slot_parse_latest_version_info() {
version_.release_note = release_note;
}
} catch (...) {
- LOG(INFO) << "error occurred";
+ SPDLOG_ERROR("unknown error occurred");
version_.load_info_done = false;
}
@@ -126,8 +128,8 @@ void VersionCheckTask::slot_parse_latest_version_info() {
connect(current_reply_, &QNetworkReply::finished, this,
&VersionCheckTask::slot_parse_current_version_info);
} catch (...) {
- LOG(ERROR) << "current version request create error";
- emit SignalTaskFinished();
+ SPDLOG_ERROR("current version request create error");
+ emit SignalTaskRunnableEnd(-1);
}
}
@@ -135,12 +137,20 @@ void VersionCheckTask::slot_parse_current_version_info() {
try {
if (current_reply_ == nullptr ||
current_reply_->error() != QNetworkReply::NoError) {
- LOG(ERROR) << "current version request network error";
+ if (current_reply_ != nullptr) {
+ SPDLOG_ERROR("current version request network error: {}",
+ current_reply_->errorString().toStdString());
+ } else {
+ SPDLOG_ERROR(
+ "current version request network error, null reply object");
+ }
+
version_.current_version_found = false;
+ version_.load_info_done = false;
} else {
version_.current_version_found = true;
current_reply_bytes_ = current_reply_->readAll();
- LOG(INFO) << "current version" << current_reply_bytes_.size();
+ SPDLOG_DEBUG("current version: {}", current_reply_bytes_.size());
auto current_reply_json =
nlohmann::json::parse(current_reply_bytes_.toStdString());
bool current_prerelease = current_reply_json["prerelease"],
@@ -150,18 +160,19 @@ void VersionCheckTask::slot_parse_current_version_info() {
version_.load_info_done = true;
}
} catch (...) {
- LOG(INFO) << "error occurred";
+ SPDLOG_ERROR("unknown error occurred");
version_.load_info_done = false;
}
- LOG(INFO) << "current version parse done" << version_.current_version_found;
+ SPDLOG_DEBUG("current version parse done: {}",
+ version_.current_version_found);
if (current_reply_ != nullptr) {
current_reply_->deleteLater();
}
emit SignalUpgradeVersion(version_);
- emit SignalTaskFinished();
+ emit SignalTaskRunnableEnd(0);
}
} // namespace GpgFrontend::UI
diff --git a/src/ui/widgets/FilePage.cpp b/src/ui/widgets/FilePage.cpp
index fe188e93..144de3d8 100644
--- a/src/ui/widgets/FilePage.cpp
+++ b/src/ui/widgets/FilePage.cpp
@@ -108,7 +108,7 @@ void FilePage::slot_file_tree_view_item_clicked(const QModelIndex& index) {
#endif
m_path_ = selected_path_;
- LOG(INFO) << "selected path" << selected_path_.u8string();
+ SPDLOG_DEBUG("selected path: {}", selected_path_.u8string());
selected_path_ = std::filesystem::path(selected_path_);
MainWindow::CryptoMenu::OperationType operation_type =
@@ -164,10 +164,10 @@ void FilePage::slot_up_level() {
std::filesystem::path path_obj(str_path);
m_path_ = path_obj;
- LOG(INFO) << "get path" << m_path_;
+ SPDLOG_DEBUG("get path: {}", m_path_.u8string());
if (m_path_.has_parent_path() && !m_path_.parent_path().empty()) {
m_path_ = m_path_.parent_path();
- LOG(INFO) << "parent path" << m_path_;
+ SPDLOG_DEBUG("parent path: {}", m_path_.u8string());
ui_->pathEdit->setText(m_path_.u8string().c_str());
this->SlotGoPath();
}
@@ -204,7 +204,7 @@ void FilePage::SlotGoPath() {
m_path_ = std::filesystem::path(fileInfo.filePath().toStdString());
#endif
- LOG(INFO) << "set path" << m_path_.u8string();
+ SPDLOG_DEBUG("set path: {}", m_path_.u8string());
ui_->fileTreeView->setRootIndex(dir_model_->index(fileInfo.filePath()));
dir_model_->setRootPath(fileInfo.filePath());
for (int i = 1; i < dir_model_->columnCount(); ++i) {
@@ -267,7 +267,7 @@ void FilePage::create_popup_menu() {
auto showHiddenAct = new QAction(_("Show Hidden File"), this);
showHiddenAct->setCheckable(true);
connect(showHiddenAct, &QAction::triggered, this, [&](bool checked) {
- LOG(INFO) << "Set Hidden" << checked;
+ SPDLOG_DEBUG("set hidden: {}", checked);
if (checked)
dir_model_->setFilter(dir_model_->filter() | QDir::Hidden);
else
@@ -279,7 +279,7 @@ void FilePage::create_popup_menu() {
auto showSystemAct = new QAction(_("Show System File"), this);
showSystemAct->setCheckable(true);
connect(showSystemAct, &QAction::triggered, this, [&](bool checked) {
- LOG(INFO) << "Set Hidden" << checked;
+ SPDLOG_DEBUG("set hidden: {}", checked);
if (checked)
dir_model_->setFilter(dir_model_->filter() | QDir::System);
else
@@ -291,7 +291,7 @@ void FilePage::create_popup_menu() {
void FilePage::onCustomContextMenu(const QPoint& point) {
QModelIndex index = ui_->fileTreeView->indexAt(point);
- LOG(INFO) << "right click" << selected_path_.u8string();
+ SPDLOG_DEBUG("right click: {}", selected_path_.u8string());
#ifdef WINDOWS
auto index_dir_str =
@@ -328,7 +328,7 @@ void FilePage::slot_open_item() {
if (info.isDir()) {
if (info.isReadable() && info.isExecutable()) {
const auto file_path = info.filePath().toUtf8().toStdString();
- LOG(INFO) << "set path" << file_path;
+ SPDLOG_DEBUG("set path: {}", file_path);
ui_->pathEdit->setText(info.filePath().toUtf8());
SlotGoPath();
} else {
@@ -340,7 +340,7 @@ void FilePage::slot_open_item() {
// handle normal text or binary file
auto main_window = qobject_cast<MainWindow*>(first_parent_);
auto qt_open_path = QString::fromStdString(selected_path_.u8string());
- LOG(INFO) << "open item" << qt_open_path.toStdString();
+ SPDLOG_DEBUG("open item: {}", qt_open_path.toStdString());
if (main_window != nullptr) main_window->SlotOpenFile(qt_open_path);
} else {
QMessageBox::critical(this, _("Error"),
@@ -365,12 +365,12 @@ void FilePage::slot_rename_item() {
#else
new_name_path /= text.toStdString();
#endif
- LOG(INFO) << "new name path" << new_name_path;
+ SPDLOG_DEBUG("new name path: {}", new_name_path.u8string());
std::filesystem::rename(old_name_path, new_name_path);
// refresh
this->SlotGoPath();
} catch (...) {
- LOG(ERROR) << "rename error" << new_name_path;
+ SPDLOG_ERROR("rename error: {}", new_name_path.u8string());
QMessageBox::critical(this, _("Error"),
_("Unable to rename the file or folder."));
}
@@ -387,7 +387,7 @@ void FilePage::slot_delete_item() {
if (ret == QMessageBox::Cancel) return;
- LOG(INFO) << "Delete Item" << data.toString().toStdString();
+ SPDLOG_DEBUG("delete item: {}", data.toString().toStdString());
if (!dir_model_->remove(index)) {
QMessageBox::critical(this, _("Error"),
@@ -441,7 +441,7 @@ void FilePage::slot_create_empty_file() {
}
void FilePage::keyPressEvent(QKeyEvent* event) {
- LOG(INFO) << "Key Press" << event->key();
+ SPDLOG_DEBUG("key press: {}", event->key());
if (ui_->pathEdit->hasFocus() &&
(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)) {
SlotGoPath();
diff --git a/src/ui/widgets/InfoBoardWidget.cpp b/src/ui/widgets/InfoBoardWidget.cpp
index 74ead2ce..98b07089 100644
--- a/src/ui/widgets/InfoBoardWidget.cpp
+++ b/src/ui/widgets/InfoBoardWidget.cpp
@@ -85,7 +85,6 @@ void InfoBoardWidget::SetInfoBoard(const QString& text,
auto info_font_size =
general_settings_state.Check("text_editor").Check("font_size", 10);
ui_->infoBoard->setFont(QFont("Times", info_font_size));
-
}
void InfoBoardWidget::SlotRefresh(const QString& text, InfoBoardStatus status) {
@@ -114,7 +113,7 @@ void InfoBoardWidget::AssociateTabWidget(QTabWidget* tab) {
void InfoBoardWidget::AddOptionalAction(const QString& name,
const std::function<void()>& action) {
- LOG(INFO) << "add option" << name.toStdString();
+ SPDLOG_DEBUG("add option: {}", name.toStdString());
auto actionButton = new QPushButton(name);
auto layout = new QHBoxLayout();
layout->setContentsMargins(5, 0, 5, 0);
@@ -144,8 +143,6 @@ void InfoBoardWidget::SlotReset() {
*/
void InfoBoardWidget::delete_widgets_in_layout(QLayout* layout,
int start_index) {
- LOG(INFO) << "Called";
-
QLayoutItem* item;
while ((item = layout->layout()->takeAt(start_index)) != nullptr) {
layout->removeItem(item);
@@ -165,7 +162,7 @@ void InfoBoardWidget::slot_copy() {
void InfoBoardWidget::slot_save() {
auto file_path = QFileDialog::getSaveFileName(
this, _("Save Information Board's Content"), {}, tr("Text (*.txt)"));
- LOG(INFO) << "file path" << file_path.toStdString();
+ SPDLOG_DEBUG("file path: {}", file_path.toStdString());
if (file_path.isEmpty()) return;
QFile file(file_path);
diff --git a/src/ui/widgets/KeyList.cpp b/src/ui/widgets/KeyList.cpp
index 9150d580..e426ed48 100644
--- a/src/ui/widgets/KeyList.cpp
+++ b/src/ui/widgets/KeyList.cpp
@@ -100,7 +100,7 @@ void KeyList::AddListGroupTab(
const QString& name, KeyListRow::KeyType selectType,
KeyListColumn::InfoType infoType,
const std::function<bool(const GpgKey&)>& filter) {
- LOG(INFO) << _("Called") << name.toStdString();
+ SPDLOG_DEBUG("add tab: {}", name.toStdString());
auto key_list = new QTableWidget(this);
if (m_key_list_ == nullptr) {
@@ -158,7 +158,7 @@ void KeyList::AddListGroupTab(
}
void KeyList::SlotRefresh() {
- LOG(INFO) << _("called") << "address" << this;
+ SPDLOG_DEBUG("refresh, address: {}", static_cast<void*>(this));
ui_->refreshKeyListButton->setDisabled(true);
ui_->syncButton->setDisabled(true);
@@ -317,10 +317,10 @@ void KeyList::dropEvent(QDropEvent* event) {
bool confirm_import_keys = true;
try {
confirm_import_keys = settings.lookup("general.confirm_import_keys");
- LOG(INFO) << "confirm_import_keys" << confirm_import_keys;
+ SPDLOG_DEBUG("confirm_import_keys: {}", confirm_import_keys);
if (confirm_import_keys) checkBox->setCheckState(Qt::Checked);
} catch (...) {
- LOG(ERROR) << _("Setting Operation Error") << _("confirm_import_keys");
+ SPDLOG_ERROR("setting operation error: confirm_import_keys");
}
// Buttons for ok and cancel
@@ -358,8 +358,7 @@ void KeyList::dropEvent(QDropEvent* event) {
QFile file;
file.setFileName(tmp.toLocalFile());
if (!file.open(QIODevice::ReadOnly)) {
- LOG(INFO) << _("Couldn't Open File") << ":"
- << tmp.toString().toStdString();
+ SPDLOG_ERROR("couldn't open file: {}", tmp.toString().toStdString());
}
QByteArray inBuffer = file.readAll();
this->import_keys(inBuffer);
@@ -379,7 +378,7 @@ void KeyList::dragEnterEvent(QDragEnterEvent* event) {
*
*/
[[maybe_unused]] void KeyList::MarkKeys(QStringList* keyIds) {
- foreach (QString id, *keyIds) { qDebug() << "marked: " << id; }
+ foreach (QString id, *keyIds) { spdlog::debug("marked: ", id.toStdString()); }
}
void KeyList::import_keys(const QByteArray& inBuffer) {
@@ -419,7 +418,7 @@ std::string KeyList::GetSelectedKey() {
}
void KeyList::slot_refresh_ui() {
- LOG(INFO) << _("Called") << buffered_keys_list_.get();
+ SPDLOG_DEBUG("refresh: {}", static_cast<void*>(buffered_keys_list_.get()));
if (buffered_keys_list_ != nullptr) {
std::lock_guard<std::mutex> guard(buffered_key_list_mutex_);
for (auto& key_table : m_key_tables_) {
@@ -451,8 +450,8 @@ void KeyList::slot_sync_with_key_server() {
CommonUtils::SlotImportKeyFromKeyServer(
key_ids, [=](const std::string& key_id, const std::string& status,
size_t current_index, size_t all_index) {
- LOG(INFO) << _("Called") << key_id << status << current_index
- << all_index;
+ SPDLOG_DEBUG("import key: {} {} {} {}", key_id, status, current_index,
+ all_index);
auto key = GpgKeyGetter::GetInstance().GetKey(key_id);
boost::format status_str = boost::format(_("Sync [%1%/%2%] %3% %4%")) %
@@ -503,7 +502,7 @@ KeyIdArgsListPtr& KeyTable::GetChecked() {
auto& ret = checked_key_ids_;
for (int i = 0; i < buffered_keys_.size(); i++) {
auto key_id = buffered_keys_[i].GetId();
- LOG(INFO) << "i: " << i << " key_id: " << key_id;
+ SPDLOG_DEBUG("i: {} key_id: {}", i, key_id);
if (key_list_->item(i, 0)->checkState() == Qt::Checked &&
std::find(ret->begin(), ret->end(), key_id) == ret->end()) {
ret->push_back(key_id);
@@ -513,7 +512,6 @@ KeyIdArgsListPtr& KeyTable::GetChecked() {
}
void KeyTable::SetChecked(KeyIdArgsListPtr key_ids) {
- LOG(INFO) << "called";
checked_key_ids_ = std::move(key_ids);
}
@@ -535,14 +533,14 @@ void KeyTable::Refresh(KeyLinkListPtr m_keys) {
int row_count = 0;
while (it != keys->end()) {
- LOG(INFO) << "filtering key id: " << it->GetId();
+ SPDLOG_DEBUG("filtering key id: {}", it->GetId());
if (filter_ != nullptr) {
if (!filter_(*it)) {
it = keys->erase(it);
continue;
}
}
- LOG(INFO) << "adding key id: " << it->GetId();
+ SPDLOG_DEBUG("adding key id: {}", it->GetId());
if (select_type_ == KeyListRow::ONLY_SECRET_KEY && !it->IsPrivateKey()) {
it = keys->erase(it);
continue;
@@ -625,7 +623,8 @@ void KeyTable::Refresh(KeyLinkListPtr m_keys) {
tmp3->setFont(strike);
}
- LOG(INFO) << "key id: " << it->GetId() << "added into key_list_:" << this;
+ SPDLOG_DEBUG("key id: {} added into key_list_: {}", it->GetId(),
+ static_cast<void*>(this));
// move to buffered keys
buffered_keys_.emplace_back(std::move(*it));
diff --git a/src/ui/widgets/PlainTextEditorPage.cpp b/src/ui/widgets/PlainTextEditorPage.cpp
index 10e19b8b..c9a65a4c 100644
--- a/src/ui/widgets/PlainTextEditorPage.cpp
+++ b/src/ui/widgets/PlainTextEditorPage.cpp
@@ -160,8 +160,6 @@ void PlainTextEditorPage::slot_format_gpg_header() {
}
void PlainTextEditorPage::ReadFile() {
- LOG(INFO) << "called";
-
read_done_ = false;
read_bytes_ = 0;
ui_->textPage->setEnabled(false);
@@ -184,10 +182,10 @@ void PlainTextEditorPage::ReadFile() {
connect(this, &PlainTextEditorPage::SignalUIBytesDisplayed, read_task,
&FileReadTask::SignalFileBytesReadNext, Qt::QueuedConnection);
- connect(read_task, &FileReadTask::SignalTaskFinished, this,
- []() { LOG(INFO) << "read thread closed"; });
+ connect(read_task, &FileReadTask::SignalTaskRunnableEnd, this,
+ []() { SPDLOG_DEBUG("read thread closed"); });
connect(this, &PlainTextEditorPage::close, read_task,
- &FileReadTask::SignalTaskFinished);
+ [=]() { read_task->SignalTaskRunnableEnd(0); });
connect(read_task, &FileReadTask::SignalFileBytesReadEnd, this, [=]() {
// set the UI
if (!binary_mode_) text_page->setReadOnly(false);
@@ -212,7 +210,7 @@ std::string binary_to_string(const std::string &source) {
void PlainTextEditorPage::slot_insert_text(QByteArray bytes_data) {
std::string data = bytes_data.toStdString();
- LOG(INFO) << "data size" << data.size();
+ SPDLOG_DEBUG("data size: {}", data.size());
read_bytes_ += data.size();
// If binary format is detected, the entire file is converted to binary
// format for display.
@@ -260,7 +258,6 @@ void PlainTextEditorPage::slot_insert_text(QByteArray bytes_data) {
this->ui_->characterLabel->setText(str.str().c_str());
}
QTimer::singleShot(25, this, &PlainTextEditorPage::SignalUIBytesDisplayed);
- LOG(INFO) << "end";
}
void PlainTextEditorPage::detect_encoding(const std::string &data) {
diff --git a/src/ui/widgets/TextEdit.cpp b/src/ui/widgets/TextEdit.cpp
index 713dbb80..4947e179 100644
--- a/src/ui/widgets/TextEdit.cpp
+++ b/src/ui/widgets/TextEdit.cpp
@@ -29,6 +29,11 @@
#include "ui/widgets/TextEdit.h"
#include <boost/format.hpp>
+#include <string>
+#include <tuple>
+#include <vector>
+
+#include "spdlog/spdlog.h"
namespace GpgFrontend::UI {
@@ -61,6 +66,8 @@ void TextEdit::SlotNewTab() {
page->GetTextPage()->setFocus();
connect(page->GetTextPage()->document(), &QTextDocument::modificationChanged,
this, &TextEdit::SlotShowModified);
+ connect(page->GetTextPage()->document(), &QTextDocument::contentsChanged,
+ this, &TextEdit::slot_save_status_to_cache_for_revovery);
}
void TextEdit::slotNewHelpTab(const QString& title, const QString& path) const {
@@ -79,15 +86,18 @@ void TextEdit::SlotNewFileTab() const {
page->SlotGoPath();
}
-void TextEdit::SlotOpenFile(QString& path) {
+void TextEdit::SlotOpenFile(const QString& path) {
QFile file(path);
- LOG(INFO) << "path" << path.toStdString();
+ SPDLOG_DEBUG("path: {}", path.toStdString());
auto result = file.open(QIODevice::ReadOnly | QIODevice::Text);
if (result) {
auto* page = new PlainTextEditorPage(path);
connect(page->GetTextPage()->document(),
&QTextDocument::modificationChanged, this,
&TextEdit::SlotShowModified);
+ // connect to cache recovery fucntion
+ connect(page->GetTextPage()->document(), &QTextDocument::contentsChanged,
+ this, &TextEdit::slot_save_status_to_cache_for_revovery);
QApplication::setOverrideCursor(Qt::WaitCursor);
auto index = tab_widget_->addTab(page, stripped_name(path));
@@ -112,35 +122,7 @@ void TextEdit::SlotOpen() {
QFileDialog::getOpenFileNames(this, _("Open file"), QDir::currentPath());
for (const auto& file_name : file_names) {
if (!file_name.isEmpty()) {
- QFile file(file_name);
-
- if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- auto* page = new PlainTextEditorPage(file_name);
-
- QTextStream in(&file);
- QApplication::setOverrideCursor(Qt::WaitCursor);
- page->GetTextPage()->setPlainText(in.readAll());
- page->SetFilePath(file_name);
- QTextDocument* document = page->GetTextPage()->document();
- document->setModified(false);
-
- tab_widget_->addTab(page, stripped_name(file_name));
- tab_widget_->setCurrentIndex(tab_widget_->count() - 1);
- QApplication::restoreOverrideCursor();
- page->GetTextPage()->setFocus();
- connect(page->GetTextPage()->document(),
- &QTextDocument::modificationChanged, this,
- &TextEdit::SlotShowModified);
- // enableAction(true)
- file.close();
- } else {
- QMessageBox::warning(
- this, _("Warning"),
- (boost::format(_("Cannot read file %1%:\n%2%.")) %
- file_name.toStdString() % file.errorString().toStdString())
- .str()
- .c_str());
- }
+ SlotOpenFile(file_name);
}
}
}
@@ -477,9 +459,17 @@ void TextEdit::SlotPrint() {
#endif
}
-void TextEdit::SlotShowModified() const {
+void TextEdit::SlotShowModified(bool changed) const {
+ // get current tab
int index = tab_widget_->currentIndex();
QString title = tab_widget_->tabText(index);
+
+ // if changed
+ if (!changed) {
+ tab_widget_->setTabText(index, title.remove(0, 2));
+ return;
+ }
+
// if doc is modified now, add leading * to title,
// otherwise remove the leading * from the title
if (CurTextPage()->GetTextPage()->document()->isModified()) {
@@ -516,7 +506,7 @@ QHash<int, QString> TextEdit::UnsavedDocuments() const {
if (ep != nullptr && ep->ReadDone() &&
ep->GetTextPage()->document()->isModified()) {
QString doc_name = tab_widget_->tabText(i);
- LOG(INFO) << "unsaved" << doc_name.toStdString();
+ SPDLOG_DEBUG("unsaved: {}", doc_name.toStdString());
// remove * before name of modified doc
doc_name.remove(0, 2);
@@ -608,4 +598,43 @@ void TextEdit::slot_file_page_path_changed(const QString& path) const {
tab_widget_->setTabText(index, mPath);
}
+void TextEdit::slot_save_status_to_cache_for_revovery() {
+ SPDLOG_DEBUG("catch text page modified event, count: {}",
+ text_page_data_modified_count_);
+ if (this->text_page_data_modified_count_++ % 3 != 0) return;
+
+ int tab_count = tab_widget_->count();
+ SPDLOG_DEBUG("current tabs count {}", tab_count);
+
+ std::vector<std::pair<int, std::string>> saved_pages;
+ std::vector<std::tuple<int, std::string, std::string>> unsaved_pages;
+
+ for (int i = 0; i < tab_count; i++) {
+ auto* target_page =
+ qobject_cast<PlainTextEditorPage*>(tab_widget_->widget(i));
+
+ // if this page is no textedit, there should be nothing to save
+ if (target_page == nullptr) {
+ continue;
+ }
+
+ auto* document = target_page->GetTextPage()->document();
+ auto tab_title = tab_widget_->tabText(i).toStdString();
+ if (!target_page->ReadDone() || !target_page->isEnabled() ||
+ !document->isModified()) {
+ auto file_path = target_page->GetFilePath().toStdString();
+ SPDLOG_DEBUG("saved page index: {}, tab title: {} tab file path: {}", i,
+ tab_title, file_path);
+
+ saved_pages.push_back({i, file_path});
+ continue;
+ }
+
+ auto raw_text = document->toRawText().toStdString();
+ SPDLOG_DEBUG("unsaved page index: {}, tab title: {} tab content: {}", i,
+ tab_title, raw_text.size());
+ unsaved_pages.push_back({i, tab_title, raw_text});
+ }
+}
+
} // namespace GpgFrontend::UI
diff --git a/src/ui/widgets/TextEdit.h b/src/ui/widgets/TextEdit.h
index cb32bfb2..2e2f949d 100644
--- a/src/ui/widgets/TextEdit.h
+++ b/src/ui/widgets/TextEdit.h
@@ -153,7 +153,7 @@ class TextEdit : public QWidget {
/**
* @details Adds a new tab with opening file by path
*/
- void SlotOpenFile(QString& path);
+ void SlotOpenFile(const QString& path);
/**
* @details Adds a new tab with the given title and opens given html file.
@@ -172,7 +172,7 @@ class TextEdit : public QWidget {
* @details put a * in front of current tabs title, if current textedit is
* modified
*/
- void SlotShowModified() const;
+ void SlotShowModified(bool) const;
/**
* @details close the current tab and decrease TabWidget->count by \a 1
@@ -193,6 +193,8 @@ class TextEdit : public QWidget {
void SlotSwitchTabDown() const;
private:
+ uint text_page_data_modified_count_ = 0; ///<
+
/**
* @details return just a filename stripped of a whole path
*
@@ -221,6 +223,13 @@ class TextEdit : public QWidget {
*/
void slot_remove_tab(int index);
+ /**
+ * @brief
+ *
+ * @param index
+ */
+ void slot_save_status_to_cache_for_revovery();
+
public slots:
/**
diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt
index 04068ca1..c7912e31 100644
--- a/third_party/CMakeLists.txt
+++ b/third_party/CMakeLists.txt
@@ -26,4 +26,6 @@
# json
set(JSON_BuildTests OFF CACHE INTERNAL "")
-add_subdirectory(json EXCLUDE_FROM_ALL) \ No newline at end of file
+add_subdirectory(json EXCLUDE_FROM_ALL)
+
+add_subdirectory(spdlog EXCLUDE_FROM_ALL) \ No newline at end of file
diff --git a/third_party/easyloggingpp b/third_party/easyloggingpp
deleted file mode 160000
-Subproject 8489989bb26c6371df103f6cbced3fbee1bc3c2
diff --git a/third_party/gpgme b/third_party/gpgme
-Subproject cc37447b625b45efb5c94c40461084460f03f24
+Subproject 64da77620a451653e9b8c41bb0c9e58e2296712
diff --git a/third_party/json b/third_party/json
-Subproject c6740d7d58a209da8960c961ee07bfb0e841e44
+Subproject da6b908c4fe63d8c6192c78f00d43ddb40cc563
diff --git a/third_party/libarchive b/third_party/libarchive
-Subproject b1b501161013296d19dfe9acb84a341c8a1755b
+Subproject 90799596b2ef2f847d669b610919e8d51a38250
diff --git a/third_party/libassuan b/third_party/libassuan
-Subproject 335030e3d204afe33873df83c29302ff1caa021
+Subproject e4e54fb4ba1b82f1cd08ea44ad4c48db4c23631
diff --git a/third_party/libconfig b/third_party/libconfig
-Subproject 020a9ce12d1be7ab79ca0674fc957e732ab67f4
+Subproject 4f13b7f5152427b5e511a09617ca2d9ff63f780
diff --git a/third_party/libgpg-error b/third_party/libgpg-error
-Subproject 220a427b4f997ef6af1b2d4e82ef1dc96e0cd6f
+Subproject 885a287a57cf060b4c5b441822c09d23b8dee2b
diff --git a/third_party/qt-aes b/third_party/qt-aes
-Subproject 845e3b4d3d3873843ca26dc365232aa1aa8ea2a
+Subproject 27410ebf00328951cd81a6242a3e8c2d508f64a
diff --git a/third_party/spdlog b/third_party/spdlog
new file mode 160000
+Subproject 927cc29444a294d76e83dfb898e797dc431ce09
diff --git a/ui/GeneralSettings.ui b/ui/GeneralSettings.ui
index 4121e762..75aef6b2 100644
--- a/ui/GeneralSettings.ui
+++ b/ui/GeneralSettings.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>643</width>
- <height>656</height>
+ <height>721</height>
</rect>
</property>
<property name="windowTitle">
@@ -17,37 +17,24 @@
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
- <widget class="QGroupBox" name="longerKeyExpirationDateBox">
+ <widget class="QGroupBox" name="cacheBox">
<property name="title">
- <string>Longer Key Expiration Date</string>
+ <string>Cache</string>
</property>
- <layout class="QGridLayout" name="gridLayout_2">
+ <layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
- <layout class="QVBoxLayout" name="verticalLayout_2">
+ <layout class="QVBoxLayout" name="verticalLayout_3">
<item>
- <widget class="QCheckBox" name="longerKeyExpirationDateCheckBox">
+ <widget class="QCheckBox" name="saveCheckedKeysCheckBox">
<property name="text">
- <string>Unlock key expiration date setting up to 30 years.</string>
+ <string>Save checked keys in Key ToolBox on exit and restore them on next start.</string>
</property>
</widget>
</item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="saveCheckedKeysBox">
- <property name="title">
- <string>Save Checked Keys</string>
- </property>
- <layout class="QGridLayout" name="gridLayout_3">
- <item row="0" column="0">
- <layout class="QVBoxLayout" name="verticalLayout_3">
<item>
- <widget class="QCheckBox" name="saveCheckedKeysCheckBox">
+ <widget class="QCheckBox" name="clearGpgPasswordCacheCheckBox">
<property name="text">
- <string>Save checked private keys on exit and restore them on next start.</string>
+ <string>Clear gpg password cache when closing GpgFrontend.</string>
</property>
</widget>
</item>
@@ -59,7 +46,7 @@
<item>
<widget class="QGroupBox" name="importConfirmationBox">
<property name="title">
- <string>Confirm drag'n'drop key import</string>
+ <string>Operation</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
@@ -71,70 +58,75 @@
</property>
</widget>
</item>
+ <item>
+ <widget class="QCheckBox" name="longerKeyExpirationDateCheckBox">
+ <property name="text">
+ <string>Enable to use longer key expiration date.</string>
+ </property>
+ </widget>
+ </item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
- <widget class="QGroupBox" name="asciiModeBox">
+ <widget class="QGroupBox" name="gnupgDatabaseBox">
<property name="title">
- <string>ASCII Mode</string>
+ <string>GnuPG</string>
</property>
- <layout class="QGridLayout" name="gridLayout_6">
+ <layout class="QGridLayout" name="gridLayout_7">
<item row="0" column="0">
- <layout class="QVBoxLayout" name="verticalLayout_6">
+ <layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QCheckBox" name="asciiModeCheckBox">
<property name="text">
- <string>ASCII encoding is not used when file encrypting and signing.</string>
+ <string>No ASCII Mode</string>
</property>
</widget>
</item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="langBox">
- <property name="title">
- <string>Language</string>
- </property>
- <layout class="QGridLayout" name="gridLayout_5">
- <item row="0" column="0">
- <layout class="QVBoxLayout" name="verticalLayout_5">
<item>
- <widget class="QComboBox" name="langSelectBox">
- <property name="sizeAdjustPolicy">
- <enum>QComboBox::AdjustToContents</enum>
+ <widget class="Line" name="line_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
- <widget class="QLabel" name="langNoteLabel">
+ <widget class="QCheckBox" name="useCustomGnuPGInstallPathCheckBox">
<property name="text">
- <string>NOTE: GpgFrontend will restart automatically if you change the language!</string>
+ <string>Use Custom GnuPG</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="currentCustomGnuPGInstallPathLabel">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="useCustomGnuPGInstallPathButton">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Select GnuPG Path</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="gnupgDatabaseBox">
- <property name="title">
- <string>GnuPG Key Database Path</string>
- </property>
- <layout class="QGridLayout" name="gridLayout_7">
- <item row="0" column="0">
- <layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QCheckBox" name="keyDatabseUseCustomCheckBox">
<property name="text">
- <string>Use Custom Path</string>
+ <string>Use Custom GnuPG Key Database Path</string>
</property>
</widget>
</item>
@@ -154,7 +146,34 @@
<bool>false</bool>
</property>
<property name="text">
- <string>Select Custom Path</string>
+ <string>Select Key Database Path</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="langBox">
+ <property name="title">
+ <string>Language</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_5">
+ <item row="0" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <item>
+ <widget class="QComboBox" name="langSelectBox">
+ <property name="sizeAdjustPolicy">
+ <enum>QComboBox::AdjustToContents</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="langNoteLabel">
+ <property name="text">
+ <string>NOTE: GpgFrontend will restart automatically if you change the language!</string>
</property>
</widget>
</item>
diff --git a/ui/GnuPGInfo.ui b/ui/GnuPGInfo.ui
index f907874f..efb895af 100644
--- a/ui/GnuPGInfo.ui
+++ b/ui/GnuPGInfo.ui
@@ -16,17 +16,20 @@
<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>5</number>
+ <number>0</number>
</property>
<property name="topMargin">
- <number>5</number>
+ <number>0</number>
</property>
<property name="rightMargin">
- <number>5</number>
+ <number>0</number>
</property>
<property name="bottomMargin">
- <number>5</number>
+ <number>0</number>
</property>
<item>
<widget class="QLabel" name="label">
@@ -51,6 +54,19 @@
</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">
@@ -64,27 +80,52 @@
</widget>
</item>
<item>
- <widget class="QLabel" name="componentDetailsTableTitle">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Components Information</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="tabShape">
+ <enum>QTabWidget::Rounded</enum>
</property>
- <property name="margin">
- <number>5</number>
+ <property name="currentIndex">
+ <number>0</number>
</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>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_2">
+ <attribute name="title">
+ <string>Configurations</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="QTableWidget" name="configurationDetailsTable">
+ <property name="sizeAdjustPolicy">
+ <enum>QAbstractScrollArea::AdjustToContents</enum>
+ </property>
+ <property name="editTriggers">
+ <set>QAbstractItemView::NoEditTriggers</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
</widget>
</item>
- <item>
- <widget class="QTableWidget" name="conponentDetailsTable"/>
- </item>
</layout>
</item>
</layout>