aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSaturneric <[email protected]>2021-07-04 19:17:53 +0000
committerSaturneric <[email protected]>2021-07-04 19:17:53 +0000
commitfe2f448d517bb0f7d37c22fe99b2bd13ef1a61c3 (patch)
tree952ad3bc8cb5f76c0d1e02792a62a3825ef6fdf0
parentAdjust and improve the basic settings page (diff)
parentUpdate Github Action Files. (diff)
downloadGpgFrontend-fe2f448d517bb0f7d37c22fe99b2bd13ef1a61c3.tar.gz
GpgFrontend-fe2f448d517bb0f7d37c22fe99b2bd13ef1a61c3.zip
Merge branch 'main' into develop
-rw-r--r--.github/workflows/debug.yml2
-rw-r--r--.github/workflows/release-ci.yml186
-rw-r--r--.github/workflows/release.yml41
-rw-r--r--CMakeLists.txt1
-rw-r--r--README.md60
-rw-r--r--README_CN.md172
-rw-r--r--include/GpgFrontend.h.in2
-rw-r--r--include/gpg/GpgContext.h2
-rw-r--r--include/ui/KeyUploadDialog.h6
-rw-r--r--resource/gpgfrontend/usr/share/applications/gpgfrontend.desktop7
-rwxr-xr-xresource/gpgfrontend/usr/share/icons/hicolor/200x200/apps/gpgfrontend-appimage-icon.pngbin0 -> 5651 bytes
-rw-r--r--resource/ts/gpg_frontend_fr.ts50
-rw-r--r--resource/ts/gpg_frontend_ru.ts50
-rw-r--r--resource/ts/gpgfrontend_en_us.ts50
-rw-r--r--resource/ts/gpgfrontend_zh_chs.ts50
-rw-r--r--resource/ts/gpgfrontend_zh_cht.ts50
-rw-r--r--src/CMakeLists.txt46
-rw-r--r--src/gpg/GpgContext.cpp37
-rw-r--r--src/ui/KeyImportDetailDialog.cpp5
-rw-r--r--src/ui/KeyServerImportDialog.cpp5
-rw-r--r--src/ui/KeyUploadDialog.cpp45
-rw-r--r--src/ui/Wizard.cpp55
-rw-r--r--src/ui/keypair_details/KeyPairDetailTab.cpp14
-rw-r--r--src/ui/keypair_details/KeyPairSubkeyTab.cpp5
-rw-r--r--src/ui/main_window/MainWindowSlotFunction.cpp4
25 files changed, 691 insertions, 254 deletions
diff --git a/.github/workflows/debug.yml b/.github/workflows/debug.yml
index c09112f1..2de9716c 100644
--- a/.github/workflows/debug.yml
+++ b/.github/workflows/debug.yml
@@ -5,12 +5,14 @@ on:
branches: [ develop ]
paths-ignore:
- '**/README.md'
+ - '**/README_CN.md'
- 'resource/ts/**'
- 'docs/**'
pull_request:
branches: [ develop ]
paths-ignore:
- '**/README.md'
+ - '**/README_CN.md'
- 'resource/ts/**'
- 'docs/**'
diff --git a/.github/workflows/release-ci.yml b/.github/workflows/release-ci.yml
new file mode 100644
index 00000000..e4371bfc
--- /dev/null
+++ b/.github/workflows/release-ci.yml
@@ -0,0 +1,186 @@
+name: Build & Package CI Test
+
+on:
+ push:
+ branches: [ develop-ci ]
+ paths-ignore:
+ - '**/README.md'
+ - '**/README_CN.md'
+ - 'resource/ts/**'
+ - 'docs/**'
+ pull_request:
+ branches: [ develop-ci ]
+ paths-ignore:
+ - '**/README.md'
+ - '**/README_CN.md'
+ - 'resource/ts/**'
+ - 'docs/**'
+
+env:
+ # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
+ BUILD_TYPE: Release
+ EXECUTABLE_OUTPUT_PATH: ./
+
+jobs:
+ build:
+ strategy:
+ matrix:
+ os: [ 'ubuntu-16.04', 'macos-latest', 'windows-latest' ]
+ runs-on: ${{ matrix.os }}
+ steps:
+
+ - uses: actions/checkout@v2
+
+ - name: Install Dependence (Linux)
+ run: |
+ sudo apt-get update
+ sudo apt-get -y install build-essential binutils git autoconf automake gettext texinfo
+ sudo apt-get -y install gcc g++
+ 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 ninja-build
+ 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-*
+ if: matrix.os == 'ubuntu-16.04'
+
+ - name: Install Dependence (macOS)
+ run: |
+ brew install cmake git autoconf automake qt@5 gcc texinfo gettext libgpg-error libassuan gpgme openssl
+ brew link qt@5
+ brew link gcc
+ brew link openssl --force
+ if: matrix.os == 'macos-latest'
+
+ - name: Cache Qt
+ id: cache-qt
+ uses: actions/cache@v1
+ with:
+ path: ../Qt
+ key: ${{ runner.os }}-QtCache
+ if: matrix.os == 'ubuntu-16.04'
+
+ - name: Install Qt
+ uses: jurplel/install-qt-action@v2
+ with:
+ cached: ${{ steps.cache-qt.outputs.cache-hit }}
+ if: matrix.os == 'ubuntu-16.04'
+
+ - name: Set up MinGW (Windows)
+ uses: msys2/setup-msys2@v2
+ with:
+ install: git msys2-devel base-devel binutils mingw-w64-x86_64-toolchain
+ release: false
+ if: matrix.os == 'windows-latest'
+
+ - name: Set up Dependence (Windows)
+ shell: msys2 {0}
+ run: |
+ pacman --noconfirm -S --needed mingw-w64-x86_64-gcc mingw-w64-x86_64-make mingw-w64-x86_64-cmake autoconf automake mingw-w64-x86_64-qt-creator mingw-w64-x86_64-gpgme
+ pacman --noconfirm -S --needed make texinfo
+ if: matrix.os == 'windows-latest'
+
+ - name: Build gpg-error (Linux)
+ run: |
+ cd ${{github.workspace}}/..
+ git clone https://github.com/saturneric/libgpg-error
+ cd libgpg-error
+ ./autogen.sh
+ ./configure --enable-maintainer-mode --enable-static=yes && make -j2
+ sudo make install
+ cd ${{github.workspace}}
+ if: matrix.os == 'ubuntu-16.04'
+
+ - name: Build assuan (Linux)
+ run: |
+ cd ${{github.workspace}}/..
+ git clone https://github.com/saturneric/libassuan
+ cd libassuan
+ ./autogen.sh
+ ./configure --enable-maintainer-mode --enable-static=yes && make -j2
+ sudo make install
+ cd ${{github.workspace}}
+ if: matrix.os == 'ubuntu-16.04'
+
+ - name: Build GpgME (Linux)
+ run: |
+ cd ${{github.workspace}}/..
+ git clone https://github.com/saturneric/gpgme
+ cd gpgme
+ ./autogen.sh
+ ./configure --enable-maintainer-mode --enable-static=yes --enable-languages=cpp && make -j2
+ sudo make install
+ cd ${{github.workspace}}
+ if: matrix.os == 'ubuntu-16.04'
+
+ - name: Build GpgME (Windows)
+ shell: msys2 {0}
+ run: |
+ git clone https://github.com/saturneric/gpgme
+ cd gpgme
+ ./autogen.sh
+ ./configure --enable-maintainer-mode --enable-static=yes --enable-languages=cpp LDFLAGS="-static" && make -j2
+ make install
+ if: matrix.os == 'windows-latest'
+
+ - name: Configure CMake
+ # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
+ # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
+ run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DEXECUTABLE_OUTPUT_PATH=${{env.EXECUTABLE_OUTPUT_PATH}}
+ if: matrix.os == 'ubuntu-16.04' || matrix.os == 'macos-latest'
+
+ - name: Build GpgFrontend
+ # Build your program with the given configuration
+ run: cmake --build ${{github.workspace}}/build --config $env.BUILD_TYPE}} -- -j 2
+ if: matrix.os == 'ubuntu-16.04' || matrix.os == 'macos-latest'
+
+ - name: Package App Bundle (macOS)
+ run: |
+ macdeployqt ${{github.workspace}}/build/release/GpgFrontend.app
+ mkdir ${{github.workspace}}/build/tmp/
+ hdiutil create ${{github.workspace}}/build/tmp/tmp.dmg -ov -volname "GpgFrontend" -fs HFS+ -srcfolder ${{github.workspace}}/build/release/
+ mkdir ${{github.workspace}}/build/artifactOut
+ hdiutil convert ${{github.workspace}}/build/tmp/tmp.dmg -format UDZO -o ${{github.workspace}}/build/artifactOut/GpgFrontend.dmg
+ if: matrix.os == 'macos-latest'
+
+ - name: Package App Image (Linux)
+ run: |
+ mkdir ${{github.workspace}}/build/artifactOut
+ cd ${{github.workspace}}/build/artifactOut
+ wget -c -nv https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage
+ chmod u+x linuxdeployqt-continuous-x86_64.AppImage
+ ./linuxdeployqt-continuous-x86_64.AppImage ${{github.workspace}}/build/release/gpgfrontend/usr/share/applications/*.desktop -appimage
+ if: matrix.os == 'ubuntu-16.04'
+
+ - name: Configure CMake & Build Binary(Windows)
+ shell: msys2 {0}
+ run: |
+ cd $(echo "/${{github.workspace}}" | sed 's/\\/\//g' | sed 's/://')
+ mkdir build && cd build
+ cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DEXECUTABLE_OUTPUT_PATH=${{env.EXECUTABLE_OUTPUT_PATH}} ..
+ # Build your program with the given configuration
+ cmake --build . --config ${{env.BUILD_TYPE}} -- -j 2
+ if: matrix.os == 'windows-latest'
+
+ - name: Get Short SHA of Commit
+ id: vars
+ run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
+
+ - name: Upload Artifact(Linux)
+ uses: actions/upload-artifact@master
+ with:
+ name: gpgfrontend-${{matrix.os}}-${{env.BUILD_TYPE}}-${{steps.vars.outputs.sha_short}}
+ path: ${{github.workspace}}/build/artifactOut/GpgFrontend*.AppImage*
+ if: matrix.os == 'ubuntu-16.04'
+
+ - name: Upload Artifact(macOS)
+ uses: actions/upload-artifact@master
+ with:
+ name: gpgfrontend-${{matrix.os}}-${{env.BUILD_TYPE}}-${{steps.vars.outputs.sha_short}}
+ path: ${{github.workspace}}/build/artifactOut/*
+ if: matrix.os == 'macos-latest'
+
+ - name: Upload Artifact(Windows)
+ uses: actions/upload-artifact@master
+ with:
+ name: gpgfrontend-${{matrix.os}}-${{env.BUILD_TYPE}}-${{steps.vars.outputs.sha_short}}
+ path: ${{github.workspace}}/build/release/*
+ if: matrix.os == 'windows-latest'
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 96535bbc..af9e6f28 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -5,12 +5,14 @@ on:
branches: [ main, develop ]
paths-ignore:
- '**/README.md'
+ - '**/README_CN.md'
- 'resource/ts/**'
- 'docs/**'
pull_request:
branches: [ develop ]
paths-ignore:
- '**/README.md'
+ - '**/README_CN.md'
- 'resource/ts/**'
- 'docs/**'
@@ -23,7 +25,7 @@ jobs:
build:
strategy:
matrix:
- os: [ 'ubuntu-latest', 'macos-latest', 'windows-latest' ]
+ os: [ 'ubuntu-16.04', 'macos-latest', 'windows-latest' ]
runs-on: ${{ matrix.os }}
steps:
@@ -34,14 +36,18 @@ jobs:
sudo apt-get update
sudo apt-get -y install build-essential binutils git autoconf automake gettext texinfo
sudo apt-get -y install gcc g++
- sudo apt-get -y install libgpgme-dev gpg
- if: matrix.os == 'ubuntu-latest'
+ 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 ninja-build
+ 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-*
+ if: matrix.os == 'ubuntu-16.04'
- name: Install Dependence (macOS)
run: |
- brew install cmake git autoconf automake qt@5 gcc texinfo gettext libgpg-error libassuan gpgme
+ brew install cmake git autoconf automake qt@5 gcc texinfo gettext libgpg-error libassuan gpgme openssl
brew link qt@5
brew link gcc
+ brew link openssl --force
if: matrix.os == 'macos-latest'
- name: Cache Qt
@@ -50,13 +56,13 @@ jobs:
with:
path: ../Qt
key: ${{ runner.os }}-QtCache
- if: matrix.os == 'ubuntu-latest'
+ if: matrix.os == 'ubuntu-16.04'
- name: Install Qt
uses: jurplel/install-qt-action@v2
with:
cached: ${{ steps.cache-qt.outputs.cache-hit }}
- if: matrix.os == 'ubuntu-latest'
+ if: matrix.os == 'ubuntu-16.04'
- name: Set up MinGW (Windows)
uses: msys2/setup-msys2@v2
@@ -81,7 +87,7 @@ jobs:
./configure --enable-maintainer-mode --enable-static=yes && make -j2
sudo make install
cd ${{github.workspace}}
- if: matrix.os == 'ubuntu-latest'
+ if: matrix.os == 'ubuntu-16.04'
- name: Build assuan (Linux)
run: |
@@ -92,7 +98,7 @@ jobs:
./configure --enable-maintainer-mode --enable-static=yes && make -j2
sudo make install
cd ${{github.workspace}}
- if: matrix.os == 'ubuntu-latest'
+ if: matrix.os == 'ubuntu-16.04'
- name: Build GpgME (Linux)
run: |
@@ -103,7 +109,7 @@ jobs:
./configure --enable-maintainer-mode --enable-static=yes --enable-languages=cpp && make -j2
sudo make install
cd ${{github.workspace}}
- if: matrix.os == 'ubuntu-latest'
+ if: matrix.os == 'ubuntu-16.04'
- name: Build GpgME (Windows)
shell: msys2 {0}
@@ -119,12 +125,12 @@ jobs:
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DEXECUTABLE_OUTPUT_PATH=${{env.EXECUTABLE_OUTPUT_PATH}}
- if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest'
+ if: matrix.os == 'ubuntu-16.04' || matrix.os == 'macos-latest'
- name: Build GpgFrontend
# Build your program with the given configuration
run: cmake --build ${{github.workspace}}/build --config $env.BUILD_TYPE}} -- -j 2
- if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest'
+ if: matrix.os == 'ubuntu-16.04' || matrix.os == 'macos-latest'
- name: Package App Bundle (macOS)
run: |
@@ -135,6 +141,15 @@ jobs:
hdiutil convert ${{github.workspace}}/build/tmp/tmp.dmg -format UDZO -o ${{github.workspace}}/build/artifactOut/GpgFrontend.dmg
if: matrix.os == 'macos-latest'
+ - name: Package App Image (Linux)
+ run: |
+ mkdir ${{github.workspace}}/build/artifactOut
+ cd ${{github.workspace}}/build/artifactOut
+ wget -c -nv https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage
+ chmod u+x linuxdeployqt-continuous-x86_64.AppImage
+ ./linuxdeployqt-continuous-x86_64.AppImage ${{github.workspace}}/build/release/gpgfrontend/usr/share/applications/*.desktop -appimage
+ if: matrix.os == 'ubuntu-16.04'
+
- name: Configure CMake & Build Binary(Windows)
shell: msys2 {0}
run: |
@@ -153,8 +168,8 @@ jobs:
uses: actions/upload-artifact@master
with:
name: gpgfrontend-${{matrix.os}}-${{env.BUILD_TYPE}}-${{steps.vars.outputs.sha_short}}
- path: ${{github.workspace}}/build/release/*
- if: matrix.os == 'ubuntu-latest'
+ path: ${{github.workspace}}/build/artifactOut/GpgFrontend*.AppImage*
+ if: matrix.os == 'ubuntu-16.04'
- name: Upload Artifact(macOS)
uses: actions/upload-artifact@master
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 811c4710..c11b26af 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -112,6 +112,7 @@ if(APPLE)
)
link_directories(
/usr/local/lib
+ /usr/local/opt/openssl/lib
)
endif()
diff --git a/README.md b/README.md
index ebc15fbc..c5b667e3 100644
--- a/README.md
+++ b/README.md
@@ -9,8 +9,8 @@
![GitHub release (latest by date)](https://img.shields.io/github/v/release/saturneric/gpgfrontend)
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fsaturneric%2FGpgFrontend.svg?type=small)](https://app.fossa.com/projects/git%2Bgithub.com%2Fsaturneric%2FGpgFrontend?ref=badge_small)
-GpgFrontend is an Easy-to-Use, Compact, Cross-Platform, and Installation-Free [OpenPGP](https://www.openpgp.org/)
-Frontend Tool.
+GpgFrontend is a Powerful, Easy-to-Use, Compact, Cross-Platform, and Installation-Free [OpenPGP](https://www.openpgp.org/)
+Crypto Tool.
By using GpgFrontend, you can quickly **encrypt and decrypt text or files**. Or at the same time as the above
operations, you can add **your own signature** to let others know that this document or this paragraph of text was
@@ -18,13 +18,16 @@ issued by you. It aims to allow ordinary users to quickly use gpg and make profe
GpgFrontend supports new features of OpenPGP.
**Notice:** GpgFrontend does not provide an embedded [gnupg](https://gnupg.org/) binary library and needs to be
-installed by the user. **This is to ensure safety and avoid code or binary files being implanted in the backdoor during
+installed by the user. **This is to ensure safety and avoid code or binary files involved in encryption and decryption being implanted in the backdoor during
the delivery process.**
[>> Quick Start](#quick-start)
[>> Code & Binary Security](https://saturneric.github.io/GpgFrontend/index.html#/about/code-binary-verify)
+[>> 中文文档](https://github.com/saturneric/GpgFrontend/blob/main/README_CN.md)
+
+
<div align="center">
<img width="640" src="https://github.com/saturneric/Blob/blob/master/screenshots/main_mac.jpg?raw=true" alt="macOS Screenshot"/>
</div>
@@ -35,7 +38,7 @@ the delivery process.**
#### Workflows Status:
-[![Build & Package](https://github.com/saturneric/GpgFrontend/actions/workflows/release.yml/badge.svg?branch=main)](https://github.com/saturneric/GpgFrontend/actions/workflows/cmake.yml)
+[![Build & Package](https://github.com/saturneric/GpgFrontend/actions/workflows/release.yml/badge.svg?branch=main)](https://github.com/saturneric/GpgFrontend/actions/workflows/release.yml)
---
@@ -51,8 +54,8 @@ the delivery process.**
- [Document](#document)
- [Purpose](#purpose)
- [Build](#build)
-- [Contract](#contract)
- - [Contributing](#contributing)
+- [Contributing & Bugs Report](#contributing--bugs-report)
+ - [Contract](#contract)
- [Maintainers](#maintainers)
- [Licenses](#LICENSES)
@@ -60,8 +63,10 @@ the delivery process.**
- Can run on **Windows, Linux and macOS**.
- Open source, free, no need to install.
-- For Windows and macOS user, just double-click, and then you can use it freely.
-- Supports multiple languages. Don’t forget to help me translate this software.
+- Just double-click, and then you can use it freely.
+- Supports multiple languages.
+ - If you are interested, you can help
+ me [translate the interface](https://saturneric.github.io/GpgFrontend/index.html#/translate-interface).
## Usage
@@ -88,43 +93,42 @@ awesome operations.
#### Windows
-1. [Download](https://gnupg.org/ftp/gcrypt/binary/gnupg-w32-2.3.1_20210420.exe) gnupg-w32-******.exe
+1. [Download](https://gnupg.org/ftp/gcrypt/binary/gnupg-w32-2.3.1_20210420.exe) `gnupg-w32-******.exe`
2. Double Click it to install it
-3. [Download GpgFrontend](https://github.com/saturneric/GpgFrontend/releases) Windows Edition from release
-4. Unzip gpgfrontend-windows-latest-*******.zip
-5. Go into the directory and double click GpgFrontend.exe
+3. [Download GpgFrontend](https://github.com/saturneric/GpgFrontend/releases) Windows Edition from the latest release
+4. Unzip `gpgfrontend-windows-latest-*******.zip`
+5. Go into the directory and double click `GpgFrontend.exe`.
#### macOS
-1. [Download GpgFrontend](https://github.com/saturneric/GpgFrontend/releases) macOS edition from release
+0. If command `gpg` is not avaliable, please use homebrew to install it first.
+1. [Download GpgFrontend](https://github.com/saturneric/GpgFrontend/releases) macOS edition from the latest release
2. Double-Click GpgFrontend.dmg to load it
+ - macOS will automatically decompress the zip file and then you will be able to see the dmg
3. Double click and run it
(due to macOS security policy, you may need a little more step).
4. If it satisfies you, you can drag it into your Application folder.
#### Debian/Ubuntu/CentOS
-1. Install gnupg
+1. Install gnupg (If you have already followed please skip)
- For Debian/Ubuntu
```shell
$ sudo apt update
- $ sudo apt install gpg qt-default
+ $ sudo apt install gpg
```
- For CentOS
```shell
- $ sudo yum install gnupg qt5-qtbase
+ $ sudo yum install gnupg
```
-2. [Download GpgFrontend](https://github.com/saturneric/GpgFrontend/releases) Linux edition from release
-3. Unzip gpgfrontend-ubuntu-latest-*******.zip
-4. Get into folder and Give gpgfrontend permission to execute
- ```shell
- $ cd gpgfrontend-ubuntu-latest-*******/
- $ chmod u+x GpgFrontend
- ```
-5. Just run it
+2. [Download GpgFrontend](https://github.com/saturneric/GpgFrontend/releases) Linux edition from the latest release
+3. Unzip gpgfrontend-ubuntu-16.04-*******.zip
+ - `ubuntu-16.04` shows that Linux distributions at the same time as 16.04 or later are supported.
+4. Give `GpgFrontend-***.AppImage` permission to execute
```shell
- $ ./GpgFrontend
+ $ chmod u+x ./GpgFrontend-***.AppImage
```
+5. Just double-click `GpgFrontend-***.AppImage` to run it.
## Document
@@ -145,13 +149,13 @@ The GpgFrontend project is as open source, and it also insists on using open sou
## Build
-The tutorial for building the software will be released shortly.
+The tutorial for building the software will be released shortly. Before the relevant documents are released, you can refer to the project-related Github Action file if you know it.
## Contract
If you want to contact me individually, you can email [[email protected]](mailto:[email protected]).
-### Contributing
+### Contributing & Bugs Report
Feel free to dive in! [Open an issue](https://github.com/saturneric/GpgFrontend/issues/new) or submit PRs.
@@ -182,4 +186,4 @@ mingw-w64: http://mingw-w64.org/doku.php
The icons of this software use materials from Alibaba vector icon library. The Alibaba vector icon library is free to
use. The icons in the free library aren't registered as trademarks. There is no copyright issue involved and can be used
-commercially. \ No newline at end of file
+commercially.
diff --git a/README_CN.md b/README_CN.md
new file mode 100644
index 00000000..e2f524df
--- /dev/null
+++ b/README_CN.md
@@ -0,0 +1,172 @@
+<img width="100" height="100" align="right" src="https://github.com/saturneric/Blob/blob/master/logos/icon.png?raw=true" alt="ICON"/>
+
+# GpgFrontend
+
+![Language](https://img.shields.io/badge/language-C%2B%2B-green)
+![License](https://img.shields.io/badge/License-GPL--3.0-orange)
+![CodeSize](https://img.shields.io/github/languages/code-size/saturneric/GpgFrontend)
+[![Codacy Badge](https://app.codacy.com/project/badge/Grade/d1750e052a85430a8f1f84e58a0fceda)](https://www.codacy.com/gh/saturneric/GpgFrontend/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=saturneric/GpgFrontend&amp;utm_campaign=Badge_Grade)
+![GitHub release (latest by date)](https://img.shields.io/github/v/release/saturneric/gpgfrontend)
+[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fsaturneric%2FGpgFrontend.svg?type=small)](https://app.fossa.com/projects/git%2Bgithub.com%2Fsaturneric%2FGpgFrontend?ref=badge_small)
+
+GpgFrontend 是一个易于使用、小巧、跨平台和免安装的 [OpenPGP](https://www.openpgp.org/) 加密解密签名工具。
+
+通过使用 GpgFrontend,你可以快速加密和解密文本或文件。或者在进行上述操作的同时加上自己的签名,让别人知道这个文件或者这段文字是出自你之手。
+该软件旨在让普通用户更快上手gpg工具,让专业用户更便捷。 GpgFrontend 支持 OpenPGP 的新特性。
+
+注意:GpgFrontend 不提供嵌入式 gnupg 二进制库,需要用户自行安装。这是为了确保安全,避免代码或二进制文件在传递过程中被植入后门。
+
+[>> 快速开始](#quick-start)
+
+[>> 代码与二进制文件安全](https://saturneric.github.io/GpgFrontend/index.html#/about/code-binary-verify)
+
+<div align="center">
+<img width="640" src="https://github.com/saturneric/Blob/blob/master/screenshots/main_mac.jpg?raw=true" alt="macOS Screenshot"/>
+</div>
+<div align="center">
+<img width="320" src="https://github.com/saturneric/Blob/blob/master/screenshots/key_info.PNG?raw=true" alt="Windows Screenshot"/>
+<img width="320" src="https://github.com/saturneric/Blob/blob/master/screenshots/keygen_ubuntu.png?raw=true" alt="Ubuntu Screenshot"/>
+</div>
+
+#### Workflows 状态:
+
+[![Build & Package](https://github.com/saturneric/GpgFrontend/actions/workflows/release.yml/badge.svg?branch=main)](https://github.com/saturneric/GpgFrontend/actions/workflows/cmake.yml)
+
+---
+
+## 内容目录
+
+- [软件特性](#软件特性)
+- [使用方法](#使用方法)
+ - [快速开始](#快速开始)
+ - [如何安装](#如何安装)
+ - [Windows](#windows)
+ - [macOS](#macos)
+ - [Debian/Ubuntu/CentOS](#debianubuntucentos)
+- [文档](#文档)
+- [开发宗旨](#开发宗旨)
+- [构建方法](#构建方法)
+- [联系](#联系)
+ - [做出贡献](#做出贡献)
+ - [维护者](#维护者)
+- [许可证](#许可证)
+
+## 软件特性
+
+- 可以在 Windows、Linux 和 macOS 上运行。
+- 开源,免费,无需安装。
+- 只需双击即可自由使用。
+- 支持多种语言。
+ - 有兴趣的可以帮我 [翻译一下界面](https://saturneric.github.io/GpgFrontend/index.html#/translate-interface) 。
+
+## 使用方法
+
+### 快速开始
+
+### 快速加密
+
+只需单击几下即可完成加密。
+
+![GIF](https://github.com/saturneric/Blob/blob/master/gif/encrypt.gif?raw=true)
+
+### 快速解密
+
+我想马上看看对方写了什么。
+
+![GIF](https://github.com/saturneric/Blob/blob/master/gif/decrypt.gif?raw=true)
+
+### 还有那些有用的操作
+
+阅读 [文档](https://saturneric.github.io/GpgFrontend/index.html#/) 中的动图,了解更多精彩操作。
+
+### 如何安装
+
+#### Windows
+
+1. [下载](https://gnupg.org/ftp/gcrypt/binary/gnupg-w32-2.3.1_20210420.exe) gnupg-w32-******.exe
+2. 双击安装
+3. [下载 GpgFrontend](https://github.com/saturneric/GpgFrontend/releases) Windows Edition from release
+4. 解压 gpgfrontend-windows-latest-*******.zip
+5. 进入目录,双击运行 GpgFrontend.exe
+
+#### macOS
+
+0. 如果命令 `gpg` 不可用,请先用Homebrew安装它.
+1. [下载 GpgFrontend](https://github.com/saturneric/GpgFrontend/releases) macOS edition from release
+2. 双击并加载 GpgFrontend.dmg
+3. 双击并运行
+ (由于macOS的安全策略,在真正能运行前请遵照系统说明).
+4. 如果你满意的话,可以将本软件复制到Application文件夹.
+
+#### Debian/Ubuntu/CentOS
+
+1. 安装 gnupg (如果你已经安装了请跳过)
+ - For Debian/Ubuntu
+ ```shell
+ $ sudo apt update
+ $ sudo apt install gpg
+ ```
+ - For CentOS
+ ```shell
+ $ sudo yum install gnupg
+ ```
+2. [下载 GpgFrontend](https://github.com/saturneric/GpgFrontend/releases) Linux edition from the latest release
+3. 解压 gpgfrontend-ubuntu-16.04-*******.zip
+ - `ubuntu-16.04` 说明ubuntu 16.04及其同时期与后来的Linux发行版都可以正常运行。
+4. 赋予 `GpgFrontend-***.AppImage` 执行权限
+ ```shell
+ $ chmod u+x ./GpgFrontend-***.AppImage
+ ```
+5. 双击运行 `GpgFrontend-***.AppImage`.
+
+## 文档
+
+如果你想获取更多信息,请阅读 [文档](https://saturneric.github.io/GpgFrontend/index.html#/).
+
+## 开发宗旨
+
+GpgFrontend 项目继承自一个相对成熟但未维护的 [gpg4usb](https://www.gpg4usb.org/) 项目。
+它继承了 gpg4usb 稳定、易用、小巧、免安装的特点。
+
+GpgFrontend 未来会增加更多功能,提高GPG在端到端传输中的易用性并缩短密文长度。同时,新功能的加入不影响旧的基础功能。
+我个人的力量总是有限的。 GpgFrontend 欢迎志愿者加入。你可以使用 GitHub 平台提交问题或提交pull request。
+
+GpgFrontend 项目作为开源项目,也坚持使用开源代码和库。
+
+## 构建方法
+
+构建软件的教程将很快发布。
+
+## 联系
+
+如果你想单独与我联系,你可以发送电子邮件到 [[email protected]](mailto:[email protected])。
+
+### 做出贡献
+
+欢迎!你可以通过 [提出issue](https://github.com/saturneric/GpgFrontend/issues/new) 或提交 PR来做出贡献。
+
+### 维护者
+
+[@Saturneric](https://github.com/saturneric).
+
+## LOGO
+
+![logo](https://github.com/saturneric/Blob/blob/master/logos/gpgfrontend-logo.jpg?raw=true)
+
+## 许可证
+
+GpgFrontend 在 [GPLv3](COPYING) 许可证下。
+
+项目使用到了一些库和二进制文件,它们(可能)具有不同的许可证,请查看它们的主页获取更多信息。您也可以从那里获取相关信息。
+
+gpg4usb: https://www.gpg4usb.org/
+
+Gnupg: https://gnupg.org/
+
+QT: https://www.qt.io/
+
+MSYS2: https://www.msys2.org/
+
+mingw-w64: http://mingw-w64.org/doku.php
+
+本软件图标使用来自阿里巴巴矢量图标库的素材。免费库中的图标未注册为商标。不涉及版权问题。 \ No newline at end of file
diff --git a/include/GpgFrontend.h.in b/include/GpgFrontend.h.in
index 3c3e72cc..de88bab2 100644
--- a/include/GpgFrontend.h.in
+++ b/include/GpgFrontend.h.in
@@ -41,6 +41,8 @@
#if OS_PLATFORM == MACOS && BUILD_FLAG == RELEASE
# define RESOURCE_DIR(appDir) (appDir + "/../Resources/")
+#elif OS_PLATFORM == LINUX && BUILD_FLAG == RELEASE
+# define RESOURCE_DIR(appDir) (appDir + "/../share/")
#else
# define RESOURCE_DIR(appDir) (appDir)
#endif
diff --git a/include/gpg/GpgContext.h b/include/gpg/GpgContext.h
index 1e5334d1..e243cc53 100644
--- a/include/gpg/GpgContext.h
+++ b/include/gpg/GpgContext.h
@@ -99,7 +99,7 @@ namespace GpgME {
void clearPasswordCache();
- void exportSecretKey(const QString &uid, QByteArray *outBuffer);
+ bool exportSecretKey(const GpgKey &key, QByteArray *outBuffer);
void getSigners(QVector<GpgKey> &signer);
diff --git a/include/ui/KeyUploadDialog.h b/include/ui/KeyUploadDialog.h
index 013c0b72..b41ced6b 100644
--- a/include/ui/KeyUploadDialog.h
+++ b/include/ui/KeyUploadDialog.h
@@ -33,6 +33,10 @@ Q_OBJECT
public:
KeyUploadDialog(GpgME::GpgContext *ctx, const QVector<GpgKey> &keys, QWidget *parent = nullptr);
+public slots:
+
+ void slotUpload();
+
private slots:
void uploadKeyToServer(QByteArray &keys);
@@ -41,6 +45,8 @@ private slots:
private:
+ GpgME::GpgContext *mCtx;
+ const QVector<GpgKey> &mKeys;
QString appPath;
QSettings settings;
QByteArray mKeyData;
diff --git a/resource/gpgfrontend/usr/share/applications/gpgfrontend.desktop b/resource/gpgfrontend/usr/share/applications/gpgfrontend.desktop
new file mode 100644
index 00000000..bce3dc62
--- /dev/null
+++ b/resource/gpgfrontend/usr/share/applications/gpgfrontend.desktop
@@ -0,0 +1,7 @@
+[Desktop Entry]
+Type=Application
+Name=GpgFrontend
+Comment=A Cross-Platform OpenPGP Frontend Software
+Exec=GpgFrontend
+Icon=gpgfrontend-appimage-icon
+Categories=Utility;
diff --git a/resource/gpgfrontend/usr/share/icons/hicolor/200x200/apps/gpgfrontend-appimage-icon.png b/resource/gpgfrontend/usr/share/icons/hicolor/200x200/apps/gpgfrontend-appimage-icon.png
new file mode 100755
index 00000000..7366dc97
--- /dev/null
+++ b/resource/gpgfrontend/usr/share/icons/hicolor/200x200/apps/gpgfrontend-appimage-icon.png
Binary files differ
diff --git a/resource/ts/gpg_frontend_fr.ts b/resource/ts/gpg_frontend_fr.ts
index c452ae46..b8694cb4 100644
--- a/resource/ts/gpg_frontend_fr.ts
+++ b/resource/ts/gpg_frontend_fr.ts
@@ -1715,115 +1715,115 @@ This is NOT your Public Key, so DON&apos;T give it away.&lt;br /&gt;Do you REALL
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="98"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="97"/>
<source>Update Keys from Keyserver</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="100"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="99"/>
<source>Import Keys from Keyserver</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="161"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="160"/>
<source>UID</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="161"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="160"/>
<source>Creation date</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="161"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="160"/>
<source>KeyID</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="161"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="160"/>
<source>Tag</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="182"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="181"/>
<source>&lt;h4&gt;Text is empty.&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="216"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="215"/>
<source>Not Key Found</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="219"/>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="389"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="218"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="388"/>
<source>Timeout</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="222"/>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="392"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="221"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="391"/>
<source>Key Server Not Found</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="225"/>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="395"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="224"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="394"/>
<source>Connection Error</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="233"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="232"/>
<source>&lt;h4&gt;CToo many responses from keyserver!&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="240"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="239"/>
<source>&lt;h4&gt;No keys found, input may be kexId, retrying search with 0x.&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="245"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="244"/>
<source>&lt;h4&gt;No keys found containing the search string!&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="249"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="248"/>
<source>&lt;h4&gt;Insufficiently specific search string!&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="277"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="276"/>
<source>revoked</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="280"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="279"/>
<source>disabled</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="320"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="319"/>
<source>&lt;h4&gt;%1 keys found. Double click a key to import it.&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="386"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="385"/>
<source>Key Not Found</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="413"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="412"/>
<source>&lt;h4&gt;Key Updated&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="415"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="414"/>
<source>&lt;h4&gt;Key Imported&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="476"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="475"/>
<source>Upload Keys from Keyserver</source>
<translation type="unfinished"></translation>
</message>
diff --git a/resource/ts/gpg_frontend_ru.ts b/resource/ts/gpg_frontend_ru.ts
index 0bc0514a..b51011e5 100644
--- a/resource/ts/gpg_frontend_ru.ts
+++ b/resource/ts/gpg_frontend_ru.ts
@@ -1715,115 +1715,115 @@ This is NOT your Public Key, so DON&apos;T give it away.&lt;br /&gt;Do you REALL
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="98"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="97"/>
<source>Update Keys from Keyserver</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="100"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="99"/>
<source>Import Keys from Keyserver</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="161"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="160"/>
<source>UID</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="161"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="160"/>
<source>Creation date</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="161"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="160"/>
<source>KeyID</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="161"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="160"/>
<source>Tag</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="182"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="181"/>
<source>&lt;h4&gt;Text is empty.&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="216"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="215"/>
<source>Not Key Found</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="219"/>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="389"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="218"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="388"/>
<source>Timeout</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="222"/>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="392"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="221"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="391"/>
<source>Key Server Not Found</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="225"/>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="395"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="224"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="394"/>
<source>Connection Error</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="233"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="232"/>
<source>&lt;h4&gt;CToo many responses from keyserver!&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="240"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="239"/>
<source>&lt;h4&gt;No keys found, input may be kexId, retrying search with 0x.&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="245"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="244"/>
<source>&lt;h4&gt;No keys found containing the search string!&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="249"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="248"/>
<source>&lt;h4&gt;Insufficiently specific search string!&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="277"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="276"/>
<source>revoked</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="280"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="279"/>
<source>disabled</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="320"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="319"/>
<source>&lt;h4&gt;%1 keys found. Double click a key to import it.&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="386"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="385"/>
<source>Key Not Found</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="413"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="412"/>
<source>&lt;h4&gt;Key Updated&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="415"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="414"/>
<source>&lt;h4&gt;Key Imported&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="476"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="475"/>
<source>Upload Keys from Keyserver</source>
<translation type="unfinished"></translation>
</message>
diff --git a/resource/ts/gpgfrontend_en_us.ts b/resource/ts/gpgfrontend_en_us.ts
index dd8139ac..3c8a01b7 100644
--- a/resource/ts/gpgfrontend_en_us.ts
+++ b/resource/ts/gpgfrontend_en_us.ts
@@ -1715,115 +1715,115 @@ This is NOT your Public Key, so DON&apos;T give it away.&lt;br /&gt;Do you REALL
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="98"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="97"/>
<source>Update Keys from Keyserver</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="100"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="99"/>
<source>Import Keys from Keyserver</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="161"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="160"/>
<source>UID</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="161"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="160"/>
<source>Creation date</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="161"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="160"/>
<source>KeyID</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="161"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="160"/>
<source>Tag</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="182"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="181"/>
<source>&lt;h4&gt;Text is empty.&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="216"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="215"/>
<source>Not Key Found</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="219"/>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="389"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="218"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="388"/>
<source>Timeout</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="222"/>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="392"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="221"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="391"/>
<source>Key Server Not Found</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="225"/>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="395"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="224"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="394"/>
<source>Connection Error</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="233"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="232"/>
<source>&lt;h4&gt;CToo many responses from keyserver!&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="240"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="239"/>
<source>&lt;h4&gt;No keys found, input may be kexId, retrying search with 0x.&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="245"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="244"/>
<source>&lt;h4&gt;No keys found containing the search string!&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="249"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="248"/>
<source>&lt;h4&gt;Insufficiently specific search string!&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="277"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="276"/>
<source>revoked</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="280"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="279"/>
<source>disabled</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="320"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="319"/>
<source>&lt;h4&gt;%1 keys found. Double click a key to import it.&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="386"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="385"/>
<source>Key Not Found</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="413"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="412"/>
<source>&lt;h4&gt;Key Updated&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="415"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="414"/>
<source>&lt;h4&gt;Key Imported&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="476"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="475"/>
<source>Upload Keys from Keyserver</source>
<translation type="unfinished"></translation>
</message>
diff --git a/resource/ts/gpgfrontend_zh_chs.ts b/resource/ts/gpgfrontend_zh_chs.ts
index dbf05389..74982abc 100644
--- a/resource/ts/gpgfrontend_zh_chs.ts
+++ b/resource/ts/gpgfrontend_zh_chs.ts
@@ -1715,115 +1715,115 @@ This is NOT your Public Key, so DON&apos;T give it away.&lt;br /&gt;Do you REALL
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="98"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="97"/>
<source>Update Keys from Keyserver</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="100"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="99"/>
<source>Import Keys from Keyserver</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="161"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="160"/>
<source>UID</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="161"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="160"/>
<source>Creation date</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="161"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="160"/>
<source>KeyID</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="161"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="160"/>
<source>Tag</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="182"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="181"/>
<source>&lt;h4&gt;Text is empty.&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="216"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="215"/>
<source>Not Key Found</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="219"/>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="389"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="218"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="388"/>
<source>Timeout</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="222"/>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="392"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="221"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="391"/>
<source>Key Server Not Found</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="225"/>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="395"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="224"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="394"/>
<source>Connection Error</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="233"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="232"/>
<source>&lt;h4&gt;CToo many responses from keyserver!&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="240"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="239"/>
<source>&lt;h4&gt;No keys found, input may be kexId, retrying search with 0x.&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="245"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="244"/>
<source>&lt;h4&gt;No keys found containing the search string!&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="249"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="248"/>
<source>&lt;h4&gt;Insufficiently specific search string!&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="277"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="276"/>
<source>revoked</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="280"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="279"/>
<source>disabled</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="320"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="319"/>
<source>&lt;h4&gt;%1 keys found. Double click a key to import it.&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="386"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="385"/>
<source>Key Not Found</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="413"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="412"/>
<source>&lt;h4&gt;Key Updated&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="415"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="414"/>
<source>&lt;h4&gt;Key Imported&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="476"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="475"/>
<source>Upload Keys from Keyserver</source>
<translation type="unfinished"></translation>
</message>
diff --git a/resource/ts/gpgfrontend_zh_cht.ts b/resource/ts/gpgfrontend_zh_cht.ts
index dbf05389..74982abc 100644
--- a/resource/ts/gpgfrontend_zh_cht.ts
+++ b/resource/ts/gpgfrontend_zh_cht.ts
@@ -1715,115 +1715,115 @@ This is NOT your Public Key, so DON&apos;T give it away.&lt;br /&gt;Do you REALL
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="98"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="97"/>
<source>Update Keys from Keyserver</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="100"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="99"/>
<source>Import Keys from Keyserver</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="161"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="160"/>
<source>UID</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="161"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="160"/>
<source>Creation date</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="161"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="160"/>
<source>KeyID</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="161"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="160"/>
<source>Tag</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="182"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="181"/>
<source>&lt;h4&gt;Text is empty.&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="216"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="215"/>
<source>Not Key Found</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="219"/>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="389"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="218"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="388"/>
<source>Timeout</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="222"/>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="392"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="221"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="391"/>
<source>Key Server Not Found</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="225"/>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="395"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="224"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="394"/>
<source>Connection Error</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="233"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="232"/>
<source>&lt;h4&gt;CToo many responses from keyserver!&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="240"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="239"/>
<source>&lt;h4&gt;No keys found, input may be kexId, retrying search with 0x.&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="245"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="244"/>
<source>&lt;h4&gt;No keys found containing the search string!&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="249"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="248"/>
<source>&lt;h4&gt;Insufficiently specific search string!&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="277"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="276"/>
<source>revoked</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="280"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="279"/>
<source>disabled</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="320"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="319"/>
<source>&lt;h4&gt;%1 keys found. Double click a key to import it.&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="386"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="385"/>
<source>Key Not Found</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="413"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="412"/>
<source>&lt;h4&gt;Key Updated&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="415"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="414"/>
<source>&lt;h4&gt;Key Imported&lt;/h4&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../src/ui/KeyServerImportDialog.cpp" line="476"/>
+ <location filename="../../src/ui/KeyServerImportDialog.cpp" line="475"/>
<source>Upload Keys from Keyserver</source>
<translation type="unfinished"></translation>
</message>
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 1a3d2860..97fae047 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -17,8 +17,13 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release)
message(STATUS "CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
# Set Resource Output Path
-if(APPLE)
- set(RESOURCE_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Resources)
+if(${CMAKE_BUILD_TYPE} STREQUAL "Release")
+ if(APPLE)
+ set(RESOURCE_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Resources)
+ elseif(LINUX)
+ file(COPY ${CMAKE_SOURCE_DIR}/resource/gpgfrontend DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
+ set(RESOURCE_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/gpgfrontend/usr/share)
+ endif()
else()
set(RESOURCE_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
endif()
@@ -45,10 +50,14 @@ file(COPY ${CMAKE_SOURCE_DIR}/resource/css DESTINATION ${RESOURCE_OUTPUT_DIRECTO
file(COPY ${CMAKE_SOURCE_DIR}/resource/icons DESTINATION ${RESOURCE_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
file(COPY ${CMAKE_SOURCE_DIR}/resource/conf DESTINATION ${RESOURCE_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
-if(APPLE)
- file(COPY ${CMAKE_SOURCE_DIR}/gpgfrontend.icns DESTINATION ${RESOURCE_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
- # Refresh App Bundle
- file(REMOVE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${AppName}.app)
+if(${CMAKE_BUILD_TYPE} STREQUAL "Release")
+ if(APPLE)
+ file(COPY ${CMAKE_SOURCE_DIR}/gpgfrontend.icns DESTINATION ${RESOURCE_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
+ # Refresh App Bundle
+ file(REMOVE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${AppName}.app)
+ elseif(LINUX)
+ file(REMOVE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/gpgfrontend/usr/bin/${AppName})
+ endif()
endif()
# Copy Utils Files
@@ -80,16 +89,25 @@ if(${CMAKE_BUILD_TYPE} STREQUAL "Release")
MACOSX_BUNDLE_LONG_VERSION_STRING ${BUILD_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION}
MACOSX_BUNDLE_BUNDLE_VERSION ${BUILD_VERSION}
- MACOSX_BUNDLE_ICON_FILE "gpgfrontend.icns"
- )
+ MACOSX_BUNDLE_ICON_FILE "gpgfrontend.icns")
add_custom_command(TARGET ${AppName} POST_BUILD
COMMAND /bin/rm -rf ./${AppName}.app/Contents/Resources
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
- COMMENT "Deleting Resources IN App Bundle")
+ COMMENT "Deleting Resources in App Bundle")
add_custom_command(TARGET ${AppName} POST_BUILD
COMMAND /bin/mv -n ./Resources ./${AppName}.app/Contents/
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
- COMMENT "Copying Resources INTO App Bundle Resource")
+ COMMENT "Copying Resources into App Bundle Resource")
+ elseif(LINUX)
+ add_executable(${AppName} ${BASE_SOURCE} ${RESOURCE_FILES} ${QT5_MOCS})
+ add_custom_command(TARGET ${AppName} POST_BUILD
+ COMMAND /bin/mkdir ./gpgfrontend/usr/bin && /bin/mv -f ./${AppName} ./gpgfrontend/usr/bin/
+ WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
+ COMMENT "Copying Binary into App Image")
+ add_custom_command(TARGET ${AppName} POST_BUILD
+ COMMAND /bin/mkdir ./gpgfrontend/usr/lib
+ WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
+ COMMENT "Complement to build the required architecture")
else()
add_executable(${AppName} ${BASE_SOURCE} ${RESOURCE_FILES} ${QT5_MOCS})
endif()
@@ -101,13 +119,13 @@ IF (MINGW)
message(STATUS "Link Application Static Library For MINGW")
target_link_libraries(${AppName}
gpgfrontend-ui gpg
- Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core)
-
-
+ Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core
+ crypto ssl)
else()
message(STATUS "Link Application Static Library For UNIX")
target_link_libraries(${AppName}
gpgfrontend-ui gpg
- Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core)
+ Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core
+ crypto ssl)
endif()
diff --git a/src/gpg/GpgContext.cpp b/src/gpg/GpgContext.cpp
index 603ad90b..67bae907 100644
--- a/src/gpg/GpgContext.cpp
+++ b/src/gpg/GpgContext.cpp
@@ -653,22 +653,27 @@ namespace GpgME {
return QString::fromUtf8(gpgme_strerror(err));
}
-/** export private key, TODO errohandling, e.g. like in seahorse (seahorse-gpg-op.c) **/
-
- void GpgContext::exportSecretKey(const QString &uid, QByteArray *outBuffer) {
- qDebug() << *outBuffer;
+ bool GpgContext::exportSecretKey(const GpgKey &key, QByteArray *outBuffer) {
+ qDebug() << "Export Secret Key" << key.id;
+ gpgme_key_t target_key[2] = {
+ key.key_refer,
+ nullptr
+ };
+
+ gpgme_data_t dataOut;
+ gpgme_data_new(&dataOut);
// export private key to outBuffer
- QStringList arguments;
- arguments << "--armor" << "--export-secret-key" << uid;
- auto *p_errArray = new QByteArray();
- executeGpgCommand(arguments, outBuffer, p_errArray);
-
- // append public key to outBuffer
- auto *pubKey = new QByteArray();
- QStringList keyList;
- keyList.append(uid);
- exportKeys(&keyList, pubKey);
- outBuffer->append(*pubKey);
+ gpgme_error_t error = gpgme_op_export_keys(mCtx, target_key,GPGME_EXPORT_MODE_SECRET, dataOut);
+
+ if(gpgme_err_code(error) != GPG_ERR_NO_ERROR) {
+ checkErr(error);
+ gpgme_data_release(dataOut);
+ return false;
+ }
+
+ readToBuffer(dataOut, outBuffer);
+ gpgme_data_release(dataOut);
+ return true;
}
/** return type should be gpgme_error_t*/
@@ -1241,4 +1246,4 @@ namespace GpgME {
}
return true;
}
-} \ No newline at end of file
+}
diff --git a/src/ui/KeyImportDetailDialog.cpp b/src/ui/KeyImportDetailDialog.cpp
index 3d8d1cdc..8d303886 100644
--- a/src/ui/KeyImportDetailDialog.cpp
+++ b/src/ui/KeyImportDetailDialog.cpp
@@ -26,9 +26,8 @@
KeyImportDetailDialog::KeyImportDetailDialog(GpgME::GpgContext *ctx, GpgImportInformation result, bool automatic,
QWidget *parent)
- : QDialog(parent) {
- mCtx = ctx;
- mResult = std::move(result);
+ : QDialog(parent), mCtx(ctx), mResult(std::move(result)) {
+
// If no key for import found, just show a message
if (mResult.considered == 0) {
if(automatic)
diff --git a/src/ui/KeyServerImportDialog.cpp b/src/ui/KeyServerImportDialog.cpp
index 1999b443..ec740691 100644
--- a/src/ui/KeyServerImportDialog.cpp
+++ b/src/ui/KeyServerImportDialog.cpp
@@ -60,7 +60,6 @@ KeyServerImportDialog::KeyServerImportDialog(GpgME::GpgContext *ctx, KeyList *ke
waitingBar = new QProgressBar();
waitingBar->setVisible(false);
waitingBar->setRange(0, 0);
- waitingBar->setFixedHeight(24);
waitingBar->setFixedWidth(200);
// Layout for messagebox
@@ -100,7 +99,7 @@ KeyServerImportDialog::KeyServerImportDialog(GpgME::GpgContext *ctx, KeyList *ke
this->setWindowTitle(tr("Import Keys from Keyserver"));
if(automatic) {
- this->setFixedSize(200, 42);
+ this->setFixedSize(240, 42);
} else {
// Restore window size & location
if (this->settings.value("ImportKeyFromServer/setWindowSize").toBool()) {
@@ -121,8 +120,6 @@ KeyServerImportDialog::KeyServerImportDialog(GpgME::GpgContext *ctx, KeyList *ke
}
}
-
-
this->setModal(true);
}
diff --git a/src/ui/KeyUploadDialog.cpp b/src/ui/KeyUploadDialog.cpp
index 6ee6aa78..e28b4230 100644
--- a/src/ui/KeyUploadDialog.cpp
+++ b/src/ui/KeyUploadDialog.cpp
@@ -27,10 +27,27 @@
#include <utility>
KeyUploadDialog::KeyUploadDialog(GpgME::GpgContext *ctx, const QVector<GpgKey> &keys, QWidget *parent)
-: appPath(qApp->applicationDirPath()),
-settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", QSettings::IniFormat),
-QDialog(parent) {
- ctx->exportKeys(keys, mKeyData);
+ : appPath(qApp->applicationDirPath()),
+ settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", QSettings::IniFormat),
+ mCtx(ctx),
+ mKeys(keys),
+ QDialog(parent) {
+
+
+ auto *pb = new QProgressBar();
+ pb->setRange(0, 0);
+
+ auto *layout = new QVBoxLayout();
+ layout->addWidget(pb);
+ this->setLayout(layout);
+
+ this->setModal(true);
+ this->setWindowTitle(tr("Uploading Public Key"));
+ this->setFixedSize(240, 42);
+}
+
+void KeyUploadDialog::slotUpload() {
+ mCtx->exportKeys(mKeys, mKeyData);
uploadKeyToServer(mKeyData);
}
@@ -66,30 +83,14 @@ void KeyUploadDialog::uploadKeyToServer(QByteArray &keys) {
this, SLOT(slotUploadFinished()));
- // A Waiting Dialog
- auto *dialog = new QDialog(this, Qt::CustomizeWindowHint | Qt::WindowTitleHint);
- dialog->setModal(true);
- dialog->setWindowTitle(tr("Uploading Public Key"));
- dialog->setFixedSize(200, 42);
-
- auto *pb = new QProgressBar();
- pb->setRange(0, 0);
- pb->setFixedSize(200, 24);
-
- auto *layout = new QVBoxLayout(dialog);
- layout->addWidget(pb);
- dialog->setLayout(layout);
-
- dialog->show();
-
// Keep Waiting
while(reply->isRunning()) {
QApplication::processEvents();
}
// Done
- dialog->hide();
- dialog->close();
+ this->hide();
+ this->close();
}
void KeyUploadDialog::slotUploadFinished() {
diff --git a/src/ui/Wizard.cpp b/src/ui/Wizard.cpp
index b3236cfc..456e8c52 100644
--- a/src/ui/Wizard.cpp
+++ b/src/ui/Wizard.cpp
@@ -162,27 +162,34 @@ ChoosePage::ChoosePage(QWidget *parent)
setSubTitle(tr("...by clicking on the appropriate link."));
auto *keygenLabel = new QLabel(tr("If you have never used GPGFrontend before and also don't own a gpg key yet you "
- "may possibly want to ") + "<a href=""Wizard::Page_GenKey"">"
+ "may possibly want to read how to") + "<a href=\"https://saturneric.github.io/GpgFrontend/index.html#/manual/generate-key\">"
+ tr("create a new keypair") + "</a><hr>");
+ keygenLabel->setTextFormat(Qt::RichText);
+ keygenLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
+ keygenLabel->setOpenExternalLinks(true);
keygenLabel->setWordWrap(true);
- // connect(keygenLabel, SIGNAL(linkActivated(QString)), this, SLOT(slotJumpPage(Qtring)));
- auto *importGpg4usbLabel = new QLabel(tr("If you upgrade from an older version of GPGFrontend you may want to ")
- + "<a href=""Wizard::Page_ImportFromGpg4usb"">"
- + tr("import settings and/or keys from GPGFrontend") + "</a>");
- importGpg4usbLabel->setWordWrap(true);
- connect(importGpg4usbLabel, SIGNAL(linkActivated(QString)), this, SLOT(slotJumpPage(QString)));
+ auto *encrDecyTextLabel = new QLabel(tr("If you want to learn how to encrypt and decrypt text, you can read ")
+ + "<a href=\"https://saturneric.github.io/GpgFrontend/index.html#/manual/encrypt-decrypt-text\">"
+ + tr("this document") + "</a><hr>");
- auto *importGnupgLabel = new QLabel(tr("If you are already using GnuPG you may want to ")
- + "<a href=""Wizard::Page_ImportFromGnupg"">"
- + tr("import keys from GnuPG") + "</a><hr>");
- importGnupgLabel->setWordWrap(true);
- connect(importGnupgLabel, SIGNAL(linkActivated(QString)), this, SLOT(slotJumpPage(QString)));
+ encrDecyTextLabel->setTextFormat(Qt::RichText);
+ encrDecyTextLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
+ encrDecyTextLabel->setOpenExternalLinks(true);
+ encrDecyTextLabel->setWordWrap(true);
+
+ auto *signVerifyTextLabel = new QLabel(tr("If you want to sign and verify text, you can read ")
+ + "<a href=\"https://saturneric.github.io/GpgFrontend/index.html#/manual/sign-verify-text\">"
+ + tr("this document") + "</a>");
+ signVerifyTextLabel->setTextFormat(Qt::RichText);
+ signVerifyTextLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
+ signVerifyTextLabel->setOpenExternalLinks(true);
+ signVerifyTextLabel->setWordWrap(true);
auto *layout = new QVBoxLayout();
layout->addWidget(keygenLabel);
- layout->addWidget(importGnupgLabel);
- layout->addWidget(importGpg4usbLabel);
+ layout->addWidget(encrDecyTextLabel);
+ layout->addWidget(signVerifyTextLabel);
setLayout(layout);
nextPage = Wizard::Page_Conclusion;
}
@@ -369,7 +376,7 @@ KeyGenPage::KeyGenPage(GpgME::GpgContext *ctx, QWidget *parent)
layout->addWidget(topLabel);
layout->addWidget(linkLabel);
layout->addWidget(createKeyButtonBox);
- connect(createKeyButton, SIGNAL(clicked()), this, SLOT(slotGenerateKeyDialog()));
+ connect(createKeyButton, SIGNAL(clicked(bool)), this, SLOT(slotGenerateKeyDialog()));
setLayout(layout);
}
@@ -379,8 +386,9 @@ int KeyGenPage::nextId() const {
}
void KeyGenPage::slotGenerateKeyDialog() {
+ qDebug() << "Try Opening KeyGenDialog";
auto *keyGenDialog = new KeyGenDialog(mCtx, this);
- keyGenDialog->exec();
+ keyGenDialog->show();
wizard()->next();
}
@@ -389,9 +397,14 @@ ConclusionPage::ConclusionPage(QWidget *parent)
setTitle(tr("Ready."));
setSubTitle(tr("Have fun with GPGFrontend!"));
- auto *bottomLabel = new QLabel(tr("You are ready to use GPGFrontend now.<br><br>"
- "The offline help will get you started with GPGFrontend. "
- "It will open in the main window.<br>"));
+ auto *bottomLabel = new QLabel(tr("You are ready to use GPGFrontend now.<br><br>")+
+ "<a href=\"https://saturneric.github.io/GpgFrontend/index.html#/overview\">"
+ + tr("The Online Document") + "</a>"
+ + tr(" will get you started with GPGFrontend. It will open in the main window.<br>"));
+
+ bottomLabel->setTextFormat(Qt::RichText);
+ bottomLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
+ bottomLabel->setOpenExternalLinks(true);
bottomLabel->setWordWrap(true);
openHelpCheckBox = new QCheckBox(tr("Open offline help."));
@@ -401,11 +414,11 @@ ConclusionPage::ConclusionPage(QWidget *parent)
dontShowWizardCheckBox->setChecked(Qt::Checked);
registerField("showWizard", dontShowWizardCheckBox);
- registerField("openHelp", openHelpCheckBox);
+ // registerField("openHelp", openHelpCheckBox);
auto *layout = new QVBoxLayout;
layout->addWidget(bottomLabel);
- layout->addWidget(openHelpCheckBox);
+ // layout->addWidget(openHelpCheckBox);
layout->addWidget(dontShowWizardCheckBox);
setLayout(layout);
setVisible(true);
diff --git a/src/ui/keypair_details/KeyPairDetailTab.cpp b/src/ui/keypair_details/KeyPairDetailTab.cpp
index c72a7685..013d8e11 100644
--- a/src/ui/keypair_details/KeyPairDetailTab.cpp
+++ b/src/ui/keypair_details/KeyPairDetailTab.cpp
@@ -131,16 +131,17 @@ KeyPairDetailTab::KeyPairDetailTab(GpgME::GpgContext *ctx, const GpgKey &mKey, Q
auto *privKeyBox = new QGroupBox(tr("Operations"));
auto *vboxPK = new QVBoxLayout();
- auto *exportButton = new QPushButton(tr("Export Private Key"));
+ auto *exportButton = new QPushButton(tr("Export Private Key (Include Subkeys)"));
vboxPK->addWidget(exportButton);
connect(exportButton, SIGNAL(clicked()), this, SLOT(slotExportPrivateKey()));
if(mKey.has_master_key) {
- auto *editExpiresButton = new QPushButton(tr("Modify Expiration Datetime"));
+ auto *editExpiresButton = new QPushButton(tr("Modify Expiration Datetime (Master Key)"));
vboxPK->addWidget(editExpiresButton);
connect(editExpiresButton, SIGNAL(clicked()), this, SLOT(slotModifyEditDatetime()));
- auto *keyServerOperaButton = new QPushButton(tr("Key Server Operation"));
+ auto *keyServerOperaButton = new QPushButton(tr("Key Server Operation (Pubkey)"));
+ keyServerOperaButton->setStyleSheet("text-align:center;");
vboxPK->addWidget(keyServerOperaButton);
connect(keyServerOperaButton, SIGNAL(clicked()), this, SLOT(slotModifyEditDatetime()));
@@ -197,7 +198,12 @@ void KeyPairDetailTab::slotExportPrivateKey() {
// export key, if ok was clicked
if (ret == QMessageBox::Ok) {
auto *keyArray = new QByteArray();
- mCtx->exportSecretKey(*keyid, keyArray);
+
+ if(!mCtx->exportSecretKey(mKey, keyArray)) {
+ QMessageBox::critical(this, "Error", "An error occurred during the export operation.");
+ return;
+ }
+
auto &key = mCtx->getKeyById(*keyid);
QString fileString = key.name + " " +key.email + "(" +
key.id + ")_secret.asc";
diff --git a/src/ui/keypair_details/KeyPairSubkeyTab.cpp b/src/ui/keypair_details/KeyPairSubkeyTab.cpp
index c5647553..70c7e4b8 100644
--- a/src/ui/keypair_details/KeyPairSubkeyTab.cpp
+++ b/src/ui/keypair_details/KeyPairSubkeyTab.cpp
@@ -222,7 +222,7 @@ void KeyPairSubkeyTab::slotRefreshSubkeyDetail() {
}
void KeyPairSubkeyTab::createSubkeyOperaMenu() {
- subkeyOperaMenu = new QMenu();
+ subkeyOperaMenu = new QMenu(this);
// auto *revokeSubkeyAct = new QAction(tr("Revoke Subkey"));
auto *editSubkeyAct = new QAction(tr("Edit Expire Date"));
connect(editSubkeyAct, SIGNAL(triggered(bool)), this, SLOT(slotEditSubkey()));
@@ -232,6 +232,7 @@ void KeyPairSubkeyTab::createSubkeyOperaMenu() {
}
void KeyPairSubkeyTab::slotEditSubkey() {
+ qDebug() << "Slot Edit Subkry";
auto *subkey = getSelectedSubkey();
if(subkey == buffered_subkeys[0]) {
subkey = nullptr;
@@ -245,7 +246,7 @@ void KeyPairSubkeyTab::slotRevokeSubkey() {
}
void KeyPairSubkeyTab::contextMenuEvent(QContextMenuEvent *event) {
- if (subkeyList->selectedItems().length() > 0) {
+ if (!subkeyList->selectedItems().isEmpty()) {
subkeyOperaMenu->exec(event->globalPos());
}
}
diff --git a/src/ui/main_window/MainWindowSlotFunction.cpp b/src/ui/main_window/MainWindowSlotFunction.cpp
index dcc31527..f820a4e6 100644
--- a/src/ui/main_window/MainWindowSlotFunction.cpp
+++ b/src/ui/main_window/MainWindowSlotFunction.cpp
@@ -352,7 +352,9 @@ void MainWindow::refreshKeysFromKeyserver() {
void MainWindow::uploadKeyToServer() {
QVector<GpgKey> keys;
keys.append(mKeyList->getSelectedKey());
- auto *dialog = new KeyUploadDialog(mCtx, keys);
+ auto *dialog = new KeyUploadDialog(mCtx, keys, this);
+ dialog->show();
+ dialog->slotUpload();
}
void MainWindow::slotFileEncrypt() {