aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt366
-rw-r--r--src/GpgFrontend.h.in63
-rw-r--r--src/GpgFrontendBuildInfo.h.in54
-rw-r--r--src/MainWindow.cpp245
-rw-r--r--src/advance/UnknownSignersChecker.cpp86
-rw-r--r--src/advance/UnknownSignersChecker.h (renamed from src/gpg/GpgSubKey.cpp)42
-rw-r--r--src/gpg/CMakeLists.txt46
-rw-r--r--src/gpg/GpgConstants.cpp163
-rw-r--r--src/gpg/GpgConstants.h101
-rw-r--r--src/gpg/GpgContext.cpp127
-rw-r--r--src/gpg/GpgContext.h95
-rw-r--r--src/gpg/GpgFileOpera.cpp249
-rw-r--r--src/gpg/GpgFunctionObject.h138
-rw-r--r--src/gpg/GpgGenKeyInfo.cpp258
-rw-r--r--src/gpg/GpgGenKeyInfo.h167
-rw-r--r--src/gpg/GpgInfo.cpp4
-rw-r--r--src/gpg/GpgInfo.h (renamed from src/gpg/GpgUID.cpp)29
-rw-r--r--src/gpg/GpgKey.cpp274
-rw-r--r--src/gpg/GpgModel.h71
-rw-r--r--src/gpg/function/BasicOperator.cpp206
-rw-r--r--src/gpg/function/BasicOperator.h69
-rw-r--r--src/gpg/function/GpgCommandExecutor.cpp59
-rw-r--r--src/gpg/function/GpgCommandExecutor.h52
-rw-r--r--src/gpg/function/GpgFileOpera.cpp162
-rw-r--r--src/gpg/function/GpgFileOpera.h58
-rw-r--r--src/gpg/function/GpgKeyGetter.cpp75
-rw-r--r--src/gpg/function/GpgKeyGetter.h52
-rw-r--r--src/gpg/function/GpgKeyImportExportor.cpp117
-rw-r--r--src/gpg/function/GpgKeyImportExportor.h100
-rw-r--r--src/gpg/function/GpgKeyManager.cpp88
-rw-r--r--src/gpg/function/GpgKeyManager.h58
-rw-r--r--src/gpg/function/GpgKeyOpera.cpp217
-rw-r--r--src/gpg/function/GpgKeyOpera.h54
-rw-r--r--src/gpg/function/UidOperator.cpp64
-rw-r--r--src/gpg/function/UidOperator.h76
-rw-r--r--src/gpg/gpg_context/GpgContext.cpp410
-rw-r--r--src/gpg/gpg_context/GpgContextBasicOpera.cpp315
-rw-r--r--src/gpg/gpg_context/GpgContextKeyInfo.cpp110
-rw-r--r--src/gpg/gpg_context/GpgContextKeyOpera.cpp410
-rw-r--r--src/gpg/gpg_context/GpgContextSubkeyOpera.cpp61
-rw-r--r--src/gpg/gpg_context/GpgContextUIDOpera.cpp80
-rw-r--r--src/gpg/model/GpgData.cpp74
-rw-r--r--src/gpg/model/GpgData.h54
-rw-r--r--src/gpg/model/GpgKey.cpp108
-rw-r--r--src/gpg/model/GpgKey.h162
-rw-r--r--src/gpg/model/GpgKeySignature.cpp28
-rw-r--r--src/gpg/model/GpgKeySignature.h85
-rw-r--r--src/gpg/model/GpgSubKey.cpp27
-rw-r--r--src/gpg/model/GpgSubKey.h102
-rw-r--r--src/gpg/model/GpgUID.cpp28
-rw-r--r--src/gpg/model/GpgUID.h81
-rw-r--r--src/gpg/result_analyse/DecryptResultAnalyse.cpp99
-rw-r--r--src/gpg/result_analyse/DecryptResultAnalyse.h49
-rw-r--r--src/gpg/result_analyse/EncryptResultAnalyse.cpp65
-rw-r--r--src/gpg/result_analyse/EncryptResultAnalyse.h45
-rw-r--r--src/gpg/result_analyse/ResultAnalyse.cpp22
-rw-r--r--src/gpg/result_analyse/ResultAnalyse.h57
-rw-r--r--src/gpg/result_analyse/SignResultAnalyse.cpp143
-rw-r--r--src/gpg/result_analyse/SignResultAnalyse.h47
-rw-r--r--src/gpg/result_analyse/VerifyResultAnalyse.cpp291
-rw-r--r--src/gpg/result_analyse/VerifyResultAnalyse.h51
-rw-r--r--src/main.cpp192
-rw-r--r--src/server/BaseAPI.cpp55
-rw-r--r--src/server/BaseAPI.h66
-rw-r--r--src/server/ComUtils.cpp286
-rw-r--r--src/server/ComUtils.h88
-rw-r--r--src/server/api/PubkeyGetter.cpp117
-rw-r--r--src/server/api/PubkeyGetter.h52
-rw-r--r--src/server/api/PubkeyUploader.cpp148
-rw-r--r--src/server/api/PubkeyUploader.h51
-rw-r--r--src/smtp/SmtpMime31
-rw-r--r--src/smtp/emailaddress.h63
-rw-r--r--src/smtp/mimeattachment.h51
-rw-r--r--src/smtp/mimecontentformatter.h43
-rw-r--r--src/smtp/mimefile.h63
-rw-r--r--src/smtp/mimehtml.h61
-rw-r--r--src/smtp/mimeinlinefile.h56
-rw-r--r--src/smtp/mimemessage.cpp426
-rw-r--r--src/smtp/mimemessage.h110
-rw-r--r--src/smtp/mimemultipart.cpp51
-rw-r--r--src/smtp/mimemultipart.h71
-rw-r--r--src/smtp/mimepart.cpp155
-rw-r--r--src/smtp/mimepart.h110
-rw-r--r--src/smtp/mimetext.h62
-rw-r--r--src/smtp/quotedprintable.h39
-rw-r--r--src/smtp/smtpclient.h197
-rw-r--r--src/smtp/smtpexports.h10
-rw-r--r--src/ui/CMakeLists.txt9
-rwxr-xr-xsrc/ui/FileEncryptionDialog.cpp467
-rwxr-xr-xsrc/ui/FileEncryptionDialog.h114
-rw-r--r--src/ui/FindWidget.cpp241
-rw-r--r--src/ui/FindWidget.h72
-rw-r--r--src/ui/GpgFrontendUI.h53
-rw-r--r--src/ui/KeyImportDetailDialog.cpp264
-rw-r--r--src/ui/KeyImportDetailDialog.h55
-rwxr-xr-xsrc/ui/KeyMgmt.cpp627
-rwxr-xr-xsrc/ui/KeyMgmt.h102
-rw-r--r--src/ui/KeyServerImportDialog.cpp853
-rw-r--r--src/ui/KeyServerImportDialog.h93
-rw-r--r--src/ui/KeyUploadDialog.cpp182
-rw-r--r--src/ui/KeyUploadDialog.h57
-rw-r--r--src/ui/MainWindow.cpp380
-rw-r--r--src/ui/MainWindow.h437
-rwxr-xr-xsrc/ui/QuitDialog.cpp205
-rwxr-xr-xsrc/ui/QuitDialog.h53
-rw-r--r--src/ui/SendMailDialog.cpp173
-rw-r--r--src/ui/ShowCopyDialog.cpp56
-rw-r--r--src/ui/ShowCopyDialog.h50
-rw-r--r--src/ui/SignalStation.cpp (renamed from src/gpg/GpgKeySignature.cpp)18
-rw-r--r--src/ui/SignalStation.h41
-rw-r--r--src/ui/UserInterfaceUtils.cpp171
-rw-r--r--src/ui/UserInterfaceUtils.h82
-rw-r--r--src/ui/VerifyDetailsDialog.cpp108
-rw-r--r--src/ui/VerifyDetailsDialog.h57
-rw-r--r--src/ui/WaitingDialog.cpp87
-rw-r--r--src/ui/WaitingDialog.h46
-rw-r--r--src/ui/Wizard.cpp482
-rw-r--r--src/ui/Wizard.h114
-rw-r--r--src/ui/function/FileReadThread.cpp68
-rw-r--r--src/ui/function/FileReadThread.h52
-rw-r--r--src/ui/function/VersionCheckThread.cpp77
-rw-r--r--src/ui/function/VersionCheckThread.h52
-rw-r--r--src/ui/help/AboutDialog.cpp331
-rw-r--r--src/ui/help/AboutDialog.h103
-rw-r--r--src/ui/help/VersionCheckThread.cpp75
-rw-r--r--src/ui/keygen/KeygenDialog.cpp555
-rw-r--r--src/ui/keygen/KeygenDialog.h117
-rw-r--r--src/ui/keygen/SubkeyGenerateDialog.cpp439
-rw-r--r--src/ui/keygen/SubkeyGenerateDialog.h97
-rw-r--r--src/ui/keypair_details/EditSubKeyDialog.cpp4
-rw-r--r--src/ui/keypair_details/EditSubKeyDialog.h30
-rw-r--r--src/ui/keypair_details/KeyDetailsDialog.cpp37
-rw-r--r--src/ui/keypair_details/KeyDetailsDialog.h47
-rw-r--r--src/ui/keypair_details/KeyNewUIDDialog.cpp147
-rw-r--r--src/ui/keypair_details/KeyNewUIDDialog.h64
-rw-r--r--src/ui/keypair_details/KeyPairDetailTab.cpp606
-rw-r--r--src/ui/keypair_details/KeyPairDetailTab.h105
-rw-r--r--src/ui/keypair_details/KeyPairSubkeyTab.cpp449
-rw-r--r--src/ui/keypair_details/KeyPairSubkeyTab.h86
-rw-r--r--src/ui/keypair_details/KeyPairUIDTab.cpp791
-rw-r--r--src/ui/keypair_details/KeyPairUIDTab.h100
-rw-r--r--src/ui/keypair_details/KeySetExpireDateDialog.cpp134
-rw-r--r--src/ui/keypair_details/KeySetExpireDateDialog.h64
-rw-r--r--src/ui/keypair_details/KeyUIDSignDialog.cpp179
-rw-r--r--src/ui/keypair_details/KeyUIDSignDialog.h64
-rw-r--r--src/ui/main_window/MainWindowFileSlotFunction.cpp912
-rw-r--r--src/ui/main_window/MainWindowServerSlotFunction.cpp374
-rw-r--r--src/ui/main_window/MainWindowSlotFunction.cpp933
-rw-r--r--src/ui/main_window/MainWindowSlotUI.cpp280
-rw-r--r--src/ui/main_window/MainWindowUI.cpp872
-rw-r--r--src/ui/settings/GlobalSettingStation.cpp94
-rw-r--r--src/ui/settings/GlobalSettingStation.h90
-rw-r--r--src/ui/settings/SettingsAdvanced.cpp73
-rw-r--r--src/ui/settings/SettingsAdvanced.h54
-rw-r--r--src/ui/settings/SettingsAppearance.cpp352
-rw-r--r--src/ui/settings/SettingsAppearance.h61
-rw-r--r--src/ui/settings/SettingsDialog.cpp276
-rwxr-xr-xsrc/ui/settings/SettingsDialog.h86
-rw-r--r--src/ui/settings/SettingsGeneral.cpp635
-rw-r--r--src/ui/settings/SettingsGeneral.h85
-rw-r--r--src/ui/settings/SettingsKeyServer.cpp240
-rw-r--r--src/ui/settings/SettingsKeyServer.h59
-rw-r--r--src/ui/settings/SettingsSendMail.cpp302
-rw-r--r--src/ui/settings/SettingsSendMail.h46
-rw-r--r--src/ui/smtp/SendMailDialog.cpp195
-rw-r--r--src/ui/smtp/SendMailDialog.h71
-rw-r--r--src/ui/widgets/EditorPage.cpp173
-rw-r--r--src/ui/widgets/EditorPage.h113
-rw-r--r--src/ui/widgets/FilePage.cpp408
-rw-r--r--src/ui/widgets/FilePage.h90
-rw-r--r--src/ui/widgets/GroupKeyList.cpp25
-rw-r--r--src/ui/widgets/GroupKeyList.h34
-rw-r--r--src/ui/widgets/HelpPage.cpp75
-rw-r--r--src/ui/widgets/HelpPage.h49
-rw-r--r--src/ui/widgets/InfoBoardWidget.cpp299
-rw-r--r--src/ui/widgets/InfoBoardWidget.h115
-rw-r--r--src/ui/widgets/KeyList.cpp637
-rw-r--r--src/ui/widgets/KeyList.h124
-rw-r--r--src/ui/widgets/SignersPicker.cpp60
-rw-r--r--src/ui/widgets/SignersPicker.h48
-rw-r--r--src/ui/widgets/TextEdit.cpp270
-rw-r--r--src/ui/widgets/TextEdit.h282
-rw-r--r--src/ui/widgets/VerifyKeyDetailBox.cpp332
-rw-r--r--src/ui/widgets/VerifyKeyDetailBox.h55
184 files changed, 18878 insertions, 10766 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 200f5beb..d5a713b1 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,146 +1,234 @@
-add_subdirectory(gpg)
-add_subdirectory(ui)
-add_subdirectory(smtp)
-add_subdirectory(server)
-add_subdirectory(advance)
-
-aux_source_directory(. BASE_SOURCE)
-
-set(APP_ICON_RESOURCE_WINDOWS "${CMAKE_SOURCE_DIR}/gpgfrontend.rc")
-set_property(SOURCE gpgfrontend.rc APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_SOURCE_DIR}/gpgfrontend.ico)
-
-
-file(GLOB_RECURSE GPGFRONTEND_HEADER_FILES RELACTIVE ${CMAKE_SOURCE_DIR}/include/*.h)
-qt5_wrap_cpp(QT5_MOCS ${GPGFRONTEND_HEADER_FILES} TARGET ${AppName})
-
-# Set Binary Output Path
-set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release)
-message(STATUS "CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
-
-# Set Resource Output Path
-if(${CMAKE_BUILD_TYPE} STREQUAL "Release")
- if(APPLE)
- set(RESOURCE_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Resources)
- elseif(LINUX)
- file(COPY ${CMAKE_SOURCE_DIR}/resource/gpgfrontend DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
- set(RESOURCE_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/gpgfrontend/usr/share)
- else()
+if (GPG_CORE)
+ message(STATUS "Build Gpg Core")
+ add_subdirectory(gpg)
+endif ()
+
+if (UI_CORE)
+ message(STATUS "Build UI Core")
+ add_subdirectory(ui)
+endif ()
+
+if (SMTP_SUPPORT)
+ message(STATUS "Build SMTP Support")
+ add_compile_definitions(SMTP_SUPPORT)
+ add_subdirectory(smtp)
+endif ()
+
+if (SERVER_SUPPORT)
+ message(STATUS "Build Server Support")
+ add_compile_definitions(SERVER_SUPPORT)
+ add_subdirectory(server)
+endif ()
+
+if (ADVANCE_SUPPORT)
+ message(STATUS "Build Advance Support")
+ add_compile_definitions(ADVANCE_SUPPORT)
+ add_subdirectory(advance)
+endif ()
+
+if (APPLICATION_BUILD)
+ aux_source_directory(. BASE_SOURCE)
+ set(APP_ICON_RESOURCE_WINDOWS "${CMAKE_SOURCE_DIR}/gpgfrontend.rc")
+ set_property(SOURCE gpgfrontend.rc APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_SOURCE_DIR}/gpgfrontend.ico)
+
+ # Set Binary Output Path
+ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release)
+ message(STATUS "CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
+endif ()
+
+
+if (APPLICATION_BUILD)
+ # Set Resource Output Path
+ if (${CMAKE_BUILD_TYPE} STREQUAL "Release")
+ if (APPLE)
+ set(RESOURCE_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Resources)
+ elseif (LINUX)
+ file(COPY ${CMAKE_SOURCE_DIR}/resource/gpgfrontend DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
+ set(RESOURCE_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/gpgfrontend/usr/share)
+ else ()
+ set(RESOURCE_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
+ endif ()
+ else ()
set(RESOURCE_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
- endif()
-else()
- set(RESOURCE_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
-endif()
-message(STATUS "RESOURCE_OUTPUT_DIRECTORY ${RESOURCE_OUTPUT_DIRECTORY}")
+ endif ()
+ message(STATUS "RESOURCE_OUTPUT_DIRECTORY ${RESOURCE_OUTPUT_DIRECTORY}")
+endif ()
# Get ALL SOURCE FILES
file(GLOB_RECURSE ALL_SOURCE_FILES RELACTIVE ${CMAKE_SOURCE_DIR}/src/*.cpp)
-# Set Translation Files
-set(QT_TS_FILES
- gpgfrontend_en_us.ts gpgfrontend_zh_cn.ts
- gpgfrontend_fr.ts gpgfrontend_ru.ts gpgfrontend_es.ts)
-list(TRANSFORM QT_TS_FILES PREPEND ${CMAKE_SOURCE_DIR}/resource/ts/)
-message(STATUS "QT_TS_FILES ${QT_TS_FILES}")
-set(QT_QM_FILES_OUTPUT_DIR ${RESOURCE_OUTPUT_DIRECTORY}/ts)
-set_source_files_properties(${QT_TS_FILES} PROPERTIES OUTPUT_LOCATION ${QT_QM_FILES_OUTPUT_DIR})
-QT5_create_translation(QON_QM_FILES ${CMAKE_SOURCE_DIR} ${QT_TS_FILES})
-message(STATUS "QON_QM_FILES ${QON_QM_FILES}")
-add_custom_target(translations DEPENDS ${QON_QM_FILES})
-
-# Set Build Information
-configure_file(${CMAKE_SOURCE_DIR}/include/GpgFrontend.h.in ${CMAKE_SOURCE_DIR}/include/GpgFrontend.h @ONLY)
-configure_file(${CMAKE_SOURCE_DIR}/include/GpgFrontendBuildInfo.h.in ${CMAKE_SOURCE_DIR}/include/GpgFrontendBuildInfo.h @ONLY)
-
-# Copy Resource Files
-file(COPY ${CMAKE_SOURCE_DIR}/resource/css DESTINATION ${RESOURCE_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
-file(COPY ${CMAKE_SOURCE_DIR}/resource/icons DESTINATION ${RESOURCE_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
-file(COPY ${CMAKE_SOURCE_DIR}/resource/conf DESTINATION ${RESOURCE_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
-
-if(${CMAKE_BUILD_TYPE} STREQUAL "Release")
- if(APPLE)
- file(COPY ${CMAKE_SOURCE_DIR}/gpgfrontend.icns DESTINATION ${RESOURCE_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
- # Refresh App Bundle
- file(REMOVE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${AppName}.app)
- elseif(LINUX)
- file(REMOVE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/gpgfrontend/usr/bin/${AppName})
- endif()
-endif()
-
-# Copy Utils Files
-if(MINGW)
- message(STATUS "Copying Dependent DLL For Windows Runtime Env")
- file(COPY ${CMAKE_SOURCE_DIR}/resource/utils/lib/ DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
- file(COPY ${CMAKE_SOURCE_DIR}/resource/utils/gpgme/ DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
- file(COPY ${CMAKE_SOURCE_DIR}/resource/utils/bearer DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
- file(COPY ${CMAKE_SOURCE_DIR}/resource/utils/iconengines DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
- file(COPY ${CMAKE_SOURCE_DIR}/resource/utils/imageformats DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
- file(COPY ${CMAKE_SOURCE_DIR}/resource/utils/printsupport DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
- file(COPY ${CMAKE_SOURCE_DIR}/resource/utils/platforms DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
- file(COPY ${CMAKE_SOURCE_DIR}/resource/utils/openssl/ DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
-endif()
-
-set(RESOURCE_FILES ${CMAKE_SOURCE_DIR}/gpgfrontend.qrc ${APP_ICON_RESOURCE_WINDOWS} ${QON_QM_FILES})
-add_custom_target(resources ALL DEPENDS ${RESOURCE_FILES})
-add_dependencies(resources translations)
-
-if(${CMAKE_BUILD_TYPE} STREQUAL "Release")
- if(MINGW)
- add_executable(${AppName} WIN32 ${BASE_SOURCE} ${RESOURCE_FILES} ${QT5_MOCS})
- elseif(APPLE)
- add_executable(${AppName} MACOSX_BUNDLE ${ICON_RESOURCE} ${BASE_SOURCE} ${RESOURCE_FILES} ${QT5_MOCS})
- set_target_properties(${AppName} PROPERTIES
- BUNDLE True
- MACOSX_BUNDLE_GUI_IDENTIFIER pub.gpgfrontend.gpgfrontend
- MACOSX_BUNDLE_BUNDLE_NAME ${AppName}
- MACOSX_BUNDLE_LONG_VERSION_STRING ${BUILD_VERSION}
- MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION}
- MACOSX_BUNDLE_BUNDLE_VERSION ${BUILD_VERSION}
- MACOSX_BUNDLE_ICON_FILE "gpgfrontend.icns")
- add_custom_command(TARGET ${AppName} POST_BUILD
- COMMAND /bin/rm -rf ./${AppName}.app/Contents/Resources
- WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
- COMMENT "Deleting Resources in App Bundle")
- add_custom_command(TARGET ${AppName} POST_BUILD
- COMMAND /bin/mv -n ./Resources ./${AppName}.app/Contents/
- WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
- COMMENT "Copying Resources into App Bundle Resource")
- elseif(LINUX)
- add_executable(${AppName} ${BASE_SOURCE} ${RESOURCE_FILES} ${QT5_MOCS})
- add_custom_command(TARGET ${AppName} POST_BUILD
- COMMAND /bin/mkdir ./gpgfrontend/usr/bin && /bin/mv -f ./${AppName} ./gpgfrontend/usr/bin/
- WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
- COMMENT "Copying Binary into App Image")
- add_custom_command(TARGET ${AppName} POST_BUILD
- COMMAND /bin/mkdir ./gpgfrontend/usr/lib
- WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
- COMMENT "Complement to build the required architecture")
- else()
+# i18n
+if (MULTI_LANG_SUPPORT)
+ message(STATUS "Build Multiply Languages Support")
+ # Set Translation Files
+ find_package(Gettext REQUIRED)
+ FIND_PROGRAM(GETTEXT_MSGFMT_EXECUTABLE msgfmt)
+ FIND_PROGRAM(GETTEXT_XGETTEXT_EXECUTABLE xgettext)
+ if (NOT GETTEXT_MSGFMT_EXECUTABLE OR NOT GETTEXT_XGETTEXT_EXECUTABLE)
+ message(ERROR "msgfmt or xgettext not found. Translations will *not* be installed")
+ else (NOT GETTEXT_MSGFMT_EXECUTABLE)
+ message(STATUS "Setting target translations")
+ add_custom_target(translations)
+ set(OUTPUT_POT_PATH ${CMAKE_SOURCE_DIR}/resource/locale/template/${PROJECT_NAME}.pot)
+ add_custom_command(
+ TARGET translations
+ COMMAND find ${CMAKE_SOURCE_DIR}/src -iname \"*.cpp\" | xargs xgettext --package-name=${PROJECT_NAME} --copyright-holder=Saturneric --package-version=${PROJECT_VERSION} [email protected] --add-comments="/*" --c++ -k_ -o ${OUTPUT_POT_PATH}
+ )
+
+ file(GLOB ALL_PO_FILES ${CMAKE_SOURCE_DIR}/resource/locale/po/*.po)
+ SET(GMO_FILES)
+ message(STATUS "ALL_PO_FILES ${ALL_PO_FILES}")
+
+ foreach (_poFile ${ALL_PO_FILES})
+ GET_FILENAME_COMPONENT(_poFileName ${_poFile} NAME)
+ string(REGEX REPLACE "\\.[^.]*$" "" _langName ${_poFileName})
+ message(STATUS "_poFileName ${_langName}")
+ make_directory(${CMAKE_SOURCE_DIR}/resource/locale/out/${_langName}/LC_MESSAGES)
+ add_custom_command(
+ TARGET translations
+ COMMAND echo Processing po LANG ${_langName}
+ )
+ add_custom_command(
+ TARGET translations
+ COMMAND msgfmt --check --verbose --output-file ${CMAKE_SOURCE_DIR}/resource/locale/out/${_langName}/LC_MESSAGES/GpgFrontend.mo ${_poFile}
+ )
+ endforeach ()
+
+ endif ()
+endif ()
+
+if (BASIC_ENV_CONFIG)
+ # Set Build Information
+ configure_file(${CMAKE_SOURCE_DIR}/src/GpgFrontend.h.in ${CMAKE_SOURCE_DIR}/src/GpgFrontend.h @ONLY)
+ configure_file(${CMAKE_SOURCE_DIR}/src/GpgFrontendBuildInfo.h.in ${CMAKE_SOURCE_DIR}/src/GpgFrontendBuildInfo.h @ONLY)
+endif ()
+
+if (APPLICATION_BUILD)
+ # Copy Resource Files
+ file(COPY ${CMAKE_SOURCE_DIR}/resource/css DESTINATION ${RESOURCE_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
+ file(COPY ${CMAKE_SOURCE_DIR}/resource/icons DESTINATION ${RESOURCE_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
+ if (MULTI_LANG_SUPPORT)
+ make_directory(${RESOURCE_OUTPUT_DIRECTORY}/locales)
+ file(COPY ${CMAKE_SOURCE_DIR}/resource/locale/out/ DESTINATION ${RESOURCE_OUTPUT_DIRECTORY}/locales FOLLOW_SYMLINK_CHAIN)
+ endif ()
+endif ()
+
+if (APPLICATION_BUILD)
+ if (${CMAKE_BUILD_TYPE} STREQUAL "Release")
+ if (APPLE)
+ file(COPY ${CMAKE_SOURCE_DIR}/gpgfrontend.icns DESTINATION ${RESOURCE_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
+ # Refresh App Bundle
+ file(REMOVE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${AppName}.app)
+ elseif (LINUX)
+ file(REMOVE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/gpgfrontend/usr/bin/${AppName})
+ endif ()
+ endif ()
+endif ()
+
+if (APPLICATION_BUILD)
+ # Copy Utils Files
+ if (MINGW)
+ message(STATUS "Copying Dependent DLL For Windows Runtime Env")
+ file(COPY ${CMAKE_SOURCE_DIR}/resource/utils/lib/ DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
+ file(COPY ${CMAKE_SOURCE_DIR}/resource/utils/gpgme/ DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
+ file(COPY ${CMAKE_SOURCE_DIR}/resource/utils/bearer DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
+ file(COPY ${CMAKE_SOURCE_DIR}/resource/utils/iconengines DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
+ file(COPY ${CMAKE_SOURCE_DIR}/resource/utils/imageformats DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
+ file(COPY ${CMAKE_SOURCE_DIR}/resource/utils/printsupport DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
+ file(COPY ${CMAKE_SOURCE_DIR}/resource/utils/platforms DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
+ file(COPY ${CMAKE_SOURCE_DIR}/resource/utils/openssl/ DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
+ endif ()
+endif ()
+
+if (APPLICATION_BUILD)
+ set(RESOURCE_FILES ${CMAKE_SOURCE_DIR}/gpgfrontend.qrc ${APP_ICON_RESOURCE_WINDOWS} ${QON_QM_FILES})
+ add_custom_target(resources ALL DEPENDS ${RESOURCE_FILES})
+ if (MULTI_LANG_SUPPORT)
+ add_dependencies(resources translations)
+ endif ()
+endif ()
+
+if (APPLICATION_BUILD)
+ if (${CMAKE_BUILD_TYPE} STREQUAL "Release")
+ if (MINGW)
+ add_executable(${AppName} WIN32 ${BASE_SOURCE} ${RESOURCE_FILES} ${QT5_MOCS})
+ elseif (APPLE)
+ add_executable(${AppName} MACOSX_BUNDLE ${ICON_RESOURCE} ${BASE_SOURCE} ${RESOURCE_FILES} ${QT5_MOCS})
+ set_target_properties(${AppName} PROPERTIES
+ BUNDLE True
+ MACOSX_BUNDLE_GUI_IDENTIFIER pub.gpgfrontend.gpgfrontend
+ MACOSX_BUNDLE_BUNDLE_NAME ${AppName}
+ MACOSX_BUNDLE_LONG_VERSION_STRING ${BUILD_VERSION}
+ MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION}
+ MACOSX_BUNDLE_BUNDLE_VERSION ${BUILD_VERSION}
+ MACOSX_BUNDLE_ICON_FILE "gpgfrontend.icns")
+ add_custom_command(TARGET ${AppName} POST_BUILD
+ COMMAND /bin/rm -rf ./${AppName}.app/Contents/Resources
+ WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
+ COMMENT "Deleting Resources in App Bundle")
+ add_custom_command(TARGET ${AppName} POST_BUILD
+ COMMAND /bin/mv -n ./Resources ./${AppName}.app/Contents/
+ WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
+ COMMENT "Copying Resources into App Bundle Resource")
+ elseif (LINUX)
+ add_executable(${AppName} ${BASE_SOURCE} ${RESOURCE_FILES} ${QT5_MOCS})
+ add_custom_command(TARGET ${AppName} POST_BUILD
+ COMMAND /bin/mkdir -p ./gpgfrontend/usr/bin && /bin/mv -f ./${AppName} ./gpgfrontend/usr/bin/
+ WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
+ COMMENT "Copying Binary into App Image")
+ add_custom_command(TARGET ${AppName} POST_BUILD
+ COMMAND /bin/mkdir -p ./gpgfrontend/usr/lib
+ WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
+ COMMENT "Complement to build the required architecture")
+ else ()
+ add_executable(${AppName} ${BASE_SOURCE} ${RESOURCE_FILES} ${QT5_MOCS})
+ endif ()
+ else ()
add_executable(${AppName} ${BASE_SOURCE} ${RESOURCE_FILES} ${QT5_MOCS})
- endif()
-else()
- add_executable(${AppName} ${BASE_SOURCE} ${RESOURCE_FILES} ${QT5_MOCS})
-endif()
-
-set(GPGFRONTEND_LIBS smtp gpgfrontend-ui advance server gpg)
-set(QT_DEPENDENCY_LIBS Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core)
-
-IF (MINGW)
- message(STATUS "Link Application Static Library For MINGW")
- target_link_libraries(${AppName}
- ${GPGFRONTEND_LIBS}
- ${QT_DEPENDENCY_LIBS}
- crypto ssl)
-elseif(APPLE)
- message(STATUS "Link Application Static Library For macOS")
- target_link_libraries(${AppName}
- ${GPGFRONTEND_LIBS}
- ${QT_DEPENDENCY_LIBS}
- crypto ssl)
-else()
- message(STATUS "Link Application Static Library For UNIX")
- target_link_libraries(${AppName}
- ${GPGFRONTEND_LIBS}
- ${QT_DEPENDENCY_LIBS}
- crypto ssl pthread)
-endif()
+ endif ()
+
+ # Make app build with resources
+ add_dependencies(${AppName} resources)
+
+endif ()
+
+if (APPLICATION_BUILD)
+
+ if (ADVANCE_SUPPORT)
+ set(GPGFRONTEND_BEFORE_UI_LIBS ${GPGFRONTEND_BEFORE_UI_LIBS} advance)
+ endif ()
+ if (ADVANCE_SUPPORT)
+ set(GPGFRONTEND_BEFORE_UI_LIBS ${GPGFRONTEND_BEFORE_UI_LIBS} server)
+ endif ()
+ if (SMTP_SUPPORT)
+ set(GPGFRONTEND_AFTER_UI_LIBS ${GPGFRONTEND_AFTER_UI_LIBS} server)
+ endif ()
+
+ set(GPGFRONTEND_LIBS ${GPGFRONTEND_AFTER_UI_LIBS} gpgfrontend-ui ${GPGFRONTEND_BEFORE_UI_LIBS} gpg_core easy_logging_pp)
+ set(QT_DEPENDENCY_LIBS Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core)
+
+ IF (MINGW)
+ message(STATUS "Link Application Static Library For MINGW")
+ find_library(libconfig NAMES libconfig++.a)
+ find_library(libintl NAMES libintl.a)
+ find_library(libiconv NAMES libiconv.a)
+
+ target_link_libraries(${AppName}
+ ${GPGFRONTEND_LIBS}
+ ${QT_DEPENDENCY_LIBS}
+ ${libintl} ${libiconv} ${libconfig} crypto ssl)
+ elseif (APPLE)
+ message(STATUS "Link Application Static Library For macOS")
+ target_link_libraries(${AppName}
+ ${GPGFRONTEND_LIBS}
+ ${QT_DEPENDENCY_LIBS}
+ crypto ssl intl)
+ else ()
+ message(STATUS "Link Application Static Library For UNIX ")
+ target_link_libraries(${AppName}
+ ${GPGFRONTEND_LIBS}
+ ${QT_DEPENDENCY_LIBS}
+ crypto ssl pthread)
+ endif ()
+endif ()
diff --git a/src/GpgFrontend.h.in b/src/GpgFrontend.h.in
new file mode 100644
index 00000000..622c2b07
--- /dev/null
+++ b/src/GpgFrontend.h.in
@@ -0,0 +1,63 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_H_IN
+#define GPGFRONTEND_H_IN
+
+// i18n
+#ifdef WINDOWS
+#include <winsock2.h>
+#include <windows.h>
+#endif
+
+#include <libintl.h>
+#define _(String) gettext (String)
+#define gettext_noop(String) String
+#define N_(String) gettext_noop (String)
+
+#ifdef WINDOWS
+#include <clocale>
+#undef vsnprintf
+#endif
+
+// logging
+#define ELPP_DEFAULT_LOGGING_FLAGS 8192
+#include <easyloggingpp/easylogging++.h>
+
+#define PROJECT_NAME "@CMAKE_PROJECT_NAME@"
+#define OS_PLATFORM @OS_PLATFORM@
+#define LOCALE_DIR "@LOCALE_DIR@"
+
+/**
+ * Resources File(s) Path Vars
+ */
+#if defined(MACOS) && defined(RELEASE)
+#define RESOURCE_DIR(appDir) (appDir + "/../Resources/")
+#elif defined(LINUX) && defined(RELEASE)
+#define RESOURCE_DIR(appDir) (appDir + "/../share/")
+#else
+#define RESOURCE_DIR(appDir) (appDir)
+#endif
+
+#endif // GPGFRONTEND_H_IN
diff --git a/src/GpgFrontendBuildInfo.h.in b/src/GpgFrontendBuildInfo.h.in
new file mode 100644
index 00000000..eaf0475b
--- /dev/null
+++ b/src/GpgFrontendBuildInfo.h.in
@@ -0,0 +1,54 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_BUILD_INFO_H_IN
+#define GPGFRONTEND_BUILD_INFO_H_IN
+
+/**
+ * Logic Version (*.*.*)
+ */
+#define VERSION_MAJOR @CMAKE_PROJECT_VERSION_MAJOR@
+#define VERSION_MINOR @CMAKE_PROJECT_VERSION_MINOR@
+#define VERSION_PATCH @CMAKE_PROJECT_VERSION_PATCH@
+
+/**
+ * Code Version (According to Git)
+ */
+#define GIT_BRANCH_NAME "@GIT_BRANCH_NAME@"
+#define GIT_COMMIT_HASH "@GIT_COMMIT_HASH@"
+
+/**
+ * Generated Information (According to CMake)
+ */
+#define PROJECT_NAME "@PROJECT_NAME@"
+#define BUILD_VERSION "@BUILD_VERSION@"
+#define GIT_VERSION "@GIT_VERSION@"
+
+/**
+ * Build Information
+ */
+#define BUILD_FLAG @BUILD_FLAG@
+#define BUILD_TIMESTAMP "@BUILD_TIMESTAMP@"
+
+#endif // GPGFRONTEND_BUILD_INFO_H_IN
diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp
deleted file mode 100644
index 73f55672..00000000
--- a/src/MainWindow.cpp
+++ /dev/null
@@ -1,245 +0,0 @@
-/**
- * This file is part of GPGFrontend.
- *
- * GPGFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Foobar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from gpg4usb-team.
- * Their source code version also complies with GNU General Public License.
- *
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]> starting on May 12, 2021.
- *
- */
-
-#include "MainWindow.h"
-#include "ui/help/VersionCheckThread.h"
-
-MainWindow::MainWindow()
- : appPath(qApp->applicationDirPath()),
- settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini",
- QSettings::IniFormat) {
-
- networkAccessManager = new QNetworkAccessManager(this);
-
- auto waitingDialog = new WaitingDialog(tr("Loading Gnupg"), this);
-
- // Init Gnupg
- auto ctx_thread = QThread::create([&]() { mCtx = new GpgME::GpgContext(); });
- ctx_thread->start();
- while (ctx_thread->isRunning())
- QApplication::processEvents();
- waitingDialog->close();
- ctx_thread->deleteLater();
-
- QString baseUrl = "https://api.github.com/repos/saturneric/gpgfrontend/releases/latest";
-
- QNetworkRequest request;
- request.setUrl(QUrl(baseUrl));
-
- QNetworkReply *replay = networkAccessManager->get(request);
-
- auto version_thread = new VersionCheckThread(replay);
-
- connect(version_thread, SIGNAL(finished()), version_thread, SLOT(deleteLater()));
- connect(version_thread, SIGNAL(upgradeVersion(const QString &, const QString &)), this, SLOT(slotVersionUpgrade(const QString &, const QString &)));
-
- version_thread->start();
-
- // Check Context Status
- if (!mCtx->isGood()) {
- QMessageBox::critical(
- nullptr, tr("ENV Loading Failed"),
- tr("Gnupg is not installed correctly, please follow the ReadME "
- "instructions to install gnupg and then open GPGFrontend."));
- QCoreApplication::quit();
- exit(0);
- }
-
- /* get path were app was started */
- setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
- setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
-
- edit = new TextEdit(this);
- setCentralWidget(edit);
-
- /* the list of Keys available*/
- mKeyList = new KeyList(mCtx, KeyListRow::SECRET_OR_PUBLIC_KEY,
- KeyListColumn::TYPE | KeyListColumn::NAME |
- KeyListColumn::EmailAddress |
- KeyListColumn::Usage | KeyListColumn::Validity,
- this);
- mKeyList->setFilter([](const GpgKey &key) -> bool {
- if (key.revoked || key.disabled || key.expired)
- return false;
- else
- return true;
- });
- mKeyList->slotRefresh();
-
- infoBoard = new InfoBoardWidget(this, mCtx, mKeyList);
-
- /* List of binary Attachments */
- attachmentDockCreated = false;
-
- /* Variable containing if restart is needed */
- this->slotSetRestartNeeded(false);
-
- keyMgmt = new KeyMgmt(mCtx, this);
- keyMgmt->hide();
- /* test attachmentdir for files alll 15s */
- auto *timer = new QTimer(this);
- connect(timer, SIGNAL(timeout()), this, SLOT(slotCheckAttachmentFolder()));
- timer->start(5000);
-
- createActions();
- createMenus();
- createToolBars();
- createStatusBar();
- createDockWindows();
-
- connect(edit->tabWidget, SIGNAL(currentChanged(int)), this,
- SLOT(slotDisableTabActions(int)));
-
- mKeyList->addMenuAction(appendSelectedKeysAct);
- mKeyList->addMenuAction(copyMailAddressToClipboardAct);
- mKeyList->addMenuAction(showKeyDetailsAct);
- mKeyList->addSeparator();
- mKeyList->addMenuAction(refreshKeysFromKeyserverAct);
- mKeyList->addMenuAction(uploadKeyToServerAct);
-
- restoreSettings();
-
- // open filename if provided as first command line parameter
- QStringList args = qApp->arguments();
- if (args.size() > 1) {
- if (!args[1].startsWith("-")) {
- if (QFile::exists(args[1]))
- edit->loadFile(args[1]);
- }
- }
- edit->curTextPage()->setFocus();
- this->setMinimumSize(1200, 700);
- this->setWindowTitle(qApp->applicationName());
- this->show();
-
- // Show wizard, if the don't show wizard message box wasn't checked
- // and keylist doesn't contain a private key
- qDebug() << "wizard/showWizard"
- << settings.value("wizard/showWizard", true).toBool();
- qDebug() << "wizard/nextPage" << settings.value("wizard/nextPage").isNull();
- if (settings.value("wizard/showWizard", true).toBool() ||
- !settings.value("wizard/nextPage").isNull()) {
- slotStartWizard();
- }
-
-}
-
-void MainWindow::restoreSettings() {
- // state sets pos & size of dock-widgets
- this->restoreState(settings.value("window/windowState").toByteArray());
-
- // Restore window size & location
- if (settings.value("window/windowSave").toBool()) {
- QPoint pos = settings.value("window/pos", QPoint(100, 100)).toPoint();
- QSize size = settings.value("window/size", QSize(800, 450)).toSize();
- this->resize(size);
- this->move(pos);
- } else {
- this->resize(QSize(800, 450));
- this->move(QPoint(100, 100));
- }
-
- // Iconsize
- QSize iconSize = settings.value("toolbar/iconsize", QSize(24, 24)).toSize();
- this->setIconSize(iconSize);
-
- importButton->setIconSize(iconSize);
- fileEncButton->setIconSize(iconSize);
- // set list of keyserver if not defined
- QStringList *keyServerDefaultList;
- keyServerDefaultList = new QStringList("http://keys.gnupg.net");
- keyServerDefaultList->append("https://keyserver.ubuntu.com");
- keyServerDefaultList->append("http://pool.sks-keyservers.net");
-
- QStringList keyServerList =
- settings.value("keyserver/keyServerList", *keyServerDefaultList)
- .toStringList();
- settings.setValue("keyserver/keyServerList", keyServerList);
-
- // set default keyserver, if it's not set
- QString defaultKeyServer = settings
- .value("keyserver/defaultKeyServer",
- QString("https://keyserver.ubuntu.com"))
- .toString();
- settings.setValue("keyserver/defaultKeyServer", defaultKeyServer);
-
- // Iconstyle
- Qt::ToolButtonStyle buttonStyle = static_cast<Qt::ToolButtonStyle>(
- settings.value("toolbar/iconstyle", Qt::ToolButtonTextUnderIcon)
- .toUInt());
- this->setToolButtonStyle(buttonStyle);
- importButton->setToolButtonStyle(buttonStyle);
- fileEncButton->setToolButtonStyle(buttonStyle);
-
- // Checked Keys
- if (settings.value("keys/saveKeyChecked").toBool()) {
- QStringList keyIds =
- settings.value("keys/savedCheckedKeyList").toStringList();
- mKeyList->setChecked(&keyIds);
- }
-}
-
-void MainWindow::saveSettings() {
- // window position and size
- settings.setValue("window/windowState", saveState());
- settings.setValue("window/pos", pos());
- settings.setValue("window/size", size());
-
- // keyid-list of private checked keys
- if (settings.value("keys/saveKeyChecked").toBool()) {
- QStringList *keyIds = mKeyList->getChecked();
- if (!keyIds->isEmpty()) {
- settings.setValue("keys/savedCheckedKeyList", *keyIds);
- } else {
- settings.setValue("keys/savedCheckedKeyList", "");
- }
- } else {
- settings.remove("keys/savedCheckedKeyList");
- }
-}
-
-void MainWindow::closeAttachmentDock() {
- if (!attachmentDockCreated) {
- return;
- }
- attachmentDock->close();
- attachmentDock->deleteLater();
- attachmentDockCreated = false;
-}
-
-void MainWindow::closeEvent(QCloseEvent *event) {
- /*
- * ask to save changes, if there are
- * modified documents in any tab
- */
- if (edit->maybeSaveAnyTab()) {
- saveSettings();
- event->accept();
- } else {
- event->ignore();
- }
-
- // clear password from memory
- mCtx->clearPasswordCache();
-}
diff --git a/src/advance/UnknownSignersChecker.cpp b/src/advance/UnknownSignersChecker.cpp
index 1b087b5c..fc70ee20 100644
--- a/src/advance/UnknownSignersChecker.cpp
+++ b/src/advance/UnknownSignersChecker.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,58 +24,52 @@
#include "advance/UnknownSignersChecker.h"
-
-UnknownSignersChecker::UnknownSignersChecker(GpgME::GpgContext *ctx, gpgme_verify_result_t result) :
- appPath(qApp->applicationDirPath()), settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini"), mCtx(ctx),
- mResult(result) {
-
-}
+UnknownSignersChecker::UnknownSignersChecker(GpgFrontend::GpgContext *ctx,
+ gpgme_verify_result_t result)
+ : appPath(qApp->applicationDirPath()),
+ settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini"),
+ mCtx(ctx),
+ mResult(result) {}
void UnknownSignersChecker::start() {
+ auto sign = mResult->signatures;
+ bool canContinue = true;
- auto sign = mResult->signatures;
- bool canContinue = true;
-
- while (sign && canContinue) {
-
- switch (gpg_err_code(sign->status)) {
- case GPG_ERR_BAD_SIGNATURE:
- break;
- case GPG_ERR_NO_ERROR:
- if (!(sign->status & GPGME_SIGSUM_KEY_MISSING))
- check_signer(sign);
- break;
- case GPG_ERR_NO_PUBKEY:
+ while (sign && canContinue) {
+ switch (gpg_err_code(sign->status)) {
+ case GPG_ERR_BAD_SIGNATURE:
+ break;
+ case GPG_ERR_NO_ERROR:
+ if (!(sign->status & GPGME_SIGSUM_KEY_MISSING)) check_signer(sign);
+ break;
+ case GPG_ERR_NO_PUBKEY:
- case GPG_ERR_CERT_REVOKED:
- case GPG_ERR_SIG_EXPIRED:
- case GPG_ERR_KEY_EXPIRED:
- check_signer(sign);
- break;
- case GPG_ERR_GENERAL:
- canContinue = false;
- break;
- default:
- break;
- }
- sign = sign->next;
+ case GPG_ERR_CERT_REVOKED:
+ case GPG_ERR_SIG_EXPIRED:
+ case GPG_ERR_KEY_EXPIRED:
+ check_signer(sign);
+ break;
+ case GPG_ERR_GENERAL:
+ canContinue = false;
+ break;
+ default:
+ break;
}
+ sign = sign->next;
+ }
- if(!unknownFprs.isEmpty()) {
- PubkeyGetter pubkeyGetter(mCtx, unknownFprs);
- pubkeyGetter.start();
- if (!pubkeyGetter.result()) {
-
- }
+ if (!unknownFprs.isEmpty()) {
+ PubkeyGetter pubkeyGetter(mCtx, unknownFprs);
+ pubkeyGetter.start();
+ if (!pubkeyGetter.result()) {
}
+ }
}
void UnknownSignersChecker::check_signer(gpgme_signature_t sign) {
-
- auto key = mCtx->getKeyByFpr(sign->fpr);
- if (!key.good) {
- qDebug() << "Find Unknown FingerPrint " << sign->fpr;
- unknownFprs.append(sign->fpr);
- }
-
+ auto key = mCtx->getKeyRefByFpr(sign->fpr);
+ if (!key.good) {
+ qDebug() << "Find Unknown FingerPrint " << sign->fpr;
+ unknownFprs.append(sign->fpr);
+ }
}
diff --git a/src/gpg/GpgSubKey.cpp b/src/advance/UnknownSignersChecker.h
index 4adda132..de07eaf8 100644
--- a/src/gpg/GpgSubKey.cpp
+++ b/src/advance/UnknownSignersChecker.h
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -21,31 +21,29 @@
* by Saturneric<[email protected]> starting on May 12, 2021.
*
*/
-#include "gpg/GpgSubKey.h"
-GpgSubKey::GpgSubKey(gpgme_subkey_t key) {
+#ifndef GPGFRONTEND_ZH_CN_TS_UNKNOWNSIGNERSCHECKER_H
+#define GPGFRONTEND_ZH_CN_TS_UNKNOWNSIGNERSCHECKER_H
- if (key == nullptr) return;
+#include "server/api/PubkeyGetter.h"
- id = key->keyid;
- pubkey_algo = gpgme_pubkey_algo_name(key->pubkey_algo);
- fpr = key->fpr;
+class UnknownSignersChecker : public QObject {
+ Q_OBJECT
+ public:
+ UnknownSignersChecker(GpgFrontend::GpgContext *ctx,
+ gpgme_verify_result_t result);
- expired = key->expired;
- revoked = key->revoked;
- secret = key->secret;
+ void start();
- disabled = key->disabled;
+ private:
+ QString appPath;
+ QSettings settings;
+ GpgFrontend::GpgContext *mCtx;
+ gpgme_verify_result_t mResult;
- length = key->length;
+ QVector<QString> unknownFprs;
- can_authenticate = key->can_authenticate;
- can_certify = key->can_certify;
- can_encrypt = key->can_encrypt;
- can_sign = key->can_sign;
- is_cardkey = key->is_cardkey;
- is_private_key = key->secret;
+ void check_signer(gpgme_signature_t sign);
+};
- timestamp = QDateTime::fromTime_t(key->timestamp);
- expires = QDateTime::fromTime_t(key->expires);
-}
+#endif // GPGFRONTEND_ZH_CN_TS_UNKNOWNSIGNERSCHECKER_H
diff --git a/src/gpg/CMakeLists.txt b/src/gpg/CMakeLists.txt
index 2bcacade..886f8fdc 100644
--- a/src/gpg/CMakeLists.txt
+++ b/src/gpg/CMakeLists.txt
@@ -1,28 +1,42 @@
aux_source_directory(./result_analyse GPG_SOURCE)
-aux_source_directory(./gpg_context GPG_SOURCE)
+aux_source_directory(./function GPG_SOURCE)
+aux_source_directory(./model GPG_SOURCE)
aux_source_directory(. GPG_SOURCE)
-add_library(gpg STATIC ${GPG_SOURCE})
+add_library(gpg_core STATIC ${GPG_SOURCE})
set(UTILS_DIR ${CMAKE_SOURCE_DIR}/utils)
set(GPGME_LIB_DIR ${UTILS_DIR}/gpgme/lib)
+if (ESAY_LOGGING_PP)
+ message(STATUS "Link ESAY_LOGGING_PP")
+ set(THIRD_PARTY_LIBS easy_logging_pp config++)
+endif ()
+
+set(BOOST_LIBS Boost::date_time Boost::filesystem)
+
+message(STATUS "Third Party Libraries " ${THIRD_PARTY_LIBS})
+
if (MINGW)
message(STATUS "Link GPG Static Library For MINGW")
- target_link_libraries(gpg
- gpgme gpg-error assuan
- Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core
- wsock32)
-elseif(APPLE)
+ target_link_libraries(gpg_core ${THIRD_PARTY_LIBS}
+ ${BOOST_LIBS}
+ gpgme gpg-error assuan wsock32)
+ target_compile_features(gpg_core PUBLIC cxx_std_17)
+elseif (APPLE)
+ find_library(libgpgme NAMES libgpgme.a)
+ find_library(libgpg-error NAMES libgpg-error.a)
+ find_library(libassuan NAMES libassuan.a)
message(STATUS "Link GPG Static Library For macOS")
- target_link_libraries(gpg
- /usr/local/lib/libgpgme.a /usr/local/lib/libgpg-error.a /usr/local/lib/libassuan.a
- Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core)
-else()
-
+ target_link_libraries(gpg_core ${THIRD_PARTY_LIBS}
+ ${BOOST_LIBS}
+ ${libgpgme} ${libgpg-error} ${libassuan}
+ dl)
+else ()
message(STATUS "Link GPG Static Library For Unix")
- target_link_libraries(gpg
- /usr/local/lib/libgpgme.a /usr/local/lib/libgpg-error.a /usr/local/lib/libassuan.a
- Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core)
-endif()
+ target_link_libraries(gpg_core ${THIRD_PARTY_LIBS}
+ libgpgme.a libgpg-error.a libassuan.a
+ ${BOOST_LIBS}
+ pthread dl)
+endif ()
diff --git a/src/gpg/GpgConstants.cpp b/src/gpg/GpgConstants.cpp
index 1d59dab5..5688287e 100644
--- a/src/gpg/GpgConstants.cpp
+++ b/src/gpg/GpgConstants.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,11 +24,156 @@
#include "gpg/GpgConstants.h"
-const char *GpgConstants::PGP_CRYPT_BEGIN = "-----BEGIN PGP MESSAGE-----";
-const char *GpgConstants::PGP_CRYPT_END = "-----END PGP MESSAGE-----";
-const char *GpgConstants::PGP_SIGNED_BEGIN = "-----BEGIN PGP SIGNED MESSAGE-----";
-const char *GpgConstants::PGP_SIGNED_END = "-----END PGP SIGNATURE-----";
-const char *GpgConstants::PGP_SIGNATURE_BEGIN = "-----BEGIN PGP SIGNATURE-----";
-const char *GpgConstants::PGP_SIGNATURE_END = "-----END PGP SIGNATURE-----";
-const char *GpgConstants::GPG_FRONTEND_SHORT_CRYPTO_HEAD = "GpgF_Scpt://";
+#include <gpg-error.h>
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/filesystem.hpp>
+
+const char* GpgFrontend::GpgConstants::PGP_CRYPT_BEGIN =
+ "-----BEGIN PGP MESSAGE-----";
+const char* GpgFrontend::GpgConstants::PGP_CRYPT_END =
+ "-----END PGP MESSAGE-----";
+const char* GpgFrontend::GpgConstants::PGP_SIGNED_BEGIN =
+ "-----BEGIN PGP SIGNED MESSAGE-----";
+const char* GpgFrontend::GpgConstants::PGP_SIGNED_END =
+ "-----END PGP SIGNATURE-----";
+const char* GpgFrontend::GpgConstants::PGP_SIGNATURE_BEGIN =
+ "-----BEGIN PGP SIGNATURE-----";
+const char* GpgFrontend::GpgConstants::PGP_SIGNATURE_END =
+ "-----END PGP SIGNATURE-----";
+const char* GpgFrontend::GpgConstants::GPG_FRONTEND_SHORT_CRYPTO_HEAD =
+ "GpgF_Scpt://";
+
+gpgme_error_t GpgFrontend::check_gpg_error(gpgme_error_t err) {
+ if (gpg_err_code(err) != GPG_ERR_NO_ERROR) {
+ LOG(ERROR) << "[Error " << gpg_err_code(err)
+ << "] Source: " << gpgme_strsource(err)
+ << " Description: " << gpgme_strerror(err);
+ }
+ return err;
+}
+
+gpg_err_code_t GpgFrontend::check_gpg_error_2_err_code(gpgme_error_t err,
+ gpgme_error_t predict) {
+ auto err_code = gpg_err_code(err);
+ if (err_code != predict) {
+ LOG(ERROR) << "[Error " << gpg_err_code(err)
+ << "] Source: " << gpgme_strsource(err)
+ << " Description: " << gpgme_strerror(err);
+ }
+ return err_code;
+}
+
+// error-handling
+gpgme_error_t GpgFrontend::check_gpg_error(gpgme_error_t err,
+ const std::string& comment) {
+ if (gpg_err_code(err) != GPG_ERR_NO_ERROR) {
+ LOG(ERROR) << "[Error " << gpg_err_code(err)
+ << "] Source: " << gpgme_strsource(err)
+ << " Description: " << gpgme_strerror(err) << " " << comment;
+ }
+ return err;
+}
+
+std::string GpgFrontend::beautify_fingerprint(
+ GpgFrontend::BypeArrayConstRef fingerprint) {
+ auto _fingerprint = fingerprint;
+ unsigned len = fingerprint.size();
+ if ((len > 0) && (len % 4 == 0))
+ for (unsigned n = 0; 4 * (n + 1) < len; ++n)
+ _fingerprint.insert(static_cast<int>(5u * n + 4u), " ");
+ return fingerprint;
+}
+
+// trim from start (in place)
+static inline void ltrim(std::string& s) {
+ s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) {
+ return !std::isspace(ch);
+ }));
+}
+
+// trim from end (in place)
+static inline void rtrim(std::string& s) {
+ s.erase(std::find_if(s.rbegin(), s.rend(),
+ [](unsigned char ch) { return !std::isspace(ch); })
+ .base(),
+ s.end());
+}
+
+// trim from both ends (in place)
+static inline std::string trim(std::string& s) {
+ ltrim(s);
+ rtrim(s);
+ return s;
+}
+
+std::string GpgFrontend::read_all_data_in_file(const std::string& path) {
+ using namespace boost::filesystem;
+ class path file_info(path.c_str());
+
+ if (!exists(file_info) || !is_regular_file(path))
+ throw std::runtime_error("no permission");
+
+ std::ifstream in_file;
+ in_file.open(path, std::ios::in);
+ if (!in_file.good()) throw std::runtime_error("cannot open file");
+ std::istreambuf_iterator<char> begin(in_file);
+ std::istreambuf_iterator<char> end;
+ std::string in_buffer(begin, end);
+ in_file.close();
+ return in_buffer;
+}
+
+bool GpgFrontend::write_buffer_to_file(const std::string& path,
+ const std::string& out_buffer) {
+ std::ofstream out_file(boost::filesystem::path(path).string(), std::ios::out);
+ if (!out_file.good()) return false;
+ out_file.write(out_buffer.c_str(), out_buffer.size());
+ out_file.close();
+ return true;
+}
+
+std::string GpgFrontend::get_file_extension(const std::string& path) {
+ // Create a Path object from given string
+ boost::filesystem::path path_obj(path);
+ // Check if file name in the path object has extension
+ if (path_obj.has_extension()) {
+ // Fetch the extension from path object and return
+ return path_obj.extension().string();
+ }
+ // In case of no extension return empty string
+ return {};
+}
+
+std::string GpgFrontend::get_only_file_name_with_path(const std::string& path) {
+ // Create a Path object from given string
+ boost::filesystem::path path_obj(path);
+ // Check if file name in the path object has extension
+ if (path_obj.has_filename()) {
+ // Fetch the extension from path object and return
+ return (path_obj.parent_path() / path_obj.stem()).string();
+ }
+ // In case of no extension return empty string
+ throw std::runtime_error("invalid file path");
+}
+
+/*
+ * isSigned returns:
+ * - 0, if text isn't signed at all
+ * - 1, if text is partially signed
+ * - 2, if text is completly signed
+ */
+int GpgFrontend::text_is_signed(GpgFrontend::BypeArrayRef text) {
+ using boost::algorithm::ends_with;
+ using boost::algorithm::starts_with;
+
+ auto trim_text = trim(text);
+ if (starts_with(trim_text, GpgConstants::PGP_SIGNED_BEGIN) &&
+ ends_with(trim_text, GpgConstants::PGP_SIGNED_END))
+ return 2;
+ else if (text.find(GpgConstants::PGP_SIGNED_BEGIN) != std::string::npos &&
+ text.find(GpgConstants::PGP_SIGNED_END) != std::string::npos)
+ return 1;
+ else
+ return 0;
+}
diff --git a/src/gpg/GpgConstants.h b/src/gpg/GpgConstants.h
new file mode 100644
index 00000000..1cd0f64d
--- /dev/null
+++ b/src/gpg/GpgConstants.h
@@ -0,0 +1,101 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPG_CONSTANTS_H
+#define GPG_CONSTANTS_H
+
+#include "GpgFrontend.h"
+
+#include <gpg-error.h>
+#include <gpgme.h>
+
+#include <cassert>
+#include <functional>
+#include <memory>
+#include <string>
+
+const int RESTART_CODE = 1000;
+
+namespace GpgFrontend {
+
+using ByteArray = std::string;
+using ByteArrayPtr = std::unique_ptr<ByteArray>;
+using StdBypeArrayPtr = std::unique_ptr<ByteArray>;
+using BypeArrayRef = ByteArray&;
+using BypeArrayConstRef = const ByteArray&;
+using StringArgsPtr = std::unique_ptr<std::vector<std::string>>;
+using StringArgsRef = std::vector<std::string>&;
+
+using GpgError = gpgme_error_t;
+
+// Result Deletor
+struct _result_ref_deletor {
+ void operator()(void* _result) {
+ // if (_result != nullptr)
+ // gpgme_result_unref(_result);
+ }
+};
+
+using GpgEncrResult =
+ std::unique_ptr<struct _gpgme_op_encrypt_result, _result_ref_deletor>;
+using GpgDecrResult =
+ std::unique_ptr<struct _gpgme_op_decrypt_result, _result_ref_deletor>;
+using GpgSignResult =
+ std::unique_ptr<struct _gpgme_op_sign_result, _result_ref_deletor>;
+using GpgVerifyResult =
+ std::unique_ptr<struct _gpgme_op_verify_result, _result_ref_deletor>;
+
+// Error Info Printer
+GpgError check_gpg_error(GpgError err);
+GpgError check_gpg_error(GpgError gpgmeError, const std::string& comment);
+gpg_err_code_t check_gpg_error_2_err_code(
+ gpgme_error_t err, gpgme_error_t predict = GPG_ERR_NO_ERROR);
+
+// Fingerprint
+std::string beautify_fingerprint(BypeArrayConstRef fingerprint);
+
+// File Operation
+std::string read_all_data_in_file(const std::string& path);
+bool write_buffer_to_file(const std::string& path,
+ const std::string& out_buffer);
+
+std::string get_file_extension(const std::string& path);
+std::string get_only_file_name_with_path(const std::string& path);
+
+// Check
+int text_is_signed(BypeArrayRef text);
+
+class GpgConstants {
+ public:
+ static const char* PGP_CRYPT_BEGIN;
+ static const char* PGP_CRYPT_END;
+ static const char* PGP_SIGNED_BEGIN;
+ static const char* PGP_SIGNED_END;
+ static const char* PGP_SIGNATURE_BEGIN;
+ static const char* PGP_SIGNATURE_END;
+ static const char* GPG_FRONTEND_SHORT_CRYPTO_HEAD;
+};
+} // namespace GpgFrontend
+
+#endif // GPG_CONSTANTS_H
diff --git a/src/gpg/GpgContext.cpp b/src/gpg/GpgContext.cpp
new file mode 100644
index 00000000..5d901c3f
--- /dev/null
+++ b/src/gpg/GpgContext.cpp
@@ -0,0 +1,127 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "gpg/GpgContext.h"
+
+#include <gpg-error.h>
+#include <gpgme.h>
+
+#include <functional>
+#include <string>
+
+#include "GpgConstants.h"
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#define INT2VOIDP(i) (void*)(uintptr_t)(i)
+
+namespace GpgFrontend {
+
+/**
+ * Constructor
+ * Set up gpgme-context, set paths to app-run path
+ */
+GpgContext::GpgContext(bool independent_database, std::string db_path,
+ int channel)
+ : SingletonFunctionObject<GpgContext>(channel) {
+ static bool _first = true;
+
+ if (_first) {
+ /* Initialize the locale environment. */
+ setlocale(LC_ALL, "");
+ gpgme_check_version(nullptr);
+ gpgme_set_locale(nullptr, LC_CTYPE, setlocale(LC_CTYPE, nullptr));
+#ifdef LC_MESSAGES
+ gpgme_set_locale(nullptr, LC_MESSAGES, setlocale(LC_MESSAGES, nullptr));
+#endif
+ _first = false;
+ }
+
+ gpgme_ctx_t _p_ctx;
+ check_gpg_error(gpgme_new(&_p_ctx));
+ _ctx_ref = CtxRefHandler(_p_ctx);
+
+ auto engineInfo = gpgme_ctx_get_engine_info(*this);
+
+ // Check ENV before running
+ bool check_pass = false, find_openpgp = false, find_gpgconf = false,
+ find_assuan = false, find_cms = false;
+ while (engineInfo != nullptr) {
+ if (engineInfo->protocol == GPGME_PROTOCOL_GPGCONF &&
+ strcmp(engineInfo->version, "1.0.0") != 0)
+ find_gpgconf = true;
+ if (engineInfo->protocol == GPGME_PROTOCOL_OpenPGP &&
+ strcmp(engineInfo->version, "1.0.0") != 0)
+ find_openpgp = true, info.AppPath = engineInfo->file_name,
+ info.DatabasePath = "default";
+ if (engineInfo->protocol == GPGME_PROTOCOL_CMS &&
+ strcmp(engineInfo->version, "1.0.0") != 0)
+ find_cms = true;
+ if (engineInfo->protocol == GPGME_PROTOCOL_ASSUAN) find_assuan = true;
+ engineInfo = engineInfo->next;
+ }
+
+ if (find_gpgconf && find_openpgp && find_cms && find_assuan)
+ check_pass = true;
+
+ if (!check_pass) {
+ good_ = false;
+ return;
+ } else {
+ // Set Independent Database
+ if (independent_database) {
+ info.DatabasePath = db_path;
+ auto err = gpgme_ctx_set_engine_info(
+ _ctx_ref.get(), GPGME_PROTOCOL_OpenPGP, info.AppPath.c_str(),
+ info.DatabasePath.c_str());
+ assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
+ }
+
+ /** Setting the output type must be done at the beginning */
+ /** think this means ascii-armor --> ? */
+ gpgme_set_armor(*this, 1);
+ // Speed up loading process
+ gpgme_set_offline(*this, 1);
+
+ check_gpg_error(gpgme_set_keylist_mode(
+ *this, GPGME_KEYLIST_MODE_LOCAL | GPGME_KEYLIST_MODE_WITH_SECRET |
+ GPGME_KEYLIST_MODE_SIGS | GPGME_KEYLIST_MODE_SIG_NOTATIONS |
+ GPGME_KEYLIST_MODE_WITH_TOFU));
+ good_ = true;
+ }
+}
+
+bool GpgContext::good() const { return good_; }
+
+void GpgContext::SetPassphraseCb(decltype(test_passphrase_cb) cb) const {
+ gpgme_set_passphrase_cb(*this, cb, nullptr);
+}
+
+std::string GpgContext::getGpgmeVersion() {
+ return {gpgme_check_version(nullptr)};
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/gpg/GpgContext.h b/src/gpg/GpgContext.h
new file mode 100644
index 00000000..5812f49f
--- /dev/null
+++ b/src/gpg/GpgContext.h
@@ -0,0 +1,95 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef __SGPGMEPP_CONTEXT_H__
+#define __SGPGMEPP_CONTEXT_H__
+
+#include "GpgConstants.h"
+#include "GpgFunctionObject.h"
+#include "GpgInfo.h"
+#include "GpgModel.h"
+
+namespace GpgFrontend {
+
+/**
+ * Custom Encapsulation of GpgME APIs
+ */
+class GpgContext : public SingletonFunctionObject<GpgContext> {
+ public:
+ explicit GpgContext(bool independent_database = false,
+ std::string path = std::string(), int channel = 0);
+
+ ~GpgContext() override = default;
+
+ [[nodiscard]] bool good() const;
+
+ [[nodiscard]] const GpgInfo& GetInfo() const { return info; }
+
+ static std::string getGpgmeVersion();
+
+ operator gpgme_ctx_t() const { return _ctx_ref.get(); }
+
+ private:
+ GpgInfo info;
+
+ struct _ctx_ref_deletor {
+ void operator()(gpgme_ctx_t _ctx) {
+ if (_ctx != nullptr) gpgme_release(_ctx);
+ }
+ };
+
+ using CtxRefHandler = std::unique_ptr<struct gpgme_context, _ctx_ref_deletor>;
+ CtxRefHandler _ctx_ref = nullptr;
+
+ bool good_ = true;
+
+ public:
+ static gpgme_error_t test_passphrase_cb(void* opaque, const char* uid_hint,
+ const char* passphrase_info,
+ int last_was_bad, int fd) {
+ LOG(INFO) << "test_passphrase_cb Called";
+ size_t res;
+ std::string pass = "abcdefg\n";
+ auto pass_len = pass.size();
+
+ size_t off = 0;
+
+ (void)opaque;
+ (void)uid_hint;
+ (void)passphrase_info;
+ (void)last_was_bad;
+
+ do {
+ res = gpgme_io_write(fd, &pass[off], pass_len - off);
+ if (res > 0) off += res;
+ } while (res > 0 && off != pass_len);
+
+ return off == pass_len ? 0 : gpgme_error_from_errno(errno);
+ }
+
+ void SetPassphraseCb(decltype(test_passphrase_cb) func) const;
+};
+} // namespace GpgFrontend
+
+#endif // __SGPGMEPP_CONTEXT_H__
diff --git a/src/gpg/GpgFileOpera.cpp b/src/gpg/GpgFileOpera.cpp
deleted file mode 100644
index af50c79a..00000000
--- a/src/gpg/GpgFileOpera.cpp
+++ /dev/null
@@ -1,249 +0,0 @@
-/**
- * This file is part of GPGFrontend.
- *
- * GPGFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Foobar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from gpg4usb-team.
- * Their source code version also complies with GNU General Public License.
- *
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]> starting on May 12, 2021.
- *
- */
-#include "gpg/GpgFileOpera.h"
-
-gpgme_error_t GpgFileOpera::encryptFile(GpgME::GpgContext *ctx, QVector<GpgKey> &keys, const QString &mPath,
- gpgme_encrypt_result_t *result) {
-
- QFileInfo fileInfo(mPath);
-
- if (!fileInfo.isFile() || !fileInfo.isReadable())
- throw std::runtime_error("no permission");
-
- QFile infile;
- infile.setFileName(mPath);
- if (!infile.open(QIODevice::ReadOnly))
- throw std::runtime_error("cannot open file");
-
- QByteArray inBuffer = infile.readAll();
- auto outBuffer = QByteArray();
- infile.close();
-
- auto error = ctx->encrypt(keys, inBuffer, &outBuffer, result);
-
- if (gpg_err_code(error) != GPG_ERR_NO_ERROR) return error;
-
- QFile outfile(mPath + ".asc");
-
- if (!outfile.open(QFile::WriteOnly))
- throw std::runtime_error("cannot open file");
-
- QDataStream out(&outfile);
- out.writeRawData(outBuffer.data(), outBuffer.length());
- outfile.close();
- return error;
-}
-
-gpgme_error_t GpgFileOpera::decryptFile(GpgME::GpgContext *ctx, const QString &mPath, gpgme_decrypt_result_t *result) {
-
- QFileInfo fileInfo(mPath);
-
- if (!fileInfo.isFile() || !fileInfo.isReadable())
- throw std::runtime_error("no permission");
-
- QFile infile;
- infile.setFileName(mPath);
- if (!infile.open(QIODevice::ReadOnly))
- throw std::runtime_error("cannot open file");
-
- QByteArray inBuffer = infile.readAll();
- auto outBuffer = QByteArray();
- infile.close();
-
- auto error = ctx->decrypt(inBuffer, &outBuffer, result);
-
- if (gpgme_err_code(error) != GPG_ERR_NO_ERROR) return error;
-
- QString outFileName, fileExtension = fileInfo.suffix();
-
- if (fileExtension == "asc" || fileExtension == "gpg") {
- int pos = mPath.lastIndexOf(QChar('.'));
- outFileName = mPath.left(pos);
- } else {
- outFileName = mPath + ".out";
- }
-
- QFile outfile(outFileName);
-
- if (!outfile.open(QFile::WriteOnly))
- throw std::runtime_error("cannot open file");
-
- QDataStream out(&outfile);
- out.writeRawData(outBuffer.data(), outBuffer.length());
- outfile.close();
-
- return error;
-}
-
-gpgme_error_t GpgFileOpera::signFile(GpgME::GpgContext *ctx, QVector<GpgKey> &keys, const QString &mPath,
- gpgme_sign_result_t *result) {
-
- QFileInfo fileInfo(mPath);
-
- if (!fileInfo.isFile() || !fileInfo.isReadable())
- throw std::runtime_error("no permission");
-
- QFile infile;
- infile.setFileName(mPath);
- if (!infile.open(QIODevice::ReadOnly))
- throw std::runtime_error("cannot open file");
-
-
- QByteArray inBuffer = infile.readAll();
- auto outBuffer = QByteArray();
- infile.close();
-
- auto error = ctx->sign(keys, inBuffer, &outBuffer, GPGME_SIG_MODE_DETACH, result);
-
- if (gpg_err_code(error) != GPG_ERR_NO_ERROR) return error;
-
- QFile outfile(mPath + ".sig");
-
- if (!outfile.open(QFile::WriteOnly))
- throw std::runtime_error("cannot open file");
-
- QDataStream out(&outfile);
- out.writeRawData(outBuffer.data(), outBuffer.length());
- outfile.close();
-
- return error;
-}
-
-gpgme_error_t GpgFileOpera::verifyFile(GpgME::GpgContext *ctx, const QString &mPath, gpgme_verify_result_t *result) {
-
- qDebug() << "Verify File Path" << mPath;
-
- QFileInfo fileInfo(mPath);
-
- if (!fileInfo.isFile() || !fileInfo.isReadable())
- throw std::runtime_error("no permission");
-
- QFile infile;
- infile.setFileName(mPath);
- if (!infile.open(QIODevice::ReadOnly))
- throw std::runtime_error("cannot open file");
-
- QByteArray inBuffer = infile.readAll();
-
- if(fileInfo.suffix() == "gpg") {
- auto error = ctx->verify(&inBuffer, nullptr, result);
- return error;
- }
- else {
- QFile signFile;
- signFile.setFileName(mPath + ".sig");
- if (!signFile.open(QIODevice::ReadOnly)) {
- throw std::runtime_error("cannot open file");
- }
-
- auto signBuffer = signFile.readAll();
- infile.close();
-
- auto error = ctx->verify(&inBuffer, &signBuffer, result);
- return error;
- }
-}
-
-gpg_error_t GpgFileOpera::encryptSignFile(GpgME::GpgContext *ctx, QVector<GpgKey> &keys, const QString &mPath,
- gpgme_encrypt_result_t *encr_res,
- gpgme_sign_result_t *sign_res) {
-
- qDebug() << "Encrypt Sign File Path" << mPath;
-
- QFileInfo fileInfo(mPath);
-
- if (!fileInfo.isFile() || !fileInfo.isReadable())
- throw std::runtime_error("no permission");
-
- QFile infile;
- infile.setFileName(mPath);
- if (!infile.open(QIODevice::ReadOnly))
- throw std::runtime_error("cannot open file");
-
- QByteArray inBuffer = infile.readAll();
- auto outBuffer = QByteArray();
- infile.close();
-
- QVector<GpgKey> signerKeys;
-
- // TODO dealing with signer keys
- auto error = ctx->encryptSign(keys, signerKeys, inBuffer, &outBuffer, encr_res, sign_res);
-
- if (gpg_err_code(error) != GPG_ERR_NO_ERROR)
- return error;
-
- QFile outfile(mPath + ".gpg");
-
- if (!outfile.open(QFile::WriteOnly))
- throw std::runtime_error("cannot open file");
-
- QDataStream out(&outfile);
- out.writeRawData(outBuffer.data(), outBuffer.length());
- outfile.close();
-
- return error;
-}
-
-gpg_error_t GpgFileOpera::decryptVerifyFile(GpgME::GpgContext *ctx, const QString &mPath, gpgme_decrypt_result_t *decr_res,
- gpgme_verify_result_t *verify_res) {
-
- qDebug() << "Decrypt Verify File Path" << mPath;
-
- QFileInfo fileInfo(mPath);
-
- if (!fileInfo.isFile() || !fileInfo.isReadable())
- throw std::runtime_error("no permission");
-
- QFile infile;
- infile.setFileName(mPath);
- if (!infile.open(QIODevice::ReadOnly))
- throw std::runtime_error("cannot open file");
-
- QByteArray inBuffer = infile.readAll();
- auto outBuffer = QByteArray();
- infile.close();
-
- auto error = ctx->decryptVerify(inBuffer, &outBuffer, decr_res, verify_res);
- if (gpg_err_code(error) != GPG_ERR_NO_ERROR) return error;
-
- QString outFileName, fileExtension = fileInfo.suffix();
-
- if (fileExtension == "asc" || fileExtension == "gpg") {
- int pos = mPath.lastIndexOf(QChar('.'));
- outFileName = mPath.left(pos);
- } else {
- outFileName = mPath + ".out";
- }
-
- QFile outfile(outFileName);
-
- if (!outfile.open(QFile::WriteOnly))
- throw std::runtime_error("cannot open file");
-
- QDataStream out(&outfile);
- out.writeRawData(outBuffer.data(), outBuffer.length());
- outfile.close();
-
- return error;
-}
diff --git a/src/gpg/GpgFunctionObject.h b/src/gpg/GpgFunctionObject.h
new file mode 100644
index 00000000..6f1d60af
--- /dev/null
+++ b/src/gpg/GpgFunctionObject.h
@@ -0,0 +1,138 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H
+#define GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H
+
+#include <easyloggingpp/easylogging++.h>
+
+#include <map>
+#include <memory>
+#include <mutex>
+#include <shared_mutex>
+#include <stdexcept>
+#include <string>
+
+namespace GpgFrontend {
+
+template <typename T>
+class SingletonFunctionObject {
+ public:
+ static T& GetInstance(int channel = 0) {
+ if (!channel) {
+ std::lock_guard<std::mutex> guard(_instance_mutex);
+ if (_instance == nullptr) _instance = std::make_unique<T>();
+ return *_instance;
+ } else {
+ // read _instances_map
+ decltype(_instances_map.end()) _it;
+ {
+ std::shared_lock lock(_instances_mutex);
+ _it = _instances_map.find(channel);
+ }
+ if (_it != _instances_map.end())
+ return *_it->second;
+ else
+ return CreateInstance(channel);
+ }
+ }
+
+ static T& CreateInstance(int channel, std::unique_ptr<T> p_obj = nullptr) {
+ if (!channel) return *_instance;
+
+ // read _instances_map
+ decltype(_instances_map.end()) _it;
+ {
+ std::shared_lock lock(_instances_mutex);
+ _it = _instances_map.find(channel);
+ }
+ if (_it == _instances_map.end()) {
+ {
+ std::lock_guard<std::mutex> guard(_default_channel_mutex);
+ int tmp = channel;
+ std::swap(_default_channel, tmp);
+ if (p_obj == nullptr) p_obj = std::make_unique<T>();
+ std::swap(_default_channel, tmp);
+ }
+ T* obj = p_obj.get();
+
+ // change _instances_map
+ {
+ std::unique_lock lock(_instances_mutex);
+ _instances_map.insert({channel, std::move(p_obj)});
+ }
+ return *obj;
+ } else {
+ return *_it->second;
+ }
+ }
+
+ static int GetDefaultChannel() { return _default_channel; }
+
+ int GetChannel() const { return channel_; }
+
+ SingletonFunctionObject(T&&) = delete;
+
+ SingletonFunctionObject(const T&) = delete;
+
+ void operator=(const T&) = delete;
+
+ protected:
+ SingletonFunctionObject() {}
+
+ SingletonFunctionObject(int channel) : channel_(channel) {}
+
+ virtual ~SingletonFunctionObject() = default;
+
+ private:
+ int channel_ = _default_channel;
+ static int _default_channel;
+ static std::mutex _default_channel_mutex;
+ static std::mutex _instance_mutex;
+ static std::shared_mutex _instances_mutex;
+ static std::unique_ptr<T> _instance;
+ static std::map<int, std::unique_ptr<T>> _instances_map;
+};
+
+template <typename T>
+int SingletonFunctionObject<T>::_default_channel = 0;
+
+template <typename T>
+std::mutex SingletonFunctionObject<T>::_default_channel_mutex;
+
+template <typename T>
+std::mutex SingletonFunctionObject<T>::_instance_mutex;
+
+template <typename T>
+std::shared_mutex SingletonFunctionObject<T>::_instances_mutex;
+
+template <typename T>
+std::unique_ptr<T> SingletonFunctionObject<T>::_instance = nullptr;
+
+template <typename T>
+std::map<int, std::unique_ptr<T>> SingletonFunctionObject<T>::_instances_map;
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H
diff --git a/src/gpg/GpgGenKeyInfo.cpp b/src/gpg/GpgGenKeyInfo.cpp
index 69da27e3..07708433 100644
--- a/src/gpg/GpgGenKeyInfo.cpp
+++ b/src/gpg/GpgGenKeyInfo.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,149 +24,149 @@
#include "gpg/GpgGenKeyInfo.h"
-const QVector<QString> GenKeyInfo::SupportedKeyAlgo = {
- "RSA",
- "DSA",
- "ED25519"
-};
-
-const QVector<QString> GenKeyInfo::SupportedSubkeyAlgo = {
- "RSA",
- "DSA",
- "ED25519",
- "ELG"
-};
-
-void GenKeyInfo::setAlgo(const QString &m_algo) {
-
- qDebug() << "set algo " << m_algo;
-
- reset_options();
-
- if (!this->subKey) {
- this->setAllowCertification(true);
- } else {
- this->setAllowCertification(false);
- }
-
- this->allowChangeCertification = false;
-
- auto lower_algo = m_algo.toLower();
-
- if(lower_algo == "rsa") {
- /**
- * RSA is the world’s premier asymmetric cryptographic algorithm,
- * and is built on the difficulty of factoring extremely large composites.
- * GnuPG supports RSA with key sizes of between 1024 and 4096 bits.
- */
- suggestMinKeySize = 1024;
- suggestMaxKeySize = 4096;
- suggestSizeAdditionStep = 1024;
- setKeySize(2048);
-
- } else if (lower_algo == "dsa") {
- /**
- * Algorithm (DSA) as a government standard for digital signatures.
- * Originally, it supported key lengths between 512 and 1024 bits.
- * Recently, NIST has declared 512-bit keys obsolete:
- * now, DSA is available in 1024, 2048 and 3072-bit lengths.
- */
- setAllowEncryption(false);
- allowChangeEncryption = false;
-
- suggestMinKeySize = 1024;
- suggestMaxKeySize = 3072;
- suggestSizeAdditionStep = 1024;
- setKeySize(2048);
-
- } else if (lower_algo == "ed25519") {
- /**
- * GnuPG supports the Elgamal asymmetric encryption algorithm in key lengths ranging from 1024 to 4096 bits.
- */
-
- setAllowEncryption(false);
- allowChangeEncryption = false;
-
- suggestMinKeySize = -1;
- suggestMaxKeySize = -1;
- suggestSizeAdditionStep = -1;
- setKeySize(-1);
- } else if (lower_algo == "elg") {
- /**
- * GnuPG supports the Elgamal asymmetric encryption algorithm in key lengths ranging from 1024 to 4096 bits.
- */
-
- setAllowAuthentication(false);
- allowChangeAuthentication = false;
-
- setAllowSigning(false);
- allowChangeSigning = false;
-
- suggestMinKeySize = 1024;
- suggestMaxKeySize = 4096;
- suggestSizeAdditionStep = 1024;
- setKeySize(2048);
- }
- GenKeyInfo::algo = lower_algo;
+#include <easyloggingpp/easylogging++.h>
+
+#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 <string>
+#include <vector>
+
+const std::vector<std::string> GpgFrontend::GenKeyInfo::SupportedKeyAlgo = {
+ "RSA", "DSA", "ED25519"};
+
+const std::vector<std::string> GpgFrontend::GenKeyInfo::SupportedSubkeyAlgo = {
+ "RSA", "DSA", "ED25519", "ELG"};
+
+void GpgFrontend::GenKeyInfo::setAlgo(const std::string &m_algo) {
+ LOG(INFO) << "GpgFrontend::GenKeyInfo::setAlgo m_algo" << m_algo;
+
+ reset_options();
+
+ if (!this->subKey) {
+ this->setAllowCertification(true);
+ } else {
+ this->setAllowCertification(false);
+ }
+
+ this->allowChangeCertification = false;
+
+ std::string lower_algo = std::string(m_algo);
+ boost::algorithm::to_lower(lower_algo);
+
+ LOG(INFO) << "GpgFrontend::GenKeyInfo::setAlgo lower_algo" << lower_algo;
+
+ if (lower_algo == "rsa") {
+ /**
+ * RSA is the world’s premier asymmetric cryptographic algorithm,
+ * and is built on the difficulty of factoring extremely large composites.
+ * GnuPG supports RSA with key sizes of between 1024 and 4096 bits.
+ */
+ suggestMinKeySize = 1024;
+ suggestMaxKeySize = 4096;
+ suggestSizeAdditionStep = 1024;
+ setKeySize(2048);
+
+ } else if (lower_algo == "dsa") {
+ /**
+ * Algorithm (DSA) as a government standard for digital signatures.
+ * Originally, it supported key lengths between 512 and 1024 bits.
+ * Recently, NIST has declared 512-bit keys obsolete:
+ * now, DSA is available in 1024, 2048 and 3072-bit lengths.
+ */
+ setAllowEncryption(false);
+ allowChangeEncryption = false;
+
+ suggestMinKeySize = 1024;
+ suggestMaxKeySize = 3072;
+ suggestSizeAdditionStep = 1024;
+ setKeySize(2048);
+
+ } else if (lower_algo == "ed25519") {
+ /**
+ * GnuPG supports the Elgamal asymmetric encryption algorithm in key lengths
+ * ranging from 1024 to 4096 bits.
+ */
+
+ setAllowEncryption(false);
+ allowChangeEncryption = false;
+
+ suggestMinKeySize = -1;
+ suggestMaxKeySize = -1;
+ suggestSizeAdditionStep = -1;
+ setKeySize(-1);
+ } else if (lower_algo == "elg") {
+ /**
+ * GnuPG supports the Elgamal asymmetric encryption algorithm in key lengths
+ * ranging from 1024 to 4096 bits.
+ */
+
+ setAllowAuthentication(false);
+ allowChangeAuthentication = false;
+
+ setAllowSigning(false);
+ allowChangeSigning = false;
+
+ suggestMinKeySize = 1024;
+ suggestMaxKeySize = 4096;
+ suggestSizeAdditionStep = 1024;
+ setKeySize(2048);
+ }
+ this->algo = lower_algo;
}
-void GenKeyInfo::reset_options() {
+void GpgFrontend::GenKeyInfo::reset_options() {
+ allowChangeEncryption = true;
+ setAllowEncryption(true);
- allowChangeEncryption = true;
- setAllowEncryption(true);
+ allowChangeCertification = true;
+ setAllowCertification(true);
- allowChangeCertification = true;
- setAllowCertification(true);
+ allowChangeSigning = true;
+ setAllowSigning(true);
- allowChangeSigning = true;
- setAllowSigning(true);
-
- allowChangeAuthentication = true;
- setAllowAuthentication(true);
-
-
- passPhrase.clear();
+ allowChangeAuthentication = true;
+ setAllowAuthentication(true);
+ passPhrase.clear();
}
-QString GenKeyInfo::getKeySizeStr() const {
- if(keySize > 0) {
- return QString::number(keySize);
- }
- else {
- return QString();
- }
-
+std::string GpgFrontend::GenKeyInfo::getKeySizeStr() const {
+ if (keySize > 0) {
+ return std::to_string(keySize);
+ } else {
+ return {};
+ }
}
-void GenKeyInfo::setKeySize(int m_key_size) {
- if (m_key_size < suggestMinKeySize || m_key_size > suggestMaxKeySize) {
- return;
- }
- GenKeyInfo::keySize = m_key_size;
+void GpgFrontend::GenKeyInfo::setKeySize(int m_key_size) {
+ if (m_key_size < suggestMinKeySize || m_key_size > suggestMaxKeySize) {
+ return;
+ }
+ GenKeyInfo::keySize = m_key_size;
}
-void GenKeyInfo::setExpired(const QDateTime &m_expired) {
- auto current = QDateTime::currentDateTime();
- if (isNonExpired() && m_expired < current.addYears(2)) {
- GenKeyInfo::expired = m_expired;
- }
+void GpgFrontend::GenKeyInfo::setExpired(
+ const boost::gregorian::date &m_expired) {
+ using namespace boost::gregorian;
+ auto current = day_clock::local_day();
+ if (isNonExpired() && m_expired < current + years(2)) {
+ GenKeyInfo::expired = m_expired;
+ }
}
-void GenKeyInfo::setNonExpired(bool m_non_expired) {
- if (!m_non_expired) {
- this->expired = QDateTime(QDateTime::fromTime_t(0));
- }
- GenKeyInfo::nonExpired = m_non_expired;
+void GpgFrontend::GenKeyInfo::setNonExpired(bool m_non_expired) {
+ using namespace boost::posix_time;
+ if (!m_non_expired) this->expired = from_time_t(0).date();
+ GenKeyInfo::nonExpired = m_non_expired;
}
-void GenKeyInfo::setAllowEncryption(bool m_allow_encryption) {
- if(allowChangeEncryption)
- GenKeyInfo::allowEncryption = m_allow_encryption;
+void GpgFrontend::GenKeyInfo::setAllowEncryption(bool m_allow_encryption) {
+ if (allowChangeEncryption) GenKeyInfo::allowEncryption = m_allow_encryption;
}
-void GenKeyInfo::setAllowCertification(bool m_allow_certification) {
- if(allowChangeCertification)
- GenKeyInfo::allowCertification = m_allow_certification;
+void GpgFrontend::GenKeyInfo::setAllowCertification(
+ bool m_allow_certification) {
+ if (allowChangeCertification)
+ GenKeyInfo::allowCertification = m_allow_certification;
}
-
diff --git a/src/gpg/GpgGenKeyInfo.h b/src/gpg/GpgGenKeyInfo.h
new file mode 100644
index 00000000..53b0c9f1
--- /dev/null
+++ b/src/gpg/GpgGenKeyInfo.h
@@ -0,0 +1,167 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_GPGGENKEYINFO_H
+#define GPGFRONTEND_GPGGENKEYINFO_H
+
+#include <boost/date_time.hpp>
+#include <boost/date_time/gregorian/greg_duration_types.hpp>
+#include <string>
+#include <vector>
+
+namespace GpgFrontend {
+
+class GenKeyInfo {
+ bool subKey = true;
+ std::string userid;
+ std::string algo;
+ int keySize = 2048;
+ boost::gregorian::date expired =
+ boost::gregorian::day_clock::local_day() + boost::gregorian::years(2);
+ bool nonExpired = false;
+
+ bool noPassPhrase = false;
+ bool allowNoPassPhrase = true;
+
+ int suggestMaxKeySize = 4096;
+ int suggestSizeAdditionStep = 1024;
+ int suggestMinKeySize = 1024;
+
+ std::string passPhrase;
+
+ public:
+ static const std::vector<std::string> SupportedKeyAlgo;
+
+ static const std::vector<std::string> SupportedSubkeyAlgo;
+
+ [[nodiscard]] bool isSubKey() const { return subKey; }
+
+ void setIsSubKey(bool m_sub_key) { GenKeyInfo::subKey = m_sub_key; }
+
+ [[nodiscard]] const std::string &getUserid() const { return userid; }
+
+ void setUserid(const std::string &m_userid) { GenKeyInfo::userid = m_userid; }
+
+ [[nodiscard]] const std::string &getAlgo() const { return algo; }
+
+ void setAlgo(const std::string &m_algo);
+
+ [[nodiscard]] std::string getKeySizeStr() const;
+
+ [[nodiscard]] int getKeySize() const { return keySize; }
+
+ void setKeySize(int m_key_size);
+
+ [[nodiscard]] const boost::gregorian::date &getExpired() const {
+ return expired;
+ }
+
+ void setExpired(const boost::gregorian::date &m_expired);
+
+ [[nodiscard]] bool isNonExpired() const { return nonExpired; }
+
+ void setNonExpired(bool m_non_expired);
+
+ [[nodiscard]] bool isNoPassPhrase() const { return this->noPassPhrase; }
+
+ void setNonPassPhrase(bool m_non_pass_phrase) {
+ GenKeyInfo::noPassPhrase = m_non_pass_phrase;
+ }
+
+ [[nodiscard]] bool isAllowSigning() const { return allowSigning; }
+
+ [[nodiscard]] bool isAllowNoPassPhrase() const { return allowNoPassPhrase; }
+
+ void setAllowSigning(bool m_allow_signing) {
+ if (allowChangeSigning) GenKeyInfo::allowSigning = m_allow_signing;
+ }
+
+ [[nodiscard]] bool isAllowEncryption() const { return allowEncryption; }
+
+ void setAllowEncryption(bool m_allow_encryption);
+
+ [[nodiscard]] bool isAllowCertification() const { return allowCertification; }
+
+ void setAllowCertification(bool m_allow_certification);
+
+ [[nodiscard]] bool isAllowAuthentication() const {
+ return allowAuthentication;
+ }
+
+ void setAllowAuthentication(bool m_allow_authentication) {
+ if (allowChangeAuthentication)
+ GenKeyInfo::allowAuthentication = m_allow_authentication;
+ }
+
+ [[nodiscard]] const std::string &getPassPhrase() const { return passPhrase; }
+
+ void setPassPhrase(const std::string &m_pass_phrase) {
+ GenKeyInfo::passPhrase = m_pass_phrase;
+ }
+
+ [[nodiscard]] bool isAllowChangeSigning() const { return allowChangeSigning; }
+ [[nodiscard]] bool isAllowChangeEncryption() const {
+ return allowChangeEncryption;
+ }
+
+ [[nodiscard]] bool isAllowChangeCertification() const {
+ return allowChangeCertification;
+ }
+
+ [[nodiscard]] bool isAllowChangeAuthentication() const {
+ return allowChangeAuthentication;
+ }
+
+ [[nodiscard]] int getSuggestMaxKeySize() const { return suggestMaxKeySize; }
+
+ [[nodiscard]] int getSuggestMinKeySize() const { return suggestMinKeySize; }
+
+ [[nodiscard]] int getSizeChangeStep() const {
+ return suggestSizeAdditionStep;
+ }
+
+ private:
+ bool allowEncryption = true;
+ bool allowChangeEncryption = true;
+
+ bool allowCertification = true;
+ bool allowChangeCertification = true;
+
+ bool allowAuthentication = true;
+ bool allowChangeAuthentication = true;
+
+ bool allowSigning = true;
+ bool allowChangeSigning = true;
+
+ void reset_options();
+
+ public:
+ explicit GenKeyInfo(bool m_is_sub_key = false) : subKey(m_is_sub_key) {
+ setAlgo("rsa");
+ }
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_GPGGENKEYINFO_H
diff --git a/src/gpg/GpgInfo.cpp b/src/gpg/GpgInfo.cpp
index 00a15ef9..392dcf08 100644
--- a/src/gpg/GpgInfo.cpp
+++ b/src/gpg/GpgInfo.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
diff --git a/src/gpg/GpgUID.cpp b/src/gpg/GpgInfo.h
index 0dc6abfd..27e13112 100644
--- a/src/gpg/GpgUID.cpp
+++ b/src/gpg/GpgInfo.h
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -22,17 +22,22 @@
*
*/
-#include "gpg/GpgUID.h"
+#ifndef GPGFRONTEND_ZH_CN_TS_GPGINFO_H
+#define GPGFRONTEND_ZH_CN_TS_GPGINFO_H
-GpgUID::GpgUID(gpgme_user_id_t user_id) :
- uid(user_id->uid), name(user_id->name), email(user_id->email), comment(user_id->comment),
- revoked(user_id->revoked), invalid(user_id->invalid) {
+#include <string>
- auto sig = user_id->signatures;
+/**
+ * Use to record some info about gnupg
+ */
+class GpgInfo {
+ public:
+ /**
+ * executable binary path of gnupg
+ */
+ std::string AppPath;
- while (sig != nullptr) {
- signatures.push_back(GpgKeySignature(sig));
- sig = sig->next;
- }
+ std::string DatabasePath;
+};
-} \ No newline at end of file
+#endif // GPGFRONTEND_ZH_CN_TS_GPGINFO_H
diff --git a/src/gpg/GpgKey.cpp b/src/gpg/GpgKey.cpp
deleted file mode 100644
index cd62fc5d..00000000
--- a/src/gpg/GpgKey.cpp
+++ /dev/null
@@ -1,274 +0,0 @@
-/**
- * This file is part of GPGFrontend.
- *
- * GPGFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Foobar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from gpg4usb-team.
- * Their source code version also complies with GNU General Public License.
- *
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]> starting on May 12, 2021.
- *
- */
-
-#include "gpg/GpgKey.h"
-
-void GpgKey::parse(gpgme_key_t key) {
-
- if(key == nullptr) return;
-
- good = true;
- key_refer = key;
- gpgme_key_ref(key_refer);
-
- is_private_key = key->secret;
- fpr = key->fpr;
- protocol = key->protocol;
- expired = (key->expired != 0u);
- revoked = (key->revoked != 0u);
-
- disabled = key->disabled;
-
- can_authenticate = key->can_authenticate;
- can_certify = key->can_certify;
- can_encrypt = key->can_encrypt;
- can_sign = key->can_sign;
-
- last_update = QDateTime(QDateTime::fromTime_t(key->last_update));
-
- switch (key->owner_trust) {
- case GPGME_VALIDITY_UNKNOWN:
- owner_trust = "Unknown";
- break;
- case GPGME_VALIDITY_UNDEFINED:
- owner_trust = "Undefined";
- break;
- case GPGME_VALIDITY_NEVER:
- owner_trust = "Never";
- break;
- case GPGME_VALIDITY_MARGINAL:
- owner_trust = "Marginal";
- break;
- case GPGME_VALIDITY_FULL:
- owner_trust = "FULL";
- break;
- case GPGME_VALIDITY_ULTIMATE:
- owner_trust = "Ultimate";
- break;
- }
-
- uids.clear();
- auto uid = key->uids;
-
- while (uid != nullptr) {
- uids.push_back(GpgUID(uid));
- uid = uid->next;
- }
-
- if (!uids.isEmpty()) {
- name = uids.first().name;
- email = uids.first().email;
- comment = uids.first().comment;
- }
-
- subKeys.clear();
- auto next = key->subkeys;
-
- while (next != nullptr) {
- subKeys.push_back(GpgSubKey(next));
- next = next->next;
- }
-
- if (!subKeys.isEmpty()) {
- id = subKeys.first().id;
- expires = subKeys.first().expires;
- pubkey_algo = subKeys.first().pubkey_algo;
- create_time = subKeys.first().timestamp;
- length = subKeys.first().length;
- has_master_key = subKeys.first().secret;
- } else {
- id = "";
- }
-
-}
-
-GpgKey::GpgKey(GpgKey &&k) noexcept {
-
- id = std::move(k.id);
- name = std::move(k.name);
- email = std::move(k.email);
- comment = std::move(k.comment);
- fpr = std::move(k.fpr);
- protocol = std::move(k.protocol);
- owner_trust = std::move(k.owner_trust);
- pubkey_algo = std::move(k.pubkey_algo);
- last_update = std::move(k.last_update);
- expires = std::move(k.expires);
- create_time = std::move(k.create_time);
-
- length = k.length;
- k.length = 0;
-
- can_encrypt = k.can_encrypt;
- can_sign = k.can_sign;
- can_certify = k.can_certify;
- can_authenticate = k.can_authenticate;
-
-
- is_private_key = k.is_private_key;
- expired = k.expired;
- revoked = k.revoked;
- disabled = k.disabled;
- k.has_master_key = k.has_master_key;
-
- good = k.good;
- k.good = false;
-
- subKeys = std::move(k.subKeys);
- uids = std::move(k.uids);
-
- key_refer = k.key_refer;
- k.key_refer = nullptr;
-
-}
-
-GpgKey &GpgKey::operator=(const GpgKey &k) {
-
- id = k.id;
- name = k.name;
- email = k.email;
- comment = k.comment;
- fpr = k.fpr;
- protocol = k.protocol;
- owner_trust = k.owner_trust;
- pubkey_algo = k.pubkey_algo;
- last_update = k.last_update;
- expires = k.expires;
- create_time = k.create_time;
-
- length = k.length;
-
- can_encrypt = k.can_encrypt;
- can_sign = k.can_sign;
- can_certify = k.can_certify;
- can_authenticate = k.can_authenticate;
-
- is_private_key = k.is_private_key;
- expired = k.expired;
- revoked = k.revoked;
- disabled = k.disabled;
-
- has_master_key = k.has_master_key;
-
- good = k.good;
-
- subKeys = k.subKeys;
- uids = k.uids;
-
- key_refer = k.key_refer;
- gpgme_key_ref(key_refer);
-
- return *this;
-}
-
-GpgKey::GpgKey(const GpgKey &k) :
- id(k.id), name(k.name), email(k.email), comment(k.comment),
- fpr(k.fpr), protocol(k.protocol), owner_trust(k.owner_trust),
- pubkey_algo(k.pubkey_algo), last_update(k.last_update),
- expires(k.expires), create_time(k.create_time){
-
- length = k.length;
-
- can_encrypt = k.can_encrypt;
- can_sign = k.can_sign;
- can_certify = k.can_certify;
- can_authenticate = k.can_authenticate;
-
- is_private_key = k.is_private_key;
- expired = k.expired;
- revoked = k.revoked;
- disabled = k.disabled;
-
- has_master_key = k.has_master_key;
-
- good = k.good;
-
- subKeys = k.subKeys;
- uids = k.uids;
-
- key_refer = k.key_refer;
- gpgme_key_ref(key_refer);
-
-}
-
-GpgKey &GpgKey::operator=(GpgKey &&k) noexcept {
-
- id = std::move(k.id);
- name = std::move(k.name);
- email = std::move(k.email);
- comment = std::move(k.comment);
- fpr = std::move(k.fpr);
- protocol = std::move(k.protocol);
- owner_trust = std::move(k.owner_trust);
- pubkey_algo = std::move(k.pubkey_algo);
- last_update = std::move(k.last_update);
- expires = std::move(k.expires);
- create_time = std::move(k.create_time);
-
- length = k.length;
- k.length = 0;
-
- can_encrypt = k.can_encrypt;
- can_sign = k.can_sign;
- can_certify = k.can_certify;
- can_authenticate = k.can_authenticate;
-
-
- is_private_key = k.is_private_key;
- expired = k.expired;
- revoked = k.revoked;
- disabled = k.disabled;
-
- has_master_key = k.has_master_key;
-
- good = k.good;
- k.good = false;
-
- subKeys = std::move(k.subKeys);
- uids = std::move(k.uids);
-
- key_refer = k.key_refer;
- k.key_refer = nullptr;
-
- return *this;
-}
-
-GpgKey::~GpgKey() {
- if(key_refer != nullptr && good) {
- gpgme_key_unref(key_refer);
- }
-}
-
-GpgKey::GpgKey(gpgme_key_t key) {
- parse(key);
-}
-
-void GpgKey::swapKeyRefer(gpgme_key_t key) {
-
- if(key == nullptr) return;
-
- gpgme_key_unref(key_refer);
- key_refer = nullptr;
- parse(key);
-}
diff --git a/src/gpg/GpgModel.h b/src/gpg/GpgModel.h
new file mode 100644
index 00000000..3e07427c
--- /dev/null
+++ b/src/gpg/GpgModel.h
@@ -0,0 +1,71 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_ZH_CN_TS_GPGMODEL_H
+#define GPGFRONTEND_ZH_CN_TS_GPGMODEL_H
+
+#include "GpgConstants.h"
+
+#include <list>
+#include <utility>
+
+#include "gpg/model/GpgData.h"
+#include "gpg/model/GpgKey.h"
+
+namespace GpgFrontend {
+
+using KeyId = std::string;
+
+using SubkeyId = std::string;
+
+using KeyIdArgsList = std::vector<KeyId>;
+
+using KeyIdArgsListPtr = std::unique_ptr<KeyIdArgsList>;
+
+using UIDArgsList = std::vector<std::string>;
+
+using UIDArgsListPtr = std::unique_ptr<UIDArgsList>;
+
+// KeyID/UID
+using SignIdArgsList = std::vector<std::pair<std::string, std::string>>;
+
+using SignIdArgsListPtr = std::unique_ptr<SignIdArgsList>;
+
+using KeyFprArgsListPtr = std::unique_ptr<std::vector<std::string>>;
+
+using KeyArgsList = std::vector<GpgKey>;
+
+using KeyListPtr = std::unique_ptr<KeyArgsList>;
+
+using GpgKeyLinkList = std::list<GpgFrontend::GpgKey>;
+
+using KeyLinkListPtr = std::unique_ptr<GpgKeyLinkList>;
+
+using KeyPtr = std::unique_ptr<GpgKey>;
+
+using KeyPtrArgsList = const std::initializer_list<KeyPtr>;
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_ZH_CN_TS_GPGMODEL_H
diff --git a/src/gpg/function/BasicOperator.cpp b/src/gpg/function/BasicOperator.cpp
new file mode 100644
index 00000000..912119e2
--- /dev/null
+++ b/src/gpg/function/BasicOperator.cpp
@@ -0,0 +1,206 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "gpg/function/BasicOperator.h"
+
+#include <vector>
+
+#include "gpg/function/GpgKeyGetter.h"
+
+GpgFrontend::GpgError GpgFrontend::BasicOperator::Encrypt(
+ KeyListPtr keys, GpgFrontend::BypeArrayRef in_buffer,
+ GpgFrontend::ByteArrayPtr& out_buffer, GpgFrontend::GpgEncrResult& result) {
+ // gpgme_encrypt_result_t e_result;
+ gpgme_key_t recipients[keys->size() + 1];
+
+ int index = 0;
+ for (const auto& key : *keys) recipients[index++] = gpgme_key_t(key);
+
+ // Last entry data_in array has to be nullptr
+ recipients[keys->size()] = nullptr;
+
+ GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
+
+ gpgme_error_t err = check_gpg_error(gpgme_op_encrypt(
+ ctx, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out));
+
+ auto temp_data_out = data_out.Read2Buffer();
+ std::swap(temp_data_out, out_buffer);
+
+ auto temp_result = GpgEncrResult(gpgme_op_encrypt_result(ctx));
+ std::swap(result, temp_result);
+
+ return err;
+}
+
+GpgFrontend::GpgError GpgFrontend::BasicOperator::Decrypt(
+ BypeArrayRef in_buffer, GpgFrontend::ByteArrayPtr& out_buffer,
+ GpgFrontend::GpgDecrResult& result) {
+ gpgme_error_t err;
+
+ GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
+ err = check_gpg_error(gpgme_op_decrypt(ctx, data_in, data_out));
+
+ auto temp_data_out = data_out.Read2Buffer();
+ std::swap(temp_data_out, out_buffer);
+
+ auto temp_result = GpgDecrResult(gpgme_op_decrypt_result(ctx));
+ std::swap(result, temp_result);
+
+ return err;
+}
+
+GpgFrontend::GpgError GpgFrontend::BasicOperator::Verify(
+ BypeArrayRef& in_buffer, ByteArrayPtr& sig_buffer,
+ GpgVerifyResult& result) const {
+ gpgme_error_t err;
+
+ GpgData data_in(in_buffer.data(), in_buffer.size());
+
+ if (sig_buffer != nullptr) {
+ GpgData sig_data(sig_buffer->data(), sig_buffer->size());
+ err = check_gpg_error(gpgme_op_verify(ctx, sig_data, data_in, nullptr));
+ } else
+ err = check_gpg_error(gpgme_op_verify(ctx, data_in, nullptr, data_in));
+
+ auto temp_result = GpgVerifyResult(gpgme_op_verify_result(ctx));
+ std::swap(result, temp_result);
+
+ return err;
+}
+
+GpgFrontend::GpgError GpgFrontend::BasicOperator::Sign(KeyListPtr keys,
+ BypeArrayRef in_buffer,
+ ByteArrayPtr& out_buffer,
+ gpgme_sig_mode_t mode,
+ GpgSignResult& result) {
+ gpgme_error_t err;
+
+ // Set Singers of this opera
+ SetSigners(*keys);
+
+ GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
+
+ /**
+ `GPGME_SIG_MODE_NORMAL'
+ A normal signature is made, the output includes the plaintext
+ and the signature.
+
+ `GPGME_SIG_MODE_DETACH'
+ A detached signature is made.
+
+ `GPGME_SIG_MODE_CLEAR'
+ A clear text signature is made. The ASCII armor and text
+ mode settings of the context are ignored.
+ */
+
+ err = check_gpg_error(gpgme_op_sign(ctx, data_in, data_out, mode));
+
+ auto temp_data_out = data_out.Read2Buffer();
+ std::swap(temp_data_out, out_buffer);
+
+ auto temp_result = GpgSignResult(gpgme_op_sign_result(ctx));
+
+ std::swap(result, temp_result);
+
+ return err;
+}
+
+gpgme_error_t GpgFrontend::BasicOperator::DecryptVerify(
+ BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
+ GpgDecrResult& decrypt_result, GpgVerifyResult& verify_result) {
+ gpgme_error_t err;
+
+ GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
+
+ err = check_gpg_error(gpgme_op_decrypt_verify(ctx, data_in, data_out));
+
+ auto temp_data_out = data_out.Read2Buffer();
+ std::swap(temp_data_out, out_buffer);
+
+ auto temp_decr_result = GpgDecrResult(gpgme_op_decrypt_result(ctx));
+ std::swap(decrypt_result, temp_decr_result);
+
+ auto temp_verify_result = GpgVerifyResult(gpgme_op_verify_result(ctx));
+ std::swap(verify_result, temp_verify_result);
+
+ return err;
+}
+
+gpgme_error_t GpgFrontend::BasicOperator::EncryptSign(
+ KeyListPtr keys, KeyListPtr signers, BypeArrayRef in_buffer,
+ ByteArrayPtr& out_buffer, GpgEncrResult& encr_result,
+ GpgSignResult& sign_result) {
+ gpgme_error_t err;
+ SetSigners(*signers);
+
+ // gpgme_encrypt_result_t e_result;
+ gpgme_key_t recipients[keys->size() + 1];
+
+ // set key for user
+ int index = 0;
+ for (const auto& key : *keys) recipients[index++] = gpgme_key_t(key);
+
+ // Last entry dataIn array has to be nullptr
+ recipients[keys->size()] = nullptr;
+
+ GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
+
+ // If the last parameter isnt 0, a private copy of data is made
+ err = check_gpg_error(gpgme_op_encrypt_sign(
+ ctx, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out));
+
+ auto temp_data_out = data_out.Read2Buffer();
+ std::swap(temp_data_out, out_buffer);
+
+ auto temp_encr_result = GpgEncrResult(gpgme_op_encrypt_result(ctx));
+ swap(encr_result, temp_encr_result);
+ auto temp_sign_result = GpgSignResult(gpgme_op_sign_result(ctx));
+ swap(sign_result, temp_sign_result);
+
+ return err;
+}
+
+void GpgFrontend::BasicOperator::SetSigners(KeyArgsList& keys) {
+ gpgme_signers_clear(ctx);
+ for (const GpgKey& key : keys) {
+ if (key.CanSignActual()) {
+ auto gpgmeError = gpgme_signers_add(ctx, gpgme_key_t(key));
+ check_gpg_error(gpgmeError);
+ }
+ }
+ if (keys.size() != gpgme_signers_count(ctx))
+ DLOG(INFO) << "No All Signers Added";
+}
+
+std::unique_ptr<GpgFrontend::KeyArgsList>
+GpgFrontend::BasicOperator::GetSigners() {
+ auto count = gpgme_signers_count(ctx);
+ auto signers = std::make_unique<std::vector<GpgKey>>();
+ for (auto i = 0u; i < count; i++) {
+ auto key = GpgKey(gpgme_signers_enum(ctx, i));
+ signers->push_back(GpgKey(std::move(key)));
+ }
+ return signers;
+}
diff --git a/src/gpg/function/BasicOperator.h b/src/gpg/function/BasicOperator.h
new file mode 100644
index 00000000..39f93668
--- /dev/null
+++ b/src/gpg/function/BasicOperator.h
@@ -0,0 +1,69 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H
+#define GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H
+
+#include "gpg/GpgConstants.h"
+#include "gpg/GpgContext.h"
+#include "gpg/GpgFunctionObject.h"
+#include "gpg/GpgModel.h"
+
+namespace GpgFrontend {
+
+class BasicOperator : public SingletonFunctionObject<BasicOperator> {
+ public:
+ gpg_error_t Encrypt(KeyListPtr keys, BypeArrayRef in_buffer,
+ ByteArrayPtr& out_buffer, GpgEncrResult& result);
+
+ gpgme_error_t EncryptSign(KeyListPtr keys, KeyListPtr signers,
+ BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
+ GpgEncrResult& encr_result,
+ GpgSignResult& sign_result);
+
+ gpgme_error_t Decrypt(BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
+ GpgDecrResult& result);
+
+ gpgme_error_t DecryptVerify(BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
+ GpgDecrResult& decrypt_result,
+ GpgVerifyResult& verify_result);
+
+ gpgme_error_t Verify(BypeArrayRef in_buffer, ByteArrayPtr& sig_buffer,
+ GpgVerifyResult& result) const;
+
+ gpg_error_t Sign(KeyListPtr keys, BypeArrayRef in_buffer,
+ ByteArrayPtr& out_buffer, gpgme_sig_mode_t mode,
+ GpgSignResult& result);
+
+ void SetSigners(KeyArgsList& keys);
+
+ std::unique_ptr<KeyArgsList> GetSigners();
+
+ private:
+ GpgContext& ctx =
+ GpgContext::GetInstance(SingletonFunctionObject::GetDefaultChannel());
+};
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H
diff --git a/src/gpg/function/GpgCommandExecutor.cpp b/src/gpg/function/GpgCommandExecutor.cpp
new file mode 100644
index 00000000..9b99b400
--- /dev/null
+++ b/src/gpg/function/GpgCommandExecutor.cpp
@@ -0,0 +1,59 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+#include "gpg/function/GpgCommandExecutor.h"
+#ifndef WINDOWS
+#include <boost/asio.hpp>
+#endif
+
+#ifndef WINDOWS
+
+using boost::process::async_pipe;
+
+void GpgFrontend::GpgCommandExecutor::Execute(
+ StringArgsRef arguments,
+ const std::function<void(async_pipe& in, async_pipe& out)>& interact_func) {
+ using namespace boost::process;
+
+ boost::asio::io_service ios;
+
+ std::vector<char> buf;
+
+ async_pipe in_pipe_stream(ios);
+ async_pipe out_pipe_stream(ios);
+
+ child child_process(ctx.GetInfo().AppPath.c_str(), arguments,
+ std_out > in_pipe_stream, std_in < out_pipe_stream);
+
+ boost::asio::async_read(
+ in_pipe_stream, boost::asio::buffer(buf),
+ [&](const boost::system::error_code& ec, std::size_t size) {
+ interact_func(in_pipe_stream, out_pipe_stream);
+ });
+
+ ios.run();
+ child_process.wait();
+ child_process.exit_code();
+}
+
+#endif
diff --git a/src/gpg/function/GpgCommandExecutor.h b/src/gpg/function/GpgCommandExecutor.h
new file mode 100644
index 00000000..f28caca8
--- /dev/null
+++ b/src/gpg/function/GpgCommandExecutor.h
@@ -0,0 +1,52 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_ZH_CN_TS_GPGCOMMANDEXECUTOR_H
+#define GPGFRONTEND_ZH_CN_TS_GPGCOMMANDEXECUTOR_H
+
+#ifndef WINDOWS
+#include <boost/process.hpp>
+#endif
+
+#include "gpg/GpgContext.h"
+#include "gpg/GpgFunctionObject.h"
+
+namespace GpgFrontend {
+class GpgCommandExecutor : public SingletonFunctionObject<GpgCommandExecutor> {
+ public:
+
+#ifndef WINDOWS
+ void Execute(StringArgsRef arguments,
+ const std::function<void(boost::process::async_pipe &in,
+ boost::process::async_pipe &out)>
+ &interact_func);
+#endif
+
+ private:
+ GpgContext &ctx = GpgContext::GetInstance();
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_ZH_CN_TS_GPGCOMMANDEXECUTOR_H
diff --git a/src/gpg/function/GpgFileOpera.cpp b/src/gpg/function/GpgFileOpera.cpp
new file mode 100644
index 00000000..c3f75cf8
--- /dev/null
+++ b/src/gpg/function/GpgFileOpera.cpp
@@ -0,0 +1,162 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+#include "gpg/function/GpgFileOpera.h"
+
+#include <memory>
+#include <string>
+
+#include "GpgConstants.h"
+#include "gpg/function/BasicOperator.h"
+
+GpgFrontend::GpgError GpgFrontend::GpgFileOpera::EncryptFile(
+ KeyListPtr keys, const std::string& path, GpgEncrResult& result) {
+ std::string in_buffer = read_all_data_in_file(path);
+ std::unique_ptr<std::string> out_buffer;
+
+ auto err = BasicOperator::GetInstance().Encrypt(std::move(keys), in_buffer,
+ out_buffer, result);
+
+ if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
+ if (!write_buffer_to_file(path + ".asc", *out_buffer)) {
+ throw std::runtime_error("write_buffer_to_file error");
+ };
+
+ return err;
+}
+
+GpgFrontend::GpgError GpgFrontend::GpgFileOpera::DecryptFile(
+ const std::string& path, GpgDecrResult& result) {
+ std::string in_buffer = read_all_data_in_file(path);
+ std::unique_ptr<std::string> out_buffer;
+
+ auto err =
+ BasicOperator::GetInstance().Decrypt(in_buffer, out_buffer, result);
+
+ assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
+
+ std::string out_file_name = get_only_file_name_with_path(path),
+ file_extension = get_file_extension(path);
+
+ if (!(file_extension == ".asc" || file_extension == ".gpg"))
+ out_file_name += ".out";
+
+ if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
+ if (!write_buffer_to_file(out_file_name, *out_buffer)) {
+ throw std::runtime_error("write_buffer_to_file error");
+ };
+
+ return err;
+}
+
+gpgme_error_t GpgFrontend::GpgFileOpera::SignFile(KeyListPtr keys,
+ const std::string& path,
+ GpgSignResult& result) {
+ auto in_buffer = read_all_data_in_file(path);
+ std::unique_ptr<std::string> out_buffer;
+
+ auto err = BasicOperator::GetInstance().Sign(
+ std::move(keys), in_buffer, out_buffer, GPGME_SIG_MODE_DETACH, result);
+
+ if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
+ if (!write_buffer_to_file(path + ".sig", *out_buffer)) {
+ throw std::runtime_error("write_buffer_to_file error");
+ };
+
+ return err;
+}
+
+gpgme_error_t GpgFrontend::GpgFileOpera::VerifyFile(const std::string& path,
+ GpgVerifyResult& result) {
+ auto in_buffer = read_all_data_in_file(path);
+ std::unique_ptr<std::string> sign_buffer = nullptr;
+
+ if (get_file_extension(path) == ".gpg") {
+ auto err =
+ BasicOperator::GetInstance().Verify(in_buffer, sign_buffer, result);
+ assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
+ return err;
+ } else {
+ sign_buffer =
+ std::make_unique<std::string>(read_all_data_in_file(path + ".sig"));
+
+ auto err =
+ BasicOperator::GetInstance().Verify(in_buffer, sign_buffer, result);
+ return err;
+ }
+}
+
+// TODO
+
+gpg_error_t GpgFrontend::GpgFileOpera::EncryptSignFile(
+ KeyListPtr keys, KeyListPtr signer_keys, const std::string& path,
+ GpgEncrResult& encr_res, GpgSignResult& sign_res) {
+ auto in_buffer = read_all_data_in_file(path);
+ std::unique_ptr<std::string> out_buffer = nullptr;
+
+ // TODO dealing with signer keys
+ auto err = BasicOperator::GetInstance().EncryptSign(
+ std::move(keys), std::move(signer_keys), in_buffer, out_buffer, encr_res,
+ sign_res);
+
+ auto out_path = path + ".gpg";
+ LOG(INFO) << "EncryptSignFile out_path" << out_path;
+ LOG(INFO) << "EncryptSignFile out_buffer size" << out_buffer->size();
+
+ if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
+ if (!write_buffer_to_file(out_path, *out_buffer)) {
+ throw std::runtime_error("write_buffer_to_file error");
+ };
+
+ return err;
+}
+
+gpg_error_t GpgFrontend::GpgFileOpera::DecryptVerifyFile(
+ const std::string& path, GpgDecrResult& decr_res,
+ GpgVerifyResult& verify_res) {
+ LOG(INFO) << "GpgFrontend::GpgFileOpera::DecryptVerifyFile Called";
+
+ auto in_buffer = read_all_data_in_file(path);
+
+ LOG(INFO) << "GpgFrontend::GpgFileOpera::DecryptVerifyFile in_buffer"
+ << in_buffer.size();
+ std::unique_ptr<std::string> out_buffer = nullptr;
+
+ auto err = BasicOperator::GetInstance().DecryptVerify(in_buffer, out_buffer,
+ decr_res, verify_res);
+
+ std::string out_file_name = get_only_file_name_with_path(path),
+ file_extension = get_file_extension(path);
+
+ if (!(file_extension == ".asc" || file_extension == ".gpg"))
+ out_file_name = path + ".out";
+ LOG(INFO) << "GpgFrontend::GpgFileOpera::DecryptVerifyFile out_file_name"
+ << out_file_name;
+
+ if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
+ if (!write_buffer_to_file(out_file_name, *out_buffer)) {
+ throw std::runtime_error("write_buffer_to_file error");
+ };
+
+ return err;
+}
diff --git a/src/gpg/function/GpgFileOpera.h b/src/gpg/function/GpgFileOpera.h
new file mode 100644
index 00000000..4aaf09f1
--- /dev/null
+++ b/src/gpg/function/GpgFileOpera.h
@@ -0,0 +1,58 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_GPGFILEOPERA_H
+#define GPGFRONTEND_GPGFILEOPERA_H
+
+#include "gpg/GpgConstants.h"
+#include "gpg/GpgContext.h"
+#include "gpg/GpgModel.h"
+
+namespace GpgFrontend {
+
+class GpgFileOpera : public SingletonFunctionObject<GpgFileOpera> {
+ public:
+ static GpgError EncryptFile(KeyListPtr keys, const std::string& path,
+ GpgEncrResult& result);
+
+ static GpgError DecryptFile(const std::string& path, GpgDecrResult& result);
+
+ static GpgError SignFile(KeyListPtr keys, const std::string& path,
+ GpgSignResult& result);
+
+ static GpgError VerifyFile(const std::string& path, GpgVerifyResult& result);
+
+ static GpgError EncryptSignFile(KeyListPtr keys, KeyListPtr signer_keys,
+ const std::string& path,
+ GpgEncrResult& encr_res,
+ GpgSignResult& sign_res);
+
+ static GpgError DecryptVerifyFile(const std::string& path,
+ GpgDecrResult& decr_res,
+ GpgVerifyResult& verify_res);
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_GPGFILEOPERA_H
diff --git a/src/gpg/function/GpgKeyGetter.cpp b/src/gpg/function/GpgKeyGetter.cpp
new file mode 100644
index 00000000..be27d69e
--- /dev/null
+++ b/src/gpg/function/GpgKeyGetter.cpp
@@ -0,0 +1,75 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "gpg/function/GpgKeyGetter.h"
+
+#include <gpg-error.h>
+
+#include "GpgConstants.h"
+
+GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetKey(const std::string& fpr) {
+ gpgme_key_t _p_key;
+ gpgme_get_key(ctx, fpr.c_str(), &_p_key, 1);
+ if (_p_key == nullptr) {
+ DLOG(WARNING) << "GpgKeyGetter GetKey Private _p_key Null fpr" << fpr;
+ return GetPubkey(fpr);
+ } else {
+ return GpgKey(std::move(_p_key));
+ }
+}
+
+GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetPubkey(
+ const std::string& fpr) {
+ gpgme_key_t _p_key;
+ gpgme_get_key(ctx, fpr.c_str(), &_p_key, 0);
+ if (_p_key == nullptr)
+ DLOG(WARNING) << "GpgKeyGetter GetKey _p_key Null" << fpr;
+ return GpgKey(std::move(_p_key));
+}
+
+GpgFrontend::KeyLinkListPtr GpgFrontend::GpgKeyGetter::FetchKey() {
+ gpgme_error_t err;
+
+ auto keys_list = std::make_unique<GpgKeyLinkList>();
+
+ err = gpgme_op_keylist_start(ctx, nullptr, 0);
+ assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
+
+ gpgme_key_t key;
+ while ((err = gpgme_op_keylist_next(ctx, &key)) == GPG_ERR_NO_ERROR) {
+ keys_list->push_back(GpgKey(std::move(key)));
+ }
+
+ assert(check_gpg_error_2_err_code(err, GPG_ERR_EOF) == GPG_ERR_EOF);
+
+ err = gpgme_op_keylist_end(ctx);
+
+ return keys_list;
+}
+GpgFrontend::KeyListPtr GpgFrontend::GpgKeyGetter::GetKeys(
+ const KeyIdArgsListPtr& ids) {
+ auto keys = std::make_unique<KeyArgsList>();
+ for (const auto& id : *ids) keys->push_back(GetKey(id));
+ return keys;
+}
diff --git a/src/gpg/function/GpgKeyGetter.h b/src/gpg/function/GpgKeyGetter.h
new file mode 100644
index 00000000..c8f5d73a
--- /dev/null
+++ b/src/gpg/function/GpgKeyGetter.h
@@ -0,0 +1,52 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H
+#define GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H
+
+#include "gpg/GpgContext.h"
+#include "gpg/GpgFunctionObject.h"
+#include "gpg/GpgModel.h"
+
+namespace GpgFrontend {
+
+class GpgKeyGetter : public SingletonFunctionObject<GpgKeyGetter> {
+ public:
+ GpgKeyGetter() = default;
+
+ GpgKey GetKey(const std::string& fpr);
+
+ KeyListPtr GetKeys(const KeyIdArgsListPtr& ids);
+
+ GpgKey GetPubkey(const std::string& fpr);
+
+ KeyLinkListPtr FetchKey();
+
+ private:
+ GpgContext& ctx =
+ GpgContext::GetInstance(SingletonFunctionObject::GetDefaultChannel());
+};
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H
diff --git a/src/gpg/function/GpgKeyImportExportor.cpp b/src/gpg/function/GpgKeyImportExportor.cpp
new file mode 100644
index 00000000..f4b88c60
--- /dev/null
+++ b/src/gpg/function/GpgKeyImportExportor.cpp
@@ -0,0 +1,117 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "gpg/function/GpgKeyImportExportor.h"
+
+#include "GpgConstants.h"
+
+/**
+ * Import key pair
+ * @param inBuffer input byte array
+ * @return Import information
+ */
+GpgFrontend::GpgImportInformation GpgFrontend::GpgKeyImportExportor::ImportKey(
+ StdBypeArrayPtr in_buffer) {
+ if (in_buffer->empty()) return GpgImportInformation();
+
+ GpgData data_in(in_buffer->data(), in_buffer->size());
+ auto err = check_gpg_error(gpgme_op_import(ctx, data_in));
+ assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
+ gpgme_import_result_t result;
+ result = gpgme_op_import_result(ctx);
+ gpgme_import_status_t status = result->imports;
+ auto import_info = std::make_unique<GpgImportInformation>(result);
+ while (status != nullptr) {
+ GpgImportedKey key;
+ key.import_status = static_cast<int>(status->status);
+ key.fpr = status->fpr;
+ import_info->importedKeys.emplace_back(key);
+ status = status->next;
+ }
+ return *import_info;
+}
+
+/**
+ * Export Key
+ * @param uid_list key ids
+ * @param out_buffer output byte array
+ * @return if success
+ */
+bool GpgFrontend::GpgKeyImportExportor::ExportKeys(
+ KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer) const {
+ if (uid_list->empty()) return false;
+
+ // Alleviate another crash problem caused by an unknown array out-of-bounds
+ // access
+ for (size_t i = 0; i < uid_list->size(); i++) {
+ GpgData data_out;
+ auto err = gpgme_op_export(ctx, (*uid_list)[i].c_str(), 0, data_out);
+ assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
+
+ DLOG(INFO) << "exportKeys read_bytes"
+ << gpgme_data_seek(data_out, 0, SEEK_END);
+
+ auto temp_out_buffer = data_out.Read2Buffer();
+ std::swap(out_buffer, temp_out_buffer);
+ }
+
+ return true;
+}
+
+/**
+ * Export keys
+ * @param keys keys used
+ * @param outBuffer output byte array
+ * @return if success
+ */
+bool GpgFrontend::GpgKeyImportExportor::ExportKeys(
+ const KeyArgsList& keys, ByteArrayPtr& out_buffer) const {
+ KeyIdArgsListPtr key_ids = std::make_unique<std::vector<std::string>>();
+ for (const auto& key : keys) key_ids->push_back(key.id());
+ return ExportKeys(key_ids, out_buffer);
+}
+
+/**
+ * Export the secret key of a key pair(including subkeys)
+ * @param key target key pair
+ * @param outBuffer output byte array
+ * @return if successful
+ */
+bool GpgFrontend::GpgKeyImportExportor::ExportSecretKey(
+ const GpgKey& key, ByteArrayPtr& out_buffer) const {
+ DLOG(INFO) << "Export Secret Key" << key.id().c_str();
+
+ gpgme_key_t target_key[2] = {gpgme_key_t(key), nullptr};
+
+ GpgData data_out;
+
+ // export private key to outBuffer
+ gpgme_error_t err =
+ gpgme_op_export_keys(ctx, target_key, GPGME_EXPORT_MODE_SECRET, data_out);
+
+ auto temp_out_buffer = data_out.Read2Buffer();
+ std::swap(out_buffer, temp_out_buffer);
+
+ return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
+}
diff --git a/src/gpg/function/GpgKeyImportExportor.h b/src/gpg/function/GpgKeyImportExportor.h
new file mode 100644
index 00000000..bceb87ef
--- /dev/null
+++ b/src/gpg/function/GpgKeyImportExportor.h
@@ -0,0 +1,100 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef _GPGKEYIMPORTEXPORTOR_H
+#define _GPGKEYIMPORTEXPORTOR_H
+
+#include <string>
+
+#include "gpg/GpgConstants.h"
+#include "gpg/GpgContext.h"
+#include "gpg/GpgFunctionObject.h"
+#include "gpg/GpgModel.h"
+
+namespace GpgFrontend {
+
+class GpgImportedKey {
+ public:
+ std::string fpr;
+ int import_status;
+};
+
+typedef std::list<GpgImportedKey> GpgImportedKeyList;
+
+class GpgImportInformation {
+ public:
+ GpgImportInformation() = default;
+
+ explicit GpgImportInformation(gpgme_import_result_t result) {
+ if (result->unchanged) unchanged = result->unchanged;
+ if (result->considered) considered = result->considered;
+ if (result->no_user_id) no_user_id = result->no_user_id;
+ if (result->imported) imported = result->imported;
+ if (result->imported_rsa) imported_rsa = result->imported_rsa;
+ if (result->unchanged) unchanged = result->unchanged;
+ if (result->new_user_ids) new_user_ids = result->new_user_ids;
+ if (result->new_sub_keys) new_sub_keys = result->new_sub_keys;
+ if (result->new_signatures) new_signatures = result->new_signatures;
+ if (result->new_revocations) new_revocations = result->new_revocations;
+ if (result->secret_read) secret_read = result->secret_read;
+ if (result->secret_imported) secret_imported = result->secret_imported;
+ if (result->secret_unchanged) secret_unchanged = result->secret_unchanged;
+ if (result->not_imported) not_imported = result->not_imported;
+ }
+
+ int considered = 0;
+ int no_user_id = 0;
+ int imported = 0;
+ int imported_rsa = 0;
+ int unchanged = 0;
+ int new_user_ids = 0;
+ int new_sub_keys = 0;
+ int new_signatures = 0;
+ int new_revocations = 0;
+ int secret_read = 0;
+ int secret_imported = 0;
+ int secret_unchanged = 0;
+ int not_imported = 0;
+ GpgImportedKeyList importedKeys;
+};
+
+class GpgKeyImportExportor
+ : public SingletonFunctionObject<GpgKeyImportExportor> {
+ public:
+ GpgImportInformation ImportKey(StdBypeArrayPtr inBuffer);
+
+ bool ExportKeys(KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer) const;
+
+ bool ExportKeys(const KeyArgsList& keys, ByteArrayPtr& outBuffer) const;
+
+ bool ExportSecretKey(const GpgKey& key, ByteArrayPtr& outBuffer) const;
+
+ private:
+ GpgContext& ctx =
+ GpgContext::GetInstance(SingletonFunctionObject::GetDefaultChannel());
+};
+
+} // namespace GpgFrontend
+
+#endif // _GPGKEYIMPORTEXPORTOR_H \ No newline at end of file
diff --git a/src/gpg/function/GpgKeyManager.cpp b/src/gpg/function/GpgKeyManager.cpp
new file mode 100644
index 00000000..9e24b3d6
--- /dev/null
+++ b/src/gpg/function/GpgKeyManager.cpp
@@ -0,0 +1,88 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "gpg/function/GpgKeyManager.h"
+
+#include <boost/date_time/posix_time/conversion.hpp>
+#include <string>
+
+#include "gpg/function/BasicOperator.h"
+#include "gpg/function/GpgKeyGetter.h"
+
+bool GpgFrontend::GpgKeyManager::signKey(
+ const GpgFrontend::GpgKey& target, GpgFrontend::KeyArgsList& keys,
+ const std::string& uid,
+ const std::unique_ptr<boost::gregorian::date>& expires) {
+ using namespace boost::posix_time;
+
+ BasicOperator::GetInstance().SetSigners(keys);
+
+ unsigned int flags = 0;
+ unsigned int expires_time_t = 0;
+
+ if (expires == nullptr)
+ flags |= GPGME_KEYSIGN_NOEXPIRE;
+ else
+ expires_time_t = to_time_t(ptime(*expires));
+
+ auto err = check_gpg_error(gpgme_op_keysign(
+ ctx, gpgme_key_t(target), uid.c_str(), expires_time_t, flags));
+
+ return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
+}
+
+bool GpgFrontend::GpgKeyManager::revSign(
+ const GpgFrontend::GpgKey& key,
+ const GpgFrontend::SignIdArgsListPtr& signature_id) {
+ auto& key_getter = GpgKeyGetter::GetInstance();
+
+ for (const auto& sign_id : *signature_id) {
+ auto signing_key = key_getter.GetKey(sign_id.first);
+ assert(signing_key.good());
+ auto err = check_gpg_error(gpgme_op_revsig(ctx, gpgme_key_t(key),
+ gpgme_key_t(signing_key),
+ sign_id.second.c_str(), 0));
+ if (check_gpg_error_2_err_code(err) != GPG_ERR_NO_ERROR) return false;
+ }
+ return true;
+}
+
+bool GpgFrontend::GpgKeyManager::setExpire(
+ const GpgFrontend::GpgKey& key, std::unique_ptr<GpgSubKey>& subkey,
+ std::unique_ptr<boost::gregorian::date>& expires) {
+ using namespace boost::posix_time;
+
+ unsigned long expires_time = 0;
+
+ if (expires != nullptr) expires_time = to_time_t(ptime(*expires));
+
+ const char* sub_fprs = nullptr;
+
+ if (subkey != nullptr) sub_fprs = subkey->fpr().c_str();
+
+ auto err = check_gpg_error(
+ gpgme_op_setexpire(ctx, gpgme_key_t(key), expires_time, sub_fprs, 0));
+
+ return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
+}
diff --git a/src/gpg/function/GpgKeyManager.h b/src/gpg/function/GpgKeyManager.h
new file mode 100644
index 00000000..2b07425c
--- /dev/null
+++ b/src/gpg/function/GpgKeyManager.h
@@ -0,0 +1,58 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H
+#define GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H
+
+#include "gpg/GpgContext.h"
+#include "gpg/GpgFunctionObject.h"
+#include "gpg/GpgModel.h"
+
+namespace GpgFrontend {
+
+class GpgKeyManager : public SingletonFunctionObject<GpgKeyManager> {
+ public:
+ /**
+ * Sign a key pair(actually a certain uid)
+ * @param target target key pair
+ * @param uid target
+ * @param expires expire date and time of the signature
+ * @return if successful
+ */
+ bool signKey(const GpgKey& target, KeyArgsList& keys, const std::string& uid,
+ const std::unique_ptr<boost::gregorian::date>& expires);
+
+ bool revSign(const GpgFrontend::GpgKey& key,
+ const GpgFrontend::SignIdArgsListPtr& signature_id);
+
+ bool setExpire(const GpgKey& key, std::unique_ptr<GpgSubKey>& subkey,
+ std::unique_ptr<boost::gregorian::date>& expires);
+
+ private:
+ GpgContext& ctx = GpgContext::GetInstance();
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H
diff --git a/src/gpg/function/GpgKeyOpera.cpp b/src/gpg/function/GpgKeyOpera.cpp
new file mode 100644
index 00000000..c60f9157
--- /dev/null
+++ b/src/gpg/function/GpgKeyOpera.cpp
@@ -0,0 +1,217 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "gpg/function/GpgKeyOpera.h"
+
+#include <boost/asio.hpp>
+#include <boost/date_time/posix_time/conversion.hpp>
+#include <boost/process/async_pipe.hpp>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "gpg/GpgConstants.h"
+#include "gpg/GpgGenKeyInfo.h"
+#include "gpg/function/GpgCommandExecutor.h"
+#include "gpg/function/GpgKeyGetter.h"
+
+/**
+ * Delete keys
+ * @param uidList key ids
+ */
+void GpgFrontend::GpgKeyOpera::DeleteKeys(
+ GpgFrontend::KeyIdArgsListPtr key_ids) {
+ GpgError err;
+ for (const auto& tmp : *key_ids) {
+ auto key = GpgKeyGetter::GetInstance().GetKey(tmp);
+ if (key.good()) {
+ LOG(INFO) << "GpgKeyOpera DeleteKeys Get Key Good";
+ err = check_gpg_error(gpgme_op_delete(ctx, gpgme_key_t(key), 1));
+ assert(gpg_err_code(err) == GPG_ERR_NO_ERROR);
+ } else
+ LOG(WARNING) << "GpgKeyOpera DeleteKeys Get Key Bad";
+ }
+}
+
+/**
+ * Set the expire date and time of a key pair(actually the master key) or subkey
+ * @param key target key pair
+ * @param subkey null if master key
+ * @param expires date and time
+ * @return if successful
+ */
+GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::SetExpire(
+ const GpgKey& key, const SubkeyId& subkey_fpr,
+ std::unique_ptr<boost::gregorian::date>& expires) {
+ unsigned long expires_time = 0;
+ if (expires != nullptr) {
+ using namespace boost::posix_time;
+ using namespace std::chrono;
+ expires_time = to_time_t(ptime(*expires)) -
+ system_clock::to_time_t(system_clock::now());
+ }
+
+ LOG(INFO) << "GpgFrontend::GpgKeyOpera::SetExpire" << key.id() << subkey_fpr
+ << expires_time;
+
+ GpgError err;
+ if (subkey_fpr.empty())
+ err = gpgme_op_setexpire(ctx, gpgme_key_t(key), expires_time, nullptr, 0);
+ else
+ err = gpgme_op_setexpire(ctx, gpgme_key_t(key), expires_time,
+ subkey_fpr.c_str(), 0);
+
+ return err;
+}
+
+/**
+ * Generate revoke cert of a key pair
+ * @param key target key pair
+ * @param outputFileName out file name(path)
+ * @return the process doing this job
+ */
+void GpgFrontend::GpgKeyOpera::GenerateRevokeCert(
+ const GpgKey& key, const std::string& output_file_name) {
+ auto args = std::vector<std::string>{
+ "--no-tty", "--command-fd", "0", "--status-fd", "1", "-o",
+ output_file_name, "--gen-revoke", key.fpr()};
+
+ using boost::asio::async_write;
+ using boost::process::async_pipe;
+#ifndef WINDOWS
+ GpgCommandExecutor::GetInstance().Execute(
+ args, [](async_pipe& in, async_pipe& out) -> void {
+ // boost::asio::streambuf buff;
+ // boost::asio::read_until(in, buff, '\n');
+ //
+ // std::istream is(&buff);
+ //
+ // while (!is.eof()) {
+ // std::string line;
+ // is >> line;
+ // LOG(INFO) << "line" << line;
+ // boost::algorithm::trim(line);
+ // if (line == std::string("[GNUPG:] GET_BOOL
+ // gen_revoke.okay")) {
+ //
+ // } else if (line ==
+ // std::string(
+ // "[GNUPG:] GET_LINE
+ // ask_revocation_reason.code")) {
+ //
+ // } else if (line ==
+ // std::string(
+ // "[GNUPG:] GET_LINE
+ // ask_revocation_reason.text")) {
+ //
+ // } else if (line ==
+ // std::string("[GNUPG:] GET_BOOL
+ // openfile.overwrite.okay")) {
+ //
+ // } else if (line ==
+ // std::string(
+ // "[GNUPG:] GET_BOOL
+ // ask_revocation_reason.okay")) {
+ //
+ // }
+ // }
+ });
+#endif
+}
+
+/**
+ * Generate a new key pair
+ * @param params key generation args
+ * @return error information
+ */
+GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateKey(
+ const std::unique_ptr<GenKeyInfo>& params) {
+ auto userid_utf8 = params->getUserid();
+ const char* userid = userid_utf8.c_str();
+ auto algo_utf8 = params->getAlgo() + params->getKeySizeStr();
+
+ LOG(INFO) << "GpgFrontend::GpgKeyOpera::GenerateKey Params"
+ << params->getAlgo() << params->getKeySizeStr();
+
+ const char* algo = algo_utf8.c_str();
+ unsigned long expires = 0;
+ {
+ using namespace boost::posix_time;
+ using namespace std::chrono;
+ expires = to_time_t(ptime(params->getExpired())) -
+ system_clock::to_time_t(system_clock::now());
+ }
+
+ unsigned int flags = 0;
+
+ if (!params->isSubKey()) flags |= GPGME_CREATE_CERT;
+ if (params->isAllowEncryption()) flags |= GPGME_CREATE_ENCR;
+ if (params->isAllowSigning()) flags |= GPGME_CREATE_SIGN;
+ if (params->isAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
+ if (params->isNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
+ if (params->isNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+
+ LOG(INFO) << "GpgFrontend::GpgKeyOpera::GenerateKey Args: " << userid << algo
+ << expires << flags;
+
+ auto err = gpgme_op_createkey(ctx, userid, algo, 0, expires, nullptr, flags);
+ return check_gpg_error(err);
+}
+
+/**
+ * Generate a new subkey of a certain key pair
+ * @param key target key pair
+ * @param params opera args
+ * @return error info
+ */
+GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateSubkey(
+ const GpgKey& key, const std::unique_ptr<GenKeyInfo>& params) {
+ if (!params->isSubKey()) return GPG_ERR_CANCELED;
+
+ auto algo_utf8 = (params->getAlgo() + params->getKeySizeStr());
+ const char* algo = algo_utf8.c_str();
+ unsigned long expires = 0;
+ {
+ using namespace boost::posix_time;
+ using namespace std::chrono;
+ expires = to_time_t(ptime(params->getExpired())) -
+ system_clock::to_time_t(system_clock::now());
+ }
+ unsigned int flags = 0;
+
+ if (!params->isSubKey()) flags |= GPGME_CREATE_CERT;
+ if (params->isAllowEncryption()) flags |= GPGME_CREATE_ENCR;
+ if (params->isAllowSigning()) flags |= GPGME_CREATE_SIGN;
+ if (params->isAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
+ if (params->isNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
+
+ flags |= GPGME_CREATE_NOPASSWD;
+
+ LOG(INFO) << "GpgFrontend::GpgKeyOpera::GenerateSubkey Args: " << key.id()
+ << algo << expires << flags;
+
+ auto err =
+ gpgme_op_createsubkey(ctx, gpgme_key_t(key), algo, 0, expires, flags);
+ return check_gpg_error(err);
+} \ No newline at end of file
diff --git a/src/gpg/function/GpgKeyOpera.h b/src/gpg/function/GpgKeyOpera.h
new file mode 100644
index 00000000..71e2de8b
--- /dev/null
+++ b/src/gpg/function/GpgKeyOpera.h
@@ -0,0 +1,54 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef _GPGKEYOPERA_H
+#define _GPGKEYOPERA_H
+
+#include "gpg/GpgConstants.h"
+#include "gpg/GpgContext.h"
+#include "gpg/GpgModel.h"
+
+namespace GpgFrontend {
+class GenKeyInfo;
+class GpgKeyOpera : public SingletonFunctionObject<GpgKeyOpera> {
+ public:
+ void DeleteKeys(KeyIdArgsListPtr key_ids);
+
+ GpgError SetExpire(const GpgKey& key, const SubkeyId& subkey_fpr,
+ std::unique_ptr<boost::gregorian::date>& expires);
+
+ static void GenerateRevokeCert(const GpgKey& key,
+ const std::string& output_file_name);
+
+ GpgFrontend::GpgError GenerateKey(const std::unique_ptr<GenKeyInfo>& params);
+
+ GpgFrontend::GpgError GenerateSubkey(
+ const GpgKey& key, const std::unique_ptr<GenKeyInfo>& params);
+
+ private:
+ GpgContext& ctx = GpgContext::GetInstance();
+};
+} // namespace GpgFrontend
+
+#endif // _GPGKEYOPERA_H \ No newline at end of file
diff --git a/src/gpg/function/UidOperator.cpp b/src/gpg/function/UidOperator.cpp
new file mode 100644
index 00000000..d7acc3b1
--- /dev/null
+++ b/src/gpg/function/UidOperator.cpp
@@ -0,0 +1,64 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "gpg/function/UidOperator.h"
+
+#include "boost/format.hpp"
+
+bool GpgFrontend::UidOperator::addUID(const GpgFrontend::GpgKey& key,
+ const std::string& uid) {
+ auto err = gpgme_op_adduid(ctx, gpgme_key_t(key), uid.c_str(), 0);
+ if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
+ return true;
+ else
+ return false;
+}
+
+bool GpgFrontend::UidOperator::revUID(const GpgFrontend::GpgKey& key,
+ const std::string& uid) {
+ auto err =
+ check_gpg_error(gpgme_op_revuid(ctx, gpgme_key_t(key), uid.c_str(), 0));
+ if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
+ return true;
+ else
+ return false;
+}
+
+bool GpgFrontend::UidOperator::setPrimaryUID(const GpgFrontend::GpgKey& key,
+ const std::string& uid) {
+ auto err = check_gpg_error(gpgme_op_set_uid_flag(
+ ctx, gpgme_key_t(key), uid.c_str(), "primary", nullptr));
+ if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
+ return true;
+ else
+ return false;
+}
+bool GpgFrontend::UidOperator::addUID(const GpgFrontend::GpgKey& key,
+ const std::string& name,
+ const std::string& comment,
+ const std::string& email) {
+ LOG(INFO) << "GpgFrontend::UidOperator::addUID" << name << comment << email;
+ auto uid = boost::format("%1%(%2%)<%3%>") % name % comment % email;
+ return addUID(key, uid.str());
+}
diff --git a/src/gpg/function/UidOperator.h b/src/gpg/function/UidOperator.h
new file mode 100644
index 00000000..7d5df254
--- /dev/null
+++ b/src/gpg/function/UidOperator.h
@@ -0,0 +1,76 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H
+#define GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H
+
+#include "gpg/GpgContext.h"
+#include "gpg/GpgModel.h"
+
+namespace GpgFrontend {
+
+class UidOperator : public SingletonFunctionObject<UidOperator> {
+ public:
+ /**
+ * create a new uid in certain key pair
+ * @param key target key pair
+ * @param uid uid args(combine name&comment&email)
+ * @return if successful
+ */
+ bool addUID(const GpgKey& key, const std::string& uid);
+
+ /**
+ * create a new uid in certain key pair
+ * @param key target key pair
+ * @param name
+ * @param comment
+ * @param email
+ * @return
+ */
+ bool addUID(const GpgKey& key, const std::string& name,
+ const std::string& comment, const std::string& email);
+
+ /**
+ * Revoke(Delete) UID from certain key pair
+ * @param key target key pair
+ * @param uid target uid
+ * @return if successful
+ */
+ bool revUID(const GpgKey& key, const std::string& uid);
+
+ /**
+ * Set one of a uid of a key pair as primary
+ * @param key target key pair
+ * @param uid target uid
+ * @return if successful
+ */
+ bool setPrimaryUID(const GpgKey& key, const std::string& uid);
+
+ private:
+ GpgContext& ctx = GpgContext::GetInstance();
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H
diff --git a/src/gpg/gpg_context/GpgContext.cpp b/src/gpg/gpg_context/GpgContext.cpp
deleted file mode 100644
index 14b54b32..00000000
--- a/src/gpg/gpg_context/GpgContext.cpp
+++ /dev/null
@@ -1,410 +0,0 @@
-/**
- * This file is part of GPGFrontend.
- *
- * GPGFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Foobar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from gpg4usb-team.
- * Their source code version also complies with GNU General Public License.
- *
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]> starting on May 12, 2021.
- *
- */
-
-#include "gpg/GpgContext.h"
-#include "ui/WaitingDialog.h"
-
-#include <functional>
-#include <unistd.h> /* contains read/write */
-
-#ifdef _WIN32
-
-#include <windows.h>
-
-#endif
-
-#define INT2VOIDP(i) (void*)(uintptr_t)(i)
-
-namespace GpgME {
-
- /** Constructor
- * Set up gpgme-context, set paths to app-run path
- */
- GpgContext::GpgContext() {
-
- /** The function `gpgme_check_version' must be called before any other
- * function in the library, because it initializes the thread support
- * subsystem in GPGME. (from the info page) */
- gpgme_check_version(nullptr);
-
- // the locale set here is used for the other setlocale calls which have nullptr
- // -> nullptr means use default, which is configured here
- setlocale(LC_ALL, settings.value("int/lang").toLocale().name().toUtf8().constData());
-
- /** set locale, because tests do also */
- gpgme_set_locale(nullptr, LC_CTYPE, setlocale(LC_CTYPE, nullptr));
- //qDebug() << "Locale set to" << LC_CTYPE << " - " << setlocale(LC_CTYPE, nullptr);
-#ifndef _WIN32
- gpgme_set_locale(nullptr, LC_MESSAGES, setlocale(LC_MESSAGES, nullptr));
-#endif
-
- err = gpgme_new(&mCtx);
- checkErr(err);
-
- gpgme_engine_info_t engineInfo;
- engineInfo = gpgme_ctx_get_engine_info(mCtx);
-
-// Check ENV before running
- bool check_pass = false, find_openpgp = false, find_gpgconf = false, find_assuan = false, find_cms = false;
- while (engineInfo != nullptr) {
- qDebug() << gpgme_get_protocol_name(engineInfo->protocol) << engineInfo->file_name << engineInfo->protocol
- << engineInfo->home_dir << engineInfo->version;
- if (engineInfo->protocol == GPGME_PROTOCOL_GPGCONF && strcmp(engineInfo->version, "1.0.0") != 0)
- find_gpgconf = true;
- if (engineInfo->protocol == GPGME_PROTOCOL_OpenPGP && strcmp(engineInfo->version, "1.0.0") != 0)
- find_openpgp = true, info.appPath = engineInfo->file_name;
- if (engineInfo->protocol == GPGME_PROTOCOL_CMS && strcmp(engineInfo->version, "1.0.0") != 0)
- find_cms = true;
- if (engineInfo->protocol == GPGME_PROTOCOL_ASSUAN)
- find_assuan = true;
-
- engineInfo = engineInfo->next;
- }
-
- if (find_gpgconf && find_openpgp && find_cms && find_assuan)
- check_pass = true;
-
- if (!check_pass) {
- good = false;
- return;
- } else good = true;
-
-
-/** Setting the output type must be done at the beginning */
-/** think this means ascii-armor --> ? */
- gpgme_set_armor(mCtx, 1);
-/** passphrase-callback */
- gpgme_set_passphrase_cb(mCtx, passphraseCb, this);
-
-/** check if app is called with -d from command line */
- if (qApp->arguments().contains("-d")) {
- qDebug() << "gpgme_data_t debug on";
- debug = true;
- } else {
- debug = false;
- }
-
- connect(this, SIGNAL(signalKeyDBChanged()),
- this, SLOT(slotRefreshKeyList()), Qt::DirectConnection);
- connect(this, SIGNAL(signalKeyUpdated(QString)),
- this, SLOT(slotUpdateKeyList(QString)), Qt::DirectConnection);
- slotRefreshKeyList();
- }
-
- /** Destructor
- * Release gpgme-context
- */
- GpgContext::~GpgContext() {
- if (mCtx) gpgme_release(mCtx);
- mCtx = nullptr;
- }
-
- bool GpgContext::isGood() const {
- return good;
- }
-
- /** Read gpgme-Data to QByteArray
- * mainly from http://basket.kde.org/ (kgpgme.cpp)
- */
-#define BUF_SIZE (32 * 1024)
-
- gpgme_error_t GpgContext::readToBuffer(gpgme_data_t dataIn, QByteArray *outBuffer) {
- gpgme_off_t ret;
- gpgme_error_t gpgErrNoError = GPG_ERR_NO_ERROR;
-
- ret = gpgme_data_seek(dataIn, 0, SEEK_SET);
- if (ret) {
- gpgErrNoError = gpgme_err_code_from_errno(errno);
- checkErr(gpgErrNoError, "failed dataseek dataIn readToBuffer");
- } else {
- char buf[BUF_SIZE + 2];
-
- while ((ret = gpgme_data_read(dataIn, buf, BUF_SIZE)) > 0) {
- const size_t size = outBuffer->size();
- outBuffer->resize(static_cast<int>(size + ret));
- memcpy(outBuffer->data() + size, buf, ret);
- }
- if (ret < 0) {
- gpgErrNoError = gpgme_err_code_from_errno(errno);
- checkErr(gpgErrNoError, "failed data_read dataIn readToBuffer");
- }
- }
- return gpgErrNoError;
- }
-
- /**
- * The Passphrase window, if not provided by env-Var GPG_AGENT_INFO
- * originally copied from http://basket.kde.org/ (kgpgme.cpp), but modified
- */
- gpgme_error_t GpgContext::passphraseCb(void *hook, const char *uid_hint,
- const char *passphrase_info,
- int last_was_bad, int fd) {
- auto *gpg = static_cast<GpgContext *>(hook);
- return gpg->passphrase(uid_hint, passphrase_info, last_was_bad, fd);
- }
-
- gpgme_error_t GpgContext::passphrase(const char *uid_hint,
- const char * /*passphrase_info*/,
- int last_was_bad, int fd) {
-
- gpgme_error_t returnValue = GPG_ERR_CANCELED;
- QString passwordDialogMessage;
- QString gpgHint = QString::fromUtf8(uid_hint);
- bool result;
-
-#ifdef _WIN32
- DWORD written;
- auto hd = INT2VOIDP(fd);
-#endif
-
- if (last_was_bad) {
- passwordDialogMessage += "<i>" + tr("Wrong password") + ".</i><br><br>\n\n";
- clearPasswordCache();
- }
-
- /** if uid provided */
- if (!gpgHint.isEmpty()) {
- // remove UID, leave only username & email
- gpgHint.remove(0, gpgHint.indexOf(" "));
- passwordDialogMessage += "<b>" + tr("Enter Password for") + "</b><br>" + gpgHint + "<br>";
- }
-
- if (mPasswordCache.isEmpty()) {
- QString password = QInputDialog::getText(QApplication::activeWindow(), tr("Enter Password"),
- passwordDialogMessage, QLineEdit::Password,
- "", &result);
-
- if (result) mPasswordCache = password.toUtf8();
- } else result = true;
-
- if (result) {
-
-#ifndef _WIN32
- if (write(fd, mPasswordCache.data(), mPasswordCache.length()) == -1) qDebug() << "something is terribly broken";
-#else
- WriteFile(hd, mPasswordCache.data(), mPasswordCache.length(), &written, 0);
-#endif
- returnValue = GPG_ERR_NO_ERROR;
- }
-
-#ifndef _WIN32
- if (write(fd, "\n", 1) == -1) qDebug() << "something is terribly broken";
-#else
- WriteFile(hd, "\n", 1, &written, 0);
-
- /* program will hang on cancel if hd not closed */
- if (!result) CloseHandle(hd);
-#endif
-
- return returnValue;
- }
-
- /** also from kgpgme.cpp, seems to clear password from mem */
- void GpgContext::clearPasswordCache() {
- if (mPasswordCache.size() > 0) {
- mPasswordCache.fill('\0');
- mPasswordCache.truncate(0);
- }
- }
-
- // error-handling
- void GpgContext::checkErr(gpgme_error_t gpgmeError, const QString &comment) {
- //if (gpgmeError != GPG_ERR_NO_ERROR && gpgmeError != GPG_ERR_CANCELED) {
- if (gpgmeError != GPG_ERR_NO_ERROR) {
- qDebug() << "[Error " << gpg_err_code(gpgmeError)
- << "] Source: " << gpgme_strsource(gpgmeError) << " Description: " << gpgErrString(gpgmeError);
- }
- }
-
- void GpgContext::checkErr(gpgme_error_t gpgmeError) {
- //if (gpgmeError != GPG_ERR_NO_ERROR && gpgmeError != GPG_ERR_CANCELED) {
- if (gpg_err_code(gpgmeError) != GPG_ERR_NO_ERROR) {
- qDebug() << "[Error " << gpg_err_code(gpgmeError)
- << "] Source: " << gpgme_strsource(gpgmeError) << " Description: " << gpgErrString(gpgmeError);
- }
- }
-
- QString GpgContext::gpgErrString(gpgme_error_t err) {
- return QString::fromUtf8(gpgme_strerror(err));
- }
-
- /** return type should be gpgme_error_t*/
- void
- GpgContext::executeGpgCommand(const QStringList &arguments, const std::function<void(QProcess *)> &interactFunc) {
- QEventLoop looper;
- auto dialog = new WaitingDialog(tr("Processing"), nullptr);
- dialog->show();
- auto *gpgProcess = new QProcess(&looper);
- gpgProcess->setProcessChannelMode(QProcess::MergedChannels);
- connect(gpgProcess, qOverload<int, QProcess::ExitStatus>(&QProcess::finished), &looper, &QEventLoop::quit);
- connect(gpgProcess, qOverload<int, QProcess::ExitStatus>(&QProcess::finished), dialog,
- &WaitingDialog::deleteLater);
- connect(gpgProcess, &QProcess::errorOccurred, []() -> void { qDebug("Error in Process"); });
- connect(gpgProcess, &QProcess::errorOccurred, &looper, &QEventLoop::quit);
- connect(gpgProcess, &QProcess::started, []() -> void { qDebug() << "Gpg Process Started Success"; });
- connect(gpgProcess, &QProcess::readyReadStandardOutput, [interactFunc, gpgProcess]() {
- qDebug() << "Function Called";
- interactFunc(gpgProcess);
- });
- gpgProcess->setProgram(info.appPath);
- gpgProcess->setArguments(arguments);
- gpgProcess->start();
- looper.exec();
- dialog->close();
-
- }
-
-
- /*
- * if there is no '\n' before the PGP-Begin-Block, but for example a whitespace,
- * GPGME doesn't recognise the Message as encrypted. This function adds '\n'
- * before the PGP-Begin-Block, if missing.
- */
- void GpgContext::preventNoDataErr(QByteArray *in) {
- int block_start = in->indexOf(GpgConstants::PGP_CRYPT_BEGIN);
- if (block_start > 0 && in->at(block_start - 1) != '\n') {
- in->insert(block_start, '\n');
- }
- block_start = in->indexOf(GpgConstants::PGP_SIGNED_BEGIN);
- if (block_start > 0 && in->at(block_start - 1) != '\n') {
- in->insert(block_start, '\n');
- }
- }
-
- /*
- * isSigned returns:
- * - 0, if text isn't signed at all
- * - 1, if text is partially signed
- * - 2, if text is completly signed
- */
- int GpgContext::textIsSigned(const QByteArray &text) {
- if (text.trimmed().startsWith(GpgConstants::PGP_SIGNED_BEGIN) &&
- text.trimmed().endsWith(GpgConstants::PGP_SIGNED_END))
- return 2;
- else if (text.contains(GpgConstants::PGP_SIGNED_BEGIN) && text.contains(GpgConstants::PGP_SIGNED_END))
- return 1;
-
- else return 0;
- }
-
- QString GpgContext::beautifyFingerprint(QString fingerprint) {
- uint len = fingerprint.length();
- if ((len > 0) && (len % 4 == 0))
- for (uint n = 0; 4 * (n + 1) < len; ++n) fingerprint.insert(static_cast<int>(5u * n + 4u), ' ');
- return fingerprint;
- }
-
- void GpgContext::slotRefreshKeyList() {
- qDebug() << "Refreshing Keys";
- this->fetch_keys();
- emit signalKeyInfoChanged();
- }
-
- QString GpgContext::getGpgmeVersion() {
- return {gpgme_check_version(nullptr)};
- }
-
- const GpgKeyList &GpgContext::getKeys() const {
- return mKeyList;
- }
-
- void GpgContext::getSigners(QVector<GpgKey> &signer, gpgme_ctx_t ctx) {
- auto count = gpgme_signers_count(ctx);
- signer.clear();
- for (auto i = 0; i < count; i++) {
- auto key = gpgme_signers_enum(ctx, i);
- auto it = mKeyMap.find(key->subkeys->keyid);
- if (it == mKeyMap.end()) {
- qDebug() << "Inconsistent state";
- signer.push_back(GpgKey(key));
- } else {
- signer.push_back(*it.value());
- }
- }
- }
-
- void GpgContext::setSigners(const QVector<GpgKey> &keys, gpgme_ctx_t ctx) {
- gpgme_signers_clear(ctx);
- for (const auto &key : keys) {
- if (checkIfKeyCanSign(key)) {
- auto gpgmeError = gpgme_signers_add(ctx, key.key_refer);
- checkErr(gpgmeError);
- }
- }
- if (keys.length() != gpgme_signers_count(ctx)) {
- qDebug() << "No All Keys Added";
- }
- }
-
- void GpgContext::slotUpdateKeyList(const QString &key_id) {
- auto it = mKeyMap.find(key_id);
- if (it != mKeyMap.end()) {
- gpgme_key_t new_key_refer;
- auto gpgmeErr = gpgme_get_key(mCtx, key_id.toUtf8().constData(), &new_key_refer, 0);
-
- if (gpgme_err_code(gpgmeErr) == GPG_ERR_EOF) {
- gpgmeErr = gpgme_get_key(mCtx, key_id.toUtf8().constData(), &new_key_refer, 1);
-
- if (gpgme_err_code(gpgmeErr) == GPG_ERR_EOF) {
- throw std::runtime_error("key_id not found in key database");
- }
-
- }
-
- if (new_key_refer != nullptr) {
- it.value()->swapKeyRefer(new_key_refer);
- emit signalKeyInfoChanged();
- }
-
- }
- }
-
- bool GpgContext::revSign(const GpgKey &key, const GpgKeySignature &signature) {
-
- auto signing_key = getKeyById(signature.keyid);
-
- auto gpgmeError = gpgme_op_revsig(mCtx, key.key_refer,
- signing_key.key_refer,
- signature.uid.toUtf8().constData(), 0);
- if (gpg_err_code(gpgmeError) == GPG_ERR_NO_ERROR) {
- emit signalKeyUpdated(key.id);
- return true;
- } else {
- checkErr(gpgmeError);
- return false;
- }
- }
-
- gpgme_ctx_t GpgME::GpgContext::create_ctx() {
- gpgme_ctx_t ctx;
- err = gpgme_new(&ctx);
- checkErr(err);
-
- gpgme_set_armor(ctx, 1);
- gpgme_set_passphrase_cb(ctx, passphraseCb, this);
- return ctx;
- }
-
-
-}
diff --git a/src/gpg/gpg_context/GpgContextBasicOpera.cpp b/src/gpg/gpg_context/GpgContextBasicOpera.cpp
deleted file mode 100644
index d9bf0bdb..00000000
--- a/src/gpg/gpg_context/GpgContextBasicOpera.cpp
+++ /dev/null
@@ -1,315 +0,0 @@
-/**
- * This file is part of GPGFrontend.
- *
- * GPGFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Foobar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from gpg4usb-team.
- * Their source code version also complies with GNU General Public License.
- *
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]> starting on May 12, 2021.
- *
- */
-
-#include "gpg/GpgContext.h"
-
-/**
- * Encrypt data
- * @param keys keys used
- * @param inBuffer input byte array
- * @param outBuffer output byte array
- * @param result opera result
- * @return error information
- */
-gpg_error_t GpgME::GpgContext::encrypt(QVector<GpgKey> &keys, const QByteArray &inBuffer, QByteArray *outBuffer,
- gpgme_encrypt_result_t *result) {
-
- gpgme_data_t dataIn = nullptr, dataOut = nullptr;
- outBuffer->resize(0);
-
- // gpgme_encrypt_result_t e_result;
- gpgme_key_t recipients[keys.count() + 1];
-
- int index = 0;
- for (const auto &key : keys) recipients[index++] = key.key_refer;
-
- // Last entry dataIn array has to be nullptr
- recipients[keys.count()] = nullptr;
-
- // If the last parameter isnt 0, a private copy of data is made
- if (mCtx) {
- err = gpgme_data_new_from_mem(&dataIn, inBuffer.data(), inBuffer.size(), 1);
- checkErr(err);
- if (!err) {
- err = gpgme_data_new(&dataOut);
- checkErr(err);
- if (!err) {
- err = gpgme_op_encrypt(mCtx, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, dataIn, dataOut);
- checkErr(err);
- if (!err) {
- err = readToBuffer(dataOut, outBuffer);
- checkErr(err);
- }
- }
- }
- }
- if (dataIn) gpgme_data_release(dataIn);
- if (dataOut) gpgme_data_release(dataOut);
-
- if (result != nullptr) *result = gpgme_op_encrypt_result(mCtx);
- return err;
-}
-
-/**
- * Decrypt data
- * @param keys keys used
- * @param inBuffer input byte array
- * @param outBuffer output byte array
- * @param result opera result
- * @return error information
- */
-gpgme_error_t GpgME::GpgContext::decrypt(const QByteArray &inBuffer, QByteArray *outBuffer,
- gpgme_decrypt_result_t *result) {
- gpgme_data_t dataIn = nullptr, dataOut = nullptr;
- gpgme_decrypt_result_t m_result = nullptr;
-
- outBuffer->resize(0);
- if (mCtx != nullptr) {
- err = gpgme_data_new_from_mem(&dataIn, inBuffer.data(), inBuffer.size(), 1);
- if (gpgme_err_code(err) == GPG_ERR_NO_ERROR) {
- err = gpgme_data_new(&dataOut);
- if (gpgme_err_code(err) == GPG_ERR_NO_ERROR) {
- err = gpgme_op_decrypt(mCtx, dataIn, dataOut);
- m_result = gpgme_op_decrypt_result(mCtx);
- if (gpgme_err_code(err) == GPG_ERR_NO_ERROR) err = readToBuffer(dataOut, outBuffer);
- }
- }
- }
-
- if (!settings.value("general/rememberPassword").toBool()) clearPasswordCache();
-
- if (dataIn) gpgme_data_release(dataIn);
- if (dataOut) gpgme_data_release(dataOut);
-
- if (result != nullptr) *result = m_result;
-
- return err;
-}
-
-/**
- * Verify data
- * @param keys keys used
- * @param inBuffer input byte array
- * @param sigBuffer signature byte array (detected by format)
- * @param result opera result
- * @return error information
- */
-gpgme_error_t GpgME::GpgContext::verify(QByteArray *inBuffer, QByteArray *sigBuffer, gpgme_verify_result_t *result) {
-
- gpgme_data_t dataIn;
- gpgme_error_t gpgmeError;
- gpgme_verify_result_t m_result;
-
- gpgmeError = gpgme_data_new_from_mem(&dataIn, inBuffer->data(), inBuffer->size(), 1);
- checkErr(gpgmeError);
-
- if (sigBuffer != nullptr) {
- gpgme_data_t sigdata;
- gpgmeError = gpgme_data_new_from_mem(&sigdata, sigBuffer->data(), sigBuffer->size(), 1);
- checkErr(gpgmeError);
- gpgmeError = gpgme_op_verify(mCtx, sigdata, dataIn, nullptr);
- } else {
- gpgmeError = gpgme_op_verify(mCtx, dataIn, nullptr, dataIn);
- }
-
- checkErr(gpgmeError);
-
- m_result = gpgme_op_verify_result(mCtx);
-
- if (result != nullptr) {
- *result = m_result;
- }
-
- return gpgmeError;
-}
-
-/**
- * Sign data
- * @param keys keys used
- * @param inBuffer input byte array
- * @param outBuffer output byte array
- * @param mode sign mode
- * @param result opera result
- * @return
- */
-gpg_error_t GpgME::GpgContext::sign(const QVector<GpgKey> &keys, const QByteArray &inBuffer, QByteArray *outBuffer,
- gpgme_sig_mode_t mode, gpgme_sign_result_t *result, bool default_ctx) {
-
- gpgme_error_t gpgmeError;
- gpgme_data_t dataIn, dataOut;
- gpgme_sign_result_t m_result;
-
- auto _ctx = mCtx;
-
- if(!default_ctx)
- _ctx = create_ctx();
-
- if (keys.isEmpty()) {
- QMessageBox::critical(nullptr, tr("Key Selection"), tr("No Private Key Selected"));
- return false;
- }
-
- // Set Singers of this opera
- setSigners(keys, _ctx);
-
- gpgmeError = gpgme_data_new_from_mem(&dataIn, inBuffer.data(), inBuffer.size(), 1);
- checkErr(gpgmeError);
- gpgmeError = gpgme_data_new(&dataOut);
- checkErr(gpgmeError);
-
- /**
- `GPGME_SIG_MODE_NORMAL'
- A normal signature is made, the output includes the plaintext
- and the signature.
-
- `GPGME_SIG_MODE_DETACH'
- A detached signature is made.
-
- `GPGME_SIG_MODE_CLEAR'
- A clear text signature is made. The ASCII armor and text
- mode settings of the context are ignored.
- */
-
- gpgmeError = gpgme_op_sign(_ctx, dataIn, dataOut, mode);
- checkErr(gpgmeError);
-
- if (gpgmeError == GPG_ERR_CANCELED) return false;
-
- if (gpgmeError != GPG_ERR_NO_ERROR) {
- QMessageBox::critical(nullptr, tr("Error in signing:"), QString::fromUtf8(gpgme_strerror(gpgmeError)));
- return false;
- }
-
- if(default_ctx)
- m_result = gpgme_op_sign_result(_ctx);
- else m_result = nullptr;
-
- if (result != nullptr) *result = m_result;
-
- if(!default_ctx) gpgme_release(_ctx);
-
- gpgmeError = readToBuffer(dataOut, outBuffer);
- checkErr(gpgmeError);
-
- gpgme_data_release(dataIn);
- gpgme_data_release(dataOut);
-
- // Of no use yet
- if (!settings.value("general/rememberPassword").toBool()) clearPasswordCache();
-
- return gpgmeError;
-}
-
-/**
- * Encrypt and sign data
- * @param keys keys used
- * @param inBuffer input byte array
- * @param outBuffer output byte array
- * @param encr_result encrypt opera result
- * @param sign_result sign opera result
- * @return
- */
-gpgme_error_t
-GpgME::GpgContext::encryptSign(QVector<GpgKey> &keys, QVector<GpgKey> &signers, const QByteArray &inBuffer,
- QByteArray *outBuffer, gpgme_encrypt_result_t *encr_result,
- gpgme_sign_result_t *sign_result) {
- gpgme_data_t data_in = nullptr, data_out = nullptr;
- outBuffer->resize(0);
-
- setSigners(signers, mCtx);
-
- //gpgme_encrypt_result_t e_result;
- gpgme_key_t recipients[keys.count() + 1];
-
- // set key for user
- int index = 0;
- for (const auto &key : keys) recipients[index++] = key.key_refer;
-
- // Last entry dataIn array has to be nullptr
- recipients[keys.count()] = nullptr;
-
- // If the last parameter isnt 0, a private copy of data is made
- if (mCtx != nullptr) {
- err = gpgme_data_new_from_mem(&data_in, inBuffer.data(), inBuffer.size(), 1);
- if (gpg_err_code(err) == GPG_ERR_NO_ERROR) {
- err = gpgme_data_new(&data_out);
- if (gpg_err_code(err) == GPG_ERR_NO_ERROR) {
- err = gpgme_op_encrypt_sign(mCtx, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out);
- if (encr_result != nullptr)
- *encr_result = gpgme_op_encrypt_result(mCtx);
- if (sign_result != nullptr)
- *sign_result = gpgme_op_sign_result(mCtx);
- if (gpg_err_code(err) == GPG_ERR_NO_ERROR) {
- err = readToBuffer(data_out, outBuffer);
- }
- }
- }
- }
-
- if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) checkErr(err);
-
- if (data_in) gpgme_data_release(data_in);
- if (data_out) gpgme_data_release(data_out);
-
- return err;
-}
-
-/**
- * Decrypt and verify data
- * @param inBuffer input byte array
- * @param outBuffer output byte array
- * @param decrypt_result decrypt opera result
- * @param verify_result verify opera result
- * @return error info
- */
-gpgme_error_t GpgME::GpgContext::decryptVerify(const QByteArray &inBuffer, QByteArray *outBuffer,
- gpgme_decrypt_result_t *decrypt_result,
- gpgme_verify_result_t *verify_result) {
- gpgme_data_t data_in = nullptr, data_out = nullptr;
-
- outBuffer->resize(0);
- if (mCtx != nullptr) {
- err = gpgme_data_new_from_mem(&data_in, inBuffer.data(), inBuffer.size(), 1);
- if (gpgme_err_code(err) == GPG_ERR_NO_ERROR) {
- err = gpgme_data_new(&data_out);
- if (gpgme_err_code(err) == GPG_ERR_NO_ERROR) {
- err = gpgme_op_decrypt_verify(mCtx, data_in, data_out);
- if (decrypt_result != nullptr)
- *decrypt_result = gpgme_op_decrypt_result(mCtx);
- if (verify_result != nullptr)
- *verify_result = gpgme_op_verify_result(mCtx);
- if (gpgme_err_code(err) == GPG_ERR_NO_ERROR) {
- err = readToBuffer(data_out, outBuffer);
- }
- }
- }
- }
-
- if (!settings.value("general/rememberPassword").toBool()) clearPasswordCache();
-
- if (data_in) gpgme_data_release(data_in);
- if (data_out) gpgme_data_release(data_out);
-
- return err;
-}
diff --git a/src/gpg/gpg_context/GpgContextKeyInfo.cpp b/src/gpg/gpg_context/GpgContextKeyInfo.cpp
deleted file mode 100644
index f6942e4e..00000000
--- a/src/gpg/gpg_context/GpgContextKeyInfo.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/**
- * This file is part of GPGFrontend.
- *
- * GPGFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Foobar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from gpg4usb-team.
- * Their source code version also complies with GNU General Public License.
- *
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]> starting on May 12, 2021.
- *
- */
-
-#include "gpg/GpgContext.h"
-
-/**
- * check if key can sign(actually)
- * @param key target key
- * @return if key sign
- */
-bool GpgME::GpgContext::checkIfKeyCanSign(const GpgKey &key) {
- if (std::any_of(key.subKeys.begin(), key.subKeys.end(), [](const GpgSubKey &subkey) -> bool {
- return subkey.secret && subkey.can_sign && !subkey.disabled && !subkey.revoked && !subkey.expired;
- }))
- return true;
- else return false;
-}
-
-/**
- * check if key can certify(actually)
- * @param key target key
- * @return if key certify
- */
-bool GpgME::GpgContext::checkIfKeyCanCert(const GpgKey &key) {
- return key.has_master_key && !key.expired && !key.revoked && !key.disabled;
-}
-
-/**
- * check if key can authenticate(actually)
- * @param key target key
- * @return if key authenticate
- */
-bool GpgME::GpgContext::checkIfKeyCanAuth(const GpgKey &key) {
- if (std::any_of(key.subKeys.begin(), key.subKeys.end(), [](const GpgSubKey &subkey) -> bool {
- return subkey.secret && subkey.can_authenticate && !subkey.disabled && !subkey.revoked && !subkey.expired;
- }))
- return true;
- else return false;
-}
-
-/**
- * check if key can encrypt(actually)
- * @param key target key
- * @return if key encrypt
- */
-bool GpgME::GpgContext::checkIfKeyCanEncr(const GpgKey &key) {
- if (std::any_of(key.subKeys.begin(), key.subKeys.end(), [](const GpgSubKey &subkey) -> bool {
- return subkey.can_encrypt && !subkey.disabled && !subkey.revoked && !subkey.expired;
- }))
- return true;
- else return false;
-}
-
-/**
- * Get target key
- * @param fpr master key's fingerprint
- * @return the key
- */
-GpgKey GpgME::GpgContext::getKeyByFpr(const QString &fpr) {
- for (const auto &key : mKeyList) {
- if (key.fpr == fpr) return key;
- else
- for (auto &subkey : key.subKeys) {
- if (subkey.fpr == fpr) return key;
- }
- }
- return GpgKey(nullptr);
-}
-
-
-/**
- * Get target key
- * @param id master key's id
- * @return the key
- */
-GpgKey GpgME::GpgContext::getKeyById(const QString &id) {
-
- for (const auto &key : mKeyList) {
- if (key.id == id) return key;
- else {
- auto sub_keys = key.subKeys;
- for (const auto &subkey : sub_keys) {
- if (subkey.id == id) return key;
- }
- }
- }
-
- return GpgKey(nullptr);
-}
diff --git a/src/gpg/gpg_context/GpgContextKeyOpera.cpp b/src/gpg/gpg_context/GpgContextKeyOpera.cpp
deleted file mode 100644
index a224231d..00000000
--- a/src/gpg/gpg_context/GpgContextKeyOpera.cpp
+++ /dev/null
@@ -1,410 +0,0 @@
-/**
- * This file is part of GPGFrontend.
- *
- * GPGFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Foobar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from gpg4usb-team.
- * Their source code version also complies with GNU General Public License.
- *
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]> starting on May 12, 2021.
- *
- */
-
-#include "gpg/GpgContext.h"
-
-/**
- * Import key pair
- * @param inBuffer input byte array
- * @return Import information
- */
-GpgImportInformation GpgME::GpgContext::importKey(QByteArray inBuffer) {
- auto *importInformation = new GpgImportInformation();
- err = gpgme_data_new_from_mem(&in, inBuffer.data(), inBuffer.size(), 1);
- checkErr(err);
- err = gpgme_op_import(mCtx, in);
- gpgme_import_result_t result;
-
- result = gpgme_op_import_result(mCtx);
-
- if (result->unchanged) importInformation->unchanged = result->unchanged;
- if (result->considered) importInformation->considered = result->considered;
- if (result->no_user_id) importInformation->no_user_id = result->no_user_id;
- if (result->imported) importInformation->imported = result->imported;
- if (result->imported_rsa) importInformation->imported_rsa = result->imported_rsa;
- if (result->unchanged) importInformation->unchanged = result->unchanged;
- if (result->new_user_ids) importInformation->new_user_ids = result->new_user_ids;
- if (result->new_sub_keys) importInformation->new_sub_keys = result->new_sub_keys;
- if (result->new_signatures) importInformation->new_signatures = result->new_signatures;
- if (result->new_revocations) importInformation->new_revocations = result->new_revocations;
- if (result->secret_read) importInformation->secret_read = result->secret_read;
- if (result->secret_imported) importInformation->secret_imported = result->secret_imported;
- if (result->secret_unchanged) importInformation->secret_unchanged = result->secret_unchanged;
- if (result->not_imported) importInformation->not_imported = result->not_imported;
-
- gpgme_import_status_t status = result->imports;
- while (status != nullptr) {
- GpgImportedKey key;
- key.importStatus = static_cast<int>(status->status);
- key.fpr = status->fpr;
- importInformation->importedKeys.emplace_back(key);
- status = status->next;
- }
- checkErr(err);
- emit signalKeyDBChanged();
- gpgme_data_release(in);
- return *importInformation;
-}
-
-/**
- * Generate a new key pair
- * @param params key generation args
- * @return error information
- */
-gpgme_error_t GpgME::GpgContext::generateKey(GenKeyInfo *params) {
-
- auto userid_utf8 = params->getUserid().toUtf8();
- const char *userid = userid_utf8.constData();
- auto algo_utf8 = (params->getAlgo() + params->getKeySizeStr()).toUtf8();
- const char *algo = algo_utf8.constData();
- unsigned long expires = QDateTime::currentDateTime().secsTo(params->getExpired());
- unsigned int flags = 0;
-
- if (!params->isSubKey()) flags |= GPGME_CREATE_CERT;
- if (params->isAllowEncryption()) flags |= GPGME_CREATE_ENCR;
- if (params->isAllowSigning()) flags |= GPGME_CREATE_SIGN;
- if (params->isAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
- if (params->isNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
- if (params->isNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
-
- err = gpgme_op_createkey(mCtx, userid, algo, 0, expires, nullptr, flags);
-
- if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) {
- checkErr(err);
- return err;
- } else {
- emit signalKeyDBChanged();
- return err;
- }
-}
-
-/**
- * Export Key
- * @param uidList key ids
- * @param outBuffer output byte array
- * @return if success
- */
-bool GpgME::GpgContext::exportKeys(QStringList *uidList, QByteArray *outBuffer) {
- gpgme_data_t dataOut = nullptr;
- outBuffer->resize(0);
-
- if (uidList->count() == 0) {
- QMessageBox::critical(nullptr, "Export Keys Error", "No Keys Selected");
- return false;
- }
-
- // Alleviate another crash problem caused by an unknown array out-of-bounds access
- gpgme_ctx_t ctx = create_ctx();
-
- for (int i = 0; i < uidList->count(); i++) {
- err = gpgme_data_new(&dataOut);
- checkErr(err);
-
- err = gpgme_op_export(ctx, uidList->at(i).toUtf8().constData(), 0, dataOut);
- checkErr(err);
-
- qDebug() << "exportKeys read_bytes" << gpgme_data_seek(dataOut, 0, SEEK_END);
-
- err = readToBuffer(dataOut, outBuffer);
- checkErr(err);
- gpgme_data_release(dataOut);
- }
-
- gpgme_release(ctx);
-
- return true;
-}
-
-/**
- * Get and store all key pairs info
- */
-void GpgME::GpgContext::fetch_keys() {
-
- gpgme_error_t gpgmeError;
-
- gpgme_key_t key;
-
- qDebug() << "Clear List and Map";
-
- mKeyList.clear();
- mKeyMap.clear();
-
- auto &keys = mKeyList;
- auto &keys_map = mKeyMap;
-
- qDebug() << "Set Key Listing Mode";
-
- gpgmeError = gpgme_set_keylist_mode(mCtx,
- GPGME_KEYLIST_MODE_LOCAL
- | GPGME_KEYLIST_MODE_WITH_SECRET
- | GPGME_KEYLIST_MODE_SIGS
- | GPGME_KEYLIST_MODE_SIG_NOTATIONS
- | GPGME_KEYLIST_MODE_WITH_TOFU);
- if (gpg_err_code(gpgmeError) != GPG_ERR_NO_ERROR) {
- checkErr(gpgmeError);
- return;
- }
-
- qDebug() << "Operate KeyList Start";
-
- gpgmeError = gpgme_op_keylist_start(mCtx, nullptr, 0);
- if (gpg_err_code(gpgmeError) != GPG_ERR_NO_ERROR) {
- checkErr(gpgmeError);
- return;
- }
-
- qDebug() << "Start Loop";
-
- while ((gpgmeError = gpgme_op_keylist_next(mCtx, &key)) == GPG_ERR_NO_ERROR) {
- if (!key->subkeys)
- continue;
-
- qDebug() << "Append Key" << key->subkeys->keyid;
-
- keys.emplace_back(key);
- keys_map.insert(keys.back().id, &keys.back());
- gpgme_key_unref(key);
- }
-
-
- if (gpg_err_code(gpgmeError) != GPG_ERR_EOF) {
- checkErr(gpgmeError);
- return;
- }
-
- gpgmeError = gpgme_op_keylist_end(mCtx);
- if (gpg_err_code(gpgmeError) != GPG_ERR_NO_ERROR) {
- checkErr(gpgmeError);
- return;
- }
-
- qDebug() << "Operate KeyList End";
-
- mKeyList = keys;
-}
-
-/**
- * Delete keys
- * @param uidList key ids
- */
-void GpgME::GpgContext::deleteKeys(QStringList *uidList) {
-
- gpgme_error_t error;
- gpgme_key_t key;
-
- for (const auto &tmp : *uidList) {
-
- error = gpgme_op_keylist_start(mCtx, tmp.toUtf8().constData(), 0);
- if (error != GPG_ERR_NO_ERROR) {
- checkErr(error);
- continue;
- }
-
- error = gpgme_op_keylist_next(mCtx, &key);
- if (error != GPG_ERR_NO_ERROR) {
- checkErr(error);
- continue;
- }
-
- error = gpgme_op_keylist_end(mCtx);
- if (error != GPG_ERR_NO_ERROR) {
- checkErr(error);
- continue;
- }
-
- error = gpgme_op_delete(mCtx, key, 1);
- if (error != GPG_ERR_NO_ERROR) {
- checkErr(error);
- continue;
- }
-
- }
- emit signalKeyDBChanged();
-}
-
-/**
- * Export keys
- * @param keys keys used
- * @param outBuffer output byte array
- * @return if success
- */
-bool GpgME::GpgContext::exportKeys(const QVector<GpgKey> &keys, QByteArray &outBuffer) {
- gpgme_data_t data_out = nullptr;
- outBuffer.resize(0);
-
- if (keys.empty()) {
- QMessageBox::critical(nullptr, "Export Keys Error", "No Keys Selected");
- return false;
- }
-
- for (const auto &key : keys) {
- err = gpgme_data_new(&data_out);
- checkErr(err);
-
- err = gpgme_op_export(mCtx, key.id.toUtf8().constData(), 0, data_out);
- checkErr(err);
-
- gpgme_data_seek(data_out, 0, SEEK_END);
-
- err = readToBuffer(data_out, &outBuffer);
- checkErr(err);
- gpgme_data_release(data_out);
- }
-
- return true;
-}
-
-/**
- * Set the expire date and time of a key pair(actually the master key) or subkey
- * @param key target key pair
- * @param subkey null if master key
- * @param expires date and time
- * @return if successful
- */
-bool GpgME::GpgContext::setExpire(const GpgKey &key, const GpgSubKey *subkey, QDateTime *expires) {
- unsigned long expires_time = 0;
- if (expires != nullptr) {
- qDebug() << "Expire Datetime" << expires->toString();
- expires_time = QDateTime::currentDateTime().secsTo(*expires);
- }
-
- const char *subfprs = nullptr;
-
- if (subkey != nullptr) subfprs = subkey->fpr.toUtf8().constData();
-
- auto gpgmeError = gpgme_op_setexpire(mCtx, key.key_refer,
- expires_time, subfprs, 0);
- if (gpgmeError == GPG_ERR_NO_ERROR) {
- emit signalKeyUpdated(key.id);
- return true;
- } else {
- checkErr(gpgmeError);
- return false;
- }
-}
-
-/**
- * Export the secret key of a key pair(including subkeys)
- * @param key target key pair
- * @param outBuffer output byte array
- * @return if successful
- */
-bool GpgME::GpgContext::exportSecretKey(const GpgKey &key, QByteArray *outBuffer) {
- qDebug() << "Export Secret Key" << key.id;
- gpgme_key_t target_key[2] = {
- key.key_refer,
- nullptr
- };
-
- gpgme_data_t dataOut;
- gpgme_data_new(&dataOut);
-
- // export private key to outBuffer
- gpgme_error_t error = gpgme_op_export_keys(mCtx, target_key, GPGME_EXPORT_MODE_SECRET, dataOut);
-
- if (gpgme_err_code(error) != GPG_ERR_NO_ERROR) {
- checkErr(error);
- gpgme_data_release(dataOut);
- return false;
- }
-
- readToBuffer(dataOut, outBuffer);
- gpgme_data_release(dataOut);
- return true;
-}
-
-/**
- * Sign a key pair(actually a certain uid)
- * @param target target key pair
- * @param uid target
- * @param expires expire date and time of the signature
- * @return if successful
- */
-bool GpgME::GpgContext::signKey(const GpgKey &target, const QVector<GpgKey> &keys, const QString &uid,
- const QDateTime *expires) {
-
- setSigners(keys, mCtx);
-
- unsigned int flags = 0;
-
- unsigned int expires_time_t = 0;
- if (expires == nullptr) flags |= GPGME_KEYSIGN_NOEXPIRE;
- else expires_time_t = QDateTime::currentDateTime().secsTo(*expires);
-
- auto gpgmeError =
- gpgme_op_keysign(mCtx, target.key_refer, uid.toUtf8().constData(), expires_time_t, flags);
-
- if (gpgmeError == GPG_ERR_NO_ERROR) {
- emit signalKeyUpdated(target.id);
- return true;
- } else {
- checkErr(gpgmeError);
- return false;
- }
-}
-
-/**
- * Generate revoke cert of a key pair
- * @param key target key pair
- * @param outputFileName out file name(path)
- * @return the process doing this job
- */
-void GpgME::GpgContext::generateRevokeCert(const GpgKey &key, const QString &outputFileName) {
- executeGpgCommand({
- "--command-fd",
- "0",
- "--status-fd",
- "1",
- //"--no-tty",
- "-o",
- outputFileName,
- "--gen-revoke",
- key.fpr
- },
- [](QProcess *proc) -> void {
- qDebug() << "Function Called" << proc;
- // Code From Gpg4Win
- while (proc->canReadLine()) {
- const QString line = QString::fromUtf8(proc->readLine()).trimmed();
- if (line == QLatin1String("[GNUPG:] GET_BOOL gen_revoke.okay")) {
- proc->write("y\n");
- } else if (line == QLatin1String(
- "[GNUPG:] GET_LINE ask_revocation_reason.code")) {
- proc->write("0\n");
- } else if (line == QLatin1String(
- "[GNUPG:] GET_LINE ask_revocation_reason.text")) {
- proc->write("\n");
- } else if (line == QLatin1String(
- "[GNUPG:] GET_BOOL openfile.overwrite.okay")) {
- // We asked before
- proc->write("y\n");
- } else if (line == QLatin1String(
- "[GNUPG:] GET_BOOL ask_revocation_reason.okay")) {
- proc->write("y\n");
- }
- }
- // Code From Gpg4Win
- }
- );
-}
diff --git a/src/gpg/gpg_context/GpgContextSubkeyOpera.cpp b/src/gpg/gpg_context/GpgContextSubkeyOpera.cpp
deleted file mode 100644
index 10243f5e..00000000
--- a/src/gpg/gpg_context/GpgContextSubkeyOpera.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * This file is part of GPGFrontend.
- *
- * GPGFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Foobar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from gpg4usb-team.
- * Their source code version also complies with GNU General Public License.
- *
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]> starting on May 12, 2021.
- *
- */
-
-#include "gpg/GpgContext.h"
-
-/**
- * Generate a new subkey of a certain key pair
- * @param key target key pair
- * @param params opera args
- * @return error info
- */
-gpgme_error_t GpgME::GpgContext::generateSubkey(const GpgKey &key, GenKeyInfo *params) {
-
- if (!params->isSubKey()) return GPG_ERR_CANCELED;
-
- auto algo_utf8 = (params->getAlgo() + params->getKeySizeStr()).toUtf8();
- const char *algo = algo_utf8.constData();
- unsigned long expires = QDateTime::currentDateTime().secsTo(params->getExpired());
- unsigned int flags = 0;
-
- if (!params->isSubKey()) flags |= GPGME_CREATE_CERT;
- if (params->isAllowEncryption()) flags |= GPGME_CREATE_ENCR;
- if (params->isAllowSigning()) flags |= GPGME_CREATE_SIGN;
- if (params->isAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
- if (params->isNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
-
- flags |= GPGME_CREATE_NOPASSWD;
-
-
- auto gpgmeError = gpgme_op_createsubkey(mCtx, key.key_refer,
- algo, 0, expires, flags);
- if (gpgme_err_code(gpgmeError) == GPG_ERR_NO_ERROR) {
- emit signalKeyUpdated(key.id);
- return gpgmeError;
- } else {
- checkErr(gpgmeError);
- return gpgmeError;
- }
-}
-
diff --git a/src/gpg/gpg_context/GpgContextUIDOpera.cpp b/src/gpg/gpg_context/GpgContextUIDOpera.cpp
deleted file mode 100644
index b96f5f8f..00000000
--- a/src/gpg/gpg_context/GpgContextUIDOpera.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * This file is part of GPGFrontend.
- *
- * GPGFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Foobar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from gpg4usb-team.
- * Their source code version also complies with GNU General Public License.
- *
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]> starting on May 12, 2021.
- *
- */
-
-#include "gpg/GpgContext.h"
-
-/**
- * create a new uid in certain key pair
- * @param key target key pair
- * @param uid uid args
- * @return if successful
- */
-bool GpgME::GpgContext::addUID(const GpgKey &key, const GpgUID &uid) {
- QString userid = QString("%1 (%3) <%2>").arg(uid.name, uid.email, uid.comment);
- auto gpgmeError = gpgme_op_adduid(mCtx, key.key_refer, userid.toUtf8().constData(), 0);
- if (gpgmeError == GPG_ERR_NO_ERROR) {
- emit signalKeyUpdated(key.id);
- return true;
- } else {
- checkErr(gpgmeError);
- return false;
- }
-
-}
-
-/**
- * Revoke(Delete) UID from certain key pair
- * @param key target key pair
- * @param uid target uid
- * @return if successful
- */
-bool GpgME::GpgContext::revUID(const GpgKey &key, const GpgUID &uid) {
- auto gpgmeError = gpgme_op_revuid(mCtx, key.key_refer, uid.uid.toUtf8().constData(), 0);
- if (gpgmeError == GPG_ERR_NO_ERROR) {
- emit signalKeyUpdated(key.id);
- return true;
- } else {
- checkErr(gpgmeError);
- return false;
- }
-}
-
-/**
- * Set one of a uid of a key pair as primary
- * @param key target key pair
- * @param uid target uid
- * @return if successful
- */
-bool GpgME::GpgContext::setPrimaryUID(const GpgKey &key, const GpgUID &uid) {
- auto gpgmeError = gpgme_op_set_uid_flag(mCtx, key.key_refer,
- uid.uid.toUtf8().constData(), "primary", nullptr);
- if (gpgmeError == GPG_ERR_NO_ERROR) {
- emit signalKeyUpdated(key.id);
- return true;
- } else {
- checkErr(gpgmeError);
- return false;
- }
-}
-
diff --git a/src/gpg/model/GpgData.cpp b/src/gpg/model/GpgData.cpp
new file mode 100644
index 00000000..c6e9b2ce
--- /dev/null
+++ b/src/gpg/model/GpgData.cpp
@@ -0,0 +1,74 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "gpg/model/GpgData.h"
+
+GpgFrontend::GpgData::GpgData() {
+ gpgme_data_t data;
+
+ auto err = gpgme_data_new(&data);
+ assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
+
+ data_ =
+ std::unique_ptr<struct gpgme_data, __data_ref_deletor>(std::move(data));
+}
+
+GpgFrontend::GpgData::GpgData(void* buffer, size_t size, bool copy) {
+ gpgme_data_t data;
+
+ auto err = gpgme_data_new_from_mem(&data, (const char*)buffer, size, copy);
+ assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
+
+ data_ =
+ std::unique_ptr<struct gpgme_data, __data_ref_deletor>(std::move(data));
+}
+
+/**
+ * Read gpgme-Data to QByteArray
+ * mainly from http://basket.kde.org/ (kgpgme.cpp)
+ */
+#define BUF_SIZE (32 * 1024)
+
+GpgFrontend::ByteArrayPtr GpgFrontend::GpgData::Read2Buffer() {
+ gpgme_off_t ret = gpgme_data_seek(*this, 0, SEEK_SET);
+ ByteArrayPtr out_buffer = std::make_unique<std::string>();
+
+ if (ret) {
+ gpgme_error_t err = gpgme_err_code_from_errno(errno);
+ assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
+ } else {
+ char buf[BUF_SIZE + 2];
+
+ while ((ret = gpgme_data_read(*this, buf, BUF_SIZE)) > 0) {
+ const size_t size = out_buffer->size();
+ out_buffer->resize(static_cast<int>(size + ret));
+ memcpy(out_buffer->data() + size, buf, ret);
+ }
+ if (ret < 0) {
+ gpgme_error_t err = gpgme_err_code_from_errno(errno);
+ assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
+ }
+ }
+ return out_buffer;
+} \ No newline at end of file
diff --git a/src/gpg/model/GpgData.h b/src/gpg/model/GpgData.h
new file mode 100644
index 00000000..e3202af6
--- /dev/null
+++ b/src/gpg/model/GpgData.h
@@ -0,0 +1,54 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef _GPGDATA_H
+#define _GPGDATA_H
+
+#include "gpg/GpgConstants.h"
+
+namespace GpgFrontend {
+
+class GpgData {
+ public:
+ GpgData();
+
+ GpgData(void* buffer, size_t size, bool copy = true);
+
+ operator gpgme_data_t() { return data_.get(); }
+
+ ByteArrayPtr Read2Buffer();
+
+ private:
+ struct __data_ref_deletor {
+ void operator()(gpgme_data_t _data) {
+ if (_data != nullptr) gpgme_data_release(_data);
+ }
+ };
+
+ std::unique_ptr<struct gpgme_data, __data_ref_deletor> data_ = nullptr;
+};
+
+} // namespace GpgFrontend
+
+#endif // _GPGDATA_H \ No newline at end of file
diff --git a/src/gpg/model/GpgKey.cpp b/src/gpg/model/GpgKey.cpp
new file mode 100644
index 00000000..c14edd2d
--- /dev/null
+++ b/src/gpg/model/GpgKey.cpp
@@ -0,0 +1,108 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "gpg/model/GpgKey.h"
+
+GpgFrontend::GpgKey::GpgKey(gpgme_key_t &&key) : _key_ref(std::move(key)) {}
+
+GpgFrontend::GpgKey::GpgKey(GpgKey &&k) noexcept { swap(_key_ref, k._key_ref); }
+
+GpgFrontend::GpgKey &GpgFrontend::GpgKey::operator=(GpgKey &&k) noexcept {
+ swap(_key_ref, k._key_ref);
+ return *this;
+}
+
+std::unique_ptr<std::vector<GpgFrontend::GpgSubKey>>
+GpgFrontend::GpgKey::subKeys() const {
+ auto p_keys = std::make_unique<std::vector<GpgSubKey>>();
+ auto next = _key_ref->subkeys;
+ while (next != nullptr) {
+ p_keys->push_back(GpgSubKey(next));
+ next = next->next;
+ }
+ return p_keys;
+}
+
+std::unique_ptr<std::vector<GpgFrontend::GpgUID>> GpgFrontend::GpgKey::uids()
+ const {
+ auto p_uids = std::make_unique<std::vector<GpgUID>>();
+ auto uid_next = _key_ref->uids;
+ while (uid_next != nullptr) {
+ p_uids->push_back(GpgUID(uid_next));
+ uid_next = uid_next->next;
+ }
+ return p_uids;
+}
+
+bool GpgFrontend::GpgKey::CanSignActual() const {
+ auto subkeys = subKeys();
+ if (std::any_of(subkeys->begin(), subkeys->end(),
+ [](const GpgSubKey &subkey) -> bool {
+ return subkey.secret() && subkey.can_sign() &&
+ !subkey.disabled() && !subkey.revoked() &&
+ !subkey.expired();
+ }))
+ return true;
+ else
+ return false;
+}
+
+bool GpgFrontend::GpgKey::CanAuthActual() const {
+ auto subkeys = subKeys();
+ if (std::any_of(subkeys->begin(), subkeys->end(),
+ [](const GpgSubKey &subkey) -> bool {
+ return subkey.secret() && subkey.can_authenticate() &&
+ !subkey.disabled() && !subkey.revoked() &&
+ !subkey.expired();
+ }))
+ return true;
+ else
+ return false;
+}
+
+/**
+ * check if key can certify(actually)
+ * @param key target key
+ * @return if key certify
+ */
+bool GpgFrontend::GpgKey::CanCertActual() const {
+ return has_master_key() && !expired() && !revoked() && !disabled();
+}
+
+/**
+ * check if key can encrypt(actually)
+ * @param key target key
+ * @return if key encrypt
+ */
+bool GpgFrontend::GpgKey::CanEncrActual() const {
+ auto subkeys = subKeys();
+ if (std::any_of(subkeys->begin(), subkeys->end(),
+ [](const GpgSubKey &subkey) -> bool {
+ return subkey.can_encrypt() && !subkey.disabled() &&
+ !subkey.revoked() && !subkey.expired();
+ }))
+ return true;
+ else
+ return false;
+}
diff --git a/src/gpg/model/GpgKey.h b/src/gpg/model/GpgKey.h
new file mode 100644
index 00000000..53c074e8
--- /dev/null
+++ b/src/gpg/model/GpgKey.h
@@ -0,0 +1,162 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_GPGKEY_H
+#define GPGFRONTEND_GPGKEY_H
+
+#include <boost/date_time.hpp>
+#include <boost/date_time/posix_time/conversion.hpp>
+
+#include "GpgSubKey.h"
+#include "GpgUID.h"
+
+namespace GpgFrontend {
+
+class GpgKey {
+ public:
+ [[nodiscard]] bool good() const { return _key_ref != nullptr; }
+
+ [[nodiscard]] std::string id() const { return _key_ref->subkeys->keyid; }
+
+ [[nodiscard]] std::string name() const { return _key_ref->uids->name; };
+
+ [[nodiscard]] std::string email() const { return _key_ref->uids->email; }
+
+ [[nodiscard]] std::string comment() const { return _key_ref->uids->comment; }
+
+ [[nodiscard]] std::string fpr() const { return _key_ref->fpr; }
+
+ [[nodiscard]] std::string protocol() const {
+ return gpgme_get_protocol_name(_key_ref->protocol);
+ }
+
+ [[nodiscard]] std::string owner_trust() const {
+ switch (_key_ref->owner_trust) {
+ case GPGME_VALIDITY_UNKNOWN:
+ return "Unknown";
+ case GPGME_VALIDITY_UNDEFINED:
+ return "Undefined";
+ case GPGME_VALIDITY_NEVER:
+ return "Never";
+ case GPGME_VALIDITY_MARGINAL:
+ return "Marginal";
+ case GPGME_VALIDITY_FULL:
+ return "FULL";
+ case GPGME_VALIDITY_ULTIMATE:
+ return "Ultimate";
+ }
+ return "Invalid";
+ }
+
+ [[nodiscard]] std::string pubkey_algo() const {
+ return gpgme_pubkey_algo_name(_key_ref->subkeys->pubkey_algo);
+ }
+
+ [[nodiscard]] boost::gregorian::date last_update() const {
+ return boost::posix_time::from_time_t(
+ static_cast<time_t>(_key_ref->last_update))
+ .date();
+ }
+
+ [[nodiscard]] boost::gregorian::date expires() const {
+ return boost::posix_time::from_time_t(_key_ref->subkeys->expires).date();
+ };
+
+ [[nodiscard]] boost::gregorian::date create_time() const {
+ return boost::posix_time::from_time_t(_key_ref->subkeys->timestamp).date();
+ };
+
+ [[nodiscard]] unsigned int length() const {
+ return _key_ref->subkeys->length;
+ }
+
+ [[nodiscard]] bool can_encrypt() const { return _key_ref->can_encrypt; }
+
+ [[nodiscard]] bool CanEncrActual() const;
+
+ [[nodiscard]] bool can_sign() const { return _key_ref->can_sign; }
+
+ [[nodiscard]] bool CanSignActual() const;
+
+ [[nodiscard]] bool can_certify() const { return _key_ref->can_certify; }
+
+ [[nodiscard]] bool CanCertActual() const;
+
+ [[nodiscard]] bool can_authenticate() const {
+ return _key_ref->can_authenticate;
+ }
+
+ [[nodiscard]] bool CanAuthActual() const;
+
+ [[nodiscard]] bool is_private_key() const { return _key_ref->secret; }
+
+ [[nodiscard]] bool expired() const { return _key_ref->expired; }
+
+ [[nodiscard]] bool revoked() const { return _key_ref->revoked; }
+
+ [[nodiscard]] bool disabled() const { return _key_ref->disabled; }
+
+ [[nodiscard]] bool has_master_key() const {
+ return _key_ref->subkeys->secret;
+ }
+
+ [[nodiscard]] std::unique_ptr<std::vector<GpgSubKey>> subKeys() const;
+
+ [[nodiscard]] std::unique_ptr<std::vector<GpgUID>> uids() const;
+
+ GpgKey() = default;
+
+ explicit GpgKey(gpgme_key_t&& key);
+
+ ~GpgKey() = default;
+
+ GpgKey(const gpgme_key_t& key) = delete;
+
+ GpgKey(GpgKey&& k) noexcept;
+
+ GpgKey& operator=(GpgKey&& k) noexcept;
+
+ GpgKey& operator=(const gpgme_key_t& key) = delete;
+
+ bool operator==(const GpgKey& o) const { return o.id() == this->id(); }
+
+ bool operator<=(const GpgKey& o) const { return this->id() < o.id(); }
+
+ explicit operator gpgme_key_t() const { return _key_ref.get(); }
+
+ private:
+ struct _key_ref_deletor {
+ void operator()(gpgme_key_t _key) {
+ if (_key != nullptr) gpgme_key_unref(_key);
+ }
+ };
+
+ using KeyRefHandler = std::unique_ptr<struct _gpgme_key, _key_ref_deletor>;
+
+ KeyRefHandler _key_ref = nullptr;
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_GPGKEY_H
diff --git a/src/gpg/model/GpgKeySignature.cpp b/src/gpg/model/GpgKeySignature.cpp
new file mode 100644
index 00000000..8f937198
--- /dev/null
+++ b/src/gpg/model/GpgKeySignature.cpp
@@ -0,0 +1,28 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "gpg/model/GpgKeySignature.h"
+
+GpgFrontend::GpgKeySignature::GpgKeySignature(gpgme_key_sig_t sig)
+ : _signature_ref(sig, [&](gpgme_key_sig_t signature) {}) {}
diff --git a/src/gpg/model/GpgKeySignature.h b/src/gpg/model/GpgKeySignature.h
new file mode 100644
index 00000000..70eaeb1c
--- /dev/null
+++ b/src/gpg/model/GpgKeySignature.h
@@ -0,0 +1,85 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_GPGKEYSIGNATURE_H
+#define GPGFRONTEND_GPGKEYSIGNATURE_H
+
+#include <boost/date_time.hpp>
+#include <string>
+
+#include "gpg/GpgConstants.h"
+
+namespace GpgFrontend {
+
+class GpgKeySignature {
+ public:
+ [[nodiscard]] bool revoked() const { return _signature_ref->revoked; }
+ [[nodiscard]] bool expired() const { return _signature_ref->expired; }
+ [[nodiscard]] bool invalid() const { return _signature_ref->invalid; }
+ [[nodiscard]] bool exportable() const { return _signature_ref->exportable; }
+
+ [[nodiscard]] gpgme_error_t status() const { return _signature_ref->status; }
+
+ [[nodiscard]] std::string keyid() const { return _signature_ref->keyid; }
+ [[nodiscard]] std::string pubkey_algo() const {
+ return gpgme_pubkey_algo_name(_signature_ref->pubkey_algo);
+ }
+
+ [[nodiscard]] boost::gregorian::date create_time() const {
+ return boost::posix_time::from_time_t(_signature_ref->timestamp).date();
+ }
+ [[nodiscard]] boost::gregorian::date expire_time() const {
+ return boost::posix_time::from_time_t(_signature_ref->expires).date();
+ }
+
+ [[nodiscard]] std::string uid() const { return _signature_ref->uid; }
+ [[nodiscard]] std::string name() const { return _signature_ref->name; }
+ [[nodiscard]] std::string email() const { return _signature_ref->email; }
+ [[nodiscard]] std::string comment() const { return _signature_ref->comment; }
+
+ GpgKeySignature() = default;
+
+ ~GpgKeySignature() = default;
+
+ explicit GpgKeySignature(gpgme_key_sig_t sig);
+
+ GpgKeySignature(GpgKeySignature &&) noexcept = default;
+
+ GpgKeySignature(const GpgKeySignature &) = delete;
+
+ GpgKeySignature &operator=(GpgKeySignature &&) noexcept = default;
+
+ GpgKeySignature &operator=(const GpgKeySignature &) = delete;
+
+ private:
+ using KeySignatrueRefHandler =
+ std::unique_ptr<struct _gpgme_key_sig,
+ std::function<void(gpgme_key_sig_t)>>;
+
+ KeySignatrueRefHandler _signature_ref = nullptr;
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_GPGKEYSIGNATURE_H
diff --git a/src/gpg/model/GpgSubKey.cpp b/src/gpg/model/GpgSubKey.cpp
new file mode 100644
index 00000000..83fbcaa2
--- /dev/null
+++ b/src/gpg/model/GpgSubKey.cpp
@@ -0,0 +1,27 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+#include "gpg/model/GpgSubKey.h"
+
+GpgFrontend::GpgSubKey::GpgSubKey(gpgme_subkey_t subkey)
+ : _subkey_ref(subkey, [&](gpgme_subkey_t subkey) {}) {}
diff --git a/src/gpg/model/GpgSubKey.h b/src/gpg/model/GpgSubKey.h
new file mode 100644
index 00000000..5f65c507
--- /dev/null
+++ b/src/gpg/model/GpgSubKey.h
@@ -0,0 +1,102 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+#ifndef GPGFRONTEND_GPGSUBKEY_H
+#define GPGFRONTEND_GPGSUBKEY_H
+
+#include <boost/date_time.hpp>
+#include <string>
+
+#include "gpg/GpgConstants.h"
+
+namespace GpgFrontend {
+
+class GpgSubKey {
+ public:
+ [[nodiscard]] std::string id() const { return _subkey_ref->keyid; }
+
+ [[nodiscard]] std::string fpr() const { return _subkey_ref->fpr; }
+
+ [[nodiscard]] std::string pubkey_algo() const {
+ return gpgme_pubkey_algo_name(_subkey_ref->pubkey_algo);
+ }
+
+ [[nodiscard]] unsigned int length() const { return _subkey_ref->length; }
+
+ [[nodiscard]] bool can_encrypt() const { return _subkey_ref->can_encrypt; }
+
+ [[nodiscard]] bool can_sign() const { return _subkey_ref->can_sign; }
+
+ [[nodiscard]] bool can_certify() const { return _subkey_ref->can_certify; }
+
+ [[nodiscard]] bool can_authenticate() const {
+ return _subkey_ref->can_authenticate;
+ }
+
+ [[nodiscard]] bool is_private_key() const { return _subkey_ref->secret; }
+
+ [[nodiscard]] bool expired() const { return _subkey_ref->expired; }
+
+ [[nodiscard]] bool revoked() const { return _subkey_ref->revoked; }
+
+ [[nodiscard]] bool disabled() const { return _subkey_ref->disabled; }
+
+ [[nodiscard]] bool secret() const { return _subkey_ref->secret; }
+
+ [[nodiscard]] bool is_cardkey() const { return _subkey_ref->is_cardkey; }
+
+ [[nodiscard]] boost::gregorian::date timestamp() const {
+ return boost::posix_time::from_time_t(_subkey_ref->timestamp).date();
+ }
+
+ [[nodiscard]] boost::gregorian::date expires() const {
+ return boost::posix_time::from_time_t(_subkey_ref->expires).date();
+ }
+
+ GpgSubKey() = default;
+
+ explicit GpgSubKey(gpgme_subkey_t subkey);
+
+ GpgSubKey(GpgSubKey&& o) noexcept { swap(_subkey_ref, o._subkey_ref); }
+
+ GpgSubKey(const GpgSubKey&) = delete;
+
+ GpgSubKey& operator=(GpgSubKey&& o) noexcept {
+ swap(_subkey_ref, o._subkey_ref);
+ return *this;
+ };
+
+ GpgSubKey& operator=(const GpgSubKey&) = delete;
+
+ bool operator==(const GpgSubKey& o) const { return fpr() == o.fpr(); }
+
+ private:
+ using SubkeyRefHandler = std::unique_ptr<struct _gpgme_subkey,
+ std::function<void(gpgme_subkey_t)>>;
+
+ SubkeyRefHandler _subkey_ref = nullptr;
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_GPGSUBKEY_H
diff --git a/src/gpg/model/GpgUID.cpp b/src/gpg/model/GpgUID.cpp
new file mode 100644
index 00000000..c0a63bab
--- /dev/null
+++ b/src/gpg/model/GpgUID.cpp
@@ -0,0 +1,28 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "gpg/model/GpgUID.h"
+
+GpgFrontend::GpgUID::GpgUID(gpgme_user_id_t uid)
+ : _uid_ref(uid, [&](gpgme_user_id_t uid) {}) {} \ No newline at end of file
diff --git a/src/gpg/model/GpgUID.h b/src/gpg/model/GpgUID.h
new file mode 100644
index 00000000..66dba321
--- /dev/null
+++ b/src/gpg/model/GpgUID.h
@@ -0,0 +1,81 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_GPGUID_H
+#define GPGFRONTEND_GPGUID_H
+
+#include "GpgKeySignature.h"
+
+namespace GpgFrontend {
+
+class GpgUID {
+ public:
+ [[nodiscard]] std::string name() const { return _uid_ref->name; }
+
+ [[nodiscard]] std::string email() const { return _uid_ref->email; }
+
+ [[nodiscard]] std::string comment() const { return _uid_ref->comment; }
+
+ [[nodiscard]] std::string uid() const { return _uid_ref->uid; }
+
+ [[nodiscard]] bool revoked() const { return _uid_ref->revoked; }
+
+ [[nodiscard]] bool invalid() const { return _uid_ref->invalid; }
+
+ [[nodiscard]] std::unique_ptr<std::vector<GpgKeySignature>> signatures()
+ const {
+ auto sigs = std::make_unique<std::vector<GpgKeySignature>>();
+ auto sig_next = _uid_ref->signatures;
+ while (sig_next != nullptr) {
+ sigs->push_back(GpgKeySignature(sig_next));
+ sig_next = sig_next->next;
+ }
+ return sigs;
+ }
+
+ GpgUID() = default;
+
+ explicit GpgUID(gpgme_user_id_t uid);
+
+ GpgUID(GpgUID &&o) noexcept { swap(_uid_ref, o._uid_ref); }
+
+ GpgUID(const GpgUID &) = delete;
+
+ GpgUID &operator=(GpgUID &&o) noexcept {
+ swap(_uid_ref, o._uid_ref);
+ return *this;
+ }
+
+ GpgUID &operator=(const GpgUID &) = delete;
+
+ private:
+ using UidRefHandler = std::unique_ptr<struct _gpgme_user_id,
+ std::function<void(gpgme_user_id_t)>>;
+
+ UidRefHandler _uid_ref = nullptr;
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_GPGUID_H \ No newline at end of file
diff --git a/src/gpg/result_analyse/DecryptResultAnalyse.cpp b/src/gpg/result_analyse/DecryptResultAnalyse.cpp
index b4d0b14f..4ff32c59 100644
--- a/src/gpg/result_analyse/DecryptResultAnalyse.cpp
+++ b/src/gpg/result_analyse/DecryptResultAnalyse.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,63 +24,68 @@
#include "gpg/result_analyse/DecryptResultAnalyse.h"
-DecryptResultAnalyse::DecryptResultAnalyse(GpgME::GpgContext *ctx, gpgme_error_t error, gpgme_decrypt_result_t result)
- : mCtx(ctx) {
+#include "gpg/function/GpgKeyGetter.h"
- stream << tr("[#] Decrypt Operation ");
+GpgFrontend::DecryptResultAnalyse::DecryptResultAnalyse(GpgError error,
+ GpgDecrResult result)
+ : error(error), result(std::move(result)) {}
- if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) {
- stream << tr("[Success]") << Qt::endl;
- } else {
- stream << tr("[Failed] ") << gpgme_strerror(error) << Qt::endl;
- setStatus(-1);
- if (result != nullptr && result->unsupported_algorithm != nullptr) {
- stream << "------------>" << Qt::endl;
- stream << tr("Unsupported Algo: ") << result->unsupported_algorithm << Qt::endl;
- }
- }
+void GpgFrontend::DecryptResultAnalyse::do_analyse() {
+ stream << "[#]" << _("Decrypt Operation");
- if (result != nullptr && result->recipients != nullptr) {
- stream << "------------>" << Qt::endl;
- if (result->file_name != nullptr) {
- stream << tr("File Name: ") << result->file_name << Qt::endl;
- stream << Qt::endl;
- }
+ if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) {
+ stream << "[" << _("Success") << "]" << std::endl;
+ } else {
+ stream << "[" << _("Failed") << "] " << gpgme_strerror(error) << std::endl;
+ setStatus(-1);
+ if (result != nullptr && result->unsupported_algorithm != nullptr) {
+ stream << "------------>" << std::endl;
+ stream << _("Unsupported Algo") << ": " << result->unsupported_algorithm
+ << std::endl;
+ }
+ }
- auto reci = result->recipients;
- if (reci != nullptr)
- stream << tr("Recipient(s): ") << Qt::endl;
- while (reci != nullptr) {
- printReci(stream, reci);
- reci = reci->next;
- }
- stream << "<------------" << Qt::endl;
+ if (result != nullptr && result->recipients != nullptr) {
+ stream << "------------>" << std::endl;
+ if (result->file_name != nullptr) {
+ stream << _("File Name") << ": " << result->file_name << std::endl;
+ stream << std::endl;
}
- stream << Qt::endl;
+ auto reci = result->recipients;
+ if (reci != nullptr) stream << _("Recipient(s)") << ": " << std::endl;
+ while (reci != nullptr) {
+ print_reci(stream, reci);
+ reci = reci->next;
+ }
+ stream << "<------------" << std::endl;
+ }
+ stream << std::endl;
}
-bool DecryptResultAnalyse::printReci(QTextStream &stream, gpgme_recipient_t reci) {
- bool keyFound = true;
- stream << QApplication::tr(" {>} Recipient: ");
+bool GpgFrontend::DecryptResultAnalyse::print_reci(std::stringstream &stream,
+ gpgme_recipient_t reci) {
+ bool keyFound = true;
+ stream << " {>} " << _("Recipient") << ": ";
- auto key = mCtx->getKeyById(reci->keyid);
- if(key.good) {
- stream << key.name;
- if (!key.email.isEmpty()) {
- stream << "<" << key.email << ">";
- }
- } else {
- stream << "<Unknown>";
- setStatus(0);
- keyFound = false;
+ auto key = GpgFrontend::GpgKeyGetter::GetInstance().GetKey(reci->keyid);
+ if (key.good()) {
+ stream << key.name().c_str();
+ if (!key.email().empty()) {
+ stream << "<" << key.email().c_str() << ">";
}
+ } else {
+ stream << "<" << _("Unknown") << ">";
+ setStatus(0);
+ keyFound = false;
+ }
- stream << Qt::endl;
+ stream << std::endl;
- stream << tr(" Keu ID: ") << reci->keyid << Qt::endl;
- stream << tr(" Public Algo: ") << gpgme_pubkey_algo_name(reci->pubkey_algo) << Qt::endl;
+ stream << " " << _("Keu ID") << ": " << key.id().c_str() << std::endl;
+ stream << " " << _("Public Algo") << ": "
+ << gpgme_pubkey_algo_name(reci->pubkey_algo) << std::endl;
- return keyFound;
+ return keyFound;
}
diff --git a/src/gpg/result_analyse/DecryptResultAnalyse.h b/src/gpg/result_analyse/DecryptResultAnalyse.h
new file mode 100644
index 00000000..0864c23b
--- /dev/null
+++ b/src/gpg/result_analyse/DecryptResultAnalyse.h
@@ -0,0 +1,49 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_DECRYPTRESULTANALYSE_H
+#define GPGFRONTEND_DECRYPTRESULTANALYSE_H
+
+#include "ResultAnalyse.h"
+#include "gpg/GpgConstants.h"
+
+namespace GpgFrontend {
+
+class DecryptResultAnalyse : public ResultAnalyse {
+ public:
+ explicit DecryptResultAnalyse(GpgError error, GpgDecrResult result);
+
+ protected:
+ void do_analyse() final;
+
+ private:
+ bool print_reci(std::stringstream &stream, gpgme_recipient_t reci);
+
+ GpgError error;
+ GpgDecrResult result;
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_DECRYPTRESULTANALYSE_H
diff --git a/src/gpg/result_analyse/EncryptResultAnalyse.cpp b/src/gpg/result_analyse/EncryptResultAnalyse.cpp
index 1ba685c9..df240a1d 100644
--- a/src/gpg/result_analyse/EncryptResultAnalyse.cpp
+++ b/src/gpg/result_analyse/EncryptResultAnalyse.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,35 +24,38 @@
#include "gpg/result_analyse/EncryptResultAnalyse.h"
-EncryptResultAnalyse::EncryptResultAnalyse(gpgme_error_t error, gpgme_encrypt_result_t result) {
-
- qDebug() << "Start Encrypt Result Analyse";
-
- stream << "[#] Encrypt Operation ";
-
- if(gpgme_err_code(error) == GPG_ERR_NO_ERROR)
- stream << "[Success]" << Qt::endl;
- else {
- stream << "[Failed] " << gpgme_strerror(error) << Qt::endl;
- setStatus(-1);
+GpgFrontend::EncryptResultAnalyse::EncryptResultAnalyse(GpgError error,
+ GpgEncrResult result)
+ : error(error), result(std::move(result)) {}
+
+void GpgFrontend::EncryptResultAnalyse::do_analyse() {
+ LOG(INFO) << _("Start Encrypt Result Analyse");
+
+ stream << "[#] " << _("Encrypt Operation") << " ";
+
+ if (gpgme_err_code(error) == GPG_ERR_NO_ERROR)
+ stream << "[" << _("Success") << "]" << std::endl;
+ else {
+ stream << "[" << _("Failed") << "] " << gpgme_strerror(error) << std::endl;
+ setStatus(-1);
+ }
+
+ if (!~status) {
+ stream << "------------>" << std::endl;
+ if (result != nullptr) {
+ stream << _("Invalid Recipients") << ": " << std::endl;
+ auto inv_reci = result->invalid_recipients;
+ while (inv_reci != nullptr) {
+ stream << _("Fingerprint") << ": " << inv_reci->fpr << std::endl;
+ stream << _("Reason") << ": " << gpgme_strerror(inv_reci->reason)
+ << std::endl;
+ stream << std::endl;
+
+ inv_reci = inv_reci->next;
+ }
}
+ stream << "<------------" << std::endl;
+ }
- if(!~status) {
- stream << "------------>" << Qt::endl;
- if (result != nullptr) {
- stream << tr("Invalid Recipients: ") << Qt::endl;
- auto inv_reci = result->invalid_recipients;
- while (inv_reci != nullptr) {
- stream << tr("Fingerprint: ") << inv_reci->fpr << Qt::endl;
- stream << tr("Reason: ") << gpgme_strerror(inv_reci->reason) << Qt::endl;
- stream << Qt::endl;
-
- inv_reci = inv_reci->next;
- }
- }
- stream << "<------------" << Qt::endl;
- }
-
- stream << Qt::endl;
-
+ stream << std::endl;
}
diff --git a/src/gpg/result_analyse/EncryptResultAnalyse.h b/src/gpg/result_analyse/EncryptResultAnalyse.h
new file mode 100644
index 00000000..e0a411d1
--- /dev/null
+++ b/src/gpg/result_analyse/EncryptResultAnalyse.h
@@ -0,0 +1,45 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_ENCRYPTRESULTANALYSE_H
+#define GPGFRONTEND_ENCRYPTRESULTANALYSE_H
+
+#include "ResultAnalyse.h"
+#include "gpg/GpgConstants.h"
+
+namespace GpgFrontend {
+class EncryptResultAnalyse : public ResultAnalyse {
+ public:
+ explicit EncryptResultAnalyse(GpgError error, GpgEncrResult result);
+
+ protected:
+ void do_analyse() final;
+
+ private:
+ GpgError error;
+ GpgEncrResult result;
+};
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_ENCRYPTRESULTANALYSE_H
diff --git a/src/gpg/result_analyse/ResultAnalyse.cpp b/src/gpg/result_analyse/ResultAnalyse.cpp
index 7186d21a..821da2ee 100644
--- a/src/gpg/result_analyse/ResultAnalyse.cpp
+++ b/src/gpg/result_analyse/ResultAnalyse.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,15 +24,19 @@
#include "gpg/result_analyse/ResultAnalyse.h"
-const QString &ResultAnalyse::getResultReport() const{
- return resultText;
+const std::string GpgFrontend::ResultAnalyse::getResultReport() const {
+ return stream.str();
}
-int ResultAnalyse::getStatus() const {
- return status;
+int GpgFrontend::ResultAnalyse::getStatus() const { return status; }
+
+void GpgFrontend::ResultAnalyse::setStatus(int mStatus) {
+ if (mStatus < status) status = mStatus;
}
-void ResultAnalyse::setStatus(int mStatus) {
- if(mStatus < status)
- status = mStatus;
+void GpgFrontend::ResultAnalyse::analyse() {
+ if (!analysed_) {
+ do_analyse();
+ analysed_ = true;
+ }
}
diff --git a/src/gpg/result_analyse/ResultAnalyse.h b/src/gpg/result_analyse/ResultAnalyse.h
new file mode 100644
index 00000000..33341b44
--- /dev/null
+++ b/src/gpg/result_analyse/ResultAnalyse.h
@@ -0,0 +1,57 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+#ifndef GPGFRONTEND_RESULTANALYSE_H
+#define GPGFRONTEND_RESULTANALYSE_H
+
+#include <sstream>
+#include <string>
+
+#include "gpg/GpgConstants.h"
+namespace GpgFrontend {
+
+class ResultAnalyse {
+ public:
+ ResultAnalyse() = default;
+
+ [[nodiscard]] const std::string getResultReport() const;
+
+ [[nodiscard]] int getStatus() const;
+
+ void analyse();
+
+ protected:
+ virtual void do_analyse() = 0;
+
+ std::stringstream stream;
+
+ int status = 1;
+
+ bool analysed_ = false;
+
+ void setStatus(int mStatus);
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_RESULTANALYSE_H
diff --git a/src/gpg/result_analyse/SignResultAnalyse.cpp b/src/gpg/result_analyse/SignResultAnalyse.cpp
index 10d76678..770594ca 100644
--- a/src/gpg/result_analyse/SignResultAnalyse.cpp
+++ b/src/gpg/result_analyse/SignResultAnalyse.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,73 +24,86 @@
#include "gpg/result_analyse/SignResultAnalyse.h"
-SignResultAnalyse::SignResultAnalyse(GpgME::GpgContext *ctx, gpgme_error_t error, gpgme_sign_result_t result) {
-
- qDebug() << "Start Sign Result Analyse";
-
- stream << tr("[#] Sign Operation ");
-
- if (gpgme_err_code(error) == GPG_ERR_NO_ERROR)
- stream << tr("[Success]") << Qt::endl;
- else {
- stream << tr("[Failed] ") << gpgme_strerror(error) << Qt::endl;
- setStatus(-1);
+#include "gpg/function/GpgKeyGetter.h"
+
+GpgFrontend::SignResultAnalyse::SignResultAnalyse(GpgError error,
+ GpgSignResult result)
+ : error(error), result(std::move(result)) {}
+
+void GpgFrontend::SignResultAnalyse::do_analyse() {
+ LOG(INFO) << _("Start Sign Result Analyse");
+
+ stream << "[#] " << _("Sign Operation") << " ";
+
+ if (gpgme_err_code(error) == GPG_ERR_NO_ERROR)
+ stream << "[" << _("Success") << "]" << std::endl;
+ else {
+ stream << "[" << _("Failed") << "] " << gpgme_strerror(error) << std::endl;
+ setStatus(-1);
+ }
+
+ if (result != nullptr &&
+ (result->signatures != nullptr || result->invalid_signers != nullptr)) {
+ LOG(INFO) << _("Sign Result Analyse Getting Result");
+ stream << "------------>" << std::endl;
+ auto new_sign = result->signatures;
+
+ while (new_sign != nullptr) {
+ stream << "[>]" << _("New Signature") << ": " << std::endl;
+
+ LOG(INFO) << _("Signers Fingerprint") << ": " << new_sign->fpr;
+
+ stream << " " << _("Sign Mode") << ": ";
+ if (new_sign->type == GPGME_SIG_MODE_NORMAL)
+ stream << _("Normal");
+ else if (new_sign->type == GPGME_SIG_MODE_CLEAR)
+ stream << _("Clear");
+ else if (new_sign->type == GPGME_SIG_MODE_DETACH)
+ stream << _("Detach");
+
+ stream << std::endl;
+
+ auto singerKey =
+ GpgFrontend::GpgKeyGetter::GetInstance().GetKey(new_sign->fpr);
+ if (singerKey.good()) {
+ stream << " " << _("Signer") << ": "
+ << singerKey.uids()->front().uid() << std::endl;
+ } else {
+ stream << " " << _("Signer") << ": "
+ << "<unknown>" << std::endl;
+ }
+ stream << " " << _("Public Key Algo") << ": "
+ << gpgme_pubkey_algo_name(new_sign->pubkey_algo) << std::endl;
+ stream << " " << _("Hash Algo") << ": "
+ << gpgme_hash_algo_name(new_sign->hash_algo) << std::endl;
+ stream << " " << _("Date & Time") << ": "
+ << boost::posix_time::to_iso_string(
+ boost::posix_time::from_time_t(new_sign->timestamp))
+ << std::endl;
+
+ stream << std::endl;
+
+ new_sign = new_sign->next;
}
- if (result != nullptr && (result->signatures != nullptr || result->invalid_signers != nullptr)) {
-
- qDebug() << "Sign Result Analyse Getting Result";
- stream << "------------>" << Qt::endl;
- auto new_sign = result->signatures;
-
- while (new_sign != nullptr) {
- stream << tr("[>] New Signature: ") << Qt::endl;
-
- qDebug() << "Signers Fingerprint: " << new_sign->fpr;
-
- stream << tr(" Sign Mode: ");
- if (new_sign->type == GPGME_SIG_MODE_NORMAL)
- stream << tr("Normal");
- else if (new_sign->type == GPGME_SIG_MODE_CLEAR)
- stream << tr("Clear");
- else if (new_sign->type == GPGME_SIG_MODE_DETACH)
- stream << tr("Detach");
+ LOG(INFO) << _("Sign Result Analyse Getting Invalid Signer");
- stream << Qt::endl;
+ auto invalid_signer = result->invalid_signers;
- GpgKey singerKey = ctx->getKeyByFpr(new_sign->fpr);
- if(singerKey.good) {
- stream << tr(" Signer: ") << singerKey.uids.first().uid << Qt::endl;
- } else {
- stream << tr(" Signer: ") << tr("<unknown>") << Qt::endl;
- }
- stream << tr(" Public Key Algo: ") << gpgme_pubkey_algo_name(new_sign->pubkey_algo) << Qt::endl;
- stream << tr(" Hash Algo: ") << gpgme_hash_algo_name(new_sign->hash_algo) << Qt::endl;
- stream << tr(" Date & Time: ") << QDateTime::fromTime_t(new_sign->timestamp).toString() << Qt::endl;
+ if (invalid_signer != nullptr)
+ stream << _("Invalid Signers") << ": " << std::endl;
- stream << Qt::endl;
-
- new_sign = new_sign->next;
- }
-
- qDebug() << "Sign Result Analyse Getting Invalid Signer";
-
- auto invalid_signer = result->invalid_signers;
-
- if (invalid_signer != nullptr)
- stream << tr("Invalid Signers: ") << Qt::endl;
-
- while (invalid_signer != nullptr) {
- setStatus(0);
- stream << tr("[>] Signer: ") << Qt::endl;
- stream << tr(" Fingerprint: ") << invalid_signer->fpr << Qt::endl;
- stream << tr(" Reason: ") << gpgme_strerror(invalid_signer->reason) << Qt::endl;
- stream << Qt::endl;
-
- invalid_signer = invalid_signer->next;
- }
- stream << "<------------" << Qt::endl;
+ while (invalid_signer != nullptr) {
+ setStatus(0);
+ stream << "[>] " << _("Signer") << ": " << std::endl;
+ stream << " " << _("Fingerprint") << ": " << invalid_signer->fpr
+ << std::endl;
+ stream << " " << _("Reason") << ": "
+ << gpgme_strerror(invalid_signer->reason) << std::endl;
+ stream << std::endl;
+ invalid_signer = invalid_signer->next;
}
-
-}
+ stream << "<------------" << std::endl;
+ }
+} \ No newline at end of file
diff --git a/src/gpg/result_analyse/SignResultAnalyse.h b/src/gpg/result_analyse/SignResultAnalyse.h
new file mode 100644
index 00000000..988ddf99
--- /dev/null
+++ b/src/gpg/result_analyse/SignResultAnalyse.h
@@ -0,0 +1,47 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_SIGNRESULTANALYSE_H
+#define GPGFRONTEND_SIGNRESULTANALYSE_H
+
+#include "ResultAnalyse.h"
+
+namespace GpgFrontend {
+
+class SignResultAnalyse : public ResultAnalyse {
+ public:
+ explicit SignResultAnalyse(GpgError error, GpgSignResult result);
+
+ protected:
+ void do_analyse();
+
+ private:
+ GpgError error;
+
+ GpgSignResult result;
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_SIGNRESULTANALYSE_H
diff --git a/src/gpg/result_analyse/VerifyResultAnalyse.cpp b/src/gpg/result_analyse/VerifyResultAnalyse.cpp
index 75e07d33..55e50f38 100644
--- a/src/gpg/result_analyse/VerifyResultAnalyse.cpp
+++ b/src/gpg/result_analyse/VerifyResultAnalyse.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -22,147 +22,172 @@
*
*/
-#include "GpgFrontend.h"
#include "gpg/result_analyse/VerifyResultAnalyse.h"
-VerifyResultAnalyse::VerifyResultAnalyse(GpgME::GpgContext *ctx, gpgme_error_t error, gpgme_verify_result_t result)
- : mCtx(ctx) {
+#include "GpgFrontend.h"
+#include "gpg/GpgConstants.h"
+#include "gpg/function/GpgKeyGetter.h"
- qDebug() << "Verify Result Analyse Started";
+GpgFrontend::VerifyResultAnalyse::VerifyResultAnalyse(GpgError error,
+ GpgVerifyResult result)
+ : error(error), result(std::move(result)) {}
- stream << tr("[#] Verify Operation ");
+void GpgFrontend::VerifyResultAnalyse::do_analyse() {
+ LOG(INFO) << _("Verify Result Analyse Started");
- if (gpgme_err_code(error) == GPG_ERR_NO_ERROR)
- stream << tr("[Success]") << Qt::endl;
- else {
- stream << tr("[Failed] ") << gpgme_strerror(error) << Qt::endl;
- setStatus(-1);
- }
+ stream << "[#] " << _("Verify Operation") << " ";
+ if (gpgme_err_code(error) == GPG_ERR_NO_ERROR)
+ stream << "[" << _("Success") << "]" << std::endl;
+ else {
+ stream << "[" << _("Failed") << "] " << gpgme_strerror(error) << std::endl;
+ setStatus(-1);
+ }
- if (result != nullptr && result->signatures) {
- stream << "------------>" << Qt::endl;
- auto sign = result->signatures;
+ if (result != nullptr && result->signatures) {
+ stream << "------------>" << std::endl;
+ auto sign = result->signatures;
- if (sign == nullptr) {
- stream << "[>] Not Signature Found" << Qt::endl;
+ if (sign == nullptr) {
+ stream << "[>] " << _("Not Signature Found") << std::endl;
+ setStatus(0);
+ return;
+ }
+
+ stream << "[>] " << _("Signed On") << " "
+ << boost::posix_time::to_iso_string(
+ boost::posix_time::from_time_t(sign->timestamp))
+ << std::endl;
+
+ stream << std::endl << "[>] " << _("Signatures") << ":" << std::endl;
+
+ bool canContinue = true;
+
+ while (sign && canContinue) {
+ switch (gpg_err_code(sign->status)) {
+ case GPG_ERR_BAD_SIGNATURE:
+ stream << _("One or More Bad Signatures.") << std::endl;
+ canContinue = false;
+ setStatus(-1);
+ break;
+ case GPG_ERR_NO_ERROR:
+ stream << _("A") << " ";
+ if (sign->summary & GPGME_SIGSUM_GREEN) {
+ stream << _("Good") << " ";
+ }
+ if (sign->summary & GPGME_SIGSUM_RED) {
+ stream << _("Bad") << " ";
+ }
+ if (sign->summary & GPGME_SIGSUM_SIG_EXPIRED) {
+ stream << _("Expired") << " ";
+ }
+ if (sign->summary & GPGME_SIGSUM_KEY_MISSING) {
+ stream << _("Missing Key's") << " ";
+ }
+ if (sign->summary & GPGME_SIGSUM_KEY_REVOKED) {
+ stream << _("Revoked Key's") << " ";
+ }
+ if (sign->summary & GPGME_SIGSUM_KEY_EXPIRED) {
+ stream << _("Expired Key's") << " ";
+ }
+ if (sign->summary & GPGME_SIGSUM_CRL_MISSING) {
+ stream << _("Missing CRL's") << " ";
+ }
+
+ if (sign->summary & GPGME_SIGSUM_VALID) {
+ stream << _("Signature Fully Valid.") << std::endl;
+ } else {
+ stream << _("Signature Not Fully Valid.") << std::endl;
+ }
+
+ if (!(sign->status & GPGME_SIGSUM_KEY_MISSING)) {
+ if (!print_signer(stream, sign)) setStatus(0);
+ } else {
+ stream << _("Key is NOT present with ID 0x") << sign->fpr
+ << std::endl;
+ }
+
+ setStatus(1);
+
+ break;
+ case GPG_ERR_NO_PUBKEY:
+ stream << _("A signature could NOT be verified due to a Missing Key")
+ << std::endl;
+ setStatus(-2);
+ break;
+ case GPG_ERR_CERT_REVOKED:
+ stream << _("A signature is valid but the key used to verify the "
+ "signature has been revoked")
+ << std::endl;
+ if (!print_signer(stream, sign)) {
+ setStatus(0);
+ }
+ setStatus(-1);
+ break;
+ case GPG_ERR_SIG_EXPIRED:
+ stream << _("A signature is valid but expired") << std::endl;
+ if (!print_signer(stream, sign)) {
setStatus(0);
- return;
- }
-
- stream << "[>] Signed On " << QDateTime::fromTime_t(sign->timestamp).toString() << Qt::endl;
-
- stream << Qt::endl << "[>] Signatures:" << Qt::endl;
-
- bool canContinue = true;
-
- while (sign && canContinue) {
-
- switch (gpg_err_code(sign->status)) {
- case GPG_ERR_BAD_SIGNATURE:
- stream << QApplication::tr("One or More Bad Signatures.") << Qt::endl;
- canContinue = false;
- setStatus(-1);
- break;
- case GPG_ERR_NO_ERROR:
- stream << QApplication::tr("A ");
- if (sign->summary & GPGME_SIGSUM_GREEN) {
- stream << QApplication::tr("Good ");
- }
- if (sign->summary & GPGME_SIGSUM_RED) {
- stream << QApplication::tr("Bad ");
- }
- if (sign->summary & GPGME_SIGSUM_SIG_EXPIRED) {
- stream << QApplication::tr("Expired ");
- }
- if (sign->summary & GPGME_SIGSUM_KEY_MISSING) {
- stream << QApplication::tr("Missing Key's ");
- }
- if (sign->summary & GPGME_SIGSUM_KEY_REVOKED) {
- stream << QApplication::tr("Revoked Key's ");
- }
- if (sign->summary & GPGME_SIGSUM_KEY_EXPIRED) {
- stream << QApplication::tr("Expired Key's ");
- }
- if (sign->summary & GPGME_SIGSUM_CRL_MISSING) {
- stream << QApplication::tr("Missing CRL's ");
- }
-
- if (sign->summary & GPGME_SIGSUM_VALID) {
- stream << QApplication::tr("Signature Fully Valid.") << Qt::endl;
- } else {
- stream << QApplication::tr("Signature Not Fully Valid.") << Qt::endl;
- }
-
- if (!(sign->status & GPGME_SIGSUM_KEY_MISSING)) {
- if (!printSigner(stream, sign)) setStatus(0);
- } else {
- stream << QApplication::tr("Key is NOT present with ID 0x") << QString(sign->fpr) << Qt::endl;
- }
-
- setStatus(1);
-
- break;
- case GPG_ERR_NO_PUBKEY:
- stream << QApplication::tr("A signature could NOT be verified due to a Missing Key\n");
- setStatus(-1);
- break;
- case GPG_ERR_CERT_REVOKED:
- stream << QApplication::tr(
- "A signature is valid but the key used to verify the signature has been revoked\n");
- if (!printSigner(stream, sign)) {
- setStatus(0);
- }
- setStatus(-1);
- break;
- case GPG_ERR_SIG_EXPIRED:
- stream << QApplication::tr("A signature is valid but expired\n");
- if (!printSigner(stream, sign)) {
- setStatus(0);
- }
- setStatus(-1);
- break;
- case GPG_ERR_KEY_EXPIRED:
- stream << QApplication::tr(
- "A signature is valid but the key used to verify the signature has expired.\n");
- if (!printSigner(stream, sign)) {
- setStatus(0);
- }
- break;
- case GPG_ERR_GENERAL:
- stream << QApplication::tr(
- "There was some other error which prevented the signature verification.\n");
- status = -1;
- canContinue = false;
- break;
- default:
- stream << QApplication::tr("Error for key with fingerprint ") <<
- GpgME::GpgContext::beautifyFingerprint(QString(sign->fpr));
- setStatus(-1);
- }
- stream << Qt::endl;
- sign = sign->next;
- }
- stream << "<------------" << Qt::endl;
+ }
+ setStatus(-1);
+ break;
+ case GPG_ERR_KEY_EXPIRED:
+ stream << _("A signature is valid but the key used to "
+ "verify the signature has expired.")
+ << std::endl;
+ if (!print_signer(stream, sign)) {
+ setStatus(0);
+ }
+ break;
+ case GPG_ERR_GENERAL:
+ stream << _("There was some other error which prevented "
+ "the signature verification.")
+ << std::endl;
+ status = -1;
+ canContinue = false;
+ break;
+ default:
+ auto fpr = std::string(sign->fpr);
+ stream << _("Error for key with fingerprint") << " "
+ << GpgFrontend::beautify_fingerprint(fpr);
+ setStatus(-1);
+ }
+ stream << std::endl;
+ sign = sign->next;
}
+ stream << "<------------" << std::endl;
+ }
}
-bool VerifyResultAnalyse::printSigner(QTextStream &stream, gpgme_signature_t sign) {
- bool keyFound = true;
- auto key = mCtx->getKeyByFpr(sign->fpr);
-
- key = mCtx->getKeyByFpr(sign->fpr);
+bool GpgFrontend::VerifyResultAnalyse::print_signer(std::stringstream &stream,
+ gpgme_signature_t sign) {
+ bool keyFound = true;
+ auto key = GpgFrontend::GpgKeyGetter::GetInstance().GetKey(sign->fpr);
+
+ if (!key.good()) {
+ stream << " " << _("Signed By") << ": "
+ << "<" << _("Unknown") << ">" << std::endl;
+ setStatus(0);
+ keyFound = false;
+ } else {
+ stream << " " << _("Signed By") << ": " << key.uids()->front().uid()
+ << std::endl;
+ }
+ stream << " " << _("Public Key Algo") << ": "
+ << gpgme_pubkey_algo_name(sign->pubkey_algo) << std::endl;
+ stream << " " << _("Hash Algo") << ": "
+ << gpgme_hash_algo_name(sign->hash_algo) << std::endl;
+ stream << " " << _("Date & Time") << ": "
+ << boost::posix_time::to_iso_string(
+ boost::posix_time::from_time_t(sign->timestamp))
+ << std::endl;
+ stream << std::endl;
+ return keyFound;
+}
- if (!key.good) {
- stream << tr(" Signed By: ") << tr("<unknown>") << Qt::endl;
- setStatus(0);
- keyFound = false;
- } else {
- stream << tr(" Signed By: ") << key.uids.first().uid << Qt::endl;
- }
- stream << tr(" Public Key Algo: ") << gpgme_pubkey_algo_name(sign->pubkey_algo) << Qt::endl;
- stream << tr(" Hash Algo: ") << gpgme_hash_algo_name(sign->hash_algo) << Qt::endl;
- stream << tr(" Date & Time: ") << QDateTime::fromTime_t(sign->timestamp).toString() << Qt::endl;
- stream << Qt::endl;
- return keyFound;
-} \ No newline at end of file
+gpgme_signature_t GpgFrontend::VerifyResultAnalyse::GetSignatures() {
+ if (result)
+ return result->signatures;
+ else
+ return nullptr;
+}
diff --git a/src/gpg/result_analyse/VerifyResultAnalyse.h b/src/gpg/result_analyse/VerifyResultAnalyse.h
new file mode 100644
index 00000000..51ce17ac
--- /dev/null
+++ b/src/gpg/result_analyse/VerifyResultAnalyse.h
@@ -0,0 +1,51 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_VERIFYRESULTANALYSE_H
+#define GPGFRONTEND_VERIFYRESULTANALYSE_H
+
+#include "ResultAnalyse.h"
+#include "gpg/model/GpgKeySignature.h"
+
+namespace GpgFrontend {
+
+class VerifyResultAnalyse : public ResultAnalyse {
+ public:
+ explicit VerifyResultAnalyse(GpgError error, GpgVerifyResult result);
+
+ gpgme_signature_t GetSignatures();
+
+ private:
+ void do_analyse();
+
+ private:
+ bool print_signer(std::stringstream &stream, gpgme_signature_t sign);
+
+ GpgError error;
+ GpgVerifyResult result;
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_VERIFYRESULTANALYSE_H
diff --git a/src/main.cpp b/src/main.cpp
index 1ec264e7..ee542ff0 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -22,77 +22,149 @@
*
*/
-#include "MainWindow.h"
#include "GpgFrontendBuildInfo.h"
+#include "ui/MainWindow.h"
+#include "ui/settings/GlobalSettingStation.h"
-int main(int argc, char *argv[]) {
+// Easy Logging Cpp
+INITIALIZE_EASYLOGGINGPP
- Q_INIT_RESOURCE(gpgfrontend);
+void init_logging();
+void init_locale();
- QApplication app(argc, argv);
+int main(int argc, char* argv[]) {
+ // Qt
+ Q_INIT_RESOURCE(gpgfrontend);
- // get application path
- QString appPath = qApp->applicationDirPath();
+ // Qt App
+ QApplication app(argc, argv);
- QApplication::setApplicationVersion(BUILD_VERSION);
- QApplication::setApplicationName(PROJECT_NAME);
+ // logging system
+ init_logging();
- // dont show icons in menus
- QApplication::setAttribute(Qt::AA_DontShowIconsInMenus);
+ // i18n
+ init_locale();
- // unicode in source
- QTextCodec::setCodecForLocale(QTextCodec::codecForName("utf-8"));
+ // App config
+ QApplication::setApplicationVersion(BUILD_VERSION);
+ QApplication::setApplicationName(PROJECT_NAME);
-#if OS_PLATFORM == WINDOWS
- // load css file
- QFile file(RESOURCE_DIR(qApp->applicationDirPath()) + "/css/default.qss");
- file.open(QFile::ReadOnly);
- QString styleSheet = QLatin1String(file.readAll());
- qApp->setStyleSheet(styleSheet);
- file.close();
+ // don't show icons in menus
+ QApplication::setAttribute(Qt::AA_DontShowIconsInMenus);
+
+ // unicode in source
+ QTextCodec::setCodecForLocale(QTextCodec::codecForName("utf-8"));
+
+#ifdef WINDOWS
+ // css
+ QFile file(RESOURCE_DIR(qApp->applicationDirPath()) + "/css/default.qss");
+ file.open(QFile::ReadOnly);
+ QString styleSheet = QLatin1String(file.readAll());
+ qApp->setStyleSheet(styleSheet);
+ file.close();
#endif
+ /**
+ * internationalisation. loop to restart mainwindow
+ * with changed translation when settings change.
+ */
+ int return_from_event_loop_code;
+
+ do {
+ QApplication::setQuitOnLastWindowClosed(true);
+
/**
- * internationalisation. loop to restart mainwindow
- * with changed translation when settings change.
- */
- if(!QDir(RESOURCE_DIR(appPath) + "/conf").exists()) {
- QDir().mkdir(RESOURCE_DIR(appPath) + "/conf");
- }
- QSettings::setDefaultFormat(QSettings::IniFormat);
- QSettings settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", QSettings::IniFormat);
- QTranslator translator, translator2;
- int return_from_event_loop_code;
-
- qDebug() << "Resource Directory" << RESOURCE_DIR(appPath);
-
- do {
- QApplication::removeTranslator(&translator);
- QApplication::removeTranslator(&translator2);
-
- QString lang = settings.value("int/lang", QLocale::system().name()).toString();
- if (lang.isEmpty()) {
- lang = QLocale::system().name();
- }
- qDebug() << "Language set" << lang;
- translator.load(RESOURCE_DIR(appPath) + "/ts/" + "gpgfrontend_" + lang);
- qDebug() << "Translator" << translator.filePath();
- QApplication::installTranslator(&translator);
-
- // set qt translations
- translator2.load(RESOURCE_DIR(appPath) + "/ts/qt_" + lang);
- qDebug() << "Translator2" << translator2.filePath();
- QApplication::installTranslator(&translator2);
-
- QApplication::setQuitOnLastWindowClosed(true);
-
- MainWindow window;
- return_from_event_loop_code = QApplication::exec();
-
- } while (return_from_event_loop_code == RESTART_CODE);
-
- return return_from_event_loop_code;
+ * The function `gpgme_check_version' must be called before any other
+ * function in the library, because it initializes the thread support
+ * subsystem in GPGME. (from the info page) */
+ gpgme_check_version(nullptr);
+
+ /** set locale, because tests do also */
+ gpgme_set_locale(nullptr, LC_CTYPE, setlocale(LC_CTYPE, nullptr));
+#ifndef _WIN32
+ gpgme_set_locale(nullptr, LC_MESSAGES, setlocale(LC_MESSAGES, nullptr));
+#endif
+
+ auto main_window = std::make_unique<GpgFrontend::UI::MainWindow>();
+ main_window->init();
+ main_window->show();
+ return_from_event_loop_code = QApplication::exec();
+
+ } while (return_from_event_loop_code == RESTART_CODE);
+
+ return return_from_event_loop_code;
}
+void init_logging() {
+ using namespace boost::posix_time;
+ using namespace boost::gregorian;
+ ptime now = second_clock::local_time();
+ el::Loggers::addFlag(el::LoggingFlag::AutoSpacing);
+ el::Configurations defaultConf;
+ defaultConf.setToDefault();
+ el::Loggers::reconfigureLogger("default", defaultConf);
+
+ defaultConf.setGlobally(el::ConfigurationType::Format,
+ "%datetime %level %func %msg");
+
+ auto logfile_path =
+ (GpgFrontend::UI::GlobalSettingStation::GetInstance().GetLogDir() /
+ to_iso_string(now));
+ logfile_path.replace_extension(".log");
+ defaultConf.setGlobally(el::ConfigurationType::Filename,
+ logfile_path.string());
+
+ el::Loggers::reconfigureLogger("default", defaultConf);
+
+ LOG(INFO) << _("Logfile Path") << logfile_path;
+}
+
+void init_locale() {
+ auto& settings =
+ GpgFrontend::UI::GlobalSettingStation::GetInstance().GetUISettings();
+
+ if (!settings.exists("general") ||
+ settings.lookup("general").getType() != libconfig::Setting::TypeGroup)
+ settings.add("general", libconfig::Setting::TypeGroup);
+
+ // set system default at first
+ auto& general = settings["general"];
+ if (!general.exists("lang"))
+ general.add("lang", libconfig::Setting::TypeString) = "";
+
+ GpgFrontend::UI::GlobalSettingStation::GetInstance().Sync();
+
+ auto* locale_name = setlocale(LC_ALL, nullptr);
+ LOG(INFO) << "current system locale" << locale_name;
+
+ // read from settings file
+ std::string lang;
+ if (!general.lookupValue("lang", lang)) {
+ LOG(ERROR) << _("Could not read properly from configure file");
+ };
+
+ LOG(INFO) << "lang" << lang;
+ LOG(INFO) << "PROJECT_NAME" << PROJECT_NAME;
+ LOG(INFO) << "locales path"
+ << GpgFrontend::UI::GlobalSettingStation::GetInstance()
+ .GetLocaleDir()
+ .c_str();
+
+ if (!lang.empty()) lang += ".UTF8";
+ // GNU gettext settings
+ locale_name = setlocale(LC_ALL, lang.c_str());
+ if (locale_name == nullptr) {
+ LOG(WARNING) << "set locale name failed";
+ } else {
+ LOG(INFO) << "locale name now" << locale_name;
+ }
+
+ bindtextdomain(PROJECT_NAME,
+ GpgFrontend::UI::GlobalSettingStation::GetInstance()
+ .GetLocaleDir()
+ .string()
+ .c_str());
+ textdomain(PROJECT_NAME);
+}
diff --git a/src/server/BaseAPI.cpp b/src/server/BaseAPI.cpp
index be388df9..aa4c3f98 100644
--- a/src/server/BaseAPI.cpp
+++ b/src/server/BaseAPI.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -23,48 +23,47 @@
*/
#include "server/BaseAPI.h"
+
#include "rapidjson/writer.h"
-BaseAPI::BaseAPI(ComUtils::ServiceType serviceType) : utils(new ComUtils(nullptr)),
- reqUrl(utils->getUrl(serviceType)), request(reqUrl) {
- request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
+BaseAPI::BaseAPI(ComUtils::ServiceType serviceType)
+ : utils(new ComUtils(nullptr)),
+ reqUrl(utils->getUrl(serviceType)),
+ request(reqUrl) {
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
}
-BaseAPI::~BaseAPI() {
- utils->deleteLater();
-}
+BaseAPI::~BaseAPI() { utils->deleteLater(); }
QNetworkReply *BaseAPI::send_json_data() {
- rapidjson::StringBuffer sb;
- rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
- document.Accept(writer);
+ rapidjson::StringBuffer sb;
+ rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
+ document.Accept(writer);
- QByteArray postData(sb.GetString());
- qDebug() << "postData" << QString::fromUtf8(postData);
+ QByteArray postData(sb.GetString());
+ qDebug() << "postData" << QString::fromUtf8(postData);
- auto reply = utils->getNetworkManager().post(request, postData);
+ auto reply = utils->getNetworkManager().post(request, postData);
- while (reply->isRunning()) QApplication::processEvents();
+ while (reply->isRunning()) QApplication::processEvents();
- QByteArray replyData = reply->readAll().constData();
- if (utils->checkServerReply(replyData)) {
- good = true, deal_reply();
- }
+ QByteArray replyData = reply->readAll().constData();
+ if (utils->checkServerReply(replyData)) {
+ good = true, deal_reply();
+ }
- return reply;
+ return reply;
}
void BaseAPI::start() {
- construct_json();
- send_json_data()->deleteLater();
+ construct_json();
+ send_json_data()->deleteLater();
}
void BaseAPI::refresh() {
- document.Clear();
- utils->clear();
- good = false;
+ document.Clear();
+ utils->clear();
+ good = false;
}
-bool BaseAPI::result() const {
- return good;
-}
+bool BaseAPI::result() const { return good; }
diff --git a/src/server/BaseAPI.h b/src/server/BaseAPI.h
new file mode 100644
index 00000000..46766fed
--- /dev/null
+++ b/src/server/BaseAPI.h
@@ -0,0 +1,66 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_ZH_CN_TS_BASEAPI_H
+#define GPGFRONTEND_ZH_CN_TS_BASEAPI_H
+
+#include "ComUtils.h"
+#include "GpgFrontend.h"
+#include "rapidjson/document.h"
+
+class BaseAPI : public QObject {
+ Q_OBJECT
+ public:
+ explicit BaseAPI(ComUtils::ServiceType serviceType);
+
+ ~BaseAPI() override;
+
+ void start();
+
+ void refresh();
+
+ [[nodiscard]] bool result() const;
+
+ private:
+ ComUtils *utils;
+
+ QUrl reqUrl;
+
+ QNetworkRequest request;
+
+ QNetworkReply *send_json_data();
+
+ protected:
+ bool good = false;
+
+ rapidjson::Document document;
+
+ const ComUtils &getUtils() { return *utils; };
+
+ virtual void construct_json() = 0;
+
+ virtual void deal_reply() = 0;
+};
+
+#endif // GPGFRONTEND_ZH_CN_TS_BASEAPI_H
diff --git a/src/server/ComUtils.cpp b/src/server/ComUtils.cpp
index 01be4ea7..6a5ce7b0 100644
--- a/src/server/ComUtils.cpp
+++ b/src/server/ComUtils.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -29,67 +29,71 @@
* @param reply reply data in byte array
* @return if successful
*/
-bool ComUtils::checkServerReply(const QByteArray &reply) {
-
- if(reply.isEmpty()) {
- QMessageBox::critical(this, tr("Error"), tr("Nothing Reply. Please check the Internet connection."));
- return false;
+bool GpgFrontend::ComUtils::checkServerReply(const QByteArray &reply) {
+ if (reply.isEmpty()) {
+ QMessageBox::critical(
+ this, _("Error"),
+ _("Nothing Reply. Please check the Internet connection."));
+ return false;
+ }
+
+ qDebug() << "Reply" << reply;
+
+ /**
+ * Server Reply Format(Except Timeout)
+ * {
+ * "status": 200,
+ * "msg": "OK",
+ * "timestamp": 1628652783895
+ * "data" : {
+ * ...
+ * }
+ * }
+ */
+
+ // check if reply is a json object
+ if (replyDoc.Parse(reply).HasParseError() || !replyDoc.IsObject()) {
+ QMessageBox::critical(this, _("Error"), _("Unknown Error"));
+ return false;
+ }
+
+ // check status(int) and message(string)
+ if (replyDoc.HasMember("status") && replyDoc.HasMember("msg") &&
+ replyDoc.HasMember("timestamp") && replyDoc.HasMember("data") &&
+ replyDoc["status"].IsNumber() && replyDoc["msg"].IsString() &&
+ replyDoc["timestamp"].IsNumber() && replyDoc["data"].IsObject()) {
+ int status = replyDoc["status"].GetInt();
+ QDateTime time;
+ time.setMSecsSinceEpoch(replyDoc["timestamp"].GetInt64());
+ auto message = replyDoc["msg"].GetString();
+ dataVal = replyDoc["data"].GetObject();
+
+ qDebug() << "Reply Date & Time" << time;
+
+ // check reply timestamp
+ if (time < QDateTime::currentDateTime().addSecs(-10)) {
+ QMessageBox::critical(this, _("Network Error"), _("Outdated Reply"));
+ return false;
}
- qDebug() << "Reply" << reply;
-
- /**
- * Server Reply Format(Except Timeout)
- * {
- * "status": 200,
- * "msg": "OK",
- * "timestamp": 1628652783895
- * "data" : {
- * ...
- * }
- * }
- */
-
- // check if reply is a json object
- if (replyDoc.Parse(reply).HasParseError() || !replyDoc.IsObject()) {
- QMessageBox::critical(this, tr("Error"), tr("Unknown Error"));
- return false;
+ // check status code if successful (200-299)
+ // check data object
+ if (status / 100 == 2) {
+ is_good = true;
+ return true;
+ } else {
+ if (dataVal.HasMember("exceptionMessage") &&
+ dataVal["exceptionMessage"].IsString())
+ QMessageBox::critical(this, message,
+ dataVal["exceptionMessage"].GetString());
+ else
+ QMessageBox::critical(this, message, _("Unknown Reason"));
}
- // check status(int) and message(string)
- if (replyDoc.HasMember("status") && replyDoc.HasMember("msg") && replyDoc.HasMember("timestamp") &&
- replyDoc.HasMember("data")
- && replyDoc["status"].IsNumber() && replyDoc["msg"].IsString() && replyDoc["timestamp"].IsNumber() &&
- replyDoc["data"].IsObject()) {
-
- int status = replyDoc["status"].GetInt();
- QDateTime time;
- time.setMSecsSinceEpoch(replyDoc["timestamp"].GetInt64());
- auto message = replyDoc["msg"].GetString();
- dataVal = replyDoc["data"].GetObject();
-
- qDebug() << "Reply Date & Time" << time;
-
- // check reply timestamp
- if (time < QDateTime::currentDateTime().addSecs(-10)) {
- QMessageBox::critical(this, tr("Network Error"), tr("Outdated Reply"));
- return false;
- }
-
- // check status code if successful (200-299)
- // check data object
- if (status / 100 == 2) {
- is_good = true;
- return true;
- } else {
- if (dataVal.HasMember("exceptionMessage") && dataVal["exceptionMessage"].IsString())
- QMessageBox::critical(this, message, dataVal["exceptionMessage"].GetString());
- else QMessageBox::critical(this, message, tr("Unknown Reason"));
- }
-
- } else QMessageBox::critical(this, tr("Network Error"), tr("Unknown Reply Format"));
+ } else
+ QMessageBox::critical(this, _("Network Error"), _("Unknown Reply Format"));
- return false;
+ return false;
}
/**
@@ -97,13 +101,15 @@ bool ComUtils::checkServerReply(const QByteArray &reply) {
* @param key key of value
* @return value in string format
*/
-QString ComUtils::getDataValueStr(const QString &key) const {
- if (is_good) {
- auto k_byte_array = key.toUtf8();
- if (dataVal.HasMember(k_byte_array.data())) {
- return dataVal[k_byte_array.data()].GetString();
- } else return {};
- } else return {};
+QString GpgFrontend::ComUtils::getDataValueStr(const QString &key) const {
+ if (is_good) {
+ auto k_byte_array = key.toUtf8();
+ if (dataVal.HasMember(k_byte_array.data())) {
+ return dataVal[k_byte_array.data()].GetString();
+ } else
+ return {};
+ } else
+ return {};
}
/**
@@ -111,87 +117,97 @@ QString ComUtils::getDataValueStr(const QString &key) const {
* @param type service which server provides
* @return url
*/
-QString ComUtils::getUrl(ComUtils::ServiceType type) const {
- auto host = settings.value("general/currentGpgfrontendServer",
- "service.gpgfrontend.pub").toString();
-
- auto protocol = QString();
- // Localhost Debug Server
- if (host == "localhost") protocol = "http://";
- else protocol = "https://";
-
- auto url = protocol + host + ":9049/";
-
- switch (type) {
- case GetServiceToken:
- url += "/user";
- break;
- case ShortenCryptText:
- url += "/text/new";
- break;
- case GetFullCryptText:
- url += "/text/get";
- break;
- case UploadPubkey:
- url += "/key/upload";
- break;
- case GetPubkey:
- url += "/key/get";
- break;
- }
-
- qDebug() << "ComUtils getUrl" << url;
-
- return url;
+QString GpgFrontend::ComUtils::getUrl(ComUtils::ServiceType type) const {
+ auto host =
+ settings
+ .value("general/currentGpgfrontendServer", "service.gpgfrontend.pub")
+ .toString();
+
+ auto protocol = QString();
+ // Localhost Debug Server
+ if (host == "localhost")
+ protocol = "http://";
+ else
+ protocol = "https://";
+
+ auto url = protocol + host + ":9049/";
+
+ switch (type) {
+ case GetServiceToken:
+ url += "/user";
+ break;
+ case ShortenCryptText:
+ url += "/text/new";
+ break;
+ case GetFullCryptText:
+ url += "/text/get";
+ break;
+ case UploadPubkey:
+ url += "/key/upload";
+ break;
+ case GetPubkey:
+ url += "/key/get";
+ break;
+ }
+
+ qDebug() << "ComUtils getUrl" << url;
+
+ return url;
}
-bool ComUtils::checkDataValueStr(const QString &key) const {
- auto key_byte_array_data = key.toUtf8().constData();
- if (is_good) {
- return dataVal.HasMember(key_byte_array_data) && dataVal[key_byte_array_data].IsString();
- } else return false;
+bool GpgFrontend::ComUtils::checkDataValueStr(const QString &key) const {
+ auto key_byte_array_data = key.toUtf8().constData();
+ if (is_good) {
+ return dataVal.HasMember(key_byte_array_data) &&
+ dataVal[key_byte_array_data].IsString();
+ } else
+ return false;
}
-bool ComUtils::checkServiceTokenFormat(const QString &uuid) const {
- return re_uuid.match(uuid).hasMatch();
+bool GpgFrontend::ComUtils::checkServiceTokenFormat(const QString &uuid) const {
+ return re_uuid.match(uuid).hasMatch();
}
-QByteArray ComUtils::getSignStringBase64(GpgME::GpgContext *ctx, const QString &str, const GpgKey &key) {
- QVector<GpgKey> keys{key};
- QByteArray outSignText;
- auto signData = str.toUtf8();
-
- // The use of multi-threading brings an improvement in UI smoothness
- gpgme_error_t error;
- auto thread = QThread::create([&]() {
- error = ctx->sign(keys, signData, &outSignText, GPGME_SIG_MODE_NORMAL, nullptr, false);
- });
- thread->start();
- while (thread->isRunning()) QApplication::processEvents();
- thread->deleteLater();
-
- return outSignText.toBase64();
+QByteArray GpgFrontend::ComUtils::getSignStringBase64(
+ GpgFrontend::GpgContext *ctx, const QString &str, const GpgKey &key) {
+ std::vector<GpgKey> keys{key};
+ QByteArray outSignText;
+ auto signData = str.toUtf8();
+
+ // The use of multi-threading brings an improvement in UI smoothness
+ gpgme_error_t error;
+ auto thread = QThread::create([&]() {
+ error = ctx->sign(keys, signData, &outSignText, GPGME_SIG_MODE_NORMAL,
+ nullptr, false);
+ });
+ thread->start();
+ while (thread->isRunning()) QApplication::processEvents();
+ thread->deleteLater();
+
+ return outSignText.toBase64();
}
-const rapidjson::Value &ComUtils::getDataValue(const QString &key) const {
- if (is_good) {
- auto k_byte_array = key.toUtf8();
- if (dataVal.HasMember(k_byte_array.data())) {
- return dataVal[k_byte_array.data()];
- }
+const rapidjson::Value &GpgFrontend::ComUtils::getDataValue(
+ const QString &key) const {
+ if (is_good) {
+ auto k_byte_array = key.toUtf8();
+ if (dataVal.HasMember(k_byte_array.data())) {
+ return dataVal[k_byte_array.data()];
}
- throw std::runtime_error("Inner Error");
+ }
+ throw std::runtime_error("Inner Error");
}
-bool ComUtils::checkDataValue(const QString &key) const{
- auto key_byte_array_data = key.toUtf8().constData();
- if (is_good) {
- return dataVal.HasMember(key_byte_array_data);
- } else return false;
+bool GpgFrontend::ComUtils::checkDataValue(const QString &key) const {
+ auto key_byte_array_data = key.toUtf8().constData();
+ if (is_good) {
+ return dataVal.HasMember(key_byte_array_data);
+ } else
+ return false;
}
-void ComUtils::clear() {
- this->dataVal.Clear();
- this->replyDoc.Clear();
- is_good = false;
+void GpgFrontend::ComUtils::clear() {
+ this->dataVal.Clear();
+ this->replyDoc.Clear();
+ is_good = false;
} \ No newline at end of file
diff --git a/src/server/ComUtils.h b/src/server/ComUtils.h
new file mode 100644
index 00000000..f281f256
--- /dev/null
+++ b/src/server/ComUtils.h
@@ -0,0 +1,88 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_ZH_CN_TS_COMUTILS_H
+#define GPGFRONTEND_ZH_CN_TS_COMUTILS_H
+
+#include "GpgFrontend.h"
+#include "gpg/GpgContext.h"
+#include "rapidjson/document.h"
+
+namespace GpgFrontend {
+
+class ComUtils : public QWidget {
+ Q_OBJECT
+ public:
+ enum ServiceType {
+ GetServiceToken,
+ ShortenCryptText,
+ GetFullCryptText,
+ UploadPubkey,
+ GetPubkey
+ };
+
+ explicit ComUtils(QWidget *parent)
+ : QWidget(parent),
+ appPath(qApp->applicationDirPath()),
+ settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini",
+ QSettings::IniFormat) {}
+
+ [[nodiscard]] QString getUrl(ServiceType type) const;
+
+ bool checkServerReply(const QByteArray &reply);
+
+ [[nodiscard]] QString getDataValueStr(const QString &key) const;
+
+ [[nodiscard]] bool checkDataValueStr(const QString &key) const;
+
+ [[nodiscard]] const rapidjson::Value &getDataValue(const QString &key) const;
+
+ [[nodiscard]] bool checkDataValue(const QString &key) const;
+
+ [[nodiscard]] bool checkServiceTokenFormat(const QString &serviceToken) const;
+
+ static QByteArray getSignStringBase64(GpgFrontend::GpgContext *ctx,
+ const QString &str, const GpgKey &key);
+
+ [[nodiscard]] bool good() const { return is_good; }
+
+ QNetworkAccessManager &getNetworkManager() { return networkMgr; }
+
+ void clear();
+
+ private:
+ QString appPath;
+ QSettings settings;
+ rapidjson::Document replyDoc;
+ rapidjson::Value dataVal;
+ QNetworkAccessManager networkMgr;
+ QRegularExpression re_uuid{
+ R"(\b[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}\b)"};
+
+ bool is_good = false;
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_ZH_CN_TS_COMUTILS_H
diff --git a/src/server/api/PubkeyGetter.cpp b/src/server/api/PubkeyGetter.cpp
index 2ba55d11..e2cb8708 100644
--- a/src/server/api/PubkeyGetter.cpp
+++ b/src/server/api/PubkeyGetter.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,73 +24,72 @@
#include "server/api/PubkeyGetter.h"
-PubkeyGetter::PubkeyGetter(GpgME::GpgContext *ctx, const QVector<QString> &fprs) : BaseAPI(ComUtils::GetPubkey),
- mCtx(ctx), mFprs(fprs) {
-}
+PubkeyGetter::PubkeyGetter(GpgFrontend::GpgContext *ctx,
+ const QVector<QString> &fprs)
+ : BaseAPI(ComUtils::GetPubkey), mCtx(ctx), mFprs(fprs) {}
void PubkeyGetter::construct_json() {
- document.SetArray();
- QStringList keyIds;
+ document.SetArray();
+ QStringList keyIds;
- rapidjson::Document::AllocatorType &allocator = document.GetAllocator();
+ rapidjson::Document::AllocatorType &allocator = document.GetAllocator();
- for (const auto &fprStr : mFprs) {
- rapidjson::Value fpr;
+ for (const auto &fprStr : mFprs) {
+ rapidjson::Value fpr;
- auto fprByteArray = fprStr.toUtf8();
- fpr.SetString(fprByteArray.constData(), fprByteArray.count());
+ auto fprByteArray = fprStr.toUtf8();
+ fpr.SetString(fprByteArray.constData(), fprByteArray.count());
- document.PushBack(fpr, allocator);
- keyIds.clear();
- }
+ document.PushBack(fpr, allocator);
+ keyIds.clear();
+ }
}
void PubkeyGetter::deal_reply() {
+ const auto &utils = getUtils();
+
+ /**
+ * {
+ * "pubkeys" : [
+ * {
+ * "publicKey" : ...,
+ * "fpr" : ...,
+ * "sha" : ...
+ * },
+ * ...
+ * ]
+ * }
+ */
+
+ if (!utils.checkDataValue("pubkeys")) {
+ QMessageBox::critical(nullptr, _("Error"),
+ _("The communication content with the server does "
+ "not meet the requirements"));
+ } else {
+ auto &pubkeys = utils.getDataValue("pubkeys");
+ qDebug() << "Pubkey Getter" << pubkeys.IsArray()
+ << pubkeys.GetArray().Size();
+ if (pubkeys.IsArray()) {
+ for (const auto &pubkey : pubkeys.GetArray()) {
+ if (pubkey.IsObject() && pubkey.HasMember("publicKey") &&
+ pubkey.HasMember("fpr") && pubkey.HasMember("sha") &&
+ pubkey["publicKey"].IsString() && pubkey["fpr"].IsString() &&
+ pubkey["sha"].IsString()) {
+ auto pubkeyData = QString(pubkey["publicKey"].GetString());
+
+ QCryptographicHash shaGen(QCryptographicHash::Sha256);
+ shaGen.addData(pubkeyData.toUtf8());
+
+ if (shaGen.result().toHex() == pubkey["sha"].GetString()) {
+ mCtx->importKey(pubkeyData.toUtf8());
+ }
+ }
+ }
- const auto &utils = getUtils();
-
- /**
- * {
- * "pubkeys" : [
- * {
- * "publicKey" : ...,
- * "fpr" : ...,
- * "sha" : ...
- * },
- * ...
- * ]
- * }
- */
-
- if (!utils.checkDataValue("pubkeys")) {
- QMessageBox::critical(nullptr, tr("Error"),
- tr("The communication content with the server does not meet the requirements"));
} else {
- auto &pubkeys = utils.getDataValue("pubkeys");
- qDebug() << "Pubkey Getter" << pubkeys.IsArray() << pubkeys.GetArray().Size();
- if (pubkeys.IsArray()) {
- for (const auto &pubkey : pubkeys.GetArray()) {
- if (pubkey.IsObject()
- && pubkey.HasMember("publicKey") && pubkey.HasMember("fpr") && pubkey.HasMember("sha")
- && pubkey["publicKey"].IsString() && pubkey["fpr"].IsString() && pubkey["sha"].IsString()) {
-
- auto pubkeyData = QString(pubkey["publicKey"].GetString());
-
- QCryptographicHash shaGen(QCryptographicHash::Sha256);
- shaGen.addData(pubkeyData.toUtf8());
-
- if (shaGen.result().toHex() == pubkey["sha"].GetString()) {
- mCtx->importKey(pubkeyData.toUtf8());
- }
-
- }
- }
-
- } else {
- QMessageBox::critical(nullptr, tr("Error"),
- tr("The communication content with the server does not meet the requirements"));
- }
+ QMessageBox::critical(nullptr, _("Error"),
+ _("The communication content with the server does "
+ "not meet the requirements"));
}
+ }
}
-
-
diff --git a/src/server/api/PubkeyGetter.h b/src/server/api/PubkeyGetter.h
new file mode 100644
index 00000000..6a3d50e9
--- /dev/null
+++ b/src/server/api/PubkeyGetter.h
@@ -0,0 +1,52 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_ZH_CN_TS_PUBKEYGETTER_H
+#define GPGFRONTEND_ZH_CN_TS_PUBKEYGETTER_H
+
+#include "GpgFrontend.h"
+#include "gpg/GpgContext.h"
+#include "server/BaseAPI.h"
+
+class ComUtils;
+
+/**
+ * Get and Import Pubkey from server
+ */
+class PubkeyGetter : public BaseAPI {
+ public:
+ PubkeyGetter(GpgFrontend::GpgContext *ctx, const QVector<QString> &fprs);
+
+ private:
+ GpgFrontend::GpgContext *mCtx;
+
+ const QVector<QString> &mFprs;
+
+ protected:
+ void construct_json() final;
+
+ void deal_reply() final;
+};
+
+#endif // GPGFRONTEND_ZH_CN_TS_PUBKEYGETTER_H
diff --git a/src/server/api/PubkeyUploader.cpp b/src/server/api/PubkeyUploader.cpp
index c6101c65..35f764d8 100644
--- a/src/server/api/PubkeyUploader.cpp
+++ b/src/server/api/PubkeyUploader.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,83 +24,83 @@
#include "server/api/PubkeyUploader.h"
-PubkeyUploader::PubkeyUploader(GpgME::GpgContext *ctx, const QVector<GpgKey> &keys) : BaseAPI(ComUtils::UploadPubkey),
- mCtx(ctx),
- mKeys(keys) {
-}
+PubkeyUploader::PubkeyUploader(GpgFrontend::GpgContext *ctx,
+ const QVector<GpgKey> &keys)
+ : BaseAPI(ComUtils::UploadPubkey), mCtx(ctx), mKeys(keys) {}
void PubkeyUploader::construct_json() {
- document.SetArray();
- QStringList keyIds;
- QCryptographicHash shaGen(QCryptographicHash::Sha256);
-
- auto &allocator = document.GetAllocator();
-
- QVector<QByteArray> keysData;
- for (const auto &key : mKeys) {
- QByteArray keyDataBuf;
- keyIds << key.id;
-
- // The use of multi-threading brings an improvement in UI smoothness
- gpgme_error_t error;
- auto thread = QThread::create([&]() {
- error = mCtx->exportKeys(&keyIds, &keyDataBuf);
- });
- thread->start();
- while (thread->isRunning()) QApplication::processEvents();
- thread->deleteLater();
- keysData.push_back(keyDataBuf);
- keyIds.clear();
- }
-
- int index = 0;
- for (const auto &keyData : keysData) {
- rapidjson::Value publicKeyObj, pubkey, sha, signedFpr;
-
- shaGen.addData(keyData);
- auto shaStr = shaGen.result().toHex();
- shaGen.reset();
-
- auto signFprStr = ComUtils::getSignStringBase64(mCtx, mKeys[index].fpr, mKeys[index]);
- qDebug() << "signFprStr" << signFprStr;
-
- pubkey.SetString(keyData.data(), keyData.count(), allocator);
- sha.SetString(shaStr.data(), shaStr.count(), allocator);
- signedFpr.SetString(signFprStr.data(), signFprStr.count(), allocator);
-
- publicKeyObj.SetObject();
- publicKeyObj.AddMember("publicKey", pubkey, allocator);
- publicKeyObj.AddMember("sha", sha, allocator);
- publicKeyObj.AddMember("signedFpr", signedFpr, allocator);
-
- document.PushBack(publicKeyObj, allocator);
- index++;
- }
+ document.SetArray();
+ QStringList keyIds;
+ QCryptographicHash shaGen(QCryptographicHash::Sha256);
+
+ auto &allocator = document.GetAllocator();
+
+ QVector<QByteArray> keysData;
+ for (const auto &key : mKeys) {
+ QByteArray keyDataBuf;
+ keyIds << key.id;
+
+ // The use of multi-threading brings an improvement in UI smoothness
+ gpgme_error_t error;
+ auto thread = QThread::create(
+ [&]() { error = mCtx->exportKeys(&keyIds, &keyDataBuf); });
+ thread->start();
+ while (thread->isRunning()) QApplication::processEvents();
+ thread->deleteLater();
+ keysData.push_back(keyDataBuf);
+ keyIds.clear();
+ }
+
+ int index = 0;
+ for (const auto &keyData : keysData) {
+ rapidjson::Value publicKeyObj, pubkey, sha, signedFpr;
+
+ shaGen.addData(keyData);
+ auto shaStr = shaGen.result().toHex();
+ shaGen.reset();
+
+ auto signFprStr =
+ ComUtils::getSignStringBase64(mCtx, mKeys[index].fpr, mKeys[index]);
+ qDebug() << "signFprStr" << signFprStr;
+
+ pubkey.SetString(keyData.data(), keyData.count(), allocator);
+ sha.SetString(shaStr.data(), shaStr.count(), allocator);
+ signedFpr.SetString(signFprStr.data(), signFprStr.count(), allocator);
+
+ publicKeyObj.SetObject();
+ publicKeyObj.AddMember("publicKey", pubkey, allocator);
+ publicKeyObj.AddMember("sha", sha, allocator);
+ publicKeyObj.AddMember("signedFpr", signedFpr, allocator);
+
+ document.PushBack(publicKeyObj, allocator);
+ index++;
+ }
}
void PubkeyUploader::deal_reply() {
-
- const auto &utils = getUtils();
-
- /**
- * {
- * "strings" : [
- * "...",
- * "..."
- * ]
- * }
- */
-
- if (!utils.checkDataValue("strings")) {
- QMessageBox::critical(nullptr, tr("Error"),
- tr("The communication content with the server does not meet the requirements"));
+ const auto &utils = getUtils();
+
+ /**
+ * {
+ * "strings" : [
+ * "...",
+ * "..."
+ * ]
+ * }
+ */
+
+ if (!utils.checkDataValue("strings")) {
+ QMessageBox::critical(nullptr, _("Error"),
+ _("The communication content with the server does "
+ "not meet the requirements"));
+ } else {
+ auto &strings = utils.getDataValue("strings");
+ qDebug() << "Pubkey Uploader" << strings.IsArray()
+ << strings.GetArray().Size();
+ if (strings.IsArray() && strings.GetArray().Size() == mKeys.size()) {
+ good = true;
} else {
- auto &strings = utils.getDataValue("strings");
- qDebug() << "Pubkey Uploader" << strings.IsArray() << strings.GetArray().Size();
- if (strings.IsArray() && strings.GetArray().Size() == mKeys.size()) {
- good = true;
- } else {
- good = false;
- }
+ good = false;
}
+ }
}
diff --git a/src/server/api/PubkeyUploader.h b/src/server/api/PubkeyUploader.h
new file mode 100644
index 00000000..efad27ac
--- /dev/null
+++ b/src/server/api/PubkeyUploader.h
@@ -0,0 +1,51 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_ZH_CN_TS_PUBKEYUPLOADER_H
+#define GPGFRONTEND_ZH_CN_TS_PUBKEYUPLOADER_H
+
+#include "GpgFrontend.h"
+#include "gpg/GpgContext.h"
+#include "rapidjson/document.h"
+#include "server/BaseAPI.h"
+
+/**
+ * Upload pubkey into server
+ */
+class PubkeyUploader : public BaseAPI {
+ public:
+ PubkeyUploader(GpgFrontend::GpgContext *ctx, const QVector<GpgKey> &keys);
+
+ private:
+ const QVector<GpgKey> &mKeys;
+
+ GpgFrontend::GpgContext *mCtx;
+
+ protected:
+ void construct_json() final;
+
+ void deal_reply() final;
+};
+
+#endif // GPGFRONTEND_ZH_CN_TS_PUBKEYUPLOADER_H
diff --git a/src/smtp/SmtpMime b/src/smtp/SmtpMime
new file mode 100644
index 00000000..940996b8
--- /dev/null
+++ b/src/smtp/SmtpMime
@@ -0,0 +1,31 @@
+/*
+ Copyright (c) 2011-2012 - Tőkés Attila
+
+ This file is part of SmtpClient for Qt.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ See the LICENSE file for more details.
+*/
+
+#ifndef SMTPMIME_H
+#define SMTPMIME_H
+
+#include "smtpclient.h"
+#include "mimepart.h"
+#include "mimehtml.h"
+#include "mimeattachment.h"
+#include "mimemessage.h"
+#include "mimetext.h"
+#include "mimeinlinefile.h"
+#include "mimefile.h"
+
+#endif // SMTPMIME_H
diff --git a/src/smtp/emailaddress.h b/src/smtp/emailaddress.h
new file mode 100644
index 00000000..90e4c1e9
--- /dev/null
+++ b/src/smtp/emailaddress.h
@@ -0,0 +1,63 @@
+/*
+ Copyright (c) 2011-2012 - Tőkés Attila
+
+ This file is part of SmtpClient for Qt.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ See the LICENSE file for more details.
+*/
+
+#ifndef EMAILADDRESS_H
+#define EMAILADDRESS_H
+
+#include <QObject>
+
+#include "smtpexports.h"
+
+class SMTP_EXPORT EmailAddress : public QObject {
+Q_OBJECT
+public:
+
+ /* [1] Constructors and Destructors */
+
+ EmailAddress() = default;
+
+ explicit EmailAddress(const QString &address, const QString &name = "");
+
+ ~EmailAddress() override;
+
+ /* [1] --- */
+
+
+ /* [2] Getters and Setters */
+ void setName(const QString &name);
+
+ void setAddress(const QString &address);
+
+ [[nodiscard]] const QString &getName() const;
+
+ [[nodiscard]] const QString &getAddress() const;
+
+ /* [2] --- */
+
+
+private:
+
+ /* [3] Private members */
+
+ QString name;
+ QString address;
+
+ /* [3] --- */
+};
+
+#endif // EMAILADDRESS_H
diff --git a/src/smtp/mimeattachment.h b/src/smtp/mimeattachment.h
new file mode 100644
index 00000000..6b98a65a
--- /dev/null
+++ b/src/smtp/mimeattachment.h
@@ -0,0 +1,51 @@
+/*
+ Copyright (c) 2011-2012 - Tőkés Attila
+
+ This file is part of SmtpClient for Qt.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ See the LICENSE file for more details.
+*/
+
+#ifndef MIMEATTACHMENT_H
+#define MIMEATTACHMENT_H
+
+#include <QFile>
+#include "mimepart.h"
+#include "mimefile.h"
+
+#include "smtpexports.h"
+
+class SMTP_EXPORT MimeAttachment : public MimeFile {
+Q_OBJECT
+public:
+
+ /* [1] Constructors and Destructors */
+
+ explicit MimeAttachment(QFile *file);
+
+ MimeAttachment(const QByteArray &stream, const QString &fileName);
+
+ ~MimeAttachment() override;
+
+ /* [1] --- */
+
+protected:
+
+ /* [2] Protected methods */
+
+ void prepare() override;
+
+ /* [2] --- */
+};
+
+#endif // MIMEATTACHMENT_H
diff --git a/src/smtp/mimecontentformatter.h b/src/smtp/mimecontentformatter.h
new file mode 100644
index 00000000..e6e3637f
--- /dev/null
+++ b/src/smtp/mimecontentformatter.h
@@ -0,0 +1,43 @@
+/*
+ Copyright (c) 2011-2012 - Tőkés Attila
+
+ This file is part of SmtpClient for Qt.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ See the LICENSE file for more details.
+*/
+
+#ifndef MIMECONTENTFORMATTER_H
+#define MIMECONTENTFORMATTER_H
+
+#include <QObject>
+#include <QByteArray>
+
+#include "smtpexports.h"
+
+class SMTP_EXPORT MimeContentFormatter : public QObject {
+Q_OBJECT
+public:
+ explicit MimeContentFormatter(int max_length = 76);
+
+ void setMaxLength(int l);
+
+ [[nodiscard]] int getMaxLength() const;
+
+ [[nodiscard]] QString format(const QString &content, bool quotedPrintable = false) const;
+
+protected:
+ int max_length;
+
+};
+
+#endif // MIMECONTENTFORMATTER_H
diff --git a/src/smtp/mimefile.h b/src/smtp/mimefile.h
new file mode 100644
index 00000000..46903da9
--- /dev/null
+++ b/src/smtp/mimefile.h
@@ -0,0 +1,63 @@
+/*
+ Copyright (c) 2011-2012 - Tőkés Attila
+
+ This file is part of SmtpClient for Qt.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ See the LICENSE file for more details.
+*/
+
+#ifndef MIMEFILE_H
+#define MIMEFILE_H
+
+#include "mimepart.h"
+#include <QFile>
+
+#include "smtpexports.h"
+
+class SMTP_EXPORT MimeFile : public MimePart {
+Q_OBJECT
+public:
+
+ /* [1] Constructors and Destructors */
+
+ MimeFile(const QByteArray &stream, const QString &fileName);
+
+ explicit MimeFile(QFile *f);
+
+ ~MimeFile() override;
+
+ /* [1] --- */
+
+
+ /* [2] Getters and Setters */
+
+ /* [2] --- */
+
+protected:
+
+ /* [3] Protected members */
+
+ QFile *file;
+
+ /* [3] --- */
+
+
+ /* [4] Protected methods */
+
+ void prepare() override;
+
+ /* [4] --- */
+
+};
+
+#endif // MIMEFILE_H
diff --git a/src/smtp/mimehtml.h b/src/smtp/mimehtml.h
new file mode 100644
index 00000000..8ce8c454
--- /dev/null
+++ b/src/smtp/mimehtml.h
@@ -0,0 +1,61 @@
+/*
+ Copyright (c) 2011-2012 - Tőkés Attila
+
+ This file is part of SmtpClient for Qt.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ See the LICENSE file for more details.
+*/
+
+#ifndef MIMEHTML_H
+#define MIMEHTML_H
+
+#include "mimetext.h"
+
+#include "smtpexports.h"
+
+class SMTP_EXPORT MimeHtml : public MimeText {
+Q_OBJECT
+public:
+
+ /* [1] Constructors and Destructors */
+
+ explicit MimeHtml(const QString &html = "");
+
+ ~MimeHtml() override;
+
+ /* [1] --- */
+
+
+ /* [2] Getters and Setters */
+
+ void setHtml(const QString &html);
+
+ [[nodiscard]] const QString &getHtml() const;
+
+ /* [2] --- */
+
+protected:
+
+ /* [3] Protected members */
+
+ /* [3] --- */
+
+
+ /* [4] Protected methods */
+
+ void prepare() override;
+
+ /* [4] --- */
+};
+
+#endif // MIMEHTML_H
diff --git a/src/smtp/mimeinlinefile.h b/src/smtp/mimeinlinefile.h
new file mode 100644
index 00000000..916f7b76
--- /dev/null
+++ b/src/smtp/mimeinlinefile.h
@@ -0,0 +1,56 @@
+/*
+ Copyright (c) 2011-2012 - Tőkés Attila
+
+ This file is part of SmtpClient for Qt.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ See the LICENSE file for more details.
+*/
+
+#ifndef MIMEINLINEFILE_H
+#define MIMEINLINEFILE_H
+
+#include "mimefile.h"
+
+#include "smtpexports.h"
+
+class SMTP_EXPORT MimeInlineFile : public MimeFile {
+public:
+
+ /* [1] Constructors and Destructors */
+
+ explicit MimeInlineFile(QFile *f);
+
+ ~MimeInlineFile() override;
+
+ /* [1] --- */
+
+
+ /* [2] Getters and Setters */
+
+ /* [2] --- */
+
+protected:
+
+ /* [3] Protected members */
+
+ /* [3] --- */
+
+
+ /* [4] Protected methods */
+
+ void prepare() override;
+
+ /* [4] --- */
+};
+
+#endif // MIMEINLINEFILE_H
diff --git a/src/smtp/mimemessage.cpp b/src/smtp/mimemessage.cpp
index cf653e0a..6c058e89 100644
--- a/src/smtp/mimemessage.cpp
+++ b/src/smtp/mimemessage.cpp
@@ -17,26 +17,26 @@
*/
#include "smtp/mimemessage.h"
-#include "smtp/quotedprintable.h"
#include <QDateTime>
#include <QLocale>
#include <typeinfo>
+#include "smtp/quotedprintable.h"
+
/* [1] Constructors and Destructors */
MimeMessage::MimeMessage(bool createAutoMimeContent)
- : replyTo(nullptr), hEncoding(MimePart::_8Bit) {
- if (createAutoMimeContent)
- this->content = new MimeMultiPart();
+ : replyTo(nullptr), hEncoding(MimePart::_8Bit) {
+ if (createAutoMimeContent) this->content = new MimeMultiPart();
- autoMimeContentCreated = createAutoMimeContent;
+ autoMimeContentCreated = createAutoMimeContent;
}
MimeMessage::~MimeMessage() {
- if (this->autoMimeContentCreated) {
- this->autoMimeContentCreated = false;
- delete (this->content);
- }
+ if (this->autoMimeContentCreated) {
+ this->autoMimeContentCreated = false;
+ delete (this->content);
+ }
}
/* [1] --- */
@@ -45,34 +45,34 @@ MimeMessage::~MimeMessage() {
MimePart &MimeMessage::getContent() { return *content; }
void MimeMessage::setContent(MimePart *content) {
- if (this->autoMimeContentCreated) {
- this->autoMimeContentCreated = false;
- delete (this->content);
- }
- this->content = content;
+ if (this->autoMimeContentCreated) {
+ this->autoMimeContentCreated = false;
+ delete (this->content);
+ }
+ this->content = content;
}
void MimeMessage::setReplyTo(EmailAddress *rto) { replyTo = rto; }
void MimeMessage::setSender(EmailAddress *e) {
- this->sender = e;
- e->setParent(this);
+ this->sender = e;
+ e->setParent(this);
}
void MimeMessage::addRecipient(EmailAddress *rcpt, RecipientType type) {
- switch (type) {
- case To:
- recipientsTo << rcpt;
- break;
- case Cc:
- recipientsCc << rcpt;
- break;
- case Bcc:
- recipientsBcc << rcpt;
- break;
- }
-
- rcpt->setParent(this);
+ switch (type) {
+ case To:
+ recipientsTo << rcpt;
+ break;
+ case Cc:
+ recipientsCc << rcpt;
+ break;
+ case Bcc:
+ recipientsBcc << rcpt;
+ break;
+ }
+
+ rcpt->setParent(this);
}
void MimeMessage::addTo(EmailAddress *rcpt) { this->recipientsTo << rcpt; }
@@ -82,36 +82,36 @@ void MimeMessage::addCc(EmailAddress *rcpt) { this->recipientsCc << rcpt; }
void MimeMessage::addBcc(EmailAddress *rcpt) { this->recipientsBcc << rcpt; }
void MimeMessage::setSubject(const QString &subject) {
- this->subject = subject;
+ this->subject = subject;
}
void MimeMessage::addPart(MimePart *part) {
- if (typeid(*content) == typeid(MimeMultiPart)) {
- ((MimeMultiPart *) content)->addPart(part);
- };
+ if (typeid(*content) == typeid(MimeMultiPart)) {
+ ((MimeMultiPart *)content)->addPart(part);
+ };
}
void MimeMessage::setInReplyTo(const QString &inReplyTo) {
- mInReplyTo = inReplyTo;
+ mInReplyTo = inReplyTo;
}
void MimeMessage::setHeaderEncoding(MimePart::Encoding hEnc) {
- this->hEncoding = hEnc;
+ this->hEncoding = hEnc;
}
const EmailAddress &MimeMessage::getSender() const { return *sender; }
-const QList<EmailAddress *> &
-MimeMessage::getRecipients(RecipientType type) const {
- switch (type) {
- default:
- case To:
- return recipientsTo;
- case Cc:
- return recipientsCc;
- case Bcc:
- return recipientsBcc;
- }
+const QList<EmailAddress *> &MimeMessage::getRecipients(
+ RecipientType type) const {
+ switch (type) {
+ default:
+ case To:
+ return recipientsTo;
+ case Cc:
+ return recipientsCc;
+ case Bcc:
+ return recipientsBcc;
+ }
}
const EmailAddress *MimeMessage::getReplyTo() const { return replyTo; }
@@ -119,13 +119,13 @@ const EmailAddress *MimeMessage::getReplyTo() const { return replyTo; }
const QString &MimeMessage::getSubject() const { return subject; }
const QList<MimePart *> &MimeMessage::getParts() const {
- if (typeid(*content) == typeid(MimeMultiPart)) {
- return ((MimeMultiPart *) content)->getParts();
- } else {
- auto *res = new QList<MimePart *>();
- res->append(content);
- return *res;
- }
+ if (typeid(*content) == typeid(MimeMultiPart)) {
+ return ((MimeMultiPart *)content)->getParts();
+ } else {
+ auto *res = new QList<MimePart *>();
+ res->append(content);
+ return *res;
+ }
}
/* [2] --- */
@@ -133,176 +133,180 @@ const QList<MimePart *> &MimeMessage::getParts() const {
/* [3] Public Methods */
QString MimeMessage::toString() {
- QString mime;
-
- /* =========== MIME HEADER ============ */
-
- /* ---------- Sender / From ----------- */
- mime = "From:";
- if (sender->getName() != "") {
- switch (hEncoding) {
- case MimePart::Base64:
- mime += " =?utf-8?B?" +
- QByteArray().append(sender->getName().toUtf8()).toBase64() + "?=";
- break;
- case MimePart::QuotedPrintable:
- mime += " =?utf-8?Q?" +
- QuotedPrintable::encode(
- QByteArray().append(sender->getName().toUtf8()))
- .replace(' ', "_")
- .replace(':', "=3A") +
- "?=";
- break;
- default:
- mime += " " + sender->getName();
- }
+ QString mime;
+
+ /* =========== MIME HEADER ============ */
+
+ /* ---------- Sender / From ----------- */
+ mime = "From:";
+ if (!sender->getName().isEmpty()) {
+ switch (hEncoding) {
+ case MimePart::Base64:
+ mime += " =?utf-8?B?" +
+ QByteArray().append(sender->getName().toUtf8()).toBase64() +
+ "?=";
+ break;
+ case MimePart::QuotedPrintable:
+ mime += " =?utf-8?Q?" +
+ QuotedPrintable::encode(
+ QByteArray().append(sender->getName().toUtf8()))
+ .replace(' ', "_")
+ .replace(':', "=3A") +
+ "?=";
+ break;
+ default:
+ mime += " " + sender->getName();
}
- mime += " <" + sender->getAddress() + ">\r\n";
- /* ---------------------------------- */
-
- /* ------- Recipients / To ---------- */
- mime += "To:";
- QList<EmailAddress *>::iterator it;
- int i;
- for (i = 0, it = recipientsTo.begin(); it != recipientsTo.end(); ++it, ++i) {
- if (i != 0) {
- mime += ",";
- }
-
- if ((*it)->getName() != "") {
- switch (hEncoding) {
- case MimePart::Base64:
- mime += " =?utf-8?B?" +
- QByteArray().append((*it)->getName().toUtf8()).toBase64() +
- "?=";
- break;
- case MimePart::QuotedPrintable:
- mime += " =?utf-8?Q?" +
- QuotedPrintable::encode(
- QByteArray().append((*it)->getName().toUtf8()))
- .replace(' ', "_")
- .replace(':', "=3A") +
- "?=";
- break;
- default:
- mime += " " + (*it)->getName();
- }
- }
- mime += " <" + (*it)->getAddress() + ">";
+ }
+ mime += " <" + sender->getAddress() + ">\r\n";
+ /* ---------------------------------- */
+
+ /* ------- Recipients / To ---------- */
+ mime += "To:";
+ QList<EmailAddress *>::iterator it;
+ int i;
+ for (i = 0, it = recipientsTo.begin(); it != recipientsTo.end(); ++it, ++i) {
+ if (i != 0) {
+ mime += ",";
}
- mime += "\r\n";
- /* ---------------------------------- */
- /* ------- Recipients / Cc ---------- */
- if (!recipientsCc.empty()) {
- mime += "Cc:";
- }
- for (i = 0, it = recipientsCc.begin(); it != recipientsCc.end(); ++it, ++i) {
- if (i != 0) {
- mime += ",";
- }
-
- if ((*it)->getName() != "") {
- switch (hEncoding) {
- case MimePart::Base64:
- mime += " =?utf-8?B?" +
- QByteArray().append((*it)->getName().toUtf8()).toBase64() +
- "?=";
- break;
- case MimePart::QuotedPrintable:
- mime += " =?utf-8?Q?" +
- QuotedPrintable::encode(
- QByteArray().append((*it)->getName().toUtf8()))
- .replace(' ', "_")
- .replace(':', "=3A") +
- "?=";
- break;
- default:
- mime += " " + (*it)->getName();
- }
- }
- mime += " <" + (*it)->getAddress() + ">";
+ if (!(*it)->getName().isEmpty()) {
+ switch (hEncoding) {
+ case MimePart::Base64:
+ mime += " =?utf-8?B?" +
+ QByteArray().append((*it)->getName().toUtf8()).toBase64() +
+ "?=";
+ break;
+ case MimePart::QuotedPrintable:
+ mime += " =?utf-8?Q?" +
+ QuotedPrintable::encode(
+ QByteArray().append((*it)->getName().toUtf8()))
+ .replace(' ', "_")
+ .replace(':', "=3A") +
+ "?=";
+ break;
+ default:
+ mime += " " + (*it)->getName();
+ }
}
- if (!recipientsCc.empty()) {
- mime += "\r\n";
+ mime += " <" + (*it)->getAddress() + ">";
+ }
+ mime += "\r\n";
+ /* ---------------------------------- */
+
+ /* ------- Recipients / Cc ---------- */
+ if (!recipientsCc.empty()) {
+ mime += "Cc:";
+ }
+ for (i = 0, it = recipientsCc.begin(); it != recipientsCc.end(); ++it, ++i) {
+ if (i != 0) {
+ mime += ",";
}
- /* ---------------------------------- */
- /* ------------ Subject ------------- */
- mime += "Subject: ";
-
- switch (hEncoding) {
+ if ((*it)->getName() != "") {
+ switch (hEncoding) {
case MimePart::Base64:
- mime += "=?utf-8?B?" + QByteArray().append(subject.toUtf8()).toBase64() + "?=";
- break;
+ mime += " =?utf-8?B?" +
+ QByteArray().append((*it)->getName().toUtf8()).toBase64() +
+ "?=";
+ break;
case MimePart::QuotedPrintable:
- mime += "=?utf-8?Q?" +
- QuotedPrintable::encode(QByteArray().append(subject.toUtf8()))
- .replace(' ', "_")
- .replace(':', "=3A") +
- "?=";
- break;
+ mime += " =?utf-8?Q?" +
+ QuotedPrintable::encode(
+ QByteArray().append((*it)->getName().toUtf8()))
+ .replace(' ', "_")
+ .replace(':', "=3A") +
+ "?=";
+ break;
default:
- mime += subject;
+ mime += " " + (*it)->getName();
+ }
}
+ mime += " <" + (*it)->getAddress() + ">";
+ }
+ if (!recipientsCc.empty()) {
mime += "\r\n";
- /* ---------------------------------- */
-
- /* ---------- Reply-To -------------- */
- if (replyTo) {
- mime += "Reply-To: ";
- if (replyTo->getName() != "") {
- switch (hEncoding) {
- case MimePart::Base64:
- mime += " =?utf-8?B?" +
- QByteArray().append(replyTo->getName().toUtf8()).toBase64() + "?=";
- break;
- case MimePart::QuotedPrintable:
- mime += " =?utf-8?Q?" +
- QuotedPrintable::encode(QByteArray().append(replyTo->getName().toUtf8()))
- .replace(' ', "_")
- .replace(':', "=3A") +
- "?=";
- break;
- default:
- mime += " " + replyTo->getName();
- }
- }
- mime += " <" + replyTo->getAddress() + ">\r\n";
- }
-
- /* ---------------------------------- */
-
- mime += "MIME-Version: 1.0\r\n";
- if (!mInReplyTo.isEmpty()) {
- mime += "In-Reply-To: <" + mInReplyTo + ">\r\n";
- mime += "References: <" + mInReplyTo + ">\r\n";
+ }
+ /* ---------------------------------- */
+
+ /* ------------ Subject ------------- */
+ mime += "Subject: ";
+
+ switch (hEncoding) {
+ case MimePart::Base64:
+ mime += "=?utf-8?B?" + QByteArray().append(subject.toUtf8()).toBase64() +
+ "?=";
+ break;
+ case MimePart::QuotedPrintable:
+ mime += "=?utf-8?Q?" +
+ QuotedPrintable::encode(QByteArray().append(subject.toUtf8()))
+ .replace(' ', "_")
+ .replace(':', "=3A") +
+ "?=";
+ break;
+ default:
+ mime += subject;
+ }
+ mime += "\r\n";
+ /* ---------------------------------- */
+
+ /* ---------- Reply-To -------------- */
+ if (replyTo) {
+ mime += "Reply-To: ";
+ if (!replyTo->getName().isEmpty()) {
+ switch (hEncoding) {
+ case MimePart::Base64:
+ mime += " =?utf-8?B?" +
+ QByteArray().append(replyTo->getName().toUtf8()).toBase64() +
+ "?=";
+ break;
+ case MimePart::QuotedPrintable:
+ mime += " =?utf-8?Q?" +
+ QuotedPrintable::encode(
+ QByteArray().append(replyTo->getName().toUtf8()))
+ .replace(' ', "_")
+ .replace(':', "=3A") +
+ "?=";
+ break;
+ default:
+ mime += " " + replyTo->getName();
+ }
}
-
- QDateTime now = QDateTime::currentDateTime();
-#if QT_VERSION_MAJOR < 5 // Qt4 workaround since RFC2822Date isn't defined
- QString shortDayName =
- QLocale::c().dayName(now.date().dayOfWeek(), QLocale::ShortFormat);
- QString shortMonthName =
- QLocale::c().monthName(now.date().month(), QLocale::ShortFormat);
- int utcOffset = now.secsTo(QDateTime(now.date(), now.time(), Qt::UTC)) / 60;
- char timezoneSign = utcOffset >= 0 ? '+' : '-';
- utcOffset = utcOffset >= 0 ? utcOffset : -utcOffset;
- QString timezone = QString("%1%2%3")
- .arg(timezoneSign)
- .arg(utcOffset / 60, 2, 10, QChar('0'))
- .arg(utcOffset % 60, 2, 10, QChar('0'));
- mime += QString("Date: %1\r\n")
- .arg(now.toString("%1, dd %2 yyyy hh:mm:ss %3")
- .arg(shortDayName)
- .arg(shortMonthName)
- .arg(timezone));
-#else // Qt5 supported
- mime += QString("Date: %1\r\n").arg(now.toString(Qt::RFC2822Date));
-#endif // support RFC2822Date
-
- mime += content->toString();
- return mime;
+ mime += " <" + replyTo->getAddress() + ">\r\n";
+ }
+
+ /* ---------------------------------- */
+
+ mime += "MIME-Version: 1.0\r\n";
+ if (!mInReplyTo.isEmpty()) {
+ mime += "In-Reply-To: <" + mInReplyTo + ">\r\n";
+ mime += "References: <" + mInReplyTo + ">\r\n";
+ }
+
+ QDateTime now = QDateTime::currentDateTime();
+#if QT_VERSION_MAJOR < 5 // Qt4 workaround since RFC2822Date isn't defined
+ QString shortDayName =
+ QLocale::c().dayName(now.date().dayOfWeek(), QLocale::ShortFormat);
+ QString shortMonthName =
+ QLocale::c().monthName(now.date().month(), QLocale::ShortFormat);
+ int utcOffset = now.secsTo(QDateTime(now.date(), now.time(), Qt::UTC)) / 60;
+ char timezoneSign = utcOffset >= 0 ? '+' : '-';
+ utcOffset = utcOffset >= 0 ? utcOffset : -utcOffset;
+ QString timezone = QString("%1%2%3")
+ .arg(timezoneSign)
+ .arg(utcOffset / 60, 2, 10, QChar('0'))
+ .arg(utcOffset % 60, 2, 10, QChar('0'));
+ mime += QString("Date: %1\r\n")
+ .arg(now.toString("%1, dd %2 yyyy hh:mm:ss %3")
+ .arg(shortDayName)
+ .arg(shortMonthName)
+ .arg(timezone));
+#else // Qt5 supported
+ mime += QString("Date: %1\r\n").arg(now.toString(Qt::RFC2822Date));
+#endif // support RFC2822Date
+
+ mime += content->toString();
+ return mime;
}
/* [3] --- */
diff --git a/src/smtp/mimemessage.h b/src/smtp/mimemessage.h
new file mode 100644
index 00000000..24e4f108
--- /dev/null
+++ b/src/smtp/mimemessage.h
@@ -0,0 +1,110 @@
+/*
+ Copyright (c) 2011-2012 - Tőkés Attila
+
+ This file is part of SmtpClient for Qt.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ See the LICENSE file for more details.
+*/
+
+#ifndef MIMEMESSAGE_H
+#define MIMEMESSAGE_H
+
+#include "mimepart.h"
+#include "mimemultipart.h"
+#include "emailaddress.h"
+#include <QList>
+
+#include "smtpexports.h"
+
+class SMTP_EXPORT MimeMessage : public QObject {
+public:
+
+ enum RecipientType {
+ To, // primary
+ Cc, // carbon copy
+ Bcc // blind carbon copy
+ };
+
+ /* [1] Constructors and Destructors */
+
+ explicit MimeMessage(bool createAutoMimeConent = true);
+
+ ~MimeMessage() override;
+
+ /* [1] --- */
+
+
+ /* [2] Getters and Setters */
+
+ void setSender(EmailAddress *e);
+
+ void addRecipient(EmailAddress *rcpt, RecipientType type = To);
+
+ void addTo(EmailAddress *rcpt);
+
+ void addCc(EmailAddress *rcpt);
+
+ void addBcc(EmailAddress *rcpt);
+
+ void setSubject(const QString &subject);
+
+ void addPart(MimePart *part);
+
+ void setReplyTo(EmailAddress *rto);
+
+ void setInReplyTo(const QString &inReplyTo);
+
+ void setHeaderEncoding(MimePart::Encoding);
+
+ [[nodiscard]] const EmailAddress &getSender() const;
+
+ [[nodiscard]] const QList<EmailAddress *> &getRecipients(RecipientType type = To) const;
+
+ [[nodiscard]] const QString &getSubject() const;
+
+ [[nodiscard]] const QList<MimePart *> &getParts() const;
+
+ [[nodiscard]] const EmailAddress *getReplyTo() const;
+
+ MimePart &getContent();
+
+ void setContent(MimePart *content);
+ /* [2] --- */
+
+
+ /* [3] Public methods */
+
+ virtual QString toString();
+
+ /* [3] --- */
+
+protected:
+
+ /* [4] Protected members */
+
+ EmailAddress *sender{};
+ EmailAddress *replyTo;
+ QList<EmailAddress *> recipientsTo, recipientsCc, recipientsBcc;
+ QString subject;
+ QString mInReplyTo;
+ MimePart *content;
+ bool autoMimeContentCreated;
+
+ MimePart::Encoding hEncoding;
+
+ /* [4] --- */
+
+
+};
+
+#endif // MIMEMESSAGE_H
diff --git a/src/smtp/mimemultipart.cpp b/src/smtp/mimemultipart.cpp
index 14a813c2..4dd00d1a 100644
--- a/src/smtp/mimemultipart.cpp
+++ b/src/smtp/mimemultipart.cpp
@@ -17,30 +17,31 @@
*/
#include "smtp/mimemultipart.h"
+
#include <QCryptographicHash>
#include <QRandomGenerator>
#include <QTime>
const QString MULTI_PART_NAMES[] = {
- "multipart/mixed", // Mixed
- "multipart/digest", // Digest
- "multipart/alternative", // Alternative
- "multipart/related", // Related
- "multipart/report", // Report
- "multipart/signed", // Signed
- "multipart/encrypted" // Encrypted
+ "multipart/mixed", // Mixed
+ "multipart/digest", // Digest
+ "multipart/alternative", // Alternative
+ "multipart/related", // Related
+ "multipart/report", // Report
+ "multipart/signed", // Signed
+ "multipart/encrypted" // Encrypted
};
MimeMultiPart::MimeMultiPart(MultiPartType type) {
- this->type = type;
- this->cType = MULTI_PART_NAMES[this->type];
- this->cEncoding = _8Bit;
+ this->type = type;
+ this->cType = MULTI_PART_NAMES[this->type];
+ this->cEncoding = _8Bit;
- QRandomGenerator generator;
+ QRandomGenerator generator;
- QCryptographicHash md5(QCryptographicHash::Md5);
- md5.addData(QByteArray().append((char) generator.generate()));
- cBoundary = md5.result().toHex();
+ QCryptographicHash md5(QCryptographicHash::Md5);
+ md5.addData(QByteArray().append((char)generator.generate()));
+ cBoundary = md5.result().toHex();
}
void MimeMultiPart::addPart(MimePart *part) { parts.append(part); }
@@ -48,23 +49,23 @@ void MimeMultiPart::addPart(MimePart *part) { parts.append(part); }
const QList<MimePart *> &MimeMultiPart::getParts() const { return parts; }
void MimeMultiPart::prepare() {
- QList<MimePart *>::iterator it;
+ QList<MimePart *>::iterator it;
- content = "";
- for (it = parts.begin(); it != parts.end(); it++) {
- content += QString("--" + cBoundary + "\r\n").toUtf8();
- (*it)->prepare();
- content += (*it)->toString().toUtf8();
- };
+ content.clear();
+ for (it = parts.begin(); it != parts.end(); it++) {
+ content += QString("--" + cBoundary + "\r\n").toUtf8();
+ (*it)->prepare();
+ content += (*it)->toString().toUtf8();
+ };
- content += QString("--" + cBoundary + "--\r\n").toUtf8();
+ content += QString("--" + cBoundary + "--\r\n").toUtf8();
- MimePart::prepare();
+ MimePart::prepare();
}
void MimeMultiPart::setMimeType(const MultiPartType type) {
- this->type = type;
- this->cType = MULTI_PART_NAMES[type];
+ this->type = type;
+ this->cType = MULTI_PART_NAMES[type];
}
MimeMultiPart::MultiPartType MimeMultiPart::getMimeType() const { return type; }
diff --git a/src/smtp/mimemultipart.h b/src/smtp/mimemultipart.h
new file mode 100644
index 00000000..b829a66f
--- /dev/null
+++ b/src/smtp/mimemultipart.h
@@ -0,0 +1,71 @@
+/*
+ Copyright (c) 2011-2012 - Tőkés Attila
+
+ This file is part of SmtpClient for Qt.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ See the LICENSE file for more details.
+*/
+
+#ifndef MIMEMULTIPART_H
+#define MIMEMULTIPART_H
+
+#include "mimepart.h"
+
+#include "smtpexports.h"
+
+class SMTP_EXPORT MimeMultiPart : public MimePart {
+Q_OBJECT
+public:
+ /* [0] Enums */
+ enum MultiPartType {
+ Mixed = 0, // RFC 2046, section 5.1.3
+ Digest = 1, // RFC 2046, section 5.1.5
+ Alternative = 2, // RFC 2046, section 5.1.4
+ Related = 3, // RFC 2387
+ Report = 4, // RFC 6522
+ Signed = 5, // RFC 1847, section 2.1
+ Encrypted = 6 // RFC 1847, section 2.2
+ };
+
+ /* [0] --- */
+
+ /* [1] Constructors and Destructors */
+ explicit MimeMultiPart(MultiPartType type = Related);
+
+ /* [1] --- */
+
+ /* [2] Getters and Setters */
+
+ void setMimeType(MultiPartType type);
+
+ [[nodiscard]] MultiPartType getMimeType() const;
+
+ [[nodiscard]] const QList<MimePart *> &getParts() const;
+
+ /* [2] --- */
+
+ /* [3] Public methods */
+
+ void addPart(MimePart *part);
+
+ void prepare() override;
+
+ /* [3] --- */
+
+protected:
+ QList<MimePart *> parts;
+
+ MultiPartType type;
+};
+
+#endif // MIMEMULTIPART_H
diff --git a/src/smtp/mimepart.cpp b/src/smtp/mimepart.cpp
index 5d33884d..10aa6cbc 100644
--- a/src/smtp/mimepart.cpp
+++ b/src/smtp/mimepart.cpp
@@ -17,14 +17,15 @@
*/
#include "smtp/mimepart.h"
+
#include "smtp/quotedprintable.h"
/* [1] Constructors and Destructors */
MimePart::MimePart() {
- cEncoding = _7Bit;
- prepared = false;
- cBoundary = "";
+ cEncoding = _7Bit;
+ prepared = false;
+ cBoundary.clear();
}
/* [1] --- */
@@ -32,13 +33,13 @@ MimePart::MimePart() {
/* [2] Getters and Setters */
void MimePart::setContent(const QByteArray &content) {
- this->content = content;
+ this->content = content;
}
void MimePart::setHeader(const QString &header) { this->header = header; }
void MimePart::addHeaderLine(const QString &line) {
- this->header += line + "\r\n";
+ this->header += line + "\r\n";
}
const QString &MimePart::getHeader() const { return header; }
@@ -66,7 +67,7 @@ void MimePart::setEncoding(Encoding enc) { this->cEncoding = enc; }
MimePart::Encoding MimePart::getEncoding() const { return this->cEncoding; }
MimeContentFormatter &MimePart::getContentFormatter() {
- return this->formatter;
+ return this->formatter;
}
/* [2] --- */
@@ -74,10 +75,9 @@ MimeContentFormatter &MimePart::getContentFormatter() {
/* [3] Public methods */
QString MimePart::toString() {
- if (!prepared)
- prepare();
+ if (!prepared) prepare();
- return mimeString;
+ return mimeString;
}
/* [3] --- */
@@ -85,75 +85,74 @@ QString MimePart::toString() {
/* [4] Protected methods */
void MimePart::prepare() {
- mimeString = QString();
-
- /* === Header Prepare === */
-
- /* Content-Type */
- mimeString.append("Content-Type: ").append(cType);
-
- if (cName != "")
- mimeString.append("; name=\"").append(cName).append("\"");
-
- if (cCharset != "")
- mimeString.append("; charset=").append(cCharset);
-
- if (cBoundary != "")
- mimeString.append("; boundary=").append(cBoundary);
-
- mimeString.append("\r\n");
- /* ------------ */
-
- /* Content-Transfer-Encoding */
- mimeString.append("Content-Transfer-Encoding: ");
- switch (cEncoding) {
- case _7Bit:
- mimeString.append("7bit\r\n");
- break;
- case _8Bit:
- mimeString.append("8bit\r\n");
- break;
- case Base64:
- mimeString.append("base64\r\n");
- break;
- case QuotedPrintable:
- mimeString.append("quoted-printable\r\n");
- break;
- }
- /* ------------------------ */
-
- /* Content-Id */
- if (cId != NULL)
- mimeString.append("Content-ID: <").append(cId).append(">\r\n");
- /* ---------- */
-
- /* Addition header lines */
-
- mimeString.append(header).append("\r\n");
-
- /* ------------------------- */
-
- /* === End of Header Prepare === */
-
- /* === Content === */
- switch (cEncoding) {
- case _7Bit:
- mimeString.append(QString(content).toLatin1());
- break;
- case _8Bit:
- mimeString.append(content);
- break;
- case Base64:
- mimeString.append(formatter.format(content.toBase64()));
- break;
- case QuotedPrintable:
- mimeString.append(formatter.format(QuotedPrintable::encode(content), true));
- break;
- }
- mimeString.append("\r\n");
- /* === End of Content === */
-
- prepared = true;
+ mimeString = QString();
+
+ /* === Header Prepare === */
+
+ /* Content-Type */
+ mimeString.append("Content-Type: ").append(cType);
+
+ if (!cName.isEmpty())
+ mimeString.append("; name=\"").append(cName).append("\"");
+
+ if (!cCharset.isEmpty()) mimeString.append("; charset=").append(cCharset);
+
+ if (!cBoundary.isEmpty()) mimeString.append("; boundary=").append(cBoundary);
+
+ mimeString.append("\r\n");
+ /* ------------ */
+
+ /* Content-Transfer-Encoding */
+ mimeString.append("Content-Transfer-Encoding: ");
+ switch (cEncoding) {
+ case _7Bit:
+ mimeString.append("7bit\r\n");
+ break;
+ case _8Bit:
+ mimeString.append("8bit\r\n");
+ break;
+ case Base64:
+ mimeString.append("base64\r\n");
+ break;
+ case QuotedPrintable:
+ mimeString.append("quoted-printable\r\n");
+ break;
+ }
+ /* ------------------------ */
+
+ /* Content-Id */
+ if (cId != nullptr)
+ mimeString.append("Content-ID: <").append(cId).append(">\r\n");
+ /* ---------- */
+
+ /* Addition header lines */
+
+ mimeString.append(header).append("\r\n");
+
+ /* ------------------------- */
+
+ /* === End of Header Prepare === */
+
+ /* === Content === */
+ switch (cEncoding) {
+ case _7Bit:
+ mimeString.append(QString(content).toLatin1());
+ break;
+ case _8Bit:
+ mimeString.append(content);
+ break;
+ case Base64:
+ mimeString.append(formatter.format(content.toBase64()));
+ break;
+ case QuotedPrintable:
+ mimeString.append(
+ formatter.format(QuotedPrintable::encode(content), true));
+ break;
+ }
+ mimeString.append("\r\n");
+ /* === End of Content === */
+
+ prepared = true;
}
/* [4] --- */
diff --git a/src/smtp/mimepart.h b/src/smtp/mimepart.h
new file mode 100644
index 00000000..1a1386de
--- /dev/null
+++ b/src/smtp/mimepart.h
@@ -0,0 +1,110 @@
+/*
+ Copyright (c) 2011-2012 - Tőkés Attila
+
+ This file is part of SmtpClient for Qt.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ See the LICENSE file for more details.
+*/
+
+#ifndef MIMEPART_H
+#define MIMEPART_H
+
+#include "mimecontentformatter.h"
+#include <QObject>
+
+#include "smtpexports.h"
+
+class SMTP_EXPORT MimePart : public QObject {
+Q_OBJECT
+public:
+ /* [0] Enumerations */
+ enum Encoding {
+ _7Bit, _8Bit, Base64, QuotedPrintable
+ };
+
+ /* [0] --- */
+
+ /* [1] Constructors and Destructors */
+
+ MimePart();
+
+ ~MimePart() = default;
+
+ /* [1] --- */
+
+ /* [2] Getters and Setters */
+
+ [[nodiscard]] const QString &getHeader() const;
+
+ [[nodiscard]] const QByteArray &getContent() const;
+
+ void setContent(const QByteArray &content);
+
+ void setHeader(const QString &header);
+
+ void addHeaderLine(const QString &line);
+
+ void setContentId(const QString &cId);
+
+ [[nodiscard]] const QString &getContentId() const;
+
+ void setContentName(const QString &cName);
+
+ [[nodiscard]] const QString &getContentName() const;
+
+ void setContentType(const QString &cType);
+
+ [[nodiscard]] const QString &getContentType() const;
+
+ void setCharset(const QString &charset);
+
+ [[nodiscard]] const QString &getCharset() const;
+
+ void setEncoding(Encoding enc);
+
+ [[nodiscard]] Encoding getEncoding() const;
+
+ MimeContentFormatter &getContentFormatter();
+
+ /* [2] --- */
+
+ /* [3] Public methods */
+
+ virtual QString toString();
+
+ virtual void prepare();
+
+ /* [3] --- */
+
+protected:
+ /* [4] Protected members */
+
+ QString header;
+ QByteArray content;
+
+ QString cId;
+ QString cName;
+ QString cType;
+ QString cCharset;
+ QString cBoundary;
+ Encoding cEncoding;
+
+ QString mimeString;
+ bool prepared;
+
+ MimeContentFormatter formatter;
+
+ /* [4] --- */
+};
+
+#endif // MIMEPART_H
diff --git a/src/smtp/mimetext.h b/src/smtp/mimetext.h
new file mode 100644
index 00000000..c21a1c5e
--- /dev/null
+++ b/src/smtp/mimetext.h
@@ -0,0 +1,62 @@
+/*
+ Copyright (c) 2011-2012 - Tőkés Attila
+
+ This file is part of SmtpClient for Qt.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ See the LICENSE file for more details.
+*/
+
+#ifndef MIMETEXT_H
+#define MIMETEXT_H
+
+#include "mimepart.h"
+
+#include "smtpexports.h"
+
+class SMTP_EXPORT MimeText : public MimePart {
+public:
+
+ /* [1] Constructors and Destructors */
+
+ explicit MimeText(const QString &text = "");
+
+ ~MimeText() override;
+
+ /* [1] --- */
+
+
+ /* [2] Getters and Setters*/
+
+ void setText(const QString &text);
+
+ [[nodiscard]] const QString &getText() const;
+
+ /* [2] --- */
+
+protected:
+
+ /* [3] Protected members */
+
+ QString text;
+ /* [3] --- */
+
+
+ /* [4] Protected methods */
+
+ void prepare() override;
+
+ /* [4] --- */
+
+};
+
+#endif // MIMETEXT_H
diff --git a/src/smtp/quotedprintable.h b/src/smtp/quotedprintable.h
new file mode 100644
index 00000000..00ca3cf8
--- /dev/null
+++ b/src/smtp/quotedprintable.h
@@ -0,0 +1,39 @@
+/*
+ Copyright (c) 2011-2012 - Tőkés Attila
+
+ This file is part of SmtpClient for Qt.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ See the LICENSE file for more details.
+*/
+
+#ifndef QUOTEDPRINTABLE_H
+#define QUOTEDPRINTABLE_H
+
+#include <QObject>
+#include <QByteArray>
+
+#include "smtpexports.h"
+
+class SMTP_EXPORT QuotedPrintable : public QObject {
+Q_OBJECT
+public:
+
+ static QString encode(const QByteArray &input);
+
+ static QByteArray decode(const QString &input);
+
+private:
+ QuotedPrintable();
+};
+
+#endif // QUOTEDPRINTABLE_H
diff --git a/src/smtp/smtpclient.h b/src/smtp/smtpclient.h
new file mode 100644
index 00000000..29c507dc
--- /dev/null
+++ b/src/smtp/smtpclient.h
@@ -0,0 +1,197 @@
+/*
+ Copyright (c) 2011-2012 - Tőkés Attila
+
+ This file is part of SmtpClient for Qt.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ See the LICENSE file for more details.
+*/
+
+#ifndef SMTPCLIENT_H
+#define SMTPCLIENT_H
+
+#include <QObject>
+#include <QtNetwork/QSslSocket>
+
+#include "mimemessage.h"
+#include "smtpexports.h"
+
+class SMTP_EXPORT SmtpClient : public QObject {
+Q_OBJECT
+public:
+
+ /* [0] Enumerations */
+
+ enum AuthMethod {
+ AuthPlain,
+ AuthLogin
+ };
+
+ enum SmtpError {
+ ConnectionTimeoutError,
+ ResponseTimeoutError,
+ SendDataTimeoutError,
+ AuthenticationFailedError,
+ ServerError, // 4xx smtp error
+ ClientError // 5xx smtp error
+ };
+
+ enum ConnectionType {
+ TcpConnection,
+ SslConnection,
+ TlsConnection // STARTTLS
+ };
+
+ /* [0] --- */
+
+
+ /* [1] Constructors and Destructors */
+
+ explicit SmtpClient(const QString &host = "localhost", int port = 25, ConnectionType ct = TcpConnection);
+
+ ~SmtpClient() override;
+
+ /* [1] --- */
+
+
+ /* [2] Getters and Setters */
+
+ [[nodiscard]] const QString &getHost() const;
+
+ void setHost(const QString &host);
+
+ [[nodiscard]] int getPort() const;
+
+ void setPort(int port);
+
+ [[nodiscard]] const QString &getName() const;
+
+ void setName(const QString &name);
+
+ [[nodiscard]] ConnectionType getConnectionType() const;
+
+ void setConnectionType(ConnectionType ct);
+
+ [[nodiscard]] const QString &getUser() const;
+
+ void setUser(const QString &user);
+
+ [[nodiscard]] const QString &getPassword() const;
+
+ void setPassword(const QString &password);
+
+ [[nodiscard]] SmtpClient::AuthMethod getAuthMethod() const;
+
+ void setAuthMethod(AuthMethod method);
+
+ [[nodiscard]] const QString &getResponseText() const;
+
+ [[nodiscard]] int getResponseCode() const;
+
+ [[nodiscard]] int getConnectionTimeout() const;
+
+ void setConnectionTimeout(int msec);
+
+ [[nodiscard]] int getResponseTimeout() const;
+
+ void setResponseTimeout(int msec);
+
+ [[nodiscard]] int getSendMessageTimeout() const;
+
+ void setSendMessageTimeout(int msec);
+
+ QTcpSocket *getSocket();
+
+
+ /* [2] --- */
+
+
+ /* [3] Public methods */
+
+ bool connectToHost();
+
+ bool login();
+
+ bool login(const QString &user, const QString &password, AuthMethod method = AuthLogin);
+
+ bool sendMail(MimeMessage &email);
+
+ void quit();
+
+
+ /* [3] --- */
+
+protected:
+
+ /* [4] Protected members */
+
+ QTcpSocket *socket;
+
+ QString host;
+ int port;
+ ConnectionType connectionType;
+ QString name;
+
+ QString user;
+ QString password;
+ AuthMethod authMethod;
+
+ int connectionTimeout;
+ int responseTimeout;
+ int sendMessageTimeout;
+
+
+ QString responseText;
+ int responseCode;
+
+
+ class ResponseTimeoutException : public std::exception {
+ };
+
+ class SendMessageTimeoutException : public std::exception {
+ };
+
+ /* [4] --- */
+
+
+ /* [5] Protected methods */
+
+ void waitForResponse();
+
+ void sendMessage(const QString &text);
+
+ /* [5] --- */
+
+protected slots:
+
+ /* [6] Protected slots */
+
+ void socketStateChanged(QAbstractSocket::SocketState state);
+
+ void socketError(QAbstractSocket::SocketError error);
+
+ void socketReadyRead();
+
+ /* [6] --- */
+
+
+signals:
+
+ /* [7] Signals */
+
+ void smtpError(SmtpClient::SmtpError e);
+
+ /* [7] --- */
+
+};
+
+#endif // SMTPCLIENT_H
diff --git a/src/smtp/smtpexports.h b/src/smtp/smtpexports.h
new file mode 100644
index 00000000..4bad0da0
--- /dev/null
+++ b/src/smtp/smtpexports.h
@@ -0,0 +1,10 @@
+#ifndef SMTPEXPORTS_H
+#define SMTPEXPORTS_H
+
+#ifdef SMTP_BUILD
+#define SMTP_EXPORT
+#else
+#define SMTP_EXPORT
+#endif
+
+#endif // SMTPEXPORTS_H
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
index b6552227..b80da2ec 100644
--- a/src/ui/CMakeLists.txt
+++ b/src/ui/CMakeLists.txt
@@ -5,10 +5,17 @@ aux_source_directory(./keygen UI_SOURCE)
aux_source_directory(./main_window UI_SOURCE)
aux_source_directory(./help UI_SOURCE)
aux_source_directory(./settings UI_SOURCE)
+aux_source_directory(./function UI_SOURCE)
+
+if (SMTP_SUPPORT)
+ message(STATUS "Build SMTP Support")
+ aux_source_directory(./smtp UI_SOURCE)
+endif ()
+
add_library(gpgfrontend-ui STATIC ${UI_SOURCE})
target_link_libraries(gpgfrontend-ui
Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core)
-message(STATUS "UI SOURCE ${UI_SOURCE}") \ No newline at end of file
+target_compile_features(gpgfrontend-ui PUBLIC cxx_std_17) \ No newline at end of file
diff --git a/src/ui/FileEncryptionDialog.cpp b/src/ui/FileEncryptionDialog.cpp
index 23ec0b2a..3e1e9b9a 100755
--- a/src/ui/FileEncryptionDialog.cpp
+++ b/src/ui/FileEncryptionDialog.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,266 +24,249 @@
#include "ui/FileEncryptionDialog.h"
-FileEncryptionDialog::FileEncryptionDialog(GpgME::GpgContext *ctx, QStringList keyList, DialogAction action,
- QWidget *parent)
- : QDialog(parent), mAction(action), mCtx(ctx){
+#include "gpg/function/BasicOperator.h"
+#include "gpg/function/GpgKeyGetter.h"
+
+namespace GpgFrontend::UI {
+FileEncryptionDialog::FileEncryptionDialog(KeyIdArgsListPtr keyList,
+ DialogAction action, QWidget* parent)
+ : QDialog(parent), mAction(action) {
+ if (mAction == Decrypt) {
+ setWindowTitle(_("Decrypt File"));
+ } else if (mAction == Encrypt) {
+ setWindowTitle(_("Encrypt File"));
+ } else if (mAction == Sign) {
+ setWindowTitle(_("Sign File"));
+ } else if (mAction == Verify) {
+ setWindowTitle(_("Verify File"));
+ }
+
+ setModal(true);
+
+ auto* buttonBox =
+ new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+ connect(buttonBox, SIGNAL(accepted()), this, SLOT(slotExecuteAction()));
+ connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+
+ auto* groupBox1 = new QGroupBox(_("Input Parameters"));
+
+ /* Setup input & Outputfileselection*/
+ inputFileEdit = new QLineEdit();
+ auto* fb1 = new QPushButton("Select");
+ connect(fb1, SIGNAL(clicked()), this, SLOT(slotSelectInputFile()));
+ auto* fl1 = new QLabel(_("Target File"));
+ fl1->setBuddy(inputFileEdit);
+
+ outputFileEdit = new QLineEdit();
+ auto* fb2 = new QPushButton("Select");
+ connect(fb2, SIGNAL(clicked()), this, SLOT(slotSelectOutputFile()));
+ auto* fl2 = new QLabel(_("Output File"));
+ fl2->setBuddy(outputFileEdit);
+
+ auto* gLayout = new QGridLayout();
+ gLayout->addWidget(fl1, 0, 0);
+ gLayout->addWidget(inputFileEdit, 0, 1);
+ gLayout->addWidget(fb1, 0, 2);
+ signFileEdit = new QLineEdit();
+ // verify does not need outfile, but signature file
+ if (mAction != Verify) {
+ gLayout->addWidget(fl2, 1, 0);
+ gLayout->addWidget(outputFileEdit, 1, 1);
+ gLayout->addWidget(fb2, 1, 2);
+ } else {
+ auto* sfb1 = new QPushButton("Select");
+ connect(sfb1, SIGNAL(clicked()), this, SLOT(slotSelectSignFile()));
+ auto* sfl1 = new QLabel(_("Signature File(.sig) Path"));
+ sfl1->setBuddy(signFileEdit);
+
+ gLayout->addWidget(sfl1, 1, 0);
+ gLayout->addWidget(signFileEdit, 1, 1);
+ gLayout->addWidget(sfb1, 1, 2);
+ }
+ groupBox1->setLayout(gLayout);
+
+ /*Setup KeyList*/
+ mKeyList = new KeyList(
+ KeyListRow::ONLY_SECRET_KEY,
+ KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage);
+ if (mAction == Verify)
+ mKeyList->setFilter([](const GpgKey& key) -> bool {
+ if (key.disabled() || key.expired() || key.revoked())
+ return false;
+ else
+ return true;
+ });
+
+ if (mAction == Encrypt)
+ mKeyList->setFilter([](const GpgKey& key) -> bool {
+ if (!key.CanEncrActual())
+ return false;
+ else
+ return true;
+ });
+
+ if (mAction == Sign)
+ mKeyList->setFilter([](const GpgKey& key) -> bool {
+ if (!key.CanSignActual())
+ return false;
+ else
+ return true;
+ });
+
+ if (mAction == Decrypt) mKeyList->setDisabled(true);
+
+ mKeyList->slotRefresh();
+ mKeyList->setChecked(keyList);
+
+ statusLabel = new QLabel();
+ statusLabel->setStyleSheet("QLabel {color: red;}");
+
+ auto* vbox2 = new QVBoxLayout();
+ vbox2->addWidget(groupBox1);
+ vbox2->addWidget(mKeyList);
+ vbox2->addWidget(statusLabel);
+ vbox2->addWidget(buttonBox);
+ vbox2->addStretch(0);
+ setLayout(vbox2);
+
+ this->setMinimumWidth(480);
+ this->show();
+}
- if (mAction == Decrypt) {
- setWindowTitle(tr("Decrypt File"));
- } else if (mAction == Encrypt) {
- setWindowTitle(tr("Encrypt File"));
+void FileEncryptionDialog::slotSelectInputFile() {
+ QString path;
+ if (inputFileEdit->text().size() > 0) {
+ path = QFileInfo(inputFileEdit->text()).absolutePath();
+ }
+
+ // QString infileName = QFileDialog::getOpenFileName(this, _("Open File"),
+ // path, _("Files") + _("All Files (*)"));
+ QString infileName = QFileDialog::getOpenFileName(this, _("Open File"), path);
+ inputFileEdit->setText(infileName);
+
+ // try to find a matching output-filename, if not yet done
+ if (!infileName.isEmpty() && outputFileEdit->text().size() == 0 &&
+ signFileEdit->text().size() == 0) {
+ if (mAction == Encrypt) {
+ outputFileEdit->setText(infileName + ".asc");
} else if (mAction == Sign) {
- setWindowTitle(tr("Sign File"));
+ outputFileEdit->setText(infileName + ".sig");
} else if (mAction == Verify) {
- setWindowTitle(tr("Verify File"));
- }
-
- setModal(true);
-
- auto *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
- connect(buttonBox, SIGNAL(accepted()), this, SLOT(slotExecuteAction()));
- connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
-
- auto *groupBox1 = new QGroupBox(tr("Input Parameters"));
-
- /* Setup input & Outputfileselection*/
- inputFileEdit = new QLineEdit();
- auto *fb1 = new QPushButton("Select");
- connect(fb1, SIGNAL(clicked()), this, SLOT(slotSelectInputFile()));
- auto *fl1 = new QLabel(tr("Target File"));
- fl1->setBuddy(inputFileEdit);
-
- outputFileEdit = new QLineEdit();
- auto *fb2 = new QPushButton("Select");
- connect(fb2, SIGNAL(clicked()), this, SLOT(slotSelectOutputFile()));
- auto *fl2 = new QLabel(tr("Output File"));
- fl2->setBuddy(outputFileEdit);
-
- auto *gLayout = new QGridLayout();
- gLayout->addWidget(fl1, 0, 0);
- gLayout->addWidget(inputFileEdit, 0, 1);
- gLayout->addWidget(fb1, 0, 2);
- signFileEdit = new QLineEdit();
- // verify does not need outfile, but signature file
- if (mAction != Verify) {
- gLayout->addWidget(fl2, 1, 0);
- gLayout->addWidget(outputFileEdit, 1, 1);
- gLayout->addWidget(fb2, 1, 2);
+ signFileEdit->setText(infileName + ".sig");
} else {
- auto *sfb1 = new QPushButton("Select");
- connect(sfb1, SIGNAL(clicked()), this, SLOT(slotSelectSignFile()));
- auto *sfl1 = new QLabel(tr("Signature File(.sig) Path"));
- sfl1->setBuddy(signFileEdit);
-
- gLayout->addWidget(sfl1, 1, 0);
- gLayout->addWidget(signFileEdit, 1, 1);
- gLayout->addWidget(sfb1, 1, 2);
- }
- groupBox1->setLayout(gLayout);
-
- /*Setup KeyList*/
- mKeyList = new KeyList(mCtx, KeyListRow::ONLY_SECRET_KEY,
- KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage);
- if(mAction == Verify)
- mKeyList->setFilter([](const GpgKey &key) -> bool {
- if(key.disabled || key.expired || key.revoked) return false;
- else return true;
- });
-
- if(mAction == Encrypt)
- mKeyList->setFilter([](const GpgKey &key) -> bool {
- if(!GpgME::GpgContext::checkIfKeyCanEncr(key)) return false;
- else return true;
- });
-
- if(mAction == Sign)
- mKeyList->setFilter([](const GpgKey &key) -> bool {
- if(!GpgME::GpgContext::checkIfKeyCanSign(key)) return false;
- else return true;
- });
-
- if(mAction == Decrypt)
- mKeyList->setDisabled(true);
-
- mKeyList->slotRefresh();
- mKeyList->setChecked(&keyList);
-
- statusLabel = new QLabel();
- statusLabel->setStyleSheet("QLabel {color: red;}");
-
- auto *vbox2 = new QVBoxLayout();
- vbox2->addWidget(groupBox1);
- vbox2->addWidget(mKeyList);
- vbox2->addWidget(statusLabel);
- vbox2->addWidget(buttonBox);
- vbox2->addStretch(0);
- setLayout(vbox2);
-
- this->setMinimumWidth(480);
- this->show();
-
-}
-
-void FileEncryptionDialog::slotSelectInputFile() {
- QString path = "";
- if (inputFileEdit->text().size() > 0) {
- path = QFileInfo(inputFileEdit->text()).absolutePath();
- }
-
-// QString infileName = QFileDialog::getOpenFileName(this, tr("Open File"), path, tr("Files") + tr("All Files (*)"));
- QString infileName = QFileDialog::getOpenFileName(this, tr("Open File"), path);
- inputFileEdit->setText(infileName);
-
- // try to find a matching output-filename, if not yet done
- if (!infileName.isEmpty()
- && outputFileEdit->text().size() == 0
- && signFileEdit->text().size() == 0) {
- if (mAction == Encrypt) {
- outputFileEdit->setText(infileName + ".asc");
- } else if (mAction == Sign) {
- outputFileEdit->setText(infileName + ".sig");
- } else if (mAction == Verify) {
- signFileEdit->setText(infileName + ".sig");
- } else {
- if (infileName.endsWith(".asc", Qt::CaseInsensitive)) {
- QString ofn = infileName;
- ofn.chop(4);
- outputFileEdit->setText(ofn);
- } else {
- outputFileEdit->setText(infileName + ".out");
- }
- }
+ if (infileName.endsWith(".asc", Qt::CaseInsensitive)) {
+ QString ofn = infileName;
+ ofn.chop(4);
+ outputFileEdit->setText(ofn);
+ } else {
+ outputFileEdit->setText(infileName + ".out");
+ }
}
+ }
}
void FileEncryptionDialog::slotSelectOutputFile() {
- QString path = "";
- if (outputFileEdit->text().size() > 0) {
- path = QFileInfo(outputFileEdit->text()).absolutePath();
- }
-
- QString outfileName = QFileDialog::getSaveFileName(this, tr("Save File"), path, nullptr, nullptr,
- QFileDialog::DontConfirmOverwrite);
- outputFileEdit->setText(outfileName);
-
+ QString path;
+ if (outputFileEdit->text().size() > 0) {
+ path = QFileInfo(outputFileEdit->text()).absolutePath();
+ }
+
+ QString outfileName =
+ QFileDialog::getSaveFileName(this, _("Save File"), path, nullptr, nullptr,
+ QFileDialog::DontConfirmOverwrite);
+ outputFileEdit->setText(outfileName);
}
void FileEncryptionDialog::slotSelectSignFile() {
- QString path = "";
- if (signFileEdit->text().size() > 0) {
- path = QFileInfo(signFileEdit->text()).absolutePath();
- }
-
- QString signfileName = QFileDialog::getSaveFileName(this, tr("Open File"), path, nullptr, nullptr,
- QFileDialog::DontConfirmOverwrite);
- signFileEdit->setText(signfileName);
-
- if (inputFileEdit->text().size() == 0 && signfileName.endsWith(".sig", Qt::CaseInsensitive)) {
- QString sfn = signfileName;
- sfn.chop(4);
- inputFileEdit->setText(sfn);
- }
-
+ QString path;
+ if (signFileEdit->text().size() > 0) {
+ path = QFileInfo(signFileEdit->text()).absolutePath();
+ }
+
+ QString signfileName =
+ QFileDialog::getSaveFileName(this, _("Open File"), path, nullptr, nullptr,
+ QFileDialog::DontConfirmOverwrite);
+ signFileEdit->setText(signfileName);
+
+ if (inputFileEdit->text().size() == 0 &&
+ signfileName.endsWith(".sig", Qt::CaseInsensitive)) {
+ QString sfn = signfileName;
+ sfn.chop(4);
+ inputFileEdit->setText(sfn);
+ }
}
void FileEncryptionDialog::slotExecuteAction() {
-
- QFile infile;
- infile.setFileName(inputFileEdit->text());
- if (!infile.open(QIODevice::ReadOnly)) {
- statusLabel->setText(tr("Couldn't open file"));
- inputFileEdit->setStyleSheet("QLineEdit { background: yellow }");
- return;
- }
-
- QByteArray inBuffer = infile.readAll();
- auto *outBuffer = new QByteArray();
- infile.close();
-
- QVector<GpgKey> keys;
- mKeyList->getCheckedKeys(keys);
-
- qDebug() << "slotExecuteAction" << mAction;
-
- if (mAction == Encrypt) {
- qDebug() << "Action Encrypt";
- gpgme_error_t err = mCtx->encrypt(keys, inBuffer, outBuffer, nullptr);
- if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) {
- qDebug() << "Error" << gpgme_strerror(err);
- QMessageBox::warning(this, tr("Error"),
- tr("Error Occurred During Encryption"));
- return;
- }
- }
-
- if (mAction == Decrypt) {
- qDebug() << "Action Decrypt";
- gpgme_error_t err = mCtx->decrypt(inBuffer, outBuffer, nullptr);
- if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) {
- qDebug() << "Error" << gpgme_strerror(err);
- QMessageBox::warning(this, tr("Error"),
- tr("Error Occurred During Decryption"));
- return;
- }
+ QFile infile;
+ infile.setFileName(inputFileEdit->text());
+ if (!infile.open(QIODevice::ReadOnly)) {
+ statusLabel->setText(_("Couldn't open file"));
+ inputFileEdit->setStyleSheet("QLineEdit { background: yellow }");
+ return;
+ }
+ auto in_data = read_all_data_in_file(inputFileEdit->text().toStdString());
+ auto out_data = std::make_unique<ByteArray>();
+
+ auto key_ids = mKeyList->getChecked();
+ auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
+
+ if (mAction == Encrypt) {
+ qDebug() << "Action Encrypt";
+ GpgEncrResult result = nullptr;
+ gpgme_error_t err = BasicOperator::GetInstance().Encrypt(
+ std::move(keys), in_data, out_data, result);
+ if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) {
+ qDebug() << "Error" << gpgme_strerror(err);
+
+ QMessageBox::warning(this, _("Error"),
+ _("Error Occurred During Encryption"));
+ return;
}
-
- if (mAction == Sign) {
- qDebug() << "Action Sign";
- gpgme_error_t err = mCtx->sign(keys, inBuffer, outBuffer, GPGME_SIG_MODE_DETACH, nullptr);
- if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) {
- qDebug() << "Error" << gpgme_strerror(err);
- QMessageBox::warning(this, tr("Error"),
- tr("Error Occurred During Signature"));
- return;
- }
+ }
+
+ else if (mAction == Decrypt) {
+ qDebug() << "Action Decrypt";
+ GpgDecrResult result = nullptr;
+ gpgme_error_t err =
+ BasicOperator::GetInstance().Decrypt(in_data, out_data, result);
+ if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) {
+ qDebug() << "Error" << gpgme_strerror(err);
+ QMessageBox::warning(this, _("Error"),
+ _("Error Occurred During Decryption"));
+ return;
}
-
- if (mAction == Verify) {
- QFile sign_file;
- sign_file.setFileName(signFileEdit->text());
- if (!sign_file.open(QIODevice::ReadOnly)) {
- statusLabel->setText(tr("Couldn't open file"));
- signFileEdit->setStyleSheet("QLineEdit { background: yellow }");
- return;
- }
- auto signBuffer = sign_file.readAll();
- gpgme_verify_result_t result;
- auto error = mCtx->verify(&inBuffer, &signBuffer, &result);
- new VerifyDetailsDialog(this, mCtx, mKeyList, error, result);
- return;
+ }
+
+ else if (mAction == Sign) {
+ qDebug() << "Action Sign";
+ GpgSignResult result = nullptr;
+ gpgme_error_t err = BasicOperator::GetInstance().Sign(
+ std::move(keys), in_data, out_data, GPGME_SIG_MODE_DETACH, result);
+ if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) {
+ qDebug() << "Error" << gpgme_strerror(err);
+ QMessageBox::warning(this, _("Error"),
+ _("Error Occurred During Signature"));
+ return;
}
+ }
- QFile outfile(outputFileEdit->text());
- if (outfile.exists()) {
- QMessageBox::StandardButton ret;
- ret = QMessageBox::warning(this, tr("File"),
- tr("File exists! Do you want to overwrite it?"),
- QMessageBox::Ok | QMessageBox::Cancel);
- if (ret == QMessageBox::Cancel) {
- return;
- }
- }
+ if (mAction == Verify) {
+ auto sign_data = std::make_unique<ByteArray>(
+ read_all_data_in_file(signFileEdit->text().toStdString()));
+ GpgVerifyResult result = nullptr;
+ auto error =
+ BasicOperator::GetInstance().Verify(in_data, sign_data, result);
+ new VerifyDetailsDialog(this, mKeyList, error, std::move(result));
+ return;
+ }
- if (!outfile.open(QFile::WriteOnly)) {
- QMessageBox::warning(this, tr("File"),
- tr("Cannot write file %1:\n%2.")
- .arg(outputFileEdit->text())
- .arg(outfile.errorString()));
- return;
- }
+ write_buffer_to_file(outputFileEdit->text().toStdString(), *out_data);
- QDataStream out(&outfile);
- out.writeRawData(outBuffer->data(), outBuffer->length());
- outfile.close();
- QMessageBox::information(nullptr, "Done", "Output saved to " + outputFileEdit->text());
-
- accept();
+ accept();
}
-void FileEncryptionDialog::slotShowKeyList() {
- mKeyList->show();
-}
+void FileEncryptionDialog::slotShowKeyList() { mKeyList->show(); }
-void FileEncryptionDialog::slotHideKeyList() {
- mKeyList->hide();
-}
+void FileEncryptionDialog::slotHideKeyList() { mKeyList->hide(); }
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/FileEncryptionDialog.h b/src/ui/FileEncryptionDialog.h
new file mode 100755
index 00000000..613f84e7
--- /dev/null
+++ b/src/ui/FileEncryptionDialog.h
@@ -0,0 +1,114 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef __FILEENCRYPTIONDIALOG_H__
+#define __FILEENCRYPTIONDIALOG_H__
+
+#include "VerifyDetailsDialog.h"
+#include "gpg/GpgContext.h"
+#include "ui/GpgFrontendUI.h"
+#include "ui/widgets/KeyList.h"
+
+namespace GpgFrontend::UI {
+
+/**
+ * @brief
+ *
+ * @class FileEncryptionDialog fileencryptiondialog.h "fileencryptiondialog.h"
+ */
+class FileEncryptionDialog : public QDialog {
+ Q_OBJECT
+
+ public:
+ enum DialogAction { Encrypt, Decrypt, Sign, Verify };
+
+ /**
+ * @brief
+ *
+ * @fn FileEncryptionDialog
+ * @param ctx
+ * @param keyList
+ * @param parent
+ */
+ FileEncryptionDialog(KeyIdArgsListPtr keyList, DialogAction action,
+ QWidget* parent = nullptr);
+
+ public slots:
+
+ /**
+ * @details
+ *
+ * @fn selectInputFile
+ */
+ void slotSelectInputFile();
+
+ /**
+ * @brief
+ *
+ * @fn selectOutputFile
+ */
+ void slotSelectOutputFile();
+
+ /**
+ * @brief
+ *
+ * @fn selectSignFile
+ */
+ void slotSelectSignFile();
+
+ /**
+ * @brief
+ *
+ * @fn executeAction
+ */
+ void slotExecuteAction();
+
+ /**
+ * @brief
+ *
+ * @fn hideKeyList
+ */
+ void slotHideKeyList();
+
+ /**
+ * @brief
+ *
+ * @fn showKeyList
+ */
+ void slotShowKeyList();
+
+ private:
+ QLineEdit* outputFileEdit;
+ QLineEdit* inputFileEdit;
+ QLineEdit* signFileEdit;
+ DialogAction mAction;
+ QLabel* statusLabel;
+
+ protected:
+ KeyList* mKeyList;
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // __FILEENCRYPTIONDIALOG_H__
diff --git a/src/ui/FindWidget.cpp b/src/ui/FindWidget.cpp
index fce62223..6326b119 100644
--- a/src/ui/FindWidget.cpp
+++ b/src/ui/FindWidget.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,135 +24,140 @@
#include "ui/FindWidget.h"
-FindWidget::FindWidget(QWidget *parent, QTextEdit *edit) :
- QWidget(parent)
-{
- mTextpage = edit;
- findEdit = new QLineEdit(this);
- auto *closeButton= new QPushButton(this->style()->standardIcon(QStyle::SP_TitleBarCloseButton),"",this);
- auto *nextButton= new QPushButton(QIcon(":button_next.png"), "");
- auto *previousButton= new QPushButton(QIcon(":button_previous.png"), "");
-
- auto *notificationWidgetLayout = new QHBoxLayout(this);
- notificationWidgetLayout->setContentsMargins(10,0,0,0);
- notificationWidgetLayout->addWidget(new QLabel(tr("Find:")));
- notificationWidgetLayout->addWidget(findEdit,2);
- notificationWidgetLayout->addWidget(nextButton);
- notificationWidgetLayout->addWidget(previousButton);
- notificationWidgetLayout->addWidget(closeButton);
-
- this->setLayout(notificationWidgetLayout);
- connect(findEdit,SIGNAL(textEdited(QString)),this,SLOT(slotFind()));
- connect(findEdit,SIGNAL(returnPressed()),this,SLOT(slotFindNext()));
- connect(nextButton,SIGNAL(clicked()),this,SLOT(slotFindNext()));
- connect(previousButton,SIGNAL(clicked()),this,SLOT(slotFindPrevious()));
- connect(closeButton,SIGNAL(clicked()),this,SLOT(slotClose()));
-
- // The timer is necessary for setting the focus
- QTimer::singleShot(0, findEdit, SLOT(setFocus()));
+namespace GpgFrontend::UI {
+
+FindWidget::FindWidget(QWidget* parent, QTextEdit* edit) : QWidget(parent) {
+ mTextpage = edit;
+ findEdit = new QLineEdit(this);
+ auto* closeButton = new QPushButton(
+ this->style()->standardIcon(QStyle::SP_TitleBarCloseButton), QString(),
+ this);
+ auto* nextButton = new QPushButton(QIcon(":button_next.png"), QString());
+ auto* previousButton = new QPushButton(QIcon(":button_previous.png"), "");
+
+ auto* notificationWidgetLayout = new QHBoxLayout(this);
+ notificationWidgetLayout->setContentsMargins(10, 0, 0, 0);
+ notificationWidgetLayout->addWidget(new QLabel(QString(_("Find")) + ": "));
+ notificationWidgetLayout->addWidget(findEdit, 2);
+ notificationWidgetLayout->addWidget(nextButton);
+ notificationWidgetLayout->addWidget(previousButton);
+ notificationWidgetLayout->addWidget(closeButton);
+
+ this->setLayout(notificationWidgetLayout);
+ connect(findEdit, SIGNAL(textEdited(QString)), this, SLOT(slotFind()));
+ connect(findEdit, SIGNAL(returnPressed()), this, SLOT(slotFindNext()));
+ connect(nextButton, SIGNAL(clicked()), this, SLOT(slotFindNext()));
+ connect(previousButton, SIGNAL(clicked()), this, SLOT(slotFindPrevious()));
+ connect(closeButton, SIGNAL(clicked()), this, SLOT(slotClose()));
+
+ // The timer is necessary for setting the focus
+ QTimer::singleShot(0, findEdit, SLOT(setFocus()));
}
-void FindWidget::setBackground()
-{
- QTextCursor cursor = mTextpage->textCursor();
- // if match is found set background of QLineEdit to white, otherwise to red
- QPalette bgPalette( findEdit->palette() );
-
- if (!findEdit->text().isEmpty() && mTextpage->document()->find(findEdit->text()).position() < 0 ) {
- bgPalette.setColor( QPalette::Base, "#ececba");
- } else {
- bgPalette.setColor( QPalette::Base, Qt::white);
- }
- findEdit->setPalette(bgPalette);
+void FindWidget::setBackground() {
+ QTextCursor cursor = mTextpage->textCursor();
+ // if match is found set background of QLineEdit to white, otherwise to red
+ QPalette bgPalette(findEdit->palette());
+
+ if (!findEdit->text().isEmpty() &&
+ mTextpage->document()->find(findEdit->text()).position() < 0) {
+ bgPalette.setColor(QPalette::Base, "#ececba");
+ } else {
+ bgPalette.setColor(QPalette::Base, Qt::white);
+ }
+ findEdit->setPalette(bgPalette);
}
-void FindWidget::slotFindNext()
-{
- QTextCursor cursor = mTextpage->textCursor();
- cursor = mTextpage->document()->find(findEdit->text(), cursor, QTextDocument::FindCaseSensitively);
-
- // if end of document is reached, restart search from beginning
- if (cursor.position() == -1) {
- cursor = mTextpage->document()->find(findEdit->text(), cursor, QTextDocument::FindCaseSensitively);
- }
-
- // cursor should not stay at -1, otherwise text is not editable
- // todo: check how gedit handles this
- if(cursor.position() != -1) {
- mTextpage->setTextCursor(cursor);
- }
- this->setBackground();
+void FindWidget::slotFindNext() {
+ QTextCursor cursor = mTextpage->textCursor();
+ cursor = mTextpage->document()->find(findEdit->text(), cursor,
+ QTextDocument::FindCaseSensitively);
+
+ // if end of document is reached, restart search from beginning
+ if (cursor.position() == -1) {
+ cursor = mTextpage->document()->find(findEdit->text(), cursor,
+ QTextDocument::FindCaseSensitively);
+ }
+
+ // cursor should not stay at -1, otherwise text is not editable
+ // todo: check how gedit handles this
+ if (cursor.position() != -1) {
+ mTextpage->setTextCursor(cursor);
+ }
+ this->setBackground();
}
-void FindWidget::slotFind()
-{
- QTextCursor cursor = mTextpage->textCursor();
-
- if (cursor.anchor() == -1) {
- cursor = mTextpage->document()->find(findEdit->text(), cursor, QTextDocument::FindCaseSensitively);
- } else {
- cursor = mTextpage->document()->find(findEdit->text(), cursor.anchor(), QTextDocument::FindCaseSensitively);
- }
-
- // if end of document is reached, restart search from beginning
- if (cursor.position() == -1) {
- cursor = mTextpage->document()->find(findEdit->text(), cursor, QTextDocument::FindCaseSensitively);
- }
-
- // cursor should not stay at -1, otherwise text is not editable
- // todo: check how gedit handles this
- if(cursor.position() != -1) {
- mTextpage->setTextCursor(cursor);
- }
- this->setBackground();
+void FindWidget::slotFind() {
+ QTextCursor cursor = mTextpage->textCursor();
+
+ if (cursor.anchor() == -1) {
+ cursor = mTextpage->document()->find(findEdit->text(), cursor,
+ QTextDocument::FindCaseSensitively);
+ } else {
+ cursor = mTextpage->document()->find(findEdit->text(), cursor.anchor(),
+ QTextDocument::FindCaseSensitively);
+ }
+
+ // if end of document is reached, restart search from beginning
+ if (cursor.position() == -1) {
+ cursor = mTextpage->document()->find(findEdit->text(), cursor,
+ QTextDocument::FindCaseSensitively);
+ }
+
+ // cursor should not stay at -1, otherwise text is not editable
+ // todo: check how gedit handles this
+ if (cursor.position() != -1) {
+ mTextpage->setTextCursor(cursor);
+ }
+ this->setBackground();
}
-void FindWidget::slotFindPrevious()
-{
- QTextDocument::FindFlags flags;
- flags |= QTextDocument::FindBackward;
- flags |= QTextDocument::FindCaseSensitively;
-
- QTextCursor cursor = mTextpage->textCursor();
- cursor = mTextpage->document()->find(findEdit->text(), cursor, flags);
-
- // if begin of document is reached, restart search from end
- if (cursor.position() == -1) {
- cursor = mTextpage->document()->find(findEdit->text(), QTextCursor::End, flags);
- }
-
- // cursor should not stay at -1, otherwise text is not editable
- // todo: check how gedit handles this
- if(cursor.position() != -1) {
- mTextpage->setTextCursor(cursor);
- }
- this->setBackground();
+void FindWidget::slotFindPrevious() {
+ QTextDocument::FindFlags flags;
+ flags |= QTextDocument::FindBackward;
+ flags |= QTextDocument::FindCaseSensitively;
+
+ QTextCursor cursor = mTextpage->textCursor();
+ cursor = mTextpage->document()->find(findEdit->text(), cursor, flags);
+
+ // if begin of document is reached, restart search from end
+ if (cursor.position() == -1) {
+ cursor =
+ mTextpage->document()->find(findEdit->text(), QTextCursor::End, flags);
+ }
+
+ // cursor should not stay at -1, otherwise text is not editable
+ // todo: check how gedit handles this
+ if (cursor.position() != -1) {
+ mTextpage->setTextCursor(cursor);
+ }
+ this->setBackground();
}
-void FindWidget::keyPressEvent( QKeyEvent* e )
-{
- switch ( e->key() )
- {
+void FindWidget::keyPressEvent(QKeyEvent* e) {
+ switch (e->key()) {
case Qt::Key_Escape:
- this->slotClose();
- break;
+ this->slotClose();
+ break;
case Qt::Key_F3:
- if (e->modifiers() & Qt::ShiftModifier) {
- this->slotFindPrevious();
- } else {
- this->slotFindNext();
- }
- break;
- }
+ if (e->modifiers() & Qt::ShiftModifier) {
+ this->slotFindPrevious();
+ } else {
+ this->slotFindNext();
+ }
+ break;
+ }
}
void FindWidget::slotClose() {
- QTextCursor cursor = mTextpage->textCursor();
-
- if ( cursor.position() == -1) {
- cursor.setPosition(0);
- mTextpage->setTextCursor(cursor);
- }
- mTextpage->setFocus();
- close();
+ QTextCursor cursor = mTextpage->textCursor();
+
+ if (cursor.position() == -1) {
+ cursor.setPosition(0);
+ mTextpage->setTextCursor(cursor);
+ }
+ mTextpage->setFocus();
+ close();
}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/FindWidget.h b/src/ui/FindWidget.h
new file mode 100644
index 00000000..e4cbdaab
--- /dev/null
+++ b/src/ui/FindWidget.h
@@ -0,0 +1,72 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef FINDWIDGET_H
+#define FINDWIDGET_H
+
+#include "ui/GpgFrontendUI.h"
+#include "ui/widgets/EditorPage.h"
+
+namespace GpgFrontend::UI {
+
+/**
+ * @brief Class for handling the find widget shown at buttom of a textedit-page
+ */
+class FindWidget : public QWidget {
+ Q_OBJECT
+
+ public:
+ /**
+ * @brief
+ *
+ * @param parent The parent widget
+ */
+ explicit FindWidget(QWidget* parent, QTextEdit* edit);
+
+ private:
+ void keyPressEvent(QKeyEvent* e) override;
+
+ /**
+ * @details Set background of findEdit to red, if no match is found (Documents
+ * textcursor position equals -1), otherwise set it to white.
+ */
+ void setBackground();
+
+ QTextEdit* mTextpage; /** Textedit associated to the notification */
+ QLineEdit* findEdit; /** Label holding the text shown in infoBoard */
+
+ private slots:
+
+ void slotFindNext();
+
+ void slotFindPrevious();
+
+ void slotFind();
+
+ void slotClose();
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // FINDWIDGET_H
diff --git a/src/ui/GpgFrontendUI.h b/src/ui/GpgFrontendUI.h
new file mode 100644
index 00000000..01f82822
--- /dev/null
+++ b/src/ui/GpgFrontendUI.h
@@ -0,0 +1,53 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_GPGFRONTENDUI_H
+#define GPGFRONTEND_GPGFRONTENDUI_H
+
+#include "GpgFrontend.h"
+
+#include <QtCore>
+#include <QtNetwork>
+#include <QtPrintSupport>
+#include <QtWidgets>
+
+#undef LIBCONFIGXX_STATIC
+#define LIBCONFIGXX_STATIC
+#include <libconfig.h++>
+
+/**
+ * Resources File(s) Path Vars
+ */
+#if defined(MACOS) && defined(RELEASE)
+#define RESOURCE_DIR(appDir) (appDir + "/../Resources/")
+#define RESOURCE_DIR_BOOST_PATH(appDir) (appDir / ".." / "Resources")
+#elif defined(LINUX) && defined(RELEASE)
+#define RESOURCE_DIR(appDir) (appDir + "/../share/")
+#define RESOURCE_DIR_BOOST_PATH(appDir) (appDir / ".." / "share")
+#else
+#define RESOURCE_DIR(appDir) (appDir)
+#define RESOURCE_DIR_BOOST_PATH(appDir) (appDir)
+#endif
+
+#endif // GPGFRONTEND_GPGFRONTENDUI_H
diff --git a/src/ui/KeyImportDetailDialog.cpp b/src/ui/KeyImportDetailDialog.cpp
index 8d303886..48d1e9ee 100644
--- a/src/ui/KeyImportDetailDialog.cpp
+++ b/src/ui/KeyImportDetailDialog.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -22,145 +22,177 @@
*
*/
-#include <ui/KeyImportDetailDialog.h>
+#include "ui/KeyImportDetailDialog.h"
-KeyImportDetailDialog::KeyImportDetailDialog(GpgME::GpgContext *ctx, GpgImportInformation result, bool automatic,
- QWidget *parent)
- : QDialog(parent), mCtx(ctx), mResult(std::move(result)) {
+#include "gpg/function/GpgKeyGetter.h"
- // If no key for import found, just show a message
- if (mResult.considered == 0) {
- if(automatic)
- QMessageBox::information(nullptr, tr("Key Update Details"), tr("No keys found"));
- else
- QMessageBox::information(nullptr, tr("Key Import Details"), tr("No keys found to import"));
- return;
- }
-
- auto *mvbox = new QVBoxLayout();
+namespace GpgFrontend::UI {
+KeyImportDetailDialog::KeyImportDetailDialog(GpgImportInformation result,
+ bool automatic, QWidget* parent)
+ : QDialog(parent), mResult(std::move(result)) {
+ // If no key for import found, just show a message
+ if (mResult.considered == 0) {
+ if (automatic)
+ QMessageBox::information(parent, _("Key Update Details"),
+ _("No keys found"));
+ else
+ QMessageBox::information(parent, _("Key Import Details"),
+ _("No keys found to import"));
+ emit finished(0);
+ this->close();
+ this->deleteLater();
+ } else {
+ auto* mv_box = new QVBoxLayout();
this->createGeneralInfoBox();
- mvbox->addWidget(generalInfoBox);
+ mv_box->addWidget(generalInfoBox);
this->createKeysTable();
- mvbox->addWidget(keysTable);
+ mv_box->addWidget(keysTable);
this->createButtonBox();
- mvbox->addWidget(buttonBox);
+ mv_box->addWidget(buttonBox);
- this->setLayout(mvbox);
- if(automatic)
- this->setWindowTitle(tr("Key Update Details"));
+ this->setLayout(mv_box);
+ if (automatic)
+ this->setWindowTitle(_("Key Update Details"));
else
- this->setWindowTitle(tr("Key Import Details"));
+ this->setWindowTitle(_("Key Import Details"));
+ auto pos = QPoint(100, 100);
+ LOG(INFO) << "parent" << parent;
+ if (parent) pos += parent->pos();
+ this->move(pos);
this->resize(QSize(600, 300));
this->setModal(true);
- this->exec();
+ this->show();
+ }
}
void KeyImportDetailDialog::createGeneralInfoBox() {
- // GridBox for general import information
- generalInfoBox = new QGroupBox(tr("General key info"));
- auto *generalInfoBoxLayout = new QGridLayout(generalInfoBox);
-
- generalInfoBoxLayout->addWidget(new QLabel(tr("Considered:")), 1, 0);
- generalInfoBoxLayout->addWidget(new QLabel(QString::number(mResult.considered)), 1, 1);
- int row = 2;
- if (mResult.unchanged != 0) {
- generalInfoBoxLayout->addWidget(new QLabel(tr("Public unchanged:")), row, 0);
- generalInfoBoxLayout->addWidget(new QLabel(QString::number(mResult.unchanged)), row, 1);
- row++;
- }
- if (mResult.imported != 0) {
- generalInfoBoxLayout->addWidget(new QLabel(tr("Imported:")), row, 0);
- generalInfoBoxLayout->addWidget(new QLabel(QString::number(mResult.imported)), row, 1);
- row++;
- }
- if (mResult.not_imported != 0) {
- generalInfoBoxLayout->addWidget(new QLabel(tr("Not imported:")), row, 0);
- generalInfoBoxLayout->addWidget(new QLabel(QString::number(mResult.not_imported)), row, 1);
- row++;
- }
- if (mResult.secret_read != 0) {
- generalInfoBoxLayout->addWidget(new QLabel(tr("Private read:")), row, 0);
- generalInfoBoxLayout->addWidget(new QLabel(QString::number(mResult.secret_read)), row, 1);
- row++;
- }
- if (mResult.secret_imported != 0) {
- generalInfoBoxLayout->addWidget(new QLabel(tr("Private imported:")), row, 0);
- generalInfoBoxLayout->addWidget(new QLabel(QString::number(mResult.secret_imported)), row, 1);
- row++;
- }
- if (mResult.secret_unchanged != 0) {
- generalInfoBoxLayout->addWidget(new QLabel(tr("Private unchanged:")), row, 0);
- generalInfoBoxLayout->addWidget(new QLabel(QString::number(mResult.secret_unchanged)), row, 1);
- row++;
- }
+ // GridBox for general import information
+ generalInfoBox = new QGroupBox(_("General key info"));
+ auto* generalInfoBoxLayout = new QGridLayout(generalInfoBox);
+
+ generalInfoBoxLayout->addWidget(new QLabel(QString(_("Considered")) + ": "),
+ 1, 0);
+ generalInfoBoxLayout->addWidget(
+ new QLabel(QString::number(mResult.considered)), 1, 1);
+ int row = 2;
+ if (mResult.unchanged != 0) {
+ generalInfoBoxLayout->addWidget(
+ new QLabel(QString(_("Public unchanged")) + ": "), row, 0);
+ generalInfoBoxLayout->addWidget(
+ new QLabel(QString::number(mResult.unchanged)), row, 1);
+ row++;
+ }
+ if (mResult.imported != 0) {
+ generalInfoBoxLayout->addWidget(new QLabel(QString(_("Imported")) + ": "),
+ row, 0);
+ generalInfoBoxLayout->addWidget(
+ new QLabel(QString::number(mResult.imported)), row, 1);
+ row++;
+ }
+ if (mResult.not_imported != 0) {
+ generalInfoBoxLayout->addWidget(
+ new QLabel(QString(_("Not Imported")) + ": "), row, 0);
+ generalInfoBoxLayout->addWidget(
+ new QLabel(QString::number(mResult.not_imported)), row, 1);
+ row++;
+ }
+ if (mResult.secret_read != 0) {
+ generalInfoBoxLayout->addWidget(
+ new QLabel(QString(_("Private Read")) + ": "), row, 0);
+ generalInfoBoxLayout->addWidget(
+ new QLabel(QString::number(mResult.secret_read)), row, 1);
+ row++;
+ }
+ if (mResult.secret_imported != 0) {
+ generalInfoBoxLayout->addWidget(
+ new QLabel(QString(_("Private Imported")) + ": "), row, 0);
+ generalInfoBoxLayout->addWidget(
+ new QLabel(QString::number(mResult.secret_imported)), row, 1);
+ row++;
+ }
+ if (mResult.secret_unchanged != 0) {
+ generalInfoBoxLayout->addWidget(
+ new QLabel(QString(_("Private Unchanged")) + ": "), row, 0);
+ generalInfoBoxLayout->addWidget(
+ new QLabel(QString::number(mResult.secret_unchanged)), row, 1);
+ row++;
+ }
}
void KeyImportDetailDialog::createKeysTable() {
- keysTable = new QTableWidget(this);
- keysTable->setRowCount(0);
- keysTable->setColumnCount(4);
- keysTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
- // Nothing is selectable
- keysTable->setSelectionMode(QAbstractItemView::NoSelection);
-
- QStringList headerLabels;
- headerLabels << tr("Name") << tr("Email") << tr("Status") << tr("Fingerprint");
- keysTable->verticalHeader()->hide();
-
- keysTable->setHorizontalHeaderLabels(headerLabels);
- int row = 0;
- for (const auto &impKey : mResult.importedKeys) {
- keysTable->setRowCount(row + 1);
- GpgKey key = mCtx->getKeyByFpr(impKey.fpr);
- if(!key.good) continue;
- keysTable->setItem(row, 0, new QTableWidgetItem(key.name));
- keysTable->setItem(row, 1, new QTableWidgetItem(key.email));
- keysTable->setItem(row, 2, new QTableWidgetItem(getStatusString(impKey.importStatus)));
- keysTable->setItem(row, 3, new QTableWidgetItem(impKey.fpr));
- row++;
- }
- keysTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
- keysTable->horizontalHeader()->setStretchLastSection(true);
- keysTable->resizeColumnsToContents();
+ LOG(INFO) << "KeyImportDetailDialog::createKeysTable() Called";
+
+ keysTable = new QTableWidget(this);
+ keysTable->setRowCount(0);
+ keysTable->setColumnCount(4);
+ keysTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ // Nothing is selectable
+ keysTable->setSelectionMode(QAbstractItemView::NoSelection);
+
+ QStringList headerLabels;
+ headerLabels << _("Name") << _("Email") << _("Status") << _("Fingerprint");
+ keysTable->verticalHeader()->hide();
+
+ keysTable->setHorizontalHeaderLabels(headerLabels);
+ int row = 0;
+ for (const auto& imp_key : mResult.importedKeys) {
+ keysTable->setRowCount(row + 1);
+ GpgKey key = GpgKeyGetter::GetInstance().GetKey(imp_key.fpr);
+ if (!key.good()) continue;
+ keysTable->setItem(
+ row, 0, new QTableWidgetItem(QString::fromStdString(key.name())));
+ keysTable->setItem(
+ row, 1, new QTableWidgetItem(QString::fromStdString(key.email())));
+ keysTable->setItem(
+ row, 2, new QTableWidgetItem(getStatusString(imp_key.import_status)));
+ keysTable->setItem(
+ row, 3, new QTableWidgetItem(QString::fromStdString(imp_key.fpr)));
+ row++;
+ }
+ keysTable->horizontalHeader()->setSectionResizeMode(
+ 0, QHeaderView::ResizeToContents);
+ keysTable->horizontalHeader()->setStretchLastSection(true);
+ keysTable->resizeColumnsToContents();
}
QString KeyImportDetailDialog::getStatusString(int keyStatus) {
- QString statusString;
- // keystatus is greater than 15, if key is private
- if (keyStatus > 15) {
- statusString.append(tr("private"));
- keyStatus = keyStatus - 16;
- } else {
- statusString.append(tr("public"));
- }
- if (keyStatus == 0) {
- statusString.append(", " + tr("unchanged"));
+ QString statusString;
+ // keystatus is greater than 15, if key is private
+ if (keyStatus > 15) {
+ statusString.append(_("Private"));
+ keyStatus = keyStatus - 16;
+ } else {
+ statusString.append(_("Public"));
+ }
+ if (keyStatus == 0) {
+ statusString.append(", " + QString(_("Unchanged")));
+ } else {
+ if (keyStatus == 1) {
+ statusString.append(", " + QString(_("New Key")));
} else {
- if (keyStatus == 1) {
- statusString.append(", " + tr("new key"));
- } else {
- if (keyStatus > 7) {
- statusString.append(", " + tr("new subkey"));
- keyStatus = keyStatus - 8;
- }
- if (keyStatus > 3) {
- statusString.append(", " + tr("new signature"));
- keyStatus = keyStatus - 4;
- }
- if (keyStatus > 1) {
- statusString.append(", " + tr("new uid"));
- keyStatus = keyStatus - 2;
- }
- }
+ if (keyStatus > 7) {
+ statusString.append(", " + QString(_("New Subkey")));
+ keyStatus = keyStatus - 8;
+ }
+ if (keyStatus > 3) {
+ statusString.append(", " + QString(_("New Signature")));
+ keyStatus = keyStatus - 4;
+ }
+ if (keyStatus > 1) {
+ statusString.append(", " + QString(_("New UID")));
+ keyStatus = keyStatus - 2;
+ }
}
- return statusString;
+ }
+ return statusString;
}
void KeyImportDetailDialog::createButtonBox() {
- buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok);
- connect(buttonBox, SIGNAL(accepted()), this, SLOT(close()));
+ buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok);
+ connect(buttonBox, SIGNAL(accepted()), this, SLOT(close()));
}
+} // namespace GpgFrontend::UI
diff --git a/src/ui/KeyImportDetailDialog.h b/src/ui/KeyImportDetailDialog.h
new file mode 100644
index 00000000..fe63baaa
--- /dev/null
+++ b/src/ui/KeyImportDetailDialog.h
@@ -0,0 +1,55 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef __KEYIMPORTDETAILSDIALOG_H__
+#define __KEYIMPORTDETAILSDIALOG_H__
+
+#include <gpg/function/GpgKeyImportExportor.h>
+
+#include "gpg/GpgContext.h"
+#include "ui/GpgFrontendUI.h"
+
+namespace GpgFrontend::UI {
+class KeyImportDetailDialog : public QDialog {
+ Q_OBJECT
+
+ public:
+ KeyImportDetailDialog(GpgImportInformation result, bool automatic,
+ QWidget* parent = nullptr);
+
+ private:
+ void createGeneralInfoBox();
+ void createKeysTable();
+ void createButtonBox();
+ static QString getStatusString(int keyStatus);
+
+ QTableWidget* keysTable{};
+ QGroupBox* generalInfoBox{};
+ QGroupBox* keyInfoBox{};
+ QDialogButtonBox* buttonBox{};
+ GpgImportInformation mResult;
+};
+} // namespace GpgFrontend::UI
+
+#endif // __KEYIMPORTDETAILSDIALOG_H__
diff --git a/src/ui/KeyMgmt.cpp b/src/ui/KeyMgmt.cpp
index 77f3b760..7459906d 100755
--- a/src/ui/KeyMgmt.cpp
+++ b/src/ui/KeyMgmt.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -26,331 +26,384 @@
#include <utility>
-KeyMgmt::KeyMgmt(GpgME::GpgContext *ctx, QWidget *parent) :
- QMainWindow(parent), appPath(qApp->applicationDirPath()),
- settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", QSettings::IniFormat) {
- mCtx = ctx;
+#include "gpg/function/GpgKeyGetter.h"
+#include "gpg/function/GpgKeyImportExportor.h"
+#include "gpg/function/GpgKeyOpera.h"
+#include "ui/SignalStation.h"
+#include "ui/UserInterfaceUtils.h"
+#include "ui/settings/GlobalSettingStation.h"
+
+namespace GpgFrontend::UI {
+KeyMgmt::KeyMgmt(QWidget* parent) : QMainWindow(parent) {
+ /* the list of Keys available*/
+ mKeyList = new KeyList();
+ mKeyList->setColumnWidth(2, 250);
+ mKeyList->setColumnWidth(3, 250);
+ setCentralWidget(mKeyList);
+ mKeyList->setDoubleClickedAction([this](const GpgKey& key, QWidget* parent) {
+ new KeyDetailsDialog(key, parent);
+ });
+
+ createActions();
+ createMenus();
+ createToolBars();
+ connect(this, SIGNAL(signalStatusBarChanged(QString)), this->parent(),
+ SLOT(slotSetStatusBarText(QString)));
+
+ auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
+
+ try {
+ int width = settings.lookup("window.icon_size.width");
+ int height = settings.lookup("window.icon_size.height");
+
+ this->setIconSize(QSize(width, height));
+
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("icon_size");
+ }
+
+ // icon_style
+ try {
+ int s_icon_style = settings.lookup("window.icon_style");
+ auto icon_style = static_cast<Qt::ToolButtonStyle>(s_icon_style);
+ this->setToolButtonStyle(icon_style);
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("icon_style");
+ }
+
+ auto pos = QPoint(50, 50);
+ LOG(INFO) << "parent" << parent;
+ if (parent) pos += parent->pos();
+ LOG(INFO) << "pos default" << pos.x() << pos.y();
+ auto size = QSize(900, 600);
+
+ try {
+ int x, y, width, height;
+ x = settings.lookup("window.key_management.position.x");
+ y = settings.lookup("window.key_management.position.y");
+ width = settings.lookup("window.key_management.size.width");
+ height = settings.lookup("window.key_management.size.height");
+ pos = QPoint(x, y);
+ size = QSize(width, height);
+
+ std::string window_state =
+ settings.lookup("window.key_management.window_state");
- /* the list of Keys available*/
- mKeyList = new KeyList(mCtx);
- mKeyList->setColumnWidth(2, 250);
- mKeyList->setColumnWidth(3, 250);
- setCentralWidget(mKeyList);
- mKeyList->setDoubleClickedAction([this](const GpgKey &key, QWidget *parent) {
- new KeyDetailsDialog(mCtx, key, parent);
- });
-
- createActions();
- createMenus();
- createToolBars();
- connect(this, SIGNAL(signalStatusBarChanged(QString)), this->parent(), SLOT(slotSetStatusBarText(QString)));
+ // state sets pos & size of dock-widgets
+ this->restoreState(
+ QByteArray::fromBase64(QByteArray::fromStdString(window_state)));
- /* Restore the iconstyle */
- this->settings.sync();
+ } catch (...) {
+ LOG(WARNING) << "cannot read pos or size from settings";
+ }
- QSize iconSize = settings.value("toolbar/iconsize", QSize(24, 24)).toSize();
- settings.setValue("toolbar/iconsize", iconSize);
+ this->resize(size);
+ this->move(pos);
- Qt::ToolButtonStyle buttonStyle = static_cast<Qt::ToolButtonStyle>(settings.value("toolbar/iconstyle",
- Qt::ToolButtonTextUnderIcon).toUInt());
- this->setIconSize(iconSize);
- this->setToolButtonStyle(buttonStyle);
+ setWindowTitle(_("KeyPair Management"));
+ mKeyList->addMenuAction(deleteSelectedKeysAct);
+ mKeyList->addMenuAction(showKeyDetailsAct);
- // state sets pos & size of dock-widgets
- this->restoreState(this->settings.value("keymgmt/windowState").toByteArray());
-
- qDebug() << "windows/windowSave" << this->settings.value("window/windowSave").toBool();
-
- // Restore window size & location
- if (this->settings.value("keymgmt/setWindowSize").toBool()) {
- QPoint pos = settings.value("keymgmt/pos", QPoint(100, 100)).toPoint();
- QSize size = settings.value("keymgmt/size", QSize(900, 600)).toSize();
- qDebug() << "Settings size" << size << "pos" << pos;
- this->setMinimumSize(size);
- this->move(pos);
- } else {
- qDebug() << "Use default min windows size and pos";
- QPoint defaultPoint(100, 100);
- QSize defaultMinSize(900, 600);
- this->setMinimumSize(defaultMinSize);
- this->move(defaultPoint);
- this->settings.setValue("keymgmt/pos", defaultPoint);
- this->settings.setValue("keymgmt/size", defaultMinSize);
- this->settings.setValue("keymgmt/setWindowSize", true);
- }
-
- setWindowTitle(tr("Key Pair Management"));
- mKeyList->addMenuAction(deleteSelectedKeysAct);
- mKeyList->addMenuAction(showKeyDetailsAct);
+ connect(this, SIGNAL(signalKeyStatusUpdated()), SignalStation::GetInstance(),
+ SIGNAL(KeyDatabaseRefresh()));
}
void KeyMgmt::createActions() {
- openKeyFileAct = new QAction(tr("&Open"), this);
- openKeyFileAct->setShortcut(tr("Ctrl+O"));
- openKeyFileAct->setToolTip(tr("Open Key File"));
- connect(openKeyFileAct, SIGNAL(triggered()), this, SLOT(slotImportKeyFromFile()));
-
- closeAct = new QAction(tr("&Close"), this);
- closeAct->setShortcut(tr("Ctrl+Q"));
- closeAct->setIcon(QIcon(":exit.png"));
- closeAct->setToolTip(tr("Close"));
- connect(closeAct, SIGNAL(triggered()), this, SLOT(close()));
-
- generateKeyPairAct = new QAction(tr("New Keypair"), this);
- generateKeyPairAct->setShortcut(tr("Ctrl+N"));
- generateKeyPairAct->setIcon(QIcon(":key_generate.png"));
- generateKeyPairAct->setToolTip(tr("Generate KeyPair"));
- connect(generateKeyPairAct, SIGNAL(triggered()), this, SLOT(slotGenerateKeyDialog()));
-
- generateSubKeyAct = new QAction(tr("New Subkey"), this);
- generateSubKeyAct->setShortcut(tr("Ctrl+Shift+N"));
- generateSubKeyAct->setIcon(QIcon(":key_generate.png"));
- generateSubKeyAct->setToolTip(tr("Generate Subkey For Selected KeyPair"));
- connect(generateSubKeyAct, SIGNAL(triggered()), this, SLOT(slotGenerateSubKey()));
-
- importKeyFromFileAct = new QAction(tr("&File"), this);
- importKeyFromFileAct->setIcon(QIcon(":import_key_from_file.png"));
- importKeyFromFileAct->setToolTip(tr("Import New Key From File"));
- connect(importKeyFromFileAct, SIGNAL(triggered()), this, SLOT(slotImportKeyFromFile()));
-
- importKeyFromClipboardAct = new QAction(tr("&Clipboard"), this);
- importKeyFromClipboardAct->setIcon(QIcon(":import_key_from_clipboard.png"));
- importKeyFromClipboardAct->setToolTip(tr("Import New Key From Clipboard"));
- connect(importKeyFromClipboardAct, SIGNAL(triggered()), this, SLOT(slotImportKeyFromClipboard()));
-
- importKeyFromKeyServerAct = new QAction(tr("&Keyserver"), this);
- importKeyFromKeyServerAct->setIcon(QIcon(":import_key_from_server.png"));
- importKeyFromKeyServerAct->setToolTip(tr("Import New Key From Keyserver"));
- connect(importKeyFromKeyServerAct, SIGNAL(triggered()), this, SLOT(slotImportKeyFromKeyServer()));
-
- exportKeyToClipboardAct = new QAction(tr("Export To &Clipboard"), this);
- exportKeyToClipboardAct->setIcon(QIcon(":export_key_to_clipboard.png"));
- exportKeyToClipboardAct->setToolTip(tr("Export Selected Key(s) To Clipboard"));
- connect(exportKeyToClipboardAct, SIGNAL(triggered()), this, SLOT(slotExportKeyToClipboard()));
-
- exportKeyToFileAct = new QAction(tr("Export To &File"), this);
- exportKeyToFileAct->setIcon(QIcon(":export_key_to_file.png"));
- exportKeyToFileAct->setToolTip(tr("Export Selected Key(s) To File"));
- connect(exportKeyToFileAct, SIGNAL(triggered()), this, SLOT(slotExportKeyToFile()));
-
- deleteSelectedKeysAct = new QAction(tr("Delete Selected Key(s)"), this);
- deleteSelectedKeysAct->setToolTip(tr("Delete the Selected keys"));
- connect(deleteSelectedKeysAct, SIGNAL(triggered()), this, SLOT(slotDeleteSelectedKeys()));
-
- deleteCheckedKeysAct = new QAction(tr("Delete Checked Key(s)"), this);
- deleteCheckedKeysAct->setToolTip(tr("Delete the Checked keys"));
- deleteCheckedKeysAct->setIcon(QIcon(":button_delete.png"));
- connect(deleteCheckedKeysAct, SIGNAL(triggered()), this, SLOT(slotDeleteCheckedKeys()));
-
- showKeyDetailsAct = new QAction(tr("Show Key Details"), this);
- showKeyDetailsAct->setToolTip(tr("Show Details for this Key"));
- connect(showKeyDetailsAct, SIGNAL(triggered()), this, SLOT(slotShowKeyDetails()));
+ openKeyFileAct = new QAction(_("Open"), this);
+ openKeyFileAct->setShortcut(QKeySequence(_("Ctrl+O")));
+ openKeyFileAct->setToolTip(_("Open Key File"));
+ connect(importKeyFromFileAct, &QAction::triggered, this,
+ [&]() { CommonUtils::GetInstance()->slotImportKeyFromFile(this); });
+
+ closeAct = new QAction(_("Close"), this);
+ closeAct->setShortcut(QKeySequence(_("Ctrl+Q")));
+ closeAct->setIcon(QIcon(":exit.png"));
+ closeAct->setToolTip(_("Close"));
+ connect(closeAct, SIGNAL(triggered()), this, SLOT(close()));
+
+ generateKeyPairAct = new QAction(_("New Keypair"), this);
+ generateKeyPairAct->setShortcut(QKeySequence(_("Ctrl+N")));
+ generateKeyPairAct->setIcon(QIcon(":key_generate.png"));
+ generateKeyPairAct->setToolTip(_("Generate KeyPair"));
+ connect(generateKeyPairAct, SIGNAL(triggered()), this,
+ SLOT(slotGenerateKeyDialog()));
+
+ generateSubKeyAct = new QAction(_("New Subkey"), this);
+ generateSubKeyAct->setShortcut(QKeySequence(_("Ctrl+Shift+N")));
+ generateSubKeyAct->setIcon(QIcon(":key_generate.png"));
+ generateSubKeyAct->setToolTip(_("Generate Subkey For Selected KeyPair"));
+ connect(generateSubKeyAct, SIGNAL(triggered()), this,
+ SLOT(slotGenerateSubKey()));
+
+ importKeyFromFileAct = new QAction(_("File"), this);
+ importKeyFromFileAct->setIcon(QIcon(":import_key_from_file.png"));
+ importKeyFromFileAct->setToolTip(_("Import New Key From File"));
+ connect(importKeyFromFileAct, &QAction::triggered, this,
+ [&]() { CommonUtils::GetInstance()->slotImportKeyFromFile(this); });
+
+ importKeyFromClipboardAct = new QAction(_("Clipboard"), this);
+ importKeyFromClipboardAct->setIcon(QIcon(":import_key_from_clipboard.png"));
+ importKeyFromClipboardAct->setToolTip(_("Import New Key From Clipboard"));
+ connect(importKeyFromClipboardAct, &QAction::triggered, this, [&]() {
+ CommonUtils::GetInstance()->slotImportKeyFromClipboard(this);
+ });
+
+ importKeyFromKeyServerAct = new QAction(_("Keyserver"), this);
+ importKeyFromKeyServerAct->setIcon(QIcon(":import_key_from_server.png"));
+ importKeyFromKeyServerAct->setToolTip(_("Import New Key From Keyserver"));
+ connect(importKeyFromKeyServerAct, &QAction::triggered, this, [&]() {
+ CommonUtils::GetInstance()->slotImportKeyFromKeyServer(this);
+ });
+
+ exportKeyToClipboardAct = new QAction(_("Export To Clipboard"), this);
+ exportKeyToClipboardAct->setIcon(QIcon(":export_key_to_clipboard.png"));
+ exportKeyToClipboardAct->setToolTip(_("Export Selected Key(s) To Clipboard"));
+ connect(exportKeyToClipboardAct, SIGNAL(triggered()), this,
+ SLOT(slotExportKeyToClipboard()));
+
+ exportKeyToFileAct = new QAction(_("Export To File"), this);
+ exportKeyToFileAct->setIcon(QIcon(":export_key_to_file.png"));
+ exportKeyToFileAct->setToolTip(_("Export Selected Key(s) To File"));
+ connect(exportKeyToFileAct, SIGNAL(triggered()), this,
+ SLOT(slotExportKeyToFile()));
+
+ deleteSelectedKeysAct = new QAction(_("Delete Selected Key(s)"), this);
+ deleteSelectedKeysAct->setToolTip(_("Delete the Selected keys"));
+ connect(deleteSelectedKeysAct, SIGNAL(triggered()), this,
+ SLOT(slotDeleteSelectedKeys()));
+
+ deleteCheckedKeysAct = new QAction(_("Delete Checked Key(s)"), this);
+ deleteCheckedKeysAct->setToolTip(_("Delete the Checked keys"));
+ deleteCheckedKeysAct->setIcon(QIcon(":button_delete.png"));
+ connect(deleteCheckedKeysAct, SIGNAL(triggered()), this,
+ SLOT(slotDeleteCheckedKeys()));
+
+ showKeyDetailsAct = new QAction(_("Show Key Details"), this);
+ showKeyDetailsAct->setToolTip(_("Show Details for this Key"));
+ connect(showKeyDetailsAct, SIGNAL(triggered()), this,
+ SLOT(slotShowKeyDetails()));
}
void KeyMgmt::createMenus() {
- fileMenu = menuBar()->addMenu(tr("&File"));
- fileMenu->addAction(openKeyFileAct);
- fileMenu->addAction(closeAct);
-
- keyMenu = menuBar()->addMenu(tr("&Key"));
- generateKeyMenu = keyMenu->addMenu(tr("&Generate Key"));
- generateKeyMenu->addAction(generateKeyPairAct);
- generateKeyMenu->addAction(generateSubKeyAct);
-
- importKeyMenu = keyMenu->addMenu(tr("&Import Key"));
- importKeyMenu->addAction(importKeyFromFileAct);
- importKeyMenu->addAction(importKeyFromClipboardAct);
- importKeyMenu->addAction(importKeyFromKeyServerAct);
- keyMenu->addAction(exportKeyToFileAct);
- keyMenu->addAction(exportKeyToClipboardAct);
- keyMenu->addSeparator();
- keyMenu->addAction(deleteCheckedKeysAct);
+ fileMenu = menuBar()->addMenu(_("File"));
+ fileMenu->addAction(openKeyFileAct);
+ fileMenu->addAction(closeAct);
+
+ keyMenu = menuBar()->addMenu(_("Key"));
+ generateKeyMenu = keyMenu->addMenu(_("Generate Key"));
+ generateKeyMenu->addAction(generateKeyPairAct);
+ generateKeyMenu->addAction(generateSubKeyAct);
+
+ importKeyMenu = keyMenu->addMenu(_("Import Key"));
+ importKeyMenu->addAction(importKeyFromFileAct);
+ importKeyMenu->addAction(importKeyFromClipboardAct);
+ importKeyMenu->addAction(importKeyFromKeyServerAct);
+ keyMenu->addAction(exportKeyToFileAct);
+ keyMenu->addAction(exportKeyToClipboardAct);
+ keyMenu->addSeparator();
+ keyMenu->addAction(deleteCheckedKeysAct);
}
void KeyMgmt::createToolBars() {
- QToolBar *keyToolBar = addToolBar(tr("Key"));
- keyToolBar->setObjectName("keytoolbar");
-
- // add button with popup menu for import
- auto *generateToolButton = new QToolButton(this);
- generateToolButton->setMenu(generateKeyMenu);
- generateToolButton->setPopupMode(QToolButton::InstantPopup);
- generateToolButton->setIcon(QIcon(":key_generate.png"));
- generateToolButton->setText(tr("Generate"));
- generateToolButton->setToolTip(tr("Generate A New Keypair or Subkey"));
- generateToolButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
- keyToolBar->addWidget(generateToolButton);
-
- // add button with popup menu for import
- auto *toolButton = new QToolButton(this);
- toolButton->setMenu(importKeyMenu);
- toolButton->setPopupMode(QToolButton::InstantPopup);
- toolButton->setIcon(QIcon(":key_import.png"));
- toolButton->setToolTip(tr("Import key"));
- toolButton->setText(tr("Import Key"));
- toolButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
- keyToolBar->addWidget(toolButton);
-
- keyToolBar->addSeparator();
- keyToolBar->addAction(deleteCheckedKeysAct);
- keyToolBar->addSeparator();
- keyToolBar->addAction(exportKeyToFileAct);
- keyToolBar->addAction(exportKeyToClipboardAct);
-
-}
-
-void KeyMgmt::slotImportKeys(QByteArray inBuffer) {
- GpgImportInformation result = mCtx->importKey(std::move(inBuffer));
- new KeyImportDetailDialog(mCtx, result, false, this);
-
-}
-
-void KeyMgmt::slotImportKeyFromFile() {
- QString fileName = QFileDialog::getOpenFileName(this, tr("Open Key"), "",
- tr("Key Files") + " (*.asc *.txt);;" + tr("Keyring files") +
- " (*.gpg);;All Files (*)");
- if (!fileName.isNull()) {
- QFile file;
- file.setFileName(fileName);
- if (!file.open(QIODevice::ReadOnly)) {
- qDebug() << tr("Couldn't Open File: ") + fileName;
- return;
- }
- QByteArray inBuffer = file.readAll();
- slotImportKeys(inBuffer);
- file.close();
- }
-}
-
-void KeyMgmt::slotImportKeyFromKeyServer() {
- importDialog = new KeyServerImportDialog(mCtx, mKeyList, false, this);
- importDialog->show();
-}
-
-void KeyMgmt::slotImportKeyFromClipboard() {
- QClipboard *cb = QApplication::clipboard();
- slotImportKeys(cb->text(QClipboard::Clipboard).toUtf8());
+ QToolBar* keyToolBar = addToolBar(_("Key"));
+ keyToolBar->setObjectName("keytoolbar");
+
+ // add button with popup menu for import
+ auto* generateToolButton = new QToolButton(this);
+ generateToolButton->setMenu(generateKeyMenu);
+ generateToolButton->setPopupMode(QToolButton::InstantPopup);
+ generateToolButton->setIcon(QIcon(":key_generate.png"));
+ generateToolButton->setText(_("Generate"));
+ generateToolButton->setToolTip(_("Generate A New Keypair or Subkey"));
+ generateToolButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
+ keyToolBar->addWidget(generateToolButton);
+
+ // add button with popup menu for import
+ auto* toolButton = new QToolButton(this);
+ toolButton->setMenu(importKeyMenu);
+ toolButton->setPopupMode(QToolButton::InstantPopup);
+ toolButton->setIcon(QIcon(":key_import.png"));
+ toolButton->setToolTip(_("Import key"));
+ toolButton->setText(_("Import Key"));
+ toolButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
+ keyToolBar->addWidget(toolButton);
+
+ keyToolBar->addSeparator();
+ keyToolBar->addAction(deleteCheckedKeysAct);
+ keyToolBar->addSeparator();
+ keyToolBar->addAction(exportKeyToFileAct);
+ keyToolBar->addAction(exportKeyToClipboardAct);
}
void KeyMgmt::slotDeleteSelectedKeys() {
- deleteKeysWithWarning(mKeyList->getSelected());
+ deleteKeysWithWarning(mKeyList->getSelected());
}
void KeyMgmt::slotDeleteCheckedKeys() {
- deleteKeysWithWarning(mKeyList->getChecked());
+ deleteKeysWithWarning(mKeyList->getChecked());
}
-void KeyMgmt::deleteKeysWithWarning(QStringList *uidList) {
- /**
- * TODO: Different Messages for private/public key, check if
- * more than one selected... compare to seahorse "delete-dialog"
- */
-
- if (uidList->isEmpty()) {
- return;
- }
- QString keynames;
- for (const auto &uid : *uidList) {
- auto key = mCtx->getKeyById(uid);
- if (!key.good) continue;
- keynames.append(key.name);
- keynames.append("<i> &lt;");
- keynames.append(key.email);
- keynames.append("&gt; </i><br/>");
- }
-
- int ret = QMessageBox::warning(this, tr("Deleting Keys"),
- "<b>" + tr("Are you sure that you want to delete the following keys?") +
- "</b><br/><br/>" + keynames +
- +"<br/>" + tr("The action can not be undone."),
- QMessageBox::No | QMessageBox::Yes);
-
- if (ret == QMessageBox::Yes) {
- mCtx->deleteKeys(uidList);
- }
+void KeyMgmt::deleteKeysWithWarning(KeyIdArgsListPtr key_ids) {
+ /**
+ * TODO: Different Messages for private/public key, check if
+ * more than one selected... compare to seahorse "delete-dialog"
+ */
+
+ LOG(INFO) << "KeyMgmt::deleteKeysWithWarning Called";
+
+ if (key_ids->empty()) return;
+ QString keynames;
+ for (const auto& key_id : *key_ids) {
+ auto key = GpgKeyGetter::GetInstance().GetKey(key_id);
+ if (!key.good()) continue;
+ keynames.append(QString::fromStdString(key.name()));
+ keynames.append("<i> &lt;");
+ keynames.append(QString::fromStdString(key.email()));
+ keynames.append("&gt; </i><br/>");
+ }
+
+ int ret = QMessageBox::warning(
+ this, _("Deleting Keys"),
+ "<b>" +
+ QString(
+ _("Are you sure that you want to delete the following keys?")) +
+ "</b><br/><br/>" + keynames + +"<br/>" +
+ _("The action can not be undone."),
+ QMessageBox::No | QMessageBox::Yes);
+
+ if (ret == QMessageBox::Yes) {
+ GpgKeyOpera::GetInstance().DeleteKeys(std::move(key_ids));
+ emit signalKeyStatusUpdated();
+ }
}
void KeyMgmt::slotShowKeyDetails() {
- if (mKeyList->getSelected()->isEmpty()) {
- return;
- }
+ auto keys_selected = mKeyList->getSelected();
+ if (keys_selected->empty()) return;
- auto key = mCtx->getKeyById(mKeyList->getSelected()->first());
+ auto key = GpgKeyGetter::GetInstance().GetKey(keys_selected->front());
- if (!key.good) {
- QMessageBox::critical(nullptr, tr("Error"), tr("Key Not Found."));
- return;
- }
+ if (!key.good()) {
+ QMessageBox::critical(nullptr, _("Error"), _("Key Not Found."));
+ return;
+ }
- new KeyDetailsDialog(mCtx, key);
+ new KeyDetailsDialog(key);
}
void KeyMgmt::slotExportKeyToFile() {
- auto *keyArray = new QByteArray();
- if (!mCtx->exportKeys(mKeyList->getChecked(), keyArray)) {
- delete keyArray;
- return;
- }
- auto key = mCtx->getKeyById(mKeyList->getSelected()->first());
- if (!key.good) {
- QMessageBox::critical(nullptr, tr("Error"), tr("Key Not Found."));
- return;
- }
- QString fileString = key.name + " " + key.email + "(" + key.id + ")_pub.asc";
-
- QString fileName = QFileDialog::getSaveFileName(this, tr("Export Key To File"), fileString,
- tr("Key Files") + " (*.asc *.txt);;All Files (*)");
- QFile file(fileName);
- if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
- delete keyArray;
- return;
- }
- QTextStream stream(&file);
- stream << *keyArray;
- file.close();
- delete keyArray;
- emit signalStatusBarChanged(QString(tr("key(s) exported")));
+ ByteArrayPtr key_export_data = nullptr;
+ auto keys_checked = mKeyList->getChecked();
+ if (!GpgKeyImportExportor::GetInstance().ExportKeys(keys_checked,
+ key_export_data)) {
+ return;
+ }
+ auto key =
+ GpgKeyGetter::GetInstance().GetKey(mKeyList->getSelected()->front());
+ if (!key.good()) {
+ QMessageBox::critical(nullptr, _("Error"), _("Key Not Found."));
+ return;
+ }
+ QString fileString = QString::fromStdString(key.name() + " " + key.email() +
+ "(" + key.id() + ")_pub.asc");
+
+ QString file_name = QFileDialog::getSaveFileName(
+ this, _("Export Key To File"), fileString,
+ QString(_("Key Files")) + " (*.asc *.txt);;All Files (*)");
+
+ write_buffer_to_file(file_name.toStdString(), *key_export_data);
+
+ emit signalStatusBarChanged(QString(_("key(s) exported")));
}
void KeyMgmt::slotExportKeyToClipboard() {
- auto *keyArray = new QByteArray();
- QClipboard *cb = QApplication::clipboard();
- if (!mCtx->exportKeys(mKeyList->getChecked(), keyArray)) {
- return;
- }
- cb->setText(*keyArray);
- delete keyArray;
+ ByteArrayPtr key_export_data = nullptr;
+ auto keys_checked = mKeyList->getChecked();
+ if (!GpgKeyImportExportor::GetInstance().ExportKeys(keys_checked,
+ key_export_data)) {
+ return;
+ }
+ QApplication::clipboard()->setText(QString::fromStdString(*key_export_data));
}
void KeyMgmt::slotGenerateKeyDialog() {
- auto *keyGenDialog = new KeyGenDialog(mCtx, this);
- keyGenDialog->show();
+ auto* keyGenDialog = new KeyGenDialog(this);
+ keyGenDialog->show();
}
-void KeyMgmt::closeEvent(QCloseEvent *event) {
- QMainWindow::closeEvent(event);
+void KeyMgmt::closeEvent(QCloseEvent* event) {
+ slotSaveWindowState();
+ QMainWindow::closeEvent(event);
}
void KeyMgmt::slotGenerateSubKey() {
- auto selectedList = mKeyList->getSelected();
- if (selectedList->empty()) {
- QMessageBox::information(nullptr,
- tr("Invalid Operation"),
- tr("Please select one KeyPair before doing this operation."));
- return;
- }
- const auto key = mCtx->getKeyById(selectedList->first());
- if (!key.good) {
- QMessageBox::critical(nullptr, tr("Error"), tr("Key Not Found."));
- return;
- }
- if (!key.is_private_key) {
- QMessageBox::critical(nullptr,
- tr("Invalid Operation"),
- tr("If a key pair does not have a private key then it will not be able to generate sub-keys."));
- return;
- }
-
- auto dialog = new SubkeyGenerateDialog(mCtx, key, this);
- dialog->show();
+ auto keys_selected = mKeyList->getSelected();
+ if (keys_selected->empty()) {
+ QMessageBox::information(
+ nullptr, _("Invalid Operation"),
+ _("Please select one KeyPair before doing this operation."));
+ return;
+ }
+ const auto key = GpgKeyGetter::GetInstance().GetKey(keys_selected->front());
+ if (!key.good()) {
+ QMessageBox::critical(nullptr, _("Error"), _("Key Not Found."));
+ return;
+ }
+ if (!key.is_private_key()) {
+ QMessageBox::critical(nullptr, _("Invalid Operation"),
+ _("If a key pair does not have a private key then "
+ "it will not be able to generate sub-keys."));
+ return;
+ }
+
+ auto dialog = new SubkeyGenerateDialog(key.id(), this);
+ dialog->show();
+}
+void KeyMgmt::slotSaveWindowState() {
+ auto& settings =
+ GpgFrontend::UI::GlobalSettingStation::GetInstance().GetUISettings();
+
+ if (!settings.exists("window") ||
+ settings.lookup("window").getType() != libconfig::Setting::TypeGroup)
+ settings.add("window", libconfig::Setting::TypeGroup);
+
+ auto& window = settings["window"];
+
+ if (!window.exists("key_management") ||
+ window.lookup("key_management").getType() !=
+ libconfig::Setting::TypeGroup)
+ window.add("key_management", libconfig::Setting::TypeGroup);
+
+ auto& key_management = window["key_management"];
+
+ if (!key_management.exists("position") ||
+ key_management.lookup("position").getType() !=
+ libconfig::Setting::TypeGroup) {
+ auto& position =
+ key_management.add("position", libconfig::Setting::TypeGroup);
+ position.add("x", libconfig::Setting::TypeInt) = pos().x();
+ position.add("y", libconfig::Setting::TypeInt) = pos().y();
+ } else {
+ key_management["position"]["x"] = pos().x();
+ key_management["position"]["y"] = pos().y();
+ }
+
+ if (!key_management.exists("size") ||
+ key_management.lookup("size").getType() !=
+ libconfig::Setting::TypeGroup) {
+ auto& size = key_management.add("size", libconfig::Setting::TypeGroup);
+ size.add("width", libconfig::Setting::TypeInt) = QWidget::width();
+ size.add("height", libconfig::Setting::TypeInt) = QWidget::height();
+ } else {
+ key_management["size"]["width"] = QWidget::width();
+ key_management["size"]["height"] = QWidget::height();
+ }
+
+ if (!key_management.exists("window_state"))
+ key_management.add("window_state", libconfig::Setting::TypeString) =
+ saveState().toBase64().toStdString();
+
+ GlobalSettingStation::GetInstance().Sync();
}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/KeyMgmt.h b/src/ui/KeyMgmt.h
new file mode 100755
index 00000000..bf1c9b5a
--- /dev/null
+++ b/src/ui/KeyMgmt.h
@@ -0,0 +1,102 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef __KEYMGMT_H__
+#define __KEYMGMT_H__
+
+#include "KeyImportDetailDialog.h"
+#include "KeyServerImportDialog.h"
+#include "ui/GpgFrontendUI.h"
+#include "ui/keygen/KeygenDialog.h"
+#include "ui/keypair_details/KeyDetailsDialog.h"
+#include "ui/widgets/KeyList.h"
+
+namespace GpgFrontend::UI {
+
+class KeyMgmt : public QMainWindow {
+ Q_OBJECT
+
+ public:
+ explicit KeyMgmt(QWidget* parent = nullptr);
+
+ public slots:
+
+ void slotGenerateSubKey();
+
+ void slotExportKeyToFile();
+
+ void slotExportKeyToClipboard();
+
+ void slotDeleteSelectedKeys();
+
+ void slotDeleteCheckedKeys();
+
+ void slotGenerateKeyDialog();
+
+ void slotShowKeyDetails();
+
+ void slotSaveWindowState();
+
+ signals:
+
+ void signalStatusBarChanged(QString);
+
+ void signalKeyStatusUpdated();
+
+ private:
+ void createMenus();
+
+ void createActions();
+
+ void createToolBars();
+
+ void deleteKeysWithWarning(GpgFrontend::KeyIdArgsListPtr uidList);
+
+ KeyList* mKeyList;
+ QMenu* fileMenu{};
+ QMenu* keyMenu{};
+ QMenu* generateKeyMenu{};
+ QMenu* importKeyMenu{};
+ QAction* openKeyFileAct{};
+ QAction* exportKeyToFileAct{};
+ QAction* exportKeyToClipboardAct{};
+ QAction* deleteCheckedKeysAct{};
+ QAction* deleteSelectedKeysAct{};
+ QAction* generateKeyDialogAct{};
+ QAction* generateKeyPairAct{};
+ QAction* generateSubKeyAct{};
+ QAction* importKeyFromClipboardAct{};
+ QAction* importKeyFromFileAct{};
+ QAction* importKeyFromKeyServerAct{};
+ QAction* closeAct{};
+ QAction* showKeyDetailsAct{};
+ KeyServerImportDialog* importDialog{};
+
+ protected:
+ void closeEvent(QCloseEvent* event) override;
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // __KEYMGMT_H__
diff --git a/src/ui/KeyServerImportDialog.cpp b/src/ui/KeyServerImportDialog.cpp
index a1355120..17db7d65 100644
--- a/src/ui/KeyServerImportDialog.cpp
+++ b/src/ui/KeyServerImportDialog.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -26,27 +26,32 @@
#include <utility>
-KeyServerImportDialog::KeyServerImportDialog(GpgME::GpgContext *ctx, KeyList *keyList, bool automatic,
- QWidget *parent)
- : QDialog(parent), appPath(qApp->applicationDirPath()),
- settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", QSettings::IniFormat),
- mCtx(ctx), mKeyList(keyList), mAutomatic(automatic) {
+#include "gpg/function/GpgKeyImportExportor.h"
+#include "ui/SignalStation.h"
+#include "ui/settings/GlobalSettingStation.h"
- if(automatic) {
- setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint);
- }
+namespace GpgFrontend::UI {
+
+KeyServerImportDialog::KeyServerImportDialog(bool automatic, QWidget* parent)
+ : QDialog(parent), mAutomatic(automatic) {
+ // Layout for messagebox
+ auto* messageLayout = new QHBoxLayout;
+ if (automatic) {
+ setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint);
+ } else {
// Buttons
- closeButton = createButton(tr("&Close"), SLOT(close()));
- importButton = createButton(tr("&Import ALL"), SLOT(slotImport()));
- searchButton = createButton(tr("&Search"), SLOT(slotSearch()));
+ closeButton = createButton(_("Close"), SLOT(close()));
+ importButton = createButton(_("Import ALL"), SLOT(slotImport()));
+ importButton->setDisabled(true);
+ searchButton = createButton(_("Search"), SLOT(slotSearch()));
// Line edit for search string
- searchLabel = new QLabel(tr("Search String:"));
+ searchLabel = new QLabel(QString(_("Search String")) + _(": "));
searchLineEdit = new QLineEdit();
// combobox for keyserverlist
- keyServerLabel = new QLabel(tr("Key Server:"));
+ keyServerLabel = new QLabel(QString(_("Key Server")) + _(": "));
keyServerComboBox = createComboBox();
// table containing the keys found
@@ -56,421 +61,549 @@ KeyServerImportDialog::KeyServerImportDialog(GpgME::GpgContext *ctx, KeyList *ke
icon = new QLabel;
icon->setFixedHeight(24);
- // Network Waiting
- waitingBar = new QProgressBar();
- waitingBar->setVisible(false);
- waitingBar->setRange(0, 0);
- waitingBar->setFixedWidth(200);
-
- // Layout for messagebox
- auto *messageLayout = new QHBoxLayout;
messageLayout->addWidget(icon);
messageLayout->addWidget(message);
- messageLayout->addWidget(waitingBar);
messageLayout->addStretch();
+ }
+
+ // Network Waiting
+ waitingBar = new QProgressBar();
+ waitingBar->setVisible(false);
+ waitingBar->setRange(0, 0);
+ waitingBar->setFixedWidth(200);
+ messageLayout->addWidget(waitingBar);
+
+ auto* mainLayout = new QGridLayout;
+
+ // 自动化调用界面布局
+ if (automatic) {
+ mainLayout->addLayout(messageLayout, 0, 0, 1, 3);
+ } else {
+ mainLayout->addWidget(searchLabel, 1, 0);
+ mainLayout->addWidget(searchLineEdit, 1, 1);
+ mainLayout->addWidget(searchButton, 1, 2);
+ mainLayout->addWidget(keyServerLabel, 2, 0);
+ mainLayout->addWidget(keyServerComboBox, 2, 1);
+ mainLayout->addWidget(keysTable, 3, 0, 1, 3);
+ mainLayout->addLayout(messageLayout, 4, 0, 1, 3);
// Layout for import and close button
- auto *buttonsLayout = new QHBoxLayout;
+ auto* buttonsLayout = new QHBoxLayout;
buttonsLayout->addStretch();
- if(!automatic)
- buttonsLayout->addWidget(importButton);
+ buttonsLayout->addWidget(importButton);
buttonsLayout->addWidget(closeButton);
-
- auto *mainLayout = new QGridLayout;
-
- // 自动化调用界面布局
- if(automatic) {
- mainLayout->addLayout(messageLayout, 0, 0, 1, 3);
- } else {
- mainLayout->addWidget(searchLabel, 1, 0);
- mainLayout->addWidget(searchLineEdit, 1, 1);
- mainLayout->addWidget(searchButton, 1, 2);
- mainLayout->addWidget(keyServerLabel, 2, 0);
- mainLayout->addWidget(keyServerComboBox, 2, 1);
- mainLayout->addWidget(keysTable, 3, 0, 1, 3);
- mainLayout->addLayout(messageLayout, 4, 0, 1, 3);
- mainLayout->addLayout(buttonsLayout, 6, 0, 1, 3);
+ mainLayout->addLayout(buttonsLayout, 6, 0, 1, 3);
+ }
+
+ this->setLayout(mainLayout);
+ if (automatic)
+ this->setWindowTitle(_("Update Keys from Keyserver"));
+ else
+ this->setWindowTitle(_("Import Keys from Keyserver"));
+
+ if (automatic) {
+ this->setFixedSize(240, 42);
+ } else {
+ auto pos = QPoint(150, 150);
+ LOG(INFO) << "parent" << parent;
+ if (parent) pos += parent->pos();
+ LOG(INFO) << "pos default" << pos.x() << pos.y();
+ auto size = QSize(800, 500);
+
+ try {
+ auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
+
+ int x, y, width, height;
+ x = settings.lookup("window.import_from_keyserver.position.x");
+ y = settings.lookup("window.import_from_keyserver.position.y");
+ width = settings.lookup("window.import_from_keyserver.size.width");
+ height = settings.lookup("window.import_from_keyserver.size.height");
+ pos = QPoint(x, y);
+ size = QSize(width, height);
+
+ } catch (...) {
+ LOG(WARNING) << "cannot read pos or size from settings";
}
- this->setLayout(mainLayout);
- if(automatic)
- this->setWindowTitle(tr("Update Keys from Keyserver"));
- else
- this->setWindowTitle(tr("Import Keys from Keyserver"));
+ this->resize(size);
+ this->move(pos);
+ }
- if(automatic) {
- this->setFixedSize(240, 42);
- } else {
- // Restore window size & location
- if (this->settings.value("ImportKeyFromServer/setWindowSize").toBool()) {
- QPoint pos = settings.value("ImportKeyFromServer/pos", QPoint(150, 150)).toPoint();
- QSize size = settings.value("ImportKeyFromServer/size", QSize(500, 300)).toSize();
- qDebug() << "Settings size" << size << "pos" << pos;
- this->setMinimumSize(size);
- this->move(pos);
- } else {
- qDebug() << "Use default min windows size and pos";
- QPoint defaultPoint(150, 150);
- QSize defaultMinSize(500, 300);
- this->setMinimumSize(defaultMinSize);
- this->move(defaultPoint);
- this->settings.setValue("ImportKeyFromServer/pos", defaultPoint);
- this->settings.setValue("ImportKeyFromServer/size", defaultMinSize);
- this->settings.setValue("ImportKeyFromServer/setWindowSize", true);
- }
- }
+ this->setModal(true);
- this->setModal(true);
-}
+ connect(this, SIGNAL(signalKeyImported()), SignalStation::GetInstance(),
+ SIGNAL(KeyDatabaseRefresh()));
-QPushButton *KeyServerImportDialog::createButton(const QString &text, const char *member) {
- auto *button = new QPushButton(text);
- connect(button, SIGNAL(clicked()), this, member);
- return button;
+ // save window pos and size to configure file
+ connect(this, SIGNAL(finished(int)), this, SLOT(slotSaveWindowState()));
}
-QComboBox *KeyServerImportDialog::createComboBox() {
- auto *comboBox = new QComboBox;
- comboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+QPushButton* KeyServerImportDialog::createButton(const QString& text,
+ const char* member) {
+ auto* button = new QPushButton(text);
+ connect(button, SIGNAL(clicked()), this, member);
+ return button;
+}
- // Read keylist from ini-file and fill it into combobox
- comboBox->addItems(settings.value("keyserver/keyServerList").toStringList());
+QComboBox* KeyServerImportDialog::createComboBox() {
+ auto* comboBox = new QComboBox;
+ comboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
- // set default keyserver in combobox
- QString keyserver = settings.value("keyserver/defaultKeyServer").toString();
- comboBox->setCurrentIndex(comboBox->findText(keyserver));
+ auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
- return comboBox;
+ try {
+ auto& server_list = settings.lookup("keyserver.server_list");
+ const auto server_list_size = server_list.getLength();
+ for (int i = 0; i < server_list_size; i++) {
+ std::string server_url = server_list[i];
+ comboBox->addItem(server_url.c_str());
+ }
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("server_list");
+ }
+
+ // set default keyserver in combobox
+ try {
+ std::string default_server = settings.lookup("keyserver.default_server");
+ comboBox->setCurrentText(default_server.c_str());
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("default_server");
+ }
+
+ return comboBox;
}
void KeyServerImportDialog::createKeysTable() {
- keysTable = new QTableWidget();
- keysTable->setColumnCount(4);
+ keysTable = new QTableWidget();
+ keysTable->setColumnCount(4);
- // always a whole row is marked
- keysTable->setSelectionBehavior(QAbstractItemView::SelectRows);
- keysTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ // always a whole row is marked
+ keysTable->setSelectionBehavior(QAbstractItemView::SelectRows);
+ keysTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
- // Make just one row selectable
- keysTable->setSelectionMode(QAbstractItemView::SingleSelection);
+ // Make just one row selectable
+ keysTable->setSelectionMode(QAbstractItemView::SingleSelection);
- QStringList labels;
- labels << tr("UID") << tr("Creation date") << tr("KeyID") << tr("Tag");
- keysTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
- keysTable->setHorizontalHeaderLabels(labels);
- keysTable->verticalHeader()->hide();
+ QStringList labels;
+ labels << _("UID") << _("Creation date") << _("KeyID") << _("Tag");
+ keysTable->horizontalHeader()->setSectionResizeMode(
+ 0, QHeaderView::ResizeToContents);
+ keysTable->setHorizontalHeaderLabels(labels);
+ keysTable->verticalHeader()->hide();
- connect(keysTable, SIGNAL(cellActivated(int, int)),
- this, SLOT(slotImport()));
+ connect(keysTable, SIGNAL(cellActivated(int, int)), this, SLOT(slotImport()));
}
-void KeyServerImportDialog::setMessage(const QString &text, bool error) {
- message->setText(text);
- if (error) {
- icon->setPixmap(QPixmap(":error.png").scaled(QSize(24, 24), Qt::KeepAspectRatio));
- } else {
- icon->setPixmap(QPixmap(":info.png").scaled(QSize(24, 24), Qt::KeepAspectRatio));
- }
+void KeyServerImportDialog::setMessage(const QString& text, bool error) {
+ if (mAutomatic) return;
+
+ message->setText(text);
+ if (error) {
+ icon->setPixmap(
+ QPixmap(":error.png").scaled(QSize(24, 24), Qt::KeepAspectRatio));
+ } else {
+ icon->setPixmap(
+ QPixmap(":info.png").scaled(QSize(24, 24), Qt::KeepAspectRatio));
+ }
}
void KeyServerImportDialog::slotSearch() {
+ if (searchLineEdit->text().isEmpty()) {
+ setMessage("<h4>" + QString(_("Text is empty.")) + "</h4>", false);
+ return;
+ }
- if (searchLineEdit->text().isEmpty()) {
- setMessage("<h4>" + tr("Text is empty.") + "</h4>", false);
- return;
- }
-
- QUrl urlFromRemote = keyServerComboBox->currentText() + "/pks/lookup?search=" + searchLineEdit->text() +
+ QUrl url_from_remote = keyServerComboBox->currentText() +
+ "/pks/lookup?search=" + searchLineEdit->text() +
"&op=index&options=mr";
- qnam = new QNetworkAccessManager(this);
- QNetworkReply *reply = qnam->get(QNetworkRequest(urlFromRemote));
-
- connect(reply, SIGNAL(finished()),
- this, SLOT(slotSearchFinished()));
-
- setLoading(true);
-
- while (reply->isRunning()) {
- QApplication::processEvents();
- }
-
- setLoading(false);
-
+ qnam = new QNetworkAccessManager(this);
+ QNetworkReply* reply = qnam->get(QNetworkRequest(url_from_remote));
+
+ connect(reply, SIGNAL(finished()), this, SLOT(slotSearchFinished()));
+
+ setLoading(true);
+ this->searchButton->setDisabled(true);
+ this->keyServerComboBox->setDisabled(true);
+ this->searchLineEdit->setReadOnly(true);
+ this->importButton->setDisabled(true);
+
+ while (reply->isRunning()) {
+ QApplication::processEvents();
+ }
+
+ this->searchButton->setDisabled(false);
+ this->keyServerComboBox->setDisabled(false);
+ this->searchLineEdit->setReadOnly(false);
+ this->importButton->setDisabled(false);
+ setLoading(false);
}
void KeyServerImportDialog::slotSearchFinished() {
- auto *reply = qobject_cast<QNetworkReply *>(sender());
-
- keysTable->clearContents();
- keysTable->setRowCount(0);
- QString firstLine = QString(reply->readLine(1024));
-
- auto error = reply->error();
- if (error != QNetworkReply::NoError) {
- qDebug() << "Error From Reply" << reply->errorString();
- switch (error) {
- case QNetworkReply::ContentNotFoundError :
- setMessage(tr("Not Key Found"), true);
- break;
- case QNetworkReply::TimeoutError :
- setMessage(tr("Timeout"), true);
- break;
- case QNetworkReply::HostNotFoundError :
- setMessage(tr("Key Server Not Found"), true);
- break;
- default:
- setMessage(tr("Connection Error"), true);
- }
+ LOG(INFO) << "KeyServerImportDialog::slotSearchFinished Called";
+
+ auto* reply = qobject_cast<QNetworkReply*>(sender());
+
+ keysTable->clearContents();
+ keysTable->setRowCount(0);
+ QString first_line = QString(reply->readLine(1024));
+
+ auto error = reply->error();
+ if (error != QNetworkReply::NoError) {
+ qDebug() << "Error From Reply" << reply->errorString();
+ switch (error) {
+ case QNetworkReply::ContentNotFoundError:
+ setMessage(_("Not Key Found"), true);
+ break;
+ case QNetworkReply::TimeoutError:
+ setMessage(_("Timeout"), true);
+ break;
+ case QNetworkReply::HostNotFoundError:
+ setMessage(_("Key Server Not Found"), true);
+ break;
+ default:
+ setMessage(_("Connection Error"), true);
+ }
+ return;
+ }
+
+ if (first_line.contains("Error")) {
+ QString text = QString(reply->readLine(1024));
+ if (text.contains("Too many responses")) {
+ setMessage(
+ "<h4>" + QString(_("Too many responses from keyserver!")) + "</h4>",
+ true);
+ return;
+ } else if (text.contains("No keys found")) {
+ // if string looks like hex string, search again with 0x prepended
+ QRegExp rx("[0-9A-Fa-f]*");
+ QString query = searchLineEdit->text();
+ if (rx.exactMatch(query)) {
+ setMessage(
+ "<h4>" +
+ QString(_("No keys found, input may be kexId, retrying search "
+ "with 0x.")) +
+ "</h4>",
+ true);
+ searchLineEdit->setText(query.prepend("0x"));
+ this->slotSearch();
return;
+ } else {
+ setMessage(
+ "<h4>" + QString(_("No keys found containing the search string!")) +
+ "</h4>",
+ true);
+ return;
+ }
+ } else if (text.contains("Insufficiently specific words")) {
+ setMessage("<h4>" + QString(_("Insufficiently specific search string!")) +
+ "</h4>",
+ true);
+ return;
+ } else {
+ setMessage(text, true);
+ return;
}
+ } else {
+ int row = 0;
+ bool strikeout = false;
+ while (reply->canReadLine()) {
+ auto line_buff = reply->readLine().trimmed();
+ QString decoded =
+ QString::fromUtf8(line_buff.constData(), line_buff.size());
+ QStringList line = decoded.split(":");
+ // TODO: have a look at two following pub lines
+ if (line[0] == "pub") {
+ strikeout = false;
+
+ QString flags = line[line.size() - 1];
+ keysTable->setRowCount(row + 1);
+
+ // flags can be "d" for disabled, "r" for revoked
+ // or "e" for expired
+ if (flags.contains("r") or flags.contains("d") or flags.contains("e")) {
+ strikeout = true;
+ if (flags.contains("e")) {
+ keysTable->setItem(row, 3,
+ new QTableWidgetItem(QString("expired")));
+ }
+ if (flags.contains("r")) {
+ keysTable->setItem(row, 3,
+ new QTableWidgetItem(QString(_("revoked"))));
+ }
+ if (flags.contains("d")) {
+ keysTable->setItem(row, 3,
+ new QTableWidgetItem(QString(_("disabled"))));
+ }
+ }
+
+ QStringList line2 = QString(reply->readLine()).split(":");
- if (firstLine.contains("Error")) {
- QString text = QString(reply->readLine(1024));
- if (text.contains("Too many responses")) {
- setMessage("<h4>" +tr("Too many responses from keyserver!") + "</h4>", true);
- return;
- } else if (text.contains("No keys found")) {
- // if string looks like hex string, search again with 0x prepended
- QRegExp rx("[0-9A-Fa-f]*");
- QString query = searchLineEdit->text();
- if (rx.exactMatch(query)) {
- setMessage("<h4>" + tr("No keys found, input may be kexId, retrying search with 0x.") + "</h4>", true);
- searchLineEdit->setText(query.prepend("0x"));
- this->slotSearch();
- return;
- } else {
- setMessage("<h4>" +tr("No keys found containing the search string!") + "</h4>", true);
- return;
- }
- } else if (text.contains("Insufficiently specific words")) {
- setMessage("<h4>" + tr("Insufficiently specific search string!") + "</h4>", true);
- return;
- } else {
- setMessage(text, true);
- return;
+ auto* uid = new QTableWidgetItem();
+ if (line2.size() > 1) {
+ uid->setText(line2[1]);
+ keysTable->setItem(row, 0, uid);
}
- } else {
- int row = 0;
- bool strikeout = false;
- while (reply->canReadLine()) {
- auto line_buff = reply->readLine().trimmed();
- QString decoded = QString::fromUtf8(line_buff.constData(), line_buff.size());
- QStringList line = decoded.split(":");
- //TODO: have a look at two following pub lines
- if (line[0] == "pub") {
- strikeout = false;
-
- QString flags = line[line.size() - 1];
- keysTable->setRowCount(row + 1);
-
- // flags can be "d" for disabled, "r" for revoked
- // or "e" for expired
- if (flags.contains("r") or flags.contains("d") or flags.contains("e")) {
- strikeout = true;
- if (flags.contains("e")) {
- keysTable->setItem(row, 3, new QTableWidgetItem(QString("expired")));
- }
- if (flags.contains("r")) {
- keysTable->setItem(row, 3, new QTableWidgetItem(QString(tr("revoked"))));
- }
- if (flags.contains("d")) {
- keysTable->setItem(row, 3, new QTableWidgetItem(QString(tr("disabled"))));
- }
- }
-
- QStringList line2 = QString(reply->readLine()).split(":");
-
- auto *uid = new QTableWidgetItem();
- if (line2.size() > 1) {
- uid->setText(line2[1]);
- keysTable->setItem(row, 0, uid);
- }
- auto *creation_date = new QTableWidgetItem(
- QDateTime::fromTime_t(line[4].toInt()).toString("dd. MMM. yyyy"));
- keysTable->setItem(row, 1, creation_date);
- auto *keyid = new QTableWidgetItem(line[1]);
- keysTable->setItem(row, 2, keyid);
- if (strikeout) {
- QFont strike = uid->font();
- strike.setStrikeOut(true);
- uid->setFont(strike);
- creation_date->setFont(strike);
- keyid->setFont(strike);
- }
- row++;
- } else {
- if (line[0] == "uid") {
- QStringList l;
- int height = keysTable->rowHeight(row - 1);
- keysTable->setRowHeight(row - 1, height + 16);
- QString tmp = keysTable->item(row - 1, 0)->text();
- tmp.append(QString("\n") + line[1]);
- auto *tmp1 = new QTableWidgetItem(tmp);
- keysTable->setItem(row - 1, 0, tmp1);
- if (strikeout) {
- QFont strike = tmp1->font();
- strike.setStrikeOut(true);
- tmp1->setFont(strike);
- }
- }
- }
- setMessage(tr("<h4>%1 keys found. Double click a key to import it.</h4>").arg(row), false);
+ auto* creation_date = new QTableWidgetItem(
+ QDateTime::fromTime_t(line[4].toInt()).toString("dd. MMM. yyyy"));
+ keysTable->setItem(row, 1, creation_date);
+ auto* keyid = new QTableWidgetItem(line[1]);
+ keysTable->setItem(row, 2, keyid);
+ if (strikeout) {
+ QFont strike = uid->font();
+ strike.setStrikeOut(true);
+ uid->setFont(strike);
+ creation_date->setFont(strike);
+ keyid->setFont(strike);
+ }
+ row++;
+ } else {
+ if (line[0] == "uid") {
+ QStringList l;
+ int height = keysTable->rowHeight(row - 1);
+ keysTable->setRowHeight(row - 1, height + 16);
+ QString tmp = keysTable->item(row - 1, 0)->text();
+ tmp.append(QString("\n") + line[1]);
+ auto* tmp1 = new QTableWidgetItem(tmp);
+ keysTable->setItem(row - 1, 0, tmp1);
+ if (strikeout) {
+ QFont strike = tmp1->font();
+ strike.setStrikeOut(true);
+ tmp1->setFont(strike);
+ }
}
- keysTable->resizeColumnsToContents();
+ }
+ setMessage(
+ QString("<h4>") +
+ QString(_("%1 keys found. Double click a key to import it."))
+ .arg(row) +
+ "</h4>",
+ false);
}
- reply->deleteLater();
+ keysTable->resizeColumnsToContents();
+ importButton->setDisabled(keysTable->size().isEmpty());
+ }
+ reply->deleteLater();
}
void KeyServerImportDialog::slotImport() {
- if (keysTable->currentRow() > -1) {
- QString keyid = keysTable->item(keysTable->currentRow(), 2)->text();
- slotImport(QStringList(keyid), keyServerComboBox->currentText());
- }
-}
-
-void KeyServerImportDialog::slotImport(const QStringList& keyIds) {
- QString keyserver = settings.value("keyserver/defaultKeyServer").toString();
- qDebug() << "Select Key Server" << keyserver;
- slotImport(keyIds, QUrl(keyserver));
+ LOG(INFO) << _("Current Row") << keysTable->currentRow();
+ if (keysTable->currentRow() > -1) {
+ QString keyid = keysTable->item(keysTable->currentRow(), 2)->text();
+ slotImport(QStringList(keyid), keyServerComboBox->currentText());
+ }
}
-void KeyServerImportDialog::slotImportKey(const QVector<GpgKey>& keys) {
- QString keyserver = settings.value("keyserver/defaultKeyServer").toString();
- qDebug() << "Select Key Server" << keyserver;
- auto keyIds = QStringList();
- for(const auto &key : keys) {
- keyIds.append(key.id);
+void KeyServerImportDialog::slotImport(const KeyIdArgsListPtr& keys) {
+ std::string target_keyserver;
+ if (keyServerComboBox != nullptr) {
+ target_keyserver = keyServerComboBox->currentText().toStdString();
+ }
+ 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;
}
- slotImport(keyIds, QUrl(keyserver));
+ }
+ auto key_ids = QStringList();
+ for (const auto& key_id : *keys)
+ key_ids.append(QString::fromStdString(key_id));
+ slotImport(key_ids, QUrl(target_keyserver.c_str()));
}
+void KeyServerImportDialog::slotImport(const QStringList& keyIds,
+ const QUrl& keyServerUrl) {
+ for (const auto& keyId : keyIds) {
+ QUrl req_url(keyServerUrl.scheme() + "://" + keyServerUrl.host() +
+ "/pks/lookup?op=get&search=0x" + keyId + "&options=mr");
-void KeyServerImportDialog::slotImport(const QStringList& keyIds, const QUrl &keyServerUrl) {
- for (const auto &keyId : keyIds) {
- QUrl reqUrl(
- keyServerUrl.scheme() + "://" + keyServerUrl.host() + "/pks/lookup?op=get&search=0x" + keyId +
- "&options=mr");
- qDebug() << "slotImport reqUrl" << reqUrl;
- auto pManager = new QNetworkAccessManager(this);
-
- QNetworkReply *reply = pManager->get(QNetworkRequest(reqUrl));
-
- connect(reply, SIGNAL(finished()),
- this, SLOT(slotImportFinished()));
-
- setLoading(true);
-
- while(reply->isRunning()) {
- QApplication::processEvents();
- }
+ LOG(INFO) << "request url" << req_url.toString().toStdString();
+ auto manager = new QNetworkAccessManager(this);
- setLoading(false);
- }
+ QNetworkReply* reply = manager->get(QNetworkRequest(req_url));
+ connect(reply, &QNetworkReply::finished, this,
+ [&, keyId]() { this->slotImportFinished(keyId); });
+ LOG(INFO) << "loading start";
+ setLoading(true);
+ while (reply->isRunning()) QApplication::processEvents();
+ setLoading(false);
+ LOG(INFO) << "loading done";
+ }
}
-void KeyServerImportDialog::slotImportFinished() {
- auto *reply = qobject_cast<QNetworkReply *>(sender());
-
- QByteArray key = reply->readAll();
-
- QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
-
- auto error = reply->error();
- if (error != QNetworkReply::NoError) {
- qDebug() << "Error From Reply" << reply->errorString();
- switch (error) {
- case QNetworkReply::ContentNotFoundError :
- setMessage(tr("Key Not Found"), true);
- break;
- case QNetworkReply::TimeoutError :
- setMessage(tr("Timeout"), true);
- break;
- case QNetworkReply::HostNotFoundError :
- setMessage(tr("Key Server Not Found"), true);
- break;
- default:
- setMessage(tr("Connection Error"), true);
- }
- if(mAutomatic) {
- setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint);
- }
- return;
+void KeyServerImportDialog::slotImportFinished(QString keyid) {
+ LOG(INFO) << _("Called");
+
+ auto* reply = qobject_cast<QNetworkReply*>(sender());
+
+ QByteArray key = reply->readAll();
+
+ auto error = reply->error();
+ if (error != QNetworkReply::NoError) {
+ LOG(ERROR) << "Error From Reply" << reply->errorString().toStdString();
+ if (!mAutomatic) {
+ switch (error) {
+ case QNetworkReply::ContentNotFoundError:
+ setMessage(_("Key Not Found"), true);
+ break;
+ case QNetworkReply::TimeoutError:
+ setMessage(_("Timeout"), true);
+ break;
+ case QNetworkReply::HostNotFoundError:
+ setMessage(_("Key Server Not Found"), true);
+ break;
+ default:
+ setMessage(_("Connection Error"), true);
+ }
+ } else {
+ switch (error) {
+ case QNetworkReply::ContentNotFoundError:
+ QMessageBox::critical(
+ nullptr, _("Public key Not Found"),
+ QString(_("Public key fingerprint %1 not found in the Keyserver"))
+ .arg(keyid));
+ break;
+ case QNetworkReply::TimeoutError:
+ QMessageBox::critical(nullptr, _("Timeout"), "Connection timeout");
+ break;
+ case QNetworkReply::HostNotFoundError:
+ QMessageBox::critical(nullptr, _("Host Not Found"),
+ "cannot resolve the default Keyserver");
+ break;
+ default:
+ QMessageBox::critical(nullptr, _("Connection Error"),
+ _("General Connection Error"));
+ }
}
-
- // Add keyserver to list in config-file, if it isn't contained
- QStringList keyServerList = settings.value("keyserver/keyServerList").toStringList();
- if (!keyServerList.contains(keyServerComboBox->currentText())) {
- keyServerList.append(keyServerComboBox->currentText());
- settings.setValue("keyserver/keyServerList", keyServerList);
+ if (mAutomatic) {
+ setWindowFlags(Qt::Window | Qt::WindowTitleHint |
+ Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint);
}
- reply->deleteLater();
+ return;
+ }
- this->importKeys(key.constData());
- if(mAutomatic) {
- setMessage(tr("<h4>Key Updated</h4>"), false);
- } else {
- setMessage(tr("<h4>Key Imported</h4>"), false);
- }
+ reply->deleteLater();
+ this->importKeys(std::make_unique<ByteArray>(key.constData(), key.length()));
+ if (!mAutomatic) {
+ setMessage(QString("<h4>") + _("Key Imported") + "</h4>", false);
+ }
}
-void KeyServerImportDialog::importKeys(QByteArray inBuffer) {
- GpgImportInformation result = mCtx->importKey(std::move(inBuffer));
- if(mAutomatic) {
- new KeyImportDetailDialog(mCtx, result, false, this);
- this->accept();
- } else {
- new KeyImportDetailDialog(mCtx, result, false, this);
- }
+void KeyServerImportDialog::importKeys(ByteArrayPtr in_data) {
+ GpgImportInformation result =
+ GpgKeyImportExportor::GetInstance().ImportKey(std::move(in_data));
+ emit signalKeyImported();
+ if (mAutomatic) {
+ auto dialog = new KeyImportDetailDialog(result, true, nullptr);
+ dialog->show();
+ this->accept();
+ } else {
+ auto dialog = new KeyImportDetailDialog(result, false, this);
+ dialog->exec();
+ }
}
void KeyServerImportDialog::setLoading(bool status) {
- if (status) {
- waitingBar->setVisible(true);
- icon->setVisible(false);
- message->setVisible(false);
- } else {
- waitingBar->setVisible(false);
- icon->setVisible(true);
- message->setVisible(true);
- }
+ waitingBar->setVisible(status);
+ if (!mAutomatic) {
+ icon->setVisible(!status);
+ message->setVisible(!status);
+ }
}
-KeyServerImportDialog::KeyServerImportDialog(GpgME::GpgContext *ctx, QWidget *parent)
- : QDialog(parent), appPath(qApp->applicationDirPath()),
- settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", QSettings::IniFormat),
- mCtx(ctx), mAutomatic(true) {
+KeyServerImportDialog::KeyServerImportDialog(QWidget* parent)
+ : QDialog(parent), mAutomatic(true) {
+ setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint);
- setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint);
+ message = new QLabel;
+ message->setFixedHeight(24);
+ icon = new QLabel;
+ icon->setFixedHeight(24);
- message = new QLabel;
- message->setFixedHeight(24);
- icon = new QLabel;
- icon->setFixedHeight(24);
+ // Network Waiting
+ waitingBar = new QProgressBar();
+ waitingBar->setVisible(false);
+ waitingBar->setRange(0, 0);
+ waitingBar->setFixedHeight(24);
+ waitingBar->setFixedWidth(200);
- // Network Waiting
- waitingBar = new QProgressBar();
- waitingBar->setVisible(false);
- waitingBar->setRange(0, 0);
- waitingBar->setFixedHeight(24);
- waitingBar->setFixedWidth(200);
+ // Layout for messagebox
+ auto* messageLayout = new QHBoxLayout;
+ messageLayout->addWidget(icon);
+ messageLayout->addWidget(message);
+ messageLayout->addWidget(waitingBar);
+ messageLayout->addStretch();
- // Layout for messagebox
- auto *messageLayout = new QHBoxLayout;
- messageLayout->addWidget(icon);
- messageLayout->addWidget(message);
- messageLayout->addWidget(waitingBar);
- messageLayout->addStretch();
+ keyServerComboBox = createComboBox();
- keyServerComboBox = createComboBox();
+ auto* mainLayout = new QGridLayout;
- auto *mainLayout = new QGridLayout;
+ mainLayout->addLayout(messageLayout, 0, 0, 1, 3);
- mainLayout->addLayout(messageLayout, 0, 0, 1, 3);
+ this->setLayout(mainLayout);
+ this->setWindowTitle(_("Upload Keys from Keyserver"));
+ this->setFixedSize(200, 42);
+ this->setModal(true);
+}
- this->setLayout(mainLayout);
- this->setWindowTitle(tr("Upload Keys from Keyserver"));
- this->setFixedSize(200, 42);
- this->setModal(true);
+void KeyServerImportDialog::slotSaveWindowState() {
+ LOG(INFO) << _("Called");
+
+ if (mAutomatic) return;
+
+ auto& settings =
+ GpgFrontend::UI::GlobalSettingStation::GetInstance().GetUISettings();
+
+ if (!settings.exists("window") ||
+ settings.lookup("window").getType() != libconfig::Setting::TypeGroup)
+ settings.add("window", libconfig::Setting::TypeGroup);
+
+ auto& window = settings["window"];
+
+ if (!window.exists("import_from_keyserver") ||
+ window.lookup("import_from_keyserver").getType() !=
+ libconfig::Setting::TypeGroup)
+ window.add("import_from_keyserver", libconfig::Setting::TypeGroup);
+
+ auto& import_from_keyserver = window["import_from_keyserver"];
+
+ if (!import_from_keyserver.exists("position") ||
+ import_from_keyserver.lookup("position").getType() !=
+ libconfig::Setting::TypeGroup) {
+ auto& position =
+ import_from_keyserver.add("position", libconfig::Setting::TypeGroup);
+ position.add("x", libconfig::Setting::TypeInt) = pos().x();
+ position.add("y", libconfig::Setting::TypeInt) = pos().y();
+ } else {
+ import_from_keyserver["position"]["x"] = pos().x();
+ import_from_keyserver["position"]["y"] = pos().y();
+ }
+
+ if (!import_from_keyserver.exists("size") ||
+ import_from_keyserver.lookup("size").getType() !=
+ libconfig::Setting::TypeGroup) {
+ auto& size =
+ import_from_keyserver.add("size", libconfig::Setting::TypeGroup);
+ size.add("width", libconfig::Setting::TypeInt) = QWidget::width();
+ size.add("height", libconfig::Setting::TypeInt) = QWidget::height();
+ } else {
+ import_from_keyserver["size"]["width"] = QWidget::width();
+ import_from_keyserver["size"]["height"] = QWidget::height();
+ }
+
+ GlobalSettingStation::GetInstance().Sync();
}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/KeyServerImportDialog.h b/src/ui/KeyServerImportDialog.h
new file mode 100644
index 00000000..67571f2f
--- /dev/null
+++ b/src/ui/KeyServerImportDialog.h
@@ -0,0 +1,93 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef __KEY_SERVER_IMPORT_DIALOG_H__
+#define __KEY_SERVER_IMPORT_DIALOG_H__
+
+#include "KeyImportDetailDialog.h"
+#include "gpg/GpgContext.h"
+#include "ui/GpgFrontendUI.h"
+#include "ui/widgets/KeyList.h"
+
+namespace GpgFrontend::UI {
+
+class KeyServerImportDialog : public QDialog {
+ Q_OBJECT
+
+ public:
+ KeyServerImportDialog(bool automatic, QWidget* parent);
+
+ KeyServerImportDialog(QWidget* parent);
+
+ void slotImport(const KeyIdArgsListPtr& keys);
+
+ void slotImport(const QStringList& keyIds, const QUrl& keyserverUrl);
+
+ signals:
+ void signalKeyImported();
+
+ private slots:
+
+ void slotImport();
+
+ void slotSearchFinished();
+
+ void slotImportFinished(QString keyid);
+
+ void slotSearch();
+
+ void slotSaveWindowState();
+
+ private:
+ void createKeysTable();
+
+ void setMessage(const QString& text, bool error);
+
+ void importKeys(ByteArrayPtr in_data);
+
+ void setLoading(bool status);
+
+ QPushButton* createButton(const QString& text, const char* member);
+
+ QComboBox* createComboBox();
+
+ bool mAutomatic = false;
+
+ QLineEdit* searchLineEdit{};
+ QComboBox* keyServerComboBox{};
+ QProgressBar* waitingBar;
+ QLabel* searchLabel{};
+ QLabel* keyServerLabel{};
+ QLabel* message{};
+ QLabel* icon{};
+ QPushButton* closeButton{};
+ QPushButton* importButton{};
+ QPushButton* searchButton{};
+ QTableWidget* keysTable{};
+ QNetworkAccessManager* qnam{};
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // __KEY_SERVER_IMPORT_DIALOG_H__
diff --git a/src/ui/KeyUploadDialog.cpp b/src/ui/KeyUploadDialog.cpp
index ab38569f..b2bfff6d 100644
--- a/src/ui/KeyUploadDialog.cpp
+++ b/src/ui/KeyUploadDialog.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,105 +24,117 @@
#include "ui/KeyUploadDialog.h"
-KeyUploadDialog::KeyUploadDialog(GpgME::GpgContext *ctx, const QVector<GpgKey> &keys, QWidget *parent)
- : appPath(qApp->applicationDirPath()),
- settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", QSettings::IniFormat),
- mCtx(ctx),
- mKeys(keys),
- QDialog(parent) {
-
-
- auto *pb = new QProgressBar();
- pb->setRange(0, 0);
- pb->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
- pb->setTextVisible(false);
-
- auto *layout = new QVBoxLayout();
- layout->addWidget(pb);
- layout->setContentsMargins(0, 0, 0, 0);
- layout->setSpacing(0);
- this->setLayout(layout);
-
- this->setModal(true);
- this->setWindowTitle(tr("Uploading Public Key"));
- this->setFixedSize(240, 42);
+#include <algorithm>
+
+#include "gpg/function/GpgKeyGetter.h"
+#include "gpg/function/GpgKeyImportExportor.h"
+
+namespace GpgFrontend::UI {
+
+KeyUploadDialog::KeyUploadDialog(const KeyIdArgsListPtr& keys_ids,
+ QWidget* parent)
+ : QDialog(parent),
+ appPath(qApp->applicationDirPath()),
+ settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini",
+ QSettings::IniFormat),
+ mKeys(GpgKeyGetter::GetInstance().GetKeys(keys_ids)) {
+ auto* pb = new QProgressBar();
+ pb->setRange(0, 0);
+ pb->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+ pb->setTextVisible(false);
+
+ auto* layout = new QVBoxLayout();
+ layout->addWidget(pb);
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->setSpacing(0);
+ this->setLayout(layout);
+
+ this->setModal(true);
+ this->setWindowTitle(_("Uploading Public Key"));
+ this->setFixedSize(240, 42);
}
void KeyUploadDialog::slotUpload() {
- mCtx->exportKeys(mKeys, mKeyData);
- uploadKeyToServer(mKeyData);
+ auto out_data = std::make_unique<ByteArray>();
+ GpgKeyImportExportor::GetInstance().ExportKeys(*mKeys, out_data);
+ uploadKeyToServer(*out_data);
}
-void KeyUploadDialog::uploadKeyToServer(QByteArray &keys) {
+void KeyUploadDialog::uploadKeyToServer(
+ const GpgFrontend::ByteArray& keys_data) {
+ // set default keyserver
+ QString keyserver = settings.value("keyserver/defaultKeyServer").toString();
- // set default keyserver
- QString keyserver = settings.value("keyserver/defaultKeyServer").toString();
+ QUrl reqUrl(keyserver + "/pks/add");
+ auto qnam = new QNetworkAccessManager(this);
- QUrl reqUrl(keyserver + "/pks/add");
- auto qnam = new QNetworkAccessManager(this);
+ // Building Post Data
+ QByteArray postData;
- // Building Post Data
- QByteArray postData;
+ auto data = std::string(keys_data);
- keys.replace("\n", "%0A")
- .replace("\r", "%0D")
- .replace("(", "%28")
- .replace(")", "%29")
- .replace("/", "%2F")
- .replace(":", "%3A")
- .replace("+", "%2B")
- .replace('=', "%3D")
- .replace(' ', '+');
+ boost::algorithm::replace_all(data, "\n", "%0A");
+ boost::algorithm::replace_all(data, "\r", "%0D");
+ boost::algorithm::replace_all(data, "(", "%28");
+ boost::algorithm::replace_all(data, ")", "%29");
+ boost::algorithm::replace_all(data, "/", "%2F");
+ boost::algorithm::replace_all(data, ":", "%3A");
+ boost::algorithm::replace_all(data, "+", "%2B");
+ boost::algorithm::replace_all(data, "=", "%3D");
+ boost::algorithm::replace_all(data, " ", "+");
- QNetworkRequest request(reqUrl);
- request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
+ QNetworkRequest request(reqUrl);
+ request.setHeader(QNetworkRequest::ContentTypeHeader,
+ "application/x-www-form-urlencoded");
- postData.append("keytext").append("=").append(keys);
+ postData.append("keytext").append("=").append(
+ QString::fromStdString(data).toUtf8());
- // Send Post Data
- QNetworkReply *reply = qnam->post(request, postData);
- connect(reply, SIGNAL(finished()),
- this, SLOT(slotUploadFinished()));
+ // Send Post Data
+ QNetworkReply* reply = qnam->post(request, postData);
+ connect(reply, SIGNAL(finished()), this, SLOT(slotUploadFinished()));
+ // Keep Waiting
+ while (reply->isRunning()) {
+ QApplication::processEvents();
+ }
- // Keep Waiting
- while(reply->isRunning()) {
- QApplication::processEvents();
- }
-
- // Done
- this->hide();
- this->close();
+ // Done
+ this->hide();
+ this->close();
}
void KeyUploadDialog::slotUploadFinished() {
- auto *reply = qobject_cast<QNetworkReply *>(sender());
-
- QByteArray response = reply->readAll();
- qDebug() << "Response: " << response.data();
-
- auto error = reply->error();
- if (error != QNetworkReply::NoError) {
- qDebug() << "Error From Reply" << reply->errorString();
- QString message;
- switch (error) {
- case QNetworkReply::ContentNotFoundError :
- message = tr("Key Not Found");
- break;
- case QNetworkReply::TimeoutError :
- message = tr("Timeout");
- break;
- case QNetworkReply::HostNotFoundError :
- message = tr("Key Server Not Found");
- break;
- default:
- message = tr("Connection Error");
- }
- QMessageBox::critical(this, "Upload Failed", message);
- return;
- } else {
- QMessageBox::information(this, "Upload Success", "Upload Public Key Successfully");
- qDebug() << "Success while contacting keyserver!";
+ auto* reply = qobject_cast<QNetworkReply*>(sender());
+
+ QByteArray response = reply->readAll();
+ qDebug() << "Response: " << response.data();
+
+ auto error = reply->error();
+ if (error != QNetworkReply::NoError) {
+ qDebug() << "Error From Reply" << reply->errorString();
+ QString message;
+ switch (error) {
+ case QNetworkReply::ContentNotFoundError:
+ message = _("Key Not Found");
+ break;
+ case QNetworkReply::TimeoutError:
+ message = _("Timeout");
+ break;
+ case QNetworkReply::HostNotFoundError:
+ message = _("Key Server Not Found");
+ break;
+ default:
+ message = _("Connection Error");
}
- reply->deleteLater();
+ QMessageBox::critical(this, "Upload Failed", message);
+ return;
+ } else {
+ QMessageBox::information(this, "Upload Success",
+ "Upload Public Key Successfully");
+ qDebug() << "Success while contacting keyserver!";
+ }
+ reply->deleteLater();
}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/KeyUploadDialog.h b/src/ui/KeyUploadDialog.h
new file mode 100644
index 00000000..b607c321
--- /dev/null
+++ b/src/ui/KeyUploadDialog.h
@@ -0,0 +1,57 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_KEYUPLOADWIDGET_H
+#define GPGFRONTEND_KEYUPLOADWIDGET_H
+
+#include "gpg/GpgContext.h"
+#include "ui/GpgFrontendUI.h"
+
+namespace GpgFrontend::UI {
+
+class KeyUploadDialog : public QDialog {
+ Q_OBJECT
+ public:
+ explicit KeyUploadDialog(const KeyIdArgsListPtr& keys_ids, QWidget* parent);
+
+ public slots:
+
+ void slotUpload();
+
+ private slots:
+
+ void uploadKeyToServer(const GpgFrontend::ByteArray& keys_data);
+
+ void slotUploadFinished();
+
+ private:
+ QString appPath;
+ QSettings settings;
+ KeyListPtr mKeys;
+ QByteArray mKeyData;
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_KEYUPLOADWIDGET_H
diff --git a/src/ui/MainWindow.cpp b/src/ui/MainWindow.cpp
new file mode 100644
index 00000000..6b0977fd
--- /dev/null
+++ b/src/ui/MainWindow.cpp
@@ -0,0 +1,380 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "MainWindow.h"
+
+#include "ui/UserInterfaceUtils.h"
+#ifdef RELEASE
+#include "ui/function/VersionCheckThread.h"
+#endif
+#include "ui/settings/GlobalSettingStation.h"
+
+namespace GpgFrontend::UI {
+
+MainWindow::MainWindow() {
+ this->setMinimumSize(1200, 700);
+ this->setWindowTitle(qApp->applicationName());
+}
+
+void MainWindow::init() noexcept {
+ try {
+ // Check Context Status
+ if (!GpgContext::GetInstance().good()) {
+ QMessageBox::critical(
+ nullptr, _("ENV Loading Failed"),
+ _("Gnupg is not installed correctly, please follow the ReadME "
+ "instructions to install gnupg and then open GpgFrontend."));
+ QCoreApplication::quit();
+ exit(0);
+ }
+
+ networkAccessManager = new QNetworkAccessManager(this);
+
+ /* get path were app was started */
+ setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
+ setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
+
+ edit = new TextEdit(this);
+ setCentralWidget(edit);
+
+ /* the list of Keys available*/
+ mKeyList = new KeyList(KeyListRow::SECRET_OR_PUBLIC_KEY,
+ KeyListColumn::TYPE | KeyListColumn::NAME |
+ KeyListColumn::EmailAddress |
+ KeyListColumn::Usage | KeyListColumn::Validity,
+ this);
+ mKeyList->setFilter([](const GpgKey& key) -> bool {
+ return !(key.revoked() || key.disabled() || key.expired());
+ });
+
+ mKeyList->slotRefresh();
+
+ infoBoard = new InfoBoardWidget(this, mKeyList);
+
+ /* List of binary Attachments */
+ attachmentDockCreated = false;
+
+ /* Variable containing if restart is needed */
+ this->slotSetRestartNeeded(false);
+
+ createActions();
+ createMenus();
+ createToolBars();
+ createStatusBar();
+ createDockWindows();
+
+ connect(edit->tabWidget, SIGNAL(currentChanged(int)), this,
+ SLOT(slotDisableTabActions(int)));
+
+ mKeyList->addMenuAction(appendSelectedKeysAct);
+ mKeyList->addMenuAction(copyMailAddressToClipboardAct);
+ mKeyList->addMenuAction(showKeyDetailsAct);
+ mKeyList->addSeparator();
+ mKeyList->addMenuAction(refreshKeysFromKeyserverAct);
+ mKeyList->addMenuAction(uploadKeyToServerAct);
+
+ restoreSettings();
+
+ // open filename if provided as first command line parameter
+ QStringList args = qApp->arguments();
+ if (args.size() > 1) {
+ if (!args[1].startsWith("-")) {
+ if (QFile::exists(args[1])) edit->loadFile(args[1]);
+ }
+ }
+ edit->curTextPage()->setFocus();
+
+ auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
+
+ if (!settings.exists("wizard") ||
+ settings.lookup("wizard").getType() != libconfig::Setting::TypeGroup)
+ settings.add("wizard", libconfig::Setting::TypeGroup);
+
+ auto& wizard = settings["wizard"];
+
+ // Show wizard, if the don't show wizard message box wasn't checked
+ // and keylist doesn't contain a private key
+
+ if (!wizard.exists("show_wizard"))
+ wizard.add("show_wizard", libconfig::Setting::TypeBoolean) = true;
+
+ bool show_wizard = true;
+ wizard.lookupValue("show_wizard", show_wizard);
+
+ LOG(INFO) << "wizard show_wizard" << show_wizard;
+
+ if (show_wizard) {
+ slotStartWizard();
+ }
+
+ emit loaded();
+
+#ifdef RELEASE
+ QString baseUrl =
+ "https://api.github.com/repos/saturneric/gpgfrontend/releases/latest";
+ QNetworkRequest request;
+ request.setUrl(QUrl(baseUrl));
+ auto* replay = networkAccessManager->get(request);
+ auto version_thread = new VersionCheckThread(replay);
+
+ connect(version_thread, SIGNAL(finished()), version_thread,
+ SLOT(deleteLater()));
+ connect(version_thread,
+ SIGNAL(upgradeVersion(const QString&, const QString&)), this,
+ SLOT(slotVersionUpgrade(const QString&, const QString&)));
+
+ version_thread->start();
+#endif
+ } catch (...) {
+ LOG(FATAL) << _("Critical error occur while loading GpgFrontend.");
+ QMessageBox::critical(nullptr, _("Loading Failed"),
+ _("Critical error occur while loading GpgFrontend."));
+ QCoreApplication::quit();
+ exit(0);
+ }
+}
+
+void MainWindow::restoreSettings() {
+ try {
+ auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
+
+ if (!settings.exists("window") ||
+ settings.lookup("window").getType() != libconfig::Setting::TypeGroup)
+ settings.add("window", libconfig::Setting::TypeGroup);
+
+ auto& window = settings["window"];
+
+ if (!window.exists("window_state"))
+ window.add("window_state", libconfig::Setting::TypeString) =
+ saveState().toBase64().toStdString();
+
+ std::string window_state = settings.lookup("window.window_state");
+ // state sets pos & size of dock-widgets
+ this->restoreState(
+ QByteArray::fromBase64(QByteArray::fromStdString(window_state)));
+
+ if (!window.exists("window_save"))
+ window.add("window_save", libconfig::Setting::TypeBoolean) = true;
+
+ bool window_save;
+ window.lookupValue("window_save", window_save);
+
+ // Restore window size & location
+ if (window_save) {
+ if (!window.exists("window_pos"))
+ window.add("window_pos", libconfig::Setting::TypeGroup);
+
+ auto& window_pos = window["window_pos"];
+
+ if (!window_pos.exists("x"))
+ window_pos.add("x", libconfig::Setting::TypeInt) = 100;
+
+ if (!window_pos.exists("y"))
+ window_pos.add("y", libconfig::Setting::TypeInt) = 100;
+
+ int x, y;
+ window_pos.lookupValue("x", x);
+ window_pos.lookupValue("y", y);
+
+ auto pos = QPoint(x, y);
+
+ if (!window.exists("window_size"))
+ window.add("window_size", libconfig::Setting::TypeGroup);
+
+ auto& window_size = window["window_size"];
+
+ if (!window_size.exists("width"))
+ window_size.add("width", libconfig::Setting::TypeInt) = 800;
+
+ if (!window_size.exists("height"))
+ window_size.add("height", libconfig::Setting::TypeInt) = 450;
+
+ int width, height;
+ window_size.lookupValue("width", width);
+ window_size.lookupValue("height", height);
+
+ auto size = QSize(width, height);
+ this->resize(size);
+ this->move(pos);
+ } else {
+ this->resize(QSize(800, 450));
+ this->move(QPoint(100, 100));
+ }
+
+ if (!window.exists("icon_size"))
+ window.add("icon_size", libconfig::Setting::TypeGroup);
+
+ auto& icon_size = window["icon_size"];
+
+ if (!icon_size.exists("width"))
+ icon_size.add("width", libconfig::Setting::TypeInt) = 24;
+
+ if (!icon_size.exists("height"))
+ icon_size.add("height", libconfig::Setting::TypeInt) = 24;
+
+ int width = icon_size["width"], height = icon_size["height"];
+ LOG(INFO) << "icon_size" << width << height;
+
+ // info board font size
+ if (!window.exists("info_font_size"))
+ window.add("info_font_size", libconfig::Setting::TypeInt) = 10;
+
+ // icons ize
+ this->setIconSize(QSize(width, height));
+ importButton->setIconSize(QSize(width, height));
+ fileEncButton->setIconSize(QSize(width, height));
+
+ if (!settings.exists("keyserver") ||
+ settings.lookup("keyserver").getType() != libconfig::Setting::TypeGroup)
+ settings.add("keyserver", libconfig::Setting::TypeGroup);
+
+ auto& keyserver = settings["keyserver"];
+
+ if (!keyserver.exists("server_list")) {
+ keyserver.add("server_list", libconfig::Setting::TypeList);
+
+ auto& server_list = keyserver["server_list"];
+ server_list.add(libconfig::Setting::TypeString) = "http://keys.gnupg.net";
+ server_list.add(libconfig::Setting::TypeString) =
+ "https://keyserver.ubuntu.com";
+ server_list.add(libconfig::Setting::TypeString) =
+ "http://pool.sks-keyservers.net";
+ }
+
+ if (!keyserver.exists("default_server")) {
+ keyserver.add("default_server", libconfig::Setting::TypeString) =
+ "https://keyserver.ubuntu.com";
+ }
+
+ if (!window.exists("icon_style")) {
+ window.add("icon_style", libconfig::Setting::TypeInt) =
+ Qt::ToolButtonTextUnderIcon;
+ }
+
+ int s_icon_style = window.lookup("icon_style");
+
+ // icon_style
+ auto icon_style = static_cast<Qt::ToolButtonStyle>(s_icon_style);
+ this->setToolButtonStyle(icon_style);
+ importButton->setToolButtonStyle(icon_style);
+ fileEncButton->setToolButtonStyle(icon_style);
+
+ if (!settings.exists("general") ||
+ settings.lookup("general").getType() != libconfig::Setting::TypeGroup)
+ settings.add("general", libconfig::Setting::TypeGroup);
+
+ auto& general = settings["general"];
+
+ if (!general.exists("save_key_checked")) {
+ general.add("save_key_checked", libconfig::Setting::TypeBoolean) = true;
+ }
+
+ bool save_key_checked = true;
+ general.lookupValue("save_key_checked", save_key_checked);
+
+ // Checked Keys
+ if (save_key_checked) {
+ if (!general.exists("save_key_checked_key_ids")) {
+ general.add("save_key_checked_key_ids", libconfig::Setting::TypeList);
+ }
+ auto key_ids_ptr = std::make_unique<KeyIdArgsList>();
+ ;
+ auto& save_key_checked_key_ids = general["save_key_checked_key_ids"];
+ const auto key_ids_size =
+ general.lookup("save_key_checked_key_ids").getLength();
+ for (auto i = 0; i < key_ids_size; i++) {
+ std::string key_id = save_key_checked_key_ids[i];
+ key_ids_ptr->push_back(key_id);
+ }
+ mKeyList->setChecked(key_ids_ptr);
+ }
+ } catch (...) {
+ LOG(ERROR) << "cannot resolve settings";
+ }
+
+ GlobalSettingStation::GetInstance().Sync();
+}
+
+void MainWindow::saveSettings() {
+ auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
+
+ try {
+ // window position and size
+ settings["window"]["window_state"] = saveState().toBase64().toStdString();
+ settings["window"]["window_pos"]["x"] = pos().x();
+ settings["window"]["window_pos"]["y"] = pos().y();
+
+ settings["window"]["window_size"]["width"] = size().width();
+ settings["window"]["window_size"]["height"] = size().height();
+
+ bool save_key_checked = settings.lookup("general.save_key_checked");
+
+ // keyid-list of private checked keys
+ if (save_key_checked) {
+ auto& key_ids = settings.lookup("general.save_key_checked_key_ids");
+ const int key_ids_size = key_ids.getLength();
+ for (auto i = 0; i < key_ids_size; i++) key_ids.remove(i);
+ auto key_ids_need_to_store = mKeyList->getChecked();
+
+ for (size_t i = 0; i < key_ids_need_to_store->size(); i++) {
+ std::string key_id = (*key_ids_need_to_store)[i];
+ key_ids.add(libconfig::Setting::TypeString) = key_id;
+ }
+
+ } else {
+ settings["general"].remove("save_key_checked");
+ }
+ } catch (...) {
+ LOG(ERROR) << "cannot save settings";
+ };
+
+ GlobalSettingStation::GetInstance().Sync();
+}
+
+void MainWindow::closeAttachmentDock() {
+ if (!attachmentDockCreated) {
+ return;
+ }
+ attachmentDock->close();
+ attachmentDock->deleteLater();
+ attachmentDockCreated = false;
+}
+
+void MainWindow::closeEvent(QCloseEvent* event) {
+ /*
+ * ask to save changes, if there are
+ * modified documents in any tab
+ */
+ if (edit->maybeSaveAnyTab()) {
+ saveSettings();
+ event->accept();
+ } else {
+ event->ignore();
+ }
+
+ // clear password from memory
+ // GpgContext::GetInstance().clearPasswordCache();
+}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h
new file mode 100644
index 00000000..e0bf9f5a
--- /dev/null
+++ b/src/ui/MainWindow.h
@@ -0,0 +1,437 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef __GPGWIN_H__
+#define __GPGWIN_H__
+
+#include "gpg/GpgConstants.h"
+#include "gpg/result_analyse/DecryptResultAnalyse.h"
+#include "gpg/result_analyse/EncryptResultAnalyse.h"
+#include "gpg/result_analyse/SignResultAnalyse.h"
+#include "ui/FileEncryptionDialog.h"
+#include "ui/FindWidget.h"
+#include "ui/GpgFrontendUI.h"
+#include "ui/KeyMgmt.h"
+#include "ui/KeyUploadDialog.h"
+#include "ui/WaitingDialog.h"
+#include "ui/Wizard.h"
+#include "ui/help/AboutDialog.h"
+#include "ui/settings/SettingsDialog.h"
+#include "ui/widgets/InfoBoardWidget.h"
+#include "ui/widgets/TextEdit.h"
+
+namespace GpgFrontend::UI {
+/**
+ * @brief
+ *
+ */
+class MainWindow : public QMainWindow {
+ Q_OBJECT
+
+ public:
+ /**
+ * @brief
+ *
+ */
+ MainWindow();
+
+ /**
+ * ONLY Called from main()
+ */
+ void init() noexcept;
+
+ signals:
+ void loaded();
+
+ public slots:
+
+ void slotSetStatusBarText(const QString& text);
+
+ protected:
+ /**
+ * @details Close event shows a save dialog, if there are unsaved documents on
+ * exit.
+ * @param event
+ */
+ void closeEvent(QCloseEvent* event) override;
+
+ public slots:
+
+ /**
+ * @details Open a new tab for path
+ */
+ void slotOpenFile(QString& path);
+
+ /**
+ * @details Open dialog for encrypting file.
+ */
+ void slotFileEncrypt();
+
+ /**
+ * @details Open dialog for decrypting file.
+ */
+ void slotFileDecrypt();
+
+ /**
+ * @details Open dialog for signing file.
+ */
+ void slotFileSign();
+
+ /**
+ * @details Open dialog for verifying file.
+ */
+ void slotFileVerify();
+
+ /**
+ * @details Open dialog for signing file.
+ */
+ void slotFileEncryptSign();
+
+ /**
+ * @details Open dialog for verifying file.
+ */
+ void slotFileDecryptVerify();
+
+ private slots:
+
+ /**
+ * @details encrypt the text of currently active textedit-page
+ * with the currently checked keys
+ */
+ void slotEncrypt();
+
+ /**
+ * @details encrypt and sign the text of currently active textedit-page
+ * with the currently checked keys
+ */
+ void slotEncryptSign();
+
+ /**
+ * @details Show a passphrase dialog and decrypt the text of currently active
+ * tab.
+ */
+ void slotDecrypt();
+
+ /**
+ * @details Sign the text of currently active tab with the checked private
+ * keys
+ */
+ void slotSign();
+
+ /**
+ * @details Verify the text of currently active tab and show verify
+ * information. If document is signed with a key, which is not in keylist,
+ * show import missing key from keyserver in Menu of verifynotification.
+ */
+ void slotVerify();
+
+ /**
+ * @details decrypt and verify the text of currently active textedit-page
+ * with the currently checked keys
+ */
+ void slotDecryptVerify();
+
+ /**
+ * @details Open dialog for encrypting file.
+ */
+ void slotFileEncryptCustom();
+
+ /**
+ * @details Open dialog for decrypting file.
+ */
+ void slotFileDecryptCustom();
+
+ /**
+ * @details Open dialog for signing file.
+ */
+ void slotFileSignCustom();
+
+ /**
+ * @details Open dialog for verifying file.
+ */
+ void slotFileVerifyCustom();
+
+ /**
+ * @details Show the details of the first of the first of selected keys
+ */
+ void slotShowKeyDetails();
+
+ /**
+ * @details Refresh key information of selected keys from default keyserver
+ */
+ void refreshKeysFromKeyserver();
+
+ /**
+ * @details upload the selected key to the keyserver
+ */
+ void uploadKeyToServer();
+
+ /**
+ * @details Open find widget.
+ */
+ void slotFind();
+
+ /**
+ * @details start the wizard
+ */
+ void slotStartWizard();
+
+ /**
+ * @details Import keys from currently active tab to keylist if possible.
+ */
+ void slotImportKeyFromEdit();
+
+ /**
+ * @details Append the selected keys to currently active textedit.
+ */
+ void slotAppendSelectedKeys();
+
+ /**
+ * @details Copy the mailaddress of selected key to clipboard.
+ * Method for keylists contextmenu.
+ */
+ void slotCopyMailAddressToClipboard();
+
+ /**
+ * @details Open key management dialog.
+ */
+ void slotOpenKeyManagement();
+
+ /**
+ * @details Open about-dialog.
+ */
+ void slotAbout();
+
+ /**
+ * @details Open check-update-tab in about-dialog.
+ */
+ void slotCheckUpdate();
+
+ /**
+ * @details Open File Opera Tab
+ */
+ void slotOpenFileTab();
+
+ /**
+ * @details Open settings-dialog.
+ */
+ void slotOpenSettingsDialog();
+
+ // /**
+ // * @details Show a warn message in status bar, if there are files in
+ // * attachment folder.
+ // */
+ // void slotCheckAttachmentFolder();
+
+ /**
+ * @details Replace double linebreaks by single linebreaks in currently active
+ * tab.
+ */
+ void slotCleanDoubleLinebreaks();
+
+ /**
+ * @details Cut the existing PGP header and footer from current tab.
+ */
+ void slotCutPgpHeader();
+
+ /**
+ * @details Add PGP header and footer to current tab.
+ */
+ void slotAddPgpHeader();
+
+ /**
+ * @details Disable tab related actions, if number of tabs is 0.
+ * @param number number of the opened tabs and -1, if no tab is opened
+ */
+ void slotDisableTabActions(int number);
+
+ /**
+ * @details get value of member restartNeeded to needed.
+ * @param needed true, if application has to be restarted
+ */
+ void slotSetRestartNeeded(bool needed);
+
+ /**
+ * @details called when need to upgrade.
+ */
+ void slotVersionUpgrade(const QString& currentVersion,
+ const QString& latestVersion);
+
+ private:
+ /**
+ * @details Create actions for the main-menu and the context-menu of the
+ * keylist.
+ */
+ void createActions();
+
+ /**
+ * @details create the menu of the main-window.
+ */
+ void createMenus();
+
+ /**
+ * @details Create edit-, crypt- and key-toolbars.
+ */
+ void createToolBars();
+
+ /**
+ * @details Create statusbar of mainwindow.
+ */
+ void createStatusBar();
+
+ /**
+ * @details Create keylist- and attachment-dockwindows.
+ */
+ void createDockWindows();
+
+ /**
+ * @details Create attachment-dockwindow.
+ */
+ void createAttachmentDock();
+
+ /**
+ * @details close attachment-dockwindow.
+ */
+ void closeAttachmentDock();
+
+ /**
+ * @details Load settings from ini-file.
+ */
+ void restoreSettings();
+
+ /**
+ * @details Save settings to ini-file.
+ */
+ void saveSettings();
+
+#ifdef ADVANCE_SUPPORT
+
+ /**
+ * @details Get full crypto text
+ */
+ QString getCryptText(const QString& shortenCryptoText);
+
+ /**
+ * @details Shorten crypto text
+ */
+ void shortenCryptText();
+
+#endif
+
+ /**
+ * @brief return true, if restart is needed
+ */
+ [[nodiscard]] bool getRestartNeeded() const;
+
+ TextEdit* edit{}; /** Tabwidget holding the edit-windows */
+ QMenu* fileMenu{}; /** Submenu for file-operations*/
+ QMenu* editMenu{}; /** Submenu for text-operations*/
+ QMenu* cryptMenu{}; /** Submenu for crypt-operations */
+ QMenu* fileEncMenu{}; /** Submenu for file crypt operations */
+ QMenu* helpMenu{}; /** Submenu for help-operations */
+ QMenu* keyMenu{}; /** Submenu for key-operations */
+ QMenu* viewMenu{}; /** Submenu for view operations */
+ QMenu* importKeyMenu{}; /** Sumenu for import operations */
+ QMenu* steganoMenu{}; /** Submenu for steganographic operations*/
+ QToolBar* cryptToolBar{}; /** Toolbar holding crypt actions */
+ QToolBar* fileToolBar{}; /** Toolbar holding file actions */
+ QToolBar* editToolBar{}; /** Toolbar holding edit actions */
+ QToolBar* specialEditToolBar{}; /** Toolbar holding special edit actions */
+ QToolBar* keyToolBar{}; /** Toolbar holding key operations */
+ QToolButton*
+ importButton{}; /** Toolbutton for import dropdown menu in toolbar */
+ QToolButton* fileEncButton{}; /** Toolbutton for file cryption dropdown menu
+ in toolbar */
+ QDockWidget* keyListDock{}; /** Encrypt Dock*/
+ QDockWidget* attachmentDock{}; /** Attachment Dock */
+ QDockWidget* infoBoardDock{};
+
+ QAction* newTabAct{}; /** Action to create new tab */
+ QAction* switchTabUpAct{}; /** Action to switch tab up*/
+ QAction* switchTabDownAct{}; /** Action to switch tab down */
+ QAction* openAct{}; /** Action to open file */
+ QAction* browserAct{}; /** Action to open file browser*/
+ QAction* saveAct{}; /** Action to save file */
+ QAction* saveAsAct{}; /** Action to save file as */
+ QAction* printAct{}; /** Action to print */
+ QAction* closeTabAct{}; /** Action to print */
+ QAction* quitAct{}; /** Action to quit application */
+ QAction* encryptAct{}; /** Action to encrypt text */
+ QAction* encryptSignAct{}; /** Action to encrypt and sign text */
+ QAction* decryptVerifyAct{}; /** Action to encrypt and sign text */
+ QAction* decryptAct{}; /** Action to decrypt text */
+ QAction* signAct{}; /** Action to sign text */
+ QAction* verifyAct{}; /** Action to verify text */
+ QAction* importKeyFromEditAct{}; /** Action to import key from edit */
+ QAction*
+ cleanDoubleLinebreaksAct{}; /** Action to remove double line breaks */
+
+ QAction*
+ appendSelectedKeysAct{}; /** Action to append selected keys to edit */
+ QAction*
+ copyMailAddressToClipboardAct{}; /** Action to copy mail to clipboard */
+ QAction* openKeyManagementAct{}; /** Action to open key management */
+ QAction* copyAct{}; /** Action to copy text */
+ QAction* quoteAct{}; /** Action to quote text */
+ QAction* cutAct{}; /** Action to cut text */
+ QAction* pasteAct{}; /** Action to paste text */
+ QAction* selectAllAct{}; /** Action to select whole text */
+ QAction* findAct{}; /** Action to find text */
+ QAction* undoAct{}; /** Action to undo last action */
+ QAction* redoAct{}; /** Action to redo last action */
+ QAction* zoomInAct{}; /** Action to zoom in */
+ QAction* zoomOutAct{}; /** Action to zoom out */
+ QAction* aboutAct{}; /** Action to open about dialog */
+ QAction* checkUpdateAct{}; /** Action to open about dialog */
+ QAction* fileEncryptAct{}; /** Action to open dialog for encrypting file */
+ QAction* fileDecryptAct{}; /** Action to open dialog for decrypting file */
+ QAction* fileSignAct{}; /** Action to open dialog for signing file */
+ QAction* fileVerifyAct{}; /** Action to open dialog for verifying file */
+ QAction* openSettingsAct{}; /** Action to open settings dialog */
+ QAction* showKeyDetailsAct{}; /** Action to open key-details dialog */
+ QAction* refreshKeysFromKeyserverAct{}; /** Action to refresh a key from
+ keyserver */
+ QAction* uploadKeyToServerAct{}; /** Action to append selected keys to edit */
+ QAction* startWizardAct{}; /** Action to open the wizard */
+ QAction* cutPgpHeaderAct{}; /** Action for cutting the PGP header */
+ QAction* addPgpHeaderAct{}; /** Action for adding the PGP header */
+
+ QAction* importKeyFromFileAct{};
+ QAction* importKeyFromClipboardAct{};
+ QAction* importKeyFromKeyServerAct{};
+
+ QLabel* statusBarIcon{}; /**< TODO */
+
+ KeyList* mKeyList{};
+ InfoBoardWidget* infoBoard{};
+
+ QNetworkAccessManager* networkAccessManager{};
+
+ bool attachmentDockCreated{};
+ bool restartNeeded{};
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // __GPGWIN_H__
diff --git a/src/ui/QuitDialog.cpp b/src/ui/QuitDialog.cpp
index 783a8a61..a5ed7c3f 100755
--- a/src/ui/QuitDialog.cpp
+++ b/src/ui/QuitDialog.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,109 +24,118 @@
#include "ui/QuitDialog.h"
-QuitDialog::QuitDialog(QWidget *parent, const QHash<int, QString>& unsavedDocs)
- : QDialog(parent) {
- setWindowTitle(tr("Unsaved Files"));
- setModal(true);
- discarded = false;
-
- /*
- * Table of unsaved documents
- */
- QHashIterator<int, QString> i(unsavedDocs);
- int row = 0;
- mFileList = new QTableWidget(this);
- mFileList->horizontalHeader()->hide();
- mFileList->setColumnCount(3);
- mFileList->setColumnWidth(0, 20);
- mFileList->setColumnHidden(2, true);
- mFileList->verticalHeader()->hide();
- mFileList->setShowGrid(false);
- mFileList->setEditTriggers(QAbstractItemView::NoEditTriggers);
- mFileList->setFocusPolicy(Qt::NoFocus);
- mFileList->horizontalHeader()->setStretchLastSection(true);
- // fill the table
- i.toFront(); //jump to the end of list to fill the table backwards
- while (i.hasNext()) {
- i.next();
- mFileList->setRowCount(mFileList->rowCount() + 1);
-
- // checkbox in front of filename
- auto *tmp0 = new QTableWidgetItem();
- tmp0->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
- tmp0->setCheckState(Qt::Checked);
- mFileList->setItem(row, 0, tmp0);
-
- // filename
- auto *tmp1 = new QTableWidgetItem(i.value());
- mFileList->setItem(row, 1, tmp1);
-
- // tab-index in hidden column
- auto *tmp2 = new QTableWidgetItem(QString::number(i.key()));
- mFileList->setItem(row, 2, tmp2);
- ++row;
- }
- /*
- * Warnbox with icon and text
- */
- auto pixmap = QPixmap(":error.png");
- pixmap = pixmap.scaled(50, 50, Qt::KeepAspectRatio, Qt::SmoothTransformation);
- auto *warn_icon = new QLabel();
- warn_icon->setPixmap(pixmap);
- auto *warn_label = new QLabel(
- tr("%1 files contain unsaved information.<br/>Save the changes before closing?").arg(row));
- auto *warnBoxLayout = new QHBoxLayout();
- warnBoxLayout->addWidget(warn_icon);
- warnBoxLayout->addWidget(warn_label);
- warnBoxLayout->setAlignment(Qt::AlignLeft);
- auto *warnBox = new QWidget(this);
- warnBox->setLayout(warnBoxLayout);
-
- /*
- * Two labels on top and under the filelist
- */
- auto *checkLabel = new QLabel(tr("Check the files you want to save:"));
- auto *note_label = new QLabel(tr("<b>Note:</b> If you don't save these files, all changes are lost.<br/>"));
-
- /*
- * Buttonbox
- */
- auto *buttonBox = new QDialogButtonBox(
- QDialogButtonBox::Discard | QDialogButtonBox::Save | QDialogButtonBox::Cancel);
- connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
- connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
- QPushButton *btnNoKey = buttonBox->button(QDialogButtonBox::Discard);
- connect(btnNoKey, SIGNAL(clicked()), SLOT(slotMyDiscard()));
-
- /*
- * Set the layout
- */
- auto *vbox = new QVBoxLayout();
- vbox->addWidget(warnBox);
- vbox->addWidget(checkLabel);
- vbox->addWidget(mFileList);
- vbox->addWidget(note_label);
- vbox->addWidget(buttonBox);
- this->setLayout(vbox);
-}
+#include <boost/format.hpp>
+namespace GpgFrontend::UI {
-void QuitDialog::slotMyDiscard() {
- discarded = true;
- reject();
+QuitDialog::QuitDialog(QWidget* parent, const QHash<int, QString>& unsavedDocs)
+ : QDialog(parent) {
+ setWindowTitle(_("Unsaved Files"));
+ setModal(true);
+ discarded = false;
+
+ /*
+ * Table of unsaved documents
+ */
+ QHashIterator<int, QString> i(unsavedDocs);
+ int row = 0;
+ mFileList = new QTableWidget(this);
+ mFileList->horizontalHeader()->hide();
+ mFileList->setColumnCount(3);
+ mFileList->setColumnWidth(0, 20);
+ mFileList->setColumnHidden(2, true);
+ mFileList->verticalHeader()->hide();
+ mFileList->setShowGrid(false);
+ mFileList->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ mFileList->setFocusPolicy(Qt::NoFocus);
+ mFileList->horizontalHeader()->setStretchLastSection(true);
+ // fill the table
+ i.toFront(); // jump to the end of list to fill the table backwards
+ while (i.hasNext()) {
+ i.next();
+ mFileList->setRowCount(mFileList->rowCount() + 1);
+
+ // checkbox in front of filename
+ auto* tmp0 = new QTableWidgetItem();
+ tmp0->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
+ tmp0->setCheckState(Qt::Checked);
+ mFileList->setItem(row, 0, tmp0);
+
+ // filename
+ auto* tmp1 = new QTableWidgetItem(i.value());
+ mFileList->setItem(row, 1, tmp1);
+
+ // tab-index in hidden column
+ auto* tmp2 = new QTableWidgetItem(QString::number(i.key()));
+ mFileList->setItem(row, 2, tmp2);
+ ++row;
+ }
+ /*
+ * Warnbox with icon and text
+ */
+ auto pixmap = QPixmap(":error.png");
+ pixmap = pixmap.scaled(50, 50, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ auto* warn_icon = new QLabel();
+ warn_icon->setPixmap(pixmap);
+
+ const auto info =
+ boost::format(_("%1% files contain unsaved information.<br/>Save the "
+ "changes before closing?")) %
+ std::to_string(row);
+ auto* warn_label = new QLabel(QString::fromStdString(info.str()));
+ auto* warnBoxLayout = new QHBoxLayout();
+ warnBoxLayout->addWidget(warn_icon);
+ warnBoxLayout->addWidget(warn_label);
+ warnBoxLayout->setAlignment(Qt::AlignLeft);
+ auto* warnBox = new QWidget(this);
+ warnBox->setLayout(warnBoxLayout);
+
+ /*
+ * Two labels on top and under the filelist
+ */
+ auto* checkLabel = new QLabel(_("Check the files you want to save:"));
+ auto* note_label = new QLabel(
+ "<b>" + QString(_("Note")) + ":</b>" +
+ _("If you don't save these files, all changes are lost.") + "<br/>");
+
+ /*
+ * Buttonbox
+ */
+ auto* buttonBox =
+ new QDialogButtonBox(QDialogButtonBox::Discard | QDialogButtonBox::Save |
+ QDialogButtonBox::Cancel);
+ connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
+ connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+ QPushButton* btnNoKey = buttonBox->button(QDialogButtonBox::Discard);
+ connect(btnNoKey, SIGNAL(clicked()), SLOT(slotMyDiscard()));
+
+ /*
+ * Set the layout
+ */
+ auto* vbox = new QVBoxLayout();
+ vbox->addWidget(warnBox);
+ vbox->addWidget(checkLabel);
+ vbox->addWidget(mFileList);
+ vbox->addWidget(note_label);
+ vbox->addWidget(buttonBox);
+ this->setLayout(vbox);
}
-bool QuitDialog::isDiscarded() const {
- return discarded;
+void QuitDialog::slotMyDiscard() {
+ discarded = true;
+ reject();
}
+bool QuitDialog::isDiscarded() const { return discarded; }
+
QList<int> QuitDialog::getTabIdsToSave() {
- QList<int> tabIdsToSave;
- for (int i = 0; i < mFileList->rowCount(); i++) {
- if (mFileList->item(i, 0)->checkState() == Qt::Checked) {
- tabIdsToSave << mFileList->item(i, 2)->text().toInt();
- }
+ QList<int> tabIdsToSave;
+ for (int i = 0; i < mFileList->rowCount(); i++) {
+ if (mFileList->item(i, 0)->checkState() == Qt::Checked) {
+ tabIdsToSave << mFileList->item(i, 2)->text().toInt();
}
- return tabIdsToSave;
+ }
+ return tabIdsToSave;
}
+} // namespace GpgFrontend::UI
diff --git a/src/ui/QuitDialog.h b/src/ui/QuitDialog.h
new file mode 100755
index 00000000..2b1dd37f
--- /dev/null
+++ b/src/ui/QuitDialog.h
@@ -0,0 +1,53 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef __QUITDIALOG_H__
+#define __QUITDIALOG_H__
+
+#include "ui/GpgFrontendUI.h"
+
+namespace GpgFrontend::UI {
+
+class QuitDialog : public QDialog {
+ Q_OBJECT
+
+ public:
+ QuitDialog(QWidget* parent, const QHash<int, QString>& unsavedDocs);
+
+ [[nodiscard]] bool isDiscarded() const;
+
+ QList<int> getTabIdsToSave();
+
+ private slots:
+
+ void slotMyDiscard();
+
+ private:
+ bool discarded;
+ QTableWidget* mFileList;
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // __QUITDIALOG_H__
diff --git a/src/ui/SendMailDialog.cpp b/src/ui/SendMailDialog.cpp
deleted file mode 100644
index 5bea7cb2..00000000
--- a/src/ui/SendMailDialog.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-/**
- * This file is part of GPGFrontend.
- *
- * GPGFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Foobar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from gpg4usb-team.
- * Their source code version also complies with GNU General Public License.
- *
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]> starting on May 12, 2021.
- *
- */
-
-#include "ui/SendMailDialog.h"
-
-#include <utility>
-#include "smtp/SmtpMime"
-
-SendMailDialog::SendMailDialog(QString text, QWidget *parent)
- : QDialog(parent), appPath(qApp->applicationDirPath()),
- settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", QSettings::IniFormat), mText(std::move(text)) {
-
- if (smtpAddress.isEmpty()) {
- QMessageBox::critical(this, tr("Incomplete configuration"),
- tr("The SMTP address is empty, please go to the setting interface to complete the configuration."));
-
- deleteLater();
- return;
-
- }
-
- senderEdit = new QLineEdit();
- senderEdit->setText(defaultSender);
- recipientEdit = new QTextEdit();
- recipientEdit->setPlaceholderText("One or more email addresses. Please use ; to separate.");
- subjectEdit = new QLineEdit();
-
- errorLabel = new QLabel();
-
- qDebug() << "Send Mail Settings" << smtpAddress << username << password << defaultSender << connectionTypeSettings;
-
- confirmButton = new QPushButton("Confirm");
-
- auto layout = new QGridLayout();
- layout->addWidget(new QLabel("Sender"), 0, 0);
- layout->addWidget(senderEdit, 0, 1);
- layout->addWidget(new QLabel("Recipient"), 1, 0);
- layout->addWidget(recipientEdit, 1, 1);
- layout->addWidget(new QLabel("Subject"), 2, 0);
- layout->addWidget(subjectEdit, 2, 1);
- layout->addWidget(confirmButton, 3, 1);
- layout->addWidget(errorLabel, 4, 0, 1, 2);
-
- connect(confirmButton, SIGNAL(clicked(bool)), this, SLOT(slotConfirm()));
-
- this->setLayout(layout);
- this->setWindowTitle("Send Mail");
- this->setModal(true);
- this->setFixedWidth(320);
- this->show();
-}
-
-bool SendMailDialog::check_email_address(const QString &str) {
- return re_email.match(str).hasMatch();
-}
-
-void SendMailDialog::slotConfirm() {
-
- QString errString;
- errorLabel->clear();
-
- QStringList rcptStringList = recipientEdit->toPlainText().split(';');
-
- if (rcptStringList.isEmpty()) {
- errString.append(tr(" Recipient cannot be empty \n"));
- } else {
- for (const auto& reci : rcptStringList) {
- qDebug() << "Receiver" << reci.trimmed();
- if (!check_email_address(reci.trimmed())) {
- errString.append(tr(" One or more Recipient's Email Address is invalid \n"));
- break;
- }
- }
- }
- if (senderEdit->text().isEmpty()) {
- errString.append(tr(" Sender cannot be empty \n"));
- } else if (!check_email_address(senderEdit->text())) {
- errString.append(tr(" Sender's Email Address is invalid \n"));
- }
-
- if (!errString.isEmpty()) {
- errorLabel->setAutoFillBackground(true);
- QPalette error = errorLabel->palette();
- error.setColor(QPalette::Window, "#ff8080");
- errorLabel->setPalette(error);
- errorLabel->setText(errString);
- return;
- }
-
- SmtpClient::ConnectionType connectionType = SmtpClient::ConnectionType::TcpConnection;
-
- if (connectionTypeSettings == "SSL") {
- connectionType = SmtpClient::ConnectionType::SslConnection;
- } else if (connectionTypeSettings == "TLS") {
- connectionType = SmtpClient::ConnectionType::TlsConnection;
- } else if (connectionTypeSettings == "STARTTLS") {
- connectionType = SmtpClient::ConnectionType::TlsConnection;
- } else {
- connectionType = SmtpClient::ConnectionType::TcpConnection;
- }
-
- SmtpClient smtp(smtpAddress, port, connectionType);
-
- // We need to set the username (your email address) and the password
- // for smtp authentification.
-
- smtp.setUser(username);
- smtp.setPassword(password);
-
- // Now we create a MimeMessage object. This will be the email.
-
- MimeMessage message;
-
- message.setSender(new EmailAddress(senderEdit->text()));
- for (const auto &reci : rcptStringList) {
- if(!reci.isEmpty())
- message.addRecipient(new EmailAddress(reci.trimmed()));
- }
- message.setSubject(subjectEdit->text());
-
- // Now add some text to the email.
- // First we create a MimeText object.
-
- MimeText text;
-
- text.setText(mText);
-
- // Now add it to the mail
- message.addPart(&text);
-
- // Now we can send the mail
- if (!smtp.connectToHost()) {
- qDebug() << "Connect to SMTP Server Failed";
- QMessageBox::critical(this, tr("Fail"), tr("Fail to Connect SMTP Server"));
- return;
- }
- if (!smtp.login()) {
- qDebug() << "Login to SMTP Server Failed";
- QMessageBox::critical(this, tr("Fail"), tr("Fail to Login into SMTP Server"));
- return;
- }
- if (!smtp.sendMail(message)) {
- qDebug() << "Send Mail to SMTP Server Failed";
- QMessageBox::critical(this, tr("Fail"), tr("Fail to Send Mail to SMTP Server"));
- return;
- }
- smtp.quit();
-
- // Close after sending email
- QMessageBox::information(this, tr("Success"), tr("Succeed in Sending Mail to SMTP Server"));
- deleteLater();
-}
diff --git a/src/ui/ShowCopyDialog.cpp b/src/ui/ShowCopyDialog.cpp
index 3286f6c4..0503e079 100644
--- a/src/ui/ShowCopyDialog.cpp
+++ b/src/ui/ShowCopyDialog.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,30 +24,36 @@
#include "ui/ShowCopyDialog.h"
-ShowCopyDialog::ShowCopyDialog(const QString &text, const QString &info, QWidget *parent) : QDialog(parent) {
- textEdit = new QTextEdit();
- textEdit->setReadOnly(true);
- textEdit->setLineWrapMode(QTextEdit::WidgetWidth);
- textEdit->setText(text);
- copyButton = new QPushButton("Copy");
- connect(copyButton, SIGNAL(clicked(bool)), this, SLOT(slotCopyText()));
-
- infoLabel = new QLabel();
- infoLabel->setText(info);
- infoLabel->setWordWrap(true);
-
- auto *layout = new QVBoxLayout();
- layout->addWidget(textEdit);
- layout->addWidget(copyButton);
- layout->addWidget(infoLabel);
-
- this->setWindowTitle("Short Ciphertext");
- this->resize(320, 120);
- this->setModal(true);
- this->setLayout(layout);
+namespace GpgFrontend::UI {
+
+ShowCopyDialog::ShowCopyDialog(const QString& text, const QString& info,
+ QWidget* parent)
+ : QDialog(parent) {
+ textEdit = new QTextEdit();
+ textEdit->setReadOnly(true);
+ textEdit->setLineWrapMode(QTextEdit::WidgetWidth);
+ textEdit->setText(text);
+ copyButton = new QPushButton("Copy");
+ connect(copyButton, SIGNAL(clicked(bool)), this, SLOT(slotCopyText()));
+
+ infoLabel = new QLabel();
+ infoLabel->setText(info);
+ infoLabel->setWordWrap(true);
+
+ auto* layout = new QVBoxLayout();
+ layout->addWidget(textEdit);
+ layout->addWidget(copyButton);
+ layout->addWidget(infoLabel);
+
+ this->setWindowTitle("Short Ciphertext");
+ this->resize(320, 120);
+ this->setModal(true);
+ this->setLayout(layout);
}
void ShowCopyDialog::slotCopyText() {
- QClipboard *cb = QApplication::clipboard();
- cb->setText(textEdit->toPlainText());
+ QClipboard* cb = QApplication::clipboard();
+ cb->setText(textEdit->toPlainText());
}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/ShowCopyDialog.h b/src/ui/ShowCopyDialog.h
new file mode 100644
index 00000000..fefef7ab
--- /dev/null
+++ b/src/ui/ShowCopyDialog.h
@@ -0,0 +1,50 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_ZH_CN_TS_SHOWCOPYDIALOG_H
+#define GPGFRONTEND_ZH_CN_TS_SHOWCOPYDIALOG_H
+
+#include "ui/GpgFrontendUI.h"
+
+namespace GpgFrontend::UI {
+
+class ShowCopyDialog : public QDialog {
+ Q_OBJECT
+ public:
+ explicit ShowCopyDialog(const QString& text, const QString& info = "",
+ QWidget* parent = nullptr);
+
+ private slots:
+
+ void slotCopyText();
+
+ private:
+ QLabel* infoLabel;
+ QTextEdit* textEdit;
+ QPushButton* copyButton;
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_ZH_CN_TS_SHOWCOPYDIALOG_H
diff --git a/src/gpg/GpgKeySignature.cpp b/src/ui/SignalStation.cpp
index 142d1550..fff2971a 100644
--- a/src/gpg/GpgKeySignature.cpp
+++ b/src/ui/SignalStation.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -22,13 +22,13 @@
*
*/
-#include "gpg/GpgKeySignature.h"
+#include "SignalStation.h"
-GpgKeySignature::GpgKeySignature(gpgme_key_sig_t key_sig) :
- revoked(key_sig->revoked), expired(key_sig->expired), invalid(key_sig->invalid),
- exportable(key_sig->exportable), status(key_sig->status),
- keyid(key_sig->keyid), pubkey_algo(gpgme_pubkey_algo_name(key_sig->pubkey_algo)),
- uid(key_sig->uid), name(key_sig->name), email(key_sig->email), comment(key_sig->comment),
- create_time(QDateTime::fromTime_t(key_sig->timestamp)), expire_time(QDateTime::fromTime_t(key_sig->expires)){
+std::unique_ptr<SignalStation> SignalStation::_instance = nullptr;
+SignalStation* SignalStation::GetInstance() {
+ if (_instance == nullptr) {
+ _instance = std::make_unique<SignalStation>();
+ }
+ return _instance.get();
}
diff --git a/src/ui/SignalStation.h b/src/ui/SignalStation.h
new file mode 100644
index 00000000..38e55d9f
--- /dev/null
+++ b/src/ui/SignalStation.h
@@ -0,0 +1,41 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_SIGNALSTATION_H
+#define GPGFRONTEND_SIGNALSTATION_H
+
+#include "ui/GpgFrontendUI.h"
+
+class SignalStation : public QObject {
+ Q_OBJECT
+ static std::unique_ptr<SignalStation> _instance;
+
+ public:
+ static SignalStation* GetInstance();
+
+ signals:
+ void KeyDatabaseRefresh();
+};
+
+#endif // GPGFRONTEND_SIGNALSTATION_H
diff --git a/src/ui/UserInterfaceUtils.cpp b/src/ui/UserInterfaceUtils.cpp
new file mode 100644
index 00000000..e8f27d2c
--- /dev/null
+++ b/src/ui/UserInterfaceUtils.cpp
@@ -0,0 +1,171 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "UserInterfaceUtils.h"
+
+#include "gpg/result_analyse/ResultAnalyse.h"
+#include "ui/SignalStation.h"
+#include "ui/WaitingDialog.h"
+#include "ui/widgets/InfoBoardWidget.h"
+#include "ui/widgets/TextEdit.h"
+
+namespace GpgFrontend::UI {
+
+std::unique_ptr<GpgFrontend::UI::CommonUtils>
+ GpgFrontend::UI::CommonUtils::_instance = nullptr;
+
+void refresh_info_board(InfoBoardWidget* info_board, int status,
+ const std::string& report_text) {
+ if (status < 0)
+ info_board->slotRefresh(QString::fromStdString(report_text),
+ INFO_ERROR_CRITICAL);
+ else if (status > 0)
+ info_board->slotRefresh(QString::fromStdString(report_text), INFO_ERROR_OK);
+ else
+ info_board->slotRefresh(QString::fromStdString(report_text),
+ INFO_ERROR_WARN);
+}
+
+void process_result_analyse(TextEdit* edit, InfoBoardWidget* info_board,
+ const ResultAnalyse& result_analyse) {
+ info_board->associateTabWidget(edit->tabWidget);
+ info_board->associateFileTreeView(edit->curFilePage());
+ refresh_info_board(info_board, result_analyse.getStatus(),
+ result_analyse.getResultReport());
+}
+
+void process_result_analyse(TextEdit* edit, InfoBoardWidget* info_board,
+ const ResultAnalyse& result_analyse_a,
+ const ResultAnalyse& result_analyse_b) {
+ LOG(INFO) << "process_result_analyse Started";
+
+ info_board->associateTabWidget(edit->tabWidget);
+ info_board->associateFileTreeView(edit->curFilePage());
+
+ refresh_info_board(
+ info_board,
+ std::min(result_analyse_a.getStatus(), result_analyse_b.getStatus()),
+ result_analyse_a.getResultReport() + result_analyse_b.getResultReport());
+}
+
+void process_operation(QWidget* parent, const std::string& waiting_title,
+ const std::function<void()>& func) {
+ auto thread = QThread::create(func);
+ QApplication::connect(thread, SIGNAL(finished()), thread,
+ SLOT(deleteLater()));
+ thread->start();
+
+ auto* dialog =
+ new WaitingDialog(QString::fromStdString(waiting_title), parent);
+ while (thread->isRunning()) {
+ QApplication::processEvents();
+ }
+ dialog->close();
+}
+
+CommonUtils* CommonUtils::GetInstance() {
+ if (_instance == nullptr) {
+ _instance = std::make_unique<CommonUtils>();
+ }
+ return _instance.get();
+}
+
+CommonUtils::CommonUtils() : QWidget(nullptr) {
+ connect(this, SIGNAL(signalKeyStatusUpdated()), SignalStation::GetInstance(),
+ SIGNAL(KeyDatabaseRefresh()));
+}
+
+void CommonUtils::slotImportKeys(QWidget* parent,
+ const std::string& in_buffer) {
+ GpgImportInformation result = GpgKeyImportExportor::GetInstance().ImportKey(
+ std::make_unique<ByteArray>(in_buffer));
+ emit signalKeyStatusUpdated();
+ new KeyImportDetailDialog(result, false, parent);
+}
+
+void CommonUtils::slotImportKeyFromFile(QWidget* parent) {
+ QString file_name = QFileDialog::getOpenFileName(
+ this, _("Open Key"), QString(),
+ QString(_("Key Files")) + " (*.asc *.txt);;" + _("Keyring files") +
+ " (*.gpg);;All Files (*)");
+ if (!file_name.isNull()) {
+ slotImportKeys(parent, read_all_data_in_file(file_name.toStdString()));
+ }
+}
+
+void CommonUtils::slotImportKeyFromKeyServer(QWidget* parent) {
+ auto dialog = new KeyServerImportDialog(false, parent);
+ dialog->show();
+}
+
+void CommonUtils::slotImportKeyFromClipboard(QWidget* parent) {
+ QClipboard* cb = QApplication::clipboard();
+ slotImportKeys(parent,
+ cb->text(QClipboard::Clipboard).toUtf8().toStdString());
+}
+
+void CommonUtils::slotExecuteGpgCommand(
+ const QStringList& arguments,
+ const std::function<void(QProcess*)>& interact_func) {
+ QEventLoop looper;
+ auto dialog = new WaitingDialog(_("Processing"), nullptr);
+ dialog->show();
+ auto* gpgProcess = new QProcess(&looper);
+ gpgProcess->setProcessChannelMode(QProcess::MergedChannels);
+
+ connect(gpgProcess, qOverload<int, QProcess::ExitStatus>(&QProcess::finished),
+ &looper, &QEventLoop::quit);
+ connect(gpgProcess, qOverload<int, QProcess::ExitStatus>(&QProcess::finished),
+ dialog, &WaitingDialog::deleteLater);
+ connect(gpgProcess, &QProcess::errorOccurred, &looper, &QEventLoop::quit);
+ connect(gpgProcess, &QProcess::started,
+ []() -> void { LOG(ERROR) << "Gpg Process Started Success"; });
+ connect(gpgProcess, &QProcess::readyReadStandardOutput,
+ [interact_func, gpgProcess]() { interact_func(gpgProcess); });
+ connect(gpgProcess, &QProcess::errorOccurred, this, [=]() -> void {
+ LOG(ERROR) << "Error in Process";
+ dialog->close();
+ QMessageBox::critical(nullptr, _("Failure"),
+ _("Failed to execute command."));
+ });
+ connect(gpgProcess, qOverload<int, QProcess::ExitStatus>(&QProcess::finished),
+ this, [=](int, QProcess::ExitStatus status) {
+ dialog->close();
+ if (status == QProcess::NormalExit)
+ QMessageBox::information(nullptr, _("Success"),
+ _("Succeed in executing command."));
+ else
+ QMessageBox::information(nullptr, _("Warning"),
+ _("Finished executing command."));
+ });
+
+ gpgProcess->setProgram(GpgContext::GetInstance().GetInfo().AppPath.c_str());
+ gpgProcess->setArguments(arguments);
+ gpgProcess->start();
+ looper.exec();
+ dialog->close();
+ dialog->deleteLater();
+}
+
+} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/UserInterfaceUtils.h b/src/ui/UserInterfaceUtils.h
new file mode 100644
index 00000000..df974257
--- /dev/null
+++ b/src/ui/UserInterfaceUtils.h
@@ -0,0 +1,82 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_USER_INTERFACE_UTILS_H
+#define GPGFRONTEND_USER_INTERFACE_UTILS_H
+
+#include "ui/GpgFrontendUI.h"
+
+namespace GpgFrontend {
+class ResultAnalyse;
+}
+
+namespace GpgFrontend::UI {
+
+class InfoBoardWidget;
+class TextEdit;
+
+void refresh_info_board(InfoBoardWidget* info_board, int status,
+ const std::string& report_text);
+
+void process_result_analyse(TextEdit* edit, InfoBoardWidget* info_board,
+ const ResultAnalyse& result_analyse);
+
+void process_result_analyse(TextEdit* edit, InfoBoardWidget* info_board,
+ const ResultAnalyse& result_analyse_a,
+ const ResultAnalyse& result_analyse_b);
+
+void process_operation(QWidget* parent, const std::string& waiting_title,
+ const std::function<void()>& func);
+
+class CommonUtils : public QWidget {
+ Q_OBJECT
+ public:
+ static CommonUtils* GetInstance();
+
+ CommonUtils();
+
+ signals:
+ void signalKeyStatusUpdated();
+
+ public slots:
+
+ void slotImportKeys(QWidget* parent, const std::string& in_buffer);
+
+ void slotImportKeyFromFile(QWidget* parent);
+
+ void slotImportKeyFromKeyServer(QWidget* parent);
+
+ void slotImportKeyFromClipboard(QWidget* parent);
+
+ void slotExecuteGpgCommand(
+ const QStringList& arguments,
+ const std::function<void(QProcess*)>& interact_func);
+
+ private:
+ static std::unique_ptr<CommonUtils> _instance;
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_USER_INTERFACE_UTILS_H
diff --git a/src/ui/VerifyDetailsDialog.cpp b/src/ui/VerifyDetailsDialog.cpp
index 641c09e9..1ad9d996 100644
--- a/src/ui/VerifyDetailsDialog.cpp
+++ b/src/ui/VerifyDetailsDialog.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,60 +24,74 @@
#include "ui/VerifyDetailsDialog.h"
-VerifyDetailsDialog::VerifyDetailsDialog(QWidget *parent, GpgME::GpgContext *ctx, KeyList *keyList, gpg_error_t error,
- gpgme_verify_result_t result) :
- QDialog(parent), mCtx(ctx), mKeyList(keyList), sign(result->signatures), error(error) {
+#include <boost/format.hpp>
+namespace GpgFrontend::UI {
- this->setWindowTitle(tr("Signature Details"));
+VerifyDetailsDialog::VerifyDetailsDialog(QWidget* parent, KeyList* keyList,
+ GpgError error, GpgVerifyResult result)
+ : QDialog(parent),
+ mKeyList(keyList),
+ mResult(std::move(result)),
+ error(error) {
+ this->setWindowTitle(_("Signature Details"));
- connect(mCtx, SIGNAL(signalKeyInfoChanged()), this, SLOT(slotRefresh()));
- mainLayout = new QHBoxLayout();
- this->setLayout(mainLayout);
+ mainLayout = new QHBoxLayout();
+ this->setLayout(mainLayout);
- slotRefresh();
+ slotRefresh();
- this->exec();
+ this->exec();
}
void VerifyDetailsDialog::slotRefresh() {
+ mVbox = new QWidget();
+ auto* mVboxLayout = new QVBoxLayout(mVbox);
+ mainLayout->addWidget(mVbox);
- mVbox = new QWidget();
- auto *mVboxLayout = new QVBoxLayout(mVbox);
- mainLayout->addWidget(mVbox);
-
- // Button Box for close button
- buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
- connect(buttonBox, SIGNAL(rejected()), this, SLOT(close()));
-
- mVboxLayout->addWidget(new QLabel(tr("Status: ") + gpgme_strerror(error)));
-
- if (sign == nullptr) {
- mVboxLayout->addWidget(new QLabel(tr("No valid input found")));
- mVboxLayout->addWidget(buttonBox);
- return;
- }
-
- // Get timestamp of signature of current text
- QDateTime timestamp;
- timestamp.setTime_t(sign->timestamp);
-
- // Set the title widget depending on sign status
- if (gpg_err_code(sign->status) == GPG_ERR_BAD_SIGNATURE) {
- mVboxLayout->addWidget(new QLabel(tr("Error Validating signature")));
- } else if (mInputSignature != nullptr) {
- mVboxLayout->addWidget(new QLabel(
- tr("File was signed on %1 <br/> It Contains:<br/><br/>").arg(QLocale::system().toString(timestamp))));
- } else {
- mVboxLayout->addWidget(new QLabel(tr("Signed on %1 <br/> It Contains:<br /><br/>").arg(
- QLocale::system().toString(timestamp))));
- }
- // Add informationbox for every single key
- while (sign) {
- auto *sbox = new VerifyKeyDetailBox(this, mCtx, mKeyList, sign);
- sign = sign->next;
- mVboxLayout->addWidget(sbox);
- }
+ // Button Box for close button
+ buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
+ connect(buttonBox, SIGNAL(rejected()), this, SLOT(close()));
+ mVboxLayout->addWidget(new QLabel(QString::fromStdString(
+ std::string(_("Status")) + ": " + gpgme_strerror(error))));
+
+ auto sign = mResult->signatures;
+
+ if (sign == nullptr) {
+ mVboxLayout->addWidget(new QLabel(_("No valid input found")));
mVboxLayout->addWidget(buttonBox);
+ return;
+ }
+
+ // Get timestamp of signature of current text
+ QDateTime timestamp;
+ timestamp.setTime_t(sign->timestamp);
+
+ // Set the title widget depending on sign status
+ if (gpg_err_code(sign->status) == GPG_ERR_BAD_SIGNATURE) {
+ mVboxLayout->addWidget(new QLabel(_("Error Validating signature")));
+ } else if (mInputSignature != nullptr) {
+ const auto info = (boost::format(_("File was signed on %1%")) %
+ QLocale::system().toString(timestamp).toStdString())
+ .str() +
+ "<br/>" + _("It Contains") + ": " + "<br/><br/>";
+ mVboxLayout->addWidget(new QLabel(info.c_str()));
+ } else {
+ const auto info = (boost::format(_("Signed on %1%")) %
+ QLocale::system().toString(timestamp).toStdString())
+ .str() +
+ "<br/>" + _("It Contains") + ": " + "<br/><br/>";
+ mVboxLayout->addWidget(new QLabel(info.c_str()));
+ }
+ // Add information box for every single key
+ while (sign) {
+ auto* sign_box = new VerifyKeyDetailBox(this, mKeyList, sign);
+ sign = sign->next;
+ mVboxLayout->addWidget(sign_box);
+ }
+
+ mVboxLayout->addWidget(buttonBox);
}
+
+} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/VerifyDetailsDialog.h b/src/ui/VerifyDetailsDialog.h
new file mode 100644
index 00000000..3de4a56f
--- /dev/null
+++ b/src/ui/VerifyDetailsDialog.h
@@ -0,0 +1,57 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef __VERIFYDETAILSDIALOG_H__
+#define __VERIFYDETAILSDIALOG_H__
+
+#include "ui/GpgFrontendUI.h"
+#include "ui/widgets/EditorPage.h"
+#include "ui/widgets/VerifyKeyDetailBox.h"
+
+namespace GpgFrontend::UI {
+
+class VerifyDetailsDialog : public QDialog {
+ Q_OBJECT
+ public:
+ explicit VerifyDetailsDialog(QWidget* parent, KeyList* keyList,
+ GpgError error, GpgVerifyResult result);
+
+ private slots:
+
+ void slotRefresh();
+
+ private:
+ KeyList* mKeyList;
+ QHBoxLayout* mainLayout;
+ QWidget* mVbox{};
+ QByteArray* mInputData{}; /** Data to be verified */
+ QByteArray* mInputSignature{}; /** Data to be verified */
+ QDialogButtonBox* buttonBox{};
+ GpgVerifyResult mResult;
+ gpgme_error_t error;
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // __VERIFYDETAILSDIALOG_H__
diff --git a/src/ui/WaitingDialog.cpp b/src/ui/WaitingDialog.cpp
index daccc3ca..a83845ab 100644
--- a/src/ui/WaitingDialog.cpp
+++ b/src/ui/WaitingDialog.cpp
@@ -1,20 +1,73 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
#include "ui/WaitingDialog.h"
-WaitingDialog::WaitingDialog(const QString &title, QWidget *parent) : QDialog(parent) {
- auto *pb = new QProgressBar();
- pb->setRange(0, 0);
- pb->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
- pb->setTextVisible(false);
-
- auto *layout = new QVBoxLayout();
- layout->setContentsMargins(0, 0, 0, 0);
- layout->setSpacing(0);
- layout->addWidget(pb);
- this->setLayout(layout);
-
- this->setModal(true);
- this->setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint);
- this->setWindowTitle(title);
- this->setFixedSize(240, 42);
- this->show();
+namespace GpgFrontend::UI {
+
+WaitingDialog::WaitingDialog(const QString& title, QWidget* parent)
+ : QDialog(parent) {
+ auto* pb = new QProgressBar();
+ pb->setRange(0, 0);
+ pb->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+ pb->setTextVisible(false);
+
+ auto* layout = new QVBoxLayout();
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->setSpacing(0);
+ layout->addWidget(pb);
+ this->setLayout(layout);
+
+ this->setModal(true);
+ this->raise();
+ this->setWindowFlags(Qt::Window | Qt::WindowTitleHint |
+ Qt::CustomizeWindowHint);
+ this->setWindowTitle(title);
+ this->setAttribute(Qt::WA_DeleteOnClose);
+ this->setFixedSize(240, 42);
+
+ if (parentWidget() == nullptr) {
+ 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;
+
+ auto pos = QPoint((screen_width - QWidget::width()) / 2,
+ (screen_height - QWidget::height()) / 2);
+ this->move(pos);
+
+ } else {
+ auto pos = QPoint(parent->x() + (parent->width() - QWidget::width()) / 2,
+ parent->y() + (parent->height() - QWidget::height()) / 2);
+ LOG(INFO) << "pos" << pos.x() << pos.y();
+ this->move(pos);
+ }
+
+ this->show();
}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/WaitingDialog.h b/src/ui/WaitingDialog.h
new file mode 100644
index 00000000..798c2a3c
--- /dev/null
+++ b/src/ui/WaitingDialog.h
@@ -0,0 +1,46 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef __UI_WAITING_DIALOG_H__
+#define __UI_WAITING_DIALOG_H__
+
+#include "ui/GpgFrontendUI.h"
+
+namespace GpgFrontend::UI {
+
+class WaitingDialog : public QDialog {
+ Q_OBJECT
+ public:
+ WaitingDialog(const QString& title, QWidget* parent);
+
+ public slots:
+
+ private slots:
+
+ private:
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // __UI_WAITING_DIALOG_H__
diff --git a/src/ui/Wizard.cpp b/src/ui/Wizard.cpp
index 8b482675..de0107c4 100644
--- a/src/ui/Wizard.cpp
+++ b/src/ui/Wizard.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,234 +24,302 @@
#include "ui/Wizard.h"
-Wizard::Wizard(GpgME::GpgContext *ctx, KeyMgmt *keyMgmt, QWidget *parent)
- : QWizard(parent), appPath(qApp->applicationDirPath()),
- settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", QSettings::IniFormat) {
- mCtx = ctx;
- mKeyMgmt = keyMgmt;
+#include "ui/settings/GlobalSettingStation.h"
- setPage(Page_Intro, new IntroPage(this));
- setPage(Page_Choose, new ChoosePage(this));
- setPage(Page_GenKey, new KeyGenPage(mCtx, this));
- setPage(Page_Conclusion, new ConclusionPage(this));
+namespace GpgFrontend::UI {
+
+Wizard::Wizard(QWidget* parent) : QWizard(parent) {
+ setPage(Page_Intro, new IntroPage(this));
+ setPage(Page_Choose, new ChoosePage(this));
+ setPage(Page_GenKey, new KeyGenPage(this));
+ setPage(Page_Conclusion, new ConclusionPage(this));
#ifndef Q_WS_MAC
- setWizardStyle(ModernStyle);
+ setWizardStyle(ModernStyle);
#endif
- setWindowTitle(tr("First Start Wizard"));
-
- // http://www.flickr.com/photos/laureenp/6141822934/
- setPixmap(QWizard::WatermarkPixmap, QPixmap(":/keys2.jpg"));
- setPixmap(QWizard::LogoPixmap, QPixmap(":/logo_small.png"));
- setPixmap(QWizard::BannerPixmap, QPixmap(":/banner.png"));
-
- setStartId(settings.value("wizard/nextPage", -1).toInt());
- settings.remove("wizard/nextPage");
-
- connect(this, SIGNAL(accepted()), this, SLOT(slotWizardAccepted()));
-
+ setWindowTitle(_("First Start Wizard"));
+
+ // http://www.flickr.com/photos/laureenp/6141822934/
+ setPixmap(QWizard::WatermarkPixmap, QPixmap(":/keys2.jpg"));
+ setPixmap(QWizard::LogoPixmap, QPixmap(":/logo_small.png"));
+ setPixmap(QWizard::BannerPixmap, QPixmap(":/banner.png"));
+
+ auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
+ int next_page_id = -1;
+ try {
+ next_page_id = settings.lookup("wizard.next_page");
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error");
+ }
+ setStartId(next_page_id);
+
+ connect(this, SIGNAL(accepted()), this, SLOT(slotWizardAccepted()));
}
void Wizard::slotWizardAccepted() {
- // Don't show is mapped to show -> negation
- settings.setValue("wizard/showWizard", !field("showWizard").toBool());
-
- if (field("openHelp").toBool()) {
- emit signalOpenHelp("docu.html#content");
- }
-}
-
-IntroPage::IntroPage(QWidget *parent)
- : QWizardPage(parent), appPath(qApp->applicationDirPath()),
- settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", QSettings::IniFormat) {
- setTitle(tr("Getting Started..."));
- setSubTitle(tr("... with GPGFrontend"));
-
- auto *topLabel = new QLabel(tr("Welcome to use GPGFrontend for decrypting and signing text or file!") +
- " <br><br><a href='https://gpgfrontend.pub'>GpgFrontend</a> " +
- tr("is a Powerful, Easy-to-Use, Compact, Cross-Platform, and Installation-Free OpenPGP Crypto Tool.") +
- tr("For brief information have a look at the") +
- " <a href='https://gpgfrontend.pub/index.html#/overview'>" +
- tr("Overview") + "</a> (" +
- tr("by clicking the link, the page will open in the web browser") +
- "). <br>");
- topLabel->setTextFormat(Qt::RichText);
- topLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
- topLabel->setOpenExternalLinks(true);
- topLabel->setWordWrap(true);
-
- // QComboBox for language selection
- auto *langLabel = new QLabel(tr("Choose a Language"));
- langLabel->setWordWrap(true);
-
- languages = SettingsDialog::listLanguages();
- auto *langSelectBox = new QComboBox();
-
- for (const auto &l : languages) {
- langSelectBox->addItem(l);
+ LOG(INFO) << _("Called");
+ // Don't show is mapped to show -> negation
+ try {
+ auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
+ if (!settings.exists("wizard")) {
+ settings.add("wizard", libconfig::Setting::TypeGroup);
}
- // selected entry from config
- QString langKey = settings.value("int/lang").toString();
- QString langValue = languages.value(langKey);
- if (langKey != "") {
- langSelectBox->setCurrentIndex(langSelectBox->findText(langValue));
+ auto& wizard = settings["wizard"];
+ if (!wizard.exists("show_wizard")) {
+ wizard.add("show_wizard", libconfig::Setting::TypeBoolean) = false;
+ } else {
+ wizard["show_wizard"] = false;
}
-
- connect(langSelectBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(slotLangChange(QString)));
-
- // set layout and add widgets
- auto *layout = new QVBoxLayout;
- layout->addWidget(topLabel);
- layout->addWidget(langLabel);
- layout->addWidget(langSelectBox);
- setLayout(layout);
-}
-
-void IntroPage::slotLangChange(const QString &lang) {
- settings.setValue("int/lang", languages.key(lang));
- settings.setValue("wizard/nextPage", this->wizard()->currentId());
- qApp->exit(RESTART_CODE);
+ GlobalSettingStation::GetInstance().Sync();
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error");
+ }
+ if (field("openHelp").toBool()) {
+ emit signalOpenHelp("docu.html#content");
+ }
}
-int IntroPage::nextId() const {
- return Wizard::Page_Choose;
+IntroPage::IntroPage(QWidget* parent) : QWizardPage(parent) {
+ setTitle(_("Getting Started..."));
+ setSubTitle(_("... with GpgFrontend"));
+
+ auto* topLabel = new QLabel(
+ QString(_("Welcome to use GpgFrontend for decrypting and signing text or "
+ "file!")) +
+ " <br><br><a href='https://gpgfrontend.pub'>GpgFrontend</a> " +
+ _("is a Powerful, Easy-to-Use, Compact, Cross-Platform, and "
+ "Installation-Free OpenPGP Crypto Tool.") +
+ _("For brief information have a look at the") +
+ " <a href='https://gpgfrontend.pub/index.html#/overview'>" +
+ _("Overview") + "</a> (" +
+ _("by clicking the link, the page will open in the web browser") +
+ "). <br>");
+ topLabel->setTextFormat(Qt::RichText);
+ topLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
+ topLabel->setOpenExternalLinks(true);
+ topLabel->setWordWrap(true);
+
+ // QComboBox for language selection
+ auto* langLabel =
+ new QLabel(_("If it supports the language currently being used in your "
+ "system, GpgFrontend will automatically set it."));
+ langLabel->setWordWrap(true);
+
+ languages = SettingsDialog::listLanguages();
+ auto* langSelectBox = new QComboBox();
+
+ for (const auto& l : languages) {
+ langSelectBox->addItem(l);
+ }
+ // selected entry from config
+
+ // auto lang = "";
+ // auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
+ // try {
+ // lang = settings.lookup("general.lang");
+ // } catch (...) {
+ // LOG(INFO) << "Read for general.lang failed";
+ // }
+ //
+ // QString langKey = lang;
+ // QString langValue = languages.value(langKey);
+ // LOG(INFO) << "lang key" << langKey.toStdString() << "lang value"
+ // << langValue.toStdString();
+ // langSelectBox->setCurrentIndex(langSelectBox->findText(langValue));
+
+ // connect(langSelectBox, SIGNAL(currentIndexChanged(QString)), this,
+ // SLOT(slotLangChange(QString)));
+
+ // set layout and add widgets
+ auto* layout = new QVBoxLayout;
+ layout->addWidget(topLabel);
+ layout->addStretch();
+ layout->addWidget(langLabel);
+ // layout->addWidget(langSelectBox);
+
+ setLayout(layout);
}
-ChoosePage::ChoosePage(QWidget *parent)
- : QWizardPage(parent) {
- setTitle(tr("Choose your action..."));
- setSubTitle(tr("...by clicking on the appropriate link."));
-
- auto *keygenLabel = new QLabel(tr("If you have never used GPGFrontend before and also don't own a gpg key yet you "
- "may possibly want to read how to") +
- " <a href=\"https://gpgfrontend.pub/index.html#/manual/generate-key\">"
- + tr("Generate Key") + "</a><hr>");
- keygenLabel->setTextFormat(Qt::RichText);
- keygenLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
- keygenLabel->setOpenExternalLinks(true);
- keygenLabel->setWordWrap(true);
-
- auto *encrDecyTextLabel = new QLabel(
- tr("If you want to learn how to encrypt, decrypt, sign and verify text, you can read ")
- + "<a href=\"https://gpgfrontend.pub/index.html#/manual/encrypt-decrypt-text\">"
- + tr("Encrypt & Decrypt Text") + "</a> " + tr("or")
- + " <a href=\"https://gpgfrontend.pub/index.html#/manual/sign-verify-text\">"
- + tr("Sign & Verify Text")
- + "</a><hr>");
-
- encrDecyTextLabel->setTextFormat(Qt::RichText);
- encrDecyTextLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
- encrDecyTextLabel->setOpenExternalLinks(true);
- encrDecyTextLabel->setWordWrap(true);
-
- auto *signVerifyTextLabel = new QLabel(tr("If you want to operate file, you can read ")
- +
- "<a href=\"https://gpgfrontend.pub/index.html#/manual/encrypt-decrypt-file\">"
- + tr("Encrypt & Sign File") + "</a> " + tr("or")
- +
- " <a href=\"https://gpgfrontend.pub/index.html#/manual/sign-verify-file\">"
- + tr("Sign & Verify File")
- + "</a><hr>");
- signVerifyTextLabel->setTextFormat(Qt::RichText);
- signVerifyTextLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
- signVerifyTextLabel->setOpenExternalLinks(true);
- signVerifyTextLabel->setWordWrap(true);
-
- auto *layout = new QVBoxLayout();
- layout->addWidget(keygenLabel);
- layout->addWidget(encrDecyTextLabel);
- layout->addWidget(signVerifyTextLabel);
- setLayout(layout);
- nextPage = Wizard::Page_Conclusion;
+// void IntroPage::slotLangChange(const QString& lang) {
+// auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
+//
+// if (!settings.exists("general") ||
+// settings.lookup("general").getType() != libconfig::Setting::TypeGroup)
+// settings.add("general", libconfig::Setting::TypeGroup);
+//
+// auto& general = settings["general"];
+// if (!general.exists("lang"))
+// general.add("lang", libconfig::Setting::TypeString) =
+// languages.key(lang).toStdString();
+// else {
+// general["lang"] = languages.key(lang).toStdString();
+// }
+//
+// if (!settings.exists("wizard") ||
+// settings.lookup("wizard").getType() != libconfig::Setting::TypeGroup)
+// settings.add("wizard", libconfig::Setting::TypeGroup);
+//
+// auto& wizard = settings["wizard"];
+// if (!wizard.exists("next_page"))
+// wizard.add("next_page", libconfig::Setting::TypeInt) =
+// this->wizard()->currentId();
+// else {
+// wizard["next_page"] = this->wizard()->currentId();
+// }
+//
+// GlobalSettingStation::GetInstance().Sync();
+//
+// qApp->exit(RESTART_CODE);
+// }
+
+int IntroPage::nextId() const { return Wizard::Page_Choose; }
+
+ChoosePage::ChoosePage(QWidget* parent) : QWizardPage(parent) {
+ setTitle(_("Choose your action..."));
+ setSubTitle(_("...by clicking on the appropriate link."));
+
+ auto* keygenLabel = new QLabel(
+ QString(_(
+ "If you have never used GpgFrontend before and also don't own a gpg "
+ "key yet you "
+ "may possibly want to read how to")) +
+ " <a href=\"https://gpgfrontend.pub/index.html#/manual/generate-key\">" +
+ _("Generate Key") + "</a><hr>");
+ keygenLabel->setTextFormat(Qt::RichText);
+ keygenLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
+ keygenLabel->setOpenExternalLinks(true);
+ keygenLabel->setWordWrap(true);
+
+ auto* encrDecyTextLabel = new QLabel(
+ QString(_(
+ "If you want to learn how to encrypt, decrypt, sign and verify text, "
+ "you can read ")) +
+ "<a "
+ "href=\"https://gpgfrontend.pub/index.html#/manual/"
+ "encrypt-decrypt-text\">" +
+ _("Encrypt & Decrypt Text") + "</a> " + _("or") +
+ " <a "
+ "href=\"https://gpgfrontend.pub/index.html#/manual/sign-verify-text\">" +
+ _("Sign & Verify Text") + "</a><hr>");
+
+ encrDecyTextLabel->setTextFormat(Qt::RichText);
+ encrDecyTextLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
+ encrDecyTextLabel->setOpenExternalLinks(true);
+ encrDecyTextLabel->setWordWrap(true);
+
+ auto* signVerifyTextLabel = new QLabel(
+ QString(_("If you want to operate file, you can read ")) +
+ "<a "
+ "href=\"https://gpgfrontend.pub/index.html#/manual/"
+ "encrypt-decrypt-file\">" +
+ _("Encrypt & Sign File") + "</a> " + _("or") +
+ " <a "
+ "href=\"https://gpgfrontend.pub/index.html#/manual/sign-verify-file\">" +
+ _("Sign & Verify File") + "</a><hr>");
+ signVerifyTextLabel->setTextFormat(Qt::RichText);
+ signVerifyTextLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
+ signVerifyTextLabel->setOpenExternalLinks(true);
+ signVerifyTextLabel->setWordWrap(true);
+
+ auto* layout = new QVBoxLayout();
+ layout->addWidget(keygenLabel);
+ layout->addWidget(encrDecyTextLabel);
+ layout->addWidget(signVerifyTextLabel);
+ setLayout(layout);
+ nextPage = Wizard::Page_Conclusion;
}
-int ChoosePage::nextId() const {
- return nextPage;
-}
+int ChoosePage::nextId() const { return nextPage; }
-void ChoosePage::slotJumpPage(const QString &page) {
- QMetaObject qmo = Wizard::staticMetaObject;
- int index = qmo.indexOfEnumerator("WizardPages");
- QMetaEnum m = qmo.enumerator(index);
+void ChoosePage::slotJumpPage(const QString& page) {
+ QMetaObject qmo = Wizard::staticMetaObject;
+ int index = qmo.indexOfEnumerator("WizardPages");
+ QMetaEnum m = qmo.enumerator(index);
- nextPage = m.keyToValue(page.toUtf8().data());
- wizard()->next();
+ nextPage = m.keyToValue(page.toUtf8().data());
+ wizard()->next();
}
-KeyGenPage::KeyGenPage(GpgME::GpgContext *ctx, QWidget *parent)
- : QWizardPage(parent) {
- mCtx = ctx;
- setTitle(tr("Create a keypair..."));
- setSubTitle(tr("...for decrypting and signing messages"));
- auto *topLabel = new QLabel(tr("You should create a new keypair."
- "The pair consists of a public and a private key.<br>"
- "Other users can use the public key to encrypt messages for you "
- "and verify messages signed by you."
- "You can use the private key to decrypt and sign messages.<br>"
- "For more information have a look at the offline tutorial (which then is shown in the main window):"));
- topLabel->setWordWrap(true);
- auto *linkLabel = new QLabel("<a href=""docu_keygen.html#content"">" + tr("Offline tutorial") + "</a>");
- //linkLabel->setOpenExternalLinks(true);
-
- // connect(linkLabel, SIGNAL(linkActivated(QString)), parentWidget()->parentWidget(), SLOT(openHelp(QString)));
-
- auto *createKeyButtonBox = new QWidget(this);
- auto *createKeyButtonBoxLayout = new QHBoxLayout(createKeyButtonBox);
- auto *createKeyButton = new QPushButton(tr("Create New Key"));
- createKeyButtonBoxLayout->addWidget(createKeyButton);
- createKeyButtonBoxLayout->addStretch(1);
- auto *layout = new QVBoxLayout();
- layout->addWidget(topLabel);
- layout->addWidget(linkLabel);
- layout->addWidget(createKeyButtonBox);
- connect(createKeyButton, SIGNAL(clicked(bool)), this, SLOT(slotGenerateKeyDialog()));
-
- setLayout(layout);
+KeyGenPage::KeyGenPage(QWidget* parent) : QWizardPage(parent) {
+ setTitle(_("Create a keypair..."));
+ setSubTitle(_("...for decrypting and signing messages"));
+ auto* topLabel = new QLabel(
+ _("You should create a new keypair."
+ "The pair consists of a public and a private key.<br>"
+ "Other users can use the public key to encrypt messages for you "
+ "and verify messages signed by you."
+ "You can use the private key to decrypt and sign messages.<br>"
+ "For more information have a look at the offline tutorial (which then "
+ "is shown in the main window):"));
+ topLabel->setWordWrap(true);
+ auto* linkLabel = new QLabel(
+ "<a href="
+ "docu_keygen.html#content"
+ ">" +
+ QString(_("Offline tutorial")) + "</a>");
+ // linkLabel->setOpenExternalLinks(true);
+
+ // connect(linkLabel, SIGNAL(linkActivated(QString)),
+ // parentWidget()->parentWidget(), SLOT(openHelp(QString)));
+
+ auto* createKeyButtonBox = new QWidget(this);
+ auto* createKeyButtonBoxLayout = new QHBoxLayout(createKeyButtonBox);
+ auto* createKeyButton = new QPushButton(_("Create New Key"));
+ createKeyButtonBoxLayout->addWidget(createKeyButton);
+ createKeyButtonBoxLayout->addStretch(1);
+ auto* layout = new QVBoxLayout();
+ layout->addWidget(topLabel);
+ layout->addWidget(linkLabel);
+ layout->addWidget(createKeyButtonBox);
+ connect(createKeyButton, SIGNAL(clicked(bool)), this,
+ SLOT(slotGenerateKeyDialog()));
+
+ setLayout(layout);
}
-int KeyGenPage::nextId() const {
- return Wizard::Page_Conclusion;
-}
+int KeyGenPage::nextId() const { return Wizard::Page_Conclusion; }
void KeyGenPage::slotGenerateKeyDialog() {
- qDebug() << "Try Opening KeyGenDialog";
- auto *keyGenDialog = new KeyGenDialog(mCtx, this);
- keyGenDialog->show();
- wizard()->next();
+ LOG(INFO) << "Try Opening KeyGenDialog";
+ (new KeyGenDialog(this))->show();
+ wizard()->next();
}
-ConclusionPage::ConclusionPage(QWidget *parent)
- : QWizardPage(parent) {
- setTitle(tr("Ready."));
- setSubTitle(tr("Have fun with GPGFrontend!"));
-
- auto *bottomLabel = new QLabel(tr("You are ready to use GPGFrontend now.<br><br>") +
- "<a href=\"https://saturneric.github.io/GpgFrontend/index.html#/overview\">"
- + tr("The Online Document") + "</a>"
- +
- tr(" will get you started with GPGFrontend. It will open in the main window.<br>"));
-
- bottomLabel->setTextFormat(Qt::RichText);
- bottomLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
- bottomLabel->setOpenExternalLinks(true);
- bottomLabel->setWordWrap(true);
-
- openHelpCheckBox = new QCheckBox(tr("Open offline help."));
- openHelpCheckBox->setChecked(Qt::Checked);
-
- dontShowWizardCheckBox = new QCheckBox(tr("Dont show the wizard again."));
- dontShowWizardCheckBox->setChecked(Qt::Checked);
-
- registerField("showWizard", dontShowWizardCheckBox);
- // registerField("openHelp", openHelpCheckBox);
-
- auto *layout = new QVBoxLayout;
- layout->addWidget(bottomLabel);
- // layout->addWidget(openHelpCheckBox);
- layout->addWidget(dontShowWizardCheckBox);
- setLayout(layout);
- setVisible(true);
+ConclusionPage::ConclusionPage(QWidget* parent) : QWizardPage(parent) {
+ setTitle(_("Ready."));
+ setSubTitle(_("Have fun with GpgFrontend!"));
+
+ auto* bottomLabel =
+ new QLabel(QString(_("You are ready to use GpgFrontend now.<br><br>")) +
+ "<a "
+ "href=\"https://saturneric.github.io/GpgFrontend/index.html#/"
+ "overview\">" +
+ _("The Online Document") + "</a>" +
+ _(" will get you started with GpgFrontend. It will open in "
+ "the main window.") +
+ "<br>");
+
+ bottomLabel->setTextFormat(Qt::RichText);
+ bottomLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
+ bottomLabel->setOpenExternalLinks(true);
+ bottomLabel->setWordWrap(true);
+
+ openHelpCheckBox = new QCheckBox(_("Open offline help."));
+ openHelpCheckBox->setChecked(Qt::Checked);
+
+ dontShowWizardCheckBox = new QCheckBox(_("Dont show the wizard again."));
+ dontShowWizardCheckBox->setChecked(Qt::Checked);
+
+ registerField("showWizard", dontShowWizardCheckBox);
+ // registerField("openHelp", openHelpCheckBox);
+
+ auto* layout = new QVBoxLayout;
+ layout->addWidget(bottomLabel);
+ // layout->addWidget(openHelpCheckBox);
+ layout->addWidget(dontShowWizardCheckBox);
+ setLayout(layout);
+ setVisible(true);
}
-int ConclusionPage::nextId() const {
- return -1;
-}
+int ConclusionPage::nextId() const { return -1; }
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/Wizard.h b/src/ui/Wizard.h
new file mode 100644
index 00000000..8d7395db
--- /dev/null
+++ b/src/ui/Wizard.h
@@ -0,0 +1,114 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef WIZARD_H
+#define WIZARD_H
+
+#include "gpg/GpgConstants.h"
+#include "ui/GpgFrontendUI.h"
+#include "ui/KeyMgmt.h"
+#include "ui/keygen/KeygenDialog.h"
+#include "ui/settings/SettingsDialog.h"
+
+namespace GpgFrontend::UI {
+
+class Wizard : public QWizard {
+ Q_OBJECT
+ Q_ENUMS(WizardPages)
+
+ public:
+ enum WizardPages { Page_Intro, Page_Choose, Page_GenKey, Page_Conclusion };
+
+ Wizard(QWidget* parent = nullptr);
+
+ private slots:
+
+ void slotWizardAccepted();
+
+ signals:
+
+ void signalOpenHelp(QString page);
+};
+
+class IntroPage : public QWizardPage {
+ Q_OBJECT
+
+ public:
+ explicit IntroPage(QWidget* parent = nullptr);
+
+ QHash<QString, QString> languages;
+
+ [[nodiscard]] int nextId() const override;
+
+ private:
+ private slots:
+
+ // void slotLangChange(const QString& lang);
+};
+
+class ChoosePage : public QWizardPage {
+ Q_OBJECT
+
+ public:
+ explicit ChoosePage(QWidget* parent = nullptr);
+
+ private slots:
+
+ void slotJumpPage(const QString& page);
+
+ private:
+ [[nodiscard]] int nextId() const override;
+
+ int nextPage;
+};
+
+class KeyGenPage : public QWizardPage {
+ Q_OBJECT
+
+ public:
+ explicit KeyGenPage(QWidget* parent = nullptr);
+
+ [[nodiscard]] int nextId() const override;
+
+ private slots:
+
+ void slotGenerateKeyDialog();
+};
+
+class ConclusionPage : public QWizardPage {
+ Q_OBJECT
+
+ public:
+ explicit ConclusionPage(QWidget* parent = nullptr);
+
+ [[nodiscard]] int nextId() const override;
+
+ private:
+ QCheckBox* dontShowWizardCheckBox;
+ QCheckBox* openHelpCheckBox;
+};
+
+} // namespace GpgFrontend::UI
+
+#endif
diff --git a/src/ui/function/FileReadThread.cpp b/src/ui/function/FileReadThread.cpp
new file mode 100644
index 00000000..a5a861ea
--- /dev/null
+++ b/src/ui/function/FileReadThread.cpp
@@ -0,0 +1,68 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "FileReadThread.h"
+
+#include <boost/filesystem.hpp>
+#include <utility>
+
+namespace GpgFrontend::UI {
+
+FileReadThread::FileReadThread(std::string path) : path(std::move(path)) {}
+
+void FileReadThread::run() {
+ LOG(INFO) << "Started";
+ boost::filesystem::path read_file_path(this->path);
+ if (is_regular_file(read_file_path)) {
+ LOG(INFO) << "Read Open";
+
+ auto fp = fopen(read_file_path.string().c_str(), "r");
+ size_t read_size;
+ LOG(INFO) << "Thread Start Reading";
+
+ char buffer[8192];
+ while ((read_size = fread(buffer, sizeof(char), sizeof buffer, fp)) > 0) {
+ // Check isInterruptionRequested
+ if (QThread::currentThread()->isInterruptionRequested()) {
+ LOG(INFO) << "Read Thread isInterruptionRequested ";
+ fclose(fp);
+ return;
+ }
+ LOG(INFO) << "Read Thread Read block size " << read_size;
+ std::string buffer_str(buffer, read_size);
+
+ emit sendReadBlock(QString::fromStdString(buffer_str));
+#ifdef RELEASE
+ QThread::msleep(16);
+#else
+ QThread::msleep(24);
+#endif
+ }
+ fclose(fp);
+ emit readDone();
+ LOG(INFO) << "Thread End Reading";
+ }
+}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/function/FileReadThread.h b/src/ui/function/FileReadThread.h
new file mode 100644
index 00000000..ebfcfb3c
--- /dev/null
+++ b/src/ui/function/FileReadThread.h
@@ -0,0 +1,52 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_FILEREADTHREAD_H
+#define GPGFRONTEND_FILEREADTHREAD_H
+
+#include "ui/GpgFrontendUI.h"
+namespace GpgFrontend::UI {
+
+class FileReadThread : public QThread {
+ Q_OBJECT
+
+ public:
+ explicit FileReadThread(std::string path);
+
+ signals:
+
+ void sendReadBlock(const QString& block);
+
+ void readDone();
+
+ protected:
+ void run() override;
+
+ private:
+ std::string path;
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_FILEREADTHREAD_H
diff --git a/src/ui/function/VersionCheckThread.cpp b/src/ui/function/VersionCheckThread.cpp
new file mode 100644
index 00000000..50a4160e
--- /dev/null
+++ b/src/ui/function/VersionCheckThread.cpp
@@ -0,0 +1,77 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "VersionCheckThread.h"
+
+#include "GpgFrontendBuildInfo.h"
+#include "rapidjson/document.h"
+
+using namespace rapidjson;
+
+namespace GpgFrontend::UI {
+
+void VersionCheckThread::run() {
+ LOG(INFO) << "Start Version Thread to get latest version from Github";
+
+ auto currentVersion = "v" + QString::number(VERSION_MAJOR) + "." +
+ QString::number(VERSION_MINOR) + "." +
+ QString::number(VERSION_PATCH);
+
+ while (mNetworkReply->isRunning()) {
+ QApplication::processEvents();
+ }
+
+ if (mNetworkReply->error() != QNetworkReply::NoError) {
+ LOG(ERROR) << "VersionCheckThread Found Network Error";
+ return;
+ }
+
+ QByteArray bytes = mNetworkReply->readAll();
+
+ Document d;
+ d.Parse(bytes.constData());
+
+ QString latestVersion = d["tag_name"].GetString();
+
+ LOG(INFO) << "Latest Version From Github" << latestVersion.toStdString();
+
+ QRegularExpression re(R"(^[vV](\d+\.)?(\d+\.)?(\*|\d+))");
+ QRegularExpressionMatch match = re.match(latestVersion);
+ if (match.hasMatch()) {
+ latestVersion = match.captured(0); // matched == "23 def"
+ LOG(INFO) << "Latest Version Matched" << latestVersion.toStdString();
+ } else {
+ latestVersion = currentVersion;
+ LOG(WARNING) << "Latest Version Unknown" << latestVersion.toStdString();
+ }
+
+ if (latestVersion != currentVersion) {
+ emit upgradeVersion(currentVersion, latestVersion);
+ }
+}
+
+VersionCheckThread::VersionCheckThread(QNetworkReply* networkReply)
+ : mNetworkReply(networkReply) {}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/function/VersionCheckThread.h b/src/ui/function/VersionCheckThread.h
new file mode 100644
index 00000000..181ee947
--- /dev/null
+++ b/src/ui/function/VersionCheckThread.h
@@ -0,0 +1,52 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_VERSIONCHECKTHREAD_H
+#define GPGFRONTEND_VERSIONCHECKTHREAD_H
+
+#include "ui/GpgFrontendUI.h"
+
+namespace GpgFrontend::UI {
+
+class VersionCheckThread : public QThread {
+ Q_OBJECT
+
+ public:
+ explicit VersionCheckThread(QNetworkReply* networkReply);
+
+ signals:
+
+ void upgradeVersion(const QString& currentVersion,
+ const QString& latestVersion);
+
+ protected:
+ void run() override;
+
+ private:
+ QNetworkReply* mNetworkReply;
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_VERSIONCHECKTHREAD_H
diff --git a/src/ui/help/AboutDialog.cpp b/src/ui/help/AboutDialog.cpp
index 8fb504db..7358ced5 100644
--- a/src/ui/help/AboutDialog.cpp
+++ b/src/ui/help/AboutDialog.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -23,197 +23,218 @@
*/
#include "ui/help/AboutDialog.h"
-#include "GpgFrontendBuildInfo.h"
+#include "GpgFrontendBuildInfo.h"
#include "rapidjson/document.h"
#include "rapidjson/writer.h"
using namespace rapidjson;
-AboutDialog::AboutDialog(int defaultIndex, QWidget *parent)
- : QDialog(parent) {
- this->setWindowTitle(tr("About ") + qApp->applicationName());
+namespace GpgFrontend::UI {
- auto *tabWidget = new QTabWidget;
- auto *infoTab = new InfoTab();
- auto *translatorsTab = new TranslatorsTab();
- updateTab = new UpdateTab();
+AboutDialog::AboutDialog(int defaultIndex, QWidget* parent) : QDialog(parent) {
+ this->setWindowTitle(QString(_("About")) + " " + qApp->applicationName());
- tabWidget->addTab(infoTab, tr("General"));
- tabWidget->addTab(translatorsTab, tr("Translators"));
- tabWidget->addTab(updateTab, tr("Update"));
+ auto* tabWidget = new QTabWidget;
+ auto* infoTab = new InfoTab();
+ auto* translatorsTab = new TranslatorsTab();
+ updateTab = new UpdateTab();
- connect(tabWidget, &QTabWidget::currentChanged, this, [&](int index) {
- qDebug() << "Current Index" << index;
- });
+ tabWidget->addTab(infoTab, _("General"));
+ tabWidget->addTab(translatorsTab, _("Translators"));
+ tabWidget->addTab(updateTab, _("Update"));
- if(defaultIndex < tabWidget->count() && defaultIndex >= 0) {
- tabWidget->setCurrentIndex(defaultIndex);
- }
+ connect(tabWidget, &QTabWidget::currentChanged, this,
+ [&](int index) { qDebug() << "Current Index" << index; });
- auto *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok);
- connect(buttonBox, SIGNAL(accepted()), this, SLOT(close()));
+ if (defaultIndex < tabWidget->count() && defaultIndex >= 0) {
+ tabWidget->setCurrentIndex(defaultIndex);
+ }
- auto *mainLayout = new QVBoxLayout;
- mainLayout->addWidget(tabWidget);
- mainLayout->addWidget(buttonBox);
- setLayout(mainLayout);
+ auto* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok);
+ connect(buttonBox, SIGNAL(accepted()), this, SLOT(close()));
+
+ auto* mainLayout = new QVBoxLayout;
+ mainLayout->addWidget(tabWidget);
+ mainLayout->addWidget(buttonBox);
+ setLayout(mainLayout);
- this->resize(320, 580);
-
- this->show();
+ this->resize(320, 580);
+ this->show();
}
-void AboutDialog::showEvent(QShowEvent *ev) {
- QDialog::showEvent(ev);
- updateTab->getLatestVersion();
+void AboutDialog::showEvent(QShowEvent* ev) {
+ QDialog::showEvent(ev);
+ updateTab->getLatestVersion();
}
-InfoTab::InfoTab(QWidget *parent)
- : QWidget(parent) {
- auto *pixmap = new QPixmap(":gpgfrontend-logo.png");
- auto *text = new QString("<center><h2>" + qApp->applicationName() + "</h2></center>"
- + "<center><b>" + qApp->applicationVersion() + "</b></center>"
- + "<center>" + GIT_VERSION + "</center>"
- + tr("<br><center>GPGFrontend is an easy-to-use, compact, cross-platform, <br>"
- "and installation-free gpg front-end tool.<br>"
- "It visualizes most of the common operations of gpg commands.<br>"
- "It's licensed under the GPL v3<br><br>"
- "<b>Developer:</b><br>"
- "Saturneric<br><br>"
- "If you have any questions or suggestions, raise an issue<br/>"
- "at <a href=\"https://github.com/saturneric/GpgFrontend\">GitHub</a> or send a mail to my mailing list at <a href=\"mailto:[email protected]\">[email protected]</a>.") +
- tr("<br><br> Built with Qt ") + qVersion()
- + tr(" and GPGME ") + GpgME::GpgContext::getGpgmeVersion() +
- tr("<br>Built at ") + BUILD_TIMESTAMP + "</center>");
-
- 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->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);
+InfoTab::InfoTab(QWidget* parent) : QWidget(parent) {
+ auto* pixmap = new QPixmap(":gpgfrontend-logo.png");
+ auto* text = new QString(
+ "<center><h2>" + qApp->applicationName() + "</h2></center>" +
+ "<center><b>" + qApp->applicationVersion() + "</b></center>" +
+ "<center>" + GIT_VERSION + "</center>" +
+ _("<br><center>GpgFrontend is an easy-to-use, compact, cross-platform, "
+ "<br>"
+ "and installation-free gpg front-end tool.<br>"
+ "It visualizes most of the common operations of gpg commands.<br>"
+ "It's licensed under the GPL v3<br><br>"
+ "<b>Developer:</b><br>"
+ "Saturneric<br><br>"
+ "If you have any questions or suggestions, raise an issue<br/>"
+ "at <a href=\"https://github.com/saturneric/GpgFrontend\">GitHub</a> "
+ "or send a mail to my mailing list at <a "
+ "href=\"mailto:[email protected]\">[email protected]</a>.") +
+ "<br><br> " + _("Built with Qt") + " " + qVersion() + " " +
+ _("and GPGME") + " " +
+ GpgFrontend::GpgContext::getGpgmeVersion().c_str() + "<br>" +
+ _("Built at") + " " + BUILD_TIMESTAMP + "</center>");
+
+ 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->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);
}
-TranslatorsTab::TranslatorsTab(QWidget *parent)
- : QWidget(parent) {
- QFile translatorsFile;
- translatorsFile.setFileName(qApp->applicationDirPath() + "/About");
- translatorsFile.open(QIODevice::ReadOnly);
- QByteArray inBuffer = translatorsFile.readAll();
+TranslatorsTab::TranslatorsTab(QWidget* parent) : QWidget(parent) {
+ QFile translatorsFile;
+ translatorsFile.setFileName(qApp->applicationDirPath() + "/About");
+ translatorsFile.open(QIODevice::ReadOnly);
+ QByteArray inBuffer = translatorsFile.readAll();
- auto *label = new QLabel(inBuffer);
- auto *mainLayout = new QVBoxLayout(this);
- mainLayout->addWidget(label);
+ auto* label = new QLabel(inBuffer);
+ auto* mainLayout = new QVBoxLayout(this);
+ mainLayout->addWidget(label);
- setLayout(mainLayout);
+ setLayout(mainLayout);
}
-UpdateTab::UpdateTab(QWidget *parent) {
- auto *pixmap = new QPixmap(":gpgfrontend-logo.png");
- auto *layout = new QGridLayout();
- auto *pixmapLabel = new QLabel();
- pixmapLabel->setPixmap(*pixmap);
- layout->addWidget(pixmapLabel, 0, 0, 1, -1, Qt::AlignCenter);
-
- currentVersion = "v" + QString::number(VERSION_MAJOR) + "."
- + QString::number(VERSION_MINOR) + "."
- + QString::number(VERSION_PATCH);
-
- auto tipsLabel = new QLabel();
- tipsLabel->setText("<center>" +
- tr("It is recommended that you always check the version of GpgFrontend and upgrade to the latest version.") +
- "</center><br><center>" +
- tr("New versions not only represent new features, but also often represent functional and security fixes.") + "</center>");
- tipsLabel->setWordWrap(true);
-
- currentVersionLabel = new QLabel();
- currentVersionLabel->setText("<center>" + tr("Current Version: ") + "<b>" + currentVersion + "</b></center>");
- currentVersionLabel->setWordWrap(true);
-
- latestVersionLabel = new QLabel();
- latestVersionLabel->setWordWrap(true);
-
- upgradeLabel = new QLabel();
- upgradeLabel->setText("<center>" +
- tr("The current version is inconsistent with the latest version on github.") +
- "</center><br><center>" +
- tr("Please click <a href=\"https://github.com/saturneric/GpgFrontend/releases\">here</a> to download the latest version.") + "</center>");
- upgradeLabel->setWordWrap(true);
- upgradeLabel->setOpenExternalLinks(true);
- upgradeLabel->setHidden(true);
-
- pb = new QProgressBar();
- pb->setRange(0, 0);
- pb->setTextVisible(false);
-
- layout->addWidget(tipsLabel, 1, 0, 1, -1);
- layout->addWidget(currentVersionLabel, 2, 0, 1, -1);
- layout->addWidget(latestVersionLabel, 3, 0, 1, -1);
- layout->addWidget(upgradeLabel, 4, 0, 1, -1);
- layout->addWidget(pb, 5, 0, 1, -1);
- layout->addItem(new QSpacerItem(20, 10, QSizePolicy::Minimum,
- QSizePolicy::Fixed), 2, 1, 1, 1);
-
- connect(this, SIGNAL(replyFromUpdateServer(QByteArray)), this, SLOT(processReplyDataFromUpdateServer(QByteArray)));
-
- setLayout(layout);
+UpdateTab::UpdateTab(QWidget* parent) {
+ auto* pixmap = new QPixmap(":gpgfrontend-logo.png");
+ auto* layout = new QGridLayout();
+ auto* pixmapLabel = new QLabel();
+ pixmapLabel->setPixmap(*pixmap);
+ layout->addWidget(pixmapLabel, 0, 0, 1, -1, Qt::AlignCenter);
+
+ currentVersion = "v" + QString::number(VERSION_MAJOR) + "." +
+ QString::number(VERSION_MINOR) + "." +
+ QString::number(VERSION_PATCH);
+
+ auto tipsLabel = new QLabel();
+ tipsLabel->setText(
+ "<center>" +
+ QString(_("It is recommended that you always check the version "
+ "of GpgFrontend and upgrade to the latest version.")) +
+ "</center><br><center>" +
+ _("New versions not only represent new features, but "
+ "also often represent functional and security fixes.") +
+ "</center>");
+ tipsLabel->setWordWrap(true);
+
+ currentVersionLabel = new QLabel();
+ currentVersionLabel->setText("<center>" + QString(_("Current Version")) +
+ _(": ") + "<b>" + currentVersion +
+ "</b></center>");
+ currentVersionLabel->setWordWrap(true);
+
+ latestVersionLabel = new QLabel();
+ latestVersionLabel->setWordWrap(true);
+
+ upgradeLabel = new QLabel();
+ upgradeLabel->setText(
+ "<center>" +
+ QString(
+ _("The current version is inconsistent with the latest version on "
+ "github.")) +
+ "</center><br><center>" + _("Please click") +
+ " <a "
+ "href=\"https://github.com/saturneric/GpgFrontend/releases\">here</a> " +
+ _("to download the latest version.") + "</center>");
+ upgradeLabel->setWordWrap(true);
+ upgradeLabel->setOpenExternalLinks(true);
+ upgradeLabel->setHidden(true);
+
+ pb = new QProgressBar();
+ pb->setRange(0, 0);
+ pb->setTextVisible(false);
+
+ layout->addWidget(tipsLabel, 1, 0, 1, -1);
+ layout->addWidget(currentVersionLabel, 2, 0, 1, -1);
+ layout->addWidget(latestVersionLabel, 3, 0, 1, -1);
+ layout->addWidget(upgradeLabel, 4, 0, 1, -1);
+ layout->addWidget(pb, 5, 0, 1, -1);
+ layout->addItem(
+ new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Fixed), 2, 1,
+ 1, 1);
+
+ connect(this, SIGNAL(replyFromUpdateServer(QByteArray)), this,
+ SLOT(processReplyDataFromUpdateServer(QByteArray)));
+
+ setLayout(layout);
}
void UpdateTab::getLatestVersion() {
+ this->pb->setHidden(false);
- this->pb->setHidden(false);
-
- qDebug() << "Try to get latest version";
+ qDebug() << "Try to get latest version";
- QString baseUrl = "https://api.github.com/repos/saturneric/gpgfrontend/releases/latest";
+ QString baseUrl =
+ "https://api.github.com/repos/saturneric/gpgfrontend/releases/latest";
- auto manager = new QNetworkAccessManager(this);
-
- QNetworkRequest request;
- request.setUrl(QUrl(baseUrl));
- QNetworkReply *replay = manager->get(request);
- auto thread = QThread::create([replay, this]() {
- while(replay->isRunning()) QApplication::processEvents();
- emit replyFromUpdateServer(replay->readAll());
- });
- connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
- thread->start();
+ auto manager = new QNetworkAccessManager(this);
+ QNetworkRequest request;
+ request.setUrl(QUrl(baseUrl));
+ QNetworkReply* replay = manager->get(request);
+ auto thread = QThread::create([replay, this]() {
+ while (replay->isRunning()) QApplication::processEvents();
+ emit replyFromUpdateServer(replay->readAll());
+ });
+ connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
+ thread->start();
}
void UpdateTab::processReplyDataFromUpdateServer(const QByteArray& data) {
+ qDebug() << "Try to Process Reply Data From Update Server";
- qDebug() << "Try to Process Reply Data From Update Server";
-
- this->pb->setHidden(true);
+ this->pb->setHidden(true);
- Document d;
- if (d.Parse(data.constData()).HasParseError() || !d.IsObject()) {
- qDebug() << "VersionCheckThread Found Network Error";
- auto latestVersion = "Unknown";
- latestVersionLabel->setText("<center><b>" + tr("Latest Version From Github: ") + latestVersion + "</b></center>");
- return;
- }
+ Document d;
+ if (d.Parse(data.constData()).HasParseError() || !d.IsObject()) {
+ qDebug() << "VersionCheckThread Found Network Error";
+ auto latestVersion = "Unknown";
+ latestVersionLabel->setText(QString("<center><b>") +
+ _("Latest Version From Github") + ": " +
+ latestVersion + "</b></center>");
+ return;
+ }
- QString latestVersion = d["tag_name"].GetString();
+ QString latestVersion = d["tag_name"].GetString();
- qDebug() << "Latest Version From Github" << latestVersion;
+ qDebug() << "Latest Version From Github" << latestVersion;
- QRegularExpression re(R"(^[vV](\d+\.)?(\d+\.)?(\*|\d+))");
- QRegularExpressionMatch match = re.match(latestVersion);
- if (match.hasMatch()) {
- latestVersion = match.captured(0);
- qDebug() << "Latest Version Matched" << latestVersion;
- } else latestVersion = "Unknown";
+ QRegularExpression re(R"(^[vV](\d+\.)?(\d+\.)?(\*|\d+))");
+ QRegularExpressionMatch match = re.match(latestVersion);
+ if (match.hasMatch()) {
+ latestVersion = match.captured(0);
+ qDebug() << "Latest Version Matched" << latestVersion;
+ } else
+ latestVersion = "Unknown";
- latestVersionLabel->setText("<center><b>" + tr("Latest Version From Github: ") + latestVersion + "</b></center>");
+ latestVersionLabel->setText("<center><b>" +
+ QString(_("Latest Version From Github")) + ": " +
+ latestVersion + "</b></center>");
- if(latestVersion > currentVersion) upgradeLabel->setHidden(false);
+ if (latestVersion > currentVersion) upgradeLabel->setHidden(false);
}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/help/AboutDialog.h b/src/ui/help/AboutDialog.h
new file mode 100644
index 00000000..a7d7099b
--- /dev/null
+++ b/src/ui/help/AboutDialog.h
@@ -0,0 +1,103 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef __ABOUTDIALOG_H__
+#define __ABOUTDIALOG_H__
+
+#include "gpg/GpgContext.h"
+#include "ui/GpgFrontendUI.h"
+namespace GpgFrontend::UI {
+
+/**
+ * @brief Class containing the main tab of about dialog
+ *
+ */
+class InfoTab : public QWidget {
+ Q_OBJECT
+
+ public:
+ explicit InfoTab(QWidget* parent = nullptr);
+};
+
+/**
+ * @brief Class containing the translator tab of about dialog
+ *
+ */
+class TranslatorsTab : public QWidget {
+ Q_OBJECT
+
+ public:
+ explicit TranslatorsTab(QWidget* parent = nullptr);
+};
+
+/**
+ * @brief Class containing the main tab of about dialog
+ *
+ */
+class UpdateTab : public QWidget {
+ Q_OBJECT
+
+ QLabel* currentVersionLabel;
+
+ QLabel* latestVersionLabel;
+
+ QLabel* upgradeLabel;
+
+ QProgressBar* pb;
+
+ QString currentVersion;
+
+ public:
+ explicit UpdateTab(QWidget* parent = nullptr);
+
+ void getLatestVersion();
+
+ private slots:
+ void processReplyDataFromUpdateServer(const QByteArray& data);
+ ;
+
+ signals:
+ void replyFromUpdateServer(QByteArray data);
+};
+
+/**
+ * @brief Class for handling the about dialog
+ *
+ */
+class AboutDialog : public QDialog {
+ Q_OBJECT
+
+ public:
+ explicit AboutDialog(int defaultIndex, QWidget* parent);
+
+ protected:
+ void showEvent(QShowEvent* ev) override;
+
+ private:
+ UpdateTab* updateTab;
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // __ABOUTDIALOG_H__
diff --git a/src/ui/help/VersionCheckThread.cpp b/src/ui/help/VersionCheckThread.cpp
deleted file mode 100644
index bf1bbeda..00000000
--- a/src/ui/help/VersionCheckThread.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * This file is part of GPGFrontend.
- *
- * GPGFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Foobar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from gpg4usb-team.
- * Their source code version also complies with GNU General Public License.
- *
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]> starting on May 12, 2021.
- *
- */
-
-#include "ui/help/VersionCheckThread.h"
-#include "GpgFrontendBuildInfo.h"
-#include "rapidjson/document.h"
-#include "rapidjson/writer.h"
-
-using namespace rapidjson;
-
-void VersionCheckThread::run() {
- qDebug() << "Start Version Thread to get latest version from Github";
-
- auto currentVersion = "v" + QString::number(VERSION_MAJOR) + "."
- + QString::number(VERSION_MINOR) + "."
- + QString::number(VERSION_PATCH);
-
- while(mNetworkReply->isRunning()) {
- QApplication::processEvents();
- }
-
- if(mNetworkReply->error() != QNetworkReply::NoError) {
- qDebug() << "VersionCheckThread Found Network Error";
- return;
- }
-
- QByteArray bytes = mNetworkReply->readAll();
-
- Document d;
- d.Parse(bytes.constData());
-
- QString latestVersion = d["tag_name"].GetString();
-
- qDebug() << "Latest Version From Github" << latestVersion;
-
- QRegularExpression re("^[vV](\\d+\\.)?(\\d+\\.)?(\\*|\\d+)");
- QRegularExpressionMatch match = re.match(latestVersion);
- if (match.hasMatch()) {
- latestVersion = match.captured(0); // matched == "23 def"
- qDebug() << "Latest Version Matched" << latestVersion;
- } else {
- latestVersion = currentVersion;
- qDebug() << "Latest Version Unknown" << latestVersion;
- }
-
- if(latestVersion != currentVersion) {
- emit upgradeVersion(currentVersion, latestVersion);
- }
-
-}
-
-VersionCheckThread::VersionCheckThread(QNetworkReply *networkReply):mNetworkReply(networkReply) {
-
-}
diff --git a/src/ui/keygen/KeygenDialog.cpp b/src/ui/keygen/KeygenDialog.cpp
index 98216dc6..382be5cb 100644
--- a/src/ui/keygen/KeygenDialog.cpp
+++ b/src/ui/keygen/KeygenDialog.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -23,339 +23,358 @@
*/
#include "ui/keygen/KeygenDialog.h"
+
+#include "gpg/function/GpgKeyOpera.h"
+#include "ui/SignalStation.h"
#include "ui/WaitingDialog.h"
-KeyGenDialog::KeyGenDialog(GpgME::GpgContext *ctx, QWidget *parent)
- : QDialog(parent), mCtx(ctx) {
+namespace GpgFrontend::UI {
- buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+KeyGenDialog::KeyGenDialog(QWidget* parent) : QDialog(parent) {
+ buttonBox =
+ new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
- this->setWindowTitle(tr("Generate Key"));
- this->setModal(true);
- generateKeyDialog();
-}
+ this->setWindowTitle(_("Generate Key"));
+ this->setModal(true);
-void KeyGenDialog::generateKeyDialog() {
+ connect(this, SIGNAL(KeyGenerated()), SignalStation::GetInstance(),
+ SIGNAL(KeyDatabaseRefresh()));
- keyUsageGroupBox = create_key_usage_group_box();
+ generateKeyDialog();
+}
- auto *groupGrid = new QGridLayout(this);
- groupGrid->addWidget(create_basic_info_group_box(), 0, 0);
- groupGrid->addWidget(keyUsageGroupBox, 1, 0);
+void KeyGenDialog::generateKeyDialog() {
+ keyUsageGroupBox = create_key_usage_group_box();
- auto *nameList = new QWidget(this);
- nameList->setLayout(groupGrid);
+ auto* groupGrid = new QGridLayout(this);
+ groupGrid->addWidget(create_basic_info_group_box(), 0, 0);
+ groupGrid->addWidget(keyUsageGroupBox, 1, 0);
- auto *vbox2 = new QVBoxLayout();
- vbox2->addWidget(nameList);
- vbox2->addWidget(errorLabel);
- vbox2->addWidget(buttonBox);
+ auto* nameList = new QWidget(this);
+ nameList->setLayout(groupGrid);
- this->setLayout(vbox2);
+ auto* vbox2 = new QVBoxLayout();
+ vbox2->addWidget(nameList);
+ vbox2->addWidget(errorLabel);
+ vbox2->addWidget(buttonBox);
- set_signal_slot();
+ this->setLayout(vbox2);
- refresh_widgets_state();
+ set_signal_slot();
+ refresh_widgets_state();
}
void KeyGenDialog::slotKeyGenAccept() {
- QString errorString = "";
-
+ std::stringstream error_stream;
+
+ /**
+ * check for errors in keygen dialog input
+ */
+ if ((nameEdit->text()).size() < 5) {
+ error_stream << " " << _("Name must contain at least five characters.")
+ << std::endl;
+ }
+ if (emailEdit->text().isEmpty() || !check_email_address(emailEdit->text())) {
+ error_stream << " " << _("Please give a email address.") << std::endl;
+ }
+
+ /**
+ * primary keys should have a reasonable expiration date (no more than 2 years
+ * in the future)
+ */
+ if (dateEdit->dateTime() > QDateTime::currentDateTime().addYears(2)) {
+ error_stream << " " << _("Expiration time no more than 2 years.")
+ << std::endl;
+ }
+
+ auto err_string = error_stream.str();
+
+ if (err_string.empty()) {
/**
- * check for errors in keygen dialog input
+ * create the string for key generation
*/
- if ((nameEdit->text()).size() < 5) {
- errorString.append(tr(" Name must contain at least five characters. \n"));
- } if(emailEdit->text().isEmpty() || !check_email_address(emailEdit->text())) {
- errorString.append(tr(" Please give a email address. \n"));
- }
- /**
- * primary keys should have a reasonable expiration date (no more than 2 years in the future)
- */
- if(dateEdit->dateTime() > QDateTime::currentDateTime().addYears(2)) {
- errorString.append(tr(" Expiration time no more than 2 years. \n"));
- }
-
- if (errorString.isEmpty()) {
- /**
- * create the string for key generation
- */
+ genKeyInfo->setUserid(
+ QString("%1(%3)<%2>")
+ .arg(nameEdit->text(), emailEdit->text(), commentEdit->text())
+ .toStdString());
- genKeyInfo.setUserid(QString("%1 (%3) <%2>").arg(nameEdit->text(), emailEdit->text(), commentEdit->text()));
+ genKeyInfo->setKeySize(keySizeSpinBox->value());
- genKeyInfo.setKeySize(keySizeSpinBox->value());
-
- if (expireCheckBox->checkState()) {
- genKeyInfo.setNonExpired(true);
- } else {
- genKeyInfo.setExpired(dateEdit->dateTime());
- }
+ if (expireCheckBox->checkState()) {
+ genKeyInfo->setNonExpired(true);
+ } else {
+ genKeyInfo->setExpired(
+ boost::posix_time::from_time_t(dateEdit->dateTime().toTime_t())
+ .date());
+ }
- gpgme_error_t error = false;
- auto thread = QThread::create([&]() {
- error = mCtx->generateKey(&genKeyInfo);
- });
- thread->start();
+ gpgme_error_t error = false;
+ auto thread = QThread::create(
+ [&]() { error = GpgKeyOpera::GetInstance().GenerateKey(genKeyInfo); });
+ thread->start();
- auto *dialog = new WaitingDialog("Generating", this);
- dialog->show();
+ auto* dialog = new WaitingDialog("Generating", this);
+ dialog->show();
- while (thread->isRunning()) {
- QCoreApplication::processEvents();
- }
+ while (thread->isRunning()) {
+ QCoreApplication::processEvents();
+ }
- dialog->close();
+ dialog->close();
- if(gpgme_err_code(error) == GPG_ERR_NO_ERROR) {
- QMessageBox::information(this, tr("Success"), tr("The new key pair has been generated."));
- this->close();
- }
- else
- QMessageBox::critical(this, tr("Failure"), tr(gpgme_strerror(error)));
+ if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) {
+ auto* msg_box = new QMessageBox(nullptr);
+ msg_box->setAttribute(Qt::WA_DeleteOnClose);
+ msg_box->setStandardButtons(QMessageBox::Ok);
+ msg_box->setWindowTitle(_("Success"));
+ msg_box->setText(_("The new key pair has been generated."));
+ msg_box->setModal(false);
+ msg_box->open();
+ emit KeyGenerated();
+ this->close();
} else {
- /**
- * create error message
- */
- errorLabel->setAutoFillBackground(true);
- QPalette error = errorLabel->palette();
- error.setColor(QPalette::Window, "#ff8080");
- errorLabel->setPalette(error);
- errorLabel->setText(errorString);
-
- this->show();
+ QMessageBox::critical(this, _("Failure"), _(gpgme_strerror(error)));
}
+
+ } else {
+ /**
+ * create error message
+ */
+ errorLabel->setAutoFillBackground(true);
+ QPalette error = errorLabel->palette();
+ error.setColor(QPalette::Window, "#ff8080");
+ errorLabel->setPalette(error);
+ errorLabel->setText(err_string.c_str());
+
+ this->show();
+ }
}
void KeyGenDialog::slotExpireBoxChanged() {
- if (expireCheckBox->checkState()) {
- dateEdit->setEnabled(false);
- } else {
- dateEdit->setEnabled(true);
- }
+ if (expireCheckBox->checkState()) {
+ dateEdit->setEnabled(false);
+ } else {
+ dateEdit->setEnabled(true);
+ }
}
-QGroupBox *KeyGenDialog::create_key_usage_group_box() {
-
- auto *groupBox = new QGroupBox(this);
- auto *grid = new QGridLayout(this);
+QGroupBox* KeyGenDialog::create_key_usage_group_box() {
+ auto* groupBox = new QGroupBox(this);
+ auto* grid = new QGridLayout(this);
- groupBox->setTitle(tr("Key Usage"));
+ groupBox->setTitle(_("Key Usage"));
- auto* encrypt = new QCheckBox(tr("Encryption"), groupBox);
- encrypt->setTristate(false);
+ auto* encrypt = new QCheckBox(_("Encryption"), groupBox);
+ encrypt->setTristate(false);
- auto* sign = new QCheckBox(tr("Signing"),groupBox);
- sign->setTristate(false);
+ auto* sign = new QCheckBox(_("Signing"), groupBox);
+ sign->setTristate(false);
- auto* cert = new QCheckBox(tr("Certification"),groupBox);
- cert->setTristate(false);
+ auto* cert = new QCheckBox(_("Certification"), groupBox);
+ cert->setTristate(false);
- auto* auth = new QCheckBox(tr("Authentication"), groupBox);
- auth->setTristate(false);
+ auto* auth = new QCheckBox(_("Authentication"), groupBox);
+ auth->setTristate(false);
- keyUsageCheckBoxes.push_back(encrypt);
- keyUsageCheckBoxes.push_back(sign);
- keyUsageCheckBoxes.push_back(cert);
- keyUsageCheckBoxes.push_back(auth);
+ keyUsageCheckBoxes.push_back(encrypt);
+ keyUsageCheckBoxes.push_back(sign);
+ keyUsageCheckBoxes.push_back(cert);
+ keyUsageCheckBoxes.push_back(auth);
- grid->addWidget(encrypt, 0, 0);
- grid->addWidget(sign, 0, 1);
- grid->addWidget(cert, 1, 0);
- grid->addWidget(auth, 1, 1);
+ grid->addWidget(encrypt, 0, 0);
+ grid->addWidget(sign, 0, 1);
+ grid->addWidget(cert, 1, 0);
+ grid->addWidget(auth, 1, 1);
- groupBox->setLayout(grid);
+ groupBox->setLayout(grid);
- return groupBox;
+ return groupBox;
}
void KeyGenDialog::slotEncryptionBoxChanged(int state) {
- if(state == 0) {
- genKeyInfo.setAllowEncryption(false);
- } else {
- genKeyInfo.setAllowEncryption(true);
- }
+ if (state == 0) {
+ genKeyInfo->setAllowEncryption(false);
+ } else {
+ genKeyInfo->setAllowEncryption(true);
+ }
}
void KeyGenDialog::slotSigningBoxChanged(int state) {
- if(state == 0) {
- genKeyInfo.setAllowSigning(false);
- } else {
- genKeyInfo.setAllowSigning(true);
- }
+ if (state == 0) {
+ genKeyInfo->setAllowSigning(false);
+ } else {
+ genKeyInfo->setAllowSigning(true);
+ }
}
void KeyGenDialog::slotCertificationBoxChanged(int state) {
- if(state == 0) {
- genKeyInfo.setAllowCertification(false);
- } else {
- genKeyInfo.setAllowCertification(true);
- }
+ if (state == 0) {
+ genKeyInfo->setAllowCertification(false);
+ } else {
+ genKeyInfo->setAllowCertification(true);
+ }
}
void KeyGenDialog::slotAuthenticationBoxChanged(int state) {
- if(state == 0) {
- genKeyInfo.setAllowAuthentication(false);
- } else {
- genKeyInfo.setAllowAuthentication(true);
- }
+ if (state == 0) {
+ genKeyInfo->setAllowAuthentication(false);
+ } else {
+ genKeyInfo->setAllowAuthentication(true);
+ }
}
void KeyGenDialog::slotActivatedKeyType(int index) {
+ qDebug() << "key type index changed " << index;
- qDebug() << "key type index changed " << index;
-
- genKeyInfo.setAlgo(this->keyTypeComboBox->itemText(index));
- refresh_widgets_state();
+ genKeyInfo->setAlgo(this->keyTypeComboBox->itemText(index).toStdString());
+ refresh_widgets_state();
}
void KeyGenDialog::refresh_widgets_state() {
-
- qDebug() << "refresh_widgets_state called";
-
- if(genKeyInfo.isAllowEncryption())
- keyUsageCheckBoxes[0]->setCheckState(Qt::CheckState::Checked);
- else
- keyUsageCheckBoxes[0]->setCheckState(Qt::CheckState::Unchecked);
-
- if(genKeyInfo.isAllowChangeEncryption())
- keyUsageCheckBoxes[0]->setDisabled(false);
- else
- keyUsageCheckBoxes[0]->setDisabled(true);
-
-
- if(genKeyInfo.isAllowSigning())
- keyUsageCheckBoxes[1]->setCheckState(Qt::CheckState::Checked);
- else
- keyUsageCheckBoxes[1]->setCheckState(Qt::CheckState::Unchecked);
-
- if(genKeyInfo.isAllowChangeSigning())
- keyUsageCheckBoxes[1]->setDisabled(false);
- else
- keyUsageCheckBoxes[1]->setDisabled(true);
-
-
- if(genKeyInfo.isAllowCertification())
- keyUsageCheckBoxes[2]->setCheckState(Qt::CheckState::Checked);
- else
- keyUsageCheckBoxes[2]->setCheckState(Qt::CheckState::Unchecked);
-
- if(genKeyInfo.isAllowChangeCertification())
- keyUsageCheckBoxes[2]->setDisabled(false);
- else
- keyUsageCheckBoxes[2]->setDisabled(true);
-
-
- if(genKeyInfo.isAllowAuthentication())
- keyUsageCheckBoxes[3]->setCheckState(Qt::CheckState::Checked);
- else
- keyUsageCheckBoxes[3]->setCheckState(Qt::CheckState::Unchecked);
-
- if(genKeyInfo.isAllowChangeAuthentication())
- keyUsageCheckBoxes[3]->setDisabled(false);
- else
- keyUsageCheckBoxes[3]->setDisabled(true);
-
-
-
- if(genKeyInfo.isAllowNoPassPhrase())
- noPassPhraseCheckBox->setDisabled(false);
- else
- noPassPhraseCheckBox->setDisabled(true);
-
-
- keySizeSpinBox->setRange(genKeyInfo.getSuggestMinKeySize(), genKeyInfo.getSuggestMaxKeySize());
- keySizeSpinBox->setValue(genKeyInfo.getKeySize());
- keySizeSpinBox->setSingleStep(genKeyInfo.getSizeChangeStep());
-
-
+ qDebug() << "refresh_widgets_state called";
+
+ if (genKeyInfo->isAllowEncryption())
+ keyUsageCheckBoxes[0]->setCheckState(Qt::CheckState::Checked);
+ else
+ keyUsageCheckBoxes[0]->setCheckState(Qt::CheckState::Unchecked);
+
+ if (genKeyInfo->isAllowChangeEncryption())
+ keyUsageCheckBoxes[0]->setDisabled(false);
+ else
+ keyUsageCheckBoxes[0]->setDisabled(true);
+
+ if (genKeyInfo->isAllowSigning())
+ keyUsageCheckBoxes[1]->setCheckState(Qt::CheckState::Checked);
+ else
+ keyUsageCheckBoxes[1]->setCheckState(Qt::CheckState::Unchecked);
+
+ if (genKeyInfo->isAllowChangeSigning())
+ keyUsageCheckBoxes[1]->setDisabled(false);
+ else
+ keyUsageCheckBoxes[1]->setDisabled(true);
+
+ if (genKeyInfo->isAllowCertification())
+ keyUsageCheckBoxes[2]->setCheckState(Qt::CheckState::Checked);
+ else
+ keyUsageCheckBoxes[2]->setCheckState(Qt::CheckState::Unchecked);
+
+ if (genKeyInfo->isAllowChangeCertification())
+ keyUsageCheckBoxes[2]->setDisabled(false);
+ else
+ keyUsageCheckBoxes[2]->setDisabled(true);
+
+ if (genKeyInfo->isAllowAuthentication())
+ keyUsageCheckBoxes[3]->setCheckState(Qt::CheckState::Checked);
+ else
+ keyUsageCheckBoxes[3]->setCheckState(Qt::CheckState::Unchecked);
+
+ if (genKeyInfo->isAllowChangeAuthentication())
+ keyUsageCheckBoxes[3]->setDisabled(false);
+ else
+ keyUsageCheckBoxes[3]->setDisabled(true);
+
+ if (genKeyInfo->isAllowNoPassPhrase())
+ noPassPhraseCheckBox->setDisabled(false);
+ else
+ noPassPhraseCheckBox->setDisabled(true);
+
+ keySizeSpinBox->setRange(genKeyInfo->getSuggestMinKeySize(),
+ genKeyInfo->getSuggestMaxKeySize());
+ keySizeSpinBox->setValue(genKeyInfo->getKeySize());
+ keySizeSpinBox->setSingleStep(genKeyInfo->getSizeChangeStep());
}
void KeyGenDialog::set_signal_slot() {
-
- connect(buttonBox, SIGNAL(accepted()), this, SLOT(slotKeyGenAccept()));
- connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
-
- connect(expireCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotExpireBoxChanged()));
-
- connect(keyUsageCheckBoxes[0], SIGNAL(stateChanged(int)), this, SLOT(slotEncryptionBoxChanged(int)));
- connect(keyUsageCheckBoxes[1], SIGNAL(stateChanged(int)), this, SLOT(slotSigningBoxChanged(int)));
- connect(keyUsageCheckBoxes[2], SIGNAL(stateChanged(int)), this, SLOT(slotCertificationBoxChanged(int)));
- connect(keyUsageCheckBoxes[3], SIGNAL(stateChanged(int)), this, SLOT(slotAuthenticationBoxChanged(int)));
-
- connect(keyTypeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotActivatedKeyType(int)));
-
- connect(noPassPhraseCheckBox, &QCheckBox::stateChanged, this, [this](int state) -> void {
- if(state == 0) {
- genKeyInfo.setNonPassPhrase(false);
- } else {
- genKeyInfo.setNonPassPhrase(true);
- }
-
- });
-
+ connect(buttonBox, SIGNAL(accepted()), this, SLOT(slotKeyGenAccept()));
+ connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+
+ connect(expireCheckBox, SIGNAL(stateChanged(int)), this,
+ SLOT(slotExpireBoxChanged()));
+
+ connect(keyUsageCheckBoxes[0], SIGNAL(stateChanged(int)), this,
+ SLOT(slotEncryptionBoxChanged(int)));
+ connect(keyUsageCheckBoxes[1], SIGNAL(stateChanged(int)), this,
+ SLOT(slotSigningBoxChanged(int)));
+ connect(keyUsageCheckBoxes[2], SIGNAL(stateChanged(int)), this,
+ SLOT(slotCertificationBoxChanged(int)));
+ connect(keyUsageCheckBoxes[3], SIGNAL(stateChanged(int)), this,
+ SLOT(slotAuthenticationBoxChanged(int)));
+
+ connect(keyTypeComboBox, SIGNAL(currentIndexChanged(int)), this,
+ SLOT(slotActivatedKeyType(int)));
+
+ connect(noPassPhraseCheckBox, &QCheckBox::stateChanged, this,
+ [this](int state) -> void {
+ if (state == 0) {
+ genKeyInfo->setNonPassPhrase(false);
+ } else {
+ genKeyInfo->setNonPassPhrase(true);
+ }
+ });
}
-bool KeyGenDialog::check_email_address(const QString &str) {
- return re_email.match(str).hasMatch();
+bool KeyGenDialog::check_email_address(const QString& str) {
+ return re_email.match(str).hasMatch();
}
-QGroupBox *KeyGenDialog::create_basic_info_group_box() {
-
- errorLabel = new QLabel(tr(""));
- nameEdit = new QLineEdit(this);
- emailEdit = new QLineEdit(this);
- commentEdit = new QLineEdit(this);
- keySizeSpinBox = new QSpinBox(this);
- keyTypeComboBox = new QComboBox(this);
-
- for(auto &algo : GenKeyInfo::SupportedKeyAlgo) {
- keyTypeComboBox->addItem(algo);
- }
- if(!GenKeyInfo::SupportedKeyAlgo.isEmpty()) {
- keyTypeComboBox->setCurrentIndex(0);
- }
-
- QDateTime maxDateTime = QDateTime::currentDateTime().addYears(2);
-
- dateEdit = new QDateTimeEdit(maxDateTime, this);
- dateEdit->setMinimumDateTime(QDateTime::currentDateTime());
- dateEdit->setMaximumDateTime(maxDateTime);
- dateEdit->setDisplayFormat("dd/MM/yyyy hh:mm:ss");
- dateEdit->setCalendarPopup(true);
- dateEdit->setEnabled(true);
-
- expireCheckBox = new QCheckBox(this);
- expireCheckBox->setCheckState(Qt::Unchecked);
-
- noPassPhraseCheckBox = new QCheckBox(this);
- noPassPhraseCheckBox->setCheckState(Qt::Unchecked);
-
- auto *vbox1 = new QGridLayout;
-
- vbox1->addWidget(new QLabel(tr("Name:")), 0, 0);
- vbox1->addWidget(new QLabel(tr("Email Address:")), 1, 0);
- vbox1->addWidget(new QLabel(tr("Comment:")), 2, 0);
- vbox1->addWidget(new QLabel(tr("Expiration Date:")), 3, 0);
- vbox1->addWidget(new QLabel(tr("Never Expire")), 3, 3);
- vbox1->addWidget(new QLabel(tr("KeySize (in Bit):")), 4, 0);
- vbox1->addWidget(new QLabel(tr("Key Type:")), 5, 0);
- vbox1->addWidget(new QLabel(tr("Non Pass Phrase")), 6, 0);
-
- vbox1->addWidget(nameEdit, 0, 1, 1, 3);
- vbox1->addWidget(emailEdit, 1, 1, 1, 3);
- vbox1->addWidget(commentEdit, 2, 1, 1, 3);
- vbox1->addWidget(dateEdit, 3, 1);
- vbox1->addWidget(expireCheckBox, 3, 2);
- vbox1->addWidget(keySizeSpinBox, 4, 1);
- vbox1->addWidget(keyTypeComboBox, 5, 1);
- vbox1->addWidget(noPassPhraseCheckBox, 6, 1);
-
- auto basicInfoGroupBox = new QGroupBox();
- basicInfoGroupBox->setLayout(vbox1);
- basicInfoGroupBox->setTitle(tr("Basic Information"));
-
- return basicInfoGroupBox;
+QGroupBox* KeyGenDialog::create_basic_info_group_box() {
+ errorLabel = new QLabel();
+ nameEdit = new QLineEdit(this);
+ emailEdit = new QLineEdit(this);
+ commentEdit = new QLineEdit(this);
+ keySizeSpinBox = new QSpinBox(this);
+ keyTypeComboBox = new QComboBox(this);
+
+ for (auto& algo : GenKeyInfo::SupportedKeyAlgo) {
+ keyTypeComboBox->addItem(QString::fromStdString(algo));
+ }
+ if (!GenKeyInfo::SupportedKeyAlgo.empty()) {
+ keyTypeComboBox->setCurrentIndex(0);
+ }
+
+ QDateTime maxDateTime = QDateTime::currentDateTime().addYears(2);
+
+ dateEdit = new QDateTimeEdit(maxDateTime, this);
+ dateEdit->setMinimumDateTime(QDateTime::currentDateTime());
+ dateEdit->setMaximumDateTime(maxDateTime);
+ dateEdit->setDisplayFormat("dd/MM/yyyy hh:mm:ss");
+ dateEdit->setCalendarPopup(true);
+ dateEdit->setEnabled(true);
+
+ expireCheckBox = new QCheckBox(this);
+ expireCheckBox->setCheckState(Qt::Unchecked);
+
+ noPassPhraseCheckBox = new QCheckBox(this);
+ noPassPhraseCheckBox->setCheckState(Qt::Unchecked);
+
+ auto* vbox1 = new QGridLayout;
+
+ vbox1->addWidget(new QLabel(QString(_("Name")) + ": "), 0, 0);
+ vbox1->addWidget(new QLabel(QString(_("Email Address")) + ": "), 1, 0);
+ vbox1->addWidget(new QLabel(QString(_("Comment")) + ": "), 2, 0);
+ vbox1->addWidget(new QLabel(QString(_("Expiration Date")) + ": "), 3, 0);
+ vbox1->addWidget(new QLabel(QString(_("Never Expire")) + ": "), 3, 3);
+ vbox1->addWidget(new QLabel(QString(_("KeySize (in Bit)")) + ": "), 4, 0);
+ vbox1->addWidget(new QLabel(QString(_("Key Type")) + ": "), 5, 0);
+ vbox1->addWidget(new QLabel(QString(_("Non Pass Phrase")) + ": "), 6, 0);
+
+ vbox1->addWidget(nameEdit, 0, 1, 1, 3);
+ vbox1->addWidget(emailEdit, 1, 1, 1, 3);
+ vbox1->addWidget(commentEdit, 2, 1, 1, 3);
+ vbox1->addWidget(dateEdit, 3, 1);
+ vbox1->addWidget(expireCheckBox, 3, 2);
+ vbox1->addWidget(keySizeSpinBox, 4, 1);
+ vbox1->addWidget(keyTypeComboBox, 5, 1);
+ vbox1->addWidget(noPassPhraseCheckBox, 6, 1);
+
+ auto basicInfoGroupBox = new QGroupBox();
+ basicInfoGroupBox->setLayout(vbox1);
+ basicInfoGroupBox->setTitle(_("Basic Information"));
+
+ return basicInfoGroupBox;
}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/keygen/KeygenDialog.h b/src/ui/keygen/KeygenDialog.h
new file mode 100644
index 00000000..c16a2e76
--- /dev/null
+++ b/src/ui/keygen/KeygenDialog.h
@@ -0,0 +1,117 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef __KEYGENDIALOG_H__
+#define __KEYGENDIALOG_H__
+
+#include "gpg/GpgContext.h"
+#include "gpg/GpgGenKeyInfo.h"
+#include "ui/GpgFrontendUI.h"
+
+namespace GpgFrontend::UI {
+
+class KeyGenDialog : public QDialog {
+ Q_OBJECT
+
+ public:
+ /**
+ * @details Constructor of this class
+ *
+ * @param ctx The current GpgME context
+ * @param key The key to show details of
+ * @param parent The parent of this widget
+ */
+ explicit KeyGenDialog(QWidget* parent = nullptr);
+
+ signals:
+ void KeyGenerated();
+
+ private:
+ QGroupBox* create_key_usage_group_box();
+
+ QGroupBox* create_basic_info_group_box();
+
+ QRegularExpression re_email{
+ R"((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\]))"};
+
+ QStringList errorMessages; /** List of errors occuring when checking entries
+ of lineedits */
+ std::unique_ptr<GenKeyInfo> genKeyInfo = std::make_unique<GenKeyInfo>();
+
+ QDialogButtonBox* buttonBox; /** Box for standard buttons */
+ QLabel* errorLabel{}; /** Label containing error message */
+ QLineEdit* nameEdit{}; /** Line edit for the keys name */
+ QLineEdit* emailEdit{}; /** Line edit for the keys email */
+ QLineEdit* commentEdit{}; /** Line edit for the keys comment */
+ QSpinBox* keySizeSpinBox{}; /** Spinbox for the keys size (in bit) */
+ QComboBox* keyTypeComboBox{}; /** Combobox for Key type */
+ QDateTimeEdit* dateEdit{}; /** Date edit for expiration date */
+ QCheckBox* expireCheckBox{}; /** Checkbox, if key should expire */
+ QCheckBox* noPassPhraseCheckBox{};
+
+ QGroupBox* keyUsageGroupBox{}; /** Group of Widgets detecting the usage of the
+ Key **/
+
+ // ENCR, SIGN, CERT, AUTH
+ std::vector<QCheckBox*> keyUsageCheckBoxes;
+
+ void generateKeyDialog();
+
+ /**
+ * @details Refresh widgets state by GenKeyInfo
+ */
+ void refresh_widgets_state();
+
+ void set_signal_slot();
+
+ bool check_email_address(const QString& str);
+
+ private slots:
+
+ /**
+ * @details when expirebox was checked/unchecked, enable/disable the
+ * expiration date box
+ */
+ void slotExpireBoxChanged();
+
+ /**
+ * @details check all lineedits for false entries. Show error, when there is
+ * one, otherwise generate the key
+ */
+ void slotKeyGenAccept();
+
+ void slotEncryptionBoxChanged(int state);
+
+ void slotSigningBoxChanged(int state);
+
+ void slotCertificationBoxChanged(int state);
+
+ void slotAuthenticationBoxChanged(int state);
+
+ void slotActivatedKeyType(int index);
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // __KEYGENDIALOG_H__
diff --git a/src/ui/keygen/SubkeyGenerateDialog.cpp b/src/ui/keygen/SubkeyGenerateDialog.cpp
index 3d709d81..593b1cae 100644
--- a/src/ui/keygen/SubkeyGenerateDialog.cpp
+++ b/src/ui/keygen/SubkeyGenerateDialog.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -23,277 +23,300 @@
*/
#include "ui/keygen/SubkeyGenerateDialog.h"
+
+#include "gpg/function/GpgKeyGetter.h"
+#include "gpg/function/GpgKeyOpera.h"
+#include "ui/SignalStation.h"
#include "ui/WaitingDialog.h"
-SubkeyGenerateDialog::SubkeyGenerateDialog(GpgME::GpgContext *ctx, const GpgKey &key, QWidget *parent)
- : genKeyInfo(true), mCtx(ctx), mKey(key), QDialog(parent) {
+namespace GpgFrontend::UI {
- buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+SubkeyGenerateDialog::SubkeyGenerateDialog(const KeyId& key_id, QWidget* parent)
+ : QDialog(parent), mKey(GpgKeyGetter::GetInstance().GetKey(key_id)) {
+ buttonBox =
+ new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
- keyUsageGroupBox = create_key_usage_group_box();
+ keyUsageGroupBox = create_key_usage_group_box();
- auto *groupGrid = new QGridLayout(this);
- groupGrid->addWidget(create_basic_info_group_box(), 0, 0);
- groupGrid->addWidget(keyUsageGroupBox, 1, 0);
+ auto* groupGrid = new QGridLayout(this);
+ groupGrid->addWidget(create_basic_info_group_box(), 0, 0);
+ groupGrid->addWidget(keyUsageGroupBox, 1, 0);
- auto *nameList = new QWidget(this);
- nameList->setLayout(groupGrid);
+ auto* nameList = new QWidget(this);
+ nameList->setLayout(groupGrid);
- auto *vbox2 = new QVBoxLayout();
- vbox2->addWidget(nameList);
- vbox2->addWidget(errorLabel);
- vbox2->addWidget(buttonBox);
+ auto* vbox2 = new QVBoxLayout();
+ vbox2->addWidget(nameList);
+ vbox2->addWidget(errorLabel);
+ vbox2->addWidget(buttonBox);
- this->setWindowTitle(tr("Generate New Subkey"));
+ this->setWindowTitle(_("Generate New Subkey"));
+ this->setLayout(vbox2);
+ this->setModal(true);
- this->setLayout(vbox2);
- this->setModal(true);
+ connect(this, SIGNAL(SubKeyGenerated()), SignalStation::GetInstance(),
+ SIGNAL(KeyDatabaseRefresh()));
- set_signal_slot();
- refresh_widgets_state();
+ set_signal_slot();
+ refresh_widgets_state();
}
-QGroupBox *SubkeyGenerateDialog::create_key_usage_group_box() {
- auto *groupBox = new QGroupBox(this);
- auto *grid = new QGridLayout(this);
+QGroupBox* SubkeyGenerateDialog::create_key_usage_group_box() {
+ auto* groupBox = new QGroupBox(this);
+ auto* grid = new QGridLayout(this);
- groupBox->setTitle("Key Usage");
+ groupBox->setTitle("Key Usage");
- auto* encrypt = new QCheckBox(tr("Encryption"), groupBox);
- encrypt->setTristate(false);
+ auto* encrypt = new QCheckBox(_("Encryption"), groupBox);
+ encrypt->setTristate(false);
- auto* sign = new QCheckBox(tr("Signing"),groupBox);
- sign->setTristate(false);
+ auto* sign = new QCheckBox(_("Signing"), groupBox);
+ sign->setTristate(false);
- auto* cert = new QCheckBox(tr("Certification"),groupBox);
- cert->setTristate(false);
+ auto* cert = new QCheckBox(_("Certification"), groupBox);
+ cert->setTristate(false);
- auto* auth = new QCheckBox(tr("Authentication"), groupBox);
- auth->setTristate(false);
+ auto* auth = new QCheckBox(_("Authentication"), groupBox);
+ auth->setTristate(false);
- keyUsageCheckBoxes.push_back(encrypt);
- keyUsageCheckBoxes.push_back(sign);
- keyUsageCheckBoxes.push_back(cert);
- keyUsageCheckBoxes.push_back(auth);
+ keyUsageCheckBoxes.push_back(encrypt);
+ keyUsageCheckBoxes.push_back(sign);
+ keyUsageCheckBoxes.push_back(cert);
+ keyUsageCheckBoxes.push_back(auth);
- grid->addWidget(encrypt, 0, 0);
- grid->addWidget(sign, 0, 1);
- grid->addWidget(cert, 1, 0);
- grid->addWidget(auth, 1, 1);
+ grid->addWidget(encrypt, 0, 0);
+ grid->addWidget(sign, 0, 1);
+ grid->addWidget(cert, 1, 0);
+ grid->addWidget(auth, 1, 1);
- groupBox->setLayout(grid);
+ groupBox->setLayout(grid);
- return groupBox;
+ return groupBox;
}
-QGroupBox *SubkeyGenerateDialog::create_basic_info_group_box() {
- errorLabel = new QLabel(tr(""));
- keySizeSpinBox = new QSpinBox(this);
- keyTypeComboBox = new QComboBox(this);
+QGroupBox* SubkeyGenerateDialog::create_basic_info_group_box() {
+ errorLabel = new QLabel();
+ keySizeSpinBox = new QSpinBox(this);
+ keyTypeComboBox = new QComboBox(this);
- for(auto &algo : GenKeyInfo::SupportedSubkeyAlgo) {
- keyTypeComboBox->addItem(algo);
- }
- if(!GenKeyInfo::SupportedKeyAlgo.isEmpty()) {
- keyTypeComboBox->setCurrentIndex(0);
- }
+ for (auto& algo : GenKeyInfo::SupportedSubkeyAlgo) {
+ keyTypeComboBox->addItem(QString::fromStdString(algo));
+ }
+ if (!GenKeyInfo::SupportedKeyAlgo.empty()) {
+ keyTypeComboBox->setCurrentIndex(0);
+ }
- QDateTime maxDateTime = QDateTime::currentDateTime().addYears(2);
+ QDateTime maxDateTime = QDateTime::currentDateTime().addYears(2);
- dateEdit = new QDateTimeEdit(maxDateTime, this);
- dateEdit->setMinimumDateTime(QDateTime::currentDateTime());
- dateEdit->setMaximumDateTime(maxDateTime);
- dateEdit->setDisplayFormat("dd/MM/yyyy hh:mm:ss");
- dateEdit->setCalendarPopup(true);
- dateEdit->setEnabled(true);
+ dateEdit = new QDateTimeEdit(maxDateTime, this);
+ dateEdit->setMinimumDateTime(QDateTime::currentDateTime());
+ dateEdit->setMaximumDateTime(maxDateTime);
+ dateEdit->setDisplayFormat("dd/MM/yyyy hh:mm:ss");
+ dateEdit->setCalendarPopup(true);
+ dateEdit->setEnabled(true);
- expireCheckBox = new QCheckBox(this);
- expireCheckBox->setCheckState(Qt::Unchecked);
+ expireCheckBox = new QCheckBox(this);
+ expireCheckBox->setCheckState(Qt::Unchecked);
- auto *vbox1 = new QGridLayout;
+ auto* vbox1 = new QGridLayout;
- vbox1->addWidget(new QLabel(tr("Expiration Date:")), 2, 0);
- vbox1->addWidget(new QLabel(tr("Never Expire")), 2, 3);
- vbox1->addWidget(new QLabel(tr("KeySize (in Bit):")), 1, 0);
- vbox1->addWidget(new QLabel(tr("Key Type:")), 0, 0);
+ vbox1->addWidget(new QLabel(QString(_("Expiration Date")) + ": "), 2, 0);
+ vbox1->addWidget(new QLabel(QString(_("Never Expire")) + ": "), 2, 3);
+ vbox1->addWidget(new QLabel(QString(_("KeySize (in Bit)")) + ": "), 1, 0);
+ vbox1->addWidget(new QLabel(QString(_("Key Type")) + ": "), 0, 0);
- vbox1->addWidget(dateEdit, 2, 1);
- vbox1->addWidget(expireCheckBox, 2, 2);
- vbox1->addWidget(keySizeSpinBox, 1, 1);
- vbox1->addWidget(keyTypeComboBox, 0, 1);
+ vbox1->addWidget(dateEdit, 2, 1);
+ vbox1->addWidget(expireCheckBox, 2, 2);
+ vbox1->addWidget(keySizeSpinBox, 1, 1);
+ vbox1->addWidget(keyTypeComboBox, 0, 1);
- auto basicInfoGroupBox = new QGroupBox();
- basicInfoGroupBox->setLayout(vbox1);
- basicInfoGroupBox->setTitle(tr("Basic Information"));
+ auto basicInfoGroupBox = new QGroupBox();
+ basicInfoGroupBox->setLayout(vbox1);
+ basicInfoGroupBox->setTitle(_("Basic Information"));
- return basicInfoGroupBox;
+ return basicInfoGroupBox;
}
void SubkeyGenerateDialog::set_signal_slot() {
- connect(buttonBox, SIGNAL(accepted()), this, SLOT(slotKeyGenAccept()));
- connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
-
- connect(expireCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotExpireBoxChanged()));
-
- connect(keyUsageCheckBoxes[0], SIGNAL(stateChanged(int)), this, SLOT(slotEncryptionBoxChanged(int)));
- connect(keyUsageCheckBoxes[1], SIGNAL(stateChanged(int)), this, SLOT(slotSigningBoxChanged(int)));
- connect(keyUsageCheckBoxes[2], SIGNAL(stateChanged(int)), this, SLOT(slotCertificationBoxChanged(int)));
- connect(keyUsageCheckBoxes[3], SIGNAL(stateChanged(int)), this, SLOT(slotAuthenticationBoxChanged(int)));
-
- connect(keyTypeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotActivatedKeyType(int)));
+ connect(buttonBox, SIGNAL(accepted()), this, SLOT(slotKeyGenAccept()));
+ connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+
+ connect(expireCheckBox, SIGNAL(stateChanged(int)), this,
+ SLOT(slotExpireBoxChanged()));
+
+ connect(keyUsageCheckBoxes[0], SIGNAL(stateChanged(int)), this,
+ SLOT(slotEncryptionBoxChanged(int)));
+ connect(keyUsageCheckBoxes[1], SIGNAL(stateChanged(int)), this,
+ SLOT(slotSigningBoxChanged(int)));
+ connect(keyUsageCheckBoxes[2], SIGNAL(stateChanged(int)), this,
+ SLOT(slotCertificationBoxChanged(int)));
+ connect(keyUsageCheckBoxes[3], SIGNAL(stateChanged(int)), this,
+ SLOT(slotAuthenticationBoxChanged(int)));
+
+ connect(keyTypeComboBox, SIGNAL(currentIndexChanged(int)), this,
+ SLOT(slotActivatedKeyType(int)));
}
void SubkeyGenerateDialog::slotExpireBoxChanged() {
- if (expireCheckBox->checkState()) {
- dateEdit->setEnabled(false);
- } else {
- dateEdit->setEnabled(true);
- }
+ if (expireCheckBox->checkState()) {
+ dateEdit->setEnabled(false);
+ } else {
+ dateEdit->setEnabled(true);
+ }
}
void SubkeyGenerateDialog::refresh_widgets_state() {
- qDebug() << "refresh_widgets_state called";
-
- if(genKeyInfo.isAllowEncryption())
- keyUsageCheckBoxes[0]->setCheckState(Qt::CheckState::Checked);
- else
- keyUsageCheckBoxes[0]->setCheckState(Qt::CheckState::Unchecked);
-
- if(genKeyInfo.isAllowChangeEncryption())
- keyUsageCheckBoxes[0]->setDisabled(false);
- else
- keyUsageCheckBoxes[0]->setDisabled(true);
-
-
- if(genKeyInfo.isAllowSigning())
- keyUsageCheckBoxes[1]->setCheckState(Qt::CheckState::Checked);
- else
- keyUsageCheckBoxes[1]->setCheckState(Qt::CheckState::Unchecked);
-
- if(genKeyInfo.isAllowChangeSigning())
- keyUsageCheckBoxes[1]->setDisabled(false);
- else
- keyUsageCheckBoxes[1]->setDisabled(true);
-
-
- if(genKeyInfo.isAllowCertification())
- keyUsageCheckBoxes[2]->setCheckState(Qt::CheckState::Checked);
- else
- keyUsageCheckBoxes[2]->setCheckState(Qt::CheckState::Unchecked);
-
- if(genKeyInfo.isAllowChangeCertification())
- keyUsageCheckBoxes[2]->setDisabled(false);
- else
- keyUsageCheckBoxes[2]->setDisabled(true);
-
-
- if(genKeyInfo.isAllowAuthentication())
- keyUsageCheckBoxes[3]->setCheckState(Qt::CheckState::Checked);
- else
- keyUsageCheckBoxes[3]->setCheckState(Qt::CheckState::Unchecked);
-
- if(genKeyInfo.isAllowChangeAuthentication())
- keyUsageCheckBoxes[3]->setDisabled(false);
- else
- keyUsageCheckBoxes[3]->setDisabled(true);
-
-
- keySizeSpinBox->setRange(genKeyInfo.getSuggestMinKeySize(), genKeyInfo.getSuggestMaxKeySize());
- keySizeSpinBox->setValue(genKeyInfo.getKeySize());
- keySizeSpinBox->setSingleStep(genKeyInfo.getSizeChangeStep());
-
+ qDebug() << "refresh_widgets_state called";
+
+ if (genKeyInfo->isAllowEncryption())
+ keyUsageCheckBoxes[0]->setCheckState(Qt::CheckState::Checked);
+ else
+ keyUsageCheckBoxes[0]->setCheckState(Qt::CheckState::Unchecked);
+
+ if (genKeyInfo->isAllowChangeEncryption())
+ keyUsageCheckBoxes[0]->setDisabled(false);
+ else
+ keyUsageCheckBoxes[0]->setDisabled(true);
+
+ if (genKeyInfo->isAllowSigning())
+ keyUsageCheckBoxes[1]->setCheckState(Qt::CheckState::Checked);
+ else
+ keyUsageCheckBoxes[1]->setCheckState(Qt::CheckState::Unchecked);
+
+ if (genKeyInfo->isAllowChangeSigning())
+ keyUsageCheckBoxes[1]->setDisabled(false);
+ else
+ keyUsageCheckBoxes[1]->setDisabled(true);
+
+ if (genKeyInfo->isAllowCertification())
+ keyUsageCheckBoxes[2]->setCheckState(Qt::CheckState::Checked);
+ else
+ keyUsageCheckBoxes[2]->setCheckState(Qt::CheckState::Unchecked);
+
+ if (genKeyInfo->isAllowChangeCertification())
+ keyUsageCheckBoxes[2]->setDisabled(false);
+ else
+ keyUsageCheckBoxes[2]->setDisabled(true);
+
+ if (genKeyInfo->isAllowAuthentication())
+ keyUsageCheckBoxes[3]->setCheckState(Qt::CheckState::Checked);
+ else
+ keyUsageCheckBoxes[3]->setCheckState(Qt::CheckState::Unchecked);
+
+ if (genKeyInfo->isAllowChangeAuthentication())
+ keyUsageCheckBoxes[3]->setDisabled(false);
+ else
+ keyUsageCheckBoxes[3]->setDisabled(true);
+
+ keySizeSpinBox->setRange(genKeyInfo->getSuggestMinKeySize(),
+ genKeyInfo->getSuggestMaxKeySize());
+ keySizeSpinBox->setValue(genKeyInfo->getKeySize());
+ keySizeSpinBox->setSingleStep(genKeyInfo->getSizeChangeStep());
}
void SubkeyGenerateDialog::slotKeyGenAccept() {
- QString errorString = "";
-
- /**
- * primary keys should have a reasonable expiration date (no more than 2 years in the future)
- */
- if(dateEdit->dateTime() > QDateTime::currentDateTime().addYears(2)) {
-
- errorString.append(tr(" Expiration time no more than 2 years. "));
- }
+ std::stringstream err_stream;
- if (errorString.isEmpty()) {
+ /**
+ * primary keys should have a reasonable expiration date (no more than 2 years
+ * in the future)
+ */
+ if (dateEdit->dateTime() > QDateTime::currentDateTime().addYears(2)) {
+ err_stream << " " << _("Expiration time no more than 2 years.") << " ";
+ }
- genKeyInfo.setKeySize(keySizeSpinBox->value());
+ auto err_string = err_stream.str();
- if (expireCheckBox->checkState()) {
- genKeyInfo.setNonExpired(true);
- } else {
- genKeyInfo.setExpired(dateEdit->dateTime());
- }
+ if (err_string.empty()) {
+ genKeyInfo->setKeySize(keySizeSpinBox->value());
- gpgme_error_t error = false;
- auto thread = QThread::create([&]() {
- error = mCtx->generateSubkey(mKey, &genKeyInfo);
- });
- thread->start();
-
- auto *dialog = new WaitingDialog("Generating", this);
- dialog->show();
-
- while (thread->isRunning()) {
- QCoreApplication::processEvents();
- }
+ if (expireCheckBox->checkState()) {
+ genKeyInfo->setNonExpired(true);
+ } else {
+ genKeyInfo->setExpired(
+ boost::posix_time::from_time_t(dateEdit->dateTime().toTime_t())
+ .date());
+ }
- dialog->close();
+ GpgError error;
+ auto thread = QThread::create([&]() {
+ LOG(INFO) << "SubkeyGenerateDialog::slotKeyGenAccept() Thread Started";
+ error = GpgKeyOpera::GetInstance().GenerateSubkey(mKey, genKeyInfo);
+ });
+ thread->start();
- if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) {
- QMessageBox::information(nullptr, tr("Success"), tr("The new subkey has been generated."));
- this->close();
- } else
- QMessageBox::critical(this, tr("Failure"), tr(gpgme_strerror(error)));
+ auto* dialog = new WaitingDialog("Generating", this);
+ dialog->show();
- } else {
- /**
- * create error message
- */
- errorLabel->setAutoFillBackground(true);
- QPalette error = errorLabel->palette();
- error.setColor(QPalette::Window, "#ff8080");
- errorLabel->setPalette(error);
- errorLabel->setText(errorString);
-
- this->show();
+ while (thread->isRunning()) {
+ QCoreApplication::processEvents();
}
+ dialog->close();
+
+ if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR) {
+ auto* msg_box = new QMessageBox(nullptr);
+ msg_box->setAttribute(Qt::WA_DeleteOnClose);
+ msg_box->setStandardButtons(QMessageBox::Ok);
+ msg_box->setWindowTitle(_("Success"));
+ msg_box->setText(_("The new subkey has been generated."));
+ msg_box->setModal(false);
+ msg_box->open();
+
+ emit SubKeyGenerated();
+ this->close();
+ } else
+ QMessageBox::critical(this, _("Failure"), _(gpgme_strerror(error)));
+
+ } else {
+ /**
+ * create error message
+ */
+ errorLabel->setAutoFillBackground(true);
+ QPalette error = errorLabel->palette();
+ error.setColor(QPalette::Window, "#ff8080");
+ errorLabel->setPalette(error);
+ errorLabel->setText(err_string.c_str());
+
+ this->show();
+ }
}
void SubkeyGenerateDialog::slotEncryptionBoxChanged(int state) {
- if(state == 0) {
- genKeyInfo.setAllowEncryption(false);
- } else {
- genKeyInfo.setAllowEncryption(true);
- }
+ if (state == 0) {
+ genKeyInfo->setAllowEncryption(false);
+ } else {
+ genKeyInfo->setAllowEncryption(true);
+ }
}
void SubkeyGenerateDialog::slotSigningBoxChanged(int state) {
- if(state == 0) {
- genKeyInfo.setAllowSigning(false);
- } else {
- genKeyInfo.setAllowSigning(true);
- }
+ if (state == 0) {
+ genKeyInfo->setAllowSigning(false);
+ } else {
+ genKeyInfo->setAllowSigning(true);
+ }
}
void SubkeyGenerateDialog::slotCertificationBoxChanged(int state) {
- if(state == 0) {
- genKeyInfo.setAllowCertification(false);
- } else {
- genKeyInfo.setAllowCertification(true);
- }
+ if (state == 0) {
+ genKeyInfo->setAllowCertification(false);
+ } else {
+ genKeyInfo->setAllowCertification(true);
+ }
}
void SubkeyGenerateDialog::slotAuthenticationBoxChanged(int state) {
- if(state == 0) {
- genKeyInfo.setAllowAuthentication(false);
- } else {
- genKeyInfo.setAllowAuthentication(true);
- }
+ if (state == 0) {
+ genKeyInfo->setAllowAuthentication(false);
+ } else {
+ genKeyInfo->setAllowAuthentication(true);
+ }
}
void SubkeyGenerateDialog::slotActivatedKeyType(int index) {
- qDebug() << "key type index changed " << index;
- genKeyInfo.setAlgo(this->keyTypeComboBox->itemText(index));
- refresh_widgets_state();
+ qDebug() << "key type index changed " << index;
+ genKeyInfo->setAlgo(this->keyTypeComboBox->itemText(index).toStdString());
+ refresh_widgets_state();
}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/keygen/SubkeyGenerateDialog.h b/src/ui/keygen/SubkeyGenerateDialog.h
new file mode 100644
index 00000000..ec7c9fb1
--- /dev/null
+++ b/src/ui/keygen/SubkeyGenerateDialog.h
@@ -0,0 +1,97 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_SUBKEYGENERATEDIALOG_H
+#define GPGFRONTEND_SUBKEYGENERATEDIALOG_H
+
+#include "gpg/GpgContext.h"
+#include "gpg/GpgGenKeyInfo.h"
+#include "ui/GpgFrontendUI.h"
+
+namespace GpgFrontend::UI {
+
+class SubkeyGenerateDialog : public QDialog {
+ Q_OBJECT
+
+ public:
+ explicit SubkeyGenerateDialog(const KeyId& key_id, QWidget* parent);
+
+ signals:
+ void SubKeyGenerated();
+
+ private:
+ GpgKey mKey;
+
+ std::unique_ptr<GenKeyInfo> genKeyInfo = std::make_unique<GenKeyInfo>(true);
+
+ QGroupBox* keyUsageGroupBox{};
+ QDialogButtonBox* buttonBox; /** Box for standardbuttons */
+ QLabel* errorLabel{}; /** Label containing error message */
+ QSpinBox* keySizeSpinBox{}; /** Spinbox for the keys size (in bit) */
+ QComboBox* keyTypeComboBox{}; /** Combobox for Keytpe */
+ QDateTimeEdit* dateEdit{}; /** Dateedit for expiration date */
+ QCheckBox* expireCheckBox{}; /** Checkbox, if key should expire */
+
+ // ENCR, SIGN, CERT, AUTH
+ std::vector<QCheckBox*> keyUsageCheckBoxes;
+
+ QGroupBox* create_key_usage_group_box();
+
+ QGroupBox* create_basic_info_group_box();
+
+ void set_signal_slot();
+
+ /**
+ * @details Refresh widgets state by GenKeyInfo
+ */
+ void refresh_widgets_state();
+
+ private slots:
+
+ /**
+ * @details when expirebox was checked/unchecked, enable/disable the
+ * expiration date box
+ */
+ void slotExpireBoxChanged();
+
+ /**
+ * @details check all lineedits for false entries. Show error, when there is
+ * one, otherwise generate the key
+ */
+ void slotKeyGenAccept();
+
+ void slotEncryptionBoxChanged(int state);
+
+ void slotSigningBoxChanged(int state);
+
+ void slotCertificationBoxChanged(int state);
+
+ void slotAuthenticationBoxChanged(int state);
+
+ void slotActivatedKeyType(int index);
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_SUBKEYGENERATEDIALOG_H
diff --git a/src/ui/keypair_details/EditSubKeyDialog.cpp b/src/ui/keypair_details/EditSubKeyDialog.cpp
index e44c987f..6c2e0ce1 100644
--- a/src/ui/keypair_details/EditSubKeyDialog.cpp
+++ b/src/ui/keypair_details/EditSubKeyDialog.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
diff --git a/src/ui/keypair_details/EditSubKeyDialog.h b/src/ui/keypair_details/EditSubKeyDialog.h
new file mode 100644
index 00000000..51842405
--- /dev/null
+++ b/src/ui/keypair_details/EditSubKeyDialog.h
@@ -0,0 +1,30 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_EDITSUBKEY_H
+#define GPGFRONTEND_EDITSUBKEY_H
+
+class EditSubKeyDialog {};
+
+#endif // GPGFRONTEND_EDITSUBKEY_H
diff --git a/src/ui/keypair_details/KeyDetailsDialog.cpp b/src/ui/keypair_details/KeyDetailsDialog.cpp
index c80374d4..f3cab771 100644
--- a/src/ui/keypair_details/KeyDetailsDialog.cpp
+++ b/src/ui/keypair_details/KeyDetailsDialog.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,21 +24,22 @@
#include "ui/keypair_details/KeyDetailsDialog.h"
-KeyDetailsDialog::KeyDetailsDialog(GpgME::GpgContext *ctx, const GpgKey& key, QWidget *parent)
- : QDialog(parent) {
+namespace GpgFrontend::UI {
+KeyDetailsDialog::KeyDetailsDialog(const GpgKey& key, QWidget* parent)
+ : QDialog(parent) {
+ tabWidget = new QTabWidget();
+ tabWidget->addTab(new KeyPairDetailTab(key.id(), tabWidget), _("KeyPair"));
+ tabWidget->addTab(new KeyPairUIDTab(key.id(), tabWidget), _("UIDs"));
+ tabWidget->addTab(new KeyPairSubkeyTab(key.id(), tabWidget), _("Subkeys"));
- tabWidget = new QTabWidget();
- tabWidget->addTab(new KeyPairDetailTab(ctx, key, tabWidget), tr("KeyPair"));
- tabWidget->addTab(new KeyPairUIDTab(ctx, key, tabWidget), tr("UIDs"));
- tabWidget->addTab(new KeyPairSubkeyTab(ctx, key, tabWidget), tr("Subkeys"));
+ auto* mainLayout = new QVBoxLayout;
+ mainLayout->addWidget(tabWidget);
- auto *mainLayout = new QVBoxLayout;
- mainLayout->addWidget(tabWidget);
-
- this->setAttribute(Qt::WA_DeleteOnClose, true);
- this->setLayout(mainLayout);
- this->setWindowTitle(tr("Key Details"));
- this->setModal(true);
- this->setMinimumSize(380, 620);
- this->show();
-} \ No newline at end of file
+ this->setAttribute(Qt::WA_DeleteOnClose, true);
+ this->setLayout(mainLayout);
+ this->setWindowTitle(_("Key Details"));
+ this->setModal(true);
+ this->setMinimumSize(380, 620);
+ this->show();
+}
+} // namespace GpgFrontend::UI
diff --git a/src/ui/keypair_details/KeyDetailsDialog.h b/src/ui/keypair_details/KeyDetailsDialog.h
new file mode 100644
index 00000000..51fc01cf
--- /dev/null
+++ b/src/ui/keypair_details/KeyDetailsDialog.h
@@ -0,0 +1,47 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef __KEYDETAILSDIALOG_H__
+#define __KEYDETAILSDIALOG_H__
+
+#include "KeyPairDetailTab.h"
+#include "KeyPairSubkeyTab.h"
+#include "KeyPairUIDTab.h"
+#include "gpg/GpgContext.h"
+#include "ui/GpgFrontendUI.h"
+
+namespace GpgFrontend::UI {
+
+class KeyDetailsDialog : public QDialog {
+ Q_OBJECT
+
+ public:
+ explicit KeyDetailsDialog(const GpgKey& key, QWidget* parent = nullptr);
+
+ private:
+ QTabWidget* tabWidget{};
+};
+} // namespace GpgFrontend::UI
+
+#endif // __KEYDETAILSDIALOG_H__
diff --git a/src/ui/keypair_details/KeyNewUIDDialog.cpp b/src/ui/keypair_details/KeyNewUIDDialog.cpp
index e12af750..809a05f8 100644
--- a/src/ui/keypair_details/KeyNewUIDDialog.cpp
+++ b/src/ui/keypair_details/KeyNewUIDDialog.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,79 +24,86 @@
#include "ui/keypair_details/KeyNewUIDDialog.h"
-KeyNewUIDDialog::KeyNewUIDDialog(GpgME::GpgContext *ctx, const GpgKey &key, QWidget *parent) :
- mCtx(ctx), mKey(key), QDialog(parent) {
-
- name = new QLineEdit();
- name->setMinimumWidth(240);
- email = new QLineEdit();
- email->setMinimumWidth(240);
- comment = new QLineEdit();
- comment->setMinimumWidth(240);
- createButton = new QPushButton("Create");
- errorLabel = new QLabel();
-
- auto gridLayout = new QGridLayout();
- gridLayout->addWidget(new QLabel(tr("Name")), 0, 0);
- gridLayout->addWidget(new QLabel(tr("Email")), 1, 0);
- gridLayout->addWidget(new QLabel(tr("Comment")), 2, 0);
-
-
- gridLayout->addWidget(name, 0 ,1);
- gridLayout->addWidget(email, 1 ,1);
- gridLayout->addWidget(comment, 2 ,1);
-
- gridLayout->addWidget(createButton, 3, 0, 1, 2);
- gridLayout->addWidget(errorLabel, 4, 0, 1, 2);
-
- connect(createButton, SIGNAL(clicked(bool)), this, SLOT(slotCreateNewUID()));
-
- this->setLayout(gridLayout);
- this->setWindowTitle(tr("Create New UID"));
- this->setAttribute(Qt::WA_DeleteOnClose, true);
- this->setModal(true);
+#include "gpg/function/GpgKeyGetter.h"
+#include "gpg/function/UidOperator.h"
+#include "ui/SignalStation.h"
+
+namespace GpgFrontend::UI {
+KeyNewUIDDialog::KeyNewUIDDialog(const KeyId& key_id, QWidget* parent)
+ : QDialog(parent), mKey(GpgKeyGetter::GetInstance().GetKey(key_id)) {
+ name = new QLineEdit();
+ name->setMinimumWidth(240);
+ email = new QLineEdit();
+ email->setMinimumWidth(240);
+ comment = new QLineEdit();
+ comment->setMinimumWidth(240);
+ createButton = new QPushButton("Create");
+ errorLabel = new QLabel();
+
+ auto gridLayout = new QGridLayout();
+ gridLayout->addWidget(new QLabel(_("Name")), 0, 0);
+ gridLayout->addWidget(new QLabel(_("Email")), 1, 0);
+ gridLayout->addWidget(new QLabel(_("Comment")), 2, 0);
+
+ gridLayout->addWidget(name, 0, 1);
+ gridLayout->addWidget(email, 1, 1);
+ gridLayout->addWidget(comment, 2, 1);
+
+ gridLayout->addWidget(createButton, 3, 0, 1, 2);
+ gridLayout->addWidget(
+ new QLabel(_("Notice: The New UID Created will be set as Primary.")), 4,
+ 0, 1, 2);
+ gridLayout->addWidget(errorLabel, 5, 0, 1, 2);
+
+ connect(createButton, SIGNAL(clicked(bool)), this, SLOT(slotCreateNewUID()));
+
+ this->setLayout(gridLayout);
+ this->setWindowTitle(_("Create New UID"));
+ this->setAttribute(Qt::WA_DeleteOnClose, true);
+ this->setModal(true);
+
+ connect(this, SIGNAL(signalUIDCreated()), SignalStation::GetInstance(),
+ SIGNAL(KeyDatabaseRefresh()));
}
void KeyNewUIDDialog::slotCreateNewUID() {
-
- QString errorString = "";
-
+ std::stringstream error_stream;
+
+ /**
+ * check for errors in keygen dialog input
+ */
+ if ((name->text()).size() < 5) {
+ error_stream << " " << _("Name must contain at least five characters.")
+ << std::endl;
+ }
+ if (email->text().isEmpty() || !check_email_address(email->text())) {
+ error_stream << " " << _("Please give a email address.") << std::endl;
+ }
+ auto error_string = error_stream.str();
+ if (error_string.empty()) {
+ if (UidOperator::GetInstance().addUID(mKey, name->text().toStdString(),
+ comment->text().toStdString(),
+ email->text().toStdString())) {
+ emit finished(1);
+ emit signalUIDCreated();
+ } else
+ emit finished(-1);
+
+ } else {
/**
- * check for errors in keygen dialog input
+ * create error message
*/
- if ((name->text()).size() < 5) {
- errorString.append(tr(" Name must contain at least five characters. \n"));
- } if(email->text().isEmpty() || !check_email_address(email->text())) {
- errorString.append(tr(" Please give a email address. \n"));
- }
-
- if (errorString.isEmpty()) {
- GpgUID uid;
- uid.name = name->text();
- uid.email = email->text();
- uid.comment = comment->text();
-
- if(mCtx->addUID(mKey, uid)) {
- emit finished(1);
-
- } else {
- emit finished(-1);
- }
-
- } else {
- /**
- * create error message
- */
- errorLabel->setAutoFillBackground(true);
- QPalette error = errorLabel->palette();
- error.setColor(QPalette::Window, "#ff8080");
- errorLabel->setPalette(error);
- errorLabel->setText(errorString);
-
- this->show();
- }
+ errorLabel->setAutoFillBackground(true);
+ QPalette error = errorLabel->palette();
+ error.setColor(QPalette::Window, "#ff8080");
+ errorLabel->setPalette(error);
+ errorLabel->setText(error_string.c_str());
+
+ this->show();
+ }
}
-bool KeyNewUIDDialog::check_email_address(const QString &str) {
- return re_email.match(str).hasMatch();
+bool KeyNewUIDDialog::check_email_address(const QString& str) {
+ return re_email.match(str).hasMatch();
}
+} // namespace GpgFrontend::UI
diff --git a/src/ui/keypair_details/KeyNewUIDDialog.h b/src/ui/keypair_details/KeyNewUIDDialog.h
new file mode 100644
index 00000000..2e38a7f4
--- /dev/null
+++ b/src/ui/keypair_details/KeyNewUIDDialog.h
@@ -0,0 +1,64 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_KEYNEWUIDDIALOG_H
+#define GPGFRONTEND_KEYNEWUIDDIALOG_H
+
+#include "gpg/GpgContext.h"
+#include "ui/GpgFrontendUI.h"
+
+namespace GpgFrontend::UI {
+class KeyNewUIDDialog : public QDialog {
+ Q_OBJECT
+
+ public:
+ KeyNewUIDDialog(const KeyId& key, QWidget* parent = nullptr);
+
+ signals:
+ void signalUIDCreated();
+
+ private slots:
+
+ void slotCreateNewUID();
+
+ private:
+ GpgKey mKey;
+
+ QLineEdit* name{};
+ QLineEdit* email{};
+ QLineEdit* comment{};
+
+ QPushButton* createButton{};
+
+ QStringList errorMessages;
+ QLabel* errorLabel{};
+
+ QRegularExpression re_email{
+ R"((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\]))"};
+
+ bool check_email_address(const QString& str);
+};
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_KEYNEWUIDDIALOG_H
diff --git a/src/ui/keypair_details/KeyPairDetailTab.cpp b/src/ui/keypair_details/KeyPairDetailTab.cpp
index c0a2df99..f88e9edc 100644
--- a/src/ui/keypair_details/KeyPairDetailTab.cpp
+++ b/src/ui/keypair_details/KeyPairDetailTab.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -23,330 +23,384 @@
*/
#include "ui/keypair_details/KeyPairDetailTab.h"
+
+#include "gpg/function/GpgKeyGetter.h"
+#include "gpg/function/GpgKeyImportExportor.h"
+#include "ui/SignalStation.h"
+#include "ui/UserInterfaceUtils.h"
#include "ui/WaitingDialog.h"
-KeyPairDetailTab::KeyPairDetailTab(GpgME::GpgContext *ctx, const GpgKey &mKey, QWidget *parent) : mKey(mKey),
- QWidget(parent) {
-
- mCtx = ctx;
- keyid = new QString(mKey.id);
-
- ownerBox = new QGroupBox(tr("Owner"));
- keyBox = new QGroupBox(tr("Master Key"));
- fingerprintBox = new QGroupBox(tr("Fingerprint"));
- additionalUidBox = new QGroupBox(tr("Additional UIDs"));
-
- nameVarLabel = new QLabel();
- nameVarLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
- emailVarLabel = new QLabel();
- emailVarLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
-
- commentVarLabel = new QLabel();
- commentVarLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
- keyidVarLabel = new QLabel();
- keyidVarLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
-
- usageVarLabel = new QLabel();
- actualUsageVarLabel = new QLabel();
-
- keySizeVarLabel = new QLabel();
- expireVarLabel = new QLabel();
- createdVarLabel = new QLabel();
- algorithmVarLabel = new QLabel();
-
- // Show the situation that master key not exists.
- masterKeyExistVarLabel = new QLabel(mKey.has_master_key ? tr("Exists") : tr("Not Exists"));
- if (!mKey.has_master_key) {
- auto paletteExpired = masterKeyExistVarLabel->palette();
- paletteExpired.setColor(masterKeyExistVarLabel->foregroundRole(), Qt::red);
- masterKeyExistVarLabel->setPalette(paletteExpired);
- } else {
- auto paletteValid = masterKeyExistVarLabel->palette();
- paletteValid.setColor(masterKeyExistVarLabel->foregroundRole(), Qt::darkGreen);
- masterKeyExistVarLabel->setPalette(paletteValid);
+namespace GpgFrontend::UI {
+KeyPairDetailTab::KeyPairDetailTab(const std::string& key_id, QWidget* parent)
+ : QWidget(parent), mKey(GpgKeyGetter::GetInstance().GetKey(key_id)) {
+ keyid = mKey.id();
+
+ ownerBox = new QGroupBox(_("Owner"));
+ keyBox = new QGroupBox(_("Master Key"));
+ fingerprintBox = new QGroupBox(_("Fingerprint"));
+ additionalUidBox = new QGroupBox(_("Additional UIDs"));
+
+ nameVarLabel = new QLabel();
+ nameVarLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ emailVarLabel = new QLabel();
+ emailVarLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
+
+ commentVarLabel = new QLabel();
+ commentVarLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ keyidVarLabel = new QLabel();
+ keyidVarLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
+
+ usageVarLabel = new QLabel();
+ actualUsageVarLabel = new QLabel();
+
+ keySizeVarLabel = new QLabel();
+ expireVarLabel = new QLabel();
+ createdVarLabel = new QLabel();
+ algorithmVarLabel = new QLabel();
+
+ // Show the situation that master key not exists.
+ masterKeyExistVarLabel =
+ new QLabel(mKey.has_master_key() ? _("Exists") : _("Not Exists"));
+ if (!mKey.has_master_key()) {
+ auto paletteExpired = masterKeyExistVarLabel->palette();
+ paletteExpired.setColor(masterKeyExistVarLabel->foregroundRole(), Qt::red);
+ masterKeyExistVarLabel->setPalette(paletteExpired);
+ } else {
+ auto paletteValid = masterKeyExistVarLabel->palette();
+ paletteValid.setColor(masterKeyExistVarLabel->foregroundRole(),
+ Qt::darkGreen);
+ masterKeyExistVarLabel->setPalette(paletteValid);
+ }
+
+ if (mKey.expired()) {
+ auto paletteExpired = expireVarLabel->palette();
+ paletteExpired.setColor(expireVarLabel->foregroundRole(), Qt::red);
+ expireVarLabel->setPalette(paletteExpired);
+ } else {
+ auto paletteValid = expireVarLabel->palette();
+ paletteValid.setColor(expireVarLabel->foregroundRole(), Qt::darkGreen);
+ expireVarLabel->setPalette(paletteValid);
+ }
+
+ auto* mvbox = new QVBoxLayout();
+ auto* vboxKD = new QGridLayout();
+ auto* vboxOD = new QGridLayout();
+
+ vboxOD->addWidget(new QLabel(QString(_("Name")) + ": "), 0, 0);
+ vboxOD->addWidget(new QLabel(QString(_("Email Address")) + ": "), 1, 0);
+ vboxOD->addWidget(new QLabel(QString(_("Comment")) + ": "), 2, 0);
+ vboxOD->addWidget(nameVarLabel, 0, 1);
+ vboxOD->addWidget(emailVarLabel, 1, 1);
+ vboxOD->addWidget(commentVarLabel, 2, 1);
+
+ vboxKD->addWidget(new QLabel(QString(_("Key ID")) + ": "), 0, 0);
+ vboxKD->addWidget(new QLabel(QString(_("Algorithm")) + ": "), 1, 0);
+ vboxKD->addWidget(new QLabel(QString(_("Key Size")) + ": "), 2, 0);
+ vboxKD->addWidget(new QLabel(QString(_("Nominal Usage")) + ": "), 3, 0);
+ vboxKD->addWidget(new QLabel(QString(_("Actual Usage")) + ": "), 4, 0);
+ vboxKD->addWidget(new QLabel(QString(_("Expires on")) + ": "), 5, 0);
+ vboxKD->addWidget(new QLabel(QString(_("Last Update")) + ": "), 6, 0);
+ vboxKD->addWidget(new QLabel(QString(_("Secret Key Existence")) + ": "), 7,
+ 0);
+
+ vboxKD->addWidget(keySizeVarLabel, 2, 1);
+ vboxKD->addWidget(expireVarLabel, 5, 1);
+ vboxKD->addWidget(algorithmVarLabel, 1, 1);
+ vboxKD->addWidget(createdVarLabel, 6, 1);
+ vboxKD->addWidget(keyidVarLabel, 0, 1);
+ vboxKD->addWidget(usageVarLabel, 3, 1);
+ vboxKD->addWidget(actualUsageVarLabel, 4, 1);
+ vboxKD->addWidget(masterKeyExistVarLabel, 7, 1);
+
+ ownerBox->setLayout(vboxOD);
+ mvbox->addWidget(ownerBox);
+ keyBox->setLayout(vboxKD);
+ mvbox->addWidget(keyBox);
+
+ fingerPrintVarLabel =
+ new QLabel(beautifyFingerprint(QString::fromStdString(mKey.fpr())));
+ fingerPrintVarLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ fingerPrintVarLabel->setStyleSheet("margin-left: 0; margin-right: 5;");
+ auto* hboxFP = new QHBoxLayout();
+
+ hboxFP->addWidget(fingerPrintVarLabel);
+
+ auto* copyFingerprintButton = new QPushButton(_("Copy"));
+ copyFingerprintButton->setFlat(true);
+ copyFingerprintButton->setToolTip(_("copy fingerprint to clipboard"));
+ connect(copyFingerprintButton, SIGNAL(clicked()), this,
+ SLOT(slotCopyFingerprint()));
+
+ hboxFP->addWidget(copyFingerprintButton);
+
+ fingerprintBox->setLayout(hboxFP);
+ mvbox->addWidget(fingerprintBox);
+ mvbox->addStretch();
+
+ if (mKey.is_private_key()) {
+ auto* privKeyBox = new QGroupBox(_("Operations"));
+ auto* vboxPK = new QVBoxLayout();
+
+ auto* exportButton =
+ new QPushButton(_("Export Private Key (Include Subkey)"));
+ vboxPK->addWidget(exportButton);
+ connect(exportButton, SIGNAL(clicked()), this,
+ SLOT(slotExportPrivateKey()));
+
+ if (mKey.has_master_key()) {
+ auto* editExpiresButton =
+ new QPushButton(_("Modify Expiration Datetime (Master Key)"));
+ vboxPK->addWidget(editExpiresButton);
+ connect(editExpiresButton, SIGNAL(clicked()), this,
+ SLOT(slotModifyEditDatetime()));
+
+ auto hBoxLayout = new QHBoxLayout();
+ auto* keyServerOperaButton =
+ new QPushButton(_("Key Server Operation (Pubkey)"));
+ keyServerOperaButton->setStyleSheet("text-align:center;");
+
+ auto* revokeCertGenButton =
+ new QPushButton(_("Generate Revoke Certificate"));
+ connect(revokeCertGenButton, SIGNAL(clicked()), this,
+ SLOT(slotGenRevokeCert()));
+
+ hBoxLayout->addWidget(keyServerOperaButton);
+ hBoxLayout->addWidget(revokeCertGenButton);
+
+ vboxPK->addLayout(hBoxLayout);
+ connect(keyServerOperaButton, SIGNAL(clicked()), this,
+ SLOT(slotModifyEditDatetime()));
+
+ // Set Menu
+ createKeyServerOperaMenu();
+ keyServerOperaButton->setMenu(keyServerOperaMenu);
}
- if (mKey.expired) {
- auto paletteExpired = expireVarLabel->palette();
- paletteExpired.setColor(expireVarLabel->foregroundRole(), Qt::red);
- expireVarLabel->setPalette(paletteExpired);
- } else {
- auto paletteValid = expireVarLabel->palette();
- paletteValid.setColor(expireVarLabel->foregroundRole(), Qt::darkGreen);
- expireVarLabel->setPalette(paletteValid);
- }
+ privKeyBox->setLayout(vboxPK);
+ mvbox->addWidget(privKeyBox);
+ }
- auto *mvbox = new QVBoxLayout();
- auto *vboxKD = new QGridLayout();
- auto *vboxOD = new QGridLayout();
-
- vboxOD->addWidget(new QLabel(tr("Name:")), 0, 0);
- vboxOD->addWidget(new QLabel(tr("Email Address:")), 1, 0);
- vboxOD->addWidget(new QLabel(tr("Comment:")), 2, 0);
- vboxOD->addWidget(nameVarLabel, 0, 1);
- vboxOD->addWidget(emailVarLabel, 1, 1);
- vboxOD->addWidget(commentVarLabel, 2, 1);
-
- vboxKD->addWidget(new QLabel(tr("Key ID: ")), 0, 0);
- vboxKD->addWidget(new QLabel(tr("Algorithm: ")), 1, 0);
- vboxKD->addWidget(new QLabel(tr("Key Size:")), 2, 0);
- vboxKD->addWidget(new QLabel(tr("Nominal Usage: ")), 3, 0);
- vboxKD->addWidget(new QLabel(tr("Actual Usage: ")), 4, 0);
- vboxKD->addWidget(new QLabel(tr("Expires on: ")), 5, 0);
- vboxKD->addWidget(new QLabel(tr("Last Update: ")), 6, 0);
- vboxKD->addWidget(new QLabel(tr("Secret Key Existence: ")), 7, 0);
-
-
- vboxKD->addWidget(keySizeVarLabel, 2, 1);
- vboxKD->addWidget(expireVarLabel, 5, 1);
- vboxKD->addWidget(algorithmVarLabel, 1, 1);
- vboxKD->addWidget(createdVarLabel, 6, 1);
- vboxKD->addWidget(keyidVarLabel, 0, 1);
- vboxKD->addWidget(usageVarLabel, 3, 1);
- vboxKD->addWidget(actualUsageVarLabel, 4, 1);
- vboxKD->addWidget(masterKeyExistVarLabel, 7, 1);
-
- ownerBox->setLayout(vboxOD);
- mvbox->addWidget(ownerBox);
- keyBox->setLayout(vboxKD);
- mvbox->addWidget(keyBox);
-
- fingerPrintVarLabel = new QLabel(beautifyFingerprint(mKey.fpr));
- fingerPrintVarLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
- fingerPrintVarLabel->setStyleSheet("margin-left: 0; margin-right: 5;");
- auto *hboxFP = new QHBoxLayout();
-
- hboxFP->addWidget(fingerPrintVarLabel);
-
- auto *copyFingerprintButton = new QPushButton(tr("Copy"));
- copyFingerprintButton->setFlat(true);
- copyFingerprintButton->setToolTip(tr("copy fingerprint to clipboard"));
- connect(copyFingerprintButton, SIGNAL(clicked()), this, SLOT(slotCopyFingerprint()));
-
- hboxFP->addWidget(copyFingerprintButton);
-
- fingerprintBox->setLayout(hboxFP);
- mvbox->addWidget(fingerprintBox);
- mvbox->addStretch();
-
- if (mKey.is_private_key) {
- auto *privKeyBox = new QGroupBox(tr("Operations"));
- auto *vboxPK = new QVBoxLayout();
-
- auto *exportButton = new QPushButton(tr("Export Private Key (Include Subkey)"));
- vboxPK->addWidget(exportButton);
- connect(exportButton, SIGNAL(clicked()), this, SLOT(slotExportPrivateKey()));
-
- if (mKey.has_master_key) {
- auto *editExpiresButton = new QPushButton(tr("Modify Expiration Datetime (Master Key)"));
- vboxPK->addWidget(editExpiresButton);
- connect(editExpiresButton, SIGNAL(clicked()), this, SLOT(slotModifyEditDatetime()));
-
- auto hBoxLayout = new QHBoxLayout();
- auto *keyServerOperaButton = new QPushButton(tr("Key Server Operation (Pubkey)"));
- keyServerOperaButton->setStyleSheet("text-align:center;");
-
- auto *revokeCertGenButton = new QPushButton(tr("Generate Revoke Certificate"));
- connect(revokeCertGenButton, SIGNAL(clicked()), this, SLOT(slotGenRevokeCert()));
-
- hBoxLayout->addWidget(keyServerOperaButton);
- hBoxLayout->addWidget(revokeCertGenButton);
-
- vboxPK->addLayout(hBoxLayout);
- connect(keyServerOperaButton, SIGNAL(clicked()), this, SLOT(slotModifyEditDatetime()));
-
- // Set Menu
- createKeyServerOperaMenu();
- keyServerOperaButton->setMenu(keyServerOperaMenu);
- }
-
- privKeyBox->setLayout(vboxPK);
- mvbox->addWidget(privKeyBox);
- }
+ if ((mKey.expired()) || (mKey.revoked())) {
+ auto* expBox = new QHBoxLayout();
+ QPixmap pixmap(":warning.png");
- if ((mKey.expired) || (mKey.revoked)) {
- auto *expBox = new QHBoxLayout();
- QPixmap pixmap(":warning.png");
-
- auto *expLabel = new QLabel();
- auto *iconLabel = new QLabel();
- if (mKey.expired) {
- expLabel->setText(tr("Warning: The Master Key has expired."));
- }
- if (mKey.revoked) {
- expLabel->setText(tr("Warning: The Master Key has been revoked"));
- }
-
- iconLabel->setPixmap(pixmap.scaled(24, 24, Qt::KeepAspectRatio));
- QFont font = expLabel->font();
- font.setBold(true);
- expLabel->setFont(font);
- expLabel->setAlignment(Qt::AlignCenter);
- expBox->addWidget(iconLabel);
- expBox->addWidget(expLabel);
- mvbox->addLayout(expBox);
+ auto* expLabel = new QLabel();
+ auto* iconLabel = new QLabel();
+ if (mKey.expired()) {
+ expLabel->setText(_("Warning: The Master Key has expired."));
+ }
+ if (mKey.revoked()) {
+ expLabel->setText(_("Warning: The Master Key has been revoked"));
}
- mvbox->setContentsMargins(0, 0, 0, 0);
-
- connect(mCtx, SIGNAL(signalKeyInfoChanged()), this, SLOT(slotRefreshKeyInfo()));
-
- slotRefreshKeyInfo();
- setAttribute(Qt::WA_DeleteOnClose, true);
- setLayout(mvbox);
+ iconLabel->setPixmap(pixmap.scaled(24, 24, Qt::KeepAspectRatio));
+ QFont font = expLabel->font();
+ font.setBold(true);
+ expLabel->setFont(font);
+ expLabel->setAlignment(Qt::AlignCenter);
+ expBox->addWidget(iconLabel);
+ expBox->addWidget(expLabel);
+ mvbox->addLayout(expBox);
+ }
+
+ // when key database updated
+ connect(SignalStation::GetInstance(), SIGNAL(KeyDatabaseRefresh()), this,
+ SLOT(slotRefreshKey()));
+
+ mvbox->setContentsMargins(0, 0, 0, 0);
+
+ slotRefreshKeyInfo();
+ setAttribute(Qt::WA_DeleteOnClose, true);
+ setLayout(mvbox);
}
void KeyPairDetailTab::slotExportPrivateKey() {
- // Show a information box with explanation about private key
- int ret = QMessageBox::information(this, tr("Exporting private Key"),
- "<h3>" + tr("You are about to export your") + "<font color=\"red\">" +
- tr("PRIVATE KEY") + "</font>!</h3>\n" +
- tr("This is NOT your Public Key, so DON'T give it away.") + "<br />" +
- tr("Do you REALLY want to export your PRIVATE KEY?"),
- QMessageBox::Cancel | QMessageBox::Ok);
-
- // export key, if ok was clicked
- if (ret == QMessageBox::Ok) {
- auto *keyArray = new QByteArray();
-
- if (!mCtx->exportSecretKey(mKey, keyArray)) {
- QMessageBox::critical(this, "Error", "An error occurred during the export operation.");
- return;
- }
-
- auto key = mCtx->getKeyById(*keyid);
- if (!key.good) {
- QMessageBox::critical(nullptr, tr("Error"), tr("Key Not Found."));
- return;
- }
- QString fileString = key.name + " " + key.email + "(" +
- key.id + ")_secret.asc";
- QString fileName = QFileDialog::getSaveFileName(this, tr("Export Key To File"), fileString,
- tr("Key Files") + " (*.asc *.txt);;All Files (*)");
- QFile file(fileName);
- if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
- QMessageBox::critical(nullptr, tr("Export Error"), tr("Couldn't open %1 for writing").arg(fileName));
- return;
- }
- QTextStream stream(&file);
- stream << *keyArray;
- file.close();
- delete keyArray;
+ // Show a information box with explanation about private key
+ int ret = QMessageBox::information(
+ this, _("Exporting private Key"),
+ "<h3>" + QString(_("You are about to export your")) +
+ "<font color=\"red\">" + _(" PRIVATE KEY ") + "</font>!</h3>\n" +
+ _("This is NOT your Public Key, so DON'T give it away.") + "<br />" +
+ _("Do you REALLY want to export your PRIVATE KEY?"),
+ QMessageBox::Cancel | QMessageBox::Ok);
+
+ // export key, if ok was clicked
+ if (ret == QMessageBox::Ok) {
+ ByteArrayPtr keyArray = nullptr;
+
+ if (!GpgKeyImportExportor::GetInstance().ExportSecretKey(mKey, keyArray)) {
+ QMessageBox::critical(
+ this, _("Error"),
+ _("An error occurred during the export operation."));
+ return;
+ }
+
+ auto key = GpgKeyGetter::GetInstance().GetKey(keyid);
+ if (!key.good()) {
+ QMessageBox::critical(nullptr, _("Error"), _("Key Not Found."));
+ return;
}
+ auto fileString =
+ key.name() + " " + key.email() + "(" + key.id() + ")_secret.asc";
+ auto fileName =
+ QFileDialog::getSaveFileName(
+ this, _("Export Key To File"), QString::fromStdString(fileString),
+ QString(_("Key Files")) + " (*.asc *.txt);;All Files (*)")
+ .toStdString();
+
+ if (!write_buffer_to_file(fileName, *keyArray)) {
+ QMessageBox::critical(
+ nullptr, _("Export Error"),
+ QString(_("Couldn't open %1 for writing")).arg(fileName.c_str()));
+ return;
+ }
+ }
}
QString KeyPairDetailTab::beautifyFingerprint(QString fingerprint) {
- uint len = fingerprint.length();
- if ((len > 0) && (len % 4 == 0))
- for (uint n = 0; 4 * (n + 1) < len; ++n)
- fingerprint.insert(static_cast<int>(5u * n + 4u), ' ');
- return fingerprint;
+ uint len = fingerprint.length();
+ if ((len > 0) && (len % 4 == 0))
+ for (uint n = 0; 4 * (n + 1) < len; ++n)
+ fingerprint.insert(static_cast<int>(5u * n + 4u), ' ');
+ return fingerprint;
}
void KeyPairDetailTab::slotCopyFingerprint() {
- QString fpr = fingerPrintVarLabel->text().trimmed().replace(" ", "");
- QClipboard *cb = QApplication::clipboard();
- cb->setText(fpr);
+ QString fpr = fingerPrintVarLabel->text().trimmed().replace(" ", QString());
+ QClipboard* cb = QApplication::clipboard();
+ cb->setText(fpr);
}
void KeyPairDetailTab::slotModifyEditDatetime() {
- auto dialog = new KeySetExpireDateDialog(mCtx, mKey, nullptr, this);
- dialog->show();
+ auto dialog = new KeySetExpireDateDialog(mKey.id(), this);
+ dialog->show();
}
void KeyPairDetailTab::slotRefreshKeyInfo() {
+ nameVarLabel->setText(QString::fromStdString(mKey.name()));
+ emailVarLabel->setText(QString::fromStdString(mKey.email()));
- nameVarLabel->setText(mKey.name);
- emailVarLabel->setText(mKey.email);
-
- commentVarLabel->setText(mKey.comment);
- keyidVarLabel->setText(mKey.id);
+ commentVarLabel->setText(QString::fromStdString(mKey.comment()));
+ keyidVarLabel->setText(QString::fromStdString(mKey.id()));
- QString usage;
- QTextStream usage_steam(&usage);
+ QString usage;
+ QTextStream usage_steam(&usage);
- if (mKey.can_certify)
- usage_steam << "Cert ";
- if (mKey.can_encrypt)
- usage_steam << "Encr ";
- if (mKey.can_sign)
- usage_steam << "Sign ";
- if (mKey.can_authenticate)
- usage_steam << "Auth ";
+ if (mKey.can_certify()) usage_steam << _("Cert") << " ";
+ if (mKey.can_encrypt()) usage_steam << _("Encr") << " ";
+ if (mKey.can_sign()) usage_steam << _("Sign") << " ";
+ if (mKey.can_authenticate()) usage_steam << _("Auth") << " ";
- usageVarLabel->setText(usage);
+ usageVarLabel->setText(usage);
- QString actualUsage;
- QTextStream actual_usage_steam(&actualUsage);
+ QString actualUsage;
+ QTextStream actual_usage_steam(&actualUsage);
- if (GpgME::GpgContext::checkIfKeyCanCert(mKey))
- actual_usage_steam << "Cert ";
- if (GpgME::GpgContext::checkIfKeyCanEncr(mKey))
- actual_usage_steam << "Encr ";
- if (GpgME::GpgContext::checkIfKeyCanSign(mKey))
- actual_usage_steam << "Sign ";
- if (GpgME::GpgContext::checkIfKeyCanAuth(mKey))
- actual_usage_steam << "Auth ";
+ if (mKey.CanCertActual()) actual_usage_steam << _("Cert") << " ";
+ if (mKey.CanEncrActual()) actual_usage_steam << _("Encr") << " ";
+ if (mKey.CanSignActual()) actual_usage_steam << _("Sign") << " ";
+ if (mKey.CanAuthActual()) actual_usage_steam << _("Auth") << " ";
- actualUsageVarLabel->setText(actualUsage);
+ actualUsageVarLabel->setText(actualUsage);
- QString keySizeVal, keyExpireVal, keyCreateTimeVal, keyAlgoVal;
+ QString keySizeVal, keyExpireVal, keyCreateTimeVal, keyAlgoVal;
- keySizeVal = QString::number(mKey.length);
-
- if (mKey.expires.toTime_t() == 0) {
- keyExpireVal = tr("Never Expire");
- } else {
- keyExpireVal = mKey.expires.toString();
- }
+ keySizeVal = QString::number(mKey.length());
- keyAlgoVal = mKey.pubkey_algo;
- keyCreateTimeVal = mKey.create_time.toString();
+ if (to_time_t(boost::posix_time::ptime(mKey.expires())) == 0) {
+ keyExpireVal = _("Never Expire");
+ } else {
+ keyExpireVal =
+ QString::fromStdString(boost::gregorian::to_iso_string(mKey.expires()));
+ }
- keySizeVarLabel->setText(keySizeVal);
- expireVarLabel->setText(keyExpireVal);
- createdVarLabel->setText(keyCreateTimeVal);
- algorithmVarLabel->setText(keyAlgoVal);
+ keyAlgoVal = QString::fromStdString(mKey.pubkey_algo());
+ keyCreateTimeVal = QString::fromStdString(to_iso_string(mKey.create_time()));
- fingerPrintVarLabel->setText(beautifyFingerprint(mKey.fpr));
+ keySizeVarLabel->setText(keySizeVal);
+ expireVarLabel->setText(keyExpireVal);
+ createdVarLabel->setText(keyCreateTimeVal);
+ algorithmVarLabel->setText(keyAlgoVal);
+ auto key_fpr = mKey.fpr();
+ fingerPrintVarLabel->setText(
+ QString::fromStdString(beautify_fingerprint(key_fpr)));
}
void KeyPairDetailTab::createKeyServerOperaMenu() {
- keyServerOperaMenu = new QMenu(this);
+ keyServerOperaMenu = new QMenu(this);
- auto *uploadKeyPair = new QAction(tr("Upload Key Pair to Key Server"), this);
- connect(uploadKeyPair, SIGNAL(triggered()), this, SLOT(slotUploadKeyToServer()));
- auto *updateKeyPair = new QAction(tr("Update Key Pair"), this);
- connect(updateKeyPair, SIGNAL(triggered()), this, SLOT(slotUpdateKeyToServer()));
+ auto* uploadKeyPair = new QAction(_("Upload Key Pair to Key Server"), this);
+ connect(uploadKeyPair, SIGNAL(triggered()), this,
+ SLOT(slotUploadKeyToServer()));
+ auto* updateKeyPair = new QAction(_("Update Key Pair"), this);
+ connect(updateKeyPair, SIGNAL(triggered()), this,
+ SLOT(slotUpdateKeyToServer()));
- keyServerOperaMenu->addAction(uploadKeyPair);
- // TODO Solve Refresh Problem
-// keyServerOperaMenu->addAction(updateKeyPair);
+ keyServerOperaMenu->addAction(uploadKeyPair);
+ keyServerOperaMenu->addAction(updateKeyPair);
}
void KeyPairDetailTab::slotUploadKeyToServer() {
- QVector<GpgKey> keys;
- keys.append(mKey);
- auto *dialog = new KeyUploadDialog(mCtx, keys);
+ auto keys = std::make_unique<KeyIdArgsList>();
+ keys->push_back(mKey.id());
+ auto* dialog = new KeyUploadDialog(keys, this);
+ dialog->show();
+ dialog->slotUpload();
}
void KeyPairDetailTab::slotUpdateKeyToServer() {
- QVector<GpgKey> keys;
- keys.append(mKey);
- auto *dialog = new KeyServerImportDialog(mCtx, this);
- dialog->show();
- dialog->slotImportKey(keys);
+ auto keys = std::make_unique<KeyIdArgsList>();
+ keys->push_back(mKey.id());
+ auto* dialog = new KeyServerImportDialog(this);
+ dialog->show();
+ dialog->slotImport(keys);
}
void KeyPairDetailTab::slotGenRevokeCert() {
- auto mOutputFileName = QFileDialog::getSaveFileName(this, tr("Generate revocation certificate"),
- QString(),
- QStringLiteral("%1 (*.rev)").arg(
- tr("Revocation Certificates")));
-
- if (!mOutputFileName.isEmpty())
- mCtx->generateRevokeCert(mKey, mOutputFileName);
-
+ auto literal = QStringLiteral("%1 (*.rev)").arg(_("Revocation Certificates"));
+ QString m_output_file_name;
+
+ QFileDialog dialog(this, "Generate revocation certificate", QString(),
+ literal);
+ dialog.setDefaultSuffix(".rev");
+ dialog.setAcceptMode(QFileDialog::AcceptSave);
+
+ if (dialog.exec()) m_output_file_name = dialog.selectedFiles().front();
+
+ if (!m_output_file_name.isEmpty())
+ CommonUtils::GetInstance()->slotExecuteGpgCommand(
+ {"--command-fd", "0", "--status-fd", "1", "--no-tty", "-o",
+ m_output_file_name, "--gen-revoke", mKey.fpr().c_str()},
+ [](QProcess* proc) -> void {
+ // Code From Gpg4Win
+ while (proc->canReadLine()) {
+ const QString line = QString::fromUtf8(proc->readLine()).trimmed();
+ LOG(INFO) << "line" << line.toStdString();
+ if (line == QLatin1String("[GNUPG:] GET_BOOL gen_revoke.okay")) {
+ proc->write("y\n");
+ } else if (line == QLatin1String("[GNUPG:] GET_LINE "
+ "ask_revocation_reason.code")) {
+ proc->write("0\n");
+ } else if (line == QLatin1String("[GNUPG:] GET_LINE "
+ "ask_revocation_reason.text")) {
+ proc->write("\n");
+ } else if (line ==
+ QLatin1String(
+ "[GNUPG:] GET_BOOL openfile.overwrite.okay")) {
+ // We asked before
+ proc->write("y\n");
+ } else if (line == QLatin1String("[GNUPG:] GET_BOOL "
+ "ask_revocation_reason.okay")) {
+ proc->write("y\n");
+ }
+ }
+ });
+}
+void KeyPairDetailTab::slotRefreshKey() {
+ LOG(INFO) << _("Called");
+ this->mKey = GpgKeyGetter::GetInstance().GetKey(mKey.id());
+ this->slotRefreshKeyInfo();
}
+} // namespace GpgFrontend::UI
diff --git a/src/ui/keypair_details/KeyPairDetailTab.h b/src/ui/keypair_details/KeyPairDetailTab.h
new file mode 100644
index 00000000..782696ac
--- /dev/null
+++ b/src/ui/keypair_details/KeyPairDetailTab.h
@@ -0,0 +1,105 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_KEYPAIRDETAILTAB_H
+#define GPGFRONTEND_KEYPAIRDETAILTAB_H
+
+#include "KeySetExpireDateDialog.h"
+#include "gpg/GpgContext.h"
+#include "ui/GpgFrontendUI.h"
+#include "ui/KeyServerImportDialog.h"
+#include "ui/KeyUploadDialog.h"
+
+namespace GpgFrontend::UI {
+
+class KeyPairDetailTab : public QWidget {
+ Q_OBJECT
+
+ /**
+ * @details Return QString with a space inserted at every fourth character
+ *
+ * @param fingerprint The fingerprint to be beautified
+ */
+ static QString beautifyFingerprint(QString fingerprint);
+
+ void createKeyServerOperaMenu();
+
+ private slots:
+
+ /**
+ * @details Export the key to a file, which is choosen in a file dialog
+ */
+ void slotExportPrivateKey();
+
+ /**
+ * @details Copy the fingerprint to clipboard
+ */
+ void slotCopyFingerprint();
+
+ void slotModifyEditDatetime();
+
+ void slotRefreshKeyInfo();
+
+ void slotUploadKeyToServer();
+
+ void slotUpdateKeyToServer();
+
+ void slotGenRevokeCert();
+
+ void slotRefreshKey();
+
+ private:
+ std::string keyid; /** The id of the key the details should be shown for */
+
+ GpgKey mKey;
+
+ QGroupBox* ownerBox; /** Groupbox containing owner information */
+ QGroupBox* keyBox; /** Groupbox containing key information */
+ QGroupBox* fingerprintBox; /** Groupbox containing fingerprint information */
+ QGroupBox* additionalUidBox; /** Groupbox containing information about
+ additional uids */
+
+ QLabel* nameVarLabel; /** Label containng the keys name */
+ QLabel* emailVarLabel; /** Label containng the keys email */
+ QLabel* commentVarLabel; /** Label containng the keys commment */
+ QLabel* keySizeVarLabel; /** Label containng the keys keysize */
+ QLabel* expireVarLabel; /** Label containng the keys expiration date */
+ QLabel* createdVarLabel; /** Label containng the keys creation date */
+ QLabel* algorithmVarLabel; /** Label containng the keys algorithm */
+ QLabel* keyidVarLabel; /** Label containng the keys keyid */
+ QLabel* fingerPrintVarLabel; /** Label containng the keys fingerprint */
+ QLabel* usageVarLabel;
+ QLabel* actualUsageVarLabel;
+ QLabel* masterKeyExistVarLabel;
+
+ QMenu* keyServerOperaMenu{};
+
+ public:
+ explicit KeyPairDetailTab(const std::string& key_id,
+ QWidget* parent = nullptr);
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_KEYPAIRDETAILTAB_H
diff --git a/src/ui/keypair_details/KeyPairSubkeyTab.cpp b/src/ui/keypair_details/KeyPairSubkeyTab.cpp
index 6a924394..4458be50 100644
--- a/src/ui/keypair_details/KeyPairSubkeyTab.cpp
+++ b/src/ui/keypair_details/KeyPairSubkeyTab.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,243 +24,278 @@
#include "ui/keypair_details/KeyPairSubkeyTab.h"
-KeyPairSubkeyTab::KeyPairSubkeyTab(GpgME::GpgContext *ctx, const GpgKey &key, QWidget *parent) : mCtx(ctx), mKey(key), QWidget(parent) {
-
- createSubkeyList();
- createSubkeyOperaMenu();
-
- listBox = new QGroupBox("Subkey List");
- detailBox = new QGroupBox("Detail of Selected Subkey");
-
- auto uidButtonsLayout = new QGridLayout();
-
- auto addSubkeyButton = new QPushButton(tr("Generate A New Subkey"));
- if(!mKey.is_private_key || !mKey.has_master_key) {
- addSubkeyButton->setDisabled(true);
- setHidden(addSubkeyButton);
- }
-
- uidButtonsLayout->addWidget(addSubkeyButton, 0, 1);
-
- auto *baseLayout = new QVBoxLayout();
-
- auto subkeyListLayout = new QGridLayout();
- subkeyListLayout->addWidget(subkeyList, 0, 0);
- subkeyListLayout->addLayout(uidButtonsLayout, 1, 0);
- subkeyListLayout->setContentsMargins(0, 10, 0, 0);
-
- auto *subkeyDetailLayout = new QGridLayout();
-
- subkeyDetailLayout->addWidget(new QLabel(tr("Key ID: ")), 0, 0);
- subkeyDetailLayout->addWidget(new QLabel(tr("Algorithm: ")), 1, 0);
- subkeyDetailLayout->addWidget(new QLabel(tr("Key Size:")), 2, 0);
- subkeyDetailLayout->addWidget(new QLabel(tr("Usage: ")), 3, 0);
- subkeyDetailLayout->addWidget(new QLabel(tr("Expires On ")), 4, 0);
- subkeyDetailLayout->addWidget(new QLabel(tr("Last Update: ")), 5, 0);
- subkeyDetailLayout->addWidget(new QLabel(tr("Existence: ")), 6, 0);
- subkeyDetailLayout->addWidget(new QLabel(tr("Fingerprint: ")), 7, 0);
-
-
- keyidVarLabel = new QLabel();
- keySizeVarLabel = new QLabel();
- expireVarLabel = new QLabel();
- algorithmVarLabel = new QLabel();
- createdVarLabel = new QLabel();
- usageVarLabel = new QLabel();
- masterKeyExistVarLabel = new QLabel();
- fingerPrintVarLabel = new QLabel();
-
- subkeyDetailLayout->addWidget(keyidVarLabel, 0, 1);
- subkeyDetailLayout->addWidget(keySizeVarLabel, 2, 1);
- subkeyDetailLayout->addWidget(expireVarLabel, 4, 1);
- subkeyDetailLayout->addWidget(algorithmVarLabel, 1, 1);
- subkeyDetailLayout->addWidget(createdVarLabel, 5, 1);
- subkeyDetailLayout->addWidget(usageVarLabel, 3, 1);
- subkeyDetailLayout->addWidget(masterKeyExistVarLabel, 6, 1);
- subkeyDetailLayout->addWidget(fingerPrintVarLabel, 7, 1);
-
- listBox->setLayout(subkeyListLayout);
- listBox->setContentsMargins(0, 5, 0, 0);
- detailBox->setLayout(subkeyDetailLayout);
-
- baseLayout->addWidget(listBox);
- baseLayout->addWidget(detailBox);
- baseLayout->addStretch();
-
- connect(addSubkeyButton, SIGNAL(clicked(bool)), this, SLOT(slotAddSubkey()));
- connect(mCtx, SIGNAL(signalKeyInfoChanged()), this, SLOT(slotRefreshSubkeyList()));
- connect(subkeyList, SIGNAL(itemSelectionChanged()), this, SLOT(slotRefreshSubkeyDetail()));
-
- baseLayout->setContentsMargins(0, 0, 0, 0);
-
- setLayout(baseLayout);
- setAttribute(Qt::WA_DeleteOnClose, true);
-
- slotRefreshSubkeyList();
-
+#include "gpg/function/GpgKeyGetter.h"
+#include "ui/SignalStation.h"
+
+namespace GpgFrontend::UI {
+
+KeyPairSubkeyTab::KeyPairSubkeyTab(const std::string& key_id, QWidget* parent)
+ : QWidget(parent), mKey(GpgKeyGetter::GetInstance().GetKey(key_id)) {
+ createSubkeyList();
+ createSubkeyOperaMenu();
+
+ listBox = new QGroupBox("Subkey List");
+ detailBox = new QGroupBox("Detail of Selected Subkey");
+
+ auto uidButtonsLayout = new QGridLayout();
+
+ auto addSubkeyButton = new QPushButton(_("Generate A New Subkey"));
+ if (!mKey.is_private_key() || !mKey.has_master_key()) {
+ addSubkeyButton->setDisabled(true);
+ setHidden(addSubkeyButton);
+ }
+
+ uidButtonsLayout->addWidget(addSubkeyButton, 0, 1);
+
+ auto* baseLayout = new QVBoxLayout();
+
+ auto subkeyListLayout = new QGridLayout();
+ subkeyListLayout->addWidget(subkeyList, 0, 0);
+ subkeyListLayout->addLayout(uidButtonsLayout, 1, 0);
+ subkeyListLayout->setContentsMargins(0, 10, 0, 0);
+
+ auto* subkeyDetailLayout = new QGridLayout();
+
+ subkeyDetailLayout->addWidget(new QLabel(QString(_("Key ID")) + ": "), 0, 0);
+ subkeyDetailLayout->addWidget(new QLabel(QString(_("Algorithm")) + ": "), 1,
+ 0);
+ subkeyDetailLayout->addWidget(new QLabel(QString(_("Key Size")) + ": "), 2,
+ 0);
+ subkeyDetailLayout->addWidget(new QLabel(QString(_("Usage")) + ": "), 3, 0);
+ subkeyDetailLayout->addWidget(new QLabel(QString(_("Expires On")) + ": "), 4,
+ 0);
+ subkeyDetailLayout->addWidget(new QLabel(QString(_("Last Update")) + ": "), 5,
+ 0);
+ subkeyDetailLayout->addWidget(new QLabel(QString(_("Existence")) + ": "), 6,
+ 0);
+ subkeyDetailLayout->addWidget(new QLabel(QString(_("Fingerprint")) + ": "), 7,
+ 0);
+
+ keyidVarLabel = new QLabel();
+ keySizeVarLabel = new QLabel();
+ expireVarLabel = new QLabel();
+ algorithmVarLabel = new QLabel();
+ createdVarLabel = new QLabel();
+ usageVarLabel = new QLabel();
+ masterKeyExistVarLabel = new QLabel();
+ fingerPrintVarLabel = new QLabel();
+
+ subkeyDetailLayout->addWidget(keyidVarLabel, 0, 1);
+ subkeyDetailLayout->addWidget(keySizeVarLabel, 2, 1);
+ subkeyDetailLayout->addWidget(expireVarLabel, 4, 1);
+ subkeyDetailLayout->addWidget(algorithmVarLabel, 1, 1);
+ subkeyDetailLayout->addWidget(createdVarLabel, 5, 1);
+ subkeyDetailLayout->addWidget(usageVarLabel, 3, 1);
+ subkeyDetailLayout->addWidget(masterKeyExistVarLabel, 6, 1);
+ subkeyDetailLayout->addWidget(fingerPrintVarLabel, 7, 1);
+
+ listBox->setLayout(subkeyListLayout);
+ listBox->setContentsMargins(0, 5, 0, 0);
+ detailBox->setLayout(subkeyDetailLayout);
+
+ baseLayout->addWidget(listBox);
+ baseLayout->addWidget(detailBox);
+ baseLayout->addStretch();
+
+ connect(addSubkeyButton, SIGNAL(clicked(bool)), this, SLOT(slotAddSubkey()));
+ connect(subkeyList, SIGNAL(itemSelectionChanged()), this,
+ SLOT(slotRefreshSubkeyDetail()));
+
+ // key database refresh signal
+ connect(SignalStation::GetInstance(), SIGNAL(KeyDatabaseRefresh()), this,
+ SLOT(slotRefreshKeyInfo()));
+ connect(SignalStation::GetInstance(), SIGNAL(KeyDatabaseRefresh()), this,
+ SLOT(slotRefreshSubkeyList()));
+
+ baseLayout->setContentsMargins(0, 0, 0, 0);
+
+ setLayout(baseLayout);
+ setAttribute(Qt::WA_DeleteOnClose, true);
+
+ slotRefreshSubkeyList();
}
void KeyPairSubkeyTab::createSubkeyList() {
- subkeyList = new QTableWidget(this);
+ subkeyList = new QTableWidget(this);
- subkeyList->setColumnCount(5);
- subkeyList->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
- subkeyList->verticalHeader()->hide();
- subkeyList->setShowGrid(false);
- subkeyList->setSelectionBehavior(QAbstractItemView::SelectRows);
+ subkeyList->setColumnCount(5);
+ subkeyList->horizontalHeader()->setSectionResizeMode(
+ QHeaderView::ResizeToContents);
+ subkeyList->verticalHeader()->hide();
+ subkeyList->setShowGrid(false);
+ subkeyList->setSelectionBehavior(QAbstractItemView::SelectRows);
- // tableitems not editable
- subkeyList->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ // tableitems not editable
+ subkeyList->setEditTriggers(QAbstractItemView::NoEditTriggers);
- // no focus (rectangle around tableitems)
- // may be it should focus on whole row
- subkeyList->setFocusPolicy(Qt::NoFocus);
- subkeyList->setAlternatingRowColors(true);
+ // no focus (rectangle around tableitems)
+ // may be it should focus on whole row
+ subkeyList->setFocusPolicy(Qt::NoFocus);
+ subkeyList->setAlternatingRowColors(true);
- QStringList labels;
- labels << tr("Subkey ID") << tr("Key Size") << tr("Algo") << tr("Create Date") << tr("Expire Date");
+ QStringList labels;
+ labels << _("Subkey ID") << _("Key Size") << _("Algo") << _("Create Date")
+ << _("Expire Date");
- subkeyList->setHorizontalHeaderLabels(labels);
- subkeyList->horizontalHeader()->setStretchLastSection(false);
+ subkeyList->setHorizontalHeaderLabels(labels);
+ subkeyList->horizontalHeader()->setStretchLastSection(false);
}
void KeyPairSubkeyTab::slotRefreshSubkeyList() {
- int row = 0;
-
- subkeyList->setSelectionMode(QAbstractItemView::SingleSelection);
-
- this->buffered_subkeys.clear();
-
- for(const auto &subkeys : mKey.subKeys) {
- if(subkeys.disabled || subkeys.revoked)
- continue;
- this->buffered_subkeys.push_back(&subkeys);
+ LOG(INFO) << "KeyPairSubkeyTab::slotRefreshSubkeyList Called";
+ int row = 0;
+
+ subkeyList->setSelectionMode(QAbstractItemView::SingleSelection);
+
+ this->buffered_subkeys.clear();
+ auto sub_keys = mKey.subKeys();
+ for (auto& sub_key : *sub_keys) {
+ if (sub_key.disabled() || sub_key.revoked()) continue;
+ this->buffered_subkeys.push_back(std::move(sub_key));
+ }
+
+ subkeyList->setRowCount(buffered_subkeys.size());
+
+ for (const auto& subkeys : buffered_subkeys) {
+ auto* tmp0 = new QTableWidgetItem(QString::fromStdString(subkeys.id()));
+ tmp0->setTextAlignment(Qt::AlignCenter);
+ subkeyList->setItem(row, 0, tmp0);
+
+ auto* tmp1 = new QTableWidgetItem(QString::number(subkeys.length()));
+ tmp1->setTextAlignment(Qt::AlignCenter);
+ subkeyList->setItem(row, 1, tmp1);
+
+ auto* tmp2 =
+ new QTableWidgetItem(QString::fromStdString(subkeys.pubkey_algo()));
+ tmp2->setTextAlignment(Qt::AlignCenter);
+ subkeyList->setItem(row, 2, tmp2);
+
+ auto* tmp3 = new QTableWidgetItem(
+ QString::fromStdString(to_iso_string(subkeys.timestamp())));
+ tmp3->setTextAlignment(Qt::AlignCenter);
+ subkeyList->setItem(row, 3, tmp3);
+
+ auto* tmp4 = new QTableWidgetItem(
+ boost::posix_time::to_time_t(
+ boost::posix_time::ptime(subkeys.expires())) == 0
+ ? _("Never Expire")
+ : QString::fromStdString(to_iso_string(subkeys.expires())));
+ tmp4->setTextAlignment(Qt::AlignCenter);
+ subkeyList->setItem(row, 4, tmp4);
+
+ if (!row) {
+ for (auto i = 0; i < subkeyList->columnCount(); i++) {
+ subkeyList->item(row, i)->setForeground(QColor(65, 105, 255));
+ }
}
- subkeyList->setRowCount(buffered_subkeys.size());
-
- for(const auto& subkeys : buffered_subkeys) {
+ row++;
+ }
- auto *tmp0 = new QTableWidgetItem(subkeys->id);
- tmp0->setTextAlignment(Qt::AlignCenter);
- subkeyList->setItem(row, 0, tmp0);
-
- auto *tmp1 = new QTableWidgetItem(QString::number(subkeys->length));
- tmp1->setTextAlignment(Qt::AlignCenter);
- subkeyList->setItem(row, 1, tmp1);
-
- auto *tmp2 = new QTableWidgetItem(subkeys->pubkey_algo);
- tmp2->setTextAlignment(Qt::AlignCenter);
- subkeyList->setItem(row, 2, tmp2);
-
- auto *tmp3= new QTableWidgetItem(subkeys->timestamp.toString());
- tmp3->setTextAlignment(Qt::AlignCenter);
- subkeyList->setItem(row, 3, tmp3);
-
- auto *tmp4= new QTableWidgetItem(subkeys->expires.toTime_t() == 0 ? tr("Never Expire") : subkeys->expires.toString());
- tmp4->setTextAlignment(Qt::AlignCenter);
- subkeyList->setItem(row, 4, tmp4);
-
- row++;
- }
-
- if(subkeyList->rowCount() > 0) {
- subkeyList->selectRow(0);
- }
+ if (subkeyList->rowCount() > 0) {
+ subkeyList->selectRow(0);
+ }
}
void KeyPairSubkeyTab::slotAddSubkey() {
- auto dialog = new SubkeyGenerateDialog(mCtx, mKey, this);
- dialog->show();
+ auto dialog = new SubkeyGenerateDialog(mKey.id(), this);
+ dialog->show();
}
void KeyPairSubkeyTab::slotRefreshSubkeyDetail() {
-
- auto key = getSelectedSubkey();
-
- keyidVarLabel->setText(key->id);
- keySizeVarLabel->setText(QString::number(key->length));
-
- expireVarLabel->setText(key->expires.toTime_t() == 0 ? tr("Never Expires") : key->expires.toString());
- if(key->expires.toTime_t() != 0 && key->expires < QDateTime::currentDateTime()) {
- auto paletteExpired = expireVarLabel->palette();
- paletteExpired.setColor(expireVarLabel->foregroundRole(), Qt::red);
- expireVarLabel->setPalette(paletteExpired);
- } else {
- auto paletteValid = expireVarLabel->palette();
- paletteValid.setColor(expireVarLabel->foregroundRole(), Qt::darkGreen);
- expireVarLabel->setPalette(paletteValid);
- }
-
- algorithmVarLabel->setText(key->pubkey_algo);
- createdVarLabel->setText(key->timestamp.toString());
-
- QString usage;
- QTextStream usage_steam(&usage);
-
- if(key->can_certify)
- usage_steam << "Cert ";
- if(key->can_encrypt)
- usage_steam << "Encr ";
- if(key->can_sign)
- usage_steam << "Sign ";
- if(key->can_authenticate)
- usage_steam << "Auth ";
-
- usageVarLabel->setText(usage);
-
- // Show the situation that master key not exists.
- masterKeyExistVarLabel->setText(key->secret ? "Exists" : "Not Exists");
- if(!key->secret){
- auto paletteExpired = masterKeyExistVarLabel->palette();
- paletteExpired.setColor(masterKeyExistVarLabel->foregroundRole(), Qt::red);
- masterKeyExistVarLabel->setPalette(paletteExpired);
- } else {
- auto paletteValid = masterKeyExistVarLabel->palette();
- paletteValid.setColor(masterKeyExistVarLabel->foregroundRole(), Qt::darkGreen);
- masterKeyExistVarLabel->setPalette(paletteValid);
- }
-
- fingerPrintVarLabel->setText(key->fpr);
+ auto& subkey = getSelectedSubkey();
+
+ keyidVarLabel->setText(QString::fromStdString(subkey.id()));
+ keySizeVarLabel->setText(QString::number(subkey.length()));
+
+ time_t subkey_time_t =
+ boost::posix_time::to_time_t(boost::posix_time::ptime(subkey.expires()));
+
+ expireVarLabel->setText(
+ subkey_time_t == 0
+ ? _("Never Expires")
+ : QString::fromStdString(to_iso_string(subkey.expires())));
+ if (subkey_time_t != 0 &&
+ subkey.expires() < boost::posix_time::second_clock::local_time().date()) {
+ auto paletteExpired = expireVarLabel->palette();
+ paletteExpired.setColor(expireVarLabel->foregroundRole(), Qt::red);
+ expireVarLabel->setPalette(paletteExpired);
+ } else {
+ auto paletteValid = expireVarLabel->palette();
+ paletteValid.setColor(expireVarLabel->foregroundRole(), Qt::darkGreen);
+ expireVarLabel->setPalette(paletteValid);
+ }
+
+ algorithmVarLabel->setText(QString::fromStdString(subkey.pubkey_algo()));
+ createdVarLabel->setText(
+ QString::fromStdString(to_iso_string(subkey.timestamp())));
+
+ QString usage;
+ QTextStream usage_steam(&usage);
+
+ if (subkey.can_certify()) usage_steam << _("Cert") << " ";
+ if (subkey.can_encrypt()) usage_steam << _("Encr") << " ";
+ if (subkey.can_sign()) usage_steam << _("Sign") << " ";
+ if (subkey.can_authenticate()) usage_steam << _("Auth") << " ";
+
+ usageVarLabel->setText(usage);
+
+ // Show the situation that master key not exists.
+ masterKeyExistVarLabel->setText(subkey.secret() ? _("Exists")
+ : _("Not Exists"));
+ if (!subkey.secret()) {
+ auto paletteExpired = masterKeyExistVarLabel->palette();
+ paletteExpired.setColor(masterKeyExistVarLabel->foregroundRole(), Qt::red);
+ masterKeyExistVarLabel->setPalette(paletteExpired);
+ } else {
+ auto paletteValid = masterKeyExistVarLabel->palette();
+ paletteValid.setColor(masterKeyExistVarLabel->foregroundRole(),
+ Qt::darkGreen);
+ masterKeyExistVarLabel->setPalette(paletteValid);
+ }
+
+ fingerPrintVarLabel->setText(QString::fromStdString(subkey.fpr()));
}
void KeyPairSubkeyTab::createSubkeyOperaMenu() {
- subkeyOperaMenu = new QMenu(this);
- // auto *revokeSubkeyAct = new QAction(tr("Revoke Subkey"));
- auto *editSubkeyAct = new QAction(tr("Edit Expire Date"));
- connect(editSubkeyAct, SIGNAL(triggered(bool)), this, SLOT(slotEditSubkey()));
+ subkeyOperaMenu = new QMenu(this);
+ // auto *revokeSubkeyAct = new QAction(_("Revoke Subkey"));
+ auto* editSubkeyAct = new QAction(_("Edit Expire Date"));
+ connect(editSubkeyAct, SIGNAL(triggered(bool)), this, SLOT(slotEditSubkey()));
- // subkeyOperaMenu->addAction(revokeSubkeyAct);
- subkeyOperaMenu->addAction(editSubkeyAct);
+ // subkeyOperaMenu->addAction(revokeSubkeyAct);
+ subkeyOperaMenu->addAction(editSubkeyAct);
}
void KeyPairSubkeyTab::slotEditSubkey() {
- qDebug() << "Slot Edit Subkry";
- auto *subkey = getSelectedSubkey();
- if(subkey == buffered_subkeys[0]) {
- subkey = nullptr;
- }
- auto dialog = new KeySetExpireDateDialog(mCtx, mKey, subkey, this);
- dialog->show();
-}
-
-void KeyPairSubkeyTab::slotRevokeSubkey() {
+ LOG(INFO) << "KeyPairSubkeyTab::slotEditSubkey Fpr"
+ << getSelectedSubkey().fpr();
+ auto dialog =
+ new KeySetExpireDateDialog(mKey.id(), getSelectedSubkey().fpr(), this);
+ dialog->show();
}
-void KeyPairSubkeyTab::contextMenuEvent(QContextMenuEvent *event) {
- if (!subkeyList->selectedItems().isEmpty()) {
- subkeyOperaMenu->exec(event->globalPos());
- }
+void KeyPairSubkeyTab::slotRevokeSubkey() {}
+
+void KeyPairSubkeyTab::contextMenuEvent(QContextMenuEvent* event) {
+ if (!subkeyList->selectedItems().isEmpty()) {
+ subkeyOperaMenu->exec(event->globalPos());
+ }
}
-const GpgSubKey *KeyPairSubkeyTab::getSelectedSubkey() {
- int row = 0;
+const GpgSubKey& KeyPairSubkeyTab::getSelectedSubkey() {
+ int row = 0;
- for(int i = 0 ; i < subkeyList->rowCount(); i++) {
- if(subkeyList->item(row, 0)->isSelected()) break;
- row++;
- }
+ for (int i = 0; i < subkeyList->rowCount(); i++) {
+ if (subkeyList->item(row, 0)->isSelected()) break;
+ row++;
+ }
- return buffered_subkeys[row];
+ return buffered_subkeys[row];
}
+void KeyPairSubkeyTab::slotRefreshKeyInfo() {
+ mKey = GpgKeyGetter::GetInstance().GetKey(mKey.id());
+}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/keypair_details/KeyPairSubkeyTab.h b/src/ui/keypair_details/KeyPairSubkeyTab.h
new file mode 100644
index 00000000..018f6ddc
--- /dev/null
+++ b/src/ui/keypair_details/KeyPairSubkeyTab.h
@@ -0,0 +1,86 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_KEYPAIRSUBKEYTAB_H
+#define GPGFRONTEND_KEYPAIRSUBKEYTAB_H
+
+#include "KeySetExpireDateDialog.h"
+#include "gpg/GpgContext.h"
+#include "ui/GpgFrontendUI.h"
+#include "ui/keygen/SubkeyGenerateDialog.h"
+
+namespace GpgFrontend::UI {
+
+class KeyPairSubkeyTab : public QWidget {
+ Q_OBJECT
+
+ public:
+ KeyPairSubkeyTab(const std::string& key, QWidget* parent);
+
+ private:
+ void createSubkeyList();
+
+ void createSubkeyOperaMenu();
+
+ const GpgSubKey& getSelectedSubkey();
+
+ GpgKey mKey;
+ QTableWidget* subkeyList{};
+ std::vector<GpgSubKey> buffered_subkeys;
+
+ QGroupBox* listBox;
+ QGroupBox* detailBox;
+
+ QMenu* subkeyOperaMenu{};
+
+ QLabel* keySizeVarLabel; /** Label containng the keys keysize */
+ QLabel* expireVarLabel; /** Label containng the keys expiration date */
+ QLabel* createdVarLabel; /** Label containng the keys creation date */
+ QLabel* algorithmVarLabel; /** Label containng the keys algorithm */
+ QLabel* keyidVarLabel; /** Label containng the keys keyid */
+ QLabel* fingerPrintVarLabel; /** Label containng the keys fingerprint */
+ QLabel* usageVarLabel;
+ QLabel* masterKeyExistVarLabel;
+
+ private slots:
+
+ void slotAddSubkey();
+
+ void slotRefreshSubkeyList();
+
+ void slotRefreshSubkeyDetail();
+
+ void slotEditSubkey();
+
+ void slotRevokeSubkey();
+
+ void slotRefreshKeyInfo();
+
+ protected:
+ void contextMenuEvent(QContextMenuEvent* event) override;
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_KEYPAIRSUBKEYTAB_H
diff --git a/src/ui/keypair_details/KeyPairUIDTab.cpp b/src/ui/keypair_details/KeyPairUIDTab.cpp
index 2954aadb..3d56699a 100644
--- a/src/ui/keypair_details/KeyPairUIDTab.cpp
+++ b/src/ui/keypair_details/KeyPairUIDTab.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,488 +24,511 @@
#include "ui/keypair_details/KeyPairUIDTab.h"
-KeyPairUIDTab::KeyPairUIDTab(GpgME::GpgContext *ctx, const GpgKey &key, QWidget *parent) : QWidget(parent), mKey(key) {
+#include "gpg/function/GpgKeyGetter.h"
+#include "gpg/function/GpgKeyManager.h"
+#include "gpg/function/UidOperator.h"
+#include "ui/SignalStation.h"
- mCtx = ctx;
+namespace GpgFrontend::UI {
- createUIDList();
- createSignList();
- createManageUIDMenu();
- createUIDPopupMenu();
- createSignPopupMenu();
+KeyPairUIDTab::KeyPairUIDTab(const std::string& key_id, QWidget* parent)
+ : QWidget(parent), mKey(GpgKeyGetter::GetInstance().GetKey(key_id)) {
+ createUIDList();
+ createSignList();
+ createManageUIDMenu();
+ createUIDPopupMenu();
+ createSignPopupMenu();
- auto uidButtonsLayout = new QGridLayout();
+ auto uidButtonsLayout = new QGridLayout();
- auto addUIDButton = new QPushButton(tr("New UID"));
- auto manageUIDButton = new QPushButton(tr("UID Management"));
+ auto addUIDButton = new QPushButton(_("New UID"));
+ auto manageUIDButton = new QPushButton(_("UID Management"));
- if(mKey.has_master_key) {
- manageUIDButton->setMenu(manageSelectedUIDMenu);
- } else {
- manageUIDButton->setDisabled(true);
- }
+ if (mKey.has_master_key()) {
+ manageUIDButton->setMenu(manageSelectedUIDMenu);
+ } else {
+ manageUIDButton->setDisabled(true);
+ }
+
+ uidButtonsLayout->addWidget(addUIDButton, 0, 1);
+ uidButtonsLayout->addWidget(manageUIDButton, 0, 2);
- uidButtonsLayout->addWidget(addUIDButton, 0, 1);
- uidButtonsLayout->addWidget(manageUIDButton, 0, 2);
+ auto gridLayout = new QGridLayout();
- auto gridLayout = new QGridLayout();
+ gridLayout->addWidget(uidList, 0, 0);
+ gridLayout->addLayout(uidButtonsLayout, 1, 0);
+ gridLayout->setContentsMargins(0, 10, 0, 0);
- gridLayout->addWidget(uidList, 0, 0);
- gridLayout->addLayout(uidButtonsLayout, 1, 0);
- gridLayout->setContentsMargins(0, 10, 0, 0);
+ auto uidGroupBox = new QGroupBox();
+ uidGroupBox->setLayout(gridLayout);
+ uidGroupBox->setTitle(_("UIDs"));
- auto uidGroupBox = new QGroupBox();
- uidGroupBox->setLayout(gridLayout);
- uidGroupBox->setTitle(tr("UIDs"));
+ auto signGridLayout = new QGridLayout();
+ signGridLayout->addWidget(sigList, 0, 0);
+ signGridLayout->setContentsMargins(0, 10, 0, 0);
- auto signGridLayout = new QGridLayout();
- signGridLayout->addWidget(sigList, 0, 0);
- signGridLayout->setContentsMargins(0, 10, 0, 0);
+ auto signGroupBox = new QGroupBox();
+ signGroupBox->setLayout(signGridLayout);
+ signGroupBox->setTitle(_("Signature of Selected UID"));
- auto signGroupBox = new QGroupBox();
- signGroupBox->setLayout(signGridLayout);
- signGroupBox->setTitle(tr("Signature of Selected UID"));
+ auto vboxLayout = new QVBoxLayout();
+ vboxLayout->addWidget(uidGroupBox);
+ vboxLayout->addWidget(signGroupBox);
+ vboxLayout->setContentsMargins(0, 0, 0, 0);
- auto vboxLayout = new QVBoxLayout();
- vboxLayout->addWidget(uidGroupBox);
- vboxLayout->addWidget(signGroupBox);
- vboxLayout->setContentsMargins(0, 0, 0, 0);
+ connect(addUIDButton, SIGNAL(clicked(bool)), this, SLOT(slotAddUID()));
+ connect(uidList, SIGNAL(itemSelectionChanged()), this,
+ SLOT(slotRefreshSigList()));
- connect(addUIDButton, SIGNAL(clicked(bool)), this, SLOT(slotAddUID()));
- connect(mCtx, SIGNAL(signalKeyInfoChanged()), this, SLOT(slotRefreshUIDList()));
- connect(uidList, SIGNAL(itemSelectionChanged()), this, SLOT(slotRefreshSigList()));
+ // Key Database Refresh
+ connect(SignalStation::GetInstance(), SIGNAL(KeyDatabaseRefresh()), this,
+ SLOT(slotRefreshKey()));
- setLayout(vboxLayout);
- setAttribute(Qt::WA_DeleteOnClose, true);
+ connect(this, SIGNAL(signalUpdateUIDInfo()), SignalStation::GetInstance(),
+ SIGNAL(KeyDatabaseRefresh()));
- slotRefreshUIDList();
+ setLayout(vboxLayout);
+ setAttribute(Qt::WA_DeleteOnClose, true);
+
+ slotRefreshUIDList();
}
void KeyPairUIDTab::createUIDList() {
-
- uidList = new QTableWidget(this);
- uidList->setColumnCount(4);
- uidList->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
- uidList->verticalHeader()->hide();
- uidList->setShowGrid(false);
- uidList->setSelectionBehavior(QAbstractItemView::SelectRows);
- uidList->setSelectionMode( QAbstractItemView::SingleSelection );
-
- // tableitems not editable
- uidList->setEditTriggers(QAbstractItemView::NoEditTriggers);
-
- // no focus (rectangle around tableitems)
- // may be it should focus on whole row
- uidList->setFocusPolicy(Qt::NoFocus);
- uidList->setAlternatingRowColors(true);
-
- QStringList labels;
- labels << tr("Select") << tr("Name") << tr("Email") << tr("Comment");
- uidList->setHorizontalHeaderLabels(labels);
- uidList->horizontalHeader()->setStretchLastSection(true);
+ uidList = new QTableWidget(this);
+ uidList->setColumnCount(4);
+ uidList->horizontalHeader()->setSectionResizeMode(
+ QHeaderView::ResizeToContents);
+ uidList->verticalHeader()->hide();
+ uidList->setShowGrid(false);
+ uidList->setSelectionBehavior(QAbstractItemView::SelectRows);
+ uidList->setSelectionMode(QAbstractItemView::SingleSelection);
+
+ // tableitems not editable
+ uidList->setEditTriggers(QAbstractItemView::NoEditTriggers);
+
+ // no focus (rectangle around tableitems)
+ // may be it should focus on whole row
+ uidList->setFocusPolicy(Qt::NoFocus);
+ uidList->setAlternatingRowColors(true);
+
+ QStringList labels;
+ labels << _("Select") << _("Name") << _("Email") << _("Comment");
+ uidList->setHorizontalHeaderLabels(labels);
+ uidList->horizontalHeader()->setStretchLastSection(true);
}
void KeyPairUIDTab::createSignList() {
-
- sigList = new QTableWidget(this);
- sigList->setColumnCount(5);
- sigList->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
- sigList->verticalHeader()->hide();
- sigList->setShowGrid(false);
- sigList->setSelectionBehavior(QAbstractItemView::SelectRows);
-
- // table items not editable
- sigList->setEditTriggers(QAbstractItemView::NoEditTriggers);
-
- // no focus (rectangle around table items)
- // may be it should focus on whole row
- sigList->setFocusPolicy(Qt::NoFocus);
- sigList->setAlternatingRowColors(true);
-
- QStringList labels;
- labels << tr("Key ID") << tr("Name") << tr("Email") << tr("Create Date") << tr("Expired Date");
- sigList->setHorizontalHeaderLabels(labels);
- sigList->horizontalHeader()->setStretchLastSection(false);
-
+ sigList = new QTableWidget(this);
+ sigList->setColumnCount(5);
+ sigList->horizontalHeader()->setSectionResizeMode(
+ QHeaderView::ResizeToContents);
+ sigList->verticalHeader()->hide();
+ sigList->setShowGrid(false);
+ sigList->setSelectionBehavior(QAbstractItemView::SelectRows);
+
+ // table items not editable
+ sigList->setEditTriggers(QAbstractItemView::NoEditTriggers);
+
+ // no focus (rectangle around table items)
+ // may be it should focus on whole row
+ sigList->setFocusPolicy(Qt::NoFocus);
+ sigList->setAlternatingRowColors(true);
+
+ QStringList labels;
+ labels << _("Key ID") << _("Name") << _("Email") << _("Create Date")
+ << _("Expired Date");
+ sigList->setHorizontalHeaderLabels(labels);
+ sigList->horizontalHeader()->setStretchLastSection(false);
}
void KeyPairUIDTab::slotRefreshUIDList() {
+ int row = 0;
- int row = 0;
+ uidList->setSelectionMode(QAbstractItemView::SingleSelection);
- uidList->setSelectionMode(QAbstractItemView::SingleSelection);
+ this->buffered_uids.clear();
- this->buffered_uids.clear();
-
- for(const auto &uid : mKey.uids) {
- if(uid.invalid || uid.revoked) {
- continue;
- }
- this->buffered_uids.push_back(&uid);
+ auto uids = mKey.uids();
+ for (auto& uid : *uids) {
+ if (uid.invalid() || uid.revoked()) {
+ continue;
}
+ this->buffered_uids.push_back(std::move(uid));
+ }
- uidList->setRowCount(buffered_uids.size());
-
- for(const auto& uid : buffered_uids) {
+ uidList->setRowCount(buffered_uids.size());
- auto *tmp0 = new QTableWidgetItem(uid->name);
- uidList->setItem(row, 1, tmp0);
+ for (const auto& uid : buffered_uids) {
+ auto* tmp0 = new QTableWidgetItem(QString::fromStdString(uid.name()));
+ uidList->setItem(row, 1, tmp0);
- auto *tmp1 = new QTableWidgetItem(uid->email);
- uidList->setItem(row, 2, tmp1);
+ auto* tmp1 = new QTableWidgetItem(QString::fromStdString(uid.email()));
+ uidList->setItem(row, 2, tmp1);
- auto *tmp2 = new QTableWidgetItem(uid->comment);
- uidList->setItem(row, 3, tmp2);
+ auto* tmp2 = new QTableWidgetItem(QString::fromStdString(uid.comment()));
+ uidList->setItem(row, 3, tmp2);
- auto *tmp3 = new QTableWidgetItem(QString::number(row));
- tmp3->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
- tmp3->setTextAlignment(Qt::AlignCenter);
- tmp3->setCheckState(Qt::Unchecked);
- uidList->setItem(row, 0, tmp3);
+ auto* tmp3 = new QTableWidgetItem(QString::number(row));
+ tmp3->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled |
+ Qt::ItemIsSelectable);
+ tmp3->setTextAlignment(Qt::AlignCenter);
+ tmp3->setCheckState(Qt::Unchecked);
+ uidList->setItem(row, 0, tmp3);
- row++;
+ if (!row) {
+ for (auto i = 0; i < uidList->columnCount(); i++) {
+ uidList->item(row, i)->setForeground(QColor(65, 105, 255));
+ }
}
- if(uidList->rowCount() > 0) {
- uidList->selectRow(0);
- }
+ row++;
+ }
- slotRefreshSigList();
+ if (uidList->rowCount() > 0) {
+ uidList->selectRow(0);
+ }
+
+ slotRefreshSigList();
}
void KeyPairUIDTab::slotRefreshSigList() {
+ int uidRow = 0, sigRow = 0;
+ for (const auto& uid : buffered_uids) {
+ // Only Show Selected UID Signatures
+ if (!uidList->item(uidRow++, 0)->isSelected()) {
+ continue;
+ }
- int uidRow = 0, sigRow = 0;
- for(const auto& uid : buffered_uids) {
-
- // Only Show Selected UID Signatures
- if(!uidList->item(uidRow++, 0)->isSelected()) {
- continue;
- }
-
- buffered_signatures.clear();
-
- for(const auto &sig : uid->signatures) {
- if(sig.invalid || sig.revoked) {
- continue;
- }
- buffered_signatures.push_back(&sig);
- }
-
- sigList->setRowCount(buffered_signatures.size());
-
- for(const auto &sig : buffered_signatures) {
+ buffered_signatures.clear();
+ auto signatures = uid.signatures();
+ for (auto& sig : *signatures) {
+ if (sig.invalid() || sig.revoked()) {
+ continue;
+ }
+ buffered_signatures.push_back(std::move(sig));
+ }
- auto *tmp0 = new QTableWidgetItem(sig->keyid);
- sigList->setItem(sigRow, 0, tmp0);
+ sigList->setRowCount(buffered_signatures.size());
- if(gpgme_err_code(sig->status) == GPG_ERR_NO_PUBKEY) {
- auto *tmp2 = new QTableWidgetItem("<Unknown>");
- sigList->setItem(sigRow, 1, tmp2);
+ for (const auto& sig : buffered_signatures) {
+ auto* tmp0 = new QTableWidgetItem(QString::fromStdString(sig.keyid()));
+ sigList->setItem(sigRow, 0, tmp0);
- auto *tmp3 = new QTableWidgetItem("<Unknown>");
- sigList->setItem(sigRow, 2, tmp3);
- } else {
- auto *tmp2 = new QTableWidgetItem(sig->name);
- sigList->setItem(sigRow, 1, tmp2);
+ if (gpgme_err_code(sig.status()) == GPG_ERR_NO_PUBKEY) {
+ auto* tmp2 = new QTableWidgetItem("<Unknown>");
+ sigList->setItem(sigRow, 1, tmp2);
- auto *tmp3 = new QTableWidgetItem(sig->email);
- sigList->setItem(sigRow, 2, tmp3);
- }
+ auto* tmp3 = new QTableWidgetItem("<Unknown>");
+ sigList->setItem(sigRow, 2, tmp3);
+ } else {
+ auto* tmp2 = new QTableWidgetItem(QString::fromStdString(sig.name()));
+ sigList->setItem(sigRow, 1, tmp2);
- auto *tmp4 = new QTableWidgetItem(sig->create_time.toString());
- sigList->setItem(sigRow, 3, tmp4);
+ auto* tmp3 = new QTableWidgetItem(QString::fromStdString(sig.email()));
+ sigList->setItem(sigRow, 2, tmp3);
+ }
- auto *tmp5 = new QTableWidgetItem(sig->expire_time.toTime_t() == 0 ? tr("Never Expires") : sig->expire_time.toString());
- tmp5->setTextAlignment(Qt::AlignCenter);
- sigList->setItem(sigRow, 4, tmp5);
+ auto* tmp4 = new QTableWidgetItem(QString::fromStdString(
+ boost::gregorian::to_iso_string(sig.create_time())));
+ sigList->setItem(sigRow, 3, tmp4);
- sigRow++;
- }
+ auto* tmp5 = new QTableWidgetItem(
+ boost::posix_time::to_time_t(
+ boost::posix_time::ptime(sig.expire_time())) == 0
+ ? _("Never Expires")
+ : QString::fromStdString(
+ boost::gregorian::to_iso_string(sig.expire_time())));
+ tmp5->setTextAlignment(Qt::AlignCenter);
+ sigList->setItem(sigRow, 4, tmp5);
- break;
+ sigRow++;
}
+
+ break;
+ }
}
void KeyPairUIDTab::slotAddSign() {
-
- QVector<GpgUID> selected_uids;
- getUIDChecked(selected_uids);
-
- if(selected_uids.isEmpty()) {
- QMessageBox::information(nullptr,
- tr("Invalid Operation"),
- tr("Please select one or more UIDs before doing this operation."));
- return;
- }
-
- auto keySignDialog = new KeyUIDSignDialog(mCtx, mKey, selected_uids, this);
- keySignDialog->show();
+ auto selected_uids = getUIDChecked();
+
+ if (selected_uids->empty()) {
+ QMessageBox::information(
+ nullptr, _("Invalid Operation"),
+ _("Please select one or more UIDs before doing this operation."));
+ return;
+ }
+
+ auto keySignDialog =
+ new KeyUIDSignDialog(mKey, std::move(selected_uids), this);
+ keySignDialog->show();
}
-
-
-void KeyPairUIDTab::getUIDChecked(QVector<GpgUID> &selected_uids) {
-
- auto &uids = buffered_uids;
-
- for (int i = 0; i < uidList->rowCount(); i++) {
- if (uidList->item(i, 0)->checkState() == Qt::Checked) {
- selected_uids.push_back(*uids[i]);
- }
- }
+UIDArgsListPtr KeyPairUIDTab::getUIDChecked() {
+ auto selected_uids = std::make_unique<UIDArgsList>();
+ for (int i = 0; i < uidList->rowCount(); i++) {
+ if (uidList->item(i, 0)->checkState() == Qt::Checked)
+ selected_uids->push_back(buffered_uids[i].uid());
+ }
+ return selected_uids;
}
void KeyPairUIDTab::createManageUIDMenu() {
+ manageSelectedUIDMenu = new QMenu(this);
- manageSelectedUIDMenu = new QMenu(this);
-
- auto *signUIDAct = new QAction(tr("Sign Selected UID(s)"), this);
- connect(signUIDAct, SIGNAL(triggered()), this, SLOT(slotAddSign()));
- auto *delUIDAct = new QAction(tr("Delete Selected UID(s)"), this);
- connect(delUIDAct, SIGNAL(triggered()), this, SLOT(slotDelUID()));
+ auto* signUIDAct = new QAction(_("Sign Selected UID(s)"), this);
+ connect(signUIDAct, SIGNAL(triggered()), this, SLOT(slotAddSign()));
+ auto* delUIDAct = new QAction(_("Delete Selected UID(s)"), this);
+ connect(delUIDAct, SIGNAL(triggered()), this, SLOT(slotDelUID()));
- if(mKey.has_master_key) {
- manageSelectedUIDMenu->addAction(signUIDAct);
- manageSelectedUIDMenu->addAction(delUIDAct);
- }
+ if (mKey.has_master_key()) {
+ manageSelectedUIDMenu->addAction(signUIDAct);
+ manageSelectedUIDMenu->addAction(delUIDAct);
+ }
}
void KeyPairUIDTab::slotAddUID() {
- auto keyNewUIDDialog = new KeyNewUIDDialog(mCtx, mKey, this);
- connect(keyNewUIDDialog, SIGNAL(finished(int)), this, SLOT(slotAddUIDResult(int)));
- connect(keyNewUIDDialog, SIGNAL(finished(int)), keyNewUIDDialog, SLOT(deleteLater()));
- keyNewUIDDialog->show();
+ auto keyNewUIDDialog = new KeyNewUIDDialog(mKey.id(), this);
+ connect(keyNewUIDDialog, SIGNAL(finished(int)), this,
+ SLOT(slotAddUIDResult(int)));
+ connect(keyNewUIDDialog, SIGNAL(finished(int)), keyNewUIDDialog,
+ SLOT(deleteLater()));
+ keyNewUIDDialog->show();
}
void KeyPairUIDTab::slotAddUIDResult(int result) {
- if(result == 1) {
- QMessageBox::information(nullptr,
- tr("Successful Operation"),
- tr("Successfully added a new UID."));
- } else if (result == -1) {
- QMessageBox::critical(nullptr,
- tr("Operation Failed"),
- tr("An error occurred during the operation."));
- }
+ if (result == 1) {
+ QMessageBox::information(nullptr, _("Successful Operation"),
+ _("Successfully added a new UID."));
+ } else if (result == -1) {
+ QMessageBox::critical(nullptr, _("Operation Failed"),
+ _("An error occurred during the operation."));
+ }
}
void KeyPairUIDTab::slotDelUID() {
-
- QVector<GpgUID> selected_uids;
- getUIDChecked(selected_uids);
-
- if(selected_uids.isEmpty()) {
- QMessageBox::information(nullptr,
- tr("Invalid Operation"),
- tr("Please select one or more UIDs before doing this operation."));
- return;
- }
-
- QString keynames;
- for (const auto &uid : selected_uids) {
- keynames.append(uid.name);
- keynames.append("<i> &lt;");
- keynames.append(uid.email);
- keynames.append("&gt; </i><br/>");
- }
-
- int ret = QMessageBox::warning(this, tr("Deleting UIDs"),
- "<b>"+tr("Are you sure that you want to delete the following uids?")+"</b><br/><br/>"+keynames+
- +"<br/>"+tr("The action can not be undone."),
- QMessageBox::No | QMessageBox::Yes);
-
-
- bool if_success = true;
-
- if (ret == QMessageBox::Yes) {
- for(const auto &uid : selected_uids) {
- if(!mCtx->revUID(mKey, uid)) {
- if_success = false;
- }
- }
-
- if(!if_success) {
- QMessageBox::critical(nullptr,
- tr("Operation Failed"),
- tr("An error occurred during the operation."));
- }
-
+ auto selected_uids = getUIDChecked();
+
+ if (selected_uids->empty()) {
+ QMessageBox::information(
+ nullptr, _("Invalid Operation"),
+ _("Please select one or more UIDs before doing this operation."));
+ return;
+ }
+
+ QString keynames;
+ for (auto& uid : *selected_uids) {
+ keynames.append(QString::fromStdString(uid));
+ keynames.append("<br/>");
+ }
+
+ int ret = QMessageBox::warning(
+ this, _("Deleting UIDs"),
+ "<b>" +
+ QString(
+ _("Are you sure that you want to delete the following UIDs?")) +
+ "</b><br/><br/>" + keynames + +"<br/>" +
+ _("The action can not be undone."),
+ QMessageBox::No | QMessageBox::Yes);
+
+ if (ret == QMessageBox::Yes) {
+ for (const auto& uid : *selected_uids) {
+ LOG(INFO) << "KeyPairUIDTab::slotDelUID UID" << uid;
+ if (!UidOperator::GetInstance().revUID(mKey, uid)) {
+ QMessageBox::critical(
+ nullptr, _("Operation Failed"),
+ QString(_("An error occurred during the delete %1 operation."))
+ .arg(uid.c_str()));
+ }
}
+ emit signalUpdateUIDInfo();
+ }
}
void KeyPairUIDTab::slotSetPrimaryUID() {
-
- GpgUID selected_uid;
-
- if(!getUIDSelected(selected_uid)) {
- auto emptyUIDMsg = new QMessageBox();
- emptyUIDMsg->setText("Please select one UID before doing this operation.");
- emptyUIDMsg->exec();
- return;
- }
-
- QString keynames;
-
- keynames.append(selected_uid.name);
- keynames.append("<i> &lt;");
- keynames.append(selected_uid.email);
- keynames.append("&gt; </i><br/>");
-
- int ret = QMessageBox::warning(this, tr("Set Primary UID"),
- "<b>"+tr("Are you sure that you want to set the Primary UID to?")+"</b><br/><br/>"+keynames+
- +"<br/>"+tr("The action can not be undone."),
- QMessageBox::No | QMessageBox::Yes);
-
- if (ret == QMessageBox::Yes) {
- if(!mCtx->setPrimaryUID(mKey, selected_uid)) {
- QMessageBox::critical(nullptr,
- tr("Operation Failed"),
- tr("An error occurred during the operation."));
- }
+ auto selected_uids = getUIDSelected();
+
+ if (selected_uids->empty()) {
+ auto emptyUIDMsg = new QMessageBox();
+ emptyUIDMsg->setText("Please select one UID before doing this operation.");
+ emptyUIDMsg->exec();
+ return;
+ }
+
+ QString keynames;
+
+ keynames.append(QString::fromStdString(selected_uids->front()));
+ keynames.append("<br/>");
+
+ int ret = QMessageBox::warning(
+ this, _("Set Primary UID"),
+ "<b>" +
+ QString(_("Are you sure that you want to set the Primary UID to?")) +
+ "</b><br/><br/>" + keynames + +"<br/>" +
+ _("The action can not be undone."),
+ QMessageBox::No | QMessageBox::Yes);
+
+ if (ret == QMessageBox::Yes) {
+ if (!UidOperator::GetInstance().setPrimaryUID(mKey,
+ selected_uids->front())) {
+ QMessageBox::critical(nullptr, _("Operation Failed"),
+ _("An error occurred during the operation."));
+ } else {
+ emit signalUpdateUIDInfo();
}
+ }
}
-bool KeyPairUIDTab::getUIDSelected(GpgUID &uid) {
- auto &uids = buffered_uids;
- for (int i = 0; i < uidList->rowCount(); i++) {
- if (uidList->item(i, 0)->isSelected()) {
- uid = *uids[i];
- return true;
- }
+UIDArgsListPtr KeyPairUIDTab::getUIDSelected() {
+ auto uids = std::make_unique<UIDArgsList>();
+ for (int i = 0; i < uidList->rowCount(); i++) {
+ if (uidList->item(i, 0)->isSelected()) {
+ uids->push_back(buffered_uids[i].uid());
}
- return false;
+ }
+ return uids;
}
-bool KeyPairUIDTab::getSignSelected(GpgKeySignature &signature) {
- auto &signatures = buffered_signatures;
- for (int i = 0; i < sigList->rowCount(); i++) {
- if (sigList->item(i, 0)->isSelected()) {
- signature = *signatures[i];
- return true;
- }
+SignIdArgsListPtr KeyPairUIDTab::getSignSelected() {
+ auto signatures = std::make_unique<SignIdArgsList>();
+ for (int i = 0; i < sigList->rowCount(); i++) {
+ if (sigList->item(i, 0)->isSelected()) {
+ auto& sign = buffered_signatures[i];
+ signatures->push_back({sign.keyid(), sign.uid()});
}
- return false;
+ }
+ return signatures;
}
void KeyPairUIDTab::createUIDPopupMenu() {
-
- uidPopupMenu = new QMenu(this);
-
- auto *serPrimaryUIDAct = new QAction(tr("Set As Primary"), this);
- connect(serPrimaryUIDAct, SIGNAL(triggered()), this, SLOT(slotSetPrimaryUID()));
- auto *signUIDAct = new QAction(tr("Sign UID"), this);
- connect(signUIDAct, SIGNAL(triggered()), this, SLOT(slotAddSignSingle()));
- auto *delUIDAct = new QAction(tr("Delete UID"), this);
- connect(delUIDAct, SIGNAL(triggered()), this, SLOT(slotDelUIDSingle()));
-
- if(mKey.has_master_key) {
- uidPopupMenu->addAction(serPrimaryUIDAct);
- uidPopupMenu->addAction(signUIDAct);
- uidPopupMenu->addAction(delUIDAct);
- }
+ uidPopupMenu = new QMenu(this);
+
+ auto* serPrimaryUIDAct = new QAction(_("Set As Primary"), this);
+ connect(serPrimaryUIDAct, SIGNAL(triggered()), this,
+ SLOT(slotSetPrimaryUID()));
+ auto* signUIDAct = new QAction(_("Sign UID"), this);
+ connect(signUIDAct, SIGNAL(triggered()), this, SLOT(slotAddSignSingle()));
+ auto* delUIDAct = new QAction(_("Delete UID"), this);
+ connect(delUIDAct, SIGNAL(triggered()), this, SLOT(slotDelUIDSingle()));
+
+ if (mKey.has_master_key()) {
+ uidPopupMenu->addAction(serPrimaryUIDAct);
+ uidPopupMenu->addAction(signUIDAct);
+ uidPopupMenu->addAction(delUIDAct);
+ }
}
-void KeyPairUIDTab::contextMenuEvent(QContextMenuEvent *event) {
- if (uidList->selectedItems().length() > 0 && sigList->selectedItems().isEmpty()) {
- uidPopupMenu->exec(event->globalPos());
- }
+void KeyPairUIDTab::contextMenuEvent(QContextMenuEvent* event) {
+ if (uidList->selectedItems().length() > 0 &&
+ sigList->selectedItems().isEmpty()) {
+ uidPopupMenu->exec(event->globalPos());
+ }
- if (!sigList->selectedItems().isEmpty()) {
- signPopupMenu->exec(event->globalPos());
- }
+ if (!sigList->selectedItems().isEmpty()) {
+ signPopupMenu->exec(event->globalPos());
+ }
}
void KeyPairUIDTab::slotAddSignSingle() {
-
- GpgUID selected_uid;
-
- if(!getUIDSelected(selected_uid)) {
- QMessageBox::information(nullptr,
- tr("Invalid Operation"),
- tr("Please select one UID before doing this operation."));
- return;
- }
-
- auto selected_uids = QVector<GpgUID>({selected_uid });
- auto keySignDialog = new KeyUIDSignDialog(mCtx, mKey, selected_uids, this);
- keySignDialog->show();
+ auto selected_uids = getUIDSelected();
+
+ if (selected_uids->empty()) {
+ QMessageBox::information(
+ nullptr, _("Invalid Operation"),
+ _("Please select one UID before doing this operation."));
+ return;
+ }
+
+ auto keySignDialog =
+ new KeyUIDSignDialog(mKey, std::move(selected_uids), this);
+ keySignDialog->show();
}
void KeyPairUIDTab::slotDelUIDSingle() {
- GpgUID selected_uid;
-
- if(!getUIDSelected(selected_uid)) {
- QMessageBox::information(nullptr,
- tr("Invalid Operation"),
- tr("Please select one UID before doing this operation."));
- return;
- }
-
- QString keynames;
-
- keynames.append(selected_uid.name);
- keynames.append("<i> &lt;");
- keynames.append(selected_uid.email);
- keynames.append("&gt; </i><br/>");
-
- int ret = QMessageBox::warning(this, tr("Deleting UID"),
- "<b>"+tr("Are you sure that you want to delete the following uid?")+"</b><br/><br/>"+keynames+
- +"<br/>"+tr("The action can not be undone."),
- QMessageBox::No | QMessageBox::Yes);
-
- if (ret == QMessageBox::Yes) {
- if(!mCtx->revUID(mKey, selected_uid)) {
- QMessageBox::critical(nullptr,
- tr("Operation Failed"),
- tr("An error occurred during the operation."));
- }
+ auto selected_uids = getUIDSelected();
+ if (selected_uids->empty()) {
+ QMessageBox::information(
+ nullptr, _("Invalid Operation"),
+ _("Please select one UID before doing this operation."));
+ return;
+ }
+
+ QString keynames;
+
+ keynames.append(QString::fromStdString(selected_uids->front()));
+ keynames.append("<br/>");
+
+ int ret = QMessageBox::warning(
+ this, _("Deleting UID"),
+ "<b>" +
+ QString(
+ _("Are you sure that you want to delete the following uid?")) +
+ "</b><br/><br/>" + keynames + +"<br/>" +
+ _("The action can not be undone."),
+ QMessageBox::No | QMessageBox::Yes);
+
+ if (ret == QMessageBox::Yes) {
+ if (!UidOperator::GetInstance().revUID(mKey, selected_uids->front())) {
+ QMessageBox::critical(nullptr, _("Operation Failed"),
+ _("An error occurred during the operation."));
+ } else {
+ emit signalUpdateUIDInfo();
}
+ }
}
void KeyPairUIDTab::createSignPopupMenu() {
- signPopupMenu = new QMenu(this);
+ signPopupMenu = new QMenu(this);
- auto *delSignAct = new QAction(tr("Delete(Revoke) Key Signature"), this);
- connect(delSignAct, SIGNAL(triggered()), this, SLOT(slotDelSign()));
+ auto* delSignAct = new QAction(_("Delete(Revoke) Key Signature"), this);
+ connect(delSignAct, SIGNAL(triggered()), this, SLOT(slotDelSign()));
- signPopupMenu->addAction(delSignAct);
+ signPopupMenu->addAction(delSignAct);
}
void KeyPairUIDTab::slotDelSign() {
- GpgKeySignature selected_sign;
-
- if(!getSignSelected(selected_sign)) {
- QMessageBox::information(nullptr,
- tr("Invalid Operation"),
- tr("Please select one Key Signature before doing this operation."));
- return;
- }
-
- if(gpgme_err_code(selected_sign.status) == GPG_ERR_NO_PUBKEY) {
- QMessageBox::critical(nullptr,
- tr("Invalid Operation"),
- tr("To delete the signature, you need to have its corresponding public key in the local database."));
- return;
- }
-
- QString keynames;
-
- keynames.append(selected_sign.name);
- keynames.append("<i> &lt;");
- keynames.append(selected_sign.email);
- keynames.append("&gt; </i><br/>");
-
- int ret = QMessageBox::warning(this, tr("Deleting Key Signature"),
- "<b>"+tr("Are you sure that you want to delete the following signature?")+"</b><br/><br/>"+keynames+
- +"<br/>"+tr("The action can not be undone."),
- QMessageBox::No | QMessageBox::Yes);
-
- if (ret == QMessageBox::Yes) {
- if(!mCtx->revSign(mKey, selected_sign)) {
- QMessageBox::critical(nullptr,
- tr("Operation Failed"),
- tr("An error occurred during the operation."));
- }
+ auto selected_signs = getSignSelected();
+ if (selected_signs->empty()) {
+ QMessageBox::information(
+ nullptr, _("Invalid Operation"),
+ _("Please select one Key Signature before doing this operation."));
+ return;
+ }
+
+ if (!GpgKeyGetter::GetInstance()
+ .GetKey(selected_signs->front().first)
+ .good()) {
+ QMessageBox::critical(
+ nullptr, _("Invalid Operation"),
+ _("To delete the signature, you need to have its corresponding public "
+ "key in the local database."));
+ return;
+ }
+
+ QString keynames;
+
+ keynames.append(QString::fromStdString(selected_signs->front().second));
+ keynames.append("<br/>");
+
+ int ret =
+ QMessageBox::warning(this, _("Deleting Key Signature"),
+ "<b>" +
+ QString(_("Are you sure that you want to delete "
+ "the following signature?")) +
+ "</b><br/><br/>" + keynames + +"<br/>" +
+ _("The action can not be undone."),
+ QMessageBox::No | QMessageBox::Yes);
+
+ if (ret == QMessageBox::Yes) {
+ if (!GpgKeyManager::GetInstance().revSign(mKey, selected_signs)) {
+ QMessageBox::critical(nullptr, _("Operation Failed"),
+ _("An error occurred during the operation."));
}
+ }
}
+void KeyPairUIDTab::slotRefreshKey() {
+ this->mKey = GpgKeyGetter::GetInstance().GetKey(this->mKey.id());
+ this->slotRefreshUIDList();
+ this->slotRefreshSigList();
+}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/keypair_details/KeyPairUIDTab.h b/src/ui/keypair_details/KeyPairUIDTab.h
new file mode 100644
index 00000000..6dece8d5
--- /dev/null
+++ b/src/ui/keypair_details/KeyPairUIDTab.h
@@ -0,0 +1,100 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_KEYPAIRUIDTAB_H
+#define GPGFRONTEND_KEYPAIRUIDTAB_H
+
+#include "KeyNewUIDDialog.h"
+#include "KeyUIDSignDialog.h"
+#include "gpg/GpgContext.h"
+#include "ui/GpgFrontendUI.h"
+
+namespace GpgFrontend::UI {
+
+class KeyPairUIDTab : public QWidget {
+ Q_OBJECT
+
+ public:
+ KeyPairUIDTab(const std::string& key_id, QWidget* parent);
+
+ signals:
+ void signalUpdateUIDInfo();
+
+ private:
+ GpgKey mKey;
+ QTableWidget* uidList{};
+ QTableWidget* sigList{};
+ QMenu* manageSelectedUIDMenu{};
+ QMenu* uidPopupMenu{};
+ QMenu* signPopupMenu{};
+ std::vector<GpgUID> buffered_uids;
+ std::vector<GpgKeySignature> buffered_signatures;
+
+ void createUIDList();
+
+ void createSignList();
+
+ void createManageUIDMenu();
+
+ void createUIDPopupMenu();
+
+ void createSignPopupMenu();
+
+ UIDArgsListPtr getUIDChecked();
+
+ UIDArgsListPtr getUIDSelected();
+
+ SignIdArgsListPtr getSignSelected();
+
+ private slots:
+
+ void slotRefreshUIDList();
+
+ void slotRefreshSigList();
+
+ void slotAddSign();
+
+ void slotAddSignSingle();
+
+ void slotAddUID();
+
+ void slotDelUID();
+
+ void slotDelUIDSingle();
+
+ void slotSetPrimaryUID();
+
+ void slotDelSign();
+
+ void slotRefreshKey();
+
+ static void slotAddUIDResult(int result);
+
+ protected:
+ void contextMenuEvent(QContextMenuEvent* event) override;
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_KEYPAIRUIDTAB_H
diff --git a/src/ui/keypair_details/KeySetExpireDateDialog.cpp b/src/ui/keypair_details/KeySetExpireDateDialog.cpp
index f76fa3ab..d197a76b 100644
--- a/src/ui/keypair_details/KeySetExpireDateDialog.cpp
+++ b/src/ui/keypair_details/KeySetExpireDateDialog.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,51 +24,99 @@
#include "ui/keypair_details/KeySetExpireDateDialog.h"
-KeySetExpireDateDialog::KeySetExpireDateDialog(GpgME::GpgContext *ctx, const GpgKey &key, const GpgSubKey *subkey, QWidget *parent) :
-QDialog(parent), mKey(key), mSubkey(subkey), mCtx(ctx) {
-
- QDateTime maxDateTime = QDateTime::currentDateTime().addYears(2);
- dateTimeEdit = new QDateTimeEdit(maxDateTime);
- dateTimeEdit->setMinimumDateTime(QDateTime::currentDateTime().addSecs(1));
- dateTimeEdit->setMaximumDateTime(maxDateTime);
- nonExpiredCheck = new QCheckBox();
- nonExpiredCheck->setTristate(false);
- confirmButton = new QPushButton(tr("Confirm"));
-
- auto *gridLayout = new QGridLayout();
- gridLayout->addWidget(dateTimeEdit, 0, 0, 1, 2);
- gridLayout->addWidget(nonExpiredCheck, 0, 2, 1, 1, Qt::AlignRight);
- gridLayout->addWidget(new QLabel(tr("Never Expire")), 0, 3);
- gridLayout->addWidget(confirmButton, 1, 3);
-
- connect(nonExpiredCheck, SIGNAL(stateChanged(int)), this, SLOT(slotNonExpiredChecked(int)));
- connect(confirmButton, SIGNAL(clicked(bool)), this, SLOT(slotConfirm()));
-
- this->setLayout(gridLayout);
- this->setWindowTitle("Edit Expire Datetime");
- this->setModal(true);
- this->setAttribute(Qt::WA_DeleteOnClose, true);
+#include <utility>
+
+#include "gpg/function/GpgKeyGetter.h"
+#include "gpg/function/GpgKeyOpera.h"
+#include "ui/SignalStation.h"
+
+namespace GpgFrontend::UI {
+
+KeySetExpireDateDialog::KeySetExpireDateDialog(const KeyId& key_id,
+ QWidget* parent)
+ : QDialog(parent), mKey(GpgKeyGetter::GetInstance().GetKey(key_id)) {
+ init();
+}
+
+KeySetExpireDateDialog::KeySetExpireDateDialog(const KeyId& key_id,
+ std::string subkey_fpr,
+ QWidget* parent)
+ : QDialog(parent),
+ mKey(GpgKeyGetter::GetInstance().GetKey(key_id)),
+ mSubkey(std::move(subkey_fpr)) {
+ init();
}
void KeySetExpireDateDialog::slotConfirm() {
- QDateTime *expires = nullptr;
- if(this->nonExpiredCheck->checkState() == Qt::Unchecked) {
- expires = new QDateTime(this->dateTimeEdit->dateTime());
- }
-
- if(!mCtx->setExpire(mKey, mSubkey, expires)) {
- QMessageBox::critical(nullptr,
- tr("Operation Failed"),
- tr("An error occurred during the operation."));
- }
- delete expires;
- this->close();
+ LOG(INFO) << "KeySetExpireDateDialog::slotConfirm Called";
+
+ std::unique_ptr<boost::gregorian::date> expires = nullptr;
+ if (this->nonExpiredCheck->checkState() == Qt::Unchecked) {
+ expires = std::make_unique<boost::gregorian::date>(
+ boost::posix_time::from_time_t(
+ this->dateTimeEdit->dateTime().toTime_t())
+ .date());
+ LOG(INFO) << "KeySetExpireDateDialog::slotConfirm" << mKey.id() << mSubkey
+ << *expires;
+ } else {
+ LOG(INFO) << "KeySetExpireDateDialog::slotConfirm" << mKey.id() << mSubkey
+ << "Non Expired";
+ }
+
+ auto err = GpgKeyOpera::GetInstance().SetExpire(mKey, mSubkey, expires);
+
+ if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) {
+ auto* msg_box = new QMessageBox(nullptr);
+ msg_box->setAttribute(Qt::WA_DeleteOnClose);
+ msg_box->setStandardButtons(QMessageBox::Ok);
+ msg_box->setWindowTitle(_("Success"));
+ msg_box->setText(_("The expire date of the key pair has been updated."));
+ msg_box->setModal(false);
+ msg_box->open();
+
+ emit signalKeyExpireDateUpdated();
+
+ } else {
+ QMessageBox::critical(this, _("Failure"), _(gpgme_strerror(err)));
+ }
+
+ this->close();
+}
+
+void KeySetExpireDateDialog::init() {
+ QDateTime maxDateTime = QDateTime::currentDateTime().addYears(2);
+ dateTimeEdit = new QDateTimeEdit(maxDateTime);
+ dateTimeEdit->setMinimumDateTime(QDateTime::currentDateTime().addSecs(1));
+ dateTimeEdit->setMaximumDateTime(maxDateTime);
+ nonExpiredCheck = new QCheckBox();
+ nonExpiredCheck->setTristate(false);
+ confirmButton = new QPushButton(_("Confirm"));
+
+ auto* gridLayout = new QGridLayout();
+ gridLayout->addWidget(dateTimeEdit, 0, 0, 1, 2);
+ gridLayout->addWidget(nonExpiredCheck, 0, 2, 1, 1, Qt::AlignRight);
+ gridLayout->addWidget(new QLabel(_("Never Expire")), 0, 3);
+ gridLayout->addWidget(confirmButton, 1, 3);
+
+ connect(nonExpiredCheck, SIGNAL(stateChanged(int)), this,
+ SLOT(slotNonExpiredChecked(int)));
+ connect(confirmButton, SIGNAL(clicked(bool)), this, SLOT(slotConfirm()));
+
+ this->setLayout(gridLayout);
+ this->setWindowTitle("Edit Expire Datetime");
+ this->setModal(true);
+ this->setAttribute(Qt::WA_DeleteOnClose, true);
+
+ connect(this, SIGNAL(signalKeyExpireDateUpdated()),
+ SignalStation::GetInstance(), SIGNAL(KeyDatabaseRefresh()));
}
void KeySetExpireDateDialog::slotNonExpiredChecked(int state) {
- if(state == 0) {
- this->dateTimeEdit->setDisabled(false);
- } else {
- this->dateTimeEdit->setDisabled(true);
- }
+ if (state == 0) {
+ this->dateTimeEdit->setDisabled(false);
+ } else {
+ this->dateTimeEdit->setDisabled(true);
+ }
}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/keypair_details/KeySetExpireDateDialog.h b/src/ui/keypair_details/KeySetExpireDateDialog.h
new file mode 100644
index 00000000..37a7f7e4
--- /dev/null
+++ b/src/ui/keypair_details/KeySetExpireDateDialog.h
@@ -0,0 +1,64 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_KEYSETEXPIREDATEDIALOG_H
+#define GPGFRONTEND_KEYSETEXPIREDATEDIALOG_H
+
+#include "gpg/GpgContext.h"
+#include "gpg/model/GpgKey.h"
+#include "gpg/model/GpgSubKey.h"
+#include "ui/GpgFrontendUI.h"
+
+namespace GpgFrontend::UI {
+
+class KeySetExpireDateDialog : public QDialog {
+ Q_OBJECT
+ public:
+ explicit KeySetExpireDateDialog(const KeyId& key_id,
+ QWidget* parent = nullptr);
+
+ explicit KeySetExpireDateDialog(const KeyId& key_id, std::string subkey_fpr,
+ QWidget* parent = nullptr);
+
+ signals:
+ void signalKeyExpireDateUpdated();
+
+ private:
+ void init();
+
+ const GpgKey mKey;
+ const SubkeyId mSubkey;
+
+ QDateTimeEdit* dateTimeEdit{};
+ QPushButton* confirmButton{};
+ QCheckBox* nonExpiredCheck{};
+
+ private slots:
+ void slotConfirm();
+ void slotNonExpiredChecked(int state);
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_KEYSETEXPIREDATEDIALOG_H
diff --git a/src/ui/keypair_details/KeyUIDSignDialog.cpp b/src/ui/keypair_details/KeyUIDSignDialog.cpp
index 9232cfce..6cce116b 100644
--- a/src/ui/keypair_details/KeyUIDSignDialog.cpp
+++ b/src/ui/keypair_details/KeyUIDSignDialog.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,88 +24,105 @@
#include "ui/keypair_details/KeyUIDSignDialog.h"
-KeyUIDSignDialog::KeyUIDSignDialog(GpgME::GpgContext *ctx, const GpgKey &key, const QVector<GpgUID> &uid, QWidget *parent) :
- mKey(key), mCtx(ctx), mUids(uid), QDialog(parent) {
-
- mKeyList = new KeyList(ctx,
- KeyListRow::ONLY_SECRET_KEY,
- KeyListColumn::NAME | KeyListColumn::EmailAddress,
- this);
-
- mKeyList->setFilter([](const GpgKey &key) -> bool {
- if(key.disabled || !key.can_certify || !key.has_master_key || key.expired || key.revoked) return false;
- else return true;
- });
- mKeyList->setExcludeKeys({key.id});
- mKeyList->slotRefresh();
-
- signKeyButton = new QPushButton("Sign");
-
- /**
- * A DateTime after 5 Years is recommend.
- */
- expiresEdit = new QDateTimeEdit(QDateTime::currentDateTime().addYears(5));
- expiresEdit->setMinimumDateTime(QDateTime::currentDateTime());
-
- /**
- * Note further that the OpenPGP protocol uses 32 bit values for timestamps
- * and thus can only encode dates up to the year 2106.
- */
- expiresEdit->setMaximumDate(QDate(2106, 1, 1));
-
- nonExpireCheck = new QCheckBox("Non Expired");
- nonExpireCheck->setTristate(false);
-
- connect(nonExpireCheck, &QCheckBox::stateChanged, this, [this] (int state) -> void {
- if(state == 0)
- expiresEdit->setDisabled(false);
- else
- expiresEdit->setDisabled(true);
- });
-
- auto layout = new QGridLayout();
-
- auto timeLayout = new QGridLayout();
-
- layout->addWidget(mKeyList, 0, 0);
- layout->addWidget(signKeyButton, 2, 0, Qt::AlignRight);
- timeLayout->addWidget(new QLabel(tr("Expire Date")), 0, 0);
- timeLayout->addWidget(expiresEdit, 0, 1);
- timeLayout->addWidget(nonExpireCheck, 0, 2);
- layout->addLayout(timeLayout, 1, 0);
-
- connect(signKeyButton, SIGNAL(clicked(bool)), this, SLOT(slotSignKey(bool)));
-
- this->setLayout(layout);
- this->setModal(true);
- this->setWindowTitle(tr("Sign For Key's UID(s)"));
- this->adjustSize();
-
- setAttribute(Qt::WA_DeleteOnClose, true);
+#include "gpg/function/GpgKeyGetter.h"
+#include "gpg/function/GpgKeyManager.h"
+#include "ui/SignalStation.h"
+
+namespace GpgFrontend::UI {
+
+KeyUIDSignDialog::KeyUIDSignDialog(const GpgKey& key, UIDArgsListPtr uid,
+ QWidget* parent)
+ : QDialog(parent), mUids(std::move(uid)), mKey(key) {
+ mKeyList =
+ new KeyList(KeyListRow::ONLY_SECRET_KEY,
+ KeyListColumn::NAME | KeyListColumn::EmailAddress, this);
+
+ mKeyList->setFilter([](const GpgKey& key) -> bool {
+ if (key.disabled() || !key.can_certify() || !key.has_master_key() ||
+ key.expired() || key.revoked())
+ return false;
+ else
+ return true;
+ });
+ mKeyList->setExcludeKeys({key.id()});
+ mKeyList->slotRefresh();
+
+ signKeyButton = new QPushButton("Sign");
+
+ /**
+ * A DateTime after 5 Years is recommend.
+ */
+ expiresEdit = new QDateTimeEdit(QDateTime::currentDateTime().addYears(5));
+ expiresEdit->setMinimumDateTime(QDateTime::currentDateTime());
+
+ /**
+ * Note further that the OpenPGP protocol uses 32 bit values for timestamps
+ * and thus can only encode dates up to the year 2106.
+ */
+ expiresEdit->setMaximumDate(QDate(2106, 1, 1));
+
+ nonExpireCheck = new QCheckBox("Non Expired");
+ nonExpireCheck->setTristate(false);
+
+ connect(nonExpireCheck, &QCheckBox::stateChanged, this,
+ [this](int state) -> void {
+ if (state == 0)
+ expiresEdit->setDisabled(false);
+ else
+ expiresEdit->setDisabled(true);
+ });
+
+ auto layout = new QGridLayout();
+
+ auto timeLayout = new QGridLayout();
+
+ layout->addWidget(mKeyList, 0, 0);
+ layout->addWidget(signKeyButton, 2, 0, Qt::AlignRight);
+ timeLayout->addWidget(new QLabel(_("Expire Date")), 0, 0);
+ timeLayout->addWidget(expiresEdit, 0, 1);
+ timeLayout->addWidget(nonExpireCheck, 0, 2);
+ layout->addLayout(timeLayout, 1, 0);
+
+ connect(signKeyButton, SIGNAL(clicked(bool)), this, SLOT(slotSignKey(bool)));
+
+ this->setLayout(layout);
+ this->setModal(true);
+ this->setWindowTitle(_("Sign For Key's UID(s)"));
+ this->adjustSize();
+
+ setAttribute(Qt::WA_DeleteOnClose, true);
+
+ connect(this, SIGNAL(signalKeyUIDSignUpdate()), SignalStation::GetInstance(),
+ SIGNAL(KeyDatabaseRefresh()));
}
void KeyUIDSignDialog::slotSignKey(bool clicked) {
-
- // Set Signers
- QVector<GpgKey> keys;
- mKeyList->getCheckedKeys(keys);
-
- const auto expires = expiresEdit->dateTime();
-
- for(const auto &uid : mUids) {
- // Sign For mKey
- if (!mCtx->signKey(mKey, keys, uid.uid, &expires)) {
- QMessageBox::critical(nullptr,
- tr("Unsuccessful Operation"),
- QString(tr("Signature operation failed for UID ") + "%1")
- .arg(uid.uid));
- }
-
+ LOG(INFO) << "KeyUIDSignDialog::slotSignKey Called";
+
+ // Set Signers
+ auto key_ids = mKeyList->getChecked();
+ auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
+
+ LOG(INFO) << "KeyUIDSignDialog::slotSignKey Key Info Got";
+ auto expires = std::make_unique<boost::gregorian::date>(
+ boost::posix_time::from_time_t(expiresEdit->dateTime().toTime_t())
+ .date());
+
+ LOG(INFO) << "KeyUIDSignDialog::slotSignKey Sign Start";
+ for (const auto& uid : *mUids) {
+ LOG(INFO) << "KeyUIDSignDialog::slotSignKey Sign UID" << uid;
+ // Sign For mKey
+ if (!GpgKeyManager::GetInstance().signKey(mKey, *keys, uid, expires)) {
+ QMessageBox::critical(
+ nullptr, _("Unsuccessful Operation"),
+ QString(_("Signature operation failed for UID %1")).arg(uid.c_str()));
}
+ }
- QMessageBox::information(nullptr,
- tr("Operation Complete"),
- tr("The signature operation of the UID is complete"));
-
- this->close();
+ QMessageBox::information(nullptr, _("Operation Complete"),
+ _("The signature operation of the UID is complete"));
+ this->close();
+ emit signalKeyUIDSignUpdate();
}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/keypair_details/KeyUIDSignDialog.h b/src/ui/keypair_details/KeyUIDSignDialog.h
new file mode 100644
index 00000000..8a83977a
--- /dev/null
+++ b/src/ui/keypair_details/KeyUIDSignDialog.h
@@ -0,0 +1,64 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_KEYUIDSIGNDIALOG_H
+#define GPGFRONTEND_KEYUIDSIGNDIALOG_H
+
+#include "gpg/GpgContext.h"
+#include "ui/GpgFrontendUI.h"
+#include "ui/widgets/KeyList.h"
+
+namespace GpgFrontend::UI {
+
+class KeyUIDSignDialog : public QDialog {
+ Q_OBJECT
+
+ public:
+ explicit KeyUIDSignDialog(const GpgKey& key, UIDArgsListPtr uid,
+ QWidget* parent = nullptr);
+
+ signals:
+ void signalKeyUIDSignUpdate();
+
+ private:
+ KeyList* mKeyList;
+
+ QPushButton* signKeyButton;
+
+ QDateTimeEdit* expiresEdit;
+
+ QCheckBox* nonExpireCheck;
+
+ UIDArgsListPtr mUids;
+
+ const GpgKey& mKey;
+
+ private slots:
+
+ void slotSignKey(bool clicked);
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_KEYUIDSIGNDIALOG_H
diff --git a/src/ui/main_window/MainWindowFileSlotFunction.cpp b/src/ui/main_window/MainWindowFileSlotFunction.cpp
index e391c666..25445dcc 100644
--- a/src/ui/main_window/MainWindowFileSlotFunction.cpp
+++ b/src/ui/main_window/MainWindowFileSlotFunction.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -23,588 +23,458 @@
*/
#include "MainWindow.h"
+#include "gpg/function/GpgFileOpera.h"
+#include "gpg/function/GpgKeyGetter.h"
+#include "ui/UserInterfaceUtils.h"
+#include "ui/widgets/SignersPicker.h"
+
+namespace GpgFrontend::UI {
+
+bool file_pre_check(QWidget* parent, const QString& path) {
+ QFileInfo file_info(path);
+ QFileInfo path_info(file_info.absolutePath());
+ if (!file_info.isFile()) {
+ QMessageBox::critical(parent, _("Error"),
+ _("Select a file before doing it."));
+ return false;
+ }
+ if (!file_info.isReadable()) {
+ QMessageBox::critical(parent, _("Error"),
+ _("No permission to read this file."));
+ return false;
+ }
+ if (!path_info.isWritable()) {
+ QMessageBox::critical(parent, _("Error"),
+ _("No permission to create file."));
+ return false;
+ }
+ return true;
+}
void MainWindow::slotFileEncrypt() {
-
- auto fileTreeView = edit->slotCurPageFileTreeView();
- auto path = fileTreeView->getSelected();
-
- QFileInfo fileInfo(path);
- QFileInfo pathInfo(fileInfo.absolutePath());
-
- if (!fileInfo.isFile()) {
- QMessageBox::critical(this, tr("Error"), tr("Select a file before doing it."));
- return;
- }
- if (!fileInfo.isReadable()) {
- QMessageBox::critical(this, tr("Error"), tr("No permission to read this file."));
- return;
- }
- if (!pathInfo.isWritable()) {
- QMessageBox::critical(this, tr("Error"), tr("No permission to create file."));
- return;
- }
- if (QFile::exists(path + ".asc")) {
- auto ret = QMessageBox::warning(this,
- tr("Warning"),
- tr("The target file already exists, do you need to overwrite it?"),
- QMessageBox::Ok | QMessageBox::Cancel);
-
- if (ret == QMessageBox::Cancel)
- return;
- }
-
- QVector<GpgKey> keys;
-
- mKeyList->getCheckedKeys(keys);
-
- if (keys.empty()) {
- QMessageBox::critical(this, tr("No Key Selected"), tr("No Key Selected"));
- return;
- }
-
- for (const auto &key : keys) {
- if (!GpgME::GpgContext::checkIfKeyCanEncr(key)) {
- QMessageBox::information(this,
- tr("Invalid Operation"),
- tr("The selected key contains a key that does not actually have a encrypt usage.<br/>")
- + tr("<br/>For example the Following Key: <br/>") + key.uids.first().uid);
- return;
-
- }
- }
-
- gpgme_encrypt_result_t result;
-
- gpgme_error_t error;
- bool if_error = false;
- auto thread = QThread::create([&]() {
- try {
- error = GpgFileOpera::encryptFile(mCtx, keys, path, &result);
- } catch (const std::runtime_error &e) {
- if_error = true;
- }
- });
- connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
- thread->start();
-
- auto *dialog = new WaitingDialog(tr("Encrypting"), this);
- while (thread->isRunning()) {
- QApplication::processEvents();
- }
-
- dialog->close();
- if (!if_error) {
- auto resultAnalyse = new EncryptResultAnalyse(error, result);
- auto &reportText = resultAnalyse->getResultReport();
- infoBoard->associateTabWidget(edit->tabWidget);
- infoBoard->associateFileTreeView(edit->curFilePage());
-
- if (resultAnalyse->getStatus() < 0)
- infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL);
- else if (resultAnalyse->getStatus() > 0)
- infoBoard->slotRefresh(reportText, INFO_ERROR_OK);
- else
- infoBoard->slotRefresh(reportText, INFO_ERROR_WARN);
-
- delete resultAnalyse;
-
- fileTreeView->update();
- } else {
- QMessageBox::critical(this, tr("Error"), tr("An error occurred during operation."));
- return;
- }
+ auto fileTreeView = edit->slotCurPageFileTreeView();
+ auto path = fileTreeView->getSelected();
+
+ if (!file_pre_check(this, path)) return;
+
+ if (QFile::exists(path + ".asc")) {
+ auto ret = QMessageBox::warning(
+ this, _("Warning"),
+ _("The target file already exists, do you need to overwrite it?"),
+ QMessageBox::Ok | QMessageBox::Cancel);
+
+ if (ret == QMessageBox::Cancel) return;
+ }
+
+ auto key_ids = mKeyList->getChecked();
+ auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
+ if (keys->empty()) {
+ QMessageBox::critical(this, _("No Key Selected"), _("No Key Selected"));
+ return;
+ }
+
+ for (const auto& key : *keys) {
+ if (!key.CanEncrActual()) {
+ QMessageBox::information(
+ this, _("Invalid Operation"),
+ QString(
+ _("The selected key contains a key that does not actually have a "
+ "encrypt usage.")) +
+ "<br/><br/>" + _("For example the Following Key:") + " <br/>" +
+ QString::fromStdString(key.uids()->front().uid()));
+ return;
+ }
+ }
+
+ GpgEncrResult result = nullptr;
+ GpgError error;
+ bool if_error = false;
+ process_operation(this, _("Encrypting"), [&]() {
+ try {
+ error = GpgFileOpera::EncryptFile(std::move(keys), path.toStdString(),
+ result);
+ } catch (const std::runtime_error& e) {
+ if_error = true;
+ }
+ });
+
+ if (!if_error) {
+ auto resultAnalyse = EncryptResultAnalyse(error, std::move(result));
+ resultAnalyse.analyse();
+ process_result_analyse(edit, infoBoard, resultAnalyse);
+ fileTreeView->update();
+ } else {
+ QMessageBox::critical(this, _("Error"),
+ _("An error occurred during operation."));
+ return;
+ }
}
void MainWindow::slotFileDecrypt() {
+ auto fileTreeView = edit->slotCurPageFileTreeView();
+ auto path = fileTreeView->getSelected();
- auto fileTreeView = edit->slotCurPageFileTreeView();
- auto path = fileTreeView->getSelected();
+ if (!file_pre_check(this, path)) return;
- QFileInfo fileInfo(path);
- QFileInfo pathInfo(fileInfo.absolutePath());
- if (!fileInfo.isFile()) {
- QMessageBox::critical(this, tr("Error"), tr("Select a file before doing it."));
- return;
- }
- if (!fileInfo.isReadable()) {
- QMessageBox::critical(this, tr("Error"), tr("No permission to read this file."));
- return;
- }
- if (!pathInfo.isWritable()) {
- QMessageBox::critical(this, tr("Error"), tr("No permission to create file."));
- return;
- }
+ QString outFileName, fileExtension = QFileInfo(path).suffix();
- QString outFileName, fileExtension = fileInfo.suffix();
+ if (fileExtension == "asc" || fileExtension == "gpg") {
+ int pos = path.lastIndexOf(QChar('.'));
+ outFileName = path.left(pos);
+ } else {
+ outFileName = path + ".out";
+ }
- if (fileExtension == "asc" || fileExtension == "gpg") {
- int pos = path.lastIndexOf(QChar('.'));
- outFileName = path.left(pos);
- } else {
- outFileName = path + ".out";
- }
+ if (QFile::exists(outFileName)) {
+ auto ret = QMessageBox::warning(
+ this, _("Warning"),
+ _("The target file already exists, do you need to overwrite it?"),
+ QMessageBox::Ok | QMessageBox::Cancel);
- if (QFile::exists(outFileName)) {
- auto ret = QMessageBox::warning(this,
- tr("Warning"),
- tr("The target file already exists, do you need to overwrite it?"),
- QMessageBox::Ok | QMessageBox::Cancel);
+ if (ret == QMessageBox::Cancel) return;
+ }
- if (ret == QMessageBox::Cancel)
- return;
- }
-
- gpgme_decrypt_result_t result;
- gpgme_error_t error;
- bool if_error = false;
-
- auto thread = QThread::create([&]() {
- try {
- error = GpgFileOpera::decryptFile(mCtx, path, &result);
- } catch (const std::runtime_error &e) {
- if_error = true;
- }
- });
- connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
- thread->start();
-
- auto *dialog = new WaitingDialog("Decrypting", this);
- while (thread->isRunning()) {
- QApplication::processEvents();
- }
-
- dialog->close();
-
- if (!if_error) {
- auto resultAnalyse = new DecryptResultAnalyse(mCtx, error, result);
- auto &reportText = resultAnalyse->getResultReport();
- infoBoard->associateTabWidget(edit->tabWidget);
- infoBoard->associateFileTreeView(edit->curFilePage());
-
- if (resultAnalyse->getStatus() < 0)
- infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL);
- else if (resultAnalyse->getStatus() > 0)
- infoBoard->slotRefresh(reportText, INFO_ERROR_OK);
- else
- infoBoard->slotRefresh(reportText, INFO_ERROR_WARN);
-
- delete resultAnalyse;
-
- fileTreeView->update();
- } else {
- QMessageBox::critical(this, tr("Error"), tr("An error occurred during operation."));
- return;
+ GpgDecrResult result = nullptr;
+ gpgme_error_t error;
+ bool if_error = false;
+ process_operation(this, _("Decrypting"), [&]() {
+ try {
+ error = GpgFileOpera::DecryptFile(path.toStdString(), result);
+ } catch (const std::runtime_error& e) {
+ if_error = true;
}
+ });
+ if (!if_error) {
+ auto resultAnalyse = DecryptResultAnalyse(error, std::move(result));
+ resultAnalyse.analyse();
+ process_result_analyse(edit, infoBoard, resultAnalyse);
+ fileTreeView->update();
+ } else {
+ QMessageBox::critical(this, _("Error"),
+ _("An error occurred during operation."));
+ return;
+ }
}
void MainWindow::slotFileSign() {
-
- auto fileTreeView = edit->slotCurPageFileTreeView();
- auto path = fileTreeView->getSelected();
-
- QFileInfo fileInfo(path);
- QFileInfo pathInfo(fileInfo.absolutePath());
-
- if (!fileInfo.isFile()) {
- QMessageBox::critical(this, tr("Error"), tr("Select a file before doing it."));
- return;
- }
- if (!fileInfo.isReadable()) {
- QMessageBox::critical(this, tr("Error"), tr("No permission to read this file."));
- return;
- }
- if (!pathInfo.isWritable()) {
- QMessageBox::critical(this, tr("Error"), tr("No permission to create file."));
- return;
- }
-
- if (QFile::exists(path + ".sig")) {
- auto ret = QMessageBox::warning(this,
- tr("Warning"),
- tr("The target file already exists, do you need to overwrite it?"),
- QMessageBox::Ok | QMessageBox::Cancel);
-
- if (ret == QMessageBox::Cancel)
- return;
- }
-
- QVector<GpgKey> keys;
-
- mKeyList->getCheckedKeys(keys);
-
- if (keys.empty()) {
- QMessageBox::critical(this, tr("No Key Selected"), tr("No Key Selected"));
- return;
- }
-
- for (const auto &key : keys) {
- if (!GpgME::GpgContext::checkIfKeyCanEncr(key)) {
- QMessageBox::information(this,
- tr("Invalid Operation"),
- tr("The selected key contains a key that does not actually have a encrypt usage.<br/>")
- + tr("<br/>For example the Following Key: <br/>") + key.uids.first().uid);
- return;
-
- }
- }
-
- gpgme_sign_result_t result;
- gpgme_error_t error;
- bool if_error = false;
-
- auto thread = QThread::create([&]() {
- try {
- error = GpgFileOpera::signFile(mCtx, keys, path, &result);
- } catch (const std::runtime_error &e) {
- if_error = true;
- }
- });
- connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
- thread->start();
-
- auto *dialog = new WaitingDialog(tr("Signing"), this);
- while (thread->isRunning()) {
- QApplication::processEvents();
- }
-
- dialog->close();
-
- if (!if_error) {
-
- auto resultAnalyse = new SignResultAnalyse(mCtx, error, result);
- auto &reportText = resultAnalyse->getResultReport();
- infoBoard->associateTabWidget(edit->tabWidget);
- infoBoard->associateFileTreeView(edit->curFilePage());
-
- if (resultAnalyse->getStatus() < 0)
- infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL);
- else if (resultAnalyse->getStatus() > 0)
- infoBoard->slotRefresh(reportText, INFO_ERROR_OK);
- else
- infoBoard->slotRefresh(reportText, INFO_ERROR_WARN);
-
- delete resultAnalyse;
-
- fileTreeView->update();
-
- } else {
- QMessageBox::critical(this, tr("Error"), tr("An error occurred during operation."));
- return;
- }
+ auto fileTreeView = edit->slotCurPageFileTreeView();
+ auto path = fileTreeView->getSelected();
+
+ if (!file_pre_check(this, path)) return;
+
+ if (QFile::exists(path + ".sig")) {
+ auto ret = QMessageBox::warning(
+ this, _("Warning"),
+ _("The target file already exists, do you need to overwrite it?"),
+ QMessageBox::Ok | QMessageBox::Cancel);
+
+ if (ret == QMessageBox::Cancel) return;
+ }
+
+ auto key_ids = mKeyList->getChecked();
+ auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
+
+ if (keys->empty()) {
+ QMessageBox::critical(this, _("No Key Selected"), _("No Key Selected"));
+ return;
+ }
+
+ for (const auto& key : *keys) {
+ if (!key.CanSignActual()) {
+ QMessageBox::information(
+ this, _("Invalid Operation"),
+ QString(_("The selected key contains a key that does not actually "
+ "have a sign usage.")) +
+ "<br/><br/>" + _("for example the Following Key:") + " <br/>" +
+ QString::fromStdString(key.uids()->front().uid()));
+ return;
+ }
+ }
+
+ GpgSignResult result = nullptr;
+ gpgme_error_t error;
+ bool if_error = false;
+
+ process_operation(this, _("Signing"), [&]() {
+ try {
+ error =
+ GpgFileOpera::SignFile(std::move(keys), path.toStdString(), result);
+ } catch (const std::runtime_error& e) {
+ if_error = true;
+ }
+ });
+
+ if (!if_error) {
+ auto resultAnalyse = SignResultAnalyse(error, std::move(result));
+ resultAnalyse.analyse();
+ process_result_analyse(edit, infoBoard, resultAnalyse);
fileTreeView->update();
+ } else {
+ QMessageBox::critical(this, _("Error"),
+ _("An error occurred during operation."));
+ return;
+ }
+
+ fileTreeView->update();
}
void MainWindow::slotFileVerify() {
-
- auto fileTreeView = edit->slotCurPageFileTreeView();
- auto path = fileTreeView->getSelected();
-
- QFileInfo fileInfo(path);
-
- QString signFilePath, dataFilePath;
-
- if (fileInfo.suffix() == "gpg") {
- dataFilePath = path;
- signFilePath = path;
- } else if (fileInfo.suffix() == "sig") {
- int pos = path.lastIndexOf(QChar('.'));
- dataFilePath = path.left(pos);
- signFilePath = path;
- } else {
- dataFilePath = path;
- signFilePath = path + ".sig";
- }
-
- QFileInfo dataFileInfo(dataFilePath), signFileInfo(signFilePath);
-
- if (!dataFileInfo.isFile() || !signFileInfo.isFile()) {
- QMessageBox::critical(this, tr("Error"),
- tr("Please select the appropriate target file or signature file. Ensure that both are in this directory."));
- return;
- }
- if (!dataFileInfo.isReadable()) {
- QMessageBox::critical(this, tr("Error"), tr("No permission to read target file."));
- return;
- }
- if (!fileInfo.isReadable()) {
- QMessageBox::critical(this, tr("Error"), tr("No permission to read signature file."));
- return;
- }
-
- gpgme_verify_result_t result;
-
- gpgme_error_t error;
- bool if_error = false;
- auto thread = QThread::create([&]() {
- try {
- error = GpgFileOpera::verifyFile(mCtx, dataFilePath, &result);
- } catch (const std::runtime_error &e) {
- if_error = true;
+ auto fileTreeView = edit->slotCurPageFileTreeView();
+ auto path = fileTreeView->getSelected();
+
+ QFileInfo fileInfo(path);
+
+ QString signFilePath, dataFilePath;
+
+ if (fileInfo.suffix() == "gpg") {
+ dataFilePath = path;
+ signFilePath = path;
+ } else if (fileInfo.suffix() == "sig") {
+ int pos = path.lastIndexOf(QChar('.'));
+ dataFilePath = path.left(pos);
+ signFilePath = path;
+ } else {
+ dataFilePath = path;
+ signFilePath = path + ".sig";
+ }
+
+ QFileInfo dataFileInfo(dataFilePath), signFileInfo(signFilePath);
+
+ if (!dataFileInfo.isFile() || !signFileInfo.isFile()) {
+ QMessageBox::critical(
+ this, _("Error"),
+ _("Please select the appropriate target file or signature file. "
+ "Ensure that both are in this directory."));
+ return;
+ }
+ if (!dataFileInfo.isReadable()) {
+ QMessageBox::critical(this, _("Error"),
+ _("No permission to read target file."));
+ return;
+ }
+ if (!fileInfo.isReadable()) {
+ QMessageBox::critical(this, _("Error"),
+ _("No permission to read signature file."));
+ return;
+ }
+
+ GpgVerifyResult result = nullptr;
+ gpgme_error_t error;
+ bool if_error = false;
+ process_operation(this, _("Verifying"), [&]() {
+ try {
+ error = GpgFileOpera::VerifyFile(dataFilePath.toStdString(), result);
+ } catch (const std::runtime_error& e) {
+ if_error = true;
+ }
+ });
+
+ if (!if_error) {
+ auto resultAnalyse = VerifyResultAnalyse(error, std::move(result));
+ resultAnalyse.analyse();
+ process_result_analyse(edit, infoBoard, resultAnalyse);
+
+ if (resultAnalyse.getStatus() == -2) {
+ QMessageBox::StandardButton reply;
+ reply = QMessageBox::question(
+ this, _("Public key not found locally"),
+ _("There is no target public key content in local for GpgFrontend to "
+ "gather enough information about this Signature. Do you want to "
+ "import the public key from Keyserver now?"),
+ QMessageBox::Yes | QMessageBox::No);
+ if (reply == QMessageBox::Yes) {
+ qDebug() << "Yes was clicked";
+ auto dialog = KeyServerImportDialog(true, this);
+ auto key_ids = std::make_unique<KeyIdArgsList>();
+ auto* signature = resultAnalyse.GetSignatures();
+ while (signature != nullptr) {
+ LOG(INFO) << "signature fpr" << signature->fpr;
+ key_ids->push_back(signature->fpr);
+ signature = signature->next;
}
- });
- connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
- thread->start();
+ dialog.slotImport(key_ids);
+ dialog.show();
- auto *dialog = new WaitingDialog(tr("Verifying"), this);
- while (thread->isRunning()) {
- QApplication::processEvents();
+ } else {
+ qDebug() << "Yes was *not* clicked";
+ }
}
- dialog->close();
-
- if (!if_error) {
- auto resultAnalyse = new VerifyResultAnalyse(mCtx, error, result);
- auto &reportText = resultAnalyse->getResultReport();
- infoBoard->associateTabWidget(edit->tabWidget);
- infoBoard->associateFileTreeView(edit->curFilePage());
-
- if (resultAnalyse->getStatus() < 0)
- infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL);
- else if (resultAnalyse->getStatus() > 0)
- infoBoard->slotRefresh(reportText, INFO_ERROR_OK);
- else
- infoBoard->slotRefresh(reportText, INFO_ERROR_WARN);
-
- if (resultAnalyse->getStatus() >= 0) {
- infoBoard->resetOptionActionsMenu();
- infoBoard->addOptionalAction("Show Verify Details", [this, error, result]() {
- VerifyDetailsDialog(this, mCtx, mKeyList, error, result);
- });
- }
- delete resultAnalyse;
+ // if (resultAnalyse.getStatus() >= 0) {
+ // infoBoard->resetOptionActionsMenu();
+ // infoBoard->addOptionalAction(
+ // "Show Verify Details", [this, error, &result]() {
+ // VerifyDetailsDialog(this, mKeyList, error, result);
+ // });
+ // }
- fileTreeView->update();
- } else {
- QMessageBox::critical(this, tr("Error"), tr("An error occurred during operation."));
- return;
- }
+ fileTreeView->update();
+ } else {
+ QMessageBox::critical(this, _("Error"),
+ _("An error occurred during operation."));
+ return;
+ }
}
void MainWindow::slotFileEncryptSign() {
- auto fileTreeView = edit->slotCurPageFileTreeView();
- auto path = fileTreeView->getSelected();
-
- QFileInfo fileInfo(path);
- QFileInfo pathInfo(fileInfo.absolutePath());
-
- if (!fileInfo.isFile()) {
- QMessageBox::critical(this, tr("Error"), tr("Select a file before doing it."));
- return;
- }
- if (!fileInfo.isReadable()) {
- QMessageBox::critical(this, tr("Error"), tr("No permission to read this file."));
- return;
- }
- if (!pathInfo.isWritable()) {
- QMessageBox::critical(this, tr("Error"), tr("No permission to create file."));
- return;
- }
- if (QFile::exists(path + ".gpg")) {
- auto ret = QMessageBox::warning(this,
- tr("Warning"),
- tr("The target file already exists, do you need to overwrite it?"),
- QMessageBox::Ok | QMessageBox::Cancel);
-
- if (ret == QMessageBox::Cancel)
- return;
- }
-
- QVector<GpgKey> keys;
+ auto fileTreeView = edit->slotCurPageFileTreeView();
+ auto path = fileTreeView->getSelected();
- mKeyList->getCheckedKeys(keys);
+ if (!file_pre_check(this, path)) return;
- if (keys.empty()) {
- QMessageBox::critical(this, tr("No Key Selected"), tr("No Key Selected"));
- return;
- }
+ if (QFile::exists(path + ".gpg")) {
+ auto ret = QMessageBox::warning(
+ this, _("Warning"),
+ _("The target file already exists, do you need to overwrite it?"),
+ QMessageBox::Ok | QMessageBox::Cancel);
- bool can_sign = false, can_encr = false;
+ if (ret == QMessageBox::Cancel) return;
+ }
- for (const auto &key : keys) {
- bool key_can_sign = GpgME::GpgContext::checkIfKeyCanSign(key);
- bool key_can_encr = GpgME::GpgContext::checkIfKeyCanEncr(key);
+ auto key_ids = mKeyList->getChecked();
+ auto p_keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
- if (!key_can_sign && !key_can_encr) {
- QMessageBox::critical(nullptr,
- tr("Invalid KeyPair"),
- tr("The selected keypair cannot be used for signing and encryption at the same time.<br/>")
- + tr("<br/>For example the Following Key: <br/>") + key.uids.first().uid);
- return;
- }
+ if (p_keys->empty()) {
+ QMessageBox::critical(this, _("No Key Selected"), _("No Key Selected"));
+ return;
+ }
- if (key_can_sign) can_sign = true;
- if (key_can_encr) can_encr = true;
- }
+ for (const auto& key : *p_keys) {
+ bool key_can_encrypt = key.CanEncrActual();
- if (!can_encr) {
- QMessageBox::critical(nullptr,
- tr("Incomplete Operation"),
- tr("None of the selected key pairs can provide the encryption function."));
- return;
+ if (!key_can_encrypt) {
+ QMessageBox::critical(
+ nullptr, _("Invalid KeyPair"),
+ QString(_("The selected keypair cannot be used for encryption.")) +
+ "<br/><br/>" + _("For example the Following Key:") + " <br/>" +
+ QString::fromStdString(key.uids()->front().uid()));
+ return;
}
+ }
- if (!can_sign) {
- QMessageBox::warning(nullptr,
- tr("Incomplete Operation"),
- tr("None of the selected key pairs can provide the signature function."));
- }
+ auto signersPicker = new SignersPicker(this);
+ QEventLoop loop;
+ connect(signersPicker, SIGNAL(finished(int)), &loop, SLOT(quit()));
+ loop.exec();
- gpgme_encrypt_result_t encr_result = nullptr;
- gpgme_sign_result_t sign_result = nullptr;
+ auto signer_key_ids = signersPicker->getCheckedSigners();
+ auto p_signer_keys = GpgKeyGetter::GetInstance().GetKeys(signer_key_ids);
- gpgme_error_t error;
- bool if_error = false;
+ for (const auto& key : *p_keys) {
+ LOG(INFO) << "Keys " << key.email();
+ }
- auto thread = QThread::create([&]() {
- try {
- error = GpgFileOpera::encryptSignFile(mCtx, keys, path, &encr_result, &sign_result);
- } catch (const std::runtime_error &e) {
- if_error = true;
- }
- });
- connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
- thread->start();
+ for (const auto& signer : *p_signer_keys) {
+ LOG(INFO) << "Signers " << signer.email();
+ }
- auto *dialog = new WaitingDialog(tr("Encrypting and Signing"), this);
- while (thread->isRunning()) {
- QApplication::processEvents();
- }
- dialog->close();
+ GpgEncrResult encr_result = nullptr;
+ GpgSignResult sign_result = nullptr;
- if (!if_error) {
+ gpgme_error_t error;
+ bool if_error = false;
- auto resultAnalyseEncr = new EncryptResultAnalyse(error, encr_result);
- auto resultAnalyseSign = new SignResultAnalyse(mCtx, error, sign_result);
- int status = std::min(resultAnalyseEncr->getStatus(), resultAnalyseSign->getStatus());
- auto reportText = resultAnalyseEncr->getResultReport() + resultAnalyseSign->getResultReport();
-
- infoBoard->associateFileTreeView(edit->curFilePage());
-
- if (status < 0)
- infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL);
- else if (status > 0)
- infoBoard->slotRefresh(reportText, INFO_ERROR_OK);
- else
- infoBoard->slotRefresh(reportText, INFO_ERROR_WARN);
+ process_operation(this, _("Encrypting and Signing"), [&]() {
+ try {
+ error = GpgFileOpera::EncryptSignFile(
+ std::move(p_keys), std::move(p_signer_keys), path.toStdString(),
+ encr_result, sign_result);
+ } catch (const std::runtime_error& e) {
+ if_error = true;
+ }
+ });
- delete resultAnalyseEncr;
- delete resultAnalyseSign;
+ if (!if_error) {
+ auto encrypt_res = EncryptResultAnalyse(error, std::move(encr_result));
+ auto sign_res = SignResultAnalyse(error, std::move(sign_result));
+ encrypt_res.analyse();
+ sign_res.analyse();
+ process_result_analyse(edit, infoBoard, encrypt_res, sign_res);
- fileTreeView->update();
+ fileTreeView->update();
- } else {
- QMessageBox::critical(this, tr("Error"), tr("An error occurred during operation."));
- return;
- }
+ } else {
+ QMessageBox::critical(this, _("Error"),
+ _("An error occurred during operation."));
+ return;
+ }
}
void MainWindow::slotFileDecryptVerify() {
- auto fileTreeView = edit->slotCurPageFileTreeView();
- auto path = fileTreeView->getSelected();
-
- QFileInfo fileInfo(path);
- QFileInfo pathInfo(fileInfo.absolutePath());
- if (!fileInfo.isFile()) {
- QMessageBox::critical(this, tr("Error"), tr("Select a file(.gpg/.asc) before doing it."));
- return;
- }
- if (!fileInfo.isReadable()) {
- QMessageBox::critical(this, tr("Error"), tr("No permission to read this file."));
- return;
- }
- if (!pathInfo.isWritable()) {
- QMessageBox::critical(this, tr("Error"), tr("No permission to create file."));
- return;
- }
-
- QString outFileName, fileExtension = fileInfo.suffix();
-
- if (fileExtension == "asc" || fileExtension == "gpg") {
- int pos = path.lastIndexOf(QChar('.'));
- outFileName = path.left(pos);
- } else {
- outFileName = path + ".out";
- }
-
- gpgme_decrypt_result_t d_result = nullptr;
- gpgme_verify_result_t v_result = nullptr;
-
- gpgme_error_t error;
- bool if_error = false;
-
- auto thread = QThread::create([&]() {
- try {
- error = GpgFileOpera::decryptVerifyFile(mCtx, path, &d_result, &v_result);
- } catch (const std::runtime_error &e) {
- if_error = true;
- }
- });
- connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
- thread->start();
+ auto fileTreeView = edit->slotCurPageFileTreeView();
+ auto path = fileTreeView->getSelected();
+
+ if (!file_pre_check(this, path)) return;
+
+ QString outFileName, fileExtension = QFileInfo(path).suffix();
+
+ if (fileExtension == "asc" || fileExtension == "gpg") {
+ int pos = path.lastIndexOf(QChar('.'));
+ outFileName = path.left(pos);
+ } else {
+ outFileName = path + ".out";
+ }
+
+ GpgDecrResult d_result = nullptr;
+ GpgVerifyResult v_result = nullptr;
+ gpgme_error_t error;
+ bool if_error = false;
+ process_operation(this, _("Decrypting and Verifying"), [&]() {
+ try {
+ error = GpgFileOpera::DecryptVerifyFile(path.toStdString(), d_result,
+ v_result);
+ } catch (const std::runtime_error& e) {
+ if_error = true;
+ }
+ });
+
+ if (!if_error) {
+ infoBoard->associateFileTreeView(edit->curFilePage());
+
+ auto decrypt_res = DecryptResultAnalyse(error, std::move(d_result));
+ auto verify_res = VerifyResultAnalyse(error, std::move(v_result));
+ decrypt_res.analyse();
+ verify_res.analyse();
+ process_result_analyse(edit, infoBoard, decrypt_res, verify_res);
+
+ // if (verify_res.getStatus() >= 0) {
+ // infoBoard->resetOptionActionsMenu();
+ // infoBoard->addOptionalAction(
+ // "Show Verify Details", [this, error, v_result]() {
+ // VerifyDetailsDialog(this, mCtx, mKeyList, error, v_result);
+ // });
+ // }
-
- auto *dialog = new WaitingDialog(tr("Decrypting and Verifying"), this);
- while (thread->isRunning()) {
- QApplication::processEvents();
- }
- dialog->close();
-
- if (!if_error) {
- infoBoard->associateFileTreeView(edit->curFilePage());
-
- auto resultAnalyseDecrypt = new DecryptResultAnalyse(mCtx, error, d_result);
- auto resultAnalyseVerify = new VerifyResultAnalyse(mCtx, error, v_result);
-
- int status = std::min(resultAnalyseDecrypt->getStatus(), resultAnalyseVerify->getStatus());
- auto &reportText = resultAnalyseDecrypt->getResultReport() + resultAnalyseVerify->getResultReport();
- if (status < 0)
- infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL);
- else if (status > 0)
- infoBoard->slotRefresh(reportText, INFO_ERROR_OK);
- else
- infoBoard->slotRefresh(reportText, INFO_ERROR_WARN);
-
- if (resultAnalyseVerify->getStatus() >= 0) {
- infoBoard->resetOptionActionsMenu();
- infoBoard->addOptionalAction("Show Verify Details", [this, error, v_result]() {
- VerifyDetailsDialog(this, mCtx, mKeyList, error, v_result);
- });
- }
- delete resultAnalyseDecrypt;
- delete resultAnalyseVerify;
-
- fileTreeView->update();
- } else {
- QMessageBox::critical(this, tr("Error"), tr("An error occurred during operation."));
- return;
- }
+ fileTreeView->update();
+ } else {
+ QMessageBox::critical(this, _("Error"),
+ _("An error occurred during operation."));
+ return;
+ }
}
void MainWindow::slotFileEncryptCustom() {
- QStringList *keyList;
- keyList = mKeyList->getChecked();
- new FileEncryptionDialog(mCtx, *keyList, FileEncryptionDialog::Encrypt, this);
+ new FileEncryptionDialog(mKeyList->getChecked(),
+ FileEncryptionDialog::Encrypt, this);
}
void MainWindow::slotFileDecryptCustom() {
- QStringList *keyList;
- keyList = mKeyList->getChecked();
- new FileEncryptionDialog(mCtx, *keyList, FileEncryptionDialog::Decrypt, this);
+ new FileEncryptionDialog(mKeyList->getChecked(),
+ FileEncryptionDialog::Decrypt, this);
}
void MainWindow::slotFileSignCustom() {
- QStringList *keyList;
- keyList = mKeyList->getChecked();
- new FileEncryptionDialog(mCtx, *keyList, FileEncryptionDialog::Sign, this);
+ new FileEncryptionDialog(mKeyList->getChecked(), FileEncryptionDialog::Sign,
+ this);
}
void MainWindow::slotFileVerifyCustom() {
- QStringList *keyList;
- keyList = mKeyList->getChecked();
- new FileEncryptionDialog(mCtx, *keyList, FileEncryptionDialog::Verify, this);
+ new FileEncryptionDialog(mKeyList->getChecked(), FileEncryptionDialog::Verify,
+ this);
}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/main_window/MainWindowServerSlotFunction.cpp b/src/ui/main_window/MainWindowServerSlotFunction.cpp
index 3a7e9f71..17491db7 100644
--- a/src/ui/main_window/MainWindowServerSlotFunction.cpp
+++ b/src/ui/main_window/MainWindowServerSlotFunction.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -23,216 +23,240 @@
*/
#include "MainWindow.h"
-#include "server/ComUtils.h"
-#include "ui/ShowCopyDialog.h"
+#ifdef SERVER_SUPPORT
#include "rapidjson/document.h"
#include "rapidjson/prettywriter.h"
+#include "server/ComUtils.h"
+#endif
+#include "ui/ShowCopyDialog.h"
+
+namespace GpgFrontend::UI {
+
+#ifdef SERVER_SUPPORT
/**
* get full size crypt text from server using short crypto text
* @param shortenCryptoText short crypto text([GpgFrontend_ShortCrypto]://)
* @return
*/
-QString MainWindow::getCryptText(const QString &shortenCryptoText) {
-
- QString ownKeyId = settings.value("general/ownKeyId").toString();
-
- GpgKey key = mCtx->getKeyById(ownKeyId);
- if (!key.good) {
- QMessageBox::critical(this, tr("Invalid Own Key"),
- tr("Own Key can not be use to do any operation. "
- "Please go to the setting interface to select an OwnKey and get a ServiceToken."));
- return {};
- }
-
- auto utils = new ComUtils(this);
+QString MainWindow::getCryptText(const QString& shortenCryptoText) {
+ QString ownKeyId = settings.value("general/ownKeyId").toString();
+
+ GpgKey key = mCtx->getKeyRefById(ownKeyId);
+ if (!key.good) {
+ QMessageBox::critical(this, _("Invalid Own Key"),
+ _("Own Key can not be use to do any operation. "
+ "Please go to the setting interface to select an "
+ "OwnKey and get a ServiceToken."));
+ return {};
+ }
- QString serviceToken = settings.value("general/serviceToken").toString();
- if (serviceToken.isEmpty() || !utils->checkServiceTokenFormat(serviceToken)) {
- QMessageBox::critical(this, tr("Error"),
- tr("Please obtain a Service Token from the server in the settings."));
- return {};
- }
+ auto utils = new ComUtils(this);
- QUrl reqUrl(utils->getUrl(ComUtils::GetFullCryptText));
- QNetworkRequest request(reqUrl);
- request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
+ QString serviceToken = settings.value("general/serviceToken").toString();
+ if (serviceToken.isEmpty() || !utils->checkServiceTokenFormat(serviceToken)) {
+ QMessageBox::critical(
+ this, _("Error"),
+ _("Please obtain a Service Token from the server in the settings."));
+ return {};
+ }
- // Sign Shorten Text
- auto outSignTextBase64 = ComUtils::getSignStringBase64(mCtx, shortenCryptoText, key);
+ QUrl reqUrl(utils->getUrl(ComUtils::GetFullCryptText));
+ QNetworkRequest request(reqUrl);
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
- rapidjson::Document doc;
- doc.SetObject();
+ // Sign Shorten Text
+ auto outSignTextBase64 =
+ ComUtils::getSignStringBase64(mCtx, shortenCryptoText, key);
- rapidjson::Value s, t;
+ rapidjson::Document doc;
+ doc.SetObject();
- // Signature
- s.SetString(outSignTextBase64.constData(), outSignTextBase64.count());
- // Service Token
- const auto t_byte_array = serviceToken.toUtf8();
- t.SetString(t_byte_array.constData(), t_byte_array.count());
+ rapidjson::Value s, t;
- rapidjson::Document::AllocatorType &allocator = doc.GetAllocator();
+ // Signature
+ s.SetString(outSignTextBase64.constData(), outSignTextBase64.count());
+ // Service Token
+ const auto t_byte_array = serviceToken.toUtf8();
+ t.SetString(t_byte_array.constData(), t_byte_array.count());
- doc.AddMember("signature", s, allocator);
- doc.AddMember("serviceToken", t, allocator);
+ rapidjson::Document::AllocatorType& allocator = doc.GetAllocator();
- rapidjson::StringBuffer sb;
- rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb);
- doc.Accept(writer);
+ doc.AddMember("signature", s, allocator);
+ doc.AddMember("serviceToken", t, allocator);
- QByteArray postData(sb.GetString());
- qDebug() << "postData" << QString::fromUtf8(postData);
+ rapidjson::StringBuffer sb;
+ rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb);
+ doc.Accept(writer);
- QNetworkReply *reply = utils->getNetworkManager().post(request, postData);
+ QByteArray postData(sb.GetString());
+ qDebug() << "postData" << QString::fromUtf8(postData);
- auto dialog = new WaitingDialog(tr("Getting Cpt From Server"), this);
- dialog->show();
+ QNetworkReply* reply = utils->getNetworkManager().post(request, postData);
- while (reply->isRunning()) QApplication::processEvents();
+ auto dialog = new WaitingDialog(_("Getting Cpt From Server"), this);
+ dialog->show();
- dialog->close();
+ while (reply->isRunning()) QApplication::processEvents();
- QByteArray replyData = reply->readAll().constData();
- if (utils->checkServerReply(replyData)) {
- /**
- * {
- * "cryptoText" : ...
- * "sha": ...
- * "serviceToken": ...
- * "date": ...
- * }
- */
+ dialog->close();
- if (!utils->checkDataValueStr("cryptoText")
- || !utils->checkDataValueStr("sha")
- || !utils->checkDataValueStr("serviceToken")) {
- QMessageBox::critical(this, tr("Error"),
- tr("The communication content with the server does not meet the requirements"));
- return {};
- }
+ QByteArray replyData = reply->readAll().constData();
+ if (utils->checkServerReply(replyData)) {
+ /**
+ * {
+ * "cryptoText" : ...
+ * "sha": ...
+ * "serviceToken": ...
+ * "date": ...
+ * }
+ */
- auto cryptoText = utils->getDataValueStr("cryptoText");
- auto sha = utils->getDataValueStr("sha");
- auto serviceTokenFromServer = utils->getDataValueStr("serviceToken");
+ if (!utils->checkDataValueStr("cryptoText") ||
+ !utils->checkDataValueStr("sha") ||
+ !utils->checkDataValueStr("serviceToken")) {
+ QMessageBox::critical(this, _("Error"),
+ _("The communication content with the server does "
+ "not meet the requirements"));
+ return {};
+ }
- QCryptographicHash sha_generator(QCryptographicHash::Sha256);
- sha_generator.addData(cryptoText.toUtf8());
+ auto cryptoText = utils->getDataValueStr("cryptoText");
+ auto sha = utils->getDataValueStr("sha");
+ auto serviceTokenFromServer = utils->getDataValueStr("serviceToken");
- if (sha_generator.result().toHex() == sha && serviceToken == serviceTokenFromServer) {
- return cryptoText;
- } else QMessageBox::critical(this, tr("Error"), tr("Invalid short ciphertext"));
+ QCryptographicHash sha_generator(QCryptographicHash::Sha256);
+ sha_generator.addData(cryptoText.toUtf8());
- return {};
- }
+ if (sha_generator.result().toHex() == sha &&
+ serviceToken == serviceTokenFromServer) {
+ return cryptoText;
+ } else
+ QMessageBox::critical(this, _("Error"), _("Invalid short ciphertext"));
return {};
-}
+ }
-void MainWindow::shortenCryptText() {
+ return {};
+}
- // gather information
- QString serviceToken = settings.value("general/serviceToken").toString();
- QString ownKeyId = settings.value("general/ownKeyId").toString();
- QByteArray cryptoText = edit->curTextPage()->toPlainText().toUtf8();
+#endif
- auto utils = new ComUtils(this);
+#ifdef SERVER_SUPPORT
- if (serviceToken.isEmpty() || !utils->checkServiceTokenFormat(serviceToken)) {
- QMessageBox::critical(this, tr("Invalid Service Token"),
- tr("Please go to the setting interface to get a ServiceToken."));
- return;
+void MainWindow::shortenCryptText() {
+ // gather information
+ QString serviceToken = settings.value("general/serviceToken").toString();
+ QString ownKeyId = settings.value("general/ownKeyId").toString();
+ QByteArray cryptoText = edit->curTextPage()->toPlainText().toUtf8();
+
+ auto utils = new ComUtils(this);
+
+ if (serviceToken.isEmpty() || !utils->checkServiceTokenFormat(serviceToken)) {
+ QMessageBox::critical(
+ this, _("Invalid Service Token"),
+ _("Please go to the setting interface to get a ServiceToken."));
+ return;
+ }
+
+ QUrl reqUrl(utils->getUrl(ComUtils::ShortenCryptText));
+ QNetworkRequest request(reqUrl);
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
+
+ GpgKey key = mCtx->getKeyRefById(ownKeyId);
+ if (!key.good) {
+ QMessageBox::critical(this, _("Invalid Own Key"),
+ _("Own Key can not be use to do any operation."));
+ return;
+ }
+
+ QCryptographicHash ch(QCryptographicHash::Md5);
+ ch.addData(cryptoText);
+ QString md5 = ch.result().toHex();
+
+ qDebug() << "md5" << md5;
+
+ QByteArray signText = QString("[%1][%2]").arg(serviceToken, md5).toUtf8();
+
+ QCryptographicHash sha(QCryptographicHash::Sha256);
+ sha.addData(signText);
+ QString shaText = sha.result().toHex();
+
+ qDebug() << "shaText" << shaText;
+
+ QByteArray outSignTextBase64 =
+ ComUtils::getSignStringBase64(mCtx, signText, key);
+
+ rapidjson::Value c, s, m, t;
+
+ rapidjson::Document doc;
+ doc.SetObject();
+
+ c.SetString(cryptoText.constData(), cryptoText.count());
+ auto m_byte_array = shaText.toUtf8();
+ m.SetString(m_byte_array.constData(), m_byte_array.count());
+ s.SetString(outSignTextBase64.constData(), outSignTextBase64.count());
+ auto t_byte_array = serviceToken.toUtf8();
+ t.SetString(t_byte_array.constData(), t_byte_array.count());
+
+ rapidjson::Document::AllocatorType& allocator = doc.GetAllocator();
+
+ doc.AddMember("cryptoText", c, allocator);
+ doc.AddMember("sha", m, allocator);
+ doc.AddMember("sign", s, allocator);
+ doc.AddMember("serviceToken", t, allocator);
+
+ rapidjson::StringBuffer sb;
+ rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb);
+ doc.Accept(writer);
+
+ QByteArray postData(sb.GetString());
+ qDebug() << "postData" << QString::fromUtf8(postData);
+
+ QNetworkReply* reply = networkAccessManager->post(request, postData);
+
+ auto* dialog = new WaitingDialog(_("Getting Scpt From Server"), this);
+ dialog->show();
+ while (reply->isRunning()) QApplication::processEvents();
+ dialog->close();
+
+ if (utils->checkServerReply(reply->readAll().constData())) {
+ /**
+ * {
+ * "shortenText" : ...
+ * "md5": ...
+ * }
+ */
+
+ if (!utils->checkDataValueStr("shortenText") ||
+ !utils->checkDataValueStr("md5")) {
+ QMessageBox::critical(this, _("Error"),
+ _("The communication content with the server does "
+ "not meet the requirements"));
+ return;
}
- QUrl reqUrl(utils->getUrl(ComUtils::ShortenCryptText));
- QNetworkRequest request(reqUrl);
- request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
-
- GpgKey key = mCtx->getKeyById(ownKeyId);
- if (!key.good) {
- QMessageBox::critical(this, tr("Invalid Own Key"), tr("Own Key can not be use to do any operation."));
- return;
+ QString shortenText = utils->getDataValueStr("shortenText");
+
+ QCryptographicHash md5_generator(QCryptographicHash::Md5);
+ md5_generator.addData(shortenText.toUtf8());
+ if (md5_generator.result().toHex() == utils->getDataValueStr("md5")) {
+ auto* dialog =
+ new ShowCopyDialog(shortenText,
+ _("Notice: Use Decrypt & Verify operation to "
+ "decrypt this short crypto text."),
+ this);
+ dialog->show();
+ } else {
+ QMessageBox::critical(
+ this, _("Error"),
+ _("There is a problem with the communication with the server"));
+ return;
}
-
- QCryptographicHash ch(QCryptographicHash::Md5);
- ch.addData(cryptoText);
- QString md5 = ch.result().toHex();
-
- qDebug() << "md5" << md5;
-
- QByteArray signText = QString("[%1][%2]").arg(serviceToken, md5).toUtf8();
-
- QCryptographicHash sha(QCryptographicHash::Sha256);
- sha.addData(signText);
- QString shaText = sha.result().toHex();
-
- qDebug() << "shaText" << shaText;
-
- QByteArray outSignTextBase64 = ComUtils::getSignStringBase64(mCtx, signText, key);
-
- rapidjson::Value c, s, m, t;
-
- rapidjson::Document doc;
- doc.SetObject();
-
- c.SetString(cryptoText.constData(), cryptoText.count());
- auto m_byte_array = shaText.toUtf8();
- m.SetString(m_byte_array.constData(), m_byte_array.count());
- s.SetString(outSignTextBase64.constData(), outSignTextBase64.count());
- auto t_byte_array = serviceToken.toUtf8();
- t.SetString(t_byte_array.constData(), t_byte_array.count());
-
- rapidjson::Document::AllocatorType &allocator = doc.GetAllocator();
-
- doc.AddMember("cryptoText", c, allocator);
- doc.AddMember("sha", m, allocator);
- doc.AddMember("sign", s, allocator);
- doc.AddMember("serviceToken", t, allocator);
-
- rapidjson::StringBuffer sb;
- rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb);
- doc.Accept(writer);
-
- QByteArray postData(sb.GetString());
- qDebug() << "postData" << QString::fromUtf8(postData);
-
- QNetworkReply *reply = networkAccessManager->post(request, postData);
-
- auto *dialog = new WaitingDialog(tr("Getting Scpt From Server"), this);
- dialog->show();
- while (reply->isRunning()) QApplication::processEvents();
- dialog->close();
-
- if (utils->checkServerReply(reply->readAll().constData())) {
-
- /**
- * {
- * "shortenText" : ...
- * "md5": ...
- * }
- */
-
- if (!utils->checkDataValueStr("shortenText") || !utils->checkDataValueStr("md5")) {
- QMessageBox::critical(this, tr("Error"),
- tr("The communication content with the server does not meet the requirements"));
- return;
- }
-
- QString shortenText = utils->getDataValueStr("shortenText");
-
- QCryptographicHash md5_generator(QCryptographicHash::Md5);
- md5_generator.addData(shortenText.toUtf8());
- if (md5_generator.result().toHex() == utils->getDataValueStr("md5")) {
- auto *dialog = new ShowCopyDialog(shortenText,
- tr("Notice: Use Decrypt & Verify operation to decrypt this short crypto text."),
- this);
- dialog->show();
- } else {
- QMessageBox::critical(this, tr("Error"), tr("There is a problem with the communication with the server"));
- return;
- }
- }
-
+ }
}
+#endif
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/main_window/MainWindowSlotFunction.cpp b/src/ui/main_window/MainWindowSlotFunction.cpp
index 501418d6..205b9440 100644
--- a/src/ui/main_window/MainWindowSlotFunction.cpp
+++ b/src/ui/main_window/MainWindowSlotFunction.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -23,559 +23,542 @@
*/
#include "MainWindow.h"
-#include "ui/SendMailDialog.h"
-#include "ui/widgets/SignersPicker.h"
-#include "server/api/PubkeyUploader.h"
+
+#ifdef ADVANCE_SUPPORT
#include "advance/UnknownSignersChecker.h"
+#endif
+#ifdef SERVER_SUPPORT
+#include "server/api/PubkeyUploader.h"
+#endif
+#ifdef SMTP_SUPPORT
+#include "ui/smtp/SendMailDialog.h"
+#endif
+#include "gpg/function/BasicOperator.h"
+#include "gpg/function/GpgKeyGetter.h"
+#include "gpg/function/GpgKeyImportExportor.h"
+#include "ui/UserInterfaceUtils.h"
+#include "ui/widgets/SignersPicker.h"
+
+namespace GpgFrontend::UI {
/**
* Encrypt Entry(Text & File)
*/
void MainWindow::slotEncrypt() {
+ if (edit->tabCount() == 0) return;
- if (edit->tabCount() == 0) return;
-
- if (edit->slotCurPageTextEdit() != nullptr) {
+ if (edit->slotCurPageTextEdit() != nullptr) {
+ auto key_ids = mKeyList->getChecked();
- QVector<GpgKey> keys;
- mKeyList->getCheckedKeys(keys);
-
- if (keys.count() == 0) {
- QMessageBox::critical(nullptr, tr("No Key Selected"), tr("No Key Selected"));
- return;
- }
-
- for (const auto &key : keys) {
- if (!GpgME::GpgContext::checkIfKeyCanEncr(key)) {
- QMessageBox::information(nullptr,
- tr("Invalid Operation"),
- tr("The selected key contains a key that does not actually have a encrypt usage.<br/>")
- + tr("<br/>For example the Following Key: <br/>") + key.uids.first().uid);
- return;
-
- }
- }
-
- auto tmp = QByteArray();
-
- gpgme_encrypt_result_t result = nullptr;
+ if (key_ids->empty()) {
+ QMessageBox::critical(nullptr, _("No Key Selected"),
+ _("No Key Selected"));
+ return;
+ }
- gpgme_error_t error;
+ auto key_getter = GpgFrontend::GpgKeyGetter::GetInstance();
+ auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
+ for (const auto& key : *keys) {
+ if (!key.CanEncrActual()) {
+ QMessageBox::information(
+ nullptr, _("Invalid Operation"),
+ QString(_(
+ "The selected key contains a key that does not actually have a "
+ "encrypt usage.")) +
+ "<br/><br/>" + _("For example the Following Key:") + " <br/>" +
+ QString::fromStdString(key.uids()->front().uid()));
+ return;
+ }
+ }
- auto thread = QThread::create([&]() {
- error = mCtx->encrypt(keys, edit->curTextPage()->toPlainText().toUtf8(), &tmp, &result);
+ auto tmp = std::make_unique<ByteArray>();
+
+ GpgEncrResult result = nullptr;
+ GpgError error;
+ bool if_error = false;
+ process_operation(this, _("Encrypting"), [&]() {
+ try {
+ auto buffer = edit->curTextPage()->toPlainText().toUtf8().toStdString();
+ error = GpgFrontend::BasicOperator::GetInstance().Encrypt(
+ std::move(keys), buffer, tmp, result);
+ } catch (const std::runtime_error& e) {
+ if_error = true;
+ }
+ });
+
+ if (!if_error) {
+ auto resultAnalyse = EncryptResultAnalyse(error, std::move(result));
+ resultAnalyse.analyse();
+ process_result_analyse(edit, infoBoard, resultAnalyse);
+
+ if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR)
+ edit->slotFillTextEditWithText(QString::fromStdString(*tmp));
+#ifdef SMTP_SUPPORT
+ // set optional actions
+ if (resultAnalyse.getStatus() >= 0) {
+ infoBoard->resetOptionActionsMenu();
+ infoBoard->addOptionalAction("Send Mail", [this]() {
+ if (settings.value("sendMail/enable", false).toBool())
+ new SendMailDialog(edit->curTextPage()->toPlainText(), this);
+ else {
+ QMessageBox::warning(nullptr, _("Function Disabled"),
+ _("Please go to the settings interface to "
+ "enable and configure this function."));
+ }
});
- connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
- thread->start();
-
- auto *dialog = new WaitingDialog(tr("Encrypting"), this);
-
- while (thread->isRunning())
- QApplication::processEvents();
-
- dialog->close();
-
- auto resultAnalyse = new EncryptResultAnalyse(error, result);
- auto &reportText = resultAnalyse->getResultReport();
-
- auto tmp2 = QString(tmp);
- edit->slotFillTextEditWithText(tmp2);
- infoBoard->associateTextEdit(edit->curTextPage());
-
- // check result analyse status
- if (resultAnalyse->getStatus() < 0)
- infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL);
- else if (resultAnalyse->getStatus() > 0)
- infoBoard->slotRefresh(reportText, INFO_ERROR_OK);
- else
- infoBoard->slotRefresh(reportText, INFO_ERROR_WARN);
-
- // set optional actions
- if (resultAnalyse->getStatus() >= 0) {
- infoBoard->resetOptionActionsMenu();
- infoBoard->addOptionalAction("Send Mail", [this]() {
- if (settings.value("sendMail/enable", false).toBool())
- new SendMailDialog(edit->curTextPage()->toPlainText(), this);
- else {
- QMessageBox::warning(nullptr,
- tr("Function Disabled"),
- tr("Please go to the settings interface to enable and configure this function."));
- }
- });
- }
+ }
+#endif
- delete resultAnalyse;
- } else if (edit->slotCurPageFileTreeView() != nullptr) {
- this->slotFileEncrypt();
+ } else {
+ QMessageBox::critical(this, _("Error"),
+ _("An error occurred during operation."));
+ return;
}
+
+ } else if (edit->slotCurPageFileTreeView() != nullptr) {
+ this->slotFileEncrypt();
+ }
}
void MainWindow::slotSign() {
+ if (edit->tabCount() == 0) return;
- if (edit->tabCount() == 0) return;
-
- if (edit->slotCurPageTextEdit() != nullptr) {
-
- QVector<GpgKey> keys;
-
- mKeyList->getPrivateCheckedKeys(keys);
-
- if (keys.isEmpty()) {
- QMessageBox::critical(this, tr("No Key Selected"), tr("No Key Selected"));
- return;
- }
-
- for (const auto &key : keys) {
- if (!GpgME::GpgContext::checkIfKeyCanSign(key)) {
- QMessageBox::information(this,
- tr("Invalid Operation"),
- tr("The selected key contains a key that does not actually have a signature usage.<br/>")
- + tr("<br/>For example the Following Key: <br/>") + key.uids.first().uid);
- return;
- }
- }
-
- auto tmp = QByteArray();
-
- gpgme_sign_result_t result = nullptr;
-
- gpgme_error_t error;
- auto thread = QThread::create([&]() {
- error = mCtx->sign(keys, edit->curTextPage()->toPlainText().toUtf8(), &tmp, GPGME_SIG_MODE_CLEAR, &result);
- });
- connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
- thread->start();
-
- auto *dialog = new WaitingDialog(tr("Signing"), this);
- while (thread->isRunning()) {
- QApplication::processEvents();
- }
- dialog->close();
-
- infoBoard->associateTextEdit(edit->curTextPage());
- edit->slotFillTextEditWithText(QString::fromUtf8(tmp));
+ if (edit->slotCurPageTextEdit() != nullptr) {
+ auto key_ids = mKeyList->getPrivateChecked();
- auto resultAnalyse = new SignResultAnalyse(mCtx, error, result);
+ if (key_ids->empty()) {
+ QMessageBox::critical(this, _("No Key Selected"), _("No Key Selected"));
+ return;
+ }
- auto &reportText = resultAnalyse->getResultReport();
- if (resultAnalyse->getStatus() < 0)
- infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL);
- else if (resultAnalyse->getStatus() > 0)
- infoBoard->slotRefresh(reportText, INFO_ERROR_OK);
- else
- infoBoard->slotRefresh(reportText, INFO_ERROR_WARN);
+ auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
+ for (const auto& key : *keys) {
+ if (!key.CanSignActual()) {
+ QMessageBox::information(
+ this, _("Invalid Operation"),
+ QString(_(
+ "The selected key contains a key that does not actually have a "
+ "signature usage.")) +
+ "<br/><br/>" + _("For example the Following Key:") + "<br/>" +
+ key.uids()->front().uid().c_str());
+ return;
+ }
+ }
- delete resultAnalyse;
- } else if (edit->slotCurPageFileTreeView() != nullptr) {
- this->slotFileSign();
+ auto tmp = std::make_unique<ByteArray>();
+
+ GpgSignResult result = nullptr;
+ gpgme_error_t error;
+ bool if_error = false;
+
+ process_operation(this, _("Signing"), [&]() {
+ try {
+ auto buffer = edit->curTextPage()->toPlainText().toUtf8().toStdString();
+ error = GpgFrontend::BasicOperator::GetInstance().Sign(
+ std::move(keys), buffer, tmp, GPGME_SIG_MODE_CLEAR, result);
+ } catch (const std::runtime_error& e) {
+ if_error = true;
+ }
+ });
+
+ if (!if_error) {
+ auto resultAnalyse = SignResultAnalyse(error, std::move(result));
+ resultAnalyse.analyse();
+ process_result_analyse(edit, infoBoard, resultAnalyse);
+
+ if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR)
+ edit->slotFillTextEditWithText(QString::fromStdString(*tmp));
+ } else {
+ QMessageBox::critical(this, _("Error"),
+ _("An error occurred during operation."));
+ return;
}
+ } else if (edit->slotCurPageFileTreeView() != nullptr) {
+ this->slotFileSign();
+ }
}
void MainWindow::slotDecrypt() {
- if (edit->tabCount() == 0) return;
-
- if (edit->slotCurPageTextEdit() != nullptr) {
-
- auto decrypted = QByteArray();
- QByteArray text = edit->curTextPage()->toPlainText().toUtf8();
- GpgME::GpgContext::preventNoDataErr(&text);
-
- if (text.trimmed().startsWith(GpgConstants::GPG_FRONTEND_SHORT_CRYPTO_HEAD)) {
- QMessageBox::critical(this, tr("Notice"), tr("Short Crypto Text only supports Decrypt & Verify."));
- return;
- }
-
- gpgme_decrypt_result_t result = nullptr;
-
- gpgme_error_t error;
- auto thread = QThread::create([&]() {
- // try decrypt, if fail do nothing, especially don't replace text
- error = mCtx->decrypt(text, &decrypted, &result);
- });
- connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
- thread->start();
-
- auto *dialog = new WaitingDialog(tr("Decrypting"), this);
- while (thread->isRunning()) {
- QApplication::processEvents();
- }
-
- dialog->close();
-
- infoBoard->associateTextEdit(edit->curTextPage());
-
- if (gpgme_err_code(error) == GPG_ERR_NO_ERROR)
- edit->slotFillTextEditWithText(QString::fromUtf8(decrypted));
-
- auto resultAnalyse = new DecryptResultAnalyse(mCtx, error, result);
-
- auto &reportText = resultAnalyse->getResultReport();
- if (resultAnalyse->getStatus() < 0)
- infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL);
- else if (resultAnalyse->getStatus() > 0)
- infoBoard->slotRefresh(reportText, INFO_ERROR_OK);
- else
- infoBoard->slotRefresh(reportText, INFO_ERROR_WARN);
+ if (edit->tabCount() == 0) return;
+
+ if (edit->slotCurPageTextEdit() != nullptr) {
+ auto decrypted = std::make_unique<ByteArray>();
+ QByteArray text = edit->curTextPage()->toPlainText().toUtf8();
+
+ if (text.trimmed().startsWith(
+ GpgConstants::GPG_FRONTEND_SHORT_CRYPTO_HEAD)) {
+ QMessageBox::critical(
+ this, _("Notice"),
+ _("Short Crypto Text only supports Decrypt & Verify."));
+ return;
+ }
- delete resultAnalyse;
- } else if (edit->slotCurPageFileTreeView() != nullptr) {
- this->slotFileDecrypt();
+ GpgDecrResult result = nullptr;
+ gpgme_error_t error;
+ bool if_error = false;
+ process_operation(this, _("Decrypting"), [&]() {
+ try {
+ auto buffer = text.toStdString();
+ error = GpgFrontend::BasicOperator::GetInstance().Decrypt(
+ buffer, decrypted, result);
+ } catch (const std::runtime_error& e) {
+ if_error = true;
+ }
+ });
+
+ if (!if_error) {
+ auto resultAnalyse = DecryptResultAnalyse(error, std::move(result));
+ resultAnalyse.analyse();
+ process_result_analyse(edit, infoBoard, resultAnalyse);
+
+ if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR)
+ edit->slotFillTextEditWithText(QString::fromStdString(*decrypted));
+ } else {
+ QMessageBox::critical(this, _("Error"),
+ _("An error occurred during operation."));
+ return;
}
+ } else if (edit->slotCurPageFileTreeView() != nullptr) {
+ this->slotFileDecrypt();
+ }
}
void MainWindow::slotFind() {
- if (edit->tabCount() == 0 || edit->curTextPage() == nullptr) {
- return;
- }
-
- // At first close verifynotification, if existing
- edit->slotCurPageTextEdit()->closeNoteByClass("findwidget");
+ if (edit->tabCount() == 0 || edit->curTextPage() == nullptr) {
+ return;
+ }
- auto *fw = new FindWidget(this, edit->curTextPage());
- edit->slotCurPageTextEdit()->showNotificationWidget(fw, "findWidget");
+ // At first close verifynotification, if existing
+ edit->slotCurPageTextEdit()->closeNoteByClass("findwidget");
+ auto* fw = new FindWidget(this, edit->curTextPage());
+ edit->slotCurPageTextEdit()->showNotificationWidget(fw, "findWidget");
}
void MainWindow::slotVerify() {
+ if (edit->tabCount() == 0) return;
+
+ if (edit->slotCurPageTextEdit() != nullptr) {
+ auto text = edit->curTextPage()->toPlainText().toUtf8();
+ // TODO(Saturneric) PreventNoDataErr
+
+ auto sig_buffer = std::make_unique<ByteArray>();
+ sig_buffer.reset();
+
+ GpgVerifyResult result = nullptr;
+ GpgError error;
+ bool if_error = false;
+ process_operation(this, _("Verifying"), [&]() {
+ try {
+ auto buffer = text.toStdString();
+ error = GpgFrontend::BasicOperator::GetInstance().Verify(
+ buffer, sig_buffer, result);
+ } catch (const std::runtime_error& e) {
+ if_error = true;
+ }
+ });
+
+ if (!if_error) {
+ auto resultAnalyse = VerifyResultAnalyse(error, std::move(result));
+ resultAnalyse.analyse();
+ process_result_analyse(edit, infoBoard, resultAnalyse);
+
+ // if (resultAnalyse->getStatus() >= 0) {
+ // infoBoard->resetOptionActionsMenu();
+ // infoBoard->addOptionalAction(
+ // "Show Verify Details", [this, error, result]() {
+ // VerifyDetailsDialog(this, mCtx, mKeyList, error, result);
+ // });
+ // }
- if (edit->tabCount() == 0) return;
-
- if (edit->slotCurPageTextEdit() != nullptr) {
-
- QByteArray text = edit->curTextPage()->toPlainText().toUtf8();
- GpgME::GpgContext::preventNoDataErr(&text);
-
- gpgme_verify_result_t result;
-
- gpgme_error_t error;
- auto thread = QThread::create([&]() {
- error = mCtx->verify(&text, nullptr, &result);
- });
- connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
- thread->start();
-
- auto *dialog = new WaitingDialog(tr("Verifying"), this);
- while (thread->isRunning())
- QApplication::processEvents();
- dialog->close();
-
- auto resultAnalyse = new VerifyResultAnalyse(mCtx, error, result);
- infoBoard->associateTextEdit(edit->curTextPage());
-
- auto &reportText = resultAnalyse->getResultReport();
- if (resultAnalyse->getStatus() < 0)
- infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL);
- else if (resultAnalyse->getStatus() > 0)
- infoBoard->slotRefresh(reportText, INFO_ERROR_OK);
- else
- infoBoard->slotRefresh(reportText, INFO_ERROR_WARN);
-
- if (resultAnalyse->getStatus() >= 0) {
- infoBoard->resetOptionActionsMenu();
- infoBoard->addOptionalAction("Show Verify Details", [this, error, result]() {
- VerifyDetailsDialog(this, mCtx, mKeyList, error, result);
- });
- }
- delete resultAnalyse;
- } else if (edit->slotCurPageFileTreeView() != nullptr) {
- this->slotFileVerify();
+ } else {
+ QMessageBox::critical(this, _("Error"),
+ _("An error occurred during operation."));
+ return;
}
+ } else if (edit->slotCurPageFileTreeView() != nullptr) {
+ this->slotFileVerify();
+ }
}
void MainWindow::slotEncryptSign() {
+ if (edit->tabCount() == 0) return;
- if (edit->tabCount() == 0) return;
-
- if (edit->slotCurPageTextEdit() != nullptr) {
-
- QVector<GpgKey> keys;
- mKeyList->getCheckedKeys(keys);
-
- if (keys.empty()) {
- QMessageBox::critical(nullptr, tr("No Key Selected"), tr("No Key Selected"));
- return;
- }
-
- for (const auto &key : keys) {
- bool key_can_encr = GpgME::GpgContext::checkIfKeyCanEncr(key);
-
- if (!key_can_encr) {
- QMessageBox::critical(nullptr,
- tr("Invalid KeyPair"),
- tr("The selected keypair cannot be used for encryption.<br/>")
- + tr("<br/>For example the Following Key: <br/>") + key.uids.first().uid);
- return;
- }
-
- }
+ if (edit->slotCurPageTextEdit() != nullptr) {
+ auto key_ids = mKeyList->getChecked();
- QVector<GpgKey> signerKeys;
-
- auto signersPicker = new SignersPicker(mCtx, this);
-
- QEventLoop loop;
- connect(signersPicker, SIGNAL(finished(int)), &loop, SLOT(quit()));
- loop.exec();
+ if (key_ids->empty()) {
+ QMessageBox::critical(nullptr, _("No Key Selected"),
+ _("No Key Selected"));
+ return;
+ }
- signersPicker->getCheckedSigners(signerKeys);
+ auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
- for (const auto &key : keys) {
- qDebug() << "Keys " << key.email;
- }
+ for (const auto& key : *keys) {
+ bool key_can_encrypt = key.CanEncrActual();
- for (const auto &signer : signerKeys) {
- qDebug() << "Signers " << signer.email;
- }
+ if (!key_can_encrypt) {
+ QMessageBox::critical(
+ nullptr, _("Invalid KeyPair"),
+ QString(_("The selected keypair cannot be used for encryption.")) +
+ "<br/><br/>" + _("For example the Following Key:") + " <br/>" +
+ QString::fromStdString(key.uids()->front().uid()));
+ return;
+ }
+ }
+ auto signersPicker = new SignersPicker(this);
+ QEventLoop loop;
+ connect(signersPicker, SIGNAL(finished(int)), &loop, SLOT(quit()));
+ loop.exec();
- auto tmp = QByteArray();
- gpgme_encrypt_result_t encr_result = nullptr;
- gpgme_sign_result_t sign_result = nullptr;
+ auto signer_key_ids = signersPicker->getCheckedSigners();
+ auto signer_keys = GpgKeyGetter::GetInstance().GetKeys(signer_key_ids);
- gpgme_error_t error;
- auto thread = QThread::create([&]() {
- error = mCtx->encryptSign(keys, signerKeys, edit->curTextPage()->toPlainText().toUtf8(), &tmp,
- &encr_result,
- &sign_result);
- });
- connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
- thread->start();
+ for (const auto& key : *keys) {
+ LOG(INFO) << "Keys " << key.email();
+ }
- auto *dialog = new WaitingDialog(tr("Encrypting and Signing"), this);
- while (thread->isRunning()) {
- QApplication::processEvents();
- }
+ for (const auto& signer : *signer_keys) {
+ LOG(INFO) << "Signers " << signer.email();
+ }
- if (settings.value("advanced/autoPubkeyExchange").toBool()) {
- PubkeyUploader pubkeyUploader(mCtx, signerKeys);
- pubkeyUploader.start();
- if (!pubkeyUploader.result()) {
- QMessageBox::warning(nullptr,
- tr("Automatic Key Exchange Warning"),
- tr("Part of the automatic key exchange failed, which may be related to your key.")
- +
- tr("If possible, try to use the RSA algorithm compatible with the server for signing."));
- }
+ GpgEncrResult encr_result = nullptr;
+ GpgSignResult sign_result = nullptr;
+ GpgError error;
+ bool if_error = false;
+
+ auto tmp = std::make_unique<ByteArray>();
+ process_operation(this, _("Encrypting and Signing"), [&]() {
+ try {
+ auto buffer = edit->curTextPage()->toPlainText().toUtf8().toStdString();
+ error = GpgFrontend::BasicOperator::GetInstance().EncryptSign(
+ std::move(keys), std::move(signer_keys), buffer, tmp, encr_result,
+ sign_result);
+ } catch (const std::runtime_error& e) {
+ if_error = true;
+ }
+ });
+
+ if (!if_error) {
+#ifdef ADVANCE_SUPPORT
+ if (settings.value("advanced/autoPubkeyExchange").toBool()) {
+ PubkeyUploader pubkeyUploader(mCtx, signerKeys);
+ pubkeyUploader.start();
+ if (!pubkeyUploader.result()) {
+ QMessageBox::warning(
+ nullptr, _("Automatic Key Exchange Warning"),
+ _("Part of the automatic key exchange failed, "
+ "which may be related to your key.") +
+ _("If possible, try to use the RSA algorithm "
+ "compatible with the server for signing."));
}
-
- dialog->close();
-
- if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) {
- auto tmp2 = QString(tmp);
- edit->slotFillTextEditWithText(tmp2);
+ }
+#endif
+ LOG(INFO) << "ResultAnalyse Started";
+ auto encrypt_res = EncryptResultAnalyse(error, std::move(encr_result));
+ auto sign_res = SignResultAnalyse(error, std::move(sign_result));
+ encrypt_res.analyse();
+ sign_res.analyse();
+ process_result_analyse(edit, infoBoard, encrypt_res, sign_res);
+ if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR)
+ edit->slotFillTextEditWithText(QString::fromStdString(*tmp));
+
+#ifdef SMTP_SUPPORT
+ infoBoard->resetOptionActionsMenu();
+ infoBoard->addOptionalAction("Send Mail", [this]() {
+ if (settings.value("sendMail/enable", false).toBool())
+ new SendMailDialog(edit->curTextPage()->toPlainText(), this);
+ else {
+ QMessageBox::warning(nullptr, _("Function Disabled"),
+ _("Please go to the settings interface to "
+ "enable and configure this function."));
}
-
- qDebug() << "Start Analyse Result";
-
- auto resultAnalyseEncr = new EncryptResultAnalyse(error, encr_result);
- auto resultAnalyseSign = new SignResultAnalyse(mCtx, error, sign_result);
- int status = std::min(resultAnalyseEncr->getStatus(), resultAnalyseSign->getStatus());
- auto reportText = resultAnalyseEncr->getResultReport() + resultAnalyseSign->getResultReport();
-
- infoBoard->associateTextEdit(edit->curTextPage());
-
- if (status < 0)
- infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL);
- else if (status > 0)
- infoBoard->slotRefresh(reportText, INFO_ERROR_OK);
- else
- infoBoard->slotRefresh(reportText, INFO_ERROR_WARN);
-
- qDebug() << "End Analyse Result";
-
- if (status >= 0) {
- infoBoard->resetOptionActionsMenu();
- infoBoard->addOptionalAction("Send Mail", [this]() {
- if (settings.value("sendMail/enable", false).toBool())
- new SendMailDialog(edit->curTextPage()->toPlainText(), this);
- else {
- QMessageBox::warning(nullptr,
- tr("Function Disabled"),
- tr("Please go to the settings interface to enable and configure this function."));
- }
- });
- infoBoard->addOptionalAction("Shorten Ciphertext", [this]() {
- if (settings.value("general/serviceToken").toString().isEmpty())
- QMessageBox::warning(nullptr,
- tr("Service Token Empty"),
- tr("Please go to the settings interface to set Own Key and get Service Token."));
- else {
- shortenCryptText();
- }
- });
+ });
+#endif
+
+#ifdef ADVANCE_SUPPORT
+ infoBoard->addOptionalAction("Shorten Ciphertext", [this]() {
+ if (settings.value("general/serviceToken").toString().isEmpty())
+ QMessageBox::warning(nullptr, _("Service Token Empty"),
+ _("Please go to the settings interface to set "
+ "Own Key and get Service Token."));
+ else {
+ shortenCryptText();
}
+ });
+#endif
- delete resultAnalyseEncr;
- delete resultAnalyseSign;
- } else if (edit->slotCurPageFileTreeView() != nullptr) {
- this->slotFileEncryptSign();
+ } else {
+ QMessageBox::critical(this, _("Error"),
+ _("An error occurred during operation."));
+ return;
}
+ } else if (edit->slotCurPageFileTreeView() != nullptr) {
+ this->slotFileEncryptSign();
+ }
}
void MainWindow::slotDecryptVerify() {
-
- if (edit->tabCount() == 0) return;
-
- if (edit->slotCurPageTextEdit() != nullptr) {
-
- auto decrypted = QByteArray();
- QString plainText = edit->curTextPage()->toPlainText();
-
-
- if (plainText.trimmed().startsWith(GpgConstants::GPG_FRONTEND_SHORT_CRYPTO_HEAD)) {
- auto cryptoText = getCryptText(plainText);
- if (!cryptoText.isEmpty()) {
- plainText = cryptoText;
- }
- }
-
- QByteArray text = plainText.toUtf8();
-
- GpgME::GpgContext::preventNoDataErr(&text);
-
- gpgme_decrypt_result_t d_result = nullptr;
- gpgme_verify_result_t v_result = nullptr;
-
- auto *dialog = new WaitingDialog(tr("Decrypting and Verifying"), this);
-
- // Automatically import public keys that are not stored locally
- if (settings.value("advanced/autoPubkeyExchange").toBool()) {
- gpgme_verify_result_t tmp_v_result = nullptr;
- auto thread = QThread::create([&]() {
- mCtx->verify(&text, nullptr, &tmp_v_result);
- });
- thread->start();
- while (thread->isRunning()) QApplication::processEvents();
- auto *checker = new UnknownSignersChecker(mCtx, tmp_v_result);
- checker->start();
- checker->deleteLater();
- }
-
- gpgme_error_t error;
- auto thread = QThread::create([&]() {
- error = mCtx->decryptVerify(text, &decrypted, &d_result, &v_result);
- });
- connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
- thread->start();
-
- while (thread->isRunning()) QApplication::processEvents();
-
- dialog->close();
-
- qDebug() << "Start Analyse Result";
-
- infoBoard->associateTextEdit(edit->curTextPage());
-
- if (gpgme_err_code(error) == GPG_ERR_NO_ERROR)
- edit->slotFillTextEditWithText(QString::fromUtf8(decrypted));
-
- auto resultAnalyseDecrypt = new DecryptResultAnalyse(mCtx, error, d_result);
- auto resultAnalyseVerify = new VerifyResultAnalyse(mCtx, error, v_result);
-
- int status = std::min(resultAnalyseDecrypt->getStatus(), resultAnalyseVerify->getStatus());
- auto &reportText = resultAnalyseDecrypt->getResultReport() + resultAnalyseVerify->getResultReport();
- if (status < 0)
- infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL);
- else if (status > 0)
- infoBoard->slotRefresh(reportText, INFO_ERROR_OK);
- else
- infoBoard->slotRefresh(reportText, INFO_ERROR_WARN);
-
- if (resultAnalyseVerify->getStatus() >= 0) {
- infoBoard->resetOptionActionsMenu();
- infoBoard->addOptionalAction("Show Verify Details", [this, error, v_result]() {
- VerifyDetailsDialog(this, mCtx, mKeyList, error, v_result);
- });
- }
- delete resultAnalyseDecrypt;
- delete resultAnalyseVerify;
-
- qDebug() << "End Analyse Result";
-
- } else if (edit->slotCurPageFileTreeView() != nullptr) {
- this->slotFileDecryptVerify();
+ if (edit->tabCount() == 0) return;
+
+ if (edit->slotCurPageTextEdit() != nullptr) {
+ QString plainText = edit->curTextPage()->toPlainText();
+
+#ifdef ADVANCE_SUPPORT
+ if (plainText.trimmed().startsWith(
+ GpgConstants::GPG_FRONTEND_SHORT_CRYPTO_HEAD)) {
+ auto cryptoText = getCryptText(plainText);
+ if (!cryptoText.isEmpty()) {
+ plainText = cryptoText;
+ }
+ }
+#endif
+
+ QByteArray text = plainText.toUtf8();
+
+ GpgDecrResult d_result = nullptr;
+ GpgVerifyResult v_result = nullptr;
+ gpgme_error_t error;
+ bool if_error = false;
+
+#ifdef ADVANCE_SUPPORT
+ // Automatically import public keys that are not stored locally
+ if (settings.value("advanced/autoPubkeyExchange").toBool()) {
+ gpgme_verify_result_t tmp_v_result = nullptr;
+ auto thread = QThread::create(
+ [&]() { mCtx->verify(&text, nullptr, &tmp_v_result); });
+ thread->start();
+ while (thread->isRunning()) QApplication::processEvents();
+ auto* checker = new UnknownSignersChecker(mCtx, tmp_v_result);
+ checker->start();
+ checker->deleteLater();
+ }
+#endif
+ auto decrypted = std::make_unique<ByteArray>();
+ process_operation(this, _("Decrypting and Verifying"), [&]() {
+ try {
+ auto buffer = text.toStdString();
+ error = BasicOperator::GetInstance().DecryptVerify(buffer, decrypted,
+ d_result, v_result);
+ } catch (const std::runtime_error& e) {
+ if_error = true;
+ }
+ });
+
+ if (!if_error) {
+ infoBoard->associateFileTreeView(edit->curFilePage());
+
+ auto decrypt_res = DecryptResultAnalyse(error, std::move(d_result));
+ auto verify_res = VerifyResultAnalyse(error, std::move(v_result));
+ decrypt_res.analyse();
+ verify_res.analyse();
+ process_result_analyse(edit, infoBoard, decrypt_res, verify_res);
+
+ edit->slotFillTextEditWithText(QString::fromStdString(*decrypted));
+
+ // if (verify_res.getStatus() >= 0) {
+ // infoBoard->resetOptionActionsMenu();
+ // infoBoard->addOptionalAction(
+ // "Show Verify Details", [this, error, v_result]() {
+ // VerifyDetailsDialog(this, mCtx, mKeyList, error,
+ // v_result);
+ // });
+ // }
+ } else {
+ QMessageBox::critical(this, _("Error"),
+ _("An error occurred during operation."));
+ return;
}
-}
+ } else if (edit->slotCurPageFileTreeView() != nullptr) {
+ this->slotFileDecryptVerify();
+ }
+}
/*
* Append the selected (not checked!) Key(s) To Textedit
*/
void MainWindow::slotAppendSelectedKeys() {
- if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) {
- return;
- }
+ if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) {
+ return;
+ }
+
+ auto exported = std::make_unique<ByteArray>();
+ auto key_ids = mKeyList->getSelected();
- auto *keyArray = new QByteArray();
- mCtx->exportKeys(mKeyList->getSelected(), keyArray);
- edit->curTextPage()->append(*keyArray);
+ GpgKeyImportExportor::GetInstance().ExportKeys(key_ids, exported);
+ edit->curTextPage()->append(QString::fromStdString(*exported));
}
void MainWindow::slotCopyMailAddressToClipboard() {
- if (mKeyList->getSelected()->isEmpty()) {
- return;
- }
- auto key = mCtx->getKeyById(mKeyList->getSelected()->first());
- if (!key.good) {
- QMessageBox::critical(nullptr, tr("Error"), tr("Key Not Found."));
- return;
- }
- QClipboard *cb = QApplication::clipboard();
- QString mail = key.email;
- cb->setText(mail);
+ auto key_ids = mKeyList->getSelected();
+ if (key_ids->empty()) return;
+
+ auto key = GpgKeyGetter::GetInstance().GetKey(key_ids->front());
+ if (!key.good()) {
+ QMessageBox::critical(nullptr, _("Error"), _("Key Not Found."));
+ return;
+ }
+ QClipboard* cb = QApplication::clipboard();
+ cb->setText(QString::fromStdString(key.email()));
}
void MainWindow::slotShowKeyDetails() {
- if (mKeyList->getSelected()->isEmpty()) {
- return;
- }
- auto key = mCtx->getKeyById(mKeyList->getSelected()->first());
- if (key.good) {
- new KeyDetailsDialog(mCtx, key, this);
- } else {
- QMessageBox::critical(nullptr, tr("Error"), tr("Key Not Found."));
- }
+ auto key_ids = mKeyList->getSelected();
+ if (key_ids->empty()) return;
+
+ auto key = GpgKeyGetter::GetInstance().GetKey(key_ids->front());
+ if (key.good()) {
+ new KeyDetailsDialog(key, this);
+ } else {
+ QMessageBox::critical(nullptr, _("Error"), _("Key Not Found."));
+ }
}
void MainWindow::refreshKeysFromKeyserver() {
- if (mKeyList->getSelected()->isEmpty()) {
- return;
- }
-
- auto *dialog = new KeyServerImportDialog(mCtx, mKeyList, true, this);
- dialog->show();
- dialog->slotImport(*mKeyList->getSelected());
+ auto key_ids = mKeyList->getSelected();
+ if (key_ids->empty()) return;
+ auto* dialog = new KeyServerImportDialog(true, this);
+ dialog->show();
+ dialog->slotImport(key_ids);
}
void MainWindow::uploadKeyToServer() {
- QVector<GpgKey> keys;
- keys.append(mKeyList->getSelectedKey());
- auto *dialog = new KeyUploadDialog(mCtx, keys, this);
- dialog->show();
- dialog->slotUpload();
+ auto key_ids = mKeyList->getSelected();
+ auto* dialog = new KeyUploadDialog(key_ids, this);
+ dialog->show();
+ dialog->slotUpload();
}
-
-void MainWindow::slotOpenFile(QString &path) {
- edit->slotOpenFile(path);
+void MainWindow::slotOpenFile(QString& path) { edit->slotOpenFile(path); }
+
+void MainWindow::slotVersionUpgrade(const QString& currentVersion,
+ const QString& latestVersion) {
+ if (currentVersion < latestVersion) {
+ QMessageBox::warning(
+ this, _("Outdated Version"),
+ QString(_("This version(%1) is out of date, please update "
+ "the latest version in time. "))
+ .arg(currentVersion) +
+ QString(_("You can download the latest version(%1) on "
+ "Github Releases Page.<br/>"))
+ .arg(latestVersion));
+ } else if (currentVersion > latestVersion) {
+ QMessageBox::warning(
+ this, _("Unreleased Version"),
+ QString(
+ _("This version(%1) has not been officially released and is not "
+ "recommended for use in a production environment. <br/>"))
+ .arg(currentVersion) +
+ QString(
+ _("You can download the latest version(%1) on Github Releases "
+ "Page.<br/>"))
+ .arg(latestVersion));
+ }
}
-void MainWindow::slotVersionUpgrade(const QString &currentVersion, const QString &latestVersion) {
- if (currentVersion < latestVersion) {
- QMessageBox::warning(this,
- tr("Outdated Version"),
- tr("This version(%1) is out of date, please update the latest version in time. ").arg(
- currentVersion)
- + tr("You can download the latest version(%1) on Github Releases Page.<br/>").arg(
- latestVersion));
- } else if (currentVersion > latestVersion) {
- QMessageBox::warning(this,
- tr("Unreleased Version"),
- tr("This version(%1) has not been officially released and is not recommended for use in a production environment. <br/>").arg(
- currentVersion)
- + tr("You can download the latest version(%1) on Github Releases Page.<br/>").arg(
- latestVersion));
- }
-}
+} // namespace GpgFrontend::UI
diff --git a/src/ui/main_window/MainWindowSlotUI.cpp b/src/ui/main_window/MainWindowSlotUI.cpp
index 7065e41c..35eb74ac 100644
--- a/src/ui/main_window/MainWindowSlotUI.cpp
+++ b/src/ui/main_window/MainWindowSlotUI.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -23,198 +23,174 @@
*/
#include "MainWindow.h"
+#include "ui/UserInterfaceUtils.h"
+#include "ui/settings/GlobalSettingStation.h"
-void MainWindow::slotAbout() {
- new AboutDialog(0, this);
-}
+namespace GpgFrontend::UI {
-void MainWindow::slotCheckUpdate() {
- new AboutDialog(2, this);
-}
+void MainWindow::slotAbout() { new AboutDialog(0, this); }
-void MainWindow::slotSetStatusBarText(const QString &text) {
- statusBar()->showMessage(text, 20000);
-}
+void MainWindow::slotCheckUpdate() { new AboutDialog(2, this); }
-void MainWindow::slotStartWizard() {
- auto *wizard = new Wizard(mCtx, keyMgmt, this);
- wizard->show();
- wizard->setModal(true);
+void MainWindow::slotSetStatusBarText(const QString& text) {
+ statusBar()->showMessage(text, 20000);
}
-
-void MainWindow::slotCheckAttachmentFolder() {
- // TODO: always check?
- if (!settings.value("mime/parseMime").toBool()) {
- return;
- }
-
- QString attachmentDir = qApp->applicationDirPath() + "/attachments/";
- // filenum minus . and ..
- uint filenum = QDir(attachmentDir).count() - 2;
- if (filenum > 0) {
- QString statusText;
- if (filenum == 1) {
- statusText = tr("There is one unencrypted file in attachment folder");
- } else {
- statusText = tr("There are ") + QString::number(filenum) + tr(" unencrypted files in attachment folder");
- }
- statusBarIcon->setStatusTip(statusText);
- statusBarIcon->show();
- } else {
- statusBarIcon->hide();
- }
+void MainWindow::slotStartWizard() {
+ auto* wizard = new Wizard(this);
+ wizard->show();
+ wizard->setModal(true);
}
void MainWindow::slotImportKeyFromEdit() {
- if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr)
- return;
- keyMgmt->slotImportKeys(edit->curTextPage()->toPlainText().toUtf8());
+ if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) return;
+ CommonUtils::GetInstance()->slotImportKeys(
+ this, edit->curTextPage()->toPlainText().toStdString());
}
void MainWindow::slotOpenKeyManagement() {
- keyMgmt->show();
- keyMgmt->raise();
- keyMgmt->activateWindow();
+ auto* dialog = new KeyMgmt(this);
+ dialog->show();
+ dialog->raise();
}
-void MainWindow::slotOpenFileTab() {
- edit->slotNewFileTab();
-}
+void MainWindow::slotOpenFileTab() { edit->slotNewFileTab(); }
void MainWindow::slotDisableTabActions(int number) {
- bool disable;
+ bool disable;
+
+ if (number == -1)
+ disable = true;
+ else
+ disable = false;
+
+ if (edit->curFilePage() != nullptr) {
+ disable = true;
+ }
+
+ printAct->setDisabled(disable);
+ saveAct->setDisabled(disable);
+ saveAsAct->setDisabled(disable);
+ quoteAct->setDisabled(disable);
+ cutAct->setDisabled(disable);
+ copyAct->setDisabled(disable);
+ pasteAct->setDisabled(disable);
+ closeTabAct->setDisabled(disable);
+ selectAllAct->setDisabled(disable);
+ findAct->setDisabled(disable);
+ verifyAct->setDisabled(disable);
+ signAct->setDisabled(disable);
+ encryptAct->setDisabled(disable);
+ encryptSignAct->setDisabled(disable);
+ decryptAct->setDisabled(disable);
+ decryptVerifyAct->setDisabled(disable);
+
+ redoAct->setDisabled(disable);
+ undoAct->setDisabled(disable);
+ zoomOutAct->setDisabled(disable);
+ zoomInAct->setDisabled(disable);
+ cleanDoubleLinebreaksAct->setDisabled(disable);
+ quoteAct->setDisabled(disable);
+ appendSelectedKeysAct->setDisabled(disable);
+ importKeyFromEditAct->setDisabled(disable);
+
+ cutPgpHeaderAct->setDisabled(disable);
+ addPgpHeaderAct->setDisabled(disable);
+}
- if (number == -1)
- disable = true;
- else
- disable = false;
+void MainWindow::slotOpenSettingsDialog() {
+ auto dialog = new SettingsDialog(this);
- if(edit->curFilePage() != nullptr) {
- disable = true;
- }
+ connect(dialog, &SettingsDialog::finished, this, [&]() -> void {
+ LOG(INFO) << "Setting Dialog Finished";
- printAct->setDisabled(disable);
- saveAct->setDisabled(disable);
- saveAsAct->setDisabled(disable);
- quoteAct->setDisabled(disable);
- cutAct->setDisabled(disable);
- copyAct->setDisabled(disable);
- pasteAct->setDisabled(disable);
- closeTabAct->setDisabled(disable);
- selectAllAct->setDisabled(disable);
- findAct->setDisabled(disable);
- verifyAct->setDisabled(disable);
- signAct->setDisabled(disable);
- encryptAct->setDisabled(disable);
- encryptSignAct->setDisabled(disable);
- decryptAct->setDisabled(disable);
- decryptVerifyAct->setDisabled(disable);
-
- redoAct->setDisabled(disable);
- undoAct->setDisabled(disable);
- zoomOutAct->setDisabled(disable);
- zoomInAct->setDisabled(disable);
- cleanDoubleLinebreaksAct->setDisabled(disable);
- quoteAct->setDisabled(disable);
- appendSelectedKeysAct->setDisabled(disable);
- importKeyFromEditAct->setDisabled(disable);
-
- cutPgpHeaderAct->setDisabled(disable);
- addPgpHeaderAct->setDisabled(disable);
-}
+ auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
-void MainWindow::slotOpenSettingsDialog() {
+ int icon_width = settings["window"]["icon_size"]["width"];
+ int icon_height = settings["window"]["icon_size"]["height"];
+
+ this->setIconSize(QSize(icon_width, icon_height));
+ importButton->setIconSize(QSize(icon_width, icon_height));
+ fileEncButton->setIconSize(QSize(icon_width, icon_height));
+
+ // Iconstyle
- auto dialog = new SettingsDialog(mCtx, this);
-
- connect(dialog, &SettingsDialog::finished, this, [&] () -> void {
-
- qDebug() << "Setting Dialog Finished";
-
- // Iconsize
- QSize iconSize = settings.value("toolbar/iconsize", QSize(32, 32)).toSize();
- this->setIconSize(iconSize);
- importButton->setIconSize(iconSize);
- fileEncButton->setIconSize(iconSize);
-
- // Iconstyle
- Qt::ToolButtonStyle buttonStyle = static_cast<Qt::ToolButtonStyle>(settings.value("toolbar/iconstyle",
- Qt::ToolButtonTextUnderIcon).toUInt());
- this->setToolButtonStyle(buttonStyle);
- importButton->setToolButtonStyle(buttonStyle);
- fileEncButton->setToolButtonStyle(buttonStyle);
-
- // restart mainwindow if necessary
- if (getRestartNeeded()) {
- if (edit->maybeSaveAnyTab()) {
- saveSettings();
- qApp->exit(RESTART_CODE);
- }
- }
-
- // steganography hide/show
- if (!settings.value("advanced/steganography").toBool()) {
- this->menuBar()->removeAction(steganoMenu->menuAction());
- } else {
- this->menuBar()->insertAction(viewMenu->menuAction(), steganoMenu->menuAction());
- }
- });
+ int icon_style = settings["window"]["icon_style"];
+ auto button_style = static_cast<Qt::ToolButtonStyle>(icon_style);
+ this->setToolButtonStyle(button_style);
+ importButton->setToolButtonStyle(button_style);
+ fileEncButton->setToolButtonStyle(button_style);
+ // restart mainwindow if necessary
+ if (getRestartNeeded()) {
+ if (edit->maybeSaveAnyTab()) {
+ saveSettings();
+ qApp->exit(RESTART_CODE);
+ }
+ }
+#ifdef ADVANCED_SUPPORT
+ // steganography hide/show
+ if (!settings.value("advanced/steganography").toBool()) {
+ this->menuBar()->removeAction(steganoMenu->menuAction());
+ } else {
+ this->menuBar()->insertAction(viewMenu->menuAction(),
+ steganoMenu->menuAction());
+ }
+#endif
+ });
}
void MainWindow::slotCleanDoubleLinebreaks() {
- if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) {
- return;
- }
+ if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) {
+ return;
+ }
- QString content = edit->curTextPage()->toPlainText();
- content.replace("\n\n", "\n");
- edit->slotFillTextEditWithText(content);
+ QString content = edit->curTextPage()->toPlainText();
+ content.replace("\n\n", "\n");
+ edit->slotFillTextEditWithText(content);
}
void MainWindow::slotAddPgpHeader() {
- if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) {
- return;
- }
+ if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) {
+ return;
+ }
- QString content = edit->curTextPage()->toPlainText().trimmed();
+ QString content = edit->curTextPage()->toPlainText().trimmed();
- content.prepend("\n\n").prepend(GpgConstants::PGP_CRYPT_BEGIN);
- content.append("\n").append(GpgConstants::PGP_CRYPT_END);
+ content.prepend("\n\n").prepend(GpgConstants::PGP_CRYPT_BEGIN);
+ content.append("\n").append(GpgConstants::PGP_CRYPT_END);
- edit->slotFillTextEditWithText(content);
+ edit->slotFillTextEditWithText(content);
}
void MainWindow::slotCutPgpHeader() {
+ if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) {
+ return;
+ }
- if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) {
- return;
- }
+ QString content = edit->curTextPage()->toPlainText();
+ int start = content.indexOf(GpgConstants::PGP_CRYPT_BEGIN);
+ int end = content.indexOf(GpgConstants::PGP_CRYPT_END);
- QString content = edit->curTextPage()->toPlainText();
- int start = content.indexOf(GpgConstants::PGP_CRYPT_BEGIN);
- int end = content.indexOf(GpgConstants::PGP_CRYPT_END);
+ if (start < 0 || end < 0) {
+ return;
+ }
- if (start < 0 || end < 0) {
- return;
- }
+ // remove head
+ int headEnd = content.indexOf("\n\n", start) + 2;
+ content.remove(start, headEnd - start);
- // remove head
- int headEnd = content.indexOf("\n\n", start) + 2;
- content.remove(start, headEnd - start);
+ // remove tail
+ end = content.indexOf(GpgConstants::PGP_CRYPT_END);
+ content.remove(end, QString(GpgConstants::PGP_CRYPT_END).size());
- // remove tail
- end = content.indexOf(GpgConstants::PGP_CRYPT_END);
- content.remove(end, QString(GpgConstants::PGP_CRYPT_END).size());
-
- edit->slotFillTextEditWithText(content.trimmed());
+ edit->slotFillTextEditWithText(content.trimmed());
}
void MainWindow::slotSetRestartNeeded(bool needed) {
- this->restartNeeded = needed;
+ this->restartNeeded = needed;
}
-bool MainWindow::getRestartNeeded() const {
- return this->restartNeeded;
-}
+bool MainWindow::getRestartNeeded() const { return this->restartNeeded; }
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/main_window/MainWindowUI.cpp b/src/ui/main_window/MainWindowUI.cpp
index 21f6e3b7..ee7a1bc0 100644
--- a/src/ui/main_window/MainWindowUI.cpp
+++ b/src/ui/main_window/MainWindowUI.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -23,428 +23,476 @@
*/
#include "MainWindow.h"
+#include "ui/UserInterfaceUtils.h"
+
+namespace GpgFrontend::UI {
void MainWindow::createActions() {
- /* Main Menu
- */
- newTabAct = new QAction(tr("&New"), this);
- newTabAct->setIcon(QIcon(":misc_doc.png"));
- QList<QKeySequence> newTabActShortcutList;
- newTabActShortcutList.append(QKeySequence(Qt::CTRL + Qt::Key_N));
- newTabActShortcutList.append(QKeySequence(Qt::CTRL + Qt::Key_T));
- newTabAct->setShortcuts(newTabActShortcutList);
- newTabAct->setToolTip(tr("Open a new file"));
- connect(newTabAct, SIGNAL(triggered()), edit, SLOT(slotNewTab()));
-
- openAct = new QAction(tr("&Open..."), this);
- openAct->setIcon(QIcon(":fileopen.png"));
- openAct->setShortcut(QKeySequence::Open);
- openAct->setToolTip(tr("Open an existing file"));
- connect(openAct, SIGNAL(triggered()), edit, SLOT(slotOpen()));
-
- browserAct = new QAction(tr("&Browser"), this);
- browserAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_B));
- browserAct->setToolTip(tr("Open a file browser"));
- connect(browserAct, SIGNAL(triggered()), this, SLOT(slotOpenFileTab()));
-
- saveAct = new QAction(tr("&Save"), this);
- saveAct->setIcon(QIcon(":filesave.png"));
- saveAct->setShortcut(QKeySequence::Save);
- saveAct->setToolTip(tr("Save the current File"));
- connect(saveAct, SIGNAL(triggered()), edit, SLOT(slotSave()));
-
- saveAsAct = new QAction(tr("Save &As") + "...", this);
- saveAsAct->setIcon(QIcon(":filesaveas.png"));
- saveAsAct->setShortcut(QKeySequence::SaveAs);
- saveAsAct->setToolTip(tr("Save the current File as..."));
- connect(saveAsAct, SIGNAL(triggered()), edit, SLOT(slotSaveAs()));
-
- printAct = new QAction(tr("&Print"), this);
- printAct->setIcon(QIcon(":fileprint.png"));
- printAct->setShortcut(QKeySequence::Print);
- printAct->setToolTip(tr("Print Document"));
- connect(printAct, SIGNAL(triggered()), edit, SLOT(slotPrint()));
-
- closeTabAct = new QAction(tr("&Close"), this);
- closeTabAct->setShortcut(QKeySequence::Close);
- closeTabAct->setToolTip(tr("Close file"));
- connect(closeTabAct, SIGNAL(triggered()), edit, SLOT(slotCloseTab()));
-
- quitAct = new QAction(tr("&Quit"), this);
- quitAct->setShortcut(QKeySequence::Quit);
- quitAct->setIcon(QIcon(":exit.png"));
- quitAct->setToolTip(tr("Quit Program"));
- connect(quitAct, SIGNAL(triggered()), this, SLOT(close()));
-
- /* Edit Menu
- */
- undoAct = new QAction(tr("&Undo"), this);
- undoAct->setShortcut(QKeySequence::Undo);
- undoAct->setToolTip(tr("Undo Last Edit Action"));
- connect(undoAct, SIGNAL(triggered()), edit, SLOT(slotUndo()));
-
- redoAct = new QAction(tr("&Redo"), this);
- redoAct->setShortcut(QKeySequence::Redo);
- redoAct->setToolTip(tr("Redo Last Edit Action"));
- connect(redoAct, SIGNAL(triggered()), edit, SLOT(slotRedo()));
-
- zoomInAct = new QAction(tr("Zoom In"), this);
- zoomInAct->setShortcut(QKeySequence::ZoomIn);
- connect(zoomInAct, SIGNAL(triggered()), edit, SLOT(slotZoomIn()));
-
- zoomOutAct = new QAction(tr("Zoom Out"), this);
- zoomOutAct->setShortcut(QKeySequence::ZoomOut);
- connect(zoomOutAct, SIGNAL(triggered()), edit, SLOT(slotZoomOut()));
-
- pasteAct = new QAction(tr("&Paste"), this);
- pasteAct->setIcon(QIcon(":button_paste.png"));
- pasteAct->setShortcut(QKeySequence::Paste);
- pasteAct->setToolTip(tr("Paste Text From Clipboard"));
- connect(pasteAct, SIGNAL(triggered()), edit, SLOT(slotPaste()));
-
- cutAct = new QAction(tr("Cu&t"), this);
- cutAct->setIcon(QIcon(":button_cut.png"));
- cutAct->setShortcut(QKeySequence::Cut);
- cutAct->setToolTip(tr("Cut the current selection's contents to the "
- "clipboard"));
- connect(cutAct, SIGNAL(triggered()), edit, SLOT(slotCut()));
-
- copyAct = new QAction(tr("&Copy"), this);
- copyAct->setIcon(QIcon(":button_copy.png"));
- copyAct->setShortcut(QKeySequence::Copy);
- copyAct->setToolTip(tr("Copy the current selection's contents to the "
- "clipboard"));
- connect(copyAct, SIGNAL(triggered()), edit, SLOT(slotCopy()));
-
- quoteAct = new QAction(tr("&Quote"), this);
- quoteAct->setIcon(QIcon(":quote.png"));
- quoteAct->setToolTip(tr("Quote whole text"));
- connect(quoteAct, SIGNAL(triggered()), edit, SLOT(slotQuote()));
-
- selectAllAct = new QAction(tr("Select &All"), this);
- selectAllAct->setIcon(QIcon(":edit.png"));
- selectAllAct->setShortcut(QKeySequence::SelectAll);
- selectAllAct->setToolTip(tr("Select the whole text"));
- connect(selectAllAct, SIGNAL(triggered()), edit, SLOT(slotSelectAll()));
-
- findAct = new QAction(tr("&Find"), this);
- findAct->setShortcut(QKeySequence::Find);
- findAct->setToolTip(tr("Find a word"));
- connect(findAct, SIGNAL(triggered()), this, SLOT(slotFind()));
-
- cleanDoubleLinebreaksAct = new QAction(tr("Remove &spacing"), this);
- cleanDoubleLinebreaksAct->setIcon(QIcon(":format-line-spacing-triple.png"));
- //cleanDoubleLineBreaksAct->setShortcut(QKeySequence::SelectAll);
- cleanDoubleLinebreaksAct->setToolTip(tr("Remove double linebreaks, e.g. in pasted text from webmailer"));
- connect(cleanDoubleLinebreaksAct, SIGNAL(triggered()), this, SLOT(slotCleanDoubleLinebreaks()));
-
- openSettingsAct = new QAction(tr("Se&ttings"), this);
- openSettingsAct->setToolTip(tr("Open settings dialog"));
- openSettingsAct->setShortcut(QKeySequence::Preferences);
- connect(openSettingsAct, SIGNAL(triggered()), this, SLOT(slotOpenSettingsDialog()));
-
- /* Crypt Menu
- */
- encryptAct = new QAction(tr("&Encrypt"), this);
- encryptAct->setIcon(QIcon(":encrypted.png"));
- encryptAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_E));
- encryptAct->setToolTip(tr("Encrypt Message"));
- connect(encryptAct, SIGNAL(triggered()), this, SLOT(slotEncrypt()));
-
- encryptSignAct = new QAction(tr("&Encrypt &Sign"), this);
- encryptSignAct->setIcon(QIcon(":encrypted_signed.png"));
- encryptSignAct->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_E));
- encryptSignAct->setToolTip(tr("Encrypt and Sign Message"));
- connect(encryptSignAct, SIGNAL(triggered()), this, SLOT(slotEncryptSign()));
-
- decryptAct = new QAction(tr("&Decrypt"), this);
- decryptAct->setIcon(QIcon(":decrypted.png"));
- decryptAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_D));
- decryptAct->setToolTip(tr("Decrypt Message"));
- connect(decryptAct, SIGNAL(triggered()), this, SLOT(slotDecrypt()));
-
- decryptVerifyAct = new QAction(tr("&Decrypt &Verify"), this);
- decryptVerifyAct->setIcon(QIcon(":decrypted_verified.png"));
- decryptVerifyAct->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_D));
- decryptVerifyAct->setToolTip(tr("Decrypt and Verify Message"));
- connect(decryptVerifyAct, SIGNAL(triggered()), this, SLOT(slotDecryptVerify()));
-
- /*
- * File encryption submenu
- */
- fileEncryptAct = new QAction(tr("&Encrypt File"), this);
- fileEncryptAct->setToolTip(tr("Encrypt File"));
- connect(fileEncryptAct, SIGNAL(triggered()), this, SLOT(slotFileEncryptCustom()));
-
- fileDecryptAct = new QAction(tr("&Decrypt File"), this);
- fileDecryptAct->setToolTip(tr("Decrypt File"));
- connect(fileDecryptAct, SIGNAL(triggered()), this, SLOT(slotFileDecryptCustom()));
-
- fileSignAct = new QAction(tr("&Sign File"), this);
- fileSignAct->setToolTip(tr("Sign File"));
- connect(fileSignAct, SIGNAL(triggered()), this, SLOT(slotFileSignCustom()));
-
- fileVerifyAct = new QAction(tr("&Verify File"), this);
- fileVerifyAct->setToolTip(tr("Verify File"));
- connect(fileVerifyAct, SIGNAL(triggered()), this, SLOT(slotFileVerifyCustom()));
-
-
- signAct = new QAction(tr("&Sign"), this);
- signAct->setIcon(QIcon(":signature.png"));
- signAct->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_I));
- signAct->setToolTip(tr("Sign Message"));
- connect(signAct, SIGNAL(triggered()), this, SLOT(slotSign()));
-
- verifyAct = new QAction(tr("&Verify"), this);
- verifyAct->setIcon(QIcon(":verify.png"));
- verifyAct->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_V));
- verifyAct->setToolTip(tr("Verify Message"));
- connect(verifyAct, SIGNAL(triggered()), this, SLOT(slotVerify()));
-
- /* Key Menu
- */
-
- importKeyFromEditAct = new QAction(tr("&Editor"), this);
- importKeyFromEditAct->setIcon(QIcon(":txt.png"));
- importKeyFromEditAct->setToolTip(tr("Import New Key From Editor"));
- connect(importKeyFromEditAct, SIGNAL(triggered()), this, SLOT(slotImportKeyFromEdit()));
-
- openKeyManagementAct = new QAction(tr("Manage &Keys"), this);
- openKeyManagementAct->setIcon(QIcon(":keymgmt.png"));
- openKeyManagementAct->setToolTip(tr("Open Keymanagement"));
- connect(openKeyManagementAct, SIGNAL(triggered()), this, SLOT(slotOpenKeyManagement()));
-
- /*
- * About Menu
- */
- aboutAct = new QAction(tr("&About"), this);
- aboutAct->setIcon(QIcon(":help.png"));
- aboutAct->setToolTip(tr("Show the application's About box"));
- connect(aboutAct, SIGNAL(triggered()), this, SLOT(slotAbout()));
-
- /*
- * Check Update Menu
- */
- checkUpdateAct = new QAction(tr("&Check for Updates"), this);
- checkUpdateAct->setIcon(QIcon(":help.png"));
- checkUpdateAct->setToolTip(tr("Check for updates"));
- connect(checkUpdateAct, SIGNAL(triggered()), this, SLOT(slotCheckUpdate()));
-
- startWizardAct = new QAction(tr("Open &Wizard"), this);
- startWizardAct->setToolTip(tr("Open the wizard"));
- connect(startWizardAct, SIGNAL(triggered()), this, SLOT(slotStartWizard()));
-
- /* Popup-Menu-Action for KeyList
- */
- appendSelectedKeysAct = new QAction(tr("Append Selected Key(s) To Text"), this);
- appendSelectedKeysAct->setToolTip(tr("Append The Selected Keys To Text in Editor"));
- connect(appendSelectedKeysAct, SIGNAL(triggered()), this, SLOT(slotAppendSelectedKeys()));
-
- copyMailAddressToClipboardAct = new QAction(tr("Copy Email"), this);
- copyMailAddressToClipboardAct->setToolTip(tr("Copy selected Email to clipboard"));
- connect(copyMailAddressToClipboardAct, SIGNAL(triggered()), this, SLOT(slotCopyMailAddressToClipboard()));
-
- // TODO: find central place for shared actions, to avoid code-duplication with keymgmt.cpp
- showKeyDetailsAct = new QAction(tr("Show Key Details"), this);
- showKeyDetailsAct->setToolTip(tr("Show Details for this Key"));
- connect(showKeyDetailsAct, SIGNAL(triggered()), this, SLOT(slotShowKeyDetails()));
-
- refreshKeysFromKeyserverAct = new QAction(tr("Refresh Key From Key Server"), this);
- refreshKeysFromKeyserverAct->setToolTip(tr("Refresh key from default key server"));
- connect(refreshKeysFromKeyserverAct, SIGNAL(triggered()), this, SLOT(refreshKeysFromKeyserver()));
-
- uploadKeyToServerAct = new QAction(tr("Upload Public Key(s) To Server"), this);
- uploadKeyToServerAct->setToolTip(tr("Upload The Selected Public Keys To Server"));
- connect(uploadKeyToServerAct, SIGNAL(triggered()), this, SLOT(uploadKeyToServer()));
-
- /* Key-Shortcuts for Tab-Switchung-Action
- */
- switchTabUpAct = new QAction(this);
- switchTabUpAct->setShortcut(QKeySequence::NextChild);
- connect(switchTabUpAct, SIGNAL(triggered()), edit, SLOT(slotSwitchTabUp()));
- this->addAction(switchTabUpAct);
-
- switchTabDownAct = new QAction(this);
- switchTabDownAct->setShortcut(QKeySequence::PreviousChild);
- connect(switchTabDownAct, SIGNAL(triggered()), edit, SLOT(slotSwitchTabDown()));
- this->addAction(switchTabDownAct);
-
- cutPgpHeaderAct = new QAction(tr("Remove PGP Header"), this);
- connect(cutPgpHeaderAct, SIGNAL(triggered()), this, SLOT(slotCutPgpHeader()));
-
- addPgpHeaderAct = new QAction(tr("Add PGP Header"), this);
- connect(addPgpHeaderAct, SIGNAL(triggered()), this, SLOT(slotAddPgpHeader()));
+ /* Main Menu
+ */
+ newTabAct = new QAction(_("New"), this);
+ newTabAct->setIcon(QIcon(":misc_doc.png"));
+ QList<QKeySequence> newTabActShortcutList;
+ newTabActShortcutList.append(QKeySequence(Qt::CTRL + Qt::Key_N));
+ newTabActShortcutList.append(QKeySequence(Qt::CTRL + Qt::Key_T));
+ newTabAct->setShortcuts(newTabActShortcutList);
+ newTabAct->setToolTip(_("Open a new file"));
+ connect(newTabAct, SIGNAL(triggered()), edit, SLOT(slotNewTab()));
+
+ openAct = new QAction(_("Open..."), this);
+ openAct->setIcon(QIcon(":fileopen.png"));
+ openAct->setShortcut(QKeySequence::Open);
+ openAct->setToolTip(_("Open an existing file"));
+ connect(openAct, SIGNAL(triggered()), edit, SLOT(slotOpen()));
+
+ browserAct = new QAction(_("Browser"), this);
+ browserAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_B));
+ browserAct->setToolTip(_("Open a file browser"));
+ connect(browserAct, SIGNAL(triggered()), this, SLOT(slotOpenFileTab()));
+
+ saveAct = new QAction(_("Save"), this);
+ saveAct->setIcon(QIcon(":filesave.png"));
+ saveAct->setShortcut(QKeySequence::Save);
+ saveAct->setToolTip(_("Save the current File"));
+ connect(saveAct, SIGNAL(triggered()), edit, SLOT(slotSave()));
+
+ saveAsAct = new QAction(QString(_("Save As")) + "...", this);
+ saveAsAct->setIcon(QIcon(":filesaveas.png"));
+ saveAsAct->setShortcut(QKeySequence::SaveAs);
+ saveAsAct->setToolTip(_("Save the current File as..."));
+ connect(saveAsAct, SIGNAL(triggered()), edit, SLOT(slotSaveAs()));
+
+ printAct = new QAction(_("Print"), this);
+ printAct->setIcon(QIcon(":fileprint.png"));
+ printAct->setShortcut(QKeySequence::Print);
+ printAct->setToolTip(_("Print Document"));
+ connect(printAct, SIGNAL(triggered()), edit, SLOT(slotPrint()));
+
+ closeTabAct = new QAction(_("Close"), this);
+ closeTabAct->setShortcut(QKeySequence::Close);
+ closeTabAct->setToolTip(_("Close file"));
+ connect(closeTabAct, SIGNAL(triggered()), edit, SLOT(slotCloseTab()));
+
+ quitAct = new QAction(_("Quit"), this);
+ quitAct->setShortcut(QKeySequence::Quit);
+ quitAct->setIcon(QIcon(":exit.png"));
+ quitAct->setToolTip(_("Quit Program"));
+ connect(quitAct, SIGNAL(triggered()), this, SLOT(close()));
+
+ /* Edit Menu
+ */
+ undoAct = new QAction(_("Undo"), this);
+ undoAct->setShortcut(QKeySequence::Undo);
+ undoAct->setToolTip(_("Undo Last Edit Action"));
+ connect(undoAct, SIGNAL(triggered()), edit, SLOT(slotUndo()));
+
+ redoAct = new QAction(_("Redo"), this);
+ redoAct->setShortcut(QKeySequence::Redo);
+ redoAct->setToolTip(_("Redo Last Edit Action"));
+ connect(redoAct, SIGNAL(triggered()), edit, SLOT(slotRedo()));
+
+ zoomInAct = new QAction(_("Zoom In"), this);
+ zoomInAct->setShortcut(QKeySequence::ZoomIn);
+ connect(zoomInAct, SIGNAL(triggered()), edit, SLOT(slotZoomIn()));
+
+ zoomOutAct = new QAction(_("Zoom Out"), this);
+ zoomOutAct->setShortcut(QKeySequence::ZoomOut);
+ connect(zoomOutAct, SIGNAL(triggered()), edit, SLOT(slotZoomOut()));
+
+ pasteAct = new QAction(_("Paste"), this);
+ pasteAct->setIcon(QIcon(":button_paste.png"));
+ pasteAct->setShortcut(QKeySequence::Paste);
+ pasteAct->setToolTip(_("Paste Text From Clipboard"));
+ connect(pasteAct, SIGNAL(triggered()), edit, SLOT(slotPaste()));
+
+ cutAct = new QAction(_("Cut"), this);
+ cutAct->setIcon(QIcon(":button_cut.png"));
+ cutAct->setShortcut(QKeySequence::Cut);
+ cutAct->setToolTip(
+ _("Cut the current selection's contents to the "
+ "clipboard"));
+ connect(cutAct, SIGNAL(triggered()), edit, SLOT(slotCut()));
+
+ copyAct = new QAction(_("Copy"), this);
+ copyAct->setIcon(QIcon(":button_copy.png"));
+ copyAct->setShortcut(QKeySequence::Copy);
+ copyAct->setToolTip(
+ _("Copy the current selection's contents to the "
+ "clipboard"));
+ connect(copyAct, SIGNAL(triggered()), edit, SLOT(slotCopy()));
+
+ quoteAct = new QAction(_("Quote"), this);
+ quoteAct->setIcon(QIcon(":quote.png"));
+ quoteAct->setToolTip(_("Quote whole text"));
+ connect(quoteAct, SIGNAL(triggered()), edit, SLOT(slotQuote()));
+
+ selectAllAct = new QAction(_("Select All"), this);
+ selectAllAct->setIcon(QIcon(":edit.png"));
+ selectAllAct->setShortcut(QKeySequence::SelectAll);
+ selectAllAct->setToolTip(_("Select the whole text"));
+ connect(selectAllAct, SIGNAL(triggered()), edit, SLOT(slotSelectAll()));
+
+ findAct = new QAction(_("Find"), this);
+ findAct->setShortcut(QKeySequence::Find);
+ findAct->setToolTip(_("Find a word"));
+ connect(findAct, SIGNAL(triggered()), this, SLOT(slotFind()));
+
+ cleanDoubleLinebreaksAct = new QAction(_("Remove spacing"), this);
+ cleanDoubleLinebreaksAct->setIcon(QIcon(":format-line-spacing-triple.png"));
+ // cleanDoubleLineBreaksAct->setShortcut(QKeySequence::SelectAll);
+ cleanDoubleLinebreaksAct->setToolTip(
+ _("Remove double linebreaks, e.g. in pasted text from Web Mailer"));
+ connect(cleanDoubleLinebreaksAct, SIGNAL(triggered()), this,
+ SLOT(slotCleanDoubleLinebreaks()));
+
+ openSettingsAct = new QAction(_("Settings"), this);
+ openSettingsAct->setToolTip(_("Open settings dialog"));
+ openSettingsAct->setShortcut(QKeySequence::Preferences);
+ connect(openSettingsAct, SIGNAL(triggered()), this,
+ SLOT(slotOpenSettingsDialog()));
+
+ /* Crypt Menu
+ */
+ encryptAct = new QAction(_("Encrypt"), this);
+ encryptAct->setIcon(QIcon(":encrypted.png"));
+ encryptAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_E));
+ encryptAct->setToolTip(_("Encrypt Message"));
+ connect(encryptAct, SIGNAL(triggered()), this, SLOT(slotEncrypt()));
+
+ encryptSignAct = new QAction(_("Encrypt Sign"), this);
+ encryptSignAct->setIcon(QIcon(":encrypted_signed.png"));
+ encryptSignAct->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_E));
+ encryptSignAct->setToolTip(_("Encrypt and Sign Message"));
+ connect(encryptSignAct, SIGNAL(triggered()), this, SLOT(slotEncryptSign()));
+
+ decryptAct = new QAction(_("Decrypt"), this);
+ decryptAct->setIcon(QIcon(":decrypted.png"));
+ decryptAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_D));
+ decryptAct->setToolTip(_("Decrypt Message"));
+ connect(decryptAct, SIGNAL(triggered()), this, SLOT(slotDecrypt()));
+
+ decryptVerifyAct = new QAction(_("Decrypt Verify"), this);
+ decryptVerifyAct->setIcon(QIcon(":decrypted_verified.png"));
+ decryptVerifyAct->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_D));
+ decryptVerifyAct->setToolTip(_("Decrypt and Verify Message"));
+ connect(decryptVerifyAct, SIGNAL(triggered()), this,
+ SLOT(slotDecryptVerify()));
+
+ /*
+ * File encryption submenu
+ */
+ fileEncryptAct = new QAction(_("Encrypt File"), this);
+ fileEncryptAct->setToolTip(_("Encrypt File"));
+ connect(fileEncryptAct, SIGNAL(triggered()), this,
+ SLOT(slotFileEncryptCustom()));
+
+ fileDecryptAct = new QAction(_("Decrypt File"), this);
+ fileDecryptAct->setToolTip(_("Decrypt File"));
+ connect(fileDecryptAct, SIGNAL(triggered()), this,
+ SLOT(slotFileDecryptCustom()));
+
+ fileSignAct = new QAction(_("Sign File"), this);
+ fileSignAct->setToolTip(_("Sign File"));
+ connect(fileSignAct, SIGNAL(triggered()), this, SLOT(slotFileSignCustom()));
+
+ fileVerifyAct = new QAction(_("Verify File"), this);
+ fileVerifyAct->setToolTip(_("Verify File"));
+ connect(fileVerifyAct, SIGNAL(triggered()), this,
+ SLOT(slotFileVerifyCustom()));
+
+ signAct = new QAction(_("Sign"), this);
+ signAct->setIcon(QIcon(":signature.png"));
+ signAct->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_I));
+ signAct->setToolTip(_("Sign Message"));
+ connect(signAct, SIGNAL(triggered()), this, SLOT(slotSign()));
+
+ verifyAct = new QAction(_("Verify"), this);
+ verifyAct->setIcon(QIcon(":verify.png"));
+ verifyAct->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_V));
+ verifyAct->setToolTip(_("Verify Message"));
+ connect(verifyAct, SIGNAL(triggered()), this, SLOT(slotVerify()));
+
+ /* Key Menu
+ */
+
+ importKeyFromFileAct = new QAction(_("File"), this);
+ importKeyFromFileAct->setIcon(QIcon(":import_key_from_file.png"));
+ importKeyFromFileAct->setToolTip(_("Import New Key From File"));
+ connect(importKeyFromFileAct, &QAction::triggered, this,
+ [&]() { CommonUtils::GetInstance()->slotImportKeyFromFile(this); });
+
+ importKeyFromClipboardAct = new QAction(_("Clipboard"), this);
+ importKeyFromClipboardAct->setIcon(QIcon(":import_key_from_clipboard.png"));
+ importKeyFromClipboardAct->setToolTip(_("Import New Key From Clipboard"));
+ connect(importKeyFromClipboardAct, &QAction::triggered, this, [&]() {
+ CommonUtils::GetInstance()->slotImportKeyFromClipboard(this);
+ });
+
+ importKeyFromKeyServerAct = new QAction(_("Keyserver"), this);
+ importKeyFromKeyServerAct->setIcon(QIcon(":import_key_from_server.png"));
+ importKeyFromKeyServerAct->setToolTip(_("Import New Key From Keyserver"));
+ connect(importKeyFromKeyServerAct, &QAction::triggered, this, [&]() {
+ CommonUtils::GetInstance()->slotImportKeyFromKeyServer(this);
+ });
+
+ importKeyFromEditAct = new QAction(_("Editor"), this);
+ importKeyFromEditAct->setIcon(QIcon(":txt.png"));
+ importKeyFromEditAct->setToolTip(_("Import New Key From Editor"));
+ connect(importKeyFromEditAct, SIGNAL(triggered()), this,
+ SLOT(slotImportKeyFromEdit()));
+
+ openKeyManagementAct = new QAction(_("Manage Keys"), this);
+ openKeyManagementAct->setIcon(QIcon(":keymgmt.png"));
+ openKeyManagementAct->setToolTip(_("Open Key Management"));
+ connect(openKeyManagementAct, SIGNAL(triggered()), this,
+ SLOT(slotOpenKeyManagement()));
+
+ /*
+ * About Menu
+ */
+ aboutAct = new QAction(_("About"), this);
+ aboutAct->setIcon(QIcon(":help.png"));
+ aboutAct->setToolTip(_("Show the application's About box"));
+ connect(aboutAct, SIGNAL(triggered()), this, SLOT(slotAbout()));
+
+ /*
+ * Check Update Menu
+ */
+ checkUpdateAct = new QAction(_("Check for Updates"), this);
+ checkUpdateAct->setIcon(QIcon(":help.png"));
+ checkUpdateAct->setToolTip(_("Check for updates"));
+ connect(checkUpdateAct, SIGNAL(triggered()), this, SLOT(slotCheckUpdate()));
+
+ startWizardAct = new QAction(_("Open Wizard"), this);
+ startWizardAct->setToolTip(_("Open the wizard"));
+ connect(startWizardAct, SIGNAL(triggered()), this, SLOT(slotStartWizard()));
+
+ /* Popup-Menu-Action for KeyList
+ */
+ appendSelectedKeysAct =
+ new QAction(_("Append Selected Key(s) To Text"), this);
+ appendSelectedKeysAct->setToolTip(
+ _("Append The Selected Keys To Text in Editor"));
+ connect(appendSelectedKeysAct, SIGNAL(triggered()), this,
+ SLOT(slotAppendSelectedKeys()));
+
+ copyMailAddressToClipboardAct = new QAction(_("Copy Email"), this);
+ copyMailAddressToClipboardAct->setToolTip(
+ _("Copy selected Email to clipboard"));
+ connect(copyMailAddressToClipboardAct, SIGNAL(triggered()), this,
+ SLOT(slotCopyMailAddressToClipboard()));
+
+ // TODO: find central place for shared actions, to avoid code-duplication with
+ // keymgmt.cpp
+ showKeyDetailsAct = new QAction(_("Show Key Details"), this);
+ showKeyDetailsAct->setToolTip(_("Show Details for this Key"));
+ connect(showKeyDetailsAct, SIGNAL(triggered()), this,
+ SLOT(slotShowKeyDetails()));
+
+ refreshKeysFromKeyserverAct =
+ new QAction(_("Refresh Key From Key Server"), this);
+ refreshKeysFromKeyserverAct->setToolTip(
+ _("Refresh key from default key server"));
+ connect(refreshKeysFromKeyserverAct, SIGNAL(triggered()), this,
+ SLOT(refreshKeysFromKeyserver()));
+
+ uploadKeyToServerAct = new QAction(_("Upload Public Key(s) To Server"), this);
+ uploadKeyToServerAct->setToolTip(
+ _("Upload The Selected Public Keys To Server"));
+ connect(uploadKeyToServerAct, SIGNAL(triggered()), this,
+ SLOT(uploadKeyToServer()));
+
+ /* Key-Shortcuts for Tab-Switchung-Action
+ */
+ switchTabUpAct = new QAction(this);
+ switchTabUpAct->setShortcut(QKeySequence::NextChild);
+ connect(switchTabUpAct, SIGNAL(triggered()), edit, SLOT(slotSwitchTabUp()));
+ this->addAction(switchTabUpAct);
+
+ switchTabDownAct = new QAction(this);
+ switchTabDownAct->setShortcut(QKeySequence::PreviousChild);
+ connect(switchTabDownAct, SIGNAL(triggered()), edit,
+ SLOT(slotSwitchTabDown()));
+ this->addAction(switchTabDownAct);
+
+ cutPgpHeaderAct = new QAction(_("Remove PGP Header"), this);
+ connect(cutPgpHeaderAct, SIGNAL(triggered()), this, SLOT(slotCutPgpHeader()));
+
+ addPgpHeaderAct = new QAction(_("Add PGP Header"), this);
+ connect(addPgpHeaderAct, SIGNAL(triggered()), this, SLOT(slotAddPgpHeader()));
}
void MainWindow::createMenus() {
- fileMenu = menuBar()->addMenu(tr("&File"));
- fileMenu->addAction(newTabAct);
- fileMenu->addAction(browserAct);
- fileMenu->addAction(openAct);
- fileMenu->addSeparator();
- fileMenu->addAction(saveAct);
- fileMenu->addAction(saveAsAct);
- fileMenu->addSeparator();
- fileMenu->addAction(printAct);
- fileMenu->addSeparator();
- fileMenu->addAction(closeTabAct);
- fileMenu->addAction(quitAct);
-
- editMenu = menuBar()->addMenu(tr("&Edit"));
- editMenu->addAction(undoAct);
- editMenu->addAction(redoAct);
- editMenu->addSeparator();
- editMenu->addAction(zoomInAct);
- editMenu->addAction(zoomOutAct);
- editMenu->addSeparator();
- editMenu->addAction(copyAct);
- editMenu->addAction(cutAct);
- editMenu->addAction(pasteAct);
- editMenu->addAction(selectAllAct);
- editMenu->addAction(findAct);
- editMenu->addSeparator();
- editMenu->addAction(quoteAct);
- editMenu->addAction(cleanDoubleLinebreaksAct);
- editMenu->addSeparator();
- editMenu->addAction(openSettingsAct);
-
- fileEncMenu = new QMenu(tr("&File..."));
- fileEncMenu->addAction(fileEncryptAct);
- fileEncMenu->addAction(fileDecryptAct);
- fileEncMenu->addAction(fileSignAct);
- fileEncMenu->addAction(fileVerifyAct);
-
- cryptMenu = menuBar()->addMenu(tr("&Crypt"));
- cryptMenu->addAction(encryptAct);
- cryptMenu->addAction(encryptSignAct);
- cryptMenu->addAction(decryptAct);
- cryptMenu->addAction(decryptVerifyAct);
- cryptMenu->addSeparator();
- cryptMenu->addAction(signAct);
- cryptMenu->addAction(verifyAct);
- cryptMenu->addSeparator();
- cryptMenu->addMenu(fileEncMenu);
-
- keyMenu = menuBar()->addMenu(tr("&Keys"));
- importKeyMenu = keyMenu->addMenu(tr("&Import Key"));
- importKeyMenu->setIcon(QIcon(":key_import.png"));
- importKeyMenu->addAction(keyMgmt->importKeyFromFileAct);
- importKeyMenu->addAction(importKeyFromEditAct);
- importKeyMenu->addAction(keyMgmt->importKeyFromClipboardAct);
- importKeyMenu->addAction(keyMgmt->importKeyFromKeyServerAct);
- importKeyMenu->addAction(keyMgmt->importKeyFromKeyServerAct);
- keyMenu->addAction(openKeyManagementAct);
-
- steganoMenu = menuBar()->addMenu(tr("&Steganography"));
- steganoMenu->addAction(cutPgpHeaderAct);
- steganoMenu->addAction(addPgpHeaderAct);
-
- // Hide menu, when steganography menu is disabled in settings
- if (!settings.value("advanced/steganography").toBool()) {
- this->menuBar()->removeAction(steganoMenu->menuAction());
- }
-
- viewMenu = menuBar()->addMenu(tr("&View"));
-
- helpMenu = menuBar()->addMenu(tr("&Help"));
- helpMenu->addAction(startWizardAct);
- helpMenu->addSeparator();
- helpMenu->addAction(checkUpdateAct);
- helpMenu->addAction(aboutAct);
-
+ fileMenu = menuBar()->addMenu(_("File"));
+ fileMenu->addAction(newTabAct);
+ fileMenu->addAction(browserAct);
+ fileMenu->addAction(openAct);
+ fileMenu->addSeparator();
+ fileMenu->addAction(saveAct);
+ fileMenu->addAction(saveAsAct);
+ fileMenu->addSeparator();
+ fileMenu->addAction(printAct);
+ fileMenu->addSeparator();
+ fileMenu->addAction(closeTabAct);
+ fileMenu->addAction(quitAct);
+
+ editMenu = menuBar()->addMenu(_("Edit"));
+ editMenu->addAction(undoAct);
+ editMenu->addAction(redoAct);
+ editMenu->addSeparator();
+ editMenu->addAction(zoomInAct);
+ editMenu->addAction(zoomOutAct);
+ editMenu->addSeparator();
+ editMenu->addAction(copyAct);
+ editMenu->addAction(cutAct);
+ editMenu->addAction(pasteAct);
+ editMenu->addAction(selectAllAct);
+ editMenu->addAction(findAct);
+ editMenu->addSeparator();
+ editMenu->addAction(quoteAct);
+ editMenu->addAction(cleanDoubleLinebreaksAct);
+ editMenu->addSeparator();
+ editMenu->addAction(openSettingsAct);
+
+ fileEncMenu = new QMenu(_("File..."));
+ fileEncMenu->addAction(fileEncryptAct);
+ fileEncMenu->addAction(fileDecryptAct);
+ fileEncMenu->addAction(fileSignAct);
+ fileEncMenu->addAction(fileVerifyAct);
+
+ cryptMenu = menuBar()->addMenu(_("Crypt"));
+ cryptMenu->addAction(encryptAct);
+ cryptMenu->addAction(encryptSignAct);
+ cryptMenu->addAction(decryptAct);
+ cryptMenu->addAction(decryptVerifyAct);
+ cryptMenu->addSeparator();
+ cryptMenu->addAction(signAct);
+ cryptMenu->addAction(verifyAct);
+ cryptMenu->addSeparator();
+ cryptMenu->addMenu(fileEncMenu);
+
+ keyMenu = menuBar()->addMenu(_("Keys"));
+ importKeyMenu = keyMenu->addMenu(_("Import Key"));
+ importKeyMenu->setIcon(QIcon(":key_import.png"));
+ importKeyMenu->addAction(importKeyFromFileAct);
+ importKeyMenu->addAction(importKeyFromEditAct);
+ importKeyMenu->addAction(importKeyFromClipboardAct);
+ importKeyMenu->addAction(importKeyFromKeyServerAct);
+ keyMenu->addAction(openKeyManagementAct);
+
+ steganoMenu = menuBar()->addMenu(_("Steganography"));
+ steganoMenu->addAction(cutPgpHeaderAct);
+ steganoMenu->addAction(addPgpHeaderAct);
+
+#ifdef ADVANCED_SUPPORT
+ // Hide menu, when steganography menu is disabled in settings
+ if (!settings.value("advanced/steganography").toBool()) {
+ this->menuBar()->removeAction(steganoMenu->menuAction());
+ }
+#endif
+
+ viewMenu = menuBar()->addMenu(_("View"));
+
+ helpMenu = menuBar()->addMenu(_("Help"));
+ helpMenu->addAction(startWizardAct);
+ helpMenu->addSeparator();
+ helpMenu->addAction(checkUpdateAct);
+ helpMenu->addAction(aboutAct);
}
void MainWindow::createToolBars() {
- fileToolBar = addToolBar(tr("File"));
- fileToolBar->setObjectName("fileToolBar");
- fileToolBar->addAction(newTabAct);
- fileToolBar->addAction(openAct);
- fileToolBar->addAction(saveAct);
- fileToolBar->hide();
- viewMenu->addAction(fileToolBar->toggleViewAction());
-
- cryptToolBar = addToolBar(tr("Crypt"));
- cryptToolBar->setObjectName("cryptToolBar");
- cryptToolBar->addAction(encryptAct);
- cryptToolBar->addAction(encryptSignAct);
- cryptToolBar->addAction(decryptAct);
- cryptToolBar->addAction(decryptVerifyAct);
- cryptToolBar->addAction(signAct);
- cryptToolBar->addAction(verifyAct);
- viewMenu->addAction(cryptToolBar->toggleViewAction());
-
- keyToolBar = addToolBar(tr("Key"));
- keyToolBar->setObjectName("keyToolBar");
- keyToolBar->addAction(openKeyManagementAct);
- viewMenu->addAction(keyToolBar->toggleViewAction());
-
- editToolBar = addToolBar(tr("Edit"));
- editToolBar->setObjectName("editToolBar");
- editToolBar->addAction(copyAct);
- editToolBar->addAction(pasteAct);
- editToolBar->addAction(selectAllAct);
- viewMenu->addAction(editToolBar->toggleViewAction());
-
- specialEditToolBar = addToolBar(tr("Special Edit"));
- specialEditToolBar->setObjectName("specialEditToolBar");
- specialEditToolBar->addAction(quoteAct);
- specialEditToolBar->addAction(cleanDoubleLinebreaksAct);
- specialEditToolBar->hide();
- viewMenu->addAction(specialEditToolBar->toggleViewAction());
-
- // Add dropdown menu for key import to keytoolbar
- importButton = new QToolButton();
- importButton->setMenu(importKeyMenu);
- importButton->setPopupMode(QToolButton::InstantPopup);
- importButton->setIcon(QIcon(":key_import.png"));
- importButton->setToolTip(tr("Import key from..."));
- importButton->setText(tr("Import key"));
- keyToolBar->addWidget(importButton);
-
- // Add dropdown menu for file encryption/decryption to crypttoolbar
- fileEncButton = new QToolButton();
- connect(fileEncButton, SIGNAL(clicked(bool)), this, SLOT(slotOpenFileTab()));
- fileEncButton->setPopupMode(QToolButton::InstantPopup);
- fileEncButton->setIcon(QIcon(":fileencryption.png"));
- fileEncButton->setToolTip(tr("Browser to view and operate file"));
- fileEncButton->setText(tr("Browser"));
- fileToolBar->addWidget(fileEncButton);
-
+ fileToolBar = addToolBar(_("File"));
+ fileToolBar->setObjectName("fileToolBar");
+ fileToolBar->addAction(newTabAct);
+ fileToolBar->addAction(openAct);
+ fileToolBar->addAction(saveAct);
+ fileToolBar->hide();
+ viewMenu->addAction(fileToolBar->toggleViewAction());
+
+ cryptToolBar = addToolBar(_("Crypt"));
+ cryptToolBar->setObjectName("cryptToolBar");
+ cryptToolBar->addAction(encryptAct);
+ cryptToolBar->addAction(encryptSignAct);
+ cryptToolBar->addAction(decryptAct);
+ cryptToolBar->addAction(decryptVerifyAct);
+ cryptToolBar->addAction(signAct);
+ cryptToolBar->addAction(verifyAct);
+ viewMenu->addAction(cryptToolBar->toggleViewAction());
+
+ keyToolBar = addToolBar(_("Key"));
+ keyToolBar->setObjectName("keyToolBar");
+ keyToolBar->addAction(openKeyManagementAct);
+ viewMenu->addAction(keyToolBar->toggleViewAction());
+
+ editToolBar = addToolBar(_("Edit"));
+ editToolBar->setObjectName("editToolBar");
+ editToolBar->addAction(copyAct);
+ editToolBar->addAction(pasteAct);
+ editToolBar->addAction(selectAllAct);
+ viewMenu->addAction(editToolBar->toggleViewAction());
+
+ specialEditToolBar = addToolBar(_("Special Edit"));
+ specialEditToolBar->setObjectName("specialEditToolBar");
+ specialEditToolBar->addAction(quoteAct);
+ specialEditToolBar->addAction(cleanDoubleLinebreaksAct);
+ specialEditToolBar->hide();
+ viewMenu->addAction(specialEditToolBar->toggleViewAction());
+
+ // Add dropdown menu for key import to keytoolbar
+ importButton = new QToolButton();
+ importButton->setMenu(importKeyMenu);
+ importButton->setPopupMode(QToolButton::InstantPopup);
+ importButton->setIcon(QIcon(":key_import.png"));
+ importButton->setToolTip(_("Import key from..."));
+ importButton->setText(_("Import key"));
+ keyToolBar->addWidget(importButton);
+
+ // Add dropdown menu for file encryption/decryption to crypttoolbar
+ fileEncButton = new QToolButton();
+ connect(fileEncButton, SIGNAL(clicked(bool)), this, SLOT(slotOpenFileTab()));
+ fileEncButton->setPopupMode(QToolButton::InstantPopup);
+ fileEncButton->setIcon(QIcon(":fileencryption.png"));
+ fileEncButton->setToolTip(_("Browser to view and operate file"));
+ fileEncButton->setText(_("Browser"));
+ fileToolBar->addWidget(fileEncButton);
}
void MainWindow::createStatusBar() {
- auto *statusBarBox = new QWidget();
- auto *statusBarBoxLayout = new QHBoxLayout();
- QPixmap *pixmap;
-
- // icon which should be shown if there are files in attachments-folder
- pixmap = new QPixmap(":statusbar_icon.png");
- statusBarIcon = new QLabel();
- statusBar()->addWidget(statusBarIcon);
-
- statusBarIcon->setPixmap(*pixmap);
- statusBar()->insertPermanentWidget(0, statusBarIcon, 0);
- statusBarIcon->hide();
- statusBar()->showMessage(tr("Ready"), 2000);
- statusBarBox->setLayout(statusBarBoxLayout);
+ auto* statusBarBox = new QWidget();
+ auto* statusBarBoxLayout = new QHBoxLayout();
+ QPixmap* pixmap;
+
+ // icon which should be shown if there are files in attachments-folder
+ pixmap = new QPixmap(":statusbar_icon.png");
+ statusBarIcon = new QLabel();
+ statusBar()->addWidget(statusBarIcon);
+
+ statusBarIcon->setPixmap(*pixmap);
+ statusBar()->insertPermanentWidget(0, statusBarIcon, 0);
+ statusBarIcon->hide();
+ statusBar()->showMessage(_("Ready"), 2000);
+ statusBarBox->setLayout(statusBarBoxLayout);
}
void MainWindow::createDockWindows() {
- /* KeyList-Dockwindow
- */
- keyListDock = new QDockWidget(tr("Key ToolBox"), this);
- keyListDock->setObjectName("EncryptDock");
- keyListDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
- keyListDock->setMinimumWidth(460);
- addDockWidget(Qt::RightDockWidgetArea, keyListDock);
- keyListDock->setWidget(mKeyList);
- viewMenu->addAction(keyListDock->toggleViewAction());
-
- infoBoardDock = new QDockWidget(tr("Information Board"), this);
- infoBoardDock->setObjectName("Information Board");
- infoBoardDock->setAllowedAreas(Qt::BottomDockWidgetArea);
- addDockWidget(Qt::BottomDockWidgetArea, infoBoardDock);
- infoBoardDock->setWidget(infoBoard);
- infoBoardDock->widget()->layout()->setContentsMargins(0, 0, 0, 0);
- viewMenu->addAction(infoBoardDock->toggleViewAction());
+ /* KeyList-Dock window
+ */
+ keyListDock = new QDockWidget(_("Key ToolBox"), this);
+ keyListDock->setObjectName("EncryptDock");
+ keyListDock->setAllowedAreas(Qt::LeftDockWidgetArea |
+ Qt::RightDockWidgetArea);
+ keyListDock->setMinimumWidth(460);
+ addDockWidget(Qt::RightDockWidgetArea, keyListDock);
+ keyListDock->setWidget(mKeyList);
+ viewMenu->addAction(keyListDock->toggleViewAction());
+
+ infoBoardDock = new QDockWidget(_("Information Board"), this);
+ infoBoardDock->setObjectName("Information Board");
+ infoBoardDock->setAllowedAreas(Qt::BottomDockWidgetArea);
+ addDockWidget(Qt::BottomDockWidgetArea, infoBoardDock);
+ infoBoardDock->setWidget(infoBoard);
+ infoBoardDock->widget()->layout()->setContentsMargins(0, 0, 0, 0);
+ viewMenu->addAction(infoBoardDock->toggleViewAction());
}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/settings/GlobalSettingStation.cpp b/src/ui/settings/GlobalSettingStation.cpp
new file mode 100644
index 00000000..e88de93b
--- /dev/null
+++ b/src/ui/settings/GlobalSettingStation.cpp
@@ -0,0 +1,94 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "GlobalSettingStation.h"
+
+std::unique_ptr<GpgFrontend::UI::GlobalSettingStation>
+ GpgFrontend::UI::GlobalSettingStation::_instance = nullptr;
+
+GpgFrontend::UI::GlobalSettingStation&
+GpgFrontend::UI::GlobalSettingStation::GetInstance() {
+ if (_instance == nullptr) {
+ _instance = std::make_unique<GlobalSettingStation>();
+ }
+ return *_instance;
+}
+
+void GpgFrontend::UI::GlobalSettingStation::Sync() noexcept {
+ using namespace libconfig;
+ try {
+ ui_cfg.writeFile(ui_config_path.string().c_str());
+ LOG(INFO) << _("Updated ui configuration successfully written to")
+ << ui_config_path;
+
+ } catch (const FileIOException& fioex) {
+ LOG(ERROR) << _("I/O error while writing ui configuration file")
+ << ui_config_path;
+ }
+}
+
+GpgFrontend::UI::GlobalSettingStation::GlobalSettingStation() noexcept {
+ using namespace boost::filesystem;
+ using namespace libconfig;
+
+ el::Loggers::addFlag(el::LoggingFlag::AutoSpacing);
+
+ LOG(INFO) << _("App Path") << app_path;
+ LOG(INFO) << _("App Configure Path") << app_configure_path;
+ LOG(INFO) << _("App Data Path") << app_data_path;
+ LOG(INFO) << _("App Log Path") << app_log_path;
+ LOG(INFO) << _("App Locale Path") << app_locale_path;
+
+ if (!is_directory(app_configure_path)) create_directory(app_configure_path);
+
+ if (!is_directory(app_data_path)) create_directory(app_data_path);
+
+ if (!is_directory(app_log_path)) create_directory(app_log_path);
+
+ if (!is_directory(ui_config_dir_path)) create_directory(ui_config_dir_path);
+
+ if (!exists(ui_config_path)) {
+ try {
+ this->ui_cfg.writeFile(ui_config_path.string().c_str());
+ LOG(INFO) << _("UserInterface configuration successfully written to")
+ << ui_config_path;
+
+ } catch (const FileIOException& fioex) {
+ LOG(ERROR)
+ << _("I/O error while writing UserInterface configuration file")
+ << ui_config_path;
+ }
+ } else {
+ try {
+ this->ui_cfg.readFile(ui_config_path.string().c_str());
+ LOG(INFO) << _("UserInterface configuration successfully read from")
+ << ui_config_path;
+ } catch (const FileIOException& fioex) {
+ LOG(ERROR) << _("I/O error while reading UserInterface configure file");
+ } catch (const ParseException& pex) {
+ LOG(ERROR) << _("Parse error at ") << pex.getFile() << ":"
+ << pex.getLine() << " - " << pex.getError();
+ }
+ }
+}
diff --git a/src/ui/settings/GlobalSettingStation.h b/src/ui/settings/GlobalSettingStation.h
new file mode 100644
index 00000000..ef2c6a9a
--- /dev/null
+++ b/src/ui/settings/GlobalSettingStation.h
@@ -0,0 +1,90 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_GLOBALSETTINGSTATION_H
+#define GPGFRONTEND_GLOBALSETTINGSTATION_H
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/path.hpp>
+
+#include "ui/GpgFrontendUI.h"
+
+namespace GpgFrontend::UI {
+
+class GlobalSettingStation : public QObject {
+ Q_OBJECT
+ public:
+ static GlobalSettingStation& GetInstance();
+
+ GlobalSettingStation() noexcept;
+
+ libconfig::Setting& GetUISettings() noexcept { return ui_cfg.getRoot(); }
+
+ [[nodiscard]] boost::filesystem::path GetAppDir() const { return app_path; }
+
+ [[nodiscard]] boost::filesystem::path GetLogDir() const {
+ return app_log_path;
+ }
+
+ [[nodiscard]] boost::filesystem::path GetLocaleDir() const {
+ return app_locale_path;
+ }
+
+ void Sync() noexcept;
+
+ private:
+ // Program Location
+ boost::filesystem::path app_path = qApp->applicationDirPath().toStdString();
+
+ // Program Data Location
+ boost::filesystem::path app_data_path =
+ QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)
+ .toStdString();
+
+ // Program Data Location
+ boost::filesystem::path app_log_path = app_data_path / "logs";
+
+ // Program Data Location
+ boost::filesystem::path app_locale_path =
+ RESOURCE_DIR_BOOST_PATH(app_path) / "locales";
+
+ // Program Configure Location
+ boost::filesystem::path app_configure_path =
+ QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation)
+ .toStdString();
+
+ // Configure File Directory Location
+ boost::filesystem::path ui_config_dir_path =
+ app_configure_path / "UserInterface";
+
+ // UI Configure File Location
+ boost::filesystem::path ui_config_path = ui_config_dir_path / "ui.cfg";
+
+ libconfig::Config ui_cfg;
+
+ static std::unique_ptr<GlobalSettingStation> _instance;
+};
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_GLOBALSETTINGSTATION_H
diff --git a/src/ui/settings/SettingsAdvanced.cpp b/src/ui/settings/SettingsAdvanced.cpp
index 30414250..b64ec8e9 100644
--- a/src/ui/settings/SettingsAdvanced.cpp
+++ b/src/ui/settings/SettingsAdvanced.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -22,46 +22,51 @@
*
*/
-#include "ui/SettingsDialog.h"
+#include "SettingsAdvanced.h"
-AdvancedTab::AdvancedTab(QWidget *parent)
-: QWidget(parent), appPath(qApp->applicationDirPath()),
-settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini",
- QSettings::IniFormat) {
- /*****************************************
- * Steganography Box
- *****************************************/
- auto *steganoBox = new QGroupBox(tr("Show Steganography Options"));
- auto *steganoBoxLayout = new QHBoxLayout();
- steganoCheckBox = new QCheckBox(tr("Show Steganographic Options."), this);
- steganoBoxLayout->addWidget(steganoCheckBox);
- steganoBox->setLayout(steganoBoxLayout);
+namespace GpgFrontend::UI {
- auto *pubkeyExchangeBox = new QGroupBox(tr("Pubkey Exchange"));
- auto *pubkeyExchangeBoxLayout = new QHBoxLayout();
- autoPubkeyExchangeCheckBox = new QCheckBox(tr("Auto Pubkey Exchange"), this);
- pubkeyExchangeBoxLayout->addWidget(autoPubkeyExchangeCheckBox);
- pubkeyExchangeBox->setLayout(pubkeyExchangeBoxLayout);
+AdvancedTab::AdvancedTab(QWidget* parent)
+ : QWidget(parent),
+ appPath(qApp->applicationDirPath()),
+ settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini",
+ QSettings::IniFormat) {
+ /*****************************************
+ * Steganography Box
+ *****************************************/
+ auto* steganoBox = new QGroupBox(_("Show Steganography Options"));
+ auto* steganoBoxLayout = new QHBoxLayout();
+ steganoCheckBox = new QCheckBox(_("Show Steganographic Options."), this);
+ steganoBoxLayout->addWidget(steganoCheckBox);
+ steganoBox->setLayout(steganoBoxLayout);
- auto *mainLayout = new QVBoxLayout;
- mainLayout->addWidget(steganoBox);
- mainLayout->addWidget(pubkeyExchangeBox);
- setSettings();
- mainLayout->addStretch(1);
- setLayout(mainLayout);
+ auto* pubkeyExchangeBox = new QGroupBox(_("Pubkey Exchange"));
+ auto* pubkeyExchangeBoxLayout = new QHBoxLayout();
+ autoPubkeyExchangeCheckBox = new QCheckBox(_("Auto Pubkey Exchange"), this);
+ pubkeyExchangeBoxLayout->addWidget(autoPubkeyExchangeCheckBox);
+ pubkeyExchangeBox->setLayout(pubkeyExchangeBoxLayout);
+
+ auto* mainLayout = new QVBoxLayout;
+ mainLayout->addWidget(steganoBox);
+ mainLayout->addWidget(pubkeyExchangeBox);
+ setSettings();
+ mainLayout->addStretch(1);
+ setLayout(mainLayout);
}
void AdvancedTab::setSettings() {
- if (settings.value("advanced/steganography").toBool()) {
- steganoCheckBox->setCheckState(Qt::Checked);
- }
- if (settings.value("advanced/autoPubkeyExchange").toBool()) {
- autoPubkeyExchangeCheckBox->setCheckState(Qt::Checked);
- }
+ if (settings.value("advanced/steganography").toBool()) {
+ steganoCheckBox->setCheckState(Qt::Checked);
+ }
+ if (settings.value("advanced/autoPubkeyExchange").toBool()) {
+ autoPubkeyExchangeCheckBox->setCheckState(Qt::Checked);
+ }
}
void AdvancedTab::applySettings() {
- settings.setValue("advanced/steganography", steganoCheckBox->isChecked());
- settings.setValue("advanced/autoPubkeyExchange", autoPubkeyExchangeCheckBox->isChecked());
+ settings.setValue("advanced/steganography", steganoCheckBox->isChecked());
+ settings.setValue("advanced/autoPubkeyExchange",
+ autoPubkeyExchangeCheckBox->isChecked());
}
+} // namespace GpgFrontend::UI
diff --git a/src/ui/settings/SettingsAdvanced.h b/src/ui/settings/SettingsAdvanced.h
new file mode 100644
index 00000000..d8ec8089
--- /dev/null
+++ b/src/ui/settings/SettingsAdvanced.h
@@ -0,0 +1,54 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_SETTINGSADVANCED_H
+#define GPGFRONTEND_SETTINGSADVANCED_H
+
+#include "ui/GpgFrontendUI.h"
+
+namespace GpgFrontend::UI {
+class AdvancedTab : public QWidget {
+ Q_OBJECT
+
+ public:
+ explicit AdvancedTab(QWidget* parent = nullptr);
+
+ void setSettings();
+
+ void applySettings();
+
+ private:
+ QString appPath;
+ QSettings settings;
+
+ QCheckBox* steganoCheckBox;
+ QCheckBox* autoPubkeyExchangeCheckBox;
+
+ signals:
+
+ void signalRestartNeeded(bool needed);
+};
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_SETTINGSADVANCED_H
diff --git a/src/ui/settings/SettingsAppearance.cpp b/src/ui/settings/SettingsAppearance.cpp
index aeb7ed70..49dc349c 100644
--- a/src/ui/settings/SettingsAppearance.cpp
+++ b/src/ui/settings/SettingsAppearance.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -22,84 +22,85 @@
*
*/
-#include "ui/SettingsDialog.h"
-
-AppearanceTab::AppearanceTab(QWidget *parent)
-: QWidget(parent), appPath(qApp->applicationDirPath()),
-settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini",
- QSettings::IniFormat) {
- /*****************************************
- * Icon-Size-Box
- *****************************************/
- auto *iconSizeBox = new QGroupBox(tr("Iconsize"));
- iconSizeGroup = new QButtonGroup();
- iconSizeSmall = new QRadioButton(tr("small"));
- iconSizeMedium = new QRadioButton(tr("medium"));
- iconSizeLarge = new QRadioButton(tr("large"));
-
- iconSizeGroup->addButton(iconSizeSmall, 1);
- iconSizeGroup->addButton(iconSizeMedium, 2);
- iconSizeGroup->addButton(iconSizeLarge, 3);
-
- auto *iconSizeBoxLayout = new QHBoxLayout();
- iconSizeBoxLayout->addWidget(iconSizeSmall);
- iconSizeBoxLayout->addWidget(iconSizeMedium);
- iconSizeBoxLayout->addWidget(iconSizeLarge);
-
- iconSizeBox->setLayout(iconSizeBoxLayout);
-
- /*****************************************
- * Icon-Style-Box
- *****************************************/
- auto *iconStyleBox = new QGroupBox(tr("Iconstyle"));
- iconStyleGroup = new QButtonGroup();
- iconTextButton = new QRadioButton(tr("just text"));
- iconIconsButton = new QRadioButton(tr("just icons"));
- iconAllButton = new QRadioButton(tr("text and icons"));
-
- iconStyleGroup->addButton(iconTextButton, 1);
- iconStyleGroup->addButton(iconIconsButton, 2);
- iconStyleGroup->addButton(iconAllButton, 3);
-
- auto *iconStyleBoxLayout = new QHBoxLayout();
- iconStyleBoxLayout->addWidget(iconTextButton);
- iconStyleBoxLayout->addWidget(iconIconsButton);
- iconStyleBoxLayout->addWidget(iconAllButton);
-
- iconStyleBox->setLayout(iconStyleBoxLayout);
-
- /*****************************************
- * Window-Size-Box
- *****************************************/
- auto *windowSizeBox = new QGroupBox(tr("Windowstate"));
- auto *windowSizeBoxLayout = new QHBoxLayout();
- windowSizeCheckBox =
- new QCheckBox(tr("Save window size and position on exit."), this);
- windowSizeBoxLayout->addWidget(windowSizeCheckBox);
- windowSizeBox->setLayout(windowSizeBoxLayout);
-
- /*****************************************
- * Info-Board-Font-Size-Box
- *****************************************/
-
- auto *infoBoardBox = new QGroupBox(tr("Information Board"));
- auto *infoBoardLayout = new QHBoxLayout();
- infoBoardFontSizeSpin = new QSpinBox();
- infoBoardFontSizeSpin->setRange(9, 18);
- infoBoardFontSizeSpin->setValue(10);
- infoBoardFontSizeSpin->setSingleStep(1);
- infoBoardLayout->addWidget(new QLabel(tr(" Front Size")));
- infoBoardLayout->addWidget(infoBoardFontSizeSpin);
- infoBoardBox->setLayout(infoBoardLayout);
-
- auto *mainLayout = new QVBoxLayout;
- mainLayout->addWidget(iconSizeBox);
- mainLayout->addWidget(iconStyleBox);
- mainLayout->addWidget(windowSizeBox);
- mainLayout->addWidget(infoBoardBox);
- mainLayout->addStretch(1);
- setSettings();
- setLayout(mainLayout);
+#include "SettingsAppearance.h"
+
+#include "GlobalSettingStation.h"
+
+namespace GpgFrontend::UI {
+
+AppearanceTab::AppearanceTab(QWidget* parent) : QWidget(parent) {
+ /*****************************************
+ * Icon-Size-Box
+ *****************************************/
+ auto* iconSizeBox = new QGroupBox(_("Icon Size"));
+ iconSizeGroup = new QButtonGroup();
+ iconSizeSmall = new QRadioButton(_("small"));
+ iconSizeMedium = new QRadioButton(_("medium"));
+ iconSizeLarge = new QRadioButton(_("large"));
+
+ iconSizeGroup->addButton(iconSizeSmall, 1);
+ iconSizeGroup->addButton(iconSizeMedium, 2);
+ iconSizeGroup->addButton(iconSizeLarge, 3);
+
+ auto* iconSizeBoxLayout = new QHBoxLayout();
+ iconSizeBoxLayout->addWidget(iconSizeSmall);
+ iconSizeBoxLayout->addWidget(iconSizeMedium);
+ iconSizeBoxLayout->addWidget(iconSizeLarge);
+
+ iconSizeBox->setLayout(iconSizeBoxLayout);
+
+ /*****************************************
+ * Icon-Style-Box
+ *****************************************/
+ auto* iconStyleBox = new QGroupBox(_("Icon Style"));
+ iconStyleGroup = new QButtonGroup();
+ iconTextButton = new QRadioButton(_("just text"));
+ iconIconsButton = new QRadioButton(_("just icons"));
+ iconAllButton = new QRadioButton(_("text and icons"));
+
+ iconStyleGroup->addButton(iconTextButton, 1);
+ iconStyleGroup->addButton(iconIconsButton, 2);
+ iconStyleGroup->addButton(iconAllButton, 3);
+
+ auto* iconStyleBoxLayout = new QHBoxLayout();
+ iconStyleBoxLayout->addWidget(iconTextButton);
+ iconStyleBoxLayout->addWidget(iconIconsButton);
+ iconStyleBoxLayout->addWidget(iconAllButton);
+
+ iconStyleBox->setLayout(iconStyleBoxLayout);
+
+ /*****************************************
+ * Window-Size-Box
+ *****************************************/
+ auto* windowSizeBox = new QGroupBox(_("Window State"));
+ auto* windowSizeBoxLayout = new QHBoxLayout();
+ windowSizeCheckBox =
+ new QCheckBox(_("Save window size and position on exit."), this);
+ windowSizeBoxLayout->addWidget(windowSizeCheckBox);
+ windowSizeBox->setLayout(windowSizeBoxLayout);
+
+ /*****************************************
+ * Info-Board-Font-Size-Box
+ *****************************************/
+
+ auto* infoBoardBox = new QGroupBox(_("Information Board"));
+ auto* infoBoardLayout = new QHBoxLayout();
+ infoBoardFontSizeSpin = new QSpinBox();
+ infoBoardFontSizeSpin->setRange(9, 18);
+ infoBoardFontSizeSpin->setValue(10);
+ infoBoardFontSizeSpin->setSingleStep(1);
+ infoBoardLayout->addWidget(new QLabel(_("Font Size in Information Board")));
+ infoBoardLayout->addWidget(infoBoardFontSizeSpin);
+ infoBoardBox->setLayout(infoBoardLayout);
+
+ auto* mainLayout = new QVBoxLayout;
+ mainLayout->addWidget(iconSizeBox);
+ mainLayout->addWidget(iconStyleBox);
+ mainLayout->addWidget(windowSizeBox);
+ mainLayout->addWidget(infoBoardBox);
+ mainLayout->addStretch(1);
+ setSettings();
+ setLayout(mainLayout);
}
/**********************************
@@ -108,47 +109,70 @@ settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini",
* appropriately
**********************************/
void AppearanceTab::setSettings() {
-
- // Iconsize
- QSize iconSize = settings.value("toolbar/iconsize", QSize(24, 24)).toSize();
- switch (iconSize.height()) {
- case 12:
- iconSizeSmall->setChecked(true);
- break;
- case 24:
- iconSizeMedium->setChecked(true);
- break;
- case 32:
- iconSizeLarge->setChecked(true);
- break;
- }
- // Iconstyle
- Qt::ToolButtonStyle iconStyle = static_cast<Qt::ToolButtonStyle>(
- settings.value("toolbar/iconstyle", Qt::ToolButtonTextUnderIcon)
- .toUInt());
- switch (iconStyle) {
- case Qt::ToolButtonTextOnly:
- iconTextButton->setChecked(true);
- break;
- case Qt::ToolButtonIconOnly:
- iconIconsButton->setChecked(true);
- break;
- case Qt::ToolButtonTextUnderIcon:
- iconAllButton->setChecked(true);
- break;
- default:
- break;
+ auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
+
+ try {
+ int width = settings.lookup("window.icon_size.width");
+ int height = settings.lookup("window.icon_size.height");
+
+ auto icon_size = QSize(width, height);
+
+ switch (icon_size.height()) {
+ case 12:
+ iconSizeSmall->setChecked(true);
+ break;
+ case 24:
+ iconSizeMedium->setChecked(true);
+ break;
+ case 32:
+ iconSizeLarge->setChecked(true);
+ break;
}
- // Window Save and Position
- if (settings.value("window/windowSave").toBool())
- windowSizeCheckBox->setCheckState(Qt::Checked);
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("icon_size");
+ }
+
+ // icon_style
+ try {
+ int s_icon_style = settings.lookup("window.icon_style");
+ auto icon_style = static_cast<Qt::ToolButtonStyle>(s_icon_style);
+
+ switch (icon_style) {
+ case Qt::ToolButtonTextOnly:
+ iconTextButton->setChecked(true);
+ break;
+ case Qt::ToolButtonIconOnly:
+ iconIconsButton->setChecked(true);
+ break;
+ case Qt::ToolButtonTextUnderIcon:
+ iconAllButton->setChecked(true);
+ break;
+ default:
+ break;
+ }
- // infoBoardFontSize
- auto infoBoardFontSize = settings.value("informationBoard/fontSize", 10).toInt();
- if (infoBoardFontSize < 9 || infoBoardFontSize > 18)
- infoBoardFontSize = 10;
- infoBoardFontSizeSpin->setValue(infoBoardFontSize);
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("icon_style");
+ }
+
+ // Window Save and Position
+ try {
+ bool window_save = settings.lookup("window.window_save");
+ if (window_save) windowSizeCheckBox->setCheckState(Qt::Checked);
+
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("window_save");
+ }
+
+ // info board font size
+ try {
+ int info_font_size = settings.lookup("window.info_font_size");
+ if (info_font_size < 9 || info_font_size > 18) info_font_size = 10;
+ infoBoardFontSizeSpin->setValue(info_font_size);
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("info_font_size");
+ }
}
/***********************************
@@ -156,32 +180,70 @@ void AppearanceTab::setSettings() {
* write them to settings-file
*************************************/
void AppearanceTab::applySettings() {
- switch (iconSizeGroup->checkedId()) {
- case 1:
- settings.setValue("toolbar/iconsize", QSize(12, 12));
- break;
- case 2:
- settings.setValue("toolbar/iconsize", QSize(24, 24));
- break;
- case 3:
- settings.setValue("toolbar/iconsize", QSize(32, 32));
- break;
- }
-
- switch (iconStyleGroup->checkedId()) {
- case 1:
- settings.setValue("toolbar/iconstyle", Qt::ToolButtonTextOnly);
- break;
- case 2:
- settings.setValue("toolbar/iconstyle", Qt::ToolButtonIconOnly);
- break;
- case 3:
- settings.setValue("toolbar/iconstyle", Qt::ToolButtonTextUnderIcon);
- break;
- }
-
- settings.setValue("window/windowSave", windowSizeCheckBox->isChecked());
-
- settings.setValue("informationBoard/fontSize", infoBoardFontSizeSpin->value());
+ auto& settings =
+ GpgFrontend::UI::GlobalSettingStation::GetInstance().GetUISettings();
+
+ if (!settings.exists("window") ||
+ settings.lookup("window").getType() != libconfig::Setting::TypeGroup)
+ settings.add("window", libconfig::Setting::TypeGroup);
+
+ auto& window = settings["window"];
+
+ int icon_size = 24;
+ switch (iconSizeGroup->checkedId()) {
+ case 1:
+ icon_size = 12;
+ break;
+ case 2:
+ icon_size = 24;
+ break;
+ case 3:
+ icon_size = 32;
+ break;
+ }
+
+ if (!window.exists("icon_size")) {
+ auto& icon_size_settings =
+ window.add("icon_size", libconfig::Setting::TypeGroup);
+ icon_size_settings.add("width", libconfig::Setting::TypeInt) = icon_size;
+ icon_size_settings.add("height", libconfig::Setting::TypeInt) = icon_size;
+ } else {
+ window["icon_size"]["width"] = icon_size;
+ window["icon_size"]["height"] = icon_size;
+ }
+
+ auto icon_style = Qt::ToolButtonTextUnderIcon;
+ switch (iconStyleGroup->checkedId()) {
+ case 1:
+ icon_style = Qt::ToolButtonTextOnly;
+ break;
+ case 2:
+ icon_style = Qt::ToolButtonIconOnly;
+ break;
+ case 3:
+ icon_style = Qt::ToolButtonTextUnderIcon;
+ break;
+ }
+
+ if (!window.exists("icon_style")) {
+ window.add("icon_style", libconfig::Setting::TypeInt) = icon_style;
+ } else {
+ window["icon_style"] = icon_style;
+ }
+
+ if (!window.exists("window_save")) {
+ window.add("window_save", libconfig::Setting::TypeBoolean) =
+ windowSizeCheckBox->isChecked();
+ } else {
+ window["window_save"] = windowSizeCheckBox->isChecked();
+ }
+
+ if (!window.exists("info_font_size")) {
+ window.add("info_font_size", libconfig::Setting::TypeBoolean) =
+ infoBoardFontSizeSpin->value();
+ } else {
+ window["info_font_size"] = infoBoardFontSizeSpin->value();
+ }
}
+} // namespace GpgFrontend::UI
diff --git a/src/ui/settings/SettingsAppearance.h b/src/ui/settings/SettingsAppearance.h
new file mode 100644
index 00000000..c0a0247b
--- /dev/null
+++ b/src/ui/settings/SettingsAppearance.h
@@ -0,0 +1,61 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_SETTINGSAPPEARANCE_H
+#define GPGFRONTEND_SETTINGSAPPEARANCE_H
+
+#include "ui/GpgFrontendUI.h"
+
+namespace GpgFrontend::UI {
+
+class AppearanceTab : public QWidget {
+ Q_OBJECT
+
+ public:
+ explicit AppearanceTab(QWidget* parent = nullptr);
+
+ void setSettings();
+
+ void applySettings();
+
+ private:
+ QButtonGroup* iconStyleGroup;
+ QRadioButton* iconSizeSmall;
+ QRadioButton* iconSizeMedium;
+ QRadioButton* iconSizeLarge;
+ QButtonGroup* iconSizeGroup;
+ QRadioButton* iconTextButton;
+ QRadioButton* iconIconsButton;
+ QRadioButton* iconAllButton;
+ QSpinBox* infoBoardFontSizeSpin;
+ QCheckBox* windowSizeCheckBox;
+
+ signals:
+
+ void signalRestartNeeded(bool needed);
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_SETTINGSAPPEARANCE_H
diff --git a/src/ui/settings/SettingsDialog.cpp b/src/ui/settings/SettingsDialog.cpp
index 0ca188f7..fcef70c7 100644
--- a/src/ui/settings/SettingsDialog.cpp
+++ b/src/ui/settings/SettingsDialog.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -22,184 +22,136 @@
*
*/
-#include "ui/SettingsDialog.h"
-#include "ui/WaitingDialog.h"
-
-SettingsDialog::SettingsDialog(GpgME::GpgContext *ctx, QWidget *parent)
- : QDialog(parent) {
- mCtx = ctx;
- tabWidget = new QTabWidget;
- generalTab = new GeneralTab(mCtx);
- appearanceTab = new AppearanceTab;
- sendMailTab = new SendMailTab;
- keyserverTab = new KeyserverTab;
- advancedTab = new AdvancedTab;
- gpgPathsTab = new GpgPathsTab;
-
- tabWidget->addTab(generalTab, tr("General"));
- tabWidget->addTab(appearanceTab, tr("Appearance"));
- tabWidget->addTab(sendMailTab, tr("Send Mail"));
- tabWidget->addTab(keyserverTab, tr("Key Server"));
- // tabWidget->addTab(gpgPathsTab, tr("Gpg paths"));
- tabWidget->addTab(advancedTab, tr("Advanced"));
-
- buttonBox =
- new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
-
- connect(buttonBox, SIGNAL(accepted()), this, SLOT(slotAccept()));
- connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
-
- auto *mainLayout = new QVBoxLayout;
- mainLayout->addWidget(tabWidget);
- mainLayout->stretch(0);
- mainLayout->addWidget(buttonBox);
- mainLayout->stretch(0);
- setLayout(mainLayout);
-
- setWindowTitle(tr("Settings"));
-
- // slots for handling the restartneeded member
- this->slotSetRestartNeeded(false);
- connect(generalTab, SIGNAL(signalRestartNeeded(bool)), this,
- SLOT(slotSetRestartNeeded(bool)));
- connect(appearanceTab, SIGNAL(signalRestartNeeded(bool)), this,
- SLOT(slotSetRestartNeeded(bool)));
- connect(sendMailTab, SIGNAL(signalRestartNeeded(bool)), this,
- SLOT(slotSetRestartNeeded(bool)));
- connect(keyserverTab, SIGNAL(signalRestartNeeded(bool)), this,
- SLOT(slotSetRestartNeeded(bool)));
- connect(advancedTab, SIGNAL(signalRestartNeeded(bool)), this,
- SLOT(slotSetRestartNeeded(bool)));
-
- connect(this, SIGNAL(signalRestartNeeded(bool)), parent,
- SLOT(slotSetRestartNeeded(bool)));
-
- this->resize(480, 640);
- this->show();
-}
+#include "SettingsDialog.h"
-bool SettingsDialog::getRestartNeeded() const { return this->restartNeeded; }
+#include "GlobalSettingStation.h"
+#include "SettingsAdvanced.h"
+#include "SettingsAppearance.h"
+#include "SettingsGeneral.h"
+#include "SettingsKeyServer.h"
-void SettingsDialog::slotSetRestartNeeded(bool needed) {
- this->restartNeeded = needed;
-}
+#ifdef SMTP_SUPPORT
+#include "SettingsSendMail.h"
+#endif
-void SettingsDialog::slotAccept() {
- generalTab->applySettings();
- sendMailTab->applySettings();
- appearanceTab->applySettings();
- keyserverTab->applySettings();
- advancedTab->applySettings();
- gpgPathsTab->applySettings();
- if (getRestartNeeded()) {
- emit signalRestartNeeded(true);
- }
- close();
-}
+namespace GpgFrontend::UI {
-// http://www.informit.com/articles/article.aspx?p=1405555&seqNum=3
-// http://developer.qt.nokia.com/wiki/How_to_create_a_multi_language_application
-QHash<QString, QString> SettingsDialog::listLanguages() {
- QHash<QString, QString> languages;
+SettingsDialog::SettingsDialog(QWidget* parent) : QDialog(parent) {
+ tabWidget = new QTabWidget;
+ generalTab = new GeneralTab();
+ appearanceTab = new AppearanceTab;
+#ifdef SMTP_SUPPORT
+ sendMailTab = new SendMailTab;
+#endif
+ keyserverTab = new KeyserverTab;
+#ifdef ADVANCED_SUPPORT
+ advancedTab = new AdvancedTab;
+#endif
- languages.insert("", tr("System Default"));
+ tabWidget->addTab(generalTab, _("General"));
+ tabWidget->addTab(appearanceTab, _("Appearance"));
+#ifdef SMTP_SUPPORT
+ tabWidget->addTab(sendMailTab, _("Send Mail"));
+#endif
+ tabWidget->addTab(keyserverTab, _("Key Server"));
+ // tabWidget->addTab(gpgPathsTab, _("Gpg paths"));
+#ifdef ADVANCED_SUPPORT
+ tabWidget->addTab(advancedTab, _("Advanced"));
+#endif
- QString appPath = qApp->applicationDirPath();
- QDir qmDir = QDir(RESOURCE_DIR(appPath) + "/ts/");
- QStringList fileNames = qmDir.entryList(QStringList("gpgfrontend_*.qm"));
+ buttonBox =
+ new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+
+ connect(buttonBox, SIGNAL(accepted()), this, SLOT(slotAccept()));
+ connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+
+ auto* mainLayout = new QVBoxLayout;
+ mainLayout->addWidget(tabWidget);
+ mainLayout->stretch(0);
+ mainLayout->addWidget(buttonBox);
+ mainLayout->stretch(0);
+ setLayout(mainLayout);
+
+ setWindowTitle(_("Settings"));
+
+ // slots for handling the restartneeded member
+ this->slotSetRestartNeeded(false);
+ connect(generalTab, SIGNAL(signalRestartNeeded(bool)), this,
+ SLOT(slotSetRestartNeeded(bool)));
+ connect(appearanceTab, SIGNAL(signalRestartNeeded(bool)), this,
+ SLOT(slotSetRestartNeeded(bool)));
+#ifdef SMTP_SUPPORT
+ connect(sendMailTab, SIGNAL(signalRestartNeeded(bool)), this,
+ SLOT(slotSetRestartNeeded(bool)));
+#endif
+ connect(keyserverTab, SIGNAL(signalRestartNeeded(bool)), this,
+ SLOT(slotSetRestartNeeded(bool)));
+#ifdef ADVANCED_SUPPORT
+ connect(advancedTab, SIGNAL(signalRestartNeeded(bool)), this,
+ SLOT(slotSetRestartNeeded(bool)));
+#endif
- for (int i = 0; i < fileNames.size(); ++i) {
- QString locale = fileNames[i];
- locale.truncate(locale.lastIndexOf('.'));
- locale.remove(0, locale.indexOf('_') + 1);
+ connect(this, SIGNAL(signalRestartNeeded(bool)), parent,
+ SLOT(slotSetRestartNeeded(bool)));
- // this works in qt 4.8
- QLocale qloc(locale);
-#if QT_VERSION < 0x040800
- QString language =
- QLocale::languageToString(qloc.language()) + " (" + locale +
- ")"; //+ " (" + QLocale::languageToString(qloc.language()) + ")";
-#else
- QString language = qloc.nativeLanguageName() + " (" + locale + ")";
-#endif
- languages.insert(locale, language);
- }
- return languages;
+ this->resize(480, 640);
+ this->show();
}
-GpgPathsTab::GpgPathsTab(QWidget *parent)
- : QWidget(parent), appPath(qApp->applicationDirPath()),
- settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini",
- QSettings::IniFormat) {
- setSettings();
-
- /*****************************************
- * Keydb Box
- *****************************************/
- auto *keydbBox = new QGroupBox(tr("Relative path to keydb"));
- auto *keydbBoxLayout = new QGridLayout();
-
- // Label containing the current keydbpath relative to default keydb path
- keydbLabel = new QLabel(accKeydbPath, this);
-
- auto *keydbButton = new QPushButton("Change keydb path", this);
- connect(keydbButton, SIGNAL(clicked()), this, SLOT(chooseKeydbDir()));
- auto *keydbDefaultButton = new QPushButton("Set keydb to default path", this);
- connect(keydbDefaultButton, SIGNAL(clicked()), this,
- SLOT(setKeydbPathToDefault()));
-
- keydbBox->setLayout(keydbBoxLayout);
- keydbBoxLayout->addWidget(new QLabel(tr("Current keydb path: ")), 1, 1);
- keydbBoxLayout->addWidget(keydbLabel, 1, 2);
- keydbBoxLayout->addWidget(keydbButton, 1, 3);
- keydbBoxLayout->addWidget(keydbDefaultButton, 2, 3);
- keydbBoxLayout->addWidget(
- new QLabel(tr("<b>NOTE: </b> Gpg4usb will restart automatically if you "
- "change the keydb path!")),
- 3, 1, 1, 3);
-
- auto *mainLayout = new QVBoxLayout;
- mainLayout->addWidget(keydbBox);
- mainLayout->addStretch(1);
- setLayout(mainLayout);
+bool SettingsDialog::getRestartNeeded() const { return this->restartNeeded; }
+
+void SettingsDialog::slotSetRestartNeeded(bool needed) {
+ this->restartNeeded = needed;
}
-QString GpgPathsTab::getRelativePath(const QString &dir1, const QString &dir2) {
- QDir dir(dir1);
- QString s;
+void SettingsDialog::slotAccept() {
+ generalTab->applySettings();
+#ifdef SMTP_SUPPORT
+ sendMailTab->applySettings();
+#endif
+ appearanceTab->applySettings();
+ keyserverTab->applySettings();
+#ifdef ADVANCED_SUPPORT
+ advancedTab->applySettings();
+#endif
- s = dir.relativeFilePath(dir2);
- qDebug() << "relative path: " << s;
- if (s.isEmpty()) {
- s = ".";
- }
- return s;
-}
+ // write settings to filesystem
+ GlobalSettingStation::GetInstance().Sync();
-void GpgPathsTab::setKeydbPathToDefault() {
- accKeydbPath = ".";
- keydbLabel->setText(".");
+ if (getRestartNeeded()) {
+ emit signalRestartNeeded(true);
+ }
+ close();
}
-QString GpgPathsTab::chooseKeydbDir() {
- QString dir = QFileDialog::getExistingDirectory(
- this, tr("Choose keydb directory"), accKeydbPath,
- QFileDialog::ShowDirsOnly);
+QHash<QString, QString> SettingsDialog::listLanguages() {
+ QHash<QString, QString> languages;
- accKeydbPath = getRelativePath(defKeydbPath, dir);
- keydbLabel->setText(accKeydbPath);
- return "";
-}
+ languages.insert(QString(), _("System Default"));
-void GpgPathsTab::setSettings() {
- defKeydbPath = qApp->applicationDirPath() + "/keydb";
+ auto locale_path = GlobalSettingStation::GetInstance().GetLocaleDir();
- accKeydbPath = settings.value("gpgpaths/keydbpath").toString();
- if (accKeydbPath.isEmpty()) {
- accKeydbPath = ".";
- }
-}
+ auto locale_dir = QDir(QString::fromStdString(locale_path.string()) );
+ QStringList file_names = locale_dir.entryList(QStringList("*"));
+
+ for (int i = 0; i < file_names.size(); ++i) {
+ QString locale = file_names[i];
+ LOG(INFO) << "locale" << locale.toStdString();
+ if (locale == "." || locale == "..") continue;
-void GpgPathsTab::applySettings() {
- settings.setValue("gpgpaths/keydbpath", accKeydbPath);
+ // this works in qt 4.8
+ QLocale q_locale(locale);
+ if (q_locale.nativeCountryName().isEmpty()) continue;
+#if QT_VERSION < 0x040800
+ QString language =
+ QLocale::languageToString(q_locale.language()) + " (" + locale +
+ ")"; //+ " (" + QLocale::languageToString(q_locale.language()) + ")";
+#else
+ auto language = q_locale.nativeLanguageName() + " (" + locale + ")";
+#endif
+ languages.insert(locale, language);
+ }
+ return languages;
}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/settings/SettingsDialog.h b/src/ui/settings/SettingsDialog.h
new file mode 100755
index 00000000..b8277906
--- /dev/null
+++ b/src/ui/settings/SettingsDialog.h
@@ -0,0 +1,86 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef __SETTINGSDIALOG_H__
+#define __SETTINGSDIALOG_H__
+
+#include "ui/GpgFrontendUI.h"
+#include "ui/widgets/KeyList.h"
+
+namespace GpgFrontend::UI {
+
+class GeneralTab;
+
+#ifdef SMTP_SUPPORT
+class SendMailTab;
+#endif
+
+class AppearanceTab;
+class KeyserverTab;
+
+#ifdef ADVANCED_SUPPORT
+class AdvancedTab;
+#endif
+
+class SettingsDialog : public QDialog {
+ Q_OBJECT
+
+ public:
+ explicit SettingsDialog(QWidget* parent = nullptr);
+
+ GeneralTab* generalTab;
+#ifdef SMTP_SUPPORT
+ SendMailTab* sendMailTab;
+#endif
+ AppearanceTab* appearanceTab;
+ KeyserverTab* keyserverTab;
+#ifdef ADVANCED_SUPPORT
+ AdvancedTab* advancedTab;
+#endif
+
+ static QHash<QString, QString> listLanguages();
+
+ public slots:
+
+ void slotAccept();
+
+ signals:
+
+ void signalRestartNeeded(bool needed);
+
+ private:
+ QTabWidget* tabWidget;
+ QDialogButtonBox* buttonBox;
+ bool restartNeeded{};
+
+ bool getRestartNeeded() const;
+
+ private slots:
+
+ void slotSetRestartNeeded(bool needed);
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // __SETTINGSDIALOG_H__
diff --git a/src/ui/settings/SettingsGeneral.cpp b/src/ui/settings/SettingsGeneral.cpp
index bec66154..98610e12 100644
--- a/src/ui/settings/SettingsGeneral.cpp
+++ b/src/ui/settings/SettingsGeneral.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -22,122 +22,145 @@
*
*/
-#include "ui/SettingsDialog.h"
-#include "ui/WaitingDialog.h"
+#include "SettingsGeneral.h"
+
+#ifdef SERVER_SUPPORT
#include "server/ComUtils.h"
+#endif
-#include "rapidjson/prettywriter.h"
+#ifdef MULTI_LANG_SUPPORT
+#include "SettingsDialog.h"
+#endif
-GeneralTab::GeneralTab(GpgME::GpgContext *ctx, QWidget *parent)
- : QWidget(parent), appPath(qApp->applicationDirPath()),
- settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini",
- QSettings::IniFormat) {
- mCtx = ctx;
-
- /*****************************************
- * GpgFrontend Server
- *****************************************/
- auto *serverBox = new QGroupBox(tr("GpgFrontend Server"));
- auto *serverBoxLayout = new QVBoxLayout();
- serverSelectBox = new QComboBox();
- serverBoxLayout->addWidget(serverSelectBox);
- serverBoxLayout->addWidget(new QLabel(
- tr("Server that provides short key and key exchange services")));
-
- serverBox->setLayout(serverBoxLayout);
-
- /*****************************************
- * Save-Checked-Keys-Box
- *****************************************/
- auto *saveCheckedKeysBox = new QGroupBox(tr("Save Checked Keys"));
- auto *saveCheckedKeysBoxLayout = new QHBoxLayout();
- saveCheckedKeysCheckBox = new QCheckBox(
- tr("Save checked private keys on exit and restore them on next start."),
- this);
- saveCheckedKeysBoxLayout->addWidget(saveCheckedKeysCheckBox);
- saveCheckedKeysBox->setLayout(saveCheckedKeysBoxLayout);
-
- /*****************************************
- * Key-Impport-Confirmation Box
- *****************************************/
- auto *importConfirmationBox =
- new QGroupBox(tr("Confirm drag'n'drop key import"));
- auto *importConfirmationBoxLayout = new QHBoxLayout();
- importConfirmationCheckBox = new QCheckBox(
- tr("Import files dropped on the keylist without confirmation."), this);
- importConfirmationBoxLayout->addWidget(importConfirmationCheckBox);
- importConfirmationBox->setLayout(importConfirmationBoxLayout);
-
- /*****************************************
- * Language Select Box
- *****************************************/
- auto *langBox = new QGroupBox(tr("Language"));
- auto *langBoxLayout = new QVBoxLayout();
- langSelectBox = new QComboBox;
- lang = SettingsDialog::listLanguages();
-
- for (const auto &l: lang) { langSelectBox->addItem(l); }
-
- langBoxLayout->addWidget(langSelectBox);
- langBoxLayout->addWidget(
- new QLabel(tr("<b>NOTE: </b> GpgFrontend will restart automatically if "
- "you change the language!")));
- langBox->setLayout(langBoxLayout);
- connect(langSelectBox, SIGNAL(currentIndexChanged(int)), this,
- SLOT(slotLanguageChanged()));
-
- /*****************************************
- * Own Key Select Box
- *****************************************/
- auto *ownKeyBox = new QGroupBox(tr("Own key"));
- auto *ownKeyBoxLayout = new QVBoxLayout();
- auto *ownKeyServiceTokenLayout = new QHBoxLayout();
- ownKeySelectBox = new QComboBox;
- getServiceTokenButton = new QPushButton(tr("Get Service Token"));
- serviceTokenLabel = new QLabel(tr("No Service Token Found"));
- serviceTokenLabel->setAlignment(Qt::AlignCenter);
-
- ownKeyBox->setLayout(ownKeyBoxLayout);
- mKeyList = new KeyList(mCtx);
-
- // Fill the keyid hashmap
- keyIds.insert("", tr("<none>"));
-
- for (const auto &keyid : *mKeyList->getAllPrivateKeys()) {
- auto key = mCtx->getKeyById(keyid);
- if (!key.good) continue;
- keyIds.insert(key.id, key.uids.first().uid);
- }
- for (const auto &k : keyIds.keys()) {
- ownKeySelectBox->addItem(keyIds.find(k).value());
- keyIdsList.append(k);
- }
- connect(ownKeySelectBox, SIGNAL(currentIndexChanged(int)), this,
- SLOT(slotOwnKeyIdChanged()));
- connect(getServiceTokenButton, SIGNAL(clicked(bool)), this,
- SLOT(slotGetServiceToken()));
-
- ownKeyBoxLayout->addWidget(new QLabel(
- tr("Key pair for synchronization and identity authentication")));
- ownKeyBoxLayout->addWidget(ownKeySelectBox);
- ownKeyBoxLayout->addLayout(ownKeyServiceTokenLayout);
- ownKeyServiceTokenLayout->addWidget(getServiceTokenButton);
- ownKeyServiceTokenLayout->addWidget(serviceTokenLabel);
- ownKeyServiceTokenLayout->stretch(0);
-
- /*****************************************
- * Mainlayout
- *****************************************/
- auto *mainLayout = new QVBoxLayout;
- mainLayout->addWidget(serverBox);
- mainLayout->addWidget(saveCheckedKeysBox);
- mainLayout->addWidget(importConfirmationBox);
- mainLayout->addWidget(langBox);
- mainLayout->addWidget(ownKeyBox);
-
- setSettings();
- mainLayout->addStretch(1);
- setLayout(mainLayout);
+#include "GlobalSettingStation.h"
+#include "gpg/function/GpgKeyGetter.h"
+#include "rapidjson/prettywriter.h"
+#include "ui/widgets/KeyList.h"
+
+namespace GpgFrontend::UI {
+
+GeneralTab::GeneralTab(QWidget* parent) : QWidget(parent) {
+#ifdef SERVER_SUPPORT
+ /*****************************************
+ * GpgFrontend Server
+ *****************************************/
+ auto* serverBox = new QGroupBox(_("GpgFrontend Server"));
+ auto* serverBoxLayout = new QVBoxLayout();
+ serverSelectBox = new QComboBox();
+ serverBoxLayout->addWidget(serverSelectBox);
+ serverBoxLayout->addWidget(new QLabel(
+ _("Server that provides short key and key exchange services")));
+
+ serverBox->setLayout(serverBoxLayout);
+#endif
+
+ /*****************************************
+ * Save-Checked-Keys-Box
+ *****************************************/
+ auto* saveCheckedKeysBox = new QGroupBox(_("Save Checked Keys"));
+ auto* saveCheckedKeysBoxLayout = new QHBoxLayout();
+ saveCheckedKeysCheckBox = new QCheckBox(
+ _("Save checked private keys on exit and restore them on next start."),
+ this);
+ saveCheckedKeysBoxLayout->addWidget(saveCheckedKeysCheckBox);
+ saveCheckedKeysBox->setLayout(saveCheckedKeysBoxLayout);
+
+ /*****************************************
+ * Key-Impport-Confirmation Box
+ *****************************************/
+ auto* importConfirmationBox =
+ new QGroupBox(_("Confirm drag'n'drop key import"));
+ auto* importConfirmationBoxLayout = new QHBoxLayout();
+ importConfirmationCheckBox = new QCheckBox(
+ _("Import files dropped on the Key List without confirmation."), this);
+ importConfirmationBoxLayout->addWidget(importConfirmationCheckBox);
+ importConfirmationBox->setLayout(importConfirmationBoxLayout);
+
+#ifdef MULTI_LANG_SUPPORT
+ /*****************************************
+ * Language Select Box
+ *****************************************/
+ auto* langBox = new QGroupBox(_("Language"));
+ auto* langBoxLayout = new QVBoxLayout();
+ langSelectBox = new QComboBox;
+ lang = SettingsDialog::listLanguages();
+
+ for (const auto& l : lang) {
+ langSelectBox->addItem(l);
+ }
+
+ langBoxLayout->addWidget(langSelectBox);
+ langBoxLayout->addWidget(new QLabel(
+ "<b>" + QString(_("NOTE")) + _(": ") + "</b>" +
+ _("GpgFrontend will restart automatically if you change the language!")));
+ langBox->setLayout(langBoxLayout);
+ connect(langSelectBox, SIGNAL(currentIndexChanged(int)), this,
+ SLOT(slotLanguageChanged()));
+#endif
+
+#ifdef SERVER_SUPPORT
+ /*****************************************
+ * Own Key Select Box
+ *****************************************/
+ auto* ownKeyBox = new QGroupBox(_("Own key"));
+ auto* ownKeyBoxLayout = new QVBoxLayout();
+ auto* ownKeyServiceTokenLayout = new QHBoxLayout();
+ ownKeySelectBox = new QComboBox;
+ getServiceTokenButton = new QPushButton(_("Get Service Token"));
+ serviceTokenLabel = new QLabel(_("No Service Token Found"));
+ serviceTokenLabel->setAlignment(Qt::AlignCenter);
+
+ ownKeyBox->setLayout(ownKeyBoxLayout);
+
+ mKeyList = new KeyList();
+
+ // Fill the keyid hashmap
+ keyIds.insert({QString(), "<none>"});
+
+ auto private_keys = mKeyList->getAllPrivateKeys();
+
+ for (const auto& keyid : *private_keys) {
+ auto key = GpgKeyGetter::GetInstance().GetKey(keyid);
+ if (!key.good()) continue;
+ keyIds.insert({key.id(), key.uids()->front().uid()});
+ }
+ for (const auto& k : keyIds) {
+ ownKeySelectBox->addItem(QString::fromStdString(k.second));
+ keyIdsList.push_back(k.first);
+ }
+ connect(ownKeySelectBox, SIGNAL(currentIndexChanged(int)), this,
+ SLOT(slotOwnKeyIdChanged()));
+ connect(getServiceTokenButton, SIGNAL(clicked(bool)), this,
+ SLOT(slotGetServiceToken()));
+
+ ownKeyBoxLayout->addWidget(new QLabel(
+ _("Key pair for synchronization and identity authentication")));
+ ownKeyBoxLayout->addWidget(ownKeySelectBox);
+ ownKeyBoxLayout->addLayout(ownKeyServiceTokenLayout);
+ ownKeyServiceTokenLayout->addWidget(getServiceTokenButton);
+ ownKeyServiceTokenLayout->addWidget(serviceTokenLabel);
+ ownKeyServiceTokenLayout->stretch(0);
+#endif
+
+ /*****************************************
+ * Mainlayout
+ *****************************************/
+ auto* mainLayout = new QVBoxLayout;
+#ifdef SERVER_SUPPORT
+ mainLayout->addWidget(serverBox);
+#endif
+ mainLayout->addWidget(saveCheckedKeysBox);
+ mainLayout->addWidget(importConfirmationBox);
+#ifdef MULTI_LANG_SUPPORT
+ mainLayout->addWidget(langBox);
+#endif
+#ifdef SERVER_SUPPORT
+ mainLayout->addWidget(ownKeyBox);
+#endif
+
+ setSettings();
+ mainLayout->addStretch(1);
+ setLayout(mainLayout);
}
/**********************************
@@ -146,55 +169,76 @@ GeneralTab::GeneralTab(GpgME::GpgContext *ctx, QWidget *parent)
* appropriately
**********************************/
void GeneralTab::setSettings() {
- // Keysaving
- if (settings.value("keys/saveKeyChecked").toBool()) {
- saveCheckedKeysCheckBox->setCheckState(Qt::Checked);
- }
-
- auto serverList = settings.value("general/gpgfrontendServerList").toStringList();
- if (serverList.empty()) {
- serverList.append("service.gpgfrontend.pub");
- serverList.append("localhost");
- }
- for (const auto &s : serverList)
- serverSelectBox->addItem(s);
-
- qDebug() << "Current Gpgfrontend Server" << settings.value("general/currentGpgfrontendServer").toString();
- serverSelectBox->setCurrentText(settings.value("general/currentGpgfrontendServer",
- "service.gpgfrontend.pub").toString());
-
- connect(serverSelectBox, QOverload<const QString &>::of(&QComboBox::currentTextChanged),
- this, [&](const QString &current) -> void {
- settings.setValue("general/currentGpgfrontendServer", current);
- });
-
- // Language setting
- QString langKey = settings.value("int/lang").toString();
- QString langValue = lang.value(langKey);
- if (langKey != "") {
- langSelectBox->setCurrentIndex(langSelectBox->findText(langValue));
- }
-
- QString own_key_id = settings.value("general/ownKeyId").toString();
- qDebug() << "OwnKeyId" << own_key_id;
- if (own_key_id.isEmpty()) {
- ownKeySelectBox->setCurrentText("<none>");
+ auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
+ try {
+ bool save_key_checked = settings.lookup("general.save_key_checked");
+ if (save_key_checked) saveCheckedKeysCheckBox->setCheckState(Qt::Checked);
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("save_key_checked");
+ }
+
+#ifdef SERVER_SUPPORT
+ auto serverList =
+ settings.value("general/gpgfrontendServerList").toStringList();
+ if (serverList.empty()) {
+ serverList.append("service.gpgfrontend.pub");
+ serverList.append("localhost");
+ }
+ for (const auto& s : serverList) serverSelectBox->addItem(s);
+
+ qDebug() << "Current Gpgfrontend Server"
+ << settings.value("general/currentGpgfrontendServer").toString();
+ serverSelectBox->setCurrentText(
+ settings
+ .value("general/currentGpgfrontendServer", "service.gpgfrontend.pub")
+ .toString());
+
+ connect(serverSelectBox,
+ QOverload<const QString&>::of(&QComboBox::currentTextChanged), this,
+ [&](const QString& current) -> void {
+ settings.setValue("general/currentGpgfrontendServer", current);
+ });
+#endif
+
+#ifdef MULTI_LANG_SUPPORT
+ try {
+ std::string lang_key = settings.lookup("general.lang");
+ QString lang_value = lang.value(lang_key.c_str());
+ LOG(INFO) << "lang settings current" << lang_value.toStdString();
+ if (!lang.empty()) {
+ langSelectBox->setCurrentIndex(langSelectBox->findText(lang_value));
} else {
- const auto text = keyIds.find(own_key_id).value();
- qDebug() << "OwnKey" << own_key_id << text;
- ownKeySelectBox->setCurrentText(text);
- }
-
- serviceToken = settings.value("general/serviceToken").toString();
- qDebug() << "Load Service Token" << serviceToken;
- if (!serviceToken.isEmpty()) {
- serviceTokenLabel->setText(serviceToken);
- }
-
- // Get own key information from keydb/gpg.conf (if contained)
- if (settings.value("general/confirmImportKeys", Qt::Checked).toBool()) {
- importConfirmationCheckBox->setCheckState(Qt::Checked);
+ langSelectBox->setCurrentIndex(0);
}
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("lang");
+ }
+#endif
+
+#ifdef SERVER_SUPPORT
+ auto own_key_id = settings.value("general/ownKeyId").toString().toStdString();
+ if (own_key_id.empty()) {
+ ownKeySelectBox->setCurrentText("<none>");
+ } else {
+ const auto uid = keyIds.find(own_key_id)->second;
+ ownKeySelectBox->setCurrentText(QString::fromStdString(uid));
+ }
+
+ serviceToken =
+ settings.value("general/serviceToken").toString().toStdString();
+ if (!serviceToken.empty()) {
+ serviceTokenLabel->setText(QString::fromStdString(serviceToken));
+ }
+#endif
+
+ try {
+ bool confirm_import_keys = settings.lookup("general.confirm_import_keys");
+ LOG(INFO) << "confirm_import_keys" << confirm_import_keys;
+ if (confirm_import_keys)
+ importConfirmationCheckBox->setCheckState(Qt::Checked);
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("confirm_import_keys");
+ }
}
/***********************************
@@ -202,157 +246,194 @@ void GeneralTab::setSettings() {
* write them to settings-file
*************************************/
void GeneralTab::applySettings() {
- settings.setValue("keys/saveKeyChecked",
- saveCheckedKeysCheckBox->isChecked());
-
- qDebug() << "serverSelectBox currentText" << serverSelectBox->currentText();
- settings.setValue("general/currentGpgfrontendServer",
- serverSelectBox->currentText());
-
- auto *serverList = new QStringList();
- for (int i = 0; i < serverSelectBox->count(); i++)
- serverList->append(serverSelectBox->itemText(i));
- settings.setValue("general/gpgfrontendServerList",
- *serverList);
- delete serverList;
-
- settings.setValue("int/lang", lang.key(langSelectBox->currentText()));
-
- settings.setValue("general/ownKeyId",
- keyIdsList[ownKeySelectBox->currentIndex()]);
-
- settings.setValue("general/serviceToken",
- serviceToken);
-
- settings.setValue("general/confirmImportKeys",
- importConfirmationCheckBox->isChecked());
+ auto& settings =
+ GpgFrontend::UI::GlobalSettingStation::GetInstance().GetUISettings();
+
+ if (!settings.exists("general") ||
+ settings.lookup("general").getType() != libconfig::Setting::TypeGroup)
+ settings.add("general", libconfig::Setting::TypeGroup);
+
+ auto& general = settings["general"];
+
+ if (!general.exists("save_key_checked"))
+ general.add("save_key_checked", libconfig::Setting::TypeBoolean) =
+ saveCheckedKeysCheckBox->isChecked();
+ else {
+ general["save_key_checked"] = saveCheckedKeysCheckBox->isChecked();
+ }
+
+#ifdef SERVER_SUPPORT
+ qDebug() << "serverSelectBox currentText" << serverSelectBox->currentText();
+ settings.setValue("general/currentGpgfrontendServer",
+ serverSelectBox->currentText());
+
+ auto* serverList = new QStringList();
+ for (int i = 0; i < serverSelectBox->count(); i++)
+ serverList->append(serverSelectBox->itemText(i));
+ settings.setValue("general/gpgfrontendServerList", *serverList);
+ delete serverList;
+#endif
+
+#ifdef MULTI_LANG_SUPPORT
+ if (!general.exists("lang"))
+ general.add("lang", libconfig::Setting::TypeBoolean) =
+ lang.key(langSelectBox->currentText()).toStdString();
+ else {
+ general["lang"] = lang.key(langSelectBox->currentText()).toStdString();
+ }
+#endif
+
+#ifdef SERVER_SUPPORT
+ settings.setValue(
+ "general/ownKeyId",
+ QString::fromStdString(keyIdsList[ownKeySelectBox->currentIndex()]));
+
+ settings.setValue("general/serviceToken",
+ QString::fromStdString(serviceToken));
+#endif
+
+ if (!general.exists("confirm_import_keys"))
+ general.add("confirm_import_keys", libconfig::Setting::TypeBoolean) =
+ importConfirmationCheckBox->isChecked();
+ else {
+ general["confirm_import_keys"] = importConfirmationCheckBox->isChecked();
+ }
}
+#ifdef MULTI_LANG_SUPPORT
void GeneralTab::slotLanguageChanged() { emit signalRestartNeeded(true); }
+#endif
+#ifdef SERVER_SUPPORT
void GeneralTab::slotOwnKeyIdChanged() {
- // Set ownKeyId to currently selected
- this->serviceTokenLabel->setText(tr("No Service Token Found"));
- serviceToken.clear();
+ // Set ownKeyId to currently selected
+ this->serviceTokenLabel->setText(_("No Service Token Found"));
+ serviceToken.clear();
}
+#endif
+#ifdef SERVER_SUPPORT
void GeneralTab::slotGetServiceToken() {
+ auto utils = new ComUtils(this);
- auto utils = new ComUtils(this);
+ QUrl reqUrl(utils->getUrl(ComUtils::GetServiceToken));
+ QNetworkRequest request(reqUrl);
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
- QUrl reqUrl(utils->getUrl(ComUtils::GetServiceToken));
- QNetworkRequest request(reqUrl);
- request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
+ const auto keyId = keyIdsList[ownKeySelectBox->currentIndex()];
+ qDebug() << "KeyId" << keyIdsList[ownKeySelectBox->currentIndex()];
- const auto keyId = keyIdsList[ownKeySelectBox->currentIndex()];
+ if (keyId.isEmpty()) {
+ QMessageBox::critical(
+ this, _("Invalid Operation"),
+ _("Own Key can not be None while getting service token."));
+ return;
+ }
- qDebug() << "KeyId" << keyIdsList[ownKeySelectBox->currentIndex()];
+ QStringList selectedKeyIds(keyIdsList[ownKeySelectBox->currentIndex()]);
- if (keyId.isEmpty()) {
- QMessageBox::critical(this, tr("Invalid Operation"),
- tr("Own Key can not be None while getting service token."));
- return;
- }
+ QByteArray keyDataBuf;
+ mCtx->exportKeys(&selectedKeyIds, &keyDataBuf);
- QStringList selectedKeyIds(keyIdsList[ownKeySelectBox->currentIndex()]);
+ GpgKey key = mCtx->getKeyRefById(keyId);
- QByteArray keyDataBuf;
- mCtx->exportKeys(&selectedKeyIds, &keyDataBuf);
+ if (!key.good) {
+ QMessageBox::critical(this, _("Error"), _("Key Not Exists"));
+ return;
+ }
- GpgKey key = mCtx->getKeyById(keyId);
+ qDebug() << "keyDataBuf" << keyDataBuf;
- if (!key.good) {
- QMessageBox::critical(this, tr("Error"),
- tr("Key Not Exists"));
- return;
- }
+ /**
+ * {
+ * "publicKey" : ...
+ * "sha": ...
+ * "signedFpr": ...
+ * "version": ...
+ * }
+ */
- qDebug() << "keyDataBuf" << keyDataBuf;
+ QCryptographicHash shaGen(QCryptographicHash::Sha256);
+ shaGen.addData(keyDataBuf);
- /**
- * {
- * "publicKey" : ...
- * "sha": ...
- * "signedFpr": ...
- * "version": ...
- * }
- */
+ auto shaStr = shaGen.result().toHex();
- QCryptographicHash shaGen(QCryptographicHash::Sha256);
- shaGen.addData(keyDataBuf);
+ auto signFprStr = ComUtils::getSignStringBase64(mCtx, key.fpr, key);
- auto shaStr = shaGen.result().toHex();
+ rapidjson::Value pubkey, ver, sha, signFpr;
- auto signFprStr = ComUtils::getSignStringBase64(mCtx, key.fpr, key);
+ rapidjson::Document doc;
+ doc.SetObject();
- rapidjson::Value pubkey, ver, sha, signFpr;
+ pubkey.SetString(keyDataBuf.constData(), keyDataBuf.count());
- rapidjson::Document doc;
- doc.SetObject();
+ auto version = qApp->applicationVersion();
+ ver.SetString(version.toUtf8().constData(),
+ qApp->applicationVersion().count());
- pubkey.SetString(keyDataBuf.constData(), keyDataBuf.count());
+ sha.SetString(shaStr.constData(), shaStr.count());
+ signFpr.SetString(signFprStr.constData(), signFprStr.count());
- auto version = qApp->applicationVersion();
- ver.SetString(version.toUtf8().constData(), qApp->applicationVersion().count());
+ rapidjson::Document::AllocatorType& allocator = doc.GetAllocator();
- sha.SetString(shaStr.constData(), shaStr.count());
- signFpr.SetString(signFprStr.constData(), signFprStr.count());
+ doc.AddMember("publicKey", pubkey, allocator);
+ doc.AddMember("sha", sha, allocator);
+ doc.AddMember("signedFpr", signFpr, allocator);
+ doc.AddMember("version", ver, allocator);
- rapidjson::Document::AllocatorType &allocator = doc.GetAllocator();
+ rapidjson::StringBuffer sb;
+ rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb);
+ doc.Accept(writer);
- doc.AddMember("publicKey", pubkey, allocator);
- doc.AddMember("sha", sha, allocator);
- doc.AddMember("signedFpr", signFpr, allocator);
- doc.AddMember("version", ver, allocator);
+ QByteArray postData(sb.GetString());
- rapidjson::StringBuffer sb;
- rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb);
- doc.Accept(writer);
+ QNetworkReply* reply = utils->getNetworkManager().post(request, postData);
- QByteArray postData(sb.GetString());
+ // Show Waiting Dailog
+ auto dialog = new WaitingDialog("Getting Token From Server", this);
+ dialog->show();
- QNetworkReply *reply = utils->getNetworkManager().post(request, postData);
+ while (reply->isRunning()) {
+ QApplication::processEvents();
+ }
- // Show Waiting Dailog
- auto dialog = new WaitingDialog("Getting Token From Server", this);
- dialog->show();
+ dialog->close();
- while (reply->isRunning()) {
- QApplication::processEvents();
- }
+ if (utils->checkServerReply(reply->readAll().constData())) {
+ /**
+ * {
+ * "serviceToken" : ...
+ * "fpr": ...
+ * }
+ */
- dialog->close();
-
- if (utils->checkServerReply(reply->readAll().constData())) {
-
- /**
- * {
- * "serviceToken" : ...
- * "fpr": ...
- * }
- */
-
- if (!utils->checkDataValueStr("serviceToken") || !utils->checkDataValueStr("fpr")) {
- QMessageBox::critical(this, tr("Error"),
- tr("The communication content with the server does not meet the requirements"));
- return;
- }
-
- QString serviceTokenTemp = utils->getDataValueStr("serviceToken");
- QString fpr = utils->getDataValueStr("fpr");
- auto key = mCtx->getKeyByFpr(fpr);
- if (utils->checkServiceTokenFormat(serviceTokenTemp) && key.good) {
- serviceToken = serviceTokenTemp;
- qDebug() << "Get Service Token" << serviceToken;
- // Auto update settings
- settings.setValue("general/serviceToken", serviceToken);
- serviceTokenLabel->setText(serviceToken);
- QMessageBox::information(this, tr("Notice"),
- tr("Succeed in getting service token"));
- } else {
- QMessageBox::critical(this, tr("Error"), tr("There is a problem with the communication with the server"));
- }
+ if (!utils->checkDataValueStr("serviceToken") ||
+ !utils->checkDataValueStr("fpr")) {
+ QMessageBox::critical(this, _("Error"),
+ _("The communication content with the server does "
+ "not meet the requirements"));
+ return;
}
+ QString serviceTokenTemp = utils->getDataValueStr("serviceToken");
+ QString fpr = utils->getDataValueStr("fpr");
+ auto key = mCtx->getKeyRefByFpr(fpr);
+ if (utils->checkServiceTokenFormat(serviceTokenTemp) && key.good) {
+ serviceToken = serviceTokenTemp;
+ qDebug() << "Get Service Token" << serviceToken;
+ // Auto update settings
+ settings.setValue("general/serviceToken", serviceToken);
+ serviceTokenLabel->setText(serviceToken);
+ QMessageBox::information(this, _("Notice"),
+ _("Succeed in getting service token"));
+ } else {
+ QMessageBox::critical(
+ this, _("Error"),
+ _("There is a problem with the communication with the server"));
+ }
+ }
}
+#endif
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/settings/SettingsGeneral.h b/src/ui/settings/SettingsGeneral.h
new file mode 100644
index 00000000..7e118f98
--- /dev/null
+++ b/src/ui/settings/SettingsGeneral.h
@@ -0,0 +1,85 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_SETTINGSGENERAL_H
+#define GPGFRONTEND_SETTINGSGENERAL_H
+
+#include "ui/GpgFrontendUI.h"
+
+namespace GpgFrontend::UI {
+class KeyList;
+
+class GeneralTab : public QWidget {
+ Q_OBJECT
+
+ public:
+ explicit GeneralTab(QWidget* parent = nullptr);
+
+ void setSettings();
+
+ void applySettings();
+
+ private:
+ QCheckBox* saveCheckedKeysCheckBox;
+ QCheckBox* importConfirmationCheckBox;
+
+#ifdef MULTI_LANG_SUPPORT
+ QComboBox* langSelectBox;
+ QHash<QString, QString> lang;
+#endif
+
+#ifdef SERVER_SUPPORT
+ QComboBox* serverSelectBox;
+ QComboBox* ownKeySelectBox;
+ QPushButton* getServiceTokenButton;
+ QLabel* serviceTokenLabel;
+ std::string serviceToken;
+ std::unordered_map<std::string, std::string> keyIds;
+#endif
+
+ std::vector<std::string> keyIdsList;
+
+ KeyList* mKeyList{};
+
+ private slots:
+
+#ifdef MULTI_LANG_SUPPORT
+
+ void slotLanguageChanged();
+
+#endif
+
+#ifdef SERVER_SUPPORT
+
+ void slotOwnKeyIdChanged();
+
+#endif
+
+ signals:
+
+ void signalRestartNeeded(bool needed);
+};
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_SETTINGSGENERAL_H
diff --git a/src/ui/settings/SettingsKeyServer.cpp b/src/ui/settings/SettingsKeyServer.cpp
index b49eb9e0..f05ad7fb 100644
--- a/src/ui/settings/SettingsKeyServer.cpp
+++ b/src/ui/settings/SettingsKeyServer.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -22,68 +22,69 @@
*
*/
-#include "ui/SettingsDialog.h"
-
-KeyserverTab::KeyserverTab(QWidget *parent)
- : QWidget(parent), appPath(qApp->applicationDirPath()),
- settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini",
- QSettings::IniFormat) {
-
- auto generalGroupBox = new QGroupBox(tr("General"));
- auto generalLayout = new QVBoxLayout();
-
- keyServerTable = new QTableWidget();
- keyServerTable->setColumnCount(3);
- keyServerTable->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
- keyServerTable->horizontalHeader()->setStretchLastSection(false);
- keyServerTable->verticalHeader()->hide();
- keyServerTable->setShowGrid(false);
- keyServerTable->sortByColumn(0, Qt::AscendingOrder);
- keyServerTable->setSelectionBehavior(QAbstractItemView::SelectRows);
- keyServerTable->setSelectionMode(QAbstractItemView::SingleSelection);
-
- // tableitems not editable
- keyServerTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
- // no focus (rectangle around tableitems)
- // may be it should focus on whole row
- keyServerTable->setFocusPolicy(Qt::NoFocus);
- keyServerTable->setAlternatingRowColors(true);
-
- QStringList labels;
- labels << tr("No.") << tr("Address") << tr("Available");
- keyServerTable->setHorizontalHeaderLabels(labels);
-
- auto *mainLayout = new QVBoxLayout(this);
- auto *label = new QLabel(tr("Default Key Server for Import:"));
-
- comboBox = new QComboBox;
- comboBox->setEditable(false);
- comboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
-
- auto *addKeyServerBox = new QWidget(this);
- auto *addKeyServerLayout = new QHBoxLayout(addKeyServerBox);
- auto *http = new QLabel("URL: ");
- newKeyServerEdit = new QLineEdit(this);
- auto *newKeyServerButton = new QPushButton(tr("Add"), this);
- connect(newKeyServerButton, SIGNAL(clicked()), this, SLOT(addKeyServer()));
- addKeyServerLayout->addWidget(http);
- addKeyServerLayout->addWidget(newKeyServerEdit);
- addKeyServerLayout->addWidget(newKeyServerButton);
-
- generalLayout->addWidget(label);
- generalLayout->addWidget(comboBox);
- generalLayout->addWidget(keyServerTable);
- generalLayout->addWidget(addKeyServerBox);
- generalLayout->addStretch(0);
-
- generalGroupBox->setLayout(generalLayout);
- mainLayout->addWidget(generalGroupBox);
- mainLayout->addStretch(0);
-
- setLayout(mainLayout);
- // Read keylist from ini-file and fill it into combobox
- setSettings();
- refreshTable();
+#include "SettingsKeyServer.h"
+
+#include "GlobalSettingStation.h"
+
+namespace GpgFrontend::UI {
+
+KeyserverTab::KeyserverTab(QWidget* parent) : QWidget(parent) {
+ auto generalGroupBox = new QGroupBox(_("General"));
+ auto generalLayout = new QVBoxLayout();
+
+ keyServerTable = new QTableWidget();
+ keyServerTable->setColumnCount(3);
+ keyServerTable->horizontalHeader()->setSectionResizeMode(
+ QHeaderView::ResizeToContents);
+ keyServerTable->horizontalHeader()->setStretchLastSection(false);
+ keyServerTable->verticalHeader()->hide();
+ keyServerTable->setShowGrid(false);
+ keyServerTable->sortByColumn(0, Qt::AscendingOrder);
+ keyServerTable->setSelectionBehavior(QAbstractItemView::SelectRows);
+ keyServerTable->setSelectionMode(QAbstractItemView::SingleSelection);
+
+ // tableitems not editable
+ keyServerTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ // no focus (rectangle around tableitems)
+ // may be it should focus on whole row
+ keyServerTable->setFocusPolicy(Qt::NoFocus);
+ keyServerTable->setAlternatingRowColors(true);
+
+ QStringList labels;
+ labels << _("No.") << _("Address") << _("Available");
+ keyServerTable->setHorizontalHeaderLabels(labels);
+
+ auto* mainLayout = new QVBoxLayout(this);
+ auto* label = new QLabel(QString(_("Default Key Server for Import")) + ": ");
+
+ comboBox = new QComboBox;
+ comboBox->setEditable(false);
+ comboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+
+ auto* addKeyServerBox = new QWidget(this);
+ auto* addKeyServerLayout = new QHBoxLayout(addKeyServerBox);
+ auto* http = new QLabel("URL: ");
+ newKeyServerEdit = new QLineEdit(this);
+ auto* newKeyServerButton = new QPushButton(_("Add"), this);
+ connect(newKeyServerButton, SIGNAL(clicked()), this, SLOT(addKeyServer()));
+ addKeyServerLayout->addWidget(http);
+ addKeyServerLayout->addWidget(newKeyServerEdit);
+ addKeyServerLayout->addWidget(newKeyServerButton);
+
+ generalLayout->addWidget(label);
+ generalLayout->addWidget(comboBox);
+ generalLayout->addWidget(keyServerTable);
+ generalLayout->addWidget(addKeyServerBox);
+ generalLayout->addStretch(0);
+
+ generalGroupBox->setLayout(generalLayout);
+ mainLayout->addWidget(generalGroupBox);
+ mainLayout->addStretch(0);
+
+ setLayout(mainLayout);
+ // Read keylist from ini-file and fill it into combobox
+ setSettings();
+ refreshTable();
}
/**********************************
@@ -92,29 +93,38 @@ KeyserverTab::KeyserverTab(QWidget *parent)
* appropriately
**********************************/
void KeyserverTab::setSettings() {
-
- keyServerStrList = settings.value("keyserver/keyServerList").toStringList();
-
- for (const auto &keyServer : keyServerStrList) {
- comboBox->addItem(keyServer);
- qDebug() << "KeyserverTab Get ListItemText" << keyServer;
+ auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
+
+ try {
+ auto& server_list = settings.lookup("keyserver.server_list");
+ const auto server_list_size = server_list.getLength();
+ for (int i = 0; i < server_list_size; i++) {
+ std::string server_url = server_list[i];
+ comboBox->addItem(server_url.c_str());
+ keyServerStrList.append(server_url.c_str());
}
-
- comboBox->setCurrentText(
- settings.value("keyserver/defaultKeyServer").toString());
-
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("server_list");
+ }
+
+ try {
+ std::string default_server = settings.lookup("keyserver.default_server");
+ comboBox->setCurrentText(default_server.c_str());
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("default_server");
+ }
}
void KeyserverTab::addKeyServer() {
- QString targetUrl;
- if (newKeyServerEdit->text().startsWith("http://") ||
- newKeyServerEdit->text().startsWith("https://"))
- targetUrl = newKeyServerEdit->text();
- else
- targetUrl = "http://" + newKeyServerEdit->text();
- keyServerStrList.append(targetUrl);
- comboBox->addItem(targetUrl);
- refreshTable();
+ QString targetUrl;
+ if (newKeyServerEdit->text().startsWith("http://") ||
+ newKeyServerEdit->text().startsWith("https://"))
+ targetUrl = newKeyServerEdit->text();
+ else
+ targetUrl = "http://" + newKeyServerEdit->text();
+ keyServerStrList.append(targetUrl);
+ comboBox->addItem(targetUrl);
+ refreshTable();
}
/***********************************
@@ -122,27 +132,51 @@ void KeyserverTab::addKeyServer() {
* write them to settings-file
*************************************/
void KeyserverTab::applySettings() {
- settings.setValue("keyserver/keyServerList", keyServerStrList);
- settings.setValue("keyserver/defaultKeyServer", comboBox->currentText());
+ auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
+
+ if (!settings.exists("keyserver") ||
+ settings.lookup("keyserver").getType() != libconfig::Setting::TypeGroup)
+ settings.add("keyserver", libconfig::Setting::TypeGroup);
+
+ auto& keyserver = settings["keyserver"];
+
+ if (keyserver.exists("server_list"))
+ keyserver.remove("server_list");
+
+ keyserver.add("server_list", libconfig::Setting::TypeList);
+
+ auto& server_list = keyserver["server_list"];
+ for (const auto& key_server_url : keyServerStrList) {
+ server_list.add(libconfig::Setting::TypeString) =
+ key_server_url.toStdString();
+ }
+
+ if (!keyserver.exists("default_server")) {
+ keyserver.add("default_server", libconfig::Setting::TypeString) =
+ comboBox->currentText().toStdString();
+ } else {
+ keyserver["default_server"] = comboBox->currentText().toStdString();
+ }
}
void KeyserverTab::refreshTable() {
-
- qDebug() << "Start Refreshing Key Server Table";
-
- keyServerTable->setRowCount(keyServerStrList.size());
-
- int index = 0;
- for (const auto &server : keyServerStrList) {
- auto *tmp1 = new QTableWidgetItem(QString::number(index));
- tmp1->setTextAlignment(Qt::AlignCenter);
- keyServerTable->setItem(index, 0, tmp1);
- auto *tmp2 = new QTableWidgetItem(server);
- tmp2->setTextAlignment(Qt::AlignCenter);
- keyServerTable->setItem(index, 1, tmp2);
- auto *tmp3 = new QTableWidgetItem("");
- tmp3->setTextAlignment(Qt::AlignCenter);
- keyServerTable->setItem(index, 2, tmp3);
- index++;
- }
+ LOG(INFO) << "Start Refreshing Key Server Table";
+
+ keyServerTable->setRowCount(keyServerStrList.size());
+
+ int index = 0;
+ for (const auto& server : keyServerStrList) {
+ auto* tmp1 = new QTableWidgetItem(QString::number(index));
+ tmp1->setTextAlignment(Qt::AlignCenter);
+ keyServerTable->setItem(index, 0, tmp1);
+ auto* tmp2 = new QTableWidgetItem(server);
+ tmp2->setTextAlignment(Qt::AlignCenter);
+ keyServerTable->setItem(index, 1, tmp2);
+ auto* tmp3 = new QTableWidgetItem();
+ tmp3->setTextAlignment(Qt::AlignCenter);
+ keyServerTable->setItem(index, 2, tmp3);
+ index++;
+ }
}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/settings/SettingsKeyServer.h b/src/ui/settings/SettingsKeyServer.h
new file mode 100644
index 00000000..5042aaa5
--- /dev/null
+++ b/src/ui/settings/SettingsKeyServer.h
@@ -0,0 +1,59 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_SETTINGSKEYSERVER_H
+#define GPGFRONTEND_SETTINGSKEYSERVER_H
+
+#include "ui/GpgFrontendUI.h"
+
+namespace GpgFrontend::UI {
+class KeyserverTab : public QWidget {
+ Q_OBJECT
+
+ public:
+ explicit KeyserverTab(QWidget* parent = nullptr);
+
+ void setSettings();
+
+ void applySettings();
+
+ private:
+ QComboBox* comboBox;
+ QLineEdit* newKeyServerEdit;
+ QTableWidget* keyServerTable;
+ QStringList keyServerStrList;
+
+ private slots:
+
+ void addKeyServer();
+
+ void refreshTable();
+
+ signals:
+
+ void signalRestartNeeded(bool needed);
+};
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_SETTINGSKEYSERVER_H
diff --git a/src/ui/settings/SettingsSendMail.cpp b/src/ui/settings/SettingsSendMail.cpp
index a5e3274f..2518991d 100644
--- a/src/ui/settings/SettingsSendMail.cpp
+++ b/src/ui/settings/SettingsSendMail.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -22,75 +22,80 @@
*
*/
-#include "ui/SettingsDialog.h"
-#include "smtp/SmtpMime"
+#include "SettingsSendMail.h"
-SendMailTab::SendMailTab(QWidget *parent)
- : QWidget(parent), appPath(qApp->applicationDirPath()),
- settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini",
- QSettings::IniFormat) {
-
- enableCheckBox = new QCheckBox(tr("Enable"));
- enableCheckBox->setTristate(false);
-
- smtpAddress = new QLineEdit();
- username = new QLineEdit();
- password = new QLineEdit();
- password->setEchoMode(QLineEdit::Password);
-
- portSpin = new QSpinBox();
- portSpin->setMinimum(1);
- portSpin->setMaximum(65535);
- connectionTypeComboBox = new QComboBox();
- connectionTypeComboBox->addItem("None");
- connectionTypeComboBox->addItem("SSL");
- connectionTypeComboBox->addItem("TLS");
- connectionTypeComboBox->addItem("STARTTLS");
-
- defaultSender = new QLineEdit();;
- checkConnectionButton = new QPushButton(tr("Check Connection"));
-
- auto generalGroupBox = new QGroupBox(tr("General"));
- auto connectGroupBox = new QGroupBox(tr("Connection"));
- auto preferenceGroupBox = new QGroupBox(tr("Preference"));
-
- auto generalLayout = new QGridLayout();
- generalLayout->addWidget(enableCheckBox);
-
- auto connectLayout = new QGridLayout();
- connectLayout->addWidget(new QLabel(tr("SMTP Address")), 1, 0);
- connectLayout->addWidget(smtpAddress, 1, 1, 1, 4);
- connectLayout->addWidget(new QLabel(tr("Username")), 2, 0);
- connectLayout->addWidget(username, 2, 1, 1, 4);
- connectLayout->addWidget(new QLabel(tr("Password")), 3, 0);
- connectLayout->addWidget(password, 3, 1, 1, 4);
- connectLayout->addWidget(new QLabel(tr("Port")), 4, 0);
- connectLayout->addWidget(portSpin, 4, 1, 1, 1);
- connectLayout->addWidget(new QLabel(tr("Connection Security")), 5, 0);
- connectLayout->addWidget(connectionTypeComboBox, 5, 1, 1, 1);
- connectLayout->addWidget(checkConnectionButton, 6, 0);
-
- auto preferenceLayout = new QGridLayout();
-
- preferenceLayout->addWidget(new QLabel(tr("Default Sender")), 0, 0);
- preferenceLayout->addWidget(defaultSender, 0, 1, 1, 4);
-
- generalGroupBox->setLayout(generalLayout);
- connectGroupBox->setLayout(connectLayout);
- preferenceGroupBox->setLayout(preferenceLayout);
-
- auto vBox = new QVBoxLayout();
- vBox->addWidget(generalGroupBox);
- vBox->addWidget(connectGroupBox);
- vBox->addWidget(preferenceGroupBox);
- vBox->addStretch(0);
-
- connect(enableCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotCheckBoxSetEnableDisable(int)));
- connect(checkConnectionButton, SIGNAL(clicked(bool)), this, SLOT(slotCheckConnection()));
-
-
- this->setLayout(vBox);
- setSettings();
+#ifdef SMTP_SUPPORT
+#include "smtp/SmtpMime"
+#endif
+
+namespace GpgFrontend::UI {
+
+SendMailTab::SendMailTab(QWidget* parent)
+ : QWidget(parent),
+ appPath(qApp->applicationDirPath()),
+ settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini",
+ QSettings::IniFormat) {
+ enableCheckBox = new QCheckBox(_("Enable"));
+ enableCheckBox->setTristate(false);
+
+ smtpAddress = new QLineEdit();
+ username = new QLineEdit();
+ password = new QLineEdit();
+ password->setEchoMode(QLineEdit::Password);
+
+ portSpin = new QSpinBox();
+ portSpin->setMinimum(1);
+ portSpin->setMaximum(65535);
+ connectionTypeComboBox = new QComboBox();
+ connectionTypeComboBox->addItem("None");
+ connectionTypeComboBox->addItem("SSL");
+ connectionTypeComboBox->addItem("TLS");
+ connectionTypeComboBox->addItem("STARTTLS");
+
+ defaultSender = new QLineEdit();
+ ;
+ checkConnectionButton = new QPushButton(_("Check Connection"));
+
+ auto generalGroupBox = new QGroupBox(_("General"));
+ auto connectGroupBox = new QGroupBox(_("Connection"));
+ auto preferenceGroupBox = new QGroupBox(_("Preference"));
+
+ auto generalLayout = new QGridLayout();
+ generalLayout->addWidget(enableCheckBox);
+
+ auto connectLayout = new QGridLayout();
+ connectLayout->addWidget(new QLabel(_("SMTP Address")), 1, 0);
+ connectLayout->addWidget(smtpAddress, 1, 1, 1, 4);
+ connectLayout->addWidget(new QLabel(_("Username")), 2, 0);
+ connectLayout->addWidget(username, 2, 1, 1, 4);
+ connectLayout->addWidget(new QLabel(_("Password")), 3, 0);
+ connectLayout->addWidget(password, 3, 1, 1, 4);
+ connectLayout->addWidget(new QLabel(_("Port")), 4, 0);
+ connectLayout->addWidget(portSpin, 4, 1, 1, 1);
+ connectLayout->addWidget(new QLabel(_("Connection Security")), 5, 0);
+ connectLayout->addWidget(connectionTypeComboBox, 5, 1, 1, 1);
+ connectLayout->addWidget(checkConnectionButton, 6, 0);
+
+ auto preferenceLayout = new QGridLayout();
+
+ preferenceLayout->addWidget(new QLabel(_("Default Sender")), 0, 0);
+ preferenceLayout->addWidget(defaultSender, 0, 1, 1, 4);
+
+ generalGroupBox->setLayout(generalLayout);
+ connectGroupBox->setLayout(connectLayout);
+ preferenceGroupBox->setLayout(preferenceLayout);
+
+ auto vBox = new QVBoxLayout();
+ vBox->addWidget(generalGroupBox);
+ vBox->addWidget(connectGroupBox);
+ vBox->addWidget(preferenceGroupBox);
+ vBox->addStretch(0);
+
+ connect(enableCheckBox, SIGNAL(stateChanged(int)), this,
+ SLOT(slotCheckBoxSetEnableDisable(int)));
+
+ this->setLayout(vBox);
+ setSettings();
}
/**********************************
@@ -99,27 +104,28 @@ SendMailTab::SendMailTab(QWidget *parent)
* appropriately
**********************************/
void SendMailTab::setSettings() {
-
- if (settings.value("sendMail/enable", false).toBool())
- enableCheckBox->setCheckState(Qt::Checked);
- else {
- enableCheckBox->setCheckState(Qt::Unchecked);
- smtpAddress->setDisabled(true);
- username->setDisabled(true);
- password->setDisabled(true);
- portSpin->setDisabled(true);
- connectionTypeComboBox->setDisabled(true);
- defaultSender->setDisabled(true);
- checkConnectionButton->setDisabled(true);
- }
-
- smtpAddress->setText(settings.value("sendMail/smtpAddress", QString()).toString());
- username->setText(settings.value("sendMail/username", QString()).toString());
- password->setText(settings.value("sendMail/password", QString()).toString());
- portSpin->setValue(settings.value("sendMail/port", 25).toInt());
- connectionTypeComboBox->setCurrentText(settings.value("sendMail/connectionType", "None").toString());
- defaultSender->setText(settings.value("sendMail/defaultSender", QString()).toString());
-
+ if (settings.value("sendMail/enable", false).toBool())
+ enableCheckBox->setCheckState(Qt::Checked);
+ else {
+ enableCheckBox->setCheckState(Qt::Unchecked);
+ smtpAddress->setDisabled(true);
+ username->setDisabled(true);
+ password->setDisabled(true);
+ portSpin->setDisabled(true);
+ connectionTypeComboBox->setDisabled(true);
+ defaultSender->setDisabled(true);
+ checkConnectionButton->setDisabled(true);
+ }
+
+ smtpAddress->setText(
+ settings.value("sendMail/smtpAddress", QString()).toString());
+ username->setText(settings.value("sendMail/username", QString()).toString());
+ password->setText(settings.value("sendMail/password", QString()).toString());
+ portSpin->setValue(settings.value("sendMail/port", 25).toInt());
+ connectionTypeComboBox->setCurrentText(
+ settings.value("sendMail/connectionType", "None").toString());
+ defaultSender->setText(
+ settings.value("sendMail/defaultSender", QString()).toString());
}
/***********************************
@@ -127,67 +133,69 @@ void SendMailTab::setSettings() {
* write them to settings-file
*************************************/
void SendMailTab::applySettings() {
-
- settings.setValue("sendMail/smtpAddress", smtpAddress->text());
- settings.setValue("sendMail/username", username->text());
- settings.setValue("sendMail/password", password->text());
- settings.setValue("sendMail/port", portSpin->value());
- settings.setValue("sendMail/connectionType", connectionTypeComboBox->currentText());
- settings.setValue("sendMail/defaultSender", defaultSender->text());
-
- settings.setValue("sendMail/enable", enableCheckBox->isChecked());
+ settings.setValue("sendMail/smtpAddress", smtpAddress->text());
+ settings.setValue("sendMail/username", username->text());
+ settings.setValue("sendMail/password", password->text());
+ settings.setValue("sendMail/port", portSpin->value());
+ settings.setValue("sendMail/connectionType",
+ connectionTypeComboBox->currentText());
+ settings.setValue("sendMail/defaultSender", defaultSender->text());
+
+ settings.setValue("sendMail/enable", enableCheckBox->isChecked());
}
+#ifdef SMTP_SUPPORT
void SendMailTab::slotCheckConnection() {
-
- SmtpClient::ConnectionType connectionType;
- const auto selectedConnType = connectionTypeComboBox->currentText();
- if (selectedConnType == "SSL") {
- connectionType = SmtpClient::ConnectionType::SslConnection;
- } else if (selectedConnType == "TLS" || selectedConnType == "STARTTLS") {
- connectionType = SmtpClient::ConnectionType::TlsConnection;
- } else {
- connectionType = SmtpClient::ConnectionType::TcpConnection;
- }
-
- SmtpClient smtp(smtpAddress->text(), portSpin->value(), connectionType);
-
- smtp.setUser(username->text());
- smtp.setPassword(password->text());
-
- bool if_success = true;
-
- if (!smtp.connectToHost()) {
- QMessageBox::critical(this, tr("Fail"), tr("Fail to Connect SMTP Server"));
- if_success = false;
- }
- if (if_success && !smtp.login()) {
- QMessageBox::critical(this, tr("Fail"), tr("Fail to Login"));
- if_success = false;
- }
-
- if (if_success)
- QMessageBox::information(this, tr("Success"), tr("Succeed in connecting and login"));
-
+ SmtpClient::ConnectionType connectionType;
+ const auto selectedConnType = connectionTypeComboBox->currentText();
+ if (selectedConnType == "SSL") {
+ connectionType = SmtpClient::ConnectionType::SslConnection;
+ } else if (selectedConnType == "TLS" || selectedConnType == "STARTTLS") {
+ connectionType = SmtpClient::ConnectionType::TlsConnection;
+ } else {
+ connectionType = SmtpClient::ConnectionType::TcpConnection;
+ }
+
+ SmtpClient smtp(smtpAddress->text(), portSpin->value(), connectionType);
+
+ smtp.setUser(username->text());
+ smtp.setPassword(password->text());
+
+ bool if_success = true;
+
+ if (!smtp.connectToHost()) {
+ QMessageBox::critical(this, _("Fail"), _("Fail to Connect SMTP Server"));
+ if_success = false;
+ }
+ if (if_success && !smtp.login()) {
+ QMessageBox::critical(this, _("Fail"), _("Fail to Login"));
+ if_success = false;
+ }
+
+ if (if_success)
+ QMessageBox::information(this, _("Success"),
+ _("Succeed in connecting and login"));
}
+#endif
void SendMailTab::slotCheckBoxSetEnableDisable(int state) {
- if (state == Qt::Checked) {
- smtpAddress->setEnabled(true);
- username->setEnabled(true);
- password->setEnabled(true);
- portSpin->setEnabled(true);
- connectionTypeComboBox->setEnabled(true);
- defaultSender->setEnabled(true);
- checkConnectionButton->setEnabled(true);
- } else {
- smtpAddress->setDisabled(true);
- username->setDisabled(true);
- password->setDisabled(true);
- portSpin->setDisabled(true);
- connectionTypeComboBox->setDisabled(true);
- defaultSender->setDisabled(true);
- checkConnectionButton->setDisabled(true);
- }
+ if (state == Qt::Checked) {
+ smtpAddress->setEnabled(true);
+ username->setEnabled(true);
+ password->setEnabled(true);
+ portSpin->setEnabled(true);
+ connectionTypeComboBox->setEnabled(true);
+ defaultSender->setEnabled(true);
+ checkConnectionButton->setEnabled(true);
+ } else {
+ smtpAddress->setDisabled(true);
+ username->setDisabled(true);
+ password->setDisabled(true);
+ portSpin->setDisabled(true);
+ connectionTypeComboBox->setDisabled(true);
+ defaultSender->setDisabled(true);
+ checkConnectionButton->setDisabled(true);
+ }
}
+} // namespace GpgFrontend::UI
diff --git a/src/ui/settings/SettingsSendMail.h b/src/ui/settings/SettingsSendMail.h
new file mode 100644
index 00000000..ec8f83c9
--- /dev/null
+++ b/src/ui/settings/SettingsSendMail.h
@@ -0,0 +1,46 @@
+//
+// Created by saturneric on 2021/11/28.
+//
+
+#ifndef GPGFRONTEND_SETTINGSSENDMAIL_H
+#define GPGFRONTEND_SETTINGSSENDMAIL_H
+
+#include "ui/GpgFrontendUI.h"
+
+namespace GpgFrontend::UI {
+class SendMailTab : public QWidget {
+ Q_OBJECT
+
+ public:
+ explicit SendMailTab(QWidget* parent = nullptr);
+
+ void setSettings();
+
+ void applySettings();
+
+ private slots:
+
+ void slotCheckBoxSetEnableDisable(int state);
+
+ private:
+ QString appPath;
+ QSettings settings;
+
+ QCheckBox* enableCheckBox;
+
+ QLineEdit* smtpAddress;
+ QLineEdit* username;
+ QLineEdit* password;
+ QSpinBox* portSpin;
+ QComboBox* connectionTypeComboBox;
+ QLineEdit* defaultSender;
+
+ QPushButton* checkConnectionButton;
+
+ signals:
+
+ void signalRestartNeeded(bool needed);
+};
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_SETTINGSSENDMAIL_H
diff --git a/src/ui/smtp/SendMailDialog.cpp b/src/ui/smtp/SendMailDialog.cpp
new file mode 100644
index 00000000..7c8933a0
--- /dev/null
+++ b/src/ui/smtp/SendMailDialog.cpp
@@ -0,0 +1,195 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "SendMailDialog.h"
+
+#include <utility>
+
+#ifdef STMP_ENABLED
+#include "smtp/SmtpMime"
+#endif
+
+namespace GpgFrontend::UI {
+
+SendMailDialog::SendMailDialog(QString text, QWidget* parent)
+ : QDialog(parent),
+ appPath(qApp->applicationDirPath()),
+ settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini",
+ QSettings::IniFormat),
+ mText(std::move(text)) {
+ if (smtpAddress.isEmpty()) {
+ QMessageBox::critical(
+ this, _("Incomplete configuration"),
+ _("The SMTP address is empty, please go to the setting interface to "
+ "complete the configuration."));
+
+ deleteLater();
+ return;
+ }
+
+ senderEdit = new QLineEdit();
+ senderEdit->setText(defaultSender);
+ recipientEdit = new QTextEdit();
+ recipientEdit->setPlaceholderText(
+ "One or more email addresses. Please use ; to separate.");
+ subjectEdit = new QLineEdit();
+
+ errorLabel = new QLabel();
+
+ qDebug() << "Send Mail Settings" << smtpAddress << username << password
+ << defaultSender << connectionTypeSettings;
+
+ confirmButton = new QPushButton("Confirm");
+
+ auto layout = new QGridLayout();
+ layout->addWidget(new QLabel("Sender"), 0, 0);
+ layout->addWidget(senderEdit, 0, 1);
+ layout->addWidget(new QLabel("Recipient"), 1, 0);
+ layout->addWidget(recipientEdit, 1, 1);
+ layout->addWidget(new QLabel("Subject"), 2, 0);
+ layout->addWidget(subjectEdit, 2, 1);
+ layout->addWidget(confirmButton, 3, 1);
+ layout->addWidget(errorLabel, 4, 0, 1, 2);
+
+#ifdef STMP_ENABLED
+ connect(confirmButton, SIGNAL(clicked(bool)), this, SLOT(slotConfirm()));
+#endif
+
+ this->setLayout(layout);
+ this->setWindowTitle("Send Mail");
+ this->setModal(true);
+ this->setFixedWidth(320);
+ this->show();
+}
+
+bool SendMailDialog::check_email_address(const QString& str) {
+ return re_email.match(str).hasMatch();
+}
+
+#ifdef STMP_ENABLED
+
+void SendMailDialog::slotConfirm() {
+ QString errString;
+ errorLabel->clear();
+
+ QStringList rcptStringList = recipientEdit->toPlainText().split(';');
+
+ if (rcptStringList.isEmpty()) {
+ errString.append(QString(" ") + _("Recipient cannot be empty") + " \n");
+ } else {
+ for (const auto& reci : rcptStringList) {
+ qDebug() << "Receiver" << reci.trimmed();
+ if (!check_email_address(reci.trimmed())) {
+ errString.append(QString(" ") +
+ _("One or more Recipient's Email Address is invalid") +
+ " \n");
+ break;
+ }
+ }
+ }
+ if (senderEdit->text().isEmpty()) {
+ errString.append(QString(" ") + _("Sender cannot be empty") + " \n");
+ } else if (!check_email_address(senderEdit->text())) {
+ errString.append(QString(" ") + _("Sender's Email Address is invalid") +
+ " \n");
+ }
+
+ if (!errString.isEmpty()) {
+ errorLabel->setAutoFillBackground(true);
+ QPalette error = errorLabel->palette();
+ error.setColor(QPalette::Window, "#ff8080");
+ errorLabel->setPalette(error);
+ errorLabel->setText(errString);
+ return;
+ }
+
+ SmtpClient::ConnectionType connectionType =
+ SmtpClient::ConnectionType::TcpConnection;
+
+ if (connectionTypeSettings == "SSL") {
+ connectionType = SmtpClient::ConnectionType::SslConnection;
+ } else if (connectionTypeSettings == "TLS") {
+ connectionType = SmtpClient::ConnectionType::TlsConnection;
+ } else if (connectionTypeSettings == "STARTTLS") {
+ connectionType = SmtpClient::ConnectionType::TlsConnection;
+ } else {
+ connectionType = SmtpClient::ConnectionType::TcpConnection;
+ }
+
+ SmtpClient smtp(smtpAddress, port, connectionType);
+
+ // We need to set the username (your email address) and the password
+ // for smtp authentification.
+
+ smtp.setUser(username);
+ smtp.setPassword(password);
+
+ // Now we create a MimeMessage object. This will be the email.
+
+ MimeMessage message;
+
+ message.setSender(new EmailAddress(senderEdit->text()));
+ for (const auto& reci : rcptStringList) {
+ if (!reci.isEmpty()) message.addRecipient(new EmailAddress(reci.trimmed()));
+ }
+ message.setSubject(subjectEdit->text());
+
+ // Now add some text to the email.
+ // First we create a MimeText object.
+
+ MimeText text;
+
+ text.setText(mText);
+
+ // Now add it to the mail
+ message.addPart(&text);
+
+ // Now we can send the mail
+ if (!smtp.connectToHost()) {
+ qDebug() << "Connect to SMTP Server Failed";
+ QMessageBox::critical(this, _("Fail"), _("Fail to Connect SMTP Server"));
+ return;
+ }
+ if (!smtp.login()) {
+ qDebug() << "Login to SMTP Server Failed";
+ QMessageBox::critical(this, _("Fail"), _("Fail to Login into SMTP Server"));
+ return;
+ }
+ if (!smtp.sendMail(message)) {
+ qDebug() << "Send Mail to SMTP Server Failed";
+ QMessageBox::critical(this, _("Fail"),
+ _("Fail to Send Mail to SMTP Server"));
+ return;
+ }
+ smtp.quit();
+
+ // Close after sending email
+ QMessageBox::information(this, _("Success"),
+ _("Succeed in Sending Mail to SMTP Server"));
+ deleteLater();
+}
+
+#endif
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/smtp/SendMailDialog.h b/src/ui/smtp/SendMailDialog.h
new file mode 100644
index 00000000..87dfd81f
--- /dev/null
+++ b/src/ui/smtp/SendMailDialog.h
@@ -0,0 +1,71 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_SENDMAILDIALOG_H
+#define GPGFRONTEND_SENDMAILDIALOG_H
+
+#include "ui/GpgFrontendUI.h"
+
+namespace GpgFrontend::UI {
+
+class SendMailDialog : public QDialog {
+ Q_OBJECT
+ public:
+ explicit SendMailDialog(QString text, QWidget* parent = nullptr);
+
+ private slots:
+
+ void slotConfirm();
+
+ private:
+ QString appPath;
+ QSettings settings;
+
+ QLineEdit* senderEdit;
+ QTextEdit* recipientEdit;
+ QLineEdit* subjectEdit;
+ QPushButton* confirmButton;
+
+ QLabel* errorLabel;
+ QString mText;
+
+ QString smtpAddress =
+ settings.value("sendMail/smtpAddress", QString()).toString();
+ QString username = settings.value("sendMail/username", QString()).toString();
+ QString password = settings.value("sendMail/password", QString()).toString();
+ QString defaultSender =
+ settings.value("sendMail/defaultSender", QString()).toString();
+ QString connectionTypeSettings =
+ settings.value("sendMail/connectionType", QString()).toString();
+ int port = settings.value("sendMail/port", QString()).toInt();
+
+ QRegularExpression re_email{
+ R"((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\]))"};
+
+ bool check_email_address(const QString& str);
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_SENDMAILDIALOG_H
diff --git a/src/ui/widgets/EditorPage.cpp b/src/ui/widgets/EditorPage.cpp
index beb37b96..94c98036 100644
--- a/src/ui/widgets/EditorPage.cpp
+++ b/src/ui/widgets/EditorPage.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,84 +24,131 @@
#include "ui/widgets/EditorPage.h"
+#include <boost/filesystem.hpp>
#include <utility>
-EditorPage::EditorPage(QString filePath, QWidget *parent) : QWidget(parent),
- fullFilePath(std::move(filePath)) {
- // Set the Textedit properties
- textPage = new QTextEdit();
- textPage->setAcceptRichText(false);
+#include "ui/function/FileReadThread.h"
- // Set the layout style
- mainLayout = new QVBoxLayout();
- mainLayout->setSpacing(0);
- mainLayout->addWidget(textPage);
- mainLayout->setContentsMargins(0, 0, 0, 0);
- setLayout(mainLayout);
+namespace GpgFrontend::UI {
- setAttribute(Qt::WA_DeleteOnClose);
- textPage->setFocus();
+EditorPage::EditorPage(QString filePath, QWidget* parent)
+ : QWidget(parent), fullFilePath(std::move(filePath)) {
+ // Set the Textedit properties
+ textPage = new QTextEdit();
+ textPage->setAcceptRichText(false);
- // Front in same width
- this->setFont({"Courier"});
-}
+ // Set the layout style
+ mainLayout = new QVBoxLayout();
+ mainLayout->setSpacing(0);
+ mainLayout->addWidget(textPage);
+ mainLayout->setContentsMargins(0, 0, 0, 0);
+ setLayout(mainLayout);
-const QString &EditorPage::getFilePath() const {
- return fullFilePath;
-}
+ textPage->setFocus();
-QTextEdit *EditorPage::getTextPage() {
- return textPage;
+ // Front in same width
+ this->setFont({"Courier"});
+ this->setAttribute(Qt::WA_DeleteOnClose);
}
-void EditorPage::setFilePath(const QString &filePath) {
- fullFilePath = filePath;
+const QString& EditorPage::getFilePath() const { return fullFilePath; }
+
+QTextEdit* EditorPage::getTextPage() { return textPage; }
+
+void EditorPage::setFilePath(const QString& filePath) {
+ fullFilePath = filePath;
}
-void EditorPage::showNotificationWidget(QWidget *widget, const char *className) {
- widget->setProperty(className, true);
- mainLayout->addWidget(widget);
+void EditorPage::showNotificationWidget(QWidget* widget,
+ const char* className) {
+ widget->setProperty(className, true);
+ mainLayout->addWidget(widget);
}
-void EditorPage::closeNoteByClass(const char *className) {
- QList<QWidget *> widgets = findChildren<QWidget *>();
- for (QWidget *widget: widgets) {
- if (widget->property(className) == true) {
- widget->close();
- }
+void EditorPage::closeNoteByClass(const char* className) {
+ QList<QWidget*> widgets = findChildren<QWidget*>();
+ for (QWidget* widget : widgets) {
+ if (widget->property(className) == true) {
+ widget->close();
}
+ }
}
void EditorPage::slotFormatGpgHeader() {
+ QString content = textPage->toPlainText();
+
+ // Get positions of the gpg-headers, if they exist
+ int start = content.indexOf(GpgFrontend::GpgConstants::PGP_SIGNED_BEGIN);
+ int startSig =
+ content.indexOf(GpgFrontend::GpgConstants::PGP_SIGNATURE_BEGIN);
+ int endSig = content.indexOf(GpgFrontend::GpgConstants::PGP_SIGNATURE_END);
+
+ if (start < 0 || startSig < 0 || endSig < 0 || signMarked) {
+ return;
+ }
+
+ signMarked = true;
+
+ // Set the fontstyle for the header
+ QTextCharFormat signFormat;
+ signFormat.setForeground(QBrush(QColor::fromRgb(80, 80, 80)));
+ signFormat.setFontPointSize(9);
+
+ // set font style for the signature
+ QTextCursor cursor(textPage->document());
+ cursor.setPosition(startSig, QTextCursor::MoveAnchor);
+ cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, endSig);
+ cursor.setCharFormat(signFormat);
+
+ // set the font style for the header
+ int headEnd = content.indexOf("\n\n", start);
+ cursor.setPosition(start, QTextCursor::MoveAnchor);
+ cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, headEnd);
+ cursor.setCharFormat(signFormat);
+}
- QString content = textPage->toPlainText();
-
- // Get positions of the gpg-headers, if they exist
- int start = content.indexOf(GpgConstants::PGP_SIGNED_BEGIN);
- int startSig = content.indexOf(GpgConstants::PGP_SIGNATURE_BEGIN);
- int endSig = content.indexOf(GpgConstants::PGP_SIGNATURE_END);
-
- if (start < 0 || startSig < 0 || endSig < 0 || signMarked) {
- return;
- }
-
- signMarked = true;
-
- // Set the fontstyle for the header
- QTextCharFormat signFormat;
- signFormat.setForeground(QBrush(QColor::fromRgb(80, 80, 80)));
- signFormat.setFontPointSize(9);
-
- // set font style for the signature
- QTextCursor cursor(textPage->document());
- cursor.setPosition(startSig, QTextCursor::MoveAnchor);
- cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, endSig);
- cursor.setCharFormat(signFormat);
-
- // set the font style for the header
- int headEnd = content.indexOf("\n\n", start);
- cursor.setPosition(start, QTextCursor::MoveAnchor);
- cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, headEnd);
- cursor.setCharFormat(signFormat);
+void EditorPage::ReadFile() {
+ LOG(INFO) << "Called";
+
+ readDone = false;
+
+ auto text_page = this->getTextPage();
+ text_page->setReadOnly(true);
+ auto thread = new FileReadThread(this->fullFilePath.toStdString());
+
+ connect(thread, &FileReadThread::sendReadBlock, this,
+ &EditorPage::slotInsertText);
+
+ connect(thread, &FileReadThread::readDone, this, [=]() {
+ LOG(INFO) << "Thread read done";
+ text_page->document()->setModified(false);
+ text_page->setReadOnly(false);
+ });
+
+ connect(thread, &FileReadThread::finished, this, [=]() {
+ LOG(INFO) << "Thread finished";
+ thread->deleteLater();
+ readDone = true;
+ readThread = nullptr;
+ });
+
+ connect(this, &EditorPage::destroyed, [=]() {
+ LOG(INFO) << "RequestInterruption for readThread";
+ thread->requestInterruption();
+ readThread = nullptr;
+ });
+ this->readThread = thread;
+ thread->start();
+}
+void EditorPage::slotInsertText(const QString& text) {
+ this->getTextPage()->insertPlainText(text);
+}
+void EditorPage::PrepareToDestroy() {
+ if (readThread) {
+ readThread->requestInterruption();
+ readThread = nullptr;
+ }
}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/widgets/EditorPage.h b/src/ui/widgets/EditorPage.h
new file mode 100644
index 00000000..a0a05dab
--- /dev/null
+++ b/src/ui/widgets/EditorPage.h
@@ -0,0 +1,113 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef __EDITORPAGE_H__
+#define __EDITORPAGE_H__
+
+#include "gpg/GpgConstants.h"
+#include "ui/GpgFrontendUI.h"
+
+QT_BEGIN_NAMESPACE
+class QVBoxLayout;
+class QHBoxLayout;
+class QString;
+class QLabel;
+QT_END_NAMESPACE
+
+namespace GpgFrontend::UI {
+
+/**
+ * @brief Class for handling a single tab of the tabwidget
+ *
+ */
+class EditorPage : public QWidget {
+ Q_OBJECT
+ public:
+ /**
+ * @details Add layout and add plaintextedit
+ *
+ * @param filePath Path of the file handled in this tab
+ * @param parent Pointer to the parent widget
+ */
+ explicit EditorPage(QString filePath = "", QWidget* parent = nullptr);
+
+ /**
+ * @details Get the filepath of the currently activated tab.
+ */
+ [[nodiscard]] const QString& getFilePath() const;
+
+ /**
+ * @details Set filepath of currently activated tab.
+ *
+ * @param filePath The path to be set
+ */
+ void setFilePath(const QString& filePath);
+
+ /**
+ * @details Return pointer tp the textedit of the currently activated tab.
+ */
+ QTextEdit* getTextPage();
+
+ /**
+ * @details Show additional widget at buttom of currently active tab
+ *
+ * @param widget The widget to be added
+ * @param className The name to handle the added widget
+ */
+ void showNotificationWidget(QWidget* widget, const char* className);
+
+ /**
+ * @details Hide all widgets with the given className
+ *
+ * @param className The classname of the widgets to hide
+ */
+ void closeNoteByClass(const char* className);
+
+ void ReadFile();
+
+ [[nodiscard]] bool ReadDone() const { return this->readDone; }
+
+ void PrepareToDestroy();
+
+ private:
+ QTextEdit* textPage; /** The textedit of the tab */
+ QVBoxLayout* mainLayout; /** The layout for the tab */
+ QString fullFilePath; /** The path to the file handled in the tab */
+ bool signMarked{}; /** true, if the signed header is marked, false if not */
+ bool readDone = false;
+ QThread* readThread = nullptr;
+
+ private slots:
+
+ /**
+ * @details Format the gpg header in another font-style
+ */
+ void slotFormatGpgHeader();
+
+ void slotInsertText(const QString& text);
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // __EDITORPAGE_H__
diff --git a/src/ui/widgets/FilePage.cpp b/src/ui/widgets/FilePage.cpp
index b9602d58..2c8df5e4 100644
--- a/src/ui/widgets/FilePage.cpp
+++ b/src/ui/widgets/FilePage.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,244 +24,258 @@
#include "ui/widgets/FilePage.h"
-#include "MainWindow.h"
-
-FilePage::FilePage(QWidget *parent) : QWidget(parent) {
-
- qDebug() << "First Parent" << parent;
- firstParent = parent;
-
- qDebug() << "New File Page";
-
- dirModel = new QFileSystemModel();
- dirModel->setRootPath(QDir::currentPath());
-
- dirTreeView = new QTreeView();
- dirTreeView->setModel(dirModel);
- dirTreeView->setAnimated(true);
- dirTreeView->setIndentation(20);
- dirTreeView->setRootIndex(dirModel->index(QDir::currentPath()));
- dirTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
- mPath = dirModel->rootPath();
-
- createPopupMenu();
-
-
- upLevelButton = new QPushButton();
- connect(upLevelButton, SIGNAL(clicked(bool)), this, SLOT(slotUpLevel()));
-
- QString buttonStyle = "QPushButton{border:none;background-color:rgba(255, 255, 255,100);}";
-
-
- auto upPixmap = QPixmap(":up.png");
- upPixmap = upPixmap.scaled(18, 18, Qt::KeepAspectRatio, Qt::SmoothTransformation);
- QIcon upButtonIcon(upPixmap);
- upLevelButton->setIcon(upButtonIcon);
- upLevelButton->setIconSize(upPixmap.rect().size());
- upLevelButton->setStyleSheet(buttonStyle);
-
- refreshButton = new QPushButton("Refresh");
- connect(refreshButton, SIGNAL(clicked(bool)), this, SLOT(slotGoPath()));
-
- goPathButton = new QPushButton();
- connect(goPathButton, SIGNAL(clicked(bool)), this, SLOT(slotGoPath()));
-
- auto updatePixmap = QPixmap(":refresh.png");
- updatePixmap = updatePixmap.scaled(18, 18, Qt::KeepAspectRatio, Qt::SmoothTransformation);
- QIcon updateButtonIcon(updatePixmap);
- goPathButton->setIcon(updateButtonIcon);
- goPathButton->setIconSize(updatePixmap.rect().size());
- goPathButton->setStyleSheet(buttonStyle);
-
- pathEdit = new QLineEdit();
- pathEdit->setText(dirModel->rootPath());
+#include <boost/filesystem.hpp>
- auto *menuLayout = new QHBoxLayout();
- menuLayout->addWidget(upLevelButton);
- menuLayout->setStretchFactor(upLevelButton, 1);
- menuLayout->addWidget(pathEdit);
- menuLayout->setStretchFactor(pathEdit, 10);
- menuLayout->addWidget(goPathButton);
- menuLayout->setStretchFactor(goPathButton, 1);
- // menuLayout->addWidget(refreshButton);
- // menuLayout->setStretchFactor(refreshButton, 1);
-
- auto *layout = new QVBoxLayout();
- layout->setContentsMargins(0, 0, 0, 0);
- layout->setSpacing(0);
- layout->addLayout(menuLayout);
- layout->setStretchFactor(menuLayout, 1);
- layout->addWidget(dirTreeView);
- layout->setStretchFactor(dirTreeView, 8);
-
- this->setLayout(layout);
-
- connect(dirTreeView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(fileTreeViewItemClicked(const QModelIndex &)));
- connect(dirTreeView, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(fileTreeViewItemDoubleClicked(const QModelIndex &)));
- connect(dirTreeView, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onCustomContextMenu(const QPoint &)));
-
- emit pathChanged(mPath);
+#include "MainWindow.h"
+namespace GpgFrontend::UI {
+
+FilePage::FilePage(QWidget* parent) : QWidget(parent) {
+ firstParent = parent;
+ LOG(INFO) << "New File Page";
+
+ dirModel = new QFileSystemModel();
+ dirModel->setRootPath(QDir::currentPath());
+
+ dirTreeView = new QTreeView();
+ dirTreeView->setModel(dirModel);
+ dirTreeView->setAnimated(true);
+ dirTreeView->setIndentation(20);
+ dirTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
+ dirTreeView->setColumnWidth(0, 320);
+ dirTreeView->setRootIndex(dirModel->index(QDir::currentPath()));
+ mPath = boost::filesystem::path(dirModel->rootPath().toStdString());
+
+ createPopupMenu();
+
+ upLevelButton = new QPushButton();
+ connect(upLevelButton, SIGNAL(clicked(bool)), this, SLOT(slotUpLevel()));
+
+ QString buttonStyle =
+ "QPushButton{border:none;background-color:rgba(255, 255, 255, 0);}";
+
+ auto upPixmap = QPixmap(":up.png");
+ upPixmap =
+ upPixmap.scaled(18, 18, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ QIcon upButtonIcon(upPixmap);
+ upLevelButton->setIcon(upButtonIcon);
+ upLevelButton->setIconSize(upPixmap.rect().size());
+ upLevelButton->setStyleSheet(buttonStyle);
+
+ refreshButton = new QPushButton(_("Refresh"));
+ connect(refreshButton, SIGNAL(clicked(bool)), this, SLOT(slotGoPath()));
+
+ goPathButton = new QPushButton();
+ connect(goPathButton, SIGNAL(clicked(bool)), this, SLOT(slotGoPath()));
+
+ auto updatePixmap = QPixmap(":refresh.png");
+ updatePixmap = updatePixmap.scaled(18, 18, Qt::KeepAspectRatio,
+ Qt::SmoothTransformation);
+ QIcon updateButtonIcon(updatePixmap);
+ goPathButton->setIcon(updateButtonIcon);
+ goPathButton->setIconSize(updatePixmap.rect().size());
+ goPathButton->setStyleSheet(buttonStyle);
+
+ pathEdit = new QLineEdit();
+ pathEdit->setText(dirModel->rootPath());
+
+ auto* menuLayout = new QHBoxLayout();
+ menuLayout->addWidget(upLevelButton);
+ menuLayout->setStretchFactor(upLevelButton, 1);
+ menuLayout->addWidget(pathEdit);
+ menuLayout->setStretchFactor(pathEdit, 10);
+ menuLayout->addWidget(goPathButton);
+ menuLayout->setStretchFactor(goPathButton, 1);
+ // menuLayout->addWidget(refreshButton);
+ // menuLayout->setStretchFactor(refreshButton, 1);
+
+ auto* layout = new QVBoxLayout();
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->setSpacing(0);
+ layout->addLayout(menuLayout);
+ layout->setStretchFactor(menuLayout, 1);
+ layout->addWidget(dirTreeView);
+ layout->setStretchFactor(dirTreeView, 8);
+
+ this->setLayout(layout);
+
+ connect(dirTreeView, SIGNAL(clicked(const QModelIndex&)), this,
+ SLOT(fileTreeViewItemClicked(const QModelIndex&)));
+ connect(dirTreeView, SIGNAL(doubleClicked(const QModelIndex&)), this,
+ SLOT(fileTreeViewItemDoubleClicked(const QModelIndex&)));
+ connect(dirTreeView, SIGNAL(customContextMenuRequested(const QPoint&)), this,
+ SLOT(onCustomContextMenu(const QPoint&)));
+
+ // refresh
+ slotGoPath();
}
-void FilePage::fileTreeViewItemClicked(const QModelIndex &index) {
- selectedPath = dirModel->fileInfo(index).absoluteFilePath();
- qDebug() << "selectedPath" << selectedPath;
+void FilePage::fileTreeViewItemClicked(const QModelIndex& index) {
+ selectedPath = boost::filesystem::path(
+ dirModel->fileInfo(index).absoluteFilePath().toStdString());
+ LOG(INFO) << "selected path" << selectedPath;
}
void FilePage::slotUpLevel() {
- QModelIndex currentRoot = dirTreeView->rootIndex();
-
- mPath = dirModel->fileInfo(currentRoot).absoluteFilePath();
- QDir dir(mPath);
- dir.makeAbsolute();
- dir.setPath(QDir::cleanPath(dir.filePath(QStringLiteral(".."))));
- mPath = dir.absolutePath();
- auto fileInfo = QFileInfo(dir.absolutePath());
- if(fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) {
- pathEdit->setText(mPath);
- slotGoPath();
- }
- qDebug() << "Current Root mPath" << mPath;
- emit pathChanged(mPath);
-}
+ QModelIndex currentRoot = dirTreeView->rootIndex();
+
+ mPath = boost::filesystem::path(
+ dirModel->fileInfo(currentRoot).absoluteFilePath().toStdString());
-void FilePage::fileTreeViewItemDoubleClicked(const QModelIndex &index) {
- mPath = dirModel->fileInfo(index).absoluteFilePath();
- auto fileInfo = QFileInfo(mPath);
- auto targetModelIndex = dirTreeView->model()->index(index.row(), 0, index.parent());
- if(fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) {
- dirTreeView->setRootIndex(targetModelIndex);
- pathEdit->setText(mPath);
+ if (mPath.has_parent_path()) {
+ mPath = mPath.parent_path();
+ auto fileInfo = QFileInfo(QString::fromStdString(mPath.string()));
+ if (fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) {
+ pathEdit->setText(QString::fromStdString(mPath.string()));
+ slotGoPath();
}
- qDebug() << "Index mPath" << mPath;
- emit pathChanged(mPath);
+ LOG(INFO) << "Current Root mPath" << mPath;
+ emit pathChanged(QString::fromStdString(mPath.string()));
+ }
}
-QString FilePage::getSelected() const {
- return selectedPath;
+void FilePage::fileTreeViewItemDoubleClicked(const QModelIndex& index) {
+ mPath = boost::filesystem::path(
+ dirModel->fileInfo(index).absoluteFilePath().toStdString());
+ auto fileInfo = QFileInfo(QString::fromStdString(mPath.string()));
+ auto targetModelIndex =
+ dirTreeView->model()->index(index.row(), 0, index.parent());
+ if (fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) {
+ dirTreeView->setRootIndex(targetModelIndex);
+ pathEdit->setText(QString::fromStdString(mPath.string()));
+ }
+ for (int i = 1; i < dirModel->columnCount(); ++i)
+ dirTreeView->resizeColumnToContents(i);
+ LOG(INFO) << "Index mPath" << mPath;
+ emit pathChanged(QString::fromStdString(mPath.string()));
}
+QString FilePage::getSelected() const { return QString::fromStdString(selectedPath.string()); }
+
void FilePage::slotGoPath() {
- qDebug() << "getSelected" << pathEdit->text();
- auto fileInfo = QFileInfo(pathEdit->text());
- if(fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) {
- mPath = fileInfo.filePath();
- qDebug() << "Set Path" << mPath;
- dirTreeView->setRootIndex(dirModel->index(fileInfo.filePath()));
- } else {
- QMessageBox::critical(this, "Error", "The path is unprivileged or unreachable.");
- }
- emit pathChanged(mPath);
+ qDebug() << "getSelected" << pathEdit->text();
+ auto fileInfo = QFileInfo(pathEdit->text());
+ if (fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) {
+ mPath = boost::filesystem::path(fileInfo.filePath().toStdString());
+ LOG(INFO) << "Set Path" << mPath;
+ dirTreeView->setRootIndex(dirModel->index(fileInfo.filePath()));
+ for (int i = 1; i < dirModel->columnCount(); ++i)
+ dirTreeView->resizeColumnToContents(i);
+ } else {
+ QMessageBox::critical(this, "Error",
+ "The path is unprivileged or unreachable.");
+ }
+ emit pathChanged(QString::fromStdString(mPath.string()));
}
void FilePage::createPopupMenu() {
- popUpMenu = new QMenu();
-
- auto openItemAct = new QAction(tr("Open"), this);
- connect(openItemAct, SIGNAL(triggered()), this, SLOT(slotOpenItem()));
- auto deleteItemAct = new QAction(tr("Delete"), this);
- connect(deleteItemAct, SIGNAL(triggered()), this, SLOT(slotDeleteItem()));
- encryptItemAct = new QAction(tr("Encrypt and Sign"), this);
- connect(encryptItemAct, SIGNAL(triggered()), this, SLOT(slotEncryptItem()));
- decryptItemAct = new QAction(tr("Decrypt and Verify"), this);
- connect(decryptItemAct, SIGNAL(triggered()), this, SLOT(slotDecryptItem()));
- signItemAct = new QAction(tr("Only Sign"), this);
- connect(signItemAct, SIGNAL(triggered()), this, SLOT(slotSignItem()));
- verifyItemAct = new QAction(tr("Only Verify"), this);
- connect(verifyItemAct, SIGNAL(triggered()), this, SLOT(slotVerifyItem()));
-
- popUpMenu->addAction(openItemAct);
- popUpMenu->addAction(deleteItemAct);
- popUpMenu->addSeparator();
- popUpMenu->addAction(encryptItemAct);
- popUpMenu->addAction(decryptItemAct);
- popUpMenu->addAction(signItemAct);
- popUpMenu->addAction(verifyItemAct);
-
+ popUpMenu = new QMenu();
+
+ auto openItemAct = new QAction(_("Open"), this);
+ connect(openItemAct, SIGNAL(triggered()), this, SLOT(slotOpenItem()));
+ auto deleteItemAct = new QAction(_("Delete"), this);
+ connect(deleteItemAct, SIGNAL(triggered()), this, SLOT(slotDeleteItem()));
+ encryptItemAct = new QAction(_("Encrypt and Sign"), this);
+ connect(encryptItemAct, SIGNAL(triggered()), this, SLOT(slotEncryptItem()));
+ decryptItemAct = new QAction(_("Decrypt and Verify"), this);
+ connect(decryptItemAct, SIGNAL(triggered()), this, SLOT(slotDecryptItem()));
+ signItemAct = new QAction(_("Only Sign"), this);
+ connect(signItemAct, SIGNAL(triggered()), this, SLOT(slotSignItem()));
+ verifyItemAct = new QAction(_("Only Verify"), this);
+ connect(verifyItemAct, SIGNAL(triggered()), this, SLOT(slotVerifyItem()));
+
+ popUpMenu->addAction(openItemAct);
+ popUpMenu->addAction(deleteItemAct);
+ popUpMenu->addSeparator();
+ popUpMenu->addAction(encryptItemAct);
+ popUpMenu->addAction(decryptItemAct);
+ popUpMenu->addAction(signItemAct);
+ popUpMenu->addAction(verifyItemAct);
}
-void FilePage::onCustomContextMenu(const QPoint &point) {
- QModelIndex index = dirTreeView->indexAt(point);
- selectedPath = dirModel->fileInfo(index).absoluteFilePath();
- qDebug() << "Right Click" << selectedPath;
- if (index.isValid()) {
- QFileInfo info(selectedPath);
- encryptItemAct->setEnabled(info.isFile() && (info.suffix() != "gpg" && info.suffix() != "sig"));
- decryptItemAct->setEnabled(info.isFile() && info.suffix() == "gpg");
- signItemAct->setEnabled(info.isFile() && (info.suffix() != "gpg" && info.suffix() != "sig"));
- verifyItemAct->setEnabled(info.isFile() && (info.suffix() == "sig" || info.suffix() == "gpg"));
-
- popUpMenu->exec(dirTreeView->viewport()->mapToGlobal(point));
- }
+void FilePage::onCustomContextMenu(const QPoint& point) {
+ QModelIndex index = dirTreeView->indexAt(point);
+ selectedPath = boost::filesystem::path(
+ dirModel->fileInfo(index).absoluteFilePath().toStdString());
+ LOG(INFO) << "FilePage::onCustomContextMenu Right Click" << selectedPath;
+ if (index.isValid()) {
+ QFileInfo info(QString::fromStdString(selectedPath.string()));
+ encryptItemAct->setEnabled(
+ info.isFile() && (info.suffix() != "gpg" && info.suffix() != "sig"));
+ decryptItemAct->setEnabled(info.isFile() && info.suffix() == "gpg");
+ signItemAct->setEnabled(info.isFile() &&
+ (info.suffix() != "gpg" && info.suffix() != "sig"));
+ verifyItemAct->setEnabled(
+ info.isFile() && (info.suffix() == "sig" || info.suffix() == "gpg"));
+
+ popUpMenu->exec(dirTreeView->viewport()->mapToGlobal(point));
+ }
}
void FilePage::slotOpenItem() {
- QFileInfo info(mPath);
- if(info.isDir()) {
- qDebug() << "getSelected" << pathEdit->text();
- if(info.isReadable() && info.isExecutable()) {
- qDebug() << "Set Path" << info.filePath();
- dirTreeView->setRootIndex(dirModel->index(info.filePath()));
- } else {
- QMessageBox::critical(this, "Error", "The path is unprivileged or unreachable.");
- }
+ QFileInfo info(QString::fromStdString(selectedPath.string()));
+ if (info.isDir()) {
+ LOG(INFO) << "FilePage::slotOpenItem getSelected"
+ << pathEdit->text().toStdString();
+ if (info.isReadable() && info.isExecutable()) {
+ LOG(INFO) << "FilePage::slotOpenItem Set Path"
+ << info.filePath().toStdString();
+ dirTreeView->setRootIndex(dirModel->index(info.filePath()));
} else {
- auto mainWindow = qobject_cast<MainWindow *>(firstParent);
- qDebug() << "Open Item" << mPath;
- if (mainWindow != nullptr)
- mainWindow->slotOpenFile(mPath);
+ QMessageBox::critical(this, "Error",
+ "The path is unprivileged or unreachable.");
}
+ } else {
+ auto mainWindow = qobject_cast<MainWindow*>(firstParent);
+ LOG(INFO) << "FilePage::slotOpenItem Open Item" << selectedPath;
+ auto qt_path = QString::fromStdString(selectedPath.string());
+ if (mainWindow != nullptr) mainWindow->slotOpenFile(qt_path);
+ }
}
void FilePage::slotDeleteItem() {
- QModelIndex index = dirTreeView->currentIndex();
- QVariant data = dirTreeView->model()->data(index);
+ QModelIndex index = dirTreeView->currentIndex();
+ QVariant data = dirTreeView->model()->data(index);
- auto ret = QMessageBox::warning(this,
- tr("Warning"),
- tr("Are you sure you want to delete it?"),
- QMessageBox::Ok | QMessageBox::Cancel);
+ auto ret = QMessageBox::warning(this, _("Warning"),
+ _("Are you sure you want to delete it?"),
+ QMessageBox::Ok | QMessageBox::Cancel);
- if(ret == QMessageBox::Cancel)
- return;
+ if (ret == QMessageBox::Cancel) return;
- qDebug() << "Delete Item" << data.toString();
+ qDebug() << "Delete Item" << data.toString();
- if(!dirModel->remove(index)){
- QMessageBox::critical(this,
- tr("Error"),
- tr("Unable to delete the file or folder."));
- }
+ if (!dirModel->remove(index)) {
+ QMessageBox::critical(this, _("Error"),
+ _("Unable to delete the file or folder."));
+ }
}
void FilePage::slotEncryptItem() {
- auto mainWindow = qobject_cast<MainWindow *>(firstParent);
- if(mainWindow != nullptr)
- mainWindow->slotFileEncryptSign();
+ auto mainWindow = qobject_cast<MainWindow*>(firstParent);
+ if (mainWindow != nullptr) mainWindow->slotFileEncryptSign();
}
void FilePage::slotDecryptItem() {
- auto mainWindow = qobject_cast<MainWindow *>(firstParent);
- if(mainWindow != nullptr)
- mainWindow->slotFileDecryptVerify();
+ auto mainWindow = qobject_cast<MainWindow*>(firstParent);
+ if (mainWindow != nullptr) mainWindow->slotFileDecryptVerify();
}
void FilePage::slotSignItem() {
- auto mainWindow = qobject_cast<MainWindow *>(firstParent);
- if(mainWindow != nullptr)
- mainWindow->slotFileSign();
+ auto mainWindow = qobject_cast<MainWindow*>(firstParent);
+ if (mainWindow != nullptr) mainWindow->slotFileSign();
}
void FilePage::slotVerifyItem() {
- auto mainWindow = qobject_cast<MainWindow *>(firstParent);
- if(mainWindow != nullptr)
- mainWindow->slotFileVerify();
+ auto mainWindow = qobject_cast<MainWindow*>(firstParent);
+ if (mainWindow != nullptr) mainWindow->slotFileVerify();
}
-void FilePage::keyPressEvent(QKeyEvent *event) {
- qDebug() << "Key Press" << event->key();
- if(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
- slotGoPath();
- }
+void FilePage::keyPressEvent(QKeyEvent* event) {
+ qDebug() << "Key Press" << event->key();
+ if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
+ slotGoPath();
+ }
}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/widgets/FilePage.h b/src/ui/widgets/FilePage.h
new file mode 100644
index 00000000..31be81f3
--- /dev/null
+++ b/src/ui/widgets/FilePage.h
@@ -0,0 +1,90 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_FILEPAGE_H
+#define GPGFRONTEND_FILEPAGE_H
+
+#include <boost/filesystem.hpp>
+
+#include "ui/GpgFrontendUI.h"
+
+namespace GpgFrontend::UI {
+
+class FilePage : public QWidget {
+ Q_OBJECT
+ public:
+ explicit FilePage(QWidget* parent = nullptr);
+
+ [[nodiscard]] QString getSelected() const;
+
+ void createPopupMenu();
+
+ signals:
+ void pathChanged(const QString& path);
+
+ private slots:
+
+ void fileTreeViewItemClicked(const QModelIndex& index);
+ void fileTreeViewItemDoubleClicked(const QModelIndex& index);
+
+ void slotUpLevel();
+ void slotGoPath();
+
+ void slotOpenItem();
+ void slotDeleteItem();
+ void slotEncryptItem();
+ void slotDecryptItem();
+ void slotSignItem();
+ void slotVerifyItem();
+
+ void onCustomContextMenu(const QPoint& point);
+
+ protected:
+ void keyPressEvent(QKeyEvent* event) override;
+
+ private:
+ QFileSystemModel* dirModel;
+ QTreeView* dirTreeView;
+ QLineEdit* pathEdit;
+
+ // using boost path
+ boost::filesystem::path mPath;
+ boost::filesystem::path selectedPath;
+
+ QPushButton* upLevelButton;
+ QPushButton* goPathButton;
+ QPushButton* refreshButton;
+
+ QMenu* popUpMenu{};
+ QAction* encryptItemAct{};
+ QAction* decryptItemAct{};
+ QAction* signItemAct{};
+ QAction* verifyItemAct{};
+
+ QWidget* firstParent;
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_FILEPAGE_H
diff --git a/src/ui/widgets/GroupKeyList.cpp b/src/ui/widgets/GroupKeyList.cpp
new file mode 100644
index 00000000..efba4428
--- /dev/null
+++ b/src/ui/widgets/GroupKeyList.cpp
@@ -0,0 +1,25 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "GroupKeyList.h"
diff --git a/src/ui/widgets/GroupKeyList.h b/src/ui/widgets/GroupKeyList.h
new file mode 100644
index 00000000..163c7126
--- /dev/null
+++ b/src/ui/widgets/GroupKeyList.h
@@ -0,0 +1,34 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_GROUPKEYLIST_H
+#define GPGFRONTEND_GROUPKEYLIST_H
+
+#include "ui/GpgFrontendUI.h"
+
+class GroupKeyList : public QWidget {
+ Q_OBJECT
+};
+
+#endif // GPGFRONTEND_GROUPKEYLIST_H
diff --git a/src/ui/widgets/HelpPage.cpp b/src/ui/widgets/HelpPage.cpp
index e018da81..7b1e86c0 100644
--- a/src/ui/widgets/HelpPage.cpp
+++ b/src/ui/widgets/HelpPage.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -26,25 +26,24 @@
#include <utility>
-HelpPage::HelpPage(const QString &path, QWidget *parent) :
- QWidget(parent) {
+namespace GpgFrontend::UI {
- browser = new QTextBrowser();
- auto *mainLayout = new QVBoxLayout();
- mainLayout->setSpacing(0);
- mainLayout->addWidget(browser);
- mainLayout->setContentsMargins(0, 0, 0, 0);
- setLayout(mainLayout);
-
- connect(browser, SIGNAL(anchorClicked(QUrl)), this, SLOT(slotOpenUrl(QUrl)));
- browser->setOpenLinks(false);
- browser->setSource(localizedHelp(QUrl(path)));
- browser->setFocus();
+HelpPage::HelpPage(const QString& path, QWidget* parent) : QWidget(parent) {
+ browser = new QTextBrowser();
+ auto* mainLayout = new QVBoxLayout();
+ mainLayout->setSpacing(0);
+ mainLayout->addWidget(browser);
+ mainLayout->setContentsMargins(0, 0, 0, 0);
+ setLayout(mainLayout);
+ connect(browser, SIGNAL(anchorClicked(QUrl)), this, SLOT(slotOpenUrl(QUrl)));
+ browser->setOpenLinks(false);
+ browser->setSource(localizedHelp(QUrl(path)));
+ browser->setFocus();
}
-void HelpPage::slotOpenUrl(const QUrl &url) {
- browser->setSource(localizedHelp(url));
+void HelpPage::slotOpenUrl(const QUrl& url) {
+ browser->setSource(localizedHelp(url));
};
/**
@@ -55,29 +54,29 @@ void HelpPage::slotOpenUrl(const QUrl &url) {
* @param url
* @return
*/
-QUrl HelpPage::localizedHelp(const QUrl &url) {
- QString path = url.toLocalFile();
- QString filename = path.mid(path.lastIndexOf("/") + 1);
- QString filepath = path.left(path.lastIndexOf("/") + 1);
- QStringList fileparts = filename.split(".");
-
- //QSettings settings;
- QString lang = QSettings().value("int/lang", QLocale::system().name()).toString();
- if (lang.isEmpty()) {
- lang = QLocale::system().name();
- }
+QUrl HelpPage::localizedHelp(const QUrl& url) {
+ QString path = url.toLocalFile();
+ QString filename = path.mid(path.lastIndexOf("/") + 1);
+ QString filepath = path.left(path.lastIndexOf("/") + 1);
+ QStringList fileparts = filename.split(".");
- fileparts.insert(1, lang);
- QString langfile = filepath + fileparts.join(".");
+ // QSettings settings;
+ QString lang =
+ QSettings().value("int/lang", QLocale::system().name()).toString();
+ if (lang.isEmpty()) {
+ lang = QLocale::system().name();
+ }
- if (QFile(QUrl(langfile).toLocalFile()).exists()) {
- return langfile;
- } else {
- return path;
- }
+ fileparts.insert(1, lang);
+ QString langfile = filepath + fileparts.join(".");
+ if (QFile(QUrl(langfile).toLocalFile()).exists()) {
+ return langfile;
+ } else {
+ return path;
+ }
}
-QTextBrowser *HelpPage::getBrowser() {
- return browser;
-}
+QTextBrowser* HelpPage::getBrowser() { return browser; }
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/widgets/HelpPage.h b/src/ui/widgets/HelpPage.h
new file mode 100644
index 00000000..25490557
--- /dev/null
+++ b/src/ui/widgets/HelpPage.h
@@ -0,0 +1,49 @@
+/*
+ * helppage.h
+ *
+ * Copyright 2008 gpg4usb-team <[email protected]>
+ *
+ * This file is part of gpg4usb.
+ *
+ * Gpg4usb is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Gpg4usb is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with gpg4usb. If not, see <http://www.gnu.org/licenses/>
+ */
+
+#ifndef HELPPAGE_H
+#define HELPPAGE_H
+
+#include "ui/GpgFrontendUI.h"
+
+namespace GpgFrontend::UI {
+
+class HelpPage : public QWidget {
+ Q_OBJECT
+ public:
+ explicit HelpPage(const QString& path, QWidget* parent = nullptr);
+
+ QTextBrowser* getBrowser();
+
+ signals:
+
+ public slots:
+
+ void slotOpenUrl(const QUrl& url);
+
+ private:
+ QTextBrowser* browser; /** The textbrowser of the tab */
+ QUrl localizedHelp(const QUrl& path);
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // HELPPAGE_H
diff --git a/src/ui/widgets/InfoBoardWidget.cpp b/src/ui/widgets/InfoBoardWidget.cpp
index b9372c59..cd469422 100644
--- a/src/ui/widgets/InfoBoardWidget.cpp
+++ b/src/ui/widgets/InfoBoardWidget.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,170 +24,193 @@
#include "ui/widgets/InfoBoardWidget.h"
-InfoBoardWidget::InfoBoardWidget(QWidget *parent, GpgME::GpgContext *ctx, KeyList *keyList) :
- QWidget(parent), mCtx(ctx), mKeyList(keyList), appPath(qApp->applicationDirPath()),
- settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini",
- QSettings::IniFormat) {
-
- infoBoard = new QTextEdit(this);
- infoBoard->setReadOnly(true);
- infoBoard->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
- infoBoard->setMinimumWidth(480);
- infoBoard->setContentsMargins(0, 0, 0, 0);
-
- connect(mCtx, SIGNAL(signalKeyInfoChanged()), this, SLOT(slotReset()));
-
- importFromKeyserverAct = new QAction(tr("Import missing key from Keyserver"), this);
- connect(importFromKeyserverAct, SIGNAL(triggered()), this, SLOT(slotImportFromKeyserver()));
-
- detailMenu = new QMenu(this);
- detailMenu->addAction(importFromKeyserverAct);
- importFromKeyserverAct->setVisible(false);
-
- auto *actionButtonMenu = new QWidget();
- actionButtonMenu->setContentsMargins(0, 0, 0, 0);
- actionButtonMenu->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
- actionButtonMenu->setFixedHeight(36);
-
- actionButtonLayout = new QHBoxLayout();
- actionButtonLayout->setContentsMargins(5, 5, 5, 5);
- actionButtonLayout->setSpacing(0);
- actionButtonMenu->setLayout(actionButtonLayout);
-
- auto label = new QLabel(tr("Optional Actions"));
- label->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
- label->setContentsMargins(0, 0, 0, 0);
-
- actionButtonLayout->addWidget(label);
- actionButtonLayout->addStretch();
-
-
- QFrame *line;
- line = new QFrame(this);
- line->setFrameShape(QFrame::HLine);
- line->setFrameShadow(QFrame::Sunken);
- line->setContentsMargins(0, 0, 0, 0);
-
- auto *notificationWidgetLayout = new QVBoxLayout(this);
- notificationWidgetLayout->setContentsMargins(0, 0, 0, 0);
- notificationWidgetLayout->setSpacing(0);
-
- notificationWidgetLayout->addWidget(infoBoard);
- notificationWidgetLayout->setStretchFactor(infoBoard, 10);
- notificationWidgetLayout->addWidget(actionButtonMenu);
- notificationWidgetLayout->setStretchFactor(actionButtonMenu, 1);
- notificationWidgetLayout->addWidget(line);
- notificationWidgetLayout->setStretchFactor(line, 1);
- notificationWidgetLayout->addStretch(0);
- this->setLayout(notificationWidgetLayout);
+#include "ui/settings/GlobalSettingStation.h"
+
+namespace GpgFrontend::UI {
+
+InfoBoardWidget::InfoBoardWidget(QWidget* parent, KeyList* keyList)
+ : QWidget(parent), mKeyList(keyList) {
+ infoBoard = new QTextEdit(this);
+ infoBoard->setReadOnly(true);
+ infoBoard->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
+ infoBoard->setMinimumWidth(480);
+ infoBoard->setContentsMargins(0, 0, 0, 0);
+
+ importFromKeyserverAct =
+ new QAction(_("Import missing key from Keyserver"), this);
+ connect(importFromKeyserverAct, SIGNAL(triggered()), this,
+ SLOT(slotImportFromKeyserver()));
+
+ detailMenu = new QMenu(this);
+ detailMenu->addAction(importFromKeyserverAct);
+ importFromKeyserverAct->setVisible(false);
+
+ auto* actionButtonMenu = new QWidget();
+ actionButtonMenu->setContentsMargins(0, 0, 0, 0);
+ actionButtonMenu->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
+ actionButtonMenu->setFixedHeight(36);
+
+ actionButtonLayout = new QHBoxLayout();
+ actionButtonLayout->setContentsMargins(5, 5, 5, 5);
+ actionButtonLayout->setSpacing(0);
+ actionButtonMenu->setLayout(actionButtonLayout);
+
+ auto label = new QLabel(_("Optional Actions"));
+ label->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+ label->setContentsMargins(0, 0, 0, 0);
+
+ actionButtonLayout->addWidget(label);
+ actionButtonLayout->addStretch();
+
+ QFrame* line;
+ line = new QFrame(this);
+ line->setFrameShape(QFrame::HLine);
+ line->setFrameShadow(QFrame::Sunken);
+ line->setContentsMargins(0, 0, 0, 0);
+
+ auto* notificationWidgetLayout = new QVBoxLayout(this);
+ notificationWidgetLayout->setContentsMargins(0, 0, 0, 0);
+ notificationWidgetLayout->setSpacing(0);
+
+ notificationWidgetLayout->addWidget(infoBoard);
+ notificationWidgetLayout->setStretchFactor(infoBoard, 10);
+ notificationWidgetLayout->addWidget(actionButtonMenu);
+ notificationWidgetLayout->setStretchFactor(actionButtonMenu, 1);
+ notificationWidgetLayout->addWidget(line);
+ notificationWidgetLayout->setStretchFactor(line, 1);
+ notificationWidgetLayout->addStretch(0);
+ this->setLayout(notificationWidgetLayout);
+
+ // set default size
+ infoBoard->resize(480, 120);
+ resize(480, 120);
}
void InfoBoardWidget::slotImportFromKeyserver() {
- auto *importDialog = new KeyServerImportDialog(mCtx, mKeyList, false, this);
- importDialog->slotImport(*keysNotInList);
+ auto* importDialog = new KeyServerImportDialog(false, this);
+ auto key_ids = std::make_unique<KeyIdArgsList>();
+ for (const auto& key_id : *keysNotInList) {
+ key_ids->push_back(key_id.toStdString());
+ }
+ importDialog->slotImport(key_ids);
}
-void InfoBoardWidget::setInfoBoard(const QString &text, InfoBoardStatus verifyLabelStatus) {
- QString color;
- infoBoard->clear();
- switch (verifyLabelStatus) {
- case INFO_ERROR_OK:
- color = "#008000";
- break;
- case INFO_ERROR_WARN:
- color = "#FF8C00";
- break;
- case INFO_ERROR_CRITICAL:
- color = "#DC143C";
- break;
- default:
- break;
- }
- infoBoard->append(text);
-
- infoBoard->setAutoFillBackground(true);
- QPalette status = infoBoard->palette();
- status.setColor(QPalette::Text, color);
- infoBoard->setPalette(status);
- auto infoBoardFontSize = settings.value("informationBoard/fontSize", 10).toInt();
- infoBoard->setFont(QFont("Times", infoBoardFontSize));
+void InfoBoardWidget::setInfoBoard(const QString& text,
+ InfoBoardStatus verifyLabelStatus) {
+ QString color;
+ infoBoard->clear();
+ switch (verifyLabelStatus) {
+ case INFO_ERROR_OK:
+ color = "#008000";
+ break;
+ case INFO_ERROR_WARN:
+ color = "#FF8C00";
+ break;
+ case INFO_ERROR_CRITICAL:
+ color = "#DC143C";
+ break;
+ default:
+ break;
+ }
+ infoBoard->append(text);
+
+ infoBoard->setAutoFillBackground(true);
+ QPalette status = infoBoard->palette();
+ status.setColor(QPalette::Text, color);
+ infoBoard->setPalette(status);
+
+ auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
+
+ // info board font size
+ auto info_font_size = 10;
+ try {
+ info_font_size = settings.lookup("window.info_font_size");
+ if (info_font_size < 9 || info_font_size > 18) info_font_size = 10;
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("info_font_size");
+ }
+ infoBoard->setFont(QFont("Times", info_font_size));
}
-void InfoBoardWidget::slotRefresh(const QString &text, InfoBoardStatus status) {
- infoBoard->clear();
- setInfoBoard(text, status);
- infoBoard->verticalScrollBar()->setValue(0);
+void InfoBoardWidget::slotRefresh(const QString& text, InfoBoardStatus status) {
+ infoBoard->clear();
+ setInfoBoard(text, status);
+ infoBoard->verticalScrollBar()->setValue(0);
}
-void InfoBoardWidget::associateTextEdit(QTextEdit *edit) {
- if (mTextPage != nullptr)
- disconnect(mTextPage, SIGNAL(textChanged()), this, SLOT(slotReset()));
- this->mTextPage = edit;
- connect(edit, SIGNAL(textChanged()), this, SLOT(slotReset()));
+void InfoBoardWidget::associateTextEdit(QTextEdit* edit) {
+ if (mTextPage != nullptr)
+ disconnect(mTextPage, SIGNAL(textChanged()), this, SLOT(slotReset()));
+ this->mTextPage = edit;
+ connect(edit, SIGNAL(textChanged()), this, SLOT(slotReset()));
}
-void InfoBoardWidget::associateFileTreeView(FilePage *treeView) {
-// if (mFileTreeView != nullptr)
-// disconnect(mFileTreeView, &FilePage::pathChanged, this, &InfoBoardWidget::slotReset);
-// this->mFileTreeView = treeView;
-// connect(treeView, &FilePage::pathChanged, this, &InfoBoardWidget::slotReset);
+void InfoBoardWidget::associateFileTreeView(FilePage* treeView) {
+ // if (mFileTreeView != nullptr)
+ // disconnect(mFileTreeView, &FilePage::pathChanged, this,
+ // &InfoBoardWidget::slotReset);
+ // this->mFileTreeView = treeView;
+ // connect(treeView, &FilePage::pathChanged, this,
+ // &InfoBoardWidget::slotReset);
}
-void InfoBoardWidget::associateTabWidget(QTabWidget *tab) {
- if (mTextPage != nullptr)
- disconnect(mTextPage, SIGNAL(textChanged()), this, SLOT(slotReset()));
-// if (mFileTreeView != nullptr)
-// disconnect(mFileTreeView, &FilePage::pathChanged, this, &InfoBoardWidget::slotReset);
- if (mTabWidget != nullptr) {
- disconnect(mTabWidget, SIGNAL(tabBarClicked(int)), this, SLOT(slotReset()));
- connect(mTabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(slotReset()));
- }
-
- mTextPage = nullptr;
- mFileTreeView = nullptr;
- mTabWidget = tab;
- connect(tab, SIGNAL(tabBarClicked(int)), this, SLOT(slotReset()));
- connect(tab, SIGNAL(tabCloseRequested(int)), this, SLOT(slotReset()));
+void InfoBoardWidget::associateTabWidget(QTabWidget* tab) {
+ if (mTextPage != nullptr)
+ disconnect(mTextPage, SIGNAL(textChanged()), this, SLOT(slotReset()));
+ // if (mFileTreeView != nullptr)
+ // disconnect(mFileTreeView, &FilePage::pathChanged, this,
+ // &InfoBoardWidget::slotReset);
+ if (mTabWidget != nullptr) {
+ disconnect(mTabWidget, SIGNAL(tabBarClicked(int)), this, SLOT(slotReset()));
+ connect(mTabWidget, SIGNAL(tabCloseRequested(int)), this,
+ SLOT(slotReset()));
+ }
+
+ mTextPage = nullptr;
+ mFileTreeView = nullptr;
+ mTabWidget = tab;
+ connect(tab, SIGNAL(tabBarClicked(int)), this, SLOT(slotReset()));
+ connect(tab, SIGNAL(tabCloseRequested(int)), this, SLOT(slotReset()));
}
-
-void InfoBoardWidget::addOptionalAction(const QString &name, const std::function<void()> &action) {
- auto actionButton = new QPushButton(name);
- auto layout = new QHBoxLayout();
- layout->setContentsMargins(5, 0, 5, 0);
- infoBoard->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
- // set margin from surroundings
- layout->addWidget(actionButton);
- actionButtonLayout->addLayout(layout);
- connect(actionButton, &QPushButton::clicked, this, [=]() {
- action();
- });
+void InfoBoardWidget::addOptionalAction(const QString& name,
+ const std::function<void()>& action) {
+ auto actionButton = new QPushButton(name);
+ auto layout = new QHBoxLayout();
+ layout->setContentsMargins(5, 0, 5, 0);
+ infoBoard->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+ // set margin from surroundings
+ layout->addWidget(actionButton);
+ actionButtonLayout->addLayout(layout);
+ connect(actionButton, &QPushButton::clicked, this, [=]() { action(); });
}
/**
* Delete All item in actionButtonLayout
*/
void InfoBoardWidget::resetOptionActionsMenu() {
- deleteWidgetsInLayout(actionButtonLayout, 2);
+ deleteWidgetsInLayout(actionButtonLayout, 2);
}
void InfoBoardWidget::slotReset() {
- this->infoBoard->clear();
- resetOptionActionsMenu();
+ this->infoBoard->clear();
+ resetOptionActionsMenu();
}
/**
* Try Delete all widget from target layout
* @param layout target layout
*/
-void InfoBoardWidget::deleteWidgetsInLayout(QLayout *layout, int start_index) {
- QLayoutItem *item;
- while ((item = layout->layout()->takeAt(start_index)) != nullptr) {
- layout->removeItem(item);
- if (item->layout() != nullptr)
- deleteWidgetsInLayout(item->layout());
- else if (item->widget() != nullptr)
- delete item->widget();
- delete item;
- }
+void InfoBoardWidget::deleteWidgetsInLayout(QLayout* layout, int start_index) {
+ QLayoutItem* item;
+ while ((item = layout->layout()->takeAt(start_index)) != nullptr) {
+ layout->removeItem(item);
+ if (item->layout() != nullptr)
+ deleteWidgetsInLayout(item->layout());
+ else if (item->widget() != nullptr)
+ delete item->widget();
+ delete item;
+ }
}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/widgets/InfoBoardWidget.h b/src/ui/widgets/InfoBoardWidget.h
new file mode 100644
index 00000000..1a13e1a2
--- /dev/null
+++ b/src/ui/widgets/InfoBoardWidget.h
@@ -0,0 +1,115 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef __VERIFYNOTIFICATION_H__
+#define __VERIFYNOTIFICATION_H__
+
+#include "EditorPage.h"
+#include "FilePage.h"
+#include "gpg/result_analyse/VerifyResultAnalyse.h"
+#include "ui/VerifyDetailsDialog.h"
+
+namespace GpgFrontend::UI {
+/**
+ * @details Enumeration for the status of Verifylabel
+ */
+typedef enum {
+ INFO_ERROR_OK = 0,
+ INFO_ERROR_WARN = 1,
+ INFO_ERROR_CRITICAL = 2,
+ INFO_ERROR_NEUTRAL = 3,
+} InfoBoardStatus;
+
+/**
+ * @brief Class for handling the verifylabel shown at buttom of a textedit-page
+ */
+class InfoBoardWidget : public QWidget {
+ Q_OBJECT
+ public:
+ /**
+ * @brief
+ *
+ * @param ctx The GPGme-Context
+ * @param parent The parent widget
+ */
+ explicit InfoBoardWidget(QWidget* parent, KeyList* keyList);
+
+ void associateTextEdit(QTextEdit* edit);
+
+ void associateFileTreeView(FilePage* treeView);
+
+ void associateTabWidget(QTabWidget* tab);
+
+ void addOptionalAction(const QString& name,
+ const std::function<void()>& action);
+
+ void resetOptionActionsMenu();
+
+ /**
+ * @details Set the text and background-color of verify notification.
+ *
+ * @param text The text to be set.
+ * @param verifyLabelStatus The status of label to set the specified color.
+ */
+ void setInfoBoard(const QString& text, InfoBoardStatus verifyLabelStatus);
+
+ QStringList* keysNotInList; /** List with keys, which are in signature but not
+ in keylist */
+
+ public slots:
+
+ /**
+ * @details Import the keys contained in keysNotInList from keyserver
+ *
+ */
+ void slotImportFromKeyserver();
+
+ void slotReset();
+
+ /**
+ * @details Refresh the contents of dialog.
+ */
+ void slotRefresh(const QString& text, InfoBoardStatus status);
+
+ private:
+ QMenu* detailMenu; /** Menu for te Button in verfiyNotification */
+ QAction* importFromKeyserverAct; /** Action for importing keys from keyserver
+ which are notin keylist */
+ QTextEdit* infoBoard;
+ KeyList* mKeyList; /** Table holding the keys */
+
+ QTextEdit* mTextPage{nullptr}; /** TextEdit associated to the notification */
+ FilePage* mFileTreeView{
+ nullptr}; /** TreeView associated to the notification */
+ QTabWidget* mTabWidget{
+ nullptr}; /** TreeView associated to the notification */
+
+ QHBoxLayout* actionButtonLayout;
+
+ void deleteWidgetsInLayout(QLayout* layout, int start_index = 0);
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // __VERIFYNOTIFICATION_H__ \ No newline at end of file
diff --git a/src/ui/widgets/KeyList.cpp b/src/ui/widgets/KeyList.cpp
index 9c9c6763..f9f33d78 100644
--- a/src/ui/widgets/KeyList.cpp
+++ b/src/ui/widgets/KeyList.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -26,394 +26,385 @@
#include <utility>
-KeyList::KeyList(GpgME::GpgContext *ctx,
- KeyListRow::KeyType selectType,
- KeyListColumn::InfoType infoType,
- QWidget *parent)
- : QWidget(parent), mSelectType(selectType), mInfoType(infoType), appPath(qApp->applicationDirPath()),
- settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", QSettings::IniFormat) {
- mCtx = ctx;
-
-
- mKeyList = new QTableWidget(this);
- mKeyList->setColumnCount(7);
- mKeyList->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
- mKeyList->verticalHeader()->hide();
- mKeyList->setShowGrid(false);
- mKeyList->sortByColumn(2, Qt::AscendingOrder);
- mKeyList->setSelectionBehavior(QAbstractItemView::SelectRows);
- mKeyList->setSelectionMode(QAbstractItemView::SingleSelection);
-
- // tableitems not editable
- mKeyList->setEditTriggers(QAbstractItemView::NoEditTriggers);
- // no focus (rectangle around tableitems)
- // may be it should focus on whole row
- mKeyList->setFocusPolicy(Qt::NoFocus);
-
- mKeyList->setAlternatingRowColors(true);
-
- // Hidden Column For Purpose
- if (!(mInfoType & KeyListColumn::TYPE)) {
- mKeyList->setColumnHidden(1, true);
- }
- if (!(mInfoType & KeyListColumn::NAME)) {
- mKeyList->setColumnHidden(2, true);
- }
- if (!(mInfoType & KeyListColumn::EmailAddress)) {
- mKeyList->setColumnHidden(3, true);
- }
- if (!(mInfoType & KeyListColumn::Usage)) {
- mKeyList->setColumnHidden(4, true);
- }
- if (!(mInfoType & KeyListColumn::Validity)) {
- mKeyList->setColumnHidden(5, true);
- }
- if (!(mInfoType & KeyListColumn::FingerPrint)) {
- mKeyList->setColumnHidden(6, true);
- }
+#include "gpg/function/GpgKeyGetter.h"
+#include "ui/SignalStation.h"
+
+namespace GpgFrontend::UI {
+
+KeyList::KeyList(KeyListRow::KeyType selectType,
+ KeyListColumn::InfoType infoType, QWidget* parent)
+ : QWidget(parent),
+ appPath(qApp->applicationDirPath()),
+ settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini",
+ QSettings::IniFormat),
+ mSelectType(selectType),
+ mInfoType(infoType) {
+ mKeyList = new QTableWidget(this);
+ mKeyList->setColumnCount(7);
+ mKeyList->horizontalHeader()->setSectionResizeMode(
+ QHeaderView::ResizeToContents);
+ mKeyList->verticalHeader()->hide();
+ mKeyList->setShowGrid(false);
+ mKeyList->sortByColumn(2, Qt::AscendingOrder);
+ mKeyList->setSelectionBehavior(QAbstractItemView::SelectRows);
+ mKeyList->setSelectionMode(QAbstractItemView::SingleSelection);
+
+ // table items not editable
+ mKeyList->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ // no focus (rectangle around table items)
+ // maybe it should focus on whole row
+ mKeyList->setFocusPolicy(Qt::NoFocus);
+
+ mKeyList->setAlternatingRowColors(true);
+
+ // Hidden Column For Purpose
+ if (!(mInfoType & KeyListColumn::TYPE)) {
+ mKeyList->setColumnHidden(1, true);
+ }
+ if (!(mInfoType & KeyListColumn::NAME)) {
+ mKeyList->setColumnHidden(2, true);
+ }
+ if (!(mInfoType & KeyListColumn::EmailAddress)) {
+ mKeyList->setColumnHidden(3, true);
+ }
+ if (!(mInfoType & KeyListColumn::Usage)) {
+ mKeyList->setColumnHidden(4, true);
+ }
+ if (!(mInfoType & KeyListColumn::Validity)) {
+ mKeyList->setColumnHidden(5, true);
+ }
+ if (!(mInfoType & KeyListColumn::FingerPrint)) {
+ mKeyList->setColumnHidden(6, true);
+ }
+
+ QStringList labels;
+ labels << _("Select") << _("Type") << _("Name") << _("Email Address")
+ << _("Usage") << _("Validity") << _("Finger Print");
+
+ mKeyList->setHorizontalHeaderLabels(labels);
+ mKeyList->horizontalHeader()->setStretchLastSection(false);
+
+ auto* layout = new QVBoxLayout;
+ layout->addWidget(mKeyList);
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->setSpacing(3);
+ setLayout(layout);
+
+ popupMenu = new QMenu(this);
+
+ // register key database refresh signal
+ connect(SignalStation::GetInstance(), SIGNAL(KeyDatabaseRefresh()), this,
+ SLOT(slotRefresh()));
+ connect(mKeyList, SIGNAL(doubleClicked(const QModelIndex&)), this,
+ SLOT(slotDoubleClicked(const QModelIndex&)));
+
+ setAcceptDrops(true);
+ slotRefresh();
+}
- QStringList labels;
- labels << tr("Select") << tr("Type") << tr("Name") << tr("Email Address")
- << tr("Usage") << tr("Validity") << tr("Finger Print");
+void KeyList::slotRefresh() {
+ LOG(INFO) << "KeyList::slotRefresh Called";
- mKeyList->setHorizontalHeaderLabels(labels);
- mKeyList->horizontalHeader()->setStretchLastSection(false);
+ auto keyList = getChecked();
+ // while filling the table, sort enabled causes errors
+ mKeyList->setSortingEnabled(false);
+ mKeyList->clearContents();
- auto *layout = new QVBoxLayout;
- layout->addWidget(mKeyList);
- layout->setContentsMargins(0, 0, 0, 0);
- layout->setSpacing(3);
- setLayout(layout);
+ auto keys = GpgKeyGetter::GetInstance().FetchKey();
- popupMenu = new QMenu(this);
+ auto it = keys->begin();
- connect(mKeyList, SIGNAL(doubleClicked(const QModelIndex &)),
- this, SLOT(slotDoubleClicked(const QModelIndex &)));
- connect(mCtx, SIGNAL(signalKeyInfoChanged()), this, SLOT(slotRefresh()));
- setAcceptDrops(true);
- slotRefresh();
-}
+ int row_count = 0;
-void KeyList::slotRefresh() {
- QStringList *keyList;
- keyList = getChecked();
- // while filling the table, sort enabled causes errors
- mKeyList->setSortingEnabled(false);
- mKeyList->clearContents();
-
- GpgKeyList keys = mCtx->getKeys();
-
- auto it = keys.begin();
-
- int row_count = 0;
-
- while (it != keys.end()) {
- if (mFilter != nullptr) {
- if (!mFilter(*it)) {
- it = keys.erase(it);
- continue;
- }
- }
- if (!excluded_key_ids.isEmpty()) {
-
- auto iterator = std::find_if(excluded_key_ids.begin(), excluded_key_ids.end(),
- [it](const auto &key_id) -> bool {
- if (it->id == key_id) return true;
- else return false;
- });
-
- if (iterator != excluded_key_ids.end()) {
- it = keys.erase(it);
- continue;
- }
- }
- if (mSelectType == KeyListRow::ONLY_SECRET_KEY && !it->is_private_key) {
- it = keys.erase(it);
- continue;
- }
- row_count++;
- it++;
+ while (it != keys->end()) {
+ if (mFilter != nullptr) {
+ if (!mFilter(*it)) {
+ it = keys->erase(it);
+ continue;
+ }
+ }
+ if (!excluded_key_ids.empty()) {
+ auto iterator =
+ std::find_if(excluded_key_ids.begin(), excluded_key_ids.end(),
+ [it](const auto& key_id) -> bool {
+ if (it->id() == key_id)
+ return true;
+ else
+ return false;
+ });
+
+ if (iterator != excluded_key_ids.end()) {
+ it = keys->erase(it);
+ continue;
+ }
+ }
+ if (mSelectType == KeyListRow::ONLY_SECRET_KEY && !it->is_private_key()) {
+ it = keys->erase(it);
+ continue;
+ }
+ row_count++;
+ it++;
+ }
+
+ mKeyList->setRowCount(row_count);
+
+ int row_index = 0;
+ it = keys->begin();
+ buffered_keys.clear();
+
+ while (it != keys->end()) {
+ buffered_keys.push_back(GpgKeyGetter::GetInstance().GetKey(it->id()));
+
+ auto* tmp0 = new QTableWidgetItem(QString::number(row_index));
+ tmp0->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled |
+ Qt::ItemIsSelectable);
+ tmp0->setTextAlignment(Qt::AlignCenter);
+ tmp0->setCheckState(Qt::Unchecked);
+ mKeyList->setItem(row_index, 0, tmp0);
+
+ QString type_str;
+ QTextStream type_steam(&type_str);
+ if (it->is_private_key()) {
+ type_steam << "pub/sec";
+ } else {
+ type_steam << "pub";
}
- mKeyList->setRowCount(row_count);
-
- int row_index = 0;
- it = keys.begin();
- buffered_keys.clear();
-
- while (it != keys.end()) {
-
- buffered_keys.push_back(*it);
-
- auto *tmp0 = new QTableWidgetItem(QString::number(row_index));
- tmp0->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
- tmp0->setTextAlignment(Qt::AlignCenter);
- tmp0->setCheckState(Qt::Unchecked);
- mKeyList->setItem(row_index, 0, tmp0);
-
- QString type_str;
- QTextStream type_steam(&type_str);
- if (it->is_private_key) {
- type_steam << "pub/sec";
- } else {
- type_steam << "pub";
- }
-
- if (it->is_private_key && !it->has_master_key) {
- type_steam << "#";
- }
- auto *tmp1 = new QTableWidgetItem(type_str);
- mKeyList->setItem(row_index, 1, tmp1);
-
- auto *tmp2 = new QTableWidgetItem(it->name);
- tmp2->setToolTip(it->name);
- mKeyList->setItem(row_index, 2, tmp2);
- auto *tmp3 = new QTableWidgetItem(it->email);
- tmp3->setToolTip(it->email);
- mKeyList->setItem(row_index, 3, tmp3);
-
- QString usage;
- QTextStream usage_steam(&usage);
-
- if (GpgME::GpgContext::checkIfKeyCanCert(*it))
- usage_steam << "C";
- if (GpgME::GpgContext::checkIfKeyCanEncr(*it))
- usage_steam << "E";
- if (GpgME::GpgContext::checkIfKeyCanSign(*it))
- usage_steam << "S";
- if (GpgME::GpgContext::checkIfKeyCanAuth(*it))
- usage_steam << "A";
-
- auto *temp_usage = new QTableWidgetItem(usage);
- temp_usage->setTextAlignment(Qt::AlignCenter);
- mKeyList->setItem(row_index, 4, temp_usage);
-
- auto *temp_validity = new QTableWidgetItem(it->owner_trust);
- temp_validity->setTextAlignment(Qt::AlignCenter);
- mKeyList->setItem(row_index, 5, temp_validity);
-
- auto *temp_fpr = new QTableWidgetItem(it->fpr);
- temp_fpr->setTextAlignment(Qt::AlignCenter);
- mKeyList->setItem(row_index, 6, temp_fpr);
-
- // strike out expired keys
- if (it->expired || it->revoked) {
- QFont strike = tmp2->font();
- strike.setStrikeOut(true);
- tmp0->setFont(strike);
- temp_usage->setFont(strike);
- temp_fpr->setFont(strike);
- temp_validity->setFont(strike);
- tmp1->setFont(strike);
- tmp2->setFont(strike);
- tmp3->setFont(strike);
- }
-
- it++;
- ++row_index;
+ if (it->is_private_key() && !it->has_master_key()) {
+ type_steam << "#";
+ }
+ auto* tmp1 = new QTableWidgetItem(type_str);
+ mKeyList->setItem(row_index, 1, tmp1);
+
+ auto* tmp2 = new QTableWidgetItem(QString::fromStdString(it->name()));
+ mKeyList->setItem(row_index, 2, tmp2);
+ auto* tmp3 = new QTableWidgetItem(QString::fromStdString(it->email()));
+ mKeyList->setItem(row_index, 3, tmp3);
+
+ QString usage;
+ QTextStream usage_steam(&usage);
+
+ if (it->CanCertActual()) usage_steam << "C";
+ if (it->CanEncrActual()) usage_steam << "E";
+ if (it->CanSignActual()) usage_steam << "S";
+ if (it->CanAuthActual()) usage_steam << "A";
+
+ auto* temp_usage = new QTableWidgetItem(usage);
+ temp_usage->setTextAlignment(Qt::AlignCenter);
+ mKeyList->setItem(row_index, 4, temp_usage);
+
+ auto* temp_validity =
+ new QTableWidgetItem(QString::fromStdString(it->owner_trust()));
+ temp_validity->setTextAlignment(Qt::AlignCenter);
+ mKeyList->setItem(row_index, 5, temp_validity);
+
+ auto* temp_fpr = new QTableWidgetItem(QString::fromStdString(it->fpr()));
+ temp_fpr->setTextAlignment(Qt::AlignCenter);
+ mKeyList->setItem(row_index, 6, temp_fpr);
+
+ // strike out expired keys
+ if (it->expired() || it->revoked()) {
+ QFont strike = tmp2->font();
+ strike.setStrikeOut(true);
+ tmp0->setFont(strike);
+ temp_usage->setFont(strike);
+ temp_fpr->setFont(strike);
+ temp_validity->setFont(strike);
+ tmp1->setFont(strike);
+ tmp2->setFont(strike);
+ tmp3->setFont(strike);
}
+ it++;
+ ++row_index;
+ }
- setChecked(keyList);
+ setChecked(keyList);
}
-QStringList *KeyList::getChecked() {
- auto *ret = new QStringList();
- for (int i = 0; i < mKeyList->rowCount(); i++) {
- if (mKeyList->item(i, 0)->checkState() == Qt::Checked) {
- *ret << buffered_keys[i].id;
- }
+KeyIdArgsListPtr KeyList::getChecked() {
+ auto ret = std::make_unique<KeyIdArgsList>();
+ for (int i = 0; i < mKeyList->rowCount(); i++) {
+ if (mKeyList->item(i, 0)->checkState() == Qt::Checked) {
+ ret->push_back(buffered_keys[i].id());
}
- return ret;
+ }
+ return ret;
}
-QStringList *KeyList::getAllPrivateKeys() {
- auto *ret = new QStringList();
- for (int i = 0; i < mKeyList->rowCount(); i++) {
- if (mKeyList->item(i, 1) && buffered_keys[i].is_private_key) {
- *ret << buffered_keys[i].id;
- }
+KeyIdArgsListPtr KeyList::getAllPrivateKeys() {
+ auto ret = std::make_unique<KeyIdArgsList>();
+ for (int i = 0; i < mKeyList->rowCount(); i++) {
+ if (mKeyList->item(i, 1) && buffered_keys[i].is_private_key()) {
+ ret->push_back(buffered_keys[i].id());
}
- return ret;
+ }
+ return ret;
}
-QStringList *KeyList::getPrivateChecked() {
- auto *ret = new QStringList();
- for (int i = 0; i < mKeyList->rowCount(); i++) {
- if ((mKeyList->item(i, 0)->checkState() == Qt::Checked) && (mKeyList->item(i, 1))) {
- *ret << buffered_keys[i].id;
- }
+KeyIdArgsListPtr KeyList::getPrivateChecked() {
+ auto ret = std::make_unique<KeyIdArgsList>();
+ for (int i = 0; i < mKeyList->rowCount(); i++) {
+ if ((mKeyList->item(i, 0)->checkState() == Qt::Checked) &&
+ (mKeyList->item(i, 1))) {
+ ret->push_back(buffered_keys[i].id());
}
- return ret;
+ }
+ return ret;
}
-void KeyList::setChecked(QStringList *keyIds) {
- if (!keyIds->isEmpty()) {
- for (int i = 0; i < mKeyList->rowCount(); i++) {
- if (keyIds->contains(buffered_keys[i].id)) {
- mKeyList->item(i, 0)->setCheckState(Qt::Checked);
- }
- }
+void KeyList::setChecked(const KeyIdArgsListPtr& keyIds) {
+ if (!keyIds->empty()) {
+ for (int i = 0; i < mKeyList->rowCount(); i++) {
+ if (std::find(keyIds->begin(), keyIds->end(), buffered_keys[i].id()) !=
+ keyIds->end()) {
+ mKeyList->item(i, 0)->setCheckState(Qt::Checked);
+ }
}
+ }
}
-QStringList *KeyList::getSelected() {
- auto *ret = new QStringList();
+KeyIdArgsListPtr KeyList::getSelected() {
+ auto ret = std::make_unique<KeyIdArgsList>();
- for (int i = 0; i < mKeyList->rowCount(); i++) {
- if (mKeyList->item(i, 0)->isSelected() == 1) {
- *ret << buffered_keys[i].id;
- }
+ for (int i = 0; i < mKeyList->rowCount(); i++) {
+ if (mKeyList->item(i, 0)->isSelected() == 1) {
+ ret->push_back(buffered_keys[i].id());
}
- return ret;
+ }
+ return ret;
}
[[maybe_unused]] bool KeyList::containsPrivateKeys() {
- for (int i = 0; i < mKeyList->rowCount(); i++) {
- if (mKeyList->item(i, 1)) {
- return true;
- }
+ for (int i = 0; i < mKeyList->rowCount(); i++) {
+ if (mKeyList->item(i, 1)) {
+ return true;
}
- return false;
+ }
+ return false;
}
void KeyList::setColumnWidth(int row, int size) {
- mKeyList->setColumnWidth(row, size);
-}
-
-void KeyList::contextMenuEvent(QContextMenuEvent *event) {
- if (mKeyList->selectedItems().length() > 0) {
- popupMenu->exec(event->globalPos());
- }
-
+ mKeyList->setColumnWidth(row, size);
}
-void KeyList::addSeparator() {
- popupMenu->addSeparator();
+void KeyList::contextMenuEvent(QContextMenuEvent* event) {
+ if (mKeyList->selectedItems().length() > 0) {
+ popupMenu->exec(event->globalPos());
+ }
}
-void KeyList::addMenuAction(QAction *act) {
- popupMenu->addAction(act);
-}
-
-void KeyList::dropEvent(QDropEvent *event) {
+void KeyList::addSeparator() { popupMenu->addSeparator(); }
- auto *dialog = new QDialog();
+void KeyList::addMenuAction(QAction* act) { popupMenu->addAction(act); }
- dialog->setWindowTitle(tr("Import Keys"));
- QLabel *label;
- label = new QLabel(
- tr("You've dropped something on the table.\n GpgFrontend will now try to import key(s).") + "\n");
+void KeyList::dropEvent(QDropEvent* event) {
+ auto* dialog = new QDialog();
- // "always import keys"-CheckBox
- auto *checkBox = new QCheckBox(tr("Always import without bothering."));
- if (settings.value("general/confirmImportKeys").toBool()) checkBox->setCheckState(Qt::Unchecked);
+ dialog->setWindowTitle(_("Import Keys"));
+ QLabel* label;
+ label =
+ new QLabel(QString(_("You've dropped something on the table.")) + "\n " +
+ _("GpgFrontend "
+ "will now try to import key(s).") +
+ "\n");
- // Buttons for ok and cancel
- auto *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
- connect(buttonBox, SIGNAL(accepted()), dialog, SLOT(accept()));
- connect(buttonBox, SIGNAL(rejected()), dialog, SLOT(reject()));
+ // "always import keys"-CheckBox
+ auto* checkBox = new QCheckBox(_("Always import without bothering."));
+ if (settings.value("general/confirmImportKeys").toBool())
+ checkBox->setCheckState(Qt::Unchecked);
- auto *vbox = new QVBoxLayout();
- vbox->addWidget(label);
- vbox->addWidget(checkBox);
- vbox->addWidget(buttonBox);
+ // Buttons for ok and cancel
+ auto* buttonBox =
+ new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+ connect(buttonBox, SIGNAL(accepted()), dialog, SLOT(accept()));
+ connect(buttonBox, SIGNAL(rejected()), dialog, SLOT(reject()));
- dialog->setLayout(vbox);
+ auto* vbox = new QVBoxLayout();
+ vbox->addWidget(label);
+ vbox->addWidget(checkBox);
+ vbox->addWidget(buttonBox);
- if (settings.value("general/confirmImportKeys", Qt::Checked).toBool()) {
- dialog->exec();
- if (dialog->result() == QDialog::Rejected) {
- return;
- }
- if (checkBox->isChecked()) {
- settings.setValue("general/confirmImportKeys", false);
- } else {
- settings.setValue("general/confirmImportKeys", true);
+ dialog->setLayout(vbox);
- }
+ if (settings.value("general/confirmImportKeys", Qt::Checked).toBool()) {
+ dialog->exec();
+ if (dialog->result() == QDialog::Rejected) {
+ return;
}
-
- if (event->mimeData()->hasUrls()) {
- for (const QUrl &tmp : event->mimeData()->urls()) {
- QFile file;
- file.setFileName(tmp.toLocalFile());
- if (!file.open(QIODevice::ReadOnly)) {
- qDebug() << tr("Couldn't Open File: ") + tmp.toString();
- }
- QByteArray inBuffer = file.readAll();
- this->importKeys(inBuffer);
- file.close();
- }
+ if (checkBox->isChecked()) {
+ settings.setValue("general/confirmImportKeys", false);
} else {
- QByteArray inBuffer(event->mimeData()->text().toUtf8());
- this->importKeys(inBuffer);
+ settings.setValue("general/confirmImportKeys", true);
}
+ }
+
+ if (event->mimeData()->hasUrls()) {
+ for (const QUrl& tmp : event->mimeData()->urls()) {
+ QFile file;
+ file.setFileName(tmp.toLocalFile());
+ if (!file.open(QIODevice::ReadOnly)) {
+ LOG(INFO) << _("Couldn't Open File") << ":"
+ << tmp.toString().toStdString();
+ }
+ QByteArray inBuffer = file.readAll();
+ this->importKeys(inBuffer);
+ file.close();
+ }
+ } else {
+ QByteArray inBuffer(event->mimeData()->text().toUtf8());
+ this->importKeys(inBuffer);
+ }
}
-void KeyList::dragEnterEvent(QDragEnterEvent *event) {
- event->acceptProposedAction();
+void KeyList::dragEnterEvent(QDragEnterEvent* event) {
+ event->acceptProposedAction();
}
/** set background color for Keys and put them to top
*
*/
-[[maybe_unused]] void KeyList::markKeys(QStringList *keyIds) {
- foreach(QString id, *keyIds) {
- qDebug() << "marked: " << id;
- }
-}
-
-void KeyList::importKeys(QByteArray inBuffer) {
- GpgImportInformation result = mCtx->importKey(std::move(inBuffer));
- new KeyImportDetailDialog(mCtx, result, false, this);
+[[maybe_unused]] void KeyList::markKeys(QStringList* keyIds) {
+ foreach (QString id, *keyIds) { qDebug() << "marked: " << id; }
}
-void KeyList::getCheckedKeys(QVector<GpgKey> &keys) {
- keys.clear();
- for (int i = 0; i < mKeyList->rowCount(); i++) {
- if (mKeyList->item(i, 0)->checkState() == Qt::Checked) {
- keys.push_back(buffered_keys[i]);
- }
- }
+void KeyList::importKeys(const QByteArray& inBuffer) {
+ auto std_buffer = std::make_unique<ByteArray>(inBuffer.toStdString());
+ GpgImportInformation result =
+ GpgKeyImportExportor::GetInstance().ImportKey(std::move(std_buffer));
+ new KeyImportDetailDialog(result, false, this);
}
-void KeyList::setExcludeKeys(std::initializer_list<QString> key_ids) {
- excluded_key_ids.clear();
- for (auto &key_id : key_ids) {
- excluded_key_ids.push_back(key_id);
- }
+void KeyList::setExcludeKeys(std::initializer_list<std::string> key_ids) {
+ excluded_key_ids.clear();
+ for (auto& key_id : key_ids) {
+ excluded_key_ids.push_back(key_id);
+ }
}
-void KeyList::setFilter(std::function<bool(const GpgKey &)> filter) {
- this->mFilter = std::move(filter);
+void KeyList::setFilter(std::function<bool(const GpgKey&)> filter) {
+ this->mFilter = std::move(filter);
}
-void KeyList::slotDoubleClicked(const QModelIndex &index) {
- if (mAction != nullptr) {
- const auto key = mCtx->getKeyById(buffered_keys[index.row()].id);
- mAction(key, this);
- }
-
+void KeyList::slotDoubleClicked(const QModelIndex& index) {
+ if (mAction != nullptr) {
+ const auto key =
+ GpgKeyGetter::GetInstance().GetKey(buffered_keys[index.row()].id());
+ mAction(key, this);
+ }
}
-void KeyList::setDoubleClickedAction(std::function<void(const GpgKey &, QWidget *)> action) {
- this->mAction = std::move(action);
+void KeyList::setDoubleClickedAction(
+ std::function<void(const GpgKey&, QWidget*)> action) {
+ this->mAction = std::move(action);
}
-void KeyList::getPrivateCheckedKeys(QVector<GpgKey> &keys) {
- keys.clear();
- for (int i = 0; i < mKeyList->rowCount(); i++) {
- if (mKeyList->item(i, 0)->checkState() == Qt::Checked && buffered_keys[i].is_private_key) {
- keys.push_back(buffered_keys[i]);
- }
+std::string KeyList::getSelectedKey() {
+ for (int i = 0; i < mKeyList->rowCount(); i++) {
+ if (mKeyList->item(i, 0)->isSelected() == 1) {
+ return buffered_keys[i].id();
}
+ }
+ return {};
}
-GpgKey KeyList::getSelectedKey() {
- for (int i = 0; i < mKeyList->rowCount(); i++) {
- if (mKeyList->item(i, 0)->isSelected() == 1) {
- return buffered_keys[i];
- }
- }
- return GpgKey();
-}
+} // namespace GpgFrontend::UI
diff --git a/src/ui/widgets/KeyList.h b/src/ui/widgets/KeyList.h
new file mode 100644
index 00000000..524b2bd0
--- /dev/null
+++ b/src/ui/widgets/KeyList.h
@@ -0,0 +1,124 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef __KEYLIST_H__
+#define __KEYLIST_H__
+
+#include "gpg/GpgContext.h"
+#include "ui/KeyImportDetailDialog.h"
+namespace GpgFrontend::UI {
+
+struct KeyListRow {
+ using KeyType = unsigned int;
+
+ static const KeyType SECRET_OR_PUBLIC_KEY = 0;
+ static const KeyType ONLY_SECRET_KEY = 1;
+};
+
+struct KeyListColumn {
+ using InfoType = unsigned int;
+
+ static constexpr InfoType ALL = ~0;
+ static constexpr InfoType TYPE = 1 << 0;
+ static constexpr InfoType NAME = 1 << 1;
+ static constexpr InfoType EmailAddress = 1 << 2;
+ static constexpr InfoType Usage = 1 << 3;
+ static constexpr InfoType Validity = 1 << 4;
+ static constexpr InfoType FingerPrint = 1 << 5;
+};
+
+class KeyList : public QWidget {
+ Q_OBJECT
+
+ public:
+ explicit KeyList(
+ KeyListRow::KeyType selectType = KeyListRow::SECRET_OR_PUBLIC_KEY,
+ KeyListColumn::InfoType infoType = KeyListColumn::ALL,
+ QWidget* parent = nullptr);
+
+ void setExcludeKeys(std::initializer_list<std::string> key_ids);
+
+ void setFilter(std::function<bool(const GpgKey&)> filter);
+
+ void setDoubleClickedAction(
+ std::function<void(const GpgKey&, QWidget*)> action);
+
+ void setColumnWidth(int row, int size);
+
+ void addMenuAction(QAction* act);
+
+ void addSeparator();
+
+ KeyIdArgsListPtr getChecked();
+
+ KeyIdArgsListPtr getPrivateChecked();
+
+ KeyIdArgsListPtr getAllPrivateKeys();
+
+ void setChecked(const KeyIdArgsListPtr& keyIds);
+
+ KeyIdArgsListPtr getSelected();
+
+ std::string getSelectedKey();
+
+ [[maybe_unused]] static void markKeys(QStringList* keyIds);
+
+ [[maybe_unused]] bool containsPrivateKeys();
+
+ public slots:
+
+ void slotRefresh();
+
+ private:
+ void importKeys(const QByteArray& inBuffer);
+
+ QString appPath;
+ QSettings settings;
+
+ QTableWidget* mKeyList;
+ QMenu* popupMenu;
+ QNetworkAccessManager* qnam{};
+ std::vector<GpgKey> buffered_keys;
+ KeyListRow::KeyType mSelectType;
+ KeyListColumn::InfoType mInfoType;
+ std::vector<std::string> excluded_key_ids;
+
+ std::function<bool(const GpgKey&)> mFilter = nullptr;
+ std::function<void(const GpgKey&, QWidget*)> mAction = nullptr;
+
+ private slots:
+
+ void slotDoubleClicked(const QModelIndex& index);
+
+ protected:
+ void contextMenuEvent(QContextMenuEvent* event) override;
+
+ void dragEnterEvent(QDragEnterEvent* event) override;
+
+ void dropEvent(QDropEvent* event) override;
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // __KEYLIST_H__
diff --git a/src/ui/widgets/SignersPicker.cpp b/src/ui/widgets/SignersPicker.cpp
index 00df5fdd..3e4b3bb5 100644
--- a/src/ui/widgets/SignersPicker.cpp
+++ b/src/ui/widgets/SignersPicker.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,36 +24,46 @@
#include "ui/widgets/SignersPicker.h"
-SignersPicker::SignersPicker(GpgME::GpgContext *ctx, QWidget *parent) : mCtx(ctx), QDialog(parent) {
- auto confirmButton = new QPushButton(tr("Confirm"));
- connect(confirmButton, SIGNAL(clicked(bool)), this, SLOT(accept()));
+namespace GpgFrontend::UI {
- /*Setup KeyList*/
- mKeyList = new KeyList(mCtx, KeyListRow::ONLY_SECRET_KEY,
- KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage);
+SignersPicker::SignersPicker(QWidget* parent) : QDialog(parent) {
+ auto confirmButton = new QPushButton(_("Confirm"));
+ connect(confirmButton, SIGNAL(clicked(bool)), this, SLOT(accept()));
- mKeyList->setFilter([](const GpgKey &key) -> bool {
- if (!GpgME::GpgContext::checkIfKeyCanSign(key)) return false;
- else return true;
- });
+ /*Setup KeyList*/
+ mKeyList = new KeyList(
+ KeyListRow::ONLY_SECRET_KEY,
+ KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage);
- mKeyList->slotRefresh();
+ mKeyList->setFilter([](const GpgKey& key) -> bool {
+ if (!key.CanSignActual())
+ return false;
+ else
+ return true;
+ });
- auto *vbox2 = new QVBoxLayout();
- vbox2->addWidget(new QLabel("Select Signer(s): "));
- vbox2->addWidget(mKeyList);
- vbox2->addWidget(confirmButton);
- vbox2->addStretch(0);
- setLayout(vbox2);
+ mKeyList->slotRefresh();
- this->setModal(true);
- this->setWindowTitle("Signers Picker");
- this->setMinimumWidth(480);
- this->show();
+ auto* vbox2 = new QVBoxLayout();
+ vbox2->addWidget(new QLabel(QString(_("Select Signer(s)")) + ": "));
+ vbox2->addWidget(mKeyList);
+ vbox2->addWidget(new QLabel(
+ _("Selecting Nothing will eventually use default key to sign.")));
+ vbox2->addWidget(confirmButton);
+ vbox2->addStretch(0);
+ setLayout(vbox2);
+ this->setWindowFlags(Qt::Window | Qt::WindowTitleHint |
+ Qt::CustomizeWindowHint);
+ this->setModal(true);
+ this->setWindowTitle("Signers Picker");
+ this->setMinimumWidth(480);
+ this->show();
}
-void SignersPicker::getCheckedSigners(QVector<GpgKey> &keys) {
- mKeyList->getPrivateCheckedKeys(keys);
+GpgFrontend::KeyIdArgsListPtr SignersPicker::getCheckedSigners() {
+ return mKeyList->getPrivateChecked();
}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/widgets/SignersPicker.h b/src/ui/widgets/SignersPicker.h
new file mode 100644
index 00000000..055b6ef6
--- /dev/null
+++ b/src/ui/widgets/SignersPicker.h
@@ -0,0 +1,48 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_ZH_CN_TS_SIGNERSPIRCKER_H
+#define GPGFRONTEND_ZH_CN_TS_SIGNERSPIRCKER_H
+
+#include "GpgFrontend.h"
+#include "gpg/GpgContext.h"
+#include "ui/widgets/KeyList.h"
+
+namespace GpgFrontend::UI {
+
+class SignersPicker : public QDialog {
+ Q_OBJECT
+
+ public:
+ explicit SignersPicker(QWidget* parent = nullptr);
+
+ GpgFrontend::KeyIdArgsListPtr getCheckedSigners();
+
+ private:
+ KeyList* mKeyList;
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_ZH_CN_TS_SIGNERSPIRCKER_H
diff --git a/src/ui/widgets/TextEdit.cpp b/src/ui/widgets/TextEdit.cpp
index eab0f799..8d4ea4a0 100644
--- a/src/ui/widgets/TextEdit.cpp
+++ b/src/ui/widgets/TextEdit.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,14 +24,18 @@
#include "ui/widgets/TextEdit.h"
-TextEdit::TextEdit(QWidget *parent) : QWidget(parent) {
+#include <boost/format.hpp>
+
+namespace GpgFrontend::UI {
+
+TextEdit::TextEdit(QWidget* parent) : QWidget(parent) {
countPage = 0;
tabWidget = new QTabWidget(this);
tabWidget->setMovable(true);
tabWidget->setTabsClosable(true);
tabWidget->setDocumentMode(true);
- auto *layout = new QVBoxLayout;
+ auto* layout = new QVBoxLayout;
layout->addWidget(tabWidget);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
@@ -39,20 +43,14 @@ TextEdit::TextEdit(QWidget *parent) : QWidget(parent) {
connect(tabWidget, SIGNAL(tabCloseRequested(int)), this,
SLOT(removeTab(int)));
- connect(this, &TextEdit::insertTargetTextPage, this,
- &TextEdit::slotInsertTargetTextPage);
- connect(this, &TextEdit::readTargetTextPageStart, this,
- &TextEdit::slotReadTargetTextPageStart);
- connect(this, &TextEdit::readTargetTextPageDone, this,
- &TextEdit::slotReadTargetTextPageDone);
slotNewTab();
setAcceptDrops(false);
}
void TextEdit::slotNewTab() {
- QString header = tr("untitled") + QString::number(++countPage) + ".txt";
+ QString header = _("untitled") + QString::number(++countPage) + ".txt";
- auto *page = new EditorPage();
+ auto* page = new EditorPage();
tabWidget->addTab(page, header);
tabWidget->setCurrentIndex(tabWidget->count() - 1);
page->getTextPage()->setFocus();
@@ -60,131 +58,59 @@ void TextEdit::slotNewTab() {
this, SLOT(slotShowModified()));
}
-void TextEdit::slotNewHelpTab(const QString &title, const QString &path) const {
-
- auto *page = new HelpPage(path);
+void TextEdit::slotNewHelpTab(const QString& title, const QString& path) const {
+ auto* page = new HelpPage(path);
tabWidget->addTab(page, title);
tabWidget->setCurrentIndex(tabWidget->count() - 1);
}
void TextEdit::slotNewFileTab() const {
-
- auto *page = new FilePage(qobject_cast<QWidget *>(parent()));
+ auto* page = new FilePage(qobject_cast<QWidget*>(parent()));
tabWidget->addTab(page, "[Browser]");
tabWidget->setCurrentIndex(tabWidget->count() - 1);
- connect(page, SIGNAL(pathChanged(const QString &)), this,
- SLOT(slotFilePagePathChanged(const QString &)));
+ connect(page, SIGNAL(pathChanged(const QString&)), this,
+ SLOT(slotFilePagePathChanged(const QString&)));
}
-void TextEdit::slotOpenFile(QString &path) {
-
+void TextEdit::slotOpenFile(QString& path) {
QFile file(path);
-
- if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- auto *page = new EditorPage(path);
- pagesHashMap.insert(page->uuid, page);
+ LOG(INFO) << " path" << path.toStdString();
+ auto result = file.open(QIODevice::ReadOnly | QIODevice::Text);
+ if (result) {
+ auto* page = new EditorPage(path);
QApplication::setOverrideCursor(Qt::WaitCursor);
-
- auto read_thread = QThread::create([&, page]() {
- QFile targetFile(path);
-
- if (targetFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
- emit readTargetTextPageStart(page->uuid);
- QTextStream in(&targetFile);
- QString readText;
- qDebug() << "Thread Start Reading" << path;
- while (!((readText = in.read(8192)).isEmpty())) {
- emit insertTargetTextPage(page->uuid, readText);
- QThread::msleep(64);
- }
- targetFile.close();
- emit readTargetTextPageDone(page->uuid);
- qDebug() << "Thread End Reading" << path;
- }
- });
-
- page->setFilePath(path);
- QTextDocument *document = page->getTextPage()->document();
- document->setModified(false);
-
tabWidget->addTab(page, strippedName(path));
tabWidget->setCurrentIndex(tabWidget->count() - 1);
QApplication::restoreOverrideCursor();
page->getTextPage()->setFocus();
-
- file.close();
- read_thread->start();
-
+ page->ReadFile();
} else {
- QMessageBox::warning(
- this, tr("Warning"),
- tr("Cannot read file %1:\n%2.").arg(path).arg(file.errorString()));
+ QMessageBox::warning(this, _("Warning"),
+ (boost::format(_("Cannot read file %1%:\n%2%.")) %
+ path.toStdString() % file.errorString().toStdString())
+ .str()
+ .c_str());
}
-}
-void TextEdit::slotInsertTargetTextPage(const QString &pagePtr,
- const QString &text) {
- auto it = pagesHashMap.find(pagePtr);
- if (it != pagesHashMap.end()) {
- auto *taregtTextPage = qobject_cast<EditorPage *>(it.value());
- if (taregtTextPage != nullptr) {
- taregtTextPage->getTextPage()->insertPlainText(text);
- taregtTextPage->getTextPage()->document()->setModified(false);
- }
- }
-}
-
-void TextEdit::slotReadTargetTextPageStart(const QString &pagePtr) {
- auto it = pagesHashMap.find(pagePtr);
- if (it != pagesHashMap.end()) {
- auto *taregtTextPage = qobject_cast<EditorPage *>(it.value());
- if (taregtTextPage != nullptr) {
- qDebug() << "Setting TextEdit At Start" << pagePtr;
- taregtTextPage->getTextPage()->setReadOnly(true);
- auto index = tabWidget->indexOf(taregtTextPage);
- if (index != -1) {
- tabWidget->setTabText(
- index, "[Loading] " + strippedName(taregtTextPage->getFilePath()));
- }
- }
- }
-}
-
-void TextEdit::slotReadTargetTextPageDone(const QString &pagePtr) {
- auto it = pagesHashMap.find(pagePtr);
- if (it != pagesHashMap.end()) {
- auto *taregtTextPage = qobject_cast<EditorPage *>(it.value());
- if (taregtTextPage != nullptr) {
- qDebug() << "Setting TextEdit At End" << pagePtr;
- taregtTextPage->getTextPage()->setReadOnly(false);
- auto index = tabWidget->indexOf(taregtTextPage);
- if (index != -1) {
- tabWidget->setTabText(index,
- strippedName(taregtTextPage->getFilePath()));
- }
- taregtTextPage->getTextPage()->document()->setModified(false);
- connect(taregtTextPage->getTextPage()->document(),
- SIGNAL(modificationChanged(bool)), this,
- SLOT(slotShowModified()));
- }
- }
+ file.close();
+ LOG(INFO) << "done";
}
void TextEdit::slotOpen() {
QStringList fileNames =
- QFileDialog::getOpenFileNames(this, tr("Open file"), QDir::currentPath());
- for (const auto &fileName : fileNames) {
+ QFileDialog::getOpenFileNames(this, _("Open file"), QDir::currentPath());
+ for (const auto& fileName : fileNames) {
if (!fileName.isEmpty()) {
QFile file(fileName);
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- auto *page = new EditorPage(fileName);
+ auto* page = new EditorPage(fileName);
QTextStream in(&file);
QApplication::setOverrideCursor(Qt::WaitCursor);
page->getTextPage()->setPlainText(in.readAll());
page->setFilePath(fileName);
- QTextDocument *document = page->getTextPage()->document();
+ QTextDocument* document = page->getTextPage()->document();
document->setModified(false);
tabWidget->addTab(page, strippedName(fileName));
@@ -197,10 +123,12 @@ void TextEdit::slotOpen() {
// enableAction(true)
file.close();
} else {
- QMessageBox::warning(this, tr("Warning"),
- tr("Cannot read file %1:\n%2.")
- .arg(fileName)
- .arg(file.errorString()));
+ QMessageBox::warning(
+ this, _("Warning"),
+ (boost::format(_("Cannot read file %1%:\n%2%.")) %
+ fileName.toStdString() % file.errorString().toStdString())
+ .str()
+ .c_str());
}
}
}
@@ -222,7 +150,7 @@ void TextEdit::slotSave() {
}
}
-bool TextEdit::saveFile(const QString &fileName) {
+bool TextEdit::saveFile(const QString& fileName) {
if (fileName.isEmpty()) {
return false;
}
@@ -230,44 +158,47 @@ bool TextEdit::saveFile(const QString &fileName) {
QFile file(fileName);
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
- EditorPage *page = slotCurPageTextEdit();
+ EditorPage* page = slotCurPageTextEdit();
QTextStream outputStream(&file);
QApplication::setOverrideCursor(Qt::WaitCursor);
outputStream << page->getTextPage()->toPlainText();
QApplication::restoreOverrideCursor();
- QTextDocument *document = page->getTextPage()->document();
+ QTextDocument* document = page->getTextPage()->document();
document->setModified(false);
int curIndex = tabWidget->currentIndex();
tabWidget->setTabText(curIndex, strippedName(fileName));
page->setFilePath(fileName);
- // statusBar()->showMessage(tr("File saved"), 2000);
+ // statusBar()->showMessage(_("File saved"), 2000);
file.close();
return true;
} else {
QMessageBox::warning(
- this, tr("File"),
- tr("Cannot write file %1:\n%2.").arg(fileName).arg(file.errorString()));
+ this, _("Warning"),
+ (boost::format(_("Cannot read file %1%:\n%2%.")) %
+ fileName.toStdString() % file.errorString().toStdString())
+ .str()
+ .c_str());
return false;
}
}
bool TextEdit::slotSaveAs() {
- if (tabWidget->count() == 0 || slotCurPageTextEdit() == 0) {
+ if (tabWidget->count() == 0 || slotCurPageTextEdit() == nullptr) {
return true;
}
- EditorPage *page = slotCurPageTextEdit();
+ EditorPage* page = slotCurPageTextEdit();
QString path;
- if (page->getFilePath() != "") {
+ if (!page->getFilePath().isEmpty()) {
path = page->getFilePath();
} else {
path = tabWidget->tabText(tabWidget->currentIndex()).remove(0, 2);
}
- QString fileName = QFileDialog::getSaveFileName(this, tr("Save file"), path);
+ QString fileName = QFileDialog::getSaveFileName(this, _("Save file"), path);
return saveFile(fileName);
}
@@ -312,34 +243,35 @@ void TextEdit::removeTab(int index) {
* If it returns false, the close event should be aborted.
*/
bool TextEdit::maybeSaveCurrentTab(bool askToSave) {
-
- EditorPage *page = slotCurPageTextEdit();
+ EditorPage* page = slotCurPageTextEdit();
// if this page is no textedit, there should be nothing to save
if (page == nullptr) {
return true;
}
- QTextDocument *document = page->getTextPage()->document();
+ QTextDocument* document = page->getTextPage()->document();
- if (document->isModified()) {
+ if (page->ReadDone() && document->isModified()) {
QMessageBox::StandardButton result = QMessageBox::Cancel;
// write title of tab to docname and remove the leading *
QString docname = tabWidget->tabText(tabWidget->currentIndex());
docname.remove(0, 2);
- const QString &filePath = page->getFilePath();
+ const QString& filePath = page->getFilePath();
if (askToSave) {
result = QMessageBox::warning(
- this, tr("Unsaved document"),
- tr("The document \"%1\" has been modified. Do you want to "
- "save your changes?<br/>")
+ this, _("Unsaved document"),
+ QString(_("The document \"%1\" has been modified. Do you want to "
+ "save your changes?"))
.arg(docname) +
- tr("<b>Note:</b> If you don't save these files, all changes are "
- "lost.<br/>"),
+ "<br/><b>" + _("Note:") + "</b>" +
+ _("If you don't save these files, all changes are "
+ "lost.") +
+ "<br/>",
QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
}
if ((result == QMessageBox::Save) || (!askToSave)) {
- if (filePath == "") {
+ if (filePath.isEmpty()) {
// QString docname = tabWidget->tabText(tabWidget->currentIndex());
// docname.remove(0,2);
return slotSaveAs();
@@ -352,6 +284,9 @@ bool TextEdit::maybeSaveCurrentTab(bool askToSave) {
return false;
}
}
+
+ // destroy
+ page->PrepareToDestroy();
return true;
}
@@ -381,7 +316,7 @@ bool TextEdit::maybeSaveAnyTab() {
if (unsavedDocs.size() > 1) {
QHashIterator<int, QString> i(unsavedDocs);
- QuitDialog *dialog;
+ QuitDialog* dialog;
dialog = new QuitDialog(this, unsavedDocs);
int result = dialog->exec();
@@ -394,28 +329,24 @@ bool TextEdit::maybeSaveAnyTab() {
return false;
}
} else {
- bool allsaved = true;
+ bool all_saved = true;
QList<int> tabIdsToSave = dialog->getTabIdsToSave();
- foreach (int tabId, tabIdsToSave) {
+ for (const auto& tabId : tabIdsToSave) {
tabWidget->setCurrentIndex(tabId);
if (!maybeSaveCurrentTab(false)) {
- allsaved = false;
+ all_saved = false;
}
}
- if (allsaved) {
- return true;
- } else {
- return false;
- }
+ return all_saved;
}
}
// code should never reach this statement
return false;
}
-QTextEdit *TextEdit::curTextPage() const {
- auto *curTextPage = qobject_cast<EditorPage *>(tabWidget->currentWidget());
+QTextEdit* TextEdit::curTextPage() const {
+ auto* curTextPage = qobject_cast<EditorPage*>(tabWidget->currentWidget());
if (curTextPage != nullptr) {
return curTextPage->getTextPage();
} else {
@@ -423,8 +354,8 @@ QTextEdit *TextEdit::curTextPage() const {
}
}
-FilePage *TextEdit::curFilePage() const {
- auto *curFilePage = qobject_cast<FilePage *>(tabWidget->currentWidget());
+FilePage* TextEdit::curFilePage() const {
+ auto* curFilePage = qobject_cast<FilePage*>(tabWidget->currentWidget());
if (curFilePage != nullptr) {
return curFilePage;
} else {
@@ -434,13 +365,13 @@ FilePage *TextEdit::curFilePage() const {
int TextEdit::tabCount() const { return tabWidget->count(); }
-EditorPage *TextEdit::slotCurPageTextEdit() const {
- auto *curPage = qobject_cast<EditorPage *>(tabWidget->currentWidget());
+EditorPage* TextEdit::slotCurPageTextEdit() const {
+ auto* curPage = qobject_cast<EditorPage*>(tabWidget->currentWidget());
return curPage;
}
-FilePage *TextEdit::slotCurPageFileTreeView() const {
- auto *curPage = qobject_cast<FilePage *>(tabWidget->currentWidget());
+FilePage* TextEdit::slotCurPageFileTreeView() const {
+ auto* curPage = qobject_cast<FilePage*>(tabWidget->currentWidget());
return curPage;
}
@@ -466,7 +397,7 @@ void TextEdit::slotQuote() const {
cursor.endEditBlock();
}
-void TextEdit::slotFillTextEditWithText(const QString &text) const {
+void TextEdit::slotFillTextEditWithText(const QString& text) const {
QTextCursor cursor(curTextPage()->document());
cursor.beginEditBlock();
this->curTextPage()->selectAll();
@@ -474,12 +405,15 @@ void TextEdit::slotFillTextEditWithText(const QString &text) const {
cursor.endEditBlock();
}
-void TextEdit::loadFile(const QString &fileName) {
+void TextEdit::loadFile(const QString& fileName) {
QFile file(fileName);
if (!file.open(QFile::ReadOnly | QFile::Text)) {
QMessageBox::warning(
- this, tr("Application"),
- tr("Cannot read file %1:\n%2.").arg(fileName).arg(file.errorString()));
+ this, _("Warning"),
+ (boost::format(_("Cannot read file %1%:\n%2%.")) %
+ fileName.toStdString() % file.errorString().toStdString())
+ .str()
+ .c_str());
return;
}
QTextStream in(&file);
@@ -489,10 +423,10 @@ void TextEdit::loadFile(const QString &fileName) {
slotCurPageTextEdit()->setFilePath(fileName);
tabWidget->setTabText(tabWidget->currentIndex(), strippedName(fileName));
file.close();
- // statusBar()->showMessage(tr("File loaded"), 2000);
+ // statusBar()->showMessage(_("File loaded"), 2000);
}
-QString TextEdit::strippedName(const QString &fullFileName) {
+QString TextEdit::strippedName(const QString& fullFileName) {
return QFileInfo(fullFileName).fileName();
}
@@ -502,19 +436,19 @@ void TextEdit::slotPrint() {
}
#ifndef QT_NO_PRINTER
- QTextDocument *document;
+ QTextDocument* document;
if (curTextPage() != nullptr) {
document = curTextPage()->document();
}
QPrinter printer;
- auto *dlg = new QPrintDialog(&printer, this);
+ auto* dlg = new QPrintDialog(&printer, this);
if (dlg->exec() != QDialog::Accepted) {
return;
}
document->print(&printer);
- // statusBar()->showMessage(tr("Ready"), 2000);
+ // statusBar()->showMessage(_("Ready"), 2000);
#endif
}
@@ -549,16 +483,19 @@ void TextEdit::slotSwitchTabDown() const {
* return a hash of tabindexes and title of unsaved tabs
*/
QHash<int, QString> TextEdit::unsavedDocuments() const {
- QHash<int, QString> unsavedDocs; // this list could be used to implement gedit
- // like "unsaved changed"-dialog
+ QHash<int, QString> unsavedDocs; // this list could be used to implement
+ // gedit like "unsaved changed"-dialog
for (int i = 0; i < tabWidget->count(); i++) {
- auto *ep = qobject_cast<EditorPage *>(tabWidget->widget(i));
- if (ep != nullptr && ep->getTextPage()->document()->isModified()) {
- QString docname = tabWidget->tabText(i);
+ auto* ep = qobject_cast<EditorPage*>(tabWidget->widget(i));
+ if (ep != nullptr && ep->ReadDone() &&
+ ep->getTextPage()->document()->isModified()) {
+ QString doc_name = tabWidget->tabText(i);
+ LOG(INFO) << "unsaved" << doc_name.toStdString();
+
// remove * before name of modified doc
- docname.remove(0, 2);
- unsavedDocs.insert(i, docname);
+ doc_name.remove(0, 2);
+ unsavedDocs.insert(i, doc_name);
}
}
return unsavedDocs;
@@ -633,7 +570,7 @@ void TextEdit::slotSelectAll() const {
curTextPage()->selectAll();
}
-void TextEdit::slotFilePagePathChanged(const QString &path) {
+void TextEdit::slotFilePagePathChanged(const QString& path) const {
int index = tabWidget->currentIndex();
QString mPath;
QFileInfo fileInfo(path);
@@ -644,6 +581,7 @@ void TextEdit::slotFilePagePathChanged(const QString &path) {
mPath = tPath;
}
mPath.prepend("[Browser] ");
- mPath.append("/");
tabWidget->setTabText(index, mPath);
}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/widgets/TextEdit.h b/src/ui/widgets/TextEdit.h
new file mode 100644
index 00000000..3cff74e7
--- /dev/null
+++ b/src/ui/widgets/TextEdit.h
@@ -0,0 +1,282 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef __TEXTEDIT_H__
+#define __TEXTEDIT_H__
+
+#include "ui/QuitDialog.h"
+#include "ui/widgets/EditorPage.h"
+#include "ui/widgets/FilePage.h"
+#include "ui/widgets/HelpPage.h"
+
+namespace GpgFrontend::UI {
+/**
+ * @brief TextEdit class
+ */
+class TextEdit : public QWidget {
+ Q_OBJECT
+ public:
+ /**
+ * @brief
+ */
+ TextEdit(QWidget* parent);
+
+ /**
+ * @details Load the content of file into the current textpage
+ *
+ * @param fileName QString containing the filename to load
+ * @return nothing
+ */
+ void loadFile(const QString& fileName);
+
+ /**
+ * @details Checks if there are unsaved documents in any tab,
+ * which may need to be saved. Call this function before
+ * closing the programme or all tabs.
+ * @return \li false, if the close event should be aborted.
+ * \li true, otherwise
+ */
+ bool maybeSaveAnyTab();
+
+ [[nodiscard]] int tabCount() const;
+
+ /**
+ * @details textpage of the currently activated tab
+ * @return \li reference to QTextEdit if tab has one
+ * \li 0 otherwise (e.g. if helppage)
+ */
+ [[nodiscard]] QTextEdit* curTextPage() const;
+
+ [[nodiscard]] FilePage* curFilePage() const;
+
+ /**
+ * @details List of currently unsaved tabs.
+ * @returns QHash<int, QString> Hash of tabindexes and title of unsaved tabs.
+ */
+ [[nodiscard]] QHash<int, QString> unsavedDocuments() const;
+
+ QTabWidget* tabWidget; /** Widget containing the tabs of the editor */
+
+ public slots:
+
+ /**
+ * @details Return pointer to the currently activated text edit tab page.
+ *
+ */
+ EditorPage* slotCurPageTextEdit() const;
+
+ /**
+ * @details Return pointer to the currently activated file treeview tab page.
+ *
+ */
+ FilePage* slotCurPageFileTreeView() const;
+
+ /**
+ * @details Insert a ">" at the begining of every line of current textedit.
+ */
+ void slotQuote() const;
+
+ /**
+ * @details replace the text of currently active textedit with given text.
+ * @param text to fill on.
+ */
+ void slotFillTextEditWithText(const QString& text) const;
+
+ /**
+ * @details Saves the content of the current tab, if it has a filepath
+ * otherwise it calls saveAs for the current tab
+ */
+ void slotSave();
+
+ /**
+ * @details Opens a savefiledialog and calls saveFile with the choosen
+ * filename.
+ *
+ * @return Return the return value of the savefile method
+ */
+ bool slotSaveAs();
+
+ /**
+ * @details Show an OpenFileDoalog and open the file in a new tab.
+ * Shows an error dialog, if the open fails.
+ * Set the focus to the tab of the opened file.
+ */
+ void slotOpen();
+
+ /**
+ * @details Open a print-dialog for the current tab
+ */
+ void slotPrint();
+
+ /**
+ * @details Adds a new tab with the title "untitled"+countpage+".txt"
+ * Sets the focus to the new tab. Increase Tab-Count by
+ * one
+ */
+ void slotNewTab();
+
+ /**
+ * @details Adds a new tab with opening file by path
+ */
+ void slotOpenFile(QString& path);
+
+ /**
+ * @details Adds a new tab with the given title and opens given html file.
+ * Increase Tab-Count by one
+ * @param title title for the tab
+ * @param path path for html file to show
+ */
+ void slotNewHelpTab(const QString& title, const QString& path) const;
+
+ /**
+ * New File Tab to do file operation
+ */
+ void slotNewFileTab() const;
+
+ /**
+ * @details put a * in front of current tabs title, if current textedit is
+ * modified
+ */
+ void slotShowModified() const;
+
+ /**
+ * @details close the current tab and decrease TabWidget->count by \a 1
+ *
+ */
+ void slotCloseTab();
+
+ /**
+ * @details Switch to the next tab.
+ *
+ */
+ void slotSwitchTabUp() const;
+
+ /**
+ * @details Switch to the previous tab.
+ *
+ */
+ void slotSwitchTabDown() const;
+
+ private:
+ /**
+ * @details return just a filename stripped of a whole path
+ *
+ * @param a filename path
+ * @return QString containing the filename
+ */
+ static QString strippedName(const QString& fullFileName);
+
+ /**
+ * @brief
+ *
+ * @param askToSave
+ */
+ bool maybeSaveCurrentTab(bool askToSave);
+
+ /****************************************************************************************
+ * Name: countPage
+ * Description: int cotaining the number of added tabs
+ */
+ int countPage; /* TODO */
+
+ private slots:
+
+ void slotFilePagePathChanged(const QString& path) const;
+
+ /**
+ * @details Remove the tab with given index
+ *
+ * @param index Tab-number to remove
+ */
+ void removeTab(int index);
+
+ /**
+ * @details Cut selected text in current textpage.
+ */
+ void slotCut() const;
+
+ /**
+ * @details Copy selected text of current textpage to clipboard.
+ */
+ void slotCopy() const;
+
+ /**
+ * @details Paste text from clipboard to current textpage.
+ */
+ void slotPaste() const;
+
+ /**
+ * @details Undo last change in current textpage.
+ *
+ */
+ void slotUndo() const;
+ /****************************************************************************************
+ * Name: redo
+ * Description: redo last change in current textpage
+ * Parameters: none
+ * Return Values: none
+ * Change on members: none
+ */
+ /**
+ * @brief
+ *
+ */
+ void slotRedo() const;
+
+ void slotZoomIn() const;
+
+ void slotZoomOut() const;
+ /****************************************************************************************
+ * Name: selectAll
+ * Description: select all in current textpage
+ * Parameters: none
+ * Return Values: none
+ * Change on members: none
+ */
+ /**
+ * @brief
+ *
+ */
+ void slotSelectAll() const;
+
+ protected:
+ /****************************************************************************************
+ * Name: saveFile
+ * Description: Saves the content of currentTab to the file filename
+ * Parameters: QString filename contains the full path of the file to
+ * save Return Values: true, if the file was saved succesfully false, if
+ * parameter filename is empty or the saving failed Change on members: sets
+ * isModified of the current tab to false
+ */
+ /**
+ * @brief
+ *
+ * @param fileName
+ */
+ bool saveFile(const QString& fileName);
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // __TEXTEDIT_H__
diff --git a/src/ui/widgets/VerifyKeyDetailBox.cpp b/src/ui/widgets/VerifyKeyDetailBox.cpp
index e0f79c3e..cd5b6641 100644
--- a/src/ui/widgets/VerifyKeyDetailBox.cpp
+++ b/src/ui/widgets/VerifyKeyDetailBox.cpp
@@ -1,7 +1,7 @@
/**
- * This file is part of GPGFrontend.
+ * This file is part of GpgFrontend.
*
- * GPGFrontend is free software: you can redistribute it and/or modify
+ * GpgFrontend is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
@@ -24,180 +24,198 @@
#include "ui/widgets/VerifyKeyDetailBox.h"
-VerifyKeyDetailBox::VerifyKeyDetailBox(QWidget *parent, GpgME::GpgContext *ctx, KeyList *keyList,
- gpgme_signature_t signature) :
- QGroupBox(parent), mCtx(ctx), mKeyList(keyList), fpr(signature->fpr) {
+#include "gpg/function/GpgKeyGetter.h"
- auto *vbox = new QVBoxLayout();
+namespace GpgFrontend::UI {
- switch (gpg_err_code(signature->status)) {
- case GPG_ERR_NO_PUBKEY: {
- this->setTitle("A Error Signature");
- auto *importButton = new QPushButton(tr("Import from keyserver"));
- connect(importButton, SIGNAL(clicked()), this, SLOT(slotImportFormKeyserver()));
+VerifyKeyDetailBox::VerifyKeyDetailBox(QWidget* parent, KeyList* keyList,
+ gpgme_signature_t signature)
+ : QGroupBox(parent), mKeyList(keyList), fpr(signature->fpr) {
+ auto* vbox = new QVBoxLayout();
- this->setTitle(tr("Key not present with id 0x") + signature->fpr);
+ switch (gpg_err_code(signature->status)) {
+ case GPG_ERR_NO_PUBKEY: {
+ this->setTitle("A Error Signature");
+ auto* importButton = new QPushButton(_("Import from keyserver"));
+ connect(importButton, SIGNAL(clicked()), this,
+ SLOT(slotImportFormKeyserver()));
- auto grid = new QGridLayout();
+ this->setTitle(QString(_("Key not present with id 0x")) + signature->fpr);
- grid->addWidget(new QLabel(tr("Status:")), 0, 0);
- //grid->addWidget(new QLabel(tr("Fingerprint:")), 1, 0);
- grid->addWidget(new QLabel(tr("Key not present in keylist")), 0, 1);
- //grid->addWidget(new QLabel(signature->fpr), 1, 1);
- grid->addWidget(importButton, 2, 0, 2, 1);
+ auto grid = new QGridLayout();
- vbox->addLayout(grid);
- break;
- }
- case GPG_ERR_NO_ERROR: {
- this->setTitle("A Signature:");
- auto gird = createKeyInfoGrid(signature);
- if(gird != nullptr) {
- vbox->addLayout(gird);
- } else {
- vbox->addWidget(new QLabel(tr("Key Information is NOT Available")));
- if(signature->fpr != nullptr) {
- vbox->addWidget(new QLabel(tr("Fingerprint: ") + QString(signature->fpr)));
- }
- }
- break;
+ grid->addWidget(new QLabel(QString(_("Status")) + _(":")), 0, 0);
+ // grid->addWidget(new QLabel(_("Fingerprint:")), 1, 0);
+ grid->addWidget(new QLabel(_("Key not present in key list")), 0, 1);
+ // grid->addWidget(new QLabel(signature->fpr), 1, 1);
+ grid->addWidget(importButton, 2, 0, 2, 1);
+
+ vbox->addLayout(grid);
+ break;
+ }
+ case GPG_ERR_NO_ERROR: {
+ this->setTitle(QString(_("A Signature")) + ":");
+ auto gird = createKeyInfoGrid(signature);
+ if (gird != nullptr) {
+ vbox->addLayout(gird);
+ } else {
+ vbox->addWidget(new QLabel(_("Key Information is NOT Available")));
+ if (signature->fpr != nullptr) {
+ vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " +
+ QString(signature->fpr)));
}
- case GPG_ERR_CERT_REVOKED: {
- this->setTitle("An Error Signature");
- vbox->addWidget(new QLabel(tr("Status: Cert Revoked")));
- auto gird = createKeyInfoGrid(signature);
- if (gird != nullptr) {
- vbox->addLayout(gird);
- } else {
- vbox->addWidget(new QLabel(tr("Key Information is NOT Available")));
- if(signature->fpr != nullptr) {
- vbox->addWidget(new QLabel(tr("Fingerprint: ") + QString(signature->fpr)));
- }
- }
- break;
+ }
+ break;
+ }
+ case GPG_ERR_CERT_REVOKED: {
+ this->setTitle("An Error Signature");
+ vbox->addWidget(
+ new QLabel(QString(_("Status")) + ":" + _("Cert Revoked")));
+ auto gird = createKeyInfoGrid(signature);
+ if (gird != nullptr) {
+ vbox->addLayout(gird);
+ } else {
+ vbox->addWidget(new QLabel(_("Key Information is NOT Available")));
+ if (signature->fpr != nullptr) {
+ vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " +
+ QString(signature->fpr)));
}
- case GPG_ERR_SIG_EXPIRED: {
- this->setTitle("An Error Signature");
- vbox->addWidget(new QLabel(tr("Status: Signature Expired")));
- auto gird = createKeyInfoGrid(signature);
- if (gird != nullptr) {
- vbox->addLayout(gird);
- } else {
- vbox->addWidget(new QLabel(tr("Key Information is NOT Available")));
- if(signature->fpr != nullptr) {
- vbox->addWidget(new QLabel(tr("Fingerprint: ") + QString(signature->fpr)));
- }
- }
- break;
+ }
+ break;
+ }
+ case GPG_ERR_SIG_EXPIRED: {
+ this->setTitle("An Error Signature");
+ vbox->addWidget(
+ new QLabel(QString(_("Status")) + ":" + _("Signature Expired")));
+ auto gird = createKeyInfoGrid(signature);
+ if (gird != nullptr) {
+ vbox->addLayout(gird);
+ } else {
+ vbox->addWidget(new QLabel(_("Key Information is NOT Available")));
+ if (signature->fpr != nullptr) {
+ vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " +
+ QString(signature->fpr)));
}
- case GPG_ERR_KEY_EXPIRED: {
- this->setTitle("An Error Signature");
- vbox->addWidget(new QLabel(tr("Status: Signature Expired")));
- vbox->addWidget(new QLabel(tr("Status: Key Expired")));
- auto gird = createKeyInfoGrid(signature);
- if (gird != nullptr) {
- vbox->addLayout(gird);
- } else {
- vbox->addWidget(new QLabel(tr("Key Information is NOT Available")));
- if(signature->fpr != nullptr) {
- vbox->addWidget(new QLabel(tr("Fingerprint: ") + QString(signature->fpr)));
- }
- }
- break;
+ }
+ break;
+ }
+ case GPG_ERR_KEY_EXPIRED: {
+ this->setTitle("An Error Signature");
+ vbox->addWidget(
+ new QLabel(QString(_("Status")) + ":" + _("Key Expired")));
+ vbox->addWidget(
+ new QLabel(QString(_("Status")) + ":" + _("Key Expired")));
+ auto gird = createKeyInfoGrid(signature);
+ if (gird != nullptr) {
+ vbox->addLayout(gird);
+ } else {
+ vbox->addWidget(new QLabel(_("Key Information is NOT Available")));
+ if (signature->fpr != nullptr) {
+ vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " +
+ QString(signature->fpr)));
}
- case GPG_ERR_GENERAL: {
- this->setTitle("An Error Signature");
- vbox->addWidget(new QLabel(tr("Status: General Error")));
- auto gird = createKeyInfoGrid(signature);
- if (gird != nullptr) {
- vbox->addLayout(gird);
- } else {
- vbox->addWidget(new QLabel(tr("Key Information is NOT Available")));
- if(signature->fpr != nullptr) {
- vbox->addWidget(new QLabel(tr("Fingerprint: ") + QString(signature->fpr)));
- }
- }
- break;
+ }
+ break;
+ }
+ case GPG_ERR_GENERAL: {
+ this->setTitle("An Error Signature");
+ vbox->addWidget(
+ new QLabel(QString(_("Status")) + ":" + _("General Error")));
+ auto gird = createKeyInfoGrid(signature);
+ if (gird != nullptr) {
+ vbox->addLayout(gird);
+ } else {
+ vbox->addWidget(new QLabel(_("Key Information is NOT Available")));
+ if (signature->fpr != nullptr) {
+ vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " +
+ QString(signature->fpr)));
}
- default: {
- this->setTitle("An Error Signature");
- this->setTitle(tr("Status: Unknown Error"));
- auto gird = createKeyInfoGrid(signature);
- if (gird != nullptr) {
- vbox->addLayout(gird);
- } else {
- vbox->addWidget(new QLabel(tr("Key Information is NOT Available")));
- if(signature->fpr != nullptr) {
- vbox->addWidget(new QLabel(tr("Fingerprint: ") + QString(signature->fpr)));
- }
- }
- break;
+ }
+ break;
+ }
+ default: {
+ this->setTitle("An Error Signature");
+ this->setTitle(QString(_("Status")) + ":" + _("Unknown Error "));
+ auto gird = createKeyInfoGrid(signature);
+ if (gird != nullptr) {
+ vbox->addLayout(gird);
+ } else {
+ vbox->addWidget(new QLabel(_("Key Information is NOT Available")));
+ if (signature->fpr != nullptr) {
+ vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " +
+ QString(signature->fpr)));
}
+ }
+ break;
}
- this->setLayout(vbox);
+ }
+ this->setLayout(vbox);
}
void VerifyKeyDetailBox::slotImportFormKeyserver() {
- auto *importDialog = new KeyServerImportDialog(mCtx, mKeyList, false, this);
- importDialog->slotImport(QStringList(fpr));
+ auto* importDialog = new KeyServerImportDialog(false, this);
+ auto key_ids = std::make_unique<KeyIdArgsList>();
+ key_ids->push_back(fpr.toStdString());
+ importDialog->slotImport(key_ids);
}
QString VerifyKeyDetailBox::beautifyFingerprint(QString fingerprint) {
- uint len = fingerprint.length();
- if ((len > 0) && (len % 4 == 0))
- for (uint n = 0; 4 * (n + 1) < len; ++n)
- fingerprint.insert(static_cast<int>(5u * n + 4u), ' ');
- return fingerprint;
+ uint len = fingerprint.length();
+ if ((len > 0) && (len % 4 == 0))
+ for (uint n = 0; 4 * (n + 1) < len; ++n)
+ fingerprint.insert(static_cast<int>(5u * n + 4u), ' ');
+ return fingerprint;
}
-QGridLayout *VerifyKeyDetailBox::createKeyInfoGrid(gpgme_signature_t &signature) {
-
- auto grid = new QGridLayout();
- GpgKey key = mCtx->getKeyByFpr(signature->fpr);
-
- if(!key.good) return nullptr;
- grid->addWidget(new QLabel(tr("Signer Name:")), 0, 0);
- grid->addWidget(new QLabel(tr("Signer Email:")), 1, 0);
- grid->addWidget(new QLabel(tr("Key's Fingerprint:")), 2, 0);
- grid->addWidget(new QLabel(tr("Valid:")), 3, 0);
- grid->addWidget(new QLabel(tr("Flags:")), 4, 0);
-
- grid->addWidget(new QLabel(key.name), 0, 1);
- grid->addWidget(new QLabel(key.email), 1, 1);
- grid->addWidget(new QLabel(beautifyFingerprint(signature->fpr)), 2, 1);
-
-
- if(signature->summary & GPGME_SIGSUM_VALID) {
- grid->addWidget(new QLabel(tr("Fully Valid")), 3, 1);
- } else {
- grid->addWidget(new QLabel(tr("NOT Fully Valid")), 3, 1);
- }
-
- QString flags;
- QTextStream textStream(&flags);
-
- if(signature->summary & GPGME_SIGSUM_GREEN) {
- textStream << tr("Good ");
- }
- if(signature->summary & GPGME_SIGSUM_RED) {
- textStream << tr("Bad ");
- }
- if(signature->summary & GPGME_SIGSUM_SIG_EXPIRED) {
- textStream << tr("Expired ");
- }
- if(signature->summary & GPGME_SIGSUM_KEY_MISSING) {
- textStream << tr("Missing Key ");
- }
- if(signature->summary & GPGME_SIGSUM_KEY_REVOKED) {
- textStream << tr("Revoked Key ");
- }
- if(signature->summary & GPGME_SIGSUM_KEY_EXPIRED) {
- textStream << tr("Expired Key ");
- }
- if(signature->summary & GPGME_SIGSUM_CRL_MISSING) {
- textStream << tr("Missing CRL ");
- }
-
- grid->addWidget(new QLabel(tr(flags.toUtf8().constData())), 4, 1);
- return grid;
+QGridLayout* VerifyKeyDetailBox::createKeyInfoGrid(
+ gpgme_signature_t& signature) {
+ auto grid = new QGridLayout();
+ GpgKey key = GpgKeyGetter::GetInstance().GetKey(signature->fpr);
+
+ if (!key.good()) return nullptr;
+ grid->addWidget(new QLabel(QString(_("Signer Name")) + ":"), 0, 0);
+ grid->addWidget(new QLabel(QString(_("Signer Email")) + ":"), 1, 0);
+ grid->addWidget(new QLabel(QString(_("Key's Fingerprint")) + ":"), 2, 0);
+ grid->addWidget(new QLabel(QString(_("Valid")) + ":"), 3, 0);
+ grid->addWidget(new QLabel(QString(_("Flags")) + ":"), 4, 0);
+
+ grid->addWidget(new QLabel(QString::fromStdString(key.name())), 0, 1);
+ grid->addWidget(new QLabel(QString::fromStdString(key.email())), 1, 1);
+ grid->addWidget(new QLabel(beautifyFingerprint(signature->fpr)), 2, 1);
+
+ if (signature->summary & GPGME_SIGSUM_VALID) {
+ grid->addWidget(new QLabel(_("Fully Valid")), 3, 1);
+ } else {
+ grid->addWidget(new QLabel(_("NOT Fully Valid")), 3, 1);
+ }
+
+ QString flags;
+ QTextStream textStream(&flags);
+
+ if (signature->summary & GPGME_SIGSUM_GREEN) {
+ textStream << _("Good") << " ";
+ }
+ if (signature->summary & GPGME_SIGSUM_RED) {
+ textStream << _("Bad") << " ";
+ }
+ if (signature->summary & GPGME_SIGSUM_SIG_EXPIRED) {
+ textStream << _("Expired") << " ";
+ }
+ if (signature->summary & GPGME_SIGSUM_KEY_MISSING) {
+ textStream << _("Missing Key") << " ";
+ }
+ if (signature->summary & GPGME_SIGSUM_KEY_REVOKED) {
+ textStream << _("Revoked Key") << " ";
+ }
+ if (signature->summary & GPGME_SIGSUM_KEY_EXPIRED) {
+ textStream << _("Expired Key") << " ";
+ }
+ if (signature->summary & GPGME_SIGSUM_CRL_MISSING) {
+ textStream << _("Missing CRL") << " ";
+ }
+
+ grid->addWidget(new QLabel(_(flags.toUtf8().constData())), 4, 1);
+ return grid;
}
+
+} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/widgets/VerifyKeyDetailBox.h b/src/ui/widgets/VerifyKeyDetailBox.h
new file mode 100644
index 00000000..c1b26bb2
--- /dev/null
+++ b/src/ui/widgets/VerifyKeyDetailBox.h
@@ -0,0 +1,55 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef __VERIFYKEYDETAILBOX_H__
+#define __VERIFYKEYDETAILBOX_H__
+
+#include "ui/KeyServerImportDialog.h"
+#include "ui/widgets/KeyList.h"
+
+namespace GpgFrontend::UI {
+
+class VerifyKeyDetailBox : public QGroupBox {
+ Q_OBJECT
+ public:
+ explicit VerifyKeyDetailBox(QWidget* parent, KeyList* mKeyList,
+ gpgme_signature_t signature);
+
+ private slots:
+
+ void slotImportFormKeyserver();
+
+ private:
+ KeyList* mKeyList;
+
+ static QString beautifyFingerprint(QString fingerprint);
+
+ static QGridLayout* createKeyInfoGrid(gpgme_signature_t& signature);
+
+ QString fpr;
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // __VERIFYKEYDETAILBOX_H__