diff options
author | Saturneric <[email protected]> | 2022-12-22 10:30:36 +0000 |
---|---|---|
committer | Saturneric <[email protected]> | 2022-12-22 10:30:36 +0000 |
commit | 3cb623b07e50d9e95dace9966dc0337e72f57dc2 (patch) | |
tree | dfe994f28f0a6dee6151febf3b50f22adceab74e | |
parent | Merge pull request #70 from saturneric/dev/2.0.8/saturneric (diff) | |
parent | fix: continue to solve ubuntu 18.04 build issues (diff) | |
download | GpgFrontend-3cb623b07e50d9e95dace9966dc0337e72f57dc2.tar.gz GpgFrontend-3cb623b07e50d9e95dace9966dc0337e72f57dc2.zip |
fix: solve conflictsv2.0.10
58 files changed, 1420 insertions, 347 deletions
diff --git a/.github/workflows/debug.yml b/.github/workflows/debug.yml index 05add7a5..26bbcad2 100644 --- a/.github/workflows/debug.yml +++ b/.github/workflows/debug.yml @@ -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' + if: matrix.os == 'windows-latest' || matrix.os == 'macos-10.15' || matrix.os == 'macos-11' || matrix.os == 'macos-12' - uses: actions/checkout@v2 with: @@ -58,7 +58,7 @@ jobs: brew unlink gettext && brew link --force gettext brew link qt@5 brew link [email protected] --force - if: matrix.os == 'macos-10.15' + if: matrix.os == 'macos-10.15' || matrix.os == 'macos-11' || matrix.os == 'macos-12' - name: Build gpg-error (Linux) run: | @@ -130,7 +130,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' + if: matrix.os == 'macos-10.15' || matrix.os == 'macos-11' || matrix.os == 'macos-12' - name: Configure CMake & Build Binary(Windows) shell: msys2 {0} @@ -158,7 +158,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' + if: matrix.os == 'macos-10.15' || matrix.os == 'macos-11' || matrix.os == 'macos-12' - name: Upload Artifact(Windows) uses: actions/upload-artifact@master diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 15e5b298..9b9e8f82 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -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' + if: matrix.os == 'windows-2019' || matrix.os == 'macos-10.15' || matrix.os == 'macos-11' || matrix.os == 'macos-12' - uses: actions/checkout@v2 with: @@ -46,7 +46,7 @@ jobs: sudo apt-get update sudo apt-get -y install build-essential binutils git autoconf automake gettext texinfo 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 libconfig++-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 @@ -57,6 +57,23 @@ jobs: sudo update-alternatives --set g++ "/usr/bin/g++-8" if: matrix.os == 'ubuntu-18.04' + - name: Install Boost (Linux) + uses: MarkusJx/[email protected] + id: install-boost + with: + # REQUIRED: Specify the required boost version + # A list of supported versions can be found here: + # https://github.com/MarkusJx/prebuilt-boost/blob/main/versions-manifest.json + boost_version: 1.78.0 + # OPTIONAL: Specify a platform version + platform_version: 18.04 + # OPTIONAL: Specify an architecture + arch: x86 + + # NOTE: If a boost version matching all requirements cannot be found, + # this build step will fail + if: matrix.os == 'ubuntu-18.04' + - name: Codesign Configuration (macOS) run: | CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12 @@ -75,7 +92,7 @@ jobs: mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles - if: matrix.os == 'macos-10.15' + if: matrix.os == 'macos-10.15' || matrix.os == 'macos-11' || matrix.os == 'macos-12' - name: Install Dependence (macOS) run: | @@ -84,7 +101,7 @@ jobs: brew unlink gettext && brew link --force gettext brew link qt@5 brew link [email protected] --force - if: matrix.os == 'macos-10.15' + if: matrix.os == 'macos-10.15' || matrix.os == 'macos-11' || matrix.os == 'macos-12' - name: Build gpg-error (Linux) run: | @@ -147,7 +164,7 @@ jobs: - name: Build GpgFrontend (Linux) # Build your GpgFrontend with the given configuration run: | - cmake -B ${{github.workspace}}/build -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} + cmake -B ${{github.workspace}}/build -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBOOST_ROOT=${{steps.install-boost.outputs.BOOST_ROOT}} cmake --build ${{github.workspace}}/build --config {{$env.BUILD_TYPE}} -- -v if: matrix.os == 'ubuntu-18.04' @@ -169,7 +186,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' + if: matrix.os == 'macos-10.15' || matrix.os == 'macos-11' || matrix.os == 'macos-12' - name: Package & Sign App Bundle (macOS) run: | @@ -184,7 +201,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' + if: matrix.os == 'macos-10.15' || matrix.os == 'macos-11' || matrix.os == 'macos-12' - name: Notarize Release Build (macOS) run: | @@ -193,7 +210,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' + if: matrix.os == 'macos-10.15' || matrix.os == 'macos-11' || matrix.os == 'macos-12' - name: Package App Image (Linux) run: | @@ -226,7 +243,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' + if: matrix.os == 'macos-10.15' || matrix.os == 'macos-11' || matrix.os == 'macos-12' - name: Upload Artifact(Windows) uses: actions/upload-artifact@master diff --git a/.gitmodules b/.gitmodules index 9131b1ff..f8ddc595 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,24 +1,24 @@ [submodule "third_party/gpgme"] path = third_party/gpgme - url = https://github.com/saturneric/gpgme + url = https://git.bktus.com/GnuPG/gpgme.git [submodule "third_party/libassuan"] path = third_party/libassuan - url = https://github.com/saturneric/libassuan + url = https://git.bktus.com/GnuPG/libassuan.git [submodule "third_party/libgpg-error"] path = third_party/libgpg-error - url = https://github.com/saturneric/libgpg-error + url = https://git.bktus.com/GnuPG/libgpg-error.git [submodule "third_party/json"] path = third_party/json - url = https://github.com/saturneric/json + url = https://git.bktus.com/GpgFrontend/json.git [submodule "third_party/easyloggingpp"] path = third_party/easyloggingpp - url = https://github.com/saturneric/easyloggingpp + url = https://git.bktus.com/GpgFrontend/easyloggingpp.git [submodule "third_party/qt-aes"] path = third_party/qt-aes - url = https://github.com/saturneric/Qt-AES + url = https://git.bktus.com/GpgFrontend/Qt-AES.git [submodule "third_party/libarchive"] path = third_party/libarchive - url = https://github.com/saturneric/libarchive.git + url = https://git.bktus.com/GpgFrontend/libarchive.git [submodule "third_party/libconfig"] path = third_party/libconfig - url = https://github.com/saturneric/libconfig + url = https://git.bktus.com/GpgFrontend/libconfig.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 171238eb..1f08f440 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,7 +27,7 @@ cmake_minimum_required(VERSION 3.16) # define project -project(GpgFrontend VERSION 2.0.9 LANGUAGES CXX) +project(GpgFrontend VERSION 2.0.10 LANGUAGES CXX) # show cmake version message(STATUS "GpgFrontend Build Configuration Started CMAKE Version ${CMAKE_VERSION}") @@ -56,6 +56,8 @@ option(GPGFRONTEND_BUILD_TYPE_STABLE "Generate release version" ON) option(GPGFRONTEND_GENERATE_LINUX_INSTALL_SOFTWARE "Generate an installable version" OFF) option(GPGFRONTEND_GENERATE_APP_PACKAGE_DEB "Generate DEB package" OFF) +option(GPGFRONTEND_GENERATE_APP_PACKAGE_RPM "Generate RPM package" OFF) +option(GPGFRONTEND_GENERATE_APP_PACKAGE_FREEBSD "Generate PKG package" OFF) option(GPGFRONTEND_CONFIGURE_FOR_XCODE_BUILD "Generate a version that can be successfully compiled and packaged in Xcode" OFF) option(GPGFRONTEND_XCODE_TEAM_ID "GpgFrontend Apple Team ID" "NONE") option(GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY "GpgFrontend Signing Certificate" "NONE") @@ -108,11 +110,21 @@ if (GPGFRONTEND_GENERATE_LINUX_INSTALL_SOFTWARE) set(GPGFRONTEND_GENERATE_APP_PACKAGE_DEB 1) endif () -# linux package build +# linux package build deb if (GPGFRONTEND_GENERATE_LINUX_INSTALL_SOFTWARE AND GPGFRONTEND_GENERATE_APP_PACKAGE_DEB) set(APP_PACKAGE_DEB 1) endif () +# linux package build rpm +if (GPGFRONTEND_GENERATE_LINUX_INSTALL_SOFTWARE AND GPGFRONTEND_GENERATE_APP_PACKAGE_RPM) + set(APP_PACKAGE_RPM 1) +endif () + +# linux package build pkg +if (GPGFRONTEND_GENERATE_LINUX_INSTALL_SOFTWARE AND GPGFRONTEND_GENERATE_APP_PACKAGE_FREEBSD) + set(APP_PACKAGE_FREEBSD 1) +endif () + # xcode archive build if (GPGFRONTEND_CONFIGURE_FOR_XCODE_BUILD) set(GPGFRONTEND_GENERATE_LINUX_INSTALL_SOFTWARE 0) @@ -333,6 +345,16 @@ if (LINUX) set(OS_PLATFORM 2) ADD_DEFINITIONS(-DLINUX) + # Get Env Info + exec_program(uname OUTPUT_VARIABLE SYSTEM_NAME) + set(SYSTEM_NAME "${SYSTEM_NAME}" CACHE INTERNAL "") + + if(SYSTEM_NAME STREQUAL "FreeBSD") + message(STATUS "FreeBSD BOX") + ADD_DEFINITIONS(-DFREEBSD) + set(FREEBSD TRUE) + endif() + message(STATUS "GCC Version ${CMAKE_CXX_COMPILER_VERSION}") if (CMAKE_CXX_COMPILER_VERSION LESS 9) message(STATUS "GCC CXX_FLAGS add filesystem support manually") @@ -421,8 +443,17 @@ 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 -find_package(Boost COMPONENTS date_time system REQUIRED) +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) diff --git a/TRANSLATORS b/TRANSLATORS index c63b1352..5a81647e 100644 --- a/TRANSLATORS +++ b/TRANSLATORS @@ -1,5 +1,6 @@ Translators: Fabian Hêche <[email protected]> (fr_FR) +huzpsb <[email protected]> (zh_CN) Google Translation Machine Reviewers: diff --git a/manual/contract.md b/manual/contract.md index bb9de59b..3a91fd66 100644 --- a/manual/contract.md +++ b/manual/contract.md @@ -9,9 +9,9 @@ It is recommended to use plain text to contact me by email, but HTML is not reco Name: Saturneric, Eric or Erich. -Email: [[email protected]](mailto:[email protected]) +Email: [[email protected]](mailto:[email protected]) (Hosted in the Federal Republic of Germany) -Tips: BKTUS(Bakantu Union) is not a company, it is my personal domain name. +Tips: BKTUS(Bakantu union us) is not a company, it is my personal domain name. ## Languages diff --git a/manual/faq.md b/manual/faq.md index b53c149a..5e09eb24 100644 --- a/manual/faq.md +++ b/manual/faq.md @@ -5,7 +5,7 @@ GpgFrontend is a cross-platform encryption tool that conforms to the OpenPGP standard. It is committed to making OpenPGP easier to use, so that more people can use the tool to protect their privacy. -## Relationship with OpenPGP(pgp) and Gnupg(gpg)? +## Relationship between OpenPGP(pgp) and Gnupg(gpg)? OpenPGP is a data encryption and decryption standard, and GpgFrontend supports it. GnuPG is a cryptographic software used to encrypt, sign communication content and manage keys for asymmetric cryptography. It follows the OpenPGP @@ -14,7 +14,7 @@ standard. GpgFrontend drives gnupg at runtime to implement operations such as en ## How to obtain and use GpgFrontend? The various versions of GpgFrontend will be released in the GitHub repository, and you can find and download the latest -version in Releases. After downloading, you can refer to the instructions in ReadME and you can start using it in just a +version [HERE](https://www.gpgfrontend.pub/#/downloads). After downloading, you can refer to the instructions in ReadME and you can start using it in just a few steps. ## I found some flaws in GpgFrontend, what should I do? @@ -44,3 +44,12 @@ released, and release a stable version at an appropriate time. But starting from 2.0.0, BETA versions will not be released unless there are special circumstances. +## How to deal with 'ENV Loading Failed'? + +The reason for this problem is that GpgFrontend failed to find the GnuGP tool in your computer. + +- For macOS users, please install GnuPG for OSX [Here](https://sourceforge.net/p/gpgosx/docu/Download/). +- For Linux users, please install gnupg through apt or yum. +- For Windows users, GnuPG is now integrated in the latest version of GpgFrontend, we recommend you to download the + latest GpgFrontend. + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4df4579a..e00f9b60 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -271,6 +271,10 @@ if (APPLICATION_BUILD) else () message(STATUS "Link Application Library For Linux") target_link_libraries(${AppName} crypto pthread) + # link for freebsd + if(FREEBSD) + target_link_libraries(${AppName} intl) + endif() # issue on filesystem support of gcc if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 9.0) target_link_libraries(${AppName} stdc++fs) @@ -315,15 +319,8 @@ if (LINUX AND LINUX_INSTALL_SOFTWARE) DESTINATION ${CMAKE_INSTALL_FULL_LOCALEDIR}) endif () - cmake_host_system_information(RESULT PRETTY_NAME QUERY DISTRIB_PRETTY_NAME) - cmake_host_system_information(RESULT DISTRO QUERY DISTRIB_INFO) - - foreach(VAR IN LISTS DISTRO) - message(STATUS "${VAR}=`${${VAR}}`") - endforeach() - if (APP_PACKAGE_DEB) - message(STATUS "Configure Deb Package") + message(STATUS "Configure DEB Package") SET(CPACK_GENERATOR "DEB") set(CPACK_INSTALL_PREFIX "/usr/local/") set(CPACK_PACKAGE_NAME "gpgfrontend") @@ -345,8 +342,9 @@ if (LINUX AND LINUX_INSTALL_SOFTWARE) set(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}") include(CPack) endif () - if (APP_PACKAGE_RPM) - message(STATUS "Configure Rpm Package") + + if (APP_PACKAGE_RPM) + message(STATUS "Configure RPM Package") SET(CPACK_GENERATOR "RPM") set(CPACK_INSTALL_PREFIX "/usr/local/") set(CPACK_PACKAGE_NAME "gpgfrontend") @@ -360,6 +358,21 @@ if (LINUX AND LINUX_INSTALL_SOFTWARE) set(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}") include(CPack) endif () + + if (APP_PACKAGE_FREEBSD) + message(STATUS "Configure PKG Package") + SET(CPACK_GENERATOR "FREEBSD") + set(CPACK_INSTALL_PREFIX "/usr/local/") + set(CPACK_FREEBSD_PACKAGE_NAME "gpgfrontend") + set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64") + set(CPACK_PACKAGE_CONTACT "[email protected]") + SET(CPACK_FREEBSD_PACKAGE_MAINTAINER "Saturneric") + + set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}") + set(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}") + set(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}") + include(CPack) + endif () endif () message(STATUS "Resource Files: ${RESOURCE_OUTPUT_DIRECTORY}") diff --git a/src/core/GpgConstants.h b/src/core/GpgConstants.h index 06f8e20d..a8a87835 100644 --- a/src/core/GpgConstants.h +++ b/src/core/GpgConstants.h @@ -31,10 +31,10 @@ #include "GpgFrontendCore.h" -const int RESTART_CODE = 1000; ///< +const int RESTART_CODE = 1000; ///< only refresh ui +const int DEEP_RESTART_CODE = 1001; // refresh core and ui namespace GpgFrontend { - using ByteArray = std::string; ///< using ByteArrayPtr = std::unique_ptr<ByteArray>; ///< using StdBypeArrayPtr = std::unique_ptr<ByteArray>; ///< diff --git a/src/core/GpgContext.cpp b/src/core/GpgContext.cpp index 28857d32..7ebd9fa9 100644 --- a/src/core/GpgContext.cpp +++ b/src/core/GpgContext.cpp @@ -102,6 +102,9 @@ GpgContext::GpgContext(const GpgContextInitArgs &args) : args_(args) { find_openpgp = true; info_.AppPath = engine_info->file_name; info_.GnupgVersion = engine_info->version; + info_.DatabasePath = std::string(engine_info->home_dir == nullptr + ? "default" + : engine_info->home_dir); break; case GPGME_PROTOCOL_CMS: find_cms = true; @@ -128,6 +131,16 @@ GpgContext::GpgContext(const GpgContextInitArgs &args) : args_(args) { engine_info = engine_info->next; } + // set custom key db path + if (!args.db_path.empty()) { + info_.DatabasePath = args.db_path; + 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; + assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR); + } + // conditional check if ((info_.GnupgVersion >= "2.0.0" && find_gpgconf && find_openpgp && find_cms) || diff --git a/src/core/GpgCoreInit.cpp b/src/core/GpgCoreInit.cpp index f1664b2a..9ccc693d 100644 --- a/src/core/GpgCoreInit.cpp +++ b/src/core/GpgCoreInit.cpp @@ -77,23 +77,69 @@ void InitLoggingSystem() { LOG(INFO) << _("log file path") << logfile_path; } +void ResetGpgFrontendCore() { reset_gpgfrontend_core(); } + void init_gpgfrontend_core() { + // read from settings file + + bool use_custom_key_database_path = false; + try { + auto& settings = + GpgFrontend::GlobalSettingStation::GetInstance().GetUISettings(); + use_custom_key_database_path = + settings.lookup("general.use_custom_key_database_path"); + } catch (...) { + LOG(ERROR) << _("Setting Operation Error") + << _("use_custom_key_database_path"); + } + + LOG(INFO) << "core loaded if use custom key databse path: " + << use_custom_key_database_path; + + std::string custom_key_database_path; + try { + auto& settings = + GpgFrontend::GlobalSettingStation::GetInstance().GetUISettings(); + custom_key_database_path = static_cast<std::string>( + settings.lookup("general.custom_key_database_path")); + + } catch (...) { + LOG(ERROR) << _("Setting Operation Error") << _("custom_key_database_path"); + } + + LOG(INFO) << "core loaded custom key databse path: " + << custom_key_database_path; + // init default channel GpgFrontend::GpgContext::CreateInstance( - GPGFRONTEND_DEFAULT_CHANNEL, [&]() -> std::unique_ptr<ChannelObject> { + GPGFRONTEND_DEFAULT_CHANNEL, [=]() -> std::unique_ptr<ChannelObject> { GpgFrontend::GpgContextInitArgs args; + + // set key database path + if (use_custom_key_database_path && !custom_key_database_path.empty()) { + args.db_path = custom_key_database_path; + } + return std::unique_ptr<ChannelObject>(new GpgContext(args)); }); // init non-ascii channel GpgFrontend::GpgContext::CreateInstance( - GPGFRONTEND_NON_ASCII_CHANNEL, [&]() -> std::unique_ptr<ChannelObject> { + GPGFRONTEND_NON_ASCII_CHANNEL, [=]() -> std::unique_ptr<ChannelObject> { GpgFrontend::GpgContextInitArgs args; args.ascii = false; + + // set key database path + if (use_custom_key_database_path && !custom_key_database_path.empty()) { + args.db_path = custom_key_database_path; + } + return std::unique_ptr<ChannelObject>(new GpgContext(args)); }); } +void reset_gpgfrontend_core() { SingletonStorageCollection::GetInstance(true); } + void new_default_settings_channel(int channel) { GpgFrontend::GpgContext::CreateInstance( channel, [&]() -> std::unique_ptr<ChannelObject> { diff --git a/src/core/GpgCoreInit.h b/src/core/GpgCoreInit.h index 150e85e9..77942b56 100644 --- a/src/core/GpgCoreInit.h +++ b/src/core/GpgCoreInit.h @@ -43,11 +43,23 @@ void GPGFRONTEND_CORE_EXPORT InitLoggingSystem(); * @brief * */ +void GPGFRONTEND_CORE_EXPORT ResetGpgFrontendCore(); + +/** + * @brief + * + */ void init_gpgfrontend_core(); /** * @brief * + */ +void reset_gpgfrontend_core(); + +/** + * @brief + * * @param channel */ void new_default_settings_channel( diff --git a/src/core/GpgFunctionObject.cpp b/src/core/GpgFunctionObject.cpp index 1289d72f..6ff83d72 100644 --- a/src/core/GpgFunctionObject.cpp +++ b/src/core/GpgFunctionObject.cpp @@ -122,11 +122,15 @@ GpgFrontend::SingletonStorageCollection::GetSingletonStorage( } GpgFrontend::SingletonStorageCollection* -GpgFrontend::SingletonStorageCollection::GetInstance() { +GpgFrontend::SingletonStorageCollection::GetInstance( + bool force_refresh = false) { static SingletonStorageCollection* instance = nullptr; - if (instance == nullptr) { + + if (force_refresh || instance == nullptr) { instance = new SingletonStorageCollection(); + LOG(INFO) << "new single storage collection created: " << instance; } + return instance; } diff --git a/src/core/GpgFunctionObject.h b/src/core/GpgFunctionObject.h index de27ea42..56d0ab22 100644 --- a/src/core/GpgFunctionObject.h +++ b/src/core/GpgFunctionObject.h @@ -125,7 +125,7 @@ class GPGFRONTEND_CORE_EXPORT SingletonStorageCollection { * * @return SingletonStorageCollection* */ - static SingletonStorageCollection* GetInstance(); + static SingletonStorageCollection* GetInstance(bool force_refresh); /** * @brief Get the Singleton Storage object @@ -173,7 +173,7 @@ class SingletonFunctionObject : public ChannelObject { "T not derived from SingletonFunctionObject<T>"); auto p_storage = - SingletonStorageCollection::GetInstance()->GetSingletonStorage( + SingletonStorageCollection::GetInstance(false)->GetSingletonStorage( typeid(T)); auto* _p_pbj = (T*)(p_storage->FindObjectInChannel(channel)); @@ -200,7 +200,7 @@ class SingletonFunctionObject : public ChannelObject { "T not derived from SingletonFunctionObject<T>"); auto p_storage = - SingletonStorageCollection::GetInstance()->GetSingletonStorage( + SingletonStorageCollection::GetInstance(false)->GetSingletonStorage( typeid(T)); auto _p_pbj = (T*)(p_storage->FindObjectInChannel(channel)); @@ -219,7 +219,7 @@ class SingletonFunctionObject : public ChannelObject { * @return T& */ static void ReleaseChannel(int channel) { - SingletonStorageCollection::GetInstance() + SingletonStorageCollection::GetInstance(false) ->GetSingletonStorage(typeid(T)) ->ReleaseChannel(channel); } @@ -244,7 +244,7 @@ class SingletonFunctionObject : public ChannelObject { * @return std::vector<int> */ static std::vector<int> GetAllChannelId() { - return SingletonStorageCollection::GetInstance() + return SingletonStorageCollection::GetInstance(false) ->GetSingletonStorage(typeid(T)) ->GetAllChannelId(); } diff --git a/src/core/GpgGenKeyInfo.cpp b/src/core/GpgGenKeyInfo.cpp index 6ca83c96..f9065529 100644 --- a/src/core/GpgGenKeyInfo.cpp +++ b/src/core/GpgGenKeyInfo.cpp @@ -28,38 +28,48 @@ #include "core/GpgGenKeyInfo.h" +#include <algorithm> #include <boost/date_time/gregorian/greg_date.hpp> #include <boost/date_time/gregorian/greg_duration.hpp> #include <boost/date_time/gregorian/gregorian_types.hpp> +#include <cassert> #include <string> #include <vector> -void GpgFrontend::GenKeyInfo::SetAlgo(const std::string &m_algo) { - LOG(INFO) << "set algo" << m_algo; +void GpgFrontend::GenKeyInfo::SetAlgo( + const GpgFrontend::GenKeyInfo::KeyGenAlgo &m_algo) { + LOG(INFO) << "set algo name" << m_algo.first; // Check algo if supported - std::string algo_args = std::string(m_algo); - boost::algorithm::to_upper(algo_args); + std::string algo_args = m_algo.second; if (standalone_) { if (!subkey_) { auto support_algo = GetSupportedKeyAlgoStandalone(); - auto it = std::find(support_algo.begin(), support_algo.end(), algo_args); + auto it = std::find_if( + support_algo.begin(), support_algo.end(), + [=](const KeyGenAlgo &o) { return o.second == algo_args; }); // Algo Not Supported if (it == support_algo.end()) return; } else { auto support_algo = GetSupportedSubkeyAlgoStandalone(); - auto it = std::find(support_algo.begin(), support_algo.end(), algo_args); + auto it = std::find_if( + support_algo.begin(), support_algo.end(), + [=](const KeyGenAlgo &o) { return o.second == algo_args; }); // Algo Not Supported if (it == support_algo.end()) return; } } else { if (!subkey_) { auto support_algo = GetSupportedKeyAlgo(); - auto it = std::find(support_algo.begin(), support_algo.end(), algo_args); + auto it = std::find_if( + support_algo.begin(), support_algo.end(), + [=](const KeyGenAlgo &o) { return o.second == algo_args; }); // Algo Not Supported if (it == support_algo.end()) return; } else { auto support_algo = GetSupportedSubkeyAlgo(); - auto it = std::find(support_algo.begin(), support_algo.end(), algo_args); + auto it = std::find_if( + support_algo.begin(), support_algo.end(), + [=](const KeyGenAlgo &o) { return o.second == algo_args; }); // Algo Not Supported if (it == support_algo.end()) return; } @@ -116,22 +126,51 @@ void GpgFrontend::GenKeyInfo::SetAlgo(const std::string &m_algo) { suggest_max_key_size_ = -1; suggest_size_addition_step_ = -1; SetKeyLength(-1); - } else if (algo_args == "elg") { - /** - * GnuPG supports the Elgamal asymmetric encryption algorithm in key lengths - * ranging from 1024 to 4096 bits. - */ + } else if (algo_args == "cv25519") { SetAllowAuthentication(false); allow_change_authentication_ = false; SetAllowSigning(false); allow_change_signing_ = false; + SetAllowCertification(false); + allow_change_certification_ = false; + suggest_min_key_size_ = 1024; suggest_max_key_size_ = 4096; suggest_size_addition_step_ = 1024; SetKeyLength(2048); + } else if (algo_args == "nistp256" || algo_args == "nistp384" || + algo_args == "nistp521") { + SetAllowAuthentication(false); + allow_change_authentication_ = false; + + SetAllowSigning(false); + allow_change_signing_ = false; + + SetAllowCertification(false); + allow_change_certification_ = false; + + suggest_min_key_size_ = -1; + suggest_max_key_size_ = -1; + suggest_size_addition_step_ = -1; + SetKeyLength(-1); + } else if (algo_args == "brainpoolp256r1") { + SetAllowAuthentication(false); + allow_change_authentication_ = false; + + SetAllowSigning(false); + allow_change_signing_ = false; + + SetAllowCertification(false); + allow_change_certification_ = false; + + suggest_min_key_size_ = -1; + suggest_max_key_size_ = -1; + suggest_size_addition_step_ = -1; + SetKeyLength(-1); } + this->algo_ = algo_args; } @@ -194,32 +233,52 @@ void GpgFrontend::GenKeyInfo::SetAllowCertification( GpgFrontend::GenKeyInfo::GenKeyInfo(bool m_is_sub_key, bool m_standalone) : standalone_(m_standalone), subkey_(m_is_sub_key) { - SetAlgo("rsa"); + assert(GetSupportedKeyAlgo().size() > 0); + SetAlgo(GetSupportedKeyAlgo()[0]); } -const std::vector<std::string> &GpgFrontend::GenKeyInfo::GetSupportedKeyAlgo() { - static const std::vector<std::string> support_key_algo = {"RSA", "DSA", - "ED25519"}; +const std::vector<GpgFrontend::GenKeyInfo::KeyGenAlgo> + &GpgFrontend::GenKeyInfo::GetSupportedKeyAlgo() { + static const std::vector<GpgFrontend::GenKeyInfo::KeyGenAlgo> + support_key_algo = { + {"RSA", "RSA"}, + {"DSA", "DSA"}, + {"ECDSA", "ED25519"}, + }; return support_key_algo; } -const std::vector<std::string> +const std::vector<GpgFrontend::GenKeyInfo::KeyGenAlgo> &GpgFrontend::GenKeyInfo::GetSupportedSubkeyAlgo() { - static const std::vector<std::string> support_subkey_algo = {"RSA", "DSA", - "ED25519"}; + static const std::vector<GpgFrontend::GenKeyInfo::KeyGenAlgo> + support_subkey_algo = { + {"RSA", "RSA"}, + {"DSA", "DSA"}, + {"ECDSA", "ED25519"}, + {"ECDH NIST P-256", "NISTP256"}, + {"ECDH NIST P-384", "NISTP384"}, + {"ECDH NIST P-521", "NISTP521"}, + // {"ECDH BrainPool P-256", "BRAINPOOlP256R1"} + }; return support_subkey_algo; } -const std::vector<std::string> +const std::vector<GpgFrontend::GenKeyInfo::KeyGenAlgo> &GpgFrontend::GenKeyInfo::GetSupportedKeyAlgoStandalone() { - static const std::vector<std::string> support_subkey_algo_standalone = { - "RSA", "DSA"}; + static const std::vector<GpgFrontend::GenKeyInfo::KeyGenAlgo> + support_subkey_algo_standalone = { + {"RSA", "RSA"}, + {"DSA", "DSA"}, + }; return support_subkey_algo_standalone; } -const std::vector<std::string> +const std::vector<GpgFrontend::GenKeyInfo::KeyGenAlgo> &GpgFrontend::GenKeyInfo::GetSupportedSubkeyAlgoStandalone() { - static const std::vector<std::string> support_subkey_algo_standalone = { - "RSA", "DSA", "ELG-E"}; + static const std::vector<GpgFrontend::GenKeyInfo::KeyGenAlgo> + support_subkey_algo_standalone = { + {"RSA", "RSA"}, + {"DSA", "DSA"}, + }; return support_subkey_algo_standalone; } diff --git a/src/core/GpgGenKeyInfo.h b/src/core/GpgGenKeyInfo.h index 73dd9680..d47b803e 100644 --- a/src/core/GpgGenKeyInfo.h +++ b/src/core/GpgGenKeyInfo.h @@ -62,34 +62,36 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo { std::string passphrase_; ///< + using KeyGenAlgo = std::pair<std::string, std::string>; + public: /** * @brief Get the Supported Key Algo object * * @return const std::vector<std::string>& */ - static const std::vector<std::string> &GetSupportedKeyAlgo(); + static const std::vector<KeyGenAlgo> &GetSupportedKeyAlgo(); /** * @brief Get the Supported Subkey Algo object * * @return const std::vector<std::string>& */ - static const std::vector<std::string> &GetSupportedSubkeyAlgo(); + static const std::vector<KeyGenAlgo> &GetSupportedSubkeyAlgo(); /** * @brief Get the Supported Key Algo Standalone object * * @return const std::vector<std::string>& */ - static const std::vector<std::string> &GetSupportedKeyAlgoStandalone(); + static const std::vector<KeyGenAlgo> &GetSupportedKeyAlgoStandalone(); /** * @brief Get the Supported Subkey Algo Standalone object * * @return const std::vector<std::string>& */ - static const std::vector<std::string> &GetSupportedSubkeyAlgoStandalone(); + static const std::vector<KeyGenAlgo> &GetSupportedSubkeyAlgoStandalone(); /** * @brief @@ -171,7 +173,7 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo { * * @param m_algo */ - void SetAlgo(const std::string &m_algo); + void SetAlgo(const GpgFrontend::GenKeyInfo::KeyGenAlgo &m_algo); /** * @brief Get the Key Size Str object diff --git a/src/core/function/GlobalSettingStation.cpp b/src/core/function/GlobalSettingStation.cpp index db8d1bc3..7231ac9e 100644 --- a/src/core/function/GlobalSettingStation.cpp +++ b/src/core/function/GlobalSettingStation.cpp @@ -55,6 +55,7 @@ GpgFrontend::GlobalSettingStation::GlobalSettingStation(int channel) noexcept 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_; if (!is_directory(app_configure_path_)) create_directory(app_configure_path_); diff --git a/src/core/function/GlobalSettingStation.h b/src/core/function/GlobalSettingStation.h index 58282466..8811623f 100644 --- a/src/core/function/GlobalSettingStation.h +++ b/src/core/function/GlobalSettingStation.h @@ -173,10 +173,9 @@ class GPGFRONTEND_CORE_EXPORT GlobalSettingStation QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) .toStdString(); ///< Program Configure Location std::filesystem::path ui_config_dir_path_ = - app_configure_path_ / - "UserInterface"; ///< Configure File Directory Location + app_configure_path_ / "conf"; ///< Configure File Directory Location std::filesystem::path ui_config_path_ = - ui_config_dir_path_ / "ui.cfg"; ///< UI Configure File Location + ui_config_dir_path_ / "main.cfg"; ///< Main Configure File Location libconfig::Config ui_cfg_; ///< UI Configure File diff --git a/src/core/function/gpg/GpgKeyGetter.cpp b/src/core/function/gpg/GpgKeyGetter.cpp index ff848e0e..571e8797 100644 --- a/src/core/function/gpg/GpgKeyGetter.cpp +++ b/src/core/function/gpg/GpgKeyGetter.cpp @@ -88,13 +88,10 @@ GpgFrontend::KeyLinkListPtr GpgFrontend::GpgKeyGetter::FetchKey() { auto keys_list = std::make_unique<GpgKeyLinkList>(); - LOG(INFO) << "cache address:" << &keys_cache_ << "object address" << this; - for (const auto& [key, value] : keys_cache_) { LOG(INFO) << "FetchKey Id:" << value.GetId(); keys_list->push_back(value.Copy()); } - LOG(INFO) << "ended"; return keys_list; } @@ -141,8 +138,6 @@ void GpgFrontend::GpgKeyGetter::FlushKeyCache() { err = gpgme_op_keylist_end(ctx_); assert(check_gpg_error_2_err_code(err, GPG_ERR_EOF) == GPG_ERR_NO_ERROR); - - LOG(INFO) << "ended"; } GpgFrontend::KeyListPtr GpgFrontend::GpgKeyGetter::GetKeys( diff --git a/src/core/function/gpg/GpgKeyOpera.cpp b/src/core/function/gpg/GpgKeyOpera.cpp index 03d8c8d9..0839c132 100644 --- a/src/core/function/gpg/GpgKeyOpera.cpp +++ b/src/core/function/gpg/GpgKeyOpera.cpp @@ -245,6 +245,10 @@ 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(); + auto algo_utf8 = (params->GetAlgo() + params->GetKeySizeStr()); const char* algo = algo_utf8.c_str(); unsigned long expires = 0; diff --git a/src/core/model/GpgKey.cpp b/src/core/model/GpgKey.cpp index ad88a649..4716d9cc 100644 --- a/src/core/model/GpgKey.cpp +++ b/src/core/model/GpgKey.cpp @@ -28,6 +28,8 @@ #include "core/model/GpgKey.h" +#include <mutex> + GpgFrontend::GpgKey::GpgKey(gpgme_key_t &&key) : key_ref_(std::move(key)) {} GpgFrontend::GpgKey::GpgKey(GpgKey &&k) noexcept { swap(key_ref_, k.key_ref_); } @@ -225,7 +227,10 @@ bool GpgFrontend::GpgKey::IsHasActualEncryptionCapability() const { } GpgFrontend::GpgKey GpgFrontend::GpgKey::Copy() const { - gpgme_key_ref(key_ref_.get()); + { + const std::lock_guard<std::mutex> guard(gpgme_key_opera_mutex); + gpgme_key_ref(key_ref_.get()); + } auto *_new_key_ref = key_ref_.get(); return GpgKey(std::move(_new_key_ref)); } diff --git a/src/core/model/GpgKey.h b/src/core/model/GpgKey.h index 4761f8a5..8c24ca5d 100644 --- a/src/core/model/GpgKey.h +++ b/src/core/model/GpgKey.h @@ -29,6 +29,8 @@ #ifndef GPGFRONTEND_GPGKEY_H #define GPGFRONTEND_GPGKEY_H +#include <mutex> + #include "GpgSubKey.h" #include "GpgUID.h" @@ -353,6 +355,8 @@ class GPGFRONTEND_CORE_EXPORT GpgKey { std::unique_ptr<struct _gpgme_key, _key_ref_deleter>; ///< KeyRefHandler key_ref_ = nullptr; ///< + + mutable std::mutex gpgme_key_opera_mutex; // mutex for gpgme key operations }; } // namespace GpgFrontend diff --git a/src/core/thread/TaskRunner.cpp b/src/core/thread/TaskRunner.cpp index 7116ca71..f70b2d4c 100644 --- a/src/core/thread/TaskRunner.cpp +++ b/src/core/thread/TaskRunner.cpp @@ -36,19 +36,18 @@ GpgFrontend::Thread::TaskRunner::TaskRunner() = default; GpgFrontend::Thread::TaskRunner::~TaskRunner() = default; void GpgFrontend::Thread::TaskRunner::PostTask(Task* task) { - LOG(TRACE) << "Post Task" << task->GetUUID(); + std::string uuid = task->GetUUID(); + LOG(TRACE) << "Post Task" << uuid; if (task == nullptr) return; task->setParent(nullptr); task->moveToThread(this); - connect(task, &Task::SignalTaskPostFinishedDone, this, [=]() { - auto it = pending_tasks_.find(task->GetUUID()); + connect(task, &Task::SignalTaskPostFinishedDone, this, [&, uuid]() { + auto it = pending_tasks_.find(uuid); if (it == pending_tasks_.end()) { - LOG(ERROR) << "Task" << task->GetUUID() << "not found in pending tasks"; return; } else { - LOG(TRACE) << "Task" << task->GetUUID() << "found in pending tasks"; it->second->deleteLater(); pending_tasks_.erase(it); } diff --git a/src/main.cpp b/src/main.cpp index b51c44ea..5f2ba02e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -34,6 +34,7 @@ #include <csignal> #include <cstddef> +#include "core/GpgConstants.h" #include "core/GpgCoreInit.h" #include "ui/GpgFrontendApplication.h" #include "ui/GpgFrontendUIInit.h" @@ -46,7 +47,11 @@ INITIALIZE_EASYLOGGINGPP /** * \brief Store the jump buff and make it possible to recover from a crash. */ +#ifdef FREEBSD +sigjmp_buf recover_env; +#else jmp_buf recover_env; +#endif constexpr int CRASH_CODE = ~0; ///< @@ -76,10 +81,12 @@ extern void init_logging_system(); * @return */ int main(int argc, char* argv[]) { +#ifdef RELEASE // re signal(SIGSEGV, handle_signal); signal(SIGFPE, handle_signal); signal(SIGILL, handle_signal); +#endif // clean something before exit atexit(before_exit); @@ -104,38 +111,40 @@ int main(int argc, char* argv[]) { int return_from_event_loop_code; do { + do { #ifndef WINDOWS - int r = sigsetjmp(recover_env, 1); + int r = sigsetjmp(recover_env, 1); #else - int r = setjmp(recover_env); + int r = setjmp(recover_env); #endif - if (!r) { - // init ui library - GpgFrontend::UI::InitGpgFrontendUI(app); - - // create main window - return_from_event_loop_code = GpgFrontend::UI::RunGpgFrontendUI(app); - } else { - LOG(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"), - _("Oh no! GpgFrontend caught a serious error in the software, so " - "it needs to be restarted. If the problem recurs, please " - "manually terminate the program and report the problem to the " - "developer."), - QMessageBox::Ok, nullptr); - message_box->exec(); - return_from_event_loop_code = CRASH_CODE; - } - - if (return_from_event_loop_code == CRASH_CODE) { - app = GpgFrontend::UI::GpgFrontendApplication::GetInstance(argc, argv, - true); - } - - LOG(INFO) << "loop refresh"; - } while (return_from_event_loop_code == RESTART_CODE || + if (!r) { + // init ui library + GpgFrontend::UI::InitGpgFrontendUI(app); + + // create main window + return_from_event_loop_code = GpgFrontend::UI::RunGpgFrontendUI(app); + } else { + LOG(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"), + _("Oh no! GpgFrontend caught a serious error in the software, so " + "it needs to be restarted. If the problem recurs, please " + "manually terminate the program and report the problem to the " + "developer."), + QMessageBox::Ok, nullptr); + message_box->exec(); + return_from_event_loop_code = CRASH_CODE; + } + + LOG(INFO) << "loop refresh"; + } while (return_from_event_loop_code == RESTART_CODE); + + // reset core + GpgFrontend::ResetGpgFrontendCore(); + + // deep restart mode + } while (return_from_event_loop_code == DEEP_RESTART_CODE || return_from_event_loop_code == CRASH_CODE); // exit the program diff --git a/src/signal.cpp b/src/signal.cpp index 135bdead..bd4cfdb1 100644 --- a/src/signal.cpp +++ b/src/signal.cpp @@ -30,7 +30,11 @@ #include "GpgFrontend.h" +#ifdef FREEBSD +extern sigjmp_buf recover_env; +#else extern jmp_buf recover_env; +#endif /** * @brief handle the signal caught. diff --git a/src/ui/UserInterfaceUtils.cpp b/src/ui/UserInterfaceUtils.cpp index 586d72ab..f2659e9d 100644 --- a/src/ui/UserInterfaceUtils.cpp +++ b/src/ui/UserInterfaceUtils.cpp @@ -53,7 +53,7 @@ void show_verify_details(QWidget *parent, InfoBoardWidget *info_board, GpgError error, const GpgVerifyResult &verify_result) { // take out result info_board->ResetOptionActionsMenu(); - info_board->AddOptionalAction("Show Verify Details", [=]() { + info_board->AddOptionalAction(_("Show Verify Details"), [=]() { VerifyDetailsDialog(parent, error, verify_result); }); } @@ -169,9 +169,10 @@ CommonUtils::CommonUtils() : QWidget(nullptr) { connect(this, &CommonUtils::SignalGnupgNotInstall, this, []() { QMessageBox::critical( nullptr, _("ENV Loading Failed"), - _("Gnupg(gpg) is not installed correctly, please follow the " - "ReadME " - "instructions in Github to install Gnupg and then open " + _("Gnupg(gpg) is not installed correctly, please follow " + "<a href='https://www.gpgfrontend.pub/#/" + "faq?id=how-to-deal-with-39env-loading-failed39'>this notes</a>" + " in FAQ to install Gnupg and then open " "GpgFrontend.")); QCoreApplication::quit(); }); diff --git a/src/ui/dialog/GeneralDialog.cpp b/src/ui/dialog/GeneralDialog.cpp index d07c2497..6fd2f32c 100644 --- a/src/ui/dialog/GeneralDialog.cpp +++ b/src/ui/dialog/GeneralDialog.cpp @@ -50,7 +50,6 @@ void GpgFrontend::UI::GeneralDialog::slot_restore_settings() noexcept { int x = general_windows_state.Check("window_pos").Check("x", 100), y = general_windows_state.Check("window_pos").Check("y", 100); - this->move({x, y}); pos_ = {x, y}; int width = @@ -58,9 +57,56 @@ void GpgFrontend::UI::GeneralDialog::slot_restore_settings() noexcept { height = general_windows_state.Check("window_size").Check("height", 247); - this->resize({width, height}); size_ = {width, height}; + if (this->parent() != nullptr) { + LOG(INFO) << "parent address" << this->parent(); + + QPoint parent_pos = {0, 0}; + QSize parent_size = {0, 0}; + + auto *parent_widget = qobject_cast<QWidget *>(this->parent()); + if (parent_widget != nullptr) { + parent_pos = parent_widget->pos(); + parent_size = parent_widget->size(); + } + + auto *parent_dialog = qobject_cast<QDialog *>(this->parent()); + if (parent_dialog != nullptr) { + parent_pos = parent_dialog->pos(); + parent_size = parent_dialog->size(); + } + + auto *parent_window = qobject_cast<QMainWindow *>(this->parent()); + if (parent_window != nullptr) { + parent_pos = parent_window->pos(); + parent_size = parent_window->size(); + } + + LOG(INFO) << "parent pos x:" << parent_pos.x() + << "y:" << parent_pos.y(); + + LOG(INFO) << "parent size width:" << parent_size.width() + << "height:" << parent_size.height(); + + LOG(INFO) << "this dialog size width:" << size_.width() + << "height:" << size_.height(); + + if (parent_pos != QPoint{0, 0}) { + QPoint parent_center{parent_pos.x() + parent_size.width() / 2, + parent_pos.y() + parent_size.height() / 2}; + + pos_ = {parent_center.x() - size_.width() / 2, + parent_center.y() - size_.height() / 2}; + + // record parent_pos_ + this->parent_pos_ = parent_pos; + this->parent_size_ = parent_size; + } + } + + this->move(pos_); + this->resize(size_); } } catch (...) { @@ -78,6 +124,9 @@ void GpgFrontend::UI::GeneralDialog::slot_save_settings() noexcept { general_windows_state["window_pos"]["x"] = pos().x(); general_windows_state["window_pos"]["y"] = pos().y(); + // update size of current dialog + size_ = this->size(); + general_windows_state["window_size"]["width"] = size_.width(); general_windows_state["window_size"]["height"] = size_.height(); general_windows_state["window_save"] = true; @@ -86,3 +135,41 @@ void GpgFrontend::UI::GeneralDialog::slot_save_settings() noexcept { LOG(ERROR) << name_ << "error"; } } + +void GpgFrontend::UI::GeneralDialog::setPosCenterOfScreen() { + auto *screen = QGuiApplication::primaryScreen(); + QRect geo = screen->availableGeometry(); + int screen_width = geo.width(); + int screen_height = geo.height(); + + LOG(INFO) << "primary screen available geometry" << screen_width + << screen_height; + + pos_ = QPoint((screen_width - QWidget::width()) / 2, + (screen_height - QWidget::height()) / 2); + this->move(pos_); +} + +/** + * @brief + * + */ +void GpgFrontend::UI::GeneralDialog::movePosition2CenterOfParent() { + LOG(INFO) << "parent pos x:" << parent_pos_.x() << "y:" << parent_pos_.y(); + + LOG(INFO) << "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"; + QPoint parent_center{parent_pos_.x() + parent_size_.width() / 2, + parent_pos_.y() + parent_size_.height() / 2}; + + // update size of current dialog + size_ = this->size(); + + pos_ = {parent_center.x() - size_.width() / 2, + parent_center.y() - size_.height() / 2}; + this->move(pos_); + } +}
\ No newline at end of file diff --git a/src/ui/dialog/GeneralDialog.h b/src/ui/dialog/GeneralDialog.h index ca480c8b..41018105 100644 --- a/src/ui/dialog/GeneralDialog.h +++ b/src/ui/dialog/GeneralDialog.h @@ -45,6 +45,18 @@ class GeneralDialog : public QDialog { */ ~GeneralDialog() override; + protected: + /** + * + */ + void setPosCenterOfScreen(); + + /** + * @brief + * + */ + void movePosition2CenterOfParent(); + private slots: /** * @@ -60,6 +72,8 @@ class GeneralDialog : public QDialog { std::string name_; ///< QPoint pos_; ///< QSize size_; ///< + QPoint parent_pos_; + QSize parent_size_; }; } // namespace GpgFrontend::UI diff --git a/src/ui/dialog/help/GnupgTab.cpp b/src/ui/dialog/help/GnupgTab.cpp index 48787987..9d783367 100644 --- a/src/ui/dialog/help/GnupgTab.cpp +++ b/src/ui/dialog/help/GnupgTab.cpp @@ -31,36 +31,103 @@ #include "GnupgTab.h" -GpgFrontend::UI::GnupgTab::GnupgTab(QWidget* parent) : QWidget(parent) { +#include "easylogging++.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(); + + ui_->setupUi(this); + + QStringList column_titles; + column_titles << _("Name") << _("Description") << _("Version") << _("Path"); + + ui_->conponentDetailsTable->setColumnCount(column_titles.length()); + ui_->conponentDetailsTable->setHorizontalHeaderLabels(column_titles); + ui_->conponentDetailsTable->horizontalHeader()->setStretchLastSection(false); + ui_->conponentDetailsTable->setSelectionBehavior( + QAbstractItemView::SelectRows); + + // tableitems not editable + ui_->conponentDetailsTable->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); + + gpgconf_process_->start(QString::fromStdString(info.GpgConfPath), + QStringList() << "--list-components"); + + connect(gpgconf_process_, + qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this, + &GnupgTab::process_components_info); +} + +void GpgFrontend::UI::GnupgTab::process_components_info( + int exit_code, QProcess::ExitStatus exit_status) { + LOG(INFO) << "called"; + GpgContext& ctx = GpgContext::GetInstance(); auto info = ctx.GetInfo(); - auto* pixmap = new QPixmap(":gnupg.png"); - auto* text = new QString( - "<center><h2>" + QString(_("GnuPG")) + "</h2></center>" + "<center><b>" + - QString(_("GnuPG Version")) + ": " + - QString::fromStdString(info.GnupgVersion) + "</b></center>" + - "<center><b>" + +"</b></center>" + "<center>" + - QString(_("GpgME Version")) + ": " + - QString::fromStdString(info.GpgMEVersion) + "</center><br /><hr />" + - "<h3>" + QString(_("PATHs")) + "</h3>" + QString(_("GpgConf")) + ": " + - QString::fromStdString(info.GpgConfPath) + "<br />" + - QString(_("GnuPG")) + ": " + QString::fromStdString(info.AppPath) + - "<br />" + QString(_("CMS")) + ": " + - QString::fromStdString(info.CMSPath) + "<br />"); - - auto* layout = new QGridLayout(); - auto* pixmapLabel = new QLabel(); - pixmapLabel->setPixmap(*pixmap); - layout->addWidget(pixmapLabel, 0, 0, 1, -1, Qt::AlignCenter); - auto* aboutLabel = new QLabel(); - aboutLabel->setText(*text); - aboutLabel->setWordWrap(true); - aboutLabel->setOpenExternalLinks(true); - layout->addWidget(aboutLabel, 1, 0, 1, -1); - layout->addItem( - new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Fixed), 2, 1, - 1, 1); - - setLayout(layout); + std::vector<std::vector<std::string>> components_info = { + {"gpgme", "GPG Made Easy", info.GpgMEVersion, "/"}, + {"gpgconf", "GPG Configure", "/", info.GpgConfPath}, + + }; + + if (gpgconf_process_ != nullptr) { + QString data = gpgconf_process_->readAllStandardOutput(); + + std::vector<std::string> line_split_list; + boost::split(line_split_list, data.toStdString(), 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(":")); + LOG(INFO) << "gpgconf info line" << line << "info size" + << info_split_list.size(); + + if (info_split_list.size() != 3) continue; + + 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]}); + } + } + } + + ui_->conponentDetailsTable->setRowCount(components_info.size()); + + int row = 0; + for (const auto& info : components_info) { + if (info.size() != 4) continue; + + auto* tmp0 = new QTableWidgetItem(QString::fromStdString(info[0])); + tmp0->setTextAlignment(Qt::AlignCenter); + ui_->conponentDetailsTable->setItem(row, 0, tmp0); + + auto* tmp1 = new QTableWidgetItem(QString::fromStdString(info[1])); + 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); + + row++; + } } diff --git a/src/ui/dialog/help/GnupgTab.h b/src/ui/dialog/help/GnupgTab.h index 4fc7ff22..c143bae3 100644 --- a/src/ui/dialog/help/GnupgTab.h +++ b/src/ui/dialog/help/GnupgTab.h @@ -35,8 +35,9 @@ #include "core/GpgContext.h" #include "ui/GpgFrontendUI.h" -namespace GpgFrontend::UI{ -class GnupgTab: public QWidget { +class Ui_GnuPGInfo; +namespace GpgFrontend::UI { +class GnupgTab : public QWidget { Q_OBJECT public: /** @@ -45,9 +46,14 @@ class GnupgTab: public QWidget { * @param parent */ explicit GnupgTab(QWidget* parent = nullptr); -}; -} + private: + std::shared_ptr<Ui_GnuPGInfo> ui_; + QProcess* gpgconf_process_; + private slots: + void process_components_info(int, QProcess::ExitStatus); +}; +} // namespace GpgFrontend::UI #endif // GPGFRONTEND_GNUPGTAB_H diff --git a/src/ui/dialog/import_export/KeyUploadDialog.cpp b/src/ui/dialog/import_export/KeyUploadDialog.cpp index 055f2e1f..ad4be0cb 100644 --- a/src/ui/dialog/import_export/KeyUploadDialog.cpp +++ b/src/ui/dialog/import_export/KeyUploadDialog.cpp @@ -33,6 +33,7 @@ #include "core/function/GlobalSettingStation.h" #include "core/function/gpg/GpgKeyGetter.h" #include "core/function/gpg/GpgKeyImportExporter.h" +#include "ui/struct/SettingsObject.h" namespace GpgFrontend::UI { @@ -40,6 +41,7 @@ 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); @@ -54,33 +56,47 @@ KeyUploadDialog::KeyUploadDialog(const KeyIdArgsListPtr& keys_ids, this->setModal(true); this->setWindowTitle(_("Uploading Public Key")); this->setFixedSize(240, 42); + this->setPosCenterOfScreen(); } void KeyUploadDialog::SlotUpload() { auto out_data = std::make_unique<ByteArray>(); GpgKeyImportExporter::GetInstance().ExportKeys(*m_keys_, out_data); slot_upload_key_to_server(*out_data); + + // Done + this->hide(); + this->close(); } void KeyUploadDialog::slot_upload_key_to_server( const GpgFrontend::ByteArray& keys_data) { + std::string target_keyserver; - if (target_keyserver.empty()) { - try { - auto& settings = GlobalSettingStation::GetInstance().GetUISettings(); - - target_keyserver = settings.lookup("keyserver.default_server").c_str(); - - LOG(INFO) << _("Set target Key Server to default Key Server") - << target_keyserver; - } catch (...) { - LOG(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")); - return; + + try { + SettingsObject key_server_json("key_server"); + + const auto key_server_list = + key_server_json.Check("server_list", nlohmann::json::array()); + + int default_key_server_index = key_server_json.Check("default_server", 0); + if (default_key_server_index >= key_server_list.size()) { + throw std::runtime_error("default_server index out of range"); } + + target_keyserver = + key_server_list[default_key_server_index].get<std::string>(); + + LOG(INFO) << _("Set target Key Server to default Key Server") + << target_keyserver; + + } catch (...) { + LOG(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")); + return; } QUrl req_url(QString::fromStdString(target_keyserver + "/pks/add")); @@ -117,10 +133,6 @@ void KeyUploadDialog::slot_upload_key_to_server( while (reply->isRunning()) { QApplication::processEvents(); } - - // Done - this->hide(); - this->close(); } void KeyUploadDialog::slot_upload_finished() { diff --git a/src/ui/dialog/key_generate/KeygenDialog.cpp b/src/ui/dialog/key_generate/KeygenDialog.cpp index 42160ec9..b7ba6369 100644 --- a/src/ui/dialog/key_generate/KeygenDialog.cpp +++ b/src/ui/dialog/key_generate/KeygenDialog.cpp @@ -254,8 +254,9 @@ void KeyGenDialog::slot_authentication_box_changed(int state) { void KeyGenDialog::slot_activated_key_type(int index) { qDebug() << "key type index changed " << index; - gen_key_info_->SetAlgo( - this->key_type_combo_box_->itemText(index).toStdString()); + // check + assert(gen_key_info_->GetSupportedKeyAlgo().size() > index); + gen_key_info_->SetAlgo(gen_key_info_->GetSupportedKeyAlgo()[index]); refresh_widgets_state(); } @@ -357,7 +358,7 @@ QGroupBox* KeyGenDialog::create_basic_info_group_box() { key_type_combo_box_ = new QComboBox(this); for (auto& algo : GenKeyInfo::GetSupportedKeyAlgo()) { - key_type_combo_box_->addItem(QString::fromStdString(algo)); + key_type_combo_box_->addItem(QString::fromStdString(algo.first)); } if (!GenKeyInfo::GetSupportedKeyAlgo().empty()) { key_type_combo_box_->setCurrentIndex(0); diff --git a/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp b/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp index 806c0e50..afa768f0 100644 --- a/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp +++ b/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp @@ -26,6 +26,8 @@ #include "SubkeyGenerateDialog.h" +#include <cassert> + #include "core/function/GlobalSettingStation.h" #include "core/function/gpg/GpgKeyGetter.h" #include "core/function/gpg/GpgKeyOpera.h" @@ -120,10 +122,10 @@ QGroupBox* SubkeyGenerateDialog::create_basic_info_group_box() { key_size_spin_box_ = new QSpinBox(this); key_type_combo_box_ = new QComboBox(this); - for (auto& algo : GenKeyInfo::GetSupportedKeyAlgo()) { - key_type_combo_box_->addItem(QString::fromStdString(algo)); + for (auto& algo : GenKeyInfo::GetSupportedSubkeyAlgo()) { + key_type_combo_box_->addItem(QString::fromStdString(algo.first)); } - if (!GenKeyInfo::GetSupportedKeyAlgo().empty()) { + if (!GenKeyInfo::GetSupportedSubkeyAlgo().empty()) { key_type_combo_box_->setCurrentIndex(0); } @@ -188,7 +190,7 @@ void SubkeyGenerateDialog::slot_expire_box_changed() { } void SubkeyGenerateDialog::refresh_widgets_state() { - qDebug() << "refresh_widgets_state called"; + LOG(INFO) << "refresh_widgets_state called"; if (gen_key_info_->IsAllowEncryption()) key_usage_check_boxes_[0]->setCheckState(Qt::CheckState::Checked); @@ -266,13 +268,13 @@ void SubkeyGenerateDialog::slot_key_gen_accept() { }); thread->start(); - auto* dialog = new WaitingDialog(_("Generating"), this); - dialog->show(); + auto* waiting_dialog = new WaitingDialog(_("Generating"), this); + waiting_dialog->show(); while (thread->isRunning()) { QCoreApplication::processEvents(); } - dialog->close(); + waiting_dialog->close(); if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR) { auto* msg_box = new QMessageBox((QWidget*)this->parent()); @@ -285,8 +287,9 @@ void SubkeyGenerateDialog::slot_key_gen_accept() { emit SignalSubKeyGenerated(); this->close(); - } else + } else { QMessageBox::critical(this, _("Failure"), _("Failed to generate key.")); + } } else { /** @@ -336,8 +339,10 @@ void SubkeyGenerateDialog::slot_authentication_box_changed(int state) { void SubkeyGenerateDialog::slot_activated_key_type(int index) { qDebug() << "key type index changed " << index; - gen_key_info_->SetAlgo( - this->key_type_combo_box_->itemText(index).toStdString()); + + // check + assert(gen_key_info_->GetSupportedSubkeyAlgo().size() > index); + gen_key_info_->SetAlgo(gen_key_info_->GetSupportedSubkeyAlgo()[index]); refresh_widgets_state(); } diff --git a/src/ui/dialog/keypair_details/KeyDetailsDialog.cpp b/src/ui/dialog/keypair_details/KeyDetailsDialog.cpp index 9c2f8003..ed578aa7 100644 --- a/src/ui/dialog/keypair_details/KeyDetailsDialog.cpp +++ b/src/ui/dialog/keypair_details/KeyDetailsDialog.cpp @@ -55,8 +55,12 @@ KeyDetailsDialog::KeyDetailsDialog(const GpgKey& key, QWidget* parent) this->setLayout(mainLayout); this->setWindowTitle(_("Key Details")); this->setModal(true); - this->setMinimumSize({520, 600}); - this->resize(this->minimumSize()); + + // this->setMinimumSize({520, 600}); + + // move to center of the parent + this->movePosition2CenterOfParent(); + this->show(); } } // namespace GpgFrontend::UI diff --git a/src/ui/dialog/keypair_details/KeyPairDetailTab.cpp b/src/ui/dialog/keypair_details/KeyPairDetailTab.cpp index 4a6e4b52..b4d2d688 100644 --- a/src/ui/dialog/keypair_details/KeyPairDetailTab.cpp +++ b/src/ui/dialog/keypair_details/KeyPairDetailTab.cpp @@ -28,6 +28,7 @@ #include "core/function/gpg/GpgKeyGetter.h" #include "core/function/gpg/GpgKeyImportExporter.h" +#include "core/model/GpgKey.h" #include "dialog/WaitingDialog.h" #include "ui/SignalStation.h" @@ -268,8 +269,12 @@ void KeyPairDetailTab::slot_refresh_key_info() { } void KeyPairDetailTab::slot_refresh_key() { - LOG(INFO) << _("Called"); - this->key_ = GpgKeyGetter::GetInstance().GetKey(key_.GetId()); + LOG(INFO) << _("called"); + + // refresh the key + GpgKey refreshed_key = GpgKeyGetter::GetInstance().GetKey(key_.GetId()); + std::swap(this->key_, refreshed_key); + this->slot_refresh_key_info(); } diff --git a/src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp b/src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp index fe1d0798..be67e5ca 100644 --- a/src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp +++ b/src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp @@ -165,7 +165,7 @@ void KeyPairSubkeyTab::create_subkey_list() { } void KeyPairSubkeyTab::slot_refresh_subkey_list() { - LOG(INFO) << "Called"; + LOG(INFO) << "called"; int row = 0; subkey_list_->setSelectionMode(QAbstractItemView::SingleSelection); @@ -177,6 +177,10 @@ 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(); + subkey_list_->setRowCount(buffered_subkeys_.size()); for (const auto& subkeys : buffered_subkeys_) { @@ -212,12 +216,20 @@ void KeyPairSubkeyTab::slot_refresh_subkey_list() { } } + LOG(INFO) << "subkey_list_ item" << row << "refreshed"; + row++; } + LOG(INFO) << "subkey_list_" + << "refreshed"; + if (subkey_list_->rowCount() > 0) { subkey_list_->selectRow(0); } + + LOG(INFO) << "slot_refresh_subkey_list" + << "ended"; } void KeyPairSubkeyTab::slot_add_subkey() { @@ -332,6 +344,7 @@ 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 b923dbec..caa4e3be 100644 --- a/src/ui/dialog/keypair_details/KeyPairUIDTab.cpp +++ b/src/ui/dialog/keypair_details/KeyPairUIDTab.cpp @@ -574,7 +574,12 @@ void KeyPairUIDTab::slot_del_sign() { } } void KeyPairUIDTab::slot_refresh_key() { - this->m_key_ = GpgKeyGetter::GetInstance().GetKey(this->m_key_.GetId()); + LOG(INFO) << "called"; + + // refresh the key + GpgKey refreshed_key = GpgKeyGetter::GetInstance().GetKey(m_key_.GetId()); + std::swap(this->m_key_, refreshed_key); + this->slot_refresh_uid_list(); this->slot_refresh_tofu_info(); this->slot_refresh_sig_list(); diff --git a/src/ui/dialog/settings/SettingsAppearance.cpp b/src/ui/dialog/settings/SettingsAppearance.cpp index 17471a0d..b5fbc6a3 100644 --- a/src/ui/dialog/settings/SettingsAppearance.cpp +++ b/src/ui/dialog/settings/SettingsAppearance.cpp @@ -30,89 +30,48 @@ #include "core/function/GlobalSettingStation.h" #include "ui/struct/SettingsObject.h" +#include "ui_AppearanceSettings.h" namespace GpgFrontend::UI { -AppearanceTab::AppearanceTab(QWidget* parent) : QWidget(parent) { - /***************************************** - * Icon-Size-Box - *****************************************/ - auto* iconSizeBox = new QGroupBox(_("Icon Size")); - icon_size_group_ = new QButtonGroup(); - icon_size_small_ = new QRadioButton(_("small")); - icon_size_medium_ = new QRadioButton(_("medium")); - icon_size_large_ = new QRadioButton(_("large")); - - icon_size_group_->addButton(icon_size_small_, 1); - icon_size_group_->addButton(icon_size_medium_, 2); - icon_size_group_->addButton(icon_size_large_, 3); - - auto* iconSizeBoxLayout = new QHBoxLayout(); - iconSizeBoxLayout->addWidget(icon_size_small_); - iconSizeBoxLayout->addWidget(icon_size_medium_); - iconSizeBoxLayout->addWidget(icon_size_large_); - - iconSizeBox->setLayout(iconSizeBoxLayout); - - /***************************************** - * Icon-Style-Box - *****************************************/ - auto* iconStyleBox = new QGroupBox(_("Icon Style")); - icon_style_group_ = new QButtonGroup(); - icon_text_button_ = new QRadioButton(_("just text")); - icon_icons_button_ = new QRadioButton(_("just icons")); - icon_all_button_ = new QRadioButton(_("text and icons")); - - icon_style_group_->addButton(icon_text_button_, 1); - icon_style_group_->addButton(icon_icons_button_, 2); - icon_style_group_->addButton(icon_all_button_, 3); - - auto* iconStyleBoxLayout = new QHBoxLayout(); - iconStyleBoxLayout->addWidget(icon_text_button_); - iconStyleBoxLayout->addWidget(icon_icons_button_); - iconStyleBoxLayout->addWidget(icon_all_button_); - - iconStyleBox->setLayout(iconStyleBoxLayout); - - /***************************************** - * Window-Size-Box - *****************************************/ - auto* windowSizeBox = new QGroupBox(_("Window State")); - auto* windowSizeBoxLayout = new QHBoxLayout(); - window_size_check_box_ = - new QCheckBox(_("Save window size and position on exit."), this); - windowSizeBoxLayout->addWidget(window_size_check_box_); - windowSizeBox->setLayout(windowSizeBoxLayout); - - /***************************************** - * Info-Board-Font-Size-Box - *****************************************/ - - auto* infoBoardBox = new QGroupBox(_("Information Board")); - auto* infoBoardLayout = new QHBoxLayout(); - info_board_font_size_spin_ = new QSpinBox(); - info_board_font_size_spin_->setRange(9, 18); - info_board_font_size_spin_->setValue(10); - info_board_font_size_spin_->setSingleStep(1); - infoBoardLayout->addWidget(new QLabel(_("Font Size in Information Board"))); - infoBoardLayout->addWidget(info_board_font_size_spin_); - infoBoardBox->setLayout(infoBoardLayout); - - auto* mainLayout = new QVBoxLayout; - mainLayout->addWidget(iconSizeBox); - mainLayout->addWidget(iconStyleBox); - mainLayout->addWidget(windowSizeBox); - mainLayout->addWidget(infoBoardBox); - mainLayout->addStretch(1); +AppearanceTab::AppearanceTab(QWidget* parent) + : QWidget(parent), ui_(std::make_shared<Ui_AppearanceSettings>()) { + ui_->setupUi(this); + + ui_->iconSizeBox->setTitle(_("Icon Size")); + ui_->smallRadioButton->setText(_("small")); + ui_->mediumRadioButton->setText(_("medium")); + ui_->largeRadioButton->setText(_("large")); + + ui_->iconStyleBox->setTitle(_("Icon Style")); + ui_->justTextRadioButton->setText(_("just text")); + ui_->justIconRadioButton->setText(_("just icons")); + ui_->textAndIconsRadioButton->setText(_("text and icons")); + + ui_->windowStateBox->setTitle(_("Window State")); + ui_->windowStateCheckBox->setText( + _("Save window size and position on exit.")); + + ui_->textEditorBox->setTitle(_("Text Editor")); + ui_->fontSizeTextEditorLabel->setText(_("Font Size in Text Editor")); + + ui_->informationBoardBox->setTitle(_("Information Board")); + ui_->fontSizeInformationBoardLabel->setText( + _("Font Size in Information Board")); + + icon_size_group_ = new QButtonGroup(this); + icon_size_group_->addButton(ui_->smallRadioButton, 1); + icon_size_group_->addButton(ui_->mediumRadioButton, 2); + icon_size_group_->addButton(ui_->largeRadioButton, 3); + + icon_style_group_ = new QButtonGroup(this); + icon_style_group_->addButton(ui_->justTextRadioButton, 1); + icon_style_group_->addButton(ui_->justIconRadioButton, 2); + icon_style_group_->addButton(ui_->textAndIconsRadioButton, 3); + SetSettings(); - setLayout(mainLayout); } -/********************************** - * Read the settings from config - * and set the buttons and checkboxes - * appropriately - **********************************/ void AppearanceTab::SetSettings() { SettingsObject general_settings_state("general_settings_state"); @@ -123,13 +82,13 @@ void AppearanceTab::SetSettings() { switch (icon_size.width()) { case 12: - icon_size_small_->setChecked(true); + ui_->smallRadioButton->setChecked(true); break; case 24: - icon_size_medium_->setChecked(true); + ui_->mediumRadioButton->setChecked(true); break; case 32: - icon_size_large_->setChecked(true); + ui_->largeRadioButton->setChecked(true); break; } @@ -140,32 +99,35 @@ void AppearanceTab::SetSettings() { switch (icon_style) { case Qt::ToolButtonTextOnly: - icon_text_button_->setChecked(true); + ui_->justTextRadioButton->setChecked(true); break; case Qt::ToolButtonIconOnly: - icon_icons_button_->setChecked(true); + ui_->justIconRadioButton->setChecked(true); break; case Qt::ToolButtonTextUnderIcon: - icon_all_button_->setChecked(true); + ui_->textAndIconsRadioButton->setChecked(true); break; default: break; } bool window_save = general_settings_state.Check("window_save", true); - if (window_save) window_size_check_box_->setCheckState(Qt::Checked); - - auto info_font_size = general_settings_state.Check("font_size", 10); - if (info_font_size < 9 || info_font_size > 18) info_font_size = 10; - info_board_font_size_spin_->setValue(info_font_size); + if (window_save) ui_->windowStateCheckBox->setCheckState(Qt::Checked); + + auto info_board_info_font_size = + general_settings_state.Check("info_board").Check("font_size", 10); + if (info_board_info_font_size < 9 || info_board_info_font_size > 18) + info_board_info_font_size = 10; + ui_->fontSizeInformationBoardSpinBox->setValue(info_board_info_font_size); + + auto text_editor_info_font_size = + general_settings_state.Check("text_editor").Check("font_size", 10); + if (text_editor_info_font_size < 9 || text_editor_info_font_size > 18) + text_editor_info_font_size = 10; + ui_->fontSizeTextEditorLabelSpinBox->setValue(text_editor_info_font_size); } -/*********************************** - * get the values of the buttons and - * write them to settings-file - *************************************/ void AppearanceTab::ApplySettings() { - SettingsObject general_settings_state("general_settings_state"); int icon_size = 24; @@ -199,9 +161,13 @@ void AppearanceTab::ApplySettings() { general_settings_state["icon_style"] = icon_style; - general_settings_state["window_save"] = window_size_check_box_->isChecked(); + general_settings_state["window_save"] = ui_->windowStateCheckBox->isChecked(); + + general_settings_state["info_board"]["font_size"] = + ui_->fontSizeInformationBoardSpinBox->value(); - general_settings_state["info_font_size"] = info_board_font_size_spin_->value(); + general_settings_state["text_editor"]["font_size"] = + ui_->fontSizeTextEditorLabelSpinBox->value(); } } // namespace GpgFrontend::UI diff --git a/src/ui/dialog/settings/SettingsAppearance.h b/src/ui/dialog/settings/SettingsAppearance.h index 7110d992..8a38c666 100644 --- a/src/ui/dialog/settings/SettingsAppearance.h +++ b/src/ui/dialog/settings/SettingsAppearance.h @@ -31,6 +31,8 @@ #include "ui/GpgFrontendUI.h" +class Ui_AppearanceSettings; + namespace GpgFrontend::UI { class AppearanceTab : public QWidget { @@ -57,16 +59,10 @@ class AppearanceTab : public QWidget { void ApplySettings(); private: + std::shared_ptr<Ui_AppearanceSettings> ui_; ///< + QButtonGroup* icon_style_group_; ///< - QRadioButton* icon_size_small_; ///< - QRadioButton* icon_size_medium_; ///< - QRadioButton* icon_size_large_; ///< - QButtonGroup* icon_size_group_; ///< - QRadioButton* icon_text_button_; ///< - QRadioButton* icon_icons_button_; ///< - QRadioButton* icon_all_button_; ///< - QSpinBox* info_board_font_size_spin_; ///< - QCheckBox* window_size_check_box_; ///< + QButtonGroup* icon_size_group_; signals: diff --git a/src/ui/dialog/settings/SettingsDialog.cpp b/src/ui/dialog/settings/SettingsDialog.cpp index e2677a0f..6737a512 100644 --- a/src/ui/dialog/settings/SettingsDialog.cpp +++ b/src/ui/dialog/settings/SettingsDialog.cpp @@ -33,6 +33,7 @@ #include "SettingsGeneral.h" #include "SettingsKeyServer.h" #include "SettingsNetwork.h" +#include "core/GpgConstants.h" #include "core/function/GlobalSettingStation.h" #include "ui/main_window/MainWindow.h" @@ -74,9 +75,24 @@ SettingsDialog::SettingsDialog(QWidget* parent) setLayout(mainLayout); // slots for handling the restart needed member - this->slot_set_restart_needed(false); + this->slot_set_restart_needed(0); + + // restart ui connect(general_tab_, &GeneralTab::SignalRestartNeeded, this, - &SettingsDialog::slot_set_restart_needed); + [=](bool needed) { + if (needed && restart_needed_ < RESTART_CODE) { + this->restart_needed_ = RESTART_CODE; + } + }); + + // restart core and ui + connect(general_tab_, &GeneralTab::SignalDeepRestartNeeded, this, + [=](bool needed) { + if (needed && restart_needed_ < DEEP_RESTART_CODE) + this->restart_needed_ = DEEP_RESTART_CODE; + }); + + // announce main window connect(this, &SettingsDialog::SignalRestartNeeded, qobject_cast<MainWindow*>(parent), &MainWindow::SlotSetRestartNeeded); @@ -85,12 +101,10 @@ SettingsDialog::SettingsDialog(QWidget* parent) this->show(); } -bool SettingsDialog::get_restart_needed() const { - return this->restart_needed_; -} +int SettingsDialog::get_restart_needed() const { return this->restart_needed_; } -void SettingsDialog::slot_set_restart_needed(bool needed) { - this->restart_needed_ = needed; +void SettingsDialog::slot_set_restart_needed(int mode) { + this->restart_needed_ = mode; } void SettingsDialog::SlotAccept() { @@ -108,7 +122,7 @@ void SettingsDialog::SlotAccept() { LOG(INFO) << "restart needed" << get_restart_needed(); if (get_restart_needed()) { - emit SignalRestartNeeded(true); + emit SignalRestartNeeded(get_restart_needed()); } close(); } diff --git a/src/ui/dialog/settings/SettingsDialog.h b/src/ui/dialog/settings/SettingsDialog.h index 172370d0..d28013f4 100644 --- a/src/ui/dialog/settings/SettingsDialog.h +++ b/src/ui/dialog/settings/SettingsDialog.h @@ -82,12 +82,12 @@ class SettingsDialog : public GeneralDialog { * * @param needed */ - void SignalRestartNeeded(bool needed); + void SignalRestartNeeded(int); private: QTabWidget* tab_widget_; ///< QDialogButtonBox* button_box_; ///< - bool restart_needed_{}; ///< + int restart_needed_{0}; ///< /** * @brief Get the Restart Needed object @@ -95,7 +95,7 @@ class SettingsDialog : public GeneralDialog { * @return true * @return false */ - bool get_restart_needed() const; + int get_restart_needed() const; private slots: @@ -104,7 +104,7 @@ class SettingsDialog : public GeneralDialog { * * @param needed */ - void slot_set_restart_needed(bool needed); + void slot_set_restart_needed(int); }; } // namespace GpgFrontend::UI diff --git a/src/ui/dialog/settings/SettingsGeneral.cpp b/src/ui/dialog/settings/SettingsGeneral.cpp index 3c7bca32..680ed014 100644 --- a/src/ui/dialog/settings/SettingsGeneral.cpp +++ b/src/ui/dialog/settings/SettingsGeneral.cpp @@ -28,6 +28,8 @@ #include "SettingsGeneral.h" +#include "core/GpgContext.h" + #ifdef MULTI_LANG_SUPPORT #include "SettingsDialog.h" #endif @@ -70,6 +72,51 @@ GeneralTab::GeneralTab(QWidget* parent) this, &GeneralTab::slot_language_changed); #endif + connect(ui_->keyDatabseUseCustomCheckBox, &QCheckBox::stateChanged, this, + [=](int state) { + ui_->customKeyDatabasePathSelectButton->setDisabled( + state != Qt::CheckState::Checked); + // announce the restart + this->slot_key_databse_path_changed(); + }); + + connect(ui_->keyDatabseUseCustomCheckBox, &QCheckBox::stateChanged, this, + &GeneralTab::slot_update_custom_key_database_path_label); + + connect( + ui_->customKeyDatabasePathSelectButton, &QPushButton::clicked, this, + [=]() { + QString selected_custom_key_database_path = + QFileDialog::getExistingDirectory( + this, _("Open Directory"), {}, + QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); + + LOG(INFO) << "key databse path selected" + << selected_custom_key_database_path.toStdString(); + + if (!selected_custom_key_database_path.isEmpty()) { + auto& settings = GlobalSettingStation::GetInstance().GetUISettings(); + auto& general = settings["general"]; + + // update settings + if (!general.exists("custom_key_database_path")) + general.add("custom_key_database_path", + libconfig::Setting::TypeString) = + selected_custom_key_database_path.toStdString(); + else { + general["custom_key_database_path"] = + selected_custom_key_database_path.toStdString(); + } + + // announce the restart + this->slot_key_databse_path_changed(); + + // update ui + this->slot_update_custom_key_database_path_label( + this->ui_->keyDatabseUseCustomCheckBox->checkState()); + } + }); + SetSettings(); } @@ -132,6 +179,19 @@ void GeneralTab::SetSettings() { } catch (...) { LOG(ERROR) << _("Setting Operation Error") << _("non_ascii_when_export"); } + + try { + bool use_custom_key_database_path = + settings.lookup("general.use_custom_key_database_path"); + if (use_custom_key_database_path) + ui_->keyDatabseUseCustomCheckBox->setCheckState(Qt::Checked); + } catch (...) { + LOG(ERROR) << _("Setting Operation Error") + << _("use_custom_key_database_path"); + } + + this->slot_update_custom_key_database_path_label( + ui_->keyDatabseUseCustomCheckBox->checkState()); } /*********************************** @@ -187,10 +247,60 @@ void GeneralTab::ApplySettings() { general["confirm_import_keys"] = ui_->importConfirmationCheckBox->isChecked(); } + + if (!general.exists("use_custom_key_database_path")) + general.add("use_custom_key_database_path", + libconfig::Setting::TypeBoolean) = + ui_->keyDatabseUseCustomCheckBox->isChecked(); + else { + general["use_custom_key_database_path"] = + ui_->keyDatabseUseCustomCheckBox->isChecked(); + } } #ifdef MULTI_LANG_SUPPORT void GeneralTab::slot_language_changed() { emit SignalRestartNeeded(true); } #endif +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)); + + // hide label (not necessary to show the default path) + this->ui_->currentKeyDatabasePathLabel->setHidden(true); + } else { + // read from settings file + std::string custom_key_database_path; + try { + auto& settings = + GpgFrontend::GlobalSettingStation::GetInstance().GetUISettings(); + custom_key_database_path = static_cast<std::string>( + settings.lookup("general.custom_key_database_path")); + + } catch (...) { + LOG(ERROR) << _("Setting Operation Error") + << _("custom_key_database_path"); + } + + LOG(INFO) << "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)); + } else { + ui_->currentKeyDatabasePathLabel->setText( + _("None custom key database path.")); + } + + this->ui_->currentKeyDatabasePathLabel->setHidden(false); + } +} + +void GeneralTab::slot_key_databse_path_changed() { + emit SignalDeepRestartNeeded(true); +} + } // namespace GpgFrontend::UI diff --git a/src/ui/dialog/settings/SettingsGeneral.h b/src/ui/dialog/settings/SettingsGeneral.h index b3e7d904..4543df7d 100644 --- a/src/ui/dialog/settings/SettingsGeneral.h +++ b/src/ui/dialog/settings/SettingsGeneral.h @@ -72,6 +72,13 @@ class GeneralTab : public QWidget { */ void SignalRestartNeeded(bool needed); + /** + * @brief + * + * @param needed + */ + void SignalDeepRestartNeeded(bool needed); + private: std::shared_ptr<Ui_GeneralSettings> ui_; ///< @@ -92,6 +99,18 @@ class GeneralTab : public QWidget { */ void slot_language_changed(); + /** + * @brief + * + */ + void slot_update_custom_key_database_path_label(int state); + + /** + * @brief + * + */ + void slot_key_databse_path_changed(); + #endif }; } // namespace GpgFrontend::UI diff --git a/src/ui/dialog/settings/SettingsKeyServer.cpp b/src/ui/dialog/settings/SettingsKeyServer.cpp index 2c09b66c..365e19d4 100644 --- a/src/ui/dialog/settings/SettingsKeyServer.cpp +++ b/src/ui/dialog/settings/SettingsKeyServer.cpp @@ -114,11 +114,6 @@ KeyserverTab::KeyserverTab(QWidget* parent) slot_refresh_table(); } -/********************************** - * Read the settings from config - * and set the buttons and checkboxes - * appropriately - **********************************/ void KeyserverTab::SetSettings() { try { SettingsObject key_server_json("key_server"); diff --git a/src/ui/main_window/GeneralMainWindow.cpp b/src/ui/main_window/GeneralMainWindow.cpp index 7df73aba..fb42d71a 100644 --- a/src/ui/main_window/GeneralMainWindow.cpp +++ b/src/ui/main_window/GeneralMainWindow.cpp @@ -33,14 +33,14 @@ #include "ui/struct/SettingsObject.h" GpgFrontend::UI::GeneralMainWindow::GeneralMainWindow(std::string name, - QWidget* parent) + QWidget *parent) : name_(std::move(name)), QMainWindow(parent) { slot_restore_settings(); } GpgFrontend::UI::GeneralMainWindow::~GeneralMainWindow() = default; -void GpgFrontend::UI::GeneralMainWindow::closeEvent(QCloseEvent* event) { +void GpgFrontend::UI::GeneralMainWindow::closeEvent(QCloseEvent *event) { slot_save_settings(); QMainWindow::closeEvent(event); } @@ -65,7 +65,6 @@ void GpgFrontend::UI::GeneralMainWindow::slot_restore_settings() noexcept { int x = general_windows_state.Check("window_pos").Check("x", 100), y = general_windows_state.Check("window_pos").Check("y", 100); - this->move({x, y}); pos_ = {x, y}; int width = @@ -73,10 +72,44 @@ void GpgFrontend::UI::GeneralMainWindow::slot_restore_settings() noexcept { height = general_windows_state.Check("window_size").Check("height", 450); - this->resize({width, height}); size_ = {width, height}; - } + if (this->parent() != nullptr) { + LOG(INFO) << "parent address" << this->parent(); + + QPoint parent_pos = {0, 0}; + QSize parent_size = {0, 0}; + + auto *parent_dialog = qobject_cast<QDialog *>(this->parent()); + if (parent_dialog != nullptr) { + parent_pos = parent_dialog->pos(); + parent_size = parent_dialog->size(); + } + + auto *parent_window = qobject_cast<QMainWindow *>(this->parent()); + if (parent_window != nullptr) { + parent_pos = parent_window->pos(); + parent_size = parent_window->size(); + } + + LOG(INFO) << "parent pos x:" << parent_pos.x() + << "y:" << parent_pos.y(); + + LOG(INFO) << "parent size width:" << parent_size.width() + << "height:" << parent_size.height(); + + if (parent_pos != QPoint{0, 0}) { + QPoint parent_center{parent_pos.x() + parent_size.width() / 2, + parent_pos.y() + parent_size.height() / 2}; + + pos_ = {parent_center.x() - size_.width() / 2, + parent_center.y() - size_.height() / 2}; + } + } + + this->move(pos_); + this->resize(size_); + } // appearance SettingsObject general_settings_state("general_settings_state"); @@ -113,6 +146,9 @@ void GpgFrontend::UI::GeneralMainWindow::slot_save_settings() noexcept { general_windows_state["window_pos"]["x"] = pos().x(); general_windows_state["window_pos"]["y"] = pos().y(); + // update size of current dialog + size_ = this->size(); + general_windows_state["window_size"]["width"] = size_.width(); general_windows_state["window_size"]["height"] = size_.height(); general_windows_state["window_save"] = true; diff --git a/src/ui/main_window/GeneralMainWindow.h b/src/ui/main_window/GeneralMainWindow.h index 71327100..8995883a 100644 --- a/src/ui/main_window/GeneralMainWindow.h +++ b/src/ui/main_window/GeneralMainWindow.h @@ -54,7 +54,7 @@ class GeneralMainWindow : public QMainWindow { * * @param event */ - void closeEvent(QCloseEvent* event); + void closeEvent(QCloseEvent* event) override; QSize icon_size_{}; ///< int font_size_{}; ///< diff --git a/src/ui/main_window/KeyMgmt.cpp b/src/ui/main_window/KeyMgmt.cpp index 6dc2b14f..9df2b918 100644 --- a/src/ui/main_window/KeyMgmt.cpp +++ b/src/ui/main_window/KeyMgmt.cpp @@ -109,6 +109,7 @@ KeyMgmt::KeyMgmt(QWidget* parent) this->statusBar()->show(); setWindowTitle(_("KeyPair Management")); + key_list_->AddMenuAction(generate_subkey_act_); key_list_->AddMenuAction(delete_selected_keys_act_); key_list_->AddMenuAction(show_key_details_act_); diff --git a/src/ui/main_window/MainWindow.cpp b/src/ui/main_window/MainWindow.cpp index e3e4c0ab..b0273d86 100644 --- a/src/ui/main_window/MainWindow.cpp +++ b/src/ui/main_window/MainWindow.cpp @@ -62,12 +62,18 @@ void MainWindow::Init() noexcept { /* Variable containing if restart is needed */ this->SlotSetRestartNeeded(false); + // init menu bar + this->setMenuBar(new QMenuBar()); + create_actions(); create_menus(); create_tool_bars(); create_status_bar(); create_dock_windows(); + // show menu bar + this->menuBar()->show(); + connect(edit_->tab_widget_, &QTabWidget::currentChanged, this, &MainWindow::slot_disable_tab_actions); connect(SignalStation::GetInstance(), diff --git a/src/ui/main_window/MainWindow.h b/src/ui/main_window/MainWindow.h index b31e2fcb..2e24cecd 100644 --- a/src/ui/main_window/MainWindow.h +++ b/src/ui/main_window/MainWindow.h @@ -148,7 +148,7 @@ class MainWindow : public GeneralMainWindow { * @details get value of member restartNeeded to needed. * @param needed true, if application has to be restarted */ - void SlotSetRestartNeeded(bool needed); + void SlotSetRestartNeeded(int); private slots: @@ -322,7 +322,7 @@ class MainWindow : public GeneralMainWindow { /** * @brief return true, if restart is needed */ - [[nodiscard]] bool get_restart_needed() const; + [[nodiscard]] int get_restart_needed() const; TextEdit* edit_{}; ///< Tabwidget holding the edit-windows QMenu* file_menu_{}; ///< Submenu for file-operations @@ -387,7 +387,7 @@ class MainWindow : public GeneralMainWindow { QAction* about_act_{}; ///< Action to open about dialog QAction* check_update_act_{}; ///< Action to open about dialog QAction* translate_act_{}; ///< Action to open about dialog - QAction* gnupg_act_{}; ///< Action to open about dialog + QAction* gnupg_act_{}; ///< Action to open about dialog QAction* open_settings_act_{}; ///< Action to open settings dialog QAction* show_key_details_act_{}; ///< Action to open key-details dialog QAction* start_wizard_act_{}; ///< Action to open the wizard @@ -403,7 +403,7 @@ class MainWindow : public GeneralMainWindow { InfoBoardWidget* info_board_{}; ///< bool attachment_dock_created_{}; ///< - bool restart_needed_{}; ///< + int restart_needed_{0}; ///< bool prohibit_update_checking_ = false; ///< }; diff --git a/src/ui/main_window/MainWindowSlotUI.cpp b/src/ui/main_window/MainWindowSlotUI.cpp index 9061349e..8961a33f 100644 --- a/src/ui/main_window/MainWindowSlotUI.cpp +++ b/src/ui/main_window/MainWindowSlotUI.cpp @@ -27,6 +27,7 @@ */ #include "MainWindow.h" +#include "core/GpgConstants.h" #include "core/function/GlobalSettingStation.h" #include "ui/UserInterfaceUtils.h" #include "ui/struct/SettingsObject.h" @@ -128,7 +129,7 @@ void MainWindow::slot_open_settings_dialog() { if (get_restart_needed()) { if (edit_->MaybeSaveAnyTab()) { save_settings(); - qApp->exit(RESTART_CODE); + qApp->exit(get_restart_needed()); } } }); @@ -182,11 +183,12 @@ void MainWindow::slot_cut_pgp_header() { edit_->SlotFillTextEditWithText(content.trimmed()); } -void MainWindow::SlotSetRestartNeeded(bool needed) { - this->restart_needed_ = needed; +void MainWindow::SlotSetRestartNeeded(int mode) { + LOG(INFO) << "restart mode" << mode; + this->restart_needed_ = mode; } -bool MainWindow::get_restart_needed() const { return this->restart_needed_; } +int MainWindow::get_restart_needed() const { return this->restart_needed_; } void MainWindow::SetCryptoMenuStatus( MainWindow::CryptoMenu::OperationType type) { diff --git a/src/ui/widgets/InfoBoardWidget.cpp b/src/ui/widgets/InfoBoardWidget.cpp index 264a67d1..74ead2ce 100644 --- a/src/ui/widgets/InfoBoardWidget.cpp +++ b/src/ui/widgets/InfoBoardWidget.cpp @@ -79,11 +79,13 @@ void InfoBoardWidget::SetInfoBoard(const QString& text, status.setColor(QPalette::Text, color); ui_->infoBoard->setPalette(status); - SettingsObject main_windows_state("main_windows_state"); + SettingsObject general_settings_state("general_settings_state"); // info board font size - auto info_font_size = main_windows_state.Check("info_font_size", 10); + 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) { diff --git a/src/ui/widgets/KeyList.cpp b/src/ui/widgets/KeyList.cpp index 0bd65f25..9150d580 100644 --- a/src/ui/widgets/KeyList.cpp +++ b/src/ui/widgets/KeyList.cpp @@ -158,7 +158,7 @@ void KeyList::AddListGroupTab( } void KeyList::SlotRefresh() { - LOG(INFO) << _("Called") << "address" << this; + LOG(INFO) << _("called") << "address" << this; ui_->refreshKeyListButton->setDisabled(true); ui_->syncButton->setDisabled(true); @@ -442,6 +442,8 @@ void KeyList::slot_sync_with_key_server() { } } + if (key_ids.empty()) return; + ui_->refreshKeyListButton->setDisabled(true); ui_->syncButton->setDisabled(true); @@ -496,7 +498,6 @@ void KeyList::check_all() { } KeyIdArgsListPtr& KeyTable::GetChecked() { - LOG(INFO) << "called"; if (checked_key_ids_ == nullptr) checked_key_ids_ = std::make_unique<KeyIdArgsList>(); auto& ret = checked_key_ids_; @@ -517,8 +518,6 @@ void KeyTable::SetChecked(KeyIdArgsListPtr key_ids) { } void KeyTable::Refresh(KeyLinkListPtr m_keys) { - LOG(INFO) << "called"; - auto& checked_key_list = GetChecked(); // while filling the table, sort enabled causes errors @@ -532,7 +531,6 @@ void KeyTable::Refresh(KeyLinkListPtr m_keys) { else keys = std::move(m_keys); - LOG(INFO) << "keys size: " << keys->size(); auto it = keys->begin(); int row_count = 0; @@ -553,7 +551,6 @@ void KeyTable::Refresh(KeyLinkListPtr m_keys) { it++; } - LOG(INFO) << "row_count: " << row_count; key_list_->setRowCount(row_count); int row_index = 0; @@ -645,8 +642,6 @@ void KeyTable::Refresh(KeyLinkListPtr m_keys) { } } } - - LOG(INFO) << "End"; } void KeyTable::UncheckALL() const { diff --git a/src/ui/widgets/PlainTextEditorPage.cpp b/src/ui/widgets/PlainTextEditorPage.cpp index 7eb682cc..10e19b8b 100644 --- a/src/ui/widgets/PlainTextEditorPage.cpp +++ b/src/ui/widgets/PlainTextEditorPage.cpp @@ -34,6 +34,7 @@ #include "core/thread/FileReadTask.h" #include "core/thread/Task.h" #include "core/thread/TaskRunnerGetter.h" +#include "ui/struct/SettingsObject.h" #include "ui_PlainTextEditor.h" namespace GpgFrontend::UI { @@ -48,7 +49,13 @@ PlainTextEditorPage::PlainTextEditorPage(QString file_path, QWidget *parent) ui_->loadingLabel->setHidden(true); // Front in same width - this->setFont({"Courier"}); + SettingsObject general_settings_state("general_settings_state"); + + // font size + auto editor_font_size = + general_settings_state.Check("text_editor").Check("font_size", 10); + ui_->textPage->setFont(QFont("Courier", editor_font_size)); + this->setAttribute(Qt::WA_DeleteOnClose); this->ui_->characterLabel->setText(_("0 character")); diff --git a/src/ui/widgets/PlainTextEditorPage.h b/src/ui/widgets/PlainTextEditorPage.h index e5c1c89d..ffa31762 100644 --- a/src/ui/widgets/PlainTextEditorPage.h +++ b/src/ui/widgets/PlainTextEditorPage.h @@ -129,7 +129,7 @@ class PlainTextEditorPage : public QWidget { size_t read_bytes_ = 0; ///< std::string charset_name_; ///< std::string language_name_; ///< - int32_t charset_confidence_; ///< + int32_t charset_confidence_{}; ///< bool is_crlf_ = false; ///< /** diff --git a/ui/AppearanceSettings.ui b/ui/AppearanceSettings.ui new file mode 100644 index 00000000..e49772c7 --- /dev/null +++ b/ui/AppearanceSettings.ui @@ -0,0 +1,192 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>AppearanceSettings</class> + <widget class="QWidget" name="AppearanceSettings"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>560</width> + <height>694</height> + </rect> + </property> + <property name="windowTitle"> + <string>Appearance Settings</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QGroupBox" name="iconSizeBox"> + <property name="title"> + <string>Icon Size</string> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QRadioButton" name="smallRadioButton"> + <property name="text"> + <string>small</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="mediumRadioButton"> + <property name="text"> + <string>medium</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="largeRadioButton"> + <property name="text"> + <string>large</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="iconStyleBox"> + <property name="title"> + <string>Icon Style</string> + </property> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QRadioButton" name="justTextRadioButton"> + <property name="text"> + <string>just text</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="justIconRadioButton"> + <property name="text"> + <string>just icons</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="textAndIconsRadioButton"> + <property name="text"> + <string>text and icons</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="windowStateBox"> + <property name="title"> + <string>Window State</string> + </property> + <layout class="QGridLayout" name="gridLayout_4"> + <item row="0" column="0"> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <widget class="QCheckBox" name="windowStateCheckBox"> + <property name="text"> + <string>Save window size and position on exit.</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="textEditorBox"> + <property name="title"> + <string>Text Editor</string> + </property> + <layout class="QGridLayout" name="gridLayout_8"> + <item row="0" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout_5"> + <item> + <widget class="QLabel" name="fontSizeTextEditorLabel"> + <property name="text"> + <string>Font Size in Text Editor</string> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="fontSizeTextEditorLabelSpinBox"> + <property name="minimum"> + <number>9</number> + </property> + <property name="maximum"> + <number>18</number> + </property> + <property name="value"> + <number>10</number> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="informationBoardBox"> + <property name="title"> + <string>Information Board</string> + </property> + <layout class="QGridLayout" name="gridLayout_6"> + <item row="0" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="QLabel" name="fontSizeInformationBoardLabel"> + <property name="text"> + <string>Font Size in Information Board</string> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="fontSizeInformationBoardSpinBox"> + <property name="minimum"> + <number>9</number> + </property> + <property name="maximum"> + <number>18</number> + </property> + <property name="value"> + <number>10</number> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/ui/GeneralSettings.ui b/ui/GeneralSettings.ui index 4bfb5f43..4121e762 100644 --- a/ui/GeneralSettings.ui +++ b/ui/GeneralSettings.ui @@ -124,6 +124,46 @@ </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> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="currentKeyDatabasePathLabel"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="customKeyDatabasePathSelectButton"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Select Custom Path</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> <spacer name="verticalSpacer"> <property name="orientation"> <enum>Qt::Vertical</enum> diff --git a/ui/GnuPGInfo.ui b/ui/GnuPGInfo.ui new file mode 100644 index 00000000..f907874f --- /dev/null +++ b/ui/GnuPGInfo.ui @@ -0,0 +1,96 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>GnuPGInfo</class> + <widget class="QWidget" name="GnuPGInfo"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>535</width> + <height>568</height> + </rect> + </property> + <property name="windowTitle"> + <string>GnuPG Info</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,0,0"> + <property name="leftMargin"> + <number>5</number> + </property> + <property name="topMargin"> + <number>5</number> + </property> + <property name="rightMargin"> + <number>5</number> + </property> + <property name="bottomMargin"> + <number>5</number> + </property> + <item> + <widget class="QLabel" name="label"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap resource="../gpgfrontend.qrc">:/gnupg.png</pixmap> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="margin"> + <number>10</number> + </property> + </widget> + </item> + <item> + <widget class="Line" name="line"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <widget class="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> + </property> + <property name="margin"> + <number>5</number> + </property> + </widget> + </item> + <item> + <widget class="QTableWidget" name="conponentDetailsTable"/> + </item> + </layout> + </item> + </layout> + </widget> + <resources> + <include location="../gpgfrontend.qrc"/> + </resources> + <connections/> +</ui> diff --git a/ui/KeyServerImportDialog.ui b/ui/KeyServerImportDialog.ui new file mode 100644 index 00000000..2600d06a --- /dev/null +++ b/ui/KeyServerImportDialog.ui @@ -0,0 +1,149 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>KeyServerImportDialog</class> + <widget class="QDialog" name="KeyServerImportDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>559</width> + <height>428</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Search String</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="lineEdit"/> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QComboBox" name="comboBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButton"> + <property name="text"> + <string>Search</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QTableWidget" name="tableWidget"/> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="QLabel" name="label_3"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>ICON</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_2"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Message</string> + </property> + </widget> + </item> + <item> + <widget class="QProgressBar" name="progressBar"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="value"> + <number>24</number> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>KeyServerImportDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>KeyServerImportDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> |