aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt322
-rw-r--r--src/GpgFrontend.h.in52
-rw-r--r--src/GpgFrontendBuildInfo.h.in23
-rw-r--r--src/GpgFrontendBuildInstallInfo.h.in11
-rw-r--r--src/GpgFrontendContext.cpp54
-rw-r--r--src/GpgFrontendContext.h78
-rw-r--r--src/app.cpp111
-rw-r--r--src/app.h37
-rw-r--r--src/cmd.cpp97
-rw-r--r--src/cmd.h43
-rw-r--r--src/core/CMakeLists.txt68
-rw-r--r--src/core/GpgConstants.cpp180
-rw-r--r--src/core/GpgConstants.h207
-rw-r--r--src/core/GpgContext.cpp660
-rw-r--r--src/core/GpgContext.h210
-rw-r--r--src/core/GpgCoreInit.cpp520
-rw-r--r--src/core/GpgCoreInit.h42
-rw-r--r--src/core/GpgFrontendCore.cpp34
-rw-r--r--src/core/GpgFrontendCore.h57
-rw-r--r--src/core/GpgFunctionObject.cpp137
-rw-r--r--src/core/GpgFunctionObject.h311
-rw-r--r--src/core/GpgGenKeyInfo.cpp284
-rw-r--r--src/core/GpgInfo.h65
-rw-r--r--src/core/GpgModel.h34
-rw-r--r--src/core/common/CoreCommonUtil.cpp58
-rw-r--r--src/core/common/CoreCommonUtil.h87
-rw-r--r--src/core/function/ArchiveFileOperator.cpp410
-rw-r--r--src/core/function/ArchiveFileOperator.h54
-rw-r--r--src/core/function/CacheManager.cpp311
-rw-r--r--src/core/function/CacheManager.h157
-rw-r--r--src/core/function/CharsetOperator.cpp133
-rw-r--r--src/core/function/CoreSignalStation.cpp15
-rw-r--r--src/core/function/CoreSignalStation.h31
-rw-r--r--src/core/function/DataObjectOperator.cpp178
-rw-r--r--src/core/function/DataObjectOperator.h40
-rw-r--r--src/core/function/FileOperator.cpp124
-rw-r--r--src/core/function/FileOperator.h92
-rw-r--r--src/core/function/GlobalSettingStation.cpp242
-rw-r--r--src/core/function/GlobalSettingStation.h181
-rw-r--r--src/core/function/KeyPackageOperator.cpp149
-rw-r--r--src/core/function/KeyPackageOperator.h44
-rw-r--r--src/core/function/LoggerManager.cpp155
-rw-r--r--src/core/function/LoggerManager.h65
-rw-r--r--src/core/function/PassphraseGenerator.cpp24
-rw-r--r--src/core/function/PassphraseGenerator.h32
-rw-r--r--src/core/function/SecureMemoryAllocator.cpp63
-rw-r--r--src/core/function/SecureMemoryAllocator.h60
-rw-r--r--src/core/function/basic/ChannelObject.cpp59
-rw-r--r--src/core/function/basic/ChannelObject.h98
-rw-r--r--src/core/function/basic/GpgFunctionObject.cpp105
-rw-r--r--src/core/function/basic/GpgFunctionObject.h194
-rw-r--r--src/core/function/basic/SingletonStorage.cpp133
-rw-r--r--src/core/function/basic/SingletonStorage.h90
-rw-r--r--src/core/function/basic/SingletonStorageCollection.cpp124
-rw-r--r--src/core/function/basic/SingletonStorageCollection.h79
-rw-r--r--src/core/function/gpg/GpgAdvancedOperator.cpp318
-rw-r--r--src/core/function/gpg/GpgAdvancedOperator.h47
-rw-r--r--src/core/function/gpg/GpgBasicOperator.cpp306
-rw-r--r--src/core/function/gpg/GpgBasicOperator.h61
-rw-r--r--src/core/function/gpg/GpgCommandExecutor.cpp371
-rw-r--r--src/core/function/gpg/GpgCommandExecutor.h61
-rw-r--r--src/core/function/gpg/GpgContext.cpp336
-rw-r--r--src/core/function/gpg/GpgContext.h76
-rw-r--r--src/core/function/gpg/GpgFileOpera.cpp540
-rw-r--r--src/core/function/gpg/GpgFileOpera.h158
-rw-r--r--src/core/function/gpg/GpgKeyGetter.cpp278
-rw-r--r--src/core/function/gpg/GpgKeyGetter.h74
-rw-r--r--src/core/function/gpg/GpgKeyImportExporter.cpp227
-rw-r--r--src/core/function/gpg/GpgKeyImportExporter.h138
-rw-r--r--src/core/function/gpg/GpgKeyManager.cpp239
-rw-r--r--src/core/function/gpg/GpgKeyManager.h60
-rw-r--r--src/core/function/gpg/GpgKeyOpera.cpp439
-rw-r--r--src/core/function/gpg/GpgKeyOpera.h49
-rw-r--r--src/core/function/gpg/GpgUIDOperator.cpp62
-rw-r--r--src/core/function/gpg/GpgUIDOperator.h23
-rw-r--r--src/core/function/result_analyse/GpgDecryptResultAnalyse.cpp115
-rw-r--r--src/core/function/result_analyse/GpgDecryptResultAnalyse.h22
-rw-r--r--src/core/function/result_analyse/GpgEncryptResultAnalyse.cpp64
-rw-r--r--src/core/function/result_analyse/GpgEncryptResultAnalyse.h20
-rw-r--r--src/core/function/result_analyse/GpgResultAnalyse.cpp14
-rw-r--r--src/core/function/result_analyse/GpgResultAnalyse.h33
-rw-r--r--src/core/function/result_analyse/GpgSignResultAnalyse.cpp132
-rw-r--r--src/core/function/result_analyse/GpgSignResultAnalyse.h13
-rw-r--r--src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp244
-rw-r--r--src/core/function/result_analyse/GpgVerifyResultAnalyse.h22
-rw-r--r--src/core/log/QtLoggerFmt.h51
-rw-r--r--src/core/model/CommonStruct.h46
-rw-r--r--src/core/model/DataObject.cpp83
-rw-r--r--src/core/model/DataObject.h104
-rw-r--r--src/core/model/GFBuffer.cpp78
-rw-r--r--src/core/model/GFBuffer.h62
-rw-r--r--src/core/model/GFDataExchanger.cpp89
-rw-r--r--src/core/model/GFDataExchanger.h53
-rw-r--r--src/core/model/GpgData.cpp121
-rw-r--r--src/core/model/GpgData.h67
-rw-r--r--src/core/model/GpgDecryptResult.cpp65
-rw-r--r--src/core/model/GpgDecryptResult.h54
-rw-r--r--src/core/model/GpgEncryptResult.cpp66
-rw-r--r--src/core/model/GpgEncryptResult.h53
-rw-r--r--src/core/model/GpgGenKeyInfo.cpp486
-rw-r--r--src/core/model/GpgGenKeyInfo.h (renamed from src/core/GpgGenKeyInfo.h)214
-rw-r--r--src/core/model/GpgGenerateKeyResult.cpp59
-rw-r--r--src/core/model/GpgGenerateKeyResult.h59
-rw-r--r--src/core/model/GpgImportInformation.cpp54
-rw-r--r--src/core/model/GpgImportInformation.h80
-rw-r--r--src/core/model/GpgKey.cpp189
-rw-r--r--src/core/model/GpgKey.h138
-rw-r--r--src/core/model/GpgKeySignature.cpp66
-rw-r--r--src/core/model/GpgKeySignature.h60
-rw-r--r--src/core/model/GpgPassphraseContext.cpp60
-rw-r--r--src/core/model/GpgPassphraseContext.h63
-rw-r--r--src/core/model/GpgRecipient.cpp40
-rw-r--r--src/core/model/GpgRecipient.h51
-rw-r--r--src/core/model/GpgSignResult.cpp65
-rw-r--r--src/core/model/GpgSignResult.h53
-rw-r--r--src/core/model/GpgSignature.cpp55
-rw-r--r--src/core/model/GpgSignature.h44
-rw-r--r--src/core/model/GpgSubKey.cpp83
-rw-r--r--src/core/model/GpgSubKey.h64
-rw-r--r--src/core/model/GpgTOFUInfo.cpp59
-rw-r--r--src/core/model/GpgTOFUInfo.h35
-rw-r--r--src/core/model/GpgUID.cpp39
-rw-r--r--src/core/model/GpgUID.h40
-rw-r--r--src/core/model/GpgVerifyResult.cpp62
-rw-r--r--src/core/model/GpgVerifyResult.h53
-rw-r--r--src/core/module/Event.cpp139
-rw-r--r--src/core/module/Event.h95
-rw-r--r--src/core/module/GlobalModuleContext.cpp377
-rw-r--r--src/core/module/GlobalModuleContext.h88
-rw-r--r--src/core/module/GlobalRegisterTable.cpp167
-rw-r--r--src/core/module/GlobalRegisterTable.h66
-rw-r--r--src/core/module/GpgFrontendModuleSystem.h34
-rw-r--r--src/core/module/Module.cpp106
-rw-r--r--src/core/module/Module.h80
-rw-r--r--src/core/module/ModuleManager.cpp184
-rw-r--r--src/core/module/ModuleManager.h179
-rw-r--r--src/core/thread/CtxCheckTask.cpp54
-rw-r--r--src/core/thread/CtxCheckTask.h63
-rw-r--r--src/core/thread/FileReadTask.cpp57
-rw-r--r--src/core/thread/FileReadTask.h22
-rw-r--r--src/core/thread/Task.cpp370
-rw-r--r--src/core/thread/Task.h223
-rw-r--r--src/core/thread/TaskRunner.cpp212
-rw-r--r--src/core/thread/TaskRunner.h83
-rw-r--r--src/core/thread/TaskRunnerGetter.cpp44
-rw-r--r--src/core/thread/TaskRunnerGetter.h32
-rw-r--r--src/core/thread/ThreadingModel.h9
-rw-r--r--src/core/typedef/CoreTypedef.h49
-rw-r--r--src/core/typedef/GpgTypedef.h76
-rw-r--r--src/core/utils/AsyncUtils.cpp103
-rw-r--r--src/core/utils/AsyncUtils.h63
-rw-r--r--src/core/utils/CacheUtils.cpp47
-rw-r--r--src/core/utils/CacheUtils.h54
-rw-r--r--src/core/utils/CommonUtils.cpp74
-rw-r--r--src/core/utils/CommonUtils.h54
-rw-r--r--src/core/utils/FilesystemUtils.cpp104
-rw-r--r--src/core/utils/FilesystemUtils.h78
-rw-r--r--src/core/utils/GpgUtils.cpp172
-rw-r--r--src/core/utils/GpgUtils.h108
-rw-r--r--src/core/utils/IOUtils.cpp162
-rw-r--r--src/core/utils/IOUtils.h130
-rw-r--r--src/core/utils/LocalizedUtils.cpp (renamed from src/core/function/CharsetOperator.h)23
-rw-r--r--src/core/utils/LocalizedUtils.h35
-rw-r--r--src/core/utils/LogUtils.cpp59
-rw-r--r--src/core/utils/LogUtils.h112
-rw-r--r--src/core/utils/MemoryUtils.cpp42
-rw-r--r--src/core/utils/MemoryUtils.h179
-rw-r--r--src/core/utils/aes/aes_ssl.h (renamed from src/core/function/aes/aes_ssl.h)9
-rw-r--r--src/core/utils/aes/aes_ssl_cbc.cpp (renamed from src/core/function/aes/aes_ssl_cbc.cpp)0
-rw-r--r--src/init.cpp148
-rw-r--r--src/init.h62
-rw-r--r--src/main.cpp192
-rw-r--r--src/main.h37
-rw-r--r--src/module/CMakeLists.txt80
-rw-r--r--src/module/GpgFrontendModule.h36
-rw-r--r--src/module/GpgFrontendModuleExport.h42
-rw-r--r--src/module/GpgFrontendModuleInit.cpp66
-rw-r--r--src/module/GpgFrontendModuleInit.h51
-rw-r--r--src/module/integrated/gnupg_info_gathering_module/CMakeLists.txt38
-rw-r--r--src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.cpp358
-rw-r--r--src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.h54
-rw-r--r--src/module/integrated/gnupg_info_gathering_module/GpgInfo.cpp80
-rw-r--r--src/module/integrated/gnupg_info_gathering_module/GpgInfo.h87
-rw-r--r--src/module/integrated/version_checking_module/CMakeLists.txt41
-rw-r--r--src/module/integrated/version_checking_module/SoftwareVersion.cpp56
-rw-r--r--src/module/integrated/version_checking_module/SoftwareVersion.h (renamed from src/ui/struct/SoftwareVersion.h)41
-rw-r--r--src/module/integrated/version_checking_module/VersionCheckTask.cpp154
-rw-r--r--src/module/integrated/version_checking_module/VersionCheckTask.h (renamed from src/ui/thread/VersionCheckTask.h)32
-rw-r--r--src/module/integrated/version_checking_module/VersionCheckingModule.cpp105
-rw-r--r--src/module/integrated/version_checking_module/VersionCheckingModule.h60
-rw-r--r--src/module/sdk/Basic.cpp27
-rw-r--r--src/module/sdk/Basic.h36
-rw-r--r--src/module/sdk/Gpg.cpp27
-rw-r--r--src/module/sdk/Gpg.h (renamed from src/core/GpgInfo.cpp)6
-rw-r--r--src/module/sdk/GpgFrontendModuleSDK.h33
-rw-r--r--src/module/sdk/GpgFrontendModuleSDKExport.h42
-rw-r--r--src/module/sdk/Log.cpp (renamed from src/before_exit.cpp)17
-rw-r--r--src/module/sdk/Log.h71
-rw-r--r--src/module/sdk/UI.cpp27
-rw-r--r--src/module/sdk/UI.h29
-rw-r--r--src/pinentry/CMakeLists.txt69
-rw-r--r--src/pinentry/accessibility.cpp44
-rw-r--r--src/pinentry/accessibility.h40
-rw-r--r--src/pinentry/capslock/capslock.cpp41
-rw-r--r--src/pinentry/capslock/capslock.h77
-rw-r--r--src/pinentry/capslock/capslock_unix.cpp137
-rw-r--r--src/pinentry/capslock/capslock_win.cpp26
-rw-r--r--src/pinentry/focusframe.cpp72
-rw-r--r--src/pinentry/focusframe.h36
-rw-r--r--src/pinentry/keyboardfocusindication.cpp43
-rw-r--r--src/pinentry/keyboardfocusindication.h42
-rw-r--r--src/pinentry/pinentry.cpp926
-rw-r--r--src/pinentry/pinentry.h355
-rw-r--r--src/pinentry/pinentry_debug.cpp31
-rw-r--r--src/pinentry/pinentry_debug.h28
-rw-r--r--src/pinentry/pinentryconfirm.cpp123
-rw-r--r--src/pinentry/pinentryconfirm.h63
-rw-r--r--src/pinentry/pinentrydialog.cpp691
-rw-r--r--src/pinentry/pinentrydialog.h171
-rw-r--r--src/pinentry/pinlineedit.cpp204
-rw-r--r--src/pinentry/pinlineedit.h60
-rw-r--r--src/pinentry/qti18n.cpp93
-rw-r--r--src/pinentry/secmem++.h91
-rw-r--r--src/pinentry/util.cpp116
-rw-r--r--src/pinentry/util.h35
-rw-r--r--src/signal.cpp40
-rw-r--r--src/test/CMakeLists.txt40
-rw-r--r--src/test/GpgFrontendCoreExport.h42
-rw-r--r--src/test/GpgFrontendTest.cpp113
-rw-r--r--src/test/GpgFrontendTest.h51
-rw-r--r--src/test/GpgFrontendTestExport.h42
-rw-r--r--src/test/core/GpgCoreTest.cpp40
-rw-r--r--src/test/core/GpgCoreTest.h42
-rw-r--r--src/test/core/GpgCoreTestBasicOpera.cpp373
-rw-r--r--src/test/core/GpgCoreTestFileBasicOpera.cpp239
-rw-r--r--src/test/core/GpgCoreTestImportExport.cpp39
-rw-r--r--src/test/core/GpgCoreTestKeyModel.cpp181
-rw-r--r--src/test/core/GpgCoreTestKeygen.cpp212
-rw-r--r--src/ui/CMakeLists.txt23
-rw-r--r--src/ui/GpgFrontendApplication.cpp75
-rw-r--r--src/ui/GpgFrontendApplication.h22
-rw-r--r--src/ui/GpgFrontendUI.h32
-rw-r--r--src/ui/GpgFrontendUIInit.cpp347
-rw-r--r--src/ui/GpgFrontendUIInit.h27
-rw-r--r--src/ui/UISignalStation.cpp44
-rw-r--r--src/ui/UISignalStation.h (renamed from src/ui/SignalStation.h)27
-rw-r--r--src/ui/UserInterfaceUtils.cpp436
-rw-r--r--src/ui/UserInterfaceUtils.h73
-rw-r--r--src/ui/dialog/GeneralDialog.cpp113
-rw-r--r--src/ui/dialog/GeneralDialog.h18
-rwxr-xr-xsrc/ui/dialog/QuitDialog.cpp66
-rwxr-xr-xsrc/ui/dialog/QuitDialog.h13
-rw-r--r--src/ui/dialog/SignersPicker.cpp32
-rw-r--r--src/ui/dialog/SignersPicker.h17
-rw-r--r--src/ui/dialog/WaitingDialog.cpp13
-rw-r--r--src/ui/dialog/WaitingDialog.h9
-rw-r--r--src/ui/dialog/Wizard.cpp197
-rw-r--r--src/ui/dialog/Wizard.h9
-rw-r--r--src/ui/dialog/details/SignatureDetailsDialog.cpp4
-rw-r--r--src/ui/dialog/details/SignatureDetailsDialog.h9
-rw-r--r--src/ui/dialog/details/VerifyDetailsDialog.cpp59
-rw-r--r--src/ui/dialog/details/VerifyDetailsDialog.h11
-rw-r--r--src/ui/dialog/gnupg/GnuPGControllerDialog.cpp316
-rw-r--r--src/ui/dialog/gnupg/GnuPGControllerDialog.h37
-rw-r--r--src/ui/dialog/help/AboutDialog.cpp228
-rw-r--r--src/ui/dialog/help/AboutDialog.h20
-rw-r--r--src/ui/dialog/help/GnupgTab.cpp184
-rw-r--r--src/ui/dialog/help/GnupgTab.h16
-rw-r--r--src/ui/dialog/import_export/ExportKeyPackageDialog.cpp136
-rw-r--r--src/ui/dialog/import_export/ExportKeyPackageDialog.h12
-rw-r--r--src/ui/dialog/import_export/KeyImportDetailDialog.cpp136
-rw-r--r--src/ui/dialog/import_export/KeyImportDetailDialog.h22
-rw-r--r--src/ui/dialog/import_export/KeyServerImportDialog.cpp409
-rw-r--r--src/ui/dialog/import_export/KeyServerImportDialog.h33
-rw-r--r--src/ui/dialog/import_export/KeyUploadDialog.cpp133
-rw-r--r--src/ui/dialog/import_export/KeyUploadDialog.h14
-rw-r--r--src/ui/dialog/key_generate/KeygenDialog.cpp334
-rw-r--r--src/ui/dialog/key_generate/KeygenDialog.h46
-rw-r--r--src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp246
-rw-r--r--src/ui/dialog/key_generate/SubkeyGenerateDialog.h35
-rw-r--r--src/ui/dialog/keypair_details/KeyDetailsDialog.cpp29
-rw-r--r--src/ui/dialog/keypair_details/KeyDetailsDialog.h12
-rw-r--r--src/ui/dialog/keypair_details/KeyNewUIDDialog.cpp46
-rw-r--r--src/ui/dialog/keypair_details/KeyNewUIDDialog.h17
-rw-r--r--src/ui/dialog/keypair_details/KeyPairDetailTab.cpp253
-rw-r--r--src/ui/dialog/keypair_details/KeyPairDetailTab.h18
-rw-r--r--src/ui/dialog/keypair_details/KeyPairOperaTab.cpp306
-rw-r--r--src/ui/dialog/keypair_details/KeyPairOperaTab.h16
-rw-r--r--src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp241
-rw-r--r--src/ui/dialog/keypair_details/KeyPairSubkeyTab.h13
-rw-r--r--src/ui/dialog/keypair_details/KeyPairUIDTab.cpp309
-rw-r--r--src/ui/dialog/keypair_details/KeyPairUIDTab.h13
-rw-r--r--src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp101
-rw-r--r--src/ui/dialog/keypair_details/KeySetExpireDateDialog.h15
-rw-r--r--src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp56
-rw-r--r--src/ui/dialog/keypair_details/KeyUIDSignDialog.h15
-rw-r--r--src/ui/dialog/settings/SettingsAdvanced.cpp96
-rw-r--r--src/ui/dialog/settings/SettingsAppearance.cpp93
-rw-r--r--src/ui/dialog/settings/SettingsAppearance.h11
-rw-r--r--src/ui/dialog/settings/SettingsDialog.cpp88
-rw-r--r--src/ui/dialog/settings/SettingsDialog.h9
-rw-r--r--src/ui/dialog/settings/SettingsGeneral.cpp250
-rw-r--r--src/ui/dialog/settings/SettingsGeneral.h22
-rw-r--r--src/ui/dialog/settings/SettingsKeyServer.cpp138
-rw-r--r--src/ui/dialog/settings/SettingsKeyServer.h9
-rw-r--r--src/ui/dialog/settings/SettingsNetwork.cpp259
-rw-r--r--src/ui/dialog/settings/SettingsNetwork.h11
-rw-r--r--src/ui/function/GenerateRevokeCertification.cpp89
-rw-r--r--src/ui/function/GenerateRevokeCertification.h (renamed from src/ui/SignalStation.cpp)22
-rw-r--r--src/ui/function/RaisePinentry.cpp122
-rw-r--r--src/ui/function/RaisePinentry.h (renamed from src/ui/dialog/settings/SettingsAdvanced.h)43
-rw-r--r--src/ui/function/SetOwnerTrustLevel.cpp96
-rw-r--r--src/ui/function/SetOwnerTrustLevel.h55
-rw-r--r--src/ui/main_window/GeneralMainWindow.cpp114
-rw-r--r--src/ui/main_window/GeneralMainWindow.h17
-rw-r--r--src/ui/main_window/KeyMgmt.cpp417
-rw-r--r--src/ui/main_window/KeyMgmt.h24
-rw-r--r--src/ui/main_window/MainWindow.cpp247
-rw-r--r--src/ui/main_window/MainWindow.h154
-rw-r--r--src/ui/main_window/MainWindowFileSlotFunction.cpp1229
-rw-r--r--src/ui/main_window/MainWindowGpgOperaFunction.cpp396
-rw-r--r--src/ui/main_window/MainWindowSlotFunction.cpp792
-rw-r--r--src/ui/main_window/MainWindowSlotUI.cpp71
-rw-r--r--src/ui/main_window/MainWindowUI.cpp565
-rw-r--r--src/ui/struct/CacheObject.cpp45
-rw-r--r--src/ui/struct/CacheObject.h52
-rw-r--r--src/ui/struct/SettingsObject.cpp91
-rw-r--r--src/ui/struct/SettingsObject.h37
-rw-r--r--src/ui/struct/SoftwareVersion.cpp101
-rw-r--r--src/ui/struct/settings/AppearanceSO.h77
-rw-r--r--src/ui/struct/settings/KeyServerSO.h79
-rw-r--r--src/ui/struct/settings/WindowStateSO.h65
-rw-r--r--src/ui/thread/KeyServerImportTask.cpp69
-rw-r--r--src/ui/thread/KeyServerImportTask.h43
-rw-r--r--src/ui/thread/KeyServerSearchTask.cpp34
-rw-r--r--src/ui/thread/KeyServerSearchTask.h37
-rw-r--r--src/ui/thread/ListedKeyServerTestTask.cpp46
-rw-r--r--src/ui/thread/ListedKeyServerTestTask.h37
-rw-r--r--src/ui/thread/ProxyConnectionTestTask.cpp31
-rw-r--r--src/ui/thread/ProxyConnectionTestTask.h34
-rw-r--r--src/ui/thread/VersionCheckTask.cpp178
-rw-r--r--src/ui/widgets/FilePage.cpp487
-rw-r--r--src/ui/widgets/FilePage.h103
-rw-r--r--src/ui/widgets/FileTreeView.cpp403
-rw-r--r--src/ui/widgets/FileTreeView.h229
-rw-r--r--src/ui/widgets/FindWidget.cpp47
-rw-r--r--src/ui/widgets/FindWidget.h9
-rw-r--r--src/ui/widgets/HelpPage.cpp6
-rw-r--r--src/ui/widgets/HelpPage.h9
-rw-r--r--src/ui/widgets/InfoBoardWidget.cpp61
-rw-r--r--src/ui/widgets/InfoBoardWidget.h9
-rw-r--r--src/ui/widgets/KeyList.cpp262
-rw-r--r--src/ui/widgets/KeyList.h30
-rw-r--r--src/ui/widgets/PlainTextEditorPage.cpp179
-rw-r--r--src/ui/widgets/PlainTextEditorPage.h44
-rw-r--r--src/ui/widgets/TOFUInfoPage.cpp27
-rw-r--r--src/ui/widgets/TOFUInfoPage.h15
-rw-r--r--src/ui/widgets/TextEdit.cpp273
-rw-r--r--src/ui/widgets/TextEdit.h20
-rw-r--r--src/ui/widgets/VerifyKeyDetailBox.cpp174
-rw-r--r--src/ui/widgets/VerifyKeyDetailBox.h11
361 files changed, 26148 insertions, 14887 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 2ecc8cb6..96334dd1 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,5 +1,4 @@
-#
-# Copyright (C) 2021 Saturneric
+# Copyright (C) 2021 Saturneric <[email protected]>
#
# This file is part of GpgFrontend.
#
@@ -20,91 +19,106 @@
# the gpg4usb project, which is under GPL-3.0-or-later.
#
# All the source code of GpgFrontend was modified and released by
-# Saturneric<[email protected]> starting on May 12, 2021.
+# Saturneric <[email protected]> starting on May 12, 2021.
#
# SPDX-License-Identifier: GPL-3.0-or-later
-# Introduce boost
-if(NOT BOOST_ROOT)
- find_package(Boost COMPONENTS date_time system REQUIRED)
-else()
- find_package(Boost
- COMPONENTS date_time system REQUIRED
- PATHS ${BOOST_ROOT} NO_DEFAULT_PATH)
+if(APPLE)
+ add_compile_definitions("_GNU_SOURCE")
endif()
+# Introduce GpgME
+find_package(Gpgme REQUIRED)
+
+# Introduce Config++
+find_package(Config++ REQUIRED)
+
# Introduce OpenSSL
-if(APPLE)
- set(OPENSSL_ROOT_DIR /usr/local/opt/openssl@3)
+if (APPLE)
+ # Define possible OpenSSL directories
+ set(OPENSSL_DIR_CANDIDATES
+ /usr/local/opt/openssl@3
+ /opt/homebrew/opt/openssl@3
+ )
+
+ # Find the valid OpenSSL directory
+ foreach(DIR IN LISTS OPENSSL_DIR_CANDIDATES)
+ if(IS_DIRECTORY "${DIR}" OR EXISTS "${DIR}")
+ set(OPENSSL_ROOT_DIR "${DIR}")
+ break() # Stop loop once a valid directory is found
+ endif()
+ endforeach()
+
+ # If not found, throw an error or warning
+ if(NOT OPENSSL_ROOT_DIR)
+ message(FATAL_ERROR "OpenSSL not found in the standard directories. Please install it or set OPENSSL_ROOT_DIR manually.")
+ endif()
endif()
find_package(OpenSSL REQUIRED)
# Introduce Qt
-if (QT5_ENV_SUPPORT)
- # Support Qt version: 6.x, 5.12.x and 5.15.x
- find_package(Qt6 6 COMPONENTS Core Test Widgets PrintSupport Network Core5Compat)
- if(NOT Qt6_DIR)
- find_package(Qt5 5 COMPONENTS Core Test Widgets PrintSupport Network REQUIRED)
- message(STATUS "Use Qt5 for application building ${Qt5_DIR}")
- else()
- message(STATUS "Use Qt6 for application building ${Qt6_DIR}")
- add_definitions(-DGPGFRONTEND_GUI_QT6)
- endif()
-
- # Qt configuration
- set(CMAKE_AUTOMOC ON)
- set(CMAKE_AUTORCC ON)
- set(CMAKE_AUTOUIC ON)
+# Support Qt version: 6.x
+find_package(Qt6 6 COMPONENTS Core Test Widgets PrintSupport Network Core5Compat LinguistTools REQUIRED)
+
+# Qt configuration
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTORCC ON)
+set(CMAKE_AUTOUIC ON)
+
+set(CMAKE_AUTORCC_OPTIONS "--compress;9")
+set(CMAKE_AUTOUIC_SEARCH_PATHS ${CMAKE_AUTOUIC_SEARCH_PATHS} ${CMAKE_SOURCE_DIR}/ui)
- set(CMAKE_AUTORCC_OPTIONS "--compress;9")
- set(CMAKE_AUTOUIC_SEARCH_PATHS ${CMAKE_AUTOUIC_SEARCH_PATHS} ${CMAKE_SOURCE_DIR}/ui)
-endif ()
# configure for output path and resources
-if (APPLICATION_BUILD)
+if (BUILD_APPLICATION)
aux_source_directory(. BASE_SOURCE)
set(APP_ICON_RESOURCE_WINDOWS "${CMAKE_SOURCE_DIR}/gpgfrontend.rc")
set_property(SOURCE gpgfrontend.rc APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_SOURCE_DIR}/gpgfrontend.ico)
if (NOT XCODE_BUILD)
# Set Binary Output Path
- set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/release)
+ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/artifacts)
else ()
# Set Binary Output Path
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE})
endif ()
endif ()
+if (BUILD_CORE)
+ # core depends pinentry
+ message("[+] Build Pinentry")
+ add_subdirectory(pinentry)
-if (GPG_CORE)
- message(STATUS "Build Gpg Core")
+ message("[+] Build Core")
add_subdirectory(core)
endif ()
-if (UI_CORE)
- message(STATUS "Build UI Core")
+if (BUILD_UI)
+ message("[+] Build UI")
add_subdirectory(ui)
endif ()
-if (SERVER_SUPPORT)
- message(STATUS "Build Server Support")
- add_compile_definitions(SERVER_SUPPORT)
- add_subdirectory(server)
+if (BUILD_MODULE)
+ message("[+] Build Module")
+ add_subdirectory(module)
endif ()
-if (ADVANCE_SUPPORT)
- message(STATUS "Build Advance Support")
- add_compile_definitions(ADVANCE_SUPPORT)
- add_subdirectory(advance)
+# build to test gpgfrontend core
+if (BUILD_TEST)
+ include(CTest)
+ enable_testing()
+ add_subdirectory(test)
endif ()
-if (APPLICATION_BUILD)
+if (BUILD_APPLICATION)
# Set Resource Output Path
if (${CMAKE_BUILD_TYPE} STREQUAL "Release")
if (APPLE)
set(RESOURCE_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Resources)
elseif (LINUX AND NOT LINUX_INSTALL_SOFTWARE)
file(COPY ${CMAKE_SOURCE_DIR}/resource/lfs/app-image/gpgfrontend DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
+ file(COPY ${CMAKE_SOURCE_DIR}/resource/appstream/com.bktus.gpgfrontend.metainfo.xml DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/gpgfrontend/usr/share/metainfo FOLLOW_SYMLINK_CHAIN)
+ file(COPY ${CMAKE_SOURCE_DIR}/resource/appstream/com.bktus.gpgfrontend.desktop DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/gpgfrontend/usr/share/applications FOLLOW_SYMLINK_CHAIN)
set(RESOURCE_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/gpgfrontend/usr/share)
else ()
set(RESOURCE_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
@@ -114,52 +128,6 @@ if (APPLICATION_BUILD)
endif ()
endif ()
-# Get ALL SOURCE FILES
-file(GLOB_RECURSE ALL_SOURCE_FILES RELACTIVE ${CMAKE_SOURCE_DIR}/src/*.cpp)
-
-# 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)
-
- set(LOCALE_OUTPUT_PATH ${RESOURCE_OUTPUT_DIRECTORY}/locales)
-
- if (NOT GETTEXT_MSGFMT_EXECUTABLE OR NOT GETTEXT_XGETTEXT_EXECUTABLE)
- message(ERROR "msgfmt or xgettext not found. Translations will *not* be installed")
- else()
- message(STATUS "Setting target translations")
- add_custom_target(translations)
- set(OUTPUT_POT_PATH ${CMAKE_SOURCE_DIR}/resource/lfs/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/lfs/locale/po/*.po)
- SET(GMO_FILES)
-
- foreach (_poFile ${ALL_PO_FILES})
- GET_FILENAME_COMPONENT(_poFileName ${_poFile} NAME)
- string(REGEX REPLACE "\\.[^.]*$" "" _langName ${_poFileName})
- message(STATUS "GNU gettext po file ${_langName}")
- make_directory(${RESOURCE_OUTPUT_DIRECTORY}/locales)
- make_directory(${RESOURCE_OUTPUT_DIRECTORY}/locales/${_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 ${LOCALE_OUTPUT_PATH}/${_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)
@@ -170,17 +138,14 @@ if (BASIC_ENV_CONFIG)
endif ()
endif ()
-if (APPLICATION_BUILD)
+if (BUILD_APPLICATION)
# Copy Resource Files
file(COPY ${CMAKE_SOURCE_DIR}/resource/css DESTINATION ${RESOURCE_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
file(COPY ${CMAKE_SOURCE_DIR}/resource/lfs/icons DESTINATION ${RESOURCE_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
file(COPY ${CMAKE_SOURCE_DIR}/TRANSLATORS DESTINATION ${RESOURCE_OUTPUT_DIRECTORY} FOLLOW_SYMLINK_CHAIN)
- if (GPG_STANDALONE_MODE)
- file(COPY ${CMAKE_SOURCE_DIR}/resource/gpg1.4 DESTINATION ${RESOURCE_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
- endif ()
endif ()
-if (APPLICATION_BUILD)
+if (BUILD_APPLICATION)
if (${CMAKE_BUILD_TYPE} STREQUAL "Release")
if (APPLE)
file(COPY ${CMAKE_SOURCE_DIR}/gpgfrontend.icns DESTINATION ${RESOURCE_OUTPUT_DIRECTORY}/ FOLLOW_SYMLINK_CHAIN)
@@ -192,7 +157,7 @@ if (APPLICATION_BUILD)
endif ()
endif ()
-if (APPLICATION_BUILD)
+if (BUILD_APPLICATION)
# Copy Utils Files
if (MINGW)
message(STATUS "Copying Dependent DLL For Windows Runtime Env")
@@ -209,10 +174,6 @@ if (APPLICATION_BUILD)
list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
unset(_libDllPath)
- file(GLOB _libDllPath "${_libDllBinPath}/libconfig++-*.dll")
- list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
-
- unset(_libDllPath)
file(GLOB _libDllPath "${_libDllBinPath}/libarchive-*.dll")
list(APPEND ALL_RUNTIME_DEP_PATH_LIST ${_libDllPath})
@@ -341,18 +302,15 @@ if (APPLICATION_BUILD)
endif ()
endif ()
-if (APPLICATION_BUILD)
+if (BUILD_APPLICATION)
set(RESOURCE_FILES ${CMAKE_SOURCE_DIR}/gpgfrontend.qrc ${APP_ICON_RESOURCE_WINDOWS} ${QON_QM_FILES})
add_custom_target(resources ALL DEPENDS ${RESOURCE_FILES})
- if (MULTI_LANG_SUPPORT)
- add_dependencies(resources translations)
- endif ()
endif ()
-if (APPLICATION_BUILD)
+if (BUILD_APPLICATION)
if (${CMAKE_BUILD_TYPE} STREQUAL "Release")
if (MINGW)
- add_executable(${AppName} WIN32 ${BASE_SOURCE} ${RESOURCE_FILES} ${QT5_MOCS})
+ add_executable(${AppName} WIN32 ${BASE_SOURCE} ${RESOURCE_FILES})
# include qt dependencies
if(NOT Qt6_DIR)
add_custom_command(TARGET ${AppName} POST_BUILD
@@ -363,10 +321,10 @@ if (APPLICATION_BUILD)
endif()
elseif (APPLE AND NOT XCODE_BUILD)
# custom app bundle packing
- add_executable(${AppName} MACOSX_BUNDLE ${ICON_RESOURCE} ${BASE_SOURCE} ${RESOURCE_FILES} ${QT5_MOCS})
+ add_executable(${AppName} MACOSX_BUNDLE ${ICON_RESOURCE} ${BASE_SOURCE} ${RESOURCE_FILES})
set_target_properties(${AppName} PROPERTIES
BUNDLE True
- MACOSX_BUNDLE_GUI_IDENTIFIER pub.gpgfrontend.gpgfrontend
+ MACOSX_BUNDLE_GUI_IDENTIFIER com.bktus.gpgfrontend
MACOSX_BUNDLE_BUNDLE_NAME ${AppName}
MACOSX_BUNDLE_LONG_VERSION_STRING ${BUILD_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION}
@@ -381,7 +339,7 @@ if (APPLICATION_BUILD)
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
COMMENT "Copying Resources into App Bundle Resource")
elseif (LINUX AND NOT LINUX_INSTALL_SOFTWARE)
- add_executable(${AppName} ${BASE_SOURCE} ${RESOURCE_FILES} ${QT5_MOCS})
+ add_executable(${AppName} ${BASE_SOURCE} ${RESOURCE_FILES})
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}
@@ -393,10 +351,10 @@ if (APPLICATION_BUILD)
# app bundle packing using xcode
elseif (APPLE AND XCODE_BUILD)
# standard app bundle packing
- add_executable(${AppName} MACOSX_BUNDLE ${ICON_RESOURCE} ${BASE_SOURCE} ${RESOURCE_FILES} ${QT5_MOCS})
+ add_executable(${AppName} MACOSX_BUNDLE ${ICON_RESOURCE} ${BASE_SOURCE} ${RESOURCE_FILES})
set_target_properties(${AppName} PROPERTIES
BUNDLE True
- MACOSX_BUNDLE_GUI_IDENTIFIER pub.gpgfrontend.gpgfrontend
+ MACOSX_BUNDLE_GUI_IDENTIFIER com.bktus.gpgfrontend
MACOSX_BUNDLE_BUNDLE_NAME ${AppName}
MACOSX_BUNDLE_LONG_VERSION_STRING ${BUILD_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION}
@@ -444,11 +402,11 @@ if (APPLICATION_BUILD)
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}"
)
else ()
- add_executable(${AppName} ${BASE_SOURCE} ${RESOURCE_FILES} ${QT5_MOCS})
+ add_executable(${AppName} ${BASE_SOURCE} ${RESOURCE_FILES})
endif ()
else ()
# if the status is debug
- add_executable(${AppName} ${BASE_SOURCE} ${RESOURCE_FILES} ${QT5_MOCS})
+ add_executable(${AppName} ${BASE_SOURCE} ${RESOURCE_FILES})
if(MINGW)
# include qt dependencies
if(NOT Qt6_DIR)
@@ -463,125 +421,75 @@ if (APPLICATION_BUILD)
# Make app build with resources
add_dependencies(${AppName} resources)
+
+ # using c++ standard 17
+ target_compile_features(${AppName} PUBLIC cxx_std_17)
endif ()
# link options for GpgFrontend
-if (APPLICATION_BUILD)
- target_link_libraries(${AppName} gpgfrontend_ui)
+if (BUILD_APPLICATION)
+ target_link_libraries(${AppName} gpgfrontend_ui gpgfrontend_module gpgfrontend_test)
if (MINGW)
message(STATUS "Link Application Library For MINGW")
target_link_libraries(${AppName} crypto)
elseif (APPLE)
message(STATUS "Link Application Library For macOS")
- target_link_libraries(${AppName} intl)
else ()
message(STATUS "Link Application Library For Linux")
target_link_libraries(${AppName} crypto pthread)
- # link for freebsd
- if(FREEBSD)
- target_link_libraries(${AppName} intl)
- endif()
- # issue on filesystem support of gcc
- if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 9.0)
- target_link_libraries(${AppName} stdc++fs)
- endif ()
endif ()
endif ()
-# using c++ standard 17
-target_compile_features(${AppName} PUBLIC cxx_std_17)
+# add i18n support
+if (BUILD_APPLICATION)
+ set(LOCALE_TS_PATH ${CMAKE_SOURCE_DIR}/resource/lfs/locale/ts)
+ set(TS_FILES "${LOCALE_TS_PATH}/GpgFrontend.de_DE.ts"
+ "${LOCALE_TS_PATH}/GpgFrontend.fr_FR.ts"
+ "${LOCALE_TS_PATH}/GpgFrontend.zh_CN.ts"
+ "${LOCALE_TS_PATH}/GpgFrontend.zh_TW.ts"
+ "${LOCALE_TS_PATH}/GpgFrontend.it_IT.ts")
+ file(GLOB_RECURSE ALL_SOURCE_FILES RELACTIVE ${CMAKE_SOURCE_DIR}/src/*.cpp)
+ qt_add_translations(${AppName}
+ RESOURCE_PREFIX "/i18n"
+ TS_FILES ${TS_FILES}
+ SOURCES ${ALL_SOURCE_FILES}
+ INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/src)
+endif()
# if building linux package
if (LINUX AND LINUX_INSTALL_SOFTWARE)
+ include(GNUInstallDirs)
if (INSTALL_GPGFRONTEND_APP)
install(TARGETS ${AppName} gpgfrontend_core gpgfrontend_ui
EXPORT GpgFrontendTargets
- RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
- LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
- ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
- )
- install(DIRECTORY /usr/local/lib/
- DESTINATION ${CMAKE_INSTALL_LIBDIR}
- FILES_MATCHING PATTERN "libgpgme.so*")
- install(DIRECTORY /usr/local/lib/
- DESTINATION ${CMAKE_INSTALL_LIBDIR}
- FILES_MATCHING PATTERN "libassuan.so*")
- install(DIRECTORY /usr/local/lib/
- DESTINATION ${CMAKE_INSTALL_LIBDIR}
- FILES_MATCHING PATTERN "libgpg-error.so*")
+ RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR})
+ install(DIRECTORY ${PC_GPGME_LIBDIR}
+ DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}
+ FILES_MATCHING PATTERN "libgpgme.so*"
+ PATTERN "lib" EXCLUDE)
+ install(DIRECTORY ${PC_GPGME_LIBDIR}
+ DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}
+ FILES_MATCHING PATTERN "libassuan.so*"
+ PATTERN "lib" EXCLUDE)
+ install(DIRECTORY ${PC_GPGME_LIBDIR}
+ DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}
+ FILES_MATCHING PATTERN "libgpg-error.so*"
+ PATTERN "lib" EXCLUDE)
install(FILES ${CMAKE_SOURCE_DIR}/TRANSLATORS
- DESTINATION /usr/local/share/${AppName}/)
- install(FILES ${CMAKE_SOURCE_DIR}/resource/meta/pub.gpgfrontend.gpgfrontend.appdata.xml
- DESTINATION /usr/share/metainfo/)
- install(DIRECTORY ${CMAKE_SOURCE_DIR}/resource/desktop/
- DESTINATION /usr/share/applications/)
+ DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/${AppName}/)
+ install(FILES ${CMAKE_SOURCE_DIR}/resource/appstream/com.bktus.gpgfrontend.appdata.xml
+ DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/metainfo/)
+ install(FILES ${CMAKE_SOURCE_DIR}/resource/appstream/com.bktus.gpgfrontend.desktop
+ DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/applications/)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/resource/lfs/pixmaps/
- DESTINATION /usr/share/pixmaps/)
+ DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/pixmaps/)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/resource/lfs/hicolor/
- DESTINATION /usr/share/icons/hicolor/)
- endif ()
- if (MULTI_LANG_SUPPORT)
- install(DIRECTORY ${LOCALE_OUTPUT_PATH}/
- DESTINATION ${CMAKE_INSTALL_FULL_LOCALEDIR})
- endif ()
-
- if (APP_PACKAGE_DEB)
- message(STATUS "Configure DEB Package")
- SET(CPACK_GENERATOR "DEB")
- set(CPACK_INSTALL_PREFIX "/usr/local/")
- set(CPACK_PACKAGE_NAME "gpgfrontend")
- set(CPACK_DEBIAN_PACKAGE_NAME "gpgfrontend")
- set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64")
- set(CPACK_PACKAGE_CONTACT "[email protected]")
- SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Saturneric")
-
- if (${DISTRO_NAME} MATCHES "Ubuntu")
- if (${DISTRO_VERSION_ID} STREQUAL "22.04")
- set(CPACK_DEBIAN_PACKAGE_DEPENDS "gpg (>= 2.2), libqt5core5a (>= 5.9), libqt5gui5 (>= 5.9), libqt5widgets5 (>= 5.9), libqt5network5 (>= 5.9), libqt5printsupport5 (>= 5.9), libconfig++9v5 (>=1.5), libarchive13(>= 3.4), openssl(>= 1.1.1), libicu70")
- elseif (${DISTRO_VERSION_ID} STREQUAL "20.04")
- set(CPACK_DEBIAN_PACKAGE_DEPENDS "gpg (>= 2.2), libqt5core5a (>= 5.9), libqt5gui5 (>= 5.9), libqt5widgets5 (>= 5.9), libqt5network5 (>= 5.9), libqt5printsupport5 (>= 5.9), libconfig++9v5 (>=1.5), libarchive13(>= 3.4), openssl(>= 1.1.1), libicu66")
- endif ()
- endif ()
-
- set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
- set(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
- set(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}")
- include(CPack)
- endif ()
-
- if (APP_PACKAGE_RPM)
- message(STATUS "Configure RPM Package")
- SET(CPACK_GENERATOR "RPM")
- set(CPACK_INSTALL_PREFIX "/usr/local/")
- set(CPACK_PACKAGE_NAME "gpgfrontend")
- set(CPACK_DEBIAN_PACKAGE_NAME "gpgfrontend")
- set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64")
- set(CPACK_PACKAGE_CONTACT "[email protected]")
- SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Saturneric")
-
- set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
- set(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
- set(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}")
- include(CPack)
- endif ()
-
- if (APP_PACKAGE_FREEBSD)
- message(STATUS "Configure PKG Package")
- SET(CPACK_GENERATOR "FREEBSD")
- set(CPACK_INSTALL_PREFIX "/usr/local/")
- set(CPACK_FREEBSD_PACKAGE_NAME "gpgfrontend")
- set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64")
- set(CPACK_PACKAGE_CONTACT "[email protected]")
- SET(CPACK_FREEBSD_PACKAGE_MAINTAINER "Saturneric")
-
- set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
- set(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
- set(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}")
- include(CPack)
+ DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/icons/hicolor/)
endif ()
endif ()
message(STATUS "Resource Files: ${RESOURCE_OUTPUT_DIRECTORY}")
-message(STATUS "Locale Files: ${LOCALE_OUTPUT_PATH}")
message(STATUS "Runtime Files: ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
diff --git a/src/GpgFrontend.h.in b/src/GpgFrontend.h.in
index f441fb8f..56173bbd 100644
--- a/src/GpgFrontend.h.in
+++ b/src/GpgFrontend.h.in
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,62 +20,20 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_H_IN
-#define GPGFRONTEND_H_IN
-
-// standard headers
-#include <cstdint>
-#include <optional>
-#include <filesystem>
+#pragma once
#ifdef WINDOWS
-#include <winsock2.h>
#include <windows.h>
+#include <winsock2.h>
#endif
-
-// i18n support
-#include <libintl.h>
-#define _(String) gettext (String)
-#define gettext_noop(String) String
-#define N_(String) gettext_noop (String)
-
-
-// fix macro bugs in mingw
-#ifdef WINDOWS
-#include <clocale>
-#undef vsnprintf
-#undef sprintf
-#undef snprintf
-#endif
-
-
-// logging system
-#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_TRACE
-#include <spdlog/spdlog.h>
-
// build info
#define PROJECT_NAME "@CMAKE_PROJECT_NAME@"
-#define OS_PLATFORM @OS_PLATFORM@
+#define OS_PLATFORM "@OS_PLATFORM@"
#define LOCALE_DIR "@LOCALE_DIR@"
-
-
-// macros to find resource files
-#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_H_IN
diff --git a/src/GpgFrontendBuildInfo.h.in b/src/GpgFrontendBuildInfo.h.in
index eff6e966..c6242b1e 100644
--- a/src/GpgFrontendBuildInfo.h.in
+++ b/src/GpgFrontendBuildInfo.h.in
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,21 +20,20 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_BUILD_INFO_H_IN
-#define GPGFRONTEND_BUILD_INFO_H_IN
+#pragma once
/**
* Logic Version (*.*.*)
*/
-#define VERSION_MAJOR @CMAKE_PROJECT_VERSION_MAJOR@
-#define VERSION_MINOR @CMAKE_PROJECT_VERSION_MINOR@
-#define VERSION_PATCH @CMAKE_PROJECT_VERSION_PATCH@
+#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)
@@ -45,18 +44,12 @@
/**
* 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_FLAG "@BUILD_FLAG@"
#define BUILD_TIMESTAMP "@BUILD_TIMESTAMP@"
-#define APP_INSTALL_FLAG "@APP_INSTALL_FLAG@"
-
-
-
-
-#endif // GPGFRONTEND_BUILD_INFO_H_IN
+#define APP_INSTALL_FLAG "@APP_INSTALL_FLAG@" \ No newline at end of file
diff --git a/src/GpgFrontendBuildInstallInfo.h.in b/src/GpgFrontendBuildInstallInfo.h.in
index abc1af0f..79ae30b6 100644
--- a/src/GpgFrontendBuildInstallInfo.h.in
+++ b/src/GpgFrontendBuildInstallInfo.h.in
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,14 +20,13 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_BUILD_INSTALL_INFO_H_IN
-#define GPGFRONTEND_BUILD_INSTALL_INFO_H_IN
+#pragma once
/**
* Build & Install Path Information
@@ -36,6 +35,4 @@
#define APP_BIN_PATH "@CMAKE_INSTALL_FULL_BINDIR@"
#define APP_LOCALSTATE_PATH "@CMAKE_INSTALL_FULL_LOCALSTATEDIR@"
#define APP_SYSCONF_PATH "@CMAKE_INSTALL_FULL_SYSCONFDIR@"
-#define APP_INFO_PATH "@CMAKE_INSTALL_FULL_INFODIR@"
-
-#endif // GPGFRONTEND_BUILD_INSTALL_INFO_H_IN \ No newline at end of file
+#define APP_INFO_PATH "@CMAKE_INSTALL_FULL_INFODIR@" \ No newline at end of file
diff --git a/src/GpgFrontendContext.cpp b/src/GpgFrontendContext.cpp
new file mode 100644
index 00000000..9d264dcd
--- /dev/null
+++ b/src/GpgFrontendContext.cpp
@@ -0,0 +1,54 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgFrontendContext.h"
+
+#include <qapplication.h>
+#include <qcoreapplication.h>
+#include <qobject.h>
+#include <qthread.h>
+
+#include "core/utils/MemoryUtils.h"
+
+namespace GpgFrontend {
+
+void GpgFrontendContext::InitApplication() {
+ app_ = SecureCreateObject<QApplication>(argc, argv);
+}
+
+auto GpgFrontendContext::GetApp() -> QApplication* { return app_; }
+
+GpgFrontendContext::GpgFrontendContext(int argc, char** argv)
+ : argc(argc), argv(argv) {}
+
+GpgFrontendContext::~GpgFrontendContext() {
+ if (app_ != nullptr) {
+ SecureDestroyObject(app_);
+ }
+}
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/GpgFrontendContext.h b/src/GpgFrontendContext.h
new file mode 100644
index 00000000..e0d176f1
--- /dev/null
+++ b/src/GpgFrontendContext.h
@@ -0,0 +1,78 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+namespace GpgFrontend {
+
+struct GpgFrontendContext;
+
+using GFCxtWPtr = std::weak_ptr<GpgFrontendContext>;
+using GFCxtSPtr = std::shared_ptr<GpgFrontendContext>;
+
+struct GpgFrontendContext {
+ int argc;
+ char** argv;
+ spdlog::level::level_enum log_level;
+
+ bool load_ui_env;
+ bool gather_external_gnupg_info;
+ bool load_default_gpg_context;
+
+ /**
+ * @brief Construct a new Gpg Frontend Context object
+ *
+ * @param argc
+ * @param argv
+ */
+ GpgFrontendContext(int argc, char** argv);
+
+ /**
+ * @brief Destroy the Gpg Frontend Context object
+ *
+ */
+ ~GpgFrontendContext();
+
+ /**
+ * @brief
+ *
+ */
+ void InitApplication();
+
+ /**
+ * @brief Get the App object
+ *
+ * @return QCoreApplication*
+ */
+ auto GetApp() -> QApplication*;
+
+ private:
+ QApplication* app_ = nullptr;
+};
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/app.cpp b/src/app.cpp
new file mode 100644
index 00000000..6d207373
--- /dev/null
+++ b/src/app.cpp
@@ -0,0 +1,111 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgFrontendContext.h"
+#include "core/GpgConstants.h"
+#include "core/GpgCoreInit.h"
+#include "module/GpgFrontendModuleInit.h"
+#include "ui/GpgFrontendUIInit.h"
+
+// main
+#include "main.h"
+
+namespace GpgFrontend {
+
+constexpr int kCrashCode = ~0; ///<
+
+/**
+ * @brief
+ *
+ * @param argc
+ * @param argv
+ * @return int
+ */
+auto StartApplication(const GFCxtWPtr& p_ctx) -> int {
+ GFCxtSPtr ctx = p_ctx.lock();
+ if (ctx == nullptr) {
+ GF_MAIN_LOG_ERROR("cannot get gpgfrontend context.");
+ return -1;
+ }
+
+ auto* app = ctx->GetApp();
+ if (app == nullptr) {
+ GF_MAIN_LOG_ERROR("cannot get qapplication from gpgfrontend context.");
+ return -1;
+ }
+
+ GF_MAIN_LOG_INFO("start running gui application");
+
+ /**
+ * internationalisation. loop to restart main window
+ * with changed translation when settings change.
+ */
+ int return_from_event_loop_code;
+ int restart_count = 0;
+
+ do {
+ // after that load ui totally
+ GpgFrontend::UI::InitGpgFrontendUI(app);
+
+ // finally create main window
+ return_from_event_loop_code = GpgFrontend::UI::RunGpgFrontendUI(app);
+
+ GF_MAIN_LOG_DEBUG("try to destroy modules system and core");
+
+ restart_count++;
+
+ GF_MAIN_LOG_DEBUG(
+ "restart loop refresh, event loop code: {}, restart count: {}",
+ return_from_event_loop_code, restart_count);
+ } while (return_from_event_loop_code == GpgFrontend::kRestartCode &&
+ restart_count < 99);
+
+ // first should shutdown the module system
+ GpgFrontend::Module::ShutdownGpgFrontendModules();
+
+ // then shutdown the core
+ GpgFrontend::DestroyGpgFrontendCore();
+ GF_MAIN_LOG_DEBUG("core and modules system destroyed");
+
+ // log for debug
+ GF_MAIN_LOG_INFO("GpgFrontend is about to exit.");
+
+ // deep restart mode
+ if (return_from_event_loop_code == GpgFrontend::kDeepRestartCode ||
+ return_from_event_loop_code == kCrashCode) {
+ // log for debug
+ GF_MAIN_LOG_DEBUG(
+ "deep restart or cash loop status caught, restart a new application");
+ QProcess::startDetached(qApp->arguments()[0], qApp->arguments());
+ };
+
+ // exit the program
+ return return_from_event_loop_code;
+}
+
+} // namespace GpgFrontend
diff --git a/src/app.h b/src/app.h
new file mode 100644
index 00000000..89004e07
--- /dev/null
+++ b/src/app.h
@@ -0,0 +1,37 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "GpgFrontendContext.h"
+
+namespace GpgFrontend {
+
+auto StartApplication(const GFCxtWPtr& p_ctx) -> int;
+
+}
diff --git a/src/cmd.cpp b/src/cmd.cpp
new file mode 100644
index 00000000..e19ad218
--- /dev/null
+++ b/src/cmd.cpp
@@ -0,0 +1,97 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "cmd.h"
+
+#include "main.h"
+
+// std
+#include <iostream>
+
+// GpgFrontend
+#include "GpgFrontendBuildInfo.h"
+#include "GpgFrontendContext.h"
+#include "test/GpgFrontendTest.h"
+
+namespace GpgFrontend {
+
+auto PrintVersion() -> int {
+ QTextStream stream(stdin);
+ stream << PROJECT_NAME << " "
+ << "v" << VERSION_MAJOR << "." << VERSION_MINOR << "." << VERSION_PATCH
+ << '\n';
+ stream << "Copyright (C) 2021 Saturneric <[email protected]>" << '\n'
+ << QObject::tr(
+ "This is free software; see the source for copying conditions.")
+ << '\n'
+ << '\n';
+
+ stream << QObject::tr("Build Timestamp: ") << BUILD_TIMESTAMP << '\n'
+ << QObject::tr("Build Version: ") << BUILD_VERSION << '\n'
+ << QObject::tr("Source Code Version: ") << GIT_VERSION << '\n';
+
+ stream << Qt::endl;
+
+ return 0;
+}
+
+auto ParseLogLevel(const QString& log_level) -> spdlog::level::level_enum {
+ if (log_level == "trace") {
+ return spdlog::level::trace;
+ }
+ if (log_level == "debug") {
+ return spdlog::level::debug;
+ }
+ if (log_level == "info") {
+ return spdlog::level::info;
+ }
+ if (log_level == "warn") {
+ return spdlog::level::warn;
+ }
+ if (log_level == "error") {
+ return spdlog::level::err;
+ }
+
+ return spdlog::level::info;
+}
+
+auto RunTest(const GFCxtWPtr& p_ctx) -> int {
+ GpgFrontend::GFCxtSPtr const ctx = p_ctx.lock();
+ if (ctx == nullptr) {
+ GF_MAIN_LOG_ERROR("cannot get gpgfrontend context for test running");
+ return -1;
+ }
+
+ GpgFrontend::Test::GpgFrontendContext test_init_args;
+ test_init_args.argc = ctx->argc;
+ test_init_args.argv = ctx->argv;
+
+ return GpgFrontend::Test::ExecuteAllTestCase(test_init_args);
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/cmd.h b/src/cmd.h
new file mode 100644
index 00000000..061926dc
--- /dev/null
+++ b/src/cmd.h
@@ -0,0 +1,43 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "GpgFrontendContext.h"
+
+namespace GpgFrontend {
+
+// functions
+
+auto PrintVersion() -> int;
+
+auto ParseLogLevel(const QString& level) -> spdlog::level::level_enum;
+
+auto RunTest(const GFCxtWPtr&) -> int;
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 22a0b88a..d51ec6d1 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -1,5 +1,4 @@
-#
-# Copyright (C) 2021 Saturneric
+# Copyright (C) 2021 Saturneric <[email protected]>
#
# This file is part of GpgFrontend.
#
@@ -20,31 +19,34 @@
# the gpg4usb project, which is under GPL-3.0-or-later.
#
# All the source code of GpgFrontend was modified and released by
-# Saturneric<[email protected]> starting on May 12, 2021.
+# Saturneric <[email protected]> starting on May 12, 2021.
#
# SPDX-License-Identifier: GPL-3.0-or-later
-aux_source_directory(./function/result_analyse GPG_SOURCE)
-aux_source_directory(./function/gpg GPG_SOURCE)
-aux_source_directory(./function/aes GPG_SOURCE)
-aux_source_directory(./function GPG_SOURCE)
-aux_source_directory(./thread GPG_SOURCE)
-aux_source_directory(./model GPG_SOURCE)
-aux_source_directory(./common GPG_SOURCE)
-aux_source_directory(. GPG_SOURCE)
+
+aux_source_directory(./function/result_analyse CORE_SOURCE)
+aux_source_directory(./function/basic CORE_SOURCE)
+aux_source_directory(./function/gpg CORE_SOURCE)
+aux_source_directory(./function/secure_memory CORE_SOURCE)
+aux_source_directory(./function CORE_SOURCE)
+aux_source_directory(./thread CORE_SOURCE)
+aux_source_directory(./model CORE_SOURCE)
+aux_source_directory(./common CORE_SOURCE)
+aux_source_directory(./module CORE_SOURCE)
+aux_source_directory(./utils/aes CORE_SOURCE)
+aux_source_directory(./utils CORE_SOURCE)
+aux_source_directory(. CORE_SOURCE)
# define libgpgfrontend_core
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
-add_library(gpgfrontend_core SHARED ${GPG_SOURCE})
+add_library(gpgfrontend_core SHARED ${CORE_SOURCE})
set(_export_file "${CMAKE_CURRENT_SOURCE_DIR}/GpgFrontendCoreExport.h")
generate_export_header(gpgfrontend_core EXPORT_FILE_NAME "${_export_file}")
-# link third-party libraries
-target_link_libraries(gpgfrontend_core PUBLIC config++)
-if (NOT LINUX)
- target_link_libraries(gpgfrontend_core PUBLIC config++ intl)
-endif ()
+if(NOT APPLE)
+ target_link_libraries(gpgfrontend_core PUBLIC mimalloc)
+endif()
# qt-aes
target_sources(gpgfrontend_core PRIVATE
@@ -54,24 +56,10 @@ target_sources(gpgfrontend_core PRIVATE
aux_source_directory(${CMAKE_SOURCE_DIR}/third_party/encoding-detect ENCODING_DETECT_SOURCE_CODE)
target_sources(gpgfrontend_core PUBLIC ${ENCODING_DETECT_SOURCE_CODE})
-# icu
-if (APPLE)
- target_include_directories(gpgfrontend_core PRIVATE /usr/local/opt/icu4c/include)
- target_link_directories(gpgfrontend_core PRIVATE /usr/local/opt/icu4c/lib)
- target_link_libraries(gpgfrontend_core PRIVATE icui18n icuuc icudata)
-else ()
- find_package(ICU 60.0 REQUIRED COMPONENTS i18n uc data)
- message("ICU version: ${ICU_VERSION}")
- message("ICU libraries: ${ICU_LIBRARIES}")
- target_link_libraries(gpgfrontend_core PRIVATE ${ICU_LIBRARIES})
-endif ()
-
# link gnupg libraries
-target_link_libraries(gpgfrontend_core PRIVATE gpgme assuan gpg-error)
+target_link_libraries(gpgfrontend_core PUBLIC gpgme assuan gpg-error)
# link openssl
target_link_libraries(gpgfrontend_core PUBLIC OpenSSL::SSL OpenSSL::Crypto)
-# link boost libraries
-target_link_libraries(gpgfrontend_core PUBLIC ${Boost_LIBRARIES})
if (MINGW)
# for uuid ability in mingw
target_link_libraries(gpgfrontend_core PUBLIC bcrypt)
@@ -81,17 +69,15 @@ endif ()
target_link_libraries(gpgfrontend_core PRIVATE spdlog)
# link libarchive
+if(APPLE)
+ set(LibArchive_INCLUDE_DIR "/usr/local/opt/libarchive/include")
+endif()
+find_package(LibArchive REQUIRED)
+target_include_directories(gpgfrontend_core PRIVATE ${LibArchive_INCLUDE_DIR})
target_link_libraries(gpgfrontend_core PRIVATE archive)
-
-# link json
-target_link_libraries(gpgfrontend_core
- PUBLIC nlohmann_json::nlohmann_json)
+
# link Qt core
-if(Qt6_DIR)
- target_link_libraries(gpgfrontend_core PUBLIC Qt6::Core)
-else()
- target_link_libraries(gpgfrontend_core PUBLIC Qt5::Core)
-endif()
+target_link_libraries(gpgfrontend_core PUBLIC Qt6::Core)
# set up pch
target_precompile_headers(gpgfrontend_core
diff --git a/src/core/GpgConstants.cpp b/src/core/GpgConstants.cpp
index 35e485d4..ade003a8 100644
--- a/src/core/GpgConstants.cpp
+++ b/src/core/GpgConstants.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,177 +28,5 @@
#include "core/GpgConstants.h"
-#include <boost/algorithm/string/predicate.hpp>
-
-#include "function/FileOperator.h"
-
-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::PGP_PUBLIC_KEY_BEGIN =
- "-----BEGIN PGP PUBLIC KEY BLOCK-----"; ///<
-const char* GpgFrontend::GpgConstants::PGP_PRIVATE_KEY_BEGIN =
- "-----BEGIN PGP PRIVATE KEY BLOCK-----"; ///<
-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) {
- SPDLOG_ERROR("[error: {}] source: {} description: {}", gpg_err_code(err),
- gpgme_strsource(err), 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 != gpg_err_code(predict)) {
- if (err_code == GPG_ERR_NO_ERROR)
- SPDLOG_WARN("[Warning {}] Source: {} description: {} predict: {}",
- gpg_err_code(err), gpgme_strsource(err), gpgme_strerror(err),
- gpgme_strerror(err));
- else
- SPDLOG_ERROR("[Error {}] Source: {} description: {} predict: {}",
- gpg_err_code(err), gpgme_strsource(err), gpgme_strerror(err),
- gpgme_strerror(err));
- }
- return err_code;
-}
-
-gpgme_error_t GpgFrontend::check_gpg_error(gpgme_error_t err,
- const std::string& comment) {
- if (gpg_err_code(err) != GPG_ERR_NO_ERROR) {
- SPDLOG_WARN("[Error {}] Source: {} description: {} predict: {}",
- gpg_err_code(err), gpgme_strsource(err), gpgme_strerror(err),
- gpgme_strerror(err));
- }
- return err;
-}
-
-std::string GpgFrontend::beautify_fingerprint(
- GpgFrontend::BypeArrayConstRef fingerprint) {
- auto len = fingerprint.size();
- std::stringstream out;
- decltype(len) count = 0;
- while (count < len) {
- if (count && !(count % 5)) out << " ";
- out << fingerprint[count];
- count++;
- }
- return out.str();
-}
-
-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);
- }));
-}
-
-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());
-}
-
-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& utf8_path) {
- std::string data;
- FileOperator::ReadFileStd(utf8_path, data);
- return data;
-}
-
-bool GpgFrontend::write_buffer_to_file(const std::string& utf8_path,
- const std::string& out_buffer) {
- return FileOperator::WriteFileStd(utf8_path, out_buffer);
-}
-
-std::string GpgFrontend::get_file_extension(const std::string& path) {
- // Create a path object from given string
- std::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().u8string();
- }
- // 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
- std::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()).u8string();
- }
- // In case of no extension return empty string
- return {};
-}
-
-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;
-}
-
-GpgFrontend::GpgEncrResult GpgFrontend::_new_result(
- gpgme_encrypt_result_t&& result) {
- gpgme_result_ref(result);
- return {result, _result_ref_deletor()};
-}
-
-GpgFrontend::GpgDecrResult GpgFrontend::_new_result(
- gpgme_decrypt_result_t&& result) {
- gpgme_result_ref(result);
- return {result, _result_ref_deletor()};
-}
-
-GpgFrontend::GpgSignResult GpgFrontend::_new_result(
- gpgme_sign_result_t&& result) {
- gpgme_result_ref(result);
- return {result, _result_ref_deletor()};
-}
-
-GpgFrontend::GpgVerifyResult GpgFrontend::_new_result(
- gpgme_verify_result_t&& result) {
- gpgme_result_ref(result);
- return {result, _result_ref_deletor()};
-}
-
-GpgFrontend::GpgGenKeyResult GpgFrontend::_new_result(
- gpgme_genkey_result_t&& result) {
- gpgme_result_ref(result);
- return {result, _result_ref_deletor()};
-}
-
-void GpgFrontend::_result_ref_deletor::operator()(void* _result) {
- SPDLOG_TRACE("gpgme unref {}", _result);
- if (_result != nullptr) gpgme_result_unref(_result);
-}
+namespace GpgFrontend {
+} // namespace GpgFrontend
diff --git a/src/core/GpgConstants.h b/src/core/GpgConstants.h
index a8a87835..c2125650 100644
--- a/src/core/GpgConstants.h
+++ b/src/core/GpgConstants.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,200 +20,35 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPG_CONSTANTS_H
-#define GPG_CONSTANTS_H
-
-#include "GpgFrontendCore.h"
-
-const int RESTART_CODE = 1000; ///< only refresh ui
-const int DEEP_RESTART_CODE = 1001; // refresh core and ui
+#pragma once
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;
-
-/**
- * @brief Result Deleter
- *
- */
-struct _result_ref_deletor {
- void operator()(void* _result);
-};
-
-using GpgEncrResult = std::shared_ptr<struct _gpgme_op_encrypt_result>; ///<
-using GpgDecrResult = std::shared_ptr<struct _gpgme_op_decrypt_result>; ///<
-using GpgSignResult = std::shared_ptr<struct _gpgme_op_sign_result>; ///<
-using GpgVerifyResult = std::shared_ptr<struct _gpgme_op_verify_result>; ///<
-using GpgGenKeyResult = std::shared_ptr<struct _gpgme_op_genkey_result>; ///<
-// Convert from gpgme_xxx_result to GpgXXXResult
-
-/**
- * @brief
- *
- * @param result
- * @return GpgEncrResult
- */
-GPGFRONTEND_CORE_EXPORT GpgEncrResult
-_new_result(gpgme_encrypt_result_t&& result);
-
-/**
- * @brief
- *
- * @param result
- * @return GpgDecrResult
- */
-GPGFRONTEND_CORE_EXPORT GpgDecrResult
-_new_result(gpgme_decrypt_result_t&& result);
-
-/**
- * @brief
- *
- * @param result
- * @return GpgSignResult
- */
-GPGFRONTEND_CORE_EXPORT GpgSignResult _new_result(gpgme_sign_result_t&& result);
-
-/**
- * @brief
- *
- * @param result
- * @return GpgVerifyResult
- */
-GPGFRONTEND_CORE_EXPORT GpgVerifyResult
-_new_result(gpgme_verify_result_t&& result);
-
-/**
- * @brief
- *
- * @param result
- * @return GpgGenKeyResult
- */
-GPGFRONTEND_CORE_EXPORT GpgGenKeyResult
-_new_result(gpgme_genkey_result_t&& result);
-
-// Error Info Printer
-
-/**
- * @brief
- *
- * @param err
- * @return GpgError
- */
-GPGFRONTEND_CORE_EXPORT GpgError check_gpg_error(GpgError err);
-
-/**
- * @brief
- *
- * @param gpgmeError
- * @param comment
- * @return GpgError
- */
-GPGFRONTEND_CORE_EXPORT GpgError check_gpg_error(GpgError gpgmeError,
- const std::string& comment);
-
-/**
- * @brief
- *
- * @param err
- * @param predict
- * @return gpg_err_code_t
- */
-GPGFRONTEND_CORE_EXPORT gpg_err_code_t check_gpg_error_2_err_code(
- gpgme_error_t err, gpgme_error_t predict = GPG_ERR_NO_ERROR);
-
-// Fingerprint
-
-/**
- * @brief
- *
- * @param fingerprint
- * @return std::string
- */
-GPGFRONTEND_CORE_EXPORT std::string beautify_fingerprint(
- BypeArrayConstRef fingerprint);
-
-// File Operation
-
-/**
- * @brief
- *
- * @param path
- * @return std::string
- */
-std::string read_all_data_in_file(const std::string& path);
-
-/**
- * @brief
- *
- * @param path
- * @param out_buffer
- * @return true
- * @return false
- */
-GPGFRONTEND_CORE_EXPORT bool write_buffer_to_file(
- const std::string& path, const std::string& out_buffer);
-
-/**
- * @brief Get the file extension object
- *
- * @param path
- * @return std::string
- */
-std::string get_file_extension(const std::string& path);
-
-/**
- * @brief Get the only file name with path object
- *
- * @param path
- * @return std::string
- */
-std::string get_only_file_name_with_path(const std::string& path);
-
-// Check
-
-/**
- * @brief
- *
- * @param text
- * @return int
- */
-int text_is_signed(BypeArrayRef text);
+constexpr int kRestartCode = 1000; ///< only refresh ui
+constexpr int kDeepRestartCode = 1001; // refresh core and ui
// Channels
-const int GPGFRONTEND_DEFAULT_CHANNEL = 0; ///<
-const int GPGFRONTEND_NON_ASCII_CHANNEL = 2; ///<
-
-/**
- * @brief
- *
- */
-class GPGFRONTEND_CORE_EXPORT 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* PGP_PUBLIC_KEY_BEGIN; ///<
- static const char* PGP_PRIVATE_KEY_BEGIN; ///<
- static const char* GPG_FRONTEND_SHORT_CRYPTO_HEAD; ///<
-};
+constexpr int kGpgFrontendDefaultChannel = 0; ///<
+constexpr int kGpgFrontendNonAsciiChannel = 2; ///<
+
+// HEADER
+constexpr const char* PGP_CRYPT_BEGIN = "-----BEGIN PGP MESSAGE-----"; ///<
+constexpr const char* PGP_CRYPT_END = "-----END PGP MESSAGE-----"; ///<
+constexpr const char* PGP_SIGNED_BEGIN =
+ "-----BEGIN PGP SIGNED MESSAGE-----"; ///<
+constexpr const char* PGP_SIGNED_END = "-----END PGP SIGNATURE-----"; ///<
+constexpr const char* PGP_SIGNATURE_BEGIN =
+ "-----BEGIN PGP SIGNATURE-----"; ///<
+constexpr const char* PGP_SIGNATURE_END = "-----END PGP SIGNATURE-----"; ///<
+constexpr const char* PGP_PUBLIC_KEY_BEGIN =
+ "-----BEGIN PGP PUBLIC KEY BLOCK-----"; ///<
+constexpr const char* PGP_PRIVATE_KEY_BEGIN =
+ "-----BEGIN PGP PRIVATE KEY BLOCK-----"; ///<
} // namespace GpgFrontend
-
-#endif // GPG_CONSTANTS_H
diff --git a/src/core/GpgContext.cpp b/src/core/GpgContext.cpp
deleted file mode 100644
index 7d98004d..00000000
--- a/src/core/GpgContext.cpp
+++ /dev/null
@@ -1,660 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#include "core/GpgContext.h"
-
-#include <gpg-error.h>
-#include <gpgme.h>
-#include <spdlog/spdlog.h>
-#include <unistd.h>
-
-#include <mutex>
-#include <shared_mutex>
-#include <string>
-
-#include "core/GpgConstants.h"
-#include "core/common/CoreCommonUtil.h"
-#include "core/function/CoreSignalStation.h"
-#include "core/function/gpg/GpgCommandExecutor.h"
-#include "core/thread/Task.h"
-#include "core/thread/TaskRunnerGetter.h"
-#include "function/gpg/GpgKeyGetter.h"
-
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
-namespace GpgFrontend {
-
-GpgContext::GpgContext(int channel)
- : SingletonFunctionObject<GpgContext>(channel) {}
-
-/**
- * Constructor
- * Set up gpgme-context, set paths to app-run path
- */
-GpgContext::GpgContext(const GpgContextInitArgs &args) : args_(args) {
- gpgme_ctx_t _p_ctx;
-
- // get gpgme library version
- info_.GpgMEVersion = gpgme_check_version(nullptr);
-
- // create a new context
- check_gpg_error(gpgme_new(&_p_ctx));
- _ctx_ref = CtxRefHandler(_p_ctx);
-
- if (args.gpg_alone) {
- info_.AppPath = args.gpg_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);
- }
-
- if (args.custom_gpgconf && !args.custom_gpgconf_path.empty()) {
- SPDLOG_DEBUG("set custom gpgconf path: {}", args.custom_gpgconf_path);
- auto err =
- gpgme_ctx_set_engine_info(_ctx_ref.get(), GPGME_PROTOCOL_GPGCONF,
- args.custom_gpgconf_path.c_str(), nullptr);
- assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
- }
-
- // set context offline mode
- SPDLOG_DEBUG("gpg context offline mode: {}", args_.offline_mode);
- gpgme_set_offline(_ctx_ref.get(), args_.offline_mode ? 1 : 0);
-
- // set option auto import missing key
- // invalid at offline mode
- SPDLOG_DEBUG("gpg context auto import missing key: {}", args_.offline_mode);
- if (!args.offline_mode && args.auto_import_missing_key)
- check_gpg_error(gpgme_set_ctx_flag(_ctx_ref.get(), "auto-key-import", "1"));
-
- // get engine info
- auto engine_info = gpgme_ctx_get_engine_info(*this);
- // Check ENV before running
- bool check_passed = false, find_openpgp = false, find_gpgconf = false,
- find_cms = false;
-
- while (engine_info != nullptr) {
- if (!strcmp(engine_info->version, "1.0.0")) {
- engine_info = engine_info->next;
- continue;
- }
-
- SPDLOG_DEBUG(
- "gpg context engine info: {} {} {} {}",
- gpgme_get_protocol_name(engine_info->protocol),
- std::string(engine_info->file_name == nullptr ? "null"
- : engine_info->file_name),
- std::string(engine_info->home_dir == nullptr ? "null"
- : engine_info->home_dir),
- std::string(engine_info->version ? "null" : engine_info->version));
-
- switch (engine_info->protocol) {
- case GPGME_PROTOCOL_OpenPGP:
- find_openpgp = true;
- info_.AppPath = engine_info->file_name;
- info_.GnupgVersion = engine_info->version;
- info_.DatabasePath = std::string(engine_info->home_dir == nullptr
- ? "default"
- : engine_info->home_dir);
- break;
- case GPGME_PROTOCOL_CMS:
- find_cms = true;
- info_.CMSPath = engine_info->file_name;
- break;
- case GPGME_PROTOCOL_GPGCONF:
- find_gpgconf = true;
- info_.GpgConfPath = engine_info->file_name;
- break;
- case GPGME_PROTOCOL_ASSUAN:
- info_.AssuanPath = engine_info->file_name;
- break;
- case GPGME_PROTOCOL_G13:
- break;
- case GPGME_PROTOCOL_UISERVER:
- break;
- case GPGME_PROTOCOL_SPAWN:
- break;
- case GPGME_PROTOCOL_DEFAULT:
- break;
- case GPGME_PROTOCOL_UNKNOWN:
- break;
- }
- engine_info = engine_info->next;
- }
-
- // set custom key db path
- if (!args.db_path.empty()) {
- info_.DatabasePath = args.db_path;
- auto err = gpgme_ctx_set_engine_info(_ctx_ref.get(), GPGME_PROTOCOL_OpenPGP,
- info_.AppPath.c_str(),
- info_.DatabasePath.c_str());
- SPDLOG_DEBUG("ctx set custom key db path: {}", info_.DatabasePath);
- assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
- }
-
- // conditional check
- if ((info_.GnupgVersion >= "2.0.0" && find_gpgconf && find_openpgp &&
- find_cms) ||
- (info_.GnupgVersion > "1.0.0" && find_gpgconf))
- check_passed = true;
-
- if (!check_passed) {
- this->good_ = false;
- SPDLOG_ERROR("env check failed");
- return;
- } else {
- // speed up loading process
- gpgme_set_offline(*this, 1);
-
- // set keylist mode
- if (info_.GnupgVersion >= "2.0.0") {
- 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));
- } else {
- check_gpg_error(gpgme_set_keylist_mode(
- *this, GPGME_KEYLIST_MODE_LOCAL | GPGME_KEYLIST_MODE_SIGS |
- GPGME_KEYLIST_MODE_SIG_NOTATIONS |
- GPGME_KEYLIST_MODE_WITH_TOFU));
- }
-
- // async, init context
- Thread::TaskRunnerGetter::GetInstance()
- .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_GPG)
- ->PostTask(new Thread::Task(
- [=](Thread::Task::DataObjectPtr) -> int {
- post_init_ctx();
- return 0;
- },
- "post_init_ctx"));
-
- good_ = true;
- }
-}
-
-void GpgContext::post_init_ctx() {
- // Set Independent Database
- if (info_.GnupgVersion <= "2.0.0" && args_.independent_database) {
- info_.DatabasePath = args_.db_path;
- SPDLOG_DEBUG("custom key db path {}", info_.DatabasePath);
- auto err = gpgme_ctx_set_engine_info(_ctx_ref.get(), GPGME_PROTOCOL_OpenPGP,
- info_.AppPath.c_str(),
- info_.DatabasePath.c_str());
- assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
- } else {
- info_.DatabasePath = "default";
- }
-
- if (args_.ascii) {
- /** Setting the output type must be done at the beginning */
- /** think this means ascii-armor --> ? */
- gpgme_set_armor(*this, 1);
- } else {
- /** Setting the output type must be done at the beginning */
- /** think this means ascii-armor --> ? */
- gpgme_set_armor(*this, 0);
- }
-
- // for unit test
- if (args_.test_mode) {
- if (info_.GnupgVersion >= "2.1.0") SetPassphraseCb(test_passphrase_cb);
- gpgme_set_status_cb(*this, test_status_cb, nullptr);
- }
-
- // preload info
- auto &info = GetInfo();
-
- // use custom qt dialog to replace pinentry
- if (!args_.use_pinentry) {
- SetPassphraseCb(custom_passphrase_cb);
- }
-
- connect(this, &GpgContext::SignalNeedUserInputPassphrase,
- CoreSignalStation::GetInstance(),
- &CoreSignalStation::SignalNeedUserInputPassphrase);
-}
-
-bool GpgContext::good() const { return good_; }
-
-void GpgContext::SetPassphraseCb(gpgme_passphrase_cb_t cb) const {
- if (info_.GnupgVersion >= "2.1.0") {
- if (gpgme_get_pinentry_mode(*this) != GPGME_PINENTRY_MODE_LOOPBACK) {
- gpgme_set_pinentry_mode(*this, GPGME_PINENTRY_MODE_LOOPBACK);
- }
- gpgme_set_passphrase_cb(*this, cb, nullptr);
- } else {
- SPDLOG_ERROR("not supported for gnupg version: {}", info_.GnupgVersion);
- }
-}
-
-gpgme_error_t GpgContext::test_passphrase_cb(void *opaque, const char *uid_hint,
- const char *passphrase_info,
- int last_was_bad, int fd) {
- size_t res;
- std::string pass = "abcdefg\n";
- auto pass_len = pass.size();
-
- size_t off = 0;
-
- 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);
-}
-
-gpgme_error_t GpgContext::custom_passphrase_cb(void *opaque,
- const char *uid_hint,
- const char *passphrase_info,
- int last_was_bad, int fd) {
- SPDLOG_DEBUG("custom passphrase cb called, bad times: {}", last_was_bad);
-
- if (last_was_bad > 3) {
- SPDLOG_WARN("failure_counts is over three times");
- return gpgme_error_from_errno(GPG_ERR_CANCELED);
- }
-
- std::string passphrase =
- CoreCommonUtil::GetInstance()->GetTempCacheValue("__key_passphrase");
- // no pawword is an error situation
- if (passphrase.empty()) {
- // user input passphrase
- SPDLOG_DEBUG("might need user to input passparase");
- passphrase = GpgContext::GetInstance().need_user_input_passphrase();
- if (passphrase.empty()) {
- gpgme_io_write(fd, "\n", 1);
- return gpgme_error_from_errno(GPG_ERR_CANCELED);
- }
- }
-
- // the user must at least write a newline character before returning from the
- // callback.
- passphrase = passphrase.append("\n");
- auto passpahrase_size = passphrase.size();
-
- size_t off = 0, res = 0;
- do {
- res = gpgme_io_write(fd, &passphrase[off], passpahrase_size - off);
- if (res > 0) off += res;
- } while (res > 0 && off != passpahrase_size);
-
- return off == passpahrase_size ? 0 : gpgme_error_from_errno(GPG_ERR_CANCELED);
-}
-
-gpgme_error_t GpgContext::test_status_cb(void *hook, const char *keyword,
- const char *args) {
- SPDLOG_DEBUG("keyword {}", keyword);
- return GPG_ERR_NO_ERROR;
-}
-
-std::string GpgContext::need_user_input_passphrase() {
- emit SignalNeedUserInputPassphrase();
-
- std::string final_passphrase;
- bool input_done = false;
- SPDLOG_DEBUG("loop start to wait from user");
- auto connection =
- connect(CoreSignalStation::GetInstance(),
- &CoreSignalStation::SignalUserInputPassphraseDone, this,
- [&](QString passphrase) {
- SPDLOG_DEBUG("SignalUserInputPassphraseDone emitted");
- final_passphrase = passphrase.toStdString();
- input_done = true;
- });
- while (!input_done) {
- QCoreApplication::processEvents(QEventLoop::AllEvents, 800);
- }
- disconnect(connection);
-
- SPDLOG_DEBUG("lopper end");
- return final_passphrase;
-}
-
-const GpgInfo &GpgContext::GetInfo(bool refresh) {
- if (!extend_info_loaded_ || refresh) {
- // try lock
- std::unique_lock lock(preload_lock_);
-
- // check twice
- if (extend_info_loaded_ && !refresh) return info_;
-
- SPDLOG_DEBUG("start to load extra info");
-
- // get all components
- GpgCommandExecutor::GetInstance().Execute(
- info_.GpgConfPath, {"--list-components"},
- [=](int exit_code, const std::string &p_out, const std::string &p_err) {
- SPDLOG_DEBUG(
- "gpgconf components exit_code: {} process stdout size: {}",
- exit_code, p_out.size());
-
- if (exit_code != 0) {
- SPDLOG_ERROR(
- "gpgconf execute error, process stderr: {} ,process stdout: "
- "{}",
- p_err, p_out);
- return;
- }
-
- auto &components_info = info_.ComponentsInfo;
- components_info["gpgme"] = {"GPG Made Easy", info_.GpgMEVersion,
- _("Embedded In"), "/"};
-
- auto gpgconf_binary_checksum =
- check_binary_chacksum(info_.GpgConfPath);
- components_info["gpgconf"] = {"GPG Configure", "/", info_.GpgConfPath,
- gpgconf_binary_checksum.has_value()
- ? gpgconf_binary_checksum.value()
- : "/"};
-
- std::vector<std::string> line_split_list;
- boost::split(line_split_list, p_out, boost::is_any_of("\n"));
-
- for (const auto &line : line_split_list) {
- std::vector<std::string> info_split_list;
- boost::split(info_split_list, line, boost::is_any_of(":"));
-
- if (info_split_list.size() != 3) continue;
-
- auto component_name = info_split_list[0];
- auto component_desc = info_split_list[1];
- auto component_path = info_split_list[2];
-
- boost::algorithm::trim(component_name);
- boost::algorithm::trim(component_desc);
- boost::algorithm::trim(component_path);
-
-#ifdef WINDOWS
- // replace some special substrings on windows platform
- boost::replace_all(component_path, "%3a", ":");
-#endif
-
- auto binary_checksum = check_binary_chacksum(component_path);
-
- SPDLOG_DEBUG(
- "gnupg component name: {} desc: {} checksum: {} path: {} ",
- component_name, component_desc,
- binary_checksum.has_value() ? binary_checksum.value() : "/",
- component_path);
-
- std::string version = "/";
-
- if (component_name == "gpg") {
- version = info_.GnupgVersion;
- }
- if (component_name == "gpg-agent") {
- info_.GpgAgentPath = component_path;
- }
- if (component_name == "dirmngr") {
- info_.DirmngrPath = component_path;
- }
- if (component_name == "keyboxd") {
- info_.KeyboxdPath = component_path;
- }
-
- {
- // try lock
- std::unique_lock lock(info_.Lock);
- // add component info to list
- components_info[component_name] = {
- component_desc, version, component_path,
- binary_checksum.has_value() ? binary_checksum.value() : "/"};
- }
- }
- });
-
- SPDLOG_DEBUG("start to get dirs info");
-
- GpgCommandExecutor::GetInstance().ExecuteConcurrently(
- info_.GpgConfPath, {"--list-dirs"},
- [=](int exit_code, const std::string &p_out, const std::string &p_err) {
- SPDLOG_DEBUG(
- "gpgconf configurations exit_code: {} process stdout size: {}",
- exit_code, p_out.size());
-
- if (exit_code != 0) {
- SPDLOG_ERROR(
- "gpgconf execute error, process stderr: {} process stdout: "
- "{}",
- p_err, p_out);
- return;
- }
-
- auto &configurations_info = info_.ConfigurationsInfo;
-
- std::vector<std::string> line_split_list;
- boost::split(line_split_list, p_out, boost::is_any_of("\n"));
-
- for (const auto &line : line_split_list) {
- std::vector<std::string> info_split_list;
- boost::split(info_split_list, line, boost::is_any_of(":"));
- SPDLOG_DEBUG("gpgconf info line: {} info size: {}", line,
- info_split_list.size());
-
- if (info_split_list.size() != 2) continue;
-
- auto configuration_name = info_split_list[0];
- auto configuration_value = info_split_list[1];
- boost::algorithm::trim(configuration_name);
- boost::algorithm::trim(configuration_value);
-
-#ifdef WINDOWS
- // replace some special substrings on windows platform
- boost::replace_all(configuration_value, "%3a", ":");
-#endif
-
- // record gnupg home path
- if (configuration_name == "homedir") {
- info_.GnuPGHomePath = info_split_list[1];
- }
-
- {
- // try lock
- std::unique_lock lock(info_.Lock);
- configurations_info[configuration_name] = {configuration_value};
- }
- }
- });
-
- SPDLOG_DEBUG("start to get components info");
-
- for (const auto &component : info_.ComponentsInfo) {
- SPDLOG_DEBUG("gpgconf check options ready", "component", component.first);
-
- if (component.first == "gpgme" || component.first == "gpgconf") continue;
-
- GpgCommandExecutor::GetInstance().ExecuteConcurrently(
- info_.GpgConfPath, {"--check-options", component.first},
- [=](int exit_code, const std::string &p_out,
- const std::string &p_err) {
- SPDLOG_DEBUG(
- "gpgconf {} options exit_code: {} process stdout "
- "size: {} ",
- component.first, exit_code, p_out.size());
-
- if (exit_code != 0) {
- SPDLOG_ERROR(
- "gpgconf {} options execute error, process "
- "stderr: {} , process stdout:",
- component.first, p_err, p_out);
- return;
- }
-
- auto &options_info = info_.OptionsInfo;
-
- std::vector<std::string> line_split_list;
- boost::split(line_split_list, p_out, boost::is_any_of("\n"));
-
- for (const auto &line : line_split_list) {
- std::vector<std::string> info_split_list;
- boost::split(info_split_list, line, boost::is_any_of(":"));
-
- SPDLOG_DEBUG("component {} options line: {} info size: {}",
- component.first, line, info_split_list.size());
-
- if (info_split_list.size() != 6) continue;
-
- auto configuration_name = info_split_list[0];
- boost::algorithm::trim(configuration_name);
- {
- // try lock
- std::unique_lock lock(info_.Lock);
- options_info[configuration_name] = {
- info_split_list[1], info_split_list[2], info_split_list[3],
- info_split_list[4], info_split_list[5]};
-
- boost::algorithm::trim(options_info[configuration_name][0]);
- boost::algorithm::trim(options_info[configuration_name][1]);
- boost::algorithm::trim(options_info[configuration_name][2]);
- boost::algorithm::trim(options_info[configuration_name][3]);
- boost::algorithm::trim(options_info[configuration_name][4]);
- }
- }
- });
- }
-
- SPDLOG_DEBUG("start to get avaliable component options info");
-
- for (const auto &component : info_.ComponentsInfo) {
- SPDLOG_DEBUG("gpgconf list options ready", "component", component.first);
-
- if (component.first == "gpgme" || component.first == "gpgconf") continue;
-
- GpgCommandExecutor::GetInstance().ExecuteConcurrently(
- info_.GpgConfPath, {"--list-options", component.first},
- [=](int exit_code, const std::string &p_out,
- const std::string &p_err) {
- SPDLOG_DEBUG(
- "gpgconf {} avaliable options exit_code: {} process stdout "
- "size: {} ",
- component.first, exit_code, p_out.size());
-
- if (exit_code != 0) {
- SPDLOG_ERROR(
- "gpgconf {} avaliable options execute error, process stderr: "
- "{} , process stdout:",
- component.first, p_err, p_out);
- return;
- }
-
- auto &available_options_info = info_.AvailableOptionsInfo;
-
- std::vector<std::string> line_split_list;
- boost::split(line_split_list, p_out, boost::is_any_of("\n"));
-
- for (const auto &line : line_split_list) {
- std::vector<std::string> info_split_list;
- boost::split(info_split_list, line, boost::is_any_of(":"));
-
- SPDLOG_DEBUG(
- "component {} avaliable options line: {} info size: {}",
- component.first, line, info_split_list.size());
-
- if (info_split_list.size() != 10) continue;
-
- auto configuration_name = info_split_list[0];
- boost::algorithm::trim(configuration_name);
- {
- // try lock
- std::unique_lock lock(info_.Lock);
- available_options_info[configuration_name] = {
- info_split_list[1], info_split_list[2], info_split_list[3],
- info_split_list[4], info_split_list[5], info_split_list[6],
- info_split_list[7], info_split_list[8], info_split_list[9]};
-
- boost::algorithm::trim(
- available_options_info[configuration_name][0]);
- boost::algorithm::trim(
- available_options_info[configuration_name][1]);
- boost::algorithm::trim(
- available_options_info[configuration_name][2]);
- boost::algorithm::trim(
- available_options_info[configuration_name][3]);
- boost::algorithm::trim(
- available_options_info[configuration_name][4]);
- boost::algorithm::trim(
- available_options_info[configuration_name][5]);
- boost::algorithm::trim(
- available_options_info[configuration_name][6]);
- boost::algorithm::trim(
- available_options_info[configuration_name][7]);
- boost::algorithm::trim(
- available_options_info[configuration_name][8]);
- }
- }
- });
- }
- extend_info_loaded_ = true;
- }
-
- // ensure nothing is changing now
- std::shared_lock lock(preload_lock_);
- return info_;
-}
-
-std::optional<std::string> GpgContext::check_binary_chacksum(
- std::filesystem::path path) {
- // check file info and access rights
- QFileInfo info(QString::fromStdString(path.u8string()));
- if (!info.exists() || !info.isFile() || !info.isReadable()) {
- SPDLOG_ERROR("get info for file {} error, exists: {}",
- info.filePath().toStdString(), info.exists());
- return {};
- }
-
- // open and read file
- QFile f(info.filePath());
- if (!f.open(QIODevice::ReadOnly)) {
- SPDLOG_ERROR("open {} to calculate check sum error: {}", path.u8string(),
- f.errorString().toStdString());
- return {};
- }
-
- // read all data from file
- auto buffer = f.readAll();
- f.close();
-
- auto hash_sha = QCryptographicHash(QCryptographicHash::Sha256);
- // md5
- hash_sha.addData(buffer);
- auto sha = hash_sha.result().toHex().toStdString();
- SPDLOG_DEBUG("checksum for file {} is {}", path.u8string(), sha);
-
- return sha.substr(0, 6);
-}
-
-void GpgContext::_ctx_ref_deleter::operator()(gpgme_ctx_t _ctx) {
- if (_ctx != nullptr) gpgme_release(_ctx);
-}
-
-} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/GpgContext.h b/src/core/GpgContext.h
deleted file mode 100644
index 474530c6..00000000
--- a/src/core/GpgContext.h
+++ /dev/null
@@ -1,210 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#ifndef __SGPGMEPP_CONTEXT_H__
-#define __SGPGMEPP_CONTEXT_H__
-
-#include <optional>
-#include <string>
-
-#include "GpgFunctionObject.h"
-#include "GpgInfo.h"
-
-namespace GpgFrontend {
-
-/**
- * @brief
- *
- */
-struct GpgContextInitArgs {
- // make no sense for gpg2
- bool independent_database = false; ///<
- std::string db_path = {};
-
- bool gpg_alone = false;
- std::string gpg_path = {};
-
- bool test_mode = false;
- bool ascii = true;
- bool offline_mode = false;
- bool auto_import_missing_key = false;
-
- bool custom_gpgconf = false;
- std::string custom_gpgconf_path;
-
- bool use_pinentry = false;
-
- GpgContextInitArgs() = default;
-};
-
-/**
- * @brief
- *
- */
-class GPGFRONTEND_CORE_EXPORT GpgContext
- : public QObject,
- public SingletonFunctionObject<GpgContext> {
- Q_OBJECT
- public:
- /**
- * @brief Construct a new Gpg Context object
- *
- * @param args
- */
- explicit GpgContext(const GpgContextInitArgs& args = {});
-
- /**
- * @brief Construct a new Gpg Context object
- *
- * @param channel
- */
- explicit GpgContext(int channel);
-
- /**
- * @brief Destroy the Gpg Context object
- *
- */
- ~GpgContext() override = default;
-
- /**
- * @brief
- *
- * @return true
- * @return false
- */
- [[nodiscard]] bool good() const;
-
- /**
- * @brief Get the Info object
- *
- * @return const GpgInfo&
- */
- [[nodiscard]] const GpgInfo& GetInfo(bool refresh = false);
-
- /**
- * @brief
- *
- * @return gpgme_ctx_t
- */
- operator gpgme_ctx_t() const { return _ctx_ref.get(); }
-
- private:
- GpgInfo info_{}; ///<
- GpgContextInitArgs args_{}; ///<
- bool extend_info_loaded_ = false;
- std::shared_mutex preload_lock_{};
-
- /**
- * @brief
- *
- */
- void post_init_ctx();
-
- /**
- * @brief
- *
- * @return std::string
- */
- std::string need_user_input_passphrase();
-
- /**
- * @brief Construct a new std::check component existence object
- *
- */
- std::optional<std::string> check_binary_chacksum(std::filesystem::path);
-
- /**
- * @brief
- *
- */
- struct _ctx_ref_deleter {
- void operator()(gpgme_ctx_t _ctx);
- };
-
- using CtxRefHandler =
- std::unique_ptr<struct gpgme_context, _ctx_ref_deleter>; ///<
- CtxRefHandler _ctx_ref = nullptr; ///<
- bool good_ = true; ///<
-
- signals:
- /**
- * @brief
- *
- */
- void SignalNeedUserInputPassphrase();
-
- public:
- /**
- * @brief
- *
- * @param opaque
- * @param uid_hint
- * @param passphrase_info
- * @param last_was_bad
- * @param fd
- * @return gpgme_error_t
- */
- static gpgme_error_t test_passphrase_cb(void* opaque, const char* uid_hint,
- const char* passphrase_info,
- int last_was_bad, int fd);
-
- /**
- * @brief
- *
- * @param opaque
- * @param uid_hint
- * @param passphrase_info
- * @param last_was_bad
- * @param fd
- * @return gpgme_error_t
- */
- static gpgme_error_t custom_passphrase_cb(void* opaque, const char* uid_hint,
- const char* passphrase_info,
- int last_was_bad, int fd);
-
- /**
- * @brief
- *
- * @param hook
- * @param keyword
- * @param args
- * @return gpgme_error_t
- */
- static gpgme_error_t test_status_cb(void* hook, const char* keyword,
- const char* args);
-
- /**
- * @brief Set the Passphrase Cb object
- *
- * @param func
- */
- void SetPassphraseCb(gpgme_passphrase_cb_t func) const;
-};
-} // namespace GpgFrontend
-
-#endif // __SGPGMEPP_CONTEXT_H__ \ No newline at end of file
diff --git a/src/core/GpgCoreInit.cpp b/src/core/GpgCoreInit.cpp
index 6d782439..1790776e 100644
--- a/src/core/GpgCoreInit.cpp
+++ b/src/core/GpgCoreInit.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,236 +20,376 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "GpgCoreInit.h"
-#include <spdlog/async.h>
-#include <spdlog/common.h>
-#include <spdlog/sinks/rotating_file_sink.h>
-#include <spdlog/sinks/stdout_color_sinks.h>
+#include <gpgme.h>
-#include <filesystem>
-#include <string>
-
-#include "GpgFunctionObject.h"
-#include "core/GpgContext.h"
+#include "core/function/CoreSignalStation.h"
#include "core/function/GlobalSettingStation.h"
-#include "function/gpg/GpgAdvancedOperator.h"
-#include "spdlog/spdlog.h"
-#include "thread/Task.h"
-#include "thread/TaskRunner.h"
-#include "thread/TaskRunnerGetter.h"
+#include "core/function/basic/ChannelObject.h"
+#include "core/function/basic/SingletonStorage.h"
+#include "core/function/gpg/GpgAdvancedOperator.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/module/ModuleManager.h"
+#include "core/thread/Task.h"
+#include "core/thread/TaskRunner.h"
+#include "core/thread/TaskRunnerGetter.h"
+#include "core/utils/CommonUtils.h"
+#include "core/utils/GpgUtils.h"
+#include "core/utils/MemoryUtils.h"
namespace GpgFrontend {
-/**
- * @brief setup logging system and do proper initialization
- *
- */
-void InitCoreLoggingSystem() {
- using namespace boost::posix_time;
- using namespace boost::gregorian;
-
- // get the log directory
- auto logfile_path =
- (GlobalSettingStation::GetInstance().GetLogDir() / "core");
- logfile_path.replace_extension(".log");
-
- // sinks
- std::vector<spdlog::sink_ptr> sinks;
- sinks.push_back(std::make_shared<spdlog::sinks::stderr_color_sink_mt>());
- sinks.push_back(std::make_shared<spdlog::sinks::rotating_file_sink_mt>(
- logfile_path.u8string(), 1048576 * 32, 8));
-
- // thread pool
- spdlog::init_thread_pool(1024, 2);
-
- // logger
- auto core_logger = std::make_shared<spdlog::async_logger>(
- "core", begin(sinks), end(sinks), spdlog::thread_pool());
- core_logger->set_pattern(
- "[%H:%M:%S.%e] [T:%t] [%=4n] %^[%=8l]%$ [%s:%#] [%!] -> %v (+%ius)");
-
-#ifdef DEBUG
- core_logger->set_level(spdlog::level::trace);
-#else
- core_logger->set_level(spdlog::level::info);
-#endif
+void DestroyGpgFrontendCore() { SingletonStorageCollection::Destroy(); }
+
+auto VerifyGpgconfPath(const QFileInfo& gnupg_install_fs_path) -> bool {
+ return gnupg_install_fs_path.isAbsolute() && gnupg_install_fs_path.exists() &&
+ gnupg_install_fs_path.isFile();
+}
- // flush policy
- core_logger->flush_on(spdlog::level::err);
- spdlog::flush_every(std::chrono::seconds(5));
+auto VerifyKeyDatabasePath(const QFileInfo& key_database_fs_path) -> bool {
+ return key_database_fs_path.isAbsolute() && key_database_fs_path.exists() &&
+ key_database_fs_path.isDir();
+}
- // register it as default logger
- spdlog::set_default_logger(core_logger);
+auto SearchGpgconfPath(const QList<QString>& candidate_paths) -> QString {
+ for (const auto& path : candidate_paths) {
+ if (VerifyGpgconfPath(QFileInfo(path))) {
+ return path;
+ }
+ }
+ return {};
}
-void ShutdownCoreLoggingSystem() {
-#ifdef WINDOWS
- // Under VisualStudio, this must be called before main finishes to workaround
- // a known VS issue
- spdlog::drop_all();
- spdlog::shutdown();
-#endif
+auto SearchKeyDatabasePath(const QList<QString>& candidate_paths) -> QString {
+ for (const auto& path : candidate_paths) {
+ GF_CORE_LOG_DEBUG("searh for candidate key database path: {}", path);
+ if (VerifyKeyDatabasePath(QFileInfo(path))) {
+ return path;
+ }
+ }
+ return {};
}
-void ResetGpgFrontendCore() { reset_gpgfrontend_core(); }
+auto InitGpgME() -> bool {
+ // init gpgme subsystem and get gpgme library version
+ Module::UpsertRTValue("core", "gpgme.version",
+ QString(gpgme_check_version(nullptr)));
-void init_gpgfrontend_core() {
- /* Initialize the locale environment. */
- SPDLOG_DEBUG("locale: {}", setlocale(LC_CTYPE, nullptr));
- // init gpgme subsystem
- 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
- // read settings
- bool forbid_all_gnupg_connection =
- GlobalSettingStation::GetInstance().LookupSettings(
- "network.forbid_all_gnupg_connection", false);
-
- bool auto_import_missing_key =
- GlobalSettingStation::GetInstance().LookupSettings(
- "network.auto_import_missing_key", false);
-
- bool use_custom_key_database_path =
- GlobalSettingStation::GetInstance().LookupSettings(
- "general.use_custom_key_database_path", false);
+ gpgme_ctx_t p_ctx;
+
+ CheckGpgError(gpgme_new(&p_ctx));
+
+ // get engine info
+ auto* engine_info = gpgme_ctx_get_engine_info(p_ctx);
+ // Check ENV before running
+ bool find_openpgp = false;
+ bool find_gpgconf = false;
+ bool find_cms = false;
+
+ while (engine_info != nullptr) {
+ if (strcmp(engine_info->version, "1.0.0") == 0) {
+ engine_info = engine_info->next;
+ continue;
+ }
+
+ GF_CORE_LOG_DEBUG(
+ "gpg context engine info: {} {} {} {}",
+ gpgme_get_protocol_name(engine_info->protocol),
+ QString(engine_info->file_name == nullptr ? "null"
+ : engine_info->file_name),
+ QString(engine_info->home_dir == nullptr ? "null"
+ : engine_info->home_dir),
+ QString(engine_info->version ? "null" : engine_info->version));
+
+ switch (engine_info->protocol) {
+ case GPGME_PROTOCOL_OpenPGP:
+ find_openpgp = true;
+
+ Module::UpsertRTValue("core", "gpgme.engine.openpgp", 1);
+ Module::UpsertRTValue("core", "gpgme.ctx.app_path",
+ QString(engine_info->file_name));
+ Module::UpsertRTValue("core", "gpgme.ctx.gnupg_version",
+ QString(engine_info->version));
+ Module::UpsertRTValue(
+ "core", "gpgme.ctx.database_path",
+ QString(engine_info->home_dir == nullptr ? "default"
+ : engine_info->home_dir));
+ break;
+ case GPGME_PROTOCOL_CMS:
+ find_cms = true;
+ Module::UpsertRTValue("core", "gpgme.engine.cms", 1);
+ Module::UpsertRTValue("core", "gpgme.ctx.cms_path",
+ QString(engine_info->file_name));
+
+ break;
+ case GPGME_PROTOCOL_GPGCONF:
+ find_gpgconf = true;
+
+ Module::UpsertRTValue("core", "gpgme.engine.gpgconf", 1);
+ Module::UpsertRTValue("core", "gpgme.ctx.gpgconf_path",
+ QString(engine_info->file_name));
+ break;
+ case GPGME_PROTOCOL_ASSUAN:
+
+ Module::UpsertRTValue("core", "gpgme.engine.assuan", 1);
+ Module::UpsertRTValue("core", "gpgme.ctx.assuan_path",
+ QString(engine_info->file_name));
+ break;
+ case GPGME_PROTOCOL_G13:
+ break;
+ case GPGME_PROTOCOL_UISERVER:
+ break;
+ case GPGME_PROTOCOL_SPAWN:
+ break;
+ case GPGME_PROTOCOL_DEFAULT:
+ break;
+ case GPGME_PROTOCOL_UNKNOWN:
+ break;
+ }
+ engine_info = engine_info->next;
+ }
- std::string custom_key_database_path =
- GlobalSettingStation::GetInstance().LookupSettings(
- "general.custom_key_database_path", std::string{});
+ // release gpgme context
+ gpgme_release(p_ctx);
- bool use_custom_gnupg_install_path =
- GlobalSettingStation::GetInstance().LookupSettings(
- "general.use_custom_gnupg_install_path", false);
+ const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gnupg_version", QString{"0.0.0"});
+ GF_CORE_LOG_DEBUG("got gnupg version from rt: {}", gnupg_version);
- std::string custom_gnupg_install_path =
- GlobalSettingStation::GetInstance().LookupSettings(
- "general.custom_gnupg_install_path", std::string{});
+ // conditional check: only support gpg 2.1.x now
+ if (!(CompareSoftwareVersion(gnupg_version, "2.1.0") >= 0 && find_gpgconf &&
+ find_openpgp && find_cms)) {
+ GF_CORE_LOG_ERROR("gpgme env check failed, abort");
+ return false;
+ }
- bool use_pinentry_as_password_input_dialog =
- GpgFrontend::GlobalSettingStation::GetInstance().LookupSettings(
- "general.use_pinentry_as_password_input_dialog", false);
+ Module::UpsertRTValue("core", "env.state.gpgme", 1);
+ return true;
+}
- SPDLOG_DEBUG("core loaded if use custom key databse path: {}",
- use_custom_key_database_path);
- SPDLOG_DEBUG("core loaded custom key databse path: {}",
- custom_key_database_path);
+void InitGpgFrontendCore(CoreInitArgs args) {
+ // initialize global register table
+ Module::UpsertRTValue("core", "env.state.gpgme", 0);
+ Module::UpsertRTValue("core", "env.state.ctx", 0);
+ Module::UpsertRTValue("core", "env.state.gnupg", 0);
+ Module::UpsertRTValue("core", "env.state.basic", 0);
+ Module::UpsertRTValue("core", "env.state.all", 0);
+
+ // initialize locale environment
+ GF_CORE_LOG_DEBUG("locale: {}", setlocale(LC_CTYPE, nullptr));
+
+ // initialize library gpgme
+ if (!InitGpgME()) {
+ CoreSignalStation::GetInstance()->SignalBadGnupgEnv(
+ QObject::tr("GpgME inilization failed"));
+ return;
+ }
- // check gpgconf path
- std::filesystem::path custom_gnupg_install_fs_path =
- custom_gnupg_install_path;
+ auto* task = new Thread::Task(
+ [args](const DataObjectPtr&) -> int {
+ auto settings = GlobalSettingStation::GetInstance().GetSettings();
+ // read settings from config file
+ auto forbid_all_gnupg_connection =
+ settings.value("network/forbid_all_gnupg_connection", false)
+ .toBool();
+
+ auto auto_import_missing_key =
+ settings.value("network/auto_import_missing_key", false).toBool();
+
+ auto use_custom_key_database_path =
+ settings.value("basic/use_custom_key_database_path", false)
+ .toBool();
+
+ auto custom_key_database_path =
+ settings.value("basic/custom_key_database_path", QString{})
+ .toString();
+
+ auto use_custom_gnupg_install_path =
+ settings.value("basic/use_custom_gnupg_install_path", false)
+ .toBool();
+
+ auto custom_gnupg_install_path =
+ settings.value("basic/custom_gnupg_install_path", QString{})
+ .toString();
+
+ auto use_pinentry_as_password_input_dialog =
+ settings.value("basic/use_pinentry_as_password_input_dialog", false)
+ .toBool();
+
+ GF_CORE_LOG_DEBUG("core loaded if use custom key databse path: {}",
+ use_custom_key_database_path);
+ GF_CORE_LOG_DEBUG("core loaded custom key databse path: {}",
+ custom_key_database_path);
+
+ QString gnupg_install_fs_path;
+ // user defined
+ if (use_custom_gnupg_install_path &&
+ !custom_gnupg_install_path.isEmpty()) {
+ // check gpgconf path
+ gnupg_install_fs_path = custom_gnupg_install_path;
#ifdef WINDOWS
- custom_gnupg_install_fs_path /= "gpgconf.exe";
+ gnupg_install_fs_path += "/gpgconf.exe";
#else
- custom_gnupg_install_fs_path /= "gpgconf";
+ gnupg_install_fs_path += "/gpgconf";
#endif
- if (!custom_gnupg_install_fs_path.is_absolute() ||
- !std::filesystem::exists(custom_gnupg_install_fs_path) ||
- !std::filesystem::is_regular_file(custom_gnupg_install_fs_path)) {
- use_custom_gnupg_install_path = false;
- SPDLOG_ERROR("core loaded custom gpgconf path is illegal: {}",
- custom_gnupg_install_fs_path.u8string());
- } else {
- SPDLOG_DEBUG("core loaded custom gpgconf path: {}",
- custom_gnupg_install_fs_path.u8string());
- }
-
- // check key database path
- std::filesystem::path custom_key_database_fs_path = custom_key_database_path;
- if (!custom_key_database_fs_path.is_absolute() ||
- !std::filesystem::exists(custom_key_database_fs_path) ||
- !std::filesystem::is_directory(custom_key_database_fs_path)) {
- use_custom_key_database_path = false;
- SPDLOG_ERROR("core loaded custom gpg key database is illegal: {}",
- custom_key_database_fs_path.u8string());
- } else {
- SPDLOG_DEBUG("core loaded custom gpg key database path: {}",
- custom_key_database_fs_path.u8string());
- }
+ if (!VerifyGpgconfPath(QFileInfo(gnupg_install_fs_path))) {
+ use_custom_gnupg_install_path = false;
+ GF_CORE_LOG_ERROR("core loaded custom gpgconf path is illegal: {}",
+ gnupg_install_fs_path);
+ } else {
+ GF_CORE_LOG_DEBUG("core loaded custom gpgconf path: {}",
+ gnupg_install_fs_path);
+ }
+ } else {
+#ifdef MACOS
+ use_custom_gnupg_install_path = true;
+ gnupg_install_fs_path = SearchGpgconfPath(
+ {"/usr/local/bin/gpgconf", "/opt/homebrew/bin/gpgconf"});
+ GF_CORE_LOG_DEBUG("core loaded searched gpgconf path: {}",
+ gnupg_install_fs_path);
+#endif
+ }
- // init default channel
- auto& default_ctx = GpgFrontend::GpgContext::CreateInstance(
- GPGFRONTEND_DEFAULT_CHANNEL, [=]() -> std::unique_ptr<ChannelObject> {
- GpgFrontend::GpgContextInitArgs args;
+ // check key database path
+ QString key_database_fs_path;
+ // user defined
+ if (use_custom_key_database_path &&
+ !custom_key_database_path.isEmpty()) {
+ key_database_fs_path = custom_key_database_path;
+ if (VerifyKeyDatabasePath(QFileInfo(key_database_fs_path))) {
+ GF_CORE_LOG_ERROR(
+ "core loaded custom gpg key database is illegal: {}",
+ key_database_fs_path);
+ } else {
+ use_custom_key_database_path = true;
+ GF_CORE_LOG_DEBUG("core loaded custom gpg key database path: {}",
+ key_database_fs_path);
+ }
+ } else {
+#ifdef MACOS
+ use_custom_key_database_path = true;
+ key_database_fs_path =
+ SearchKeyDatabasePath({QDir::home().path() + "/.gnupg"});
+ GF_CORE_LOG_DEBUG("core loaded searched key database path: {}",
+ key_database_fs_path);
+#endif
+ }
- // set key database path
- if (use_custom_key_database_path && !custom_key_database_path.empty()) {
- args.db_path = custom_key_database_path;
+ if (args.load_default_gpg_context) {
+ // init ctx, also checking the basical env
+ auto& ctx = GpgFrontend::GpgContext::CreateInstance(
+ kGpgFrontendDefaultChannel, [=]() -> ChannelObjectPtr {
+ GpgFrontend::GpgContextInitArgs args;
+
+ // set key database path
+ if (use_custom_key_database_path &&
+ !key_database_fs_path.isEmpty()) {
+ args.db_path = key_database_fs_path;
+ }
+
+ // set custom gnupg path
+ if (use_custom_gnupg_install_path) {
+ args.custom_gpgconf = true;
+ args.custom_gpgconf_path = gnupg_install_fs_path;
+ }
+
+ args.offline_mode = forbid_all_gnupg_connection;
+ args.auto_import_missing_key = auto_import_missing_key;
+ args.use_pinentry = use_pinentry_as_password_input_dialog;
+
+ return ConvertToChannelObjectPtr<>(
+ SecureCreateUniqueObject<GpgContext>(
+ args, kGpgFrontendDefaultChannel));
+ });
+
+ // exit if failed
+ if (!ctx.Good()) {
+ GF_CORE_LOG_ERROR("default gnupg context init error, abort");
+ CoreSignalStation::GetInstance()->SignalBadGnupgEnv(
+ QObject::tr("GpgME Context inilization failed"));
+ return -1;
+ }
+ Module::UpsertRTValue("core", "env.state.ctx", 1);
}
- if (use_custom_gnupg_install_path) {
- args.custom_gpgconf = true;
- args.custom_gpgconf_path = custom_gnupg_install_fs_path.u8string();
+ if (args.load_default_gpg_context) {
+ if (!GpgKeyGetter::GetInstance().FlushKeyCache()) {
+ CoreSignalStation::GetInstance()->SignalBadGnupgEnv(
+ QObject::tr("Gpg Key Detabase inilization failed"));
+ };
+ }
+ GF_CORE_LOG_INFO(
+ "basic env checking finished, "
+ "including gpgme, ctx, and key infos");
+ Module::UpsertRTValue("core", "env.state.basic", 1);
+ CoreSignalStation::GetInstance()->SignalGoodGnupgEnv();
+
+ // if gnupg-info-gathering module activated
+ if (args.gather_external_gnupg_info &&
+ Module::IsModuleAcivate("com.bktus.gpgfrontend.module."
+ "integrated.gnupg-info-gathering")) {
+ GF_CORE_LOG_DEBUG(
+ "module gnupg-info-gathering is activated, "
+ "loading external gnupg info...");
+
+ // gather external gnupg info
+ Module::TriggerEvent(
+ "GPGFRONTEND_CORE_INITLIZED",
+ [](const Module::EventIdentifier& /*e*/,
+ const Module::Event::ListenerIdentifier& l_id,
+ DataObjectPtr o) {
+ GF_CORE_LOG_DEBUG(
+ "received event GPGFRONTEND_CORE_INITLIZED callback "
+ "from module: {}",
+ l_id);
+
+ if (l_id ==
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-"
+ "gathering") {
+ GF_CORE_LOG_DEBUG(
+ "received callback from gnupg-info-gathering ");
+
+ // try to restart all components
+ GpgFrontend::GpgAdvancedOperator::RestartGpgComponents();
+ Module::UpsertRTValue("core", "env.state.gnupg", 1);
+
+ // announce that all checkings were finished
+ GF_CORE_LOG_INFO(
+ "all env checking finished, including gpgme, "
+ "ctx and gnupg");
+ Module::UpsertRTValue("core", "env.state.all", 1);
+ }
+ });
+ } else {
+ GF_CORE_LOG_DEBUG("gnupg-info-gathering is not activated");
+ Module::UpsertRTValue("core", "env.state.all", 1);
}
+ return 0;
+ },
+ "core_init_task");
- args.offline_mode = forbid_all_gnupg_connection;
- args.auto_import_missing_key = auto_import_missing_key;
- args.use_pinentry = use_pinentry_as_password_input_dialog;
-
- return std::unique_ptr<ChannelObject>(new GpgContext(args));
- });
-
- // exit if failed
- if (!default_ctx.good()) {
- SPDLOG_ERROR("default gnupg context init error");
- };
-
- // async init no-ascii channel
- Thread::TaskRunnerGetter::GetInstance()
- .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_GPG)
- ->PostTask(
- new Thread::Task([=](Thread::Task::DataObjectPtr data_obj) -> int {
- // init non-ascii channel
- auto& ctx = GpgFrontend::GpgContext::CreateInstance(
- GPGFRONTEND_NON_ASCII_CHANNEL,
- [=]() -> std::unique_ptr<ChannelObject> {
- GpgFrontend::GpgContextInitArgs args;
- args.ascii = false;
-
- // set key database path
- if (use_custom_key_database_path &&
- !custom_key_database_path.empty()) {
- args.db_path = custom_key_database_path;
- }
-
- if (use_custom_gnupg_install_path) {
- args.custom_gpgconf = true;
- args.custom_gpgconf_path =
- custom_gnupg_install_fs_path.u8string();
- }
-
- args.offline_mode = forbid_all_gnupg_connection;
- args.auto_import_missing_key = auto_import_missing_key;
- args.use_pinentry = use_pinentry_as_password_input_dialog;
-
- return std::unique_ptr<ChannelObject>(new GpgContext(args));
- });
-
- if (!ctx.good()) SPDLOG_ERROR("no-ascii channel init error");
- return ctx.good() ? 0 : -1;
- }));
-
- // try to restart all components
- GpgFrontend::GpgAdvancedOperator::GetInstance().RestartGpgComponents();
-}
+ QObject::connect(task, &Thread::Task::SignalTaskEnd, []() {
-void reset_gpgfrontend_core() { SingletonStorageCollection::GetInstance(true); }
+ });
-void new_default_settings_channel(int channel) {
- GpgFrontend::GpgContext::CreateInstance(
- channel, [&]() -> std::unique_ptr<ChannelObject> {
- GpgFrontend::GpgContextInitArgs args;
- return std::unique_ptr<ChannelObject>(new GpgContext(args));
- });
+ // start the thread to check ctx and gnupg state
+ // it may take a few seconds or minutes
+ GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default)
+ ->PostTask(task);
}
} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/GpgCoreInit.h b/src/core/GpgCoreInit.h
index 41e04d60..15f0254d 100644
--- a/src/core/GpgCoreInit.h
+++ b/src/core/GpgCoreInit.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,57 +20,33 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGCOREINIT_H
-#define GPGFRONTEND_GPGCOREINIT_H
+#pragma once
#include "GpgConstants.h"
namespace GpgFrontend {
-/**
- * @brief
- *
- */
-void GPGFRONTEND_CORE_EXPORT InitCoreLoggingSystem();
-
-/**
- * @brief
- *
- */
-void GPGFRONTEND_CORE_EXPORT ShutdownCoreLoggingSystem();
-
-/**
- * @brief
- *
- */
-void GPGFRONTEND_CORE_EXPORT ResetGpgFrontendCore();
-
-/**
- * @brief
- *
- */
-void init_gpgfrontend_core();
+struct CoreInitArgs {
+ bool gather_external_gnupg_info;
+ bool load_default_gpg_context;
+};
/**
* @brief
*
*/
-void reset_gpgfrontend_core();
+void GPGFRONTEND_CORE_EXPORT DestroyGpgFrontendCore();
/**
* @brief
*
- * @param channel
*/
-void new_default_settings_channel(
- int channel = GpgFrontend::GPGFRONTEND_DEFAULT_CHANNEL);
+void GPGFRONTEND_CORE_EXPORT InitGpgFrontendCore(CoreInitArgs);
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGCOREINIT_H
diff --git a/src/core/GpgFrontendCore.cpp b/src/core/GpgFrontendCore.cpp
new file mode 100644
index 00000000..2508f4e7
--- /dev/null
+++ b/src/core/GpgFrontendCore.cpp
@@ -0,0 +1,34 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "core/GpgFrontendCore.h"
+
+#ifndef MACOS
+// mimalloc
+#include <mimalloc-new-delete.h>
+#endif
diff --git a/src/core/GpgFrontendCore.h b/src/core/GpgFrontendCore.h
index 0b433b96..14b1f878 100644
--- a/src/core/GpgFrontendCore.h
+++ b/src/core/GpgFrontendCore.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,56 +20,33 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGFRONTENDCORE_H
-#define GPGFRONTEND_GPGFRONTENDCORE_H
+#pragma once
-#include "GpgFrontend.h"
-
-// gnupg
-#include <gpgme.h>
+// Qt
+#include <QtCore>
-// std includes
-#include <cassert>
-#include <filesystem>
-#include <functional>
-#include <map>
-#include <memory>
-#include <mutex>
-#include <random>
-#include <shared_mutex>
-#include <stdexcept>
-#include <string>
-#include <typeinfo>
-#include <utility>
+// std
+#include <cstdint>
#include <vector>
-// boost includes
-#include <boost/date_time.hpp>
-#include <boost/date_time/posix_time/conversion.hpp>
-#include <boost/filesystem/operations.hpp>
-#include <boost/filesystem/path.hpp>
-#include <boost/format.hpp>
+// spdlog library configuration
+#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_TRACE
+#include <spdlog/spdlog.h>
-// Qt includes
-#include <QtCore>
+// logger fmt
+#include "log/QtLoggerFmt.h"
-// libconfig includes
-#include <libconfig.h++>
-
-// libarchive includes
-#include <libarchive/libarchive/archive.h>
-#include <libarchive/libarchive/archive_entry.h>
+// gpgme library
+#include <gpgme.h>
-// json includes
-#include <nlohmann/json.hpp>
+// logbal includes or macroes
+#include "GpgFrontend.h"
-// dll export macro
+// dll export macroes
#include "GpgFrontendCoreExport.h"
-
-#endif // GPGFRONTEND_GPGFRONTENDCORE_H
diff --git a/src/core/GpgFunctionObject.cpp b/src/core/GpgFunctionObject.cpp
deleted file mode 100644
index 0ddc290c..00000000
--- a/src/core/GpgFunctionObject.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#include "core/GpgFunctionObject.h"
-
-#include <cassert>
-#include <functional>
-#include <memory>
-#include <mutex>
-#include <shared_mutex>
-
-void GpgFrontend::ChannelObject::SetChannel(int channel) {
- this->channel_ = channel;
-}
-
-int GpgFrontend::ChannelObject::GetChannel() const { return channel_; }
-
-int GpgFrontend::ChannelObject::GetDefaultChannel() { return _default_channel; }
-
-void GpgFrontend::SingletonStorage::ReleaseChannel(int channel) {
- decltype(instances_map_.end()) _it;
- {
- std::shared_lock<std::shared_mutex> lock(instances_mutex_);
- _it = instances_map_.find(channel);
- }
- if (_it != instances_map_.end()) instances_map_.erase(_it);
-}
-
-GpgFrontend::ChannelObject* GpgFrontend::SingletonStorage::FindObjectInChannel(
- int channel) {
- // read instances_map_
- decltype(instances_map_.end()) _it;
- {
- std::shared_lock<std::shared_mutex> lock(instances_mutex_);
- _it = instances_map_.find(channel);
- if (_it == instances_map_.end()) {
- return nullptr;
- } else {
- return _it->second.get();
- }
- }
-}
-
-std::vector<int> GpgFrontend::SingletonStorage::GetAllChannelId() {
- std::vector<int> _channels;
- for (const auto& [key, value] : instances_map_) {
- _channels.push_back(key);
- }
- return _channels;
-}
-
-GpgFrontend::ChannelObject* GpgFrontend::SingletonStorage::SetObjectInChannel(
- int channel, std::unique_ptr<ChannelObject> p_obj) {
- {
- SPDLOG_TRACE("set channel: {} instance address: {}", channel,
- static_cast<void*>(&instances_map_));
-
- assert(p_obj != nullptr);
- if (p_obj == nullptr) return nullptr;
-
- auto raw_obj = p_obj.get();
- p_obj->SetChannel(channel);
- {
- std::unique_lock<std::shared_mutex> lock(instances_mutex_);
- instances_map_.insert({channel, std::move(p_obj)});
- }
- return raw_obj;
- }
-}
-
-GpgFrontend::SingletonStorage*
-GpgFrontend::SingletonStorageCollection::GetSingletonStorage(
- const std::type_info& type_id) {
- const auto hash = type_id.hash_code();
-
- while (true) {
- decltype(storages_map_.end()) _it;
- {
- std::shared_lock<std::shared_mutex> lock(storages_mutex_);
- _it = storages_map_.find(hash);
- }
- if (_it == storages_map_.end()) {
- {
- std::unique_lock<std::shared_mutex> lock(storages_mutex_);
- storages_map_.insert({hash, std::make_unique<SingletonStorage>()});
- }
- SPDLOG_TRACE("hash: {} created, storage address: {} type_name: {}", hash,
- static_cast<void*>(&storages_map_), type_id.name());
- continue;
- } else {
- return _it->second.get();
- }
- }
-}
-
-GpgFrontend::SingletonStorageCollection*
-GpgFrontend::SingletonStorageCollection::GetInstance(
- bool force_refresh = false) {
- static SingletonStorageCollection* instance = nullptr;
-
- if (force_refresh || instance == nullptr) {
- instance = new SingletonStorageCollection();
- SPDLOG_DEBUG("new single storage collection created: {}",
- static_cast<void*>(instance));
- }
-
- return instance;
-}
-
-GpgFrontend::ChannelObject::ChannelObject() noexcept = default;
-
-GpgFrontend::ChannelObject::ChannelObject(int channel) : channel_(channel) {}
diff --git a/src/core/GpgFunctionObject.h b/src/core/GpgFunctionObject.h
deleted file mode 100644
index 9b8c2aa3..00000000
--- a/src/core/GpgFunctionObject.h
+++ /dev/null
@@ -1,311 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#ifndef GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H
-#define GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H
-
-#include <mutex>
-
-#include "GpgConstants.h"
-
-namespace GpgFrontend {
-
-/**
- * @brief object which in channel system
- *
- */
-class GPGFRONTEND_CORE_EXPORT ChannelObject {
- public:
- /**
- * @brief Construct a new Default Channel Object object
- *
- */
- ChannelObject() noexcept;
-
- /**
- * @brief Construct a new Channel Object object
- *
- * @param channel
- */
- ChannelObject(int channel);
-
- /**
- * @brief Get the Default Channel object
- *
- * @return int
- */
- static int GetDefaultChannel();
-
- /**
- * @brief Get the Channel object
- *
- * @return int
- */
- [[nodiscard]] int GetChannel() const;
-
- /**
- * @brief Set the Channel object
- *
- * @param channel
- */
- void SetChannel(int channel);
-
- private:
- int channel_ = _default_channel; ///< The channel id
- static constexpr int _default_channel = 0; ///< The default channel id
-};
-
-class GPGFRONTEND_CORE_EXPORT SingletonStorage {
- public:
- /**
- * @brief
- *
- * @param channel
- */
- void ReleaseChannel(int channel);
-
- /**
- * @brief
- *
- * @param channel
- * @return T*
- */
- ChannelObject* FindObjectInChannel(int channel);
-
- /**
- * @brief Get all the channel ids
- *
- * @return std::vector<int>
- */
- std::vector<int> GetAllChannelId();
-
- /**
- * @brief Set a new object in channel object
- *
- * @param channel
- * @param p_obj
- * @return T*
- */
- ChannelObject* SetObjectInChannel(int channel,
- std::unique_ptr<ChannelObject> p_obj);
-
- private:
- std::shared_mutex instances_mutex_; ///< mutex for _instances_map
- std::map<int, std::unique_ptr<ChannelObject>>
- instances_map_; ///< map of singleton instances
-};
-
-class GPGFRONTEND_CORE_EXPORT SingletonStorageCollection {
- public:
- /**
- * @brief Get the Instance object
- *
- * @return SingletonStorageCollection*
- */
- static SingletonStorageCollection* GetInstance(bool force_refresh);
-
- /**
- * @brief Get the Singleton Storage object
- *
- * @param singleton_function_object
- * @return SingletonStorage*
- */
- SingletonStorage* GetSingletonStorage(const std::type_info&);
-
- private:
- std::shared_mutex storages_mutex_; ///< mutex for storages_map_
- std::map<size_t, std::unique_ptr<SingletonStorage>> storages_map_;
-};
-/**
- * @brief
- *
- * @tparam T
- */
-template <typename T>
-class SingletonFunctionObject : public ChannelObject {
- public:
- /**
- * @brief prohibit copy
- *
- */
- SingletonFunctionObject(const SingletonFunctionObject<T>&) = delete;
-
- /**
- * @brief prohibit copy
- *
- * @return SingletonFunctionObject&
- */
- SingletonFunctionObject& operator=(const SingletonFunctionObject<T>&) =
- delete;
-
- /**
- * @brief Get the Instance object
- *
- * @param channel
- * @return T&
- */
- static T& GetInstance(
- int channel = GpgFrontend::GPGFRONTEND_DEFAULT_CHANNEL) {
- static std::mutex g_channel_mutex_map_lock;
- static std::map<int, std::mutex> g_channel_mutex_map;
-
- {
- std::lock_guard<std::mutex> guard(g_channel_mutex_map_lock);
- if (g_channel_mutex_map.find(channel) == g_channel_mutex_map.end()) {
- g_channel_mutex_map[channel];
- }
- }
-
- static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value,
- "T not derived from SingletonFunctionObject<T>");
-
- auto* p_storage =
- SingletonStorageCollection::GetInstance(false)->GetSingletonStorage(
- typeid(T));
- auto* _p_pbj = (T*)(p_storage->FindObjectInChannel(channel));
-
- if (_p_pbj == nullptr) {
- // lock this channel
- std::lock_guard<std::mutex> guard(g_channel_mutex_map[channel]);
-
- // double check
- if ((_p_pbj = (T*)(p_storage->FindObjectInChannel(channel))) != nullptr)
- return *_p_pbj;
-
- // do create object of this channel
- auto new_obj = std::unique_ptr<ChannelObject>(new T(channel));
- return *(T*)(p_storage->SetObjectInChannel(channel, std::move(new_obj)));
- } else {
- return *_p_pbj;
- }
- }
-
- /**
- * @brief Create a Instance object
- *
- * @param channel
- * @param factory
- * @return T&
- */
- static T& CreateInstance(
- int channel,
- std::function<std::unique_ptr<ChannelObject>(void)> factory) {
- static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value,
- "T not derived from SingletonFunctionObject<T>");
-
- auto p_storage =
- SingletonStorageCollection::GetInstance(false)->GetSingletonStorage(
- typeid(T));
-
- auto _p_pbj = (T*)(p_storage->FindObjectInChannel(channel));
-
- if (_p_pbj == nullptr) {
- return *(
- T*)(p_storage->SetObjectInChannel(channel, std::move(factory())));
- } else
- return *_p_pbj;
- }
-
- /**
- * @brief
- *
- * @param channel
- * @return T&
- */
- static void ReleaseChannel(int channel) {
- SingletonStorageCollection::GetInstance(false)
- ->GetSingletonStorage(typeid(T))
- ->ReleaseChannel(channel);
- }
-
- /**
- * @brief Get the Default Channel object
- *
- * @return int
- */
- static int GetDefaultChannel() { return ChannelObject::GetDefaultChannel(); }
-
- /**
- * @brief Get the Channel object
- *
- * @return int
- */
- [[nodiscard]] int GetChannel() const { return ChannelObject::GetChannel(); }
-
- /**
- * @brief Get all the channel ids
- *
- * @return std::vector<int>
- */
- static std::vector<int> GetAllChannelId() {
- return SingletonStorageCollection::GetInstance(false)
- ->GetSingletonStorage(typeid(T))
- ->GetAllChannelId();
- }
-
- /**
- * @brief Construct a new Singleton Function Object object
- *
- */
- SingletonFunctionObject(T&&) = delete;
-
- /**
- * @brief Construct a new Singleton Function Object object
- *
- */
- SingletonFunctionObject(const T&) = delete;
-
- /**
- * @brief
- *
- */
- void operator=(const T&) = delete;
-
- protected:
- /**
- * @brief Construct a new Singleton Function Object object
- *
- */
- SingletonFunctionObject() = default;
-
- /**
- * @brief Construct a new Singleton Function Object object
- *
- * @param channel
- */
- explicit SingletonFunctionObject(int channel) : ChannelObject(channel) {}
-
- /**
- * @brief Destroy the Singleton Function Object object
- *
- */
- virtual ~SingletonFunctionObject() = default;
-};
-} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H
diff --git a/src/core/GpgGenKeyInfo.cpp b/src/core/GpgGenKeyInfo.cpp
deleted file mode 100644
index 290c93c2..00000000
--- a/src/core/GpgGenKeyInfo.cpp
+++ /dev/null
@@ -1,284 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#include "core/GpgGenKeyInfo.h"
-
-#include <algorithm>
-#include <boost/date_time/gregorian/greg_date.hpp>
-#include <boost/date_time/gregorian/greg_duration.hpp>
-#include <boost/date_time/gregorian/gregorian_types.hpp>
-#include <cassert>
-#include <string>
-#include <vector>
-
-void GpgFrontend::GenKeyInfo::SetAlgo(
- const GpgFrontend::GenKeyInfo::KeyGenAlgo &m_algo) {
- SPDLOG_DEBUG("set algo name: {}", m_algo.first);
- // Check algo if supported
- std::string algo_args = m_algo.second;
- if (standalone_) {
- if (!subkey_) {
- auto support_algo = GetSupportedKeyAlgoStandalone();
- auto it = std::find_if(
- support_algo.begin(), support_algo.end(),
- [=](const KeyGenAlgo &o) { return o.second == algo_args; });
- // Algo Not Supported
- if (it == support_algo.end()) return;
- } else {
- auto support_algo = GetSupportedSubkeyAlgoStandalone();
- auto it = std::find_if(
- support_algo.begin(), support_algo.end(),
- [=](const KeyGenAlgo &o) { return o.second == algo_args; });
- // Algo Not Supported
- if (it == support_algo.end()) return;
- }
- } else {
- if (!subkey_) {
- auto support_algo = GetSupportedKeyAlgo();
- auto it = std::find_if(
- support_algo.begin(), support_algo.end(),
- [=](const KeyGenAlgo &o) { return o.second == algo_args; });
- // Algo Not Supported
- if (it == support_algo.end()) return;
- } else {
- auto support_algo = GetSupportedSubkeyAlgo();
- auto it = std::find_if(
- support_algo.begin(), support_algo.end(),
- [=](const KeyGenAlgo &o) { return o.second == algo_args; });
- // Algo Not Supported
- if (it == support_algo.end()) return;
- }
- }
-
- // reset all options
- reset_options();
-
- if (!this->subkey_) {
- this->SetAllowCertification(true);
- } else {
- this->SetAllowCertification(false);
- }
-
- this->allow_change_certification_ = false;
-
- if (!standalone_) boost::algorithm::to_lower(algo_args);
-
- if (algo_args == "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.
- */
- suggest_min_key_size_ = 1024;
- suggest_max_key_size_ = 4096;
- suggest_size_addition_step_ = 1024;
- SetKeyLength(2048);
-
- } else if (algo_args == "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);
- allow_change_encryption_ = false;
-
- suggest_min_key_size_ = 1024;
- suggest_max_key_size_ = 3072;
- suggest_size_addition_step_ = 1024;
- SetKeyLength(2048);
-
- } else if (algo_args == "ed25519") {
- /**
- * GnuPG supports the Elgamal asymmetric encryption algorithm in key lengths
- * ranging from 1024 to 4096 bits.
- */
- SetAllowEncryption(false);
- allow_change_encryption_ = false;
-
- suggest_min_key_size_ = -1;
- suggest_max_key_size_ = -1;
- suggest_size_addition_step_ = -1;
- SetKeyLength(-1);
- } else if (algo_args == "cv25519") {
- SetAllowAuthentication(false);
- allow_change_authentication_ = false;
-
- SetAllowSigning(false);
- allow_change_signing_ = false;
-
- SetAllowCertification(false);
- allow_change_certification_ = false;
-
- suggest_min_key_size_ = 1024;
- suggest_max_key_size_ = 4096;
- suggest_size_addition_step_ = 1024;
- SetKeyLength(2048);
- } else if (algo_args == "nistp256" || algo_args == "nistp384" ||
- algo_args == "nistp521") {
- SetAllowAuthentication(false);
- allow_change_authentication_ = false;
-
- SetAllowSigning(false);
- allow_change_signing_ = false;
-
- SetAllowCertification(false);
- allow_change_certification_ = false;
-
- suggest_min_key_size_ = -1;
- suggest_max_key_size_ = -1;
- suggest_size_addition_step_ = -1;
- SetKeyLength(-1);
- } else if (algo_args == "brainpoolp256r1") {
- SetAllowAuthentication(false);
- allow_change_authentication_ = false;
-
- SetAllowSigning(false);
- allow_change_signing_ = false;
-
- SetAllowCertification(false);
- allow_change_certification_ = false;
-
- suggest_min_key_size_ = -1;
- suggest_max_key_size_ = -1;
- suggest_size_addition_step_ = -1;
- SetKeyLength(-1);
- }
-
- this->algo_ = algo_args;
-}
-
-void GpgFrontend::GenKeyInfo::reset_options() {
- allow_change_encryption_ = true;
- SetAllowEncryption(true);
-
- allow_change_certification_ = true;
- SetAllowCertification(true);
-
- allow_change_signing_ = true;
- SetAllowSigning(true);
-
- allow_change_authentication_ = true;
- SetAllowAuthentication(true);
-
- passphrase_.clear();
-}
-
-std::string GpgFrontend::GenKeyInfo::GetKeySizeStr() const {
- if (key_size_ > 0) {
- return std::to_string(key_size_);
- } else {
- return {};
- }
-}
-
-void GpgFrontend::GenKeyInfo::SetKeyLength(int m_key_size) {
- if (m_key_size < suggest_min_key_size_ ||
- m_key_size > suggest_max_key_size_) {
- return;
- }
- GenKeyInfo::key_size_ = m_key_size;
-}
-
-void GpgFrontend::GenKeyInfo::SetExpireTime(
- const boost::posix_time::ptime &m_expired) {
- using namespace boost::gregorian;
- if (!IsNonExpired()) {
- GenKeyInfo::expired_ = m_expired;
- }
-}
-
-void GpgFrontend::GenKeyInfo::SetNonExpired(bool m_non_expired) {
- using namespace boost::posix_time;
- if (!m_non_expired) this->expired_ = from_time_t(0);
- GenKeyInfo::non_expired_ = m_non_expired;
-}
-
-void GpgFrontend::GenKeyInfo::SetAllowEncryption(bool m_allow_encryption) {
- if (allow_change_encryption_)
- GenKeyInfo::allow_encryption_ = m_allow_encryption;
-}
-
-void GpgFrontend::GenKeyInfo::SetAllowCertification(
- bool m_allow_certification) {
- if (allow_change_certification_)
- GenKeyInfo::allow_certification_ = m_allow_certification;
-}
-
-GpgFrontend::GenKeyInfo::GenKeyInfo(bool m_is_sub_key, bool m_standalone)
- : standalone_(m_standalone), subkey_(m_is_sub_key) {
- assert(GetSupportedKeyAlgo().size() > 0);
- SetAlgo(GetSupportedKeyAlgo()[0]);
-}
-
-const std::vector<GpgFrontend::GenKeyInfo::KeyGenAlgo>
- &GpgFrontend::GenKeyInfo::GetSupportedKeyAlgo() {
- static const std::vector<GpgFrontend::GenKeyInfo::KeyGenAlgo>
- support_key_algo = {
- {"RSA", "RSA"},
- {"DSA", "DSA"},
- {"ECDSA", "ED25519"},
- };
- return support_key_algo;
-}
-
-const std::vector<GpgFrontend::GenKeyInfo::KeyGenAlgo>
- &GpgFrontend::GenKeyInfo::GetSupportedSubkeyAlgo() {
- static const std::vector<GpgFrontend::GenKeyInfo::KeyGenAlgo>
- support_subkey_algo = {
- {"RSA", "RSA"},
- {"DSA", "DSA"},
- {"ECDSA", "ED25519"},
- {"ECDH NIST P-256", "NISTP256"},
- {"ECDH NIST P-384", "NISTP384"},
- {"ECDH NIST P-521", "NISTP521"},
- // {"ECDH BrainPool P-256", "BRAINPOOlP256R1"}
- };
- return support_subkey_algo;
-}
-
-const std::vector<GpgFrontend::GenKeyInfo::KeyGenAlgo>
- &GpgFrontend::GenKeyInfo::GetSupportedKeyAlgoStandalone() {
- static const std::vector<GpgFrontend::GenKeyInfo::KeyGenAlgo>
- support_subkey_algo_standalone = {
- {"RSA", "RSA"},
- {"DSA", "DSA"},
- };
- return support_subkey_algo_standalone;
-}
-
-const std::vector<GpgFrontend::GenKeyInfo::KeyGenAlgo>
- &GpgFrontend::GenKeyInfo::GetSupportedSubkeyAlgoStandalone() {
- static const std::vector<GpgFrontend::GenKeyInfo::KeyGenAlgo>
- support_subkey_algo_standalone = {
- {"RSA", "RSA"},
- {"DSA", "DSA"},
- };
- return support_subkey_algo_standalone;
-}
diff --git a/src/core/GpgInfo.h b/src/core/GpgInfo.h
deleted file mode 100644
index f4415af1..00000000
--- a/src/core/GpgInfo.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#ifndef GPGFRONTEND_ZH_CN_TS_GPGINFO_H
-#define GPGFRONTEND_ZH_CN_TS_GPGINFO_H
-
-#include <mutex>
-#include <string>
-
-namespace GpgFrontend {
-/**
- * @brief Use to record some info about gnupg
- *
- */
-class GpgInfo {
- public:
- std::string GnupgVersion; ///< version of gnupg
- std::string GpgMEVersion; ///<
-
- std::string AppPath; ///< executable binary path of gnupg
- std::string DatabasePath; ///< key database path
- std::string GpgConfPath; ///< executable binary path of gpgconf
- std::string AssuanPath; ///< executable binary path of assuan
- std::string CMSPath; ///< executable binary path of cms
- std::string GpgAgentPath; ///< executable binary path of gpg-agent
- std::string DirmngrPath; ///< executable binary path of dirmgr
- std::string KeyboxdPath; ///< executable binary path of keyboxd
-
- std::string GnuPGHomePath; ///< value of ---homedir
-
- std::map<std::string, std::vector<std::string>> ComponentsInfo; ///<
- std::map<std::string, std::vector<std::string>> ConfigurationsInfo; ///<
- std::map<std::string, std::vector<std::string>> OptionsInfo; ///<
- std::map<std::string, std::vector<std::string>> AvailableOptionsInfo; ///<
-
- std::shared_mutex Lock;
-};
-} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ZH_CN_TS_GPGINFO_H
diff --git a/src/core/GpgModel.h b/src/core/GpgModel.h
index d8d4e6fe..72574988 100644
--- a/src/core/GpgModel.h
+++ b/src/core/GpgModel.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,38 +20,20 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_ZH_CN_TS_GPGMODEL_H
-#define GPGFRONTEND_ZH_CN_TS_GPGMODEL_H
+#pragma once
-#include "core/GpgConstants.h"
+//
+#include "core/typedef/GpgTypedef.h"
+
+//
#include "core/model/GpgData.h"
#include "core/model/GpgKey.h"
#include "core/model/GpgSignature.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>; ///<
-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
+// namespace GpgFrontend
diff --git a/src/core/common/CoreCommonUtil.cpp b/src/core/common/CoreCommonUtil.cpp
deleted file mode 100644
index 93cad60a..00000000
--- a/src/core/common/CoreCommonUtil.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
- *
- */
-
-#include "CoreCommonUtil.h"
-
-#include <string>
-
-namespace GpgFrontend {
-
-std::unique_ptr<CoreCommonUtil> CoreCommonUtil::instance_ = nullptr; ///<
-
-CoreCommonUtil* CoreCommonUtil::GetInstance() {
- if (instance_ == nullptr) {
- instance_ = std::make_unique<CoreCommonUtil>();
- }
- return instance_.get();
-}
-
-void CoreCommonUtil::SetTempCacheValue(const std::string& key,
- const std::string& value) {
- temp_cache_[key] = value;
-}
-
-std::string CoreCommonUtil::GetTempCacheValue(const std::string& key) {
- std::string temp_cache_value;
- std::swap(temp_cache_value, temp_cache_[key]);
- return temp_cache_value;
-}
-
-void CoreCommonUtil::ResetTempCacheValue(const std::string& key) {
- std::string temp_cache_value;
- std::swap(temp_cache_value, temp_cache_[key]);
-}
-
-} // namespace GpgFrontend
diff --git a/src/core/common/CoreCommonUtil.h b/src/core/common/CoreCommonUtil.h
deleted file mode 100644
index 58bb4d40..00000000
--- a/src/core/common/CoreCommonUtil.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
- *
- */
-
-#ifndef GPGFRONTEND_CORECOMMONUTIL_H
-#define GPGFRONTEND_CORECOMMONUTIL_H
-
-#include <string>
-
-#include "core/GpgFrontendCore.h"
-
-namespace GpgFrontend {
-
-class GPGFRONTEND_CORE_EXPORT CoreCommonUtil : public QObject {
- Q_OBJECT
- public:
- /**
- * @brief Construct a new Core Common Util object
- *
- */
- static CoreCommonUtil *GetInstance();
-
- /**
- * @brief
- *
- */
- CoreCommonUtil() = default;
-
- /**
- * @brief set a temp cache under a certain key
- *
- */
- void SetTempCacheValue(const std::string &, const std::string &);
-
- /**
- * @brief after get the temp cache, its value will be imediately ease in
- * storage
- *
- * @return std::string
- */
- std::string GetTempCacheValue(const std::string &);
-
- /**
- * @brief imediately ease temp cache in storage
- *
- * @return std::string
- */
- void ResetTempCacheValue(const std::string &);
-
- signals:
-
- /**
- * @brief
- *
- */
- void SignalGnupgNotInstall();
-
- private:
- static std::unique_ptr<CoreCommonUtil> instance_; ///<
- std::map<std::string, std::string> temp_cache_; //<
-};
-
-} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_CORECOMMONUTIL_H
diff --git a/src/core/function/ArchiveFileOperator.cpp b/src/core/function/ArchiveFileOperator.cpp
index 8aad0500..a4b90698 100644
--- a/src/core/function/ArchiveFileOperator.cpp
+++ b/src/core/function/ArchiveFileOperator.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,7 +28,15 @@
#include "ArchiveFileOperator.h"
-int copy_data(struct archive *ar, struct archive *aw) {
+#include <archive.h>
+#include <archive_entry.h>
+#include <sys/fcntl.h>
+
+#include "core/utils/AsyncUtils.h"
+
+namespace GpgFrontend {
+
+auto CopyData(struct archive *ar, struct archive *aw) -> int {
int r;
const void *buff;
size_t size;
@@ -38,231 +46,217 @@ int copy_data(struct archive *ar, struct archive *aw) {
r = archive_read_data_block(ar, &buff, &size, &offset);
if (r == ARCHIVE_EOF) return (ARCHIVE_OK);
if (r != ARCHIVE_OK) {
- SPDLOG_ERROR("archive_read_data_block() failed: {}",
- archive_error_string(ar));
+ GF_CORE_LOG_ERROR("archive_read_data_block() failed: {}",
+ archive_error_string(ar));
return (r);
}
r = archive_write_data_block(aw, buff, size, offset);
if (r != ARCHIVE_OK) {
- SPDLOG_ERROR("archive_write_data_block() failed: {}",
- archive_error_string(aw));
+ GF_CORE_LOG_ERROR("archive_write_data_block() failed: {}",
+ archive_error_string(aw));
return (r);
}
}
}
-void GpgFrontend::ArchiveFileOperator::CreateArchive(
- const std::filesystem::path &base_path,
- const std::filesystem::path &archive_path, int compress,
- const std::vector<std::filesystem::path> &files) {
- SPDLOG_DEBUG("CreateArchive: {}", archive_path.u8string());
-
- auto current_base_path_backup = QDir::currentPath();
- QDir::setCurrent(base_path.u8string().c_str());
-
- auto relative_archive_path =
- std::filesystem::relative(archive_path, base_path);
-
- std::vector<std::filesystem::path> relative_files;
- relative_files.reserve(files.size());
- for (const auto &file : files) {
- relative_files.push_back(std::filesystem::relative(file, base_path));
- }
-
- struct archive *a;
- struct archive_entry *entry;
- ssize_t len;
- int fd;
-
- SPDLOG_DEBUG("compress: {}", compress);
-
- a = archive_write_new();
- switch (compress) {
-#ifndef NO_BZIP2_CREATE
- case 'j':
- case 'y':
- archive_write_add_filter_bzip2(a);
- break;
-#endif
-#ifndef NO_COMPRESS_CREATE
- case 'Z':
- archive_write_add_filter_compress(a);
- break;
-#endif
-#ifndef NO_GZIP_CREATE
- case 'z':
- archive_write_add_filter_gzip(a);
- break;
-#endif
- default:
- archive_write_add_filter_none(a);
- break;
- }
- archive_write_set_format_ustar(a);
- archive_write_set_format_pax_restricted(a);
-
- auto u8_filename = relative_archive_path.u8string();
-
- if (!u8_filename.empty() && u8_filename == u8"-")
- throw std::runtime_error("cannot write to stdout");
-
-#ifdef WINDOWS
- archive_write_open_filename_w(a, relative_archive_path.wstring().c_str());
-#else
- archive_write_open_filename(a, u8_filename.c_str());
-#endif
-
- for (const auto &file : relative_files) {
- struct archive *disk = archive_read_disk_new();
-#ifndef NO_LOOKUP
- archive_read_disk_set_standard_lookup(disk);
-#endif
- int r;
-
- SPDLOG_DEBUG("reading file: {}", file.u8string());
-
-#ifdef WINDOWS
- r = archive_read_disk_open_w(disk, file.wstring().c_str());
-#else
- r = archive_read_disk_open(disk, file.u8string().c_str());
-#endif
-
- SPDLOG_DEBUG("read file done: {}", file.u8string());
-
- if (r != ARCHIVE_OK) {
- SPDLOG_ERROR("{archive_read_disk_open() failed: {}",
- archive_error_string(disk));
- throw std::runtime_error("archive_read_disk_open() failed");
- }
+struct ArchiveReadClientData {
+ GFDataExchanger *ex;
+ std::array<std::byte, 1024> buf;
+ const std::byte *p_buf = buf.data();
+};
+
+auto ArchiveReadCallback(struct archive *, void *client_data,
+ const void **buffer) -> ssize_t {
+ auto *rdata = static_cast<ArchiveReadClientData *>(client_data);
+ *buffer = reinterpret_cast<const void *>(rdata->p_buf);
+ return rdata->ex->Read(rdata->buf.data(), rdata->buf.size());
+}
- for (;;) {
- entry = archive_entry_new();
- r = archive_read_next_header2(disk, entry);
-
- if (r == ARCHIVE_EOF) break;
- if (r != ARCHIVE_OK) {
- SPDLOG_ERROR("archive_read_next_header2() failed: {}",
- archive_error_string(disk));
- throw std::runtime_error("archive_read_next_header2() failed");
- }
- archive_read_disk_descend(disk);
-
- SPDLOG_DEBUG("Adding: {} size: {} bytes: {} file type: {}",
- archive_entry_pathname_utf8(entry),
- archive_entry_size(entry), archive_entry_filetype(entry));
-
- r = archive_write_header(a, entry);
- if (r < ARCHIVE_OK) {
- SPDLOG_ERROR("archive_write_header() failed: {}",
- archive_error_string(a));
- throw std::runtime_error("archive_write_header() failed");
- }
- if (r == ARCHIVE_FATAL) throw std::runtime_error("archive fatal");
- if (r > ARCHIVE_FAILED) {
- QByteArray buff;
-#ifdef WINDOWS
- FileOperator::ReadFile(
- QString::fromStdWString(archive_entry_sourcepath_w(entry)), buff);
-#else
- FileOperator::ReadFile(archive_entry_sourcepath(entry), buff);
-#endif
- archive_write_data(a, buff.data(), buff.size());
- }
- archive_entry_free(entry);
- }
- archive_read_close(disk);
- archive_read_free(disk);
- }
- archive_write_close(a);
- archive_write_free(a);
+auto ArchiveWriteCallback(struct archive *, void *client_data,
+ const void *buffer, size_t length) -> ssize_t {
+ auto *ex = static_cast<GFDataExchanger *>(client_data);
+ return ex->Write(static_cast<const std::byte *>(buffer), length);
+}
- QDir::setCurrent(current_base_path_backup);
+auto ArchiveCloseWriteCallback(struct archive *, void *client_data) -> int {
+ auto *ex = static_cast<GFDataExchanger *>(client_data);
+ ex->CloseWrite();
+ return 0;
}
-void GpgFrontend::ArchiveFileOperator::ExtractArchive(
- const std::filesystem::path &archive_path,
- const std::filesystem::path &base_path) {
- SPDLOG_DEBUG("ExtractArchive: {}", archive_path.u8string());
+void ArchiveFileOperator::NewArchive2DataExchanger(
+ const QString &target_directory, std::shared_ptr<GFDataExchanger> exchanger,
+ const OperationCallback &cb) {
+ RunIOOperaAsync(
+ [=](const DataObjectPtr &data_object) -> GFError {
+ std::array<char, 1024> buff{};
+ auto ret = 0;
+ const auto base_path = QDir(QDir(target_directory).absolutePath());
- auto current_base_path_backup = QDir::currentPath();
- QDir::setCurrent(base_path.u8string().c_str());
+ auto *archive = archive_write_new();
+ archive_write_add_filter_none(archive);
+ archive_write_set_format_pax_restricted(archive);
- struct archive *a;
- struct archive *ext;
- struct archive_entry *entry;
+ archive_write_open(archive, exchanger.get(), nullptr,
+ ArchiveWriteCallback, ArchiveCloseWriteCallback);
- a = archive_read_new();
- ext = archive_write_disk_new();
- archive_write_disk_set_options(ext, 0);
-#ifndef NO_BZIP2_EXTRACT
- archive_read_support_filter_bzip2(a);
-#endif
-#ifndef NO_GZIP_EXTRACT
- archive_read_support_filter_gzip(a);
-#endif
-#ifndef NO_COMPRESS_EXTRACT
- archive_read_support_filter_compress(a);
-#endif
-#ifndef NO_TAR_EXTRACT
- archive_read_support_format_tar(a);
-#endif
-#ifndef NO_CPIO_EXTRACT
- archive_read_support_format_cpio(a);
-#endif
-#ifndef NO_LOOKUP
- archive_write_disk_set_standard_lookup(ext);
-#endif
+ auto *disk = archive_read_disk_new();
+ archive_read_disk_set_standard_lookup(disk);
- auto filename = archive_path.u8string();
-
- if (!filename.empty() && filename == u8"-") {
- SPDLOG_ERROR("cannot read from stdin");
- }
#ifdef WINDOWS
- if (archive_read_open_filename_w(a, archive_path.wstring().c_str(), 10240) !=
- ARCHIVE_OK) {
+ auto r = archive_read_disk_open_w(
+ disk, target_directory.toStdWString().c_str());
#else
- if (archive_read_open_filename(a, archive_path.u8string().c_str(), 10240) !=
- ARCHIVE_OK) {
+ auto r = archive_read_disk_open(disk, target_directory.toUtf8());
#endif
- SPDLOG_ERROR("archive_read_open_filename() failed: {}",
- archive_error_string(a));
- throw std::runtime_error("archive_read_open_filename() failed");
- }
-
- for (;;) {
- int r = archive_read_next_header(a, &entry);
- if (r == ARCHIVE_EOF) break;
- if (r != ARCHIVE_OK) {
- SPDLOG_ERROR("archive_read_next_header() failed: {}",
- archive_error_string(a));
- throw std::runtime_error("archive_read_next_header() failed");
- }
- SPDLOG_DEBUG("Adding: {} size: {} bytes: {} file type: {}",
- archive_entry_pathname_utf8(entry), archive_entry_size(entry),
- archive_entry_filetype(entry));
- r = archive_write_header(ext, entry);
- if (r != ARCHIVE_OK) {
- SPDLOG_ERROR("archive_write_header() failed: {}",
- archive_error_string(ext));
- } else {
- r = copy_data(a, ext);
- if (r != ARCHIVE_OK) {
- SPDLOG_ERROR("copy_data() failed: {}", archive_error_string(ext));
- }
- }
- }
- archive_read_close(a);
- archive_read_free(a);
- archive_write_close(ext);
- archive_write_free(ext);
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR("archive_read_disk_open() failed: {}, abort...",
+ archive_error_string(disk));
+ archive_read_free(disk);
+ archive_write_free(archive);
+ return -1;
+ }
+
+ for (;;) {
+ auto *entry = archive_entry_new();
+ r = archive_read_next_header2(disk, entry);
+ if (r == ARCHIVE_EOF) break;
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR(
+ "archive_read_next_header2() failed, ret: {}, explain: {}", r,
+ archive_error_string(disk));
+ ret = -1;
+ break;
+ }
+
+ archive_read_disk_descend(disk);
+
+ // turn absolute path to relative path
+ archive_entry_set_pathname(
+ entry,
+ base_path.relativeFilePath(QString(archive_entry_pathname(entry)))
+ .toUtf8());
+
+ r = archive_write_header(archive, entry);
+ if (r < ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR(
+ "archive_write_header() failed, ret: {}, explain: {} ", r,
+ archive_error_string(archive));
+ continue;
+ }
+
+ if (r == ARCHIVE_FATAL) {
+ GF_CORE_LOG_ERROR(
+ "archive_write_header() failed, ret: {}, explain: {}, "
+ "abort ...",
+ r, archive_error_string(archive));
+ ret = -1;
+ break;
+ }
+
+ if (r > ARCHIVE_FAILED) {
+ auto fd = open(archive_entry_sourcepath(entry), O_RDONLY);
+ auto len = read(fd, buff.data(), buff.size());
+ while (len > 0) {
+ archive_write_data(archive, buff.data(), len);
+ len = read(fd, buff.data(), buff.size());
+ }
+ close(fd);
+ }
+ archive_entry_free(entry);
+ }
+
+ archive_read_free(disk);
+ archive_write_free(archive);
+ return ret;
+ },
+ cb, "archive_write_new");
+}
- QDir::setCurrent(current_base_path_backup);
+void ArchiveFileOperator::ExtractArchiveFromDataExchanger(
+ std::shared_ptr<GFDataExchanger> ex, const QString &target_path,
+ const OperationCallback &cb) {
+ RunIOOperaAsync(
+ [=](const DataObjectPtr &data_object) -> GFError {
+ auto *archive = archive_read_new();
+ auto *ext = archive_write_disk_new();
+
+ auto r = archive_read_support_filter_all(archive);
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR(
+ "archive_read_support_filter_all(), ret: {}, reason: {}", r,
+ archive_error_string(archive));
+ return r;
+ }
+
+ r = archive_read_support_format_all(archive);
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR(
+ "archive_read_support_format_all(), ret: {}, reason: {}", r,
+ archive_error_string(archive));
+ return r;
+ }
+
+ auto rdata = ArchiveReadClientData{};
+ rdata.ex = ex.get();
+
+ r = archive_read_open(archive, &rdata, nullptr, ArchiveReadCallback,
+ nullptr);
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR("archive_read_open(), ret: {}, reason: {}", r,
+ archive_error_string(archive));
+ return r;
+ }
+
+ r = archive_write_disk_set_options(ext, 0);
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR(
+ "archive_write_disk_set_options(), ret: {}, reason: {}", r,
+ archive_error_string(archive));
+ return r;
+ }
+
+ for (;;) {
+ struct archive_entry *entry;
+ r = archive_read_next_header(archive, &entry);
+ if (r == ARCHIVE_EOF) break;
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR("archive_read_next_header(), ret: {}, reason: {}",
+ r, archive_error_string(archive));
+ break;
+ }
+
+ archive_entry_set_pathname(
+ entry,
+ (target_path + "/" + archive_entry_pathname(entry)).toUtf8());
+
+ r = archive_write_header(ext, entry);
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR("archive_write_header(), ret: {}, reason: {}", r,
+ archive_error_string(archive));
+ } else {
+ r = CopyData(archive, ext);
+ }
+ }
+
+ r = archive_read_free(archive);
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR("archive_read_free(), ret: {}, reason: {}", r,
+ archive_error_string(archive));
+ }
+ r = archive_write_free(ext);
+ if (r != ARCHIVE_OK) {
+ GF_CORE_LOG_ERROR("archive_read_free(), ret: {}, reason: {}", r,
+ archive_error_string(archive));
+ }
+
+ return 0;
+ },
+ cb, "archive_read_new");
}
-void GpgFrontend::ArchiveFileOperator::ListArchive(
- const std::filesystem::path &archive_path) {
+void ArchiveFileOperator::ListArchive(const QString &archive_path) {
struct archive *a;
struct archive_entry *entry;
int r;
@@ -270,14 +264,16 @@ void GpgFrontend::ArchiveFileOperator::ListArchive(
a = archive_read_new();
archive_read_support_filter_all(a);
archive_read_support_format_all(a);
- r = archive_read_open_filename(a, archive_path.u8string().c_str(),
+ r = archive_read_open_filename(a, archive_path.toUtf8(),
10240); // Note 1
if (r != ARCHIVE_OK) return;
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
- SPDLOG_DEBUG("File: {}", archive_entry_pathname(entry));
- SPDLOG_DEBUG("File Path: {}", archive_entry_pathname(entry));
+ GF_CORE_LOG_DEBUG("File: {}", archive_entry_pathname(entry));
+ GF_CORE_LOG_DEBUG("File Path: {}", archive_entry_pathname(entry));
archive_read_data_skip(a); // Note 2
}
r = archive_read_free(a); // Note 3
if (r != ARCHIVE_OK) return;
}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/ArchiveFileOperator.h b/src/core/function/ArchiveFileOperator.h
index 4db5af5f..bfeec0c4 100644
--- a/src/core/function/ArchiveFileOperator.h
+++ b/src/core/function/ArchiveFileOperator.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,40 +20,50 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_ARCHIVEFILEOPERATOR_H
-#define GPGFRONTEND_ARCHIVEFILEOPERATOR_H
+#pragma once
#include "core/GpgFrontendCore.h"
-#include "core/function/FileOperator.h"
+#include "core/model/GFDataExchanger.h"
+#include "core/typedef/CoreTypedef.h"
+#include "core/utils/IOUtils.h"
namespace GpgFrontend {
-struct ArchiveStruct {
- struct archive *archive;
- struct archive_entry *entry;
- int fd;
- bool is_open;
- std::string name;
-};
-
class GPGFRONTEND_CORE_EXPORT ArchiveFileOperator {
public:
- static void ListArchive(const std::filesystem::path &archive_path);
+ /**
+ * @brief
+ *
+ * @param archive_path
+ */
+ static void ListArchive(const QString &archive_path);
- static void CreateArchive(const std::filesystem::path &base_path,
- const std::filesystem::path &archive_path,
- int compress,
- const std::vector<std::filesystem::path> &files);
+ /**
+ * @brief Create a Archive object
+ *
+ * @param base_path
+ * @param archive_path
+ * @param compress
+ * @param files
+ */
+ static void NewArchive2DataExchanger(const QString &target_directory,
+ std::shared_ptr<GFDataExchanger>,
+ const OperationCallback &cb);
- static void ExtractArchive(const std::filesystem::path &archive_path,
- const std::filesystem::path &base_path);
+ /**
+ * @brief
+ *
+ * @param archive_path
+ * @param base_path
+ */
+ static void ExtractArchiveFromDataExchanger(
+ std::shared_ptr<GFDataExchanger> fd, const QString &target_path,
+ const OperationCallback &cb);
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ARCHIVEFILEOPERATOR_H
diff --git a/src/core/function/CacheManager.cpp b/src/core/function/CacheManager.cpp
index d9aead66..719c962d 100644
--- a/src/core/function/CacheManager.cpp
+++ b/src/core/function/CacheManager.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -29,119 +29,256 @@
#include "CacheManager.h"
#include <algorithm>
-#include <boost/format.hpp>
-#include <string>
+#include <shared_mutex>
+#include <utility>
-#include "function/DataObjectOperator.h"
-#include "spdlog/spdlog.h"
+#include "core/function/DataObjectOperator.h"
+#include "core/utils/MemoryUtils.h"
-GpgFrontend::CacheManager::CacheManager(int channel)
- : m_timer_(new QTimer(this)),
- SingletonFunctionObject<CacheManager>(channel) {
- connect(m_timer_, &QTimer::timeout, this, &CacheManager::flush_cache_storage);
- m_timer_->start(15000);
+namespace GpgFrontend {
- load_all_cache_storage();
-}
+template <typename Key, typename Value>
+class ThreadSafeMap {
+ public:
+ using MapType = std::map<Key, Value>;
+ using IteratorType = typename MapType::iterator;
-void GpgFrontend::CacheManager::SaveCache(std::string key,
- const nlohmann::json& value,
- bool flush) {
- auto data_object_key = get_data_object_key(key);
- cache_storage_.insert(key, value);
+ void insert(const Key& key, const Value& value) {
+ std::unique_lock lock(mutex_);
+ (*map_)[key] = value;
+ }
- if (std::find(key_storage_.begin(), key_storage_.end(), key) ==
- key_storage_.end()) {
- SPDLOG_DEBUG("register new key of cache", key);
- key_storage_.push_back(key);
+ auto get(const Key& key) -> std::optional<Value> {
+ std::shared_lock lock(mutex_);
+ auto it = map_->find(key);
+ if (it != map_->end()) {
+ return it->second;
+ }
+ return std::nullopt;
}
- if (flush) {
- flush_cache_storage();
+ auto exists(const Key& key) -> bool {
+ std::shared_lock lock(mutex_);
+ return map_->count(key) > 0;
}
-}
-nlohmann::json GpgFrontend::CacheManager::LoadCache(std::string key) {
- auto data_object_key = get_data_object_key(key);
+ auto begin() -> IteratorType { return map_mirror_->begin(); }
+
+ auto end() -> IteratorType { return map_mirror_->end(); }
- if (!cache_storage_.exists(key)) {
- cache_storage_.insert(key, load_cache_storage(key, {}));
+ auto mirror() -> ThreadSafeMap& {
+ std::shared_lock lock(mutex_);
+ *map_mirror_ = *map_;
+ return *this;
}
- auto cache = cache_storage_.get(key);
- if (cache)
- return *cache;
- else
- return {};
-}
+ auto remove(QString key) -> bool {
+ std::unique_lock lock(mutex_);
+ auto it = map_->find(key);
+ if (it != map_->end()) {
+ map_->erase(it);
+ return true;
+ }
+ return false;
+ }
-nlohmann::json GpgFrontend::CacheManager::LoadCache(
- std::string key, nlohmann::json default_value) {
- auto data_object_key = get_data_object_key(key);
- if (!cache_storage_.exists(key)) {
- cache_storage_.insert(key, load_cache_storage(key, default_value));
+ private:
+ std::unique_ptr<MapType, SecureObjectDeleter<MapType>> map_mirror_ =
+ std::move(SecureCreateUniqueObject<MapType>());
+ std::unique_ptr<MapType, SecureObjectDeleter<MapType>> map_ =
+ std::move(SecureCreateUniqueObject<MapType>());
+ mutable std::shared_mutex mutex_;
+};
+
+class CacheManager::Impl : public QObject {
+ Q_OBJECT
+ public:
+ Impl() : flush_timer_(new QTimer(this)) {
+ connect(flush_timer_, &QTimer::timeout, this,
+ &Impl::slot_flush_cache_storage);
+ flush_timer_->start(15000);
+
+ // load data from storage
+ load_all_cache_storage();
}
- auto cache = cache_storage_.get(key);
- if (cache)
- return *cache;
- else
- return {};
-}
+ void SaveDurableCache(QString key, const QJsonDocument& value, bool flush) {
+ auto data_object_key = get_data_object_key(key);
+ durable_cache_storage_.insert(key, value);
-std::string GpgFrontend::CacheManager::get_data_object_key(std::string key) {
- return (boost::format("__cache_data_%1%") % key).str();
-}
+ if (!key_storage_.contains(key)) {
+ GF_CORE_LOG_DEBUG("register new key of cache", key);
+ key_storage_.push_back(key);
+ }
-nlohmann::json GpgFrontend::CacheManager::load_cache_storage(
- std::string key, nlohmann::json default_value) {
- auto data_object_key = get_data_object_key(key);
- auto stored_data =
- GpgFrontend::DataObjectOperator::GetInstance().GetDataObject(
- data_object_key);
+ if (flush) slot_flush_cache_storage();
+ }
- if (stored_data.has_value()) {
- return stored_data.value();
- } else {
- return default_value;
+ auto LoadDurableCache(const QString& key) -> QJsonDocument {
+ auto data_object_key = get_data_object_key(key);
+
+ if (!durable_cache_storage_.exists(key)) {
+ durable_cache_storage_.insert(key, load_cache_storage(key, {}));
+ }
+
+ auto cache = durable_cache_storage_.get(key);
+ if (cache.has_value()) return cache.value();
+ return {};
}
-}
-void GpgFrontend::CacheManager::flush_cache_storage() {
- for (auto cache : cache_storage_.mirror()) {
- auto key = get_data_object_key(cache.first);
- SPDLOG_DEBUG("save cache into filesystem, key {}, value size: {}", key,
- cache.second.size());
- GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(key,
- cache.second);
+ auto LoadDurableCache(const QString& key, QJsonDocument default_value)
+ -> QJsonDocument {
+ auto data_object_key = get_data_object_key(key);
+ if (!durable_cache_storage_.exists(key)) {
+ durable_cache_storage_.insert(
+ key, load_cache_storage(key, std::move(default_value)));
+ }
+
+ auto cache = durable_cache_storage_.get(key);
+ if (cache.has_value()) return cache.value();
+ return {};
}
- GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(drk_key_,
- key_storage_);
-}
-void GpgFrontend::CacheManager::register_cache_key(std::string key) {}
+ auto ResetDurableCache(const QString& key) -> bool {
+ auto data_object_key = get_data_object_key(key);
+ return durable_cache_storage_.remove(key);
+ }
+
+ void FlushCacheStorage() { this->slot_flush_cache_storage(); }
-void GpgFrontend::CacheManager::load_all_cache_storage() {
- SPDLOG_DEBUG("start to load all cache from file system");
- auto stored_data =
- GpgFrontend::DataObjectOperator::GetInstance().GetDataObject(drk_key_);
+ void SaveCache(const QString& key, QString value) {
+ runtime_cache_storage_.insert(key, new QString(std::move(value)));
+ }
- // get cache data list from file system
- nlohmann::json registered_key_list;
- if (stored_data.has_value()) {
- registered_key_list = std::move(stored_data.value());
+ auto LoadCache(const QString& key) -> QString {
+ auto* value = runtime_cache_storage_.object(key);
+ if (value == nullptr) return {};
+ return *value;
}
- if (!registered_key_list.is_array()) {
+ void ResetCache(const QString& key) { runtime_cache_storage_.remove(key); }
+
+ private slots:
+
+ /**
+ * @brief
+ *
+ */
+ void slot_flush_cache_storage() {
+ for (const auto& cache : durable_cache_storage_.mirror()) {
+ auto key = get_data_object_key(cache.first);
+ GF_CORE_LOG_TRACE("save cache into filesystem, key {}", key);
+ GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(
+ key, QJsonDocument(cache.second));
+ }
GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(
- drk_key_, nlohmann::json::array());
- SPDLOG_ERROR("drk_key_ is not an array, abort.");
- return;
+ drk_key_, QJsonDocument(key_storage_));
}
- for (auto key : registered_key_list) {
- load_cache_storage(key, {});
+ private:
+ QCache<QString, QString> runtime_cache_storage_;
+ ThreadSafeMap<QString, QJsonDocument> durable_cache_storage_;
+ QJsonArray key_storage_;
+ QTimer* flush_timer_;
+ const QString drk_key_ = "__cache_manage_data_register_key_list";
+
+ /**
+ * @brief Get the data object key object
+ *
+ * @param key
+ * @return QString
+ */
+ static auto get_data_object_key(const QString& key) -> QString {
+ return QString("__cache_data_%1").arg(key);
}
- key_storage_ = registered_key_list;
-} \ No newline at end of file
+ /**
+ * @brief
+ *
+ * @param key
+ * @param default_value
+ * @return QJsonObject
+ */
+ static auto load_cache_storage(const QString& key,
+ QJsonDocument default_value) -> QJsonDocument {
+ auto data_object_key = get_data_object_key(key);
+ auto stored_data =
+ GpgFrontend::DataObjectOperator::GetInstance().GetDataObject(
+ data_object_key);
+
+ if (stored_data.has_value()) return stored_data.value();
+ return default_value;
+ }
+
+ /**
+ * @brief
+ *
+ */
+ void load_all_cache_storage() {
+ GF_CORE_LOG_DEBUG("start to load all cache from file system");
+ auto stored_data =
+ GpgFrontend::DataObjectOperator::GetInstance().GetDataObject(drk_key_);
+
+ // get cache data list from file system
+ QJsonArray registered_key_list;
+ if (stored_data->isArray()) {
+ registered_key_list = stored_data->array();
+ } else {
+ GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(
+ drk_key_, QJsonDocument(QJsonArray()));
+ }
+
+ for (const auto& key : registered_key_list) {
+ load_cache_storage(key.toString(), {});
+ }
+
+ key_storage_ = registered_key_list;
+ }
+
+ /**
+ * @brief
+ *
+ * @param key
+ */
+ void register_cache_key(const QString& key) {}
+};
+
+CacheManager::CacheManager(int channel)
+ : SingletonFunctionObject<CacheManager>(channel),
+ p_(SecureCreateUniqueObject<Impl>()) {}
+
+CacheManager::~CacheManager() { p_->FlushCacheStorage(); }
+
+void CacheManager::SaveDurableCache(const QString& key,
+ const QJsonDocument& value, bool flush) {
+ p_->SaveDurableCache(key, value, flush);
+}
+
+auto CacheManager::LoadDurableCache(const QString& key) -> QJsonDocument {
+ return p_->LoadDurableCache(key);
+}
+
+auto CacheManager::LoadDurableCache(const QString& key,
+ QJsonDocument default_value)
+ -> QJsonDocument {
+ return p_->LoadDurableCache(key, std::move(default_value));
+}
+
+auto CacheManager::ResetDurableCache(const QString& key) -> bool {
+ return p_->ResetDurableCache(key);
+}
+
+void CacheManager::SaveCache(const QString& key, QString value) {
+ p_->SaveCache(key, std::move(value));
+}
+
+auto CacheManager::LoadCache(const QString& key) -> QString {
+ return p_->LoadCache(key);
+}
+
+void CacheManager::ResetCache(const QString& key) {
+ return p_->ResetCache(key);
+}
+} // namespace GpgFrontend
+
+#include "CacheManager.moc" \ No newline at end of file
diff --git a/src/core/function/CacheManager.h b/src/core/function/CacheManager.h
index 8234de2a..67e7fd75 100644
--- a/src/core/function/CacheManager.h
+++ b/src/core/function/CacheManager.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,94 +20,99 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_CACHEMANAGER_H
-#define GPGFRONTEND_CACHEMANAGER_H
+#pragma once
-#include <string>
-
-#include "core/GpgFunctionObject.h"
+#include "core/function/basic/GpgFunctionObject.h"
namespace GpgFrontend {
-template <typename Key, typename Value>
-class ThreadSafeMap {
- public:
- using MapType = std::map<Key, Value>;
- using IteratorType = typename MapType::iterator;
-
- void insert(const Key& key, const Value& value) {
- std::unique_lock lock(mutex_);
- map_[key] = value;
- }
-
- std::optional<Value> get(const Key& key) {
- std::shared_lock lock(mutex_);
- auto it = map_.find(key);
- if (it != map_.end()) {
- return it->second;
- }
- return std::nullopt;
- }
-
- bool exists(const Key& key) {
- std::shared_lock lock(mutex_);
- return map_.count(key) > 0;
- }
-
- IteratorType begin() { return map_mirror_.begin(); }
-
- IteratorType end() { return map_mirror_.end(); }
-
- ThreadSafeMap& mirror() {
- std::shared_lock lock(mutex_);
- map_mirror_ = map_;
- return *this;
- }
-
- private:
- MapType map_mirror_;
- MapType map_;
- mutable std::shared_mutex mutex_;
-};
-
class GPGFRONTEND_CORE_EXPORT CacheManager
- : public QObject,
- public SingletonFunctionObject<CacheManager> {
- Q_OBJECT
+ : public SingletonFunctionObject<CacheManager> {
public:
- CacheManager(int channel = SingletonFunctionObject::GetDefaultChannel());
-
- void SaveCache(std::string key, const nlohmann::json& value,
- bool flush = false);
-
- nlohmann::json LoadCache(std::string key);
-
- nlohmann::json LoadCache(std::string key, nlohmann::json default_value);
+ /**
+ * @brief Construct a new Cache Manager object
+ *
+ * @param channel
+ */
+ explicit CacheManager(
+ int channel = SingletonFunctionObject::GetDefaultChannel());
+
+ /**
+ * @brief Destroy the Cache Manager object
+ *
+ */
+ ~CacheManager() override;
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @param value
+ */
+ void SaveCache(const QString& key, QString value);
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @param value
+ * @param flush
+ */
+ void SaveDurableCache(const QString& key, const QJsonDocument& value,
+ bool flush = false);
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @param value
+ */
+ auto LoadCache(const QString& key) -> QString;
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @return QJsonDocument
+ */
+ auto LoadDurableCache(const QString& key) -> QJsonDocument;
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @param default_value
+ * @return QJsonDocument
+ */
+ auto LoadDurableCache(const QString& key, QJsonDocument default_value)
+ -> QJsonDocument;
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @return auto
+ */
+ void ResetCache(const QString& key);
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @return true
+ * @return false
+ */
+ auto ResetDurableCache(const QString& key) -> bool;
private:
- std::string get_data_object_key(std::string key);
-
- nlohmann::json load_cache_storage(std::string key,
- nlohmann::json default_value);
-
- void load_all_cache_storage();
-
- void flush_cache_storage();
-
- void register_cache_key(std::string key);
-
- ThreadSafeMap<std::string, nlohmann::json> cache_storage_;
- nlohmann::json key_storage_;
- QTimer* m_timer_;
- const std::string drk_key_ = "__cache_manage_data_register_key_list";
+ class Impl;
+ SecureUniquePtr<Impl> p_;
};
} // namespace GpgFrontend
-
-#endif
diff --git a/src/core/function/CharsetOperator.cpp b/src/core/function/CharsetOperator.cpp
deleted file mode 100644
index 72c5e72b..00000000
--- a/src/core/function/CharsetOperator.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#include "core/function/CharsetOperator.h"
-
-#include <spdlog/spdlog.h>
-#include <unicode/ucnv.h>
-#include <unicode/ucsdet.h>
-#include <unicode/ustring.h>
-#include <unicode/utypes.h>
-
-#include <cstddef>
-#include <memory>
-#include <string>
-
-GpgFrontend::CharsetOperator::CharsetInfo GpgFrontend::CharsetOperator::Detect(
- const std::string &buffer) {
- const UCharsetMatch *ucm;
- UErrorCode status = U_ZERO_ERROR;
- UCharsetDetector *csd = ucsdet_open(&status);
-
- status = U_ZERO_ERROR;
- if (U_FAILURE(status)) {
- SPDLOG_ERROR("failed to open charset detector: {}", u_errorName(status));
- return {"unknown", "unknown", 0};
- }
-
- SPDLOG_DEBUG("detecting charset buffer: {} bytes", buffer.size());
-
- status = U_ZERO_ERROR;
- ucsdet_setText(csd, buffer.data(), buffer.size(), &status);
- if (U_FAILURE(status)) {
- SPDLOG_ERROR("failed to set text to charset detector: {}",
- u_errorName(status));
- return {"unknown", "unknown", 0};
- }
-
- status = U_ZERO_ERROR;
- ucm = ucsdet_detect(csd, &status);
-
- if (U_FAILURE(status)) return {"unknown", "unknown", 0};
-
- status = U_ZERO_ERROR;
- const char *name = ucsdet_getName(ucm, &status);
- if (U_FAILURE(status)) return {"unknown", "unknown", 0};
-
- status = U_ZERO_ERROR;
- int confidence = ucsdet_getConfidence(ucm, &status);
- if (U_FAILURE(status)) return {name, "unknown", 0};
-
- status = U_ZERO_ERROR;
- const char *language = ucsdet_getLanguage(ucm, &status);
- if (U_FAILURE(status)) return {name, "unknown", confidence};
-
- SPDLOG_DEBUG("Detected charset: {} {} {}", name, language, confidence);
- return {name, language, confidence};
-}
-
-bool GpgFrontend::CharsetOperator::Convert2Utf8(const std::string &buffer,
- std::string &out_buffer,
- std::string from_charset_name) {
- UErrorCode status = U_ZERO_ERROR;
- const auto from_encode = std::string("utf-8");
- const auto to_encode = from_charset_name;
-
- SPDLOG_DEBUG("Converting buffer: {}", buffer.size());
-
- // test if the charset is supported
- UConverter *conv = ucnv_open(from_encode.c_str(), &status);
- ucnv_close(conv);
- if (U_FAILURE(status)) {
- SPDLOG_ERROR("failed to open converter: {}, from encode: {}",
- u_errorName(status), from_encode);
- return false;
- }
-
- // test if the charset is supported
- conv = ucnv_open(to_encode.c_str(), &status);
- ucnv_close(conv);
- if (U_FAILURE(status)) {
- SPDLOG_ERROR("failed to open converter: {}, to encode: {}",
- u_errorName(status), to_encode);
- return false;
- }
-
- status = U_ZERO_ERROR;
- int32_t target_limit = 0, target_capacity = 0;
-
- target_capacity =
- ucnv_convert(from_encode.c_str(), to_encode.c_str(), nullptr,
- target_limit, buffer.data(), buffer.size(), &status);
-
- if (status == U_BUFFER_OVERFLOW_ERROR) {
- status = U_ZERO_ERROR;
- out_buffer.clear();
- out_buffer.resize(target_capacity);
- ucnv_convert(from_encode.c_str(), to_encode.c_str(), out_buffer.data(),
- out_buffer.size(), buffer.data(), buffer.size(), &status);
- }
-
- if (U_FAILURE(status)) {
- SPDLOG_ERROR("failed to convert to utf-8: {}", u_errorName(status));
- return false;
- }
-
- SPDLOG_DEBUG("converted buffer: {} bytes", out_buffer.size());
- return true;
-} \ No newline at end of file
diff --git a/src/core/function/CoreSignalStation.cpp b/src/core/function/CoreSignalStation.cpp
index f78d417b..8cb84743 100644
--- a/src/core/function/CoreSignalStation.cpp
+++ b/src/core/function/CoreSignalStation.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -29,11 +29,12 @@
#include "core/function/CoreSignalStation.h"
std::unique_ptr<GpgFrontend::CoreSignalStation>
- GpgFrontend::CoreSignalStation::_instance = nullptr;
+ GpgFrontend::CoreSignalStation::instance = nullptr;
-GpgFrontend::CoreSignalStation* GpgFrontend::CoreSignalStation::GetInstance() {
- if (_instance == nullptr) {
- _instance = std::make_unique<CoreSignalStation>();
+auto GpgFrontend::CoreSignalStation::GetInstance()
+ -> GpgFrontend::CoreSignalStation* {
+ if (instance == nullptr) {
+ instance = std::make_unique<CoreSignalStation>();
}
- return _instance.get();
+ return instance.get();
}
diff --git a/src/core/function/CoreSignalStation.h b/src/core/function/CoreSignalStation.h
index 7497cab7..e0a11fa3 100644
--- a/src/core/function/CoreSignalStation.h
+++ b/src/core/function/CoreSignalStation.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,26 +20,27 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_CORESIGNALSTATION_H
-#define GPGFRONTEND_CORESIGNALSTATION_H
+#pragma once
#include "core/GpgFrontendCore.h"
namespace GpgFrontend {
+class GpgPassphraseContext;
+
/**
* @brief
*
*/
class GPGFRONTEND_CORE_EXPORT CoreSignalStation : public QObject {
Q_OBJECT
- static std::unique_ptr<CoreSignalStation> _instance;
+ static std::unique_ptr<CoreSignalStation> instance;
public:
/**
@@ -47,7 +48,7 @@ class GPGFRONTEND_CORE_EXPORT CoreSignalStation : public QObject {
*
* @return SignalStation*
*/
- static CoreSignalStation* GetInstance();
+ static auto GetInstance() -> CoreSignalStation*;
signals:
@@ -55,15 +56,25 @@ class GPGFRONTEND_CORE_EXPORT CoreSignalStation : public QObject {
* @brief
*
*/
- void SignalUserInputPassphraseDone(QString passparase);
+ void SignalNeedUserInputPassphrase(QSharedPointer<GpgPassphraseContext>);
+
+ /**
+ * @brief
+ *
+ */
+ void SignalUserInputPassphraseCallback(QSharedPointer<GpgPassphraseContext>);
/**
* @brief
*
*/
- void SignalNeedUserInputPassphrase();
+ void SignalBadGnupgEnv(QString);
+
+ /**
+ * @brief
+ *
+ */
+ void SignalGoodGnupgEnv();
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_CORESIGNALSTATION_H
diff --git a/src/core/function/DataObjectOperator.cpp b/src/core/function/DataObjectOperator.cpp
index 180cef30..e1d8b4da 100644
--- a/src/core/function/DataObjectOperator.cpp
+++ b/src/core/function/DataObjectOperator.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -30,143 +30,131 @@
#include <qt-aes/qaesencryption.h>
-#include <boost/date_time.hpp>
-
-#include "core/function/FileOperator.h"
#include "core/function/PassphraseGenerator.h"
+#include "core/utils/IOUtils.h"
+
+namespace GpgFrontend {
-void GpgFrontend::DataObjectOperator::init_app_secure_key() {
- SPDLOG_DEBUG("initializing application secure key");
- FileOperator::WriteFileStd(app_secure_key_path_,
- PassphraseGenerator::GetInstance().Generate(256));
- std::filesystem::permissions(
- app_secure_key_path_,
- std::filesystem::perms::owner_read | std::filesystem::perms::owner_write);
+void DataObjectOperator::init_app_secure_key() {
+ GF_CORE_LOG_INFO("initializing application secure key...");
+ WriteFile(app_secure_key_path_,
+ PassphraseGenerator::GetInstance().Generate(256).toUtf8());
+ QFile::setPermissions(app_secure_key_path_,
+ QFileDevice::ReadOwner | QFileDevice::WriteOwner);
}
-GpgFrontend::DataObjectOperator::DataObjectOperator(int channel)
+DataObjectOperator::DataObjectOperator(int channel)
: SingletonFunctionObject<DataObjectOperator>(channel) {
- if (!is_directory(app_secure_path_)) create_directory(app_secure_path_);
-
- if (!exists(app_secure_key_path_)) {
- init_app_secure_key();
+ if (!QDir(app_secure_path_).exists()) QDir(app_secure_path_).mkpath(".");
+ if (!QFileInfo(app_secure_key_path_).exists()) init_app_secure_key();
+
+ QByteArray key;
+ if (!ReadFile(app_secure_key_path_, key)) {
+ GF_CORE_LOG_ERROR("failed to read app secure key file: {}",
+ app_secure_key_path_);
+ // unsafe mode
+ key = {};
}
- std::string key;
- if (!FileOperator::ReadFileStd(app_secure_key_path_.u8string(), key)) {
- SPDLOG_ERROR("failed to read app secure key file: {}",
- app_secure_key_path_.u8string());
- throw std::runtime_error("failed to read app secure key file");
- }
- hash_key_ = QCryptographicHash::hash(QByteArray::fromStdString(key),
- QCryptographicHash::Sha256);
- SPDLOG_DEBUG("app secure key loaded {} bytes", hash_key_.size());
+ hash_key_ = QCryptographicHash::hash(key, QCryptographicHash::Sha256);
- if (!exists(app_data_objs_path_)) create_directory(app_data_objs_path_);
+ if (!QDir(app_data_objs_path_).exists()) {
+ QDir(app_data_objs_path_).mkpath(".");
+ }
}
-std::string GpgFrontend::DataObjectOperator::SaveDataObj(
- const std::string& _key, const nlohmann::json& value) {
- std::string _hash_obj_key = {};
- if (_key.empty()) {
- _hash_obj_key =
+auto DataObjectOperator::SaveDataObj(const QString& key,
+ const QJsonDocument& value) -> QString {
+ QByteArray hash_obj_key = {};
+ if (key.isEmpty()) {
+ hash_obj_key =
QCryptographicHash::hash(
- hash_key_ + QByteArray::fromStdString(
- PassphraseGenerator::GetInstance().Generate(32) +
- to_iso_extended_string(
- boost::posix_time::second_clock::local_time())),
+ hash_key_ +
+ PassphraseGenerator::GetInstance().Generate(32).toUtf8() +
+ QDateTime::currentDateTime().toString().toUtf8(),
QCryptographicHash::Sha256)
- .toHex()
- .toStdString();
+ .toHex();
} else {
- _hash_obj_key =
- QCryptographicHash::hash(hash_key_ + QByteArray::fromStdString(_key),
- QCryptographicHash::Sha256)
- .toHex()
- .toStdString();
+ hash_obj_key = QCryptographicHash::hash(hash_key_ + key.toUtf8(),
+ QCryptographicHash::Sha256)
+ .toHex();
}
- const auto obj_path = app_data_objs_path_ / _hash_obj_key;
-
- QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
- QAESEncryption::Padding::ISO);
- auto encoded =
- encryption.encode(QByteArray::fromStdString(to_string(value)), hash_key_);
-
- SPDLOG_DEBUG("saving data object {} to {} , size: {} bytes", _hash_obj_key,
- obj_path.u8string(), encoded.size());
-
- FileOperator::WriteFileStd(obj_path.u8string(), encoded.toStdString());
+ const auto target_obj_path = app_data_objs_path_ + "/" + hash_obj_key;
+ auto encoded_data =
+ QAESEncryption(QAESEncryption::AES_256, QAESEncryption::ECB,
+ QAESEncryption::Padding::ISO)
+ .encode(value.toJson(), hash_key_);
+ GF_CORE_LOG_TRACE("saving data object {} to disk {} , size: {} bytes",
+ hash_obj_key, target_obj_path, encoded_data.size());
+
+ // recreate if not exists
+ if (!QDir(app_data_objs_path_).exists()) {
+ QDir(app_data_objs_path_).mkpath(".");
+ }
- return _key.empty() ? _hash_obj_key : std::string();
+ if (!WriteFile(target_obj_path, encoded_data)) {
+ GF_CORE_LOG_ERROR("failed to write data object to disk: {}", key);
+ }
+ return key.isEmpty() ? hash_obj_key : QString();
}
-std::optional<nlohmann::json> GpgFrontend::DataObjectOperator::GetDataObject(
- const std::string& _key) {
+auto DataObjectOperator::GetDataObject(const QString& key)
+ -> std::optional<QJsonDocument> {
try {
- SPDLOG_DEBUG("get data object {}", _key);
- auto _hash_obj_key =
- QCryptographicHash::hash(hash_key_ + QByteArray::fromStdString(_key),
- QCryptographicHash::Sha256)
- .toHex()
- .toStdString();
-
- const auto obj_path = app_data_objs_path_ / _hash_obj_key;
-
- if (!std::filesystem::exists(obj_path)) {
- SPDLOG_ERROR("data object not found :{}", _key);
+ GF_CORE_LOG_TRACE("try to get data object from disk, key: {}", key);
+ auto hash_obj_key = QCryptographicHash::hash(hash_key_ + key.toUtf8(),
+ QCryptographicHash::Sha256)
+ .toHex();
+
+ const auto obj_path = app_data_objs_path_ + "/" + hash_obj_key;
+ if (!QFileInfo(obj_path).exists()) {
+ GF_CORE_LOG_WARN("data object not found from disk, key: {}", key);
return {};
}
- std::string buffer;
- if (!FileOperator::ReadFileStd(obj_path.u8string(), buffer)) {
- SPDLOG_ERROR("failed to read data object: {}", _key);
+ QByteArray encoded_data;
+ if (!ReadFile(obj_path, encoded_data)) {
+ GF_CORE_LOG_ERROR("failed to read data object from disk, key: {}", key);
return {};
}
- SPDLOG_DEBUG("data object found {}", _key);
-
- auto encoded = QByteArray::fromStdString(buffer);
QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
QAESEncryption::Padding::ISO);
- SPDLOG_DEBUG("decrypting data object {} , hash key size: {}",
- encoded.size(), hash_key_.size());
-
- auto decoded =
- encryption.removePadding(encryption.decode(encoded, hash_key_));
-
- SPDLOG_DEBUG("data object decoded: {}", _key);
-
- return nlohmann::json::parse(decoded.toStdString());
+ auto decoded_data =
+ encryption.removePadding(encryption.decode(encoded_data, hash_key_));
+ GF_CORE_LOG_TRACE("data object has been decoded, key: {}, data: {}", key,
+ decoded_data);
+ return QJsonDocument::fromJson(decoded_data);
} catch (...) {
- SPDLOG_ERROR("failed to get data object: {}", _key);
+ GF_CORE_LOG_ERROR("failed to get data object, caught exception: {}", key);
return {};
}
}
-std::optional<nlohmann::json>
-GpgFrontend::DataObjectOperator::GetDataObjectByRef(const std::string& _ref) {
+auto DataObjectOperator::GetDataObjectByRef(const QString& _ref)
+ -> std::optional<QJsonDocument> {
if (_ref.size() != 64) return {};
try {
- const auto& _hash_obj_key = _ref;
- const auto obj_path = app_data_objs_path_ / _hash_obj_key;
+ const auto& hash_obj_key = _ref;
+ const auto obj_path = app_data_objs_path_ + "/" + hash_obj_key;
- if (!std::filesystem::exists(obj_path)) return {};
+ if (!QFileInfo(obj_path).exists()) return {};
- std::string buffer;
- if (!FileOperator::ReadFileStd(obj_path.u8string(), buffer)) return {};
- auto encoded = QByteArray::fromStdString(buffer);
+ QByteArray encoded_data;
+ if (!ReadFile(obj_path, encoded_data)) return {};
QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
QAESEncryption::Padding::ISO);
- auto decoded =
- encryption.removePadding(encryption.decode(encoded, hash_key_));
+ auto decoded_data =
+ encryption.removePadding(encryption.decode(encoded_data, hash_key_));
- return nlohmann::json::parse(decoded.toStdString());
+ return QJsonDocument::fromJson(decoded_data);
} catch (...) {
return {};
}
}
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/DataObjectOperator.h b/src/core/function/DataObjectOperator.h
index ae5dc62c..fedbd905 100644
--- a/src/core/function/DataObjectOperator.h
+++ b/src/core/function/DataObjectOperator.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,17 +20,18 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_DATAOBJECTOPERATOR_H
-#define GPGFRONTEND_DATAOBJECTOPERATOR_H
+#pragma once
+
+#include <optional>
-#include "core/GpgFunctionObject.h"
#include "core/function/GlobalSettingStation.h"
+#include "core/function/basic/GpgFunctionObject.h"
namespace GpgFrontend {
@@ -45,11 +46,11 @@ class GPGFRONTEND_CORE_EXPORT DataObjectOperator
explicit DataObjectOperator(
int channel = SingletonFunctionObject::GetDefaultChannel());
- std::string SaveDataObj(const std::string &_key, const nlohmann::json &value);
+ auto SaveDataObj(const QString &_key, const QJsonDocument &value) -> QString;
- std::optional<nlohmann::json> GetDataObject(const std::string &_key);
+ auto GetDataObject(const QString &_key) -> std::optional<QJsonDocument>;
- std::optional<nlohmann::json> GetDataObjectByRef(const std::string &_ref);
+ auto GetDataObjectByRef(const QString &_ref) -> std::optional<QJsonDocument>;
private:
/**
@@ -60,21 +61,16 @@ class GPGFRONTEND_CORE_EXPORT DataObjectOperator
GlobalSettingStation &global_setting_station_ =
GlobalSettingStation::GetInstance(); ///< GlobalSettingStation
- std::filesystem::path app_secure_path_ =
- global_setting_station_.GetAppConfigPath() /
- "secure"; ///< Where sensitive information is stored
- std::filesystem::path app_secure_key_path_ =
- app_secure_path_ / "app.key"; ///< Where the key of data object is stored
- std::filesystem::path app_data_objs_path_ =
- global_setting_station_.GetAppDataPath() / "data_objs"; ///< Where data
- ///< object is
- ///< stored
+ QString app_secure_path_ =
+ global_setting_station_.GetAppDataPath() +
+ "/secure"; ///< Where sensitive information is stored
+ QString app_secure_key_path_ =
+ app_secure_path_ +
+ "/app.key"; ///< Where the key of data object is stored
+ QString app_data_objs_path_ =
+ global_setting_station_.GetAppDataPath() + "/data_objs";
- std::random_device rd_; ///< Random device
- std::mt19937 mt_ = std::mt19937(rd_()); ///< Mersenne twister
- QByteArray hash_key_; ///< Hash key
+ QByteArray hash_key_; ///< Hash key
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_DATAOBJECTOPERATOR_H
diff --git a/src/core/function/FileOperator.cpp b/src/core/function/FileOperator.cpp
deleted file mode 100644
index 41552246..00000000
--- a/src/core/function/FileOperator.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#include "FileOperator.h"
-
-bool GpgFrontend::FileOperator::ReadFile(const QString& file_name,
- QByteArray& data) {
- QFile file(file_name);
- if (!file.open(QIODevice::ReadOnly)) {
- SPDLOG_ERROR("failed to open file: {}", file_name.toStdString());
- return false;
- }
- data = file.readAll();
- file.close();
- return true;
-}
-
-bool GpgFrontend::FileOperator::WriteFile(const QString& file_name,
- const QByteArray& data) {
- QFile file(file_name);
- if (!file.open(QIODevice::WriteOnly)) {
- SPDLOG_ERROR("failed to open file: {}", file_name.toStdString());
- return false;
- }
- file.write(data);
- file.close();
- return true;
-}
-
-bool GpgFrontend::FileOperator::ReadFileStd(
- const std::filesystem::path& file_name, std::string& data) {
- QByteArray byte_data;
-#ifdef WINDOWS
- bool res = ReadFile(QString::fromStdU16String(file_name.u16string()).toUtf8(),
- byte_data);
-#else
- bool res = ReadFile(QString::fromStdString(file_name.u8string()).toUtf8(),
- byte_data);
-#endif
- data = byte_data.toStdString();
- return res;
-}
-
-bool GpgFrontend::FileOperator::WriteFileStd(
- const std::filesystem::path& file_name, const std::string& data) {
- return WriteFile(QString::fromStdString(file_name.u8string()).toUtf8(),
- QByteArray::fromStdString(data));
-}
-
-std::string GpgFrontend::FileOperator::CalculateHash(
- const std::filesystem::path& file_path) {
- // Returns empty QByteArray() on failure.
- QFileInfo info(QString::fromStdString(file_path.string()));
- std::stringstream ss;
-
- if (info.isFile() && info.isReadable()) {
- ss << "[#] " << _("File Hash Information") << std::endl;
- ss << " " << _("filename") << _(": ")
- << file_path.filename().u8string().c_str() << std::endl;
-
- QFile f(info.filePath());
- if (f.open(QFile::ReadOnly)) {
- // read all data
- auto buffer = f.readAll();
- ss << " " << _("file size(bytes)") << _(": ") << buffer.size()
- << std::endl;
-
- // md5
- auto hash_md5 = QCryptographicHash(QCryptographicHash::Md5);
- hash_md5.addData(buffer);
- auto md5 = hash_md5.result().toHex().toStdString();
- SPDLOG_DEBUG("md5 {}", md5);
- ss << " "
- << "md5" << _(": ") << md5 << std::endl;
-
- // sha1
- auto hash_sha1 = QCryptographicHash(QCryptographicHash::Sha1);
- hash_sha1.addData(buffer);
- auto sha1 = hash_sha1.result().toHex().toStdString();
- SPDLOG_DEBUG("sha1 {}", sha1);
- ss << " "
- << "sha1" << _(": ") << sha1 << std::endl;
-
- // sha1
- auto hash_sha256 = QCryptographicHash(QCryptographicHash::Sha256);
- hash_sha256.addData(buffer);
- auto sha256 = hash_sha256.result().toHex().toStdString();
- SPDLOG_DEBUG("sha256 {}", sha256);
- ss << " "
- << "sha256" << _(": ") << sha256 << std::endl;
-
- ss << std::endl;
- }
- } else {
- ss << "[#] " << _("Error in Calculating File Hash ") << std::endl;
- }
-
- return ss.str();
-}
diff --git a/src/core/function/FileOperator.h b/src/core/function/FileOperator.h
deleted file mode 100644
index a727b1de..00000000
--- a/src/core/function/FileOperator.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#ifndef GPGFRONTEND_FILEOPERATOR_H
-#define GPGFRONTEND_FILEOPERATOR_H
-
-#include "core/GpgFrontendCore.h"
-
-namespace GpgFrontend {
-
-/**
- * @brief provides file operations
- *
- */
-class GPGFRONTEND_CORE_EXPORT FileOperator {
- public:
- /**
- * @brief read file content using std struct
- *
- *
- * @param file_name file name
- * @param data data read from file
- * @return
- */
- static bool ReadFileStd(const std::filesystem::path &file_name,
- std::string &data);
-
- /**
- * @brief write file content using std struct
- *
- * @param file_name file name
- * @param data data to write to file
- * @return
- */
- static bool WriteFileStd(const std::filesystem::path &file_name,
- const std::string &data);
-
- /**
- * @brief read file content
- *
- * @param file_name file name
- * @param data data read from file
- * @return true if success
- * @return false if failed
- */
- static bool ReadFile(const QString &file_name, QByteArray &data);
-
- /**
- * @brief write file content
- *
- * @param file_name file name
- * @param data data to write to file
- * @return true if success
- * @return false if failed
- */
- static bool WriteFile(const QString &file_name, const QByteArray &data);
-
- /**
- * calculate the hash of a file
- * @param file_path
- * @return
- */
- static std::string CalculateHash(const std::filesystem::path &file_path);
-};
-} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_FILEOPERATOR_H
diff --git a/src/core/function/GlobalSettingStation.cpp b/src/core/function/GlobalSettingStation.cpp
index 6b743268..0158e8b3 100644
--- a/src/core/function/GlobalSettingStation.cpp
+++ b/src/core/function/GlobalSettingStation.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,136 +28,160 @@
#include "GlobalSettingStation.h"
-#include "core/function/FileOperator.h"
+#include "core/module/ModuleManager.h"
+#include "core/utils/FilesystemUtils.h"
+
+// macros to find resource files
+#if defined(MACOS) && defined(RELEASE)
+#define RESOURCE_DIR(appDir) (appDir + "/../Resources/")
+#define RESOURCE_DIR_PATH(appDir) (appDir / ".." / "Resources")
+#elif defined(LINUX) && defined(RELEASE)
+#define RESOURCE_DIR(appDir) (appDir + "/../share/")
+#define RESOURCE_DIR_PATH(appDir) (appDir / ".." / "share")
+#else
+#define RESOURCE_DIR(appDir) (appDir)
+#define RESOURCE_DIR_PATH(appDir) (appDir)
+#endif
+
+namespace GpgFrontend {
+
+class GlobalSettingStation::Impl {
+ public:
+ /**
+ * @brief Construct a new Global Setting Station object
+ *
+ */
+ explicit Impl() noexcept {
+ GF_CORE_LOG_INFO("app path: {}", GetAppDir());
+ GF_CORE_LOG_INFO("app working path: {}", working_path_);
+
+ auto portable_file_path = working_path_ + "/PORTABLE.txt";
+ if (QFileInfo(portable_file_path).exists()) {
+ GF_CORE_LOG_INFO(
+ "dectected portable mode, reconfiguring config and data path...");
+ Module::UpsertRTValue("core", "env.state.portable", 1);
+
+ app_data_path_ = working_path_;
+ app_log_path_ = app_data_path_ + "/logs";
+ app_data_objs_path_ = app_data_path_ + "/data_objs";
+
+ portable_mode_ = true;
+ }
+
+ GF_CORE_LOG_INFO("app data path: {}", app_data_path_);
+ GF_CORE_LOG_INFO("app log path: {}", app_log_path_);
-void GpgFrontend::GlobalSettingStation::SyncSettings() noexcept {
- using namespace libconfig;
- try {
- ui_cfg_.writeFile(ui_config_path_.u8string().c_str());
- SPDLOG_DEBUG("updated ui configuration successfully written to {}",
- ui_config_path_.u8string());
+ GF_CORE_LOG_INFO("app log files total size: {}", GetLogFilesSize());
+ GF_CORE_LOG_INFO("app data objects files total size: {}",
+ GetDataObjectsFilesSize());
- } catch (const FileIOException &fioex) {
- SPDLOG_ERROR("i/o error while writing ui configuration file: {}",
- ui_config_path_.u8string());
+ if (!QDir(app_data_path_).exists()) QDir(app_data_path_).mkpath(".");
+ if (!QDir(app_log_path_).exists()) QDir(app_log_path_).mkpath(".");
}
-}
-GpgFrontend::GlobalSettingStation::GlobalSettingStation(int channel) noexcept
- : SingletonFunctionObject<GlobalSettingStation>(channel) {
- using namespace std::filesystem;
- using namespace libconfig;
-
- SPDLOG_INFO("app path: {}", app_path_.u8string());
- SPDLOG_INFO("app configure path: {}", app_configure_path_.u8string());
- SPDLOG_INFO("app data path: {}", app_data_path_.u8string());
- SPDLOG_INFO("app log path: {}", app_log_path_.u8string());
- SPDLOG_INFO("app locale path: {}", app_locale_path_.u8string());
- SPDLOG_INFO("app conf path: {}", ui_config_path_.u8string());
-
- SPDLOG_INFO("app log files total size: {}", GetLogFilesSize());
- SPDLOG_INFO("app data objects files total size: {}",
- GetDataObjectsFilesSize());
-
- 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_.u8string().c_str());
- SPDLOG_DEBUG("user interface configuration successfully written to {}",
- ui_config_path_.u8string());
-
- } catch (const FileIOException &fioex) {
- SPDLOG_DEBUG(
- "i/o error while writing UserInterface configuration file {}",
- ui_config_path_.u8string());
- }
- } else {
- try {
- this->ui_cfg_.readFile(ui_config_path_.u8string().c_str());
- SPDLOG_DEBUG("user interface configuration successfully read from {}",
- ui_config_path_.u8string());
- } catch (const FileIOException &fioex) {
- SPDLOG_ERROR("i/o error while reading UserInterface configure file");
- } catch (const ParseException &pex) {
- SPDLOG_ERROR("parse error at {} : {} - {}", pex.getFile(), pex.getLine(),
- pex.getError());
- }
+ [[nodiscard]] auto GetSettings() -> QSettings {
+ if (!portable_mode_) return QSettings();
+ return {app_portable_config_path_, QSettings::IniFormat};
}
-}
-libconfig::Setting &
-GpgFrontend::GlobalSettingStation::GetUISettings() noexcept {
- return ui_cfg_.getRoot();
-}
+ [[nodiscard]] auto GetLogFilesSize() const -> QString {
+ return GetHumanFriendlyFileSize(GetFileSizeByPath(app_log_path_, "*.log"));
+ }
+
+ [[nodiscard]] auto GetDataObjectsFilesSize() const -> QString {
+ return GetHumanFriendlyFileSize(
+ GetFileSizeByPath(app_data_objs_path_, "*"));
+ }
-void GpgFrontend::GlobalSettingStation::init_app_secure_key() {}
+ void ClearAllLogFiles() const {
+ DeleteAllFilesByPattern(app_log_path_, "*.log");
+ }
-int64_t GpgFrontend::GlobalSettingStation::get_files_size_at_path(
- std::filesystem::path path, std::string filename_pattern) const {
- auto dir = QDir(QString::fromStdString(path.u8string()));
- QFileInfoList fileList = dir.entryInfoList(
- QStringList() << QString::fromStdString(filename_pattern), QDir::Files);
- qint64 totalSize = 0;
+ void ClearAllDataObjects() const {
+ DeleteAllFilesByPattern(app_data_objs_path_, "*");
+ }
- for (const QFileInfo &fileInfo : fileList) {
- totalSize += fileInfo.size();
+ /**
+ * @brief Get the App Dir object
+ *
+ * @return QString
+ */
+ [[nodiscard]] auto GetAppDir() const -> QString {
+ return QCoreApplication::applicationDirPath();
}
- return totalSize;
-}
-std::string GpgFrontend::GlobalSettingStation::get_human_readable_size(
- int64_t size) const {
- double num = size;
- QStringList list;
- list << "KB"
- << "MB"
- << "GB"
- << "TB";
-
- QStringListIterator i(list);
- QString unit("bytes");
-
- while (num >= 1024.0 && i.hasNext()) {
- unit = i.next();
- num /= 1024.0;
+ /**
+ * @brief Get the App Data Path object
+ *
+ * @return QString
+ */
+ [[nodiscard]] auto GetAppDataPath() const -> QString {
+ return app_data_path_;
}
- return (QString().setNum(num, 'f', 2) + " " + unit).toStdString();
+
+ /**
+ * @brief Get the Log Dir object
+ *
+ * @return QString
+ */
+ [[nodiscard]] auto GetLogDir() const -> QString { return app_log_path_; }
+
+ private:
+ QString working_path_ = QDir::currentPath();
+
+ QString app_data_path_ = QString{QStandardPaths::writableLocation(
+ QStandardPaths::AppLocalDataLocation)}; ///< Program Data Location
+
+ QString app_log_path_ = app_data_path_ + "/logs"; ///< Program Data Location
+
+ QString app_data_objs_path_ =
+ app_data_path_ + "/data_objs"; ///< Object storage path
+
+ bool portable_mode_ = false; ///<
+ QString app_portable_config_path_ =
+ working_path_ + "/config.ini"; ///< take effect only in portable mode
+
+ /**
+ * @brief
+ *
+ */
+ void init_app_secure_key() {}
+};
+
+GlobalSettingStation::GlobalSettingStation(int channel) noexcept
+ : SingletonFunctionObject<GlobalSettingStation>(channel),
+ p_(SecureCreateUniqueObject<Impl>()) {}
+
+GlobalSettingStation::~GlobalSettingStation() noexcept = default;
+
+auto GlobalSettingStation::GetSettings() const -> QSettings {
+ return p_->GetSettings();
}
-std::string GpgFrontend::GlobalSettingStation::GetLogFilesSize() const {
- return get_human_readable_size(
- get_files_size_at_path(app_log_path_, "*.log"));
+auto GlobalSettingStation::GetAppDir() const -> QString {
+ return p_->GetAppDir();
}
-std::string GpgFrontend::GlobalSettingStation::GetDataObjectsFilesSize() const {
- return get_human_readable_size(
- get_files_size_at_path(app_data_objs_path_, "*"));
+auto GlobalSettingStation::GetAppDataPath() const -> QString {
+ return p_->GetAppDataPath();
}
-void GpgFrontend::GlobalSettingStation::ClearAllLogFiles() const {
- delete_all_files(app_log_path_, "*.log");
+[[nodiscard]] auto GlobalSettingStation::GetLogDir() const -> QString {
+ return p_->GetLogDir();
}
-void GpgFrontend::GlobalSettingStation::ClearAllDataObjects() const {
- delete_all_files(app_data_objs_path_, "*");
+auto GlobalSettingStation::GetLogFilesSize() const -> QString {
+ return p_->GetLogFilesSize();
}
-void GpgFrontend::GlobalSettingStation::delete_all_files(
- std::filesystem::path path, std::string filename_pattern) const {
- auto dir = QDir(QString::fromStdString(path.u8string()));
+auto GlobalSettingStation::GetDataObjectsFilesSize() const -> QString {
+ return p_->GetDataObjectsFilesSize();
+}
- // 使用name filters来只选取以.log结尾的文件
- QStringList logFiles = dir.entryList(
- QStringList() << QString::fromStdString(filename_pattern), QDir::Files);
+void GlobalSettingStation::ClearAllLogFiles() const { p_->ClearAllLogFiles(); }
- // 遍历并删除所有符合条件的文件
- for (const auto &file : logFiles) {
- QFile::remove(dir.absoluteFilePath(file));
- }
+void GlobalSettingStation::ClearAllDataObjects() const {
+ p_->ClearAllDataObjects();
}
-GpgFrontend::GlobalSettingStation::~GlobalSettingStation() noexcept = default;
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/GlobalSettingStation.h b/src/core/function/GlobalSettingStation.h
index 80780f4b..85ac57b4 100644
--- a/src/core/function/GlobalSettingStation.h
+++ b/src/core/function/GlobalSettingStation.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,26 +20,24 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GLOBALSETTINGSTATION_H
-#define GPGFRONTEND_GLOBALSETTINGSTATION_H
+#pragma once
-#include <filesystem>
-
-#include "GpgFrontendBuildInstallInfo.h"
-#include "core/GpgFrontendCore.h"
-#include "core/GpgFunctionObject.h"
+#include "core/function/basic/GpgFunctionObject.h"
namespace GpgFrontend {
/**
- * @brief
+ * @class GlobalSettingStation
+ * @brief Singleton class for managing global settings in the application.
*
+ * This class handles reading and writing of global settings, as well as
+ * managing application directories and resource paths.
*/
class GPGFRONTEND_CORE_EXPORT GlobalSettingStation
: public SingletonFunctionObject<GlobalSettingStation> {
@@ -58,179 +56,60 @@ class GPGFRONTEND_CORE_EXPORT GlobalSettingStation
~GlobalSettingStation() noexcept override;
/**
- * @brief
- *
- * @return libconfig::Setting&
- */
- libconfig::Setting &GetUISettings() noexcept;
-
- /**
- * @brief
+ * @brief Get the Settings object
*
- * @return libconfig::Setting&
+ * @return QSettings
*/
- template <typename T>
- T LookupSettings(std::string path, T default_value) noexcept {
- T value = default_value;
- try {
- value = static_cast<T>(GetUISettings().lookup(path));
- } catch (...) {
- SPDLOG_WARN("setting not found: {}", path);
- }
- return value;
- }
+ [[nodiscard]] auto GetSettings() const -> QSettings;
/**
* @brief Get the App Dir object
*
- * @return std::filesystem::path
+ * @return QString
*/
- [[nodiscard]] std::filesystem::path GetAppDir() const { return app_path_; }
-
- [[nodiscard]] std::filesystem::path GetAppDataPath() const {
- return app_data_path_;
- }
+ [[nodiscard]] auto GetAppDir() const -> QString;
/**
- * @brief Get the Log Dir object
- *
- * @return std::filesystem::path
+ * @brief Gets the application data directory.
+ * @return Path to the application data directory.
*/
- [[nodiscard]] std::filesystem::path GetLogDir() const {
- return app_log_path_;
- }
+ [[nodiscard]] auto GetAppDataPath() const -> QString;
/**
- * @brief Get the Standalone Database Dir object
- *
- * @return std::filesystem::path
- */
- [[nodiscard]] std::filesystem::path GetStandaloneDatabaseDir() const {
- auto db_path = app_configure_path_ / "db";
- if (!std::filesystem::exists(db_path)) {
- std::filesystem::create_directory(db_path);
- }
- return db_path;
- }
-
- [[nodiscard]] std::filesystem::path GetAppConfigPath() const {
- return app_configure_path_;
- }
-
- /**
- * @brief Get the Standalone Gpg Bin Dir object
+ * @brief Get the Log Dir object
*
- * @return std::filesystem::path
+ * @return QString
*/
- [[nodiscard]] std::filesystem::path GetStandaloneGpgBinDir() const {
- return app_resource_path_ / "gpg1.4" / "gpg";
- }
+ [[nodiscard]] auto GetLogDir() const -> QString;
/**
- * @brief Get the Locale Dir object
+ * @brief Get the Log Files Size object
*
- * @return std::filesystem::path
+ * @return QString
*/
- [[nodiscard]] std::filesystem::path GetLocaleDir() const {
- return app_locale_path_;
- }
+ [[nodiscard]] auto GetLogFilesSize() const -> QString;
/**
- * @brief Get the Resource Dir object
+ * @brief Get the Data Objects Files Size object
*
- * @return std::filesystem::path
+ * @return QString
*/
- [[nodiscard]] std::filesystem::path GetResourceDir() const {
- return app_resource_path_;
- }
+ [[nodiscard]] auto GetDataObjectsFilesSize() const -> QString;
/**
- * @brief Get the Certs Dir object
+ * @brief clear all log files
*
- * @return std::filesystem::path
*/
- [[nodiscard]] std::filesystem::path GetCertsDir() const {
- return app_resource_path_ / "certs";
- }
-
- [[nodiscard]] std::string GetLogFilesSize() const;
-
- [[nodiscard]] std::string GetDataObjectsFilesSize() const;
-
void ClearAllLogFiles() const;
- void ClearAllDataObjects() const;
-
/**
- * @brief sync the settings to the file
+ * @brief clear all data objects
*
*/
- void SyncSettings() noexcept;
+ void ClearAllDataObjects() const;
private:
- std::filesystem::path app_path_ = QCoreApplication::applicationDirPath()
- .toStdString(); ///< Program Location
- std::filesystem::path app_data_path_ =
- QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)
- .toStdString(); ///< Program Data Location
- std::filesystem::path app_log_path_ =
- app_data_path_ / "logs"; ///< Program Data Location
- std::filesystem::path app_data_objs_path_ =
- app_data_path_ / "data_objs"; ///< Object storage path
-
-#ifdef LINUX_INSTALL_BUILD
- std::filesystem::path app_resource_path_ =
- std::filesystem::path(APP_LOCALSTATE_PATH) /
- "gpgfrontend"; ///< Program Data Location
-#else
- std::filesystem::path app_resource_path_ =
- RESOURCE_DIR_BOOST_PATH(app_path_); ///< Program Data Location
-#endif
-
-#ifdef LINUX_INSTALL_BUILD
- std::filesystem::path app_locale_path_ =
- std::string(APP_LOCALE_PATH); ///< Program Data Location
-#else
- std::filesystem::path app_locale_path_ =
- app_resource_path_ / "locales"; ///< Program Data Location
-#endif
-
- std::filesystem::path app_configure_path_ =
- QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation)
- .toStdString(); ///< Program Configure Location
- std::filesystem::path ui_config_dir_path_ =
- app_configure_path_ / "conf"; ///< Configure File Directory Location
- std::filesystem::path ui_config_path_ =
- ui_config_dir_path_ / "main.cfg"; ///< Main Configure File Location
-
- libconfig::Config ui_cfg_; ///< UI Configure File
-
- /**
- * @brief
- *
- */
- void init_app_secure_key();
-
- /**
- * @brief
- *
- */
- int64_t get_files_size_at_path(std::filesystem::path path,
- std::string filename_pattern) const;
-
- /**
- * @brief
- *
- */
- std::string get_human_readable_size(int64_t size) const;
-
- /**
- * @brief
- *
- */
- void delete_all_files(std::filesystem::path path,
- std::string filename_pattern) const;
+ class Impl;
+ SecureUniquePtr<Impl> p_;
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GLOBALSETTINGSTATION_H
diff --git a/src/core/function/KeyPackageOperator.cpp b/src/core/function/KeyPackageOperator.cpp
index 5c917ab8..abb84512 100644
--- a/src/core/function/KeyPackageOperator.cpp
+++ b/src/core/function/KeyPackageOperator.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,71 +28,88 @@
#include "KeyPackageOperator.h"
-#include "FileOperator.h"
-#include "function/PassphraseGenerator.h"
-#include "function/gpg/GpgKeyGetter.h"
-#include "function/gpg/GpgKeyImportExporter.h"
-#include "qt-aes/qaesencryption.h"
+#include <qt-aes/qaesencryption.h>
+
+#include "core/function/KeyPackageOperator.h"
+#include "core/function/PassphraseGenerator.h"
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/function/gpg/GpgKeyImportExporter.h"
+#include "core/typedef/CoreTypedef.h"
+#include "core/utils/GpgUtils.h"
+#include "core/utils/IOUtils.h"
namespace GpgFrontend {
-bool KeyPackageOperator::GeneratePassphrase(
- const std::filesystem::path& phrase_path, std::string& phrase) {
+auto KeyPackageOperator::GeneratePassphrase(const QString& phrase_path,
+ QString& phrase) -> bool {
phrase = PassphraseGenerator::GetInstance().Generate(256);
- SPDLOG_DEBUG("generated passphrase: {} bytes", phrase.size());
- return FileOperator::WriteFileStd(phrase_path, phrase);
+ GF_CORE_LOG_DEBUG("generated passphrase: {} bytes", phrase.size());
+ return WriteFile(phrase_path, phrase.toUtf8());
}
-bool KeyPackageOperator::GenerateKeyPackage(
- const std::filesystem::path& key_package_path,
- const std::string& key_package_name, KeyIdArgsListPtr& key_ids,
- std::string& phrase, bool secret) {
- SPDLOG_DEBUG("generating key package: {}", key_package_name);
-
- ByteArrayPtr key_export_data = nullptr;
- if (!GpgKeyImportExporter::GetInstance().ExportAllKeys(
- key_ids, key_export_data, secret)) {
- SPDLOG_ERROR("failed to export keys");
- return false;
- }
-
- auto key = QByteArray::fromStdString(phrase);
- auto data = QString::fromStdString(*key_export_data).toLocal8Bit().toBase64();
-
- auto hash_key = QCryptographicHash::hash(key, QCryptographicHash::Sha256);
- QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
- QAESEncryption::Padding::ISO);
- auto encoded = encryption.encode(data, hash_key);
-
- SPDLOG_DEBUG("writing key package: {}", key_package_name);
- return FileOperator::WriteFileStd(key_package_path, encoded.toStdString());
+void KeyPackageOperator::GenerateKeyPackage(const QString& key_package_path,
+ const QString& key_package_name,
+ const KeyArgsList& keys,
+ QString& phrase, bool secret,
+ const OperationCallback& cb) {
+ GF_CORE_LOG_DEBUG("generating key package: {}", key_package_name);
+
+ GpgKeyImportExporter::GetInstance().ExportKeys(
+ keys, secret, true, false, false,
+ [=](GpgError err, const DataObjectPtr& data_obj) {
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ GF_LOG_ERROR("export keys error, reason: {}",
+ DescribeGpgErrCode(err).second);
+ cb(-1, data_obj);
+ return;
+ }
+
+ if (CheckGpgError(err) == GPG_ERR_USER_1 || data_obj == nullptr ||
+ !data_obj->Check<GFBuffer>()) {
+ cb(-1, data_obj);
+ return;
+ }
+
+ auto gf_buffer = ExtractParams<GFBuffer>(data_obj, 0);
+
+ auto data = gf_buffer.ConvertToQByteArray().toBase64();
+ auto hash_key = QCryptographicHash::hash(phrase.toUtf8(),
+ QCryptographicHash::Sha256);
+ QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
+ QAESEncryption::Padding::ISO);
+ auto encoded_data = encryption.encode(data, hash_key);
+ GF_CORE_LOG_DEBUG("writing key package, name: {}", key_package_name);
+
+ cb(WriteFile(key_package_path, encoded_data) ? 0 : -1,
+ TransferParams());
+ return;
+ });
}
-bool KeyPackageOperator::ImportKeyPackage(
- const std::filesystem::path& key_package_path,
- const std::filesystem::path& phrase_path,
- GpgFrontend::GpgImportInformation& import_info) {
- SPDLOG_DEBUG("importing key package: {]", key_package_path.u8string());
+auto KeyPackageOperator::ImportKeyPackage(const QString& key_package_path,
+ const QString& phrase_path)
+ -> std::tuple<bool, std::shared_ptr<GpgImportInformation>> {
+ GF_CORE_LOG_DEBUG("importing key package: {}", key_package_path);
- std::string encrypted_data;
- FileOperator::ReadFileStd(key_package_path, encrypted_data);
+ QByteArray encrypted_data;
+ ReadFile(key_package_path, encrypted_data);
- if (encrypted_data.empty()) {
- SPDLOG_ERROR("failed to read key package: {}", key_package_path.u8string());
- return false;
+ if (encrypted_data.isEmpty()) {
+ GF_CORE_LOG_ERROR("failed to read key package: {}", key_package_path);
+ return {false, nullptr};
};
- std::string passphrase;
- FileOperator::ReadFileStd(phrase_path, passphrase);
- SPDLOG_DEBUG("passphrase: {} bytes", passphrase.size());
+ QByteArray passphrase;
+ ReadFile(phrase_path, passphrase);
+ GF_CORE_LOG_DEBUG("passphrase: {} bytes", passphrase.size());
if (passphrase.size() != 256) {
- SPDLOG_ERROR("failed to read passphrase: {}", phrase_path.u8string());
- return false;
+ GF_CORE_LOG_ERROR("failed to read passphrase: {}", phrase_path);
+ return {false, nullptr};
}
- auto hash_key = QCryptographicHash::hash(
- QByteArray::fromStdString(passphrase), QCryptographicHash::Sha256);
- auto encoded = QByteArray::fromStdString(encrypted_data);
+ auto hash_key =
+ QCryptographicHash::hash(passphrase, QCryptographicHash::Sha256);
+ auto encoded = encrypted_data;
QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
QAESEncryption::Padding::ISO);
@@ -100,20 +117,30 @@ bool KeyPackageOperator::ImportKeyPackage(
auto decoded = encryption.removePadding(encryption.decode(encoded, hash_key));
auto key_data = QByteArray::fromBase64(decoded);
- SPDLOG_DEBUG("key data size: {}", key_data.size());
- if (!key_data.startsWith(GpgConstants::PGP_PUBLIC_KEY_BEGIN) &&
- !key_data.startsWith(GpgConstants::PGP_PRIVATE_KEY_BEGIN)) {
- return false;
+ GF_CORE_LOG_DEBUG("import key package, read key data size: {}",
+ key_data.size());
+ if (!key_data.startsWith(PGP_PUBLIC_KEY_BEGIN) &&
+ !key_data.startsWith(PGP_PRIVATE_KEY_BEGIN)) {
+ return {false, nullptr};
}
- auto key_data_ptr = std::make_unique<ByteArray>(key_data.toStdString());
- import_info =
- GpgKeyImportExporter::GetInstance().ImportKey(std::move(key_data_ptr));
- return true;
+ auto import_info =
+ GpgKeyImportExporter::GetInstance().ImportKey(GFBuffer(key_data));
+ return {true, import_info};
}
-std::string KeyPackageOperator::GenerateKeyPackageName() {
+auto KeyPackageOperator::GenerateKeyPackageName() -> QString {
return generate_key_package_name();
}
+/**
+ * @brief generate key package name
+ *
+ * @return QString key package name
+ */
+auto KeyPackageOperator::generate_key_package_name() -> QString {
+ return QString("KeyPackage_%1")
+ .arg(QRandomGenerator::global()->bounded(999, 99999));
+}
+
} // namespace GpgFrontend
diff --git a/src/core/function/KeyPackageOperator.h b/src/core/function/KeyPackageOperator.h
index 00b0dbaa..968e14f5 100644
--- a/src/core/function/KeyPackageOperator.h
+++ b/src/core/function/KeyPackageOperator.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,17 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_KEYPACKAGEOPERATOR_H
-#define GPGFRONTEND_KEYPACKAGEOPERATOR_H
+#pragma once
-#include "core/GpgFrontendCore.h"
#include "core/function/gpg/GpgKeyImportExporter.h"
+#include "core/typedef/CoreTypedef.h"
namespace GpgFrontend {
@@ -48,15 +47,15 @@ class GPGFRONTEND_CORE_EXPORT KeyPackageOperator {
* @return true if passphrase was generated and saved
* @return false if passphrase was not generated and saved
*/
- static bool GeneratePassphrase(const std::filesystem::path &phrase_path,
- std::string &phrase);
+ static auto GeneratePassphrase(const QString &phrase_path, QString &phrase)
+ -> bool;
/**
* @brief generate the name of the key package
*
- * @return std::string name of the key package
+ * @return QString name of the key package
*/
- static std::string GenerateKeyPackageName();
+ static auto GenerateKeyPackageName() -> QString;
/**
* @brief generate key package
@@ -69,10 +68,10 @@ class GPGFRONTEND_CORE_EXPORT KeyPackageOperator {
* @return true if key package was generated
* @return false if key package was not generated
*/
- static bool GenerateKeyPackage(const std::filesystem::path &key_package_path,
- const std::string &key_package_name,
- KeyIdArgsListPtr &key_ids, std::string &phrase,
- bool secret);
+ static void GenerateKeyPackage(const QString &key_package_path,
+ const QString &key_package_name,
+ const KeyArgsList &keys, QString &phrase,
+ bool secret, const OperationCallback &cb);
/**
* @brief import key package
@@ -83,25 +82,16 @@ class GPGFRONTEND_CORE_EXPORT KeyPackageOperator {
* @return true if key package was imported
* @return false if key package was not imported
*/
- static bool ImportKeyPackage(const std::filesystem::path &key_package_path,
- const std::filesystem::path &phrase_path,
- GpgFrontend::GpgImportInformation &import_info);
+ static auto ImportKeyPackage(const QString &key_package_path,
+ const QString &phrase_path)
+ -> std::tuple<bool, std::shared_ptr<GpgImportInformation>>;
private:
/**
* @brief generate key package name
*
- * @return std::string key package name
+ * @return QString key package name
*/
- static std::string generate_key_package_name() {
- std::random_device rd_; ///< Random device
- auto mt_ = std::mt19937(rd_()); ///< Mersenne twister
-
- std::uniform_int_distribution<int> dist(999, 99999);
- auto file_string = boost::format("KeyPackage_%1%") % dist(mt_);
- return file_string.str();
- }
+ static auto generate_key_package_name() -> QString;
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_KEYPACKAGEOPERATOR_H
diff --git a/src/core/function/LoggerManager.cpp b/src/core/function/LoggerManager.cpp
new file mode 100644
index 00000000..3b88e4f0
--- /dev/null
+++ b/src/core/function/LoggerManager.cpp
@@ -0,0 +1,155 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "LoggerManager.h"
+
+#include <spdlog/async.h>
+#include <spdlog/common.h>
+#include <spdlog/sinks/rotating_file_sink.h>
+#include <spdlog/sinks/stdout_color_sinks.h>
+
+#include "core/function/GlobalSettingStation.h"
+
+namespace GpgFrontend {
+
+std::shared_ptr<spdlog::logger> LoggerManager::default_logger = nullptr;
+spdlog::level::level_enum LoggerManager::default_log_level =
+ spdlog::level::debug;
+
+LoggerManager::LoggerManager(int channel)
+ : SingletonFunctionObject<LoggerManager>(channel) {
+ spdlog::init_thread_pool(1024, 2);
+ spdlog::flush_every(std::chrono::seconds(5));
+}
+
+LoggerManager::~LoggerManager() {
+#ifdef WINDOWS
+ // Under VisualStudio, this must be called before main finishes to workaround
+ // a known VS issue
+ spdlog::drop_all();
+ spdlog::shutdown();
+#endif
+
+ if (default_logger) default_logger = nullptr;
+}
+
+auto LoggerManager::GetLogger(const QString& id)
+ -> std::shared_ptr<spdlog::logger> {
+ auto m_it = logger_map_.find(id);
+ if (m_it == logger_map_.end()) return GetDefaultLogger();
+ return m_it->second;
+}
+
+auto LoggerManager::RegisterAsyncLogger(const QString& id,
+ spdlog::level::level_enum level)
+ -> std::shared_ptr<spdlog::logger> {
+ // get the log directory
+ auto log_file_path =
+ GlobalSettingStation::GetInstance().GetLogDir() + "/" + id + ".log";
+
+ // sinks
+ std::vector<spdlog::sink_ptr> sinks;
+ sinks.push_back(GpgFrontend::SecureCreateSharedObject<
+ spdlog::sinks::stderr_color_sink_mt>());
+ sinks.push_back(GpgFrontend::SecureCreateSharedObject<
+ spdlog::sinks::rotating_file_sink_mt>(
+ log_file_path.toUtf8().constData(), 1048576 * 32, 8));
+
+ // logger
+ auto logger = GpgFrontend::SecureCreateSharedObject<spdlog::async_logger>(
+ id.toStdString(), begin(sinks), end(sinks), spdlog::thread_pool());
+ logger->set_pattern(
+ "[%H:%M:%S.%e] [T:%t] [%=6n] %^[%=8l]%$ [%s:%#] [%!] -> %v (+%ius)");
+
+ // set the level of logger
+ logger->set_level(level);
+
+ // flush policy
+#ifdef DEBUG
+ logger->flush_on(spdlog::level::trace);
+#else
+ core_logger->flush_on(spdlog::level::err);
+#endif
+
+ logger_map_[id] = logger;
+ return logger;
+}
+
+auto LoggerManager::RegisterSyncLogger(const QString& id,
+ spdlog::level::level_enum level)
+ -> std::shared_ptr<spdlog::logger> {
+ // get the log directory
+ auto log_file_path =
+ GlobalSettingStation::GetInstance().GetLogDir() + "/" + id + ".log";
+
+ // sinks
+ std::vector<spdlog::sink_ptr> sinks;
+ sinks.push_back(GpgFrontend::SecureCreateSharedObject<
+ spdlog::sinks::stderr_color_sink_mt>());
+ sinks.push_back(GpgFrontend::SecureCreateSharedObject<
+ spdlog::sinks::rotating_file_sink_mt>(
+ log_file_path.toUtf8().constData(), 1048576 * 32, 8));
+
+ // logger
+ auto logger = GpgFrontend::SecureCreateSharedObject<spdlog::logger>(
+ id.toStdString(), begin(sinks), end(sinks));
+ logger->set_pattern(
+ "[%H:%M:%S.%e] [T:%t] [%=6n] %^[%=8l]%$ [%s:%#] [%!] -> %v (+%ius)");
+
+ // set the level of logger
+ logger->set_level(level);
+
+ logger_map_[id] = logger;
+ return logger;
+}
+
+auto LoggerManager::GetDefaultLogger() -> std::shared_ptr<spdlog::logger> {
+ if (default_logger == nullptr) {
+ // sinks
+ std::vector<spdlog::sink_ptr> sinks;
+ sinks.push_back(GpgFrontend::SecureCreateSharedObject<
+ spdlog::sinks::stderr_color_sink_mt>());
+
+ // logger
+ auto logger = GpgFrontend::SecureCreateSharedObject<spdlog::logger>(
+ "default", begin(sinks), end(sinks));
+ logger->set_pattern(
+ "[%H:%M:%S.%e] [T:%t] [%=6n] %^[%=8l]%$ [%s:%#] [%!] -> %v (+%ius)");
+
+ // set the level of logger
+ logger->set_level(default_log_level);
+ spdlog::set_default_logger(logger);
+ default_logger = logger;
+ }
+ return default_logger;
+}
+
+void LoggerManager::SetDefaultLogLevel(spdlog::level::level_enum level) {
+ default_log_level = level;
+}
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/LoggerManager.h b/src/core/function/LoggerManager.h
new file mode 100644
index 00000000..78fecc3c
--- /dev/null
+++ b/src/core/function/LoggerManager.h
@@ -0,0 +1,65 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/function/basic/GpgFunctionObject.h"
+
+namespace spdlog {
+class logger;
+}
+
+namespace GpgFrontend {
+
+class GPGFRONTEND_CORE_EXPORT LoggerManager
+ : public SingletonFunctionObject<LoggerManager> {
+ public:
+ explicit LoggerManager(int channel);
+
+ ~LoggerManager() override;
+
+ auto RegisterAsyncLogger(const QString& id, spdlog::level::level_enum)
+ -> std::shared_ptr<spdlog::logger>;
+
+ auto RegisterSyncLogger(const QString& id, spdlog::level::level_enum)
+ -> std::shared_ptr<spdlog::logger>;
+
+ auto GetLogger(const QString& id) -> std::shared_ptr<spdlog::logger>;
+
+ static auto GetDefaultLogger() -> std::shared_ptr<spdlog::logger>;
+
+ static void SetDefaultLogLevel(spdlog::level::level_enum);
+
+ private:
+ static spdlog::level::level_enum default_log_level;
+ static std::shared_ptr<spdlog::logger> default_logger;
+
+ std::map<QString, std::shared_ptr<spdlog::logger>> logger_map_;
+};
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/PassphraseGenerator.cpp b/src/core/function/PassphraseGenerator.cpp
index de963fa1..b7f1e877 100644
--- a/src/core/function/PassphraseGenerator.cpp
+++ b/src/core/function/PassphraseGenerator.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,10 +20,30 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "PassphraseGenerator.h"
+
+namespace GpgFrontend {
+
+auto PassphraseGenerator::Generate(int len) -> QString {
+ auto file_string = QString("KeyPackage_%1")
+ .arg(QRandomGenerator::global()->bounded(999, 99999));
+ static const char kAlphanum[] =
+ "0123456789"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz";
+ QString tmp_str;
+ tmp_str.reserve(len);
+
+ for (int i = 0; i < len; ++i) {
+ tmp_str += kAlphanum[QRandomGenerator::global()->bounded(
+ static_cast<quint32>(sizeof(kAlphanum)))];
+ }
+ return tmp_str;
+}
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/PassphraseGenerator.h b/src/core/function/PassphraseGenerator.h
index a61356fe..2e5925b6 100644
--- a/src/core/function/PassphraseGenerator.h
+++ b/src/core/function/PassphraseGenerator.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,17 +20,15 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_PASSPHRASEGENERATOR_H
-#define GPGFRONTEND_PASSPHRASEGENERATOR_H
+#pragma once
-#include "core/GpgFrontendCore.h"
-#include "core/GpgFunctionObject.h"
+#include "core/function/basic/GpgFunctionObject.h"
namespace GpgFrontend {
@@ -55,29 +53,13 @@ class GPGFRONTEND_CORE_EXPORT PassphraseGenerator
* @brief generate passphrase
*
* @param len length of the passphrase
- * @return std::string passphrase
+ * @return QString passphrase
*/
- std::string Generate(int len) {
- std::uniform_int_distribution<int> dist(999, 99999);
-
- auto file_string = boost::format("KeyPackage_%1%") % dist(mt_);
- static const char alphanum[] =
- "0123456789"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz";
- std::string tmp_str;
- tmp_str.reserve(len);
-
- for (int i = 0; i < len; ++i) {
- tmp_str += alphanum[dist(mt_) % (sizeof(alphanum) - 1)];
- }
- return tmp_str;
- }
+ auto Generate(int len) -> QString;
+ private:
std::random_device rd_; ///< Random device
std::mt19937 mt_ = std::mt19937(rd_()); ///< Mersenne twister
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_PASSPHRASEGENERATOR_H
diff --git a/src/core/function/SecureMemoryAllocator.cpp b/src/core/function/SecureMemoryAllocator.cpp
new file mode 100644
index 00000000..692c36c5
--- /dev/null
+++ b/src/core/function/SecureMemoryAllocator.cpp
@@ -0,0 +1,63 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "SecureMemoryAllocator.h"
+
+#ifndef MACOS
+#include <mimalloc.h>
+#endif
+
+namespace GpgFrontend {
+
+auto SecureMemoryAllocator::Allocate(std::size_t size) -> void* {
+#ifndef MACOS
+ auto* addr = mi_malloc(size);
+#else
+ auto* addr = malloc(size);
+#endif
+ return addr;
+}
+
+auto SecureMemoryAllocator::Reallocate(void* ptr, std::size_t size) -> void* {
+#ifndef MACOS
+ auto* addr = mi_realloc(ptr, size);
+#else
+ auto* addr = realloc(ptr, size);
+#endif
+ return addr;
+}
+
+void SecureMemoryAllocator::Deallocate(void* p) {
+#ifndef MACOS
+ mi_free(p);
+#else
+ free(p);
+#endif
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/SecureMemoryAllocator.h b/src/core/function/SecureMemoryAllocator.h
new file mode 100644
index 00000000..e9f1c1c3
--- /dev/null
+++ b/src/core/function/SecureMemoryAllocator.h
@@ -0,0 +1,60 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <memory>
+
+#include "core/utils/LogUtils.h"
+
+namespace GpgFrontend {
+
+class GPGFRONTEND_CORE_EXPORT SecureMemoryAllocator {
+ public:
+ static auto Allocate(std::size_t) -> void *;
+
+ static auto Reallocate(void *, std::size_t) -> void *;
+
+ static void Deallocate(void *);
+};
+
+template <typename T>
+struct SecureObjectDeleter {
+ void operator()(T *ptr) {
+ if (ptr) {
+ ptr->~T();
+ SecureMemoryAllocator::Deallocate(ptr);
+ }
+ }
+};
+
+template <typename T>
+using SecureUniquePtr = std::unique_ptr<T, SecureObjectDeleter<T>>;
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/basic/ChannelObject.cpp b/src/core/function/basic/ChannelObject.cpp
new file mode 100644
index 00000000..18449ddb
--- /dev/null
+++ b/src/core/function/basic/ChannelObject.cpp
@@ -0,0 +1,59 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "ChannelObject.h"
+
+#include <iostream>
+
+namespace GpgFrontend {
+
+ChannelObject::ChannelObject() noexcept = default;
+
+ChannelObject::ChannelObject(int channel, QString type)
+ : channel_(channel), type_(std::move(type)) {}
+
+#ifdef DEBUG
+ChannelObject::~ChannelObject() noexcept {
+ // using iostream instead of spdlog bacause at this time spdlog may have
+ // already been destroyed.
+ QTextStream(stdout) << "releasing channel object: " << this->type_
+ << Qt::endl;
+}
+#else
+ChannelObject::~ChannelObject() noexcept = default;
+#endif
+
+void ChannelObject::SetChannel(int channel) { this->channel_ = channel; }
+
+auto ChannelObject::GetChannel() const -> int { return channel_; }
+
+auto ChannelObject::GetDefaultChannel() -> int {
+ return kGpgFrontendDefaultChannel;
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/basic/ChannelObject.h b/src/core/function/basic/ChannelObject.h
new file mode 100644
index 00000000..27be55c4
--- /dev/null
+++ b/src/core/function/basic/ChannelObject.h
@@ -0,0 +1,98 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/GpgConstants.h"
+#include "core/function/SecureMemoryAllocator.h"
+namespace GpgFrontend {
+
+/**
+ * @brief object which in channel system is called "channel"
+ *
+ */
+class GPGFRONTEND_CORE_EXPORT ChannelObject {
+ public:
+ /**
+ * @brief Construct a new Default Channel Object object
+ *
+ */
+ ChannelObject() noexcept;
+
+ /**
+ * @brief Destroy the Channel Object object
+ *
+ */
+ virtual ~ChannelObject() noexcept;
+
+ /**
+ * @brief Construct a new Channel Object object
+ *
+ * @param channel
+ */
+ explicit ChannelObject(int channel, QString type);
+
+ /**
+ * @brief Get the Default Channel object
+ *
+ * @return int
+ */
+ static auto GetDefaultChannel() -> int;
+
+ /**
+ * @brief Get the Channel object
+ *
+ * @return int
+ */
+ [[nodiscard]] auto GetChannel() const -> int;
+
+ /**
+ * @brief Set the Channel object
+ *
+ * @param channel
+ */
+ void SetChannel(int channel);
+
+ private:
+ int channel_ = kGpgFrontendDefaultChannel; ///< The channel id
+ QString type_;
+};
+
+template <typename Derived>
+auto ConvertToChannelObjectPtr(
+ std::unique_ptr<Derived, SecureObjectDeleter<Derived>> derivedPtr)
+ -> std::unique_ptr<ChannelObject, SecureObjectDeleter<ChannelObject>> {
+ static_assert(std::is_base_of_v<ChannelObject, Derived>,
+ "Derived must be a subclass of ChannelObject");
+
+ ChannelObject* base_ptr = derivedPtr.release();
+ return std::unique_ptr<ChannelObject, SecureObjectDeleter<ChannelObject>>(
+ base_ptr);
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/basic/GpgFunctionObject.cpp b/src/core/function/basic/GpgFunctionObject.cpp
new file mode 100644
index 00000000..e9e444f1
--- /dev/null
+++ b/src/core/function/basic/GpgFunctionObject.cpp
@@ -0,0 +1,105 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgFunctionObject.h"
+
+#include <map>
+#include <mutex>
+#include <typeinfo>
+
+#include "core/function/SecureMemoryAllocator.h"
+#include "core/function/basic/ChannelObject.h"
+
+struct FunctionObjectTypeLockInfo {
+ std::map<int, std::mutex> channel_lock_map;
+ std::mutex type_lock;
+};
+
+std::mutex g_function_object_mutex_map_lock;
+std::map<size_t, FunctionObjectTypeLockInfo> g_function_object_mutex_map;
+
+namespace GpgFrontend {
+auto GetGlobalFunctionObjectChannelLock(const std::type_info& type, int channel)
+ -> std::mutex& {
+ std::lock_guard<std::mutex> lock_guard(g_function_object_mutex_map_lock);
+ auto& channel_map = g_function_object_mutex_map[type.hash_code()];
+ return channel_map.channel_lock_map[channel];
+}
+
+auto GetGlobalFunctionObjectTypeLock(const std::type_info& type)
+ -> std::mutex& {
+ std::lock_guard<std::mutex> lock_guard(g_function_object_mutex_map_lock);
+ auto& channel_map = g_function_object_mutex_map[type.hash_code()];
+ return channel_map.type_lock;
+}
+
+/**
+ * @brief Get the Instance object
+ *
+ * @param channel
+ * @return T&
+ */
+auto GetChannelObjectInstance(const std::type_info& type, int channel)
+ -> ChannelObject* {
+ GF_DEFAULT_LOG_TRACE("try to get instance of type: {} at channel: {}",
+ type.name(), channel);
+
+ // lock this channel
+ std::lock_guard<std::mutex> guard(
+ GetGlobalFunctionObjectChannelLock(type, channel));
+
+ auto* p_storage =
+ SingletonStorageCollection::GetInstance(false)->GetSingletonStorage(type);
+ GF_DEFAULT_LOG_TRACE("get singleton storage result, p_storage: {}",
+ static_cast<void*>(p_storage));
+
+ auto* p_pbj =
+ static_cast<ChannelObject*>(p_storage->FindObjectInChannel(channel));
+ GF_DEFAULT_LOG_TRACE("find channel object result, channel {}, p_pbj: {}",
+ channel, static_cast<void*>(p_pbj));
+
+ return p_pbj;
+}
+
+auto CreateChannelObjectInstance(const std::type_info& type, int channel,
+ SecureUniquePtr<ChannelObject> channel_object)
+ -> ChannelObject* {
+ // lock this channel
+ std::lock_guard<std::mutex> guard(
+ GetGlobalFunctionObjectChannelLock(type, channel));
+
+ auto* p_storage =
+ SingletonStorageCollection::GetInstance(false)->GetSingletonStorage(type);
+ GF_DEFAULT_LOG_TRACE("create channel object, channel {}, type: {}", channel,
+ type.name());
+
+ // do create object of this channel
+ return p_storage->SetObjectInChannel(channel, std::move(channel_object));
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/basic/GpgFunctionObject.h b/src/core/function/basic/GpgFunctionObject.h
new file mode 100644
index 00000000..1ea352b6
--- /dev/null
+++ b/src/core/function/basic/GpgFunctionObject.h
@@ -0,0 +1,194 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include <mutex>
+#include <stdexcept>
+
+#include "core/GpgFrontendCoreExport.h"
+#include "core/function/basic/ChannelObject.h"
+#include "core/function/basic/SingletonStorage.h"
+#include "core/function/basic/SingletonStorageCollection.h"
+#include "core/utils/MemoryUtils.h"
+
+namespace GpgFrontend {
+
+auto GPGFRONTEND_CORE_EXPORT GetChannelObjectInstance(
+ const std::type_info& type, int channel) -> ChannelObject*;
+
+auto GPGFRONTEND_CORE_EXPORT CreateChannelObjectInstance(
+ const std::type_info& type, int channel,
+ SecureUniquePtr<ChannelObject> channel_object) -> ChannelObject*;
+
+auto GPGFRONTEND_CORE_EXPORT
+GetGlobalFunctionObjectTypeLock(const std::type_info& type) -> std::mutex&;
+
+/**
+ * @brief
+ *
+ * @tparam T
+ */
+template <typename T>
+class SingletonFunctionObject : public ChannelObject {
+ public:
+ /**
+ * @brief prohibit copy
+ *
+ */
+ SingletonFunctionObject(const SingletonFunctionObject<T>&) = delete;
+
+ /**
+ * @brief prohibit copy
+ *
+ * @return SingletonFunctionObject&
+ */
+ auto operator=(const SingletonFunctionObject<T>&)
+ -> SingletonFunctionObject& = delete;
+
+ /**
+ * @brief Get the Instance object
+ *
+ * @param channel
+ * @return T&
+ */
+ static auto GetInstance(int channel = GpgFrontend::kGpgFrontendDefaultChannel)
+ -> T& {
+ static_assert(std::is_base_of_v<SingletonFunctionObject<T>, T>,
+ "T not derived from SingletonFunctionObject<T>");
+
+ const auto& type = typeid(T);
+ std::lock_guard<std::mutex> guard(GetGlobalFunctionObjectTypeLock(type));
+ auto* channel_object = GetChannelObjectInstance(type, channel);
+ if (channel_object == nullptr) {
+ channel_object = CreateChannelObjectInstance(
+ type, channel,
+ ConvertToChannelObjectPtr(SecureCreateUniqueObject<T>(channel)));
+ }
+ return *static_cast<T*>(channel_object);
+ }
+
+ /**
+ * @brief Create a Instance object
+ *
+ * @param channel
+ * @param factory
+ * @return T&
+ */
+ static auto CreateInstance(
+ int channel, const std::function<ChannelObjectPtr(void)>& factory) -> T& {
+ static_assert(std::is_base_of_v<SingletonFunctionObject<T>, T>,
+ "T not derived from SingletonFunctionObject<T>");
+
+ const auto& type = typeid(T);
+ std::lock_guard<std::mutex> guard(GetGlobalFunctionObjectTypeLock(type));
+ return *static_cast<T*>(
+ CreateChannelObjectInstance(type, channel, factory()));
+ }
+
+ /**
+ * @brief
+ *
+ * @param channel
+ * @return T&
+ */
+ static void ReleaseChannel(int channel) {
+ SingletonStorageCollection::GetInstance(false)
+ ->GetSingletonStorage(typeid(T))
+ ->ReleaseChannel(channel);
+ }
+
+ /**
+ * @brief Get the Default Channel object
+ *
+ * @return int
+ */
+ static auto GetDefaultChannel() -> int {
+ return ChannelObject::GetDefaultChannel();
+ }
+
+ /**
+ * @brief Get the Channel object
+ *
+ * @return int
+ */
+ [[nodiscard]] auto GetChannel() const -> int {
+ return ChannelObject::GetChannel();
+ }
+
+ /**
+ * @brief Get all the channel ids
+ *
+ * @return std::vector<int>
+ */
+ static auto GetAllChannelId() -> std::vector<int> {
+ return SingletonStorageCollection::GetInstance(false)
+ ->GetSingletonStorage(typeid(T))
+ ->GetAllChannelId();
+ }
+
+ /**
+ * @brief Construct a new Singleton Function Object object
+ *
+ */
+ SingletonFunctionObject(T&&) = delete;
+
+ /**
+ * @brief Construct a new Singleton Function Object object
+ *
+ */
+ SingletonFunctionObject(const T&) = delete;
+
+ /**
+ * @brief
+ *
+ */
+ void operator=(const T&) = delete;
+
+ protected:
+ /**
+ * @brief Construct a new Singleton Function Object object
+ *
+ */
+ SingletonFunctionObject() = default;
+
+ /**
+ * @brief Construct a new Singleton Function Object object
+ *
+ * @param channel
+ */
+ explicit SingletonFunctionObject(int channel)
+ : ChannelObject(channel, typeid(T).name()) {}
+
+ /**
+ * @brief Destroy the Singleton Function Object object
+ *
+ */
+ virtual ~SingletonFunctionObject() = default;
+};
+} // namespace GpgFrontend
diff --git a/src/core/function/basic/SingletonStorage.cpp b/src/core/function/basic/SingletonStorage.cpp
new file mode 100644
index 00000000..eab71e0f
--- /dev/null
+++ b/src/core/function/basic/SingletonStorage.cpp
@@ -0,0 +1,133 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "SingletonStorage.h"
+
+#include <shared_mutex>
+
+#include "core/function/basic/ChannelObject.h"
+#include "utils/MemoryUtils.h"
+
+namespace GpgFrontend {
+
+class SingletonStorage::Impl {
+ public:
+ void ReleaseChannel(int channel) {
+ decltype(instances_map_.end()) ins_it;
+ {
+ std::shared_lock<std::shared_mutex> lock(instances_mutex_);
+ ins_it = instances_map_.find(channel);
+ }
+ if (ins_it != instances_map_.end()) instances_map_.erase(ins_it);
+ }
+
+ auto FindObjectInChannel(int channel) -> GpgFrontend::ChannelObject* {
+ // read instances_map_
+ decltype(instances_map_.end()) ins_it;
+ {
+ std::shared_lock<std::shared_mutex> lock(instances_mutex_);
+ ins_it = instances_map_.find(channel);
+ if (ins_it == instances_map_.end()) {
+ GF_DEFAULT_LOG_TRACE("cannot find channel object, channel: {}",
+ channel);
+ return nullptr;
+ }
+ return ins_it->second.get();
+ }
+ }
+
+ auto GetAllChannelId() -> std::vector<int> {
+ std::vector<int> channels;
+ channels.reserve(instances_map_.size());
+ for (const auto& [key, value] : instances_map_) {
+ channels.push_back(key);
+ }
+ return channels;
+ }
+
+ auto SetObjectInChannel(int channel, ChannelObjectPtr p_obj)
+ -> GpgFrontend::ChannelObject* {
+ GF_DEFAULT_LOG_TRACE(
+ "set channel object, type: {} in channel: {}, address: {}",
+ typeid(p_obj.get()).name(), channel, static_cast<void*>(p_obj.get()));
+
+ assert(p_obj != nullptr);
+ if (p_obj == nullptr) {
+ GF_DEFAULT_LOG_ERROR(
+ "cannot set a nullptr as a channel obejct of channel: {}", channel);
+ return nullptr;
+ }
+
+ p_obj->SetChannel(channel);
+ auto* raw_obj = p_obj.get();
+
+ {
+ GF_DEFAULT_LOG_TRACE(
+ "register channel object to instances map, "
+ "channel: {}, address: {}",
+ channel, static_cast<void*>(p_obj.get()));
+ std::unique_lock<std::shared_mutex> lock(instances_mutex_);
+ instances_map_[channel] = std::move(p_obj);
+ }
+
+ GF_DEFAULT_LOG_TRACE(
+ "set channel: {} success, current channel object address: {}", channel,
+ static_cast<void*>(raw_obj));
+ return raw_obj;
+ }
+
+ private:
+ std::shared_mutex instances_mutex_; ///< mutex for _instances_map
+ std::map<int, ChannelObjectPtr>
+ instances_map_; ///< map of singleton instances
+};
+
+SingletonStorage::SingletonStorage() noexcept
+ : p_(SecureCreateUniqueObject<Impl>()) {}
+
+SingletonStorage::~SingletonStorage() = default;
+
+void SingletonStorage::ReleaseChannel(int channel) {
+ p_->ReleaseChannel(channel);
+}
+
+auto SingletonStorage::FindObjectInChannel(int channel)
+ -> GpgFrontend::ChannelObject* {
+ return p_->FindObjectInChannel(channel);
+}
+
+auto SingletonStorage::GetAllChannelId() -> std::vector<int> {
+ return p_->GetAllChannelId();
+}
+
+auto SingletonStorage::SetObjectInChannel(int channel, ChannelObjectPtr p_obj)
+ -> GpgFrontend::ChannelObject* {
+ return p_->SetObjectInChannel(channel, std::move(p_obj));
+}
+
+}; // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/basic/SingletonStorage.h b/src/core/function/basic/SingletonStorage.h
new file mode 100644
index 00000000..0ef47443
--- /dev/null
+++ b/src/core/function/basic/SingletonStorage.h
@@ -0,0 +1,90 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/function/SecureMemoryAllocator.h"
+
+namespace GpgFrontend {
+
+class ChannelObject;
+
+using ChannelObjectPtr = SecureUniquePtr<ChannelObject>;
+
+class GPGFRONTEND_CORE_EXPORT SingletonStorage {
+ public:
+ /**
+ * @brief
+ *
+ */
+ SingletonStorage() noexcept;
+
+ /**
+ * @brief
+ *
+ */
+ ~SingletonStorage();
+
+ /**
+ * @brief
+ *
+ * @param channel
+ */
+ void ReleaseChannel(int channel);
+
+ /**
+ * @brief
+ *
+ * @param channel
+ * @return T*
+ */
+ auto FindObjectInChannel(int channel) -> ChannelObject*;
+
+ /**
+ * @brief Get all the channel ids
+ *
+ * @return std::vector<int>
+ */
+ auto GetAllChannelId() -> std::vector<int>;
+
+ /**
+ * @brief Set a new object in channel object
+ *
+ * @param channel
+ * @param p_obj
+ * @return T*
+ */
+ auto SetObjectInChannel(int channel, ChannelObjectPtr p_obj)
+ -> ChannelObject*;
+
+ private:
+ class Impl;
+ SecureUniquePtr<Impl> p_;
+};
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/basic/SingletonStorageCollection.cpp b/src/core/function/basic/SingletonStorageCollection.cpp
new file mode 100644
index 00000000..c22b5242
--- /dev/null
+++ b/src/core/function/basic/SingletonStorageCollection.cpp
@@ -0,0 +1,124 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "SingletonStorageCollection.h"
+
+#include <memory>
+#include <shared_mutex>
+
+#include "core/function/SecureMemoryAllocator.h"
+#include "core/function/basic/SingletonStorage.h"
+#include "core/utils/MemoryUtils.h"
+
+namespace GpgFrontend {
+
+SecureUniquePtr<SingletonStorageCollection> global_instance = nullptr;
+
+class SingletonStorageCollection::Impl {
+ public:
+ /**
+ * @brief Get the Instance object
+ *
+ * @return SingletonStorageCollection*
+ */
+ static auto GetInstance(bool force_refresh) -> SingletonStorageCollection* {
+ if (force_refresh || global_instance == nullptr) {
+ global_instance = SecureCreateUniqueObject<SingletonStorageCollection>();
+ GF_DEFAULT_LOG_TRACE(
+ "a new global singleton storage collection created, address: {}",
+ static_cast<void*>(global_instance.get()));
+ }
+ return global_instance.get();
+ }
+
+ /**
+ * @brief Get the Instance object
+ *
+ * @return SingletonStorageCollection*
+ */
+ static void Destroy() { global_instance = nullptr; }
+
+ /**
+ * @brief Get the Singleton Storage object
+ *
+ * @param singleton_function_object
+ * @return SingletonStorage*
+ */
+ auto GetSingletonStorage(const std::type_info& type_id) -> SingletonStorage* {
+ const auto hash = type_id.hash_code();
+
+ while (true) {
+ decltype(storages_map_.end()) ins_it;
+ {
+ std::shared_lock<std::shared_mutex> lock(storages_mutex_);
+ ins_it = storages_map_.find(hash);
+ }
+ if (ins_it == storages_map_.end()) {
+ auto storage = SecureCreateUniqueObject<SingletonStorage>();
+ GF_DEFAULT_LOG_TRACE(
+ "hash: {} created, singleton storage address: {} type_name: {}",
+ hash, static_cast<void*>(storage.get()), type_id.name());
+
+ {
+ std::unique_lock<std::shared_mutex> lock(storages_mutex_);
+ storages_map_.insert({hash, std::move(storage)});
+ }
+ continue;
+ }
+ return ins_it->second.get();
+ }
+ }
+
+ private:
+ std::shared_mutex storages_mutex_; ///< mutex for storages_map_
+ std::map<size_t, SingletonStoragePtr> storages_map_;
+};
+
+SingletonStorageCollection::SingletonStorageCollection() noexcept
+ : p_(SecureCreateUniqueObject<Impl>()) {}
+
+SingletonStorageCollection::~SingletonStorageCollection() = default;
+
+auto GpgFrontend::SingletonStorageCollection::GetInstance(bool force_refresh)
+ -> GpgFrontend::SingletonStorageCollection* {
+ return Impl::GetInstance(force_refresh);
+}
+
+void SingletonStorageCollection::Destroy() {
+ GF_DEFAULT_LOG_TRACE(
+ "global singleton storage collection is about to destroy, address: {}",
+ static_cast<void*>(global_instance.get()));
+ return SingletonStorageCollection::Impl::Destroy();
+}
+
+auto SingletonStorageCollection::GetSingletonStorage(
+ const std::type_info& type_id) -> GpgFrontend::SingletonStorage* {
+ return p_->GetSingletonStorage(type_id);
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/basic/SingletonStorageCollection.h b/src/core/function/basic/SingletonStorageCollection.h
new file mode 100644
index 00000000..38ced83b
--- /dev/null
+++ b/src/core/function/basic/SingletonStorageCollection.h
@@ -0,0 +1,79 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/function/SecureMemoryAllocator.h"
+
+namespace GpgFrontend {
+class SingletonStorage;
+
+using SingletonStoragePtr =
+ std::unique_ptr<SingletonStorage, SecureObjectDeleter<SingletonStorage>>;
+
+class GPGFRONTEND_CORE_EXPORT SingletonStorageCollection {
+ public:
+ /**
+ * @brief
+ *
+ */
+ SingletonStorageCollection() noexcept;
+
+ /**
+ * @brief
+ *
+ */
+ ~SingletonStorageCollection();
+
+ /**
+ * @brief Get the Instance object
+ *
+ * @return SingletonStorageCollection*
+ */
+ static auto GetInstance(bool force_refresh) -> SingletonStorageCollection*;
+
+ /**
+ * @brief
+ *
+ */
+ static void Destroy();
+
+ /**
+ * @brief Get the Singleton Storage object
+ *
+ * @param singleton_function_object
+ * @return SingletonStorage*
+ */
+ auto GetSingletonStorage(const std::type_info&) -> SingletonStorage*;
+
+ private:
+ class Impl;
+ SecureUniquePtr<Impl> p_;
+};
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/gpg/GpgAdvancedOperator.cpp b/src/core/function/gpg/GpgAdvancedOperator.cpp
index 2a3bba42..8b60003c 100644
--- a/src/core/function/gpg/GpgAdvancedOperator.cpp
+++ b/src/core/function/gpg/GpgAdvancedOperator.cpp
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2023. Saturneric
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
- * This file is part of GpgFrontend.
+ * 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
@@ -20,9 +20,10 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
+ *
*/
//
@@ -32,152 +33,189 @@
#include "GpgAdvancedOperator.h"
#include "core/function/gpg/GpgCommandExecutor.h"
-#include "spdlog/spdlog.h"
-
-GpgFrontend::GpgAdvancedOperator::GpgAdvancedOperator(int channel)
- : SingletonFunctionObject(channel) {}
-
-bool GpgFrontend::GpgAdvancedOperator::ClearGpgPasswordCache() {
- bool success = false;
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().GpgConfPath, {"--reload", "gpg-agent"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- SPDLOG_DEBUG("gpgconf reload exit code: {}", exit_code);
- success = true;
- }
- });
- return success;
+#include "core/module/ModuleManager.h"
+
+void GpgFrontend::GpgAdvancedOperator::ClearGpgPasswordCache(
+ OperationCallback cb) {
+ const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gpgconf_path", QString{});
+ GF_CORE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path);
+
+ if (gpgconf_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid gpgconf path from rt, abort.");
+ cb(-1, TransferParams());
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {gpgconf_path,
+ {"--reload", "gpg-agent"},
+ [=](int exit_code, const QString & /*p_out*/,
+ const QString & /*p_err*/) {
+ GF_CORE_LOG_DEBUG("gpgconf reload exit code: {}", exit_code);
+ cb(exit_code == 0 ? 0 : -1, TransferParams());
+ }});
}
-bool GpgFrontend::GpgAdvancedOperator::ReloadGpgComponents() {
- bool success = false;
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().GpgConfPath, {"--reload"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- success = true;
- } else {
- SPDLOG_ERROR(
- "gpgconf execute error, process stderr: {}, process stdout: {}",
- p_err, p_out);
- return;
- }
- });
- return success;
+void GpgFrontend::GpgAdvancedOperator::ReloadGpgComponents(
+ OperationCallback cb) {
+ const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gpgconf_path", QString{});
+ GF_CORE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path);
+
+ if (gpgconf_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid gpgconf path from rt, abort.");
+ cb(-1, TransferParams());
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {gpgconf_path,
+ {"--reload"},
+ [=](int exit_code, const QString &, const QString &) {
+ GF_CORE_LOG_DEBUG("gpgconf reload exit code: {}", exit_code);
+ cb(exit_code == 0 ? 0 : -1, TransferParams());
+ }});
}
-bool GpgFrontend::GpgAdvancedOperator::RestartGpgComponents() {
- bool success = false;
-
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().GpgConfPath, {"--verbose", "--kill", "all"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- success = true;
- return;
- } else {
- SPDLOG_ERROR(
- "gpgconf execute error, process stderr: {}, process stdout: {}",
- p_err, p_out);
- return;
- }
- });
-
- if (!success) return false;
-
- success &= StartGpgAgent();
-
- success &= StartDirmngr();
-
- success &= StartKeyBoxd();
-
- return success;
+void GpgFrontend::GpgAdvancedOperator::RestartGpgComponents() {
+ const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gpgconf_path", QString{});
+ GF_CORE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path);
+
+ if (gpgconf_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid gpgconf path from rt, abort.");
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {gpgconf_path,
+ {"--verbose", "--kill", "all"},
+ [=](int exit_code, const QString &p_out, const QString &p_err) {
+ GF_CORE_LOG_DEBUG("gpgconf --kill all command got exit code: {}",
+ exit_code);
+ bool success = true;
+ if (exit_code != 0) {
+ success = false;
+ GF_CORE_LOG_ERROR(
+ "gpgconf execute error, process stderr: {}, process stdout: {}",
+ p_err, p_out);
+ return;
+ }
+
+ GF_CORE_LOG_DEBUG("gpgconf --kill --all execute result: {}", success);
+ if (!success) {
+ GF_CORE_LOG_ERROR(
+ "restart all component after core initilized failed");
+ Module::UpsertRTValue(
+ "core", "gpg_advanced_operator.restart_gpg_components", false);
+ return;
+ }
+
+ StartGpgAgent([](int err, DataObjectPtr) {
+ if (err >= 0) {
+ Module::UpsertRTValue(
+ "core", "gpg_advanced_operator.restart_gpg_components", true);
+ return;
+ }
+ });
+ }});
}
-bool GpgFrontend::GpgAdvancedOperator::ResetConfigures() {
- bool success = false;
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().GpgConfPath, {"--apply-defaults"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- success = true;
- } else {
- SPDLOG_ERROR(
- "gpgconf execute error, process stderr: {}, process stdout: {}",
- p_err, p_out);
- return;
- }
- });
-
- return success;
+void GpgFrontend::GpgAdvancedOperator::ResetConfigures(OperationCallback cb) {
+ const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gpgconf_path", QString{});
+ GF_CORE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path);
+
+ if (gpgconf_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid gpgconf path from rt, abort.");
+ cb(-1, TransferParams());
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {gpgconf_path,
+ {"--apply-defaults"},
+ [=](int exit_code, const QString &, const QString &) {
+ GF_CORE_LOG_DEBUG("gpgconf apply-defaults exit code: {}", exit_code);
+ cb(exit_code == 0 ? 0 : -1, TransferParams());
+ }});
}
-bool GpgFrontend::GpgAdvancedOperator::StartGpgAgent() {
- bool success = false;
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().GpgAgentPath,
- {"--homedir", ctx_.GetInfo().GnuPGHomePath, "--daemon"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- success = true;
- SPDLOG_INFO("start gpg-agent successfully");
- } else if (exit_code == 2) {
- success = true;
- SPDLOG_INFO("gpg-agent already started");
- } else {
- SPDLOG_ERROR(
- "gpg-agent execute error, process stderr: {}, process stdout: {}",
- p_err, p_out);
- return;
- }
- });
-
- return success;
+void GpgFrontend::GpgAdvancedOperator::StartGpgAgent(OperationCallback cb) {
+ const auto gpg_agent_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ "gnupg.gpg_agent_path", QString{});
+ GF_CORE_LOG_DEBUG("got gnupg agent path from rt: {}", gpg_agent_path);
+
+ const auto home_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ "gnupg.home_path", QString{});
+ GF_CORE_LOG_DEBUG("got gnupg home path from rt: {}", home_path);
+
+ if (gpg_agent_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid gpg agent path from rt, abort.");
+ cb(-1, TransferParams());
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {gpg_agent_path,
+ {"--homedir", home_path, "--daemon"},
+ [=](int exit_code, const QString &, const QString &) {
+ GF_CORE_LOG_DEBUG("gpgconf daemon exit code: {}", exit_code);
+ cb(exit_code >= 0 ? 0 : -1, TransferParams());
+ }});
}
-bool GpgFrontend::GpgAdvancedOperator::StartDirmngr() {
- bool success = false;
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().DirmngrPath,
- {"--homedir", ctx_.GetInfo().GnuPGHomePath, "--daemon"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- success = true;
- SPDLOG_INFO("start dirmngr successfully");
- } else if (exit_code == 2) {
- success = true;
- SPDLOG_INFO("dirmngr already started");
- } else {
- SPDLOG_ERROR(
- "dirmngr execute error, process stderr: {}, process stdout: {}",
- p_err, p_out);
- return;
- }
- });
-
- return success;
+void GpgFrontend::GpgAdvancedOperator::StartDirmngr(OperationCallback cb) {
+ const auto dirmngr_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ "gnupg.dirmngr_path", QString{});
+ GF_CORE_LOG_DEBUG("got gnupg dirmngr path from rt: {}", dirmngr_path);
+
+ const auto home_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ "gnupg.home_path", QString{});
+ GF_CORE_LOG_DEBUG("got gnupg home path from rt: {}", home_path);
+
+ if (dirmngr_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid dirmngr path from rt, abort.");
+ cb(-1, TransferParams());
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {dirmngr_path,
+ {"--homedir", home_path, "--daemon"},
+ [=](int exit_code, const QString &, const QString &) {
+ GF_CORE_LOG_DEBUG("gpgconf daemon exit code: {}", exit_code);
+ cb(exit_code >= 0 ? 0 : -1, TransferParams());
+ }});
}
-bool GpgFrontend::GpgAdvancedOperator::StartKeyBoxd() {
- bool success = false;
- GpgFrontend::GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().KeyboxdPath,
- {"--homedir", ctx_.GetInfo().GnuPGHomePath, "--daemon"},
- [&](int exit_code, const std::string &p_out, const std::string &p_err) {
- if (exit_code == 0) {
- success = true;
- SPDLOG_INFO("start keyboxd successfully");
- } else if (exit_code == 2) {
- success = true;
- SPDLOG_INFO("keyboxd already started");
- } else {
- SPDLOG_ERROR(
- "keyboxd execute error, process stderr: {}, process stdout: {}",
- p_err, p_out);
- return;
- }
- });
-
- return success;
+void GpgFrontend::GpgAdvancedOperator::StartKeyBoxd(OperationCallback cb) {
+ const auto keyboxd_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ "gnupg.keyboxd_path", QString{});
+ GF_CORE_LOG_DEBUG("got gnupg keyboxd path from rt: {}", keyboxd_path);
+
+ const auto home_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ "gnupg.home_path", QString{});
+ GF_CORE_LOG_DEBUG("got gnupg home path from rt: {}", home_path);
+
+ if (keyboxd_path.isEmpty()) {
+ GF_CORE_LOG_ERROR("cannot get valid keyboxd path from rt, abort.");
+ cb(-1, TransferParams());
+ return;
+ }
+
+ GpgFrontend::GpgCommandExecutor::ExecuteSync(
+ {keyboxd_path,
+ {"--homedir", home_path, "--daemon"},
+ [=](int exit_code, const QString &, const QString &) {
+ GF_CORE_LOG_DEBUG("gpgconf daemon exit code: {}", exit_code);
+ cb(exit_code >= 0 ? 0 : -1, TransferParams());
+ }});
}
diff --git a/src/core/function/gpg/GpgAdvancedOperator.h b/src/core/function/gpg/GpgAdvancedOperator.h
index 5325020a..d6b57095 100644
--- a/src/core/function/gpg/GpgAdvancedOperator.h
+++ b/src/core/function/gpg/GpgAdvancedOperator.h
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2023. Saturneric
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
- * This file is part of GpgFrontend.
+ * 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
@@ -20,42 +20,31 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
+ *
*/
//
// Created by eric on 07.01.2023.
//
-#ifndef GPGFRONTEND_GPGADVANCEDOPERATOR_H
-#define GPGFRONTEND_GPGADVANCEDOPERATOR_H
+#pragma once
-#include "core/GpgConstants.h"
-#include "core/GpgContext.h"
-#include "core/GpgFunctionObject.h"
+#include "core/typedef/CoreTypedef.h"
namespace GpgFrontend {
-class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
- : public SingletonFunctionObject<GpgAdvancedOperator> {
+class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator {
public:
/**
- * @brief Construct a new Basic Operator object
- *
- * @param channel Channel corresponding to the context
- */
- explicit GpgAdvancedOperator(
- int channel = SingletonFunctionObject::GetDefaultChannel());
-
- /**
* @brief
*
* @return true
* @return false
*/
- bool ClearGpgPasswordCache();
+ static void ClearGpgPasswordCache(OperationCallback);
/**
* @brief
@@ -63,7 +52,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
* @return true
* @return false
*/
- bool ReloadGpgComponents();
+ static void ReloadGpgComponents(OperationCallback);
/**
* @brief
@@ -71,7 +60,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
* @return true
* @return false
*/
- bool RestartGpgComponents();
+ static void RestartGpgComponents();
/**
* @brief
@@ -79,7 +68,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
* @return true
* @return false
*/
- bool ResetConfigures();
+ static void ResetConfigures(OperationCallback);
/**
* @brief
@@ -87,7 +76,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
* @return true
* @return false
*/
- bool StartGpgAgent();
+ static void StartGpgAgent(OperationCallback);
/**
* @brief
@@ -95,7 +84,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
* @return true
* @return false
*/
- bool StartDirmngr();
+ static void StartDirmngr(OperationCallback);
/**
* @brief
@@ -103,13 +92,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator
* @return true
* @return false
*/
- bool StartKeyBoxd();
-
- private:
- GpgContext& ctx_ = GpgContext::GetInstance(
- SingletonFunctionObject::GetChannel()); ///< Corresponding context
+ static void StartKeyBoxd(OperationCallback);
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGADVANCEDOPERATOR_H
diff --git a/src/core/function/gpg/GpgBasicOperator.cpp b/src/core/function/gpg/GpgBasicOperator.cpp
index 71f84907..e5916c77 100644
--- a/src/core/function/gpg/GpgBasicOperator.cpp
+++ b/src/core/function/gpg/GpgBasicOperator.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,195 +28,213 @@
#include "GpgBasicOperator.h"
-#include <vector>
+#include <gpg-error.h>
-#include "GpgKeyGetter.h"
+#include "core/GpgModel.h"
+#include "core/model/GpgDecryptResult.h"
+#include "core/model/GpgEncryptResult.h"
+#include "core/model/GpgSignResult.h"
+#include "core/model/GpgVerifyResult.h"
+#include "core/utils/AsyncUtils.h"
+#include "core/utils/GpgUtils.h"
-GpgFrontend::GpgBasicOperator::GpgBasicOperator(int channel)
- : SingletonFunctionObject<GpgBasicOperator>(channel) {}
-
-GpgFrontend::GpgError GpgFrontend::GpgBasicOperator::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];
+namespace GpgFrontend {
- int index = 0;
- for (const auto& key : *keys) recipients[index++] = gpgme_key_t(key);
+GpgBasicOperator::GpgBasicOperator(int channel)
+ : SingletonFunctionObject<GpgBasicOperator>(channel) {}
- // Last entry data_in array has to be nullptr
- recipients[keys->size()] = nullptr;
+void GpgBasicOperator::Encrypt(KeyArgsList keys, GFBuffer in_buffer, bool ascii,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync([=](const DataObjectPtr& data_object) -> GpgError {
+ if (keys.empty()) return GPG_ERR_CANCELED;
- GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
- gpgme_error_t err = check_gpg_error(gpgme_op_encrypt(
- ctx_, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out));
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
- auto temp_data_out = data_out.Read2Buffer();
- std::swap(temp_data_out, out_buffer);
+ GpgData data_in(in_buffer);
+ GpgData data_out;
- auto temp_result = _new_result(gpgme_op_encrypt_result(ctx_));
- std::swap(result, temp_result);
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ data_out.Read2GFBuffer()});
- return err;
+ return err;
+ },
+ cb, "gpgme_op_encrypt", "2.1.0");
}
-GpgFrontend::GpgError GpgFrontend::GpgBasicOperator::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 = _new_result(gpgme_op_decrypt_result(ctx_));
- std::swap(result, temp_result);
-
- return err;
+void GpgBasicOperator::Decrypt(GFBuffer in_buffer,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_buffer);
+ GpgData data_out;
+
+ auto err = CheckGpgError(
+ gpgme_op_decrypt(ctx_.DefaultContext(), data_in, data_out));
+ data_object->Swap(
+ {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())),
+ data_out.Read2GFBuffer()});
+
+ return err;
+ },
+ cb, "gpgme_op_decrypt", "2.1.0");
}
-GpgFrontend::GpgError GpgFrontend::GpgBasicOperator::Verify(
- BypeArrayRef& in_buffer, ByteArrayPtr& sig_buffer,
- GpgVerifyResult& result) const {
- gpgme_error_t err;
-
- GpgData data_in(in_buffer.data(), in_buffer.size());
- GpgData data_out;
-
- if (sig_buffer != nullptr && sig_buffer->size() > 0) {
- 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_out));
-
- auto temp_result = _new_result(gpgme_op_verify_result(ctx_));
- std::swap(result, temp_result);
-
- return err;
+void GpgBasicOperator::Verify(GFBuffer in_buffer, GFBuffer sig_buffer,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ GpgData data_in(in_buffer);
+ GpgData data_out;
+
+ if (!sig_buffer.Empty()) {
+ GpgData sig_data(sig_buffer);
+ err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), sig_data,
+ data_in, nullptr));
+ } else {
+ err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), data_in,
+ nullptr, data_out));
+ }
+
+ data_object->Swap({
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ });
+
+ return err;
+ },
+ cb, "gpgme_op_verify", "2.1.0");
}
-GpgFrontend::GpgError GpgFrontend::GpgBasicOperator::Sign(
- KeyListPtr signers, BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
- gpgme_sig_mode_t mode, GpgSignResult& result) {
- gpgme_error_t err;
-
- // Set Singers of this opera
- SetSigners(*signers);
+void GpgBasicOperator::Sign(KeyArgsList signers, GFBuffer in_buffer,
+ GpgSignMode mode, bool ascii,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ if (signers.empty()) return GPG_ERR_CANCELED;
- GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
+ GpgError err;
- err = check_gpg_error(gpgme_op_sign(ctx_, data_in, data_out, mode));
+ // Set Singers of this opera
+ SetSigners(signers, ascii);
- auto temp_data_out = data_out.Read2Buffer();
- std::swap(temp_data_out, out_buffer);
+ GpgData data_in(in_buffer);
+ GpgData data_out;
- auto temp_result = _new_result(gpgme_op_sign_result(ctx_));
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(gpgme_op_sign(ctx, data_in, data_out, mode));
- std::swap(result, temp_result);
-
- return err;
+ data_object->Swap({GpgSignResult(gpgme_op_sign_result(ctx)),
+ data_out.Read2GFBuffer()});
+ return err;
+ },
+ cb, "gpgme_op_sign", "2.1.0");
}
-gpgme_error_t GpgFrontend::GpgBasicOperator::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));
+void GpgBasicOperator::DecryptVerify(GFBuffer in_buffer,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
- auto temp_data_out = data_out.Read2Buffer();
- std::swap(temp_data_out, out_buffer);
+ GpgData data_in(in_buffer);
+ GpgData data_out;
- auto temp_decr_result = _new_result(gpgme_op_decrypt_result(ctx_));
- std::swap(decrypt_result, temp_decr_result);
+ err = CheckGpgError(
+ gpgme_op_decrypt_verify(ctx_.DefaultContext(), data_in, data_out));
- auto temp_verify_result = _new_result(gpgme_op_verify_result(ctx_));
- std::swap(verify_result, temp_verify_result);
+ data_object->Swap(
+ {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())),
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ data_out.Read2GFBuffer()});
- return err;
+ return err;
+ },
+ cb, "gpgme_op_decrypt_verify", "2.1.0");
}
-gpgme_error_t GpgFrontend::GpgBasicOperator::EncryptSign(
- KeyListPtr keys, KeyListPtr signers, BypeArrayRef in_buffer,
- ByteArrayPtr& out_buffer, GpgEncrResult& encr_result,
- GpgSignResult& sign_result) {
- gpgme_error_t err;
- SetSigners(*signers);
+void GpgBasicOperator::EncryptSign(KeyArgsList keys, KeyArgsList signers,
+ GFBuffer in_buffer, bool ascii,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ if (keys.empty() || signers.empty()) return GPG_ERR_CANCELED;
- // gpgme_encrypt_result_t e_result;
- gpgme_key_t recipients[keys->size() + 1];
+ GpgError err;
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
- // set key for user
- int index = 0;
- for (const auto& key : *keys) recipients[index++] = gpgme_key_t(key);
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
- // Last entry dataIn array has to be nullptr
- recipients[keys->size()] = nullptr;
+ SetSigners(signers, ascii);
- GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
+ GpgData data_in(in_buffer);
+ GpgData 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* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(gpgme_op_encrypt_sign(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
- auto temp_data_out = data_out.Read2Buffer();
- std::swap(temp_data_out, out_buffer);
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ GpgSignResult(gpgme_op_sign_result(ctx)),
+ data_out.Read2GFBuffer()});
+ return err;
+ },
+ cb, "gpgme_op_encrypt_sign", "2.1.0");
+}
- auto temp_encr_result = _new_result(gpgme_op_encrypt_result(ctx_));
- swap(encr_result, temp_encr_result);
- auto temp_sign_result = _new_result(gpgme_op_sign_result(ctx_));
- swap(sign_result, temp_sign_result);
+void GpgBasicOperator::SetSigners(const KeyArgsList& signers, bool ascii) {
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
- return err;
-}
+ gpgme_signers_clear(ctx);
-void GpgFrontend::GpgBasicOperator::SetSigners(KeyArgsList& signers) {
- gpgme_signers_clear(ctx_);
for (const GpgKey& key : signers) {
- SPDLOG_DEBUG("key fpr: {}", key.GetFingerprint());
+ GF_CORE_LOG_DEBUG("key fpr: {}", key.GetFingerprint());
if (key.IsHasActualSigningCapability()) {
- SPDLOG_DEBUG("signer");
- auto error = gpgme_signers_add(ctx_, gpgme_key_t(key));
- check_gpg_error(error);
+ GF_CORE_LOG_DEBUG("signer");
+ auto error = gpgme_signers_add(ctx, gpgme_key_t(key));
+ CheckGpgError(error);
}
}
- if (signers.size() != gpgme_signers_count(ctx_))
- SPDLOG_DEBUG("not all signers added");
+ if (signers.size() != gpgme_signers_count(ctx_.DefaultContext()))
+ GF_CORE_LOG_DEBUG("not all signers added");
}
-std::unique_ptr<GpgFrontend::KeyArgsList>
-GpgFrontend::GpgBasicOperator::GetSigners() {
- auto count = gpgme_signers_count(ctx_);
+auto GpgBasicOperator::GetSigners(bool ascii) -> std::unique_ptr<KeyArgsList> {
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+
+ 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));
+ for (auto i = 0U; i < count; i++) {
+ auto key = GpgKey(gpgme_signers_enum(ctx, i));
signers->push_back(GpgKey(std::move(key)));
}
return signers;
}
-gpg_error_t GpgFrontend::GpgBasicOperator::EncryptSymmetric(
- GpgFrontend::ByteArray& in_buffer, GpgFrontend::ByteArrayPtr& out_buffer,
- GpgFrontend::GpgEncrResult& result) {
- // deepcopy from ByteArray to GpgData
- GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
-
- gpgme_error_t err = check_gpg_error(gpgme_op_encrypt(
- ctx_, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out));
-
- auto temp_data_out = data_out.Read2Buffer();
- std::swap(temp_data_out, out_buffer);
-
- // TODO(Saturneric): maybe a bug of gpgme
- if (gpgme_err_code(err) == GPG_ERR_NO_ERROR) {
- auto temp_result = _new_result(gpgme_op_encrypt_result(ctx_));
- std::swap(result, temp_result);
- }
-
- return err;
+void GpgBasicOperator::EncryptSymmetric(GFBuffer in_buffer, bool ascii,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_buffer);
+ GpgData data_out;
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(
+ ctx, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out));
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ data_out.Read2GFBuffer()});
+
+ return err;
+ },
+ cb, "gpgme_op_encrypt_symmetric", "2.1.0");
}
+} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgBasicOperator.h b/src/core/function/gpg/GpgBasicOperator.h
index 696ac9dc..4b1a2688 100644
--- a/src/core/function/gpg/GpgBasicOperator.h
+++ b/src/core/function/gpg/GpgBasicOperator.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,19 +20,20 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H
-#define GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H
+#pragma once
-#include "core/GpgConstants.h"
-#include "core/GpgContext.h"
-#include "core/GpgFunctionObject.h"
-#include "core/GpgModel.h"
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/function/result_analyse/GpgResultAnalyse.h"
+#include "core/model/GFBuffer.h"
+#include "core/typedef/CoreTypedef.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
@@ -52,19 +53,13 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
int channel = SingletonFunctionObject::GetDefaultChannel());
/**
- * @brief Call the interface provided by gpgme for encryption operation
+ * @brief
*
* All incoming data pointers out_buffer will be replaced with new valid
* values
*
- * @param keys list of public keys
- * @param in_buffer data that needs to be encrypted
- * @param out_buffer encrypted data
- * @param result the result of the operation
- * @return error code
*/
- gpg_error_t Encrypt(KeyListPtr keys, BypeArrayRef in_buffer,
- ByteArrayPtr& out_buffer, GpgEncrResult& result);
+ void Encrypt(KeyArgsList, GFBuffer, bool, const GpgOperationCallback&);
/**
* @brief Call the interface provided by GPGME to symmetrical encryption
@@ -72,10 +67,10 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
* @param in_buffer Data for encryption
* @param out_buffer Encrypted data
* @param result Encrypted results
- * @return gpg_error_t
+ * @return GpgError
*/
- gpg_error_t EncryptSymmetric(BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
- GpgEncrResult& result);
+ void EncryptSymmetric(GFBuffer in_buffer, bool ascii,
+ const GpgOperationCallback& cb);
/**
*
@@ -90,10 +85,8 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
* @param sign_result Signature result
* @return
*/
- gpgme_error_t EncryptSign(KeyListPtr keys, KeyListPtr signers,
- BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
- GpgEncrResult& encr_result,
- GpgSignResult& sign_result);
+ void EncryptSign(KeyArgsList keys, KeyArgsList signers, GFBuffer in_buffer,
+ bool ascii, const GpgOperationCallback& cb);
/**
* @brief Call the interface provided by gpgme for decryption operation
@@ -103,8 +96,7 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
* @param result the result of the operation
* @return error code
*/
- gpgme_error_t Decrypt(BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
- GpgDecrResult& result);
+ void Decrypt(GFBuffer in_buffer, const GpgOperationCallback& cb);
/**
* @brief Call the interface provided by gpgme to perform decryption and
@@ -116,9 +108,7 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
* @param verify_result the result of the verifying operation
* @return error code
*/
- gpgme_error_t DecryptVerify(BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
- GpgDecrResult& decrypt_result,
- GpgVerifyResult& verify_result);
+ void DecryptVerify(GFBuffer in_buffer, const GpgOperationCallback& cb);
/**
* @brief Call the interface provided by gpgme for verification operation
@@ -128,8 +118,8 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
* @param result the result of the operation
* @return error code
*/
- gpgme_error_t Verify(BypeArrayRef in_buffer, ByteArrayPtr& sig_buffer,
- GpgVerifyResult& result) const;
+ void Verify(GFBuffer in_buffer, GFBuffer sig_buffer,
+ const GpgOperationCallback& cb);
/**
* @brief Call the interface provided by gpgme for signing operation
@@ -151,9 +141,8 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
* @param result the result of the operation
* @return error code
*/
- gpg_error_t Sign(KeyListPtr signers, BypeArrayRef in_buffer,
- ByteArrayPtr& out_buffer, gpgme_sig_mode_t mode,
- GpgSignResult& result);
+ void Sign(KeyArgsList signers, GFBuffer in_buffer, GpgSignMode mode,
+ bool ascii, const GpgOperationCallback& cb);
/**
* @brief Set the private key for signatures, this operation is a global
@@ -161,19 +150,17 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator
*
* @param keys
*/
- void SetSigners(KeyArgsList& signers);
+ void SetSigners(const KeyArgsList& signers, bool ascii);
/**
* @brief Get a global signature private keys that has been set.
*
* @return Intelligent pointer pointing to the private key list
*/
- std::unique_ptr<KeyArgsList> GetSigners();
+ auto GetSigners(bool ascii) -> std::unique_ptr<KeyArgsList>;
private:
GpgContext& ctx_ = GpgContext::GetInstance(
SingletonFunctionObject::GetChannel()); ///< Corresponding context
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H
diff --git a/src/core/function/gpg/GpgCommandExecutor.cpp b/src/core/function/gpg/GpgCommandExecutor.cpp
index 86c47c60..8c994515 100644
--- a/src/core/function/gpg/GpgCommandExecutor.cpp
+++ b/src/core/function/gpg/GpgCommandExecutor.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,252 +20,231 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "GpgCommandExecutor.h"
-#include "GpgFunctionObject.h"
+#include "core/model/DataObject.h"
+#include "core/module/Module.h"
+#include "core/thread/Task.h"
#include "core/thread/TaskRunnerGetter.h"
-GpgFrontend::GpgCommandExecutor::GpgCommandExecutor(int channel)
- : SingletonFunctionObject<GpgCommandExecutor>(channel) {}
+namespace GpgFrontend {
-void GpgFrontend::GpgCommandExecutor::Execute(
- std::string cmd, std::vector<std::string> arguments,
- std::function<void(int, std::string, std::string)> callback,
- std::function<void(QProcess *)> interact_func) {
- SPDLOG_DEBUG("called cmd {} arguments size: {}", cmd, arguments.size());
+auto BuildTaskFromExecCtx(const GpgCommandExecutor::ExecuteContext &context)
+ -> Thread::Task * {
+ const auto &cmd = context.cmd;
+ const auto &arguments = context.arguments;
+ const auto &interact_function = context.int_func;
+ const auto &cmd_executor_callback = context.cb_func;
- Thread::Task::TaskCallback result_callback =
- [](int rtn, Thread::Task::DataObjectPtr data_object) {
- SPDLOG_DEBUG("data object use count: {}", data_object.use_count());
- if (data_object->GetObjectSize() != 4)
- throw std::runtime_error("invalid data object size");
+ const QString joined_argument = QStringList::fromVector(arguments).join(" ");
+
+ GF_CORE_LOG_DEBUG("building task: called cmd {} arguments size: {}", cmd,
+ arguments.size());
- auto exit_code = data_object->PopObject<int>();
- auto process_stdout = data_object->PopObject<std::string>();
- auto process_stderr = data_object->PopObject<std::string>();
- auto callback = data_object->PopObject<
- std::function<void(int, std::string, std::string)>>();
+ Thread::Task::TaskCallback result_callback =
+ [cmd, joined_argument](int /*rtn*/, const DataObjectPtr &data_object) {
+ GF_CORE_LOG_DEBUG(
+ "data object args count of cmd executor result callback: {}",
+ data_object->GetObjectSize());
+ if (!data_object->Check<int, QString, GpgCommandExecutorCallback>()) {
+ GF_CORE_LOG_ERROR("data object checking failed");
+ return;
+ }
+
+ auto exit_code = ExtractParams<int>(data_object, 0);
+ auto process_stdout = ExtractParams<QString>(data_object, 1);
+ auto callback =
+ ExtractParams<GpgCommandExecutorCallback>(data_object, 2);
// call callback
- callback(exit_code, process_stdout, process_stderr);
+ GF_CORE_LOG_DEBUG(
+ "calling custom callback from caller of cmd {} {}, "
+ "exit_code: {}",
+ cmd, joined_argument, exit_code);
+ callback(exit_code, process_stdout, {});
};
Thread::Task::TaskRunnable runner =
- [](GpgFrontend::Thread::Task::DataObjectPtr data_object) -> int {
- SPDLOG_DEBUG("process runner called, data object size: {}",
- data_object->GetObjectSize());
+ [joined_argument](const DataObjectPtr &data_object) -> int {
+ GF_CORE_LOG_DEBUG("process runner called, data object size: {}",
+ data_object->GetObjectSize());
- if (data_object->GetObjectSize() != 4)
- throw std::runtime_error("invalid data object size");
+ if (!data_object->Check<QString, QStringList, GpgCommandExecutorInteractor,
+ GpgCommandExecutorCallback>()) {
+ GF_CORE_LOG_ERROR("data object checking failed");
+ return -1;
+ }
// get arguments
- auto cmd = data_object->PopObject<std::string>();
- SPDLOG_DEBUG("get cmd: {}", cmd);
- auto arguments = data_object->PopObject<std::vector<std::string>>();
+ auto cmd = ExtractParams<QString>(data_object, 0);
+ auto arguments = ExtractParams<QStringList>(data_object, 1);
auto interact_func =
- data_object->PopObject<std::function<void(QProcess *)>>();
+ ExtractParams<GpgCommandExecutorInteractor>(data_object, 2);
+ auto callback = ExtractParams<GpgCommandExecutorCallback>(data_object, 3);
+ // create process
auto *cmd_process = new QProcess();
+ // move to current thread
+ //
+ cmd_process->moveToThread(QThread::currentThread());
+ // set process channel mode
+ // this is to make sure we can get all output from stdout and stderr
cmd_process->setProcessChannelMode(QProcess::MergedChannels);
+ cmd_process->setProgram(cmd);
+
+ // set arguments
+ QStringList q_arguments;
+ for (const auto &argument : arguments) {
+ q_arguments.append(argument);
+ }
+ cmd_process->setArguments(q_arguments);
- QObject::connect(cmd_process, &QProcess::started,
- []() -> void { SPDLOG_DEBUG("process started"); });
+ QObject::connect(
+ cmd_process, &QProcess::started, [cmd, joined_argument]() -> void {
+ GF_CORE_LOG_DEBUG(
+ "\n== Process Execute Started ==\nCommand: {}\nArguments: "
+ "{}\n========================",
+ cmd, joined_argument);
+ });
QObject::connect(
cmd_process, &QProcess::readyReadStandardOutput,
[interact_func, cmd_process]() { interact_func(cmd_process); });
- QObject::connect(cmd_process, &QProcess::errorOccurred,
- [=](QProcess::ProcessError error) {
- SPDLOG_ERROR("error in executing command: {} error: {}",
- cmd, error);
- });
QObject::connect(
- cmd_process, qOverload<int, QProcess::ExitStatus>(&QProcess::finished),
- [=](int, QProcess::ExitStatus status) {
- if (status == QProcess::NormalExit)
- SPDLOG_DEBUG(
- "proceess finished, succeed in executing command: {}, exit "
- "status: {}",
- cmd, status);
- else
- SPDLOG_ERROR(
- "proceess finished, error in executing command: {}, exit "
- "status: {}",
- cmd, status);
+ cmd_process, &QProcess::errorOccurred,
+ [=](QProcess::ProcessError error) {
+ GF_CORE_LOG_ERROR(
+ "caught error while executing command: {} {}, error: {}", cmd,
+ joined_argument, error);
});
- cmd_process->setProgram(QString::fromStdString(cmd));
-
- QStringList q_arguments;
- for (const auto &argument : arguments)
- q_arguments.append(QString::fromStdString(argument));
- cmd_process->setArguments(q_arguments);
-
- SPDLOG_DEBUG("process execute ready, cmd: {} {}", cmd,
- q_arguments.join(" ").toStdString());
+ GF_CORE_LOG_DEBUG(
+ "\n== Process Execute Ready ==\nCommand: {}\nArguments: "
+ "{}\n========================",
+ cmd, joined_argument);
cmd_process->start();
cmd_process->waitForFinished();
- std::string process_stdout =
- cmd_process->readAllStandardOutput().toStdString(),
- process_stderr =
- cmd_process->readAllStandardError().toStdString();
+ QString process_stdout = cmd_process->readAllStandardOutput();
int exit_code = cmd_process->exitCode();
+ GF_CORE_LOG_DEBUG(
+ "\n==== Process Execution Summary ====\n"
+ "Command: {}\n"
+ "Arguments: {}\n"
+ "Exit Code: {}\n"
+ "---- Standard Output ----\n"
+ "{}\n"
+ "===============================",
+ cmd, joined_argument, exit_code, process_stdout);
+
cmd_process->close();
cmd_process->deleteLater();
- // transfer result
- SPDLOG_DEBUG("runner append object");
- data_object->AppendObject(std::move(process_stderr));
- data_object->AppendObject(std::move(process_stdout));
- data_object->AppendObject(std::move(exit_code));
- SPDLOG_DEBUG("runner append object done");
-
+ data_object->Swap({exit_code, process_stdout, callback});
return 0;
};
- // data transfer into task
- auto data_object = std::make_shared<Thread::Task::DataObject>();
- SPDLOG_DEBUG("executor append object");
- data_object->AppendObject(std::move(callback));
- data_object->AppendObject(std::move(interact_func));
- data_object->AppendObject(std::move(arguments));
- data_object->AppendObject(std::move(std::string{cmd}));
- SPDLOG_DEBUG("executor append object done");
-
- auto *process_task = new GpgFrontend::Thread::Task(
- std::move(runner), fmt::format("Execute/{}", cmd), data_object,
+ return new Thread::Task(
+ std::move(runner), QString("GpgCommamdExecutor(%1){%2}").arg(cmd),
+ TransferParams(cmd, arguments, interact_function, cmd_executor_callback),
std::move(result_callback));
+}
+
+GpgCommandExecutor::ExecuteContext::ExecuteContext(
+ QString cmd, QList<QString> arguments, GpgCommandExecutorCallback callback,
+ Module::TaskRunnerPtr task_runner, GpgCommandExecutorInteractor int_func)
+ : cmd(std::move(cmd)),
+ arguments(std::move(arguments)),
+ cb_func(std::move(callback)),
+ int_func(std::move(int_func)),
+ task_runner(std::move(task_runner)) {}
+
+void GpgCommandExecutor::ExecuteSync(ExecuteContext context) {
+ Thread::Task *task = BuildTaskFromExecCtx(context);
QEventLoop looper;
- QObject::connect(process_task, &Thread::Task::SignalTaskEnd, &looper,
+ QObject::connect(task, &Thread::Task::SignalTaskEnd, &looper,
&QEventLoop::quit);
- GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
- .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_External_Process)
- ->PostTask(process_task);
-
+ Thread::TaskRunnerPtr target_task_runner = nullptr;
+
+ if (context.task_runner != nullptr) {
+ target_task_runner = context.task_runner;
+ } else {
+ target_task_runner =
+ GpgFrontend::Thread::TaskRunnerGetter::GetInstance().GetTaskRunner(
+ Thread::TaskRunnerGetter::kTaskRunnerType_External_Process);
+ }
+ target_task_runner->PostTask(task);
+
+ // to arvoid dead lock issue we need to check if current thread is the same as
+ // target thread. if it is, we can't call exec() because it will block the
+ // current thread.
+ GF_CORE_LOG_TRACE("blocking until gpg command finish...");
// block until task finished
// this is to keep reference vaild until task finished
looper.exec();
}
-void GpgFrontend::GpgCommandExecutor::ExecuteConcurrently(
- std::string cmd, std::vector<std::string> arguments,
- std::function<void(int, std::string, std::string)> callback,
- std::function<void(QProcess *)> interact_func) {
- SPDLOG_DEBUG("called cmd {} arguments size: {}", cmd, arguments.size());
-
- Thread::Task::TaskCallback result_callback =
- [](int rtn, Thread::Task::DataObjectPtr data_object) {
- if (data_object->GetObjectSize() != 4)
- throw std::runtime_error("invalid data object size");
-
- auto exit_code = data_object->PopObject<int>();
- auto process_stdout = data_object->PopObject<std::string>();
- auto process_stderr = data_object->PopObject<std::string>();
- auto callback = data_object->PopObject<
- std::function<void(int, std::string, std::string)>>();
-
- // call callback
- callback(exit_code, process_stdout, process_stderr);
- };
-
- Thread::Task::TaskRunnable runner =
- [](GpgFrontend::Thread::Task::DataObjectPtr data_object) -> int {
- SPDLOG_DEBUG("process runner called, data object size: {}",
- data_object->GetObjectSize());
-
- if (data_object->GetObjectSize() != 4)
- throw std::runtime_error("invalid data object size");
-
- SPDLOG_DEBUG("runner pop object");
- // get arguments
- auto cmd = data_object->PopObject<std::string>();
- auto arguments = data_object->PopObject<std::vector<std::string>>();
- auto interact_func =
- data_object->PopObject<std::function<void(QProcess *)>>();
- SPDLOG_DEBUG("runner pop object done");
-
- auto *cmd_process = new QProcess();
- cmd_process->setProcessChannelMode(QProcess::MergedChannels);
-
- QObject::connect(cmd_process, &QProcess::started,
- []() -> void { SPDLOG_DEBUG("process started"); });
- QObject::connect(
- cmd_process, &QProcess::readyReadStandardOutput,
- [interact_func, cmd_process]() { interact_func(cmd_process); });
- QObject::connect(cmd_process, &QProcess::errorOccurred,
- [=](QProcess::ProcessError error) {
- SPDLOG_ERROR("error in executing command: {} error: {}",
- cmd, error);
- });
- QObject::connect(
- cmd_process, qOverload<int, QProcess::ExitStatus>(&QProcess::finished),
- [=](int, QProcess::ExitStatus status) {
- if (status == QProcess::NormalExit)
- SPDLOG_DEBUG(
- "proceess finished, succeed in executing command: {}, exit "
- "status: {}",
- cmd, status);
- else
- SPDLOG_ERROR(
- "proceess finished, error in executing command: {}, exit "
- "status: {}",
- cmd, status);
- });
-
- cmd_process->setProgram(QString::fromStdString(cmd));
- cmd_process->setProcessChannelMode(QProcess::SeparateChannels);
-
- QStringList q_arguments;
- for (const auto &argument : arguments)
- q_arguments.append(QString::fromStdString(argument));
- cmd_process->setArguments(q_arguments);
-
- SPDLOG_DEBUG("process start ready, cmd: {} {}", cmd,
- q_arguments.join(" ").toStdString());
-
- cmd_process->start();
- cmd_process->waitForFinished();
-
- std::string process_stdout =
- cmd_process->readAllStandardOutput().toStdString(),
- process_stderr =
- cmd_process->readAllStandardError().toStdString();
- int exit_code = cmd_process->exitCode();
-
- cmd_process->close();
- cmd_process->deleteLater();
-
- // transfer result
- SPDLOG_DEBUG("runner append object");
- data_object->AppendObject(std::move(process_stderr));
- data_object->AppendObject(std::move(process_stdout));
- data_object->AppendObject(std::move(exit_code));
- SPDLOG_DEBUG("runner append object done");
-
- return 0;
- };
-
- // data transfer into task
- auto data_object = std::make_shared<Thread::Task::DataObject>();
- data_object->AppendObject(std::move(callback));
- data_object->AppendObject(std::move(interact_func));
- data_object->AppendObject(std::move(arguments));
- data_object->AppendObject(std::move(std::string{cmd}));
-
- auto *process_task = new GpgFrontend::Thread::Task(
- std::move(runner), fmt::format("ExecuteConcurrently/{}", cmd),
- data_object, std::move(result_callback), false);
+void GpgCommandExecutor::ExecuteConcurrentlyAsync(ExecuteContexts contexts) {
+ for (auto &context : contexts) {
+ const auto &cmd = context.cmd;
+ GF_CORE_LOG_INFO("gpg concurrently called cmd {}", cmd);
+
+ Thread::Task *task = BuildTaskFromExecCtx(context);
+
+ if (context.task_runner != nullptr) {
+ context.task_runner->PostTask(task);
+ } else {
+ GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(
+ Thread::TaskRunnerGetter::kTaskRunnerType_External_Process)
+ ->PostTask(task);
+ }
+ }
+}
- GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
- .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_External_Process)
- ->PostTask(process_task);
+void GpgCommandExecutor::ExecuteConcurrentlySync(ExecuteContexts contexts) {
+ QEventLoop looper;
+ auto remaining_tasks = contexts.size();
+ Thread::TaskRunnerPtr target_task_runner = nullptr;
+
+ for (auto &context : contexts) {
+ const auto &cmd = context.cmd;
+ GF_CORE_LOG_DEBUG("gpg concurrently called cmd: {}", cmd);
+
+ Thread::Task *task = BuildTaskFromExecCtx(context);
+
+ QObject::connect(task, &Thread::Task::SignalTaskEnd, [&]() {
+ --remaining_tasks;
+ GF_CORE_LOG_DEBUG("remaining tasks: {}", remaining_tasks);
+ if (remaining_tasks <= 0) {
+ GF_CORE_LOG_DEBUG("no remaining task, quit");
+ looper.quit();
+ }
+ });
+
+ if (context.task_runner != nullptr) {
+ target_task_runner = context.task_runner;
+ } else {
+ target_task_runner =
+ GpgFrontend::Thread::TaskRunnerGetter::GetInstance().GetTaskRunner(
+ Thread::TaskRunnerGetter::kTaskRunnerType_External_Process);
+ }
+
+ target_task_runner->PostTask(task);
+ }
+
+ GF_CORE_LOG_TRACE("blocking until concurrent gpg commands finish...");
+ // block until task finished
+ // this is to keep reference vaild until task finished
+ looper.exec();
}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/gpg/GpgCommandExecutor.h b/src/core/function/gpg/GpgCommandExecutor.h
index da0e7a8b..d161406a 100644
--- a/src/core/function/gpg/GpgCommandExecutor.h
+++ b/src/core/function/gpg/GpgCommandExecutor.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,39 +20,43 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_ZH_CN_TS_GPGCOMMANDEXECUTOR_H
-#define GPGFRONTEND_ZH_CN_TS_GPGCOMMANDEXECUTOR_H
+#pragma once
-#ifndef WINDOWS
-#include <boost/process.hpp>
-#endif
-
-#include "core/GpgContext.h"
-#include "core/GpgFunctionObject.h"
-#include "core/thread/Task.h"
+#include "core/module/Module.h"
namespace GpgFrontend {
+using GpgCommandExecutorCallback = std::function<void(int, QString, QString)>;
+using GpgCommandExecutorInteractor = std::function<void(QProcess *)>;
+
/**
* @brief Extra commands related to GPG
*
*/
-class GPGFRONTEND_CORE_EXPORT GpgCommandExecutor
- : public SingletonFunctionObject<GpgCommandExecutor> {
+class GPGFRONTEND_CORE_EXPORT GpgCommandExecutor {
public:
- /**
- * @brief Construct a new Gpg Command Executor object
- *
- * @param channel Corresponding context
- */
- explicit GpgCommandExecutor(
- int channel = SingletonFunctionObject::GetDefaultChannel());
+ struct ExecuteContext {
+ QString cmd;
+ QStringList arguments;
+ GpgCommandExecutorCallback cb_func;
+ GpgCommandExecutorInteractor int_func;
+ Module::TaskRunnerPtr task_runner = nullptr;
+
+ ExecuteContext(
+ QString cmd, QStringList arguments,
+ GpgCommandExecutorCallback callback = [](int, const QString &,
+ const QString &) {},
+ Module::TaskRunnerPtr task_runner = nullptr,
+ GpgCommandExecutorInteractor int_func = [](QProcess *) {});
+ };
+
+ using ExecuteContexts = QList<ExecuteContext>;
/**
* @brief Excuting a command
@@ -60,22 +64,11 @@ class GPGFRONTEND_CORE_EXPORT GpgCommandExecutor
* @param arguments Command parameters
* @param interact_func Command answering function
*/
- void Execute(
- std::string cmd, std::vector<std::string> arguments,
- std::function<void(int, std::string, std::string)> callback =
- [](int, std::string, std::string) {},
- std::function<void(QProcess *)> interact_func = [](QProcess *) {});
+ static void ExecuteSync(ExecuteContext);
- void ExecuteConcurrently(
- std::string cmd, std::vector<std::string> arguments,
- std::function<void(int, std::string, std::string)> callback,
- std::function<void(QProcess *)> interact_func = [](QProcess *) {});
+ static void ExecuteConcurrentlyAsync(ExecuteContexts);
- private:
- GpgContext &ctx_ = GpgContext::GetInstance(
- SingletonFunctionObject::GetChannel()); ///< Corresponding context
+ static void ExecuteConcurrentlySync(ExecuteContexts);
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ZH_CN_TS_GPGCOMMANDEXECUTOR_H
diff --git a/src/core/function/gpg/GpgContext.cpp b/src/core/function/gpg/GpgContext.cpp
new file mode 100644
index 00000000..104e254f
--- /dev/null
+++ b/src/core/function/gpg/GpgContext.cpp
@@ -0,0 +1,336 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "core/function/gpg/GpgContext.h"
+
+#include <gpg-error.h>
+#include <gpgme.h>
+
+#include <cassert>
+#include <mutex>
+
+#include "core/function/CoreSignalStation.h"
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/model/GpgPassphraseContext.h"
+#include "core/module/ModuleManager.h"
+#include "core/utils/CacheUtils.h"
+#include "core/utils/GpgUtils.h"
+#include "core/utils/MemoryUtils.h"
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+namespace GpgFrontend {
+
+class GpgContext::Impl {
+ public:
+ /**
+ * Constructor
+ * Set up gpgme-context, set paths to app-run path
+ */
+ Impl(GpgContext *parent, const GpgContextInitArgs &args)
+ : parent_(parent),
+ args_(args),
+ good_(default_ctx_initialize(args) && binary_ctx_initialize(args)) {}
+
+ ~Impl() {
+ if (ctx_ref_ != nullptr) {
+ gpgme_release(ctx_ref_);
+ }
+
+ if (binary_ctx_ref_ != nullptr) {
+ gpgme_release(binary_ctx_ref_);
+ }
+ }
+
+ [[nodiscard]] auto BinaryContext() const -> gpgme_ctx_t {
+ return binary_ctx_ref_;
+ }
+
+ [[nodiscard]] auto DefaultContext() const -> gpgme_ctx_t { return ctx_ref_; }
+
+ [[nodiscard]] auto Good() const -> bool { return good_; }
+
+ auto SetPassphraseCb(const gpgme_ctx_t &ctx, gpgme_passphrase_cb_t cb)
+ -> bool {
+ if (gpgme_get_pinentry_mode(ctx) != GPGME_PINENTRY_MODE_LOOPBACK) {
+ if (CheckGpgError(gpgme_set_pinentry_mode(
+ ctx, GPGME_PINENTRY_MODE_LOOPBACK)) != GPG_ERR_NO_ERROR) {
+ return false;
+ }
+ }
+ gpgme_set_passphrase_cb(ctx, cb, reinterpret_cast<void *>(parent_));
+ return true;
+ }
+
+ static auto TestPassphraseCb(void *opaque, const char *uid_hint,
+ const char *passphrase_info, int last_was_bad,
+ int fd) -> gpgme_error_t {
+ size_t res;
+ QString pass = "abcdefg\n";
+ auto pass_len = pass.size();
+
+ size_t off = 0;
+
+ 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);
+ }
+
+ static auto CustomPassphraseCb(void *hook, const char *uid_hint,
+ const char *passphrase_info, int prev_was_bad,
+ int fd) -> gpgme_error_t {
+ auto context_cache = GetCacheValue("PinentryContext");
+ bool ask_for_new = context_cache == "NEW_PASSPHRASE";
+ auto context =
+ QSharedPointer<GpgPassphraseContext>(new GpgPassphraseContext(
+ uid_hint != nullptr ? uid_hint : "",
+ passphrase_info != nullptr ? passphrase_info : "",
+ prev_was_bad != 0, ask_for_new));
+
+ GF_CORE_LOG_DEBUG(
+ "custom passphrase cb called, uid: {}, info: {}, last_was_bad: {}",
+ uid_hint == nullptr ? "<empty>" : QString{uid_hint},
+ passphrase_info == nullptr ? "<empty>" : QString{passphrase_info},
+ prev_was_bad);
+
+ QEventLoop looper;
+ QObject::connect(CoreSignalStation::GetInstance(),
+ &CoreSignalStation::SignalUserInputPassphraseCallback,
+ &looper, &QEventLoop::quit);
+
+ emit CoreSignalStation::GetInstance()->SignalNeedUserInputPassphrase(
+ context);
+ looper.exec();
+
+ ResetCacheValue("PinentryContext");
+ auto passphrase = context->GetPassphrase().toStdString();
+ auto passpahrase_size = passphrase.size();
+ GF_CORE_LOG_DEBUG("get passphrase from pinentry size: {}",
+ passpahrase_size);
+
+ size_t res = 0;
+ if (passpahrase_size > 0) {
+ size_t off = 0;
+ do {
+ res = gpgme_io_write(fd, &passphrase[off], passpahrase_size - off);
+ if (res > 0) off += res;
+ } while (res > 0 && off != passpahrase_size);
+ }
+
+ res += gpgme_io_write(fd, "\n", 1);
+
+ GF_CORE_LOG_DEBUG("custom passphrase cd is about to return, res: {}", res);
+ return res == passpahrase_size + 1
+ ? 0
+ : gpgme_error_from_errno(GPG_ERR_CANCELED);
+ }
+
+ static auto TestStatusCb(void *hook, const char *keyword, const char *args)
+ -> gpgme_error_t {
+ GF_CORE_LOG_DEBUG("keyword {}", keyword);
+ return GPG_ERR_NO_ERROR;
+ }
+
+ private:
+ GpgContext *parent_;
+ GpgContextInitArgs args_{}; ///<
+ gpgme_ctx_t ctx_ref_ = nullptr; ///<
+ gpgme_ctx_t binary_ctx_ref_ = nullptr; ///<
+ bool good_ = true;
+ std::mutex ctx_ref_lock_;
+ std::mutex binary_ctx_ref_lock_;
+
+ static auto set_ctx_key_list_mode(const gpgme_ctx_t &ctx) -> bool {
+ assert(ctx != nullptr);
+
+ const auto gpgme_version = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.version", QString{"0.0.0"});
+ GF_CORE_LOG_DEBUG("got gpgme version version from rt: {}", gpgme_version);
+
+ if (gpgme_get_keylist_mode(ctx) == 0) {
+ GF_CORE_LOG_ERROR(
+ "ctx is not a valid pointer, reported by gpgme_get_keylist_mode");
+ return false;
+ }
+
+ // set keylist mode
+ return CheckGpgError(gpgme_set_keylist_mode(
+ ctx, GPGME_KEYLIST_MODE_LOCAL | GPGME_KEYLIST_MODE_WITH_SECRET |
+ GPGME_KEYLIST_MODE_SIGS |
+ GPGME_KEYLIST_MODE_SIG_NOTATIONS |
+ GPGME_KEYLIST_MODE_WITH_TOFU)) == GPG_ERR_NO_ERROR;
+ }
+
+ static auto set_ctx_openpgp_engine_info(gpgme_ctx_t ctx) -> bool {
+ const auto app_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.app_path", QString{});
+ const auto database_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.database_path", QString{});
+
+ GF_CORE_LOG_DEBUG("ctx set engine info, db path: {}, app path: {}",
+ database_path, app_path);
+
+ auto app_path_buffer = app_path.toUtf8();
+ auto database_path_buffer = database_path.toUtf8();
+
+ auto err = gpgme_ctx_set_engine_info(
+ ctx, gpgme_get_protocol(ctx),
+ app_path.isEmpty() ? nullptr : app_path_buffer,
+ database_path.isEmpty() ? nullptr : database_path_buffer);
+
+ assert(CheckGpgError(err) == GPG_ERR_NO_ERROR);
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR;
+
+ return true;
+ }
+
+ auto common_ctx_initialize(const gpgme_ctx_t &ctx,
+ const GpgContextInitArgs &args) -> bool {
+ assert(ctx != nullptr);
+
+ if (args.custom_gpgconf && !args.custom_gpgconf_path.isEmpty()) {
+ GF_CORE_LOG_DEBUG("set custom gpgconf path: {}",
+ args.custom_gpgconf_path);
+ auto err =
+ gpgme_ctx_set_engine_info(ctx, GPGME_PROTOCOL_GPGCONF,
+ args.custom_gpgconf_path.toUtf8(), nullptr);
+
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ GF_CORE_LOG_ERROR("set gpg context engine info error: {}",
+ DescribeGpgErrCode(err).second);
+ return false;
+ }
+ }
+
+ // set context offline mode
+ GF_CORE_LOG_DEBUG("gpg context offline mode: {}", args_.offline_mode);
+ gpgme_set_offline(ctx, args_.offline_mode ? 1 : 0);
+
+ // set option auto import missing key
+ // invalid at offline mode
+ GF_CORE_LOG_DEBUG("gpg context auto import missing key: {}",
+ args_.offline_mode);
+ if (!args.offline_mode && args.auto_import_missing_key) {
+ if (CheckGpgError(gpgme_set_ctx_flag(ctx, "auto-key-import", "1")) !=
+ GPG_ERR_NO_ERROR) {
+ return false;
+ }
+ }
+
+ if (!set_ctx_key_list_mode(ctx)) {
+ GF_CORE_LOG_DEBUG("set ctx key list mode failed");
+ return false;
+ }
+
+ // for unit test
+ if (args_.test_mode) {
+ if (!SetPassphraseCb(ctx, TestPassphraseCb)) {
+ GF_CORE_LOG_ERROR("set passphrase cb failed, test");
+ return false;
+ };
+ } else if (!args_.use_pinentry) {
+ if (!SetPassphraseCb(ctx, CustomPassphraseCb)) {
+ GF_CORE_LOG_DEBUG("set passphrase cb failed, custom");
+ return false;
+ }
+ }
+
+ // set custom gpg key db path
+ if (!args_.db_path.isEmpty()) {
+ Module::UpsertRTValue("core", "gpgme.ctx.database_path", args_.db_path);
+ }
+
+ if (!set_ctx_openpgp_engine_info(ctx)) {
+ GF_CORE_LOG_ERROR("set gpgme context openpgp engine info failed");
+ return false;
+ }
+
+ return true;
+ }
+
+ auto binary_ctx_initialize(const GpgContextInitArgs &args) -> bool {
+ gpgme_ctx_t p_ctx;
+ if (auto err = CheckGpgError(gpgme_new(&p_ctx)); err != GPG_ERR_NO_ERROR) {
+ GF_CORE_LOG_ERROR("get new gpg context error: {}",
+ DescribeGpgErrCode(err).second);
+ return false;
+ }
+ assert(p_ctx != nullptr);
+ binary_ctx_ref_ = p_ctx;
+
+ if (!common_ctx_initialize(binary_ctx_ref_, args)) {
+ GF_CORE_LOG_ERROR("get new ctx failed, binary");
+ return false;
+ }
+
+ gpgme_set_armor(binary_ctx_ref_, 0);
+ return true;
+ }
+
+ auto default_ctx_initialize(const GpgContextInitArgs &args) -> bool {
+ gpgme_ctx_t p_ctx;
+ if (CheckGpgError(gpgme_new(&p_ctx)) != GPG_ERR_NO_ERROR) {
+ GF_CORE_LOG_ERROR("get new ctx failed, default");
+ return false;
+ }
+ assert(p_ctx != nullptr);
+ ctx_ref_ = p_ctx;
+
+ if (!common_ctx_initialize(ctx_ref_, args)) {
+ return false;
+ }
+
+ gpgme_set_armor(ctx_ref_, 1);
+ return true;
+ }
+};
+
+GpgContext::GpgContext(int channel)
+ : SingletonFunctionObject<GpgContext>(channel),
+ p_(SecureCreateUniqueObject<Impl>(this, GpgContextInitArgs{})) {}
+
+GpgContext::GpgContext(GpgContextInitArgs args, int channel)
+ : SingletonFunctionObject<GpgContext>(channel),
+ p_(SecureCreateUniqueObject<Impl>(this, args)) {}
+
+auto GpgContext::Good() const -> bool { return p_->Good(); }
+
+auto GpgContext::BinaryContext() -> gpgme_ctx_t { return p_->BinaryContext(); }
+
+auto GpgContext::DefaultContext() -> gpgme_ctx_t {
+ return p_->DefaultContext();
+}
+
+GpgContext::~GpgContext() = default;
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/gpg/GpgContext.h b/src/core/function/gpg/GpgContext.h
new file mode 100644
index 00000000..d473a341
--- /dev/null
+++ b/src/core/function/gpg/GpgContext.h
@@ -0,0 +1,76 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/function/SecureMemoryAllocator.h"
+#include "core/function/basic/GpgFunctionObject.h"
+
+namespace GpgFrontend {
+
+/**
+ * @brief
+ *
+ */
+struct GpgContextInitArgs {
+ QString db_path = {}; ///<
+
+ bool test_mode = false; ///<
+ bool offline_mode = false; ///<
+ bool auto_import_missing_key = false; ///<
+
+ bool custom_gpgconf = false; ///<
+ QString custom_gpgconf_path; ///<
+
+ bool use_pinentry = false; ///<
+};
+
+/**
+ * @brief
+ *
+ */
+class GPGFRONTEND_CORE_EXPORT GpgContext
+ : public SingletonFunctionObject<GpgContext> {
+ public:
+ explicit GpgContext(int channel);
+
+ explicit GpgContext(GpgContextInitArgs args, int channel);
+
+ virtual ~GpgContext() override;
+
+ [[nodiscard]] auto Good() const -> bool;
+
+ auto BinaryContext() -> gpgme_ctx_t;
+
+ auto DefaultContext() -> gpgme_ctx_t;
+
+ private:
+ class Impl;
+ SecureUniquePtr<Impl> p_;
+};
+} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgFileOpera.cpp b/src/core/function/gpg/GpgFileOpera.cpp
index 30678cf0..e3d47cf6 100644
--- a/src/core/function/gpg/GpgFileOpera.cpp
+++ b/src/core/function/gpg/GpgFileOpera.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,235 +20,353 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "GpgFileOpera.h"
-#include <memory>
-#include <string>
+#include "core/function/ArchiveFileOperator.h"
+#include "core/function/gpg/GpgBasicOperator.h"
+#include "core/model/GpgData.h"
+#include "core/model/GpgDecryptResult.h"
+#include "core/model/GpgEncryptResult.h"
+#include "core/model/GpgKey.h"
+#include "core/model/GpgSignResult.h"
+#include "core/model/GpgVerifyResult.h"
+#include "core/utils/AsyncUtils.h"
+#include "core/utils/GpgUtils.h"
-#include "GpgBasicOperator.h"
-#include "GpgConstants.h"
-#include "function/FileOperator.h"
+namespace GpgFrontend {
-GpgFrontend::GpgFileOpera::GpgFileOpera(int channel)
+constexpr ssize_t kDataExchangerSize = 8192;
+
+GpgFileOpera::GpgFileOpera(int channel)
: SingletonFunctionObject<GpgFileOpera>(channel) {}
-GpgFrontend::GpgError GpgFrontend::GpgFileOpera::EncryptFile(
- KeyListPtr keys, const std::string& in_path, const std::string& out_path,
- GpgEncrResult& result, int _channel) {
-#ifdef WINDOWS
- auto in_path_std =
- std::filesystem::path(QString::fromStdString(in_path).toStdU16String());
- auto out_path_std =
- std::filesystem::path(QString::fromStdString(out_path).toStdU16String());
-#else
- auto in_path_std = std::filesystem::path(in_path);
- auto out_path_std = std::filesystem::path(out_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(in_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
-
- std::unique_ptr<std::string> out_buffer = nullptr;
-
- auto err = GpgBasicOperator::GetInstance(_channel).Encrypt(
- std::move(keys), in_buffer, out_buffer, result);
-
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) {
- throw std::runtime_error("write_buffer_to_file error");
- };
-
- return err;
+void GpgFileOpera::EncryptFile(std::vector<GpgKey> keys, const QString& in_path,
+ bool ascii, const QString& out_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx))});
+
+ return err;
+ },
+ cb, "gpgme_op_encrypt", "2.1.0");
}
-GpgFrontend::GpgError GpgFrontend::GpgFileOpera::DecryptFile(
- const std::string& in_path, const std::string& out_path,
- GpgDecrResult& result) {
-#ifdef WINDOWS
- auto in_path_std =
- std::filesystem::path(QString::fromStdString(in_path).toStdU16String());
- auto out_path_std =
- std::filesystem::path(QString::fromStdString(out_path).toStdU16String());
-#else
- auto in_path_std = std::filesystem::path(in_path);
- auto out_path_std = std::filesystem::path(out_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(in_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
- std::unique_ptr<std::string> out_buffer;
-
- auto err =
- GpgBasicOperator::GetInstance().Decrypt(in_buffer, out_buffer, result);
-
- assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
-
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) {
- throw std::runtime_error("write_buffer_to_file error");
- };
-
- return err;
+void GpgFileOpera::EncryptDirectory(std::vector<GpgKey> keys,
+ const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ auto ex = std::make_shared<GFDataExchanger>(kDataExchangerSize);
+
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
+
+ GpgData data_in(ex);
+ GpgData data_out(out_path, false);
+
+ GF_CORE_LOG_DEBUG("encrypt directory start");
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx))});
+
+ GF_CORE_LOG_DEBUG("encrypt directory finished, err: {}", err);
+ return err;
+ },
+ cb, "gpgme_op_encrypt", "2.1.0");
+
+ ArchiveFileOperator::NewArchive2DataExchanger(
+ in_path, ex, [=](GFError err, const DataObjectPtr&) {
+ GF_CORE_LOG_DEBUG("new archive 2 data exchanger operation, err: {}",
+ err);
+ });
+}
+
+void GpgFileOpera::DecryptFile(const QString& in_path, const QString& out_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto err = CheckGpgError(
+ gpgme_op_decrypt(ctx_.DefaultContext(), data_in, data_out));
+ data_object->Swap(
+ {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext()))});
+
+ return err;
+ },
+ cb, "gpgme_op_decrypt", "2.1.0");
+}
+
+void GpgFileOpera::DecryptArchive(const QString& in_path,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ auto ex = std::make_shared<GFDataExchanger>(kDataExchangerSize);
+
+ ArchiveFileOperator::ExtractArchiveFromDataExchanger(
+ ex, out_path, [](GFError err, const DataObjectPtr&) {
+ GF_CORE_LOG_DEBUG(
+ "extract archive from data exchanger operation, err: {}", err);
+ });
+
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_path, true);
+ GpgData data_out(ex);
+
+ auto err = CheckGpgError(
+ gpgme_op_decrypt(ctx_.DefaultContext(), data_in, data_out));
+
+ data_object->Swap(
+ {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext()))});
+ return err;
+ },
+ cb, "gpgme_op_decrypt", "2.1.0");
}
-gpgme_error_t GpgFrontend::GpgFileOpera::SignFile(KeyListPtr keys,
- const std::string& in_path,
- const std::string& out_path,
- GpgSignResult& result,
- int _channel) {
-#ifdef WINDOWS
- auto in_path_std =
- std::filesystem::path(QString::fromStdString(in_path).toStdU16String());
- auto out_path_std =
- std::filesystem::path(QString::fromStdString(out_path).toStdU16String());
-#else
- auto in_path_std = std::filesystem::path(in_path);
- auto out_path_std = std::filesystem::path(out_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(in_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
- std::unique_ptr<std::string> out_buffer;
-
- auto err = GpgBasicOperator::GetInstance(_channel).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 (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) {
- throw std::runtime_error("write_buffer_to_file error");
- };
-
- return err;
+void GpgFileOpera::SignFile(KeyArgsList keys, const QString& in_path,
+ bool ascii, const QString& out_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ // Set Singers of this opera
+ GpgBasicOperator::GetInstance().SetSigners(keys, ascii);
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(
+ gpgme_op_sign(ctx, data_in, data_out, GPGME_SIG_MODE_DETACH));
+
+ data_object->Swap({
+ GpgSignResult(gpgme_op_sign_result(ctx)),
+ });
+ return err;
+ },
+ cb, "gpgme_op_sign", "2.1.0");
}
-gpgme_error_t GpgFrontend::GpgFileOpera::VerifyFile(
- const std::string& data_path, const std::string& sign_path,
- GpgVerifyResult& result, int _channel) {
-#ifdef WINDOWS
- auto data_path_std =
- std::filesystem::path(QString::fromStdString(data_path).toStdU16String());
- auto sign_path_std =
- std::filesystem::path(QString::fromStdString(sign_path).toStdU16String());
-#else
- auto data_path_std = std::filesystem::path(data_path);
- auto sign_path_std = std::filesystem::path(sign_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(data_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
- std::unique_ptr<std::string> sign_buffer = nullptr;
- if (!sign_path.empty()) {
- std::string sign_buffer_str;
- if (!FileOperator::ReadFileStd(sign_path_std, sign_buffer_str)) {
- throw std::runtime_error("read file error");
- }
- sign_buffer = std::make_unique<std::string>(sign_buffer_str);
- }
- auto err = GpgBasicOperator::GetInstance(_channel).Verify(
- in_buffer, sign_buffer, result);
- return err;
+void GpgFileOpera::VerifyFile(const QString& data_path,
+ const QString& sign_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ GpgData data_in(data_path, true);
+ GpgData data_out;
+ if (!sign_path.isEmpty()) {
+ GpgData sig_data(sign_path, true);
+ err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), sig_data,
+ data_in, nullptr));
+ } else {
+ err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), data_in,
+ nullptr, data_out));
+ }
+
+ data_object->Swap({
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ });
+
+ return err;
+ },
+ cb, "gpgme_op_verify", "2.1.0");
}
-gpg_error_t GpgFrontend::GpgFileOpera::EncryptSignFile(
- KeyListPtr keys, KeyListPtr signer_keys, const std::string& in_path,
- const std::string& out_path, GpgEncrResult& encr_res,
- GpgSignResult& sign_res, int _channel) {
-#ifdef WINDOWS
- auto in_path_std =
- std::filesystem::path(QString::fromStdString(in_path).toStdU16String());
- auto out_path_std =
- std::filesystem::path(QString::fromStdString(out_path).toStdU16String());
-#else
- auto in_path_std = std::filesystem::path(in_path);
- auto out_path_std = std::filesystem::path(out_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(in_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
- std::unique_ptr<std::string> out_buffer = nullptr;
-
- auto err = GpgBasicOperator::GetInstance(_channel).EncryptSign(
- std::move(keys), std::move(signer_keys), in_buffer, out_buffer, encr_res,
- sign_res);
-
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) {
- throw std::runtime_error("write_buffer_to_file error");
- };
-
- return err;
+void GpgFileOpera::EncryptSignFile(KeyArgsList keys, KeyArgsList signer_keys,
+ const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
+
+ GpgBasicOperator::GetInstance().SetSigners(signer_keys, ascii);
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(gpgme_op_encrypt_sign(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+
+ data_object->Swap({
+ GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ GpgSignResult(gpgme_op_sign_result(ctx)),
+ });
+ return err;
+ },
+ cb, "gpgme_op_encrypt_sign", "2.1.0");
}
-gpg_error_t GpgFrontend::GpgFileOpera::DecryptVerifyFile(
- const std::string& in_path, const std::string& out_path,
- GpgDecrResult& decr_res, GpgVerifyResult& verify_res) {
-#ifdef WINDOWS
- auto in_path_std =
- std::filesystem::path(QString::fromStdString(in_path).toStdU16String());
- auto out_path_std =
- std::filesystem::path(QString::fromStdString(out_path).toStdU16String());
-#else
- auto in_path_std = std::filesystem::path(in_path);
- auto out_path_std = std::filesystem::path(out_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(in_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
-
- std::unique_ptr<std::string> out_buffer = nullptr;
- auto err = GpgBasicOperator::GetInstance().DecryptVerify(
- in_buffer, out_buffer, decr_res, verify_res);
-
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) {
- throw std::runtime_error("write file error");
- };
-
- return err;
+void GpgFileOpera::EncryptSignDirectory(KeyArgsList keys,
+ KeyArgsList signer_keys,
+ const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ auto ex = std::make_shared<GFDataExchanger>(kDataExchangerSize);
+
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
+
+ GpgBasicOperator::GetInstance().SetSigners(signer_keys, ascii);
+
+ GpgData data_in(ex);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(gpgme_op_encrypt_sign(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+
+ data_object->Swap({
+ GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ GpgSignResult(gpgme_op_sign_result(ctx)),
+ });
+ return err;
+ },
+ cb, "gpgme_op_encrypt_sign", "2.1.0");
+
+ ArchiveFileOperator::NewArchive2DataExchanger(
+ in_path, ex, [=](GFError err, const DataObjectPtr&) {
+ GF_CORE_LOG_DEBUG("new archive 2 fd operation, err: {}", err);
+ });
}
-unsigned int GpgFrontend::GpgFileOpera::EncryptFileSymmetric(
- const std::string& in_path, const std::string& out_path,
- GpgFrontend::GpgEncrResult& result, int _channel) {
-#ifdef WINDOWS
- auto in_path_std =
- std::filesystem::path(QString::fromStdString(in_path).toStdU16String());
- auto out_path_std =
- std::filesystem::path(QString::fromStdString(out_path).toStdU16String());
-#else
- auto in_path_std = std::filesystem::path(in_path);
- auto out_path_std = std::filesystem::path(out_path);
-#endif
-
- std::string in_buffer;
- if (!FileOperator::ReadFileStd(in_path_std, in_buffer)) {
- throw std::runtime_error("read file error");
- }
-
- std::unique_ptr<std::string> out_buffer;
- auto err = GpgBasicOperator::GetInstance(_channel).EncryptSymmetric(
- in_buffer, out_buffer, result);
-
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
- if (!FileOperator::WriteFileStd(out_path_std, *out_buffer)) {
- throw std::runtime_error("write_buffer_to_file error");
- };
-
- return err;
+
+void GpgFileOpera::DecryptVerifyFile(const QString& in_path,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ err = CheckGpgError(
+ gpgme_op_decrypt_verify(ctx_.DefaultContext(), data_in, data_out));
+
+ data_object->Swap({
+ GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())),
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ });
+
+ return err;
+ },
+ cb, "gpgme_op_decrypt_verify", "2.1.0");
+}
+
+void GpgFileOpera::DecryptVerifyArchive(const QString& in_path,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ auto ex = std::make_shared<GFDataExchanger>(kDataExchangerSize);
+
+ ArchiveFileOperator::ExtractArchiveFromDataExchanger(
+ ex, out_path, [](GFError err, const DataObjectPtr&) {
+ GF_CORE_LOG_DEBUG("extract archive from ex operation, err: {}", err);
+ });
+
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(ex);
+
+ err = CheckGpgError(
+ gpgme_op_decrypt_verify(ctx_.DefaultContext(), data_in, data_out));
+
+ data_object->Swap({
+ GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())),
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ });
+
+ return err;
+ },
+ cb, "gpgme_op_decrypt_verify", "2.1.0");
+}
+
+void GpgFileOpera::EncryptFileSymmetric(const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(
+ ctx, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out));
+ data_object->Swap({
+ GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ });
+
+ return err;
+ },
+ cb, "gpgme_op_encrypt_symmetric", "2.1.0");
+}
+
+void GpgFileOpera::EncryptDerectorySymmetric(const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb) {
+ auto ex = std::make_shared<GFDataExchanger>(kDataExchangerSize);
+
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(ex);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(
+ ctx, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out));
+ data_object->Swap({
+ GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ });
+
+ return err;
+ },
+ cb, "gpgme_op_encrypt_symmetric", "2.1.0");
+
+ ArchiveFileOperator::NewArchive2DataExchanger(
+ in_path, ex, [=](GFError err, const DataObjectPtr&) {
+ GF_CORE_LOG_DEBUG("new archive 2 fd operation, err: {}", err);
+ });
}
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/gpg/GpgFileOpera.h b/src/core/function/gpg/GpgFileOpera.h
index dc81bc53..b015ebe9 100644
--- a/src/core/function/gpg/GpgFileOpera.h
+++ b/src/core/function/gpg/GpgFileOpera.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,59 +20,87 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGFILEOPERA_H
-#define GPGFRONTEND_GPGFILEOPERA_H
+#pragma once
-#include "core/GpgConstants.h"
-#include "core/GpgContext.h"
-#include "core/GpgModel.h"
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/function/result_analyse/GpgResultAnalyse.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
/**
- * @brief Executive files related to the basic operations that are provided by
- * GpgBasicOperator
+ * @brief Executive files related to the basic operations of GPG
+ *
* @class class: GpgBasicOperator
*/
class GPGFRONTEND_CORE_EXPORT GpgFileOpera
: public SingletonFunctionObject<GpgFileOpera> {
public:
+ /**
+ * @brief Construct a new Gpg File Opera object
+ *
+ * @param channel
+ */
explicit GpgFileOpera(
int channel = SingletonFunctionObject::GetDefaultChannel());
/**
- * @brief Encrypted file
+ * @brief Encrypted file with public key
*
* @param keys Used public key
* @param in_path The path where the enter file is located
* @param out_path The path where the output file is located
* @param result Encrypted results
- * @param _channel Channel in context
+ * @param channel Channel in context
* @return unsigned int error code
*/
- static unsigned int EncryptFile(KeyListPtr keys, const std::string& in_path,
- const std::string& out_path,
- GpgEncrResult& result,
- int _channel = GPGFRONTEND_DEFAULT_CHANNEL);
+ void EncryptFile(KeyArgsList keys, const QString& in_path, bool ascii,
+ const QString& out_path, const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param keys
+ * @param in_path
+ * @param ascii
+ * @param out_path
+ * @param cb
+ */
+ void EncryptDirectory(KeyArgsList keys, const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb);
/**
- * @brief 运用对称加密算法加密文件
+ * @brief Encrypted file symmetrically (with password)
*
* @param in_path
* @param out_path
* @param result
- * @param _channel
+ * @param channel
* @return unsigned int
*/
- static unsigned int EncryptFileSymmetric(
- const std::string& in_path, const std::string& out_path,
- GpgEncrResult& result, int _channel = GPGFRONTEND_DEFAULT_CHANNEL);
+ void EncryptFileSymmetric(const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param in_path
+ * @param ascii
+ * @param out_path
+ * @param cb
+ */
+ void EncryptDerectorySymmetric(const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb);
/**
* @brief
@@ -82,37 +110,43 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera
* @param result
* @return GpgError
*/
- static GpgError DecryptFile(const std::string& in_path,
- const std::string& out_path,
- GpgDecrResult& result);
+ void DecryptFile(const QString& in_path, const QString& out_path,
+ const GpgOperationCallback& cb);
/**
* @brief
*
+ * @param in_path
+ * @param out_path
+ * @param cb
+ */
+ void DecryptArchive(const QString& in_path, const QString& out_path,
+ const GpgOperationCallback& cb);
+
+ /**
+ * @brief Sign file with private key
+ *
* @param keys
* @param in_path
* @param out_path
* @param result
- * @param _channel
+ * @param channel
* @return GpgError
*/
- static GpgError SignFile(KeyListPtr keys, const std::string& in_path,
- const std::string& out_path, GpgSignResult& result,
- int _channel = GPGFRONTEND_DEFAULT_CHANNEL);
+ void SignFile(KeyArgsList keys, const QString& in_path, bool ascii,
+ const QString& out_path, const GpgOperationCallback& cb);
/**
- * @brief
+ * @brief Verify file with public key
*
- * @param data_path
- * @param sign_path
- * @param result
- * @param _channel
+ * @param data_path The path where the enter file is located
+ * @param sign_path The path where the signature file is located
+ * @param result Verify results
+ * @param channel Channel in context
* @return GpgError
*/
- static GpgError VerifyFile(const std::string& data_path,
- const std::string& sign_path,
- GpgVerifyResult& result,
- int _channel = GPGFRONTEND_DEFAULT_CHANNEL);
+ void VerifyFile(const QString& data_path, const QString& sign_path,
+ const GpgOperationCallback& cb);
/**
* @brief
@@ -120,18 +154,28 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera
* @param keys
* @param signer_keys
* @param in_path
+ * @param ascii
* @param out_path
- * @param encr_res
- * @param sign_res
- * @param _channel
- * @return GpgError
+ * @param cb
*/
- static GpgError EncryptSignFile(KeyListPtr keys, KeyListPtr signer_keys,
- const std::string& in_path,
- const std::string& out_path,
- GpgEncrResult& encr_res,
- GpgSignResult& sign_res,
- int _channel = GPGFRONTEND_DEFAULT_CHANNEL);
+ void EncryptSignFile(KeyArgsList keys, KeyArgsList signer_keys,
+ const QString& in_path, bool ascii,
+ const QString& out_path, const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param keys
+ * @param signer_keys
+ * @param in_path
+ * @param ascii
+ * @param out_path
+ * @param cb
+ */
+ void EncryptSignDirectory(KeyArgsList keys, KeyArgsList signer_keys,
+ const QString& in_path, bool ascii,
+ const QString& out_path,
+ const GpgOperationCallback& cb);
/**
* @brief
@@ -142,12 +186,22 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera
* @param verify_res
* @return GpgError
*/
- static GpgError DecryptVerifyFile(const std::string& in_path,
- const std::string& out_path,
- GpgDecrResult& decr_res,
- GpgVerifyResult& verify_res);
+ void DecryptVerifyFile(const QString& in_path, const QString& out_path,
+ const GpgOperationCallback& cb);
+
+ /**
+ * @brief
+ *
+ * @param in_path
+ * @param out_path
+ * @param cb
+ */
+ void DecryptVerifyArchive(const QString& in_path, const QString& out_path,
+ const GpgOperationCallback& cb);
+
+ private:
+ GpgContext& ctx_ = GpgContext::GetInstance(
+ SingletonFunctionObject::GetChannel()); ///< Corresponding context
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGFILEOPERA_H
diff --git a/src/core/function/gpg/GpgKeyGetter.cpp b/src/core/function/gpg/GpgKeyGetter.cpp
index ee6d2b09..e22979d7 100644
--- a/src/core/function/gpg/GpgKeyGetter.cpp
+++ b/src/core/function/gpg/GpgKeyGetter.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -32,136 +32,212 @@
#include <mutex>
#include <shared_mutex>
-#include <utility>
-#include "GpgConstants.h"
-#include "model/GpgKey.h"
+#include "core/GpgModel.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/utils/GpgUtils.h"
-GpgFrontend::GpgKeyGetter::GpgKeyGetter(int channel)
- : SingletonFunctionObject<GpgKeyGetter>(channel) {
- SPDLOG_DEBUG("called channel: {}", channel);
-}
+namespace GpgFrontend {
-GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetKey(const std::string& fpr,
- bool use_cache) {
- // find in cache first
- if (use_cache) {
- auto key = get_key_in_cache(fpr);
- if (key.IsGood()) return key;
+class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
+ public:
+ explicit Impl(int channel)
+ : SingletonFunctionObject<GpgKeyGetter::Impl>(channel) {
+ GF_CORE_LOG_DEBUG("called channel: {}", channel);
}
- gpgme_key_t _p_key = nullptr;
- gpgme_get_key(ctx_, fpr.c_str(), &_p_key, 1);
- if (_p_key == nullptr) {
- SPDLOG_WARN("GpgKeyGetter GetKey Private _p_key Null fpr", fpr);
- return GetPubkey(fpr);
- } else {
- return GpgKey(std::move(_p_key));
- }
-}
+ auto GetKey(const QString& fpr, bool use_cache) -> GpgKey {
+ // find in cache first
+ if (use_cache) {
+ auto key = get_key_in_cache(fpr);
+ if (key.IsGood()) return key;
+ }
-GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetPubkey(const std::string& fpr,
- bool use_cache) {
- // find in cache first
- if (use_cache) {
- auto key = get_key_in_cache(fpr);
- if (key.IsGood()) return key;
+ gpgme_key_t p_key = nullptr;
+ gpgme_get_key(ctx_.DefaultContext(), fpr.toUtf8(), &p_key, 1);
+ if (p_key == nullptr) {
+ GF_CORE_LOG_WARN("GpgKeyGetter GetKey Private _p_key Null fpr", fpr);
+ return GetPubkey(fpr, true);
+ }
+ return GpgKey(std::move(p_key));
}
- gpgme_key_t _p_key = nullptr;
- gpgme_get_key(ctx_, fpr.c_str(), &_p_key, 0);
- if (_p_key == nullptr) SPDLOG_WARN("GpgKeyGetter GetKey _p_key Null", fpr);
- return GpgKey(std::move(_p_key));
-}
+ auto GetPubkey(const QString& fpr, bool use_cache) -> GpgKey {
+ // find in cache first
+ if (use_cache) {
+ auto key = get_key_in_cache(fpr);
+ if (key.IsGood()) return key;
+ }
-GpgFrontend::KeyLinkListPtr GpgFrontend::GpgKeyGetter::FetchKey() {
- // get the lock
- std::lock_guard<std::mutex> lock(keys_cache_mutex_);
+ gpgme_key_t p_key = nullptr;
+ gpgme_get_key(ctx_.DefaultContext(), fpr.toUtf8(), &p_key, 0);
+ if (p_key == nullptr)
+ GF_CORE_LOG_WARN("GpgKeyGetter GetKey _p_key Null", fpr);
+ return GpgKey(std::move(p_key));
+ }
- auto keys_list = std::make_unique<GpgKeyLinkList>();
+ auto FetchKey() -> KeyLinkListPtr {
+ if (keys_cache_.empty()) {
+ FlushKeyCache();
+ }
- for (const auto& [key, value] : keys_cache_) {
- keys_list->push_back(value.Copy());
+ auto keys_list = std::make_unique<GpgKeyLinkList>();
+
+ {
+ // get the lock
+ std::lock_guard<std::mutex> lock(keys_cache_mutex_);
+ for (const auto& [key, value] : keys_cache_) {
+ keys_list->push_back(value);
+ }
+ }
+ return keys_list;
}
- return keys_list;
-}
-void GpgFrontend::GpgKeyGetter::FlushKeyCache() {
- SPDLOG_DEBUG("called channel id: {}", GetChannel());
+ auto FlushKeyCache() -> bool {
+ GF_CORE_LOG_DEBUG("flush key channel called, channel: {}", GetChannel());
- // clear the keys cache
- keys_cache_.clear();
+ // clear the keys cache
+ keys_cache_.clear();
- // init
- GpgError err = gpgme_op_keylist_start(ctx_, nullptr, 0);
+ // init
+ GpgError err = gpgme_op_keylist_start(ctx_.DefaultContext(), nullptr, 0);
- // for debug
- assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
+ // for debug
+ assert(CheckGpgError(err) == GPG_ERR_NO_ERROR);
- // return when error
- if (check_gpg_error_2_err_code(err) != GPG_ERR_NO_ERROR) return;
+ // return when error
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) return false;
- {
- // get the lock
- std::lock_guard<std::mutex> lock(keys_cache_mutex_);
- gpgme_key_t key;
- while ((err = gpgme_op_keylist_next(ctx_, &key)) == GPG_ERR_NO_ERROR) {
- auto gpg_key = GpgKey(std::move(key));
-
- // detect if the key is in a smartcard
- // if so, try to get full information using gpgme_get_key()
- // this maybe a bug in gpgme
- if (gpg_key.IsHasCardKey()) {
- gpg_key = GetKey(gpg_key.GetId(), false);
+ {
+ // get the lock
+ std::lock_guard<std::mutex> lock(keys_cache_mutex_);
+ gpgme_key_t key;
+ while ((err = gpgme_op_keylist_next(ctx_.DefaultContext(), &key)) ==
+ GPG_ERR_NO_ERROR) {
+ auto gpg_key = GpgKey(std::move(key));
+
+ // detect if the key is in a smartcard
+ // if so, try to get full information using gpgme_get_key()
+ // this maybe a bug in gpgme
+ if (gpg_key.IsHasCardKey()) {
+ gpg_key = GetKey(gpg_key.GetId(), false);
+ }
+
+ keys_cache_.insert({gpg_key.GetId(), std::move(gpg_key)});
}
+ }
+
+ GF_CORE_LOG_DEBUG("flush key channel cache address: {} object address: {}",
+ static_cast<void*>(&keys_cache_),
+ static_cast<void*>(this));
+
+ // for debug
+ assert(CheckGpgError2ErrCode(err, GPG_ERR_EOF) == GPG_ERR_EOF);
+
+ err = gpgme_op_keylist_end(ctx_.DefaultContext());
+ assert(CheckGpgError2ErrCode(err, GPG_ERR_EOF) == GPG_ERR_NO_ERROR);
- keys_cache_.insert({gpg_key.GetId(), std::move(gpg_key)});
+ GF_CORE_LOG_DEBUG("flush key channel done, channel: {}", GetChannel());
+ return true;
+ }
+
+ auto GetKeys(const KeyIdArgsListPtr& ids) -> KeyListPtr {
+ auto keys = std::make_unique<KeyArgsList>();
+ for (const auto& key_id : *ids) keys->emplace_back(GetKey(key_id, true));
+ return keys;
+ }
+
+ auto GetKeysCopy(const KeyLinkListPtr& keys) -> KeyLinkListPtr {
+ // get the lock
+ std::lock_guard<std::mutex> lock(ctx_mutex_);
+ auto keys_copy = std::make_unique<GpgKeyLinkList>();
+ for (const auto& key : *keys) keys_copy->emplace_back(key);
+ return keys_copy;
+ }
+
+ auto GetKeysCopy(const KeyListPtr& keys) -> KeyListPtr {
+ // get the lock
+ std::lock_guard<std::mutex> lock(ctx_mutex_);
+ auto keys_copy = std::make_unique<KeyArgsList>();
+ for (const auto& key : *keys) keys_copy->emplace_back(key);
+ return keys_copy;
+ }
+
+ private:
+ /**
+ * @brief Get the gpgme context object
+ *
+ */
+ GpgContext& ctx_ =
+ GpgContext::GetInstance(SingletonFunctionObject::GetChannel());
+
+ /**
+ * @brief shared mutex for the keys cache
+ *
+ */
+ mutable std::mutex ctx_mutex_;
+
+ /**
+ * @brief cache the keys with key id
+ *
+ */
+ std::map<QString, GpgKey> keys_cache_;
+
+ /**
+ * @brief shared mutex for the keys cache
+ *
+ */
+ mutable std::mutex keys_cache_mutex_;
+
+ /**
+ * @brief Get the Key object
+ *
+ * @param id
+ * @return GpgKey
+ */
+ auto get_key_in_cache(const QString& key_id) -> GpgKey {
+ std::lock_guard<std::mutex> lock(keys_cache_mutex_);
+ if (keys_cache_.find(key_id) != keys_cache_.end()) {
+ std::lock_guard<std::mutex> lock(ctx_mutex_);
+ // return a copy of the key in cache
+ return keys_cache_[key_id];
}
+
+ // return a bad key
+ return {};
}
+};
- SPDLOG_DEBUG("cache address: {} object address: {}",
- static_cast<void*>(&keys_cache_), static_cast<void*>(this));
+GpgKeyGetter::GpgKeyGetter(int channel)
+ : SingletonFunctionObject<GpgKeyGetter>(channel),
+ p_(SecureCreateUniqueObject<Impl>(channel)) {
+ GF_CORE_LOG_DEBUG("called channel: {}", channel);
+}
- // for debug
- assert(check_gpg_error_2_err_code(err, GPG_ERR_EOF) == GPG_ERR_EOF);
+GpgKeyGetter::~GpgKeyGetter() = default;
- err = gpgme_op_keylist_end(ctx_);
- assert(check_gpg_error_2_err_code(err, GPG_ERR_EOF) == GPG_ERR_NO_ERROR);
+auto GpgKeyGetter::GetKey(const QString& key_id, bool use_cache) -> GpgKey {
+ return p_->GetKey(key_id, use_cache);
}
-GpgFrontend::KeyListPtr GpgFrontend::GpgKeyGetter::GetKeys(
- const KeyIdArgsListPtr& ids) {
- auto keys = std::make_unique<KeyArgsList>();
- for (const auto& id : *ids) keys->emplace_back(GetKey(id));
- return keys;
+auto GpgKeyGetter::GetPubkey(const QString& key_id, bool use_cache) -> GpgKey {
+ return p_->GetPubkey(key_id, use_cache);
}
-GpgFrontend::KeyLinkListPtr GpgFrontend::GpgKeyGetter::GetKeysCopy(
- const GpgFrontend::KeyLinkListPtr& keys) {
- // get the lock
- std::lock_guard<std::mutex> lock(ctx_mutex_);
- auto keys_copy = std::make_unique<GpgKeyLinkList>();
- for (const auto& key : *keys) keys_copy->emplace_back(key.Copy());
- return keys_copy;
+auto GpgKeyGetter::FlushKeyCache() -> bool { return p_->FlushKeyCache(); }
+
+auto GpgKeyGetter::GetKeys(const KeyIdArgsListPtr& ids) -> KeyListPtr {
+ return p_->GetKeys(ids);
}
-GpgFrontend::KeyListPtr GpgFrontend::GpgKeyGetter::GetKeysCopy(
- const GpgFrontend::KeyListPtr& keys) {
- // get the lock
- std::lock_guard<std::mutex> lock(ctx_mutex_);
- auto keys_copy = std::make_unique<KeyArgsList>();
- for (const auto& key : *keys) keys_copy->emplace_back(key.Copy());
- return keys_copy;
+auto GpgKeyGetter::GetKeysCopy(const KeyLinkListPtr& keys) -> KeyLinkListPtr {
+ return p_->GetKeysCopy(keys);
}
-GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::get_key_in_cache(
- const std::string& id) {
- std::lock_guard<std::mutex> lock(keys_cache_mutex_);
- if (keys_cache_.find(id) != keys_cache_.end()) {
- std::lock_guard<std::mutex> lock(ctx_mutex_);
- // return a copy of the key in cache
- return keys_cache_[id].Copy();
- }
- // return a bad key
- return GpgKey();
+auto GpgKeyGetter::GetKeysCopy(const KeyListPtr& keys) -> KeyListPtr {
+ return p_->GetKeysCopy(keys);
}
+
+auto GpgKeyGetter::FetchKey() -> KeyLinkListPtr { return p_->FetchKey(); }
+
+} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgKeyGetter.h b/src/core/function/gpg/GpgKeyGetter.h
index c96dbea7..91138623 100644
--- a/src/core/function/gpg/GpgKeyGetter.h
+++ b/src/core/function/gpg/GpgKeyGetter.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,21 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H
-#define GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H
+#pragma once
-#include <mutex>
-#include <vector>
-
-#include "core/GpgContext.h"
-#include "core/GpgFunctionObject.h"
-#include "core/GpgModel.h"
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
@@ -50,8 +45,13 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
*
* @param channel
*/
- explicit GpgKeyGetter(
- int channel = SingletonFunctionObject::GetDefaultChannel());
+ explicit GpgKeyGetter(int channel = kGpgFrontendDefaultChannel);
+
+ /**
+ * @brief Destroy the Gpg Key Getter object
+ *
+ */
+ ~GpgKeyGetter();
/**
* @brief Get the Key object
@@ -59,7 +59,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
* @param fpr
* @return GpgKey
*/
- GpgKey GetKey(const std::string& id, bool use_cache = true);
+ auto GetKey(const QString& key_id, bool use_cache = true) -> GpgKey;
/**
* @brief Get the Keys object
@@ -67,7 +67,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
* @param ids
* @return KeyListPtr
*/
- KeyListPtr GetKeys(const KeyIdArgsListPtr& ids);
+ auto GetKeys(const KeyIdArgsListPtr& key_ids) -> KeyListPtr;
/**
* @brief Get the Pubkey object
@@ -75,20 +75,20 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
* @param fpr
* @return GpgKey
*/
- GpgKey GetPubkey(const std::string& id, bool use_cache = true);
+ auto GetPubkey(const QString& key_id, bool use_cache = true) -> GpgKey;
/**
* @brief Get all the keys by receiving a linked list
*
* @return KeyLinkListPtr
*/
- KeyLinkListPtr FetchKey();
+ auto FetchKey() -> KeyLinkListPtr;
/**
* @brief flush the keys in the cache
*
*/
- void FlushKeyCache();
+ auto FlushKeyCache() -> bool;
/**
* @brief Get the Keys Copy object
@@ -96,7 +96,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
* @param keys
* @return KeyListPtr
*/
- KeyListPtr GetKeysCopy(const KeyListPtr& keys);
+ auto GetKeysCopy(const KeyListPtr& keys) -> KeyListPtr;
/**
* @brief Get the Keys Copy object
@@ -104,42 +104,10 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
* @param keys
* @return KeyLinkListPtr
*/
- KeyLinkListPtr GetKeysCopy(const KeyLinkListPtr& keys);
+ auto GetKeysCopy(const KeyLinkListPtr& keys) -> KeyLinkListPtr;
private:
- /**
- * @brief Get the gpgme context object
- *
- */
- GpgContext& ctx_ =
- GpgContext::GetInstance(SingletonFunctionObject::GetChannel());
-
- /**
- * @brief shared mutex for the keys cache
- *
- */
- mutable std::mutex ctx_mutex_;
-
- /**
- * @brief cache the keys with key id
- *
- */
- std::map<std::string, GpgKey> keys_cache_;
-
- /**
- * @brief shared mutex for the keys cache
- *
- */
- mutable std::mutex keys_cache_mutex_;
-
- /**
- * @brief Get the Key object
- *
- * @param id
- * @return GpgKey
- */
- GpgKey get_key_in_cache(const std::string& id);
+ class Impl;
+ SecureUniquePtr<Impl> p_;
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H
diff --git a/src/core/function/gpg/GpgKeyImportExporter.cpp b/src/core/function/gpg/GpgKeyImportExporter.cpp
index 01349c94..09b51359 100644
--- a/src/core/function/gpg/GpgKeyImportExporter.cpp
+++ b/src/core/function/gpg/GpgKeyImportExporter.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,79 +28,76 @@
#include "GpgKeyImportExporter.h"
-#include <memory>
+#include "core/GpgModel.h"
+#include "core/model/GpgImportInformation.h"
+#include "core/utils/AsyncUtils.h"
+#include "core/utils/GpgUtils.h"
-#include "GpgConstants.h"
-#include "GpgKeyGetter.h"
+namespace GpgFrontend {
-GpgFrontend::GpgKeyImportExporter::GpgKeyImportExporter(int channel)
- : SingletonFunctionObject<GpgKeyImportExporter>(channel) {}
+GpgKeyImportExporter::GpgKeyImportExporter(int channel)
+ : SingletonFunctionObject<GpgKeyImportExporter>(channel),
+ ctx_(GpgContext::GetInstance(SingletonFunctionObject::GetChannel())) {}
/**
* Import key pair
* @param inBuffer input byte array
* @return Import information
*/
-GpgFrontend::GpgImportInformation GpgFrontend::GpgKeyImportExporter::ImportKey(
- StdBypeArrayPtr in_buffer) {
- if (in_buffer->empty()) return {};
+auto GpgKeyImportExporter::ImportKey(const GFBuffer& in_buffer)
+ -> std::shared_ptr<GpgImportInformation> {
+ if (in_buffer.Empty()) return {};
- GpgData data_in(in_buffer->data(), in_buffer->size());
- auto err = check_gpg_error(gpgme_op_import(ctx_, data_in));
+ GpgData data_in(in_buffer);
+ auto err = CheckGpgError(gpgme_op_import(ctx_.DefaultContext(), data_in));
if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
gpgme_import_result_t result;
- result = gpgme_op_import_result(ctx_);
+ result = gpgme_op_import_result(ctx_.DefaultContext());
gpgme_import_status_t status = result->imports;
- auto import_info = std::make_unique<GpgImportInformation>(result);
+ auto import_info = SecureCreateSharedObject<GpgImportInformation>(result);
while (status != nullptr) {
- GpgImportedKey key;
+ GpgImportInformation::GpgImportedKey key;
key.import_status = static_cast<int>(status->status);
key.fpr = status->fpr;
- import_info->importedKeys.emplace_back(key);
+ import_info->imported_keys.emplace_back(key);
status = status->next;
}
- return *import_info;
+ return import_info;
}
/**
- * Export Key
- * @param uid_list key ids
- * @param out_buffer output byte array
+ * Export keys
+ * @param keys keys used
+ * @param outBuffer output byte array
* @return if success
*/
-bool GpgFrontend::GpgKeyImportExporter::ExportKeys(KeyIdArgsListPtr& uid_list,
- ByteArrayPtr& out_buffer,
- bool secret) const {
- if (uid_list->empty()) return false;
+auto GpgKeyImportExporter::ExportKey(const GpgKey& key, bool secret, bool ascii,
+ bool shortest, bool ssh_mode) const
+ -> std::tuple<GpgError, GFBuffer> {
+ if (!key.IsGood()) return {GPG_ERR_CANCELED, {}};
- int _mode = 0;
- if (secret) _mode |= GPGME_EXPORT_MODE_SECRET;
+ int mode = 0;
+ if (secret) mode |= GPGME_EXPORT_MODE_SECRET;
+ if (shortest) mode |= GPGME_EXPORT_MODE_MINIMAL;
+ if (ssh_mode) mode |= GPGME_EXPORT_MODE_SSH;
- auto keys = GpgKeyGetter::GetInstance().GetKeys(uid_list);
- auto keys_array = new gpgme_key_t[keys->size() + 1];
+ std::vector<gpgme_key_t> keys_array;
- int index = 0;
- for (const auto& key : *keys) {
- keys_array[index++] = gpgme_key_t(key);
- }
- keys_array[index] = nullptr;
+ // Last entry data_in array has to be nullptr
+ keys_array.emplace_back(key);
+ keys_array.emplace_back(nullptr);
GpgData data_out;
- auto err = gpgme_op_export_keys(ctx_, keys_array, _mode, data_out);
- if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return false;
-
- delete[] keys_array;
-
- SPDLOG_DEBUG("export keys read_bytes: {}",
- gpgme_data_seek(data_out, 0, SEEK_END));
-
- auto temp_out_buffer = data_out.Read2Buffer();
-
- swap(temp_out_buffer, out_buffer);
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = gpgme_op_export_keys(ctx, keys_array.data(), mode, data_out);
+ if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
- return true;
+ GF_CORE_LOG_DEBUG(
+ "operation of exporting a key finished, ascii: {}, read_bytes: {}", ascii,
+ gpgme_data_seek(data_out, 0, SEEK_END));
+ return {err, data_out.Read2GFBuffer()};
}
/**
@@ -109,114 +106,36 @@ bool GpgFrontend::GpgKeyImportExporter::ExportKeys(KeyIdArgsListPtr& uid_list,
* @param outBuffer output byte array
* @return if success
*/
-bool GpgFrontend::GpgKeyImportExporter::ExportKeys(const KeyArgsList& keys,
- ByteArrayPtr& out_buffer,
- bool secret) const {
- KeyIdArgsListPtr key_ids = std::make_unique<std::vector<std::string>>();
- for (const auto& key : keys) key_ids->push_back(key.GetId());
- return ExportKeys(key_ids, out_buffer, secret);
+void GpgKeyImportExporter::ExportKeys(const KeyArgsList& keys, bool secret,
+ bool ascii, bool shortest, bool ssh_mode,
+ const GpgOperationCallback& cb) const {
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ if (keys.empty()) return GPG_ERR_CANCELED;
+
+ int mode = 0;
+ if (secret) mode |= GPGME_EXPORT_MODE_SECRET;
+ if (shortest) mode |= GPGME_EXPORT_MODE_MINIMAL;
+ if (ssh_mode) mode |= GPGME_EXPORT_MODE_SSH;
+
+ std::vector<gpgme_key_t> keys_array(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ keys_array.emplace_back(nullptr);
+
+ GpgData data_out;
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = gpgme_op_export_keys(ctx, keys_array.data(), mode, data_out);
+ if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
+
+ GF_CORE_LOG_DEBUG(
+ "operation of exporting keys finished, ascii: {}, read_bytes: {}",
+ ascii, gpgme_data_seek(data_out, 0, SEEK_END));
+
+ data_object->Swap({data_out.Read2GFBuffer()});
+ return err;
+ },
+ cb, "gpgme_op_export_keys", "2.1.0");
}
-/**
- * Export all the keys both private and public keys
- * @param uid_list key ids
- * @param out_buffer output byte array
- * @return if success
- */
-bool GpgFrontend::GpgKeyImportExporter::ExportAllKeys(
- KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer, bool secret) const {
- bool result = true;
- result = ExportKeys(uid_list, out_buffer, false) & result;
-
- ByteArrayPtr temp_buffer;
- if (secret) {
- result = ExportKeys(uid_list, temp_buffer, true) & result;
- }
- out_buffer->append(*temp_buffer);
- return result;
-}
-
-/**
- * Export the secret key of a key pair(including subkeys)
- * @param key target key pair
- * @param outBuffer output byte array
- * @return if successful
- */
-bool GpgFrontend::GpgKeyImportExporter::ExportSecretKey(
- const GpgKey& key, ByteArrayPtr& out_buffer) const {
- SPDLOG_DEBUG("export secret key: {}", key.GetId().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;
-}
-
-bool GpgFrontend::GpgKeyImportExporter::ExportKey(
- const GpgFrontend::GpgKey& key,
- GpgFrontend::ByteArrayPtr& out_buffer) const {
- GpgData data_out;
- auto err = gpgme_op_export(ctx_, key.GetId().c_str(), 0, data_out);
-
- SPDLOG_DEBUG("export keys read_bytes: {}",
- gpgme_data_seek(data_out, 0, SEEK_END));
-
- auto temp_out_buffer = data_out.Read2Buffer();
- std::swap(out_buffer, temp_out_buffer);
- return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
-}
-
-bool GpgFrontend::GpgKeyImportExporter::ExportKeyOpenSSH(
- const GpgFrontend::GpgKey& key,
- GpgFrontend::ByteArrayPtr& out_buffer) const {
- GpgData data_out;
- auto err = gpgme_op_export(ctx_, key.GetId().c_str(), GPGME_EXPORT_MODE_SSH,
- data_out);
-
- SPDLOG_DEBUG("read_bytes: {}", gpgme_data_seek(data_out, 0, SEEK_END));
-
- auto temp_out_buffer = data_out.Read2Buffer();
- std::swap(out_buffer, temp_out_buffer);
- return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
-}
-
-bool GpgFrontend::GpgKeyImportExporter::ExportSecretKeyShortest(
- const GpgFrontend::GpgKey& key,
- GpgFrontend::ByteArrayPtr& out_buffer) const {
- GpgData data_out;
- auto err = gpgme_op_export(ctx_, key.GetId().c_str(),
- GPGME_EXPORT_MODE_MINIMAL, data_out);
-
- SPDLOG_DEBUG("read_bytes: {}", gpgme_data_seek(data_out, 0, SEEK_END));
-
- auto temp_out_buffer = data_out.Read2Buffer();
- std::swap(out_buffer, temp_out_buffer);
- return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
-}
-
-GpgFrontend::GpgImportInformation::GpgImportInformation() = default;
-
-GpgFrontend::GpgImportInformation::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;
-}
+} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgKeyImportExporter.h b/src/core/function/gpg/GpgKeyImportExporter.h
index 6e90f436..14b2b2bf 100644
--- a/src/core/function/gpg/GpgKeyImportExporter.h
+++ b/src/core/function/gpg/GpgKeyImportExporter.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,67 +20,22 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef _GPGKEYIMPORTEXPORTOR_H
-#define _GPGKEYIMPORTEXPORTOR_H
+#pragma once
-#include <string>
-
-#include "core/GpgConstants.h"
-#include "core/GpgContext.h"
-#include "core/GpgFunctionObject.h"
-#include "core/GpgModel.h"
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/model/GFBuffer.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
-/**
- * @brief
- *
- */
-class GpgImportedKey {
- public:
- std::string fpr; ///<
- int import_status; ///<
-};
-
-typedef std::list<GpgImportedKey> GpgImportedKeyList; ///<
-
-/**
- * @brief
- *
- */
-class GPGFRONTEND_CORE_EXPORT GpgImportInformation {
- public:
- GpgImportInformation();
-
- /**
- * @brief Construct a new Gpg Import Information object
- *
- * @param result
- */
- explicit GpgImportInformation(gpgme_import_result_t result);
-
- 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 GpgImportInformation;
/**
* @brief
@@ -103,31 +58,19 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyImportExporter
* @param inBuffer
* @return GpgImportInformation
*/
- GpgImportInformation ImportKey(StdBypeArrayPtr inBuffer);
+ auto ImportKey(const GFBuffer&) -> std::shared_ptr<GpgImportInformation>;
/**
* @brief
*
- * @param uid_list
- * @param out_buffer
- * @param secret
- * @return true
- * @return false
- */
- bool ExportKeys(KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer,
- bool secret = false) const;
-
- /**
- * @brief
- *
- * @param keys
- * @param outBuffer
+ * @param key
* @param secret
- * @return true
- * @return false
+ * @param ascii
+ * @return std::tuple<GpgError, GFBuffer>
*/
- bool ExportKeys(const KeyArgsList& keys, ByteArrayPtr& outBuffer,
- bool secret = false) const;
+ [[nodiscard]] auto ExportKey(const GpgKey& key, bool secret, bool ascii,
+ bool shortest, bool ssh_mode = false) const
+ -> std::tuple<GpgError, GFBuffer>;
/**
* @brief
@@ -138,55 +81,12 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyImportExporter
* @return true
* @return false
*/
- bool ExportAllKeys(KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer,
- bool secret) const;
-
- /**
- * @brief
- *
- * @param key
- * @param out_buffer
- * @return true
- * @return false
- */
- bool ExportKey(const GpgKey& key, ByteArrayPtr& out_buffer) const;
-
- /**
- * @brief
- *
- * @param key
- * @param out_buffer
- * @return true
- * @return false
- */
- bool ExportKeyOpenSSH(const GpgKey& key, ByteArrayPtr& out_buffer) const;
-
- /**
- * @brief
- *
- * @param key
- * @param outBuffer
- * @return true
- * @return false
- */
- bool ExportSecretKey(const GpgKey& key, ByteArrayPtr& outBuffer) const;
-
- /**
- * @brief
- *
- * @param key
- * @param outBuffer
- * @return true
- * @return false
- */
- bool ExportSecretKeyShortest(const GpgKey& key,
- ByteArrayPtr& outBuffer) const;
+ void ExportKeys(const KeyArgsList& keys, bool secret, bool ascii,
+ bool shortest, bool ssh_mode,
+ const GpgOperationCallback& cb) const;
private:
- GpgContext& ctx_ =
- GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); ///<
+ GpgContext& ctx_;
};
} // namespace GpgFrontend
-
-#endif // _GPGKEYIMPORTEXPORTOR_H \ No newline at end of file
diff --git a/src/core/function/gpg/GpgKeyManager.cpp b/src/core/function/gpg/GpgKeyManager.cpp
index e556eec6..8d7d9a28 100644
--- a/src/core/function/gpg/GpgKeyManager.cpp
+++ b/src/core/function/gpg/GpgKeyManager.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,150 +28,146 @@
#include "GpgKeyManager.h"
-#include <boost/algorithm/string.hpp>
-#include <boost/date_time/posix_time/conversion.hpp>
-#include <memory>
-#include <string>
-
-#include "GpgBasicOperator.h"
-#include "GpgKeyGetter.h"
-#include "spdlog/spdlog.h"
+#include "core/GpgModel.h"
+#include "core/function/gpg/GpgBasicOperator.h"
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/utils/GpgUtils.h"
GpgFrontend::GpgKeyManager::GpgKeyManager(int channel)
: SingletonFunctionObject<GpgKeyManager>(channel) {}
-bool GpgFrontend::GpgKeyManager::SignKey(
+auto GpgFrontend::GpgKeyManager::SignKey(
const GpgFrontend::GpgKey& target, GpgFrontend::KeyArgsList& keys,
- const std::string& uid,
- const std::unique_ptr<boost::posix_time::ptime>& expires) {
- using namespace boost::posix_time;
-
- GpgBasicOperator::GetInstance().SetSigners(keys);
+ const QString& uid, const std::unique_ptr<QDateTime>& expires) -> bool {
+ GpgBasicOperator::GetInstance().SetSigners(keys, true);
unsigned int flags = 0;
unsigned int expires_time_t = 0;
- if (expires == nullptr)
+ if (expires == nullptr) {
flags |= GPGME_KEYSIGN_NOEXPIRE;
- else
- expires_time_t = to_time_t(*expires);
+ } else {
+ expires_time_t = expires->toSecsSinceEpoch();
+ }
- auto err = check_gpg_error(gpgme_op_keysign(
- ctx_, gpgme_key_t(target), uid.c_str(), expires_time_t, flags));
+ auto err = CheckGpgError(
+ gpgme_op_keysign(ctx_.DefaultContext(), static_cast<gpgme_key_t>(target),
+ uid.toUtf8(), expires_time_t, flags));
- return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
-bool GpgFrontend::GpgKeyManager::RevSign(
+auto GpgFrontend::GpgKeyManager::RevSign(
const GpgFrontend::GpgKey& key,
- const GpgFrontend::SignIdArgsListPtr& signature_id) {
+ const GpgFrontend::SignIdArgsListPtr& signature_id) -> bool {
auto& key_getter = GpgKeyGetter::GetInstance();
for (const auto& sign_id : *signature_id) {
auto signing_key = key_getter.GetKey(sign_id.first);
assert(signing_key.IsGood());
- 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;
+ auto err = CheckGpgError(
+ gpgme_op_revsig(ctx_.DefaultContext(), gpgme_key_t(key),
+ gpgme_key_t(signing_key), sign_id.second.toUtf8(), 0));
+ if (CheckGpgError(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::posix_time::ptime>& expires) {
- using namespace boost::posix_time;
-
+auto GpgFrontend::GpgKeyManager::SetExpire(const GpgFrontend::GpgKey& key,
+ std::unique_ptr<GpgSubKey>& subkey,
+ std::unique_ptr<QDateTime>& expires)
+ -> bool {
unsigned long expires_time = 0;
- if (expires != nullptr) expires_time = to_time_t(ptime(*expires));
+ if (expires != nullptr) expires_time = expires->toSecsSinceEpoch();
const char* sub_fprs = nullptr;
- if (subkey != nullptr) sub_fprs = subkey->GetFingerprint().c_str();
+ if (subkey != nullptr) sub_fprs = subkey->GetFingerprint().toUtf8();
- auto err = check_gpg_error(
- gpgme_op_setexpire(ctx_, gpgme_key_t(key), expires_time, sub_fprs, 0));
+ auto err = CheckGpgError(gpgme_op_setexpire(ctx_.DefaultContext(),
+ static_cast<gpgme_key_t>(key),
+ expires_time, sub_fprs, 0));
- return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
-bool GpgFrontend::GpgKeyManager::SetOwnerTrustLevel(const GpgKey& key,
- int trust_level) {
+auto GpgFrontend::GpgKeyManager::SetOwnerTrustLevel(const GpgKey& key,
+ int trust_level) -> bool {
if (trust_level < 0 || trust_level > 5) {
- SPDLOG_ERROR("illegal owner trust level: {}", trust_level);
+ GF_CORE_LOG_ERROR("illegal owner trust level: {}", trust_level);
}
- AutomatonNextStateHandler next_state_handler =
- [](AutomatonState state, std::string status, std::string args) {
- SPDLOG_DEBUG("next_state_handler state: {}, gpg_status: {}, args: {}",
- state, status, args);
- std::vector<std::string> tokens;
- boost::split(tokens, args, boost::is_any_of(" "));
-
- switch (state) {
- case AS_START:
- if (status == "GET_LINE" && args == "keyedit.prompt")
- return AS_COMMAND;
- return AS_ERROR;
- case AS_COMMAND:
- if (status == "GET_LINE" && args == "edit_ownertrust.value") {
- return AS_VALUE;
- }
- return AS_ERROR;
- case AS_VALUE:
- if (status == "GET_LINE" && args == "keyedit.prompt") {
- return AS_QUIT;
- } else if (status == "GET_BOOL" &&
- args == "edit_ownertrust.set_ultimate.okay") {
- return AS_REALLY_ULTIMATE;
- }
- return AS_ERROR;
- case AS_REALLY_ULTIMATE:
- if (status == "GET_LINE" && args == "keyedit.prompt") {
- return AS_QUIT;
- }
- return AS_ERROR;
- case AS_QUIT:
- if (status == "GET_LINE" && args == "keyedit.save.okay") {
- return AS_SAVE;
- }
- return AS_ERROR;
- case AS_ERROR:
- if (status == "GET_LINE" && args == "keyedit.prompt") {
- return AS_QUIT;
- }
- return AS_ERROR;
- default:
- return AS_ERROR;
- };
- };
+ AutomatonNextStateHandler next_state_handler = [](AutomatonState state,
+ QString status,
+ QString args) {
+ GF_CORE_LOG_DEBUG("next_state_handler state: {}, gpg_status: {}, args: {}",
+ state, status, args);
+ auto tokens = args.split(' ');
+
+ switch (state) {
+ case AS_START:
+ if (status == "GET_LINE" && args == "keyedit.prompt") {
+ return AS_COMMAND;
+ }
+ return AS_ERROR;
+ case AS_COMMAND:
+ if (status == "GET_LINE" && args == "edit_ownertrust.value") {
+ return AS_VALUE;
+ }
+ return AS_ERROR;
+ case AS_VALUE:
+ if (status == "GET_LINE" && args == "keyedit.prompt") {
+ return AS_QUIT;
+ } else if (status == "GET_BOOL" &&
+ args == "edit_ownertrust.set_ultimate.okay") {
+ return AS_REALLY_ULTIMATE;
+ }
+ return AS_ERROR;
+ case AS_REALLY_ULTIMATE:
+ if (status == "GET_LINE" && args == "keyedit.prompt") {
+ return AS_QUIT;
+ }
+ return AS_ERROR;
+ case AS_QUIT:
+ if (status == "GET_LINE" && args == "keyedit.save.okay") {
+ return AS_SAVE;
+ }
+ return AS_ERROR;
+ case AS_ERROR:
+ if (status == "GET_LINE" && args == "keyedit.prompt") {
+ return AS_QUIT;
+ }
+ return AS_ERROR;
+ default:
+ return AS_ERROR;
+ };
+ };
AutomatonActionHandler action_handler =
[trust_level](AutomatonHandelStruct& handler, AutomatonState state) {
- SPDLOG_DEBUG("action_handler state: {}", state);
+ GF_CORE_LOG_DEBUG("action_handler state: {}", state);
switch (state) {
case AS_COMMAND:
- return std::string("trust");
+ return QString("trust");
case AS_VALUE:
handler.SetSuccess(true);
- return std::to_string(trust_level);
+ return QString::number(trust_level);
case AS_REALLY_ULTIMATE:
handler.SetSuccess(true);
- return std::string("Y");
+ return QString("Y");
case AS_QUIT:
- return std::string("quit");
+ return QString("quit");
case AS_SAVE:
handler.SetSuccess(true);
- return std::string("Y");
+ return QString("Y");
case AS_START:
case AS_ERROR:
- return std::string("");
+ return QString("");
default:
- return std::string("");
+ return QString("");
}
- return std::string("");
+ return QString("");
};
auto key_fpr = key.GetFingerprint();
@@ -180,49 +176,43 @@ bool GpgFrontend::GpgKeyManager::SetOwnerTrustLevel(const GpgKey& key,
GpgData data_out;
- auto err = gpgme_op_interact(ctx_, gpgme_key_t(key), 0,
- GpgKeyManager::interactor_cb_fnc,
- (void*)&handel_struct, data_out);
- if (err != GPG_ERR_NO_ERROR) {
- SPDLOG_ERROR("fail to set owner trust level {} to key {}, err: {}",
- trust_level, key.GetId(), gpgme_strerror(err));
- }
-
- return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR &&
- handel_struct.Success();
+ auto err = gpgme_op_interact(
+ ctx_.DefaultContext(), static_cast<gpgme_key_t>(key), 0,
+ GpgKeyManager::interactor_cb_fnc, (void*)&handel_struct, data_out);
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR && handel_struct.Success();
}
-gpgme_error_t GpgFrontend::GpgKeyManager::interactor_cb_fnc(void* handle,
- const char* status,
- const char* args,
- int fd) {
- auto handle_struct = static_cast<AutomatonHandelStruct*>(handle);
- std::string status_s = status;
- std::string args_s = args;
- SPDLOG_DEBUG("cb start status: {}, args: {}, fd: {}, handle struct state: {}",
- status_s, args_s, fd, handle_struct->CuurentStatus());
+auto GpgFrontend::GpgKeyManager::interactor_cb_fnc(void* handle,
+ const char* status,
+ const char* args, int fd)
+ -> gpgme_error_t {
+ auto* handle_struct = static_cast<AutomatonHandelStruct*>(handle);
+ QString status_s = status;
+ QString args_s = args;
+ GF_CORE_LOG_DEBUG(
+ "cb start status: {}, args: {}, fd: {}, handle struct state: {}",
+ status_s, args_s, fd, handle_struct->CuurentStatus());
if (status_s == "KEY_CONSIDERED") {
- std::vector<std::string> tokens;
- boost::split(tokens, args, boost::is_any_of(" "));
+ auto tokens = QString(args).split(' ');
if (tokens.empty() || tokens[0] != handle_struct->KeyFpr()) {
- SPDLOG_ERROR("handle struct key fpr {} mismatch token: {}, exit...",
- handle_struct->KeyFpr(), tokens[0]);
+ GF_CORE_LOG_ERROR("handle struct key fpr {} mismatch token: {}, exit...",
+ handle_struct->KeyFpr(), tokens[0]);
return -1;
}
return 0;
}
- if (status_s == "GOT_IT" || status_s.empty()) {
- SPDLOG_DEBUG("status GOT_IT, continue...");
+ if (status_s == "GOT_IT" || status_s.isEmpty()) {
+ GF_CORE_LOG_DEBUG("status GOT_IT, continue...");
return 0;
}
AutomatonState next_state = handle_struct->NextState(status_s, args_s);
if (next_state == AS_ERROR) {
- SPDLOG_DEBUG("handle struct next state caught error, skipping...");
+ GF_CORE_LOG_DEBUG("handle struct next state caught error, skipping...");
return GPG_ERR_FALSE;
}
@@ -233,10 +223,11 @@ gpgme_error_t GpgFrontend::GpgKeyManager::interactor_cb_fnc(void* handle,
// set state and preform action
handle_struct->SetStatus(next_state);
Command cmd = handle_struct->Action();
- SPDLOG_DEBUG("handle struct action done, next state: {}, action cmd: {}",
- next_state, cmd);
- if (!cmd.empty()) {
- gpgme_io_write(fd, cmd.c_str(), cmd.size());
+ GF_CORE_LOG_DEBUG("handle struct action done, next state: {}, action cmd: {}",
+ next_state, cmd);
+ if (!cmd.isEmpty()) {
+ auto btye_array = cmd.toUtf8();
+ gpgme_io_write(fd, btye_array, btye_array.size());
gpgme_io_write(fd, "\n", 1);
} else if (status_s == "GET_LINE") {
// avoid trapping in this state
diff --git a/src/core/function/gpg/GpgKeyManager.h b/src/core/function/gpg/GpgKeyManager.h
index 62f7baca..8b4d41b2 100644
--- a/src/core/function/gpg/GpgKeyManager.h
+++ b/src/core/function/gpg/GpgKeyManager.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,21 +20,19 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H
-#define GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H
+#pragma once
#include <functional>
-#include <string>
-#include "core/GpgContext.h"
-#include "core/GpgFunctionObject.h"
-#include "core/GpgModel.h"
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
@@ -60,8 +58,8 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager
* @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::posix_time::ptime>& expires);
+ auto SignKey(const GpgKey& target, KeyArgsList& keys, const QString& uid,
+ const std::unique_ptr<QDateTime>& expires) -> bool;
/**
* @brief
@@ -71,8 +69,8 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager
* @return true
* @return false
*/
- bool RevSign(const GpgFrontend::GpgKey& key,
- const GpgFrontend::SignIdArgsListPtr& signature_id);
+ auto RevSign(const GpgFrontend::GpgKey& key,
+ const GpgFrontend::SignIdArgsListPtr& signature_id) -> bool;
/**
* @brief Set the Expire object
@@ -83,21 +81,21 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager
* @return true
* @return false
*/
- bool SetExpire(const GpgKey& key, std::unique_ptr<GpgSubKey>& subkey,
- std::unique_ptr<boost::posix_time::ptime>& expires);
+ auto SetExpire(const GpgKey& key, std::unique_ptr<GpgSubKey>& subkey,
+ std::unique_ptr<QDateTime>& expires) -> bool;
/**
* @brief
*
* @return
*/
- bool SetOwnerTrustLevel(const GpgKey& key, int trust_level);
+ auto SetOwnerTrustLevel(const GpgKey& key, int trust_level) -> bool;
private:
- static gpgme_error_t interactor_cb_fnc(void* handle, const char* status,
- const char* args, int fd);
+ static auto interactor_cb_fnc(void* handle, const char* status,
+ const char* args, int fd) -> gpgme_error_t;
- using Command = std::string;
+ using Command = QString;
using AutomatonState = enum {
AS_START,
AS_COMMAND,
@@ -113,35 +111,37 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager
using AutomatonActionHandler =
std::function<Command(AutomatonHandelStruct&, AutomatonState)>;
using AutomatonNextStateHandler =
- std::function<AutomatonState(AutomatonState, std::string, std::string)>;
+ std::function<AutomatonState(AutomatonState, QString, QString)>;
struct AutomatonHandelStruct {
void SetStatus(AutomatonState next_state) { current_state_ = next_state; }
- AutomatonState CuurentStatus() { return current_state_; }
+ auto CuurentStatus() -> AutomatonState { return current_state_; }
void SetHandler(AutomatonNextStateHandler next_state_handler,
AutomatonActionHandler action_handler) {
- next_state_handler_ = next_state_handler;
- action_handler_ = action_handler;
+ next_state_handler_ = std::move(next_state_handler);
+ action_handler_ = std::move(action_handler);
}
- AutomatonState NextState(std::string gpg_status, std::string args) {
- return next_state_handler_(current_state_, gpg_status, args);
+ auto NextState(QString gpg_status, QString args) -> AutomatonState {
+ return next_state_handler_(current_state_, std::move(gpg_status),
+ std::move(args));
}
- Command Action() { return action_handler_(*this, current_state_); }
+ auto Action() -> Command { return action_handler_(*this, current_state_); }
void SetSuccess(bool success) { success_ = success; }
- bool Success() { return success_; }
+ [[nodiscard]] auto Success() const -> bool { return success_; }
- std::string KeyFpr() { return key_fpr_; }
+ auto KeyFpr() -> QString { return key_fpr_; }
- AutomatonHandelStruct(std::string key_fpr) : key_fpr_(key_fpr) {}
+ explicit AutomatonHandelStruct(QString key_fpr)
+ : key_fpr_(std::move(key_fpr)) {}
private:
AutomatonState current_state_ = AS_START;
AutomatonNextStateHandler next_state_handler_;
AutomatonActionHandler action_handler_;
bool success_ = false;
- std::string key_fpr_;
+ QString key_fpr_;
};
GpgContext& ctx_ =
@@ -149,5 +149,3 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H
diff --git a/src/core/function/gpg/GpgKeyOpera.cpp b/src/core/function/gpg/GpgKeyOpera.cpp
index d5919cff..d9133905 100644
--- a/src/core/function/gpg/GpgKeyOpera.cpp
+++ b/src/core/function/gpg/GpgKeyOpera.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,38 +28,42 @@
#include "GpgKeyOpera.h"
-#include <boost/asio.hpp>
-#include <boost/date_time/posix_time/conversion.hpp>
-#include <boost/format.hpp>
-#include <boost/process/async_pipe.hpp>
-#include <memory>
-#include <string>
-#include <vector>
+#include <gpg-error.h>
-#include "GpgCommandExecutor.h"
-#include "GpgKeyGetter.h"
-#include "core/GpgConstants.h"
-#include "core/GpgGenKeyInfo.h"
+#include <memory>
-GpgFrontend::GpgKeyOpera::GpgKeyOpera(int channel)
+#include "core/GpgModel.h"
+#include "core/function/gpg/GpgCommandExecutor.h"
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/model/DataObject.h"
+#include "core/model/GpgGenKeyInfo.h"
+#include "core/model/GpgGenerateKeyResult.h"
+#include "core/module/ModuleManager.h"
+#include "core/typedef/GpgTypedef.h"
+#include "core/utils/AsyncUtils.h"
+#include "core/utils/CommonUtils.h"
+#include "core/utils/GpgUtils.h"
+
+namespace GpgFrontend {
+
+GpgKeyOpera::GpgKeyOpera(int channel)
: SingletonFunctionObject<GpgKeyOpera>(channel) {}
/**
* Delete keys
* @param uidList key ids
*/
-void GpgFrontend::GpgKeyOpera::DeleteKeys(
- GpgFrontend::KeyIdArgsListPtr key_ids) {
+void GpgKeyOpera::DeleteKeys(GpgFrontend::KeyIdArgsListPtr key_ids) {
GpgError err;
for (const auto& tmp : *key_ids) {
auto key = GpgKeyGetter::GetInstance().GetKey(tmp);
if (key.IsGood()) {
- err = check_gpg_error(
- gpgme_op_delete_ext(ctx_, gpgme_key_t(key),
- GPGME_DELETE_ALLOW_SECRET | GPGME_DELETE_FORCE));
+ err = CheckGpgError(gpgme_op_delete_ext(
+ ctx_.DefaultContext(), static_cast<gpgme_key_t>(key),
+ GPGME_DELETE_ALLOW_SECRET | GPGME_DELETE_FORCE));
assert(gpg_err_code(err) == GPG_ERR_NO_ERROR);
} else {
- SPDLOG_WARN("GpgKeyOpera DeleteKeys get key failed", tmp);
+ GF_CORE_LOG_WARN("GpgKeyOpera DeleteKeys get key failed", tmp);
}
}
}
@@ -72,26 +76,24 @@ void GpgFrontend::GpgKeyOpera::DeleteKeys(
* @param expires date and time
* @return if successful
*/
-GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::SetExpire(
- const GpgKey& key, const SubkeyId& subkey_fpr,
- std::unique_ptr<boost::posix_time::ptime>& expires) {
+auto GpgKeyOpera::SetExpire(const GpgKey& key, const SubkeyId& subkey_fpr,
+ std::unique_ptr<QDateTime>& expires) -> GpgError {
unsigned long expires_time = 0;
if (expires != nullptr) {
- using namespace boost::posix_time;
- using namespace std::chrono;
- expires_time =
- to_time_t(*expires) - system_clock::to_time_t(system_clock::now());
+ expires_time = QDateTime::currentDateTime().secsTo(*expires);
}
- SPDLOG_DEBUG(key.GetId(), subkey_fpr, expires_time);
-
GpgError err;
- if (key.GetFingerprint() == subkey_fpr || 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);
+ if (key.GetFingerprint() == subkey_fpr || subkey_fpr.isEmpty()) {
+ err =
+ gpgme_op_setexpire(ctx_.DefaultContext(), static_cast<gpgme_key_t>(key),
+ expires_time, nullptr, 0);
+ } else {
+ err =
+ gpgme_op_setexpire(ctx_.DefaultContext(), static_cast<gpgme_key_t>(key),
+ expires_time, subkey_fpr.toUtf8(), 0);
+ }
return err;
}
@@ -102,48 +104,52 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::SetExpire(
* @param outputFileName out file name(path)
* @return the process doing this job
*/
-void GpgFrontend::GpgKeyOpera::GenerateRevokeCert(
- const GpgKey& key, const std::string& output_file_path) {
+void GpgKeyOpera::GenerateRevokeCert(const GpgKey& key,
+ const QString& output_path) {
+ const auto app_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.app_path", QString{});
// get all components
- GpgCommandExecutor::GetInstance().Execute(
- ctx_.GetInfo().AppPath,
- {"--command-fd", "0", "--status-fd", "1", "--no-tty", "-o",
- output_file_path, "--gen-revoke", key.GetFingerprint().c_str()},
- [=](int exit_code, const std::string& p_out, const std::string& p_err) {
- if (exit_code != 0) {
- SPDLOG_ERROR(
- "gnupg gen revoke execute error, process stderr: {}, process "
- "stdout: {}",
- p_err, p_out);
- } else {
- SPDLOG_DEBUG(
- "gnupg gen revoke exit_code: {}, process stdout size: {}",
- exit_code, p_out.size());
- }
- },
- [](QProcess* proc) -> void {
- // Code From Gpg4Win
- while (proc->canReadLine()) {
- const QString line = QString::fromUtf8(proc->readLine()).trimmed();
- SPDLOG_DEBUG("line: {}", line.toStdString());
- if (line == QLatin1String("[GNUPG:] GET_BOOL gen_revoke.okay")) {
- proc->write("y\n");
- } else if (line == QLatin1String("[GNUPG:] GET_LINE "
- "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");
- }
- }
- });
+ GpgCommandExecutor::ExecuteSync(
+ {app_path,
+ {"--command-fd", "0", "--status-fd", "1", "--no-tty", "-o", output_path,
+ "--gen-revoke", key.GetFingerprint()},
+ [=](int exit_code, const QString& p_out, const QString& p_err) {
+ if (exit_code != 0) {
+ GF_CORE_LOG_ERROR(
+ "gnupg gen revoke execute error, process stderr: {}, process "
+ "stdout: {}",
+ p_err, p_out);
+ } else {
+ GF_CORE_LOG_DEBUG(
+ "gnupg gen revoke exit_code: {}, process stdout size: {}",
+ exit_code, p_out.size());
+ }
+ },
+ nullptr,
+ [](QProcess* proc) -> void {
+ // Code From Gpg4Win
+ while (proc->canReadLine()) {
+ const QString line = QString::fromUtf8(proc->readLine()).trimmed();
+ GF_CORE_LOG_DEBUG("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");
+ }
+ }
+ }});
}
/**
@@ -151,138 +157,199 @@ void GpgFrontend::GpgKeyOpera::GenerateRevokeCert(
* @param params key generation args
* @return error information
*/
-GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateKey(
- const std::unique_ptr<GenKeyInfo>& params, GpgGenKeyResult& result) {
- auto userid_utf8 = params->GetUserid();
- const char* userid = userid_utf8.c_str();
- auto algo_utf8 = params->GetAlgo() + params->GetKeySizeStr();
-
- SPDLOG_DEBUG("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->GetExpireTime())) -
- system_clock::to_time_t(system_clock::now());
- }
+void GpgKeyOpera::GenerateKey(const std::shared_ptr<GenKeyInfo>& params,
+ const GpgOperationCallback& callback) {
+ RunGpgOperaAsync(
+ [&ctx = ctx_, params](const DataObjectPtr& data_object) -> GpgError {
+ auto userid_utf8 = params->GetUserid();
+ const char* userid = userid_utf8.toUtf8();
+ auto algo_utf8 = params->GetAlgo() + params->GetKeySizeStr();
+
+ GF_CORE_LOG_DEBUG("params: {} {}", params->GetAlgo(),
+ params->GetKeySizeStr());
+
+ auto algo = algo_utf8.toUtf8();
+ unsigned long expires =
+ QDateTime::currentDateTime().secsTo(params->GetExpireTime());
+
+ GpgError err;
+ 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;
+
+ GF_CORE_LOG_DEBUG("key generation args: {}", userid, algo, expires,
+ flags);
+ err = gpgme_op_createkey(ctx.DefaultContext(), userid, algo, 0, expires,
+ nullptr, flags);
+
+ if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
+ data_object->Swap({GpgGenerateKeyResult{
+ gpgme_op_genkey_result(ctx.DefaultContext())}});
+ } else {
+ data_object->Swap({GpgGenerateKeyResult{}});
+ }
- GpgError err;
+ return CheckGpgError(err);
+ },
+ callback, "gpgme_op_createkey", "2.1.0");
+}
- SPDLOG_DEBUG("ctx version, {}", ctx_.GetInfo(false).GnupgVersion);
+/**
+ * Generate a new subkey of a certain key pair
+ * @param key target key pair
+ * @param params opera args
+ * @return error info
+ */
+void GpgKeyOpera::GenerateSubkey(const GpgKey& key,
+ const std::shared_ptr<GenKeyInfo>& params,
+ const GpgOperationCallback& callback) {
+ RunGpgOperaAsync(
+ [key, &ctx = ctx_, params](const DataObjectPtr&) -> GpgError {
+ if (!params->IsSubKey()) return GPG_ERR_CANCELED;
+
+ GF_CORE_LOG_DEBUG("generate subkey algo {} key size {}",
+ params->GetAlgo(), params->GetKeySizeStr());
+
+ auto algo = (params->GetAlgo() + params->GetKeySizeStr()).toUtf8();
+ unsigned long expires =
+ QDateTime::currentDateTime().secsTo(params->GetExpireTime());
+ 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;
+
+ GF_CORE_LOG_DEBUG("args: {} {} {} {}", key.GetId(), algo, expires,
+ flags);
+
+ auto err = gpgme_op_createsubkey(ctx.DefaultContext(),
+ static_cast<gpgme_key_t>(key), algo, 0,
+ expires, flags);
+ return CheckGpgError(err);
+ },
+ callback, "gpgme_op_createsubkey", "2.1.13");
+}
- if (ctx_.GetInfo(false).GnupgVersion >= "2.1.0") {
- unsigned int flags = 0;
+void GpgKeyOpera::GenerateKeyWithSubkey(
+ const std::shared_ptr<GenKeyInfo>& params,
+ const std::shared_ptr<GenKeyInfo>& subkey_params,
+ const GpgOperationCallback& callback) {
+ RunGpgOperaAsync(
+ [&ctx = ctx_, params,
+ subkey_params](const DataObjectPtr& data_object) -> GpgError {
+ auto userid = params->GetUserid().toUtf8();
+ auto algo = (params->GetAlgo() + params->GetKeySizeStr()).toUtf8();
+ unsigned long expires = expires =
+ QDateTime::currentDateTime().secsTo(params->GetExpireTime());
+
+ GpgError err;
+ 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;
+
+ GF_CORE_LOG_DEBUG("key generation args: {}", userid, algo, expires,
+ flags);
+ err = gpgme_op_createkey(ctx.DefaultContext(), userid, algo, 0, expires,
+ nullptr, flags);
+
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ data_object->Swap({GpgGenerateKeyResult{}});
+ return err;
+ }
- 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;
+ auto genkey_result =
+ GpgGenerateKeyResult{gpgme_op_genkey_result(ctx.DefaultContext())};
- SPDLOG_DEBUG("args: {}", userid, algo, expires, flags);
+ auto key =
+ GpgKeyGetter::GetInstance().GetKey(genkey_result.GetFingerprint());
+ if (!key.IsGood()) {
+ GF_CORE_LOG_ERROR("cannot get key which has been generate, fpr: {}",
+ genkey_result.GetFingerprint());
+ return err;
+ }
- err = gpgme_op_createkey(ctx_, userid, algo, 0, expires, nullptr, flags);
+ if (subkey_params == nullptr || !subkey_params->IsSubKey()) return err;
- } else {
- std::stringstream ss;
- auto param_format =
- boost::format{
- "<GnupgKeyParms format=\"internal\">\n"
- "Key-Type: %1%\n"
- "Key-Usage: sign\n"
- "Key-Length: %2%\n"
- "Name-Real: %3%\n"
- "Name-Comment: %4%\n"
- "Name-Email: %5%\n"} %
- params->GetAlgo() % params->GetKeyLength() % params->GetName() %
- params->GetComment() % params->GetEmail();
- ss << param_format;
-
- if (!params->IsNonExpired()) {
- auto date = params->GetExpireTime().date();
- ss << boost::format{"Expire-Date: %1%\n"} % to_iso_string(date);
- } else
- ss << boost::format{"Expire-Date: 0\n"};
- if (!params->IsNoPassPhrase())
- ss << boost::format{"Passphrase: %1%\n"} % params->GetPassPhrase();
-
- ss << "</GnupgKeyParms>";
-
- SPDLOG_DEBUG("params: {}", ss.str());
-
- err = gpgme_op_genkey(ctx_, ss.str().c_str(), nullptr, nullptr);
- }
+ GF_CORE_LOG_DEBUG(
+ "try to generate subkey of key: {}, algo {} key size {}",
+ key.GetId(), subkey_params->GetAlgo(),
+ subkey_params->GetKeySizeStr());
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) {
- auto temp_result = _new_result(gpgme_op_genkey_result(ctx_));
- std::swap(temp_result, result);
- }
+ algo = (subkey_params->GetAlgo() + subkey_params->GetKeySizeStr())
+ .toUtf8();
+ expires =
+ QDateTime::currentDateTime().secsTo(subkey_params->GetExpireTime());
- return check_gpg_error(err);
-}
+ flags = 0;
+ if (subkey_params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
+ if (subkey_params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
+ if (subkey_params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
+ if (subkey_params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
+ if (subkey_params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
-/**
- * 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;
-
- SPDLOG_DEBUG("generate subkey algo {} key size {}", params->GetAlgo(),
- params->GetKeySizeStr());
-
- auto algo_utf8 = (params->GetAlgo() + params->GetKeySizeStr());
- const char* algo = algo_utf8.c_str();
- unsigned long expires = 0;
- {
- using namespace boost::posix_time;
- using namespace std::chrono;
- expires = to_time_t(ptime(params->GetExpireTime())) -
- system_clock::to_time_t(system_clock::now());
- }
- unsigned int flags = 0;
+ GF_CORE_LOG_DEBUG("subkey generation args: {} {} {} {}", key.GetId(),
+ algo, expires, flags);
- 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_createsubkey(ctx.DefaultContext(),
+ static_cast<gpgme_key_t>(key), algo, 0,
+ expires, flags);
- SPDLOG_DEBUG("args: {} {} {} {}", key.GetId(), algo, expires, flags);
+ if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
+ data_object->Swap(
+ {genkey_result, GpgGenerateKeyResult{gpgme_op_genkey_result(
+ ctx.DefaultContext())}});
+ } else {
+ data_object->Swap({genkey_result, GpgGenerateKeyResult{}});
+ }
- auto err =
- gpgme_op_createsubkey(ctx_, gpgme_key_t(key), algo, 0, expires, flags);
- return check_gpg_error(err);
+ return CheckGpgError(err);
+ },
+ callback, "gpgme_op_createkey&gpgme_op_createsubkey", "2.1.0");
}
-GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::ModifyPassword(
- const GpgFrontend::GpgKey& key) {
- if (ctx_.GetInfo(false).GnupgVersion < "2.0.15") {
- SPDLOG_ERROR("operator not support");
- return GPG_ERR_NOT_SUPPORTED;
- }
- auto err = gpgme_op_passwd(ctx_, gpgme_key_t(key), 0);
- return check_gpg_error(err);
+void GpgKeyOpera::ModifyPassword(const GpgKey& key,
+ const GpgOperationCallback& callback) {
+ RunGpgOperaAsync(
+ [&key, &ctx = ctx_](const DataObjectPtr&) -> GpgError {
+ return gpgme_op_passwd(ctx.DefaultContext(),
+ static_cast<gpgme_key_t>(key), 0);
+ },
+ callback, "gpgme_op_passwd", "2.0.15");
}
-GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::ModifyTOFUPolicy(
- const GpgFrontend::GpgKey& key, gpgme_tofu_policy_t tofu_policy) {
- if (ctx_.GetInfo(false).GnupgVersion < "2.1.10") {
- SPDLOG_ERROR("operator not support");
+
+auto GpgKeyOpera::ModifyTOFUPolicy(const GpgKey& key,
+ gpgme_tofu_policy_t tofu_policy)
+ -> GpgError {
+ const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gnupg_version", QString{"2.0.0"});
+ GF_CORE_LOG_DEBUG("got gnupg version from rt: {}", gnupg_version);
+
+ if (CompareSoftwareVersion(gnupg_version, "2.1.10") < 0) {
+ GF_CORE_LOG_ERROR("operator not support");
return GPG_ERR_NOT_SUPPORTED;
}
- auto err = gpgme_op_tofu_policy(ctx_, gpgme_key_t(key), tofu_policy);
- return check_gpg_error(err);
+
+ auto err = gpgme_op_tofu_policy(ctx_.DefaultContext(),
+ static_cast<gpgme_key_t>(key), tofu_policy);
+ return CheckGpgError(err);
}
-void GpgFrontend::GpgKeyOpera::DeleteKey(const GpgFrontend::KeyId& key_id) {
+void GpgKeyOpera::DeleteKey(const GpgFrontend::KeyId& key_id) {
auto keys = std::make_unique<KeyIdArgsList>();
keys->push_back(key_id);
DeleteKeys(std::move(keys));
}
+} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgKeyOpera.h b/src/core/function/gpg/GpgKeyOpera.h
index 5446bd66..a060af1a 100644
--- a/src/core/function/gpg/GpgKeyOpera.h
+++ b/src/core/function/gpg/GpgKeyOpera.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,18 +20,18 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef _GPGKEYOPERA_H
-#define _GPGKEYOPERA_H
+#pragma once
-#include "core/GpgConstants.h"
-#include "core/GpgContext.h"
-#include "core/GpgModel.h"
+#include <functional>
+
+#include "core/function/gpg/GpgContext.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
/**
@@ -77,8 +77,8 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera
* @param expires
* @return GpgError
*/
- GpgError SetExpire(const GpgKey& key, const SubkeyId& subkey_fpr,
- std::unique_ptr<boost::posix_time::ptime>& expires);
+ auto SetExpire(const GpgKey& key, const SubkeyId& subkey_fpr,
+ std::unique_ptr<QDateTime>& expires) -> GpgError;
/**
* @brief
@@ -86,8 +86,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera
* @param key
* @param output_file_name
*/
- void GenerateRevokeCert(const GpgKey& key,
- const std::string& output_file_name);
+ void GenerateRevokeCert(const GpgKey& key, const QString& output_path);
/**
* @brief
@@ -95,7 +94,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera
* @param key
* @return GpgFrontend::GpgError
*/
- GpgFrontend::GpgError ModifyPassword(const GpgKey& key);
+ void ModifyPassword(const GpgKey& key, const GpgOperationCallback&);
/**
* @brief
@@ -104,8 +103,8 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera
* @param tofu_policy
* @return GpgFrontend::GpgError
*/
- GpgFrontend::GpgError ModifyTOFUPolicy(const GpgKey& key,
- gpgme_tofu_policy_t tofu_policy);
+ auto ModifyTOFUPolicy(const GpgKey& key, gpgme_tofu_policy_t tofu_policy)
+ -> GpgFrontend::GpgError;
/**
* @brief
*
@@ -113,8 +112,8 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera
* @param result
* @return GpgFrontend::GpgError
*/
- GpgFrontend::GpgError GenerateKey(const std::unique_ptr<GenKeyInfo>& params,
- GpgGenKeyResult& result);
+ void GenerateKey(const std::shared_ptr<GenKeyInfo>&,
+ const GpgOperationCallback&);
/**
* @brief
@@ -123,13 +122,23 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera
* @param params
* @return GpgFrontend::GpgError
*/
- GpgFrontend::GpgError GenerateSubkey(
- const GpgKey& key, const std::unique_ptr<GenKeyInfo>& params);
+ void GenerateSubkey(const GpgKey& key,
+ const std::shared_ptr<GenKeyInfo>& params,
+ const GpgOperationCallback&);
+
+ /**
+ * @brief
+ *
+ * @param params
+ * @param subkey_params
+ * @param callback
+ */
+ void GenerateKeyWithSubkey(const std::shared_ptr<GenKeyInfo>& params,
+ const std::shared_ptr<GenKeyInfo>& subkey_params,
+ const GpgOperationCallback& callback);
private:
GpgContext& ctx_ =
GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); ///<
};
} // namespace GpgFrontend
-
-#endif // _GPGKEYOPERA_H \ No newline at end of file
diff --git a/src/core/function/gpg/GpgUIDOperator.cpp b/src/core/function/gpg/GpgUIDOperator.cpp
index 7e7a711e..6c0373de 100644
--- a/src/core/function/gpg/GpgUIDOperator.cpp
+++ b/src/core/function/gpg/GpgUIDOperator.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,44 +28,38 @@
#include "GpgUIDOperator.h"
-#include "boost/format.hpp"
+#include "core/GpgModel.h"
+#include "core/utils/GpgUtils.h"
-GpgFrontend::GpgUIDOperator::GpgUIDOperator(int channel)
+namespace GpgFrontend {
+
+GpgUIDOperator::GpgUIDOperator(int channel)
: SingletonFunctionObject<GpgUIDOperator>(channel) {}
-bool GpgFrontend::GpgUIDOperator::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;
+auto GpgUIDOperator::AddUID(const GpgKey& key, const QString& uid) -> bool {
+ auto err = gpgme_op_adduid(ctx_.DefaultContext(),
+ static_cast<gpgme_key_t>(key), uid.toUtf8(), 0);
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
-bool GpgFrontend::GpgUIDOperator::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;
+auto GpgUIDOperator::RevUID(const GpgKey& key, const QString& uid) -> bool {
+ auto err = CheckGpgError(gpgme_op_revuid(
+ ctx_.DefaultContext(), static_cast<gpgme_key_t>(key), uid.toUtf8(), 0));
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
-bool GpgFrontend::GpgUIDOperator::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;
+auto GpgUIDOperator::SetPrimaryUID(const GpgKey& key, const QString& uid)
+ -> bool {
+ auto err = CheckGpgError(gpgme_op_set_uid_flag(
+ ctx_.DefaultContext(), static_cast<gpgme_key_t>(key), uid.toUtf8(),
+ "primary", nullptr));
+ return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
-bool GpgFrontend::GpgUIDOperator::AddUID(const GpgFrontend::GpgKey& key,
- const std::string& name,
- const std::string& comment,
- const std::string& email) {
- SPDLOG_DEBUG("new uuid: {} {} {}", name, comment, email);
- auto uid = boost::format("%1%(%2%)<%3%>") % name % comment % email;
- return AddUID(key, uid.str());
+auto GpgUIDOperator::AddUID(const GpgKey& key, const QString& name,
+ const QString& comment, const QString& email)
+ -> bool {
+ GF_CORE_LOG_DEBUG("new uuid: {} {} {}", name, comment, email);
+ return AddUID(key, QString("%1(%2)<%3>").arg(name).arg(comment).arg(email));
}
+
+} // namespace GpgFrontend
diff --git a/src/core/function/gpg/GpgUIDOperator.h b/src/core/function/gpg/GpgUIDOperator.h
index c4a7d87b..b2cec8bc 100644
--- a/src/core/function/gpg/GpgUIDOperator.h
+++ b/src/core/function/gpg/GpgUIDOperator.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,17 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H
-#define GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H
+#pragma once
-#include "core/GpgContext.h"
-#include "core/GpgModel.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
/**
@@ -54,7 +53,7 @@ class GPGFRONTEND_CORE_EXPORT GpgUIDOperator
* @param uid uid args(combine name&comment&email)
* @return if successful
*/
- bool AddUID(const GpgKey& key, const std::string& uid);
+ auto AddUID(const GpgKey& key, const QString& uid) -> bool;
/**
* create a new uid in certain key pair
@@ -64,8 +63,8 @@ class GPGFRONTEND_CORE_EXPORT GpgUIDOperator
* @param email
* @return
*/
- bool AddUID(const GpgKey& key, const std::string& name,
- const std::string& comment, const std::string& email);
+ auto AddUID(const GpgKey& key, const QString& name, const QString& comment,
+ const QString& email) -> bool;
/**
* Revoke(Delete) UID from certain key pair
@@ -73,7 +72,7 @@ class GPGFRONTEND_CORE_EXPORT GpgUIDOperator
* @param uid target uid
* @return if successful
*/
- bool RevUID(const GpgKey& key, const std::string& uid);
+ auto RevUID(const GpgKey& key, const QString& uid) -> bool;
/**
* Set one of a uid of a key pair as primary
@@ -81,7 +80,7 @@ class GPGFRONTEND_CORE_EXPORT GpgUIDOperator
* @param uid target uid
* @return if successful
*/
- bool SetPrimaryUID(const GpgKey& key, const std::string& uid);
+ auto SetPrimaryUID(const GpgKey& key, const QString& uid) -> bool;
private:
GpgContext& ctx_ =
@@ -89,5 +88,3 @@ class GPGFRONTEND_CORE_EXPORT GpgUIDOperator
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H
diff --git a/src/core/function/result_analyse/GpgDecryptResultAnalyse.cpp b/src/core/function/result_analyse/GpgDecryptResultAnalyse.cpp
index d3ec8d6e..5d0ce920 100644
--- a/src/core/function/result_analyse/GpgDecryptResultAnalyse.cpp
+++ b/src/core/function/result_analyse/GpgDecryptResultAnalyse.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,70 +28,103 @@
#include "GpgDecryptResultAnalyse.h"
-#include "function/gpg/GpgKeyGetter.h"
+#include "core/GpgModel.h"
+#include "core/function/gpg/GpgKeyGetter.h"
GpgFrontend::GpgDecryptResultAnalyse::GpgDecryptResultAnalyse(
- GpgError m_error, GpgDecrResult m_result)
- : error_(m_error), result_(std::move(m_result)) {}
+ GpgError m_error, GpgDecryptResult m_result)
+ : error_(m_error), result_(m_result) {}
-void GpgFrontend::GpgDecryptResultAnalyse::do_analyse() {
- stream_ << "[#] " << _("Decrypt Operation");
+void GpgFrontend::GpgDecryptResultAnalyse::doAnalyse() {
+ auto *result = result_.GetRaw();
+
+ stream_ << "# " << tr("Decrypt Operation") << " ";
if (gpgme_err_code(error_) == GPG_ERR_NO_ERROR) {
- stream_ << "[" << _("Success") << "]" << std::endl;
+ stream_ << "- " << tr("Success") << " " << Qt::endl;
} else {
- stream_ << "[" << _("Failed") << "] " << gpgme_strerror(error_)
- << std::endl;
- set_status(-1);
- if (result_ != nullptr && result_->unsupported_algorithm != nullptr) {
- stream_ << "------------>" << std::endl;
- stream_ << _("Unsupported Algo") << ": " << result_->unsupported_algorithm
- << std::endl;
+ 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;
}
}
- 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;
+ if (result != nullptr && result->recipients != nullptr) {
+ stream_ << Qt::endl;
+
+ stream_ << "## " << tr("Gernal State") << ": " << Qt::endl;
+
+ if (result->file_name != nullptr) {
+ stream_ << "- " << tr("File Name") << ": " << result->file_name
+ << Qt::endl;
+ }
+ stream_ << "- " << tr("MIME") << ": "
+ << (result->is_mime == 0 ? tr("false") : tr("true")) << Qt::endl;
+
+ stream_ << "- " << tr("Message Integrity Protection") << ": "
+ << (result->legacy_cipher_nomdc == 0 ? tr("true") : tr("false"))
+ << Qt::endl;
+ if (result->legacy_cipher_nomdc == 1) setStatus(0); /// < unsafe situation
+
+ if (result->symkey_algo != nullptr) {
+ stream_ << "- " << tr("Symmetric Encryption Algorithm") << ": "
+ << result->symkey_algo << Qt::endl;
+ }
+
+ if (result->session_key != nullptr) {
+ stream_ << "- " << tr("Session Key") << ": " << result->session_key
+ << Qt::endl;
}
- if (result_->is_mime) {
- stream_ << _("MIME") << ": " << _("true") << std::endl;
+
+ stream_ << "- " << tr("German Encryption Standards") << ": "
+ << (result->is_de_vs == 0 ? tr("false") : tr("true")) << Qt::endl;
+
+ stream_ << Qt::endl << Qt::endl;
+
+ auto *recipient = result->recipients;
+ auto index = 0;
+ if (recipient != nullptr) {
+ stream_ << "## " << tr("Recipient(s)") << ": " << Qt::endl << Qt::endl;
}
- auto recipient = result_->recipients;
- if (recipient != nullptr) stream_ << _("Recipient(s)") << ": " << std::endl;
while (recipient != nullptr) {
+ // check
+ if (recipient->keyid == nullptr) return;
+ stream_ << "### " << tr("Recipient") << " [" << ++index << "]: ";
print_recipient(stream_, recipient);
+ stream_ << Qt::endl
+ << "---------------------------------------" << Qt::endl
+ << Qt::endl;
recipient = recipient->next;
}
- stream_ << "<------------" << std::endl;
+
+ stream_ << Qt::endl;
}
- stream_ << std::endl;
+ stream_ << Qt::endl;
}
void GpgFrontend::GpgDecryptResultAnalyse::print_recipient(
- std::stringstream &stream, gpgme_recipient_t recipient) {
- // check
- if (recipient->keyid == nullptr) return;
-
- stream << " {>} " << _("Recipient") << ": ";
+ QTextStream &stream, gpgme_recipient_t recipient) {
auto key = GpgFrontend::GpgKeyGetter::GetInstance().GetKey(recipient->keyid);
if (key.IsGood()) {
- stream << key.GetName().c_str();
- if (!key.GetEmail().empty()) {
- stream << "<" << key.GetEmail().c_str() << ">";
- }
+ stream << key.GetName();
+ if (!key.GetComment().isEmpty()) stream << "(" << key.GetComment() << ")";
+ if (!key.GetEmail().isEmpty()) stream << "<" << key.GetEmail() << ">";
} else {
- stream << "<" << _("Unknown") << ">";
- set_status(0);
+ stream << "<" << tr("unknown") << ">";
+ setStatus(0);
}
- stream << std::endl;
+ stream << Qt::endl;
- stream << " " << _("Key ID") << ": " << recipient->keyid << std::endl;
- stream << " " << _("Public Key Algo") << ": "
- << gpgme_pubkey_algo_name(recipient->pubkey_algo) << std::endl;
+ stream << "- " << tr("Key ID") << ": " << recipient->keyid << Qt::endl;
+ stream << "- " << tr("Public Key Algo") << ": "
+ << gpgme_pubkey_algo_name(recipient->pubkey_algo) << Qt::endl;
+ stream << "- " << tr("Status") << ": " << gpgme_strerror(recipient->status)
+ << Qt::endl;
}
diff --git a/src/core/function/result_analyse/GpgDecryptResultAnalyse.h b/src/core/function/result_analyse/GpgDecryptResultAnalyse.h
index 1fc08d1f..c795e025 100644
--- a/src/core/function/result_analyse/GpgDecryptResultAnalyse.h
+++ b/src/core/function/result_analyse/GpgDecryptResultAnalyse.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,17 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGDECRYPTRESULTANALYSE_H
-#define GPGFRONTEND_GPGDECRYPTRESULTANALYSE_H
+#pragma once
#include "GpgResultAnalyse.h"
-#include "core/GpgConstants.h"
+#include "core/model/GpgDecryptResult.h"
namespace GpgFrontend {
@@ -40,6 +39,7 @@ namespace GpgFrontend {
*/
class GPGFRONTEND_CORE_EXPORT GpgDecryptResultAnalyse
: public GpgResultAnalyse {
+ Q_OBJECT
public:
/**
* @brief Construct a new Decrypt Result Analyse object
@@ -47,14 +47,14 @@ class GPGFRONTEND_CORE_EXPORT GpgDecryptResultAnalyse
* @param m_error
* @param m_result
*/
- explicit GpgDecryptResultAnalyse(GpgError m_error, GpgDecrResult m_result);
+ explicit GpgDecryptResultAnalyse(GpgError m_error, GpgDecryptResult m_result);
protected:
/**
* @brief
*
*/
- void do_analyse() final;
+ void doAnalyse() final;
private:
/**
@@ -63,12 +63,10 @@ class GPGFRONTEND_CORE_EXPORT GpgDecryptResultAnalyse
* @param stream
* @param recipient
*/
- void print_recipient(std::stringstream &stream, gpgme_recipient_t recipient);
+ void print_recipient(QTextStream &stream, gpgme_recipient_t recipient);
- GpgError error_; ///<
- GpgDecrResult result_; ///<
+ GpgError error_; ///<
+ GpgDecryptResult result_; ///<
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGDECRYPTRESULTANALYSE_H
diff --git a/src/core/function/result_analyse/GpgEncryptResultAnalyse.cpp b/src/core/function/result_analyse/GpgEncryptResultAnalyse.cpp
index 21d37eab..a6b18b0a 100644
--- a/src/core/function/result_analyse/GpgEncryptResultAnalyse.cpp
+++ b/src/core/function/result_analyse/GpgEncryptResultAnalyse.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,39 +28,53 @@
#include "GpgEncryptResultAnalyse.h"
-GpgFrontend::GpgEncryptResultAnalyse::GpgEncryptResultAnalyse(
- GpgError error, GpgEncrResult result)
- : error_(error), result_(std::move(result)) {}
+#include "core/model/GpgEncryptResult.h"
-void GpgFrontend::GpgEncryptResultAnalyse::do_analyse() {
- SPDLOG_DEBUG("start encrypt result analyse");
+namespace GpgFrontend {
- stream_ << "[#] " << _("Encrypt Operation") << " ";
+GpgEncryptResultAnalyse::GpgEncryptResultAnalyse(GpgError error,
+ GpgEncryptResult result)
+ : error_(error), result_(result) {}
- if (gpgme_err_code(error_) == GPG_ERR_NO_ERROR)
- stream_ << "[" << _("Success") << "]" << std::endl;
- else {
- stream_ << "[" << _("Failed") << "] " << gpgme_strerror(error_)
- << std::endl;
- set_status(-1);
+void GpgEncryptResultAnalyse::doAnalyse() {
+ stream_ << "# " << tr("Encrypt 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);
}
- if (!~status_) {
- stream_ << "------------>" << std::endl;
- if (result_ != nullptr) {
- stream_ << _("Invalid Recipients") << ": " << std::endl;
- auto inv_reci = result_->invalid_recipients;
+ if ((~status_) == 0) {
+ stream_ << Qt::endl;
+
+ const auto *result = result_.GetRaw();
+
+ if (result != nullptr) {
+ stream_ << "## " << tr("Invalid Recipients") << ": " << Qt::endl
+ << Qt::endl;
+
+ auto *inv_reci = result->invalid_recipients;
+ auto index = 0;
+
while (inv_reci != nullptr) {
- stream_ << _("Fingerprint") << ": " << inv_reci->fpr << std::endl;
- stream_ << _("Reason") << ": " << gpgme_strerror(inv_reci->reason)
- << std::endl;
- stream_ << std::endl;
+ stream_ << "### " << tr("Recipients") << " " << ++index << ": "
+ << Qt::endl;
+ stream_ << "- " << tr("Fingerprint") << ": " << inv_reci->fpr
+ << Qt::endl;
+ stream_ << "- " << tr("Reason") << ": "
+ << gpgme_strerror(inv_reci->reason) << Qt::endl;
+ stream_ << Qt::endl << Qt::endl;
inv_reci = inv_reci->next;
}
}
- stream_ << "<------------" << std::endl;
+ stream_ << Qt::endl;
}
- stream_ << std::endl;
+ stream_ << Qt::endl;
}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/result_analyse/GpgEncryptResultAnalyse.h b/src/core/function/result_analyse/GpgEncryptResultAnalyse.h
index 6811ef06..e9594628 100644
--- a/src/core/function/result_analyse/GpgEncryptResultAnalyse.h
+++ b/src/core/function/result_analyse/GpgEncryptResultAnalyse.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,17 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGENCRYPTRESULTANALYSE_H
-#define GPGFRONTEND_GPGENCRYPTRESULTANALYSE_H
+#pragma once
#include "GpgResultAnalyse.h"
-#include "core/GpgConstants.h"
+#include "core/model/GpgEncryptResult.h"
namespace GpgFrontend {
/**
@@ -39,6 +38,7 @@ namespace GpgFrontend {
*/
class GPGFRONTEND_CORE_EXPORT GpgEncryptResultAnalyse
: public GpgResultAnalyse {
+ Q_OBJECT
public:
/**
* @brief Construct a new Encrypt Result Analyse object
@@ -46,19 +46,17 @@ class GPGFRONTEND_CORE_EXPORT GpgEncryptResultAnalyse
* @param error
* @param result
*/
- explicit GpgEncryptResultAnalyse(GpgError error, GpgEncrResult result);
+ explicit GpgEncryptResultAnalyse(GpgError error, GpgEncryptResult result);
protected:
/**
* @brief
*
*/
- void do_analyse() final;
+ void doAnalyse() final;
private:
- GpgError error_; ///<
- GpgEncrResult result_; ///<
+ GpgError error_; ///<
+ GpgEncryptResult result_; ///<
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGENCRYPTRESULTANALYSE_H
diff --git a/src/core/function/result_analyse/GpgResultAnalyse.cpp b/src/core/function/result_analyse/GpgResultAnalyse.cpp
index 40ba4c3e..4c1f44e7 100644
--- a/src/core/function/result_analyse/GpgResultAnalyse.cpp
+++ b/src/core/function/result_analyse/GpgResultAnalyse.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,19 +28,19 @@
#include "GpgResultAnalyse.h"
-const std::string GpgFrontend::GpgResultAnalyse::GetResultReport() const {
- return stream_.str();
+auto GpgFrontend::GpgResultAnalyse::GetResultReport() const -> const QString {
+ return *stream_.string();
}
-int GpgFrontend::GpgResultAnalyse::GetStatus() const { return status_; }
+auto GpgFrontend::GpgResultAnalyse::GetStatus() const -> int { return status_; }
-void GpgFrontend::GpgResultAnalyse::set_status(int m_status) {
+void GpgFrontend::GpgResultAnalyse::setStatus(int m_status) {
if (m_status < status_) status_ = m_status;
}
void GpgFrontend::GpgResultAnalyse::Analyse() {
if (!analysed_) {
- do_analyse();
+ doAnalyse();
analysed_ = true;
}
}
diff --git a/src/core/function/result_analyse/GpgResultAnalyse.h b/src/core/function/result_analyse/GpgResultAnalyse.h
index e609505f..9958b6a2 100644
--- a/src/core/function/result_analyse/GpgResultAnalyse.h
+++ b/src/core/function/result_analyse/GpgResultAnalyse.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,21 +20,21 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGRESULTANALYSE_H
-#define GPGFRONTEND_GPGRESULTANALYSE_H
+#pragma once
#include <sstream>
-#include <string>
-#include "core/GpgConstants.h"
+#include "core/typedef/GpgTypedef.h"
+
namespace GpgFrontend {
-class GPGFRONTEND_CORE_EXPORT GpgResultAnalyse {
+class GPGFRONTEND_CORE_EXPORT GpgResultAnalyse : public QObject {
+ Q_OBJECT
public:
/**
* @brief Construct a new Result Analyse object
@@ -45,16 +45,16 @@ class GPGFRONTEND_CORE_EXPORT GpgResultAnalyse {
/**
* @brief Get the Result Report object
*
- * @return const std::string
+ * @return const QString
*/
- [[nodiscard]] const std::string GetResultReport() const;
+ [[nodiscard]] auto GetResultReport() const -> const QString;
/**
* @brief Get the Status object
*
* @return int
*/
- [[nodiscard]] int GetStatus() const;
+ [[nodiscard]] auto GetStatus() const -> int;
/**
* @brief
@@ -67,20 +67,19 @@ class GPGFRONTEND_CORE_EXPORT GpgResultAnalyse {
* @brief
*
*/
- virtual void do_analyse() = 0;
+ virtual void doAnalyse() = 0;
/**
* @brief Set the status object
*
* @param m_status
*/
- void set_status(int m_status);
+ void setStatus(int m_status);
- std::stringstream stream_; ///<
- int status_ = 1; ///<
- bool analysed_ = false; ///<
+ QString buffer_;
+ QTextStream stream_ = QTextStream(&buffer_); ///<
+ int status_ = 1; ///<
+ bool analysed_ = false; ///<
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGRESULTANALYSE_H
diff --git a/src/core/function/result_analyse/GpgSignResultAnalyse.cpp b/src/core/function/result_analyse/GpgSignResultAnalyse.cpp
index e4d1354f..bf429f38 100644
--- a/src/core/function/result_analyse/GpgSignResultAnalyse.cpp
+++ b/src/core/function/result_analyse/GpgSignResultAnalyse.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,88 +28,98 @@
#include "GpgSignResultAnalyse.h"
-#include "function/gpg/GpgKeyGetter.h"
+#include "core/GpgModel.h"
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/utils/LocalizedUtils.h"
-GpgFrontend::GpgSignResultAnalyse::GpgSignResultAnalyse(GpgError error,
- GpgSignResult result)
+namespace GpgFrontend {
+
+GpgSignResultAnalyse::GpgSignResultAnalyse(GpgError error, GpgSignResult result)
: error_(error), result_(std::move(result)) {}
-void GpgFrontend::GpgSignResultAnalyse::do_analyse() {
- SPDLOG_DEBUG("start sign result analyse");
+void GpgSignResultAnalyse::doAnalyse() {
+ auto *result = this->result_.GetRaw();
- stream_ << "[#] " << _("Sign Operation") << " ";
+ stream_ << "# " << tr("Sign Operation") << " ";
- if (gpgme_err_code(error_) == GPG_ERR_NO_ERROR)
- stream_ << "[" << _("Success") << "]" << std::endl;
- else {
- stream_ << "[" << _("Failed") << "] " << gpgme_strerror(error_)
- << std::endl;
- set_status(-1);
+ 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_->signatures != nullptr || result_->invalid_signers != nullptr)) {
- SPDLOG_DEBUG("sign result analyse getting result");
- stream_ << "------------>" << std::endl;
- auto new_sign = result_->signatures;
+ if (result != nullptr &&
+ (result->signatures != nullptr || result->invalid_signers != nullptr)) {
+ stream_ << Qt::endl;
+ auto *new_sign = result->signatures;
+ auto index = 0;
while (new_sign != nullptr) {
- stream_ << "[>]" << _("New Signature") << ": " << std::endl;
-
- SPDLOG_DEBUG("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_ << "## " << tr("New Signature") << " [" << ++index
+ << "]: " << Qt::endl;
+
+ 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");
+ }
- stream_ << std::endl;
+ stream_ << Qt::endl;
- auto singerKey =
- GpgFrontend::GpgKeyGetter::GetInstance().GetKey(new_sign->fpr);
- if (singerKey.IsGood()) {
- stream_ << " " << _("Signer") << ": "
- << singerKey.GetUIDs()->front().GetUID() << std::endl;
+ auto singer_key = GpgKeyGetter::GetInstance().GetKey(new_sign->fpr);
+ if (singer_key.IsGood()) {
+ stream_ << "- " << tr("Signer") << ": "
+ << singer_key.GetUIDs()->front().GetUID() << Qt::endl;
} else {
- stream_ << " " << _("Signer") << ": "
- << "<unknown>" << std::endl;
+ stream_ << "- " << tr("Signer") << ": "
+ << "<unknown>" << Qt::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") << "(" << _("UTC") << ")"
+ 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") << "(" << tr("UTC") << ")"
<< ": "
- << boost::posix_time::to_iso_extended_string(
- boost::posix_time::from_time_t(new_sign->timestamp))
- << std::endl;
+ << QDateTime::fromSecsSinceEpoch(new_sign->timestamp).toString()
+ << Qt::endl;
+ stream_ << "- " << tr("Date") << "(" << tr("Localized") << ")"
+ << ": " << GetFormatedDateByTimestamp(new_sign->timestamp)
+ << Qt::endl;
- stream_ << std::endl;
+ stream_ << Qt::endl
+ << "---------------------------------------" << Qt::endl
+ << Qt::endl;
new_sign = new_sign->next;
}
- SPDLOG_DEBUG("sign result analyse getting invalid signer");
+ auto *invalid_signer = result->invalid_signers;
+ stream_ << Qt::endl;
- auto invalid_signer = result_->invalid_signers;
-
- if (invalid_signer != nullptr)
- stream_ << _("Invalid Signers") << ": " << std::endl;
+ if (invalid_signer != nullptr) {
+ stream_ << "## " << tr("Invalid Signers") << ": " << Qt::endl;
+ }
+ index = 0;
while (invalid_signer != nullptr) {
- set_status(0);
- stream_ << "[>] " << _("Signer") << ": " << std::endl;
- stream_ << " " << _("Fingerprint") << ": " << invalid_signer->fpr
- << std::endl;
- stream_ << " " << _("Reason") << ": "
- << gpgme_strerror(invalid_signer->reason) << std::endl;
- stream_ << std::endl;
+ setStatus(0);
+ stream_ << "### " << tr("Signer") << " [" << ++index << "]: " << Qt::endl
+ << 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_ << "<------------" << std::endl;
+ stream_ << Qt::endl;
}
-} \ No newline at end of file
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/result_analyse/GpgSignResultAnalyse.h b/src/core/function/result_analyse/GpgSignResultAnalyse.h
index 43a78942..58a20417 100644
--- a/src/core/function/result_analyse/GpgSignResultAnalyse.h
+++ b/src/core/function/result_analyse/GpgSignResultAnalyse.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,16 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGSIGNRESULTANALYSE_H
-#define GPGFRONTEND_GPGSIGNRESULTANALYSE_H
+#pragma once
#include "GpgResultAnalyse.h"
+#include "core/model/GpgSignResult.h"
namespace GpgFrontend {
@@ -38,6 +38,7 @@ namespace GpgFrontend {
*
*/
class GPGFRONTEND_CORE_EXPORT GpgSignResultAnalyse : public GpgResultAnalyse {
+ Q_OBJECT
public:
/**
* @brief Construct a new Sign Result Analyse object
@@ -52,7 +53,7 @@ class GPGFRONTEND_CORE_EXPORT GpgSignResultAnalyse : public GpgResultAnalyse {
* @brief
*
*/
- void do_analyse();
+ void doAnalyse() override;
private:
GpgError error_; ///<
@@ -61,5 +62,3 @@ class GPGFRONTEND_CORE_EXPORT GpgSignResultAnalyse : public GpgResultAnalyse {
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGSIGNRESULTANALYSE_H
diff --git a/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp b/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp
index b19db5b2..224aa06b 100644
--- a/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp
+++ b/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,188 +28,200 @@
#include "GpgVerifyResultAnalyse.h"
-#include <boost/format.hpp>
-
#include "GpgFrontend.h"
-#include "core/GpgConstants.h"
-#include "function/gpg/GpgKeyGetter.h"
+#include "core/GpgModel.h"
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/utils/CommonUtils.h"
+#include "core/utils/LocalizedUtils.h"
GpgFrontend::GpgVerifyResultAnalyse::GpgVerifyResultAnalyse(
GpgError error, GpgVerifyResult result)
- : error_(error), result_(std::move(result)) {}
+ : error_(error), result_(result) {}
-void GpgFrontend::GpgVerifyResultAnalyse::do_analyse() {
- SPDLOG_DEBUG("started");
+void GpgFrontend::GpgVerifyResultAnalyse::doAnalyse() {
+ auto *result = this->result_.GetRaw();
- stream_ << "[#] " << _("Verify Operation") << " ";
+ stream_ << "# " << tr("Verify Operation") << " ";
- if (gpgme_err_code(error_) == GPG_ERR_NO_ERROR)
- stream_ << "[" << _("Success") << "]" << std::endl;
- else {
- stream_ << "[" << _("Failed") << "] " << gpgme_strerror(error_)
- << std::endl;
- set_status(-1);
+ 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_->signatures != nullptr) {
- stream_ << "------------>" << std::endl;
- auto sign = result_->signatures;
+ if (result != nullptr && result->signatures != nullptr) {
+ stream_ << Qt::endl;
+ auto *sign = result->signatures;
+
+ stream_ << "-> " << tr("Signed On") << "(" << tr("UTC") << ")"
+ << " " << QDateTime::fromSecsSinceEpoch(sign->timestamp).toString()
+ << Qt::endl;
- stream_ << "[>] " << _("Signed On") << "(" << _("UTC") << ")"
- << " "
- << boost::posix_time::to_iso_extended_string(
- boost::posix_time::from_time_t(sign->timestamp))
- << std::endl;
+ stream_ << "-> " << tr("Signed On") << "(" << tr("Localized") << ")"
+ << " " << GetFormatedDateByTimestamp(sign->timestamp) << Qt::endl;
- stream_ << std::endl << "[>] " << _("Signatures List") << ":" << std::endl;
+ stream_ << Qt::endl << "## " << tr("Signatures List") << ":" << Qt::endl;
+ stream_ << Qt::endl;
- bool canContinue = true;
+ bool can_continue = true;
int count = 1;
- while (sign && canContinue) {
- stream_ << boost::format(_("Signature [%1%]:")) % count++ << std::endl;
+ while ((sign != nullptr) && can_continue) {
+ stream_ << "### " << tr("Signature [%1]:").arg(count++) << Qt::endl;
+ stream_ << "- " << tr("Status") << ": ";
switch (gpg_err_code(sign->status)) {
case GPG_ERR_BAD_SIGNATURE:
- stream_ << _("A Bad Signature.") << std::endl;
+ stream_ << tr("A Bad Signature.") << Qt::endl;
print_signer(stream_, sign);
- stream_ << _("This Signature is invalid.") << std::endl;
- canContinue = false;
- set_status(-1);
+ stream_ << tr("This Signature is invalid.") << Qt::endl;
+ can_continue = false;
+ setStatus(-1);
break;
case GPG_ERR_NO_ERROR:
- stream_ << _("A") << " ";
- if (sign->summary & GPGME_SIGSUM_GREEN) {
- stream_ << _("Good") << " ";
+ stream_ << tr("A") << " ";
+ if ((sign->summary & GPGME_SIGSUM_GREEN) != 0) {
+ stream_ << tr("Good") << " ";
}
- if (sign->summary & GPGME_SIGSUM_RED) {
- stream_ << _("Bad") << " ";
+ if ((sign->summary & GPGME_SIGSUM_RED) != 0) {
+ stream_ << tr("Bad") << " ";
}
- if (sign->summary & GPGME_SIGSUM_SIG_EXPIRED) {
- stream_ << _("Expired") << " ";
+ if ((sign->summary & GPGME_SIGSUM_SIG_EXPIRED) != 0) {
+ stream_ << tr("Expired") << " ";
}
- if (sign->summary & GPGME_SIGSUM_KEY_MISSING) {
- stream_ << _("Missing Key's") << " ";
+ if ((sign->summary & GPGME_SIGSUM_KEY_MISSING) != 0) {
+ stream_ << tr("Missing Key's") << " ";
}
- if (sign->summary & GPGME_SIGSUM_KEY_REVOKED) {
- stream_ << _("Revoked Key's") << " ";
+ if ((sign->summary & GPGME_SIGSUM_KEY_REVOKED) != 0) {
+ stream_ << tr("Revoked Key's") << " ";
}
- if (sign->summary & GPGME_SIGSUM_KEY_EXPIRED) {
- stream_ << _("Expired Key's") << " ";
+ if ((sign->summary & GPGME_SIGSUM_KEY_EXPIRED) != 0) {
+ stream_ << tr("Expired Key's") << " ";
}
- if (sign->summary & GPGME_SIGSUM_CRL_MISSING) {
- stream_ << _("Missing CRL's") << " ";
+ if ((sign->summary & GPGME_SIGSUM_CRL_MISSING) != 0) {
+ stream_ << tr("Missing CRL's") << " ";
}
- if (sign->summary & GPGME_SIGSUM_VALID) {
- stream_ << _("Signature Fully Valid.") << std::endl;
+ if ((sign->summary & GPGME_SIGSUM_VALID) != 0) {
+ stream_ << tr("Signature Fully Valid.") << Qt::endl;
} else {
- stream_ << _("Signature Not Fully Valid.") << std::endl;
- stream_ << _("(May used a subkey to sign)") << std::endl;
+ stream_ << tr("Signature Not Fully Valid.") << Qt::endl;
+ stream_ << tr("(Adjust Trust Level to make it Fully Vaild)")
+ << Qt::endl;
}
- if (!(sign->status & GPGME_SIGSUM_KEY_MISSING)) {
- if (!print_signer(stream_, sign)) set_status(0);
+ if ((sign->status & GPGME_SIGSUM_KEY_MISSING) == 0U) {
+ if (!print_signer(stream_, sign)) setStatus(0);
} else {
- stream_ << _("Key is NOT present with ID 0x") << sign->fpr
- << std::endl;
+ stream_ << tr("Key is NOT present with ID 0x") << sign->fpr
+ << Qt::endl;
}
- set_status(1);
+ setStatus(1);
break;
case GPG_ERR_NO_PUBKEY:
- stream_ << _("A signature could NOT be verified due to a Missing Key")
- << std::endl;
- set_status(-2);
+ stream_
+ << tr("A signature could NOT be verified due to a Missing Key")
+ << Qt::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;
+ stream_ << tr("A signature is valid but the key used to verify the "
+ "signature has been revoked")
+ << Qt::endl;
if (!print_signer(stream_, sign)) {
- set_status(0);
+ setStatus(0);
}
- set_status(-1);
+ setStatus(-1);
break;
case GPG_ERR_SIG_EXPIRED:
- stream_ << _("A signature is valid but expired") << std::endl;
+ stream_ << tr("A signature is valid but expired") << Qt::endl;
if (!print_signer(stream_, sign)) {
- set_status(0);
+ setStatus(0);
}
- set_status(-1);
+ 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;
+ stream_ << tr("A signature is valid but the key used to "
+ "verify the signature has expired.")
+ << Qt::endl;
if (!print_signer(stream_, sign)) {
- set_status(0);
+ setStatus(0);
}
break;
case GPG_ERR_GENERAL:
- stream_ << _("There was some other error which prevented "
- "the signature verification.")
- << std::endl;
+ stream_ << tr("There was some other error which prevented "
+ "the signature verification.")
+ << Qt::endl;
status_ = -1;
- canContinue = false;
+ can_continue = false;
break;
default:
- auto fpr = std::string(sign->fpr);
- stream_ << _("Error for key with fingerprint") << " "
- << GpgFrontend::beautify_fingerprint(fpr);
- set_status(-1);
+ auto fpr = QString(sign->fpr);
+ stream_ << tr("Error for key with fingerprint") << " "
+ << GpgFrontend::BeautifyFingerprint(fpr);
+ setStatus(-1);
}
- stream_ << std::endl;
+ stream_ << Qt::endl;
sign = sign->next;
}
- stream_ << "<------------" << std::endl;
+ stream_ << Qt::endl;
} else {
stream_
- << "[>] "
- << _("Could not find information that can be used for verification.")
- << std::endl;
- set_status(0);
+ << "-> "
+ << tr("Could not find information that can be used for verification.")
+ << Qt::endl;
+ setStatus(0);
return;
}
}
-bool GpgFrontend::GpgVerifyResultAnalyse::print_signer(
- std::stringstream &stream, gpgme_signature_t sign) {
- bool keyFound = true;
+auto GpgFrontend::GpgVerifyResultAnalyse::print_signer(QTextStream &stream,
+ gpgme_signature_t sign)
+ -> bool {
+ bool key_found = true;
auto key = GpgFrontend::GpgKeyGetter::GetInstance().GetKey(sign->fpr);
if (!key.IsGood()) {
- stream << " " << _("Signed By") << ": "
- << "<" << _("Unknown") << ">" << std::endl;
- set_status(0);
- keyFound = false;
+ stream << "- " << tr("Signed By") << ": "
+ << "<" << tr("Unknown") << ">" << Qt::endl;
+ setStatus(0);
+ key_found = false;
} else {
- stream << " " << _("Signed By") << ": "
- << key.GetUIDs()->front().GetUID() << std::endl;
+ stream << "- " << tr("Signed By") << ": " << key.GetUIDs()->front().GetUID()
+ << Qt::endl;
+ }
+ if (sign->pubkey_algo != 0U) {
+ stream << "- " << tr("Public Key Algo") << ": "
+ << gpgme_pubkey_algo_name(sign->pubkey_algo) << Qt::endl;
+ }
+ if (sign->hash_algo != 0U) {
+ stream << "- " << tr("Hash Algo") << ": "
+ << gpgme_hash_algo_name(sign->hash_algo) << Qt::endl;
}
- if (sign->pubkey_algo)
- stream << " " << _("Public Key Algo") << ": "
- << gpgme_pubkey_algo_name(sign->pubkey_algo) << std::endl;
- if (sign->hash_algo)
- stream << " " << _("Hash Algo") << ": "
- << gpgme_hash_algo_name(sign->hash_algo) << std::endl;
- if (sign->timestamp)
- stream << " " << _("Date") << "(" << _("UTC") << ")"
- << ": "
- << boost::posix_time::to_iso_extended_string(
- boost::posix_time::from_time_t(sign->timestamp))
- << std::endl;
- stream << std::endl;
- return keyFound;
+ if (sign->timestamp != 0U) {
+ stream << "- " << tr("Date") << "(" << tr("UTC") << ")"
+ << ": " << QDateTime::fromSecsSinceEpoch(sign->timestamp).toString()
+ << Qt::endl;
+
+ stream << "- " << tr("Date") << "(" << tr("Localized") << ")"
+ << ": " << GetFormatedDateByTimestamp(sign->timestamp) << Qt::endl;
+ }
+ stream << Qt::endl;
+ return key_found;
}
-gpgme_signature_t GpgFrontend::GpgVerifyResultAnalyse::GetSignatures() const {
- if (result_)
- return result_->signatures;
- else
- return nullptr;
+auto GpgFrontend::GpgVerifyResultAnalyse::GetSignatures() const
+ -> gpgme_signature_t {
+ if (result_.IsGood()) {
+ return result_.GetRaw()->signatures;
+ }
+ return nullptr;
}
-GpgFrontend::GpgVerifyResult
-GpgFrontend::GpgVerifyResultAnalyse::TakeChargeOfResult() {
- return std::move(result_);
+
+auto GpgFrontend::GpgVerifyResultAnalyse::TakeChargeOfResult()
+ -> GpgFrontend::GpgVerifyResult {
+ return result_;
}
diff --git a/src/core/function/result_analyse/GpgVerifyResultAnalyse.h b/src/core/function/result_analyse/GpgVerifyResultAnalyse.h
index ce8e03ad..8aa2e41f 100644
--- a/src/core/function/result_analyse/GpgVerifyResultAnalyse.h
+++ b/src/core/function/result_analyse/GpgVerifyResultAnalyse.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,17 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGVERIFYRESULTANALYSE_H
-#define GPGFRONTEND_GPGVERIFYRESULTANALYSE_H
+#pragma once
#include "GpgResultAnalyse.h"
-#include "core/model/GpgKeySignature.h"
+#include "core/model/GpgVerifyResult.h"
namespace GpgFrontend {
/**
@@ -38,6 +37,7 @@ namespace GpgFrontend {
*
*/
class GPGFRONTEND_CORE_EXPORT GpgVerifyResultAnalyse : public GpgResultAnalyse {
+ Q_OBJECT
public:
/**
* @brief Construct a new Verify Result Analyse object
@@ -52,21 +52,21 @@ class GPGFRONTEND_CORE_EXPORT GpgVerifyResultAnalyse : public GpgResultAnalyse {
*
* @return gpgme_signature_t
*/
- gpgme_signature_t GetSignatures() const;
+ auto GetSignatures() const -> gpgme_signature_t;
/**
* @brief
*
* @return GpgVerifyResult
*/
- GpgVerifyResult TakeChargeOfResult();
+ auto TakeChargeOfResult() -> GpgVerifyResult;
- private:
+ protected:
/**
* @brief
*
*/
- void do_analyse();
+ void doAnalyse() final;
private:
/**
@@ -77,12 +77,10 @@ class GPGFRONTEND_CORE_EXPORT GpgVerifyResultAnalyse : public GpgResultAnalyse {
* @return true
* @return false
*/
- bool print_signer(std::stringstream &stream, gpgme_signature_t sign);
+ auto print_signer(QTextStream &stream, gpgme_signature_t sign) -> bool;
GpgError error_; ///<
GpgVerifyResult result_; ///<
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGVERIFYRESULTANALYSE_H
diff --git a/src/core/log/QtLoggerFmt.h b/src/core/log/QtLoggerFmt.h
new file mode 100644
index 00000000..3cb38160
--- /dev/null
+++ b/src/core/log/QtLoggerFmt.h
@@ -0,0 +1,51 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+template <>
+struct fmt::formatter<QString> {
+ // Parses format specifications.
+ constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
+ auto it = std::find(ctx.begin(), ctx.end(), '}');
+ if (it != ctx.end() && *it != '}') {
+ throw fmt::format_error("invalid format specifier for QString");
+ }
+ return it;
+ }
+
+ // Formats the QString qstr and writes it to the output.
+ template <typename FormatContext>
+ auto format(const QString& qstr, FormatContext& ctx) const
+ -> decltype(ctx.out()) {
+ // Convert QString to UTF-8 QString (to handle Unicode characters
+ // correctly)
+ QByteArray utf8Str = qstr.toUtf8();
+ return fmt::format_to(ctx.out(), "{}", utf8Str.constData());
+ }
+};
diff --git a/src/core/model/CommonStruct.h b/src/core/model/CommonStruct.h
new file mode 100644
index 00000000..d7d09602
--- /dev/null
+++ b/src/core/model/CommonStruct.h
@@ -0,0 +1,46 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+namespace GpgFrontend {
+
+/**
+ * @brief
+ *
+ */
+template <typename T>
+struct GPGFRONTEND_CORE_EXPORT RefDeleter {
+ void operator()(T* _key) {
+ gpgme_unre
+ }
+};
+
+template <typename T>
+using KeyRefHandler = std::unique_ptr<T, RefDeleter<T>>; ///<
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/DataObject.cpp b/src/core/model/DataObject.cpp
new file mode 100644
index 00000000..d0e9d141
--- /dev/null
+++ b/src/core/model/DataObject.cpp
@@ -0,0 +1,83 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "DataObject.h"
+
+#include <stack>
+
+namespace GpgFrontend {
+
+class DataObject::Impl {
+ public:
+ Impl() = default;
+
+ Impl(std::initializer_list<std::any> init_list) : params_(init_list) {}
+
+ void AppendObject(const std::any& obj) { params_.push_back(obj); }
+
+ auto GetParameter(size_t index) -> std::any {
+ if (index >= params_.size()) {
+ throw std::out_of_range("index out of range");
+ }
+ return params_[index];
+ }
+
+ auto GetObjectSize() -> size_t { return params_.size(); }
+
+ private:
+ std::vector<std::any> params_;
+};
+
+DataObject::DataObject() : p_(SecureCreateUniqueObject<Impl>()) {}
+
+DataObject::DataObject(std::initializer_list<std::any> i)
+ : p_(SecureCreateUniqueObject<Impl>(i)) {}
+
+DataObject::~DataObject() = default;
+
+DataObject::DataObject(DataObject&&) noexcept = default;
+
+auto DataObject::operator[](size_t index) const -> std::any {
+ return p_->GetParameter(index);
+}
+
+auto DataObject::GetParameter(size_t index) const -> std::any {
+ return p_->GetParameter(index);
+}
+
+void DataObject::AppendObject(std::any obj) { return p_->AppendObject(obj); }
+
+auto DataObject::GetObjectSize() const -> size_t { return p_->GetObjectSize(); }
+
+void DataObject::Swap(DataObject& other) noexcept { std::swap(p_, other.p_); }
+
+void DataObject::Swap(DataObject&& other) noexcept { p_ = std::move(other.p_); }
+
+void swap(DataObject& a, DataObject& b) noexcept { a.Swap(b); }
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/DataObject.h b/src/core/model/DataObject.h
new file mode 100644
index 00000000..6b41a051
--- /dev/null
+++ b/src/core/model/DataObject.h
@@ -0,0 +1,104 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include <any>
+#include <typeindex>
+#include <typeinfo>
+
+#include "core/GpgFrontendCoreExport.h"
+#include "core/utils/MemoryUtils.h"
+
+namespace GpgFrontend {
+
+class DataObject;
+using DataObjectPtr = std::shared_ptr<DataObject>; ///<
+
+class GPGFRONTEND_CORE_EXPORT DataObject {
+ public:
+ DataObject();
+
+ DataObject(std::initializer_list<std::any>);
+
+ ~DataObject();
+
+ DataObject(DataObject&&) noexcept;
+
+ auto operator[](size_t index) const -> std::any;
+
+ void AppendObject(std::any);
+
+ [[nodiscard]] auto GetParameter(size_t index) const -> std::any;
+
+ [[nodiscard]] auto GetObjectSize() const -> size_t;
+
+ void Swap(DataObject& other) noexcept;
+
+ void Swap(DataObject&& other) noexcept;
+
+ template <typename... Args>
+ auto Check() -> bool {
+ if (sizeof...(Args) != GetObjectSize()) return false;
+
+ std::vector<std::type_info const*> type_list = {&typeid(Args)...};
+ for (size_t i = 0; i < type_list.size(); ++i) {
+ if (std::type_index(*type_list[i]) !=
+ std::type_index((*this)[i].type())) {
+ GF_CORE_LOG_ERROR(
+ "value of index {} in data object is type: {}, "
+ "not expected type: {}",
+ i, ((*this)[i]).type().name(), type_list[i]->name());
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private:
+ class Impl;
+ SecureUniquePtr<Impl> p_;
+};
+
+template <typename... Args>
+auto TransferParams(Args&&... args) -> std::shared_ptr<DataObject> {
+ return GpgFrontend::SecureCreateSharedObject<DataObject>(
+ DataObject{std::forward<Args>(args)...});
+}
+
+template <typename T>
+auto ExtractParams(const std::shared_ptr<DataObject>& d_o, int index) -> T {
+ if (!d_o) {
+ throw std::invalid_argument("nullptr provided for DataObjectPtr");
+ }
+ return std::any_cast<T>(d_o->GetParameter(index));
+}
+
+void swap(DataObject& a, DataObject& b) noexcept;
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GFBuffer.cpp b/src/core/model/GFBuffer.cpp
new file mode 100644
index 00000000..c65ae689
--- /dev/null
+++ b/src/core/model/GFBuffer.cpp
@@ -0,0 +1,78 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GFBuffer.h"
+
+namespace GpgFrontend {
+
+GFBuffer::GFBuffer()
+ : buffer_(SecureCreateSharedObject<std::vector<std::byte>>()) {}
+
+GFBuffer::GFBuffer(const char* c_str)
+ : buffer_(SecureCreateSharedObject<std::vector<std::byte>>()) {
+ if (c_str == nullptr) {
+ return;
+ }
+
+ size_t const length = std::strlen(c_str);
+ buffer_->reserve(length);
+ buffer_->assign(reinterpret_cast<const std::byte*>(c_str),
+ reinterpret_cast<const std::byte*>(c_str) + length);
+}
+
+GFBuffer::GFBuffer(QByteArray buffer)
+ : buffer_(SecureCreateSharedObject<std::vector<std::byte>>()) {
+ std::transform(buffer.begin(), buffer.end(), std::back_inserter(*buffer_),
+ [](const char c) { return static_cast<std::byte>(c); });
+}
+
+GFBuffer::GFBuffer(QString str)
+ : buffer_(SecureCreateSharedObject<std::vector<std::byte>>()) {
+ std::transform(
+ str.begin(), str.end(), std::back_inserter(*buffer_),
+ [](const QChar c) { return static_cast<std::byte>(c.unicode()); });
+}
+
+auto GFBuffer::operator==(const GFBuffer& o) const -> bool {
+ return equal(buffer_->begin(), buffer_->end(), o.buffer_->begin());
+}
+
+auto GFBuffer::Data() const -> std::byte* { return buffer_->data(); }
+
+void GFBuffer::Resize(size_t size) { buffer_->resize(size); }
+
+auto GFBuffer::Size() const -> size_t { return buffer_->size(); }
+
+auto GFBuffer::ConvertToQByteArray() const -> QByteArray {
+ return QByteArray::fromRawData(reinterpret_cast<const char*>(Data()),
+ static_cast<qsizetype>(Size()));
+}
+
+auto GFBuffer::Empty() const -> bool { return this->Size() == 0; }
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GFBuffer.h b/src/core/model/GFBuffer.h
new file mode 100644
index 00000000..d947401e
--- /dev/null
+++ b/src/core/model/GFBuffer.h
@@ -0,0 +1,62 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/GpgFrontendCoreExport.h"
+#include "core/utils/MemoryUtils.h"
+
+namespace GpgFrontend {
+
+class GPGFRONTEND_CORE_EXPORT GFBuffer {
+ public:
+ GFBuffer();
+
+ explicit GFBuffer(const char* c_str);
+
+ explicit GFBuffer(QByteArray buffer);
+
+ explicit GFBuffer(QString str);
+
+ auto operator==(const GFBuffer& o) const -> bool;
+
+ [[nodiscard]] auto Data() const -> std::byte*;
+
+ void Resize(size_t size);
+
+ [[nodiscard]] auto Size() const -> size_t;
+
+ [[nodiscard]] auto Empty() const -> bool;
+
+ [[nodiscard]] auto ConvertToQByteArray() const -> QByteArray;
+
+ private:
+ std::shared_ptr<std::vector<std::byte>> buffer_;
+};
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GFDataExchanger.cpp b/src/core/model/GFDataExchanger.cpp
new file mode 100644
index 00000000..70a6498e
--- /dev/null
+++ b/src/core/model/GFDataExchanger.cpp
@@ -0,0 +1,89 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GFDataExchanger.h"
+
+#include "core/utils/LogUtils.h"
+
+namespace GpgFrontend {
+
+auto GFDataExchanger::Write(const std::byte* buffer, size_t size) -> ssize_t {
+ if (close_) return -1;
+ if (size == 0) return 0;
+
+ std::atomic<ssize_t> write_bytes = 0;
+ std::unique_lock<std::mutex> lock(mutex_);
+ try {
+ for (size_t i = 0; i < size; i++) {
+ if (queue_.size() == queue_max_size_) not_empty_.notify_all();
+ not_full_.wait(lock,
+ [=] { return queue_.size() < queue_max_size_ || close_; });
+ if (close_) return -1;
+
+ queue_.push(buffer[i]);
+ write_bytes++;
+ }
+ } catch (...) {
+ GF_CORE_LOG_ERROR(
+ "gf data exchanger caught exception when it writes to queue, abort...");
+ }
+
+ if (!queue_.empty()) not_empty_.notify_all();
+ return write_bytes;
+}
+
+auto GFDataExchanger::Read(std::byte* buffer, size_t size) -> ssize_t {
+ std::unique_lock<std::mutex> lock(mutex_);
+ if (size <= 0 || (close_ && queue_.empty())) return 0;
+
+ std::atomic<ssize_t> read_bytes = 0;
+ for (size_t i = 0; i < size; ++i) {
+ if (queue_.empty()) not_full_.notify_all();
+ not_empty_.wait(lock, [=] { return !queue_.empty() || close_; });
+
+ if (close_ && queue_.empty()) return 0;
+ buffer[i] = queue_.front();
+ queue_.pop();
+ read_bytes++;
+ }
+
+ if (queue_.size() < queue_max_size_) not_full_.notify_all();
+ return read_bytes;
+}
+
+void GFDataExchanger::CloseWrite() {
+ std::unique_lock<std::mutex> const lock(mutex_);
+
+ close_ = true;
+ not_full_.notify_all();
+ not_empty_.notify_all();
+}
+
+GFDataExchanger::GFDataExchanger(ssize_t size) : queue_max_size_(size) {}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GFDataExchanger.h b/src/core/model/GFDataExchanger.h
new file mode 100644
index 00000000..7d4ab050
--- /dev/null
+++ b/src/core/model/GFDataExchanger.h
@@ -0,0 +1,53 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include <queue>
+
+namespace GpgFrontend {
+
+class GFDataExchanger {
+ public:
+ explicit GFDataExchanger(ssize_t size);
+
+ auto Write(const std::byte* buffer, size_t size) -> ssize_t;
+
+ auto Read(std::byte* buffer, size_t size) -> ssize_t;
+
+ void CloseWrite();
+
+ private:
+ std::condition_variable not_full_, not_empty_;
+ std::queue<std::byte> queue_;
+ std::mutex mutex_;
+ const ssize_t queue_max_size_;
+ std::atomic_bool close_ = false;
+};
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgData.cpp b/src/core/model/GpgData.cpp
index 05f61a46..6ab44994 100644
--- a/src/core/model/GpgData.cpp
+++ b/src/core/model/GpgData.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,52 +28,129 @@
#include "core/model/GpgData.h"
-GpgFrontend::GpgData::GpgData() {
+#include <unistd.h>
+
+#include "core/model/GFDataExchanger.h"
+#include "core/typedef/GpgTypedef.h"
+
+namespace GpgFrontend {
+
+constexpr size_t kBufferSize = 32 * 1024;
+
+auto GFReadExCb(void* handle, void* buffer, size_t size) -> ssize_t {
+ auto* ex = static_cast<GFDataExchanger*>(handle);
+ return ex->Read(static_cast<std::byte*>(buffer), size);
+}
+
+auto GFWriteExCb(void* handle, const void* buffer, size_t size) -> ssize_t {
+ auto* ex = static_cast<GFDataExchanger*>(handle);
+ return ex->Write(static_cast<const std::byte*>(buffer), size);
+}
+
+void GFReleaseExCb(void* handle) {
+ auto* ex = static_cast<GFDataExchanger*>(handle);
+ ex->CloseWrite();
+}
+
+GpgData::GpgData() {
gpgme_data_t data;
auto err = gpgme_data_new(&data);
assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
- data_ref_ = std::unique_ptr<struct gpgme_data, _data_ref_deleter>(data);
+ data_ref_ = std::unique_ptr<struct gpgme_data, DataRefDeleter>(data);
}
-GpgFrontend::GpgData::GpgData(void* buffer, size_t size, bool copy) {
+GpgData::GpgData(GFBuffer buffer) : cached_buffer_(buffer) {
+ gpgme_data_t data;
+
+ auto err = gpgme_data_new_from_mem(
+ &data, reinterpret_cast<const char*>(buffer.Data()), buffer.Size(), 0);
+ assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
+
+ data_ref_ = std::unique_ptr<struct gpgme_data, DataRefDeleter>(data);
+}
+
+GpgData::GpgData(const void* buffer, size_t size, bool copy) {
gpgme_data_t data;
auto err = gpgme_data_new_from_mem(&data, static_cast<const char*>(buffer),
size, copy);
assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
- data_ref_ = std::unique_ptr<struct gpgme_data, _data_ref_deleter>(data);
+ data_ref_ = std::unique_ptr<struct gpgme_data, DataRefDeleter>(data);
}
-/**
- * Read gpgme-Data to QByteArray
- * mainly from http://basket.kde.org/ (kgpgme.cpp)
- */
-#define BUF_SIZE (32 * 1024)
+GpgData::GpgData(int fd) : fd_(fd), data_cbs_() {
+ gpgme_data_t data;
+
+ auto err = gpgme_data_new_from_fd(&data, fd_);
+ assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
+
+ data_ref_ = std::unique_ptr<struct gpgme_data, DataRefDeleter>(data);
+}
+
+GpgData::GpgData(const QString& path, bool read) {
+ gpgme_data_t data;
+
+ // support unicode path
+ QFile file(path);
+ file.open(read ? QIODevice::ReadOnly : QIODevice::WriteOnly);
+ fp_ = fdopen(dup(file.handle()), read ? "rb" : "wb");
+
+ auto err = gpgme_data_new_from_stream(&data, fp_);
+ assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
+
+ data_ref_ = std::unique_ptr<struct gpgme_data, DataRefDeleter>(data);
+}
+
+GpgData::GpgData(std::shared_ptr<GFDataExchanger> ex)
+ : data_cbs_(), data_ex_(std::move(ex)) {
+ gpgme_data_t data;
+
+ data_cbs_.read = GFReadExCb;
+ data_cbs_.write = GFWriteExCb;
+ data_cbs_.seek = nullptr;
+ data_cbs_.release = GFReleaseExCb;
+
+ auto err = gpgme_data_new_from_cbs(&data, &data_cbs_, data_ex_.get());
+ assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
+
+ data_ref_ = std::unique_ptr<struct gpgme_data, DataRefDeleter>(data);
+}
+
+GpgData::~GpgData() {
+ if (fp_ != nullptr) {
+ fclose(fp_);
+ }
+
+ if (fd_ >= 0) {
+ close(fd_);
+ }
+}
-GpgFrontend::ByteArrayPtr GpgFrontend::GpgData::Read2Buffer() {
+auto GpgData::Read2GFBuffer() -> GFBuffer {
gpgme_off_t ret = gpgme_data_seek(*this, 0, SEEK_SET);
- ByteArrayPtr out_buffer = std::make_unique<std::string>();
+ GFBuffer out_buffer;
- if (ret) {
- gpgme_error_t err = gpgme_err_code_from_errno(errno);
+ if (ret != 0) {
+ const GpgError err = gpgme_err_code_from_errno(errno);
assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
} else {
- char buf[BUF_SIZE + 2];
+ std::array<std::byte, kBufferSize + 2> buf;
- 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);
+ while ((ret = gpgme_data_read(*this, buf.data(), kBufferSize)) > 0) {
+ const size_t size = out_buffer.Size();
+ out_buffer.Resize(static_cast<int>(size + ret));
+ memcpy(out_buffer.Data() + size, buf.data(), ret);
}
if (ret < 0) {
- gpgme_error_t err = gpgme_err_code_from_errno(errno);
+ const GpgError err = gpgme_err_code_from_errno(errno);
assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
}
}
return out_buffer;
}
-GpgFrontend::GpgData::operator gpgme_data_t() { return data_ref_.get(); } \ No newline at end of file
+GpgData::operator gpgme_data_t() { return data_ref_.get(); }
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgData.h b/src/core/model/GpgData.h
index 816465d3..358ebd19 100644
--- a/src/core/model/GpgData.h
+++ b/src/core/model/GpgData.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,23 +20,27 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef _GPGDATA_H
-#define _GPGDATA_H
+#pragma once
-#include "core/GpgConstants.h"
+#include "core/GpgFrontendCoreExport.h"
+#include "core/model/GFBuffer.h"
+#include "core/typedef/CoreTypedef.h"
namespace GpgFrontend {
+
+class GFDataExchanger;
+
/**
* @brief
*
*/
-class GpgData {
+class GPGFRONTEND_CORE_EXPORT GpgData {
public:
/**
* @brief Construct a new Gpg Data object
@@ -51,7 +55,40 @@ class GpgData {
* @param size
* @param copy
*/
- GpgData(void* buffer, size_t size, bool copy = true);
+ GpgData(const void* buffer, size_t size, bool copy = true);
+
+ /**
+ * @brief Construct a new Gpg Data object
+ *
+ * @param fd
+ */
+ explicit GpgData(int fd);
+
+ /**
+ * @brief Construct a new Gpg Data object
+ *
+ * @param fd
+ */
+ explicit GpgData(std::shared_ptr<GFDataExchanger>);
+
+ /**
+ * @brief Construct a new Gpg Data object
+ *
+ * @param path
+ */
+ explicit GpgData(const QString& path, bool read);
+
+ /**
+ * @brief Construct a new Gpg Data object
+ *
+ */
+ explicit GpgData(GFBuffer);
+
+ /**
+ * @brief Destroy the Gpg Data object
+ *
+ */
+ ~GpgData();
/**
* @brief
@@ -65,23 +102,27 @@ class GpgData {
*
* @return ByteArrayPtr
*/
- ByteArrayPtr Read2Buffer();
+ auto Read2GFBuffer() -> GFBuffer;
private:
/**
* @brief
*
*/
- struct _data_ref_deleter {
+ struct DataRefDeleter {
void operator()(gpgme_data_t _data) {
if (_data != nullptr) gpgme_data_release(_data);
}
};
- std::unique_ptr<struct gpgme_data, _data_ref_deleter> data_ref_ =
- nullptr; ///<
+ GFBuffer cached_buffer_;
+
+ std::unique_ptr<struct gpgme_data, DataRefDeleter> data_ref_ = nullptr; ///<
+ FILE* fp_ = nullptr;
+ int fd_ = -1;
+
+ struct gpgme_data_cbs data_cbs_;
+ std::shared_ptr<GFDataExchanger> data_ex_;
};
} // namespace GpgFrontend
-
-#endif // _GPGDATA_H \ No newline at end of file
diff --git a/src/core/model/GpgDecryptResult.cpp b/src/core/model/GpgDecryptResult.cpp
new file mode 100644
index 00000000..3568bfd9
--- /dev/null
+++ b/src/core/model/GpgDecryptResult.cpp
@@ -0,0 +1,65 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgDecryptResult.h"
+
+namespace GpgFrontend {
+
+GpgDecryptResult::GpgDecryptResult(gpgme_decrypt_result_t r)
+ : result_ref_(std::shared_ptr<struct _gpgme_op_decrypt_result>(
+ (gpgme_result_ref(r), r), [](gpgme_decrypt_result_t p) {
+ if (p != nullptr) {
+ gpgme_result_unref(p);
+ }
+ })) {}
+
+GpgDecryptResult::GpgDecryptResult() = default;
+
+GpgDecryptResult::~GpgDecryptResult() = default;
+
+auto GpgDecryptResult::IsGood() -> bool { return result_ref_ != nullptr; }
+
+auto GpgDecryptResult::GetRaw() -> gpgme_decrypt_result_t {
+ return result_ref_.get();
+}
+
+auto GpgDecryptResult::Recipients() -> std::vector<GpgRecipient> {
+ std::vector<GpgRecipient> result;
+ for (auto* reci = result_ref_->recipients; reci != nullptr;
+ reci = reci->next) {
+ try {
+ result.emplace_back(reci);
+ } catch (...) {
+ GF_CORE_LOG_ERROR(
+ "caught exception when processing invalid_recipients, "
+ "maybe nullptr of fpr");
+ }
+ }
+ return result;
+}
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgDecryptResult.h b/src/core/model/GpgDecryptResult.h
new file mode 100644
index 00000000..8289d97d
--- /dev/null
+++ b/src/core/model/GpgDecryptResult.h
@@ -0,0 +1,54 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/model/GpgRecipient.h"
+#include "core/typedef/GpgTypedef.h"
+
+namespace GpgFrontend {
+
+class GPGFRONTEND_CORE_EXPORT GpgDecryptResult {
+ public:
+ auto IsGood() -> bool;
+
+ auto GetRaw() -> gpgme_decrypt_result_t;
+
+ auto Recipients() -> std::vector<GpgRecipient>;
+
+ explicit GpgDecryptResult(gpgme_decrypt_result_t);
+
+ GpgDecryptResult();
+
+ virtual ~GpgDecryptResult();
+
+ private:
+ std::shared_ptr<struct _gpgme_op_decrypt_result> result_ref_ = nullptr; ///<
+};
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgEncryptResult.cpp b/src/core/model/GpgEncryptResult.cpp
new file mode 100644
index 00000000..843cf7eb
--- /dev/null
+++ b/src/core/model/GpgEncryptResult.cpp
@@ -0,0 +1,66 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgEncryptResult.h"
+
+namespace GpgFrontend {
+GpgEncryptResult::GpgEncryptResult(gpgme_encrypt_result_t r)
+ : result_ref_(std::shared_ptr<struct _gpgme_op_encrypt_result>(
+ (gpgme_result_ref(r), r), [](gpgme_encrypt_result_t p) {
+ if (p != nullptr) {
+ gpgme_result_unref(p);
+ }
+ })) {}
+
+GpgEncryptResult::GpgEncryptResult() = default;
+
+GpgEncryptResult::~GpgEncryptResult() = default;
+
+auto GpgEncryptResult::IsGood() -> bool { return result_ref_ != nullptr; }
+
+auto GpgEncryptResult::GetRaw() -> gpgme_encrypt_result_t {
+ return result_ref_.get();
+}
+
+auto GpgEncryptResult::InvalidRecipients()
+ -> std::vector<std::tuple<QString, GpgError>> {
+ std::vector<std::tuple<QString, GpgError>> result;
+ for (auto* invalid_key = result_ref_->invalid_recipients;
+ invalid_key != nullptr; invalid_key = invalid_key->next) {
+ try {
+ result.emplace_back(QString{invalid_key->fpr}, invalid_key->reason);
+ } catch (...) {
+ GF_CORE_LOG_ERROR(
+ "caught exception when processing invalid_recipients, "
+ "maybe nullptr of fpr");
+ }
+ }
+ return result;
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgEncryptResult.h b/src/core/model/GpgEncryptResult.h
new file mode 100644
index 00000000..61fca710
--- /dev/null
+++ b/src/core/model/GpgEncryptResult.h
@@ -0,0 +1,53 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/typedef/GpgTypedef.h"
+
+namespace GpgFrontend {
+
+class GPGFRONTEND_CORE_EXPORT GpgEncryptResult {
+ public:
+ auto IsGood() -> bool;
+
+ auto GetRaw() -> gpgme_encrypt_result_t;
+
+ auto InvalidRecipients() -> std::vector<std::tuple<QString, GpgError>>;
+
+ explicit GpgEncryptResult(gpgme_encrypt_result_t);
+
+ GpgEncryptResult();
+
+ virtual ~GpgEncryptResult();
+
+ private:
+ std::shared_ptr<struct _gpgme_op_encrypt_result> result_ref_ = nullptr; ///<
+};
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgGenKeyInfo.cpp b/src/core/model/GpgGenKeyInfo.cpp
new file mode 100644
index 00000000..60f76d96
--- /dev/null
+++ b/src/core/model/GpgGenKeyInfo.cpp
@@ -0,0 +1,486 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgGenKeyInfo.h"
+
+#include <algorithm>
+#include <cassert>
+
+#include "core/utils/LogUtils.h"
+
+namespace GpgFrontend {
+
+void GenKeyInfo::SetAlgo(const QString &t_algo_args) {
+ auto algo_args = t_algo_args.toLower();
+ GF_CORE_LOG_DEBUG("set algo args: {}", algo_args);
+
+ // reset all options
+ reset_options();
+
+ if (!this->subkey_) {
+ this->SetAllowCertification(true);
+ } else {
+ this->SetAllowCertification(false);
+ }
+
+ this->allow_change_certification_ = false;
+
+ if (algo_args == "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.
+ */
+ suggest_min_key_size_ = 1024;
+ suggest_max_key_size_ = 4096;
+ suggest_size_addition_step_ = 1024;
+ SetKeyLength(2048);
+
+ } else if (algo_args == "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);
+ allow_change_encryption_ = false;
+
+ suggest_min_key_size_ = 1024;
+ suggest_max_key_size_ = 3072;
+ suggest_size_addition_step_ = 1024;
+ SetKeyLength(2048);
+
+ } else if (algo_args == "ed25519") {
+ /**
+ * GnuPG supports the Elgamal asymmetric encryption algorithm in key lengths
+ * ranging from 1024 to 4096 bits.
+ */
+ SetAllowEncryption(false);
+ allow_change_encryption_ = false;
+
+ suggest_min_key_size_ = -1;
+ suggest_max_key_size_ = -1;
+ suggest_size_addition_step_ = -1;
+ SetKeyLength(-1);
+ } else if (algo_args == "cv25519" || algo_args == "nistp256" ||
+ algo_args == "nistp384" || algo_args == "nistp521" ||
+ algo_args == "brainpoolp256r1" || algo_args == "brainpoolp384r1" ||
+ algo_args == "brainpoolp512r1") {
+ SetAllowAuthentication(false);
+ allow_change_authentication_ = false;
+
+ SetAllowSigning(false);
+ allow_change_signing_ = false;
+
+ SetAllowCertification(false);
+ allow_change_certification_ = false;
+
+ suggest_min_key_size_ = -1;
+ suggest_max_key_size_ = -1;
+ suggest_size_addition_step_ = -1;
+ SetKeyLength(-1);
+ } else {
+ SPDLOG_ERROR("unsupported gen key algo arguments: {}", algo_args);
+ return;
+ }
+
+ this->algo_ = algo_args;
+}
+
+void GenKeyInfo::reset_options() {
+ allow_change_encryption_ = true;
+ SetAllowEncryption(true);
+
+ allow_change_certification_ = true;
+ SetAllowCertification(true);
+
+ allow_change_signing_ = true;
+ SetAllowSigning(true);
+
+ allow_change_authentication_ = true;
+ SetAllowAuthentication(true);
+
+ passphrase_.clear();
+}
+
+auto GenKeyInfo::GetKeySizeStr() const -> QString {
+ if (key_size_ > 0) {
+ return QString::number(key_size_);
+ }
+ return {};
+}
+
+void GenKeyInfo::SetKeyLength(int m_key_size) {
+ if (m_key_size < suggest_min_key_size_ ||
+ m_key_size > suggest_max_key_size_) {
+ return;
+ }
+ GenKeyInfo::key_size_ = m_key_size;
+}
+
+void GenKeyInfo::SetExpireTime(const QDateTime &m_expired) {
+ if (!IsNonExpired()) {
+ GenKeyInfo::expired_ = m_expired;
+ }
+}
+
+void GenKeyInfo::SetNonExpired(bool m_non_expired) {
+ if (!m_non_expired) this->expired_ = QDateTime::fromSecsSinceEpoch(0);
+ GenKeyInfo::non_expired_ = m_non_expired;
+}
+
+void GenKeyInfo::SetAllowEncryption(bool m_allow_encryption) {
+ if (allow_change_encryption_) {
+ GenKeyInfo::allow_encryption_ = m_allow_encryption;
+ }
+}
+
+void GenKeyInfo::SetAllowCertification(bool m_allow_certification) {
+ if (allow_change_certification_) {
+ GenKeyInfo::allow_certification_ = m_allow_certification;
+ }
+}
+
+GenKeyInfo::GenKeyInfo(bool m_is_sub_key) : subkey_(m_is_sub_key) {
+ assert(!GetSupportedKeyAlgo().empty());
+ SetAlgo(std::get<0>(GetSupportedKeyAlgo()[0]));
+}
+
+auto GenKeyInfo::GetSupportedKeyAlgo()
+ -> const std::vector<GenKeyInfo::KeyGenAlgo> & {
+ static const std::vector<GenKeyInfo::KeyGenAlgo> kSupportKeyAlgo = {
+ {"RSA", "RSA", ""},
+ {"DSA", "DSA", ""},
+ {"ECDSA", "ED25519", ""},
+ {"ECDSA + ECDH", "ED25519", "CV25519"},
+ {"ECDSA + ECDH NIST P-256", "ED25519", "NISTP256"},
+ {"ECDSA + ECDH BrainPool P-256", "ED25519", "BRAINPOOlP256R1"},
+ };
+ return kSupportKeyAlgo;
+}
+
+auto GenKeyInfo::GetSupportedSubkeyAlgo()
+ -> const std::vector<GenKeyInfo::KeyGenAlgo> & {
+ static const std::vector<GenKeyInfo::KeyGenAlgo> kSupportSubkeyAlgo = {
+ {"RSA", "", "RSA"},
+ {"DSA", "", "DSA"},
+ {"ECDSA", "", "ED25519"},
+ {"ECDH", "", "CV25519"},
+ {"ECDH NIST P-256", "", "NISTP256"},
+ {"ECDH NIST P-384", "", "NISTP384"},
+ {"ECDH NIST P-521", "", "NISTP521"},
+ {"ECDH BrainPool P-256", "", "BRAINPOOlP256R1"},
+ {"ECDH BrainPool P-384", "", "BRAINPOOlP384R1"},
+ {"ECDH BrainPool P-512", "", "BRAINPOOlP512R1"}};
+
+ return kSupportSubkeyAlgo;
+}
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+[[nodiscard]] auto GenKeyInfo::IsSubKey() const -> bool { return subkey_; }
+
+/**
+ * @brief Set the Is Sub Key object
+ *
+ * @param m_sub_key
+ */
+void GenKeyInfo::SetIsSubKey(bool m_sub_key) {
+ GenKeyInfo::subkey_ = m_sub_key;
+}
+
+/**
+ * @brief Get the Userid object
+ *
+ * @return QString
+ */
+[[nodiscard]] auto GenKeyInfo::GetUserid() const -> QString {
+ return QString("%1(%2)<%3>").arg(name_).arg(comment_).arg(email_);
+}
+
+/**
+ * @brief Set the Name object
+ *
+ * @param m_name
+ */
+void GenKeyInfo::SetName(const QString &m_name) { this->name_ = m_name; }
+
+/**
+ * @brief Set the Email object
+ *
+ * @param m_email
+ */
+void GenKeyInfo::SetEmail(const QString &m_email) { this->email_ = m_email; }
+
+/**
+ * @brief Set the Comment object
+ *
+ * @param m_comment
+ */
+void GenKeyInfo::SetComment(const QString &m_comment) {
+ this->comment_ = m_comment;
+}
+
+/**
+ * @brief Get the Name object
+ *
+ * @return QString
+ */
+[[nodiscard]] auto GenKeyInfo::GetName() const -> QString { return name_; }
+
+/**
+ * @brief Get the Email object
+ *
+ * @return QString
+ */
+[[nodiscard]] auto GenKeyInfo::GetEmail() const -> QString { return email_; }
+
+/**
+ * @brief Get the Comment object
+ *
+ * @return QString
+ */
+[[nodiscard]] auto GenKeyInfo::GetComment() const -> QString {
+ return comment_;
+}
+
+/**
+ * @brief Get the Algo object
+ *
+ * @return const QString&
+ */
+[[nodiscard]] auto GenKeyInfo::GetAlgo() const -> const QString & {
+ return algo_;
+}
+
+/**
+ * @brief Get the Key Size object
+ *
+ * @return int
+ */
+[[nodiscard]] auto GenKeyInfo::GetKeyLength() const -> int { return key_size_; }
+
+/**
+ * @brief Get the Expired object
+ *
+ * @return const QDateTime&
+ */
+[[nodiscard]] auto GenKeyInfo::GetExpireTime() const -> const QDateTime & {
+ return expired_;
+}
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+[[nodiscard]] auto GenKeyInfo::IsNonExpired() const -> bool {
+ return non_expired_;
+}
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+[[nodiscard]] auto GenKeyInfo::IsNoPassPhrase() const -> bool {
+ return this->no_passphrase_;
+}
+
+/**
+ * @brief Set the Non Pass Phrase object
+ *
+ * @param m_non_pass_phrase
+ */
+void GenKeyInfo::SetNonPassPhrase(bool m_non_pass_phrase) {
+ GenKeyInfo::no_passphrase_ = m_non_pass_phrase;
+}
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+[[nodiscard]] auto GenKeyInfo::IsAllowSigning() const -> bool {
+ return allow_signing_;
+}
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+[[nodiscard]] auto GenKeyInfo::IsAllowNoPassPhrase() const -> bool {
+ return allow_no_pass_phrase_;
+}
+
+/**
+ * @brief Set the Allow Signing object
+ *
+ * @param m_allow_signing
+ */
+void GenKeyInfo::SetAllowSigning(bool m_allow_signing) {
+ if (allow_change_signing_) GenKeyInfo::allow_signing_ = m_allow_signing;
+}
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+[[nodiscard]] auto GenKeyInfo::IsAllowEncryption() const -> bool {
+ return allow_encryption_;
+}
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+[[nodiscard]] auto GenKeyInfo::IsAllowCertification() const -> bool {
+ return allow_certification_;
+}
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+[[nodiscard]] auto GenKeyInfo::IsAllowAuthentication() const -> bool {
+ return allow_authentication_;
+}
+
+/**
+ * @brief Set the Allow Authentication object
+ *
+ * @param m_allow_authentication
+ */
+void GenKeyInfo::SetAllowAuthentication(bool m_allow_authentication) {
+ if (allow_change_authentication_) {
+ GenKeyInfo::allow_authentication_ = m_allow_authentication;
+ }
+}
+
+/**
+ * @brief Get the Pass Phrase object
+ *
+ * @return const QString&
+ */
+[[nodiscard]] auto GenKeyInfo::GetPassPhrase() const -> const QString & {
+ return passphrase_;
+}
+
+/**
+ * @brief Set the Pass Phrase object
+ *
+ * @param m_pass_phrase
+ */
+void GenKeyInfo::SetPassPhrase(const QString &m_pass_phrase) {
+ GenKeyInfo::passphrase_ = m_pass_phrase;
+}
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+[[nodiscard]] auto GenKeyInfo::IsAllowChangeSigning() const -> bool {
+ return allow_change_signing_;
+}
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+[[nodiscard]] auto GenKeyInfo::IsAllowChangeEncryption() const -> bool {
+ return allow_change_encryption_;
+}
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+[[nodiscard]] auto GenKeyInfo::IsAllowChangeCertification() const -> bool {
+ return allow_change_certification_;
+}
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+[[nodiscard]] auto GenKeyInfo::IsAllowChangeAuthentication() const -> bool {
+ return allow_change_authentication_;
+}
+
+/**
+ * @brief Get the Suggest Max Key Size object
+ *
+ * @return int
+ */
+[[nodiscard]] auto GenKeyInfo::GetSuggestMaxKeySize() const -> int {
+ return suggest_max_key_size_;
+}
+
+/**
+ * @brief Get the Suggest Min Key Size object
+ *
+ * @return int
+ */
+[[nodiscard]] auto GenKeyInfo::GetSuggestMinKeySize() const -> int {
+ return suggest_min_key_size_;
+}
+
+/**
+ * @brief Get the Size Change Step object
+ *
+ * @return int
+ */
+[[nodiscard]] auto GenKeyInfo::GetSizeChangeStep() const -> int {
+ return suggest_size_addition_step_;
+}
+
+} // namespace GpgFrontend
diff --git a/src/core/GpgGenKeyInfo.h b/src/core/model/GpgGenKeyInfo.h
index d47b803e..166c6b0f 100644
--- a/src/core/GpgGenKeyInfo.h
+++ b/src/core/model/GpgGenKeyInfo.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,78 +20,41 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGGENKEYINFO_H
-#define GPGFRONTEND_GPGGENKEYINFO_H
-
-#include <boost/date_time.hpp>
-#include <boost/date_time/gregorian/greg_duration_types.hpp>
-#include <boost/format.hpp>
-#include <string>
-#include <vector>
-
-#include "GpgFrontend.h"
+#pragma once
namespace GpgFrontend {
class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
- bool standalone_ = false; ///<
- bool subkey_ = false; ///<
- std::string name_; ///<
- std::string email_; ///<
- std::string comment_; ///<
-
- std::string algo_; ///<
- int key_size_ = 2048;
- boost::posix_time::ptime expired_ =
- boost::posix_time::second_clock::local_time() +
- boost::gregorian::years(2); ///<
- bool non_expired_ = false; ///<
-
- bool no_passphrase_ = false; ///<
- bool allow_no_pass_phrase_ = true; ///<
-
- int suggest_max_key_size_ = 4096; ///<
- int suggest_size_addition_step_ = 1024; ///<
- int suggest_min_key_size_ = 1024; ///<
-
- std::string passphrase_; ///<
-
- using KeyGenAlgo = std::pair<std::string, std::string>;
-
public:
- /**
- * @brief Get the Supported Key Algo object
- *
- * @return const std::vector<std::string>&
- */
- static const std::vector<KeyGenAlgo> &GetSupportedKeyAlgo();
+ using KeyGenAlgo = std::tuple<QString, QString, QString>;
/**
- * @brief Get the Supported Subkey Algo object
+ * @brief Construct a new Gen Key Info object
*
- * @return const std::vector<std::string>&
+ * @param m_is_sub_key
+ * @param m_standalone
*/
- static const std::vector<KeyGenAlgo> &GetSupportedSubkeyAlgo();
+ explicit GenKeyInfo(bool m_is_sub_key = false);
/**
- * @brief Get the Supported Key Algo Standalone object
+ * @brief Get the Supported Key Algo object
*
- * @return const std::vector<std::string>&
+ * @return const std::vector<QString>&
*/
- static const std::vector<KeyGenAlgo> &GetSupportedKeyAlgoStandalone();
+ static auto GetSupportedKeyAlgo() -> const std::vector<KeyGenAlgo> &;
/**
- * @brief Get the Supported Subkey Algo Standalone object
+ * @brief Get the Supported Subkey Algo object
*
- * @return const std::vector<std::string>&
+ * @return const std::vector<QString>&
*/
- static const std::vector<KeyGenAlgo> &GetSupportedSubkeyAlgoStandalone();
+ static auto GetSupportedSubkeyAlgo() -> const std::vector<KeyGenAlgo> &;
/**
* @brief
@@ -99,95 +62,91 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
* @return true
* @return false
*/
- [[nodiscard]] bool IsSubKey() const { return subkey_; }
+ [[nodiscard]] auto IsSubKey() const -> bool;
/**
* @brief Set the Is Sub Key object
*
* @param m_sub_key
*/
- void SetIsSubKey(bool m_sub_key) { GenKeyInfo::subkey_ = m_sub_key; }
+ void SetIsSubKey(bool m_sub_key);
/**
* @brief Get the Userid object
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetUserid() const {
- auto uid_format = boost::format("%1%(%2%)<%3%>") % this->name_ %
- this->comment_ % this->email_;
- return uid_format.str();
- }
+ [[nodiscard]] auto GetUserid() const -> QString;
/**
* @brief Set the Name object
*
* @param m_name
*/
- void SetName(const std::string &m_name) { this->name_ = m_name; }
+ void SetName(const QString &m_name);
/**
* @brief Set the Email object
*
* @param m_email
*/
- void SetEmail(const std::string &m_email) { this->email_ = m_email; }
+ void SetEmail(const QString &m_email);
/**
* @brief Set the Comment object
*
* @param m_comment
*/
- void SetComment(const std::string &m_comment) { this->comment_ = m_comment; }
+ void SetComment(const QString &m_comment);
/**
* @brief Get the Name object
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetName() const { return name_; }
+ [[nodiscard]] auto GetName() const -> QString;
/**
* @brief Get the Email object
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetEmail() const { return email_; }
+ [[nodiscard]] auto GetEmail() const -> QString;
/**
* @brief Get the Comment object
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetComment() const { return comment_; }
+ [[nodiscard]] auto GetComment() const -> QString;
/**
* @brief Get the Algo object
*
- * @return const std::string&
+ * @return const QString&
*/
- [[nodiscard]] const std::string &GetAlgo() const { return algo_; }
+ [[nodiscard]] auto GetAlgo() const -> const QString &;
/**
* @brief Set the Algo object
*
* @param m_algo
*/
- void SetAlgo(const GpgFrontend::GenKeyInfo::KeyGenAlgo &m_algo);
+ void SetAlgo(const QString &);
/**
* @brief Get the Key Size Str object
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetKeySizeStr() const;
+ [[nodiscard]] auto GetKeySizeStr() const -> QString;
/**
* @brief Get the Key Size object
*
* @return int
*/
- [[nodiscard]] int GetKeyLength() const { return key_size_; }
+ [[nodiscard]] auto GetKeyLength() const -> int;
/**
* @brief Set the Key Size object
@@ -199,18 +158,16 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
/**
* @brief Get the Expired object
*
- * @return const boost::posix_time::ptime&
+ * @return const QDateTime&
*/
- [[nodiscard]] const boost::posix_time::ptime &GetExpireTime() const {
- return expired_;
- }
+ [[nodiscard]] auto GetExpireTime() const -> const QDateTime &;
/**
* @brief Set the Expired object
*
* @param m_expired
*/
- void SetExpireTime(const boost::posix_time::ptime &m_expired);
+ void SetExpireTime(const QDateTime &m_expired);
/**
* @brief
@@ -218,7 +175,7 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
* @return true
* @return false
*/
- [[nodiscard]] bool IsNonExpired() const { return non_expired_; }
+ [[nodiscard]] auto IsNonExpired() const -> bool;
/**
* @brief Set the Non Expired object
@@ -233,16 +190,14 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
* @return true
* @return false
*/
- [[nodiscard]] bool IsNoPassPhrase() const { return this->no_passphrase_; }
+ [[nodiscard]] auto IsNoPassPhrase() const -> bool;
/**
* @brief Set the Non Pass Phrase object
*
* @param m_non_pass_phrase
*/
- void SetNonPassPhrase(bool m_non_pass_phrase) {
- GenKeyInfo::no_passphrase_ = m_non_pass_phrase;
- }
+ void SetNonPassPhrase(bool m_non_pass_phrase);
/**
* @brief
@@ -250,7 +205,7 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
* @return true
* @return false
*/
- [[nodiscard]] bool IsAllowSigning() const { return allow_signing_; }
+ [[nodiscard]] auto IsAllowSigning() const -> bool;
/**
* @brief
@@ -258,18 +213,14 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
* @return true
* @return false
*/
- [[nodiscard]] bool IsAllowNoPassPhrase() const {
- return allow_no_pass_phrase_;
- }
+ [[nodiscard]] auto IsAllowNoPassPhrase() const -> bool;
/**
* @brief Set the Allow Signing object
*
* @param m_allow_signing
*/
- void SetAllowSigning(bool m_allow_signing) {
- if (allow_change_signing_) GenKeyInfo::allow_signing_ = m_allow_signing;
- }
+ void SetAllowSigning(bool m_allow_signing);
/**
* @brief
@@ -277,7 +228,7 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
* @return true
* @return false
*/
- [[nodiscard]] bool IsAllowEncryption() const { return allow_encryption_; }
+ [[nodiscard]] auto IsAllowEncryption() const -> bool;
/**
* @brief Set the Allow Encryption object
@@ -292,9 +243,7 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
* @return true
* @return false
*/
- [[nodiscard]] bool IsAllowCertification() const {
- return allow_certification_;
- }
+ [[nodiscard]] auto IsAllowCertification() const -> bool;
/**
* @brief Set the Allow Certification object
@@ -309,35 +258,28 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
* @return true
* @return false
*/
- [[nodiscard]] bool IsAllowAuthentication() const {
- return allow_authentication_;
- }
+ [[nodiscard]] auto IsAllowAuthentication() const -> bool;
/**
* @brief Set the Allow Authentication object
*
* @param m_allow_authentication
*/
- void SetAllowAuthentication(bool m_allow_authentication) {
- if (allow_change_authentication_)
- GenKeyInfo::allow_authentication_ = m_allow_authentication;
- }
+ void SetAllowAuthentication(bool m_allow_authentication);
/**
* @brief Get the Pass Phrase object
*
- * @return const std::string&
+ * @return const QString&
*/
- [[nodiscard]] const std::string &GetPassPhrase() const { return passphrase_; }
+ [[nodiscard]] auto GetPassPhrase() const -> const QString &;
/**
* @brief Set the Pass Phrase object
*
* @param m_pass_phrase
*/
- void SetPassPhrase(const std::string &m_pass_phrase) {
- GenKeyInfo::passphrase_ = m_pass_phrase;
- }
+ void SetPassPhrase(const QString &m_pass_phrase);
/**
* @brief
@@ -345,9 +287,7 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
* @return true
* @return false
*/
- [[nodiscard]] bool IsAllowChangeSigning() const {
- return allow_change_signing_;
- }
+ [[nodiscard]] auto IsAllowChangeSigning() const -> bool;
/**
* @brief
@@ -355,9 +295,7 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
* @return true
* @return false
*/
- [[nodiscard]] bool IsAllowChangeEncryption() const {
- return allow_change_encryption_;
- }
+ [[nodiscard]] auto IsAllowChangeEncryption() const -> bool;
/**
* @brief
@@ -365,9 +303,7 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
* @return true
* @return false
*/
- [[nodiscard]] bool IsAllowChangeCertification() const {
- return allow_change_certification_;
- }
+ [[nodiscard]] auto IsAllowChangeCertification() const -> bool;
/**
* @brief
@@ -375,38 +311,49 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
* @return true
* @return false
*/
- [[nodiscard]] bool IsAllowChangeAuthentication() const {
- return allow_change_authentication_;
- }
+ [[nodiscard]] auto IsAllowChangeAuthentication() const -> bool;
/**
* @brief Get the Suggest Max Key Size object
*
* @return int
*/
- [[nodiscard]] int GetSuggestMaxKeySize() const {
- return suggest_max_key_size_;
- }
+ [[nodiscard]] auto GetSuggestMaxKeySize() const -> int;
/**
* @brief Get the Suggest Min Key Size object
*
* @return int
*/
- [[nodiscard]] int GetSuggestMinKeySize() const {
- return suggest_min_key_size_;
- }
+ [[nodiscard]] auto GetSuggestMinKeySize() const -> int;
/**
* @brief Get the Size Change Step object
*
* @return int
*/
- [[nodiscard]] int GetSizeChangeStep() const {
- return suggest_size_addition_step_;
- }
+ [[nodiscard]] auto GetSizeChangeStep() const -> int;
private:
+ bool subkey_ = false; ///<
+ QString name_; ///<
+ QString email_; ///<
+ QString comment_; ///<
+
+ QString algo_; ///<
+ int key_size_ = 2048;
+ QDateTime expired_ = QDateTime::currentDateTime().addYears(2);
+ bool non_expired_ = false; ///<
+
+ bool no_passphrase_ = false; ///<
+ bool allow_no_pass_phrase_ = true; ///<
+
+ int suggest_max_key_size_ = 4096; ///<
+ int suggest_size_addition_step_ = 1024; ///<
+ int suggest_min_key_size_ = 1024; ///<
+
+ QString passphrase_; ///<
+
bool allow_encryption_ = true; ///<
bool allow_change_encryption_ = true; ///<
bool allow_certification_ = true; ///<
@@ -421,17 +368,6 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo {
*
*/
void reset_options();
-
- public:
- /**
- * @brief Construct a new Gen Key Info object
- *
- * @param m_is_sub_key
- * @param m_standalone
- */
- explicit GenKeyInfo(bool m_is_sub_key = false, bool m_standalone = false);
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGGENKEYINFO_H
diff --git a/src/core/model/GpgGenerateKeyResult.cpp b/src/core/model/GpgGenerateKeyResult.cpp
new file mode 100644
index 00000000..f7ebf14e
--- /dev/null
+++ b/src/core/model/GpgGenerateKeyResult.cpp
@@ -0,0 +1,59 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgGenerateKeyResult.h"
+
+#include <gpgme.h>
+
+namespace GpgFrontend {
+
+GpgGenerateKeyResult::GpgGenerateKeyResult(gpgme_genkey_result_t r)
+ : result_ref_(std::shared_ptr<struct _gpgme_op_genkey_result>(
+ (gpgme_result_ref(r), r), [](gpgme_genkey_result_t p) {
+ if (p != nullptr) {
+ gpgme_result_unref(p);
+ }
+ })) {}
+
+auto GpgGenerateKeyResult::IsGood() -> bool { return result_ref_ != nullptr; }
+
+auto GpgGenerateKeyResult::GetFingerprint() -> QString const {
+ return result_ref_->fpr;
+}
+
+GpgGenerateKeyResult::GpgGenerateKeyResult() = default;
+
+GpgGenerateKeyResult::GpgGenerateKeyResult(const GpgGenerateKeyResult &) =
+ default;
+
+auto GpgGenerateKeyResult::operator=(const GpgGenerateKeyResult &)
+ -> GpgGenerateKeyResult & = default;
+
+GpgGenerateKeyResult::~GpgGenerateKeyResult() = default;
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgGenerateKeyResult.h b/src/core/model/GpgGenerateKeyResult.h
new file mode 100644
index 00000000..f312d415
--- /dev/null
+++ b/src/core/model/GpgGenerateKeyResult.h
@@ -0,0 +1,59 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/GpgFrontendCore.h"
+#include "core/GpgFrontendCoreExport.h"
+
+namespace GpgFrontend {
+
+class GPGFRONTEND_CORE_EXPORT GpgGenerateKeyResult {
+ public:
+ auto IsGood() -> bool;
+
+ auto GetFingerprint() -> QString const;
+
+ explicit GpgGenerateKeyResult(gpgme_genkey_result_t);
+
+ GpgGenerateKeyResult();
+
+ GpgGenerateKeyResult(const GpgGenerateKeyResult &);
+
+ auto operator=(const GpgGenerateKeyResult &) -> GpgGenerateKeyResult &;
+
+ virtual ~GpgGenerateKeyResult();
+
+ private:
+ using ResultRefHandler =
+ std::shared_ptr<struct _gpgme_op_genkey_result>; ///<
+
+ ResultRefHandler result_ref_ = nullptr; ///<
+};
+
+} // namespace GpgFrontend
diff --git a/src/core/model/GpgImportInformation.cpp b/src/core/model/GpgImportInformation.cpp
new file mode 100644
index 00000000..cda146de
--- /dev/null
+++ b/src/core/model/GpgImportInformation.cpp
@@ -0,0 +1,54 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgImportInformation.h"
+
+namespace GpgFrontend {
+
+GpgImportInformation::GpgImportInformation() = default;
+
+GpgImportInformation::GpgImportInformation(gpgme_import_result_t result) {
+ if (result->unchanged != 0) unchanged = result->unchanged;
+ if (result->considered != 0) considered = result->considered;
+ if (result->no_user_id != 0) no_user_id = result->no_user_id;
+ if (result->imported != 0) imported = result->imported;
+ if (result->imported_rsa != 0) imported_rsa = result->imported_rsa;
+ if (result->unchanged != 0) unchanged = result->unchanged;
+ if (result->new_user_ids != 0) new_user_ids = result->new_user_ids;
+ if (result->new_sub_keys != 0) new_sub_keys = result->new_sub_keys;
+ if (result->new_signatures != 0) new_signatures = result->new_signatures;
+ if (result->new_revocations != 0) new_revocations = result->new_revocations;
+ if (result->secret_read != 0) secret_read = result->secret_read;
+ if (result->secret_imported != 0) secret_imported = result->secret_imported;
+ if (result->secret_unchanged != 0) {
+ secret_unchanged = result->secret_unchanged;
+ }
+ if (result->not_imported != 0) not_imported = result->not_imported;
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgImportInformation.h b/src/core/model/GpgImportInformation.h
new file mode 100644
index 00000000..5f85a338
--- /dev/null
+++ b/src/core/model/GpgImportInformation.h
@@ -0,0 +1,80 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+namespace GpgFrontend {
+
+/**
+ * @brief
+ *
+ */
+class GPGFRONTEND_CORE_EXPORT GpgImportInformation {
+ public:
+ /**
+ * @brief
+ *
+ */
+ class GpgImportedKey {
+ public:
+ QString fpr; ///<
+ int import_status; ///<
+ };
+
+ using GpgImportedKeyList = std::list<GpgImportedKey>; ///<
+
+ /**
+ * @brief Construct a new Gpg Import Information object
+ *
+ */
+ GpgImportInformation();
+
+ /**
+ * @brief Construct a new Gpg Import Information object
+ *
+ * @param result
+ */
+ explicit GpgImportInformation(gpgme_import_result_t result);
+
+ 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 imported_keys; ///<
+};
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgKey.cpp b/src/core/model/GpgKey.cpp
index 3a167b81..ab962b5d 100644
--- a/src/core/model/GpgKey.cpp
+++ b/src/core/model/GpgKey.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -30,70 +30,80 @@
#include <mutex>
-GpgFrontend::GpgKey::GpgKey(gpgme_key_t &&key) : key_ref_(std::move(key)) {}
+namespace GpgFrontend {
-GpgFrontend::GpgKey::GpgKey(GpgKey &&k) noexcept { swap(key_ref_, k.key_ref_); }
+GpgKey::GpgKey(gpgme_key_t &&key) : key_ref_(key) {}
-GpgFrontend::GpgKey &GpgFrontend::GpgKey::operator=(GpgKey &&k) noexcept {
+GpgKey::GpgKey(GpgKey &&k) noexcept { swap(key_ref_, k.key_ref_); }
+
+auto GpgKey::operator=(GpgKey &&k) noexcept -> GpgKey & {
swap(key_ref_, k.key_ref_);
return *this;
}
-bool GpgFrontend::GpgKey::operator==(const GpgKey &o) const {
+GpgKey::GpgKey(const GpgKey &key) {
+ auto *key_ref = key.key_ref_.get();
+ gpgme_key_ref(key_ref);
+ this->key_ref_ = KeyRefHandler(key_ref);
+}
+
+auto GpgKey::operator=(const GpgKey &key) -> GpgKey & {
+ if (this == &key) {
+ return *this;
+ }
+
+ auto *key_ref = key.key_ref_.get();
+ gpgme_key_ref(key_ref);
+
+ this->key_ref_ = KeyRefHandler(key_ref);
+ return *this;
+}
+
+auto GpgKey::operator==(const GpgKey &o) const -> bool {
return o.GetId() == this->GetId();
}
-bool GpgFrontend::GpgKey::operator<=(const GpgKey &o) const {
+auto GpgKey::operator<=(const GpgKey &o) const -> bool {
return this->GetId() < o.GetId();
}
-GpgFrontend::GpgKey::operator gpgme_key_t() const { return key_ref_.get(); }
+GpgKey::operator gpgme_key_t() const { return key_ref_.get(); }
-bool GpgFrontend::GpgKey::IsGood() const { return key_ref_ != nullptr; }
+auto GpgKey::IsGood() const -> bool { return key_ref_ != nullptr; }
-std::string GpgFrontend::GpgKey::GetId() const {
- return key_ref_->subkeys->keyid;
-}
+auto GpgKey::GetId() const -> QString { return key_ref_->subkeys->keyid; }
-std::string GpgFrontend::GpgKey::GetName() const {
- return key_ref_->uids->name;
-};
+auto GpgKey::GetName() const -> QString { return key_ref_->uids->name; };
-std::string GpgFrontend::GpgKey::GetEmail() const {
- return key_ref_->uids->email;
-}
+auto GpgKey::GetEmail() const -> QString { return key_ref_->uids->email; }
-std::string GpgFrontend::GpgKey::GetComment() const {
- return key_ref_->uids->comment;
-}
+auto GpgKey::GetComment() const -> QString { return key_ref_->uids->comment; }
-std::string GpgFrontend::GpgKey::GetFingerprint() const {
- return key_ref_->fpr;
-}
+auto GpgKey::GetFingerprint() const -> QString { return key_ref_->fpr; }
-std::string GpgFrontend::GpgKey::GetProtocol() const {
+auto GpgKey::GetProtocol() const -> QString {
return gpgme_get_protocol_name(key_ref_->protocol);
}
-std::string GpgFrontend::GpgKey::GetOwnerTrust() const {
+auto GpgKey::GetOwnerTrust() const -> QString {
switch (key_ref_->owner_trust) {
case GPGME_VALIDITY_UNKNOWN:
- return _("Unknown");
+ return tr("Unknown");
case GPGME_VALIDITY_UNDEFINED:
- return _("Undefined");
+ return tr("Undefined");
case GPGME_VALIDITY_NEVER:
- return _("Never");
+ return tr("Never");
case GPGME_VALIDITY_MARGINAL:
- return _("Marginal");
+ return tr("Marginal");
case GPGME_VALIDITY_FULL:
- return _("Full");
+ return tr("Full");
case GPGME_VALIDITY_ULTIMATE:
- return _("Ultimate");
+ return tr("Ultimate");
}
return "Invalid";
}
-int GpgFrontend::GpgKey::GetOwnerTrustLevel() const {
+auto GpgKey::GetOwnerTrustLevel() const -> int {
switch (key_ref_->owner_trust) {
case GPGME_VALIDITY_UNKNOWN:
return 0;
@@ -111,66 +121,65 @@ int GpgFrontend::GpgKey::GetOwnerTrustLevel() const {
return 0;
}
-std::string GpgFrontend::GpgKey::GetPublicKeyAlgo() const {
+auto GpgKey::GetPublicKeyAlgo() const -> QString {
return gpgme_pubkey_algo_name(key_ref_->subkeys->pubkey_algo);
}
-boost::posix_time::ptime GpgFrontend::GpgKey::GetLastUpdateTime() const {
- return boost::posix_time::from_time_t(
+auto GpgKey::GetLastUpdateTime() const -> QDateTime {
+ return QDateTime::fromSecsSinceEpoch(
static_cast<time_t>(key_ref_->last_update));
}
-boost::posix_time::ptime GpgFrontend::GpgKey::GetExpireTime() const {
- return boost::posix_time::from_time_t(key_ref_->subkeys->expires);
+auto GpgKey::GetExpireTime() const -> QDateTime {
+ return QDateTime::fromSecsSinceEpoch(key_ref_->subkeys->expires);
};
-boost::posix_time::ptime GpgFrontend::GpgKey::GetCreateTime() const {
- return boost::posix_time::from_time_t(key_ref_->subkeys->timestamp);
+auto GpgKey::GetCreateTime() const -> QDateTime {
+ return QDateTime::fromSecsSinceEpoch(key_ref_->subkeys->timestamp);
};
-unsigned int GpgFrontend::GpgKey::GetPrimaryKeyLength() const {
+auto GpgKey::GetPrimaryKeyLength() const -> unsigned int {
return key_ref_->subkeys->length;
}
-bool GpgFrontend::GpgKey::IsHasEncryptionCapability() const {
+auto GpgKey::IsHasEncryptionCapability() const -> bool {
return key_ref_->can_encrypt;
}
-bool GpgFrontend::GpgKey::IsHasSigningCapability() const {
+auto GpgKey::IsHasSigningCapability() const -> bool {
return key_ref_->can_sign;
}
-bool GpgFrontend::GpgKey::IsHasCertificationCapability() const {
+auto GpgKey::IsHasCertificationCapability() const -> bool {
return key_ref_->can_certify;
}
-bool GpgFrontend::GpgKey::IsHasAuthenticationCapability() const {
+auto GpgKey::IsHasAuthenticationCapability() const -> bool {
return key_ref_->can_authenticate;
}
-bool GpgFrontend::GpgKey::IsHasCardKey() const {
+auto GpgKey::IsHasCardKey() const -> bool {
auto subkeys = GetSubKeys();
return std::any_of(
subkeys->begin(), subkeys->end(),
[](const GpgSubKey &subkey) -> bool { return subkey.IsCardKey(); });
}
-bool GpgFrontend::GpgKey::IsPrivateKey() const { return key_ref_->secret; }
+auto GpgKey::IsPrivateKey() const -> bool { return key_ref_->secret; }
-bool GpgFrontend::GpgKey::IsExpired() const { return key_ref_->expired; }
+auto GpgKey::IsExpired() const -> bool { return key_ref_->expired; }
-bool GpgFrontend::GpgKey::IsRevoked() const { return key_ref_->revoked; }
+auto GpgKey::IsRevoked() const -> bool { return key_ref_->revoked; }
-bool GpgFrontend::GpgKey::IsDisabled() const { return key_ref_->disabled; }
+auto GpgKey::IsDisabled() const -> bool { return key_ref_->disabled; }
-bool GpgFrontend::GpgKey::IsHasMasterKey() const {
+auto GpgKey::IsHasMasterKey() const -> bool {
return key_ref_->subkeys->secret;
}
-std::unique_ptr<std::vector<GpgFrontend::GpgSubKey>>
-GpgFrontend::GpgKey::GetSubKeys() const {
+auto GpgKey::GetSubKeys() const -> std::unique_ptr<std::vector<GpgSubKey>> {
auto p_keys = std::make_unique<std::vector<GpgSubKey>>();
- auto next = key_ref_->subkeys;
+ auto *next = key_ref_->subkeys;
while (next != nullptr) {
p_keys->push_back(GpgSubKey(next));
next = next->next;
@@ -178,10 +187,9 @@ GpgFrontend::GpgKey::GetSubKeys() const {
return p_keys;
}
-std::unique_ptr<std::vector<GpgFrontend::GpgUID>> GpgFrontend::GpgKey::GetUIDs()
- const {
+auto GpgKey::GetUIDs() const -> std::unique_ptr<std::vector<GpgUID>> {
auto p_uids = std::make_unique<std::vector<GpgUID>>();
- auto uid_next = key_ref_->uids;
+ auto *uid_next = key_ref_->uids;
while (uid_next != nullptr) {
p_uids->push_back(GpgUID(uid_next));
uid_next = uid_next->next;
@@ -189,32 +197,24 @@ std::unique_ptr<std::vector<GpgFrontend::GpgUID>> GpgFrontend::GpgKey::GetUIDs()
return p_uids;
}
-bool GpgFrontend::GpgKey::IsHasActualSigningCapability() const {
+auto GpgKey::IsHasActualSigningCapability() const -> bool {
auto subkeys = GetSubKeys();
- if (std::any_of(subkeys->begin(), subkeys->end(),
- [](const GpgSubKey &subkey) -> bool {
- return subkey.IsSecretKey() &&
- subkey.IsHasSigningCapability() &&
- !subkey.IsDisabled() && !subkey.IsRevoked() &&
- !subkey.IsExpired();
- }))
- return true;
- else
- return false;
+ return std::any_of(
+ subkeys->begin(), subkeys->end(), [](const GpgSubKey &subkey) -> bool {
+ return subkey.IsSecretKey() && subkey.IsHasSigningCapability() &&
+ !subkey.IsDisabled() && !subkey.IsRevoked() &&
+ !subkey.IsExpired();
+ });
}
-bool GpgFrontend::GpgKey::IsHasActualAuthenticationCapability() const {
+auto GpgKey::IsHasActualAuthenticationCapability() const -> bool {
auto subkeys = GetSubKeys();
- if (std::any_of(subkeys->begin(), subkeys->end(),
- [](const GpgSubKey &subkey) -> bool {
- return subkey.IsSecretKey() &&
- subkey.IsHasAuthenticationCapability() &&
- !subkey.IsDisabled() && !subkey.IsRevoked() &&
- !subkey.IsExpired();
- }))
- return true;
- else
- return false;
+ return std::any_of(
+ subkeys->begin(), subkeys->end(), [](const GpgSubKey &subkey) -> bool {
+ return subkey.IsSecretKey() && subkey.IsHasAuthenticationCapability() &&
+ !subkey.IsDisabled() && !subkey.IsRevoked() &&
+ !subkey.IsExpired();
+ });
}
/**
@@ -222,7 +222,7 @@ bool GpgFrontend::GpgKey::IsHasActualAuthenticationCapability() const {
* @param key target key
* @return if key certify
*/
-bool GpgFrontend::GpgKey::IsHasActualCertificationCapability() const {
+auto GpgKey::IsHasActualCertificationCapability() const -> bool {
return IsHasMasterKey() && !IsExpired() && !IsRevoked() && !IsDisabled();
}
@@ -231,28 +231,17 @@ bool GpgFrontend::GpgKey::IsHasActualCertificationCapability() const {
* @param key target key
* @return if key encrypt
*/
-bool GpgFrontend::GpgKey::IsHasActualEncryptionCapability() const {
+auto GpgKey::IsHasActualEncryptionCapability() const -> bool {
auto subkeys = GetSubKeys();
- if (std::any_of(subkeys->begin(), subkeys->end(),
- [](const GpgSubKey &subkey) -> bool {
- return subkey.IsHasEncryptionCapability() &&
- !subkey.IsDisabled() && !subkey.IsRevoked() &&
- !subkey.IsExpired();
- }))
- return true;
- else
- return false;
-}
-
-GpgFrontend::GpgKey GpgFrontend::GpgKey::Copy() const {
- {
- const std::lock_guard<std::mutex> guard(gpgme_key_opera_mutex);
- gpgme_key_ref(key_ref_.get());
- }
- auto *_new_key_ref = key_ref_.get();
- return GpgKey(std::move(_new_key_ref));
+ return std::any_of(
+ subkeys->begin(), subkeys->end(), [](const GpgSubKey &subkey) -> bool {
+ return subkey.IsHasEncryptionCapability() && !subkey.IsDisabled() &&
+ !subkey.IsRevoked() && !subkey.IsExpired();
+ });
}
-void GpgFrontend::GpgKey::_key_ref_deleter::operator()(gpgme_key_t _key) {
+void GpgKey::KeyRefDeleter::operator()(gpgme_key_t _key) {
if (_key != nullptr) gpgme_key_unref(_key);
}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgKey.h b/src/core/model/GpgKey.h
index fb87b791..70599b99 100644
--- a/src/core/model/GpgKey.h
+++ b/src/core/model/GpgKey.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,19 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGKEY_H
-#define GPGFRONTEND_GPGKEY_H
+#pragma once
-#include <mutex>
-
-#include "GpgSubKey.h"
-#include "GpgUID.h"
+#include "core/model/GpgSubKey.h"
+#include "core/model/GpgUID.h"
namespace GpgFrontend {
@@ -41,6 +38,7 @@ namespace GpgFrontend {
*
*/
class GPGFRONTEND_CORE_EXPORT GpgKey {
+ Q_DECLARE_TR_FUNCTIONS(GpgKey)
public:
/**
* @brief
@@ -48,98 +46,98 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsGood() const;
+ [[nodiscard]] auto IsGood() const -> bool;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetId() const;
+ [[nodiscard]] auto GetId() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetName() const;
+ [[nodiscard]] auto GetName() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetEmail() const;
+ [[nodiscard]] auto GetEmail() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetComment() const;
+ [[nodiscard]] auto GetComment() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetFingerprint() const;
+ [[nodiscard]] auto GetFingerprint() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetProtocol() const;
+ [[nodiscard]] auto GetProtocol() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetOwnerTrust() const;
+ [[nodiscard]] auto GetOwnerTrust() const -> QString;
/**
* @brief
*
* @return int
*/
- [[nodiscard]] int GetOwnerTrustLevel() const;
+ [[nodiscard]] auto GetOwnerTrustLevel() const -> int;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetPublicKeyAlgo() const;
+ [[nodiscard]] auto GetPublicKeyAlgo() const -> QString;
/**
* @brief
*
- * @return boost::posix_time::ptime
+ * @return QDateTime
*/
- [[nodiscard]] boost::posix_time::ptime GetLastUpdateTime() const;
+ [[nodiscard]] auto GetLastUpdateTime() const -> QDateTime;
/**
* @brief
*
- * @return boost::posix_time::ptime
+ * @return QDateTime
*/
- [[nodiscard]] boost::posix_time::ptime GetExpireTime() const;
+ [[nodiscard]] auto GetExpireTime() const -> QDateTime;
/**
* @brief Create a time object
*
- * @return boost::posix_time::ptime
+ * @return QDateTime
*/
- [[nodiscard]] boost::posix_time::ptime GetCreateTime() const;
+ [[nodiscard]] auto GetCreateTime() const -> QDateTime;
/**
* @brief s
*
* @return unsigned int
*/
- [[nodiscard]] unsigned int GetPrimaryKeyLength() const;
+ [[nodiscard]] auto GetPrimaryKeyLength() const -> unsigned int;
/**
* @brief
@@ -147,7 +145,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasEncryptionCapability() const;
+ [[nodiscard]] auto IsHasEncryptionCapability() const -> bool;
/**
* @brief
@@ -156,7 +154,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasActualEncryptionCapability() const;
+ [[nodiscard]] auto IsHasActualEncryptionCapability() const -> bool;
/**
* @brief
@@ -164,7 +162,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasSigningCapability() const;
+ [[nodiscard]] auto IsHasSigningCapability() const -> bool;
/**
* @brief
@@ -172,7 +170,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasActualSigningCapability() const;
+ [[nodiscard]] auto IsHasActualSigningCapability() const -> bool;
/**
* @brief
@@ -180,7 +178,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasCertificationCapability() const;
+ [[nodiscard]] auto IsHasCertificationCapability() const -> bool;
/**
* @brief
@@ -188,7 +186,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasActualCertificationCapability() const;
+ [[nodiscard]] auto IsHasActualCertificationCapability() const -> bool;
/**
* @brief
@@ -196,7 +194,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasAuthenticationCapability() const;
+ [[nodiscard]] auto IsHasAuthenticationCapability() const -> bool;
/**
* @brief
@@ -204,7 +202,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasActualAuthenticationCapability() const;
+ [[nodiscard]] auto IsHasActualAuthenticationCapability() const -> bool;
/**
* @brief
@@ -212,7 +210,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasCardKey() const;
+ [[nodiscard]] auto IsHasCardKey() const -> bool;
/**
* @brief
@@ -220,7 +218,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsPrivateKey() const;
+ [[nodiscard]] auto IsPrivateKey() const -> bool;
/**
* @brief
@@ -228,7 +226,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsExpired() const;
+ [[nodiscard]] auto IsExpired() const -> bool;
/**
* @brief
@@ -236,7 +234,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsRevoked() const;
+ [[nodiscard]] auto IsRevoked() const -> bool;
/**
* @brief
@@ -244,7 +242,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsDisabled() const;
+ [[nodiscard]] auto IsDisabled() const -> bool;
/**
* @brief
@@ -252,21 +250,22 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasMasterKey() const;
+ [[nodiscard]] auto IsHasMasterKey() const -> bool;
/**
* @brief
*
* @return std::unique_ptr<std::vector<GpgSubKey>>
*/
- [[nodiscard]] std::unique_ptr<std::vector<GpgSubKey>> GetSubKeys() const;
+ [[nodiscard]] auto GetSubKeys() const
+ -> std::unique_ptr<std::vector<GpgSubKey>>;
/**
* @brief
*
* @return std::unique_ptr<std::vector<GpgUID>>
*/
- [[nodiscard]] std::unique_ptr<std::vector<GpgUID>> GetUIDs() const;
+ [[nodiscard]] auto GetUIDs() const -> std::unique_ptr<std::vector<GpgUID>>;
/**
* @brief Construct a new Gpg Key object
@@ -299,7 +298,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
*
* @param k
*/
- GpgKey(GpgKey&& k) noexcept;
+ GpgKey(GpgKey&&) noexcept;
/**
* @brief
@@ -307,7 +306,22 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @param k
* @return GpgKey&
*/
- GpgKey& operator=(GpgKey&& k) noexcept;
+ auto operator=(GpgKey&&) noexcept -> GpgKey&;
+
+ /**
+ * @brief Construct a new Gpg Key object
+ *
+ * @param k
+ */
+ GpgKey(const GpgKey&);
+
+ /**
+ * @brief
+ *
+ * @param k
+ * @return GpgKey&
+ */
+ auto operator=(const GpgKey&) -> GpgKey&;
/**
* @brief
@@ -315,7 +329,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @param key
* @return GpgKey&
*/
- GpgKey& operator=(const gpgme_key_t& key) = delete;
+ auto operator=(const gpgme_key_t&) -> GpgKey& = delete;
/**
* @brief
@@ -324,7 +338,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- bool operator==(const GpgKey& o) const;
+ auto operator==(const GpgKey&) const -> bool;
/**
* @brief
@@ -333,7 +347,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
* @return true
* @return false
*/
- bool operator<=(const GpgKey& o) const;
+ auto operator<=(const GpgKey&) const -> bool;
/**
* @brief
@@ -342,30 +356,18 @@ class GPGFRONTEND_CORE_EXPORT GpgKey {
*/
explicit operator gpgme_key_t() const;
- /**
- * @brief
- *
- * @return GpgKey
- */
- [[nodiscard]] GpgKey Copy() const;
-
private:
/**
* @brief
*
*/
- struct GPGFRONTEND_CORE_EXPORT _key_ref_deleter {
+ struct GPGFRONTEND_CORE_EXPORT KeyRefDeleter {
void operator()(gpgme_key_t _key);
};
- using KeyRefHandler =
- std::unique_ptr<struct _gpgme_key, _key_ref_deleter>; ///<
+ using KeyRefHandler = std::unique_ptr<struct _gpgme_key, KeyRefDeleter>; ///<
KeyRefHandler key_ref_ = nullptr; ///<
-
- mutable std::mutex gpgme_key_opera_mutex; // mutex for gpgme key operations
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGKEY_H
diff --git a/src/core/model/GpgKeySignature.cpp b/src/core/model/GpgKeySignature.cpp
index aa196391..3182000c 100644
--- a/src/core/model/GpgKeySignature.cpp
+++ b/src/core/model/GpgKeySignature.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,67 +28,53 @@
#include "core/model/GpgKeySignature.h"
-GpgFrontend::GpgKeySignature::GpgKeySignature() = default;
+namespace GpgFrontend {
-GpgFrontend::GpgKeySignature::~GpgKeySignature() = default;
+GpgKeySignature::GpgKeySignature() = default;
-GpgFrontend::GpgKeySignature::GpgKeySignature(gpgme_key_sig_t sig)
+GpgKeySignature::~GpgKeySignature() = default;
+
+GpgKeySignature::GpgKeySignature(gpgme_key_sig_t sig)
: signature_ref_(sig, [&](gpgme_key_sig_t signature) {}) {}
-GpgFrontend::GpgKeySignature::GpgKeySignature(GpgKeySignature &&) noexcept =
+GpgKeySignature::GpgKeySignature(GpgKeySignature &&) noexcept = default;
+
+GpgKeySignature &GpgKeySignature::operator=(GpgKeySignature &&) noexcept =
default;
-GpgFrontend::GpgKeySignature &GpgFrontend::GpgKeySignature::operator=(
- GpgKeySignature &&) noexcept = default;
+bool GpgKeySignature::IsRevoked() const { return signature_ref_->revoked; }
-bool GpgFrontend::GpgKeySignature::IsRevoked() const {
- return signature_ref_->revoked;
-}
-
-bool GpgFrontend::GpgKeySignature::IsExpired() const {
- return signature_ref_->expired;
-}
+bool GpgKeySignature::IsExpired() const { return signature_ref_->expired; }
-bool GpgFrontend::GpgKeySignature::IsInvalid() const {
- return signature_ref_->invalid;
-}
+bool GpgKeySignature::IsInvalid() const { return signature_ref_->invalid; }
-bool GpgFrontend::GpgKeySignature::IsExportable() const {
+bool GpgKeySignature::IsExportable() const {
return signature_ref_->exportable;
}
-gpgme_error_t GpgFrontend::GpgKeySignature::GetStatus() const {
+gpgme_error_t GpgKeySignature::GetStatus() const {
return signature_ref_->status;
}
-std::string GpgFrontend::GpgKeySignature::GetKeyID() const {
- return signature_ref_->keyid;
-}
+QString GpgKeySignature::GetKeyID() const { return signature_ref_->keyid; }
-std::string GpgFrontend::GpgKeySignature::GetPubkeyAlgo() const {
+QString GpgKeySignature::GetPubkeyAlgo() const {
return gpgme_pubkey_algo_name(signature_ref_->pubkey_algo);
}
-boost::posix_time::ptime GpgFrontend::GpgKeySignature::GetCreateTime() const {
- return boost::posix_time::from_time_t(signature_ref_->timestamp);
+QDateTime GpgKeySignature::GetCreateTime() const {
+ return QDateTime::fromSecsSinceEpoch(signature_ref_->timestamp);
}
-boost::posix_time::ptime GpgFrontend::GpgKeySignature::GetExpireTime() const {
- return boost::posix_time::from_time_t(signature_ref_->expires);
+QDateTime GpgKeySignature::GetExpireTime() const {
+ return QDateTime::fromSecsSinceEpoch(signature_ref_->expires);
}
-std::string GpgFrontend::GpgKeySignature::GetUID() const {
- return signature_ref_->uid;
-}
+QString GpgKeySignature::GetUID() const { return signature_ref_->uid; }
-std::string GpgFrontend::GpgKeySignature::GetName() const {
- return signature_ref_->name;
-}
+QString GpgKeySignature::GetName() const { return signature_ref_->name; }
-std::string GpgFrontend::GpgKeySignature::GetEmail() const {
- return signature_ref_->email;
-}
+QString GpgKeySignature::GetEmail() const { return signature_ref_->email; }
-std::string GpgFrontend::GpgKeySignature::GetComment() const {
- return signature_ref_->comment;
-} \ No newline at end of file
+QString GpgKeySignature::GetComment() const { return signature_ref_->comment; }
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgKeySignature.h b/src/core/model/GpgKeySignature.h
index 25de2c75..c9ceeccc 100644
--- a/src/core/model/GpgKeySignature.h
+++ b/src/core/model/GpgKeySignature.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,19 +20,15 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGKEYSIGNATURE_H
-#define GPGFRONTEND_GPGKEYSIGNATURE_H
+#pragma once
-#include <boost/date_time.hpp>
-#include <string>
-
-#include "core/GpgConstants.h"
+#include "core/typedef/GpgTypedef.h"
/**
* @brief
@@ -52,7 +48,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeySignature {
* @return true
* @return false
*/
- [[nodiscard]] bool IsRevoked() const;
+ [[nodiscard]] auto IsRevoked() const -> bool;
/**
* @brief
@@ -60,7 +56,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeySignature {
* @return true
* @return false
*/
- [[nodiscard]] bool IsExpired() const;
+ [[nodiscard]] auto IsExpired() const -> bool;
/**
* @brief
@@ -68,7 +64,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeySignature {
* @return true
* @return false
*/
- [[nodiscard]] bool IsInvalid() const;
+ [[nodiscard]] auto IsInvalid() const -> bool;
/**
* @brief
@@ -76,70 +72,70 @@ class GPGFRONTEND_CORE_EXPORT GpgKeySignature {
* @return true
* @return false
*/
- [[nodiscard]] bool IsExportable() const;
+ [[nodiscard]] auto IsExportable() const -> bool;
/**
* @brief
*
* @return gpgme_error_t
*/
- [[nodiscard]] gpgme_error_t GetStatus() const;
+ [[nodiscard]] auto GetStatus() const -> GpgError;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetKeyID() const;
+ [[nodiscard]] auto GetKeyID() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetPubkeyAlgo() const;
+ [[nodiscard]] auto GetPubkeyAlgo() const -> QString;
/**
* @brief Create a time object
*
- * @return boost::posix_time::ptime
+ * @return QDateTime
*/
- [[nodiscard]] boost::posix_time::ptime GetCreateTime() const;
+ [[nodiscard]] auto GetCreateTime() const -> QDateTime;
/**
* @brief
*
- * @return boost::posix_time::ptime
+ * @return QDateTime
*/
- [[nodiscard]] boost::posix_time::ptime GetExpireTime() const;
+ [[nodiscard]] auto GetExpireTime() const -> QDateTime;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetUID() const;
+ [[nodiscard]] auto GetUID() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetName() const;
+ [[nodiscard]] auto GetName() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetEmail() const;
+ [[nodiscard]] auto GetEmail() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetComment() const;
+ [[nodiscard]] auto GetComment() const -> QString;
/**
* @brief Construct a new Gpg Key Signature object
@@ -177,14 +173,14 @@ class GPGFRONTEND_CORE_EXPORT GpgKeySignature {
*
* @return GpgKeySignature&
*/
- GpgKeySignature &operator=(GpgKeySignature &&) noexcept;
+ auto operator=(GpgKeySignature &&) noexcept -> GpgKeySignature &;
/**
* @brief
*
* @return GpgKeySignature&
*/
- GpgKeySignature &operator=(const GpgKeySignature &) = delete;
+ auto operator=(const GpgKeySignature &) -> GpgKeySignature & = delete;
private:
using KeySignatrueRefHandler =
@@ -195,5 +191,3 @@ class GPGFRONTEND_CORE_EXPORT GpgKeySignature {
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGKEYSIGNATURE_H
diff --git a/src/core/model/GpgPassphraseContext.cpp b/src/core/model/GpgPassphraseContext.cpp
new file mode 100644
index 00000000..5df3f5a8
--- /dev/null
+++ b/src/core/model/GpgPassphraseContext.cpp
@@ -0,0 +1,60 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgPassphraseContext.h"
+
+namespace GpgFrontend {
+
+GpgPassphraseContext::GpgPassphraseContext(const QString& uids_info,
+ const QString& passphrase_info,
+ bool prev_was_bad, bool ask_for_new)
+ : passphrase_info_(passphrase_info),
+ uids_info_(uids_info),
+ prev_was_bad_(prev_was_bad),
+ ask_for_new_(ask_for_new) {}
+
+GpgPassphraseContext::GpgPassphraseContext() = default;
+
+auto GpgPassphraseContext::GetPassphrase() const -> QString {
+ return passphrase_;
+}
+
+void GpgPassphraseContext::SetPassphrase(const QString& passphrase) {
+ passphrase_ = passphrase;
+}
+
+auto GpgPassphraseContext::GetUidsInfo() const -> QString { return uids_info_; }
+
+auto GpgPassphraseContext::GetPassphraseInfo() const -> QString {
+ return passphrase_info_;
+}
+
+auto GpgPassphraseContext::IsPreWasBad() const -> bool { return prev_was_bad_; }
+
+auto GpgPassphraseContext::IsAskForNew() const -> bool { return ask_for_new_; }
+} // namespace GpgFrontend
diff --git a/src/core/model/GpgPassphraseContext.h b/src/core/model/GpgPassphraseContext.h
new file mode 100644
index 00000000..2bc1ac75
--- /dev/null
+++ b/src/core/model/GpgPassphraseContext.h
@@ -0,0 +1,63 @@
+
+
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+namespace GpgFrontend {
+
+class GPGFRONTEND_CORE_EXPORT GpgPassphraseContext : public QObject {
+ Q_OBJECT
+ public:
+ GpgPassphraseContext(const QString& uids_info, const QString& passphrase_info,
+ bool prev_was_bad, bool ask_for_new);
+
+ GpgPassphraseContext();
+
+ void SetPassphrase(const QString& passphrase);
+
+ [[nodiscard]] auto GetPassphrase() const -> QString;
+
+ [[nodiscard]] auto GetUidsInfo() const -> QString;
+
+ [[nodiscard]] auto GetPassphraseInfo() const -> QString;
+
+ [[nodiscard]] auto IsPreWasBad() const -> bool;
+
+ [[nodiscard]] auto IsAskForNew() const -> bool;
+
+ private:
+ QString passphrase_info_;
+ QString uids_info_;
+ QString passphrase_;
+ bool prev_was_bad_;
+ bool ask_for_new_;
+};
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgRecipient.cpp b/src/core/model/GpgRecipient.cpp
new file mode 100644
index 00000000..54de43bc
--- /dev/null
+++ b/src/core/model/GpgRecipient.cpp
@@ -0,0 +1,40 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgRecipient.h"
+
+namespace GpgFrontend {
+
+GpgRecipient::GpgRecipient() = default;
+
+GpgRecipient::GpgRecipient(gpgme_recipient_t r) {
+ this->keyid = QString{r->keyid};
+ this->pubkey_algo = QString{gpgme_pubkey_algo_name(r->pubkey_algo)};
+ this->status = r->status;
+}
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgRecipient.h b/src/core/model/GpgRecipient.h
new file mode 100644
index 00000000..a436c1d7
--- /dev/null
+++ b/src/core/model/GpgRecipient.h
@@ -0,0 +1,51 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/GpgFrontendCoreExport.h"
+#include "core/typedef/GpgTypedef.h"
+
+namespace GpgFrontend {
+
+struct GPGFRONTEND_CORE_EXPORT GpgRecipient {
+ /* The key ID of key for which the text was encrypted. */
+ QString keyid;
+
+ /* The public key algorithm of the recipient key. */
+ QString pubkey_algo;
+
+ /* The status of the recipient. */
+ GpgError status;
+
+ GpgRecipient();
+
+ explicit GpgRecipient(gpgme_recipient_t r);
+};
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgSignResult.cpp b/src/core/model/GpgSignResult.cpp
new file mode 100644
index 00000000..4a0e5f35
--- /dev/null
+++ b/src/core/model/GpgSignResult.cpp
@@ -0,0 +1,65 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgSignResult.h"
+
+namespace GpgFrontend {
+GpgSignResult::GpgSignResult(gpgme_sign_result_t r)
+ : result_ref_(std::shared_ptr<struct _gpgme_op_sign_result>(
+ (gpgme_result_ref(r), r), [](gpgme_sign_result_t p) {
+ if (p != nullptr) {
+ gpgme_result_unref(p);
+ }
+ })) {}
+
+GpgSignResult::GpgSignResult() = default;
+
+GpgSignResult::~GpgSignResult() = default;
+
+auto GpgSignResult::IsGood() -> bool { return result_ref_ != nullptr; }
+
+auto GpgSignResult::GetRaw() -> gpgme_sign_result_t {
+ return result_ref_.get();
+}
+
+auto GpgSignResult::InvalidSigners()
+ -> std::vector<std::tuple<QString, GpgError>> {
+ std::vector<std::tuple<QString, GpgError>> result;
+ for (auto* invalid_key = result_ref_->invalid_signers; invalid_key != nullptr;
+ invalid_key = invalid_key->next) {
+ try {
+ result.emplace_back(QString{invalid_key->fpr}, invalid_key->reason);
+ } catch (...) {
+ GF_CORE_LOG_ERROR(
+ "caught exception when processing invalid_signers, "
+ "maybe nullptr of fpr");
+ }
+ }
+ return result;
+}
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgSignResult.h b/src/core/model/GpgSignResult.h
new file mode 100644
index 00000000..ccb0361f
--- /dev/null
+++ b/src/core/model/GpgSignResult.h
@@ -0,0 +1,53 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/GpgFrontendCoreExport.h"
+#include "core/typedef/GpgTypedef.h"
+
+namespace GpgFrontend {
+
+class GPGFRONTEND_CORE_EXPORT GpgSignResult {
+ public:
+ auto IsGood() -> bool;
+
+ auto GetRaw() -> gpgme_sign_result_t;
+
+ auto InvalidSigners() -> std::vector<std::tuple<QString, GpgError>>;
+
+ explicit GpgSignResult(gpgme_sign_result_t);
+
+ GpgSignResult();
+
+ virtual ~GpgSignResult();
+
+ private:
+ std::shared_ptr<struct _gpgme_op_sign_result> result_ref_ = nullptr; ///<
+};
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgSignature.cpp b/src/core/model/GpgSignature.cpp
index 73f9179d..e2cb7e4b 100644
--- a/src/core/model/GpgSignature.cpp
+++ b/src/core/model/GpgSignature.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,21 +28,28 @@
#include "GpgSignature.h"
+namespace GpgFrontend {
+
/**
* @brief Construct a new Gpg Signature object
*
*/
-GpgFrontend::GpgSignature::GpgSignature(GpgSignature &&) noexcept = default;
+GpgSignature::GpgSignature(GpgSignature &&) noexcept = default;
/**
* @brief
*
* @return GpgSignature&
*/
-GpgFrontend::GpgSignature &GpgFrontend::GpgSignature::operator=(
- GpgFrontend::GpgSignature &&) noexcept = default;
+auto GpgSignature::operator=(GpgSignature &&) noexcept
+ -> GpgSignature & = default;
-GpgFrontend::GpgSignature::GpgSignature(gpgme_signature_t sig)
+/**
+ * @brief Construct a new Gpg Signature:: Gpg Signature object
+ *
+ * @param sig
+ */
+GpgSignature::GpgSignature(gpgme_signature_t sig)
: signature_ref_(sig, [&](gpgme_signature_t signature) {}) {}
/**
@@ -50,7 +57,7 @@ GpgFrontend::GpgSignature::GpgSignature(gpgme_signature_t sig)
*
* @return gpgme_validity_t
*/
-gpgme_validity_t GpgFrontend::GpgSignature::GetValidity() const {
+auto GpgSignature::GetValidity() const -> gpgme_validity_t {
return signature_ref_->validity;
}
@@ -59,7 +66,7 @@ gpgme_validity_t GpgFrontend::GpgSignature::GetValidity() const {
*
* @return gpgme_error_t
*/
-gpgme_error_t GpgFrontend::GpgSignature::GetStatus() const {
+auto GpgSignature::GetStatus() const -> gpgme_error_t {
return signature_ref_->status;
}
@@ -68,52 +75,52 @@ gpgme_error_t GpgFrontend::GpgSignature::GetStatus() const {
*
* @return gpgme_error_t
*/
-gpgme_error_t GpgFrontend::GpgSignature::GetSummary() const {
+auto GpgSignature::GetSummary() const -> gpgme_error_t {
return signature_ref_->summary;
}
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
-std::string GpgFrontend::GpgSignature::GetPubkeyAlgo() const {
+auto GpgSignature::GetPubkeyAlgo() const -> QString {
return gpgme_pubkey_algo_name(signature_ref_->pubkey_algo);
}
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
-std::string GpgFrontend::GpgSignature::GetHashAlgo() const {
+auto GpgSignature::GetHashAlgo() const -> QString {
return gpgme_hash_algo_name(signature_ref_->hash_algo);
}
/**
* @brief Create a time object
*
- * @return boost::posix_time::ptime
+ * @return QDateTime
*/
-boost::posix_time::ptime GpgFrontend::GpgSignature::GetCreateTime() const {
- return boost::posix_time::from_time_t(signature_ref_->timestamp);
+auto GpgSignature::GetCreateTime() const -> QDateTime {
+ return QDateTime::fromSecsSinceEpoch(signature_ref_->timestamp);
}
/**
* @brief
*
- * @return boost::posix_time::ptime
+ * @return QDateTime
*/
-boost::posix_time::ptime GpgFrontend::GpgSignature::GetExpireTime() const {
- return boost::posix_time::from_time_t(signature_ref_->exp_timestamp);
+auto GpgSignature::GetExpireTime() const -> QDateTime {
+ return QDateTime::fromSecsSinceEpoch(signature_ref_->exp_timestamp);
}
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
-std::string GpgFrontend::GpgSignature::GetFingerprint() const {
+auto GpgSignature::GetFingerprint() const -> QString {
return signature_ref_->fpr;
}
@@ -121,10 +128,12 @@ std::string GpgFrontend::GpgSignature::GetFingerprint() const {
* @brief Construct a new Gpg Signature object
*
*/
-GpgFrontend::GpgSignature::GpgSignature() = default;
+GpgSignature::GpgSignature() = default;
/**
* @brief Destroy the Gpg Signature object
*
*/
-GpgFrontend::GpgSignature::~GpgSignature() = default;
+GpgSignature::~GpgSignature() = default;
+
+} // namespace GpgFrontend
diff --git a/src/core/model/GpgSignature.h b/src/core/model/GpgSignature.h
index 2e49c4d7..316b9100 100644
--- a/src/core/model/GpgSignature.h
+++ b/src/core/model/GpgSignature.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,19 +20,15 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGSIGNATURE_H
-#define GPGFRONTEND_GPGSIGNATURE_H
+#pragma once
-#include <boost/date_time/gregorian/greg_date.hpp>
-#include <boost/date_time/posix_time/conversion.hpp>
-
-#include "core/GpgConstants.h"
+#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
@@ -47,56 +43,56 @@ class GPGFRONTEND_CORE_EXPORT GpgSignature {
*
* @return gpgme_validity_t
*/
- [[nodiscard]] gpgme_validity_t GetValidity() const;
+ [[nodiscard]] auto GetValidity() const -> gpgme_validity_t;
/**
* @brief
*
* @return gpgme_error_t
*/
- [[nodiscard]] gpgme_error_t GetStatus() const;
+ [[nodiscard]] auto GetStatus() const -> GpgError;
/**
* @brief
*
* @return gpgme_error_t
*/
- [[nodiscard]] gpgme_error_t GetSummary() const;
+ [[nodiscard]] auto GetSummary() const -> GpgError;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetPubkeyAlgo() const;
+ [[nodiscard]] auto GetPubkeyAlgo() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetHashAlgo() const;
+ [[nodiscard]] auto GetHashAlgo() const -> QString;
/**
* @brief Create a time object
*
- * @return boost::posix_time::ptime
+ * @return QDateTime
*/
- [[nodiscard]] boost::posix_time::ptime GetCreateTime() const;
+ [[nodiscard]] auto GetCreateTime() const -> QDateTime;
/**
* @brief
*
- * @return boost::posix_time::ptime
+ * @return QDateTime
*/
- [[nodiscard]] boost::posix_time::ptime GetExpireTime() const;
+ [[nodiscard]] auto GetExpireTime() const -> QDateTime;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetFingerprint() const;
+ [[nodiscard]] auto GetFingerprint() const -> QString;
/**
* @brief Construct a new Gpg Signature object
@@ -134,14 +130,14 @@ class GPGFRONTEND_CORE_EXPORT GpgSignature {
*
* @return GpgSignature&
*/
- GpgSignature &operator=(GpgSignature &&) noexcept;
+ auto operator=(GpgSignature &&) noexcept -> GpgSignature &;
/**
* @brief
*
* @return GpgSignature&
*/
- GpgSignature &operator=(const GpgSignature &) = delete;
+ auto operator=(const GpgSignature &) -> GpgSignature & = delete;
private:
using KeySignatrueRefHandler =
@@ -151,5 +147,3 @@ class GPGFRONTEND_CORE_EXPORT GpgSignature {
KeySignatrueRefHandler signature_ref_ = nullptr; ///<
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGSIGNATURE_H
diff --git a/src/core/model/GpgSubKey.cpp b/src/core/model/GpgSubKey.cpp
index e63816b1..eaef1498 100644
--- a/src/core/model/GpgSubKey.cpp
+++ b/src/core/model/GpgSubKey.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,84 +20,79 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#include "core/model/GpgSubKey.h"
+#include "GpgSubKey.h"
-GpgFrontend::GpgSubKey::GpgSubKey() = default;
+namespace GpgFrontend {
-GpgFrontend::GpgSubKey::GpgSubKey(gpgme_subkey_t subkey)
- : _subkey_ref(subkey, [&](gpgme_subkey_t subkey) {}) {}
+GpgSubKey::GpgSubKey() = default;
-GpgFrontend::GpgSubKey::GpgSubKey(GpgSubKey&& o) noexcept {
- swap(_subkey_ref, o._subkey_ref);
+GpgSubKey::GpgSubKey(gpgme_subkey_t subkey)
+ : subkey_ref_(subkey, [&](gpgme_subkey_t subkey) {}) {}
+
+GpgSubKey::GpgSubKey(GpgSubKey&& o) noexcept {
+ swap(subkey_ref_, o.subkey_ref_);
}
-GpgFrontend::GpgSubKey& GpgFrontend::GpgSubKey::operator=(
- GpgSubKey&& o) noexcept {
- swap(_subkey_ref, o._subkey_ref);
+auto GpgSubKey::operator=(GpgSubKey&& o) noexcept -> GpgSubKey& {
+ swap(subkey_ref_, o.subkey_ref_);
return *this;
};
-bool GpgFrontend::GpgSubKey::operator==(const GpgSubKey& o) const {
+auto GpgSubKey::operator==(const GpgSubKey& o) const -> bool {
return GetFingerprint() == o.GetFingerprint();
}
-std::string GpgFrontend::GpgSubKey::GetID() const { return _subkey_ref->keyid; }
+auto GpgSubKey::GetID() const -> QString { return subkey_ref_->keyid; }
-std::string GpgFrontend::GpgSubKey::GetFingerprint() const {
- return _subkey_ref->fpr;
-}
+auto GpgSubKey::GetFingerprint() const -> QString { return subkey_ref_->fpr; }
-std::string GpgFrontend::GpgSubKey::GetPubkeyAlgo() const {
- return gpgme_pubkey_algo_name(_subkey_ref->pubkey_algo);
+auto GpgSubKey::GetPubkeyAlgo() const -> QString {
+ return gpgme_pubkey_algo_name(subkey_ref_->pubkey_algo);
}
-unsigned int GpgFrontend::GpgSubKey::GetKeyLength() const {
- return _subkey_ref->length;
+auto GpgSubKey::GetKeyLength() const -> unsigned int {
+ return subkey_ref_->length;
}
-bool GpgFrontend::GpgSubKey::IsHasEncryptionCapability() const {
- return _subkey_ref->can_encrypt;
+auto GpgSubKey::IsHasEncryptionCapability() const -> bool {
+ return subkey_ref_->can_encrypt;
}
-bool GpgFrontend::GpgSubKey::IsHasSigningCapability() const {
- return _subkey_ref->can_sign;
+auto GpgSubKey::IsHasSigningCapability() const -> bool {
+ return subkey_ref_->can_sign;
}
-bool GpgFrontend::GpgSubKey::IsHasCertificationCapability() const {
- return _subkey_ref->can_certify;
+auto GpgSubKey::IsHasCertificationCapability() const -> bool {
+ return subkey_ref_->can_certify;
}
-bool GpgFrontend::GpgSubKey::IsHasAuthenticationCapability() const {
- return _subkey_ref->can_authenticate;
+auto GpgSubKey::IsHasAuthenticationCapability() const -> bool {
+ return subkey_ref_->can_authenticate;
}
-bool GpgFrontend::GpgSubKey::IsPrivateKey() const {
- return _subkey_ref->secret;
-}
+auto GpgSubKey::IsPrivateKey() const -> bool { return subkey_ref_->secret; }
-bool GpgFrontend::GpgSubKey::IsExpired() const { return _subkey_ref->expired; }
+auto GpgSubKey::IsExpired() const -> bool { return subkey_ref_->expired; }
-bool GpgFrontend::GpgSubKey::IsRevoked() const { return _subkey_ref->revoked; }
+auto GpgSubKey::IsRevoked() const -> bool { return subkey_ref_->revoked; }
-bool GpgFrontend::GpgSubKey::IsDisabled() const {
- return _subkey_ref->disabled;
-}
+auto GpgSubKey::IsDisabled() const -> bool { return subkey_ref_->disabled; }
-bool GpgFrontend::GpgSubKey::IsSecretKey() const { return _subkey_ref->secret; }
+auto GpgSubKey::IsSecretKey() const -> bool { return subkey_ref_->secret; }
-bool GpgFrontend::GpgSubKey::IsCardKey() const {
- return _subkey_ref->is_cardkey;
-}
+auto GpgSubKey::IsCardKey() const -> bool { return subkey_ref_->is_cardkey; }
-boost::posix_time::ptime GpgFrontend::GpgSubKey::GetCreateTime() const {
- return boost::posix_time::from_time_t(_subkey_ref->timestamp);
+auto GpgSubKey::GetCreateTime() const -> QDateTime {
+ return QDateTime::fromSecsSinceEpoch(subkey_ref_->timestamp);
}
-boost::posix_time::ptime GpgFrontend::GpgSubKey::GetExpireTime() const {
- return boost::posix_time::from_time_t(_subkey_ref->expires);
+auto GpgSubKey::GetExpireTime() const -> QDateTime {
+ return QDateTime::fromSecsSinceEpoch(subkey_ref_->expires);
}
+
+} // namespace GpgFrontend
diff --git a/src/core/model/GpgSubKey.h b/src/core/model/GpgSubKey.h
index 5a86d21d..d8268c34 100644
--- a/src/core/model/GpgSubKey.h
+++ b/src/core/model/GpgSubKey.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,19 +20,13 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGSUBKEY_H
-#define GPGFRONTEND_GPGSUBKEY_H
-
-#include <boost/date_time.hpp>
-#include <string>
-
-#include "core/GpgConstants.h"
+#pragma once
namespace GpgFrontend {
@@ -45,30 +39,30 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey {
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetID() const;
+ [[nodiscard]] auto GetID() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetFingerprint() const;
+ [[nodiscard]] auto GetFingerprint() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetPubkeyAlgo() const;
+ [[nodiscard]] auto GetPubkeyAlgo() const -> QString;
/**
* @brief
*
* @return unsigned int
*/
- [[nodiscard]] unsigned int GetKeyLength() const;
+ [[nodiscard]] auto GetKeyLength() const -> unsigned int;
/**
* @brief
@@ -76,7 +70,7 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasEncryptionCapability() const;
+ [[nodiscard]] auto IsHasEncryptionCapability() const -> bool;
/**
* @brief
@@ -84,7 +78,7 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasSigningCapability() const;
+ [[nodiscard]] auto IsHasSigningCapability() const -> bool;
/**
* @brief
@@ -92,7 +86,7 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasCertificationCapability() const;
+ [[nodiscard]] auto IsHasCertificationCapability() const -> bool;
/**
* @brief
@@ -100,7 +94,7 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsHasAuthenticationCapability() const;
+ [[nodiscard]] auto IsHasAuthenticationCapability() const -> bool;
/**
* @brief
@@ -108,7 +102,7 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsPrivateKey() const;
+ [[nodiscard]] auto IsPrivateKey() const -> bool;
/**
* @brief
@@ -116,7 +110,7 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsExpired() const;
+ [[nodiscard]] auto IsExpired() const -> bool;
/**
* @brief
@@ -124,7 +118,7 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsRevoked() const;
+ [[nodiscard]] auto IsRevoked() const -> bool;
/**
* @brief
@@ -132,7 +126,7 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsDisabled() const;
+ [[nodiscard]] auto IsDisabled() const -> bool;
/**
* @brief
@@ -140,7 +134,7 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsSecretKey() const;
+ [[nodiscard]] auto IsSecretKey() const -> bool;
/**
* @brief
@@ -148,21 +142,21 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey {
* @return true
* @return false
*/
- [[nodiscard]] bool IsCardKey() const;
+ [[nodiscard]] auto IsCardKey() const -> bool;
/**
* @brief
*
- * @return boost::posix_time::ptime
+ * @return QDateTime
*/
- [[nodiscard]] boost::posix_time::ptime GetCreateTime() const;
+ [[nodiscard]] auto GetCreateTime() const -> QDateTime;
/**
* @brief
*
- * @return boost::posix_time::ptime
+ * @return QDateTime
*/
- [[nodiscard]] boost::posix_time::ptime GetExpireTime() const;
+ [[nodiscard]] QDateTime GetExpireTime() const;
/**
* @brief Construct a new Gpg Sub Key object
@@ -196,14 +190,14 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey {
* @param o
* @return GpgSubKey&
*/
- GpgSubKey& operator=(GpgSubKey&& o) noexcept;
+ auto operator=(GpgSubKey&& o) noexcept -> GpgSubKey&;
/**
* @brief
*
* @return GpgSubKey&
*/
- GpgSubKey& operator=(const GpgSubKey&) = delete;
+ auto operator=(const GpgSubKey&) -> GpgSubKey& = delete;
/**
* @brief
@@ -212,16 +206,14 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey {
* @return true
* @return false
*/
- bool operator==(const GpgSubKey& o) const;
+ auto operator==(const GpgSubKey& o) const -> bool;
private:
using SubkeyRefHandler =
std::unique_ptr<struct _gpgme_subkey,
std::function<void(gpgme_subkey_t)>>; ///<
- SubkeyRefHandler _subkey_ref = nullptr; ///<
+ SubkeyRefHandler subkey_ref_ = nullptr; ///<
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGSUBKEY_H
diff --git a/src/core/model/GpgTOFUInfo.cpp b/src/core/model/GpgTOFUInfo.cpp
index 84ce1e29..251affc2 100644
--- a/src/core/model/GpgTOFUInfo.cpp
+++ b/src/core/model/GpgTOFUInfo.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,39 +28,40 @@
#include "GpgTOFUInfo.h"
-GpgFrontend::GpgTOFUInfo::GpgTOFUInfo() = default;
+namespace GpgFrontend {
-GpgFrontend::GpgTOFUInfo::GpgTOFUInfo(gpgme_tofu_info_t tofu_info)
- : _tofu_info_ref(tofu_info, [&](gpgme_tofu_info_t tofu_info) {}) {}
+GpgTOFUInfo::GpgTOFUInfo() = default;
-GpgFrontend::GpgTOFUInfo::GpgTOFUInfo(GpgTOFUInfo&& o) noexcept {
- swap(_tofu_info_ref, o._tofu_info_ref);
+GpgTOFUInfo::GpgTOFUInfo(gpgme_tofu_info_t tofu_info)
+ : tofu_info_ref_(tofu_info, [&](gpgme_tofu_info_t tofu_info) {}) {}
+
+GpgTOFUInfo::GpgTOFUInfo(GpgTOFUInfo&& o) noexcept {
+ swap(tofu_info_ref_, o.tofu_info_ref_);
}
-GpgFrontend::GpgTOFUInfo& GpgFrontend::GpgTOFUInfo::operator=(
- GpgTOFUInfo&& o) noexcept {
- swap(_tofu_info_ref, o._tofu_info_ref);
+auto GpgTOFUInfo::operator=(GpgTOFUInfo&& o) noexcept -> GpgTOFUInfo& {
+ swap(tofu_info_ref_, o.tofu_info_ref_);
return *this;
};
-unsigned GpgFrontend::GpgTOFUInfo::GetValidity() const {
- return _tofu_info_ref->validity;
+auto GpgTOFUInfo::GetValidity() const -> unsigned {
+ return tofu_info_ref_->validity;
}
-unsigned GpgFrontend::GpgTOFUInfo::GetPolicy() const {
- return _tofu_info_ref->policy;
+auto GpgTOFUInfo::GetPolicy() const -> unsigned {
+ return tofu_info_ref_->policy;
}
-unsigned long GpgFrontend::GpgTOFUInfo::GetSignCount() const {
- return _tofu_info_ref->signcount;
+auto GpgTOFUInfo::GetSignCount() const -> unsigned long {
+ return tofu_info_ref_->signcount;
}
-unsigned long GpgFrontend::GpgTOFUInfo::GetEncrCount() const {
- return _tofu_info_ref->encrcount;
+auto GpgTOFUInfo::GetEncrCount() const -> unsigned long {
+ return tofu_info_ref_->encrcount;
}
-unsigned long GpgFrontend::GpgTOFUInfo::GetSignFirst() const {
- return _tofu_info_ref->signfirst;
+auto GpgTOFUInfo::GetSignFirst() const -> unsigned long {
+ return tofu_info_ref_->signfirst;
}
/**
@@ -68,8 +69,8 @@ unsigned long GpgFrontend::GpgTOFUInfo::GetSignFirst() const {
*
* @return unsigned long
*/
-unsigned long GpgFrontend::GpgTOFUInfo::GetSignLast() const {
- return _tofu_info_ref->signlast;
+auto GpgTOFUInfo::GetSignLast() const -> unsigned long {
+ return tofu_info_ref_->signlast;
}
/**
@@ -77,15 +78,17 @@ unsigned long GpgFrontend::GpgTOFUInfo::GetSignLast() const {
*
* @return unsigned long
*/
-unsigned long GpgFrontend::GpgTOFUInfo::GetEncrLast() const {
- return _tofu_info_ref->encrlast;
+auto GpgTOFUInfo::GetEncrLast() const -> unsigned long {
+ return tofu_info_ref_->encrlast;
}
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
-std::string GpgFrontend::GpgTOFUInfo::GetDescription() const {
- return _tofu_info_ref->description;
-} \ No newline at end of file
+auto GpgTOFUInfo::GetDescription() const -> QString {
+ return tofu_info_ref_->description;
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgTOFUInfo.h b/src/core/model/GpgTOFUInfo.h
index b82a4eb2..ec4c49b7 100644
--- a/src/core/model/GpgTOFUInfo.h
+++ b/src/core/model/GpgTOFUInfo.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,16 +20,13 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGTOFU_H
-#define GPGFRONTEND_GPGTOFU_H
-
-#include "core/GpgConstants.h"
+#pragma once
namespace GpgFrontend {
/**
@@ -43,55 +40,55 @@ class GPGFRONTEND_CORE_EXPORT GpgTOFUInfo {
*
* @return unsigned
*/
- [[nodiscard]] unsigned GetValidity() const;
+ [[nodiscard]] auto GetValidity() const -> unsigned;
/**
* @brief
*
* @return unsigned
*/
- [[nodiscard]] unsigned GetPolicy() const;
+ [[nodiscard]] auto GetPolicy() const -> unsigned;
/**
* @brief
*
* @return unsigned long
*/
- [[nodiscard]] unsigned long GetSignCount() const;
+ [[nodiscard]] auto GetSignCount() const -> unsigned long;
/**
* @brief
*
* @return unsigned long
*/
- [[nodiscard]] unsigned long GetEncrCount() const;
+ [[nodiscard]] auto GetEncrCount() const -> unsigned long;
/**
* @brief
*
* @return unsigned long
*/
- [[nodiscard]] unsigned long GetSignFirst() const;
+ [[nodiscard]] auto GetSignFirst() const -> unsigned long;
/**
* @brief
*
* @return unsigned long
*/
- [[nodiscard]] unsigned long GetSignLast() const;
+ [[nodiscard]] auto GetSignLast() const -> unsigned long;
/**
* @brief
*
* @return unsigned long
*/
- [[nodiscard]] unsigned long GetEncrLast() const;
+ [[nodiscard]] auto GetEncrLast() const -> unsigned long;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetDescription() const;
+ [[nodiscard]] auto GetDescription() const -> QString;
/**
* @brief Construct a new Gpg T O F U Info object
@@ -125,23 +122,21 @@ class GPGFRONTEND_CORE_EXPORT GpgTOFUInfo {
* @param o
* @return GpgTOFUInfo&
*/
- GpgTOFUInfo& operator=(GpgTOFUInfo&& o) noexcept;
+ auto operator=(GpgTOFUInfo&& o) noexcept -> GpgTOFUInfo&;
/**
* @brief
*
* @return GpgTOFUInfo&
*/
- GpgTOFUInfo& operator=(const GpgTOFUInfo&) = delete;
+ auto operator=(const GpgTOFUInfo&) -> GpgTOFUInfo& = delete;
private:
using SubkeyRefHandler =
std::unique_ptr<struct _gpgme_tofu_info,
std::function<void(gpgme_tofu_info_t)>>; ///<
- SubkeyRefHandler _tofu_info_ref = nullptr; ///<
+ SubkeyRefHandler tofu_info_ref_ = nullptr; ///<
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGTOFU_H
diff --git a/src/core/model/GpgUID.cpp b/src/core/model/GpgUID.cpp
index d87192c3..e0d9d3a6 100644
--- a/src/core/model/GpgUID.cpp
+++ b/src/core/model/GpgUID.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,31 +28,30 @@
#include "core/model/GpgUID.h"
-GpgFrontend::GpgUID::GpgUID() = default;
+namespace GpgFrontend {
-GpgFrontend::GpgUID::GpgUID(gpgme_user_id_t uid)
+GpgUID::GpgUID() = default;
+
+GpgUID::GpgUID(gpgme_user_id_t uid)
: uid_ref_(uid, [&](gpgme_user_id_t uid) {}) {}
-GpgFrontend::GpgUID::GpgUID(GpgUID &&o) noexcept { swap(uid_ref_, o.uid_ref_); }
+GpgUID::GpgUID(GpgUID &&o) noexcept { swap(uid_ref_, o.uid_ref_); }
-std::string GpgFrontend::GpgUID::GetName() const { return uid_ref_->name; }
+auto GpgUID::GetName() const -> QString { return uid_ref_->name; }
-std::string GpgFrontend::GpgUID::GetEmail() const { return uid_ref_->email; }
+auto GpgUID::GetEmail() const -> QString { return uid_ref_->email; }
-std::string GpgFrontend::GpgUID::GetComment() const {
- return uid_ref_->comment;
-}
+auto GpgUID::GetComment() const -> QString { return uid_ref_->comment; }
-std::string GpgFrontend::GpgUID::GetUID() const { return uid_ref_->uid; }
+auto GpgUID::GetUID() const -> QString { return uid_ref_->uid; }
-bool GpgFrontend::GpgUID::GetRevoked() const { return uid_ref_->revoked; }
+auto GpgUID::GetRevoked() const -> bool { return uid_ref_->revoked; }
-bool GpgFrontend::GpgUID::GetInvalid() const { return uid_ref_->invalid; }
+auto GpgUID::GetInvalid() const -> bool { return uid_ref_->invalid; }
-std::unique_ptr<std::vector<GpgFrontend::GpgTOFUInfo>>
-GpgFrontend::GpgUID::GetTofuInfos() const {
+auto GpgUID::GetTofuInfos() const -> std::unique_ptr<std::vector<GpgTOFUInfo>> {
auto infos = std::make_unique<std::vector<GpgTOFUInfo>>();
- auto info_next = uid_ref_->tofu;
+ auto *info_next = uid_ref_->tofu;
while (info_next != nullptr) {
infos->push_back(GpgTOFUInfo(info_next));
info_next = info_next->next;
@@ -60,13 +59,15 @@ GpgFrontend::GpgUID::GetTofuInfos() const {
return infos;
}
-std::unique_ptr<std::vector<GpgFrontend::GpgKeySignature>>
-GpgFrontend::GpgUID::GetSignatures() const {
+auto GpgUID::GetSignatures() const
+ -> std::unique_ptr<std::vector<GpgKeySignature>> {
auto sigs = std::make_unique<std::vector<GpgKeySignature>>();
- auto sig_next = uid_ref_->signatures;
+ auto *sig_next = uid_ref_->signatures;
while (sig_next != nullptr) {
sigs->push_back(GpgKeySignature(sig_next));
sig_next = sig_next->next;
}
return sigs;
}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgUID.h b/src/core/model/GpgUID.h
index 670c318d..14b4db3f 100644
--- a/src/core/model/GpgUID.h
+++ b/src/core/model/GpgUID.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,14 +20,13 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGUID_H
-#define GPGFRONTEND_GPGUID_H
+#pragma once
#include "GpgKeySignature.h"
#include "GpgTOFUInfo.h"
@@ -42,30 +41,30 @@ class GPGFRONTEND_CORE_EXPORT GpgUID {
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetName() const;
+ [[nodiscard]] auto GetName() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetEmail() const;
+ [[nodiscard]] auto GetEmail() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetComment() const;
+ [[nodiscard]] auto GetComment() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
- [[nodiscard]] std::string GetUID() const;
+ [[nodiscard]] auto GetUID() const -> QString;
/**
* @brief
@@ -73,7 +72,7 @@ class GPGFRONTEND_CORE_EXPORT GpgUID {
* @return true
* @return false
*/
- [[nodiscard]] bool GetRevoked() const;
+ [[nodiscard]] auto GetRevoked() const -> bool;
/**
* @brief
@@ -81,22 +80,23 @@ class GPGFRONTEND_CORE_EXPORT GpgUID {
* @return true
* @return false
*/
- [[nodiscard]] bool GetInvalid() const;
+ [[nodiscard]] auto GetInvalid() const -> bool;
/**
* @brief
*
* @return std::unique_ptr<std::vector<GpgTOFUInfo>>
*/
- [[nodiscard]] std::unique_ptr<std::vector<GpgTOFUInfo>> GetTofuInfos() const;
+ [[nodiscard]] auto GetTofuInfos() const
+ -> std::unique_ptr<std::vector<GpgTOFUInfo>>;
/**
* @brief
*
* @return std::unique_ptr<std::vector<GpgKeySignature>>
*/
- [[nodiscard]] std::unique_ptr<std::vector<GpgKeySignature>> GetSignatures()
- const;
+ [[nodiscard]] auto GetSignatures() const
+ -> std::unique_ptr<std::vector<GpgKeySignature>>;
/**
* @brief Construct a new Gpg U I D object
@@ -130,14 +130,14 @@ class GPGFRONTEND_CORE_EXPORT GpgUID {
* @param o
* @return GpgUID&
*/
- GpgUID &operator=(GpgUID &&o) noexcept;
+ auto operator=(GpgUID &&o) noexcept -> GpgUID &;
/**
* @brief
*
* @return GpgUID&
*/
- GpgUID &operator=(const GpgUID &) = delete;
+ auto operator=(const GpgUID &) -> GpgUID & = delete;
private:
using UidRefHandler =
@@ -148,5 +148,3 @@ class GPGFRONTEND_CORE_EXPORT GpgUID {
};
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_GPGUID_H \ No newline at end of file
diff --git a/src/core/model/GpgVerifyResult.cpp b/src/core/model/GpgVerifyResult.cpp
new file mode 100644
index 00000000..75421c69
--- /dev/null
+++ b/src/core/model/GpgVerifyResult.cpp
@@ -0,0 +1,62 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgVerifyResult.h"
+
+#include "core/model/GpgSignature.h"
+
+namespace GpgFrontend {
+GpgVerifyResult::GpgVerifyResult(gpgme_verify_result_t r)
+ : result_ref_(std::shared_ptr<struct _gpgme_op_verify_result>(
+ (gpgme_result_ref(r), r), [](gpgme_verify_result_t p) {
+ if (p != nullptr) {
+ gpgme_result_unref(p);
+ }
+ })) {}
+
+GpgVerifyResult::GpgVerifyResult() = default;
+
+GpgVerifyResult::~GpgVerifyResult() = default;
+
+auto GpgVerifyResult::IsGood() const -> bool { return result_ref_ != nullptr; }
+
+auto GpgVerifyResult::GetRaw() const -> gpgme_verify_result_t {
+ return result_ref_.get();
+}
+
+auto GpgVerifyResult::GetSignature() const -> std::vector<GpgSignature> {
+ std::vector<GpgSignature> sigatures;
+
+ auto* signature = result_ref_->signatures;
+ while (signature != nullptr) {
+ sigatures.emplace_back(signature);
+ signature = signature->next;
+ }
+ return sigatures;
+}
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgVerifyResult.h b/src/core/model/GpgVerifyResult.h
new file mode 100644
index 00000000..cae43c10
--- /dev/null
+++ b/src/core/model/GpgVerifyResult.h
@@ -0,0 +1,53 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/GpgFrontendCoreExport.h"
+#include "core/typedef/GpgTypedef.h"
+
+namespace GpgFrontend {
+
+class GPGFRONTEND_CORE_EXPORT GpgVerifyResult {
+ public:
+ [[nodiscard]] auto IsGood() const -> bool;
+
+ [[nodiscard]] auto GetRaw() const -> gpgme_verify_result_t;
+
+ [[nodiscard]] auto GetSignature() const -> std::vector<GpgSignature>;
+
+ explicit GpgVerifyResult(gpgme_verify_result_t);
+
+ GpgVerifyResult();
+
+ virtual ~GpgVerifyResult();
+
+ private:
+ std::shared_ptr<struct _gpgme_op_verify_result> result_ref_ = nullptr; ///<
+};
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/module/Event.cpp b/src/core/module/Event.cpp
new file mode 100644
index 00000000..fab26453
--- /dev/null
+++ b/src/core/module/Event.cpp
@@ -0,0 +1,139 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "Event.h"
+
+namespace GpgFrontend::Module {
+
+class Event::Impl {
+ public:
+ Impl(QString event_id, std::initializer_list<ParameterInitializer> params,
+ EventCallback callback)
+ : event_identifier_(std::move(event_id)),
+ callback_(std::move(callback)),
+ callback_thread_(QThread::currentThread()) {
+ for (const auto& param : params) {
+ AddParameter(param);
+ }
+ GF_CORE_LOG_DEBUG("create event {}", event_identifier_);
+ }
+
+ auto operator[](const QString& key) const -> std::optional<ParameterValue> {
+ auto it_data = data_.find(key);
+ if (it_data != data_.end()) {
+ return it_data->second;
+ }
+ return std::nullopt;
+ }
+
+ auto operator==(const Event& other) const -> bool {
+ return event_identifier_ == other.p_->event_identifier_;
+ }
+
+ auto operator!=(const Event& other) const -> bool {
+ return !(*this == other);
+ }
+
+ auto operator<(const Event& other) const -> bool {
+ return this->event_identifier_ < other.p_->event_identifier_;
+ }
+
+ explicit operator QString() const { return event_identifier_; }
+
+ auto GetIdentifier() -> EventIdentifier { return event_identifier_; }
+
+ void AddParameter(const QString& key, const ParameterValue& value) {
+ data_[key] = value;
+ }
+
+ void AddParameter(const ParameterInitializer& param) {
+ AddParameter(param.key, param.value);
+ }
+
+ void ExecuteCallback(ListenerIdentifier listener_id,
+ const DataObjectPtr& data_object) {
+ GF_CORE_LOG_DEBUG("try to execute callback for event {} with listener {}",
+ event_identifier_, listener_id);
+ if (callback_) {
+ GF_CORE_LOG_DEBUG("executing callback for event {} with listener {}",
+ event_identifier_, listener_id);
+ if (!QMetaObject::invokeMethod(
+ callback_thread_,
+ [callback = callback_, event_identifier = event_identifier_,
+ listener_id, data_object]() {
+ callback(event_identifier, listener_id, data_object);
+ })) {
+ GF_CORE_LOG_ERROR(
+ "failed to invoke callback for event {} with listener {}",
+ event_identifier_, listener_id);
+ }
+ }
+ }
+
+ private:
+ EventIdentifier event_identifier_;
+ std::map<QString, ParameterValue> data_;
+ EventCallback callback_;
+ QThread* callback_thread_ = nullptr; ///<
+};
+
+Event::Event(const QString& event_id,
+ std::initializer_list<ParameterInitializer> params,
+ EventCallback callback)
+ : p_(SecureCreateUniqueObject<Impl>(event_id, params,
+ std::move(callback))) {}
+
+Event::~Event() = default;
+
+auto Event::Event::operator==(const Event& other) const -> bool {
+ return this->p_ == other.p_;
+}
+
+auto Event::Event::operator!=(const Event& other) const -> bool {
+ return this->p_ != other.p_;
+}
+
+auto Event::Event::operator<(const Event& other) const -> bool {
+ return this->p_ < other.p_;
+}
+
+Event::Event::operator QString() const { return static_cast<QString>(*p_); }
+
+auto Event::Event::GetIdentifier() -> EventIdentifier {
+ return p_->GetIdentifier();
+}
+
+void Event::AddParameter(const QString& key, const ParameterValue& value) {
+ p_->AddParameter(key, value);
+}
+
+void Event::ExecuteCallback(ListenerIdentifier l_id, DataObjectPtr d_o) {
+ p_->ExecuteCallback(std::move(l_id), d_o);
+}
+
+} // namespace GpgFrontend::Module \ No newline at end of file
diff --git a/src/core/module/Event.h b/src/core/module/Event.h
new file mode 100644
index 00000000..92268216
--- /dev/null
+++ b/src/core/module/Event.h
@@ -0,0 +1,95 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include <any>
+#include <functional>
+#include <optional>
+
+#include "core/GpgFrontendCore.h"
+#include "core/model/DataObject.h"
+
+namespace GpgFrontend::Module {
+
+class Event;
+
+using EventRefrernce = std::shared_ptr<Event>;
+using EventIdentifier = QString;
+using Evnets = std::vector<Event>;
+
+class GPGFRONTEND_CORE_EXPORT Event {
+ public:
+ using ParameterValue = std::any;
+ using EventIdentifier = QString;
+ using ListenerIdentifier = QString;
+ using EventCallback =
+ std::function<void(EventIdentifier, ListenerIdentifier, DataObjectPtr)>;
+ struct ParameterInitializer {
+ QString key;
+ ParameterValue value;
+ };
+
+ explicit Event(const QString&,
+ std::initializer_list<ParameterInitializer> = {},
+ EventCallback = nullptr);
+
+ ~Event();
+
+ auto operator[](const QString& key) const -> std::optional<ParameterValue>;
+
+ auto operator==(const Event& other) const -> bool;
+
+ auto operator!=(const Event& other) const -> bool;
+
+ auto operator<(const Event& other) const -> bool;
+
+ auto operator<=(const Event& other) const -> bool;
+
+ explicit operator QString() const;
+
+ auto GetIdentifier() -> EventIdentifier;
+
+ void AddParameter(const QString& key, const ParameterValue& value);
+
+ void ExecuteCallback(ListenerIdentifier, DataObjectPtr);
+
+ private:
+ class Impl;
+ SecureUniquePtr<Impl> p_;
+};
+
+template <typename... Args>
+auto MakeEvent(const EventIdentifier& event_id, Args&&... args,
+ Event::EventCallback e_cb) -> EventRefrernce {
+ std::initializer_list<Event::ParameterInitializer> params = {
+ Event::ParameterInitializer{std::forward<Args>(args)}...};
+ return GpgFrontend::SecureCreateSharedObject<Event>(event_id, params, e_cb);
+}
+
+} // namespace GpgFrontend::Module \ No newline at end of file
diff --git a/src/core/module/GlobalModuleContext.cpp b/src/core/module/GlobalModuleContext.cpp
new file mode 100644
index 00000000..50f97334
--- /dev/null
+++ b/src/core/module/GlobalModuleContext.cpp
@@ -0,0 +1,377 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GlobalModuleContext.h"
+
+#include <set>
+#include <unordered_map>
+#include <unordered_set>
+
+#include "core/module/Event.h"
+#include "core/module/Module.h"
+#include "core/thread/Task.h"
+#include "model/DataObject.h"
+#include "thread/TaskRunnerGetter.h"
+#include "utils/MemoryUtils.h"
+
+namespace GpgFrontend::Module {
+
+class GlobalModuleContext::Impl {
+ public:
+ explicit Impl() {
+ // Initialize acquired channels with default values.
+ acquired_channel_.insert(kGpgFrontendDefaultChannel);
+ acquired_channel_.insert(kGpgFrontendNonAsciiChannel);
+ }
+
+ auto GetChannel(ModuleRawPtr module) -> int {
+ // Search for the module in the register table.
+ auto module_info_opt =
+ search_module_register_table(module->GetModuleIdentifier());
+ if (!module_info_opt.has_value()) {
+ GF_CORE_LOG_ERROR(
+ "cannot find module id {} at register table, fallbacking to "
+ "default "
+ "channel",
+ module->GetModuleIdentifier());
+ return GetDefaultChannel(module);
+ }
+
+ auto module_info = module_info_opt.value();
+ return module_info->channel;
+ }
+
+ static auto GetDefaultChannel(ModuleRawPtr) -> int {
+ return kGpgFrontendDefaultChannel;
+ }
+
+ auto GetTaskRunner(ModuleRawPtr /*module*/) -> std::optional<TaskRunnerPtr> {
+ return Thread::TaskRunnerGetter::GetInstance().GetTaskRunner(
+ Thread::TaskRunnerGetter::kTaskRunnerType_Module);
+ }
+
+ auto GetTaskRunner(ModuleIdentifier /*module_id*/)
+ -> std::optional<TaskRunnerPtr> {
+ return Thread::TaskRunnerGetter::GetInstance().GetTaskRunner(
+ Thread::TaskRunnerGetter::kTaskRunnerType_Module);
+ }
+
+ auto GetGlobalTaskRunner() -> std::optional<TaskRunnerPtr> {
+ return default_task_runner_;
+ }
+
+ auto RegisterModule(const ModulePtr& module) -> bool {
+ GF_CORE_LOG_DEBUG("attempting to register module: {}",
+ module->GetModuleIdentifier());
+ // Check if the module is null or already registered.
+ if (module == nullptr ||
+ module_register_table_.find(module->GetModuleIdentifier()) !=
+ module_register_table_.end()) {
+ GF_CORE_LOG_ERROR(
+ "module is null or have already registered this module");
+ return false;
+ }
+
+ if (!module->Register()) {
+ GF_CORE_LOG_ERROR("register module {} failed",
+ module->GetModuleIdentifier());
+ return false;
+ }
+
+ auto register_info =
+ GpgFrontend::SecureCreateSharedObject<ModuleRegisterInfo>();
+ register_info->module = module;
+ register_info->channel = acquire_new_unique_channel();
+
+ // move module to its task runner' thread
+ register_info->module->setParent(nullptr);
+ register_info->module->moveToThread(
+ Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Module)
+ ->GetThread());
+
+ // Register the module with its identifier.
+ module_register_table_[module->GetModuleIdentifier()] = register_info;
+
+ GF_CORE_LOG_DEBUG("successfully registered module: {}",
+ module->GetModuleIdentifier());
+ return true;
+ }
+
+ auto ActiveModule(ModuleIdentifier module_id) -> bool {
+ GF_CORE_LOG_DEBUG("attempting to activate module: {}", module_id);
+
+ // Search for the module in the register table.
+ auto module_info_opt = search_module_register_table(module_id);
+ if (!module_info_opt.has_value()) {
+ GF_CORE_LOG_ERROR("cannot find module id {} at register table",
+ module_id);
+ return false;
+ }
+
+ auto module_info = module_info_opt.value();
+
+ // try to get module from module info
+ auto module = module_info->module;
+ if (module == nullptr) {
+ GF_CORE_LOG_ERROR(
+ "module id {} at register table is releated to a null module",
+ module_id);
+ return false;
+ }
+
+ // Activate the module if it is not already active.
+ if (!module_info->activate) {
+ module->Active();
+ module_info->activate = true;
+ }
+
+ GF_CORE_LOG_DEBUG("module activation status: {}", module_info->activate);
+ return module_info->activate;
+ }
+
+ auto ListenEvent(ModuleIdentifier module_id, EventIdentifier event) -> bool {
+ GF_CORE_LOG_DEBUG("module: {} is attempting to listen to event {}",
+ module_id, event);
+ // Check if the event exists, if not, create it.
+ auto met_it = module_events_table_.find(event);
+ if (met_it == module_events_table_.end()) {
+ module_events_table_[event] = std::unordered_set<ModuleIdentifier>();
+ met_it = module_events_table_.find(event);
+ GF_CORE_LOG_INFO("new event {} of module system created", event);
+ }
+
+ auto& listeners_set = met_it->second;
+ // Add the listener (module) to the event.
+ auto listener_it = listeners_set.find(module_id);
+ if (listener_it == listeners_set.end()) {
+ listeners_set.insert(module_id);
+ }
+ return true;
+ }
+
+ auto DeactivateModule(ModuleIdentifier module_id) -> bool {
+ // Search for the module in the register table.
+ auto module_info_opt = search_module_register_table(module_id);
+ if (!module_info_opt.has_value()) {
+ GF_CORE_LOG_ERROR("cannot find module id {} at register table",
+ module_id);
+ return false;
+ }
+
+ auto module_info = module_info_opt.value();
+ // Activate the module if it is not already deactive.
+ if (!module_info->activate && module_info->module->Deactive()) {
+ module_info->activate = false;
+ }
+
+ return !module_info->activate;
+ }
+
+ auto TriggerEvent(const EventRefrernce& event) -> bool {
+ auto event_id = event->GetIdentifier();
+ GF_CORE_LOG_DEBUG("attempting to trigger event: {}", event_id);
+
+ // Find the set of listeners associated with the given event in the table
+ auto met_it = module_events_table_.find(event_id);
+ if (met_it == module_events_table_.end()) {
+ // Log a warning if the event is not registered and nobody is listening
+ GF_CORE_LOG_WARN(
+ "event {} is not listening by anyone and not registered as well",
+ event_id);
+ return false;
+ }
+
+ // Retrieve the set of listeners for this event
+ auto& listeners_set = met_it->second;
+
+ // Check if the set of listeners is empty
+ if (listeners_set.empty()) {
+ // Log a warning if nobody is listening to this event
+ GF_CORE_LOG_WARN("event {} is not listening by anyone",
+ event->GetIdentifier());
+ return false;
+ }
+
+ // Log the number of listeners for this event
+ GF_CORE_LOG_DEBUG("event {}'s current listeners size: {}",
+ event->GetIdentifier(), listeners_set.size());
+
+ // Iterate through each listener and execute the corresponding module
+ for (const auto& listener_module_id : listeners_set) {
+ // Search for the module's information in the registration table
+ auto module_info_opt = search_module_register_table(listener_module_id);
+
+ // Log an error if the module is not found in the registration table
+ if (!module_info_opt.has_value()) {
+ GF_CORE_LOG_ERROR("cannot find module id {} at register table",
+ listener_module_id);
+ continue;
+ }
+
+ // Retrieve the module's information
+ auto module_info = module_info_opt.value();
+ auto module = module_info->module;
+
+ GF_CORE_LOG_DEBUG(
+ "module {} is listening to event {}, activate state: {}",
+ module_info->module->GetModuleIdentifier(), event->GetIdentifier(),
+ module_info->activate);
+
+ // Check if the module is activated
+ if (!module_info->activate) continue;
+
+ Thread::Task::TaskRunnable const exec_runnerable =
+ [module, event](DataObjectPtr) -> int { return module->Exec(event); };
+
+ Thread::Task::TaskCallback const exec_callback =
+ [listener_module_id, event_id](int code, DataObjectPtr) {
+ if (code < 0) {
+ // Log an error if the module execution fails
+ GF_CORE_LOG_ERROR(
+ "module {} execution failed of event {}: exec return code {}",
+ listener_module_id, event_id, code);
+ }
+ };
+
+ Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Module)
+ ->PostTask(new Thread::Task(exec_runnerable,
+ QString("event/%1/module/exec/%2")
+ .arg(event_id)
+ .arg(listener_module_id),
+ nullptr, exec_callback));
+ }
+
+ // Return true to indicate successful execution of all modules
+ return true;
+ }
+
+ auto IsModuleActivated(const ModuleIdentifier& m_id) const -> bool {
+ auto m = search_module_register_table(m_id);
+ return m.has_value() && m->get()->activate;
+ }
+
+ private:
+ struct ModuleRegisterInfo {
+ int channel;
+ ModulePtr module;
+ bool activate;
+ };
+
+ using ModuleRegisterInfoPtr = std::shared_ptr<ModuleRegisterInfo>;
+
+ std::unordered_map<ModuleIdentifier, ModuleRegisterInfoPtr>
+ module_register_table_;
+ std::map<EventIdentifier, std::unordered_set<ModuleIdentifier>>
+ module_events_table_;
+
+ std::set<int> acquired_channel_;
+ TaskRunnerPtr default_task_runner_;
+
+ auto acquire_new_unique_channel() -> int {
+ int random_channel = QRandomGenerator::global()->bounded(65535);
+ // Ensure the acquired channel is unique.
+ while (acquired_channel_.find(random_channel) != acquired_channel_.end()) {
+ random_channel = QRandomGenerator::global()->bounded(65535);
+ }
+
+ // Add the acquired channel to the set.
+ acquired_channel_.insert(random_channel);
+ return random_channel;
+ }
+
+ // Function to search for a module in the register table.
+ auto search_module_register_table(const ModuleIdentifier& identifier) const
+ -> std::optional<ModuleRegisterInfoPtr> {
+ auto mrt_it = module_register_table_.find(identifier);
+ if (mrt_it == module_register_table_.end()) {
+ return std::nullopt;
+ }
+ return mrt_it->second;
+ }
+};
+
+// Constructor for GlobalModuleContext, takes a TaskRunnerPtr as an argument.
+GlobalModuleContext::GlobalModuleContext()
+ : p_(SecureCreateUniqueObject<Impl>()) {}
+
+GlobalModuleContext::~GlobalModuleContext() = default;
+
+// Function to get the task runner associated with a module.
+auto GlobalModuleContext::GetTaskRunner(ModuleRawPtr module)
+ -> std::optional<TaskRunnerPtr> {
+ return p_->GetTaskRunner(module);
+}
+
+// Function to get the task runner associated with a module.
+auto GlobalModuleContext::GetTaskRunner(ModuleIdentifier module_id)
+ -> std::optional<TaskRunnerPtr> {
+ return p_->GetTaskRunner(std::move(module_id));
+}
+
+// Function to get the global task runner.
+auto GlobalModuleContext::GetGlobalTaskRunner()
+ -> std::optional<TaskRunnerPtr> {
+ return p_->GetGlobalTaskRunner();
+}
+
+auto GlobalModuleContext::RegisterModule(ModulePtr module) -> bool {
+ return p_->RegisterModule(std::move(module));
+}
+
+auto GlobalModuleContext::ActiveModule(ModuleIdentifier module_id) -> bool {
+ return p_->ActiveModule(std::move(module_id));
+}
+
+auto GlobalModuleContext::ListenEvent(ModuleIdentifier module_id,
+ EventIdentifier event) -> bool {
+ return p_->ListenEvent(std::move(module_id), std::move(event));
+}
+
+auto GlobalModuleContext::DeactivateModule(ModuleIdentifier module_id) -> bool {
+ return p_->DeactivateModule(std::move(module_id));
+}
+
+auto GlobalModuleContext::TriggerEvent(EventRefrernce event) -> bool {
+ return p_->TriggerEvent(std::move(event));
+}
+
+auto GlobalModuleContext::GetChannel(ModuleRawPtr module) -> int {
+ return p_->GetChannel(module);
+}
+
+auto GlobalModuleContext::GetDefaultChannel(ModuleRawPtr channel) -> int {
+ return GlobalModuleContext::Impl::GetDefaultChannel(channel);
+}
+
+auto GlobalModuleContext::IsModuleActivated(ModuleIdentifier m_id) -> bool {
+ return p_->IsModuleActivated(std::move(m_id));
+}
+
+} // namespace GpgFrontend::Module
diff --git a/src/core/module/GlobalModuleContext.h b/src/core/module/GlobalModuleContext.h
new file mode 100644
index 00000000..1c971bb5
--- /dev/null
+++ b/src/core/module/GlobalModuleContext.h
@@ -0,0 +1,88 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include <optional>
+
+#include "core/module/Event.h"
+#include "core/thread/TaskRunner.h"
+#include "function/SecureMemoryAllocator.h"
+#include "module/GlobalRegisterTable.h"
+
+namespace GpgFrontend::Module {
+
+class GlobalModuleContext;
+class GlobalRegisterTable;
+
+class Module;
+class ModuleManager;
+using ModuleIdentifier = QString;
+using ModulePtr = std::shared_ptr<Module>;
+using ModuleRawPtr = Module*;
+
+using GMCPtr = std::shared_ptr<GlobalModuleContext>;
+using GRTPtr = std::shared_ptr<GlobalRegisterTable>;
+
+using TaskRunnerPtr = std::shared_ptr<Thread::TaskRunner>;
+
+class GPGFRONTEND_CORE_EXPORT GlobalModuleContext : public QObject {
+ Q_OBJECT
+ public:
+ explicit GlobalModuleContext();
+
+ ~GlobalModuleContext() override;
+
+ auto GetChannel(ModuleRawPtr) -> int;
+
+ static auto GetDefaultChannel(ModuleRawPtr) -> int;
+
+ auto GetTaskRunner(ModuleRawPtr) -> std::optional<TaskRunnerPtr>;
+
+ auto GetTaskRunner(ModuleIdentifier) -> std::optional<TaskRunnerPtr>;
+
+ auto GetGlobalTaskRunner() -> std::optional<TaskRunnerPtr>;
+
+ auto RegisterModule(ModulePtr) -> bool;
+
+ auto ActiveModule(ModuleIdentifier) -> bool;
+
+ auto DeactivateModule(ModuleIdentifier) -> bool;
+
+ auto ListenEvent(ModuleIdentifier, EventIdentifier) -> bool;
+
+ auto TriggerEvent(EventRefrernce) -> bool;
+
+ auto IsModuleActivated(ModuleIdentifier) -> bool;
+
+ private:
+ class Impl;
+ SecureUniquePtr<Impl> p_;
+};
+
+} // namespace GpgFrontend::Module \ No newline at end of file
diff --git a/src/core/module/GlobalRegisterTable.cpp b/src/core/module/GlobalRegisterTable.cpp
new file mode 100644
index 00000000..c16eba37
--- /dev/null
+++ b/src/core/module/GlobalRegisterTable.cpp
@@ -0,0 +1,167 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GlobalRegisterTable.h"
+
+#include <any>
+#include <optional>
+#include <shared_mutex>
+#include <sstream>
+#include <unordered_map>
+#include <vector>
+
+#include "function/SecureMemoryAllocator.h"
+#include "utils/MemoryUtils.h"
+
+namespace GpgFrontend::Module {
+
+class GlobalRegisterTable::Impl {
+ public:
+ struct RTNode {
+ std::optional<std::any> value = std::nullopt;
+ std::unordered_map<QString, SecureUniquePtr<RTNode>> children;
+ int version = 0;
+ const std::type_info* type = nullptr;
+ };
+
+ explicit Impl(GlobalRegisterTable* parent) : parent_(parent) {}
+
+ auto PublishKV(const Namespace& n, const Key& k, std::any v) -> bool {
+ QStringList const segments = k.split('.');
+ int version = 0;
+
+ {
+ std::unique_lock lock(lock_);
+ auto& root_rt_node =
+ global_register_table_.emplace(n, SecureCreateUniqueObject<RTNode>())
+ .first->second;
+
+ RTNode* current = root_rt_node.get();
+ for (const QString& segment : segments) {
+ current = current->children
+ .emplace(segment, SecureCreateUniqueObject<RTNode>())
+ .first->second.get();
+ }
+
+ current->value = v;
+ current->type = &v.type();
+ version = ++current->version;
+ }
+
+ emit parent_->SignalPublish(n, k, version, v);
+ return true;
+ }
+
+ auto LookupKV(const Namespace& n, const Key& k) -> std::optional<std::any> {
+ QStringList const segments = k.split('.');
+
+ std::optional<std::any> rtn = std::nullopt;
+ {
+ std::shared_lock const lock(lock_);
+ auto it = global_register_table_.find(n);
+ if (it == global_register_table_.end()) return std::nullopt;
+
+ RTNode* current = it->second.get();
+ for (const QString& segment : segments) {
+ auto it = current->children.find(segment);
+ if (it == current->children.end()) return std::nullopt;
+ current = it->second.get();
+ }
+ rtn = current->value;
+ }
+ return rtn;
+ }
+
+ auto ListChildKeys(const Namespace& n, const Key& k) -> std::vector<Key> {
+ QStringList const segments = k.split('.');
+
+ std::vector<Key> rtn;
+ {
+ std::shared_lock lock(lock_);
+ auto it = global_register_table_.find(n);
+ if (it == global_register_table_.end()) return {};
+
+ RTNode* current = it->second.get();
+ for (const QString& segment : segments) {
+ auto it = current->children.find(segment);
+ if (it == current->children.end()) return {};
+ current = it->second.get();
+ }
+
+ for (auto& it : current->children) {
+ rtn.emplace_back(it.first);
+ }
+ }
+ return rtn;
+ }
+
+ auto ListenPublish(QObject* o, const Namespace& n, const Key& k, LPCallback c)
+ -> bool {
+ if (o == nullptr) return false;
+ return QObject::connect(parent_, &GlobalRegisterTable::SignalPublish, o,
+ [n, k, c](const Namespace& pn, const Key& pk,
+ int ver, std::any value) {
+ if (pn == n && pk == k) {
+ c(pn, pk, ver, std::move(value));
+ }
+ }) == nullptr;
+ }
+
+ private:
+ using Table = std::map<Namespace, SecureUniquePtr<RTNode>>;
+ std::shared_mutex lock_;
+ GlobalRegisterTable* parent_;
+
+ Table global_register_table_;
+};
+
+GlobalRegisterTable::GlobalRegisterTable()
+ : p_(SecureCreateUniqueObject<Impl>(this)) {}
+
+GlobalRegisterTable::~GlobalRegisterTable() = default;
+
+auto GlobalRegisterTable::PublishKV(Namespace n, Key k, std::any v) -> bool {
+ return p_->PublishKV(n, k, v);
+}
+
+auto GlobalRegisterTable::LookupKV(Namespace n, Key v)
+ -> std::optional<std::any> {
+ return p_->LookupKV(n, v);
+}
+
+auto GlobalRegisterTable::ListenPublish(QObject* o, Namespace n, Key k,
+ LPCallback c) -> bool {
+ return p_->ListenPublish(o, n, k, c);
+}
+
+auto GlobalRegisterTable::ListChildKeys(Namespace n, Key k)
+ -> std::vector<Key> {
+ return p_->ListChildKeys(n, k);
+}
+
+} // namespace GpgFrontend::Module \ No newline at end of file
diff --git a/src/core/module/GlobalRegisterTable.h b/src/core/module/GlobalRegisterTable.h
new file mode 100644
index 00000000..db68c888
--- /dev/null
+++ b/src/core/module/GlobalRegisterTable.h
@@ -0,0 +1,66 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include <any>
+#include <functional>
+#include <optional>
+
+#include "function/SecureMemoryAllocator.h"
+
+namespace GpgFrontend::Module {
+
+using Namespace = QString;
+using Key = QString;
+using LPCallback = std::function<void(Namespace, Key, int, std::any)>;
+
+class GlobalRegisterTable : public QObject {
+ Q_OBJECT
+ public:
+ GlobalRegisterTable();
+
+ ~GlobalRegisterTable() override;
+
+ auto PublishKV(Namespace, Key, std::any) -> bool;
+
+ auto LookupKV(Namespace, Key) -> std::optional<std::any>;
+
+ auto ListenPublish(QObject *, Namespace, Key, LPCallback) -> bool;
+
+ auto ListChildKeys(Namespace n, Key k) -> std::vector<Key>;
+
+ signals:
+ void SignalPublish(Namespace, Key, int, std::any);
+
+ private:
+ class Impl;
+ SecureUniquePtr<Impl> p_;
+};
+
+} // namespace GpgFrontend::Module \ No newline at end of file
diff --git a/src/core/module/GpgFrontendModuleSystem.h b/src/core/module/GpgFrontendModuleSystem.h
new file mode 100644
index 00000000..903aec69
--- /dev/null
+++ b/src/core/module/GpgFrontendModuleSystem.h
@@ -0,0 +1,34 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include <core/GpgFrontendCore.h>
+#include <core/module/Event.h>
+#include <core/module/Module.h>
+#include <core/module/ModuleManager.h> \ No newline at end of file
diff --git a/src/core/module/Module.cpp b/src/core/module/Module.cpp
new file mode 100644
index 00000000..cab72a9a
--- /dev/null
+++ b/src/core/module/Module.cpp
@@ -0,0 +1,106 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "Module.h"
+
+#include "core/module/GlobalModuleContext.h"
+
+namespace GpgFrontend::Module {
+
+class Module::Impl {
+ public:
+ friend class GlobalModuleContext;
+
+ using ExecCallback = std::function<void(int)>;
+
+ Impl(ModuleRawPtr m_ptr, ModuleIdentifier id, ModuleVersion version,
+ ModuleMetaData meta_data)
+ : m_ptr_(m_ptr),
+ identifier_(std::move(id)),
+ version_(std::move(version)),
+ meta_data_(std::move(meta_data)) {}
+
+ auto GetChannel() -> int { return get_gpc()->GetChannel(m_ptr_); }
+
+ auto GetDefaultChannel() -> int {
+ return get_gpc()->GetDefaultChannel(m_ptr_);
+ }
+
+ auto GetTaskRunner() -> std::optional<TaskRunnerPtr> {
+ return get_gpc()->GetTaskRunner(m_ptr_);
+ }
+
+ auto ListenEvent(EventIdentifier event) -> bool {
+ return get_gpc()->ListenEvent(GetModuleIdentifier(), std::move(event));
+ }
+
+ [[nodiscard]] auto GetModuleIdentifier() const -> ModuleIdentifier {
+ return identifier_;
+ }
+
+ void SetGPC(GlobalModuleContext* gpc) { gpc_ = gpc; }
+
+ private:
+ GlobalModuleContext* gpc_;
+ Module* m_ptr_;
+ const ModuleIdentifier identifier_;
+ const ModuleVersion version_;
+ const ModuleMetaData meta_data_;
+
+ auto get_gpc() -> GlobalModuleContext* {
+ if (gpc_ == nullptr) {
+ throw std::runtime_error("module is not registered by module manager");
+ }
+ return gpc_;
+ }
+};
+
+Module::Module(ModuleIdentifier id, ModuleVersion version,
+ ModuleMetaData meta_data)
+ : p_(SecureCreateUniqueObject<Impl>(this, id, version, meta_data)) {}
+
+Module::~Module() = default;
+
+auto Module::getChannel() -> int { return p_->GetChannel(); }
+
+auto Module::getDefaultChannel() -> int { return p_->GetDefaultChannel(); }
+
+auto Module::getTaskRunner() -> TaskRunnerPtr {
+ return p_->GetTaskRunner().value_or(nullptr);
+}
+
+auto Module::listenEvent(EventIdentifier event) -> bool {
+ return p_->ListenEvent(std::move(event));
+}
+
+auto Module::GetModuleIdentifier() const -> ModuleIdentifier {
+ return p_->GetModuleIdentifier();
+}
+
+void Module::SetGPC(GlobalModuleContext* gpc) { p_->SetGPC(gpc); }
+} // namespace GpgFrontend::Module \ No newline at end of file
diff --git a/src/core/module/Module.h b/src/core/module/Module.h
new file mode 100644
index 00000000..2742475e
--- /dev/null
+++ b/src/core/module/Module.h
@@ -0,0 +1,80 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/module/Event.h"
+#include "core/thread/TaskRunner.h"
+
+namespace GpgFrontend::Module {
+
+class Module;
+class GlobalModuleContext;
+class ModuleManager;
+
+using ModuleIdentifier = QString;
+using ModuleVersion = QString;
+using ModuleMetaData = std::map<QString, QString>;
+using ModulePtr = std::shared_ptr<Module>;
+
+using TaskRunnerPtr = std::shared_ptr<Thread::TaskRunner>;
+
+class GPGFRONTEND_CORE_EXPORT Module : public QObject {
+ Q_OBJECT
+ public:
+ Module(ModuleIdentifier, ModuleVersion, ModuleMetaData);
+
+ ~Module();
+
+ virtual auto Register() -> bool = 0;
+
+ virtual auto Active() -> bool = 0;
+
+ virtual auto Exec(EventRefrernce) -> int = 0;
+
+ virtual auto Deactive() -> bool = 0;
+
+ [[nodiscard]] auto GetModuleIdentifier() const -> ModuleIdentifier;
+
+ void SetGPC(GlobalModuleContext*);
+
+ protected:
+ auto getChannel() -> int;
+
+ auto getDefaultChannel() -> int;
+
+ auto getTaskRunner() -> TaskRunnerPtr;
+
+ auto listenEvent(EventIdentifier) -> bool;
+
+ private:
+ class Impl;
+ SecureUniquePtr<Impl> p_;
+};
+
+} // namespace GpgFrontend::Module \ No newline at end of file
diff --git a/src/core/module/ModuleManager.cpp b/src/core/module/ModuleManager.cpp
new file mode 100644
index 00000000..83e7c1ff
--- /dev/null
+++ b/src/core/module/ModuleManager.cpp
@@ -0,0 +1,184 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "ModuleManager.h"
+
+#include <memory>
+
+#include "GpgConstants.h"
+#include "core/module/GlobalModuleContext.h"
+#include "core/module/GlobalRegisterTable.h"
+#include "core/module/Module.h"
+#include "core/thread/Task.h"
+#include "function/SecureMemoryAllocator.h"
+#include "function/basic/GpgFunctionObject.h"
+#include "thread/TaskRunnerGetter.h"
+#include "utils/MemoryUtils.h"
+
+namespace GpgFrontend::Module {
+
+class ModuleManager::Impl {
+ public:
+ Impl()
+ : gmc_(GpgFrontend::SecureCreateUniqueObject<GlobalModuleContext>()),
+ grt_(GpgFrontend::SecureCreateUniqueObject<GlobalRegisterTable>()) {}
+
+ ~Impl() = default;
+
+ void RegisterModule(const ModulePtr& module) {
+ Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default)
+ ->PostTask(new Thread::Task(
+ [=](GpgFrontend::DataObjectPtr) -> int {
+ module->SetGPC(gmc_.get());
+ gmc_->RegisterModule(module);
+ return 0;
+ },
+ __func__, nullptr));
+ }
+
+ void TriggerEvent(const EventRefrernce& event) {
+ Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default)
+ ->PostTask(new Thread::Task(
+ [=](const GpgFrontend::DataObjectPtr&) -> int {
+ gmc_->TriggerEvent(event);
+ return 0;
+ },
+ __func__, nullptr));
+ }
+
+ void ActiveModule(const ModuleIdentifier& identifier) {
+ Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default)
+ ->PostTask(new Thread::Task(
+ [=](const GpgFrontend::DataObjectPtr&) -> int {
+ gmc_->ActiveModule(identifier);
+ return 0;
+ },
+ __func__, nullptr));
+ }
+
+ auto GetTaskRunner(ModuleIdentifier module_id)
+ -> std::optional<TaskRunnerPtr> {
+ return gmc_->GetTaskRunner(std::move(module_id));
+ }
+
+ auto UpsertRTValue(Namespace n, Key k, std::any v) -> bool {
+ return grt_->PublishKV(n, k, v);
+ }
+
+ auto RetrieveRTValue(Namespace n, Key k) -> std::optional<std::any> {
+ return grt_->LookupKV(n, k);
+ }
+
+ auto ListenPublish(QObject* o, Namespace n, Key k, LPCallback c) -> bool {
+ return grt_->ListenPublish(o, n, k, c);
+ }
+
+ auto ListRTChildKeys(const QString& n, const QString& k) -> std::vector<Key> {
+ return grt_->ListChildKeys(n, k);
+ }
+
+ auto IsModuleActivated(ModuleIdentifier id) -> bool {
+ return gmc_->IsModuleActivated(id);
+ }
+
+ private:
+ static ModuleMangerPtr global_module_manager;
+ SecureUniquePtr<GlobalModuleContext> gmc_;
+ SecureUniquePtr<GlobalRegisterTable> grt_;
+};
+
+auto IsModuleAcivate(ModuleIdentifier id) -> bool {
+ return ModuleManager::GetInstance().IsModuleActivated(id);
+}
+
+auto UpsertRTValue(const QString& namespace_, const QString& key,
+ const std::any& value) -> bool {
+ return ModuleManager::GetInstance().UpsertRTValue(namespace_, key,
+ std::any(value));
+}
+
+auto ListenRTPublishEvent(QObject* o, Namespace n, Key k, LPCallback c)
+ -> bool {
+ return ModuleManager::GetInstance().ListenRTPublish(o, n, k, c);
+}
+
+auto ListRTChildKeys(const QString& namespace_, const QString& key)
+ -> std::vector<Key> {
+ return ModuleManager::GetInstance().ListRTChildKeys(namespace_, key);
+}
+
+ModuleManager::ModuleManager(int channel)
+ : SingletonFunctionObject<ModuleManager>(channel),
+ p_(SecureCreateUniqueObject<Impl>()) {}
+
+ModuleManager::~ModuleManager() = default;
+
+void ModuleManager::RegisterModule(ModulePtr module) {
+ return p_->RegisterModule(module);
+}
+
+void ModuleManager::TriggerEvent(EventRefrernce event) {
+ return p_->TriggerEvent(event);
+}
+
+void ModuleManager::ActiveModule(ModuleIdentifier id) {
+ return p_->ActiveModule(id);
+}
+
+auto ModuleManager::GetTaskRunner(ModuleIdentifier id)
+ -> std::optional<TaskRunnerPtr> {
+ return p_->GetTaskRunner(std::move(id));
+}
+
+auto ModuleManager::UpsertRTValue(Namespace n, Key k, std::any v) -> bool {
+ return p_->UpsertRTValue(n, k, v);
+}
+
+auto ModuleManager::RetrieveRTValue(Namespace n, Key k)
+ -> std::optional<std::any> {
+ return p_->RetrieveRTValue(n, k);
+}
+
+auto ModuleManager::ListenRTPublish(QObject* o, Namespace n, Key k,
+ LPCallback c) -> bool {
+ return p_->ListenPublish(o, n, k, c);
+}
+
+auto ModuleManager::ListRTChildKeys(const QString& n, const QString& k)
+ -> std::vector<Key> {
+ return p_->ListRTChildKeys(n, k);
+}
+
+auto ModuleManager::IsModuleActivated(ModuleIdentifier id) -> bool {
+ return p_->IsModuleActivated(id);
+}
+
+} // namespace GpgFrontend::Module \ No newline at end of file
diff --git a/src/core/module/ModuleManager.h b/src/core/module/ModuleManager.h
new file mode 100644
index 00000000..93b89e95
--- /dev/null
+++ b/src/core/module/ModuleManager.h
@@ -0,0 +1,179 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include <mutex>
+#include <vector>
+
+#include "core/function/SecureMemoryAllocator.h"
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/module/Event.h"
+#include "core/utils/MemoryUtils.h"
+
+namespace GpgFrontend::Thread {
+class TaskRunner;
+}
+
+namespace GpgFrontend::Module {
+
+using TaskRunnerPtr = std::shared_ptr<Thread::TaskRunner>;
+
+class Event;
+class Module;
+class GlobalModuleContext;
+class ModuleManager;
+
+using EventRefrernce = std::shared_ptr<Event>;
+using ModuleIdentifier = QString;
+using ModulePtr = std::shared_ptr<Module>;
+using ModuleMangerPtr = std::shared_ptr<ModuleManager>;
+using GMCPtr = std::shared_ptr<GlobalModuleContext>;
+using Namespace = QString;
+using Key = QString;
+using LPCallback = std::function<void(Namespace, Key, int, std::any)>;
+
+class GPGFRONTEND_CORE_EXPORT ModuleManager
+ : public SingletonFunctionObject<ModuleManager> {
+ public:
+ explicit ModuleManager(int channel);
+
+ virtual ~ModuleManager() override;
+
+ void RegisterModule(ModulePtr);
+
+ auto IsModuleActivated(ModuleIdentifier) -> bool;
+
+ void TriggerEvent(EventRefrernce);
+
+ void ActiveModule(ModuleIdentifier);
+
+ void DeactiveModule(ModuleIdentifier);
+
+ auto GetTaskRunner(ModuleIdentifier) -> std::optional<TaskRunnerPtr>;
+
+ auto UpsertRTValue(Namespace, Key, std::any) -> bool;
+
+ auto RetrieveRTValue(Namespace, Key) -> std::optional<std::any>;
+
+ auto ListenRTPublish(QObject*, Namespace, Key, LPCallback) -> bool;
+
+ auto ListRTChildKeys(const QString&, const QString&) -> std::vector<Key>;
+
+ private:
+ class Impl;
+ SecureUniquePtr<Impl> p_;
+};
+
+template <typename T, typename... Args>
+void RegisterModule(Args&&... args) {
+ ModuleManager::GetInstance().RegisterModule(
+ GpgFrontend::SecureCreateSharedObject<T>(std::forward<Args>(args)...));
+}
+
+template <typename T, typename... Args>
+void RegisterAndActivateModule(Args&&... args) {
+ auto& manager = ModuleManager::GetInstance();
+ auto module =
+ GpgFrontend::SecureCreateSharedObject<T>(std::forward<Args>(args)...);
+ manager.RegisterModule(module);
+ manager.ActiveModule(module->GetModuleIdentifier());
+}
+
+template <typename... Args>
+void TriggerEvent(const EventIdentifier& event_id, Args&&... args,
+ Event::EventCallback e_cb = nullptr) {
+ ModuleManager::GetInstance().TriggerEvent(
+ std::move(MakeEvent(event_id, std::forward<Args>(args)..., e_cb)));
+}
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+auto GPGFRONTEND_CORE_EXPORT IsModuleAcivate(ModuleIdentifier) -> bool;
+
+/**
+ * @brief
+ *
+ * @param namespace_
+ * @param key
+ * @param value
+ * @return true
+ * @return false
+ */
+auto GPGFRONTEND_CORE_EXPORT UpsertRTValue(const QString& namespace_,
+ const QString& key,
+ const std::any& value) -> bool;
+
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+auto GPGFRONTEND_CORE_EXPORT ListenRTPublishEvent(QObject*, Namespace, Key,
+ LPCallback) -> bool;
+
+/**
+ * @brief
+ *
+ * @param namespace_
+ * @param key
+ * @return std::vector<Key>
+ */
+auto GPGFRONTEND_CORE_EXPORT ListRTChildKeys(const QString& namespace_,
+ const QString& key)
+ -> std::vector<Key>;
+
+template <typename T>
+auto RetrieveRTValueTyped(const QString& namespace_, const QString& key)
+ -> std::optional<T> {
+ auto any_value =
+ ModuleManager::GetInstance().RetrieveRTValue(namespace_, key);
+ if (any_value && any_value->type() == typeid(T)) {
+ return std::any_cast<T>(*any_value);
+ }
+ return std::nullopt;
+}
+
+template <typename T>
+auto RetrieveRTValueTypedOrDefault(const QString& namespace_,
+ const QString& key, const T& defaultValue)
+ -> T {
+ auto any_value =
+ ModuleManager::GetInstance().RetrieveRTValue(namespace_, key);
+ if (any_value && any_value->type() == typeid(T)) {
+ return std::any_cast<T>(*any_value);
+ }
+ return defaultValue;
+}
+
+} // namespace GpgFrontend::Module \ No newline at end of file
diff --git a/src/core/thread/CtxCheckTask.cpp b/src/core/thread/CtxCheckTask.cpp
deleted file mode 100644
index 9735fcaa..00000000
--- a/src/core/thread/CtxCheckTask.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
- *
- */
-
-#include "core/thread/CtxCheckTask.h"
-
-#include "core/GpgContext.h"
-#include "core/GpgCoreInit.h"
-#include "core/common/CoreCommonUtil.h"
-#include "core/function/gpg/GpgKeyGetter.h"
-#include "thread/Task.h"
-
-GpgFrontend::Thread::CtxCheckTask::CtxCheckTask() : Task("ctx_check_task") {
- connect(this, &CtxCheckTask::SignalGnupgNotInstall,
- CoreCommonUtil::GetInstance(),
- &CoreCommonUtil::SignalGnupgNotInstall);
-}
-
-void GpgFrontend::Thread::CtxCheckTask::Run() {
- // Init GpgFrontend Core
- init_gpgfrontend_core();
-
- // Create & Check Gnupg Context Status
- if (!GpgContext::GetInstance().good()) {
- emit SignalGnupgNotInstall();
- }
- // Try flushing key cache
- else
- GpgFrontend::GpgKeyGetter::GetInstance().FlushKeyCache();
-
- SPDLOG_DEBUG("ctx check task runnable done");
-}
diff --git a/src/core/thread/CtxCheckTask.h b/src/core/thread/CtxCheckTask.h
deleted file mode 100644
index 06ddfd82..00000000
--- a/src/core/thread/CtxCheckTask.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
- *
- */
-
-#ifndef GPGFRONTEND_CTXCHECKTRHEAD_H
-#define GPGFRONTEND_CTXCHECKTRHEAD_H
-
-#include "core/GpgFrontendCore.h"
-#include "core/thread/Task.h"
-
-namespace GpgFrontend::Thread {
-/**
- * @brief
- *
- */
-class GPGFRONTEND_CORE_EXPORT CtxCheckTask : public Task {
- Q_OBJECT
- public:
- /**
- * @brief Construct a new Ctx Check Thread object
- *
- */
- CtxCheckTask();
-
- signals:
- /**
- * @brief
- *
- */
- void SignalGnupgNotInstall();
-
- protected:
- /**
- * @brief
- *
- */
- void Run() override;
-};
-} // namespace GpgFrontend::Thread
-
-#endif // GPGFRONTEND_CTXCHECKTRHEAD_H
diff --git a/src/core/thread/FileReadTask.cpp b/src/core/thread/FileReadTask.cpp
index 73954d28..c757d4c0 100644
--- a/src/core/thread/FileReadTask.cpp
+++ b/src/core/thread/FileReadTask.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,8 +19,10 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
@@ -28,58 +30,51 @@
namespace GpgFrontend::UI {
-FileReadTask::FileReadTask(std::string path) : Task("file_read_task") {
- connect(this, &FileReadTask::SignalFileBytesReadNext, this,
- &FileReadTask::read_bytes);
+constexpr size_t kBufferSize = 8192;
-#ifdef WINDOWS
- std::filesystem::path read_file_path(
- QString::fromStdString(path).toStdU16String());
-#else
- std::filesystem::path read_file_path(
- QString::fromStdString(path).toStdString());
-#endif
- read_file_path_ = read_file_path;
+FileReadTask::FileReadTask(QString path)
+ : Task("file_read_task"), read_file_path_(std::move(path)) {
+ HoldOnLifeCycle(true);
+ connect(this, &FileReadTask::SignalFileBytesReadNext, this,
+ &FileReadTask::slot_read_bytes);
}
-void FileReadTask::Run() {
- SetFinishAfterRun(false);
-
- if (is_regular_file(read_file_path_)) {
- SPDLOG_DEBUG("read open file: {}", read_file_path_.u8string());
+auto FileReadTask::Run() -> int {
+ if (QFileInfo(read_file_path_).isFile()) {
+ GF_CORE_LOG_DEBUG("read open file: {}", read_file_path_);
- target_file_.setFileName(
- QString::fromStdString(read_file_path_.u8string()));
+ target_file_.setFileName(read_file_path_);
target_file_.open(QIODevice::ReadOnly);
if (!(target_file_.isOpen() && target_file_.isReadable())) {
- SPDLOG_ERROR("file not open or not readable");
+ GF_CORE_LOG_ERROR("file not open or not readable");
if (target_file_.isOpen()) target_file_.close();
- return;
+ return -1;
}
- SPDLOG_DEBUG("started reading: {}", read_file_path_.u8string());
- read_bytes();
+ GF_CORE_LOG_DEBUG("started reading: {}", read_file_path_);
+ slot_read_bytes();
} else {
emit SignalFileBytesReadEnd();
}
+ return 0;
}
-void FileReadTask::read_bytes() {
+void FileReadTask::slot_read_bytes() {
QByteArray read_buffer;
if (!target_file_.atEnd() &&
- (read_buffer = target_file_.read(buffer_size_)).size() > 0) {
- SPDLOG_DEBUG("read bytes: {}", read_buffer.size());
+ (read_buffer = target_file_.read(kBufferSize)).size() > 0) {
+ GF_CORE_LOG_DEBUG("io thread read bytes: {}", read_buffer.size());
emit SignalFileBytesRead(std::move(read_buffer));
} else {
- SPDLOG_DEBUG("read bytes end");
+ GF_CORE_LOG_DEBUG("io thread read bytes end");
emit SignalFileBytesReadEnd();
// announce finish task
- emit SignalTaskRunnableEnd(0);
+ emit SignalTaskShouldEnd(0);
}
}
FileReadTask::~FileReadTask() {
- SPDLOG_DEBUG("close file: {}", read_file_path_.u8string());
+ GF_CORE_LOG_DEBUG("close file: {}", read_file_path_);
if (target_file_.isOpen()) target_file_.close();
}
diff --git a/src/core/thread/FileReadTask.h b/src/core/thread/FileReadTask.h
index d4e61cbe..22be33ef 100644
--- a/src/core/thread/FileReadTask.h
+++ b/src/core/thread/FileReadTask.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,13 +19,14 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_FILEREADTHREAD_H
-#define GPGFRONTEND_FILEREADTHREAD_H
+#pragma once
#include "core/GpgFrontendCore.h"
#include "core/thread/Task.h"
@@ -39,11 +40,11 @@ namespace GpgFrontend::UI {
class GPGFRONTEND_CORE_EXPORT FileReadTask : public GpgFrontend::Thread::Task {
Q_OBJECT
public:
- explicit FileReadTask(std::string path);
+ explicit FileReadTask(QString path);
virtual ~FileReadTask() override;
- void Run() override;
+ int Run() override;
signals:
void SignalFileBytesRead(QByteArray bytes);
@@ -51,15 +52,12 @@ class GPGFRONTEND_CORE_EXPORT FileReadTask : public GpgFrontend::Thread::Task {
void SignalFileBytesReadNext();
private:
- std::filesystem::path read_file_path_;
+ QString read_file_path_;
QFile target_file_;
- const size_t buffer_size_ = 4096;
QEventLoop looper;
private slots:
- void read_bytes();
+ void slot_read_bytes();
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_FILEREADTHREAD_H
diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp
index 7173b69e..1d251520 100644
--- a/src/core/thread/Task.cpp
+++ b/src/core/thread/Task.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,209 +19,237 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "core/thread/Task.h"
-#include <boost/uuid/uuid.hpp>
-#include <boost/uuid/uuid_generators.hpp>
-#include <boost/uuid/uuid_io.hpp>
-#include <functional>
-#include <string>
-#include <utility>
+#include <qscopedpointer.h>
-#include "core/thread/TaskRunner.h"
+#include "utils/MemoryUtils.h"
-const std::string GpgFrontend::Thread::Task::DEFAULT_TASK_NAME = "default-task";
+namespace GpgFrontend::Thread {
-GpgFrontend::Thread::Task::Task(std::string name)
- : uuid_(generate_uuid()), name_(name) {
- SPDLOG_TRACE("task {}/ created", GetFullID());
- init();
-}
+class Task::Impl {
+ public:
+ Impl(Task *parent, QString name)
+ : parent_(parent), uuid_(generate_uuid()), name_(std::move(name)) {
+ GF_CORE_LOG_TRACE("task {} created", GetFullID());
+ init();
+ }
-GpgFrontend::Thread::Task::Task(TaskRunnable runnable, std::string name,
- DataObjectPtr data_object, bool sequency)
- : uuid_(generate_uuid()),
- name_(name),
- runnable_(std::move(runnable)),
- callback_(std::move([](int, const std::shared_ptr<DataObject> &) {})),
- callback_thread_(QThread::currentThread()),
- data_object_(data_object),
- sequency_(sequency) {
- SPDLOG_TRACE("task {} created with runnable, callback_thread_: {}",
- GetFullID(), static_cast<void *>(callback_thread_));
- init();
-}
+ Impl(Task *parent, TaskRunnable runnable, QString name,
+ DataObjectPtr data_object)
+ : parent_(parent),
+ uuid_(generate_uuid()),
+ name_(std::move(name)),
+ runnable_(std::move(runnable)),
+ callback_([](int, const DataObjectPtr &) {}),
+ callback_thread_(QThread::currentThread()),
+ data_object_(std::move(data_object)) {
+ GF_CORE_LOG_TRACE("task {} created with runnable, callback_thread_: {}",
+ GetFullID(), static_cast<void *>(callback_thread_));
+ init();
+ }
-GpgFrontend::Thread::Task::Task(TaskRunnable runnable, std::string name,
- DataObjectPtr data_object,
- TaskCallback callback, bool sequency)
- : uuid_(generate_uuid()),
- name_(name),
- runnable_(std::move(runnable)),
- callback_(std::move(callback)),
- callback_thread_(QThread::currentThread()),
- data_object_(data_object),
- sequency_(sequency) {
- init();
- SPDLOG_TRACE(
- "task {} created with runnable and callback, callback_thread_: {}",
- GetFullID(), static_cast<void *>(callback_thread_));
-}
+ Impl(Task *parent, TaskRunnable runnable, QString name,
+ DataObjectPtr data_object, TaskCallback callback)
+ : parent_(parent),
+ uuid_(generate_uuid()),
+ name_(std::move(name)),
+ runnable_(std::move(runnable)),
+ callback_(std::move(callback)),
+ callback_thread_(QThread::currentThread()),
+ data_object_(std::move(data_object)) {
+ GF_CORE_LOG_TRACE(
+ "task {} created with runnable and callback, callback_thread_: {}",
+ GetFullID(), static_cast<void *>(callback_thread_));
+ init();
+ }
-GpgFrontend::Thread::Task::~Task() {
- SPDLOG_TRACE("task {} destroyed", GetFullID());
-}
+ ~Impl() { GF_CORE_LOG_TRACE("task {} destroyed", GetFullID()); }
+
+ /**
+ * @brief
+ *
+ * @return QString
+ */
+ [[nodiscard]] auto GetFullID() const -> QString {
+ return uuid_ + "/" + name_;
+ }
+
+ /**
+ * @brief
+ *
+ * @return QString
+ */
+ [[nodiscard]] auto GetUUID() const -> QString { return uuid_; }
+
+ /**
+ * @brief
+ *
+ * @return int
+ */
+ auto Run() -> int {
+ GF_CORE_LOG_TRACE("task {} is in classical runnable and callback mode",
+ GetFullID());
+
+ if (runnable_) return runnable_(data_object_);
+
+ GF_CORE_LOG_WARN("no runnable in task, do callback operation, task: {}",
+ GetFullID());
+ return 0;
+ }
+
+ /**
+ * @brief Set the Finish After Run object
+ *
+ * @param finish_after_run
+ */
+ void HoldOnLifeCycle(bool hold_on) { parent_->setAutoDelete(!hold_on); }
+
+ /**
+ * @brief
+ *
+ * @param rtn
+ */
+ void SetRTN(int rtn) { this->rtn_ = rtn; }
+
+ /**
+ * @brief
+ *
+ * @return auto
+ */
+ [[nodiscard]] auto GetRTN() const { return this->rtn_; }
+
+ private:
+ Task *const parent_;
+ const QString uuid_;
+ const QString name_;
+ TaskRunnable runnable_; ///<
+ TaskCallback callback_; ///<
+ int rtn_ = -99; ///<
+ QThread *callback_thread_ = nullptr; ///<
+ DataObjectPtr data_object_ = nullptr; ///<
+
+ void init() {
+ GF_CORE_LOG_TRACE("task {} created, parent: {}, impl: {}", name_,
+ (void *)parent_, (void *)this);
+
+ //
+ HoldOnLifeCycle(false);
+
+ //
+ connect(parent_, &Task::SignalRun, parent_, &Task::slot_exception_safe_run);
+
+ auto *callback_thread = callback_thread_ != nullptr
+ ? callback_thread_
+ : QCoreApplication::instance()->thread();
+ //
+ connect(parent_, &Task::SignalTaskShouldEnd, callback_thread,
+ [this](int rtn) {
+ // set task returning code
+ SetRTN(rtn);
+ try {
+ if (callback_) {
+ GF_CORE_LOG_TRACE(
+ "task callback {} is starting with runnerable rtn: {}",
+ GetFullID(), rtn);
+
+ callback_(rtn_, data_object_);
+ GF_CORE_LOG_TRACE("task callback {} finished, rtn: {}",
+ GetFullID(), rtn);
+ }
+ } catch (...) {
+ GF_CORE_LOG_ERROR("task {} callback caught exception, rtn: {}",
+ GetFullID(), rtn);
+ }
+ emit parent_->SignalTaskEnd();
+ });
+
+ //
+ connect(parent_, &Task::SignalTaskEnd, parent_, &Task::deleteLater);
+ }
+
+ /**
+ * @brief
+ *
+ * @return QString
+ */
+ static auto generate_uuid() -> QString {
+ return QUuid::createUuid().toString();
+ }
+};
+
+Task::Task(QString name) : p_(new Impl(this, name)) {}
+
+Task::Task(TaskRunnable runnable, QString name, DataObjectPtr data_object)
+ : p_(SecureCreateUniqueObject<Impl>(this, runnable, name, data_object)) {}
+
+Task::Task(TaskRunnable runnable, QString name, DataObjectPtr data_object,
+ TaskCallback callback)
+ : p_(SecureCreateUniqueObject<Impl>(this, runnable, name, data_object,
+ callback)) {}
+
+Task::~Task() = default;
/**
* @brief
*
- * @return std::string
+ * @return QString
*/
-std::string GpgFrontend::Thread::Task::GetFullID() const {
- return uuid_ + "/" + name_;
-}
-
-std::string GpgFrontend::Thread::Task::GetUUID() const { return uuid_; }
+QString Task::GetFullID() const { return p_->GetFullID(); }
-bool GpgFrontend::Thread::Task::GetSequency() const { return sequency_; }
+QString Task::GetUUID() const { return p_->GetUUID(); }
-void GpgFrontend::Thread::Task::SetFinishAfterRun(
- bool run_callback_after_runnable_finished) {
- this->run_callback_after_runnable_finished_ =
- run_callback_after_runnable_finished;
-}
+void Task::HoldOnLifeCycle(bool hold_on) { p_->HoldOnLifeCycle(hold_on); }
-void GpgFrontend::Thread::Task::SetRTN(int rtn) { this->rtn_ = rtn; }
-
-void GpgFrontend::Thread::Task::init() {
- // after runnable finished, running callback
- connect(this, &Task::SignalTaskRunnableEnd, this,
- &Task::slot_task_run_callback);
-}
+void Task::setRTN(int rtn) { p_->SetRTN(rtn); }
-void GpgFrontend::Thread::Task::slot_task_run_callback(int rtn) {
- SPDLOG_TRACE("task runnable {} finished, rtn: {}", GetFullID(), rtn);
- // set return value
- this->SetRTN(rtn);
+void Task::SafelyRun() { emit SignalRun(); }
- try {
- if (callback_) {
- if (callback_thread_ == QThread::currentThread()) {
- SPDLOG_DEBUG("callback thread is the same thread");
- if (!QMetaObject::invokeMethod(callback_thread_,
- [callback = callback_, rtn = rtn_,
- data_object = data_object_, this]() {
- callback(rtn, data_object);
- // do cleaning work
- emit SignalTaskEnd();
- })) {
- SPDLOG_ERROR("failed to invoke callback");
- }
- // just finished, let callack thread to raise SignalTaskEnd
- return;
- } else {
- // waiting for callback to finish
- if (!QMetaObject::invokeMethod(
- callback_thread_,
- [callback = callback_, rtn = rtn_,
- data_object = data_object_]() { callback(rtn, data_object); },
- Qt::BlockingQueuedConnection)) {
- SPDLOG_ERROR("failed to invoke callback");
- }
- }
- }
- } catch (std::exception &e) {
- SPDLOG_ERROR("exception caught: {}", e.what());
- } catch (...) {
- SPDLOG_ERROR("unknown exception caught");
- }
+int Task::Run() { return p_->Run(); }
- // raise signal, announcing this task come to an end
- SPDLOG_DEBUG("task {}, starting calling signal SignalTaskEnd", GetFullID());
- emit SignalTaskEnd();
+void Task::run() {
+ GF_CORE_LOG_TRACE("interface run() of task {} was called by thread: {}",
+ GetFullID(), QThread::currentThread()->currentThreadId());
+ this->SafelyRun();
}
-void GpgFrontend::Thread::Task::run() {
- SPDLOG_TRACE("task {} starting", GetFullID());
+Task::TaskHandler::TaskHandler(Task *task) : task_(task) {}
- // build runnable package for running
- auto runnable_package = [=, id = GetFullID()]() {
- SPDLOG_DEBUG("task {} runnable start runing", id);
- // Run() will set rtn by itself
- Run();
- // raise signal to anounce after runnable returned
- if (run_callback_after_runnable_finished_) emit SignalTaskRunnableEnd(rtn_);
- };
-
- if (thread() != QThread::currentThread()) {
- SPDLOG_DEBUG("task running thread is not object living thread");
- // if running sequently
- if (sequency_) {
- // running in another thread, blocking until returned
- if (!QMetaObject::invokeMethod(thread(), runnable_package,
- Qt::BlockingQueuedConnection)) {
- SPDLOG_ERROR("qt invoke method failed");
- }
- } else {
- // running in another thread, non-blocking
- if (!QMetaObject::invokeMethod(thread(), runnable_package)) {
- SPDLOG_ERROR("qt invoke method failed");
- }
- }
- } else {
- if (!QMetaObject::invokeMethod(this, runnable_package)) {
- SPDLOG_ERROR("qt invoke method failed");
- }
- }
+void Task::TaskHandler::Start() {
+ if (task_ != nullptr) task_->SafelyRun();
}
-void GpgFrontend::Thread::Task::SlotRun() { run(); }
-
-void GpgFrontend::Thread::Task::Run() {
- if (runnable_) {
- SetRTN(runnable_(data_object_));
- } else {
- SPDLOG_WARN("no runnable in task, do callback operation");
- }
+void Task::TaskHandler::Cancel() {
+ if (task_ != nullptr) emit task_->SignalTaskEnd();
}
-GpgFrontend::Thread::Task::DataObject::Destructor *
-GpgFrontend::Thread::Task::DataObject::get_heap_ptr(size_t bytes_size) {
- Destructor *dstr_ptr = new Destructor();
- dstr_ptr->p_obj = malloc(bytes_size);
- return dstr_ptr;
+auto Task::TaskHandler::GetTask() -> Task * {
+ if (task_ != nullptr) return task_;
+ return nullptr;
}
-GpgFrontend::Thread::Task::DataObject::~DataObject() {
- if (!data_objects_.empty())
- SPDLOG_WARN("data_objects_ is not empty",
- "address:", static_cast<void *>(this));
- while (!data_objects_.empty()) {
- free_heap_ptr(data_objects_.top());
- data_objects_.pop();
- }
-}
+void Task::slot_exception_safe_run() noexcept {
+ auto rtn = p_->GetRTN();
+ try {
+ GF_CORE_LOG_TRACE("task runnable {} is starting...", GetFullID());
-size_t GpgFrontend::Thread::Task::DataObject::GetObjectSize() {
- return data_objects_.size();
-}
+ // Run() will set rtn by itself
+ rtn = this->Run();
-void GpgFrontend::Thread::Task::DataObject::free_heap_ptr(Destructor *ptr) {
- SPDLOG_TRACE("p_obj: {} data object: {}",
- static_cast<const void *>(ptr->p_obj),
- static_cast<void *>(this));
- if (ptr->destroy != nullptr) {
- ptr->destroy(ptr->p_obj);
+ GF_CORE_LOG_TRACE("task runnable {} finished, rtn: {}", GetFullID());
+ } catch (...) {
+ GF_CORE_LOG_ERROR("exception was caught at task: {}", GetFullID());
}
- free(const_cast<void *>(ptr->p_obj));
- delete ptr;
-}
-std::string GpgFrontend::Thread::Task::generate_uuid() {
- return boost::uuids::to_string(boost::uuids::random_generator()());
+ // raise signal to anounce after runnable returned
+ if (this->autoDelete()) emit this->SignalTaskShouldEnd(rtn);
}
+auto Task::GetRTN() { return p_->GetRTN(); }
+} // namespace GpgFrontend::Thread \ No newline at end of file
diff --git a/src/core/thread/Task.h b/src/core/thread/Task.h
index ce354697..97a14949 100644
--- a/src/core/thread/Task.h
+++ b/src/core/thread/Task.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,23 +20,17 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_TASK_H
-#define GPGFRONTEND_TASK_H
-
-#include <functional>
-#include <memory>
-#include <stack>
-#include <string>
-#include <type_traits>
-#include <utility>
+#pragma once
#include "core/GpgFrontendCore.h"
+#include "core/function/SecureMemoryAllocator.h"
+#include "core/model/DataObject.h"
namespace GpgFrontend::Thread {
@@ -45,253 +39,136 @@ class TaskRunner;
class GPGFRONTEND_CORE_EXPORT Task : public QObject, public QRunnable {
Q_OBJECT
public:
- class DataObject;
- using DataObjectPtr = std::shared_ptr<DataObject>; ///<
+ friend class TaskRunner;
+
using TaskRunnable = std::function<int(DataObjectPtr)>; ///<
using TaskCallback = std::function<void(int, DataObjectPtr)>; ///<
- static const std::string DEFAULT_TASK_NAME;
-
- friend class TaskRunner;
-
- /**
- * @brief DataObject to be passed to the callback function.
- *
- */
- class GPGFRONTEND_CORE_EXPORT DataObject {
+ class TaskHandler {
public:
- struct Destructor {
- const void *p_obj;
- void (*destroy)(const void *);
- };
-
- /**
- * @brief Get the Objects Size
- *
- * @return size_t
- */
- size_t GetObjectSize();
-
- /**
- * @brief
- *
- * @tparam T
- * @param ptr
- */
- template <typename T>
- void AppendObject(T &&obj) {
- SPDLOG_TRACE("append object: {}", static_cast<void *>(this));
- auto *obj_dstr = this->get_heap_ptr(sizeof(T));
- new ((void *)obj_dstr->p_obj) T(std::forward<T>(obj));
+ explicit TaskHandler(Task*);
- if (std::is_class_v<T>) {
- auto destructor = [](const void *x) {
- static_cast<const T *>(x)->~T();
- };
- obj_dstr->destroy = destructor;
- } else {
- obj_dstr->destroy = nullptr;
- }
+ void Start();
- data_objects_.push(obj_dstr);
- }
+ void Cancel();
- /**
- * @brief
- *
- * @tparam T
- * @param ptr
- */
- template <typename T>
- void AppendObject(T *obj) {
- SPDLOG_TRACE("called: {}", static_cast<void *>(this));
- auto *obj_dstr = this->get_heap_ptr(sizeof(T));
- auto *ptr_heap = new ((void *)obj_dstr->p_obj) T(std::move(*obj));
- if (std::is_class_v<T>) {
- SPDLOG_TRACE("is class");
- auto destructor = [](const void *x) {
- static_cast<const T *>(x)->~T();
- };
- obj_dstr->destroy = destructor;
- } else {
- obj_dstr->destroy = nullptr;
- }
- data_objects_.push(std::move(obj_dstr));
- }
-
- /**
- * @brief
- *
- * @tparam T
- * @return std::shared_ptr<T>
- */
- template <typename T>
- T PopObject() {
- SPDLOG_TRACE("pop object: {}", static_cast<void *>(this));
- if (data_objects_.empty()) throw std::runtime_error("No object to pop");
- auto *obj_dstr = data_objects_.top();
- auto *heap_ptr = (T *)obj_dstr->p_obj;
- auto obj = std::move(*(T *)(heap_ptr));
- this->free_heap_ptr(obj_dstr);
- data_objects_.pop();
- return obj;
- }
-
- /**
- * @brief Destroy the Data Object object
- *
- */
- ~DataObject();
+ auto GetTask() -> Task*;
private:
- std::stack<Destructor *> data_objects_; ///<
-
- /**
- * @brief Get the heap ptr object
- *
- * @param bytes_size
- * @return void*
- */
- Destructor *get_heap_ptr(size_t bytes_size);
-
- /**
- * @brief
- *
- * @param heap_ptr
- */
- void free_heap_ptr(Destructor *);
+ QPointer<Task> task_;
};
/**
* @brief Construct a new Task object
*
*/
- Task(std::string name = DEFAULT_TASK_NAME);
+ explicit Task(QString name);
/**
* @brief Construct a new Task object
*
* @param callback The callback function to be executed.
*/
- explicit Task(TaskRunnable runnable, std::string name = DEFAULT_TASK_NAME,
- DataObjectPtr data_object = nullptr, bool sequency = true);
+ explicit Task(TaskRunnable runnable, QString name,
+ DataObjectPtr data_object = nullptr);
/**
* @brief Construct a new Task object
*
* @param runnable
*/
- explicit Task(
- TaskRunnable runnable, std::string name, DataObjectPtr data,
- TaskCallback callback = [](int, const std::shared_ptr<DataObject> &) {},
- bool sequency = true);
+ explicit Task(TaskRunnable runnable, QString name, DataObjectPtr data,
+ TaskCallback callback);
/**
* @brief Destroy the Task object
*
*/
- virtual ~Task() override;
+ ~Task() override;
/**
- * @brief Run - run the task
+ * @brief
*
+ * @return QString
*/
- virtual void Run();
+ [[nodiscard]] auto GetUUID() const -> QString;
/**
- * @brief
+ * @brief Get the Full I D object
*
- * @return std::string
+ * @return QString
*/
- std::string GetUUID() const;
+ [[nodiscard]] auto GetFullID() const -> QString;
/**
* @brief
*
- * @return std::string
+ * @param hold_on
*/
- std::string GetFullID() const;
+ void HoldOnLifeCycle(bool hold_on);
/**
- * @brief
+ * @brief can be overwrite by subclass
*
- * @return std::string
+ * @return int
*/
- bool GetSequency() const;
-
- public slots:
+ virtual auto Run() -> int;
/**
* @brief
*
+ * @return auto
*/
- void SlotRun();
+ [[nodiscard]] auto GetRTN();
- signals:
- /**
- * @brief announce runnable finished
- *
- */
- void SignalTaskRunnableEnd(int rtn);
+ public slots:
/**
- * @brief runnable and callabck all finished
+ * @brief shouldn't be overwrite by subclass
*
*/
- void SignalTaskEnd();
+ void SafelyRun();
- protected:
- /**
- * @brief Set the Finish After Run object
- *
- * @param finish_after_run
- */
- void SetFinishAfterRun(bool finish_after_run);
+ signals:
/**
* @brief
*
- * @param rtn
*/
- void SetRTN(int rtn);
-
- private:
- const std::string uuid_;
- const std::string name_;
- const bool sequency_ = true; ///< must run in the same thread
- TaskCallback callback_; ///<
- TaskRunnable runnable_; ///<
- bool run_callback_after_runnable_finished_ = true; ///<
- int rtn_ = 0; ///<
- QThread *callback_thread_ = nullptr; ///<
- DataObjectPtr data_object_ = nullptr; ///<
+ void SignalRun();
/**
* @brief
*
*/
- void init();
+ void SignalTaskShouldEnd(int);
/**
* @brief
*
*/
- virtual void run() override;
+ void SignalTaskEnd();
+ protected:
/**
* @brief
*
- * @return std::string
+ * @param rtn
*/
- static std::string generate_uuid();
+ void setRTN(int rtn);
private slots:
+
/**
* @brief
*
*/
- void slot_task_run_callback(int rtn);
+ void slot_exception_safe_run() noexcept;
+
+ private:
+ class Impl;
+ SecureUniquePtr<Impl> p_;
+
+ void run() override;
};
} // namespace GpgFrontend::Thread
-
-#endif // GPGFRONTEND_TASK_H \ No newline at end of file
diff --git a/src/core/thread/TaskRunner.cpp b/src/core/thread/TaskRunner.cpp
index 461d5fb5..8e381384 100644
--- a/src/core/thread/TaskRunner.cpp
+++ b/src/core/thread/TaskRunner.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,128 +19,132 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "core/thread/TaskRunner.h"
#include "core/thread/Task.h"
-#include "spdlog/spdlog.h"
-GpgFrontend::Thread::TaskRunner::TaskRunner() = default;
+namespace GpgFrontend::Thread {
+
+class TaskRunner::Impl : public QThread {
+ public:
+ Impl() : QThread(nullptr) {}
-GpgFrontend::Thread::TaskRunner::~TaskRunner() = default;
+ void PostTask(Task* task) {
+ if (task == nullptr) {
+ GF_CORE_LOG_ERROR("task posted is null");
+ return;
+ }
-void GpgFrontend::Thread::TaskRunner::PostTask(Task* task) {
- if (task == nullptr) {
- SPDLOG_ERROR("task posted is null");
- return;
+ task->setParent(nullptr);
+ task->moveToThread(this);
+
+ GF_CORE_LOG_TRACE("runner starts task: {} at thread: {}", task->GetFullID(),
+ this->currentThreadId());
+ task->SafelyRun();
}
- SPDLOG_TRACE("post task: {}", task->GetFullID());
+ auto RegisterTask(const QString& name, const Task::TaskRunnable& runnerable,
+ const Task::TaskCallback& cb, DataObjectPtr params)
+ -> Task::TaskHandler {
+ auto* raw_task = new Task(runnerable, name, std::move(params), cb);
+ raw_task->setParent(nullptr);
+ raw_task->moveToThread(this);
+
+ connect(raw_task, &Task::SignalRun, this, [this, raw_task]() {
+ pending_tasks_[raw_task->GetFullID()] = raw_task;
+ });
- task->setParent(nullptr);
- task->moveToThread(this);
+ connect(raw_task, &Task::SignalTaskEnd, this, [this, raw_task]() {
+ pending_tasks_.remove(raw_task->GetFullID());
+ });
- {
- std::lock_guard<std::mutex> lock(tasks_mutex_);
- tasks.push(task);
+ GF_CORE_LOG_TRACE("runner starts task: {} at thread: {}",
+ raw_task->GetFullID(), this->currentThreadId());
+
+ return Task::TaskHandler(raw_task);
}
- quit();
-}
-void GpgFrontend::Thread::TaskRunner::PostScheduleTask(Task* task,
- size_t seconds) {
- if (task == nullptr) return;
- // TODO
-}
+ void PostTask(const QString& name, const Task::TaskRunnable& runnerable,
+ const Task::TaskCallback& cb, DataObjectPtr params) {
+ PostTask(new Task(runnerable, name, std::move(params), cb));
+ }
-[[noreturn]] void GpgFrontend::Thread::TaskRunner::run() {
- SPDLOG_TRACE("task runner runing, thread id: {}", QThread::currentThreadId());
- while (true) {
- if (tasks.empty()) {
- SPDLOG_TRACE("no tasks to run, trapping into event loop...");
- exec();
- } else {
- SPDLOG_TRACE("start to run task(s), queue size: {}", tasks.size());
-
- Task* task = nullptr;
- {
- std::lock_guard<std::mutex> lock(tasks_mutex_);
- task = std::move(tasks.front());
- tasks.pop();
- pending_tasks_.insert({task->GetUUID(), task});
- }
-
- if (task != nullptr) {
- try {
- // triger
- SPDLOG_TRACE("running task {}, sequency: {}", task->GetFullID(),
- task->GetSequency());
-
- // when a signal SignalTaskEnd raise, do unregister work
- connect(task, &Task::SignalTaskEnd, this, [this, task]() {
- unregister_finished_task(task->GetUUID());
- });
-
- if (!task->GetSequency()) {
- // if it need to run concurrently, we should create a new thread to
- // run it.
- auto* concurrent_thread = new QThread(nullptr);
- task->setParent(nullptr);
- task->moveToThread(concurrent_thread);
- // start thread
- concurrent_thread->start();
-
- connect(task, &Task::SignalTaskEnd, concurrent_thread,
- &QThread::quit);
- // concurrent thread is responsible for deleting the task
- connect(concurrent_thread, &QThread::finished, task,
- &Task::deleteLater);
- }
-
- // run the task
- task->run();
- } catch (const std::exception& e) {
- SPDLOG_ERROR("task runner: exception in task {}, exception: {}",
- task->GetFullID(), e.what());
- // if any exception caught, destroy the task, remove the task from the
- // pending tasks
- unregister_finished_task(task->GetUUID());
- } catch (...) {
- SPDLOG_ERROR("task runner: unknown exception in task: {}",
- task->GetFullID());
- // if any exception caught, destroy the task, remove the task from the
- // pending tasks
- unregister_finished_task(task->GetUUID());
- }
- }
+ void PostConcurrentTask(Task* task) {
+ if (task == nullptr) {
+ GF_CORE_LOG_ERROR("task posted is null");
+ return;
}
+
+ auto* concurrent_thread = new QThread(this);
+
+ task->setParent(nullptr);
+ task->moveToThread(concurrent_thread);
+
+ connect(task, &Task::SignalTaskEnd, concurrent_thread, &QThread::quit);
+ connect(concurrent_thread, &QThread::finished, concurrent_thread,
+ &QThread::deleteLater);
+
+ concurrent_thread->start();
+
+ GF_CORE_LOG_TRACE("runner starts task concurrenctly: {}",
+ task->GetFullID());
+ task->SafelyRun();
}
-}
-/**
- * @brief
- *
- */
-void GpgFrontend::Thread::TaskRunner::unregister_finished_task(
- std::string task_uuid) {
- SPDLOG_DEBUG("cleaning task {}", task_uuid);
- // search in map
- auto pending_task = pending_tasks_.find(task_uuid);
- if (pending_task == pending_tasks_.end()) {
- SPDLOG_ERROR("cannot find task in pending list: {}", task_uuid);
- return;
- } else {
- std::lock_guard<std::mutex> lock(tasks_mutex_);
- // if thread runs sequenctly, that means the thread is living in this
- // thread, so we can delete it. Or, its living thread need to delete it.
- if (pending_task->second->GetSequency())
- pending_task->second->deleteLater();
- pending_tasks_.erase(pending_task);
+ void PostScheduleTask(Task* task, size_t seconds) {
+ if (task == nullptr) return;
+ // TODO
}
- SPDLOG_DEBUG("clean task {} done", task_uuid);
+ private:
+ QMap<QString, Task*> pending_tasks_;
+};
+
+TaskRunner::TaskRunner() : p_(SecureCreateUniqueObject<Impl>()) {}
+
+TaskRunner::~TaskRunner() {
+ if (p_->isRunning()) {
+ Stop();
+ }
+}
+
+void TaskRunner::PostTask(Task* task) { p_->PostTask(task); }
+
+void TaskRunner::PostTask(const QString& name, const Task::TaskRunnable& runner,
+ const Task::TaskCallback& cb, DataObjectPtr params) {
+ p_->PostTask(name, runner, cb, std::move(params));
+}
+
+void TaskRunner::PostConcurrentTask(Task* task) {
+ p_->PostConcurrentTask(task);
+}
+
+void TaskRunner::PostScheduleTask(Task* task, size_t seconds) {
+ p_->PostScheduleTask(task, seconds);
+}
+
+void TaskRunner::Start() { p_->start(); }
+
+void TaskRunner::Stop() {
+ p_->quit();
+ p_->wait();
+}
+
+auto TaskRunner::GetThread() -> QThread* { return p_.get(); }
+
+auto TaskRunner::IsRunning() -> bool { return p_->isRunning(); }
+
+auto TaskRunner::RegisterTask(const QString& name,
+ const Task::TaskRunnable& runnable,
+ const Task::TaskCallback& cb, DataObjectPtr p_pbj)
+ -> Task::TaskHandler {
+ return p_->RegisterTask(name, runnable, cb, p_pbj);
}
+} // namespace GpgFrontend::Thread
diff --git a/src/core/thread/TaskRunner.h b/src/core/thread/TaskRunner.h
index 35cd1a30..8a93ad0b 100644
--- a/src/core/thread/TaskRunner.h
+++ b/src/core/thread/TaskRunner.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,25 +19,22 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_TASKRUNNER_H
-#define GPGFRONTEND_TASKRUNNER_H
-
-#include <cstddef>
-#include <mutex>
-#include <queue>
+#pragma once
#include "core/GpgFrontendCore.h"
+#include "core/function/SecureMemoryAllocator.h"
+#include "core/thread/Task.h"
namespace GpgFrontend::Thread {
-class Task;
-
-class GPGFRONTEND_CORE_EXPORT TaskRunner : public QThread {
+class GPGFRONTEND_CORE_EXPORT TaskRunner : public QObject {
Q_OBJECT
public:
/**
@@ -50,13 +47,34 @@ class GPGFRONTEND_CORE_EXPORT TaskRunner : public QThread {
* @brief Destroy the Task Runner object
*
*/
- virtual ~TaskRunner() override;
+ ~TaskRunner() override;
+
+ /**
+ * @brief
+ *
+ */
+ void Start();
/**
* @brief
*
*/
- [[noreturn]] void run() override;
+ void Stop();
+
+ /**
+ * @brief Get the Thread object
+ *
+ * @return QThread*
+ */
+ auto GetThread() -> QThread*;
+
+ /**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+ auto IsRunning() -> bool;
public slots:
@@ -70,23 +88,38 @@ class GPGFRONTEND_CORE_EXPORT TaskRunner : public QThread {
/**
* @brief
*
- * @param task
- * @param seconds
+ * @param runner
+ * @param cb
*/
- void PostScheduleTask(Task* task, size_t seconds);
+ void PostTask(const QString&, const Task::TaskRunnable&,
+ const Task::TaskCallback&, DataObjectPtr);
- private:
- std::queue<Task*> tasks; ///< The task queue
- std::map<std::string, Task*> pending_tasks_; ///< The pending tasks
- std::mutex tasks_mutex_; ///< The task queue mutex
- QThreadPool thread_pool_{this}; ///< run non-sequency task
+ /**
+ * @brief
+ *
+ * @return std::tuple<QPointer<Task>, TaskTrigger>
+ */
+ auto RegisterTask(const QString&, const Task::TaskRunnable&,
+ const Task::TaskCallback&, DataObjectPtr)
+ -> Task::TaskHandler;
+
+ /**
+ * @brief
+ *
+ * @param task
+ */
+ void PostConcurrentTask(Task* task);
/**
* @brief
*
+ * @param task
+ * @param seconds
*/
- void unregister_finished_task(std::string);
+ void PostScheduleTask(Task* task, size_t seconds);
+
+ private:
+ class Impl;
+ SecureUniquePtr<Impl> p_;
};
} // namespace GpgFrontend::Thread
-
-#endif // GPGFRONTEND_TASKRUNNER_H \ No newline at end of file
diff --git a/src/core/thread/TaskRunnerGetter.cpp b/src/core/thread/TaskRunnerGetter.cpp
index 186483ec..bdcd89d0 100644
--- a/src/core/thread/TaskRunnerGetter.cpp
+++ b/src/core/thread/TaskRunnerGetter.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,28 +19,46 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "core/thread/TaskRunnerGetter.h"
-GpgFrontend::Thread::TaskRunnerGetter::TaskRunnerGetter(int channel)
- : SingletonFunctionObject<TaskRunnerGetter>(channel) {}
+#include <mutex>
+
+#include "core/GpgConstants.h"
+#include "core/thread/TaskRunner.h"
+
+namespace GpgFrontend::Thread {
-GpgFrontend::Thread::TaskRunner*
-GpgFrontend::Thread::TaskRunnerGetter::GetTaskRunner(
- TaskRunnerType runner_type) {
+TaskRunnerGetter::TaskRunnerGetter(int)
+ : SingletonFunctionObject<TaskRunnerGetter>(kGpgFrontendDefaultChannel) {}
+
+auto TaskRunnerGetter::GetTaskRunner(TaskRunnerType runner_type)
+ -> TaskRunnerPtr {
+ std::lock_guard<std::mutex> lock_guard(task_runners_map_lock_);
while (true) {
auto it = task_runners_.find(runner_type);
if (it != task_runners_.end()) {
return it->second;
- } else {
- auto runner = new TaskRunner();
- task_runners_[runner_type] = runner;
- runner->start();
- continue;
+ }
+
+ auto runner = GpgFrontend::SecureCreateSharedObject<TaskRunner>();
+ task_runners_[runner_type] = runner;
+ runner->Start();
+ }
+}
+
+void TaskRunnerGetter::StopAllTeakRunner() {
+ for (const auto& [key, value] : task_runners_) {
+ if (value->IsRunning()) {
+ value->Stop();
}
}
}
+
+} // namespace GpgFrontend::Thread \ No newline at end of file
diff --git a/src/core/thread/TaskRunnerGetter.h b/src/core/thread/TaskRunnerGetter.h
index 80b25c3e..49ed25c0 100644
--- a/src/core/thread/TaskRunnerGetter.h
+++ b/src/core/thread/TaskRunnerGetter.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,20 +19,25 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_TASKRUNNERGETTER_H
-#define GPGFRONTEND_TASKRUNNERGETTER_H
+#pragma once
+
+#include <mutex>
#include "core/GpgFrontendCore.h"
-#include "core/GpgFunctionObject.h"
+#include "core/function/basic/GpgFunctionObject.h"
#include "core/thread/TaskRunner.h"
namespace GpgFrontend::Thread {
+using TaskRunnerPtr = std::shared_ptr<TaskRunner>;
+
class GPGFRONTEND_CORE_EXPORT TaskRunnerGetter
: public GpgFrontend::SingletonFunctionObject<TaskRunnerGetter> {
public:
@@ -41,18 +46,21 @@ class GPGFRONTEND_CORE_EXPORT TaskRunnerGetter
kTaskRunnerType_GPG,
kTaskRunnerType_IO,
kTaskRunnerType_Network,
+ kTaskRunnerType_Module,
kTaskRunnerType_External_Process,
};
- TaskRunnerGetter(int channel = SingletonFunctionObject::GetDefaultChannel());
+ explicit TaskRunnerGetter(
+ int channel = SingletonFunctionObject::GetDefaultChannel());
- TaskRunner *GetTaskRunner(
- TaskRunnerType runner_type = kTaskRunnerType_Default);
+ auto GetTaskRunner(TaskRunnerType runner_type = kTaskRunnerType_Default)
+ -> TaskRunnerPtr;
+
+ void StopAllTeakRunner();
private:
- std::map<TaskRunnerType, TaskRunner *> task_runners_;
+ std::map<TaskRunnerType, TaskRunnerPtr> task_runners_;
+ std::mutex task_runners_map_lock_;
};
} // namespace GpgFrontend::Thread
-
-#endif // GPGFRONTEND_TASKRUNNERGETTER_H \ No newline at end of file
diff --git a/src/core/thread/ThreadingModel.h b/src/core/thread/ThreadingModel.h
index eb6c9039..2fcc11c8 100644
--- a/src/core/thread/ThreadingModel.h
+++ b/src/core/thread/ThreadingModel.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,17 +20,14 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_THREADINGMODEL_H
-#define GPGFRONTEND_THREADINGMODEL_H
+#pragma once
#include "core/thread/Task.h"
#include "core/thread/TaskRunner.h"
#include "core/thread/TaskRunnerGetter.h"
-
-#endif // GPGFRONTEND_THREADINGMODEL_H \ No newline at end of file
diff --git a/src/core/typedef/CoreTypedef.h b/src/core/typedef/CoreTypedef.h
new file mode 100644
index 00000000..51c6d11a
--- /dev/null
+++ b/src/core/typedef/CoreTypedef.h
@@ -0,0 +1,49 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/model/DataObject.h"
+
+namespace GpgFrontend {
+
+using GFError = uint32_t;
+using ByteArray = QByteArray; ///<
+using ByteArrayPtr = std::shared_ptr<ByteArray>; ///<
+using StdBypeArrayPtr = std::shared_ptr<ByteArray>; ///<
+using BypeArrayRef = ByteArray&; ///<
+using ConstBypeArrayRef = const ByteArray&; ///<
+using BypeArrayConstRef = const ByteArray&; ///<
+using StringArgsPtr = std::unique_ptr<std::vector<QString>>; ///<
+using StringArgsRef = std::vector<QString>&; ///<
+ ///
+ ///
+
+using OperaRunnable = std::function<GFError(DataObjectPtr)>;
+using OperationCallback = std::function<void(GFError, DataObjectPtr)>;
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/typedef/GpgTypedef.h b/src/core/typedef/GpgTypedef.h
new file mode 100644
index 00000000..cf0887bf
--- /dev/null
+++ b/src/core/typedef/GpgTypedef.h
@@ -0,0 +1,76 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include <tuple>
+
+#include "core/model/DataObject.h"
+
+namespace GpgFrontend {
+
+class GpgKey; ///< forward declaration
+class GpgSubKey;
+class GpgSignature;
+class GpgTOFUInfo;
+
+using GpgError = gpgme_error_t; ///< gpgme error
+using GpgErrorCode = gpg_err_code_t;
+using GpgErrorDesc = std::pair<QString, QString>;
+
+using KeyId = QString; ///<
+using SubkeyId = QString; ///<
+using KeyIdArgsList = std::vector<KeyId>; ///<
+using KeyIdArgsListPtr = std::unique_ptr<KeyIdArgsList>; ///<
+using UIDArgsList = std::vector<QString>; ///<
+using UIDArgsListPtr = std::unique_ptr<UIDArgsList>; ///<
+using SignIdArgsList = std::vector<std::pair<QString, QString>>; ///<
+using SignIdArgsListPtr = std::unique_ptr<SignIdArgsList>; ///<
+using KeyFprArgsListPtr = std::unique_ptr<std::vector<QString>>; ///<
+using KeyArgsList = std::vector<GpgKey>; ///<
+using KeyListPtr = std::shared_ptr<KeyArgsList>; ///<
+using GpgKeyLinkList = std::list<GpgKey>; ///<
+using KeyLinkListPtr = std::unique_ptr<GpgKeyLinkList>; ///<
+using KeyPtr = std::unique_ptr<GpgKey>; ///<
+using KeyPtrArgsList = const std::initializer_list<KeyPtr>; ///<
+
+using GpgSignMode = gpgme_sig_mode_t;
+
+using GpgOperaRunnable = std::function<GpgError(DataObjectPtr)>;
+using GpgOperationCallback = std::function<void(GpgError, DataObjectPtr)>;
+using GpgOperationFuture = std::future<std::tuple<GpgError, DataObjectPtr>>;
+
+enum GpgOperation {
+ kENCRYPT,
+ kDECRYPT,
+ kSIGN,
+ kVERIFY,
+ kENCRYPT_SIGN,
+ kDECRYPT_VERIFY
+};
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/utils/AsyncUtils.cpp b/src/core/utils/AsyncUtils.cpp
new file mode 100644
index 00000000..6100b83d
--- /dev/null
+++ b/src/core/utils/AsyncUtils.cpp
@@ -0,0 +1,103 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "AsyncUtils.h"
+
+#include "core/module/ModuleManager.h"
+#include "core/thread/Task.h"
+#include "core/thread/TaskRunnerGetter.h"
+#include "core/utils/CommonUtils.h"
+#include "model/DataObject.h"
+
+namespace GpgFrontend {
+
+auto RunGpgOperaAsync(GpgOperaRunnable runnable, GpgOperationCallback callback,
+ const QString& operation, const QString& minial_version)
+ -> Thread::Task::TaskHandler {
+ const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gnupg_version", minial_version);
+ GF_CORE_LOG_DEBUG("got gnupg version from rt: {}", gnupg_version);
+
+ if (CompareSoftwareVersion(gnupg_version, "2.0.15") < 0) {
+ GF_CORE_LOG_ERROR("operator not support");
+ callback(GPG_ERR_NOT_SUPPORTED, TransferParams());
+ return Thread::Task::TaskHandler(nullptr);
+ }
+
+ auto handler =
+ Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_GPG)
+ ->RegisterTask(
+ operation,
+ [=](const DataObjectPtr& data_object) -> int {
+ auto custom_data_object = TransferParams();
+ auto err = runnable(custom_data_object);
+ data_object->Swap({err, custom_data_object});
+ return 0;
+ },
+ [=](int rtn, const DataObjectPtr& data_object) {
+ if (rtn < 0) {
+ callback(GPG_ERR_USER_1,
+ ExtractParams<DataObjectPtr>(data_object, 1));
+ } else {
+ callback(ExtractParams<GpgError>(data_object, 0),
+ ExtractParams<DataObjectPtr>(data_object, 1));
+ }
+ },
+ TransferParams());
+ handler.Start();
+ return handler;
+}
+
+auto RunIOOperaAsync(OperaRunnable runnable, OperationCallback callback,
+ const QString& operation) -> Thread::Task::TaskHandler {
+ auto handler =
+ Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_IO)
+ ->RegisterTask(
+ operation,
+ [=](const DataObjectPtr& data_object) -> int {
+ auto custom_data_object = TransferParams();
+ GpgError err = runnable(custom_data_object);
+
+ data_object->Swap({err, custom_data_object});
+ return 0;
+ },
+ [=](int rtn, const DataObjectPtr& data_object) {
+ if (rtn < 0) {
+ callback(-1, ExtractParams<DataObjectPtr>(data_object, 1));
+ } else {
+ callback(ExtractParams<GFError>(data_object, 0),
+ ExtractParams<DataObjectPtr>(data_object, 1));
+ }
+ },
+ TransferParams());
+ handler.Start();
+ return handler;
+}
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/utils/AsyncUtils.h b/src/core/utils/AsyncUtils.h
new file mode 100644
index 00000000..e587fad2
--- /dev/null
+++ b/src/core/utils/AsyncUtils.h
@@ -0,0 +1,63 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/GpgFrontendCore.h"
+#include "core/thread/Task.h"
+#include "core/typedef/CoreTypedef.h"
+#include "core/typedef/GpgTypedef.h"
+
+namespace GpgFrontend {
+
+/**
+ * @brief
+ *
+ * @param runnable
+ * @param callback
+ * @param operation
+ * @param minial_version
+ */
+auto GPGFRONTEND_CORE_EXPORT RunGpgOperaAsync(GpgOperaRunnable runnable,
+ GpgOperationCallback callback,
+ const QString& operation,
+ const QString& minial_version)
+ -> Thread::Task::TaskHandler;
+
+/**
+ * @brief
+ *
+ * @param runnable
+ * @param callback
+ * @param operation
+ */
+auto GPGFRONTEND_CORE_EXPORT RunIOOperaAsync(OperaRunnable runnable,
+ OperationCallback callback,
+ const QString& operation)
+ -> Thread::Task::TaskHandler;
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/utils/CacheUtils.cpp b/src/core/utils/CacheUtils.cpp
new file mode 100644
index 00000000..e521870c
--- /dev/null
+++ b/src/core/utils/CacheUtils.cpp
@@ -0,0 +1,47 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "CacheUtils.h"
+
+#include "core/function/CacheManager.h"
+
+namespace GpgFrontend {
+
+void SetCacheValue(const QString& key, QString value) {
+ CacheManager::GetInstance().SaveCache(key, std::move(value));
+}
+
+auto GetCacheValue(const QString& key) -> QString {
+ return CacheManager::GetInstance().LoadCache(key);
+}
+
+void ResetCacheValue(const QString& key) {
+ CacheManager::GetInstance().ResetCache(key);
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/utils/CacheUtils.h b/src/core/utils/CacheUtils.h
new file mode 100644
index 00000000..48b9ac4b
--- /dev/null
+++ b/src/core/utils/CacheUtils.h
@@ -0,0 +1,54 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+namespace GpgFrontend {
+
+/**
+ * @brief set a temp cache under a certain key
+ *
+ */
+void GPGFRONTEND_CORE_EXPORT SetCacheValue(const QString &key, QString value);
+
+/**
+ * @brief after get the temp cache, its value will be imediately ease in
+ * storage
+ *
+ * @return QString
+ */
+auto GPGFRONTEND_CORE_EXPORT GetCacheValue(const QString &key) -> QString;
+
+/**
+ * @brief imediately ease temp cache in storage
+ *
+ * @return QString
+ */
+void GPGFRONTEND_CORE_EXPORT ResetCacheValue(const QString &);
+
+} // namespace GpgFrontend
diff --git a/src/core/utils/CommonUtils.cpp b/src/core/utils/CommonUtils.cpp
new file mode 100644
index 00000000..0b182241
--- /dev/null
+++ b/src/core/utils/CommonUtils.cpp
@@ -0,0 +1,74 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "CommonUtils.h"
+
+namespace GpgFrontend {
+
+auto BeautifyFingerprint(QString fingerprint) -> QString {
+ auto len = fingerprint.size();
+ QString buffer;
+ QTextStream out(&buffer);
+ decltype(len) count = 0;
+ while (count < len) {
+ if ((count != 0U) && ((count % 5) == 0)) out << " ";
+ out << fingerprint[count];
+ count++;
+ }
+ return out.readAll();
+}
+
+auto CompareSoftwareVersion(const QString& a, const QString& b) -> int {
+ auto remove_prefix = [](const QString& version) {
+ return version.startsWith('v') ? version.mid(1) : version;
+ };
+
+ auto real_version_a = remove_prefix(a);
+ auto real_version_b = remove_prefix(b);
+
+ QStringList split_a = real_version_a.split('.');
+ QStringList split_b = real_version_b.split('.');
+
+ const auto min_depth = std::min(split_a.size(), split_b.size());
+
+ for (int i = 0; i < min_depth; ++i) {
+ int const num_a = split_a[i].toInt();
+ int const num_b = split_b[i].toInt();
+
+ if (num_a != num_b) {
+ return (num_a > num_b) ? 1 : -1;
+ }
+ }
+
+ if (split_a.size() != split_b.size()) {
+ return (split_a.size() > split_b.size()) ? 1 : -1;
+ }
+
+ return 0;
+}
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/utils/CommonUtils.h b/src/core/utils/CommonUtils.h
new file mode 100644
index 00000000..a45c6056
--- /dev/null
+++ b/src/core/utils/CommonUtils.h
@@ -0,0 +1,54 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/typedef/CoreTypedef.h"
+
+namespace GpgFrontend {
+
+/**
+ * @brief
+ *
+ * @param fingerprint
+ * @return QString
+ */
+auto GPGFRONTEND_CORE_EXPORT BeautifyFingerprint(QString fingerprint)
+ -> QString;
+
+/**
+ * @brief
+ *
+ * @param a
+ * @param b
+ * @return int
+ */
+auto GPGFRONTEND_CORE_EXPORT CompareSoftwareVersion(const QString& a,
+ const QString& b) -> int;
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/utils/FilesystemUtils.cpp b/src/core/utils/FilesystemUtils.cpp
new file mode 100644
index 00000000..9e531955
--- /dev/null
+++ b/src/core/utils/FilesystemUtils.cpp
@@ -0,0 +1,104 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "FilesystemUtils.h"
+
+namespace GpgFrontend {
+
+auto GetOnlyFileNameWithPath(const QString &path) -> QString {
+ // Create a path object from given string
+ QFileInfo file_info(path);
+ // Check if file name in the path object has extension
+ if (!file_info.fileName().isEmpty()) {
+ // Fetch the extension from path object and return
+ return file_info.path() + "/" + file_info.baseName();
+ }
+ // In case of no extension return empty string
+ return {};
+}
+
+auto GetFileExtension(const QString &path) -> QString {
+ return QFileInfo(path).suffix();
+}
+
+/**
+ * @brief
+ *
+ */
+auto GetFileSizeByPath(const QString &path, const QString &filename_pattern)
+ -> int64_t {
+ auto dir = QDir(path);
+ QFileInfoList const file_list =
+ dir.entryInfoList(QStringList() << filename_pattern, QDir::Files);
+ qint64 total_size = 0;
+
+ for (const QFileInfo &file_info : file_list) {
+ total_size += file_info.size();
+ }
+ return total_size;
+}
+
+/**
+ * @brief
+ *
+ */
+auto GetHumanFriendlyFileSize(int64_t size) -> QString {
+ auto num = static_cast<double>(size);
+ QStringList list;
+ list << "KB"
+ << "MB"
+ << "GB"
+ << "TB";
+
+ QStringListIterator i(list);
+ QString unit("bytes");
+
+ while (num >= 1024.0 && i.hasNext()) {
+ unit = i.next();
+ num /= 1024.0;
+ }
+ return (QString().setNum(num, 'f', 2) + " " + unit);
+}
+
+/**
+ * @brief
+ *
+ */
+void DeleteAllFilesByPattern(const QString &path,
+ const QString &filename_pattern) {
+ auto dir = QDir(path);
+
+ QStringList const log_files =
+ dir.entryList(QStringList() << filename_pattern, QDir::Files);
+
+ for (const auto &file : log_files) {
+ QFile::remove(dir.absoluteFilePath(file));
+ }
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/utils/FilesystemUtils.h b/src/core/utils/FilesystemUtils.h
new file mode 100644
index 00000000..0b58bbb7
--- /dev/null
+++ b/src/core/utils/FilesystemUtils.h
@@ -0,0 +1,78 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+namespace GpgFrontend {
+
+/**
+ * @brief Get the file extension object
+ *
+ * @param path
+ * @return QString
+ */
+auto GPGFRONTEND_CORE_EXPORT GetFileExtension(const QString& path) -> QString;
+
+/**
+ * @brief Get the only file name with path object
+ *
+ * @param path
+ * @return QString
+ */
+auto GPGFRONTEND_CORE_EXPORT GetOnlyFileNameWithPath(const QString& path)
+ -> QString;
+
+/**
+ * @brief Get the File Size By Path object
+ *
+ * @param path The path of the file
+ * @param filename_pattern The pattern of the file name, e.g. "*.txt"
+ * @return int64_t
+ */
+auto GPGFRONTEND_CORE_EXPORT GetFileSizeByPath(
+ const QString& path, const QString& filename_pattern)
+ -> int64_t;
+
+/**
+ * @brief Get the Human Readable File Size object
+ *
+ * @param size
+ * @return QString
+ */
+auto GPGFRONTEND_CORE_EXPORT GetHumanFriendlyFileSize(int64_t size) -> QString;
+
+/**
+ * @brief
+ *
+ * @param path
+ * @param filename_pattern
+ */
+void GPGFRONTEND_CORE_EXPORT DeleteAllFilesByPattern(
+ const QString& path, const QString& filename_pattern);
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/utils/GpgUtils.cpp b/src/core/utils/GpgUtils.cpp
new file mode 100644
index 00000000..75a412e7
--- /dev/null
+++ b/src/core/utils/GpgUtils.cpp
@@ -0,0 +1,172 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgUtils.h"
+
+namespace GpgFrontend {
+
+inline auto Trim(QString& s) -> QString { return s.trimmed(); }
+
+auto GetGpgmeErrorString(size_t buffer_size, gpgme_error_t err) -> QString {
+ std::vector<char> buffer(buffer_size);
+
+ gpgme_error_t const ret = gpgme_strerror_r(err, buffer.data(), buffer.size());
+ if (ret == ERANGE && buffer_size < 1024) {
+ return GetGpgmeErrorString(buffer_size * 2, err);
+ }
+
+ return {buffer.data()};
+}
+
+auto GetGpgmeErrorString(gpgme_error_t err) -> QString {
+ return GetGpgmeErrorString(64, err);
+}
+
+auto CheckGpgError(GpgError err) -> GpgError {
+ auto err_code = gpg_err_code(err);
+ if (err_code != GPG_ERR_NO_ERROR) {
+ GF_CORE_LOG_ERROR(
+ "gpg operation failed [error code: {}], source: {} description: {}",
+ err_code, gpgme_strsource(err), GetGpgmeErrorString(err));
+ }
+ return err_code;
+}
+
+auto CheckGpgError2ErrCode(GpgError err, GpgError predict) -> GpgErrorCode {
+ auto err_code = gpg_err_code(err);
+ if (err_code != gpg_err_code(predict)) {
+ if (err_code == GPG_ERR_NO_ERROR) {
+ GF_CORE_LOG_WARN("[Warning {}] Source: {} description: {} predict: {}",
+ gpg_err_code(err), gpgme_strsource(err),
+ GetGpgmeErrorString(err), GetGpgmeErrorString(predict));
+ } else {
+ GF_CORE_LOG_ERROR("[Error {}] Source: {} description: {} predict: {}",
+ gpg_err_code(err), gpgme_strsource(err),
+ GetGpgmeErrorString(err), GetGpgmeErrorString(predict));
+ }
+ }
+ return err_code;
+}
+
+auto DescribeGpgErrCode(GpgError err) -> GpgErrorDesc {
+ return {gpgme_strsource(err), GetGpgmeErrorString(err)};
+}
+
+auto CheckGpgError(GpgError err, const QString& /*comment*/) -> GpgError {
+ if (gpg_err_code(err) != GPG_ERR_NO_ERROR) {
+ GF_CORE_LOG_WARN("[Error {}] Source: {} description: {}", gpg_err_code(err),
+ gpgme_strsource(err), GetGpgmeErrorString(err));
+ }
+ return err;
+}
+
+auto TextIsSigned(QString text) -> int {
+ auto trim_text = Trim(text);
+ if (trim_text.startsWith(PGP_SIGNED_BEGIN) &&
+ trim_text.endsWith(PGP_SIGNED_END)) {
+ return 2;
+ }
+ if (text.contains(PGP_SIGNED_BEGIN) && text.contains(PGP_SIGNED_END)) {
+ return 1;
+ }
+ return 0;
+}
+
+auto SetExtensionOfOutputFile(const QString& path, GpgOperation opera,
+ bool ascii) -> QString {
+ QString new_extension;
+ QString current_extension = QFileInfo(path).suffix();
+
+ if (ascii) {
+ switch (opera) {
+ case kENCRYPT:
+ case kSIGN:
+ case kENCRYPT_SIGN:
+ new_extension = current_extension + ".asc";
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (opera) {
+ case kENCRYPT:
+ case kENCRYPT_SIGN:
+ new_extension = current_extension + ".gpg";
+ break;
+ case kSIGN:
+ new_extension = current_extension + ".sig";
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (!new_extension.isEmpty()) {
+ return QFileInfo(path).path() + "/" + QFileInfo(path).completeBaseName() +
+ "." + new_extension;
+ }
+
+ return path;
+}
+
+auto SetExtensionOfOutputFileForArchive(const QString& path, GpgOperation opera,
+ bool ascii) -> QString {
+ QString extension;
+
+ if (ascii) {
+ switch (opera) {
+ case kENCRYPT:
+ case kENCRYPT_SIGN:
+ extension = ".tar.asc";
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (opera) {
+ case kENCRYPT:
+ case kENCRYPT_SIGN:
+ extension = ".tar.gpg";
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (!extension.isEmpty()) {
+ auto last_dot_index = path.lastIndexOf('.');
+ if (last_dot_index != -1) {
+ return path.left(last_dot_index) + extension;
+ }
+ return path + extension;
+ }
+
+ return path; // 如果没有匹配的操作,则返回原始路径
+}
+
+} // namespace GpgFrontend
diff --git a/src/core/utils/GpgUtils.h b/src/core/utils/GpgUtils.h
new file mode 100644
index 00000000..e6a466dc
--- /dev/null
+++ b/src/core/utils/GpgUtils.h
@@ -0,0 +1,108 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/function/result_analyse/GpgResultAnalyse.h"
+#include "core/typedef/CoreTypedef.h"
+#include "core/typedef/GpgTypedef.h"
+
+namespace GpgFrontend {
+
+// Error Info Printer
+
+/**
+ * @brief
+ *
+ * @param err
+ * @return GpgError
+ */
+auto GPGFRONTEND_CORE_EXPORT CheckGpgError(GpgError err) -> GpgError;
+
+/**
+ * @brief
+ *
+ * @param gpgmeError
+ * @param comment
+ * @return GpgError
+ */
+auto GPGFRONTEND_CORE_EXPORT CheckGpgError(GpgError gpgmeError,
+ const QString& comment) -> GpgError;
+
+/**
+ * @brief
+ *
+ * @param err
+ * @param predict
+ * @return gpg_err_code_t
+ */
+auto GPGFRONTEND_CORE_EXPORT CheckGpgError2ErrCode(
+ gpgme_error_t err, gpgme_error_t predict = GPG_ERR_NO_ERROR)
+ -> gpg_err_code_t;
+
+/**
+ * @brief
+ *
+ * @param err
+ * @return GpgErrorDesc
+ */
+auto GPGFRONTEND_CORE_EXPORT DescribeGpgErrCode(GpgError err) -> GpgErrorDesc;
+
+// Check
+
+/**
+ * @brief
+ *
+ * @param text
+ * @return int
+ */
+auto GPGFRONTEND_CORE_EXPORT TextIsSigned(BypeArrayRef text) -> int;
+
+/**
+ * @brief
+ *
+ * @param opera
+ * @param ascii
+ * @return QString
+ */
+auto GPGFRONTEND_CORE_EXPORT SetExtensionOfOutputFile(const QString& path,
+ GpgOperation opera,
+ bool ascii) -> QString;
+
+/**
+ * @brief
+ *
+ * @param path
+ * @param opera
+ * @param ascii
+ * @return QString
+ */
+auto GPGFRONTEND_CORE_EXPORT SetExtensionOfOutputFileForArchive(
+ const QString& path, GpgOperation opera, bool ascii) -> QString;
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/utils/IOUtils.cpp b/src/core/utils/IOUtils.cpp
new file mode 100644
index 00000000..5ca765d9
--- /dev/null
+++ b/src/core/utils/IOUtils.cpp
@@ -0,0 +1,162 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "IOUtils.h"
+
+#include "core/GpgModel.h"
+
+namespace GpgFrontend {
+
+auto ReadFile(const QString& file_name, QByteArray& data) -> bool {
+ QFile file(file_name);
+ if (!file.open(QIODevice::ReadOnly)) {
+ GF_CORE_LOG_ERROR("failed to open file: {}", file_name);
+ return false;
+ }
+ data = file.readAll();
+ file.close();
+ return true;
+}
+
+auto WriteFile(const QString& file_name, const QByteArray& data) -> bool {
+ QFile file(file_name);
+ if (!file.open(QIODevice::WriteOnly)) {
+ GF_CORE_LOG_ERROR("failed to open file for writing: {}", file_name);
+ return false;
+ }
+ file.write(data);
+ file.close();
+ return true;
+}
+
+auto ReadFileGFBuffer(const QString& file_name) -> std::tuple<bool, GFBuffer> {
+ QByteArray byte_data;
+ const bool res = ReadFile(file_name, byte_data);
+
+ return {res, GFBuffer(byte_data)};
+}
+
+auto WriteFileGFBuffer(const QString& file_name, GFBuffer data) -> bool {
+ return WriteFile(file_name, data.ConvertToQByteArray());
+}
+
+auto CalculateHash(const QString& file_path) -> QString {
+ // Returns empty QByteArray() on failure.
+ QFileInfo const info(file_path);
+ QString buffer;
+ QTextStream ss(&buffer);
+
+ if (info.isFile() && info.isReadable()) {
+ ss << "[#] " << QObject::tr("File Hash Information") << Qt::endl;
+ ss << " " << QObject::tr("filename") << QObject::tr(": ")
+ << info.fileName() << Qt::endl;
+
+ QFile f(info.filePath());
+ if (f.open(QFile::ReadOnly)) {
+ // read all data
+ auto buffer = f.readAll();
+ ss << " " << QObject::tr("file size(bytes)") << QObject::tr(": ")
+ << buffer.size() << Qt::endl;
+
+ // md5
+ auto hash_md5 = QCryptographicHash(QCryptographicHash::Md5);
+ hash_md5.addData(buffer);
+ auto md5 = hash_md5.result().toHex();
+ GF_CORE_LOG_DEBUG("md5 {}", md5);
+ ss << " "
+ << "md5" << QObject::tr(": ") << md5 << Qt::endl;
+
+ // sha1
+ auto hash_sha1 = QCryptographicHash(QCryptographicHash::Sha1);
+ hash_sha1.addData(buffer);
+ auto sha1 = hash_sha1.result().toHex();
+ GF_CORE_LOG_DEBUG("sha1 {}", sha1);
+ ss << " "
+ << "sha1" << QObject::tr(": ") << sha1 << Qt::endl;
+
+ // sha1
+ auto hash_sha256 = QCryptographicHash(QCryptographicHash::Sha256);
+ hash_sha256.addData(buffer);
+ auto sha256 = hash_sha256.result().toHex();
+ GF_CORE_LOG_DEBUG("sha256 {}", sha256);
+ ss << " "
+ << "sha256" << QObject::tr(": ") << sha256 << Qt::endl;
+
+ ss << Qt::endl;
+ }
+ } else {
+ ss << "[#] " << QObject::tr("Error in Calculating File Hash ") << Qt::endl;
+ }
+
+ return ss.readAll();
+}
+
+auto GetTempFilePath() -> QString {
+ QString const temp_dir = QDir::tempPath();
+ QString const filename = QUuid::createUuid().toString() + ".data";
+ return temp_dir + "/" + filename;
+}
+
+auto CreateTempFileAndWriteData(const QString& data) -> QString {
+ auto temp_file = GetTempFilePath();
+ WriteFile(temp_file, data.toUtf8());
+ return temp_file;
+}
+
+auto TargetFilePreCheck(const QString& path, bool read)
+ -> std::tuple<bool, QString> {
+ QFileInfo const file_info(path);
+
+ if (read) {
+ if (!file_info.exists()) {
+ return {false, QObject::tr("target path doesn't exists")};
+ }
+ } else {
+ QFileInfo const path_info(file_info.absolutePath());
+ if (!path_info.isWritable()) {
+ return {false, QObject::tr("do NOT have permission to write path")};
+ }
+ }
+
+ if (read ? !file_info.isReadable() : false) {
+ return {false, QObject::tr("do NOT have permission to read/write file")};
+ }
+
+ return {true, QObject::tr("Success")};
+}
+
+auto GetFullExtension(const QString& path) -> QString {
+ QString const filename = QFileInfo(path).fileName();
+
+ auto const dot_index = filename.indexOf('.');
+ if (dot_index == -1) return {};
+
+ return filename.mid(dot_index);
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/utils/IOUtils.h b/src/core/utils/IOUtils.h
new file mode 100644
index 00000000..42c663c3
--- /dev/null
+++ b/src/core/utils/IOUtils.h
@@ -0,0 +1,130 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/model/GFBuffer.h"
+
+namespace GpgFrontend {
+
+/**
+ * @brief
+ *
+ * @param file_name
+ * @return GFBuffer
+ */
+auto GPGFRONTEND_CORE_EXPORT ReadFileGFBuffer(const QString &file_name)
+ -> std::tuple<bool, GFBuffer>;
+
+/**
+ * @brief
+ *
+ * @param file_name
+ * @param data
+ * @return true
+ * @return false
+ */
+auto GPGFRONTEND_CORE_EXPORT WriteFileGFBuffer(const QString &file_name,
+ GFBuffer data) -> bool;
+
+/**
+ * @brief read file content
+ *
+ * @param file_name file name
+ * @param data data read from file
+ * @return true if success
+ * @return false if failed
+ */
+auto GPGFRONTEND_CORE_EXPORT ReadFile(const QString &file_name,
+ QByteArray &data) -> bool;
+
+/**
+ * @brief write file content
+ *
+ * @param file_name file name
+ * @param data data to write to file
+ * @return true if success
+ * @return false if failed
+ */
+auto GPGFRONTEND_CORE_EXPORT WriteFile(const QString &file_name,
+ const QByteArray &data) -> bool;
+
+/**
+ * calculate the hash of a file
+ * @param file_path
+ * @return
+ */
+auto GPGFRONTEND_CORE_EXPORT CalculateHash(const QString &file_path) -> QString;
+
+/**
+ * @brief
+ *
+ * @param path
+ * @param out_buffer
+ * @return true
+ * @return false
+ */
+auto GPGFRONTEND_CORE_EXPORT WriteBufferToFile(const QString &path,
+ const QString &out_buffer)
+ -> bool;
+
+/**
+ * @brief
+ *
+ * @return QString
+ */
+auto GPGFRONTEND_CORE_EXPORT GetTempFilePath() -> QString;
+
+/**
+ * @brief
+ *
+ * @param data
+ * @return QString
+ */
+auto GPGFRONTEND_CORE_EXPORT CreateTempFileAndWriteData(const QString &data)
+ -> QString;
+
+/**
+ * @brief
+ *
+ * @param path
+ * @param read
+ * @return std::tuple<bool, QString>
+ */
+auto GPGFRONTEND_CORE_EXPORT TargetFilePreCheck(const QString &path, bool read)
+ -> std::tuple<bool, QString>;
+
+/**
+ * @brief
+ *
+ * @param path
+ * @return QString
+ */
+auto GPGFRONTEND_CORE_EXPORT GetFullExtension(QString path) -> QString;
+
+} // namespace GpgFrontend
diff --git a/src/core/function/CharsetOperator.h b/src/core/utils/LocalizedUtils.cpp
index 41ce62f4..b8c91039 100644
--- a/src/core/function/CharsetOperator.h
+++ b/src/core/utils/LocalizedUtils.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,28 +20,19 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_CHARSETDETECTOR_H
-#define GPGFRONTEND_CHARSETDETECTOR_H
+#include "LocalizedUtils.h"
-#include "core/GpgFrontendCore.h"
+#include "core/utils/LogUtils.h"
namespace GpgFrontend {
-class GPGFRONTEND_CORE_EXPORT CharsetOperator {
- public:
- using CharsetInfo = std::tuple<std::string, std::string, int>;
-
- static CharsetInfo Detect(const std::string &buffer);
-
- static bool Convert2Utf8(const std::string &buffer, std::string &out_buffer,
- std::string from_charset_name);
-};
+auto GetFormatedDateByTimestamp(time_t timestamp) -> QString {
+ return QLocale::system().toString(QDateTime::fromSecsSinceEpoch(timestamp));
+}
} // namespace GpgFrontend
-
-#endif // GPGFRONTEND_CHARSETDETECTOR_H
diff --git a/src/core/utils/LocalizedUtils.h b/src/core/utils/LocalizedUtils.h
new file mode 100644
index 00000000..d7aaf0c8
--- /dev/null
+++ b/src/core/utils/LocalizedUtils.h
@@ -0,0 +1,35 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+namespace GpgFrontend {
+
+auto GPGFRONTEND_CORE_EXPORT GetFormatedDateByTimestamp(time_t) -> QString;
+
+} \ No newline at end of file
diff --git a/src/core/utils/LogUtils.cpp b/src/core/utils/LogUtils.cpp
new file mode 100644
index 00000000..fbf0c8d3
--- /dev/null
+++ b/src/core/utils/LogUtils.cpp
@@ -0,0 +1,59 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "LogUtils.h"
+
+#include "core/function/LoggerManager.h"
+
+namespace GpgFrontend {
+
+auto GetDefaultLogger() -> std::shared_ptr<spdlog::logger> {
+ return LoggerManager::GetDefaultLogger();
+}
+
+auto GetCoreLogger() -> std::shared_ptr<spdlog::logger> {
+ return LoggerManager::GetInstance().GetLogger("core");
+}
+
+auto GetLogger(const QString& id) -> std::shared_ptr<spdlog::logger> {
+ return LoggerManager::GetInstance().GetLogger(id);
+}
+
+void SetDefaultLogLevel(spdlog::level::level_enum level) {
+ return LoggerManager::SetDefaultLogLevel(level);
+}
+
+void RegisterAsyncLogger(const QString& id, spdlog::level::level_enum level) {
+ LoggerManager::GetInstance().RegisterAsyncLogger(id, level);
+}
+
+void RegisterSyncLogger(const QString& id, spdlog::level::level_enum level) {
+ LoggerManager::GetInstance().RegisterSyncLogger(id, level);
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/utils/LogUtils.h b/src/core/utils/LogUtils.h
new file mode 100644
index 00000000..d838e830
--- /dev/null
+++ b/src/core/utils/LogUtils.h
@@ -0,0 +1,112 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+namespace GpgFrontend {
+
+/**
+ * @brief
+ *
+ * @return std::shared_ptr<spdlog::logger>
+ */
+auto GPGFRONTEND_CORE_EXPORT GetDefaultLogger()
+ -> std::shared_ptr<spdlog::logger>;
+
+/**
+ * @brief
+ *
+ * @return std::shared_ptr<spdlog::logger>
+ */
+auto GPGFRONTEND_CORE_EXPORT GetCoreLogger() -> std::shared_ptr<spdlog::logger>;
+
+/**
+ * @brief
+ *
+ * @return std::shared_ptr<spdlog::logger>
+ */
+auto GPGFRONTEND_CORE_EXPORT GetLogger(const QString &)
+ -> std::shared_ptr<spdlog::logger>;
+
+/**
+ * @brief Set the Default Log Level object
+ *
+ * @return auto
+ */
+void GPGFRONTEND_CORE_EXPORT SetDefaultLogLevel(spdlog::level::level_enum);
+
+/**
+ * @brief
+ *
+ * @return auto
+ */
+void GPGFRONTEND_CORE_EXPORT RegisterAsyncLogger(const QString &,
+ spdlog::level::level_enum);
+
+/**
+ * @brief
+ *
+ * @return auto
+ */
+void GPGFRONTEND_CORE_EXPORT RegisterSyncLogger(const QString &,
+ spdlog::level::level_enum);
+
+} // namespace GpgFrontend
+
+#define GF_DEFAULT_LOG_TRACE(...) \
+ SPDLOG_LOGGER_TRACE(GpgFrontend::GetDefaultLogger(), __VA_ARGS__)
+#define GF_DEFAULT_LOG_DEBUG(...) \
+ SPDLOG_LOGGER_DEBUG(GpgFrontend::GetDefaultLogger(), __VA_ARGS__)
+#define GF_DEFAULT_LOG_INFO(...) \
+ SPDLOG_LOGGER_INFO(GpgFrontend::GetDefaultLogger(), __VA_ARGS__)
+#define GF_DEFAULT_LOG_WARN(...) \
+ SPDLOG_LOGGER_WARN(GpgFrontend::GetDefaultLogger(), __VA_ARGS__)
+#define GF_DEFAULT_LOG_ERROR(...) \
+ SPDLOG_LOGGER_ERROR(GpgFrontend::GetDefaultLogger(), __VA_ARGS__)
+
+#define GF_CORE_LOG_TRACE(...) \
+ SPDLOG_LOGGER_TRACE(GpgFrontend::GetCoreLogger(), __VA_ARGS__)
+#define GF_CORE_LOG_DEBUG(...) \
+ SPDLOG_LOGGER_DEBUG(GpgFrontend::GetCoreLogger(), __VA_ARGS__)
+#define GF_CORE_LOG_INFO(...) \
+ SPDLOG_LOGGER_INFO(GpgFrontend::GetCoreLogger(), __VA_ARGS__)
+#define GF_CORE_LOG_WARN(...) \
+ SPDLOG_LOGGER_WARN(GpgFrontend::GetCoreLogger(), __VA_ARGS__)
+#define GF_CORE_LOG_ERROR(...) \
+ SPDLOG_LOGGER_ERROR(GpgFrontend::GetCoreLogger(), __VA_ARGS__)
+
+#define GF_LOG_TRACE(ID, ...) \
+ SPDLOG_LOGGER_TRACE(GpgFrontend::GetLogger(ID), __VA_ARGS__)
+#define GF_LOG_DEBUG(ID, ...) \
+ SPDLOG_LOGGER_DEBUG(GpgFrontend::GetLogger(ID), __VA_ARGS__)
+#define GF_LOG_INFO(ID, ...) \
+ SPDLOG_LOGGER_INFO(GpgFrontend::GetLogger(ID), __VA_ARGS__)
+#define GF_LOG_WARN(ID, ...) \
+ SPDLOG_LOGGER_WARN(GpgFrontend::GetLogger(ID), __VA_ARGS__)
+#define GF_LOG_ERROR(ID, ...) \
+ SPDLOG_LOGGER_ERROR(GpgFrontend::GetLogger(ID), __VA_ARGS__) \ No newline at end of file
diff --git a/src/core/utils/MemoryUtils.cpp b/src/core/utils/MemoryUtils.cpp
new file mode 100644
index 00000000..f002fd87
--- /dev/null
+++ b/src/core/utils/MemoryUtils.cpp
@@ -0,0 +1,42 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "MemoryUtils.h"
+
+namespace GpgFrontend {
+
+auto SecureMalloc(std::size_t size) -> void * {
+ return SecureMemoryAllocator::Allocate(size);
+}
+
+auto SecureRealloc(void *ptr, std::size_t size) -> void * {
+ return SecureMemoryAllocator::Reallocate(ptr, size);
+}
+
+void SecureFree(void *ptr) { SecureMemoryAllocator::Deallocate(ptr); }
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/utils/MemoryUtils.h b/src/core/utils/MemoryUtils.h
new file mode 100644
index 00000000..76c75fc6
--- /dev/null
+++ b/src/core/utils/MemoryUtils.h
@@ -0,0 +1,179 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/GpgFrontendCoreExport.h"
+#include "core/function/SecureMemoryAllocator.h"
+
+/* To avoid that a compiler optimizes certain memset calls away, these
+ macros may be used instead. */
+#define wipememory2(_ptr, _set, _len) \
+ do { \
+ volatile char *_vptr = (volatile char *)(_ptr); \
+ size_t _vlen = (_len); \
+ while (_vlen) { \
+ *_vptr = (_set); \
+ _vptr++; \
+ _vlen--; \
+ } \
+ } while (0)
+#define wipememory(_ptr, _len) wipememory2(_ptr, 0, _len)
+#define wipe(_ptr, _len) wipememory2(_ptr, 0, _len)
+
+#define xtoi_1(p) \
+ (*(p) <= '9' ? (*(p) - '0') \
+ : *(p) <= 'F' ? (*(p) - 'A' + 10) \
+ : (*(p) - 'a' + 10))
+#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p) + 1))
+
+namespace GpgFrontend {
+
+template <typename T>
+class PointerConverter {
+ public:
+ explicit PointerConverter(void *ptr) : ptr_(ptr) {}
+
+ auto AsType() const -> T * { return static_cast<T *>(ptr_); }
+
+ private:
+ void *ptr_;
+};
+
+/**
+ * @brief
+ *
+ * @return void*
+ */
+auto GPGFRONTEND_CORE_EXPORT SecureMalloc(std::size_t) -> void *;
+
+/**
+ * @brief
+ *
+ * @return void*
+ */
+auto GPGFRONTEND_CORE_EXPORT SecureRealloc(void *, std::size_t) -> void *;
+
+/**
+ * @brief
+ *
+ * @tparam T
+ * @return T*
+ */
+template <typename T>
+auto SecureMallocAsType(std::size_t size) -> T * {
+ return PointerConverter<T>(SecureMemoryAllocator::Allocate(size)).AsType();
+}
+
+/**
+ * @brief
+ *
+ * @return void*
+ */
+template <typename T>
+auto SecureReallocAsType(T *ptr, std::size_t size) -> T * {
+ return PointerConverter<T>(SecureMemoryAllocator::Reallocate(ptr, size))
+ .AsType();
+}
+
+/**
+ * @brief
+ *
+ */
+void GPGFRONTEND_CORE_EXPORT SecureFree(void *);
+
+template <typename T, typename... Args>
+static auto SecureCreateObject(Args &&...args) -> T * {
+ void *mem = SecureMemoryAllocator::Allocate(sizeof(T));
+ if (!mem) return nullptr;
+
+ try {
+ return new (mem) T(std::forward<Args>(args)...);
+ } catch (...) {
+ SecureMemoryAllocator::Deallocate(mem);
+ throw;
+ }
+}
+
+template <typename T>
+static void SecureDestroyObject(T *obj) {
+ if (!obj) return;
+ obj->~T();
+ SecureMemoryAllocator::Deallocate(obj);
+}
+
+template <typename T, typename... Args>
+static auto SecureCreateUniqueObject(Args &&...args)
+ -> std::unique_ptr<T, SecureObjectDeleter<T>> {
+ void *mem = SecureMemoryAllocator::Allocate(sizeof(T));
+ if (!mem) throw std::bad_alloc();
+
+ try {
+ return std::unique_ptr<T, SecureObjectDeleter<T>>(
+ new (mem) T(std::forward<Args>(args)...));
+ } catch (...) {
+ SecureMemoryAllocator::Deallocate(mem);
+ throw;
+ }
+}
+
+template <typename T, typename... Args>
+auto SecureCreateSharedObject(Args &&...args) -> std::shared_ptr<T> {
+ void *mem = SecureMemoryAllocator::Allocate(sizeof(T));
+ if (!mem) throw std::bad_alloc();
+
+ try {
+ T *obj = new (mem) T(std::forward<Args>(args)...);
+ return std::shared_ptr<T>(obj, [](T *ptr) {
+ ptr->~T();
+ SecureMemoryAllocator::Deallocate(ptr);
+ });
+ } catch (...) {
+ SecureMemoryAllocator::Deallocate(mem);
+ throw;
+ }
+}
+
+template <typename T, typename... Args>
+auto SecureCreateQSharedObject(Args &&...args) -> QSharedPointer<T> {
+ void *mem = SecureMemoryAllocator::Allocate(sizeof(T));
+ if (!mem) throw std::bad_alloc();
+
+ try {
+ T *obj = new (mem) T(std::forward<Args>(args)...);
+ return QSharedPointer<T>(obj, [](T *ptr) {
+ ptr->~T();
+ SecureMemoryAllocator::Deallocate(ptr);
+ });
+ } catch (...) {
+ SecureMemoryAllocator::Deallocate(mem);
+ throw;
+ }
+}
+
+}; // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/aes/aes_ssl.h b/src/core/utils/aes/aes_ssl.h
index e75b68dd..5c3ac935 100644
--- a/src/core/function/aes/aes_ssl.h
+++ b/src/core/utils/aes/aes_ssl.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,14 +20,13 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_AES_SSL_H
-#define GPGFRONTEND_AES_SSL_H
+#pragma once
#include <openssl/aes.h>
#include <openssl/evp.h>
@@ -70,5 +69,3 @@ uint8_t *aes_256_cbc_encrypt(EVP_CIPHER_CTX *e, uint8_t *plaintext, int *len);
uint8_t *aes_256_cbc_decrypt(EVP_CIPHER_CTX *e, uint8_t *ciphertext, int *len);
} // namespace GpgFrontend::RawAPI
-
-#endif // GPGFRONTEND_AES_SSL_H
diff --git a/src/core/function/aes/aes_ssl_cbc.cpp b/src/core/utils/aes/aes_ssl_cbc.cpp
index 3aa80ef5..3aa80ef5 100644
--- a/src/core/function/aes/aes_ssl_cbc.cpp
+++ b/src/core/utils/aes/aes_ssl_cbc.cpp
diff --git a/src/init.cpp b/src/init.cpp
index ddab4add..4f9cf821 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,23 +20,26 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#include <spdlog/async.h>
-#include <spdlog/common.h>
-#include <spdlog/sinks/rotating_file_sink.h>
-#include <spdlog/sinks/stdout_color_sinks.h>
+#include "init.h"
-#include <filesystem>
-#include <string>
-
-#include "GpgFrontend.h"
-#include "GpgFrontendBuildInfo.h"
+#include "core/GpgCoreInit.h"
#include "core/function/GlobalSettingStation.h"
+#include "core/thread/TaskRunnerGetter.h"
+#include "core/utils/LogUtils.h"
+#include "module/GpgFrontendModuleInit.h"
+#include "ui/GpgFrontendUIInit.h"
+
+// main
+#include "GpgFrontendContext.h"
+#include "main.h"
+
+namespace GpgFrontend {
#ifdef WINDOWS
int setenv(const char *name, const char *value, int overwrite) {
@@ -50,66 +53,91 @@ int setenv(const char *name, const char *value, int overwrite) {
}
#endif
-void init_logging_system() {
- using namespace boost::posix_time;
- using namespace boost::gregorian;
-
- // sinks
- std::vector<spdlog::sink_ptr> sinks;
- sinks.push_back(std::make_shared<spdlog::sinks::stderr_color_sink_mt>());
+void InitLoggingSystem(const GFCxtSPtr &ctx) {
+ RegisterSyncLogger("core", ctx->log_level);
- // thread pool
- spdlog::init_thread_pool(1024, 2);
+ RegisterSyncLogger("main", ctx->log_level);
- // logger
- auto main_logger = std::make_shared<spdlog::async_logger>(
- "main", begin(sinks), end(sinks), spdlog::thread_pool());
- main_logger->set_pattern(
- "[%H:%M:%S.%e] [T:%t] [%=4n] %^[%=8l]%$ [%s:%#] [%!] -> %v (+%ius)");
+ RegisterSyncLogger("module", ctx->log_level);
-#ifdef DEBUG
- main_logger->set_level(spdlog::level::trace);
-#else
- main_logger->set_level(spdlog::level::info);
-#endif
-
- // flush policy
- main_logger->flush_on(spdlog::level::err);
- spdlog::flush_every(std::chrono::seconds(5));
-
- // register it as default logger
- spdlog::set_default_logger(main_logger);
-}
-
-void shutdown_logging_system() {
-#ifdef WINDOWS
- // Under VisualStudio, this must be called before main finishes to workaround
- // a known VS issue
- spdlog::drop_all();
- spdlog::shutdown();
-#endif
+ if (ctx->load_ui_env) {
+ // init the logging system for ui
+ RegisterSyncLogger("ui", ctx->log_level);
+ } else {
+ RegisterSyncLogger("test", ctx->log_level);
+ }
}
-void init_global_path_env() {
+void InitGlobalPathEnv() {
// read settings
bool use_custom_gnupg_install_path =
- GpgFrontend::GlobalSettingStation::GetInstance().LookupSettings(
- "general.use_custom_gnupg_install_path", false);
+ GlobalSettingStation::GetInstance()
+ .GetSettings()
+ .value("basic/use_custom_gnupg_install_path", false)
+ .toBool();
- std::string custom_gnupg_install_path =
- GpgFrontend::GlobalSettingStation::GetInstance().LookupSettings(
- "general.custom_gnupg_install_path", std::string{});
+ QString custom_gnupg_install_path =
+ GlobalSettingStation::GetInstance()
+ .GetSettings()
+ .value("basic/custom_gnupg_install_path")
+ .toString();
// add custom gnupg install path into env $PATH
- if (use_custom_gnupg_install_path && !custom_gnupg_install_path.empty()) {
- std::string path_value = getenv("PATH");
- SPDLOG_DEBUG("Current System PATH: {}", path_value);
+ if (use_custom_gnupg_install_path && !custom_gnupg_install_path.isEmpty()) {
+ QString path_value = getenv("PATH");
+ GF_MAIN_LOG_DEBUG("Current System PATH: {}", path_value);
setenv("PATH",
- ((std::filesystem::path{custom_gnupg_install_path}).u8string() +
- ":" + path_value)
- .c_str(),
+ (QDir(custom_gnupg_install_path).absolutePath() + ":" + path_value)
+ .toUtf8(),
1);
- std::string modified_path_value = getenv("PATH");
- SPDLOG_DEBUG("Modified System PATH: {}", modified_path_value);
+ QString modified_path_value = getenv("PATH");
+ GF_MAIN_LOG_DEBUG("Modified System PATH: {}", modified_path_value);
}
}
+
+void InitGlobalBasicalEnv(const GFCxtWPtr &p_ctx, bool gui_mode) {
+ GFCxtSPtr ctx = p_ctx.lock();
+ if (ctx == nullptr) {
+ return;
+ }
+
+ // initialize logging system
+ SetDefaultLogLevel(ctx->log_level);
+ InitLoggingSystem(ctx);
+
+ // change path to search for related
+ InitGlobalPathEnv();
+
+ // init application
+ ctx->InitApplication();
+
+ // should load module system first
+ Module::ModuleInitArgs module_init_args;
+ module_init_args.log_level = ctx->log_level;
+ Module::LoadGpgFrontendModules(module_init_args);
+
+ if (ctx->load_ui_env) {
+ // then preload ui
+ UI::PreInitGpgFrontendUI();
+ }
+
+ CoreInitArgs core_init_args;
+ core_init_args.gather_external_gnupg_info = ctx->gather_external_gnupg_info;
+ core_init_args.load_default_gpg_context = ctx->load_default_gpg_context;
+
+ // then load core
+ InitGpgFrontendCore(core_init_args);
+}
+
+void ShutdownGlobalBasicalEnv(const GFCxtWPtr &p_ctx) {
+ GFCxtSPtr ctx = p_ctx.lock();
+ if (ctx == nullptr) {
+ return;
+ }
+
+ Thread::TaskRunnerGetter::GetInstance().StopAllTeakRunner();
+
+ DestroyGpgFrontendCore();
+}
+
+} // namespace GpgFrontend
diff --git a/src/init.h b/src/init.h
new file mode 100644
index 00000000..1481b435
--- /dev/null
+++ b/src/init.h
@@ -0,0 +1,62 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "GpgFrontendContext.h"
+
+namespace GpgFrontend {
+
+/**
+ * @brief
+ *
+ * @param args
+ */
+void InitLoggingSystem(const GFCxtSPtr &);
+
+/**
+ * @brief init global PATH env
+ *
+ */
+void InitGlobalPathEnv();
+
+/**
+ * @brief
+ *
+ * @param args
+ */
+void InitGlobalBasicalEnv(const GFCxtWPtr &, bool);
+
+/**
+ * @brief
+ *
+ * @param p_ctx
+ */
+void ShutdownGlobalBasicalEnv(const GFCxtWPtr &p_ctx);
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
index 6ceff2a3..eea2e9f6 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -30,60 +30,13 @@
* \mainpage GpgFrontend Develop Document Main Page
*/
-#include <csetjmp>
-#include <csignal>
-#include <cstddef>
-#include <cstdlib>
-#include <string>
+#include <memory>
-#include "core/GpgConstants.h"
-#include "core/GpgCoreInit.h"
-#include "core/function/GlobalSettingStation.h"
-#include "spdlog/spdlog.h"
-#include "ui/GpgFrontendApplication.h"
-#include "ui/GpgFrontendUIInit.h"
-
-/**
- * \brief Store the jump buff and make it possible to recover from a crash.
- */
-#ifdef FREEBSD
-sigjmp_buf recover_env;
-#else
-jmp_buf recover_env;
-#endif
-
-constexpr int CRASH_CODE = ~0; ///<
-
-/**
- * @brief handle the signal SIGSEGV
- *
- * @param sig
- */
-extern void handle_signal(int sig);
-
-/**
- * @brief processes before exit the program.
- *
- */
-extern void before_exit();
-
-/**
- * @brief initialize the logging system.
- *
- */
-extern void init_logging_system();
-
-/**
- * @brief initialize the logging system.
- *
- */
-extern void shutdown_logging_system();
-
-/**
- * @brief init global PATH env
- *
- */
-extern void init_global_path_env();
+#include "GpgFrontendContext.h"
+#include "app.h"
+#include "cmd.h"
+#include "core/utils/MemoryUtils.h"
+#include "init.h"
/**
*
@@ -91,93 +44,54 @@ extern void init_global_path_env();
* @param argv
* @return
*/
-int main(int argc, char* argv[]) {
-#ifdef RELEASE
- // re
- signal(SIGSEGV, handle_signal);
- signal(SIGFPE, handle_signal);
- signal(SIGILL, handle_signal);
-#endif
+auto main(int argc, char* argv[]) -> int {
+ GpgFrontend::GFCxtSPtr ctx =
+ GpgFrontend::SecureCreateSharedObject<GpgFrontend::GpgFrontendContext>(
+ argc, argv);
+ ctx->InitApplication();
- // clean something before exit
- atexit(before_exit);
+ auto rtn = 0;
// initialize qt resources
Q_INIT_RESOURCE(gpgfrontend);
- // create qt application
- auto* app =
- GpgFrontend::UI::GpgFrontendApplication::GetInstance(argc, argv, true);
-
- // init the logging system for main
- init_logging_system();
-
- // init the logging system for core
- GpgFrontend::InitCoreLoggingSystem();
-
- // init the logging system for ui
- GpgFrontend::UI::InitUILoggingSystem();
-
- // change path to search for related
- init_global_path_env();
-
- /**
- * internationalisation. loop to restart main window
- * with changed translation when settings change.
- */
- int return_from_event_loop_code;
- int restart_count = 0;
-
- do {
-#ifndef WINDOWS
- int r = sigsetjmp(recover_env, 1);
-#else
- int r = setjmp(recover_env);
-#endif
- if (!r) {
- // init ui library
- GpgFrontend::UI::InitGpgFrontendUI(app);
-
- // create main window
- return_from_event_loop_code = GpgFrontend::UI::RunGpgFrontendUI(app);
- } else {
- SPDLOG_ERROR("recover from a crash");
- // when signal is caught, restart the main window
- auto* message_box = new QMessageBox(
- QMessageBox::Critical, _("A serious error has occurred"),
- _("Oh no! GpgFrontend caught a serious error in the software, so "
- "it needs to be restarted. If the problem recurs, please "
- "manually terminate the program and report the problem to the "
- "developer."),
- QMessageBox::Ok, nullptr);
- message_box->exec();
- return_from_event_loop_code = CRASH_CODE;
- }
-
- restart_count++;
-
- SPDLOG_DEBUG("restart loop refresh, event loop code: {}, restart count: {}",
- return_from_event_loop_code, restart_count);
- } while (return_from_event_loop_code == RESTART_CODE && restart_count < 3);
-
- // shutdown the logging system for ui
- GpgFrontend::UI::ShutdownUILoggingSystem();
-
- // shutdown the logging system for core
- GpgFrontend::ShutdownCoreLoggingSystem();
-
- // log for debug
- SPDLOG_INFO("GpgFrontend about to exit.");
-
- // deep restart mode
- if (return_from_event_loop_code == DEEP_RESTART_CODE ||
- return_from_event_loop_code == CRASH_CODE) {
- // log for debug
- SPDLOG_DEBUG(
- "deep restart or cash loop status caught, restart a new application");
- QProcess::startDetached(qApp->arguments()[0], qApp->arguments());
- };
-
- // exit the program
- return return_from_event_loop_code;
+ QCommandLineParser parser;
+ parser.addHelpOption();
+ parser.addOptions({
+ {{"v", "version"}, "show version information"},
+ {{"t", "test"}, "run all unit test cases"},
+ {{"l", "log-level"},
+ "set log level (trace, debug, info, warn, error)",
+ "debug"},
+ });
+
+ parser.process(*ctx->GetApp());
+
+ ctx->log_level = spdlog::level::info;
+
+ if (parser.isSet("v")) {
+ return GpgFrontend::PrintVersion();
+ }
+
+ if (parser.isSet("l")) {
+ ctx->log_level = GpgFrontend::ParseLogLevel(parser.value("l"));
+ }
+
+ if (parser.isSet("t")) {
+ ctx->gather_external_gnupg_info = false;
+ ctx->load_default_gpg_context = false;
+
+ InitGlobalBasicalEnv(ctx, false);
+ rtn = RunTest(ctx);
+ ShutdownGlobalBasicalEnv(ctx);
+ return rtn;
+ }
+
+ ctx->gather_external_gnupg_info = true;
+ ctx->load_default_gpg_context = true;
+ InitGlobalBasicalEnv(ctx, true);
+
+ rtn = StartApplication(ctx);
+ ShutdownGlobalBasicalEnv(ctx);
+ return rtn;
}
diff --git a/src/main.h b/src/main.h
new file mode 100644
index 00000000..d22b2acf
--- /dev/null
+++ b/src/main.h
@@ -0,0 +1,37 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/utils/LogUtils.h"
+
+#define GF_MAIN_LOG_TRACE(...) GF_LOG_TRACE("main", __VA_ARGS__)
+#define GF_MAIN_LOG_DEBUG(...) GF_LOG_DEBUG("main", __VA_ARGS__)
+#define GF_MAIN_LOG_INFO(...) GF_LOG_INFO("main", __VA_ARGS__)
+#define GF_MAIN_LOG_WARN(...) GF_LOG_WARN("main", __VA_ARGS__)
+#define GF_MAIN_LOG_ERROR(...) GF_LOG_ERROR("main", __VA_ARGS__) \ No newline at end of file
diff --git a/src/module/CMakeLists.txt b/src/module/CMakeLists.txt
new file mode 100644
index 00000000..b12e207a
--- /dev/null
+++ b/src/module/CMakeLists.txt
@@ -0,0 +1,80 @@
+# Copyright (C) 2021 Saturneric <[email protected]>
+#
+# This file is part of GpgFrontend.
+#
+# GpgFrontend is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# GpgFrontend is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+#
+# The initial version of the source code is inherited from
+# the gpg4usb project, which is under GPL-3.0-or-later.
+#
+# All the source code of GpgFrontend was modified and released by
+# Saturneric <[email protected]> starting on May 12, 2021.
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+set(CMAKE_CXX_VISIBILITY_PRESET hidden)
+set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
+
+# define libgpgfrontend_module_sdk
+aux_source_directory(sdk MODULE_SDK_SOURCE)
+
+add_library(gpgfrontend_module_sdk SHARED ${MODULE_SDK_SOURCE})
+set(_export_file_sdk "${CMAKE_CURRENT_SOURCE_DIR}/sdk/GpgFrontendModuleSDKExport.h")
+generate_export_header(gpgfrontend_module_sdk EXPORT_FILE_NAME "${_export_file_sdk}")
+target_include_directories(gpgfrontend_module_sdk PUBLIC
+ sdk
+ ${CMAKE_CURRENT_BINARY_DIR}/gpgfrontend_module_sdk_autogen/include
+ ${CMAKE_SOURCE_DIR}/third_party/spdlog/include)
+
+# link module system
+target_link_libraries(gpgfrontend_module_sdk
+ PUBLIC gpgfrontend_core)
+
+# tracking integrated modules
+set(all_integrated_module_libraries "")
+file(GLOB children LIST_DIRECTORIES true "integrated/*")
+foreach(child ${children})
+ if(IS_DIRECTORY ${child})
+ get_filename_component(dirName ${child} NAME)
+ add_subdirectory("integrated/${dirName}")
+
+ string(REPLACE "_module" "" stripped_module ${dirName})
+ set(integrated_lib_name "gpgfrontend_integrated_module_${stripped_module}")
+ list(APPEND all_integrated_module_libraries ${integrated_lib_name})
+ endif()
+endforeach()
+
+aux_source_directory(. MODULE_SOURCE)
+add_library(gpgfrontend_module SHARED ${MODULE_SOURCE})
+
+set(_export_file "${CMAKE_CURRENT_SOURCE_DIR}/GpgFrontendModuleExport.h")
+generate_export_header(gpgfrontend_module EXPORT_FILE_NAME "${_export_file}")
+
+# set up pch
+target_precompile_headers(gpgfrontend_module PUBLIC GpgFrontendModule.h)
+
+# add ui generator include path
+target_include_directories(gpgfrontend_module PUBLIC
+ ${CMAKE_CURRENT_BINARY_DIR}/gpgfrontend_module_autogen/include
+ ${CMAKE_SOURCE_DIR}/third_party/spdlog/include)
+
+# link gpgfrontend_module_sdk
+target_link_libraries(gpgfrontend_module PRIVATE gpgfrontend_module_sdk)
+
+# link all integrated modules
+message(STATUS "All Module Libraries: ${all_integrated_module_libraries}")
+target_link_libraries(gpgfrontend_module PRIVATE ${all_integrated_module_libraries})
+
+# using std c++ 17
+target_compile_features(gpgfrontend_module PUBLIC cxx_std_17) \ No newline at end of file
diff --git a/src/module/GpgFrontendModule.h b/src/module/GpgFrontendModule.h
new file mode 100644
index 00000000..cf7d8557
--- /dev/null
+++ b/src/module/GpgFrontendModule.h
@@ -0,0 +1,36 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+/**
+ * Project internal dependencies
+ */
+#include "GpgFrontend.h"
+#include "GpgFrontendModuleExport.h"
+#include "core/GpgFrontendCore.h"
diff --git a/src/module/GpgFrontendModuleExport.h b/src/module/GpgFrontendModuleExport.h
new file mode 100644
index 00000000..33ecbd3b
--- /dev/null
+++ b/src/module/GpgFrontendModuleExport.h
@@ -0,0 +1,42 @@
+
+#ifndef GPGFRONTEND_MODULE_EXPORT_H
+#define GPGFRONTEND_MODULE_EXPORT_H
+
+#ifdef GPGFRONTEND_MODULE_STATIC_DEFINE
+# define GPGFRONTEND_MODULE_EXPORT
+# define GPGFRONTEND_MODULE_NO_EXPORT
+#else
+# ifndef GPGFRONTEND_MODULE_EXPORT
+# ifdef gpgfrontend_module_EXPORTS
+ /* We are building this library */
+# define GPGFRONTEND_MODULE_EXPORT __attribute__((visibility("default")))
+# else
+ /* We are using this library */
+# define GPGFRONTEND_MODULE_EXPORT __attribute__((visibility("default")))
+# endif
+# endif
+
+# ifndef GPGFRONTEND_MODULE_NO_EXPORT
+# define GPGFRONTEND_MODULE_NO_EXPORT __attribute__((visibility("hidden")))
+# endif
+#endif
+
+#ifndef GPGFRONTEND_MODULE_DEPRECATED
+# define GPGFRONTEND_MODULE_DEPRECATED __attribute__ ((__deprecated__))
+#endif
+
+#ifndef GPGFRONTEND_MODULE_DEPRECATED_EXPORT
+# define GPGFRONTEND_MODULE_DEPRECATED_EXPORT GPGFRONTEND_MODULE_EXPORT GPGFRONTEND_MODULE_DEPRECATED
+#endif
+
+#ifndef GPGFRONTEND_MODULE_DEPRECATED_NO_EXPORT
+# define GPGFRONTEND_MODULE_DEPRECATED_NO_EXPORT GPGFRONTEND_MODULE_NO_EXPORT GPGFRONTEND_MODULE_DEPRECATED
+#endif
+
+#if 0 /* DEFINE_NO_DEPRECATED */
+# ifndef GPGFRONTEND_MODULE_NO_DEPRECATED
+# define GPGFRONTEND_MODULE_NO_DEPRECATED
+# endif
+#endif
+
+#endif /* GPGFRONTEND_MODULE_EXPORT_H */
diff --git a/src/module/GpgFrontendModuleInit.cpp b/src/module/GpgFrontendModuleInit.cpp
new file mode 100644
index 00000000..6f88b9ec
--- /dev/null
+++ b/src/module/GpgFrontendModuleInit.cpp
@@ -0,0 +1,66 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgFrontendModuleInit.h"
+
+#include <core/module/ModuleManager.h>
+
+#include "core/thread/Task.h"
+#include "core/thread/TaskRunnerGetter.h"
+
+// integrated modules
+#include "integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.h"
+#include "integrated/version_checking_module/VersionCheckingModule.h"
+#include "spdlog/common.h"
+
+namespace GpgFrontend::Module {
+
+void LoadGpgFrontendModules(ModuleInitArgs) {
+ // must init at default thread before core
+ Thread::TaskRunnerGetter::GetInstance().GetTaskRunner()->PostTask(
+ new Thread::Task(
+ [](const DataObjectPtr&) -> int {
+ MODULE_LOG_INFO("loading integrated module...");
+
+ // VersionCheckingModule
+ RegisterAndActivateModule<
+ Integrated::VersionCheckingModule::VersionCheckingModule>();
+
+ // VersionCheckingModule
+ RegisterAndActivateModule<Integrated::GnuPGInfoGatheringModule::
+ GnuPGInfoGatheringModule>();
+
+ MODULE_LOG_INFO("load integrated module done.");
+ return 0;
+ },
+ "modules_system_init_task"));
+}
+
+void ShutdownGpgFrontendModules() {}
+
+} // namespace GpgFrontend::Module \ No newline at end of file
diff --git a/src/module/GpgFrontendModuleInit.h b/src/module/GpgFrontendModuleInit.h
new file mode 100644
index 00000000..a3a8bbd3
--- /dev/null
+++ b/src/module/GpgFrontendModuleInit.h
@@ -0,0 +1,51 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "module/GpgFrontendModule.h"
+
+namespace GpgFrontend::Module {
+
+struct ModuleInitArgs {
+ spdlog::level::level_enum log_level;
+};
+
+/**
+ * @brief init the module library
+ *
+ */
+void GPGFRONTEND_MODULE_EXPORT LoadGpgFrontendModules(ModuleInitArgs args);
+
+/**
+ * @brief shutdown the module library
+ *
+ */
+void GPGFRONTEND_MODULE_EXPORT ShutdownGpgFrontendModules();
+
+}; // namespace GpgFrontend::Module
diff --git a/src/module/integrated/gnupg_info_gathering_module/CMakeLists.txt b/src/module/integrated/gnupg_info_gathering_module/CMakeLists.txt
new file mode 100644
index 00000000..2a62b08e
--- /dev/null
+++ b/src/module/integrated/gnupg_info_gathering_module/CMakeLists.txt
@@ -0,0 +1,38 @@
+# Copyright (C) 2021 Saturneric <[email protected]>
+#
+# This file is part of GpgFrontend.
+#
+# GpgFrontend is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# GpgFrontend is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+#
+# The initial version of the source code is inherited from
+# the gpg4usb project, which is under GPL-3.0-or-later.
+#
+# All the source code of GpgFrontend was modified and released by
+# Saturneric <[email protected]> starting on May 12, 2021.
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering
+
+aux_source_directory(. INTEGRATED_MODULE_SOURCE)
+
+# define libgpgfrontend_module
+add_library(gpgfrontend_integrated_module_gnupg_info_gathering SHARED ${INTEGRATED_MODULE_SOURCE})
+
+# link sdk
+target_link_libraries(gpgfrontend_integrated_module_gnupg_info_gathering PRIVATE
+ gpgfrontend_module_sdk)
+
+# using std c++ 17
+target_compile_features(gpgfrontend_integrated_module_gnupg_info_gathering PRIVATE cxx_std_17) \ No newline at end of file
diff --git a/src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.cpp b/src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.cpp
new file mode 100644
index 00000000..91bf93f5
--- /dev/null
+++ b/src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.cpp
@@ -0,0 +1,358 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GnuPGInfoGatheringModule.h"
+
+#include <vector>
+
+#include "GpgInfo.h"
+#include "Log.h"
+#include "core/function/gpg/GpgCommandExecutor.h"
+#include "core/module/ModuleManager.h"
+
+namespace GpgFrontend::Module::Integrated::GnuPGInfoGatheringModule {
+
+auto CheckBinaryChacksum(QString path) -> std::optional<QString> {
+ // check file info and access rights
+ QFileInfo info(path);
+ if (!info.exists() || !info.isFile() || !info.isReadable()) {
+ MODULE_LOG_ERROR("get info for file {} error, exists: {}", info.filePath(),
+ info.exists());
+ return {};
+ }
+
+ // open and read file
+ QFile f(info.filePath());
+ if (!f.open(QIODevice::ReadOnly)) {
+ MODULE_LOG_ERROR("open {} to calculate check sum error: {}", path,
+ f.errorString());
+ return {};
+ }
+
+ // read all data from file
+ auto buffer = f.readAll();
+ f.close();
+
+ auto hash_sha = QCryptographicHash(QCryptographicHash::Sha256);
+ // md5
+ hash_sha.addData(buffer);
+ return QString(hash_sha.result().toHex()).left(6);
+}
+
+GnuPGInfoGatheringModule::GnuPGInfoGatheringModule()
+ : Module(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ "1.0.0",
+ ModuleMetaData{{"description", "try to gathering gnupg informations"},
+ {"author", "saturneric"}}) {}
+
+GnuPGInfoGatheringModule::~GnuPGInfoGatheringModule() = default;
+
+auto GnuPGInfoGatheringModule::Register() -> bool {
+ MODULE_LOG_DEBUG("gnupg info gathering module registering");
+ listenEvent("GPGFRONTEND_CORE_INITLIZED");
+ return true;
+}
+
+auto GnuPGInfoGatheringModule::Active() -> bool {
+ MODULE_LOG_DEBUG("gnupg info gathering module activating");
+ return true;
+}
+
+auto GnuPGInfoGatheringModule::Exec(EventRefrernce event) -> int {
+ MODULE_LOG_DEBUG("gnupg info gathering module executing, event id: {}",
+ event->GetIdentifier());
+
+ const auto gpgme_version = RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.version", QString{"0.0.0"});
+ MODULE_LOG_DEBUG("got gpgme version from rt: {}", gpgme_version);
+
+ const auto gpgconf_path = RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gpgconf_path", QString{});
+ MODULE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path);
+
+ MODULE_LOG_DEBUG("start to load extra info at module gnupginfogathering...");
+
+ // get all components
+ GpgCommandExecutor::ExecuteSync(
+ {gpgconf_path,
+ {"--list-components"},
+ [this, gpgme_version, gpgconf_path](int exit_code, const QString &p_out,
+ const QString &p_err) {
+ MODULE_LOG_DEBUG(
+ "gpgconf components exit_code: {} process stdout size: {}",
+ exit_code, p_out.size());
+
+ if (exit_code != 0) {
+ MODULE_LOG_ERROR(
+ "gpgconf execute error, process stderr: {}, "
+ "process stdout: {}",
+ p_err, p_out);
+ return;
+ }
+
+ std::vector<GpgComponentInfo> component_infos;
+ GpgComponentInfo c_i_gpgme;
+ c_i_gpgme.name = "gpgme";
+ c_i_gpgme.desc = "GPG Made Easy";
+ c_i_gpgme.version = gpgme_version;
+ c_i_gpgme.path = tr("Embedded In");
+ c_i_gpgme.binary_checksum = "/";
+
+ GpgComponentInfo c_i_gpgconf;
+ c_i_gpgconf.name = "gpgconf";
+ c_i_gpgconf.desc = "GPG Configure";
+ c_i_gpgconf.version = "/";
+ c_i_gpgconf.path = gpgconf_path;
+ auto gpgconf_binary_checksum = CheckBinaryChacksum(gpgconf_path);
+ c_i_gpgconf.binary_checksum = (gpgconf_binary_checksum.has_value()
+ ? gpgconf_binary_checksum.value()
+ : QString("/"));
+
+ component_infos.push_back(c_i_gpgme);
+ component_infos.push_back(c_i_gpgconf);
+
+ auto const jsonlized_gpgme_component_info = c_i_gpgme.Json();
+ auto const jsonlized_gpgconf_component_info = c_i_gpgconf.Json();
+ UpsertRTValue(GetModuleIdentifier(), "gnupg.components.gpgme",
+ QJsonDocument(jsonlized_gpgme_component_info).toJson());
+ UpsertRTValue(
+ GetModuleIdentifier(), "gnupg.components.gpgconf",
+ QJsonDocument(jsonlized_gpgconf_component_info).toJson());
+
+ auto line_split_list = p_out.split("\n");
+
+ for (const auto &line : line_split_list) {
+ auto info_split_list = line.split(":");
+
+ if (info_split_list.size() != 3) continue;
+
+ auto component_name = info_split_list[0].trimmed();
+ auto component_desc = info_split_list[1].trimmed();
+ auto component_path = info_split_list[2].trimmed();
+
+#ifdef WINDOWS
+ // replace some special substrings on windows platform
+ component_path.replace("%3a", ":");
+#endif
+
+ auto binary_checksum = CheckBinaryChacksum(component_path);
+
+ MODULE_LOG_DEBUG(
+ "gnupg component name: {} desc: {} checksum: {} path: {} ",
+ component_name, component_desc,
+ binary_checksum.has_value() ? binary_checksum.value() : "/",
+ component_path);
+
+ QString version = "/";
+
+ if (component_name == "gpg") {
+ version = RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gnupg_version", QString{"2.0.0"});
+ }
+ if (component_name == "gpg-agent") {
+ UpsertRTValue(GetModuleIdentifier(), "gnupg.gpg_agent_path",
+ QString(component_path));
+ }
+ if (component_name == "dirmngr") {
+ UpsertRTValue(GetModuleIdentifier(), "gnupg.dirmngr_path",
+ QString(component_path));
+ }
+ if (component_name == "keyboxd") {
+ UpsertRTValue(GetModuleIdentifier(), "gnupg.keyboxd_path",
+ QString(component_path));
+ }
+
+ {
+ GpgComponentInfo c_i;
+ c_i.name = component_name;
+ c_i.desc = component_desc;
+ c_i.version = version;
+ c_i.path = component_path;
+ c_i.binary_checksum =
+ (binary_checksum.has_value() ? binary_checksum.value()
+ : QString("/"));
+
+ auto const jsonlized_component_info = c_i.Json();
+ UpsertRTValue(GetModuleIdentifier(),
+ QString("gnupg.components.%1").arg(component_name),
+ QJsonDocument(jsonlized_component_info).toJson());
+
+ component_infos.push_back(c_i);
+ }
+ }
+ },
+ getTaskRunner()});
+
+ GpgCommandExecutor::ExecuteContexts exec_contexts;
+
+ exec_contexts.emplace_back(GpgCommandExecutor::ExecuteContext{
+ gpgconf_path,
+ {"--list-dirs"},
+ [this](int exit_code, const QString &p_out, const QString &p_err) {
+ MODULE_LOG_DEBUG(
+ "gpgconf configurations exit_code: {} process stdout size: {}",
+ exit_code, p_out.size());
+
+ if (exit_code != 0) {
+ MODULE_LOG_ERROR(
+ "gpgconf execute error, process stderr: {} process stdout: "
+ "{}",
+ p_err, p_out);
+ return;
+ }
+
+ auto line_split_list = p_out.split("\n");
+
+ for (const auto &line : line_split_list) {
+ auto info_split_list = line.split(":");
+ MODULE_LOG_DEBUG("gpgconf info line: {} info size: {}", line,
+ info_split_list.size());
+
+ if (info_split_list.size() != 2) continue;
+
+ auto configuration_name = info_split_list[0].trimmed();
+ auto configuration_value = info_split_list[1].trimmed();
+
+#ifdef WINDOWS
+ // replace some special substrings on windows platform
+ configuration_value.replace("%3a", ":");
+#endif
+
+ // record gnupg home path
+ if (configuration_name == "homedir") {
+ UpsertRTValue(GetModuleIdentifier(), "gnupg.home_path",
+ configuration_value);
+ }
+
+ UpsertRTValue(GetModuleIdentifier(),
+ QString("gnupg.dirs.%1").arg(configuration_name),
+ configuration_value);
+ }
+ },
+ getTaskRunner()});
+
+ auto components = ListRTChildKeys(GetModuleIdentifier(), "gnupg.components");
+
+ for (const auto &component : components) {
+ auto component_info_json = RetrieveRTValueTypedOrDefault(
+ GetModuleIdentifier(), QString("gnupg.components.%1").arg(component),
+ QByteArray{});
+
+ auto jsonlized_component_info =
+ QJsonDocument::fromJson(component_info_json);
+ assert(jsonlized_component_info.isObject());
+
+ auto component_info = GpgComponentInfo(jsonlized_component_info.object());
+ MODULE_LOG_DEBUG("gpgconf check options ready, component: {}",
+ component_info.name);
+
+ if (component_info.name == "gpgme" || component_info.name == "gpgconf") {
+ continue;
+ }
+
+ exec_contexts.emplace_back(GpgCommandExecutor::ExecuteContext{
+ gpgconf_path,
+ {"--list-options", component_info.name},
+ [this, component_info](int exit_code, const QString &p_out,
+ const QString &p_err) {
+ MODULE_LOG_DEBUG(
+ "gpgconf {} avaliable options exit_code: {} process stdout "
+ "size: {} ",
+ component_info.name, exit_code, p_out.size());
+
+ if (exit_code != 0) {
+ MODULE_LOG_ERROR(
+ "gpgconf {} avaliable options execute error, process stderr: "
+ "{} , process stdout:",
+ component_info.name, p_err, p_out);
+ return;
+ }
+
+ std::vector<GpgOptionsInfo> options_infos;
+
+ auto line_split_list = p_out.split("\n");
+
+ for (const auto &line : line_split_list) {
+ auto info_split_list = line.split(":");
+
+ MODULE_LOG_DEBUG(
+ "component {} avaliable options line: {} info size: {}",
+ component_info.name, line, info_split_list.size());
+
+ if (info_split_list.size() < 10) continue;
+
+ // The format of each line is:
+ // name:flags:level:description:type:alt-type:argname:default:argdef:value
+
+ auto option_name = info_split_list[0].trimmed();
+ auto option_flags = info_split_list[1].trimmed();
+ auto option_level = info_split_list[2].trimmed();
+ auto option_desc = info_split_list[3].trimmed();
+ auto option_type = info_split_list[4].trimmed();
+ auto option_alt_type = info_split_list[5].trimmed();
+ auto option_argname = info_split_list[6].trimmed();
+ auto option_default = info_split_list[7].trimmed();
+ auto option_argdef = info_split_list[8].trimmed();
+ auto option_value = info_split_list[9].trimmed();
+
+ GpgOptionsInfo info;
+ info.name = option_name;
+ info.flags = option_flags;
+ info.level = option_level;
+ info.description = option_desc;
+ info.type = option_type;
+ info.alt_type = option_alt_type;
+ info.argname = option_argname;
+ info.default_value = option_default;
+ info.argdef = option_argdef;
+ info.value = option_value;
+
+ auto const jsonlized_option_info = info.Json();
+ UpsertRTValue(GetModuleIdentifier(),
+ QString("gnupg.components.%1.options.%2")
+ .arg(component_info.name)
+ .arg(option_name),
+ QJsonDocument(jsonlized_option_info).toJson());
+ options_infos.push_back(info);
+ }
+ },
+ getTaskRunner()});
+ }
+
+ GpgCommandExecutor::ExecuteConcurrentlySync(exec_contexts);
+ UpsertRTValue(GetModuleIdentifier(), "gnupg.gathering_done", true);
+ event->ExecuteCallback(GetModuleIdentifier(), TransferParams(true));
+
+ MODULE_LOG_DEBUG("gnupg external info gathering done");
+ return 0;
+}
+
+auto GnuPGInfoGatheringModule::Deactive() -> bool { return true; }
+
+} // namespace GpgFrontend::Module::Integrated::GnuPGInfoGatheringModule
diff --git a/src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.h b/src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.h
new file mode 100644
index 00000000..5c228298
--- /dev/null
+++ b/src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.h
@@ -0,0 +1,54 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include <module/sdk/GpgFrontendModuleSDK.h>
+
+namespace GpgFrontend::Module::Integrated::GnuPGInfoGatheringModule {
+
+/**
+ * @brief Use to record some info about gnupg
+ *
+ */
+class GPGFRONTEND_MODULE_SDK_EXPORT GnuPGInfoGatheringModule : public Module {
+ Q_OBJECT
+ public:
+ GnuPGInfoGatheringModule();
+
+ ~GnuPGInfoGatheringModule() override;
+
+ auto Register() -> bool override;
+
+ auto Active() -> bool override;
+
+ auto Exec(EventRefrernce) -> int override;
+
+ auto Deactive() -> bool override;
+};
+} // namespace GpgFrontend::Module::Integrated::GnuPGInfoGatheringModule
diff --git a/src/module/integrated/gnupg_info_gathering_module/GpgInfo.cpp b/src/module/integrated/gnupg_info_gathering_module/GpgInfo.cpp
new file mode 100644
index 00000000..2015bc0a
--- /dev/null
+++ b/src/module/integrated/gnupg_info_gathering_module/GpgInfo.cpp
@@ -0,0 +1,80 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "module/integrated/gnupg_info_gathering_module/GpgInfo.h"
+
+namespace GpgFrontend::Module::Integrated::GnuPGInfoGatheringModule {
+
+GpgOptionsInfo::GpgOptionsInfo(const QJsonObject &j) {
+ if (const auto v = j["name"]; v.isString()) name = v.toString();
+ if (const auto v = j["flags"]; v.isString()) flags = v.toString();
+ if (const auto v = j["level"]; v.isString()) level = v.toString();
+ if (const auto v = j["description"]; v.isString()) description = v.toString();
+ if (const auto v = j["type"]; v.isString()) type = v.toString();
+ if (const auto v = j["alt_type"]; v.isString()) alt_type = v.toString();
+ if (const auto v = j["argname"]; v.isString()) argname = v.toString();
+ if (const auto v = j["default_value"]; v.isString())
+ default_value = v.toString();
+ if (const auto v = j["argdef"]; v.isString()) argdef = v.toString();
+ if (const auto v = j["value"]; v.isString()) value = v.toString();
+}
+
+auto GpgOptionsInfo::Json() const -> QJsonObject {
+ QJsonObject j;
+ j["name"] = name;
+ j["flags"] = flags;
+ j["level"] = level;
+ j["description"] = description;
+ j["type"] = type;
+ j["alt_type"] = alt_type;
+ j["argname"] = argname;
+ j["default_value"] = default_value;
+ j["argdef"] = argdef;
+ j["value"] = value;
+ return j;
+}
+
+auto GpgComponentInfo::Json() const -> QJsonObject {
+ QJsonObject j;
+ j["name"] = name;
+ j["desc"] = desc;
+ j["version"] = version;
+ j["path"] = path;
+ j["binary_checksum"] = binary_checksum;
+ return j;
+}
+
+GpgComponentInfo::GpgComponentInfo(const QJsonObject &j) {
+ if (const auto v = j["name"]; v.isString()) name = v.toString();
+ if (const auto v = j["desc"]; v.isString()) desc = v.toString();
+ if (const auto v = j["version"]; v.isString()) version = v.toString();
+ if (const auto v = j["path"]; v.isString()) path = v.toString();
+ if (const auto v = j["binary_checksum"]; v.isString())
+ binary_checksum = v.toString();
+}
+} // namespace GpgFrontend::Module::Integrated::GnuPGInfoGatheringModule
diff --git a/src/module/integrated/gnupg_info_gathering_module/GpgInfo.h b/src/module/integrated/gnupg_info_gathering_module/GpgInfo.h
new file mode 100644
index 00000000..fb12b811
--- /dev/null
+++ b/src/module/integrated/gnupg_info_gathering_module/GpgInfo.h
@@ -0,0 +1,87 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+namespace GpgFrontend::Module::Integrated::GnuPGInfoGatheringModule {
+/**
+ * @brief Use to record some info about gnupg
+ *
+ */
+class GpgInfo {
+ public:
+ QString GnuPGHomePath; ///< value of ---homedir
+
+ std::map<QString, std::vector<QString>> ComponentsInfo; ///<
+ std::map<QString, std::vector<QString>> ConfigurationsInfo; ///<
+ std::map<QString, std::vector<QString>> OptionsInfo; ///<
+ std::map<QString, std::vector<QString>> AvailableOptionsInfo; ///<
+};
+
+/**
+ * @brief Use to record some info about gnupg components
+ *
+ */
+struct GpgComponentInfo {
+ QString name;
+ QString desc;
+ QString version;
+ QString path;
+ QString binary_checksum;
+
+ GpgComponentInfo() = default;
+
+ explicit GpgComponentInfo(const QJsonObject &j);
+
+ [[nodiscard]] auto Json() const -> QJsonObject;
+};
+
+/**
+ * The format of each line is:
+ * name:flags:level:description:type:alt-type:argname:default:argdef:value
+ */
+struct GpgOptionsInfo {
+ QString name;
+ QString flags;
+ QString level;
+ QString description;
+ QString type;
+ QString alt_type;
+ QString argname;
+ QString default_value;
+ QString argdef;
+ QString value;
+
+ GpgOptionsInfo() = default;
+
+ explicit GpgOptionsInfo(const QJsonObject &j);
+
+ [[nodiscard]] auto Json() const -> QJsonObject;
+};
+
+} // namespace GpgFrontend::Module::Integrated::GnuPGInfoGatheringModule
diff --git a/src/module/integrated/version_checking_module/CMakeLists.txt b/src/module/integrated/version_checking_module/CMakeLists.txt
new file mode 100644
index 00000000..0b474ce9
--- /dev/null
+++ b/src/module/integrated/version_checking_module/CMakeLists.txt
@@ -0,0 +1,41 @@
+# Copyright (C) 2021 Saturneric <[email protected]>
+#
+# This file is part of GpgFrontend.
+#
+# GpgFrontend is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# GpgFrontend is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+#
+# The initial version of the source code is inherited from
+# the gpg4usb project, which is under GPL-3.0-or-later.
+#
+# All the source code of GpgFrontend was modified and released by
+# Saturneric <[email protected]> starting on May 12, 2021.
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# com.bktus.gpgfrontend.module.integrated.version-checking
+
+aux_source_directory(. INTEGRATED_MODULE_SOURCE)
+
+# define libgpgfrontend_module
+add_library(gpgfrontend_integrated_module_version_checking SHARED ${INTEGRATED_MODULE_SOURCE})
+
+# link sdk
+target_link_libraries(gpgfrontend_integrated_module_version_checking PRIVATE
+ gpgfrontend_module_sdk)
+
+# link Qt
+target_link_libraries(gpgfrontend_integrated_module_version_checking PRIVATE Qt6::Network)
+
+# using std c++ 17
+target_compile_features(gpgfrontend_integrated_module_version_checking PRIVATE cxx_std_17) \ No newline at end of file
diff --git a/src/module/integrated/version_checking_module/SoftwareVersion.cpp b/src/module/integrated/version_checking_module/SoftwareVersion.cpp
new file mode 100644
index 00000000..117212cb
--- /dev/null
+++ b/src/module/integrated/version_checking_module/SoftwareVersion.cpp
@@ -0,0 +1,56 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "SoftwareVersion.h"
+
+#include "core/utils/CommonUtils.h"
+
+namespace GpgFrontend::Module::Integrated::VersionCheckingModule {
+
+bool VersionCheckingModule::SoftwareVersion::NeedUpgrade() const {
+ MODULE_LOG_DEBUG("compair version current {} latest {}, result {}",
+ current_version, latest_version,
+ CompareSoftwareVersion(current_version, latest_version));
+
+ MODULE_LOG_DEBUG("load done: {}, pre-release: {}, draft: {}", loading_done,
+ latest_prerelease_version_from_remote,
+ latest_draft_from_remote);
+ return loading_done && !latest_prerelease_version_from_remote &&
+ !latest_draft_from_remote &&
+ CompareSoftwareVersion(current_version, latest_version) < 0;
+}
+
+bool VersionCheckingModule::SoftwareVersion::VersionWithdrawn() const {
+ return loading_done && !current_version_publish_in_remote &&
+ current_version_is_a_prerelease && !current_version_is_drafted;
+}
+
+bool VersionCheckingModule::SoftwareVersion::CurrentVersionReleased() const {
+ return loading_done && current_version_publish_in_remote;
+}
+} // namespace GpgFrontend::Module::Integrated::VersionCheckingModule \ No newline at end of file
diff --git a/src/ui/struct/SoftwareVersion.h b/src/module/integrated/version_checking_module/SoftwareVersion.h
index 9d861ef1..43f718fa 100644
--- a/src/ui/struct/SoftwareVersion.h
+++ b/src/module/integrated/version_checking_module/SoftwareVersion.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,33 +20,32 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_SOFTWAREVERSION_H
-#define GPGFRONTEND_SOFTWAREVERSION_H
+#pragma once
-#include <boost/date_time.hpp>
+#include <module/sdk/GpgFrontendModuleSDK.h>
-namespace GpgFrontend::UI {
+namespace GpgFrontend::Module::Integrated::VersionCheckingModule {
/**
* @brief
*
*/
struct SoftwareVersion {
- std::string latest_version; ///<
- std::string current_version; ///<
- bool latest_prerelease = false; ///<
- bool latest_draft = false; ///<
- bool current_prerelease = false; ///<
- bool current_draft = false; ///<
- bool load_info_done = false; ///<
- bool current_version_found = false; ///<
- std::string publish_date; ///<
- std::string release_note; ///<
+ QString latest_version; ///<
+ QString current_version; ///<
+ bool latest_prerelease_version_from_remote = false; ///<
+ bool latest_draft_from_remote = false; ///<
+ bool current_version_is_a_prerelease = false; ///<
+ bool current_version_is_drafted = false; ///<
+ bool loading_done = false; ///<
+ bool current_version_publish_in_remote = false; ///<
+ QString publish_date; ///<
+ QString release_note; ///<
/**
* @brief
@@ -54,7 +53,7 @@ struct SoftwareVersion {
* @return true
* @return false
*/
- [[nodiscard]] bool InfoValid() const { return load_info_done; }
+ [[nodiscard]] bool InfoValid() const { return loading_done; }
/**
* @brief
@@ -70,7 +69,7 @@ struct SoftwareVersion {
* @return true
* @return false
*/
- [[nodiscard]] bool VersionWithDrawn() const;
+ [[nodiscard]] bool VersionWithdrawn() const;
/**
* @brief
@@ -81,8 +80,6 @@ struct SoftwareVersion {
[[nodiscard]] bool CurrentVersionReleased() const;
private:
- static int version_compare(const std::string& a, const std::string& b);
+ static int version_compare(const QString& a, const QString& b);
};
-} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_SOFTWAREVERSION_H
+} // namespace GpgFrontend::Module::Integrated::VersionCheckingModule
diff --git a/src/module/integrated/version_checking_module/VersionCheckTask.cpp b/src/module/integrated/version_checking_module/VersionCheckTask.cpp
new file mode 100644
index 00000000..261ab1ca
--- /dev/null
+++ b/src/module/integrated/version_checking_module/VersionCheckTask.cpp
@@ -0,0 +1,154 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "VersionCheckTask.h"
+
+#include <QMetaType>
+#include <QtNetwork>
+
+#include "GpgFrontendBuildInfo.h"
+
+namespace GpgFrontend::Module::Integrated::VersionCheckingModule {
+
+VersionCheckTask::VersionCheckTask()
+ : Task("version_check_task"),
+ network_manager_(new QNetworkAccessManager(this)),
+ current_version_(QString("v") + VERSION_MAJOR + "." + VERSION_MINOR +
+ "." + VERSION_PATCH) {
+ HoldOnLifeCycle(true);
+ qRegisterMetaType<SoftwareVersion>("SoftwareVersion");
+ version_.current_version = current_version_;
+}
+
+auto VersionCheckTask::Run() -> int {
+ MODULE_LOG_DEBUG("current project version: {}", current_version_);
+ QString latest_version_url =
+ "https://api.github.com/repos/saturneric/gpgfrontend/releases/latest";
+
+ QNetworkRequest latest_request;
+ latest_request.setUrl(QUrl(latest_version_url));
+ latest_reply_ = network_manager_->get(latest_request);
+ connect(latest_reply_, &QNetworkReply::finished, this,
+ &VersionCheckTask::slot_parse_latest_version_info);
+ return 0;
+}
+
+void VersionCheckTask::slot_parse_latest_version_info() {
+ version_.current_version = current_version_;
+
+ if (latest_reply_ == nullptr ||
+ latest_reply_->error() != QNetworkReply::NoError) {
+ MODULE_LOG_ERROR("latest version request error");
+ version_.latest_version = current_version_;
+ } else {
+ latest_reply_bytes_ = latest_reply_->readAll();
+ auto latest_reply_json = QJsonDocument::fromJson(latest_reply_bytes_);
+
+ QString latest_version = latest_reply_json["tag_name"].toString();
+ MODULE_LOG_INFO("latest version from Github: {}", latest_version);
+
+ QRegularExpression re(R"(^[vV](\d+\.)?(\d+\.)?(\*|\d+))");
+ auto version_match = re.match(latest_version);
+ if (version_match.hasMatch()) {
+ latest_version = version_match.captured(0);
+ MODULE_LOG_DEBUG("latest version matched: {}", latest_version);
+ } else {
+ latest_version = current_version_;
+ MODULE_LOG_WARN("latest version unknown");
+ }
+
+ bool prerelease = latest_reply_json["prerelease"].toBool();
+ bool draft = latest_reply_json["draft"].toBool();
+ auto publish_date = latest_reply_json["published_at"].toString();
+ auto release_note = latest_reply_json["body"].toString();
+ version_.latest_version = latest_version;
+ version_.latest_prerelease_version_from_remote = prerelease;
+ version_.latest_draft_from_remote = draft;
+ version_.publish_date = publish_date;
+ version_.release_note = release_note;
+ }
+
+ if (latest_reply_ != nullptr) {
+ latest_reply_->deleteLater();
+ }
+
+ try {
+ QString current_version_url =
+ "https://api.github.com/repos/saturneric/gpgfrontend/releases/tags/" +
+ current_version_;
+
+ QNetworkRequest current_request;
+ current_request.setUrl(QUrl(current_version_url));
+ current_reply_ = network_manager_->get(current_request);
+
+ connect(current_reply_, &QNetworkReply::finished, this,
+ &VersionCheckTask::slot_parse_current_version_info);
+ } catch (...) {
+ MODULE_LOG_ERROR("current version request create error");
+ emit SignalTaskShouldEnd(-1);
+ }
+}
+
+void VersionCheckTask::slot_parse_current_version_info() {
+ if (current_reply_ == nullptr ||
+ current_reply_->error() != QNetworkReply::NoError) {
+ if (current_reply_ != nullptr) {
+ MODULE_LOG_ERROR("current version request network error: {}",
+ current_reply_->errorString().toStdString());
+ } else {
+ MODULE_LOG_ERROR(
+ "current version request network error, null reply object");
+ }
+ version_.current_version_publish_in_remote = false;
+ } else {
+ version_.current_version_publish_in_remote = true;
+ current_reply_bytes_ = current_reply_->readAll();
+ auto current_reply_json = QJsonDocument::fromJson(current_reply_bytes_);
+
+ if (current_reply_json.isObject()) {
+ bool current_prerelease = current_reply_json["prerelease"].toBool();
+ bool current_draft = current_reply_json["draft"].toBool();
+ version_.latest_prerelease_version_from_remote = current_prerelease;
+ version_.latest_draft_from_remote = current_draft;
+
+ // loading done
+ version_.loading_done = true;
+ } else {
+ MODULE_LOG_WARN("cannot parse data got from github");
+ }
+ }
+
+ MODULE_LOG_DEBUG("current version parse done: {}",
+ version_.current_version_publish_in_remote);
+
+ if (current_reply_ != nullptr) current_reply_->deleteLater();
+ emit SignalUpgradeVersion(version_);
+ emit SignalTaskShouldEnd(0);
+}
+
+} // namespace GpgFrontend::Module::Integrated::VersionCheckingModule
diff --git a/src/ui/thread/VersionCheckTask.h b/src/module/integrated/version_checking_module/VersionCheckTask.h
index 0dbce17f..f5091819 100644
--- a/src/ui/thread/VersionCheckTask.h
+++ b/src/module/integrated/version_checking_module/VersionCheckTask.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,23 +20,23 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_VERSIONCHECKTHREAD_H
-#define GPGFRONTEND_VERSIONCHECKTHREAD_H
+#pragma once
-#include <memory>
-#include <string>
+#include <core/thread/Task.h>
+#include <module/sdk/GpgFrontendModuleSDK.h>
-#include "core/thread/Task.h"
-#include "ui/GpgFrontendUI.h"
-#include "ui/struct/SoftwareVersion.h"
+#include "SoftwareVersion.h"
-namespace GpgFrontend::UI {
+class QNetworkReply;
+class QNetworkAccessManager;
+
+namespace GpgFrontend::Module::Integrated::VersionCheckingModule {
/**
* @brief
@@ -44,13 +44,12 @@ namespace GpgFrontend::UI {
*/
class VersionCheckTask : public Thread::Task {
Q_OBJECT
-
public:
/**
* @brief Construct a new Version Check Thread object
*
*/
- explicit VersionCheckTask();
+ VersionCheckTask();
signals:
@@ -67,7 +66,7 @@ class VersionCheckTask : public Thread::Task {
*
*/
- void Run() override;
+ auto Run() -> int override;
private slots:
@@ -89,10 +88,9 @@ class VersionCheckTask : public Thread::Task {
QNetworkReply* latest_reply_ = nullptr; ///< latest version info reply
QNetworkReply* current_reply_ = nullptr; ///< current version info reply
QNetworkAccessManager* network_manager_; ///<
- std::string current_version_;
+ QString current_version_;
SoftwareVersion version_;
};
-} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_VERSIONCHECKTHREAD_H
+} // namespace GpgFrontend::Module::Integrated::VersionCheckingModule
+ // GpgFrontend::Module::Custom::IntegradedModule::VersionCheckingModule
diff --git a/src/module/integrated/version_checking_module/VersionCheckingModule.cpp b/src/module/integrated/version_checking_module/VersionCheckingModule.cpp
new file mode 100644
index 00000000..9b62a9c8
--- /dev/null
+++ b/src/module/integrated/version_checking_module/VersionCheckingModule.cpp
@@ -0,0 +1,105 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "VersionCheckingModule.h"
+
+#include "Log.h"
+#include "SoftwareVersion.h"
+#include "VersionCheckTask.h"
+#include "core/module/Module.h"
+#include "core/module/ModuleManager.h"
+
+namespace GpgFrontend::Module::Integrated::VersionCheckingModule {
+
+VersionCheckingModule::VersionCheckingModule()
+ : Module("com.bktus.gpgfrontend.module.integrated.version-checking",
+ "1.0.0",
+ ModuleMetaData{{"description", "try to check gpgfrontend version"},
+ {"author", "saturneric"}}) {}
+
+VersionCheckingModule::~VersionCheckingModule() = default;
+
+auto VersionCheckingModule::Register() -> bool {
+ MODULE_LOG_INFO("version checking module registering");
+ listenEvent("APPLICATION_LOADED");
+ listenEvent("CHECK_APPLICATION_VERSION");
+ return true;
+}
+
+auto VersionCheckingModule::Active() -> bool {
+ MODULE_LOG_INFO("version checking module activating");
+ return true;
+}
+
+auto VersionCheckingModule::Exec(EventRefrernce event) -> int {
+ MODULE_LOG_INFO("version checking module executing, event id: {}",
+ event->GetIdentifier());
+
+ auto* task = new VersionCheckTask();
+ connect(task, &VersionCheckTask::SignalUpgradeVersion, this,
+ &VersionCheckingModule::SignalVersionCheckDone);
+ connect(this, &VersionCheckingModule::SignalVersionCheckDone, this,
+ [this, event](SoftwareVersion version) {
+ SlotVersionCheckDone(std::move(version));
+ event->ExecuteCallback(GetModuleIdentifier(),
+ TransferParams(version.loading_done));
+ });
+ getTaskRunner()->PostTask(task);
+ return 0;
+}
+
+auto VersionCheckingModule::Deactive() -> bool { return true; }
+
+void VersionCheckingModule::SlotVersionCheckDone(SoftwareVersion version) {
+ MODULE_LOG_DEBUG("registering software information info to rt");
+ UpsertRTValue(GetModuleIdentifier(), "version.current_version",
+ version.current_version);
+ UpsertRTValue(GetModuleIdentifier(), "version.latest_version",
+ version.latest_version);
+ UpsertRTValue(GetModuleIdentifier(), "version.current_version_is_drafted",
+ version.current_version_is_drafted);
+ UpsertRTValue(GetModuleIdentifier(),
+ "version.current_version_is_a_prerelease",
+ version.current_version_is_a_prerelease);
+ UpsertRTValue(GetModuleIdentifier(),
+ "version.current_version_publish_in_remote",
+ version.current_version_publish_in_remote);
+ UpsertRTValue(GetModuleIdentifier(),
+ "version.latest_prerelease_version_from_remote",
+ version.latest_prerelease_version_from_remote);
+ UpsertRTValue(GetModuleIdentifier(), "version.need_upgrade",
+ version.NeedUpgrade());
+ UpsertRTValue(GetModuleIdentifier(), "version.current_version_released",
+ version.CurrentVersionReleased());
+ UpsertRTValue(GetModuleIdentifier(), "version.current_a_withdrawn_version",
+ version.VersionWithdrawn());
+ UpsertRTValue(GetModuleIdentifier(), "version.loading_done",
+ version.loading_done);
+ MODULE_LOG_DEBUG("register software information to rt done");
+}
+} // namespace GpgFrontend::Module::Integrated::VersionCheckingModule
diff --git a/src/module/integrated/version_checking_module/VersionCheckingModule.h b/src/module/integrated/version_checking_module/VersionCheckingModule.h
new file mode 100644
index 00000000..0a215588
--- /dev/null
+++ b/src/module/integrated/version_checking_module/VersionCheckingModule.h
@@ -0,0 +1,60 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include <module/sdk/GpgFrontendModuleSDK.h>
+
+#include "SoftwareVersion.h"
+
+namespace GpgFrontend::Module::Integrated::VersionCheckingModule {
+
+class GPGFRONTEND_MODULE_SDK_EXPORT VersionCheckingModule : public Module {
+ Q_OBJECT
+ public:
+ VersionCheckingModule();
+
+ ~VersionCheckingModule() override;
+
+ auto Register() -> bool override;
+
+ auto Active() -> bool override;
+
+ auto Exec(EventRefrernce) -> int override;
+
+ auto Deactive() -> bool override;
+
+ signals:
+
+ void SignalVersionCheckDone(SoftwareVersion);
+
+ public slots:
+
+ void SlotVersionCheckDone(SoftwareVersion);
+};
+} // namespace GpgFrontend::Module::Integrated::VersionCheckingModule
diff --git a/src/module/sdk/Basic.cpp b/src/module/sdk/Basic.cpp
new file mode 100644
index 00000000..63859763
--- /dev/null
+++ b/src/module/sdk/Basic.cpp
@@ -0,0 +1,27 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */ \ No newline at end of file
diff --git a/src/module/sdk/Basic.h b/src/module/sdk/Basic.h
new file mode 100644
index 00000000..62a547b3
--- /dev/null
+++ b/src/module/sdk/Basic.h
@@ -0,0 +1,36 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+namespace GpgFrontend::Module::SDK {
+
+
+
+
+} \ No newline at end of file
diff --git a/src/module/sdk/Gpg.cpp b/src/module/sdk/Gpg.cpp
new file mode 100644
index 00000000..63859763
--- /dev/null
+++ b/src/module/sdk/Gpg.cpp
@@ -0,0 +1,27 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */ \ No newline at end of file
diff --git a/src/core/GpgInfo.cpp b/src/module/sdk/Gpg.h
index a77f0ed4..0702632a 100644
--- a/src/core/GpgInfo.cpp
+++ b/src/module/sdk/Gpg.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,10 +20,10 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#include "core/GpgInfo.h"
+#pragma once \ No newline at end of file
diff --git a/src/module/sdk/GpgFrontendModuleSDK.h b/src/module/sdk/GpgFrontendModuleSDK.h
new file mode 100644
index 00000000..97769462
--- /dev/null
+++ b/src/module/sdk/GpgFrontendModuleSDK.h
@@ -0,0 +1,33 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include <core/module/GpgFrontendModuleSystem.h>
+#include <module/sdk/GpgFrontendModuleSDKExport.h>
+#include <module/sdk/Log.h> \ No newline at end of file
diff --git a/src/module/sdk/GpgFrontendModuleSDKExport.h b/src/module/sdk/GpgFrontendModuleSDKExport.h
new file mode 100644
index 00000000..a62168bc
--- /dev/null
+++ b/src/module/sdk/GpgFrontendModuleSDKExport.h
@@ -0,0 +1,42 @@
+
+#ifndef GPGFRONTEND_MODULE_SDK_EXPORT_H
+#define GPGFRONTEND_MODULE_SDK_EXPORT_H
+
+#ifdef GPGFRONTEND_MODULE_SDK_STATIC_DEFINE
+# define GPGFRONTEND_MODULE_SDK_EXPORT
+# define GPGFRONTEND_MODULE_SDK_NO_EXPORT
+#else
+# ifndef GPGFRONTEND_MODULE_SDK_EXPORT
+# ifdef gpgfrontend_module_sdk_EXPORTS
+ /* We are building this library */
+# define GPGFRONTEND_MODULE_SDK_EXPORT __attribute__((visibility("default")))
+# else
+ /* We are using this library */
+# define GPGFRONTEND_MODULE_SDK_EXPORT __attribute__((visibility("default")))
+# endif
+# endif
+
+# ifndef GPGFRONTEND_MODULE_SDK_NO_EXPORT
+# define GPGFRONTEND_MODULE_SDK_NO_EXPORT __attribute__((visibility("hidden")))
+# endif
+#endif
+
+#ifndef GPGFRONTEND_MODULE_SDK_DEPRECATED
+# define GPGFRONTEND_MODULE_SDK_DEPRECATED __attribute__ ((__deprecated__))
+#endif
+
+#ifndef GPGFRONTEND_MODULE_SDK_DEPRECATED_EXPORT
+# define GPGFRONTEND_MODULE_SDK_DEPRECATED_EXPORT GPGFRONTEND_MODULE_SDK_EXPORT GPGFRONTEND_MODULE_SDK_DEPRECATED
+#endif
+
+#ifndef GPGFRONTEND_MODULE_SDK_DEPRECATED_NO_EXPORT
+# define GPGFRONTEND_MODULE_SDK_DEPRECATED_NO_EXPORT GPGFRONTEND_MODULE_SDK_NO_EXPORT GPGFRONTEND_MODULE_SDK_DEPRECATED
+#endif
+
+#if 0 /* DEFINE_NO_DEPRECATED */
+# ifndef GPGFRONTEND_MODULE_SDK_NO_DEPRECATED
+# define GPGFRONTEND_MODULE_SDK_NO_DEPRECATED
+# endif
+#endif
+
+#endif /* GPGFRONTEND_MODULE_SDK_EXPORT_H */
diff --git a/src/before_exit.cpp b/src/module/sdk/Log.cpp
index 31c56354..384fac1d 100644
--- a/src/before_exit.cpp
+++ b/src/module/sdk/Log.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,18 +20,17 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#include "core/function/GlobalSettingStation.h"
+#include "Log.h"
-/**
- * @brief Actions performed before exiting the application
- *
- */
-void before_exit() {
-}
+#include <stdexcept>
+
+#include "core/function/GlobalSettingStation.h"
+
+namespace GpgFrontend::Module::SDK {} // namespace GpgFrontend::Module::SDK
diff --git a/src/module/sdk/Log.h b/src/module/sdk/Log.h
new file mode 100644
index 00000000..0c40a097
--- /dev/null
+++ b/src/module/sdk/Log.h
@@ -0,0 +1,71 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "core/utils/LogUtils.h"
+#include "module/sdk/GpgFrontendModuleSDK.h"
+
+#define MODULE_LOG_TRACE(...) GF_LOG_TRACE("module", __VA_ARGS__)
+#define MODULE_LOG_DEBUG(...) GF_LOG_DEBUG("module", __VA_ARGS__)
+#define MODULE_LOG_INFO(...) GF_LOG_INFO("module", __VA_ARGS__)
+#define MODULE_LOG_WARN(...) GF_LOG_WARN("module", __VA_ARGS__)
+#define MODULE_LOG_ERROR(...) GF_LOG_ERROR("module", __VA_ARGS__)
+
+namespace spdlog {
+class logger;
+}
+
+namespace GpgFrontend::Module::SDK {
+
+template <typename... Args>
+void ModuleLogTrace(const char* fmt, const Args&... args) {
+ MODULE_LOG_TRACE(fmt, args...);
+}
+
+template <typename... Args>
+void ModuleLogDebug(const char* fmt, const Args&... args) {
+ MODULE_LOG_DEBUG(fmt, args...);
+}
+
+template <typename... Args>
+void ModuleLogInfo(const char* fmt, const Args&... args) {
+ MODULE_LOG_INFO(fmt, args...);
+}
+
+template <typename... Args>
+void ModuleLogWarn(const char* fmt, const Args&... args) {
+ MODULE_LOG_WARN(fmt, args...);
+}
+
+template <typename... Args>
+void ModuleLogError(const char* fmt, const Args&... args) {
+ MODULE_LOG_ERROR(fmt, args...);
+}
+
+} // namespace GpgFrontend::Module::SDK
diff --git a/src/module/sdk/UI.cpp b/src/module/sdk/UI.cpp
new file mode 100644
index 00000000..63859763
--- /dev/null
+++ b/src/module/sdk/UI.cpp
@@ -0,0 +1,27 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */ \ No newline at end of file
diff --git a/src/module/sdk/UI.h b/src/module/sdk/UI.h
new file mode 100644
index 00000000..0702632a
--- /dev/null
+++ b/src/module/sdk/UI.h
@@ -0,0 +1,29 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once \ No newline at end of file
diff --git a/src/pinentry/CMakeLists.txt b/src/pinentry/CMakeLists.txt
new file mode 100644
index 00000000..b31e4f05
--- /dev/null
+++ b/src/pinentry/CMakeLists.txt
@@ -0,0 +1,69 @@
+# Copyright (C) 2021 Saturneric <[email protected]>
+#
+# This file is part of GpgFrontend.
+#
+# GpgFrontend is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# GpgFrontend is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+#
+# The initial version of the source code is inherited from
+# the gpg4usb project, which is under GPL-3.0-or-later.
+#
+# All the source code of GpgFrontend was modified and released by
+# Saturneric <[email protected]> starting on May 12, 2021.
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+aux_source_directory(. PINENTRY_SOURCE)
+
+# capslock
+list(APPEND PINENTRY_SOURCE "capslock/capslock.cpp")
+if (MINGW)
+ list(APPEND PINENTRY_SOURCE "capslock/capslock_win.cpp")
+else()
+ list(APPEND PINENTRY_SOURCE "capslock/capslock_unix.cpp")
+endif()
+
+add_library(gpgfrontend_pinentry SHARED ${PINENTRY_SOURCE})
+
+target_link_libraries(gpgfrontend_pinentry PUBLIC gpgfrontend_core)
+
+# link Qt core
+target_link_libraries(gpgfrontend_pinentry PUBLIC Qt6::Widgets)
+
+# spdlog
+target_link_libraries(gpgfrontend_pinentry PRIVATE spdlog)
+
+# using std c++ 17
+target_compile_features(gpgfrontend_pinentry PUBLIC cxx_std_17)
+
+# link for different platforms
+if (MINGW)
+ message(STATUS "Link GPG Static Library For MINGW")
+ target_link_libraries(gpgfrontend_pinentry PUBLIC wsock32)
+elseif (APPLE)
+ message(STATUS "Link GPG Static Library For macOS")
+ target_link_libraries(gpgfrontend_pinentry PUBLIC dl)
+ if (XCODE_BUILD)
+ set_target_properties(gpgfrontend_pinentry
+ PROPERTIES
+ ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
+ LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
+ LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
+ XCODE_ATTRIBUTE_SKIP_INSTALL "Yes"
+ XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}")
+ endif ()
+else ()
+ # linux
+ message(STATUS "Link GPG Static Library For Unix")
+ target_link_libraries(gpgfrontend_pinentry PUBLIC pthread dl)
+endif ()
diff --git a/src/pinentry/accessibility.cpp b/src/pinentry/accessibility.cpp
new file mode 100644
index 00000000..f139832a
--- /dev/null
+++ b/src/pinentry/accessibility.cpp
@@ -0,0 +1,44 @@
+/* accessibility.cpp - Helpers for making pinentry accessible
+ * Copyright (C) 2021 g10 Code GmbH
+ *
+ * Software engineering by Ingo Klöcker <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "accessibility.h"
+
+#include <QString>
+#include <QWidget>
+
+namespace Accessibility {
+
+void setDescription(QWidget *w, const QString &text) {
+ if (w) {
+#ifndef QT_NO_ACCESSIBILITY
+ w->setAccessibleDescription(text);
+#endif
+ }
+}
+
+void setName(QWidget *w, const QString &text) {
+ if (w) {
+#ifndef QT_NO_ACCESSIBILITY
+ w->setAccessibleName(text);
+#endif
+ }
+}
+
+} // namespace Accessibility
diff --git a/src/pinentry/accessibility.h b/src/pinentry/accessibility.h
new file mode 100644
index 00000000..9ef912d6
--- /dev/null
+++ b/src/pinentry/accessibility.h
@@ -0,0 +1,40 @@
+/* accessibility.h - Helpers for making pinentry accessible
+ * Copyright (C) 2021 g10 Code GmbH
+ *
+ * Software engineering by Ingo Klöcker <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __PINENTRY_QT_ACCESSIBILITY_H__
+#define __PINENTRY_QT_ACCESSIBILITY_H__
+
+class QString;
+class QWidget;
+
+namespace Accessibility
+{
+
+/* Wrapper for QWidget::setAccessibleDescription which does nothing if
+ QT_NO_ACCESSIBILITY is defined. */
+void setDescription(QWidget *w, const QString &text);
+
+/* Wrapper for QWidget::setAccessibleName which does nothing if
+ QT_NO_ACCESSIBILITY is defined. */
+void setName(QWidget *w, const QString &text);
+
+} // namespace Accessibility
+
+#endif // __PINENTRY_QT_ACCESSIBILITY_H__
diff --git a/src/pinentry/capslock/capslock.cpp b/src/pinentry/capslock/capslock.cpp
new file mode 100644
index 00000000..a730c220
--- /dev/null
+++ b/src/pinentry/capslock/capslock.cpp
@@ -0,0 +1,41 @@
+/* capslock.cpp - Helper to check whether Caps Lock is on
+ * Copyright (C) 2021 g10 Code GmbH
+ *
+ * Software engineering by Ingo Klöcker <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <QDebug>
+#include <QGuiApplication>
+
+#include "capslock.h"
+
+CapsLockWatcher::Private::Private(CapsLockWatcher *q) : q{q} {
+#ifdef PINENTRY_QT_WAYLAND
+ if (qApp->platformName() == QLatin1String("wayland")) {
+ watchWayland();
+ }
+#endif
+}
+
+CapsLockWatcher::CapsLockWatcher(QObject *parent)
+ : QObject{parent}, d{new Private{this}} {
+ if (qApp->platformName() == QLatin1String("wayland")) {
+#ifndef PINENTRY_QT_WAYLAND
+ qWarning() << "CapsLockWatcher was compiled without support for Wayland";
+#endif
+ }
+}
diff --git a/src/pinentry/capslock/capslock.h b/src/pinentry/capslock/capslock.h
new file mode 100644
index 00000000..138f88cc
--- /dev/null
+++ b/src/pinentry/capslock/capslock.h
@@ -0,0 +1,77 @@
+/* capslock.h - Helper to check whether Caps Lock is on
+ * Copyright (C) 2021 g10 Code GmbH
+ *
+ * Software engineering by Ingo Klöcker <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __PINENTRY_QT_CAPSLOCK_H__
+#define __PINENTRY_QT_CAPSLOCK_H__
+
+#include <QObject>
+#include <memory>
+
+enum class LockState { Unknown = -1, Off, On };
+
+LockState capsLockState();
+
+#ifdef PINENTRY_QT_WAYLAND
+namespace KWayland {
+namespace Client {
+class Registry;
+class Seat;
+} // namespace Client
+} // namespace KWayland
+#endif
+
+class CapsLockWatcher : public QObject {
+ Q_OBJECT
+
+ public:
+ explicit CapsLockWatcher(QObject *parent = nullptr);
+
+ Q_SIGNALS:
+ void stateChanged(bool locked);
+
+ private:
+ class Private;
+ std::unique_ptr<Private> d;
+};
+
+class CapsLockWatcher::Private {
+ public:
+ explicit Private(CapsLockWatcher *);
+#ifdef PINENTRY_QT_WAYLAND
+ void watchWayland();
+#endif
+
+ private:
+#ifdef PINENTRY_QT_WAYLAND
+ void registry_seatAnnounced(quint32, quint32);
+ void seat_hasKeyboardChanged(bool);
+ void keyboard_modifiersChanged(quint32);
+#endif
+
+ private:
+ CapsLockWatcher *const q;
+
+#ifdef PINENTRY_QT_WAYLAND
+ KWayland::Client::Registry *registry = nullptr;
+ KWayland::Client::Seat *seat = nullptr;
+#endif
+};
+
+#endif // __PINENTRY_QT_CAPSLOCK_H__
diff --git a/src/pinentry/capslock/capslock_unix.cpp b/src/pinentry/capslock/capslock_unix.cpp
new file mode 100644
index 00000000..e4f4cd17
--- /dev/null
+++ b/src/pinentry/capslock/capslock_unix.cpp
@@ -0,0 +1,137 @@
+/* capslock_unix.cpp - Helper to check whether Caps Lock is on
+ * Copyright (C) 2021 g10 Code GmbH
+ *
+ * Software engineering by Ingo Klöcker <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "capslock.h"
+
+#ifdef PINENTRY_QT_WAYLAND
+#include <KWayland/Client/connection_thread.h>
+#include <KWayland/Client/keyboard.h>
+#include <KWayland/Client/registry.h>
+#include <KWayland/Client/seat.h>
+#endif
+
+#include <QGuiApplication>
+
+#ifdef PINENTRY_QT_X11
+#include <X11/XKBlib.h>
+
+#include <QX11Info>
+#undef Status
+#endif
+
+#include <QDebug>
+
+#ifdef PINENTRY_QT_WAYLAND
+using namespace KWayland::Client;
+#endif
+
+#ifdef PINENTRY_QT_WAYLAND
+static bool watchingWayland = false;
+#endif
+
+LockState capsLockState() {
+ static bool reportUnsupportedPlatform = true;
+#ifdef PINENTRY_QT_X11
+ if (qApp->platformName() == QLatin1String("xcb")) {
+ unsigned int state;
+ XkbGetIndicatorState(QX11Info::display(), XkbUseCoreKbd, &state);
+ return (state & 0x01) == 1 ? LockState::On : LockState::Off;
+ }
+#endif
+#ifdef PINENTRY_QT_WAYLAND
+ if (qApp->platformName() == QLatin1String("wayland")) {
+ if (!watchingWayland && reportUnsupportedPlatform) {
+ qDebug() << "Use CapsLockWatcher for checking for Caps Lock on Wayland";
+ }
+ } else
+#endif
+ if (reportUnsupportedPlatform) {
+ qWarning() << "Checking for Caps Lock not possible on unsupported platform:"
+ << qApp->platformName();
+ }
+ reportUnsupportedPlatform = false;
+ return LockState::Unknown;
+}
+
+#ifdef PINENTRY_QT_WAYLAND
+void CapsLockWatcher::Private::watchWayland() {
+ watchingWayland = true;
+ auto connection = ConnectionThread::fromApplication(q);
+ if (!connection) {
+ qWarning() << "Failed to get connection to Wayland server from QPA";
+ return;
+ }
+ registry = new Registry{q};
+ registry->create(connection);
+ if (!registry->isValid()) {
+ qWarning() << "Failed to create valid KWayland registry";
+ return;
+ }
+ registry->setup();
+
+ connect(registry, &Registry::seatAnnounced, q,
+ [this](quint32 name, quint32 version) {
+ registry_seatAnnounced(name, version);
+ });
+}
+
+void CapsLockWatcher::Private::registry_seatAnnounced(quint32 name,
+ quint32 version) {
+ Q_ASSERT(registry);
+ seat = registry->createSeat(name, version, q);
+ if (!seat->isValid()) {
+ qWarning() << "Failed to create valid KWayland seat";
+ return;
+ }
+
+ connect(seat, &Seat::hasKeyboardChanged, q,
+ [this](bool hasKeyboard) { seat_hasKeyboardChanged(hasKeyboard); });
+}
+
+void CapsLockWatcher::Private::seat_hasKeyboardChanged(bool hasKeyboard) {
+ Q_ASSERT(seat);
+
+ if (!hasKeyboard) {
+ qDebug() << "Seat has no keyboard";
+ return;
+ }
+
+ auto keyboard = seat->createKeyboard(q);
+ if (!keyboard->isValid()) {
+ qWarning() << "Failed to create valid KWayland keyboard";
+ return;
+ }
+
+ connect(keyboard, &Keyboard::modifiersChanged, q,
+ [this](quint32, quint32, quint32 locked, quint32) {
+ keyboard_modifiersChanged(locked);
+ });
+}
+
+void CapsLockWatcher::Private::keyboard_modifiersChanged(quint32 locked) {
+ const bool capsLockIsLocked = (locked & 2u) != 0;
+ qDebug() << "Caps Lock is locked:" << capsLockIsLocked;
+ Q_EMIT q->stateChanged(capsLockIsLocked);
+}
+#endif
diff --git a/src/pinentry/capslock/capslock_win.cpp b/src/pinentry/capslock/capslock_win.cpp
new file mode 100644
index 00000000..46bc7043
--- /dev/null
+++ b/src/pinentry/capslock/capslock_win.cpp
@@ -0,0 +1,26 @@
+/* capslock_win.cpp - Helper to check whether Caps Lock is on
+ * Copyright (C) 2021 g10 Code GmbH
+ *
+ * Software engineering by Ingo Klöcker <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <windows.h>
+
+#include "capslock.h"
+
+LockState capsLockState() {
+ return (GetKeyState(VK_CAPITAL) & 1) ? LockState::On : LockState::Off;
+}
diff --git a/src/pinentry/focusframe.cpp b/src/pinentry/focusframe.cpp
new file mode 100644
index 00000000..c0c9f562
--- /dev/null
+++ b/src/pinentry/focusframe.cpp
@@ -0,0 +1,72 @@
+/* focusframe.cpp - A focus indicator for labels.
+ * Copyright (C) 2022 g10 Code GmbH
+ *
+ * Software engineering by Ingo Klöcker <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "focusframe.h"
+
+#if QT_CONFIG(graphicseffect)
+#include <QGraphicsEffect>
+#endif
+#include <QStyleOptionFocusRect>
+#include <QStylePainter>
+
+static QRect effectiveWidgetRect(const QWidget *w) {
+ // based on QWidgetPrivate::effectiveRectFor
+#if QT_CONFIG(graphicseffect)
+ const auto *const graphicsEffect = w->graphicsEffect();
+ if (graphicsEffect && graphicsEffect->isEnabled())
+ return graphicsEffect->boundingRectFor(w->rect()).toAlignedRect();
+#endif // QT_CONFIG(graphicseffect)
+ return w->rect();
+}
+
+static QRect clipRect(const QWidget *w) {
+ // based on QWidgetPrivate::clipRect
+ if (!w->isVisible()) {
+ return QRect();
+ }
+ QRect r = effectiveWidgetRect(w);
+ int ox = 0;
+ int oy = 0;
+ while (w && w->isVisible() && !w->isWindow() && w->parentWidget()) {
+ ox -= w->x();
+ oy -= w->y();
+ w = w->parentWidget();
+ r &= QRect(ox, oy, w->width(), w->height());
+ }
+ return r;
+}
+
+void FocusFrame::paintEvent(QPaintEvent *) {
+ if (!widget()) {
+ return;
+ }
+
+ QStylePainter p{this};
+ QStyleOptionFocusRect option;
+ initStyleOption(&option);
+ const int vmargin =
+ style()->pixelMetric(QStyle::PM_FocusFrameVMargin, &option);
+ const int hmargin =
+ style()->pixelMetric(QStyle::PM_FocusFrameHMargin, &option);
+ const QRect rect =
+ clipRect(widget()).adjusted(0, 0, hmargin * 2, vmargin * 2);
+ p.setClipRect(rect);
+ p.drawPrimitive(QStyle::PE_FrameFocusRect, option);
+}
diff --git a/src/pinentry/focusframe.h b/src/pinentry/focusframe.h
new file mode 100644
index 00000000..3d2231ea
--- /dev/null
+++ b/src/pinentry/focusframe.h
@@ -0,0 +1,36 @@
+/* focusframe.h - A focus indicator for labels.
+ * Copyright (C) 2022 g10 Code GmbH
+ *
+ * Software engineering by Ingo Klöcker <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __FOCUSFRAME_H__
+#define __FOCUSFRAME_H__
+
+#include <QFocusFrame>
+
+class FocusFrame : public QFocusFrame
+{
+ Q_OBJECT
+public:
+ using QFocusFrame::QFocusFrame;
+
+protected:
+ void paintEvent(QPaintEvent *event) override;
+};
+
+#endif // __FOCUSFRAME_H__
diff --git a/src/pinentry/keyboardfocusindication.cpp b/src/pinentry/keyboardfocusindication.cpp
new file mode 100644
index 00000000..d783d981
--- /dev/null
+++ b/src/pinentry/keyboardfocusindication.cpp
@@ -0,0 +1,43 @@
+/* keyboardfocusindication.cpp - Helper for extended keyboard focus indication.
+ * Copyright (C) 2022 g10 Code GmbH
+ *
+ * Software engineering by Ingo Klöcker <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "keyboardfocusindication.h"
+
+#include "focusframe.h"
+
+#include <QApplication>
+
+KeyboardFocusIndication::KeyboardFocusIndication(QObject *parent)
+ : QObject{parent}
+{
+ connect(qApp, &QApplication::focusChanged, this, &KeyboardFocusIndication::updateFocusFrame);
+}
+
+void KeyboardFocusIndication::updateFocusFrame(QWidget *, QWidget *focusWidget)
+{
+ if (focusWidget && focusWidget->inherits("QLabel") && focusWidget->window()->testAttribute(Qt::WA_KeyboardFocusChange)) {
+ if (!focusFrame) {
+ focusFrame = new FocusFrame{focusWidget};
+ }
+ focusFrame->setWidget(focusWidget);
+ } else if (focusFrame) {
+ focusFrame->setWidget(nullptr);
+ }
+}
diff --git a/src/pinentry/keyboardfocusindication.h b/src/pinentry/keyboardfocusindication.h
new file mode 100644
index 00000000..e86a317e
--- /dev/null
+++ b/src/pinentry/keyboardfocusindication.h
@@ -0,0 +1,42 @@
+/* keyboardfocusindication.h - Helper for extended keyboard focus indication.
+ * Copyright (C) 2022 g10 Code GmbH
+ *
+ * Software engineering by Ingo Klöcker <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __KEYBOARDFOCUSINDICATION_H__
+#define __KEYBOARDFOCUSINDICATION_H__
+
+#include <QObject>
+#include <QPointer>
+#include <QWidget>
+
+class FocusFrame;
+
+class KeyboardFocusIndication : public QObject
+{
+ Q_OBJECT
+public:
+ KeyboardFocusIndication(QObject *parent);
+
+private:
+ void updateFocusFrame(QWidget *, QWidget *);
+
+ QPointer<FocusFrame> focusFrame;
+};
+
+#endif // __KEYBOARDFOCUSINDICATION_H__
diff --git a/src/pinentry/pinentry.cpp b/src/pinentry/pinentry.cpp
new file mode 100644
index 00000000..4a5f1408
--- /dev/null
+++ b/src/pinentry/pinentry.cpp
@@ -0,0 +1,926 @@
+/* pinentry.c - The PIN entry support library
+ * Copyright (C) 2002, 2003, 2007, 2008, 2010, 2015, 2016, 2021 g10 Code GmbH
+ *
+ * This file is part of PINENTRY.
+ *
+ * PINENTRY is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * PINENTRY is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef WINDOWS
+#include <errno.h>
+#endif
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#ifndef WINDOWS
+#include <sys/utsname.h>
+#endif
+#ifndef WINDOWS
+#include <locale.h>
+#endif
+#include <limits.h>
+#ifdef WINDOWS
+#include <windows.h>
+#endif
+
+#include <assuan.h>
+
+#include "core/utils/MemoryUtils.h"
+#include "pinentry.h"
+
+#ifdef WINDOWS
+#define getpid() GetCurrentProcessId()
+#endif
+
+/* Keep the name of our program here. */
+static char this_pgmname[50];
+
+struct pinentry pinentry;
+
+static const char *flavor_flag;
+
+/* Because gtk_init removes the --display arg from the command lines
+ * and our command line parser is called after gtk_init (so that it
+ * does not see gtk specific options) we don't have a way to get hold
+ * of the --display option. Our solution is to remember --display in
+ * the call to pinentry_have_display and set it then in our
+ * parser. */
+static char *remember_display;
+
+static void pinentry_reset(int use_defaults) {
+ /* GPG Agent sets these options once when it starts the pinentry.
+ Don't reset them. */
+ int grab = pinentry.grab;
+ char *ttyname = pinentry.ttyname;
+ char *ttytype = pinentry.ttytype_l;
+ char *ttyalert = pinentry.ttyalert;
+ char *lc_ctype = pinentry.lc_ctype;
+ char *lc_messages = pinentry.lc_messages;
+ int allow_external_password_cache = pinentry.allow_external_password_cache;
+ char *default_ok = pinentry.default_ok;
+ char *default_cancel = pinentry.default_cancel;
+ char *default_prompt = pinentry.default_prompt;
+ char *default_pwmngr = pinentry.default_pwmngr;
+ char *default_cf_visi = pinentry.default_cf_visi;
+ char *default_tt_visi = pinentry.default_tt_visi;
+ char *default_tt_hide = pinentry.default_tt_hide;
+ char *default_capshint = pinentry.default_capshint;
+ char *touch_file = pinentry.touch_file;
+ unsigned long owner_pid = pinentry.owner_pid;
+ int owner_uid = pinentry.owner_uid;
+ char *owner_host = pinentry.owner_host;
+ int constraints_enforce = pinentry.constraints_enforce;
+ char *constraints_hint_short = pinentry.constraints_hint_short;
+ char *constraints_hint_long = pinentry.constraints_hint_long;
+ char *constraints_error_title = pinentry.constraints_error_title;
+
+ /* These options are set from the command line. Don't reset
+ them. */
+ int debug = pinentry.debug;
+ char *display = pinentry.display;
+ int parent_wid = pinentry.parent_wid;
+
+ pinentry_color_t color_fg = pinentry.color_fg;
+ int color_fg_bright = pinentry.color_fg_bright;
+ pinentry_color_t color_bg = pinentry.color_bg;
+ pinentry_color_t color_so = pinentry.color_so;
+ int color_so_bright = pinentry.color_so_bright;
+ pinentry_color_t color_ok = pinentry.color_ok;
+ int color_ok_bright = pinentry.color_ok_bright;
+ pinentry_color_t color_qualitybar = pinentry.color_qualitybar;
+ int color_qualitybar_bright = pinentry.color_qualitybar_bright;
+
+ int timeout = pinentry.timeout;
+
+ char *invisible_char = pinentry.invisible_char;
+
+ /* Free any allocated memory. */
+ if (use_defaults) {
+ free(pinentry.ttyname);
+ free(pinentry.ttytype_l);
+ free(pinentry.ttyalert);
+ free(pinentry.lc_ctype);
+ free(pinentry.lc_messages);
+ free(pinentry.default_ok);
+ free(pinentry.default_cancel);
+ free(pinentry.default_prompt);
+ free(pinentry.default_pwmngr);
+ free(pinentry.default_cf_visi);
+ free(pinentry.default_tt_visi);
+ free(pinentry.default_tt_hide);
+ free(pinentry.default_capshint);
+ free(pinentry.touch_file);
+ free(pinentry.owner_host);
+ free(pinentry.display);
+ free(pinentry.constraints_hint_short);
+ free(pinentry.constraints_hint_long);
+ free(pinentry.constraints_error_title);
+ }
+
+ free(pinentry.title);
+ free(pinentry.description);
+ free(pinentry.error);
+ free(pinentry.prompt);
+ free(pinentry.ok);
+ free(pinentry.notok);
+ free(pinentry.cancel);
+ GpgFrontend::SecureFree(pinentry.pin);
+ free(pinentry.repeat_passphrase);
+ free(pinentry.repeat_error_string);
+ free(pinentry.quality_bar);
+ free(pinentry.quality_bar_tt);
+ free(pinentry.formatted_passphrase_hint);
+ free(pinentry.keyinfo);
+ free(pinentry.specific_err_info);
+
+ /* Reset the pinentry structure. */
+ memset(&pinentry, 0, sizeof(pinentry));
+
+ /* Restore options without a default we want to preserve. */
+ pinentry.invisible_char = invisible_char;
+
+ /* Restore other options or set defaults. */
+
+ if (use_defaults) {
+ /* Pinentry timeout in seconds. */
+ pinentry.timeout = 60;
+
+ /* Global grab. */
+ pinentry.grab = 1;
+
+ pinentry.color_fg = PINENTRY_COLOR_DEFAULT;
+ pinentry.color_fg_bright = 0;
+ pinentry.color_bg = PINENTRY_COLOR_DEFAULT;
+ pinentry.color_so = PINENTRY_COLOR_DEFAULT;
+ pinentry.color_so_bright = 0;
+ pinentry.color_ok = PINENTRY_COLOR_DEFAULT;
+ pinentry.color_ok_bright = 0;
+ pinentry.color_qualitybar = PINENTRY_COLOR_DEFAULT;
+ pinentry.color_qualitybar_bright = 0;
+
+ pinentry.owner_uid = -1;
+ } else /* Restore the options. */
+ {
+ pinentry.grab = grab;
+ pinentry.ttyname = ttyname;
+ pinentry.ttytype_l = ttytype;
+ pinentry.ttyalert = ttyalert;
+ pinentry.lc_ctype = lc_ctype;
+ pinentry.lc_messages = lc_messages;
+ pinentry.allow_external_password_cache = allow_external_password_cache;
+ pinentry.default_ok = default_ok;
+ pinentry.default_cancel = default_cancel;
+ pinentry.default_prompt = default_prompt;
+ pinentry.default_pwmngr = default_pwmngr;
+ pinentry.default_cf_visi = default_cf_visi;
+ pinentry.default_tt_visi = default_tt_visi;
+ pinentry.default_tt_hide = default_tt_hide;
+ pinentry.default_capshint = default_capshint;
+ pinentry.touch_file = touch_file;
+ pinentry.owner_pid = owner_pid;
+ pinentry.owner_uid = owner_uid;
+ pinentry.owner_host = owner_host;
+ pinentry.constraints_enforce = constraints_enforce;
+ pinentry.constraints_hint_short = constraints_hint_short;
+ pinentry.constraints_hint_long = constraints_hint_long;
+ pinentry.constraints_error_title = constraints_error_title;
+
+ pinentry.debug = debug;
+ pinentry.display = display;
+ pinentry.parent_wid = parent_wid;
+
+ pinentry.color_fg = color_fg;
+ pinentry.color_fg_bright = color_fg_bright;
+ pinentry.color_bg = color_bg;
+ pinentry.color_so = color_so;
+ pinentry.color_so_bright = color_so_bright;
+ pinentry.color_ok = color_ok;
+ pinentry.color_ok_bright = color_ok_bright;
+ pinentry.color_qualitybar = color_qualitybar;
+ pinentry.color_qualitybar_bright = color_qualitybar_bright;
+
+ pinentry.timeout = timeout;
+ }
+}
+
+static gpg_error_t pinentry_assuan_reset_handler(assuan_context_t ctx,
+ char *line) {
+ (void)ctx;
+ (void)line;
+
+ pinentry_reset(0);
+
+ return 0;
+}
+
+/* Copy TEXT or TEXTLEN to BUFFER and escape as required. Return a
+ pointer to the end of the new buffer. Note that BUFFER must be
+ large enough to keep the entire text; allocataing it 3 times of
+ TEXTLEN is sufficient. */
+static char *copy_and_escape(char *buffer, const void *text, size_t textlen) {
+ int i;
+ const unsigned char *s = (unsigned char *)text;
+ char *p = buffer;
+
+ for (i = 0; i < textlen; i++) {
+ if (s[i] < ' ' || s[i] == '+') {
+ snprintf(p, 4, "%%%02X", s[i]);
+ p += 3;
+ } else if (s[i] == ' ')
+ *p++ = '+';
+ else
+ *p++ = s[i];
+ }
+ return p;
+}
+
+/* Perform percent unescaping in STRING and return the new valid length
+ of the string. A terminating Nul character is inserted at the end of
+ the unescaped string.
+ */
+static size_t do_unescape_inplace(char *s) {
+ unsigned char *p, *p0;
+
+ p = p0 = (unsigned char *)s;
+ while (*s) {
+ if (*s == '%' && s[1] && s[2]) {
+ s++;
+ *p++ = xtoi_2(s);
+ s += 2;
+ } else
+ *p++ = *s++;
+ }
+ *p = 0;
+
+ return (p - p0);
+}
+
+/* Return a malloced copy of the commandline for PID. If this is not
+ * possible NULL is returned. */
+#ifndef WINDOWS
+static char *get_cmdline(unsigned long pid) {
+ char buffer[200];
+ FILE *fp;
+ size_t i, n;
+
+ snprintf(buffer, sizeof buffer, "/proc/%lu/cmdline", pid);
+
+ fp = fopen(buffer, "rb");
+ if (!fp) return NULL;
+ n = fread(buffer, 1, sizeof buffer - 1, fp);
+ if (n < sizeof buffer - 1 && ferror(fp)) {
+ /* Some error occurred. */
+ fclose(fp);
+ return NULL;
+ }
+ fclose(fp);
+ if (n == 0) return NULL;
+ /* Arguments are delimited by Nuls. We should do proper quoting but
+ * that can be a bit complicated, thus we simply replace the Nuls by
+ * spaces. */
+ for (i = 0; i < n; i++)
+ if (!buffer[i] && i < n - 1) buffer[i] = ' ';
+ buffer[i] = 0; /* Make sure the last byte is the string terminator. */
+
+ return strdup(buffer);
+}
+#endif /*!WINDOWS*/
+
+/* Atomically ask the kernel for information about process PID.
+ * Return a malloc'ed copy of the process name as long as the process
+ * uid matches UID. If it cannot determine that the process has uid
+ * UID, it returns NULL.
+ *
+ * This is not as informative as get_cmdline, but it verifies that the
+ * process does belong to the user in question.
+ */
+#ifndef WINDOWS
+static char *get_pid_name_for_uid(unsigned long pid, int uid) {
+ char buffer[400];
+ FILE *fp;
+ size_t end, n;
+ char *uidstr;
+
+ snprintf(buffer, sizeof buffer, "/proc/%lu/status", pid);
+
+ fp = fopen(buffer, "rb");
+ if (!fp) return NULL;
+ n = fread(buffer, 1, sizeof buffer - 1, fp);
+ if (n < sizeof buffer - 1 && ferror(fp)) {
+ /* Some error occurred. */
+ fclose(fp);
+ return NULL;
+ }
+ fclose(fp);
+ if (n == 0) return NULL;
+ buffer[n] = 0;
+ /* Fixme: Is it specified that "Name" is always the first line? For
+ * robustness I would prefer to have a real parser here. -wk */
+ if (strncmp(buffer, "Name:\t", 6)) return NULL;
+ end = strcspn(buffer + 6, "\n") + 6;
+ buffer[end] = 0;
+
+ /* check that uid matches what we expect */
+ uidstr = strstr(buffer + end + 1, "\nUid:\t");
+ if (!uidstr) return NULL;
+ if (atoi(uidstr + 6) != uid) return NULL;
+
+ return strdup(buffer + 6);
+}
+#endif /*!WINDOWS*/
+
+const char *pinentry_get_pgmname(void) { return this_pgmname; }
+
+/* Return a malloced string with the title. The caller mus free the
+ * string. If no title is available or the title string has an error
+ * NULL is returned. */
+char *pinentry_get_title(pinentry_t pe) {
+ char *title;
+
+ if (pe->title) title = strdup(pe->title);
+#ifndef WINDOWS
+ else if (pe->owner_pid) {
+ char buf[200];
+ struct utsname utsbuf;
+ char *pidname = NULL;
+ char *cmdline = NULL;
+
+ if (pe->owner_host && !uname(&utsbuf) &&
+ !strcmp(utsbuf.nodename, pe->owner_host)) {
+ pidname = get_pid_name_for_uid(pe->owner_pid, pe->owner_uid);
+ if (pidname) cmdline = get_cmdline(pe->owner_pid);
+ }
+
+ if (pe->owner_host && (cmdline || pidname))
+ snprintf(buf, sizeof buf, "[%lu]@%s (%s)", pe->owner_pid, pe->owner_host,
+ cmdline ? cmdline : pidname);
+ else if (pe->owner_host)
+ snprintf(buf, sizeof buf, "[%lu]@%s", pe->owner_pid, pe->owner_host);
+ else
+ snprintf(buf, sizeof buf, "[%lu] <unknown host>", pe->owner_pid);
+ free(pidname);
+ free(cmdline);
+ title = strdup(buf);
+ }
+#endif /*!WINDOWS*/
+ else
+ title = strdup(this_pgmname);
+
+ return title;
+}
+
+/* Run a quality inquiry for PASSPHRASE of LENGTH. (We need LENGTH
+ because not all backends might be able to return a proper
+ C-string.). Returns: A value between -100 and 100 to give an
+ estimate of the passphrase's quality. Negative values are use if
+ the caller won't even accept that passphrase. Note that we expect
+ just one data line which should not be escaped in any represent a
+ numeric signed decimal value. Extra data is currently ignored but
+ should not be send at all. */
+int pinentry_inq_quality(const QString &passphrase) {
+ int score = 0;
+
+ score += std::min(40, static_cast<int>(passphrase.length()) * 2);
+
+ bool has_upper = false;
+ bool has_lower = false;
+ bool has_digit = false;
+ bool has_special = false;
+ for (const auto ch : passphrase) {
+ if (ch.isUpper()) has_upper = true;
+ if (ch.isLower()) has_lower = true;
+ if (ch.isDigit()) has_digit = true;
+ if (!ch.isLetterOrNumber()) has_special = true;
+ }
+
+ int const variety_count =
+ static_cast<int>(has_upper) + static_cast<int>(has_lower) +
+ static_cast<int>(has_digit) + static_cast<int>(has_special);
+ score += variety_count * 10;
+
+ for (size_t i = 0; i < passphrase.length() - 1; ++i) {
+ if (passphrase[i] == passphrase[i + 1]) {
+ score -= 5;
+ }
+ }
+
+ std::unordered_map<QChar, int> char_count;
+ for (const auto ch : passphrase) {
+ char_count[ch]++;
+ }
+ for (auto &p : char_count) {
+ if (p.second > 1) {
+ score -= (p.second - 1) * 3;
+ }
+ }
+
+ QString const lower_password = passphrase.toLower();
+ if (lower_password.contains("password") ||
+ lower_password.contains("123456")) {
+ score -= 30;
+ }
+
+ return std::max(-100, std::min(100, score));
+}
+
+/* Run a checkpin inquiry */
+char *pinentry_inq_checkpin(pinentry_t pin, const char *passphrase,
+ size_t length) {
+ assuan_context_t ctx = (assuan_context_t)pin->ctx_assuan;
+ const char prefix[] = "INQUIRE CHECKPIN ";
+ char *command;
+ char *line;
+ size_t linelen;
+ int gotvalue = 0;
+ char *value = NULL;
+ int rc;
+
+ if (!ctx) return 0; /* Can't run the callback. */
+
+ if (length > 300)
+ length = 300; /* Limit so that it definitely fits into an Assuan
+ line. */
+
+ command =
+ GpgFrontend::SecureMallocAsType<char>(strlen(prefix) + 3 * length + 1);
+ if (!command) return 0;
+ strcpy(command, prefix);
+ copy_and_escape(command + strlen(command), passphrase, length);
+ rc = assuan_write_line(ctx, command);
+ GpgFrontend::SecureFree(command);
+ if (rc) {
+ fprintf(stderr, "ASSUAN WRITE LINE failed: rc=%d\n", rc);
+ return 0;
+ }
+
+ for (;;) {
+ do {
+ rc = assuan_read_line(ctx, &line, &linelen);
+ if (rc) {
+ fprintf(stderr, "ASSUAN READ LINE failed: rc=%d\n", rc);
+ return 0;
+ }
+ } while (*line == '#' || !linelen);
+ if (line[0] == 'E' && line[1] == 'N' && line[2] == 'D' &&
+ (!line[3] || line[3] == ' '))
+ break; /* END command received*/
+ if (line[0] == 'C' && line[1] == 'A' && line[2] == 'N' &&
+ (!line[3] || line[3] == ' '))
+ break; /* CAN command received*/
+ if (line[0] == 'E' && line[1] == 'R' && line[2] == 'R' &&
+ (!line[3] || line[3] == ' '))
+ break; /* ERR command received*/
+ if (line[0] != 'D' || line[1] != ' ' || linelen < 3 || gotvalue) continue;
+ gotvalue = 1;
+ value = strdup(line + 2);
+ }
+
+ return value;
+}
+
+/* Run a genpin inquiry */
+char *pinentry_inq_genpin(pinentry_t pin) {
+ assuan_context_t ctx = (assuan_context_t)pin->ctx_assuan;
+ const char prefix[] = "INQUIRE GENPIN";
+ char *line;
+ size_t linelen;
+ int gotvalue = 0;
+ char *value = NULL;
+ int rc;
+
+ if (!ctx) return 0; /* Can't run the callback. */
+
+ rc = assuan_write_line(ctx, prefix);
+ if (rc) {
+ fprintf(stderr, "ASSUAN WRITE LINE failed: rc=%d\n", rc);
+ return 0;
+ }
+
+ for (;;) {
+ do {
+ rc = assuan_read_line(ctx, &line, &linelen);
+ if (rc) {
+ fprintf(stderr, "ASSUAN READ LINE failed: rc=%d\n", rc);
+ free(value);
+ return 0;
+ }
+ } while (*line == '#' || !linelen);
+ if (line[0] == 'E' && line[1] == 'N' && line[2] == 'D' &&
+ (!line[3] || line[3] == ' '))
+ break; /* END command received*/
+ if (line[0] == 'C' && line[1] == 'A' && line[2] == 'N' &&
+ (!line[3] || line[3] == ' '))
+ break; /* CAN command received*/
+ if (line[0] == 'E' && line[1] == 'R' && line[2] == 'R' &&
+ (!line[3] || line[3] == ' '))
+ break; /* ERR command received*/
+ if (line[0] != 'D' || line[1] != ' ' || linelen < 3 || gotvalue) continue;
+ gotvalue = 1;
+ value = strdup(line + 2);
+ }
+
+ return value;
+}
+
+/* Try to make room for at least LEN bytes in the pinentry. Returns
+ new buffer on success and 0 on failure or when the old buffer is
+ sufficient. */
+char *pinentry_setbufferlen(pinentry_t pin, int len) {
+ char *newp;
+
+ if (pin->pin_len)
+ assert(pin->pin);
+ else
+ assert(!pin->pin);
+
+ if (len < 2048) len = 2048;
+
+ if (len <= pin->pin_len) return pin->pin;
+
+ newp = GpgFrontend::SecureReallocAsType<char>(pin->pin, len);
+ if (newp) {
+ pin->pin = newp;
+ pin->pin_len = len;
+ } else {
+ GpgFrontend::SecureFree(pin->pin);
+ pin->pin = 0;
+ pin->pin_len = 0;
+ }
+ return newp;
+}
+
+static void pinentry_setbuffer_clear(pinentry_t pin) {
+ if (!pin->pin) {
+ assert(pin->pin_len == 0);
+ return;
+ }
+
+ assert(pin->pin_len > 0);
+
+ GpgFrontend::SecureFree(pin->pin);
+ pin->pin = NULL;
+ pin->pin_len = 0;
+}
+
+/* passphrase better be alloced with secmem_alloc. */
+void pinentry_setbuffer_use(pinentry_t pin, char *passphrase, int len) {
+ if (!passphrase) {
+ assert(len == 0);
+ pinentry_setbuffer_clear(pin);
+
+ return;
+ }
+
+ if (passphrase && len == 0) len = strlen(passphrase) + 1;
+
+ if (pin->pin) GpgFrontend::SecureFree(pin->pin);
+
+ pin->pin = passphrase;
+ pin->pin_len = len;
+}
+
+static struct assuan_malloc_hooks assuan_malloc_hooks = {
+ GpgFrontend::SecureMalloc, GpgFrontend::SecureRealloc,
+ GpgFrontend::SecureFree};
+
+/* Initialize the secure memory subsystem, drop privileges and return.
+ Must be called early. */
+void pinentry_init(const char *pgmname) {
+ /* Store away our name. */
+ if (strlen(pgmname) > sizeof this_pgmname - 2) abort();
+ strcpy(this_pgmname, pgmname);
+
+ gpgrt_check_version(NULL);
+
+ assuan_set_malloc_hooks(&assuan_malloc_hooks);
+}
+
+/* Simple test to check whether DISPLAY is set or the option --display
+ was given. Used to decide whether the GUI or curses should be
+ initialized. */
+int pinentry_have_display(int argc, char **argv) {
+ int found = 0;
+
+ for (; argc; argc--, argv++) {
+ if (!strcmp(*argv, "--display")) {
+ if (argv[1] && !remember_display) {
+ remember_display = strdup(argv[1]);
+ if (!remember_display) {
+#ifndef WINDOWS
+ fprintf(stderr, "%s: %s\n", this_pgmname, strerror(errno));
+#endif
+ exit(EXIT_FAILURE);
+ }
+ }
+ found = 1;
+ break;
+ } else if (!strncmp(*argv, "--display=", 10)) {
+ if (!remember_display) {
+ remember_display = strdup(*argv + 10);
+ if (!remember_display) {
+#ifndef WINDOWS
+ fprintf(stderr, "%s: %s\n", this_pgmname, strerror(errno));
+#endif
+ exit(EXIT_FAILURE);
+ }
+ }
+ found = 1;
+ break;
+ }
+ }
+
+#ifndef WINDOWS
+ {
+ const char *s;
+ s = getenv("DISPLAY");
+ if (s && *s) found = 1;
+ }
+#endif
+
+ return found;
+}
+
+/* Print usage information and and provide strings for help. */
+static const char *my_strusage(int level) {
+ const char *p;
+
+ switch (level) {
+ case 11:
+ p = this_pgmname;
+ break;
+ case 12:
+ p = "pinentry";
+ break;
+ case 13:
+ p = 0;
+ break;
+ case 14:
+ p = "Copyright (C) 2023 Saturneric";
+ break;
+ case 19:
+ p = "Please report bugs to <[email protected]>.\n";
+ break;
+ case 1:
+ case 40: {
+ static char *str;
+
+ if (!str) {
+ size_t n = 50 + strlen(this_pgmname);
+ str = static_cast<char *>(malloc(n));
+ if (str) {
+ snprintf(str, n, "Usage: %s [options] (-h for help)", this_pgmname);
+ }
+ }
+ p = str;
+ } break;
+ case 41:
+ p = "Ask securely for a secret and print it to stdout.";
+ break;
+
+ case 42:
+ p = "1"; /* Flag print 40 as part of 41. */
+ break;
+
+ default:
+ p = NULL;
+ break;
+ }
+ return p;
+}
+
+char *parse_color(char *arg, pinentry_color_t *color_p, int *bright_p) {
+ static struct {
+ const char *name;
+ pinentry_color_t color;
+ } colors[] = {
+ {"none", PINENTRY_COLOR_NONE}, {"default", PINENTRY_COLOR_DEFAULT},
+ {"black", PINENTRY_COLOR_BLACK}, {"red", PINENTRY_COLOR_RED},
+ {"green", PINENTRY_COLOR_GREEN}, {"yellow", PINENTRY_COLOR_YELLOW},
+ {"blue", PINENTRY_COLOR_BLUE}, {"magenta", PINENTRY_COLOR_MAGENTA},
+ {"cyan", PINENTRY_COLOR_CYAN}, {"white", PINENTRY_COLOR_WHITE}};
+
+ int i;
+ char *new_arg;
+ pinentry_color_t color = PINENTRY_COLOR_DEFAULT;
+
+ if (!arg) return NULL;
+
+ new_arg = strchr(arg, ',');
+ if (new_arg) new_arg++;
+
+ if (bright_p) {
+ const char *bname[] = {"bright-", "bright", "bold-", "bold"};
+
+ *bright_p = 0;
+ for (i = 0; i < sizeof(bname) / sizeof(bname[0]); i++)
+ if (!strncasecmp(arg, bname[i], strlen(bname[i]))) {
+ *bright_p = 1;
+ arg += strlen(bname[i]);
+ }
+ }
+
+ for (i = 0; i < sizeof(colors) / sizeof(colors[0]); i++)
+ if (!strncasecmp(arg, colors[i].name, strlen(colors[i].name)))
+ color = colors[i].color;
+
+ *color_p = color;
+ return new_arg;
+}
+
+/* Set the optional flag used with getinfo. */
+void pinentry_set_flavor_flag(const char *string) { flavor_flag = string; }
+
+static gpg_error_t option_handler(assuan_context_t ctx, const char *key,
+ const char *value) {
+ (void)ctx;
+
+ if (!strcmp(key, "no-grab") && !*value)
+ pinentry.grab = 0;
+ else if (!strcmp(key, "grab") && !*value)
+ pinentry.grab = 1;
+ else if (!strcmp(key, "debug-wait")) {
+#ifndef WINDOWS
+ fprintf(stderr, "%s: waiting for debugger - my pid is %u ...\n",
+ this_pgmname, (unsigned int)getpid());
+ sleep(*value ? atoi(value) : 5);
+ fprintf(stderr, "%s: ... okay\n", this_pgmname);
+#endif
+ } else if (!strcmp(key, "display")) {
+ if (pinentry.display) free(pinentry.display);
+ pinentry.display = strdup(value);
+ if (!pinentry.display) return gpg_error_from_syserror();
+ } else if (!strcmp(key, "ttyname")) {
+ if (pinentry.ttyname) free(pinentry.ttyname);
+ pinentry.ttyname = strdup(value);
+ if (!pinentry.ttyname) return gpg_error_from_syserror();
+ } else if (!strcmp(key, "ttytype")) {
+ if (pinentry.ttytype_l) free(pinentry.ttytype_l);
+ pinentry.ttytype_l = strdup(value);
+ if (!pinentry.ttytype_l) return gpg_error_from_syserror();
+ } else if (!strcmp(key, "ttyalert")) {
+ if (pinentry.ttyalert) free(pinentry.ttyalert);
+ pinentry.ttyalert = strdup(value);
+ if (!pinentry.ttyalert) return gpg_error_from_syserror();
+ } else if (!strcmp(key, "lc-ctype")) {
+ if (pinentry.lc_ctype) free(pinentry.lc_ctype);
+ pinentry.lc_ctype = strdup(value);
+ if (!pinentry.lc_ctype) return gpg_error_from_syserror();
+ } else if (!strcmp(key, "lc-messages")) {
+ if (pinentry.lc_messages) free(pinentry.lc_messages);
+ pinentry.lc_messages = strdup(value);
+ if (!pinentry.lc_messages) return gpg_error_from_syserror();
+ } else if (!strcmp(key, "owner")) {
+ long along;
+ char *endp;
+
+ free(pinentry.owner_host);
+ pinentry.owner_host = NULL;
+ pinentry.owner_uid = -1;
+ pinentry.owner_pid = 0;
+
+ errno = 0;
+ along = strtol(value, &endp, 10);
+ if (along && !errno) {
+ pinentry.owner_pid = (unsigned long)along;
+ if (*endp) {
+ errno = 0;
+ if (*endp == '/') { /* we have a uid */
+ endp++;
+ along = strtol(endp, &endp, 10);
+ if (along >= 0 && !errno) pinentry.owner_uid = (int)along;
+ }
+ if (endp) {
+ while (*endp == ' ') endp++;
+ if (*endp) {
+ pinentry.owner_host = strdup(endp);
+ for (endp = pinentry.owner_host; *endp && *endp != ' '; endp++)
+ ;
+ *endp = 0;
+ }
+ }
+ }
+ }
+ } else if (!strcmp(key, "parent-wid")) {
+ pinentry.parent_wid = atoi(value);
+ /* FIXME: Use strtol and add some error handling. */
+ } else if (!strcmp(key, "touch-file")) {
+ if (pinentry.touch_file) free(pinentry.touch_file);
+ pinentry.touch_file = strdup(value);
+ if (!pinentry.touch_file) return gpg_error_from_syserror();
+ } else if (!strcmp(key, "default-ok")) {
+ pinentry.default_ok = strdup(value);
+ if (!pinentry.default_ok) return gpg_error_from_syserror();
+ } else if (!strcmp(key, "default-cancel")) {
+ pinentry.default_cancel = strdup(value);
+ if (!pinentry.default_cancel) return gpg_error_from_syserror();
+ } else if (!strcmp(key, "default-prompt")) {
+ pinentry.default_prompt = strdup(value);
+ if (!pinentry.default_prompt) return gpg_error_from_syserror();
+ } else if (!strcmp(key, "default-pwmngr")) {
+ pinentry.default_pwmngr = strdup(value);
+ if (!pinentry.default_pwmngr) return gpg_error_from_syserror();
+ } else if (!strcmp(key, "default-cf-visi")) {
+ pinentry.default_cf_visi = strdup(value);
+ if (!pinentry.default_cf_visi) return gpg_error_from_syserror();
+ } else if (!strcmp(key, "default-tt-visi")) {
+ pinentry.default_tt_visi = strdup(value);
+ if (!pinentry.default_tt_visi) return gpg_error_from_syserror();
+ } else if (!strcmp(key, "default-tt-hide")) {
+ pinentry.default_tt_hide = strdup(value);
+ if (!pinentry.default_tt_hide) return gpg_error_from_syserror();
+ } else if (!strcmp(key, "default-capshint")) {
+ pinentry.default_capshint = strdup(value);
+ if (!pinentry.default_capshint) return gpg_error_from_syserror();
+ } else if (!strcmp(key, "allow-external-password-cache") && !*value) {
+ pinentry.allow_external_password_cache = 1;
+ pinentry.tried_password_cache = 0;
+ } else if (!strcmp(key, "allow-emacs-prompt") && !*value) {
+#ifdef INSIDE_EMACS
+ pinentry_enable_emacs_cmd_handler();
+#endif
+ } else if (!strcmp(key, "invisible-char")) {
+ if (pinentry.invisible_char) free(pinentry.invisible_char);
+ pinentry.invisible_char = strdup(value);
+ if (!pinentry.invisible_char) return gpg_error_from_syserror();
+ } else if (!strcmp(key, "formatted-passphrase") && !*value) {
+ pinentry.formatted_passphrase = 1;
+ } else if (!strcmp(key, "formatted-passphrase-hint")) {
+ if (pinentry.formatted_passphrase_hint)
+ free(pinentry.formatted_passphrase_hint);
+ pinentry.formatted_passphrase_hint = strdup(value);
+ if (!pinentry.formatted_passphrase_hint) return gpg_error_from_syserror();
+ do_unescape_inplace(pinentry.formatted_passphrase_hint);
+ } else if (!strcmp(key, "constraints-enforce") && !*value)
+ pinentry.constraints_enforce = 1;
+ else if (!strcmp(key, "constraints-hint-short")) {
+ if (pinentry.constraints_hint_short) free(pinentry.constraints_hint_short);
+ pinentry.constraints_hint_short = strdup(value);
+ if (!pinentry.constraints_hint_short) return gpg_error_from_syserror();
+ do_unescape_inplace(pinentry.constraints_hint_short);
+ } else if (!strcmp(key, "constraints-hint-long")) {
+ if (pinentry.constraints_hint_long) free(pinentry.constraints_hint_long);
+ pinentry.constraints_hint_long = strdup(value);
+ if (!pinentry.constraints_hint_long) return gpg_error_from_syserror();
+ do_unescape_inplace(pinentry.constraints_hint_long);
+ } else if (!strcmp(key, "constraints-error-title")) {
+ if (pinentry.constraints_error_title)
+ free(pinentry.constraints_error_title);
+ pinentry.constraints_error_title = strdup(value);
+ if (!pinentry.constraints_error_title) return gpg_error_from_syserror();
+ do_unescape_inplace(pinentry.constraints_error_title);
+ } else
+ return gpg_error(GPG_ERR_UNKNOWN_OPTION);
+ return 0;
+}
+
+/* Note, that it is sufficient to allocate the target string D as
+ long as the source string S, i.e.: strlen(s)+1; */
+static void strcpy_escaped(char *d, const char *s) {
+ while (*s) {
+ if (*s == '%' && s[1] && s[2]) {
+ s++;
+ *d++ = xtoi_2(s);
+ s += 2;
+ } else
+ *d++ = *s++;
+ }
+ *d = 0;
+}
+
+/* Return a staically allocated string with information on the mode,
+ * uid, and gid of DEVICE. On error "?" is returned if DEVICE is
+ * NULL, "-" is returned. */
+static const char *device_stat_string(const char *device) {
+#ifdef HAVE_STAT
+ static char buf[40];
+ struct stat st;
+
+ if (!device || !*device) return "-";
+
+ if (stat(device, &st)) return "?"; /* Error */
+ snprintf(buf, sizeof buf, "%lo/%lu/%lu", (unsigned long)st.st_mode,
+ (unsigned long)st.st_uid, (unsigned long)st.st_gid);
+ return buf;
+#else
+ return "-";
+#endif
+} \ No newline at end of file
diff --git a/src/pinentry/pinentry.h b/src/pinentry/pinentry.h
new file mode 100644
index 00000000..80452e93
--- /dev/null
+++ b/src/pinentry/pinentry.h
@@ -0,0 +1,355 @@
+/* pinentry.h - The interface for the PIN entry support library.
+ * Copyright (C) 2002, 2003, 2010, 2015, 2021 g10 Code GmbH
+ *
+ * This file is part of PINENTRY.
+ *
+ * PINENTRY is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * PINENTRY is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef PINENTRY_H
+#define PINENTRY_H
+
+#include <cstdint>
+
+#ifdef __cplusplus
+extern "C" {
+#if 0
+}
+#endif
+#endif
+
+typedef enum {
+ PINENTRY_COLOR_NONE,
+ PINENTRY_COLOR_DEFAULT,
+ PINENTRY_COLOR_BLACK,
+ PINENTRY_COLOR_RED,
+ PINENTRY_COLOR_GREEN,
+ PINENTRY_COLOR_YELLOW,
+ PINENTRY_COLOR_BLUE,
+ PINENTRY_COLOR_MAGENTA,
+ PINENTRY_COLOR_CYAN,
+ PINENTRY_COLOR_WHITE
+} pinentry_color_t;
+
+struct pinentry {
+ /* The window title, or NULL. (Assuan: "SETTITLE TITLE".) */
+ char *title;
+ /* The description to display, or NULL. (Assuan: "SETDESC
+ DESC".) */
+ char *description;
+ /* The error message to display, or NULL. (Assuan: "SETERROR
+ MESSAGE".) */
+ char *error;
+ /* The prompt to display, or NULL. (Assuan: "SETPROMPT
+ prompt".) */
+ char *prompt;
+ /* The OK button text to display, or NULL. (Assuan: "SETOK
+ OK".) */
+ char *ok;
+ /* The Not-OK button text to display, or NULL. This is the text for
+ the alternative option shown by the third button. (Assuan:
+ "SETNOTOK NOTOK".) */
+ char *notok;
+ /* The Cancel button text to display, or NULL. (Assuan: "SETCANCEL
+ CANCEL".) */
+ char *cancel;
+
+ /* The buffer to store the secret into. */
+ char *pin;
+ /* The length of the buffer. */
+ int pin_len;
+ /* Whether the pin was read from an external cache (1) or entered by
+ the user (0). */
+ int pin_from_cache;
+
+ /* The name of the X display to use if X is available and supported.
+ (Assuan: "OPTION display DISPLAY".) */
+ char *display;
+ /* The name of the terminal node to open if X not available or
+ supported. (Assuan: "OPTION ttyname TTYNAME".) */
+ char *ttyname;
+ /* The type of the terminal. (Assuan: "OPTION ttytype TTYTYPE".) */
+ char *ttytype_l;
+ /* Set the alert mode (none, beep or flash). */
+ char *ttyalert;
+ /* The LC_CTYPE value for the terminal. (Assuan: "OPTION lc-ctype
+ LC_CTYPE".) */
+ char *lc_ctype;
+ /* The LC_MESSAGES value for the terminal. (Assuan: "OPTION
+ lc-messages LC_MESSAGES".) */
+ char *lc_messages;
+
+ /* True if debug mode is requested. */
+ int debug;
+
+ /* The number of seconds before giving up while waiting for user input. */
+ int timeout;
+
+ /* True if caller should grab the keyboard. (Assuan: "OPTION grab"
+ or "OPTION no-grab".) */
+ int grab;
+
+ /* The PID of the owner or 0 if not known. The owner is the process
+ * which actually triggered the the pinentry. For example gpg. */
+ unsigned long owner_pid;
+
+ /* The numeric uid (user ID) of the owner process or -1 if not
+ * known. */
+ int owner_uid;
+
+ /* The malloced hostname of the owner or NULL. */
+ char *owner_host;
+
+ /* The window ID of the parent window over which the pinentry window
+ should be displayed. (Assuan: "OPTION parent-wid WID".) */
+ int parent_wid;
+
+ /* The name of an optional file which will be touched after a curses
+ entry has been displayed. (Assuan: "OPTION touch-file
+ FILENAME".) */
+ char *touch_file;
+
+ /* The frontend should set this to -1 if the user canceled the
+ request, and to the length of the PIN stored in pin
+ otherwise. */
+ int result;
+
+ /* The frontend should set this if the NOTOK button was pressed. */
+ int canceled;
+
+ /* The frontend should set this to true if an error with the local
+ conversion occurred. */
+ int locale_err;
+
+ /* The frontend should set this to a gpg-error so that commands are
+ able to return specific error codes. This is an ugly hack due to
+ the fact that pinentry_cmd_handler_t returns the length of the
+ passphrase or a negative error code. */
+ int specific_err;
+
+ /* The frontend may store a string with the error location here. */
+ const char *specific_err_loc;
+
+ /* The frontend may store a malloced string here to emit an ERROR
+ * status code with this extra info along with SPECIFIC_ERR. */
+ char *specific_err_info;
+
+ /* The frontend should set this to true if the window close button
+ has been used. This flag is used in addition to a regular return
+ value. */
+ int close_button;
+
+ /* The caller should set this to true if only one button is
+ required. This is useful for notification dialogs where only a
+ dismiss button is required. */
+ int one_button;
+
+ /* Whether this is a CONFIRM pinentry. */
+ int confirm;
+
+ /* If true a second prompt for the passphrase is shown and the user
+ is expected to enter the same passphrase again. Pinentry checks
+ that both match. (Assuan: "SETREPEAT".) */
+ char *repeat_passphrase;
+
+ /* The string to show if a repeated passphrase does not match.
+ (Assuan: "SETREPEATERROR ERROR".) */
+ char *repeat_error_string;
+
+ /* The string to show if a repeated passphrase does match.
+ (Assuan: "SETREPEATOK STRING".) */
+ char *repeat_ok_string;
+
+ /* Set to true if the passphrase has been entered a second time and
+ matches the first passphrase. */
+ int repeat_okay;
+
+ /* If this is not NULL, a passphrase quality indicator is shown.
+ There will also be an inquiry back to the caller to get an
+ indication of the quality for the passphrase entered so far. The
+ string is used as a label for the quality bar. (Assuan:
+ "SETQUALITYBAR LABEL".) */
+ char *quality_bar;
+
+ /* The tooltip to be shown for the qualitybar. Malloced or NULL.
+ (Assuan: "SETQUALITYBAR_TT TOOLTIP".) */
+ char *quality_bar_tt;
+
+ /* If this is not NULL, a generate action should be shown.
+ There will be an inquiry back to the caller to get such a
+ PIN. generate action. Malloced or NULL.
+ (Assuan: "SETGENPIN LABEL" .) */
+ char *genpin_label;
+
+ /* The tooltip to be shown for the generate action. Malloced or NULL.
+ (Assuan: "SETGENPIN_TT TOOLTIP".) */
+ char *genpin_tt;
+
+ /* Specifies whether passphrase formatting should be enabled.
+ (Assuan: "OPTION formatted-passphrase") */
+ int formatted_passphrase;
+
+ /* A hint to be shown near the passphrase input field if passphrase
+ formatting is enabled. Malloced or NULL.
+ (Assuan: "OPTION formatted-passphrase-hint=HINT".) */
+ char *formatted_passphrase_hint;
+
+ /* For the curses pinentry, the color of error messages. */
+ pinentry_color_t color_fg;
+ int color_fg_bright;
+ pinentry_color_t color_bg;
+ pinentry_color_t color_so;
+ int color_so_bright;
+ pinentry_color_t color_ok;
+ int color_ok_bright;
+ pinentry_color_t color_qualitybar;
+ int color_qualitybar_bright;
+
+ /* Malloced and i18ned default strings or NULL. These strings may
+ include an underscore character to indicate an accelerator key.
+ A double underscore represents a plain one. */
+ /* (Assuan: "OPTION default-ok OK"). */
+ char *default_ok;
+ /* (Assuan: "OPTION default-cancel CANCEL"). */
+ char *default_cancel;
+ /* (Assuan: "OPTION default-prompt PROMPT"). */
+ char *default_prompt;
+ /* (Assuan: "OPTION default-pwmngr
+ SAVE_PASSWORD_WITH_PASSWORD_MANAGER?"). */
+ char *default_pwmngr;
+ /* (Assuan: "OPTION default-cf-visi
+ Do you really want to make your passphrase visible?"). */
+ char *default_cf_visi;
+ /* (Assuan: "OPTION default-tt-visi
+ Make passphrase visible?"). */
+ char *default_tt_visi;
+ /* (Assuan: "OPTION default-tt-hide
+ Hide passphrase"). */
+ char *default_tt_hide;
+ /* (Assuan: "OPTION default-capshint
+ Caps Lock is on"). */
+ char *default_capshint;
+
+ /* Whether we are allowed to read the password from an external
+ cache. (Assuan: "OPTION allow-external-password-cache") */
+ int allow_external_password_cache;
+
+ /* We only try the cache once. */
+ int tried_password_cache;
+
+ /* A stable identifier for the key. (Assuan: "SETKEYINFO
+ KEYINFO".) */
+ char *keyinfo;
+
+ /* Whether we may cache the password (according to the user). */
+ int may_cache_password;
+
+ /* NOTE: If you add any additional fields to this structure, be sure
+ to update the initializer in pinentry/pinentry.c!!! */
+
+ /* For the quality indicator and genpin we need to do an inquiry.
+ Thus we need to save the assuan ctx. */
+ void *ctx_assuan;
+
+ /* An UTF-8 string with an invisible character used to override the
+ default in some pinentries. Only the first character is
+ used. */
+ char *invisible_char;
+
+ /* Whether the passphrase constraints are enforced by gpg-agent.
+ (Assuan: "OPTION constraints-enforce") */
+ int constraints_enforce;
+
+ /* A short translated hint for the user with the constraints for new
+ passphrases to be displayed near the passphrase input field.
+ Malloced or NULL.
+ (Assuan: "OPTION constraints-hint-short=At least 8 characters".) */
+ char *constraints_hint_short;
+
+ /* A longer translated hint for the user with the constraints for new
+ passphrases to be displayed for example as tooltip. Malloced or NULL.
+ (Assuan: "OPTION constraints-hint-long=The passphrase must ...".) */
+ char *constraints_hint_long;
+
+ /* A short translated title for an error dialog informing the user about
+ unsatisfied passphrase constraints. Malloced or NULL.
+ (Assuan: "OPTION constraints-error-title=Passphrase Not Allowed".) */
+ char *constraints_error_title;
+};
+typedef struct pinentry *pinentry_t;
+
+/* The pinentry command handler type processes the pinentry request
+ PIN. If PIN->pin is zero, request a confirmation, otherwise a PIN
+ entry. On confirmation, the function should return TRUE if
+ confirmed, and FALSE otherwise. On PIN entry, the function should
+ return -1 if an error occurred or the user cancelled the operation
+ and 1 otherwise. */
+typedef int (*pinentry_cmd_handler_t)(pinentry_t pin);
+
+const char *pinentry_get_pgmname(void);
+
+char *pinentry_get_title(pinentry_t pe);
+
+/* Run a quality inquiry for PASSPHRASE of LENGTH. */
+int pinentry_inq_quality(const QString &passphrase);
+
+/* Run a checkpin inquiry for PASSPHRASE of LENGTH. Returns NULL, if the
+ passphrase satisfies the constraints. Otherwise, returns a malloced error
+ string. */
+char *pinentry_inq_checkpin(pinentry_t pin, const char *passphrase,
+ std::size_t length);
+
+/* Run a genpin iquriry. Returns a malloced string or NULL */
+char *pinentry_inq_genpin(pinentry_t pin);
+
+/* Try to make room for at least LEN bytes for the pin in the pinentry
+ PIN. Returns new buffer on success and 0 on failure. */
+char *pinentry_setbufferlen(pinentry_t pin, int len);
+
+/* Use the buffer at BUFFER for PIN->PIN. BUFFER must be NULL or
+ allocated using secmem_alloc. LEN is the size of the buffer. If
+ it is unknown, but BUFFER is a NUL terminated string, you pass 0 to
+ just use strlen(buffer)+1. */
+void pinentry_setbuffer_use(pinentry_t pin, char *buffer, int len);
+
+/* Initialize the secure memory subsystem, drop privileges and
+ return. Must be called early. */
+void pinentry_init(const char *pgmname);
+
+/* Return true if either DISPLAY is set or ARGV contains the string
+ "--display". */
+int pinentry_have_display(int argc, char **argv);
+
+/* Parse the command line options. May exit the program if only help
+ or version output is requested. */
+void pinentry_parse_opts(int argc, char *argv[]);
+
+/* Set the optional flag used with getinfo. */
+void pinentry_set_flavor_flag(const char *string);
+
+#ifdef WINDOWS
+/* Windows declares sleep as obsolete, but provides a definition for
+ _sleep but non for the still existing sleep. */
+#define sleep(a) _sleep((a))
+#endif /*WINDOWS*/
+
+#if 0
+{
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PINENTRY_H */
diff --git a/src/pinentry/pinentry_debug.cpp b/src/pinentry/pinentry_debug.cpp
new file mode 100644
index 00000000..9afbcdb3
--- /dev/null
+++ b/src/pinentry/pinentry_debug.cpp
@@ -0,0 +1,31 @@
+/* pinentry_debug.h - Logging category for pinentry
+ * Copyright (C) 2021 g10 Code GmbH
+ *
+ * Software engineering by Ingo Klöcker <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "pinentry_debug.h"
+
+#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
+Q_LOGGING_CATEGORY(PINENTRY_LOG, "gpg.pinentry", QtWarningMsg)
+#else
+Q_LOGGING_CATEGORY(PINENTRY_LOG, "gpg.pinentry")
+#endif
diff --git a/src/pinentry/pinentry_debug.h b/src/pinentry/pinentry_debug.h
new file mode 100644
index 00000000..fc8c808a
--- /dev/null
+++ b/src/pinentry/pinentry_debug.h
@@ -0,0 +1,28 @@
+/* pinentry_debug.h - Logging category for pinentry
+ * Copyright (C) 2021 g10 Code GmbH
+ *
+ * Software engineering by Ingo Klöcker <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __PINENTRY_QT_DEBUG_H__
+#define __PINENTRY_QT_DEBUG_H__
+
+#include <QLoggingCategory>
+
+Q_DECLARE_LOGGING_CATEGORY(PINENTRY_LOG)
+
+#endif // __PINENTRY_QT_DEBUG_H__
diff --git a/src/pinentry/pinentryconfirm.cpp b/src/pinentry/pinentryconfirm.cpp
new file mode 100644
index 00000000..31d55b5c
--- /dev/null
+++ b/src/pinentry/pinentryconfirm.cpp
@@ -0,0 +1,123 @@
+/* pinentryconfirm.cpp - A QMessageBox with a timeout
+ *
+ * Copyright (C) 2011 Ben Kibbey <[email protected]>
+ * Copyright (C) 2022 g10 Code GmbH
+ *
+ * Software engineering by Ingo Klöcker <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "pinentryconfirm.h"
+
+#include <QAbstractButton>
+#include <QApplication>
+#include <QFontMetrics>
+#include <QGridLayout>
+#include <QLabel>
+#include <QSpacerItem>
+
+#include "accessibility.h"
+#include "pinentrydialog.h"
+
+namespace {
+QLabel *messageBoxLabel(QMessageBox *messageBox) {
+ return messageBox->findChild<QLabel *>(QStringLiteral("qt_msgbox_label"));
+}
+} // namespace
+
+PinentryConfirm::PinentryConfirm(Icon icon, const QString &title,
+ const QString &text, StandardButtons buttons,
+ QWidget *parent, Qt::WindowFlags flags)
+ : QMessageBox{icon, title, text, buttons, parent, flags} {
+ _timer.callOnTimeout(this, &PinentryConfirm::slotTimeout);
+
+#ifndef QT_NO_ACCESSIBILITY
+ QAccessible::installActivationObserver(this);
+ accessibilityActiveChanged(QAccessible::isActive());
+#endif
+
+#if QT_VERSION >= 0x050000
+ /* This is in line with PinentryDialog ctor to have a maximizing
+ * animation when opening. */
+ if (qApp->platformName() != QLatin1String("wayland")) {
+ setWindowState(Qt::WindowMinimized);
+ QTimer::singleShot(0, this, [this]() { raiseWindow(this); });
+ }
+#else
+ activateWindow();
+ raise();
+#endif
+}
+
+PinentryConfirm::~PinentryConfirm() {
+#ifndef QT_NO_ACCESSIBILITY
+ QAccessible::removeActivationObserver(this);
+#endif
+}
+
+void PinentryConfirm::setTimeout(std::chrono::seconds timeout) {
+ _timer.setInterval(timeout);
+}
+
+std::chrono::seconds PinentryConfirm::timeout() const {
+ return std::chrono::duration_cast<std::chrono::seconds>(
+ _timer.intervalAsDuration());
+}
+
+bool PinentryConfirm::timedOut() const { return _timed_out; }
+
+void PinentryConfirm::showEvent(QShowEvent *event) {
+ static bool resized;
+ if (!resized) {
+ QGridLayout *lay = dynamic_cast<QGridLayout *>(layout());
+ if (lay) {
+ QSize textSize = fontMetrics().size(Qt::TextExpandTabs, text(),
+ fontMetrics().maxWidth());
+ QSpacerItem *horizontalSpacer =
+ new QSpacerItem(textSize.width() + iconPixmap().width(), 0,
+ QSizePolicy::Minimum, QSizePolicy::Expanding);
+ lay->addItem(horizontalSpacer, lay->rowCount(), 1, 1,
+ lay->columnCount() - 1);
+ }
+ resized = true;
+ }
+
+ QMessageBox::showEvent(event);
+
+ if (timeout() > std::chrono::milliseconds::zero()) {
+ _timer.setSingleShot(true);
+ _timer.start();
+ }
+}
+
+void PinentryConfirm::slotTimeout() {
+ QAbstractButton *b = button(QMessageBox::Cancel);
+ _timed_out = true;
+
+ if (b) {
+ b->animateClick();
+ }
+}
+
+#ifndef QT_NO_ACCESSIBILITY
+void PinentryConfirm::accessibilityActiveChanged(bool active) {
+ // Allow text label to get focus if accessibility is active
+ const auto focusPolicy = active ? Qt::StrongFocus : Qt::ClickFocus;
+ if (auto label = messageBoxLabel(this)) {
+ label->setFocusPolicy(focusPolicy);
+ }
+}
+#endif
diff --git a/src/pinentry/pinentryconfirm.h b/src/pinentry/pinentryconfirm.h
new file mode 100644
index 00000000..7be7c268
--- /dev/null
+++ b/src/pinentry/pinentryconfirm.h
@@ -0,0 +1,63 @@
+/* pinentryconfirm.h - A QMessageBox with a timeout
+ *
+ * Copyright (C) 2011 Ben Kibbey <[email protected]>
+ * Copyright (C) 2022 g10 Code GmbH
+ *
+ * Software engineering by Ingo Klöcker <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef PINENTRYCONFIRM_H
+#define PINENTRYCONFIRM_H
+
+#include <QAccessible>
+#include <QMessageBox>
+#include <QTimer>
+
+class PinentryConfirm : public QMessageBox
+#ifndef QT_NO_ACCESSIBILITY
+ , public QAccessible::ActivationObserver
+#endif
+{
+ Q_OBJECT
+public:
+ PinentryConfirm(Icon icon, const QString &title, const QString &text,
+ StandardButtons buttons = NoButton, QWidget *parent = nullptr,
+ Qt::WindowFlags flags = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint);
+ ~PinentryConfirm() override;
+
+ void setTimeout(std::chrono::seconds timeout);
+ std::chrono::seconds timeout() const;
+
+ bool timedOut() const;
+
+protected:
+ void showEvent(QShowEvent *event) override;
+
+private Q_SLOTS:
+ void slotTimeout();
+
+private:
+#ifndef QT_NO_ACCESSIBILITY
+ void accessibilityActiveChanged(bool active) override;
+#endif
+
+private:
+ QTimer _timer;
+ bool _timed_out = false;
+};
+
+#endif
diff --git a/src/pinentry/pinentrydialog.cpp b/src/pinentry/pinentrydialog.cpp
new file mode 100644
index 00000000..a8d85455
--- /dev/null
+++ b/src/pinentry/pinentrydialog.cpp
@@ -0,0 +1,691 @@
+/* pinentrydialog.cpp - A (not yet) secure Qt 4 dialog for PIN entry.
+ * Copyright (C) 2002, 2008 Klarälvdalens Datakonsult AB (KDAB)
+ * Copyright 2007 Ingo Klöcker
+ * Copyright 2016 Intevation GmbH
+ * Copyright (C) 2021, 2022 g10 Code GmbH
+ *
+ * Written by Steffen Hansen <[email protected]>.
+ * Modified by Andre Heinecke <[email protected]>
+ * Software engineering by Ingo Klöcker <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "pinentrydialog.h"
+
+#include <qnamespace.h>
+
+#include <QAccessible>
+#include <QAction>
+#include <QApplication>
+#include <QCheckBox>
+#include <QDebug>
+#include <QDialogButtonBox>
+#include <QFontMetrics>
+#include <QGridLayout>
+#include <QHBoxLayout>
+#include <QKeyEvent>
+#include <QLabel>
+#include <QLineEdit>
+#include <QMessageBox>
+#include <QPainter>
+#include <QPalette>
+#include <QProgressBar>
+#include <QPushButton>
+#include <QRegularExpression>
+#include <QStyle>
+#include <QVBoxLayout>
+
+#include "accessibility.h"
+#include "capslock/capslock.h"
+#include "core/utils/MemoryUtils.h"
+#include "pinentry.h"
+#include "pinlineedit.h"
+#include "util.h"
+
+#ifdef Q_OS_WIN
+#include <windows.h>
+#if QT_VERSION >= 0x050700
+#include <QtPlatformHeaders/QWindowsWindowFunctions>
+#endif
+#endif
+
+void raiseWindow(QWidget *w) {
+#ifdef Q_OS_WIN
+#if QT_VERSION >= 0x050700
+ QWindowsWindowFunctions::setWindowActivationBehavior(
+ QWindowsWindowFunctions::AlwaysActivateWindow);
+#endif
+#endif
+ w->setWindowState((w->windowState() & ~Qt::WindowMinimized) |
+ Qt::WindowActive);
+ w->activateWindow();
+ w->raise();
+}
+
+QPixmap applicationIconPixmap(const QIcon &overlayIcon) {
+ QPixmap pm = qApp->windowIcon().pixmap(48, 48);
+
+ if (!overlayIcon.isNull()) {
+ QPainter painter(&pm);
+ const int emblemSize = 22;
+ painter.drawPixmap(pm.width() - emblemSize, 0,
+ overlayIcon.pixmap(emblemSize, emblemSize));
+ }
+
+ return pm;
+}
+
+void PinEntryDialog::slotTimeout() {
+ _timed_out = true;
+ reject();
+}
+
+PinEntryDialog::PinEntryDialog(QWidget *parent, const char *name, int timeout,
+ bool modal, bool enable_quality_bar,
+ const QString &repeatString,
+ const QString &visibilityTT,
+ const QString &hideTT)
+ : QDialog{parent},
+ _have_quality_bar{enable_quality_bar},
+ mVisibilityTT{visibilityTT},
+ mHideTT{hideTT} {
+ Q_UNUSED(name)
+
+ if (modal) {
+ setWindowModality(Qt::ApplicationModal);
+ setModal(true);
+ }
+
+ QPalette red_text_palette;
+ red_text_palette.setColor(QPalette::WindowText, Qt::red);
+
+ auto *const main_layout = new QVBoxLayout{this};
+
+ auto *const hbox = new QHBoxLayout;
+
+ _icon = new QLabel(this);
+ _icon->setPixmap(applicationIconPixmap());
+ hbox->addWidget(_icon, 0, Qt::AlignVCenter | Qt::AlignLeft);
+
+ auto *const grid = new QGridLayout;
+ int row = 1;
+
+ _error = new QLabel{this};
+ _error->setTextFormat(Qt::PlainText);
+ _error->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ _error->setPalette(red_text_palette);
+ _error->hide();
+ grid->addWidget(_error, row, 1, 1, 2);
+
+ row++;
+ _desc = new QLabel{this};
+ _desc->setTextFormat(Qt::PlainText);
+ _desc->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ _desc->hide();
+ grid->addWidget(_desc, row, 1, 1, 2);
+
+ row++;
+ mCapsLockHint = new QLabel{this};
+ mCapsLockHint->setTextFormat(Qt::PlainText);
+ mCapsLockHint->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ mCapsLockHint->setPalette(red_text_palette);
+ mCapsLockHint->setAlignment(Qt::AlignCenter);
+ mCapsLockHint->setVisible(false);
+ grid->addWidget(mCapsLockHint, row, 1, 1, 2);
+
+ row++;
+ {
+ _prompt = new QLabel(this);
+ _prompt->setTextFormat(Qt::PlainText);
+ _prompt->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ _prompt->hide();
+ grid->addWidget(_prompt, row, 1);
+
+ auto *const l = new QHBoxLayout;
+ _edit = new PinLineEdit(this);
+ _edit->setMaxLength(256);
+ _edit->setMinimumWidth(_edit->fontMetrics().averageCharWidth() * 20 + 48);
+ _edit->setEchoMode(QLineEdit::Password);
+ _prompt->setBuddy(_edit);
+ l->addWidget(_edit, 1);
+
+ if (!repeatString.isNull()) {
+ mGenerateButton = new QPushButton{this};
+ mGenerateButton->setIcon(QIcon(QLatin1String(":password-generate.svg")));
+ mGenerateButton->setVisible(false);
+ l->addWidget(mGenerateButton);
+ }
+ grid->addLayout(l, row, 2);
+ }
+
+ /* Set up the show password action */
+ const QIcon visibility_icon = QIcon(QLatin1String(":visibility.svg"));
+ const QIcon hide_icon = QIcon(QLatin1String(":hint.svg"));
+#if QT_VERSION >= 0x050200
+ if (!visibility_icon.isNull() && !hide_icon.isNull()) {
+ mVisiActionEdit =
+ _edit->addAction(visibility_icon, QLineEdit::TrailingPosition);
+ mVisiActionEdit->setVisible(false);
+ mVisiActionEdit->setToolTip(mVisibilityTT);
+ } else
+#endif
+ {
+ if (!mVisibilityTT.isNull()) {
+ row++;
+ mVisiCB = new QCheckBox{mVisibilityTT, this};
+ grid->addWidget(mVisiCB, row, 1, 1, 2, Qt::AlignLeft);
+ }
+ }
+
+ row++;
+ mConstraintsHint = new QLabel{this};
+ mConstraintsHint->setTextFormat(Qt::PlainText);
+ mConstraintsHint->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ mConstraintsHint->setVisible(false);
+ grid->addWidget(mConstraintsHint, row, 2);
+
+ row++;
+ mFormattedPassphraseHintSpacer = new QLabel{this};
+ mFormattedPassphraseHintSpacer->setVisible(false);
+ mFormattedPassphraseHint = new QLabel{this};
+ mFormattedPassphraseHint->setTextFormat(Qt::PlainText);
+ mFormattedPassphraseHint->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ mFormattedPassphraseHint->setVisible(false);
+ grid->addWidget(mFormattedPassphraseHintSpacer, row, 1);
+ grid->addWidget(mFormattedPassphraseHint, row, 2);
+
+ if (!repeatString.isNull()) {
+ row++;
+ auto *repeat_label = new QLabel{this};
+ repeat_label->setTextFormat(Qt::PlainText);
+ repeat_label->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ repeat_label->setText(repeatString);
+ grid->addWidget(repeat_label, row, 1);
+
+ mRepeat = new PinLineEdit(this);
+ mRepeat->setMaxLength(256);
+ mRepeat->setEchoMode(QLineEdit::Password);
+ repeat_label->setBuddy(mRepeat);
+ grid->addWidget(mRepeat, row, 2);
+
+ row++;
+ mRepeatError = new QLabel{this};
+ mRepeatError->setTextFormat(Qt::PlainText);
+ mRepeatError->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ mRepeatError->setPalette(red_text_palette);
+ mRepeatError->hide();
+ grid->addWidget(mRepeatError, row, 2);
+ }
+
+ if (enable_quality_bar) {
+ row++;
+ _quality_bar_label = new QLabel(this);
+ _quality_bar_label->setTextFormat(Qt::PlainText);
+ _quality_bar_label->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ _quality_bar_label->setAlignment(Qt::AlignVCenter);
+ grid->addWidget(_quality_bar_label, row, 1);
+
+ _quality_bar = new QProgressBar(this);
+ _quality_bar->setAlignment(Qt::AlignCenter);
+ _quality_bar_label->setBuddy(_quality_bar);
+ grid->addWidget(_quality_bar, row, 2);
+ }
+
+ hbox->addLayout(grid, 1);
+ main_layout->addLayout(hbox);
+
+ auto *const buttons = new QDialogButtonBox(this);
+ buttons->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+ _ok = buttons->button(QDialogButtonBox::Ok);
+ _cancel = buttons->button(QDialogButtonBox::Cancel);
+
+ if (style()->styleHint(QStyle::SH_DialogButtonBox_ButtonsHaveIcons)) {
+ _ok->setIcon(style()->standardIcon(QStyle::SP_DialogOkButton));
+ _cancel->setIcon(style()->standardIcon(QStyle::SP_DialogCancelButton));
+ }
+
+ main_layout->addStretch(1);
+ main_layout->addWidget(buttons);
+ main_layout->setSizeConstraint(QLayout::SetFixedSize);
+
+ if (timeout > 0) {
+ _timer = new QTimer(this);
+ connect(_timer, &QTimer::timeout, this, &PinEntryDialog::slotTimeout);
+ _timer->start(timeout * 1000);
+ }
+
+ connect(buttons, &QDialogButtonBox::accepted, this,
+ &PinEntryDialog::onAccept);
+ connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
+ connect(_edit, &QLineEdit::textChanged, this, &PinEntryDialog::updateQuality);
+ connect(_edit, &QLineEdit::textChanged, this, &PinEntryDialog::textChanged);
+ connect(_edit, &PinLineEdit::backspacePressed, this,
+ &PinEntryDialog::onBackspace);
+ if (mGenerateButton != nullptr) {
+ connect(mGenerateButton, &QPushButton::clicked, this,
+ &PinEntryDialog::generatePin);
+ }
+ if (mVisiActionEdit != nullptr) {
+ connect(mVisiActionEdit, &QAction::triggered, this,
+ &PinEntryDialog::toggleVisibility);
+ }
+ if (mVisiCB != nullptr) {
+ connect(mVisiCB, &QCheckBox::toggled, this,
+ &PinEntryDialog::toggleVisibility);
+ }
+ if (mRepeat != nullptr) {
+ connect(mRepeat, &QLineEdit::textChanged, this,
+ &PinEntryDialog::textChanged);
+ }
+
+ auto *caps_lock_watcher = new CapsLockWatcher{this};
+ connect(caps_lock_watcher, &CapsLockWatcher::stateChanged, this,
+ [this](bool locked) { mCapsLockHint->setVisible(locked); });
+
+ connect(qApp, &QApplication::focusChanged, this,
+ &PinEntryDialog::focusChanged);
+ connect(qApp, &QApplication::applicationStateChanged, this,
+ &PinEntryDialog::checkCapsLock);
+ checkCapsLock();
+
+ setAttribute(Qt::WA_DeleteOnClose);
+ setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
+
+ /* This is mostly an issue on Windows where this results
+ in the pinentry popping up nicely with an animation and
+ comes to front. It is not ifdefed for Windows only since
+ window managers on Linux like KWin can also have this
+ result in an animation when the pinentry is shown and
+ not just popping it up.
+ */
+ if (qApp->platformName() != QLatin1String("wayland")) {
+ setWindowState(Qt::WindowMinimized);
+ QTimer::singleShot(0, this, [this]() { raiseWindow(this); });
+ } else {
+ raiseWindow(this);
+ }
+}
+
+void PinEntryDialog::keyPressEvent(QKeyEvent *e) {
+ const auto return_pressed =
+ (!e->modifiers() &&
+ (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return)) ||
+ (e->modifiers() & Qt::KeypadModifier && e->key() == Qt::Key_Enter);
+ if (return_pressed && _edit->hasFocus() && (mRepeat != nullptr)) {
+ // if the user pressed Return in the first input field, then move the
+ // focus to the repeat input field and prevent further event processing
+ // by QDialog (which would trigger the default button)
+ mRepeat->setFocus();
+ e->ignore();
+ return;
+ }
+
+ QDialog::keyPressEvent(e);
+}
+
+void PinEntryDialog::keyReleaseEvent(QKeyEvent *event) {
+ QDialog::keyReleaseEvent(event);
+ checkCapsLock();
+}
+
+void PinEntryDialog::showEvent(QShowEvent *event) {
+ QDialog::showEvent(event);
+ _edit->setFocus();
+}
+
+void PinEntryDialog::setDescription(const QString &txt) {
+ _desc->setVisible(!txt.isEmpty());
+ _desc->setText(txt);
+ _icon->setPixmap(applicationIconPixmap());
+ setError(QString());
+}
+
+QString PinEntryDialog::description() const { return _desc->text(); }
+
+void PinEntryDialog::setError(const QString &txt) {
+ if (!txt.isNull()) {
+ _icon->setPixmap(
+ applicationIconPixmap(QIcon{QStringLiteral(":data-error.svg")}));
+ }
+ _error->setText(txt);
+ _error->setVisible(!txt.isEmpty());
+}
+
+QString PinEntryDialog::error() const { return _error->text(); }
+
+void PinEntryDialog::setPin(const QString &txt) { _edit->setPin(txt); }
+
+QString PinEntryDialog::pin() const { return _edit->pin(); }
+
+void PinEntryDialog::setPrompt(const QString &txt) {
+ _prompt->setText(txt);
+ _prompt->setVisible(!txt.isEmpty());
+ if (txt.contains("PIN")) _disable_echo_allowed = false;
+}
+
+QString PinEntryDialog::prompt() const { return _prompt->text(); }
+
+void PinEntryDialog::setOkText(const QString &txt) {
+ _ok->setText(txt);
+ _ok->setVisible(!txt.isEmpty());
+}
+
+void PinEntryDialog::setCancelText(const QString &txt) {
+ _cancel->setText(txt);
+ _cancel->setVisible(!txt.isEmpty());
+}
+
+void PinEntryDialog::setQualityBar(const QString &txt) {
+ if (_have_quality_bar) {
+ _quality_bar_label->setText(txt);
+ }
+}
+
+void PinEntryDialog::setQualityBarTT(const QString &txt) {
+ if (_have_quality_bar) {
+ _quality_bar->setToolTip(txt);
+ }
+}
+
+void PinEntryDialog::setGenpinLabel(const QString &txt) {
+ if (mGenerateButton == nullptr) {
+ return;
+ }
+ mGenerateButton->setVisible(!txt.isEmpty());
+ if (!txt.isEmpty()) {
+ Accessibility::setName(mGenerateButton, txt);
+ }
+}
+
+void PinEntryDialog::setGenpinTT(const QString &txt) {
+ if (mGenerateButton != nullptr) {
+ mGenerateButton->setToolTip(txt);
+ }
+}
+
+void PinEntryDialog::setCapsLockHint(const QString &txt) {
+ mCapsLockHint->setText(txt);
+}
+
+void PinEntryDialog::setFormattedPassphrase(
+ const PinEntryDialog::FormattedPassphraseOptions &options) {
+ mFormatPassphrase = options.formatPassphrase;
+ mFormattedPassphraseHint->setTextFormat(Qt::RichText);
+ mFormattedPassphraseHint->setText(QLatin1String("<html>") +
+ options.hint.toHtmlEscaped() +
+ QLatin1String("</html>"));
+ Accessibility::setName(mFormattedPassphraseHint, options.hint);
+ // toggleFormattedPassphrase();
+}
+
+void PinEntryDialog::setConstraintsOptions(const ConstraintsOptions &options) {
+ mEnforceConstraints = options.enforce;
+ mConstraintsHint->setText(options.shortHint);
+ if (!options.longHint.isEmpty()) {
+ mConstraintsHint->setToolTip(
+ QLatin1String("<html>") +
+ options.longHint.toHtmlEscaped().replace(QLatin1String("\n\n"),
+ QLatin1String("<br>")) +
+ QLatin1String("</html>"));
+ Accessibility::setDescription(mConstraintsHint, options.longHint);
+ }
+ mConstraintsErrorTitle = options.errorTitle;
+
+ mConstraintsHint->setVisible(mEnforceConstraints &&
+ !options.shortHint.isEmpty());
+}
+
+void PinEntryDialog::toggleFormattedPassphrase() {
+ const bool enable_formatting =
+ mFormatPassphrase && _edit->echoMode() == QLineEdit::Normal;
+ _edit->setFormattedPassphrase(enable_formatting);
+ if (mRepeat != nullptr) {
+ mRepeat->setFormattedPassphrase(enable_formatting);
+ const bool hint_about_to_be_hidden =
+ mFormattedPassphraseHint->isVisible() && !enable_formatting;
+ if (hint_about_to_be_hidden) {
+ // set hint spacer to current height of hint label before hiding the hint
+ mFormattedPassphraseHintSpacer->setMinimumHeight(
+ mFormattedPassphraseHint->height());
+ mFormattedPassphraseHintSpacer->setVisible(true);
+ } else if (enable_formatting) {
+ mFormattedPassphraseHintSpacer->setVisible(false);
+ }
+ mFormattedPassphraseHint->setVisible(enable_formatting);
+ }
+}
+
+void PinEntryDialog::onBackspace() {
+ cancelTimeout();
+
+ if (_disable_echo_allowed) {
+ _edit->setEchoMode(QLineEdit::NoEcho);
+ if (mRepeat != nullptr) {
+ mRepeat->setEchoMode(QLineEdit::NoEcho);
+ }
+ }
+}
+
+void PinEntryDialog::updateQuality(const QString &txt) {
+ int length;
+ int percent;
+ QPalette pal;
+
+ _disable_echo_allowed = false;
+
+ if (!_have_quality_bar) {
+ return;
+ }
+
+ length = txt.length();
+ percent = length != 0 ? pinentry_inq_quality(txt) : 0;
+ if (length == 0) {
+ _quality_bar->reset();
+ } else {
+ pal = _quality_bar->palette();
+ if (percent < 0) {
+ pal.setColor(QPalette::Highlight, QColor("red"));
+ percent = -percent;
+ } else {
+ pal.setColor(QPalette::Highlight, QColor("green"));
+ }
+ _quality_bar->setPalette(pal);
+ _quality_bar->setValue(percent);
+ }
+}
+
+void PinEntryDialog::setPinentryInfo(struct pinentry peinfo) {
+ _pinentry_info =
+ GpgFrontend::SecureCreateUniqueObject<struct pinentry>(peinfo);
+}
+
+void PinEntryDialog::focusChanged(QWidget *old, QWidget *now) {
+ // Grab keyboard. It might be a little weird to do it here, but it works!
+ // Previously this code was in showEvent, but that did not work in Qt4.
+ if (!_pinentry_info || (_pinentry_info->grab != 0)) {
+ if (_grabbed && (old != nullptr) && (old == _edit || old == mRepeat)) {
+ old->releaseKeyboard();
+ _grabbed = false;
+ }
+ if (!_grabbed && (now != nullptr) && (now == _edit || now == mRepeat)) {
+ now->grabKeyboard();
+ _grabbed = true;
+ }
+ }
+}
+
+void PinEntryDialog::textChanged(const QString &text) {
+ Q_UNUSED(text);
+
+ cancelTimeout();
+
+ if ((mVisiActionEdit != nullptr) && sender() == _edit) {
+ mVisiActionEdit->setVisible(!_edit->pin().isEmpty());
+ }
+ if (mGenerateButton != nullptr) {
+ mGenerateButton->setVisible(_edit->pin().isEmpty()
+#ifndef QT_NO_ACCESSIBILITY
+ && !mGenerateButton->accessibleName().isEmpty()
+#endif
+ );
+ }
+}
+
+void PinEntryDialog::generatePin() {
+ unique_malloced_ptr<char> pin{pinentry_inq_genpin(_pinentry_info.get())};
+ if (pin) {
+ if (_edit->echoMode() == QLineEdit::Password) {
+ if (mVisiActionEdit != nullptr) {
+ mVisiActionEdit->trigger();
+ }
+ if (mVisiCB != nullptr) {
+ mVisiCB->setChecked(true);
+ }
+ }
+ const auto pin_str = QString::fromUtf8(pin.get());
+ _edit->setPin(pin_str);
+ mRepeat->setPin(pin_str);
+ // explicitly focus the first input field and select the generated password
+ _edit->setFocus();
+ _edit->selectAll();
+ }
+}
+
+void PinEntryDialog::toggleVisibility() {
+ if (sender() != mVisiCB) {
+ if (_edit->echoMode() == QLineEdit::Password) {
+ if (mVisiActionEdit != nullptr) {
+ mVisiActionEdit->setIcon(QIcon(QLatin1String(":hint.svg")));
+ mVisiActionEdit->setToolTip(mHideTT);
+ }
+ _edit->setEchoMode(QLineEdit::Normal);
+ if (mRepeat != nullptr) {
+ mRepeat->setEchoMode(QLineEdit::Normal);
+ }
+ } else {
+ if (mVisiActionEdit != nullptr) {
+ mVisiActionEdit->setIcon(QIcon(QLatin1String(":visibility.svg")));
+ mVisiActionEdit->setToolTip(mVisibilityTT);
+ }
+ _edit->setEchoMode(QLineEdit::Password);
+ if (mRepeat != nullptr) {
+ mRepeat->setEchoMode(QLineEdit::Password);
+ }
+ }
+ } else {
+ if (mVisiCB->isChecked()) {
+ if (mRepeat != nullptr) {
+ mRepeat->setEchoMode(QLineEdit::Normal);
+ }
+ _edit->setEchoMode(QLineEdit::Normal);
+ } else {
+ if (mRepeat != nullptr) {
+ mRepeat->setEchoMode(QLineEdit::Password);
+ }
+ _edit->setEchoMode(QLineEdit::Password);
+ }
+ }
+ toggleFormattedPassphrase();
+}
+
+QString PinEntryDialog::repeatedPin() const {
+ if (mRepeat != nullptr) {
+ return mRepeat->pin();
+ }
+ return QString();
+}
+
+bool PinEntryDialog::timedOut() const { return _timed_out; }
+
+void PinEntryDialog::setRepeatErrorText(const QString &err) {
+ if (mRepeatError != nullptr) {
+ mRepeatError->setText(err);
+ }
+}
+
+void PinEntryDialog::cancelTimeout() {
+ if (_timer != nullptr) {
+ _timer->stop();
+ }
+}
+
+void PinEntryDialog::checkCapsLock() {
+ const auto state = capsLockState();
+ if (state != LockState::Unknown) {
+ mCapsLockHint->setVisible(state == LockState::On);
+ }
+}
+
+void PinEntryDialog::onAccept() {
+ cancelTimeout();
+
+ if ((mRepeat != nullptr) && mRepeat->pin() != _edit->pin()) {
+#ifndef QT_NO_ACCESSIBILITY
+ if (QAccessible::isActive()) {
+ QMessageBox::information(this, mRepeatError->text(),
+ mRepeatError->text());
+ } else
+#endif
+ {
+ mRepeatError->setVisible(true);
+ }
+ return;
+ }
+
+ const auto result = checkConstraints();
+ if (result != PassphraseNotOk) {
+ accept();
+ }
+}
+
+PinEntryDialog::PassphraseCheckResult PinEntryDialog::checkConstraints() {
+ if (!mEnforceConstraints) {
+ return PassphraseNotChecked;
+ }
+
+ const auto passphrase = _edit->pin().toUtf8();
+ unique_malloced_ptr<char> error{pinentry_inq_checkpin(
+ _pinentry_info.get(), passphrase.constData(), passphrase.size())};
+
+ if (!error) {
+ return PassphraseOk;
+ }
+
+ const auto message_lines =
+ QString::fromUtf8(QByteArray::fromPercentEncoding(error.get()))
+ .split(QChar{'\n'});
+ if (message_lines.isEmpty()) {
+ // shouldn't happen because pinentry_inq_checkpin() either returns NULL or a
+ // non-empty string
+ return PassphraseOk;
+ }
+ const auto &first_line = message_lines.first();
+ const auto index_of_first_non_empty_additional_line =
+ message_lines.indexOf(QRegularExpression{QStringLiteral(".*\\S.*")}, 1);
+ const auto additional_lines =
+ index_of_first_non_empty_additional_line > 0
+ ? message_lines.mid(index_of_first_non_empty_additional_line)
+ .join(QChar{'\n'})
+ : QString{};
+ QMessageBox message_box{this};
+ message_box.setIcon(QMessageBox::Information);
+ message_box.setWindowTitle(mConstraintsErrorTitle);
+ message_box.setText(first_line);
+ message_box.setInformativeText(additional_lines);
+ message_box.setStandardButtons(QMessageBox::Ok);
+ message_box.exec();
+ return PassphraseNotOk;
+}
diff --git a/src/pinentry/pinentrydialog.h b/src/pinentry/pinentrydialog.h
new file mode 100644
index 00000000..9f405b10
--- /dev/null
+++ b/src/pinentry/pinentrydialog.h
@@ -0,0 +1,171 @@
+/* pinentrydialog.h - A (not yet) secure Qt 4 dialog for PIN entry.
+ * Copyright (C) 2002, 2008 Klarälvdalens Datakonsult AB (KDAB)
+ * Copyright 2007 Ingo Klöcker
+ * Copyright 2016 Intevation GmbH
+ * Copyright (C) 2021, 2022 g10 Code GmbH
+ *
+ * Written by Steffen Hansen <[email protected]>.
+ * Modified by Andre Heinecke <[email protected]>
+ * Software engineering by Ingo Klöcker <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __PINENTRYDIALOG_H__
+#define __PINENTRYDIALOG_H__
+
+#include <QAccessible>
+#include <QDialog>
+#include <QStyle>
+#include <QTimer>
+
+#include "core/function/SecureMemoryAllocator.h"
+#include "pinentry.h"
+
+class QIcon;
+class QLabel;
+class QPushButton;
+class QLineEdit;
+class PinLineEdit;
+class QString;
+class QProgressBar;
+class QCheckBox;
+class QAction;
+
+QPixmap applicationIconPixmap(const QIcon &overlayIcon = {});
+
+void raiseWindow(QWidget *w);
+
+class PinEntryDialog : public QDialog {
+ Q_OBJECT
+
+ Q_PROPERTY(QString description READ description WRITE setDescription)
+ Q_PROPERTY(QString error READ error WRITE setError)
+ Q_PROPERTY(QString pin READ pin WRITE setPin)
+ Q_PROPERTY(QString prompt READ prompt WRITE setPrompt)
+ public:
+ struct FormattedPassphraseOptions {
+ bool formatPassphrase;
+ QString hint;
+ };
+ struct ConstraintsOptions {
+ bool enforce;
+ QString shortHint;
+ QString longHint;
+ QString errorTitle;
+ };
+
+ explicit PinEntryDialog(QWidget *parent = 0, const char *name = 0,
+ int timeout = 0, bool modal = false,
+ bool enable_quality_bar = false,
+ const QString &repeatString = QString(),
+ const QString &visibiltyTT = QString(),
+ const QString &hideTT = QString());
+
+ void setDescription(const QString &);
+ QString description() const;
+
+ void setError(const QString &);
+ QString error() const;
+
+ void setPin(const QString &);
+ QString pin() const;
+
+ QString repeatedPin() const;
+ void setRepeatErrorText(const QString &);
+
+ void setPrompt(const QString &);
+ QString prompt() const;
+
+ void setOkText(const QString &);
+ void setCancelText(const QString &);
+
+ void setQualityBar(const QString &);
+ void setQualityBarTT(const QString &);
+
+ void setGenpinLabel(const QString &);
+ void setGenpinTT(const QString &);
+
+ void setCapsLockHint(const QString &);
+
+ void setFormattedPassphrase(const FormattedPassphraseOptions &options);
+
+ void setConstraintsOptions(const ConstraintsOptions &options);
+
+ void setPinentryInfo(struct pinentry);
+
+ bool timedOut() const;
+
+ protected Q_SLOTS:
+ void updateQuality(const QString &);
+ void slotTimeout();
+ void textChanged(const QString &);
+ void focusChanged(QWidget *old, QWidget *now);
+ void toggleVisibility();
+ void onBackspace();
+ void generatePin();
+ void toggleFormattedPassphrase();
+
+ protected:
+ void keyPressEvent(QKeyEvent *event) override;
+ void keyReleaseEvent(QKeyEvent *event) override;
+ void showEvent(QShowEvent *event) override;
+
+ private Q_SLOTS:
+ void cancelTimeout();
+ void checkCapsLock();
+ void onAccept();
+
+ private:
+ enum PassphraseCheckResult {
+ PassphraseNotChecked = -1,
+ PassphraseNotOk = 0,
+ PassphraseOk
+ };
+ PassphraseCheckResult checkConstraints();
+
+ QLabel *_icon = nullptr;
+ QLabel *_desc = nullptr;
+ QLabel *_error = nullptr;
+ QLabel *_prompt = nullptr;
+ QLabel *_quality_bar_label = nullptr;
+ QProgressBar *_quality_bar = nullptr;
+ PinLineEdit *_edit = nullptr;
+ PinLineEdit *mRepeat = nullptr;
+ QLabel *mRepeatError = nullptr;
+ QPushButton *_ok = nullptr;
+ QPushButton *_cancel = nullptr;
+ bool _grabbed = false;
+ bool _have_quality_bar = false;
+ bool _timed_out = false;
+ bool _disable_echo_allowed = true;
+ bool mEnforceConstraints = false;
+ bool mFormatPassphrase = false;
+
+ GpgFrontend::SecureUniquePtr<struct pinentry> _pinentry_info = nullptr;
+ QTimer *_timer = nullptr;
+ QString mVisibilityTT;
+ QString mHideTT;
+ QAction *mVisiActionEdit = nullptr;
+ QPushButton *mGenerateButton = nullptr;
+ QCheckBox *mVisiCB = nullptr;
+ QLabel *mFormattedPassphraseHint = nullptr;
+ QLabel *mFormattedPassphraseHintSpacer = nullptr;
+ QLabel *mCapsLockHint = nullptr;
+ QLabel *mConstraintsHint = nullptr;
+ QString mConstraintsErrorTitle;
+};
+
+#endif // __PINENTRYDIALOG_H__
diff --git a/src/pinentry/pinlineedit.cpp b/src/pinentry/pinlineedit.cpp
new file mode 100644
index 00000000..9d172b56
--- /dev/null
+++ b/src/pinentry/pinlineedit.cpp
@@ -0,0 +1,204 @@
+/* pinlineedit.cpp - Modified QLineEdit widget.
+ * Copyright (C) 2018 Damien Goutte-Gattat
+ * Copyright (C) 2021 g10 Code GmbH
+ *
+ * Software engineering by Ingo Klöcker <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "pinlineedit.h"
+
+#include <QClipboard>
+#include <QGuiApplication>
+#include <QKeyEvent>
+
+static const int FormattedPassphraseGroupSize = 5;
+static const QChar FormattedPassphraseSeparator = QChar::Nbsp;
+
+namespace {
+struct Selection {
+ bool empty() const { return start < 0 || start >= end; }
+ int length() const { return empty() ? 0 : end - start; }
+
+ int start;
+ int end;
+};
+} // namespace
+
+class PinLineEdit::Private {
+ PinLineEdit *const q;
+
+ public:
+ Private(PinLineEdit *q) : q{q} {}
+
+ QString formatted(QString text) const {
+ const int dashCount = text.size() / FormattedPassphraseGroupSize;
+ text.reserve(text.size() + dashCount);
+ for (int i = FormattedPassphraseGroupSize; i < text.size();
+ i += FormattedPassphraseGroupSize + 1) {
+ text.insert(i, FormattedPassphraseSeparator);
+ }
+ return text;
+ }
+
+ Selection formattedSelection(Selection selection) const {
+ if (selection.empty()) {
+ return selection;
+ }
+ return {selection.start + selection.start / FormattedPassphraseGroupSize,
+ selection.end + (selection.end - 1) / FormattedPassphraseGroupSize};
+ }
+
+ QString unformatted(QString text) const {
+ for (int i = FormattedPassphraseGroupSize; i < text.size();
+ i += FormattedPassphraseGroupSize) {
+ text.remove(i, 1);
+ }
+ return text;
+ }
+
+ Selection unformattedSelection(Selection selection) const {
+ if (selection.empty()) {
+ return selection;
+ }
+ return {
+ selection.start - selection.start / (FormattedPassphraseGroupSize + 1),
+ selection.end - selection.end / (FormattedPassphraseGroupSize + 1)};
+ }
+
+ void copyToClipboard() {
+ if (q->echoMode() != QLineEdit::Normal) {
+ return;
+ }
+
+ QString text = q->selectedText();
+ if (mFormattedPassphrase) {
+ text.remove(FormattedPassphraseSeparator);
+ }
+ if (!text.isEmpty()) {
+ QGuiApplication::clipboard()->setText(text);
+ }
+ }
+
+ int selectionEnd() {
+#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
+ return q->selectionEnd();
+#else
+ return q->selectionStart() + q->selectedText().size();
+#endif
+ }
+
+ public:
+ bool mFormattedPassphrase = false;
+};
+
+PinLineEdit::PinLineEdit(QWidget *parent)
+ : QLineEdit(parent), d{new Private{this}} {
+ connect(this, SIGNAL(textEdited(QString)), this, SLOT(textEdited()));
+}
+
+PinLineEdit::~PinLineEdit() = default;
+
+void PinLineEdit::setFormattedPassphrase(bool on) {
+ if (on == d->mFormattedPassphrase) {
+ return;
+ }
+ d->mFormattedPassphrase = on;
+ Selection selection{selectionStart(), d->selectionEnd()};
+ if (d->mFormattedPassphrase) {
+ setText(d->formatted(text()));
+ selection = d->formattedSelection(selection);
+ } else {
+ setText(d->unformatted(text()));
+ selection = d->unformattedSelection(selection);
+ }
+ if (!selection.empty()) {
+ setSelection(selection.start, selection.length());
+ }
+}
+
+void PinLineEdit::copy() const { d->copyToClipboard(); }
+
+void PinLineEdit::cut() {
+ if (hasSelectedText()) {
+ copy();
+ del();
+ }
+}
+
+void PinLineEdit::setPin(const QString &pin) {
+ setText(d->mFormattedPassphrase ? d->formatted(pin) : pin);
+}
+
+QString PinLineEdit::pin() const {
+ if (d->mFormattedPassphrase) {
+ return d->unformatted(text());
+ } else {
+ return text();
+ }
+}
+
+void PinLineEdit::keyPressEvent(QKeyEvent *e) {
+ if (e == QKeySequence::Copy) {
+ copy();
+ return;
+ } else if (e == QKeySequence::Cut) {
+ if (!isReadOnly() && hasSelectedText()) {
+ copy();
+ del();
+ }
+ return;
+ } else if (e == QKeySequence::DeleteEndOfLine) {
+ if (!isReadOnly()) {
+ setSelection(cursorPosition(), text().size());
+ copy();
+ del();
+ }
+ return;
+ } else if (e == QKeySequence::DeleteCompleteLine) {
+ if (!isReadOnly()) {
+ setSelection(0, text().size());
+ copy();
+ del();
+ }
+ return;
+ }
+
+ QLineEdit::keyPressEvent(e);
+
+ if (e->key() == Qt::Key::Key_Backspace) {
+ emit backspacePressed();
+ }
+}
+
+void PinLineEdit::textEdited() {
+ if (!d->mFormattedPassphrase) {
+ return;
+ }
+ auto currentText = text();
+ // first calculate the cursor position in the reformatted text; the cursor
+ // is put left of the separators, so that backspace works as expected
+ auto cursorPos = cursorPosition();
+ cursorPos -= QStringView{currentText}.left(cursorPos).count(
+ FormattedPassphraseSeparator);
+ cursorPos += std::max(cursorPos - 1, 0) / FormattedPassphraseGroupSize;
+ // then reformat the text
+ currentText.remove(FormattedPassphraseSeparator);
+ currentText = d->formatted(currentText);
+ // finally, set reformatted text and updated cursor position
+ setText(currentText);
+ setCursorPosition(cursorPos);
+}
diff --git a/src/pinentry/pinlineedit.h b/src/pinentry/pinlineedit.h
new file mode 100644
index 00000000..72ac85a5
--- /dev/null
+++ b/src/pinentry/pinlineedit.h
@@ -0,0 +1,60 @@
+/* pinlineedit.h - Modified QLineEdit widget.
+ * Copyright (C) 2018 Damien Goutte-Gattat
+ * Copyright (C) 2021 g10 Code GmbH
+ *
+ * Software engineering by Ingo Klöcker <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _PINLINEEDIT_H_
+#define _PINLINEEDIT_H_
+
+#include <QLineEdit>
+
+class PinLineEdit : public QLineEdit {
+ Q_OBJECT
+
+ public:
+ explicit PinLineEdit(QWidget *parent = nullptr);
+ ~PinLineEdit() override;
+
+ void setPin(const QString &pin);
+ QString pin() const;
+
+ public Q_SLOTS:
+ void setFormattedPassphrase(bool on);
+ void copy() const;
+ void cut();
+
+ Q_SIGNALS:
+ void backspacePressed();
+
+ protected:
+ void keyPressEvent(QKeyEvent *) override;
+
+ private:
+ using QLineEdit::setText;
+ using QLineEdit::text;
+
+ private Q_SLOTS:
+ void textEdited();
+
+ private:
+ class Private;
+ std::unique_ptr<Private> d;
+};
+
+#endif // _PINLINEEDIT_H_
diff --git a/src/pinentry/qti18n.cpp b/src/pinentry/qti18n.cpp
new file mode 100644
index 00000000..49c27dd3
--- /dev/null
+++ b/src/pinentry/qti18n.cpp
@@ -0,0 +1,93 @@
+/* qti18n.cpp - Load qt translations for pinentry.
+ * Copyright 2021 g10 Code GmbH
+ * SPDX-FileCopyrightText: 2015 Lukáš Tinkl <[email protected]>
+ * SPDX-FileCopyrightText: 2021 Ingo Klöcker <[email protected]>
+ *
+ * Copied from k18n under the terms of LGPLv2 or later.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <QCoreApplication>
+#include <QDebug>
+#include <QLibraryInfo>
+#include <QLocale>
+#include <QTranslator>
+
+static bool loadCatalog(const QString &catalog, const QLocale &locale) {
+ auto translator = new QTranslator(QCoreApplication::instance());
+
+ if (!translator->load(locale, catalog, QString(),
+ QLibraryInfo::path(QLibraryInfo::TranslationsPath))) {
+ qDebug() << "Loading the" << catalog << "catalog failed for locale"
+ << locale;
+ delete translator;
+ return false;
+ }
+ QCoreApplication::instance()->installTranslator(translator);
+ return true;
+}
+
+static bool loadCatalog(const QString &catalog, const QLocale &locale,
+ const QLocale &fallbackLocale) {
+ // try to load the catalog for locale
+ if (loadCatalog(catalog, locale)) {
+ return true;
+ }
+ // if this fails, then try the fallback locale (if it's different from locale)
+ if (fallbackLocale != locale) {
+ return loadCatalog(catalog, fallbackLocale);
+ }
+ return false;
+}
+
+// load global Qt translation, needed in KDE e.g. by lots of builtin dialogs
+// (QColorDialog, QFontDialog) that we use
+static void loadTranslation(const QString &localeName,
+ const QString &fallbackLocaleName) {
+ const QLocale locale{localeName};
+ const QLocale fallbackLocale{fallbackLocaleName};
+ // first, try to load the qt_ meta catalog
+ if (loadCatalog(QStringLiteral("qt_"), locale, fallbackLocale)) {
+ return;
+ }
+ // if loading the meta catalog failed, then try loading the four catalogs
+ // it depends on, i.e. qtbase, qtscript, qtmultimedia, qtxmlpatterns,
+ // separately
+ const auto catalogs = {
+ QStringLiteral("qtbase_"),
+ /* QStringLiteral("qtscript_"),
+ QStringLiteral("qtmultimedia_"),
+ QStringLiteral("qtxmlpatterns_"), */
+ };
+ for (const auto &catalog : catalogs) {
+ loadCatalog(catalog, locale, fallbackLocale);
+ }
+}
+
+static void load() {
+ // The way Qt translation system handles plural forms makes it necessary to
+ // have a translation file which contains only plural forms for `en`. That's
+ // why we load the `en` translation unconditionally, then load the
+ // translation for the current locale to overload it.
+ loadCatalog(QStringLiteral("qt_"), QLocale{QStringLiteral("en")});
+
+ const QLocale locale = QLocale::system();
+ if (locale.name() != QStringLiteral("en")) {
+ loadTranslation(locale.name(), locale.bcp47Name());
+ }
+}
+
+Q_COREAPP_STARTUP_FUNCTION(load)
diff --git a/src/pinentry/secmem++.h b/src/pinentry/secmem++.h
new file mode 100644
index 00000000..116da880
--- /dev/null
+++ b/src/pinentry/secmem++.h
@@ -0,0 +1,91 @@
+/* STL allocator for secmem
+ * Copyright (C) 2008 Marc Mutz <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __SECMEM_SECMEMPP_H__
+#define __SECMEM_SECMEMPP_H__
+
+#include "../secmem/secmem.h"
+#include <cstddef>
+
+namespace secmem {
+
+ template <typename T>
+ class alloc {
+ public:
+ // type definitions:
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef T* pointer;
+ typedef const T* const_pointer;
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef T value_type;
+
+ // rebind
+ template <typename U>
+ struct rebind {
+ typedef alloc<U> other;
+ };
+
+ // address
+ pointer address( reference value ) const {
+ return &value;
+ }
+ const_pointer address( const_reference value ) const {
+ return &value;
+ }
+
+ // (trivial) ctors and dtors
+ alloc() {}
+ alloc( const alloc & ) {}
+ template <typename U> alloc( const alloc<U> & ) {}
+ // copy ctor is ok
+ ~alloc() {}
+
+ // de/allocation
+ size_type max_size() const {
+ return secmem_get_max_size();
+ }
+
+ pointer allocate( size_type n, void * =0 ) {
+ return static_cast<pointer>( secmem_malloc( n * sizeof(T) ) );
+ }
+
+ void deallocate( pointer p, size_type ) {
+ secmem_free( p );
+ }
+
+ // de/construct
+ void construct( pointer p, const T & value ) {
+ void * loc = p;
+ new (loc)T(value);
+ }
+ void destruct( pointer p ) {
+ p->~T();
+ }
+ };
+
+ // equality comparison
+ template <typename T1,typename T2>
+ bool operator==( const alloc<T1> &, const alloc<T2> & ) { return true; }
+ template <typename T1, typename T2>
+ bool operator!=( const alloc<T1> &, const alloc<T2> & ) { return false; }
+
+}
+
+#endif /* __SECMEM_SECMEMPP_H__ */
diff --git a/src/pinentry/util.cpp b/src/pinentry/util.cpp
new file mode 100644
index 00000000..f1bac4ba
--- /dev/null
+++ b/src/pinentry/util.cpp
@@ -0,0 +1,116 @@
+/* Quintuple Agent
+ * Copyright (C) 1999 Robert Bihlmeyer <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _GNU_SOURCE 1
+
+#include <unistd.h>
+#ifndef WINDOWS
+# include <errno.h>
+#endif
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "util.h"
+
+#ifndef HAVE_DOSISH_SYSTEM
+static int uid_set = 0;
+static uid_t real_uid, file_uid;
+#endif /*!HAVE_DOSISH_SYSTEM*/
+
+/* Write DATA of size BYTES to FD, until all is written or an error
+ occurs. */
+ssize_t
+xwrite(int fd, const void *data, size_t bytes)
+{
+ char *ptr;
+ size_t todo;
+ ssize_t written = 0;
+
+ for (ptr = (char *)data, todo = bytes; todo; ptr += written, todo -= written)
+ {
+ do
+ written = write (fd, ptr, todo);
+ while (
+#ifdef WINDOWS
+ 0
+#else
+ written == -1 && errno == EINTR
+#endif
+ );
+ if (written < 0)
+ break;
+ }
+ return written;
+}
+
+#if 0
+extern int debug;
+
+int
+debugmsg(const char *fmt, ...)
+{
+ va_list va;
+ int ret;
+
+ if (debug) {
+ va_start(va, fmt);
+ fprintf(stderr, "\e[4m");
+ ret = vfprintf(stderr, fmt, va);
+ fprintf(stderr, "\e[24m");
+ va_end(va);
+ return ret;
+ } else
+ return 0;
+}
+#endif
+
+/* initialize uid variables */
+#ifndef HAVE_DOSISH_SYSTEM
+static void
+init_uids(void)
+{
+ real_uid = getuid();
+ file_uid = geteuid();
+ uid_set = 1;
+}
+#endif
+
+
+/* drop all additional privileges */
+void
+drop_privs(void)
+{
+#ifndef HAVE_DOSISH_SYSTEM
+ if (!uid_set)
+ init_uids();
+ if (real_uid != file_uid) {
+ if (setuid(real_uid) < 0) {
+ perror("dropping privileges failed");
+ exit(EXIT_FAILURE);
+ }
+ file_uid = real_uid;
+ }
+#endif
+}
diff --git a/src/pinentry/util.h b/src/pinentry/util.h
new file mode 100644
index 00000000..e6ad1dad
--- /dev/null
+++ b/src/pinentry/util.h
@@ -0,0 +1,35 @@
+/* util.h - Helper for managing malloced pointers
+ * Copyright (C) 2021 g10 Code GmbH
+ *
+ * Software engineering by Ingo Klöcker <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __PINENTRY_QT_UTIL_H__
+#define __PINENTRY_QT_UTIL_H__
+
+#include <stdlib.h>
+
+namespace _detail {
+struct FreeDeleter {
+ void operator()(void *ptr) const { free(ptr); }
+};
+} // namespace _detail
+
+template <class T>
+using unique_malloced_ptr = std::unique_ptr<T, _detail::FreeDeleter>;
+
+#endif // __PINENTRY_QT_UTIL_H__
diff --git a/src/signal.cpp b/src/signal.cpp
index da4dfb39..7722c36f 100644
--- a/src/signal.cpp
+++ b/src/signal.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,46 +20,10 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#include <csetjmp>
-
#include "GpgFrontend.h"
-
-#ifdef FREEBSD
-extern sigjmp_buf recover_env;
-#else
-extern jmp_buf recover_env;
-#endif
-
-/**
- * @brief handle the signal caught.
- *
- * @param sig signal number
- */
-void handle_signal(int sig) {
- static int _repeat_handle_num = 1, last_sig = sig;
- // SPDLOG_DEBUG("signal caught {}", sig);
- std::cout << "signal caught" << sig;
-
- if (last_sig == sig)
- _repeat_handle_num++;
- else
- _repeat_handle_num = 1, last_sig = sig;
-
- if (_repeat_handle_num > 3) {
- std::cout << "The same signal appears three times,"
- << "execute the termination operation." << sig;
- exit(-1);
- }
-
-#ifndef WINDOWS
- siglongjmp(recover_env, 1);
-#else
- longjmp(recover_env, 1);
-#endif
-}
diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt
new file mode 100644
index 00000000..c892c6b5
--- /dev/null
+++ b/src/test/CMakeLists.txt
@@ -0,0 +1,40 @@
+# Copyright (C) 2021 Saturneric <[email protected]>
+#
+# This file is part of GpgFrontend.
+#
+# GpgFrontend is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# GpgFrontend is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+#
+# The initial version of the source code is inherited from
+# the gpg4usb project, which is under GPL-3.0-or-later.
+#
+# All the source code of GpgFrontend was modified and released by
+# Saturneric <[email protected]> starting on May 12, 2021.
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Set configure for test
+
+aux_source_directory(./core TEST_SOURCE)
+aux_source_directory(. TEST_SOURCE)
+
+add_library(gpgfrontend_test SHARED ${TEST_SOURCE})
+
+set(_export_file "${CMAKE_CURRENT_SOURCE_DIR}/GpgFrontendTestExport.h")
+generate_export_header(gpgfrontend_test EXPORT_FILE_NAME "${_export_file}")
+
+target_link_libraries(gpgfrontend_test PRIVATE gtest)
+target_link_libraries(gpgfrontend_test PRIVATE gpgfrontend_core)
+target_link_libraries(gpgfrontend_test PRIVATE spdlog)
+
+add_test(AllTestsInGpgFrontend gpgfrontend_test)
diff --git a/src/test/GpgFrontendCoreExport.h b/src/test/GpgFrontendCoreExport.h
new file mode 100644
index 00000000..4d1b2f0b
--- /dev/null
+++ b/src/test/GpgFrontendCoreExport.h
@@ -0,0 +1,42 @@
+
+#ifndef GPGFRONTEND_TEST_EXPORT_H
+#define GPGFRONTEND_TEST_EXPORT_H
+
+#ifdef GPGFRONTEND_TEST_STATIC_DEFINE
+# define GPGFRONTEND_TEST_EXPORT
+# define GPGFRONTEND_TEST_NO_EXPORT
+#else
+# ifndef GPGFRONTEND_TEST_EXPORT
+# ifdef gpgfrontend_test_EXPORTS
+ /* We are building this library */
+# define GPGFRONTEND_TEST_EXPORT __attribute__((visibility("default")))
+# else
+ /* We are using this library */
+# define GPGFRONTEND_TEST_EXPORT __attribute__((visibility("default")))
+# endif
+# endif
+
+# ifndef GPGFRONTEND_TEST_NO_EXPORT
+# define GPGFRONTEND_TEST_NO_EXPORT __attribute__((visibility("hidden")))
+# endif
+#endif
+
+#ifndef GPGFRONTEND_TEST_DEPRECATED
+# define GPGFRONTEND_TEST_DEPRECATED __attribute__ ((__deprecated__))
+#endif
+
+#ifndef GPGFRONTEND_TEST_DEPRECATED_EXPORT
+# define GPGFRONTEND_TEST_DEPRECATED_EXPORT GPGFRONTEND_TEST_EXPORT GPGFRONTEND_TEST_DEPRECATED
+#endif
+
+#ifndef GPGFRONTEND_TEST_DEPRECATED_NO_EXPORT
+# define GPGFRONTEND_TEST_DEPRECATED_NO_EXPORT GPGFRONTEND_TEST_NO_EXPORT GPGFRONTEND_TEST_DEPRECATED
+#endif
+
+#if 0 /* DEFINE_NO_DEPRECATED */
+# ifndef GPGFRONTEND_TEST_NO_DEPRECATED
+# define GPGFRONTEND_TEST_NO_DEPRECATED
+# endif
+#endif
+
+#endif /* GPGFRONTEND_TEST_EXPORT_H */
diff --git a/src/test/GpgFrontendTest.cpp b/src/test/GpgFrontendTest.cpp
new file mode 100644
index 00000000..95b4179a
--- /dev/null
+++ b/src/test/GpgFrontendTest.cpp
@@ -0,0 +1,113 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgFrontendTest.h"
+
+#include <gtest/gtest.h>
+
+#include "core/GpgConstants.h"
+#include "core/function/GlobalSettingStation.h"
+#include "core/function/basic/ChannelObject.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/function/gpg/GpgKeyImportExporter.h"
+#include "core/utils/IOUtils.h"
+
+namespace GpgFrontend::Test {
+
+auto GenerateRandomString(size_t length) -> QString {
+ const QString characters =
+ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+ std::random_device random_device;
+ std::mt19937 generator(random_device());
+ std::uniform_int_distribution<> distribution(0, characters.size() - 1);
+
+ QString random_string;
+ for (size_t i = 0; i < length; ++i) {
+ random_string += characters[distribution(generator)];
+ }
+
+ return random_string;
+}
+
+void ConfigureGpgContext() {
+ auto db_path = QDir(QDir::tempPath() + "/" + GenerateRandomString(12));
+ GF_TEST_LOG_DEBUG("setting up new database path for test case: {}",
+ db_path.path());
+
+ if (db_path.exists()) db_path.rmdir(".");
+ db_path.mkpath(".");
+
+ GpgContext::CreateInstance(
+ kGpgFrontendDefaultChannel, [=]() -> ChannelObjectPtr {
+ GpgContextInitArgs args;
+ args.test_mode = true;
+ args.offline_mode = true;
+ args.db_path = db_path.path();
+
+ return ConvertToChannelObjectPtr<>(SecureCreateUniqueObject<GpgContext>(
+ args, kGpgFrontendDefaultChannel));
+ });
+}
+
+void ImportPrivateKeys(const QString& data_path, QSettings settings) {
+ auto key_files = QDir(":/test/key").entryList();
+
+ for (const auto& key_file : key_files) {
+ auto [success, gf_buffer] =
+ ReadFileGFBuffer(QString(":/test/key") + "/" + key_file);
+ if (success) {
+ GpgKeyImportExporter::GetInstance(kGpgFrontendDefaultChannel)
+ .ImportKey(gf_buffer);
+ } else {
+ GF_TEST_LOG_ERROR("read from key file failed: {}", key_file);
+ }
+ }
+}
+
+void SetupGlobalTestEnv() {
+ auto app_path = GlobalSettingStation::GetInstance().GetAppDir();
+ auto test_path = app_path + "/test";
+ auto test_config_path = test_path + "/conf/test.ini";
+ auto test_data_path = test_path + "/data";
+
+ GF_TEST_LOG_INFO("test config file path: {}", test_config_path);
+ GF_TEST_LOG_INFO("test data file path: {}", test_data_path);
+
+ ImportPrivateKeys(test_data_path,
+ QSettings(test_config_path, QSettings::IniFormat));
+}
+
+auto ExecuteAllTestCase(GpgFrontendContext args) -> int {
+ ConfigureGpgContext();
+ SetupGlobalTestEnv();
+
+ testing::InitGoogleTest(&args.argc, args.argv);
+ return RUN_ALL_TESTS();
+}
+
+} // namespace GpgFrontend::Test \ No newline at end of file
diff --git a/src/test/GpgFrontendTest.h b/src/test/GpgFrontendTest.h
new file mode 100644
index 00000000..405eee90
--- /dev/null
+++ b/src/test/GpgFrontendTest.h
@@ -0,0 +1,51 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "GpgFrontendTestExport.h"
+
+// Core
+#include "core/utils/LogUtils.h"
+
+namespace GpgFrontend::Test {
+
+struct GpgFrontendContext {
+ int argc;
+ char **argv;
+};
+
+auto GPGFRONTEND_TEST_EXPORT ExecuteAllTestCase(GpgFrontendContext args) -> int;
+
+#define GF_TEST_LOG_TRACE(...) GF_LOG_TRACE("test", __VA_ARGS__)
+#define GF_TEST_LOG_DEBUG(...) GF_LOG_DEBUG("test", __VA_ARGS__)
+#define GF_TEST_LOG_INFO(...) GF_LOG_INFO("test", __VA_ARGS__)
+#define GF_TEST_LOG_WARN(...) GF_LOG_WARN("test", __VA_ARGS__)
+#define GF_TEST_LOG_ERROR(...) GF_LOG_ERROR("test", __VA_ARGS__)
+
+} // namespace GpgFrontend::Test
diff --git a/src/test/GpgFrontendTestExport.h b/src/test/GpgFrontendTestExport.h
new file mode 100644
index 00000000..4d1b2f0b
--- /dev/null
+++ b/src/test/GpgFrontendTestExport.h
@@ -0,0 +1,42 @@
+
+#ifndef GPGFRONTEND_TEST_EXPORT_H
+#define GPGFRONTEND_TEST_EXPORT_H
+
+#ifdef GPGFRONTEND_TEST_STATIC_DEFINE
+# define GPGFRONTEND_TEST_EXPORT
+# define GPGFRONTEND_TEST_NO_EXPORT
+#else
+# ifndef GPGFRONTEND_TEST_EXPORT
+# ifdef gpgfrontend_test_EXPORTS
+ /* We are building this library */
+# define GPGFRONTEND_TEST_EXPORT __attribute__((visibility("default")))
+# else
+ /* We are using this library */
+# define GPGFRONTEND_TEST_EXPORT __attribute__((visibility("default")))
+# endif
+# endif
+
+# ifndef GPGFRONTEND_TEST_NO_EXPORT
+# define GPGFRONTEND_TEST_NO_EXPORT __attribute__((visibility("hidden")))
+# endif
+#endif
+
+#ifndef GPGFRONTEND_TEST_DEPRECATED
+# define GPGFRONTEND_TEST_DEPRECATED __attribute__ ((__deprecated__))
+#endif
+
+#ifndef GPGFRONTEND_TEST_DEPRECATED_EXPORT
+# define GPGFRONTEND_TEST_DEPRECATED_EXPORT GPGFRONTEND_TEST_EXPORT GPGFRONTEND_TEST_DEPRECATED
+#endif
+
+#ifndef GPGFRONTEND_TEST_DEPRECATED_NO_EXPORT
+# define GPGFRONTEND_TEST_DEPRECATED_NO_EXPORT GPGFRONTEND_TEST_NO_EXPORT GPGFRONTEND_TEST_DEPRECATED
+#endif
+
+#if 0 /* DEFINE_NO_DEPRECATED */
+# ifndef GPGFRONTEND_TEST_NO_DEPRECATED
+# define GPGFRONTEND_TEST_NO_DEPRECATED
+# endif
+#endif
+
+#endif /* GPGFRONTEND_TEST_EXPORT_H */
diff --git a/src/test/core/GpgCoreTest.cpp b/src/test/core/GpgCoreTest.cpp
new file mode 100644
index 00000000..1d7ddaa0
--- /dev/null
+++ b/src/test/core/GpgCoreTest.cpp
@@ -0,0 +1,40 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgCoreTest.h"
+
+#include "core/function/gpg/GpgKeyImportExporter.h"
+#include "core/utils/IOUtils.h"
+#include "core/utils/MemoryUtils.h"
+
+namespace GpgFrontend::Test {
+
+void GpgCoreTest::TearDown() {}
+
+void GpgCoreTest::SetUp() {}
+} // namespace GpgFrontend::Test
diff --git a/src/test/core/GpgCoreTest.h b/src/test/core/GpgCoreTest.h
new file mode 100644
index 00000000..26097f2c
--- /dev/null
+++ b/src/test/core/GpgCoreTest.h
@@ -0,0 +1,42 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include <gtest/gtest.h>
+
+namespace GpgFrontend::Test {
+
+class GpgCoreTest : public ::testing::Test {
+ public:
+ void SetUp() override;
+
+ void TearDown() override;
+};
+
+} // namespace GpgFrontend::Test \ No newline at end of file
diff --git a/src/test/core/GpgCoreTestBasicOpera.cpp b/src/test/core/GpgCoreTestBasicOpera.cpp
new file mode 100644
index 00000000..e525afa9
--- /dev/null
+++ b/src/test/core/GpgCoreTestBasicOpera.cpp
@@ -0,0 +1,373 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgCoreTest.h"
+#include "core/GpgModel.h"
+#include "core/function/basic/ChannelObject.h"
+#include "core/function/gpg/GpgBasicOperator.h"
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/function/result_analyse/GpgDecryptResultAnalyse.h"
+#include "core/model/GpgDecryptResult.h"
+#include "core/model/GpgEncryptResult.h"
+#include "core/model/GpgSignResult.h"
+#include "core/model/GpgVerifyResult.h"
+#include "core/utils/GpgUtils.h"
+
+namespace GpgFrontend::Test {
+
+TEST_F(GpgCoreTest, CoreEncryptDecrTest) {
+ std::atomic_bool callback_called_flag{false};
+
+ auto encrypt_key = GpgKeyGetter::GetInstance().GetPubkey(
+ "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29");
+
+ GpgBasicOperator::GetInstance().Encrypt(
+ {encrypt_key}, GFBuffer("Hello GpgFrontend!"), true,
+ [&callback_called_flag](GpgError err, const DataObjectPtr& data_obj) {
+ ASSERT_TRUE((data_obj->Check<GpgEncryptResult, GFBuffer>()));
+ auto result = ExtractParams<GpgEncryptResult>(data_obj, 0);
+ auto encr_out_buffer = ExtractParams<GFBuffer>(data_obj, 1);
+ ASSERT_TRUE(result.InvalidRecipients().empty());
+ ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
+
+ GpgBasicOperator::GetInstance().Decrypt(
+ encr_out_buffer, [&callback_called_flag](
+ GpgError err, const DataObjectPtr& data_obj) {
+ auto d_result = ExtractParams<GpgDecryptResult>(data_obj, 0);
+ auto decr_out_buffer = ExtractParams<GFBuffer>(data_obj, 1);
+ ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
+ ASSERT_FALSE(d_result.Recipients().empty());
+ ASSERT_EQ(d_result.Recipients()[0].keyid, "6A2764F8298DEB29");
+
+ ASSERT_EQ(decr_out_buffer, GFBuffer("Hello GpgFrontend!"));
+
+ // stop waiting
+ callback_called_flag = true;
+ });
+ });
+
+ int retry_count = 1000;
+ while (!callback_called_flag && retry_count-- > 0) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ }
+
+ ASSERT_TRUE(callback_called_flag);
+}
+
+TEST_F(GpgCoreTest, CoreEncryptSymmetricDecrTest) {
+ std::atomic_bool callback_called_flag{false};
+
+ auto encrypt_text = GFBuffer("Hello GpgFrontend!");
+
+ GpgBasicOperator::GetInstance().EncryptSymmetric(
+ encrypt_text, true,
+ [&callback_called_flag](GpgError err, const DataObjectPtr& data_obj) {
+ ASSERT_TRUE((data_obj->Check<GpgEncryptResult, GFBuffer>()));
+ auto result = ExtractParams<GpgEncryptResult>(data_obj, 0);
+ auto encr_out_buffer = ExtractParams<GFBuffer>(data_obj, 1);
+ ASSERT_TRUE(result.InvalidRecipients().empty());
+ ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
+
+ GpgBasicOperator::GetInstance().Decrypt(
+ encr_out_buffer, [&callback_called_flag](
+ GpgError err, const DataObjectPtr& data_obj) {
+ auto d_result = ExtractParams<GpgDecryptResult>(data_obj, 0);
+ auto decr_out_buffer = ExtractParams<GFBuffer>(data_obj, 1);
+ ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
+ ASSERT_TRUE(d_result.Recipients().empty());
+ ASSERT_EQ(decr_out_buffer, GFBuffer("Hello GpgFrontend!"));
+
+ // stop waiting
+ callback_called_flag = true;
+ });
+ });
+
+ int retry_count = 1000;
+ while (!callback_called_flag && retry_count-- > 0) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ }
+
+ ASSERT_TRUE(callback_called_flag);
+}
+
+TEST_F(GpgCoreTest, CoreEncryptDecrTest_KeyNotFound_1) {
+ std::atomic_bool callback_called_flag{false};
+
+ auto encr_out_data = GFBuffer(
+ "-----BEGIN PGP MESSAGE-----\n"
+ "\n"
+ "hQEMA6UM/S9sZ32MAQf9Fb6gp6nvgKTQBv2mmjXia6ODXYq6kNeLsPVzLCbHyWOs\n"
+ "0GDED11R1NksA3EQxFf4fzLkDpbo68r5bWy7c28c99Fr68IRET19Tw6Gu65MQezD\n"
+ "Rdzo1oVqmK9sfKqOT3+0S2H+suFYw5kfBztMZLVGGl9R9fOXdKcj0fqGs2br3e9D\n"
+ "ArBFqq07Bae2DD1J8mckWB2x9Uem4vjRiY+vEJcEdAS1N5xu1n7qzzyDgcRcS34X\n"
+ "PNBQeTrFMc2RS7mnip2DbyZVEjORobhguK6xZyqXXbvFacStGWDLptV3dcCn4JRO\n"
+ "dIORyt5wugqAtgE4qEGTvr/pJ/oXPw4Wve/trece/9I/AR38vW8ntVmDa/hV75iZ\n"
+ "4QGAhQ8grD4kq31GHXHUOmBX51XXW9SINmplC8elEx3R460EUZJjjb0OvTih+eZH\n"
+ "=8n2H\n"
+ "-----END PGP MESSAGE-----");
+
+ GpgBasicOperator::GetInstance().Decrypt(
+ encr_out_data,
+ [=, &callback_called_flag](GpgError err, const DataObjectPtr& data_obj) {
+ auto d_result = ExtractParams<GpgDecryptResult>(data_obj, 0);
+ auto decr_out_buffer = ExtractParams<GFBuffer>(data_obj, 1);
+ ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_SECKEY);
+ ASSERT_FALSE(d_result.Recipients().empty());
+ ASSERT_EQ(d_result.Recipients()[0].keyid, "A50CFD2F6C677D8C");
+
+ // stop waiting
+ callback_called_flag = true;
+ });
+
+ int retry_count = 1000;
+ while (!callback_called_flag && retry_count-- > 0) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ }
+
+ ASSERT_TRUE(callback_called_flag);
+}
+
+TEST_F(GpgCoreTest, CoreEncryptDecrTest_KeyNotFound_ResultAnalyse) {
+ std::atomic_bool callback_called_flag{false};
+
+ auto encr_out_data = GFBuffer(
+ "-----BEGIN PGP MESSAGE-----\n"
+ "\n"
+ "hQEMA6UM/S9sZ32MAQf9Fb6gp6nvgKTQBv2mmjXia6ODXYq6kNeLsPVzLCbHyWOs\n"
+ "0GDED11R1NksA3EQxFf4fzLkDpbo68r5bWy7c28c99Fr68IRET19Tw6Gu65MQezD\n"
+ "Rdzo1oVqmK9sfKqOT3+0S2H+suFYw5kfBztMZLVGGl9R9fOXdKcj0fqGs2br3e9D\n"
+ "ArBFqq07Bae2DD1J8mckWB2x9Uem4vjRiY+vEJcEdAS1N5xu1n7qzzyDgcRcS34X\n"
+ "PNBQeTrFMc2RS7mnip2DbyZVEjORobhguK6xZyqXXbvFacStGWDLptV3dcCn4JRO\n"
+ "dIORyt5wugqAtgE4qEGTvr/pJ/oXPw4Wve/trece/9I/AR38vW8ntVmDa/hV75iZ\n"
+ "4QGAhQ8grD4kq31GHXHUOmBX51XXW9SINmplC8elEx3R460EUZJjjb0OvTih+eZH\n"
+ "=8n2H\n"
+ "-----END PGP MESSAGE-----");
+
+ GpgBasicOperator::GetInstance().Decrypt(
+ encr_out_data,
+ [=, &callback_called_flag](GpgError err, const DataObjectPtr& data_obj) {
+ auto d_result = ExtractParams<GpgDecryptResult>(data_obj, 0);
+ auto decr_out_buffer = ExtractParams<GFBuffer>(data_obj, 1);
+ ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_SECKEY);
+ ASSERT_FALSE(d_result.Recipients().empty());
+ ASSERT_EQ(d_result.Recipients()[0].keyid, "A50CFD2F6C677D8C");
+
+ GpgDecryptResultAnalyse analyse{err, d_result};
+ analyse.Analyse();
+ ASSERT_EQ(analyse.GetStatus(), -1);
+ ASSERT_FALSE(analyse.GetResultReport().isEmpty());
+
+ // stop waiting
+ callback_called_flag = true;
+ });
+
+ int retry_count = 1000;
+ while (!callback_called_flag && retry_count-- > 0) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ }
+
+ ASSERT_TRUE(callback_called_flag);
+}
+
+TEST_F(GpgCoreTest, CoreSignVerifyNormalTest) {
+ std::atomic_bool callback_called_flag{false};
+
+ auto sign_key = GpgKeyGetter::GetInstance().GetPubkey(
+ "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1");
+ auto sign_text = GFBuffer("Hello GpgFrontend!");
+
+ GpgBasicOperator::GetInstance().Sign(
+ {sign_key}, sign_text, GPGME_SIG_MODE_NORMAL, true,
+ [&callback_called_flag](GpgError err, const DataObjectPtr& data_obj) {
+ ASSERT_TRUE((data_obj->Check<GpgSignResult, GFBuffer>()));
+ auto result = ExtractParams<GpgSignResult>(data_obj, 0);
+ auto sign_out_buffer = ExtractParams<GFBuffer>(data_obj, 1);
+ ASSERT_TRUE(result.InvalidSigners().empty());
+ ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
+
+ GpgBasicOperator::GetInstance().Verify(
+ sign_out_buffer, GFBuffer(),
+ [&callback_called_flag](GpgError err,
+ const DataObjectPtr& data_obj) {
+ auto d_result = ExtractParams<GpgVerifyResult>(data_obj, 0);
+ ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
+ ASSERT_FALSE(d_result.GetSignature().empty());
+ ASSERT_EQ(d_result.GetSignature().at(0).GetFingerprint(),
+ "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1");
+
+ // stop waiting
+ callback_called_flag = true;
+ });
+ });
+
+ int retry_count = 1000;
+ while (!callback_called_flag && retry_count-- > 0) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ }
+
+ ASSERT_TRUE(callback_called_flag);
+}
+
+TEST_F(GpgCoreTest, CoreSignVerifyDetachTest) {
+ std::atomic_bool callback_called_flag{false};
+
+ auto sign_key = GpgKeyGetter::GetInstance().GetPubkey(
+ "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1");
+ auto sign_text = GFBuffer("Hello GpgFrontend!");
+
+ GpgBasicOperator::GetInstance().Sign(
+ {sign_key}, sign_text, GPGME_SIG_MODE_DETACH, true,
+ [=, &callback_called_flag](GpgError err, const DataObjectPtr& data_obj) {
+ ASSERT_TRUE((data_obj->Check<GpgSignResult, GFBuffer>()));
+ auto result = ExtractParams<GpgSignResult>(data_obj, 0);
+ auto sign_out_buffer = ExtractParams<GFBuffer>(data_obj, 1);
+ ASSERT_TRUE(result.InvalidSigners().empty());
+ ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
+
+ GpgBasicOperator::GetInstance().Verify(
+ sign_text, sign_out_buffer,
+ [&callback_called_flag](GpgError err,
+ const DataObjectPtr& data_obj) {
+ auto d_result = ExtractParams<GpgVerifyResult>(data_obj, 0);
+ ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
+ ASSERT_FALSE(d_result.GetSignature().empty());
+ ASSERT_EQ(d_result.GetSignature().at(0).GetFingerprint(),
+ "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1");
+
+ // stop waiting
+ callback_called_flag = true;
+ });
+ });
+
+ int retry_count = 1000;
+ while (!callback_called_flag && retry_count-- > 0) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ }
+
+ ASSERT_TRUE(callback_called_flag);
+}
+
+TEST_F(GpgCoreTest, CoreSignVerifyClearTest) {
+ std::atomic_bool callback_called_flag{false};
+
+ auto sign_key = GpgKeyGetter::GetInstance().GetPubkey(
+ "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1");
+ auto sign_text = GFBuffer("Hello GpgFrontend!");
+
+ GpgBasicOperator::GetInstance().Sign(
+ {sign_key}, sign_text, GPGME_SIG_MODE_CLEAR, true,
+ [&callback_called_flag](GpgError err, const DataObjectPtr& data_obj) {
+ ASSERT_TRUE((data_obj->Check<GpgSignResult, GFBuffer>()));
+ auto result = ExtractParams<GpgSignResult>(data_obj, 0);
+ auto sign_out_buffer = ExtractParams<GFBuffer>(data_obj, 1);
+ ASSERT_TRUE(result.InvalidSigners().empty());
+ ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
+
+ GpgBasicOperator::GetInstance().Verify(
+ sign_out_buffer, GFBuffer(),
+ [&callback_called_flag](GpgError err,
+ const DataObjectPtr& data_obj) {
+ auto verify_reult = ExtractParams<GpgVerifyResult>(data_obj, 0);
+ ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
+ ASSERT_FALSE(verify_reult.GetSignature().empty());
+ ASSERT_EQ(verify_reult.GetSignature().at(0).GetFingerprint(),
+ "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1");
+
+ // stop waiting
+ callback_called_flag = true;
+ });
+ });
+
+ int retry_count = 1000;
+ while (!callback_called_flag && retry_count-- > 0) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ }
+
+ ASSERT_TRUE(callback_called_flag);
+}
+
+TEST_F(GpgCoreTest, CoreEncryptSignDecrVerifyTest) {
+ std::atomic_bool callback_called_flag{false};
+
+ auto encrypt_key = GpgKeyGetter::GetInstance().GetPubkey(
+ "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1");
+ auto sign_key = GpgKeyGetter::GetInstance().GetKey(
+ "8933EB283A18995F45D61DAC021D89771B680FFB");
+ auto encrypt_text = GFBuffer("Hello GpgFrontend!");
+
+ ASSERT_TRUE(sign_key.IsPrivateKey());
+ ASSERT_TRUE(sign_key.IsHasActualSigningCapability());
+
+ GpgBasicOperator::GetInstance().EncryptSign(
+ {encrypt_key}, {sign_key}, encrypt_text, true,
+ [&callback_called_flag](GpgError err, const DataObjectPtr& data_obj) {
+ ASSERT_TRUE(
+ (data_obj->Check<GpgEncryptResult, GpgSignResult, GFBuffer>()));
+ auto encr_result = ExtractParams<GpgEncryptResult>(data_obj, 0);
+ auto sign_result = ExtractParams<GpgSignResult>(data_obj, 1);
+ auto encr_out_buffer = ExtractParams<GFBuffer>(data_obj, 2);
+ ASSERT_TRUE(encr_result.InvalidRecipients().empty());
+ ASSERT_TRUE(sign_result.InvalidSigners().empty());
+ ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
+
+ GpgBasicOperator::GetInstance().DecryptVerify(
+ encr_out_buffer, [&callback_called_flag](
+ GpgError err, const DataObjectPtr& data_obj) {
+ ASSERT_TRUE(
+ (data_obj
+ ->Check<GpgDecryptResult, GpgVerifyResult, GFBuffer>()));
+ auto decrypt_result =
+ ExtractParams<GpgDecryptResult>(data_obj, 0);
+ auto verify_reult = ExtractParams<GpgVerifyResult>(data_obj, 1);
+ auto decr_out_buffer = ExtractParams<GFBuffer>(data_obj, 2);
+
+ ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
+
+ ASSERT_FALSE(decrypt_result.Recipients().empty());
+ ASSERT_EQ(decr_out_buffer, GFBuffer("Hello GpgFrontend!"));
+
+ ASSERT_EQ(decrypt_result.Recipients()[0].keyid,
+ "F89C95A05088CC93");
+ ASSERT_FALSE(verify_reult.GetSignature().empty());
+ ASSERT_EQ(verify_reult.GetSignature().at(0).GetFingerprint(),
+ "8933EB283A18995F45D61DAC021D89771B680FFB");
+
+ // stop waiting
+ callback_called_flag = true;
+ });
+ });
+
+ int retry_count = 1000;
+ while (!callback_called_flag && retry_count-- > 0) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ }
+
+ ASSERT_TRUE(callback_called_flag);
+}
+
+} // namespace GpgFrontend::Test
diff --git a/src/test/core/GpgCoreTestFileBasicOpera.cpp b/src/test/core/GpgCoreTestFileBasicOpera.cpp
new file mode 100644
index 00000000..029ff6fc
--- /dev/null
+++ b/src/test/core/GpgCoreTestFileBasicOpera.cpp
@@ -0,0 +1,239 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GpgCoreTest.h"
+#include "core/GpgModel.h"
+#include "core/function/basic/ChannelObject.h"
+#include "core/function/gpg/GpgBasicOperator.h"
+#include "core/function/gpg/GpgFileOpera.h"
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/function/result_analyse/GpgDecryptResultAnalyse.h"
+#include "core/model/GpgDecryptResult.h"
+#include "core/model/GpgEncryptResult.h"
+#include "core/model/GpgSignResult.h"
+#include "core/model/GpgVerifyResult.h"
+#include "core/utils/GpgUtils.h"
+#include "core/utils/IOUtils.h"
+
+namespace GpgFrontend::Test {
+
+TEST_F(GpgCoreTest, CoreFileEncryptDecrTest) {
+ std::atomic_bool callback_called_flag{false};
+
+ auto encrypt_key = GpgKeyGetter::GetInstance().GetPubkey(
+ "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29");
+ auto input_file = CreateTempFileAndWriteData("Hello GpgFrontend!");
+ auto output_file = GetTempFilePath();
+
+ GpgFileOpera::GetInstance().EncryptFile(
+ {encrypt_key}, input_file, true, output_file,
+ [output_file, &callback_called_flag](GpgError err,
+ const DataObjectPtr& data_obj) {
+ ASSERT_TRUE((data_obj->Check<GpgEncryptResult>()));
+
+ auto result = ExtractParams<GpgEncryptResult>(data_obj, 0);
+ ASSERT_TRUE(result.InvalidRecipients().empty());
+ ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
+
+ auto decrpypt_output_file = GetTempFilePath();
+ GpgFileOpera::GetInstance().DecryptFile(
+ output_file, decrpypt_output_file,
+ [decrpypt_output_file, &callback_called_flag](
+ GpgError err, const DataObjectPtr& data_obj) {
+ auto d_result = ExtractParams<GpgDecryptResult>(data_obj, 0);
+
+ ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
+ ASSERT_FALSE(d_result.Recipients().empty());
+ ASSERT_EQ(d_result.Recipients()[0].keyid, "6A2764F8298DEB29");
+
+ const auto [read_success, buffer] =
+ ReadFileGFBuffer(decrpypt_output_file);
+ ASSERT_TRUE(read_success);
+ ASSERT_EQ(buffer, GFBuffer("Hello GpgFrontend!"));
+
+ // stop waiting
+ callback_called_flag = true;
+ });
+ });
+
+ int retry_count = 1000;
+ while (!callback_called_flag && retry_count-- > 0) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ }
+
+ ASSERT_TRUE(callback_called_flag);
+}
+
+TEST_F(GpgCoreTest, CoreFileEncryptSymmetricDecrTest) {
+ std::atomic_bool callback_called_flag{false};
+
+ auto input_file = CreateTempFileAndWriteData("Hello GpgFrontend!");
+ auto output_file = GetTempFilePath();
+
+ GpgFileOpera::GetInstance().EncryptFileSymmetric(
+ input_file, true, output_file,
+ [&callback_called_flag, output_file](GpgError err,
+ const DataObjectPtr& data_obj) {
+ ASSERT_TRUE((data_obj->Check<GpgEncryptResult>()));
+ auto result = ExtractParams<GpgEncryptResult>(data_obj, 0);
+ ASSERT_TRUE(result.InvalidRecipients().empty());
+ ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
+
+ auto decrpypt_output_file = GetTempFilePath();
+ GpgFileOpera::GetInstance().DecryptFile(
+ output_file, decrpypt_output_file,
+ [&callback_called_flag, decrpypt_output_file](
+ GpgError err, const DataObjectPtr& data_obj) {
+ ASSERT_TRUE((data_obj->Check<GpgDecryptResult>()));
+
+ auto decrypt_result =
+ ExtractParams<GpgDecryptResult>(data_obj, 0);
+ ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
+ ASSERT_TRUE(decrypt_result.Recipients().empty());
+
+ const auto [read_success, buffer] =
+ ReadFileGFBuffer(decrpypt_output_file);
+ ASSERT_TRUE(read_success);
+ ASSERT_EQ(buffer, GFBuffer("Hello GpgFrontend!"));
+
+ // stop waiting
+ callback_called_flag = true;
+ });
+ });
+
+ int retry_count = 1000;
+ while (!callback_called_flag && retry_count-- > 0) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ }
+
+ ASSERT_TRUE(callback_called_flag);
+}
+
+TEST_F(GpgCoreTest, CoreFileSignVerifyNormalTest) {
+ std::atomic_bool callback_called_flag{false};
+
+ auto sign_key = GpgKeyGetter::GetInstance().GetPubkey(
+ "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1");
+ auto input_file = CreateTempFileAndWriteData("Hello GpgFrontend!");
+ auto output_file = GetTempFilePath();
+
+ GpgFileOpera::GetInstance().SignFile(
+ {sign_key}, input_file, true, output_file,
+ [&callback_called_flag, input_file, output_file](
+ GpgError err, const DataObjectPtr& data_obj) {
+ ASSERT_TRUE((data_obj->Check<GpgSignResult>()));
+ auto result = ExtractParams<GpgSignResult>(data_obj, 0);
+ ASSERT_TRUE(result.InvalidSigners().empty());
+ ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
+
+ GpgFileOpera::GetInstance().VerifyFile(
+ input_file, output_file,
+ [&callback_called_flag](GpgError err,
+ const DataObjectPtr& data_obj) {
+ auto d_result = ExtractParams<GpgVerifyResult>(data_obj, 0);
+ ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
+ ASSERT_FALSE(d_result.GetSignature().empty());
+ ASSERT_EQ(d_result.GetSignature().at(0).GetFingerprint(),
+ "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1");
+
+ // stop waiting
+ callback_called_flag = true;
+ });
+ });
+
+ int retry_count = 1000;
+ while (!callback_called_flag && retry_count-- > 0) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ }
+
+ ASSERT_TRUE(callback_called_flag);
+}
+
+TEST_F(GpgCoreTest, CoreFileEncryptSignDecrVerifyTest) {
+ std::atomic_bool callback_called_flag{false};
+
+ auto encrypt_key = GpgKeyGetter::GetInstance().GetPubkey(
+ "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1");
+ auto sign_key = GpgKeyGetter::GetInstance().GetKey(
+ "8933EB283A18995F45D61DAC021D89771B680FFB");
+ auto input_file = CreateTempFileAndWriteData("Hello GpgFrontend!");
+ auto output_file = GetTempFilePath();
+
+ ASSERT_TRUE(sign_key.IsPrivateKey());
+ ASSERT_TRUE(sign_key.IsHasActualSigningCapability());
+
+ GpgFileOpera::GetInstance().EncryptSignFile(
+ {encrypt_key}, {sign_key}, input_file, true, output_file,
+ [&callback_called_flag, output_file](GpgError err,
+ const DataObjectPtr& data_obj) {
+ ASSERT_TRUE((data_obj->Check<GpgEncryptResult, GpgSignResult>()));
+ auto encr_result = ExtractParams<GpgEncryptResult>(data_obj, 0);
+ auto sign_result = ExtractParams<GpgSignResult>(data_obj, 1);
+ ASSERT_TRUE(encr_result.InvalidRecipients().empty());
+ ASSERT_TRUE(sign_result.InvalidSigners().empty());
+ ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
+
+ auto decrpypt_output_file = GetTempFilePath();
+ GpgFileOpera::GetInstance().DecryptVerifyFile(
+ output_file, decrpypt_output_file,
+ [&callback_called_flag, decrpypt_output_file](
+ GpgError err, const DataObjectPtr& data_obj) {
+ ASSERT_TRUE(
+ (data_obj->Check<GpgDecryptResult, GpgVerifyResult>()));
+ auto decrypt_result =
+ ExtractParams<GpgDecryptResult>(data_obj, 0);
+ auto verify_reult = ExtractParams<GpgVerifyResult>(data_obj, 1);
+
+ ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
+
+ ASSERT_FALSE(decrypt_result.Recipients().empty());
+ ASSERT_EQ(decrypt_result.Recipients()[0].keyid,
+ "F89C95A05088CC93");
+ ASSERT_FALSE(verify_reult.GetSignature().empty());
+ ASSERT_EQ(verify_reult.GetSignature().at(0).GetFingerprint(),
+ "8933EB283A18995F45D61DAC021D89771B680FFB");
+
+ const auto [read_success, buffer] =
+ ReadFileGFBuffer(decrpypt_output_file);
+ ASSERT_TRUE(read_success);
+ ASSERT_EQ(buffer, GFBuffer("Hello GpgFrontend!"));
+
+ // stop waiting
+ callback_called_flag = true;
+ });
+ });
+
+ int retry_count = 1000;
+ while (!callback_called_flag && retry_count-- > 0) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ }
+
+ ASSERT_TRUE(callback_called_flag);
+}
+
+} // namespace GpgFrontend::Test
diff --git a/src/test/core/GpgCoreTestImportExport.cpp b/src/test/core/GpgCoreTestImportExport.cpp
new file mode 100644
index 00000000..faf8b58a
--- /dev/null
+++ b/src/test/core/GpgCoreTestImportExport.cpp
@@ -0,0 +1,39 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include <string>
+#include <vector>
+
+#include "GpgCoreTest.h"
+#include "core/GpgConstants.h"
+
+namespace GpgFrontend::Test {
+
+// TEST_F(GpgCoreTest, CoreExportSecretTest) {}
+
+} // namespace GpgFrontend::Test \ No newline at end of file
diff --git a/src/test/core/GpgCoreTestKeyModel.cpp b/src/test/core/GpgCoreTestKeyModel.cpp
new file mode 100644
index 00000000..cf1fd9ea
--- /dev/null
+++ b/src/test/core/GpgCoreTestKeyModel.cpp
@@ -0,0 +1,181 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include <gtest/gtest.h>
+
+#include "GpgCoreTest.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/model/GpgData.h"
+#include "core/model/GpgKey.h"
+#include "core/utils/GpgUtils.h"
+
+namespace GpgFrontend::Test {
+
+TEST_F(GpgCoreTest, CoreInitTest) {
+ auto& ctx = GpgContext::GetInstance(kGpgFrontendDefaultChannel);
+ auto& ctx_default = GpgContext::GetInstance();
+ ASSERT_TRUE(ctx.Good());
+ ASSERT_TRUE(ctx_default.Good());
+}
+
+TEST_F(GpgCoreTest, GpgDataTest) {
+ auto data_buff = QString(
+ "cqEh8fyKWtmiXrW2zzlszJVGJrpXDDpzgP7ZELGxhfZYFi8rMrSVKDwrpFZBSWMG");
+
+ GpgData data(data_buff.data(), data_buff.size());
+
+ auto out_buffer = data.Read2GFBuffer();
+ ASSERT_EQ(out_buffer.Size(), 64);
+}
+
+TEST_F(GpgCoreTest, GpgKeyTest) {
+ auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel)
+ .GetKey("9490795B78F8AFE9F93BD09281704859182661FB");
+ ASSERT_TRUE(key.IsGood());
+ ASSERT_TRUE(key.IsPrivateKey());
+ ASSERT_TRUE(key.IsHasMasterKey());
+
+ ASSERT_FALSE(key.IsDisabled());
+ ASSERT_FALSE(key.IsRevoked());
+
+ ASSERT_EQ(key.GetProtocol(), "OpenPGP");
+
+ ASSERT_EQ(key.GetSubKeys()->size(), 2);
+ ASSERT_EQ(key.GetUIDs()->size(), 1);
+
+ ASSERT_TRUE(key.IsHasCertificationCapability());
+ ASSERT_FALSE(key.IsHasEncryptionCapability());
+ ASSERT_TRUE(key.IsHasSigningCapability());
+ ASSERT_FALSE(key.IsHasAuthenticationCapability());
+ ASSERT_FALSE(key.IsHasActualCertificationCapability());
+ ASSERT_FALSE(key.IsHasActualEncryptionCapability());
+ ASSERT_FALSE(key.IsHasActualSigningCapability());
+ ASSERT_FALSE(key.IsHasActualAuthenticationCapability());
+
+ ASSERT_EQ(key.GetName(), "GpgFrontendTest");
+ ASSERT_TRUE(key.GetComment().isEmpty());
+ ASSERT_EQ(key.GetEmail(), "[email protected]");
+ ASSERT_EQ(key.GetId(), "81704859182661FB");
+ ASSERT_EQ(key.GetFingerprint(), "9490795B78F8AFE9F93BD09281704859182661FB");
+ ASSERT_EQ(key.GetExpireTime(),
+ QDateTime::fromString("20230905T040000", Qt::ISODate));
+ ASSERT_EQ(key.GetPublicKeyAlgo(), "RSA");
+ ASSERT_EQ(key.GetPrimaryKeyLength(), 3072);
+ ASSERT_EQ(key.GetLastUpdateTime(),
+ QDateTime::fromString("19700101T000000", Qt::ISODate));
+ ASSERT_EQ(key.GetCreateTime(),
+ QDateTime::fromString("20210905T060153", Qt::ISODate));
+
+ ASSERT_EQ(key.GetOwnerTrust(), "Unknown");
+
+ ASSERT_EQ(key.IsExpired(),
+ key.GetExpireTime() < QDateTime::currentDateTime());
+}
+
+TEST_F(GpgCoreTest, GpgSubKeyTest) {
+ auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel)
+ .GetKey("9490795B78F8AFE9F93BD09281704859182661FB");
+ auto sub_keys = key.GetSubKeys();
+ ASSERT_EQ(sub_keys->size(), 2);
+
+ auto& sub_key = sub_keys->back();
+
+ ASSERT_FALSE(sub_key.IsRevoked());
+ ASSERT_FALSE(sub_key.IsDisabled());
+ ASSERT_EQ(sub_key.GetCreateTime(),
+ QDateTime::fromString("20210905T060153", Qt::ISODate));
+
+ ASSERT_FALSE(sub_key.IsCardKey());
+ ASSERT_TRUE(sub_key.IsPrivateKey());
+ ASSERT_EQ(sub_key.GetID(), "2B36803235B5E25B");
+ ASSERT_EQ(sub_key.GetFingerprint(),
+ "50D37E8F8EE7340A6794E0592B36803235B5E25B");
+ ASSERT_EQ(sub_key.GetKeyLength(), 3072);
+ ASSERT_EQ(sub_key.GetPubkeyAlgo(), "RSA");
+ ASSERT_FALSE(sub_key.IsHasCertificationCapability());
+ ASSERT_FALSE(sub_key.IsHasAuthenticationCapability());
+ ASSERT_FALSE(sub_key.IsHasSigningCapability());
+ ASSERT_TRUE(sub_key.IsHasEncryptionCapability());
+ ASSERT_EQ(key.GetExpireTime(),
+ QDateTime::fromString("20230905T040000", Qt::ISODate));
+
+ ASSERT_EQ(sub_key.IsExpired(),
+ sub_key.GetExpireTime() < QDateTime::currentDateTime());
+}
+
+TEST_F(GpgCoreTest, GpgUIDTest) {
+ auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel)
+ .GetKey("9490795B78F8AFE9F93BD09281704859182661FB");
+ auto uids = key.GetUIDs();
+ ASSERT_EQ(uids->size(), 1);
+ auto& uid = uids->front();
+
+ ASSERT_EQ(uid.GetName(), "GpgFrontendTest");
+ ASSERT_TRUE(uid.GetComment().isEmpty());
+ ASSERT_EQ(uid.GetEmail(), "[email protected]");
+ ASSERT_EQ(uid.GetUID(), "GpgFrontendTest <[email protected]>");
+ ASSERT_FALSE(uid.GetInvalid());
+ ASSERT_FALSE(uid.GetRevoked());
+}
+
+TEST_F(GpgCoreTest, GpgKeySignatureTest) {
+ auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel)
+ .GetKey("9490795B78F8AFE9F93BD09281704859182661FB");
+ auto uids = key.GetUIDs();
+ ASSERT_EQ(uids->size(), 1);
+ auto& uid = uids->front();
+
+ auto signatures = uid.GetSignatures();
+ ASSERT_EQ(signatures->size(), 1);
+ auto& signature = signatures->front();
+
+ ASSERT_EQ(signature.GetName(), "GpgFrontendTest");
+ ASSERT_TRUE(signature.GetComment().isEmpty());
+ ASSERT_EQ(signature.GetEmail(), "[email protected]");
+ ASSERT_EQ(signature.GetKeyID(), "81704859182661FB");
+ ASSERT_EQ(signature.GetPubkeyAlgo(), "RSA");
+
+ ASSERT_FALSE(signature.IsRevoked());
+ ASSERT_FALSE(signature.IsInvalid());
+ ASSERT_EQ(CheckGpgError(signature.GetStatus()), GPG_ERR_NO_ERROR);
+ ASSERT_EQ(signature.GetUID(),
+ "GpgFrontendTest <[email protected]>");
+}
+
+TEST_F(GpgCoreTest, GpgKeyGetterTest) {
+ auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel)
+ .GetKey("9490795B78F8AFE9F93BD09281704859182661FB");
+ ASSERT_TRUE(key.IsGood());
+ auto keys = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel).FetchKey();
+
+ EXPECT_GT(keys->size(), 0);
+ ASSERT_TRUE(find(keys->begin(), keys->end(), key) != keys->end());
+}
+
+} // namespace GpgFrontend::Test \ No newline at end of file
diff --git a/src/test/core/GpgCoreTestKeygen.cpp b/src/test/core/GpgCoreTestKeygen.cpp
new file mode 100644
index 00000000..57e7cbb9
--- /dev/null
+++ b/src/test/core/GpgCoreTestKeygen.cpp
@@ -0,0 +1,212 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include <gtest/gtest.h>
+#include <qeventloop.h>
+
+#include <cstddef>
+
+#include "GpgCoreTest.h"
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/function/gpg/GpgKeyOpera.h"
+#include "core/function/result_analyse/GpgResultAnalyse.h"
+#include "core/model/GpgGenKeyInfo.h"
+#include "core/model/GpgGenerateKeyResult.h"
+#include "core/model/GpgKey.h"
+#include "core/utils/GpgUtils.h"
+#include "core/utils/MemoryUtils.h"
+
+namespace GpgFrontend::Test {
+
+TEST_F(GpgCoreTest, GenerateKeyTest) {
+ auto keygen_info = SecureCreateSharedObject<GenKeyInfo>();
+ keygen_info->SetName("foo_0");
+ keygen_info->SetEmail("[email protected]");
+ keygen_info->SetComment("");
+ keygen_info->SetKeyLength(1024);
+ keygen_info->SetAlgo(std::get<1>(keygen_info->GetSupportedKeyAlgo()[0]));
+ keygen_info->SetNonExpired(true);
+ keygen_info->SetNonPassPhrase(true);
+
+ std::atomic_bool callback_called_flag{false};
+
+ GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel)
+ .GenerateKey(keygen_info, [&callback_called_flag](
+ GpgError err,
+ const DataObjectPtr& data_object) {
+ ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
+
+ ASSERT_EQ(data_object->GetObjectSize(), 1);
+ ASSERT_TRUE(data_object->Check<GpgGenerateKeyResult>());
+
+ auto result = ExtractParams<GpgGenerateKeyResult>(data_object, 0);
+ ASSERT_TRUE(result.IsGood());
+ auto fpr = result.GetFingerprint();
+
+ auto key =
+ GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel).GetKey(fpr);
+ ASSERT_TRUE(key.IsGood());
+
+ GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel).DeleteKey(fpr);
+
+ callback_called_flag = true;
+ ASSERT_FALSE(fpr.isEmpty());
+ });
+
+ int retry_count = 1000;
+ while (!callback_called_flag && retry_count-- > 0) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ }
+
+ ASSERT_TRUE(callback_called_flag);
+}
+
+TEST_F(GpgCoreTest, GenerateKeyTest_1) {
+ auto keygen_info = SecureCreateSharedObject<GenKeyInfo>();
+ keygen_info->SetName("foo_1");
+ keygen_info->SetEmail("[email protected]");
+ keygen_info->SetComment("hello gpgfrontend");
+ keygen_info->SetAlgo(std::get<1>(keygen_info->GetSupportedKeyAlgo()[0]));
+ keygen_info->SetKeyLength(4096);
+ keygen_info->SetNonExpired(false);
+ keygen_info->SetExpireTime(
+ QDateTime::currentDateTime().addSecs(static_cast<qint64>(24 * 3600)));
+ keygen_info->SetNonPassPhrase(false);
+
+ std::atomic_bool callback_called_flag{false};
+
+ GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel)
+ .GenerateKey(keygen_info, [&callback_called_flag](
+ GpgError err,
+ const DataObjectPtr& data_object) {
+ ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
+
+ ASSERT_EQ(data_object->GetObjectSize(), 1);
+ ASSERT_TRUE(data_object->Check<GpgGenerateKeyResult>());
+
+ auto result = ExtractParams<GpgGenerateKeyResult>(data_object, 0);
+ ASSERT_TRUE(result.IsGood());
+ auto fpr = result.GetFingerprint();
+
+ auto key =
+ GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel).GetKey(fpr);
+ ASSERT_TRUE(key.IsGood());
+
+ GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel).DeleteKey(fpr);
+
+ callback_called_flag = true;
+ ASSERT_FALSE(fpr.isEmpty());
+ });
+
+ int retry_count = 2000;
+ while (!callback_called_flag && retry_count-- > 0) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ }
+
+ ASSERT_TRUE(callback_called_flag);
+}
+
+TEST_F(GpgCoreTest, GenerateKeyTest_4) {
+ auto keygen_info = SecureCreateSharedObject<GenKeyInfo>();
+ keygen_info->SetName("foo_2");
+ keygen_info->SetEmail("[email protected]");
+ keygen_info->SetComment("");
+ keygen_info->SetAlgo(std::get<1>(keygen_info->GetSupportedKeyAlgo()[1]));
+ keygen_info->SetNonExpired(true);
+ keygen_info->SetNonPassPhrase(false);
+
+ std::atomic_bool callback_called_flag{false};
+
+ GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel)
+ .GenerateKey(keygen_info, [&callback_called_flag](
+ GpgError err,
+ const DataObjectPtr& data_object) {
+ ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
+
+ auto result = ExtractParams<GpgGenerateKeyResult>(data_object, 0);
+ ASSERT_TRUE(result.IsGood());
+ auto fpr = result.GetFingerprint();
+
+ auto key =
+ GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel).GetKey(fpr);
+ ASSERT_TRUE(key.IsGood());
+
+ GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel).DeleteKey(fpr);
+
+ callback_called_flag = true;
+ ASSERT_FALSE(fpr.isEmpty());
+ });
+
+ int retry_count = 2000;
+ while (!callback_called_flag && retry_count-- > 0) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ }
+
+ ASSERT_TRUE(callback_called_flag);
+}
+
+TEST_F(GpgCoreTest, GenerateKeyTest_5) {
+ auto keygen_info = SecureCreateSharedObject<GenKeyInfo>();
+ keygen_info->SetName("foo_3");
+ keygen_info->SetEmail("[email protected]");
+ keygen_info->SetComment("");
+ keygen_info->SetAlgo(std::get<1>(keygen_info->GetSupportedKeyAlgo()[2]));
+ keygen_info->SetNonExpired(true);
+ keygen_info->SetNonPassPhrase(false);
+
+ std::atomic_bool callback_called_flag{false};
+
+ GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel)
+ .GenerateKey(keygen_info, [&callback_called_flag](
+ GpgError err,
+ const DataObjectPtr& data_object) {
+ ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
+
+ auto result = ExtractParams<GpgGenerateKeyResult>(data_object, 0);
+ ASSERT_TRUE(result.IsGood());
+ auto fpr = result.GetFingerprint();
+
+ auto key =
+ GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel).GetKey(fpr);
+ ASSERT_TRUE(key.IsGood());
+
+ GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel).DeleteKey(fpr);
+
+ callback_called_flag = true;
+ ASSERT_FALSE(fpr.isEmpty());
+ });
+
+ int retry_count = 1000;
+ while (!callback_called_flag && retry_count-- > 0) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ }
+
+ ASSERT_TRUE(callback_called_flag);
+}
+
+} // namespace GpgFrontend::Test
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
index ba72c49a..c9c27462 100644
--- a/src/ui/CMakeLists.txt
+++ b/src/ui/CMakeLists.txt
@@ -1,5 +1,4 @@
-#
-# Copyright (C) 2021 Saturneric
+# Copyright (C) 2021 Saturneric <[email protected]>
#
# This file is part of GpgFrontend.
#
@@ -20,10 +19,11 @@
# the gpg4usb project, which is under GPL-3.0-or-later.
#
# All the source code of GpgFrontend was modified and released by
-# Saturneric<[email protected]> starting on May 12, 2021.
+# Saturneric <[email protected]> starting on May 12, 2021.
#
# SPDX-License-Identifier: GPL-3.0-or-later
+
# tracking source files
aux_source_directory(. UI_SOURCE)
aux_source_directory(dialog/keypair_details UI_SOURCE)
@@ -38,6 +38,7 @@ aux_source_directory(struct UI_SOURCE)
aux_source_directory(dialog/import_export UI_SOURCE)
aux_source_directory(dialog/gnupg UI_SOURCE)
aux_source_directory(dialog UI_SOURCE)
+aux_source_directory(function UI_SOURCE)
# define libgpgfrontend_ui
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
@@ -47,17 +48,15 @@ set(_export_file "${CMAKE_CURRENT_SOURCE_DIR}/GpgFrontendUIExport.h")
generate_export_header(gpgfrontend_ui EXPORT_FILE_NAME "${_export_file}")
# link Qt
-if(Qt6_DIR)
- target_link_libraries(gpgfrontend_ui
- Qt6::Network Qt6::PrintSupport Qt6::Widgets Qt6::Test Qt6::Core5Compat Qt6::Core)
-else()
- target_link_libraries(gpgfrontend_ui
- Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core)
-endif()
+target_link_libraries(gpgfrontend_ui
+ Qt6::Network Qt6::PrintSupport Qt6::Test Qt6::Core5Compat)
+
# link gpgfrontend_core
-target_link_libraries(gpgfrontend_ui
- gpgfrontend_core)
+target_link_libraries(gpgfrontend_ui gpgfrontend_core)
+
+# link buddled pinentry
+target_link_libraries(gpgfrontend_ui gpgfrontend_pinentry)
# set up pch
target_precompile_headers(gpgfrontend_ui PUBLIC GpgFrontendUI.h)
diff --git a/src/ui/GpgFrontendApplication.cpp b/src/ui/GpgFrontendApplication.cpp
index 3697adde..1304aad5 100644
--- a/src/ui/GpgFrontendApplication.cpp
+++ b/src/ui/GpgFrontendApplication.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,8 +19,10 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
@@ -35,62 +37,49 @@ namespace GpgFrontend::UI {
GpgFrontendApplication::GpgFrontendApplication(int &argc, char *argv[])
: QApplication(argc, argv) {
#ifndef MACOS
- this->setWindowIcon(QIcon(":gpgfrontend.png"));
+ this->setWindowIcon(QIcon(":/icons/gpgfrontend.png"));
#endif
// set the extra information of the build
- this->setApplicationVersion(BUILD_VERSION);
- this->setApplicationName(PROJECT_NAME);
- this->setQuitOnLastWindowClosed(true);
+ GpgFrontendApplication::setApplicationVersion(BUILD_VERSION);
+ GpgFrontendApplication::setApplicationName(PROJECT_NAME);
+ GpgFrontendApplication::setApplicationDisplayName(PROJECT_NAME);
+ GpgFrontendApplication::setOrganizationName(PROJECT_NAME);
+ GpgFrontendApplication::setQuitOnLastWindowClosed(true);
// don't show icons in menus
- this->setAttribute(Qt::AA_DontShowIconsInMenus);
+ GpgFrontendApplication::setAttribute(Qt::AA_DontShowIconsInMenus);
// unicode in source
QTextCodec::setCodecForLocale(QTextCodec::codecForName("utf-8"));
}
-GpgFrontendApplication *GpgFrontendApplication::GetInstance(int argc,
- char *argv[],
- bool new_instance) {
- static GpgFrontendApplication *instance = nullptr;
- static int static_argc = argc;
- static char **static_argv = argv;
-
- if (new_instance || !instance) {
- if (instance != nullptr) {
- SPDLOG_DEBUG("old application exists, quitting...");
- instance->quit();
- delete instance;
- }
- SPDLOG_DEBUG("creating new application instance, argc: {}", argc);
- instance = new GpgFrontendApplication(static_argc, static_argv);
- }
- return instance;
-}
-
bool GpgFrontendApplication::notify(QObject *receiver, QEvent *event) {
- bool app_done = true;
+#ifdef RELEASE
try {
- app_done = QApplication::notify(receiver, event);
+ return QApplication::notify(receiver, event);
} catch (const std::exception &ex) {
- SPDLOG_ERROR("exception caught in notify: {}", ex.what());
- QMessageBox::information(nullptr, _("Standard Exception Thrown"),
- _("Oops, an standard exception was thrown "
- "during the running of the "
- "program. This is not a serious problem, it may "
- "be the negligence of the programmer, "
- "please report this problem if you can."));
+ GF_UI_LOG_ERROR("exception was caught in notify: {}", ex.what());
+ QMessageBox::information(
+ nullptr, tr("Standard Exception Thrown"),
+ tr("Oops, an standard exception was thrown "
+ "during the running of the "
+ "program. This is not a serious problem, it may "
+ "be the negligence of the programmer, "
+ "please report this problem if you can."));
} catch (...) {
- SPDLOG_ERROR("unknown exception caught in notify");
+ GF_UI_LOG_ERROR("unknown exception was caught in notify");
QMessageBox::information(
- nullptr, _("Unhandled Exception Thrown"),
- _("Oops, an unhandled exception was thrown "
- "during the running of the program. This is not a "
- "serious problem, it may be the negligence of the programmer, "
- "please report this problem if you can."));
+ nullptr, tr("Unhandled Exception Thrown"),
+ tr("Oops, an unhandled exception was thrown "
+ "during the running of the program. This is not a "
+ "serious problem, it may be the negligence of the programmer, "
+ "please report this problem if you can."));
}
- return app_done;
+ return -1;
+#else
+ return QApplication::notify(receiver, event);
+#endif
}
} // namespace GpgFrontend::UI
diff --git a/src/ui/GpgFrontendApplication.h b/src/ui/GpgFrontendApplication.h
index 06338bb6..1ec782cf 100644
--- a/src/ui/GpgFrontendApplication.h
+++ b/src/ui/GpgFrontendApplication.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,15 +19,16 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "ui/GpgFrontendUI.h"
-#ifndef GPGFRONTEND_GPGFRONTENDAPPLICATION_H
-#define GPGFRONTEND_GPGFRONTENDAPPLICATION_H
+#pragma once
namespace GpgFrontend::UI {
@@ -48,15 +49,6 @@ class GPGFRONTEND_UI_EXPORT GpgFrontendApplication : public QApplication {
*/
~GpgFrontendApplication() override = default;
- /**
- * @brief Get the GpgFrontend Application object
- *
- * @return GpgFrontendApplication*
- */
- static GpgFrontendApplication *GetInstance(int argc = 0,
- char *argv[] = nullptr,
- bool new_instance = false);
-
protected:
/**
* @brief
@@ -68,5 +60,3 @@ class GPGFRONTEND_UI_EXPORT GpgFrontendApplication : public QApplication {
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_GPGFRONTENDAPPLICATION_H \ No newline at end of file
diff --git a/src/ui/GpgFrontendUI.h b/src/ui/GpgFrontendUI.h
index 4389aa41..b3115795 100644
--- a/src/ui/GpgFrontendUI.h
+++ b/src/ui/GpgFrontendUI.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,37 +20,29 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGFRONTENDUI_H
-#define GPGFRONTEND_GPGFRONTENDUI_H
+#pragma once
/**
* Basic dependency
*/
-#include <QtCore>
-#include <QtNetwork>
-#include <QtPrintSupport>
#include <QtWidgets>
-#include <optional>
-/**
- * Project internal dependencies
- */
+// Core
#include "GpgFrontend.h"
#include "core/GpgFrontendCore.h"
-#include "core/GpgModel.h"
-#include "core/thread/ThreadingModel.h"
-#include "ui/GpgFrontendUIExport.h"
+#include "core/utils/LogUtils.h"
-/**
- * 3rd party dependencies
- */
-
-#include <qt-aes/qaesencryption.h>
+// UI
+#include "ui/GpgFrontendUIExport.h"
-#endif // GPGFRONTEND_GPGFRONTENDUI_H
+#define GF_UI_LOG_TRACE(...) GF_LOG_TRACE("ui", __VA_ARGS__)
+#define GF_UI_LOG_DEBUG(...) GF_LOG_DEBUG("ui", __VA_ARGS__)
+#define GF_UI_LOG_INFO(...) GF_LOG_INFO("ui", __VA_ARGS__)
+#define GF_UI_LOG_WARN(...) GF_LOG_WARN("ui", __VA_ARGS__)
+#define GF_UI_LOG_ERROR(...) GF_LOG_ERROR("ui", __VA_ARGS__)
diff --git a/src/ui/GpgFrontendUIInit.cpp b/src/ui/GpgFrontendUIInit.cpp
index bfe4d828..c7f54286 100644
--- a/src/ui/GpgFrontendUIInit.cpp
+++ b/src/ui/GpgFrontendUIInit.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,76 +28,109 @@
#include "GpgFrontendUIInit.h"
-#include <spdlog/async.h>
-#include <spdlog/common.h>
-#include <spdlog/sinks/rotating_file_sink.h>
-#include <spdlog/sinks/stdout_color_sinks.h>
-
-#include <string>
+#include <clocale>
#include "core/GpgConstants.h"
+#include "core/function/CoreSignalStation.h"
#include "core/function/GlobalSettingStation.h"
-#include "core/thread/CtxCheckTask.h"
-#include "core/thread/TaskRunnerGetter.h"
-#include "spdlog/spdlog.h"
-#include "ui/SignalStation.h"
+#include "core/module/ModuleManager.h"
+#include "ui/UISignalStation.h"
#include "ui/UserInterfaceUtils.h"
#include "ui/main_window/MainWindow.h"
-#if !defined(RELEASE) && defined(WINDOWS)
-#include "core/function/GlobalSettingStation.h"
-#endif
-
namespace GpgFrontend::UI {
-extern void init_logging_system();
-extern void init_locale();
+extern void InitLocale();
+
+void WaitEnvCheckingProcess() {
+ GF_UI_LOG_DEBUG("need to waiting for env checking process");
+
+ // create and show loading window before starting the main window
+ auto* waiting_dialog = new QProgressDialog();
+ waiting_dialog->setMaximum(0);
+ waiting_dialog->setMinimum(0);
+ auto* waiting_dialog_label = new QLabel(
+ QObject::tr("Loading Gnupg Info...") + "<br /><br />" +
+ QObject::tr("If this process is too slow, please set the key "
+ "server address appropriately in the gnupg configuration "
+ "file (depending "
+ "on the network situation in your country or region)."));
+ waiting_dialog_label->setWordWrap(true);
+ waiting_dialog->setLabel(waiting_dialog_label);
+ waiting_dialog->resize(420, 120);
+ QApplication::connect(CoreSignalStation::GetInstance(),
+ &CoreSignalStation::SignalGoodGnupgEnv, waiting_dialog,
+ [=]() {
+ GF_UI_LOG_DEBUG("gpg env loaded successfuly");
+ waiting_dialog->finished(0);
+ waiting_dialog->deleteLater();
+ });
+
+ // new local event looper
+ QEventLoop looper;
+ QApplication::connect(CoreSignalStation::GetInstance(),
+ &CoreSignalStation::SignalGoodGnupgEnv, &looper,
+ &QEventLoop::quit);
+
+ QApplication::connect(waiting_dialog, &QProgressDialog::canceled, [=]() {
+ GF_UI_LOG_DEBUG("cancel clicked on wairing dialog");
+ QApplication::quit();
+ exit(0);
+ });
+
+ auto env_state =
+ Module::RetrieveRTValueTypedOrDefault<>("core", "env.state.basic", 0);
+ GF_UI_LOG_DEBUG("ui is ready to wating for env initialized, env_state: {}",
+ env_state);
+
+ // check twice to avoid some unlucky sitations
+ if (env_state == 1) {
+ GF_UI_LOG_DEBUG("env state turned initialized before the looper start");
+ waiting_dialog->finished(0);
+ waiting_dialog->deleteLater();
+ return;
+ }
+
+ // show the loading window
+ waiting_dialog->setModal(true);
+ waiting_dialog->setFocus();
+ waiting_dialog->show();
+
+ // block the main thread until the gpg context is loaded
+ looper.exec();
+}
+
+void PreInitGpgFrontendUI() { CommonUtils::GetInstance(); }
-void InitGpgFrontendUI(QApplication* app) {
+void InitGpgFrontendUI(QApplication* /*app*/) {
// init locale
- init_locale();
-
-#if !defined(RELEASE) && defined(WINDOWS)
- // css
- std::filesystem::path css_path =
- GpgFrontend::GlobalSettingStation::GetInstance().GetResourceDir() /
- "css" / "default.qss";
- QFile file(css_path.u8string().c_str());
- file.open(QFile::ReadOnly);
- QString styleSheet = QLatin1String(file.readAll());
- qApp->setStyleSheet(styleSheet);
- file.close();
-#endif
+ InitLocale();
// init signal station
- SignalStation::GetInstance();
+ UISignalStation::GetInstance();
// init common utils
CommonUtils::GetInstance();
+ auto settings = GlobalSettingStation::GetInstance().GetSettings();
+
// application proxy configure
- bool proxy_enable =
- GlobalSettingStation::GetInstance().LookupSettings("proxy.enable", false);
+ bool proxy_enable = settings.value("proxy/enable", false).toBool();
// if enable proxy for application
if (proxy_enable) {
try {
- std::string proxy_type =
- GlobalSettingStation::GetInstance().LookupSettings("proxy.proxy_type",
- std::string{});
- std::string proxy_host =
- GlobalSettingStation::GetInstance().LookupSettings("proxy.proxy_host",
- std::string{});
- int proxy_port =
- GlobalSettingStation::GetInstance().LookupSettings("proxy.port", 0);
- std::string proxy_username =
- GlobalSettingStation::GetInstance().LookupSettings("proxy.username",
- std::string{});
- std::string proxy_password =
- GlobalSettingStation::GetInstance().LookupSettings("proxy.password",
- std::string{});
- SPDLOG_DEBUG("proxy settings: type {}, host {}, port: {}", proxy_type,
- proxy_host, proxy_port);
+ QString proxy_type =
+ settings.value("proxy/proxy_type", QString{}).toString();
+ QString proxy_host =
+ settings.value("proxy/proxy_host", QString{}).toString();
+ int proxy_port = settings.value("prox/port", 0).toInt();
+ QString proxy_username =
+ settings.value("proxy/username", QString{}).toString();
+ QString proxy_password =
+ settings.value("proxy/password", QString{}).toString();
+ GF_UI_LOG_DEBUG("proxy settings: type {}, host {}, port: {}", proxy_type,
+ proxy_host, proxy_port);
QNetworkProxy::ProxyType proxy_type_qt = QNetworkProxy::NoProxy;
if (proxy_type == "HTTP") {
@@ -112,19 +145,21 @@ void InitGpgFrontendUI(QApplication* app) {
QNetworkProxy proxy;
if (proxy_type_qt != QNetworkProxy::DefaultProxy) {
proxy.setType(proxy_type_qt);
- proxy.setHostName(QString::fromStdString(proxy_host));
+ proxy.setHostName(proxy_host);
proxy.setPort(proxy_port);
- if (!proxy_username.empty())
- proxy.setUser(QString::fromStdString(proxy_username));
- if (!proxy_password.empty())
- proxy.setPassword(QString::fromStdString(proxy_password));
+ if (!proxy_username.isEmpty()) {
+ proxy.setUser(proxy_username);
+ }
+ if (!proxy_password.isEmpty()) {
+ proxy.setPassword(proxy_password);
+ }
} else {
proxy.setType(proxy_type_qt);
}
QNetworkProxy::setApplicationProxy(proxy);
} catch (...) {
- SPDLOG_ERROR("setting operation error: proxy setings");
+ GF_UI_LOG_ERROR("setting operation error: proxy setings");
// no proxy by default
QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy);
}
@@ -133,196 +168,60 @@ void InitGpgFrontendUI(QApplication* app) {
QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy);
}
- // create the thread to load the gpg context
- auto* init_ctx_task = new Thread::CtxCheckTask();
-
- // create and show loading window before starting the main window
- auto* waiting_dialog = new QProgressDialog();
- waiting_dialog->setMaximum(0);
- waiting_dialog->setMinimum(0);
- auto waiting_dialog_label =
- new QLabel(QString(_("Loading Gnupg Info...")) + "<br /><br />" +
- _("If this process is too slow, please set the key "
- "server address appropriately in the gnupg configuration "
- "file (depending "
- "on the network situation in your country or region)."));
- waiting_dialog_label->setWordWrap(true);
- waiting_dialog->setLabel(waiting_dialog_label);
- waiting_dialog->resize(420, 120);
- app->connect(init_ctx_task, &Thread::CtxCheckTask::SignalTaskEnd,
- waiting_dialog, [=]() {
- SPDLOG_DEBUG("gpg context loaded");
- waiting_dialog->finished(0);
- waiting_dialog->deleteLater();
- });
-
- app->connect(waiting_dialog, &QProgressDialog::canceled, [=]() {
- SPDLOG_DEBUG("cancel clicked");
- app->quit();
- exit(0);
- });
-
- // show the loading window
- waiting_dialog->setModal(true);
- waiting_dialog->setFocus();
- waiting_dialog->show();
-
- // new local event looper
- QEventLoop looper;
- app->connect(init_ctx_task, &Thread::CtxCheckTask::SignalTaskEnd, &looper,
- &QEventLoop::quit);
-
- // start the thread to load the gpg context
- Thread::TaskRunnerGetter::GetInstance().GetTaskRunner()->PostTask(
- init_ctx_task);
+ if (Module::RetrieveRTValueTypedOrDefault<>("core", "env.state.basic", 0) ==
+ 0) {
+ WaitEnvCheckingProcess();
+ }
- // block the main thread until the gpg context is loaded
- looper.exec();
+ qRegisterMetaType<QSharedPointer<GpgPassphraseContext> >(
+ "QSharedPointer<GpgPassphraseContext>");
}
-int RunGpgFrontendUI(QApplication* app) {
+auto RunGpgFrontendUI(QApplication* app) -> int {
// create main window and show it
auto main_window = std::make_unique<GpgFrontend::UI::MainWindow>();
// pre-check, if application need to restart
if (CommonUtils::GetInstance()->isApplicationNeedRestart()) {
- SPDLOG_DEBUG("application need to restart, before mian window init");
- return DEEP_RESTART_CODE;
- } else {
- main_window->Init();
- SPDLOG_DEBUG("main window inited");
- main_window->show();
+ GF_UI_LOG_DEBUG("application need to restart, before mian window init");
+ return kDeepRestartCode;
}
+ // init main window
+ main_window->Init();
+
+ // show main windows
+ GF_UI_LOG_DEBUG("main window is ready to show");
+ main_window->show();
+
// start the main event loop
return app->exec();
}
-void InitUILoggingSystem() {
- using namespace boost::posix_time;
- using namespace boost::gregorian;
-
- // get the log directory
- auto logfile_path = (GlobalSettingStation::GetInstance().GetLogDir() / "ui");
- logfile_path.replace_extension(".log");
-
- // sinks
- std::vector<spdlog::sink_ptr> sinks;
- sinks.push_back(std::make_shared<spdlog::sinks::stderr_color_sink_mt>());
- sinks.push_back(std::make_shared<spdlog::sinks::rotating_file_sink_mt>(
- logfile_path.u8string(), 1048576 * 32, 32));
-
- // thread pool
- spdlog::init_thread_pool(1024, 2);
-
- // logger
- auto ui_logger = std::make_shared<spdlog::async_logger>(
- "ui", begin(sinks), end(sinks), spdlog::thread_pool());
- ui_logger->set_pattern(
- "[%H:%M:%S.%e] [T:%t] [%=4n] %^[%=8l]%$ [%s:%#] [%!] -> %v (+%ius)");
-
-#ifdef DEBUG
- ui_logger->set_level(spdlog::level::trace);
-#else
- ui_logger->set_level(spdlog::level::info);
-#endif
-
- // flush policy
- ui_logger->flush_on(spdlog::level::err);
- spdlog::flush_every(std::chrono::seconds(5));
-
- // register it as default logger
- spdlog::set_default_logger(ui_logger);
-}
-
-void ShutdownUILoggingSystem() {
-#ifdef WINDOWS
- // Under VisualStudio, this must be called before main finishes to workaround
- // a known VS issue
- spdlog::drop_all();
- spdlog::shutdown();
-#endif
-}
+void GPGFRONTEND_UI_EXPORT DestroyGpgFrontendUI() {}
/**
* @brief setup the locale and load the translations
*
*/
-void init_locale() {
+void InitLocale() {
// get the instance of the GlobalSettingStation
- auto& settings =
- GpgFrontend::GlobalSettingStation::GetInstance().GetUISettings();
-
- // create general settings if not exist
- 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) = "";
-
- // sync the settings to the file
- GpgFrontend::GlobalSettingStation::GetInstance().SyncSettings();
-
- SPDLOG_DEBUG("current system locale: {}", setlocale(LC_ALL, nullptr));
+ auto settings =
+ GpgFrontend::GlobalSettingStation::GetInstance().GetSettings();
// read from settings file
- std::string lang;
- if (!general.lookupValue("lang", lang)) {
- SPDLOG_ERROR(_("could not read properly from configure file"));
- };
-
- SPDLOG_DEBUG("lang from settings: {}", lang);
- SPDLOG_DEBUG("project name: {}", PROJECT_NAME);
- SPDLOG_DEBUG("locales path: {}",
- GpgFrontend::GlobalSettingStation::GetInstance()
- .GetLocaleDir()
- .u8string());
-
-#ifndef WINDOWS
- if (!lang.empty()) {
- std::string lc = lang + ".UTF-8";
-
- // set LC_ALL
- auto* locale_name = setlocale(LC_ALL, lc.c_str());
- if (locale_name == nullptr) SPDLOG_WARN("set LC_ALL failed, lc: {}", lc);
- auto language = getenv("LANGUAGE");
- // set LANGUAGE
- std::string language_env = language == nullptr ? "en" : language;
- language_env.insert(0, lang + ":");
- SPDLOG_DEBUG("language env: {}", language_env);
- if (setenv("LANGUAGE", language_env.c_str(), 1)) {
- SPDLOG_WARN("set LANGUAGE {} failed", language_env);
- };
- }
-#else
- if (!lang.empty()) {
- std::string lc = lang;
-
- // set LC_ALL
- auto* locale_name = setlocale(LC_ALL, lc.c_str());
- if (locale_name == nullptr) SPDLOG_WARN("set LC_ALL failed, lc: {}", lc);
-
- auto language = getenv("LANGUAGE");
- // set LANGUAGE
- std::string language_env = language == nullptr ? "en" : language;
- language_env.insert(0, lang + ":");
- language_env.insert(0, "LANGUAGE=");
- SPDLOG_DEBUG("language env: {}", language_env);
- if (putenv(language_env.c_str())) {
- SPDLOG_WARN("set LANGUAGE {} failed", language_env);
- };
+ auto lang = settings.value("basic/lang").toString();
+ GF_UI_LOG_INFO("current system locale: {}", QLocale().name());
+ GF_UI_LOG_INFO("current custom locale settings: {}", lang);
+
+ auto target_locale = lang.isEmpty() ? QLocale() : QLocale(lang);
+ auto* translator = new QTranslator(QCoreApplication::instance());
+ if (translator->load(target_locale, QLatin1String(PROJECT_NAME),
+ QLatin1String("."), QLatin1String(":/i18n"),
+ QLatin1String(".qm"))) {
+ GF_UI_LOG_INFO("load target translation file done");
+ QCoreApplication::installTranslator(translator);
}
-#endif
-
- bindtextdomain(PROJECT_NAME, GpgFrontend::GlobalSettingStation::GetInstance()
- .GetLocaleDir()
- .u8string()
- .c_str());
- bind_textdomain_codeset(PROJECT_NAME, "utf-8");
- textdomain(PROJECT_NAME);
}
} // namespace GpgFrontend::UI
diff --git a/src/ui/GpgFrontendUIInit.h b/src/ui/GpgFrontendUIInit.h
index 0e68aa57..fd62f3f6 100644
--- a/src/ui/GpgFrontendUIInit.h
+++ b/src/ui/GpgFrontendUIInit.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,42 +20,39 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GPGFRONTENDUIINIT_H
-#define GPGFRONTEND_GPGFRONTENDUIINIT_H
+#pragma once
#include "GpgFrontendUI.h"
namespace GpgFrontend::UI {
/**
- * @brief init the UI library
+ * @brief
*
*/
-void GPGFRONTEND_UI_EXPORT InitGpgFrontendUI(QApplication *);
+void GPGFRONTEND_UI_EXPORT PreInitGpgFrontendUI();
/**
- * @brief
- *
+ * @brief init the UI library
+ *
*/
-void GPGFRONTEND_UI_EXPORT InitUILoggingSystem();
+void GPGFRONTEND_UI_EXPORT InitGpgFrontendUI(QApplication *);
/**
- * @brief
- *
+ * @brief init the UI library
+ *
*/
-void GPGFRONTEND_UI_EXPORT ShutdownUILoggingSystem();
+void GPGFRONTEND_UI_EXPORT DestroyGpgFrontendUI();
/**
* @brief run main window
*/
-int GPGFRONTEND_UI_EXPORT RunGpgFrontendUI(QApplication *);
+auto GPGFRONTEND_UI_EXPORT RunGpgFrontendUI(QApplication *) -> int;
}; // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_GPGFRONTENDUIINIT_H
diff --git a/src/ui/UISignalStation.cpp b/src/ui/UISignalStation.cpp
new file mode 100644
index 00000000..8357cb06
--- /dev/null
+++ b/src/ui/UISignalStation.cpp
@@ -0,0 +1,44 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "UISignalStation.h"
+
+namespace GpgFrontend::UI {
+
+std::unique_ptr<UISignalStation> UISignalStation::instance = nullptr;
+
+auto UISignalStation::GetInstance() -> UISignalStation* {
+ if (instance == nullptr) {
+ instance = std::unique_ptr<UISignalStation>(new UISignalStation());
+ }
+ return instance.get();
+}
+
+UISignalStation::UISignalStation() = default;
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/SignalStation.h b/src/ui/UISignalStation.h
index 17e866f5..aee61300 100644
--- a/src/ui/SignalStation.h
+++ b/src/ui/UISignalStation.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,27 +20,29 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_SIGNALSTATION_H
-#define GPGFRONTEND_SIGNALSTATION_H
+#pragma once
-#include "ui/GpgFrontendUI.h"
#include "ui/widgets/InfoBoardWidget.h"
+namespace GpgFrontend {
+class GpgPassphraseContext;
+}
+
namespace GpgFrontend::UI {
/**
* @brief
*
*/
-class SignalStation : public QObject {
+class UISignalStation : public QObject {
Q_OBJECT
- static std::unique_ptr<SignalStation> _instance;
+ static std::unique_ptr<UISignalStation> instance;
public:
/**
@@ -48,7 +50,7 @@ class SignalStation : public QObject {
*
* @return SignalStation*
*/
- static SignalStation* GetInstance();
+ static auto GetInstance() -> UISignalStation*;
signals:
/**
@@ -90,21 +92,22 @@ class SignalStation : public QObject {
* @brief
*
*/
- void SignalUserInputPassphraseDone(QString passparase);
+ void SignalNeedUserInputPassphrase(QSharedPointer<GpgPassphraseContext>);
/**
* @brief
*
*/
- void SignalNeedUserInputPassphrase();
+ void SignalUserInputPassphraseCallback(QSharedPointer<GpgPassphraseContext>);
/**
* @brief
*
*/
void SignalRestartApplication(int);
+
+ private:
+ UISignalStation();
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_SIGNALSTATION_H
diff --git a/src/ui/UserInterfaceUtils.cpp b/src/ui/UserInterfaceUtils.cpp
index 7e236c02..751b1f03 100644
--- a/src/ui/UserInterfaceUtils.cpp
+++ b/src/ui/UserInterfaceUtils.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,25 +28,28 @@
#include "UserInterfaceUtils.h"
-#include <string>
-#include <utility>
+#include <gpg-error.h>
+#include <qdialog.h>
+
+#include <QtNetwork>
#include <vector>
#include "core/GpgConstants.h"
-#include "core/common/CoreCommonUtil.h"
-#include "core/function/CacheManager.h"
#include "core/function/CoreSignalStation.h"
-#include "core/function/FileOperator.h"
-#include "core/function/GlobalSettingStation.h"
#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/model/GpgImportInformation.h"
+#include "core/module/ModuleManager.h"
#include "core/thread/Task.h"
-#include "core/thread/TaskRunner.h"
#include "core/thread/TaskRunnerGetter.h"
-#include "dialog/gnupg/GnuPGControllerDialog.h"
-#include "spdlog/spdlog.h"
-#include "ui/SignalStation.h"
+#include "core/typedef/GpgTypedef.h"
+#include "core/utils/GpgUtils.h"
+#include "core/utils/IOUtils.h"
+#include "ui/UISignalStation.h"
#include "ui/dialog/WaitingDialog.h"
+#include "ui/dialog/gnupg/GnuPGControllerDialog.h"
+#include "ui/struct/CacheObject.h"
#include "ui/struct/SettingsObject.h"
+#include "ui/struct/settings/KeyServerSO.h"
#include "ui/widgets/TextEdit.h"
namespace GpgFrontend::UI {
@@ -58,7 +61,7 @@ void show_verify_details(QWidget *parent, InfoBoardWidget *info_board,
GpgError error, const GpgVerifyResult &verify_result) {
// take out result
info_board->ResetOptionActionsMenu();
- info_board->AddOptionalAction(_("Show Verify Details"), [=]() {
+ info_board->AddOptionalAction(QObject::tr("Show Verify Details"), [=]() {
VerifyDetailsDialog(parent, error, verify_result);
});
}
@@ -67,17 +70,18 @@ void import_unknown_key_from_keyserver(
QWidget *parent, const GpgVerifyResultAnalyse &verify_res) {
QMessageBox::StandardButton reply;
reply = QMessageBox::question(
- parent, _("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?"),
+ parent, QObject::tr("Public key not found locally"),
+ QObject::tr(
+ "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) {
- auto dialog = KeyServerImportDialog(true, parent);
+ auto dialog = KeyServerImportDialog(parent);
auto key_ids = std::make_unique<KeyIdArgsList>();
auto *signature = verify_res.GetSignatures();
while (signature != nullptr) {
- SPDLOG_DEBUG("signature fpr: {}", signature->fpr);
+ GF_UI_LOG_DEBUG("signature fpr: {}", signature->fpr);
key_ids->push_back(signature->fpr);
signature = signature->next;
}
@@ -87,15 +91,14 @@ void import_unknown_key_from_keyserver(
}
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);
+ const QString &report_text) {
+ if (status < 0) {
+ info_board->SlotRefresh(report_text, INFO_ERROR_CRITICAL);
+ } else if (status > 0) {
+ info_board->SlotRefresh(report_text, INFO_ERROR_OK);
+ } else {
+ info_board->SlotRefresh(report_text, INFO_ERROR_WARN);
+ }
}
void process_result_analyse(TextEdit *edit, InfoBoardWidget *info_board,
@@ -116,12 +119,11 @@ void process_result_analyse(TextEdit *edit, InfoBoardWidget *info_board,
result_analyse_a.GetResultReport() + result_analyse_b.GetResultReport());
}
-void process_operation(QWidget *parent, const std::string &waiting_title,
+void process_operation(QWidget *parent, const QString &waiting_title,
const Thread::Task::TaskRunnable func,
const Thread::Task::TaskCallback callback,
- Thread::Task::DataObjectPtr data_object) {
- auto *dialog =
- new WaitingDialog(QString::fromStdString(waiting_title), parent);
+ DataObjectPtr data_object) {
+ auto *dialog = new WaitingDialog(waiting_title, parent);
auto *process_task = new Thread::Task(std::move(func), waiting_title,
data_object, std::move(callback));
@@ -146,7 +148,7 @@ void process_operation(QWidget *parent, const std::string &waiting_title,
looper.exec();
}
-CommonUtils *CommonUtils::GetInstance() {
+auto CommonUtils::GetInstance() -> CommonUtils * {
if (instance_ == nullptr) {
instance_ = std::make_unique<CommonUtils>();
}
@@ -154,109 +156,154 @@ CommonUtils *CommonUtils::GetInstance() {
}
CommonUtils::CommonUtils() : QWidget(nullptr) {
- connect(CoreCommonUtil::GetInstance(), &CoreCommonUtil::SignalGnupgNotInstall,
- this, &CommonUtils::SignalGnupgNotInstall);
+ connect(CoreSignalStation::GetInstance(),
+ &CoreSignalStation::SignalBadGnupgEnv, this,
+ &CommonUtils::SignalBadGnupgEnv);
connect(this, &CommonUtils::SignalKeyStatusUpdated,
- SignalStation::GetInstance(),
- &SignalStation::SignalKeyDatabaseRefresh);
+ UISignalStation::GetInstance(),
+ &UISignalStation::SignalKeyDatabaseRefresh);
connect(this, &CommonUtils::SignalKeyDatabaseRefreshDone,
- SignalStation::GetInstance(),
- &SignalStation::SignalKeyDatabaseRefreshDone);
- connect(this, &CommonUtils::SignalUserInputPassphraseDone,
- CoreSignalStation::GetInstance(),
- &CoreSignalStation::SignalUserInputPassphraseDone);
+ UISignalStation::GetInstance(),
+ &UISignalStation::SignalKeyDatabaseRefreshDone);
// directly connect to SignalKeyStatusUpdated
// to avoid the delay of signal emitting
// when the key database is refreshed
- connect(SignalStation::GetInstance(),
- &SignalStation::SignalKeyDatabaseRefresh, this,
+ connect(UISignalStation::GetInstance(),
+ &UISignalStation::SignalKeyDatabaseRefresh, this,
&CommonUtils::slot_update_key_status);
- connect(CoreSignalStation::GetInstance(),
- &CoreSignalStation::SignalNeedUserInputPassphrase, this,
- &CommonUtils::slot_popup_passphrase_input_dialog);
-
connect(this, &CommonUtils::SignalRestartApplication,
- SignalStation::GetInstance(),
- &SignalStation::SignalRestartApplication);
+ UISignalStation::GetInstance(),
+ &UISignalStation::SignalRestartApplication);
- connect(SignalStation::GetInstance(),
- &SignalStation::SignalRestartApplication, this,
+ connect(UISignalStation::GetInstance(),
+ &UISignalStation::SignalRestartApplication, this,
&CommonUtils::SlotRestartApplication);
- connect(this, &CommonUtils::SignalGnupgNotInstall, this, [=]() {
- QMessageBox msgBox;
- msgBox.setText(_("GnuPG Context Loading Failed"));
- msgBox.setInformativeText(
- _("Gnupg(gpg) is not installed correctly, please follow "
- "<a href='https://www.gpgfrontend.bktus.com/#/"
- "faq?id=how-to-deal-with-39env-loading-failed39'>this notes</a>"
- " in FAQ to install Gnupg and then open "
- "GpgFrontend. Or, you can open GnuPG Controller to set a custom "
- "GnuPG "
- "which GpgFrontend should use. Then, GpgFrontend will restart."));
- msgBox.setStandardButtons(QMessageBox::Open | QMessageBox::Cancel);
- msgBox.setDefaultButton(QMessageBox::Save);
- int ret = msgBox.exec();
-
- switch (ret) {
- case QMessageBox::Open:
- (new GnuPGControllerDialog(this))->exec();
- // restart application when loop start
- application_need_to_restart_at_once_ = true;
- // restart application, core and ui
- emit SignalRestartApplication(DEEP_RESTART_CODE);
- break;
- case QMessageBox::Cancel:
- // close application
- emit SignalRestartApplication(0);
- break;
- default:
- // close application
- emit SignalRestartApplication(0);
- break;
- }
+ connect(this, &CommonUtils::SignalBadGnupgEnv, this,
+ [=](const QString &reason) {
+ QMessageBox msg_box;
+ msg_box.setText(tr("GnuPG Context Loading Failed"));
+ msg_box.setInformativeText(
+ tr("Gnupg(gpg) is not installed correctly, please follow "
+ "<a href='https://www.gpgfrontend.bktus.com/#/"
+ "faq?id=how-to-deal-with-39env-loading-failed39'>this "
+ "notes</a> in FAQ to install Gnupg and then open "
+ "GpgFrontend. <br />"
+ "Or, you can open GnuPG Controller to set a "
+ "custom GnuPG which GpgFrontend should use. Then, "
+ "GpgFrontend will restart. <br /><br />"
+ "Breif Reason: %1")
+ .arg(reason));
+ msg_box.setStandardButtons(QMessageBox::Open | QMessageBox::Cancel);
+ msg_box.setDefaultButton(QMessageBox::Save);
+ int ret = msg_box.exec();
+
+ switch (ret) {
+ case QMessageBox::Open:
+ (new GnuPGControllerDialog(this))->exec();
+ // restart application when loop start
+ application_need_to_restart_at_once_ = true;
+ // restart application, core and ui
+ emit SignalRestartApplication(kDeepRestartCode);
+ break;
+ case QMessageBox::Cancel:
+ // close application
+ emit SignalRestartApplication(0);
+ break;
+ default:
+ // close application
+ emit SignalRestartApplication(0);
+ break;
+ }
+ });
+}
+
+void CommonUtils::WaitForOpera(QWidget *parent,
+ const QString &waiting_dialog_title,
+ const OperaWaitingCb &opera) {
+ QEventLoop looper;
+ QPointer<WaitingDialog> const dialog =
+ new WaitingDialog(waiting_dialog_title, parent);
+ connect(dialog, &QDialog::finished, &looper, &QEventLoop::quit);
+ connect(dialog, &QDialog::finished, dialog, &QDialog::deleteLater);
+ dialog->show();
+
+ QTimer::singleShot(64, parent, [=]() {
+ opera([dialog]() {
+ if (dialog != nullptr) {
+ GF_UI_LOG_DEBUG("called operating waiting cb, dialog: {}",
+ static_cast<void *>(dialog));
+ dialog->close();
+ dialog->accept();
+ }
+ });
});
+
+ looper.exec();
}
-void CommonUtils::SlotImportKeys(QWidget *parent,
- const std::string &in_buffer) {
- GpgImportInformation result = GpgKeyImportExporter::GetInstance().ImportKey(
- std::make_unique<ByteArray>(in_buffer));
+void CommonUtils::RaiseMessageBox(QWidget *parent, GpgError err) {
+ GpgErrorDesc desc = DescribeGpgErrCode(err);
+ GpgErrorCode err_code = CheckGpgError2ErrCode(err);
+
+ if (err_code == GPG_ERR_NO_ERROR) {
+ QMessageBox::information(parent, tr("Success"),
+ tr("Gpg Operation succeed."));
+ } else {
+ RaiseFailureMessageBox(parent, err);
+ }
+}
+
+void CommonUtils::RaiseFailureMessageBox(QWidget *parent, GpgError err) {
+ GpgErrorDesc desc = DescribeGpgErrCode(err);
+ GpgErrorCode err_code = CheckGpgError2ErrCode(err);
+
+ QMessageBox::critical(parent, tr("Failure"),
+ tr("Gpg Operation failed.\n\nError code: %1\nSource: "
+ " %2\nDescription: %3")
+ .arg(err_code)
+ .arg(desc.first)
+ .arg(desc.second));
+}
+
+void CommonUtils::SlotImportKeys(QWidget *parent, const QString &in_buffer) {
+ auto info =
+ GpgKeyImportExporter::GetInstance().ImportKey(GFBuffer(in_buffer));
emit SignalKeyStatusUpdated();
- new KeyImportDetailDialog(result, false, parent);
+
+ (new KeyImportDetailDialog(info, parent))->exec();
}
void CommonUtils::SlotImportKeyFromFile(QWidget *parent) {
- QString file_name = QFileDialog::getOpenFileName(
- this, _("Open Key"), QString(),
- QString(_("Key Files")) + " (*.asc *.txt);;" + _("Keyring files") +
- " (*.gpg);;All Files (*)");
+ auto file_name = QFileDialog::getOpenFileName(this, tr("Open Key"), QString(),
+ tr("Key Files")) +
+ " (*.asc *.txt);;" + tr("Keyring files") +
+ " (*.gpg);;All Files (*)";
if (!file_name.isNull()) {
QByteArray key_buffer;
- if (!FileOperator::ReadFile(file_name, key_buffer)) {
- QMessageBox::critical(nullptr, _("File Open Failed"),
- _("Failed to open file: ") + file_name);
+ if (!ReadFile(file_name, key_buffer)) {
+ QMessageBox::critical(nullptr, tr("File Open Failed"),
+ tr("Failed to open file: ") + file_name);
return;
}
- SlotImportKeys(parent, key_buffer.toStdString());
+ SlotImportKeys(parent, key_buffer);
}
}
void CommonUtils::SlotImportKeyFromKeyServer(QWidget *parent) {
- auto dialog = new KeyServerImportDialog(false, parent);
+ auto *dialog = new KeyServerImportDialog(parent);
dialog->show();
}
void CommonUtils::SlotImportKeyFromClipboard(QWidget *parent) {
QClipboard *cb = QApplication::clipboard();
- SlotImportKeys(parent,
- cb->text(QClipboard::Clipboard).toUtf8().toStdString());
+ SlotImportKeys(parent, cb->text(QClipboard::Clipboard));
}
void CommonUtils::SlotExecuteCommand(
- const std::string &cmd, const QStringList &arguments,
+ const QString &cmd, const QStringList &arguments,
const std::function<void(QProcess *)> &interact_func) {
QEventLoop looper;
auto *cmd_process = new QProcess(&looper);
@@ -267,21 +314,21 @@ void CommonUtils::SlotExecuteCommand(
&QEventLoop::quit);
connect(cmd_process, &QProcess::errorOccurred, &looper, &QEventLoop::quit);
connect(cmd_process, &QProcess::started,
- []() -> void { SPDLOG_DEBUG("process started"); });
+ []() -> void { GF_UI_LOG_DEBUG("process started"); });
connect(cmd_process, &QProcess::readyReadStandardOutput,
[interact_func, cmd_process]() { interact_func(cmd_process); });
connect(cmd_process, &QProcess::errorOccurred, this,
- [=]() -> void { SPDLOG_ERROR("error in process"); });
+ [=]() -> void { GF_UI_LOG_ERROR("error in process"); });
connect(cmd_process,
qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this,
[=](int, QProcess::ExitStatus status) {
if (status == QProcess::NormalExit)
- SPDLOG_DEBUG("succeed in executing command: {}", cmd);
+ GF_UI_LOG_DEBUG("succeed in executing command: {}", cmd);
else
- SPDLOG_WARN("error in executing command: {}", cmd);
+ GF_UI_LOG_WARN("error in executing command: {}", cmd);
});
- cmd_process->setProgram(QString::fromStdString(cmd));
+ cmd_process->setProgram(cmd);
cmd_process->setArguments(arguments);
cmd_process->start();
looper.exec();
@@ -291,7 +338,7 @@ void CommonUtils::SlotExecuteGpgCommand(
const QStringList &arguments,
const std::function<void(QProcess *)> &interact_func) {
QEventLoop looper;
- auto dialog = new WaitingDialog(_("Processing"), nullptr);
+ auto dialog = new WaitingDialog(tr("Processing"), nullptr);
dialog->show();
auto *gpg_process = new QProcess(&looper);
gpg_process->setProcessChannelMode(QProcess::MergedChannels);
@@ -304,29 +351,32 @@ void CommonUtils::SlotExecuteGpgCommand(
&WaitingDialog::deleteLater);
connect(gpg_process, &QProcess::errorOccurred, &looper, &QEventLoop::quit);
connect(gpg_process, &QProcess::started,
- []() -> void { SPDLOG_DEBUG("gpg process started"); });
+ []() -> void { GF_UI_LOG_DEBUG("gpg process started"); });
connect(gpg_process, &QProcess::readyReadStandardOutput,
[interact_func, gpg_process]() { interact_func(gpg_process); });
connect(gpg_process, &QProcess::errorOccurred, this, [=]() -> void {
- SPDLOG_ERROR("Error in Process");
+ GF_UI_LOG_ERROR("Error in Process");
dialog->close();
- QMessageBox::critical(nullptr, _("Failure"),
- _("Failed to execute command."));
+ QMessageBox::critical(nullptr, tr("Failure"),
+ tr("Failed to execute command."));
});
connect(gpg_process,
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."));
+ QMessageBox::information(nullptr, tr("Success"),
+ tr("Succeed in executing command."));
else
- QMessageBox::information(nullptr, _("Warning"),
- _("Finished executing command."));
+ QMessageBox::information(nullptr, tr("Warning"),
+ tr("Finished executing command."));
});
- gpg_process->setProgram(
- GpgContext::GetInstance().GetInfo(false).AppPath.c_str());
+ const auto app_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.app_path", QString{});
+ GF_UI_LOG_DEBUG("got gnupg app path from rt: {}", app_path);
+
+ gpg_process->setProgram(app_path);
gpg_process->setArguments(arguments);
gpg_process->start();
looper.exec();
@@ -336,51 +386,33 @@ void CommonUtils::SlotExecuteGpgCommand(
void CommonUtils::SlotImportKeyFromKeyServer(
const KeyIdArgsList &key_ids, const ImportCallbackFunctiopn &callback) {
- // target key server that we need to import key from it
- std::string target_keyserver;
-
- try {
- auto &settings = GlobalSettingStation::GetInstance().GetUISettings();
- SettingsObject key_server_json("key_server");
-
- // get key servers from settings
- const auto key_server_list =
- key_server_json.Check("server_list", nlohmann::json::array());
- if (key_server_list.empty()) {
- throw std::runtime_error("No key server configured");
- }
-
- const int target_key_server_index =
- key_server_json.Check("default_server", 0);
- if (target_key_server_index >= key_server_list.size()) {
- throw std::runtime_error("default_server index out of range");
- }
- target_keyserver =
- key_server_list[target_key_server_index].get<std::string>();
-
- SPDLOG_DEBUG("set target key server to default Key Server: {}",
- target_keyserver);
- } catch (...) {
- SPDLOG_ERROR(_("Cannot read default_keyserver From Settings"));
- QMessageBox::critical(nullptr, _("Default Keyserver Not Found"),
- _("Cannot read default keyserver from your settings, "
- "please set a default keyserver first"));
+ auto target_keyserver =
+ KeyServerSO(SettingsObject("key_server")).GetTargetServer();
+ if (target_keyserver.isEmpty()) {
+ QMessageBox::critical(
+ nullptr, tr("Default Keyserver Not Found"),
+ tr("Cannot read default keyserver from your settings, "
+ "please set a default keyserver first"));
return;
}
+ GF_UI_LOG_DEBUG("set target key server to default Key Server: {}",
+ target_keyserver);
- auto thread = QThread::create([target_keyserver, key_ids, callback]() {
- QUrl target_keyserver_url(target_keyserver.c_str());
+ auto *thread = QThread::create([target_keyserver, key_ids, callback]() {
+ QUrl target_keyserver_url(target_keyserver);
auto network_manager = std::make_unique<QNetworkAccessManager>();
// LOOP
- decltype(key_ids.size()) current_index = 1, all_index = key_ids.size();
+ decltype(key_ids.size()) current_index = 1;
+ decltype(key_ids.size()) all_index = key_ids.size();
+
for (const auto &key_id : key_ids) {
// New Req Url
- QUrl req_url(
- target_keyserver_url.scheme() + "://" + target_keyserver_url.host() +
- "/pks/lookup?op=get&search=0x" + key_id.c_str() + "&options=mr");
+ QUrl req_url(target_keyserver_url.scheme() + "://" +
+ target_keyserver_url.host() +
+ "/pks/lookup?op=get&search=0x" + key_id + "&options=mr");
- SPDLOG_DEBUG("request url: {}", req_url.toString().toStdString());
+ GF_UI_LOG_DEBUG("request url: {}", req_url.toString().toStdString());
// Waiting for reply
QNetworkReply *reply = network_manager->get(QNetworkRequest(req_url));
@@ -388,41 +420,35 @@ void CommonUtils::SlotImportKeyFromKeyServer(
connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
loop.exec();
- // Get Data
- auto key_data = reply->readAll();
- auto key_data_ptr =
- std::make_unique<ByteArray>(key_data.data(), key_data.size());
-
// Detect status
- std::string status;
+ QString status;
auto error = reply->error();
if (error != QNetworkReply::NoError) {
switch (error) {
case QNetworkReply::ContentNotFoundError:
- status = _("Key Not Found");
+ status = tr("Key Not Found");
break;
case QNetworkReply::TimeoutError:
- status = _("Timeout");
+ status = tr("Timeout");
break;
case QNetworkReply::HostNotFoundError:
- status = _("Key Server Not Found");
+ status = tr("Key Server Not Found");
break;
default:
- status = _("Connection Error");
+ status = tr("Connection Error");
}
}
reply->deleteLater();
// Try importing
- GpgImportInformation result =
- GpgKeyImportExporter::GetInstance().ImportKey(
- std::move(key_data_ptr));
+ auto result = GpgKeyImportExporter::GetInstance().ImportKey(
+ GFBuffer(reply->readAll()));
- if (result.imported == 1) {
- status = _("The key has been updated");
+ if (result->imported == 1) {
+ status = tr("The key has been updated");
} else {
- status = _("No need to update the key");
+ status = tr("No need to update the key");
}
callback(key_id, status, current_index, all_index);
current_index++;
@@ -433,8 +459,8 @@ void CommonUtils::SlotImportKeyFromKeyServer(
}
void CommonUtils::slot_update_key_status() {
- auto refresh_task = new Thread::Task(
- [](Thread::Task::DataObjectPtr) -> int {
+ auto *refresh_task = new Thread::Task(
+ [](DataObjectPtr) -> int {
// flush key cache for all GpgKeyGetter Intances.
for (const auto &channel_id : GpgKeyGetter::GetAllChannelId()) {
GpgKeyGetter::GetInstance(channel_id).FlushKeyCache();
@@ -443,33 +469,15 @@ void CommonUtils::slot_update_key_status() {
},
"update_key_database_task");
connect(refresh_task, &Thread::Task::SignalTaskEnd, this,
- &CommonUtils::SignalKeyDatabaseRefreshDone,
- Qt::BlockingQueuedConnection);
+ &CommonUtils::SignalKeyDatabaseRefreshDone);
// post the task to the default task runner
Thread::TaskRunnerGetter::GetInstance().GetTaskRunner()->PostTask(
refresh_task);
}
-void CommonUtils::slot_popup_passphrase_input_dialog() {
- auto *dialog = new QInputDialog(QApplication::activeWindow(), Qt::Dialog);
- dialog->setModal(true);
- dialog->setWindowTitle(_("Password Input Dialog"));
- dialog->setInputMode(QInputDialog::TextInput);
- dialog->setTextEchoMode(QLineEdit::Password);
- dialog->setLabelText(_("Please Input The Password"));
- dialog->resize(500, 80);
- dialog->exec();
-
- QString password = dialog->textValue();
- dialog->deleteLater();
-
- // send signal
- emit SignalUserInputPassphraseDone(password);
-}
-
void CommonUtils::SlotRestartApplication(int code) {
- SPDLOG_DEBUG("application need restart, code: {}", code);
+ GF_UI_LOG_DEBUG("application need restart, code: {}", code);
if (code == 0) {
std::exit(0);
@@ -482,41 +490,39 @@ bool CommonUtils::isApplicationNeedRestart() {
return application_need_to_restart_at_once_;
}
-bool CommonUtils::KeyExistsinFavouriteList(const GpgKey &key) {
+auto CommonUtils::KeyExistsinFavouriteList(const GpgKey &key) -> bool {
// load cache
- auto key_array = CacheManager::GetInstance().LoadCache("favourite_key_pair");
- if (!key_array.is_array()) {
- CacheManager::GetInstance().SaveCache("favourite_key_pair",
- nlohmann::json::array());
- }
+ auto json_data = CacheObject("favourite_key_pair");
+ if (!json_data.isArray()) json_data.setArray(QJsonArray());
+
+ auto key_array = json_data.array();
return std::find(key_array.begin(), key_array.end(), key.GetFingerprint()) !=
key_array.end();
}
void CommonUtils::AddKey2Favourtie(const GpgKey &key) {
- auto key_array = CacheManager::GetInstance().LoadCache("favourite_key_pair");
- if (!key_array.is_array()) {
- CacheManager::GetInstance().SaveCache("favourite_key_pair",
- nlohmann::json::array());
- }
+ auto json_data = CacheObject("favourite_key_pair");
+ QJsonArray key_array;
+ if (json_data.isArray()) key_array = json_data.array();
+
key_array.push_back(key.GetFingerprint());
- CacheManager::GetInstance().SaveCache("favourite_key_pair", key_array, true);
+ json_data.setArray(key_array);
}
void CommonUtils::RemoveKeyFromFavourite(const GpgKey &key) {
- auto key_array = CacheManager::GetInstance().LoadCache("favourite_key_pair");
- if (!key_array.is_array()) {
- CacheManager::GetInstance().SaveCache("favourite_key_pair",
- nlohmann::json::array(), true);
- return;
- }
- auto it = std::find(key_array.begin(), key_array.end(), key.GetFingerprint());
- if (it != key_array.end()) {
- auto rm_it =
- std::remove(key_array.begin(), key_array.end(), key.GetFingerprint());
- key_array.erase(rm_it, key_array.end());
- CacheManager::GetInstance().SaveCache("favourite_key_pair", key_array);
+ auto json_data = CacheObject("favourite_key_pair");
+ QJsonArray key_array;
+ if (json_data.isArray()) key_array = json_data.array();
+
+ QString fingerprint = key.GetFingerprint();
+ QJsonArray new_key_array;
+ for (auto &&item : key_array) {
+ if (item.isString() && item.toString() != fingerprint) {
+ new_key_array.append(item);
+ }
}
+
+ json_data.setArray(new_key_array);
}
} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/UserInterfaceUtils.h b/src/ui/UserInterfaceUtils.h
index 59c803b9..39a4633e 100644
--- a/src/ui/UserInterfaceUtils.h
+++ b/src/ui/UserInterfaceUtils.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,18 +20,20 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_USER_INTERFACE_UTILS_H
-#define GPGFRONTEND_USER_INTERFACE_UTILS_H
+#pragma once
+
+#include <qwidget.h>
-#include "core/GpgModel.h"
#include "core/function/result_analyse/GpgVerifyResultAnalyse.h"
#include "core/model/GpgKey.h"
+#include "core/thread/ThreadingModel.h"
+#include "core/typedef/GpgTypedef.h"
#include "ui/GpgFrontendUI.h"
namespace GpgFrontend {
@@ -43,6 +45,9 @@ namespace GpgFrontend::UI {
class InfoBoardWidget;
class TextEdit;
+using OperaWaitingHd = std::function<void()>;
+using OperaWaitingCb = const std::function<void(OperaWaitingHd)>;
+
/**
* @brief
*
@@ -71,7 +76,7 @@ void import_unknown_key_from_keyserver(
* @param report_text
*/
void refresh_info_board(InfoBoardWidget* info_board, int status,
- const std::string& report_text);
+ const QString& report_text);
/**
* @brief
@@ -103,10 +108,10 @@ void process_result_analyse(TextEdit* edit, InfoBoardWidget* info_board,
* @param func
*/
void process_operation(
- QWidget* parent, const std::string& waiting_title,
+ QWidget* parent, const QString& waiting_title,
GpgFrontend::Thread::Task::TaskRunnable func,
GpgFrontend::Thread::Task::TaskCallback callback = nullptr,
- Thread::Task::DataObjectPtr data_object = nullptr);
+ DataObjectPtr data_object = nullptr);
/**
* @brief
@@ -115,8 +120,8 @@ void process_operation(
* @param key_id
* @param key_server
*/
-void import_key_from_keyserver(QWidget* parent, const std::string& key_id,
- const std::string& key_server);
+void import_key_from_keyserver(QWidget* parent, const QString& key_id,
+ const QString& key_server);
/**
* @brief
@@ -129,8 +134,8 @@ class CommonUtils : public QWidget {
* @brief
*
*/
- using ImportCallbackFunctiopn = std::function<void(
- const std::string&, const std::string&, size_t, size_t)>;
+ using ImportCallbackFunctiopn =
+ std::function<void(const QString&, const QString&, size_t, size_t)>;
/**
* @brief Construct a new Common Utils object
@@ -148,57 +153,67 @@ class CommonUtils : public QWidget {
/**
* @brief
*
+ * @param err
*/
- bool isApplicationNeedRestart();
+ static void WaitForOpera(QWidget* parent, const QString&,
+ const OperaWaitingCb&);
/**
* @brief
*
+ * @param err
*/
- bool KeyExistsinFavouriteList(const GpgKey& key);
+ static void RaiseMessageBox(QWidget* parent, GpgError err);
/**
* @brief
*
+ * @param err
*/
- void AddKey2Favourtie(const GpgKey& key);
+ static void RaiseFailureMessageBox(QWidget* parent, GpgError err);
/**
* @brief
*
*/
- void RemoveKeyFromFavourite(const GpgKey& key);
+ bool isApplicationNeedRestart();
- signals:
/**
* @brief
*
*/
- void SignalKeyStatusUpdated();
+ bool KeyExistsinFavouriteList(const GpgKey& key);
/**
* @brief
*
*/
- void SignalGnupgNotInstall();
+ void AddKey2Favourtie(const GpgKey& key);
/**
- * @brief emit when the key database is refreshed
+ * @brief
*
*/
- void SignalKeyDatabaseRefreshDone();
+ void RemoveKeyFromFavourite(const GpgKey& key);
+ signals:
/**
* @brief
*
*/
- void SignalNeedUserInputPassphrase();
+ void SignalKeyStatusUpdated();
/**
* @brief
*
*/
- void SignalUserInputPassphraseDone(QString passphrase);
+ void SignalBadGnupgEnv(QString);
+
+ /**
+ * @brief emit when the key database is refreshed
+ *
+ */
+ void SignalKeyDatabaseRefreshDone();
/**
* @brief
@@ -213,7 +228,7 @@ class CommonUtils : public QWidget {
* @param parent
* @param in_buffer
*/
- void SlotImportKeys(QWidget* parent, const std::string& in_buffer);
+ void SlotImportKeys(QWidget* parent, const QString& in_buffer);
/**
* @brief
@@ -263,7 +278,7 @@ class CommonUtils : public QWidget {
* @param arguments
* @param interact_func
*/
- void SlotExecuteCommand(const std::string& cmd, const QStringList& arguments,
+ void SlotExecuteCommand(const QString& cmd, const QStringList& arguments,
const std::function<void(QProcess*)>& interact_func);
/**
@@ -280,17 +295,9 @@ class CommonUtils : public QWidget {
*/
void slot_update_key_status();
- /**
- * @brief
- *
- */
- void slot_popup_passphrase_input_dialog();
-
private:
static std::unique_ptr<CommonUtils> instance_; ///<
bool application_need_to_restart_at_once_ = false;
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_USER_INTERFACE_UTILS_H
diff --git a/src/ui/dialog/GeneralDialog.cpp b/src/ui/dialog/GeneralDialog.cpp
index d4b6613e..386573a3 100644
--- a/src/ui/dialog/GeneralDialog.cpp
+++ b/src/ui/dialog/GeneralDialog.cpp
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2022. Saturneric
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
- * This file is part of GpgFrontend.
+ * 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
@@ -20,17 +20,21 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
+ *
*/
#include "GeneralDialog.h"
#include "ui/struct/SettingsObject.h"
+#include "ui/struct/settings/WindowStateSO.h"
+
+namespace GpgFrontend {
-GpgFrontend::UI::GeneralDialog::GeneralDialog(std::string name, QWidget *parent)
- : name_(std::move(name)), QDialog(parent) {
+GpgFrontend::UI::GeneralDialog::GeneralDialog(QString name, QWidget *parent)
+ : QDialog(parent), name_(std::move(name)) {
slot_restore_settings();
connect(this, &QDialog::finished, this, &GeneralDialog::slot_save_settings);
}
@@ -42,37 +46,37 @@ void GpgFrontend::UI::GeneralDialog::slot_restore_settings() noexcept {
update_rect_cache();
SettingsObject general_windows_state(name_ + "_dialog_state");
- bool window_save = general_windows_state.Check("window_save", false);
+ auto window_state = WindowStateSO(general_windows_state);
// Restore window size & location
- if (window_save) {
- int x = general_windows_state.Check("window_pos").Check("x", 0),
- y = general_windows_state.Check("window_pos").Check("y", 0);
- SPDLOG_DEBUG("stored dialog pos, x: {}, y: {}", x, y);
+ if (window_state.window_save) {
+ int x = window_state.x;
+ int y = window_state.y;
+ GF_UI_LOG_DEBUG("stored dialog pos, x: {}, y: {}", x, y);
QPoint relative_pos = {x, y};
QPoint pos = parent_rect_.topLeft() + relative_pos;
- SPDLOG_DEBUG("relative dialog pos, x: {}, y: {}", relative_pos.x(),
- relative_pos.y());
+ GF_UI_LOG_DEBUG("relative dialog pos, x: {}, y: {}", relative_pos.x(),
+ relative_pos.y());
- int width = general_windows_state.Check("window_size").Check("width", 0),
- height =
- general_windows_state.Check("window_size").Check("height", 0);
- SPDLOG_DEBUG("stored dialog size, width: {}, height: {}", width, height);
+ int width = window_state.width;
+ int height = window_state.height;
+ GF_UI_LOG_DEBUG("stored dialog size, width: {}, height: {}", width,
+ height);
- QRect target_rect_ = {pos.x(), pos.y(), width, height};
- SPDLOG_DEBUG("dialog stored target rect, width: {}, height: {}", width,
- height);
+ QRect target_rect = {pos.x(), pos.y(), width, height};
+ GF_UI_LOG_DEBUG("dialog stored target rect, width: {}, height: {}", width,
+ height);
// check for valid
- if (width > 0 && height > 0 && screen_rect_.contains(target_rect_)) {
- this->setGeometry(target_rect_);
+ if (width > 0 && height > 0 && screen_rect_.contains(target_rect)) {
+ this->setGeometry(target_rect);
this->rect_restored_ = true;
}
}
} catch (...) {
- SPDLOG_ERROR("error at restoring settings");
+ GF_UI_LOG_ERROR("error at restoring settings");
}
}
@@ -82,24 +86,26 @@ void GpgFrontend::UI::GeneralDialog::slot_save_settings() noexcept {
update_rect_cache();
- SPDLOG_DEBUG("dialog pos, x: {}, y: {}", rect_.x(), rect_.y());
- SPDLOG_DEBUG("dialog size, width: {}, height: {}", rect_.width(),
- rect_.height());
+ GF_UI_LOG_DEBUG("dialog pos, x: {}, y: {}", rect_.x(), rect_.y());
+ GF_UI_LOG_DEBUG("dialog size, width: {}, height: {}", rect_.width(),
+ rect_.height());
// window position relative to parent
auto relative_pos = rect_.topLeft() - parent_rect_.topLeft();
- SPDLOG_DEBUG("store dialog pos, x: {}, y: {}", relative_pos.x(),
- relative_pos.y());
+ GF_UI_LOG_DEBUG("store dialog pos, x: {}, y: {}", relative_pos.x(),
+ relative_pos.y());
- general_windows_state["window_pos"]["x"] = relative_pos.x();
- general_windows_state["window_pos"]["y"] = relative_pos.y();
+ WindowStateSO window_state;
+ window_state.x = relative_pos.x();
+ window_state.y = relative_pos.y();
+ window_state.width = rect_.width();
+ window_state.height = rect_.height();
+ window_state.window_save = true;
- general_windows_state["window_size"]["width"] = rect_.width();
- general_windows_state["window_size"]["height"] = rect_.height();
- general_windows_state["window_save"] = true;
+ general_windows_state.Store(window_state.Json());
} catch (...) {
- SPDLOG_ERROR(name_, "error");
+ GF_UI_LOG_ERROR("general dialog: {}, caught exception", name_);
}
}
@@ -108,8 +114,8 @@ void GpgFrontend::UI::GeneralDialog::setPosCenterOfScreen() {
int screen_width = screen_rect_.width();
int screen_height = screen_rect_.height();
- SPDLOG_DEBUG("dialog current screen available geometry", screen_width,
- screen_height);
+ GF_UI_LOG_DEBUG("dialog current screen available geometry", screen_width,
+ screen_height);
// update rect of current dialog
rect_ = this->geometry();
@@ -126,14 +132,14 @@ void GpgFrontend::UI::GeneralDialog::movePosition2CenterOfParent() {
update_rect_cache();
// log for debug
- SPDLOG_DEBUG("parent pos x: {} y: {}", parent_rect_.x(), parent_rect_.y());
- SPDLOG_DEBUG("parent size width: {}, height: {}", parent_rect_.width(),
- parent_rect_.height());
- SPDLOG_DEBUG("parent center pos x: {}, y: {}", parent_rect_.center().x(),
- parent_rect_.center().y());
- SPDLOG_DEBUG("dialog pos x: {} y: {}", rect_.x(), rect_.y());
- SPDLOG_DEBUG("dialog size width: {} height: {}", rect_.width(),
- rect_.height());
+ GF_UI_LOG_DEBUG("parent pos x: {} y: {}", parent_rect_.x(), parent_rect_.y());
+ GF_UI_LOG_DEBUG("parent size width: {}, height: {}", parent_rect_.width(),
+ parent_rect_.height());
+ GF_UI_LOG_DEBUG("parent center pos x: {}, y: {}", parent_rect_.center().x(),
+ parent_rect_.center().y());
+ GF_UI_LOG_DEBUG("dialog pos x: {} y: {}", rect_.x(), rect_.y());
+ GF_UI_LOG_DEBUG("dialog size width: {} height: {}", rect_.width(),
+ rect_.height());
if (parent_rect_.topLeft() != QPoint{0, 0} &&
parent_rect_.size() != QSize{0, 0}) {
@@ -143,8 +149,9 @@ void GpgFrontend::UI::GeneralDialog::movePosition2CenterOfParent() {
QPoint target_position =
parent_rect_.center() - QPoint(rect_.width() / 2, rect_.height() / 2);
- SPDLOG_DEBUG("update position to parent's center, target pos, x:{}, y: {}",
- target_position.x(), target_position.y());
+ GF_UI_LOG_DEBUG(
+ "update position to parent's center, target pos, x:{}, y: {}",
+ target_position.x(), target_position.y());
this->move(target_position);
} else {
@@ -191,18 +198,22 @@ void GpgFrontend::UI::GeneralDialog::update_rect_cache() {
* @brief
*
*/
-bool GpgFrontend::UI::GeneralDialog::isRectRestored() { return rect_restored_; }
+auto GpgFrontend::UI::GeneralDialog::isRectRestored() -> bool {
+ return rect_restored_;
+}
/**
* @brief
*
*/
void GpgFrontend::UI::GeneralDialog::showEvent(QShowEvent *event) {
- SPDLOG_DEBUG("General Dialog named {} is about to show, caught show event",
- name_);
+ GF_UI_LOG_DEBUG("General Dialog named {} is about to show, caught show event",
+ name_);
// default position strategy
if (!isRectRestored()) movePosition2CenterOfParent();
- QWidget::showEvent(event);
-} \ No newline at end of file
+ QDialog::showEvent(event);
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/ui/dialog/GeneralDialog.h b/src/ui/dialog/GeneralDialog.h
index dc42fb6b..604c8475 100644
--- a/src/ui/dialog/GeneralDialog.h
+++ b/src/ui/dialog/GeneralDialog.h
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2022. Saturneric
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
- * This file is part of GpgFrontend.
+ * 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
@@ -20,13 +20,13 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
+ *
*/
-#ifndef GPGFRONTEND_GENERALDIALOG_H
-#define GPGFRONTEND_GENERALDIALOG_H
+#pragma once
#include "ui/GpgFrontendUI.h"
@@ -38,7 +38,7 @@ class GeneralDialog : public QDialog {
*
* @param name
*/
- explicit GeneralDialog(std::string name, QWidget* parent = nullptr);
+ explicit GeneralDialog(QString name, QWidget* parent = nullptr);
/**
*
@@ -86,12 +86,10 @@ class GeneralDialog : public QDialog {
*/
void update_rect_cache();
- std::string name_; ///<
+ QString name_; ///<
QRect rect_;
QRect parent_rect_;
QRect screen_rect_;
bool rect_restored_ = false;
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_GENERALDIALOG_H
diff --git a/src/ui/dialog/QuitDialog.cpp b/src/ui/dialog/QuitDialog.cpp
index 87b1c1e1..6dd5674e 100755
--- a/src/ui/dialog/QuitDialog.cpp
+++ b/src/ui/dialog/QuitDialog.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,13 +28,11 @@
#include "QuitDialog.h"
-#include <boost/format.hpp>
-
namespace GpgFrontend::UI {
QuitDialog::QuitDialog(QWidget* parent, const QHash<int, QString>& unsavedDocs)
: GeneralDialog("quit_dialog", parent) {
- setWindowTitle(_("Unsaved Files"));
+ setWindowTitle(tr("Unsaved Files"));
setModal(true);
discarded_ = false;
@@ -77,52 +75,54 @@ QuitDialog::QuitDialog(QWidget* parent, const QHash<int, QString>& unsavedDocs)
/*
* Warnbox with icon and text
*/
- auto pixmap = QPixmap(":error.png");
+ auto pixmap = QPixmap(":/icons/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);
+ const auto info = tr("%1 files contain unsaved information.<br/>Save the "
+ "changes before closing?")
+ .arg(row);
+ auto* warn_label = new QLabel(info);
+ auto* warn_box_layout = new QHBoxLayout();
+ warn_box_layout->addWidget(warn_icon);
+ warn_box_layout->addWidget(warn_label);
+ warn_box_layout->setAlignment(Qt::AlignLeft);
+ auto* warn_box = new QWidget(this);
+ warn_box->setLayout(warn_box_layout);
/*
* Two labels on top and under the filelist
*/
- auto* checkLabel = new QLabel(_("Check the files you want to save:"));
+ auto* check_label = new QLabel(tr("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/>");
+ "<b>" + tr("Note") + ":</b>" +
+ tr("If you don't save these files, all changes are lost.") + "<br/>");
/*
* Buttonbox
*/
- auto* buttonBox =
+ auto* button_box =
new QDialogButtonBox(QDialogButtonBox::Discard | QDialogButtonBox::Save |
QDialogButtonBox::Cancel);
- connect(buttonBox, &QDialogButtonBox::accepted, this, &QuitDialog::accept);
- connect(buttonBox, &QDialogButtonBox::rejected, this, &QuitDialog::reject);
- QPushButton* btnNoKey = buttonBox->button(QDialogButtonBox::Discard);
- connect(btnNoKey, &QPushButton::clicked, this, &QuitDialog::slot_my_discard);
+ connect(button_box, &QDialogButtonBox::accepted, this, &QuitDialog::accept);
+ connect(button_box, &QDialogButtonBox::rejected, this, &QuitDialog::reject);
+ QPushButton* btn_no_key = button_box->button(QDialogButtonBox::Discard);
+ connect(btn_no_key, &QPushButton::clicked, this,
+ &QuitDialog::slot_my_discard);
/*
* Set the layout
*/
auto* vbox = new QVBoxLayout();
- vbox->addWidget(warnBox);
- vbox->addWidget(checkLabel);
+ vbox->addWidget(warn_box);
+ vbox->addWidget(check_label);
vbox->addWidget(m_fileList_);
vbox->addWidget(note_label);
- vbox->addWidget(buttonBox);
+ vbox->addWidget(button_box);
this->setLayout(vbox);
+
+ this->movePosition2CenterOfParent();
}
void QuitDialog::slot_my_discard() {
@@ -130,16 +130,16 @@ void QuitDialog::slot_my_discard() {
reject();
}
-bool QuitDialog::IsDiscarded() const { return discarded_; }
+auto QuitDialog::IsDiscarded() const -> bool { return discarded_; }
-QList<int> QuitDialog::GetTabIdsToSave() {
- QList<int> tabIdsToSave;
+auto QuitDialog::GetTabIdsToSave() -> QList<int> {
+ QList<int> tab_ids_to_save;
for (int i = 0; i < m_fileList_->rowCount(); i++) {
if (m_fileList_->item(i, 0)->checkState() == Qt::Checked) {
- tabIdsToSave << m_fileList_->item(i, 2)->text().toInt();
+ tab_ids_to_save << m_fileList_->item(i, 2)->text().toInt();
}
}
- return tabIdsToSave;
+ return tab_ids_to_save;
}
} // namespace GpgFrontend::UI
diff --git a/src/ui/dialog/QuitDialog.h b/src/ui/dialog/QuitDialog.h
index 2fd9e382..0c25c2c8 100755
--- a/src/ui/dialog/QuitDialog.h
+++ b/src/ui/dialog/QuitDialog.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,14 +20,13 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef __QUITDIALOG_H__
-#define __QUITDIALOG_H__
+#pragma once
#include "ui/GpgFrontendUI.h"
#include "ui/dialog/GeneralDialog.h"
@@ -56,14 +55,14 @@ class QuitDialog : public GeneralDialog {
* @return true
* @return false
*/
- [[nodiscard]] bool IsDiscarded() const;
+ [[nodiscard]] auto IsDiscarded() const -> bool;
/**
* @brief Get the Tab Ids To Save object
*
* @return QList<int>
*/
- QList<int> GetTabIdsToSave();
+ auto GetTabIdsToSave() -> QList<int>;
private slots:
@@ -79,5 +78,3 @@ class QuitDialog : public GeneralDialog {
};
} // namespace GpgFrontend::UI
-
-#endif // __QUITDIALOG_H__
diff --git a/src/ui/dialog/SignersPicker.cpp b/src/ui/dialog/SignersPicker.cpp
index 8969618e..378a58c7 100644
--- a/src/ui/dialog/SignersPicker.cpp
+++ b/src/ui/dialog/SignersPicker.cpp
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2022. Saturneric
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
- * This file is part of GpgFrontend.
+ * 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
@@ -20,21 +20,23 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
+ *
*/
#include "SignersPicker.h"
+#include "core/GpgModel.h"
#include "ui/widgets/KeyList.h"
namespace GpgFrontend::UI {
SignersPicker::SignersPicker(QWidget* parent)
: GeneralDialog(typeid(SignersPicker).name(), parent) {
- auto confirm_button = new QPushButton(_("Confirm"));
- auto cancel_button = new QPushButton(_("Cancel"));
+ auto* confirm_button = new QPushButton(tr("Confirm"));
+ auto* cancel_button = new QPushButton(tr("Cancel"));
connect(confirm_button, &QPushButton::clicked,
[=]() { this->accepted_ = true; });
@@ -42,9 +44,9 @@ SignersPicker::SignersPicker(QWidget* parent)
connect(cancel_button, &QPushButton::clicked, this, &QDialog::reject);
/*Setup KeyList*/
- key_list_ = new KeyList(false, this);
+ key_list_ = new KeyList(0U, this);
key_list_->AddListGroupTab(
- _("Signers"), "signers", KeyListRow::ONLY_SECRET_KEY,
+ tr("Signers"), "signers", KeyListRow::ONLY_SECRET_KEY,
KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage,
[](const GpgKey& key, const KeyTable&) -> bool {
return key.IsHasActualSigningCapability();
@@ -52,13 +54,13 @@ SignersPicker::SignersPicker(QWidget* parent)
key_list_->SlotRefresh();
auto* vbox2 = new QVBoxLayout();
- vbox2->addWidget(new QLabel(QString(_("Select Signer(s)")) + ": "));
+ vbox2->addWidget(new QLabel(tr("Select Signer(s)") + ": "));
vbox2->addWidget(key_list_);
vbox2->addWidget(new QLabel(
QString(
- _("Please select one or more private keys you use for signing.")) +
+ tr("Please select one or more private keys you use for signing.")) +
"\n" +
- _("If no key is selected, the default key will be used for signing.")));
+ tr("If no key is selected, the default key will be used for signing.")));
vbox2->addWidget(confirm_button);
vbox2->addWidget(cancel_button);
vbox2->addStretch(0);
@@ -68,15 +70,17 @@ SignersPicker::SignersPicker(QWidget* parent)
Qt::CustomizeWindowHint);
this->setModal(true);
- this->setWindowTitle("Signers Picker");
+ this->setWindowTitle(tr("Signers Picker"));
this->setMinimumWidth(480);
+
+ movePosition2CenterOfParent();
this->show();
}
-GpgFrontend::KeyIdArgsListPtr SignersPicker::GetCheckedSigners() {
+auto SignersPicker::GetCheckedSigners() -> GpgFrontend::KeyIdArgsListPtr {
return key_list_->GetPrivateChecked();
}
-bool SignersPicker::GetStatus() const { return this->accepted_; }
+auto SignersPicker::GetStatus() const -> bool { return this->accepted_; }
} // namespace GpgFrontend::UI
diff --git a/src/ui/dialog/SignersPicker.h b/src/ui/dialog/SignersPicker.h
index 5533f9d8..c7e1bfa5 100644
--- a/src/ui/dialog/SignersPicker.h
+++ b/src/ui/dialog/SignersPicker.h
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2022. Saturneric
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
- * This file is part of GpgFrontend.
+ * 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
@@ -20,15 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
+ *
*/
-#ifndef GPGFRONTEND_ZH_CN_TS_SIGNERSPIRCKER_H
-#define GPGFRONTEND_ZH_CN_TS_SIGNERSPIRCKER_H
+#pragma once
#include "GpgFrontendUI.h"
+#include "core/typedef/GpgTypedef.h"
#include "ui/dialog//GeneralDialog.h"
namespace GpgFrontend::UI {
@@ -55,7 +56,7 @@ class SignersPicker : public GeneralDialog {
*
* @return GpgFrontend::KeyIdArgsListPtr
*/
- GpgFrontend::KeyIdArgsListPtr GetCheckedSigners();
+ KeyIdArgsListPtr GetCheckedSigners();
/**
*
@@ -69,5 +70,3 @@ class SignersPicker : public GeneralDialog {
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_ZH_CN_TS_SIGNERSPIRCKER_H
diff --git a/src/ui/dialog/WaitingDialog.cpp b/src/ui/dialog/WaitingDialog.cpp
index b0888581..9c9a91d4 100644
--- a/src/ui/dialog/WaitingDialog.cpp
+++ b/src/ui/dialog/WaitingDialog.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,7 +28,7 @@
#include "WaitingDialog.h"
-#include "dialog/GeneralDialog.h"
+#include "ui/dialog/GeneralDialog.h"
namespace GpgFrontend::UI {
@@ -36,23 +36,20 @@ WaitingDialog::WaitingDialog(const QString& title, QWidget* parent)
: GeneralDialog("WaitingDialog", parent) {
auto* pb = new QProgressBar();
pb->setRange(0, 0);
- pb->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+ pb->setSizePolicy(QSizePolicy::Expanding, 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);
+ this->movePosition2CenterOfParent();
this->show();
}
diff --git a/src/ui/dialog/WaitingDialog.h b/src/ui/dialog/WaitingDialog.h
index c8193cba..d042c215 100644
--- a/src/ui/dialog/WaitingDialog.h
+++ b/src/ui/dialog/WaitingDialog.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,14 +20,13 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef __UI_WAITING_DIALOG_H__
-#define __UI_WAITING_DIALOG_H__
+#pragma once
#include "ui/GpgFrontendUI.h"
#include "ui/dialog/GeneralDialog.h"
@@ -51,5 +50,3 @@ class WaitingDialog : public GeneralDialog {
};
} // namespace GpgFrontend::UI
-
-#endif // __UI_WAITING_DIALOG_H__
diff --git a/src/ui/dialog/Wizard.cpp b/src/ui/dialog/Wizard.cpp
index 77f07559..89ebee27 100644
--- a/src/ui/dialog/Wizard.cpp
+++ b/src/ui/dialog/Wizard.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,6 +28,7 @@
#include "Wizard.h"
+#include "core/GpgModel.h"
#include "core/function/GlobalSettingStation.h"
namespace GpgFrontend::UI {
@@ -40,15 +41,17 @@ Wizard::Wizard(QWidget* parent) : QWizard(parent) {
#ifndef Q_WS_MAC
setWizardStyle(ModernStyle);
#endif
- setWindowTitle(_("First Start Wizard"));
+ 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"));
-
- int next_page_id = GlobalSettingStation::GetInstance().LookupSettings(
- "wizard.next_page", -1);
+ setPixmap(QWizard::WatermarkPixmap, QPixmap(":/icons/keys2.jpg"));
+ setPixmap(QWizard::LogoPixmap, QPixmap(":/icons/logo_small.png"));
+ setPixmap(QWizard::BannerPixmap, QPixmap(":/icons/banner.png"));
+
+ int next_page_id = GlobalSettingStation::GetInstance()
+ .GetSettings()
+ .value("wizard.next_page", -1)
+ .toInt();
setStartId(next_page_id);
connect(this, &Wizard::accepted, this, &Wizard::slot_wizard_accepted);
@@ -57,19 +60,10 @@ Wizard::Wizard(QWidget* parent) : QWizard(parent) {
void Wizard::slot_wizard_accepted() {
// Don't show is mapped to show -> negation
try {
- auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
- if (!settings.exists("wizard")) {
- settings.add("wizard", libconfig::Setting::TypeGroup);
- }
- auto& wizard = settings["wizard"];
- if (!wizard.exists("show_wizard")) {
- wizard.add("show_wizard", libconfig::Setting::TypeBoolean) = false;
- } else {
- wizard["show_wizard"] = false;
- }
- GlobalSettingStation::GetInstance().SyncSettings();
+ auto settings = GlobalSettingStation::GetInstance().GetSettings();
+ settings.setValue("wizard/show_wizard", false);
} catch (...) {
- SPDLOG_ERROR("setting operation error");
+ GF_UI_LOG_ERROR("setting operation error");
}
if (field("openHelp").toBool()) {
emit SignalOpenHelp("docu.html#content");
@@ -77,19 +71,20 @@ void Wizard::slot_wizard_accepted() {
}
IntroPage::IntroPage(QWidget* parent) : QWizardPage(parent) {
- setTitle(_("Getting Started..."));
- setSubTitle(_("... with GpgFrontend"));
+ setTitle(tr("Getting Started..."));
+ setSubTitle(tr("... with GpgFrontend"));
auto* topLabel = new QLabel(
- QString(_("Welcome to use GpgFrontend for decrypting and signing text or "
- "file!")) +
+ QString(
+ tr("Welcome to use GpgFrontend for decrypting and signing text or "
+ "file!")) +
" <br><br><a href='https://gpgfrontend.bktus.com'>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") +
+ 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.bktus.com/index.html#/overview'>" +
- _("Overview") + "</a> (" +
- _("by clicking the link, the page will open in the web browser") +
+ 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);
@@ -97,18 +92,16 @@ IntroPage::IntroPage(QWidget* parent) : QWizardPage(parent) {
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);
+ auto* lang_label =
+ new QLabel(tr("If it supports the language currently being used in your "
+ "system, GpgFrontend will automatically set it."));
+ lang_label->setWordWrap(true);
// set layout and add widgets
auto* layout = new QVBoxLayout;
layout->addWidget(topLabel);
layout->addStretch();
-#ifdef MULTI_LANG_SUPPORT
- layout->addWidget(langLabel);
-#endif
+ layout->addWidget(lang_label);
setLayout(layout);
}
@@ -116,60 +109,56 @@ IntroPage::IntroPage(QWidget* parent) : QWizardPage(parent) {
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.bktus.com/index.html#/manual/"
+ setTitle(tr("Choose your action..."));
+ setSubTitle(tr("...by clicking on the appropriate link."));
+
+ auto* keygen_label = 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.bktus.com/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 ")) +
+ tr("Generate Key") + "</a><hr>");
+ keygen_label->setTextFormat(Qt::RichText);
+ keygen_label->setTextInteractionFlags(Qt::TextBrowserInteraction);
+ keygen_label->setOpenExternalLinks(true);
+ keygen_label->setWordWrap(true);
+
+ auto* encr_decy_text_label = new QLabel(
+ tr("If you want to learn how to encrypt, decrypt, sign and verify text, "
+ "you can read ") +
"<a "
"href=\"https://gpgfrontend.bktus.com/index.html#/manual/"
"encrypt-decrypt-text\">" +
- _("Encrypt & Decrypt Text") + "</a> " + _("or") +
+ tr("Encrypt & Decrypt Text") + "</a> " + tr("or") +
" <a "
"href=\"https://gpgfrontend.bktus.com/index.html#/manual/"
"sign-verify-text\">" +
- _("Sign & Verify Text") + "</a><hr>");
+ tr("Sign & Verify Text") + "</a><hr>");
- encrDecyTextLabel->setTextFormat(Qt::RichText);
- encrDecyTextLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
- encrDecyTextLabel->setOpenExternalLinks(true);
- encrDecyTextLabel->setWordWrap(true);
+ encr_decy_text_label->setTextFormat(Qt::RichText);
+ encr_decy_text_label->setTextInteractionFlags(Qt::TextBrowserInteraction);
+ encr_decy_text_label->setOpenExternalLinks(true);
+ encr_decy_text_label->setWordWrap(true);
- auto* signVerifyTextLabel =
- new QLabel(QString(_("If you want to operate file, you can read ")) +
+ auto* sign_verify_text_label =
+ new QLabel(tr("If you want to operate file, you can read ") +
"<a "
"href=\"https://gpgfrontend.bktus.com/index.html#/manual/"
"encrypt-decrypt-file\">" +
- _("Encrypt & Sign File") + "</a> " + _("or") +
+ tr("Encrypt & Sign File") + "</a> " + tr("or") +
" <a "
"href=\"https://gpgfrontend.bktus.com/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);
+ tr("Sign & Verify File") + "</a><hr>");
+ sign_verify_text_label->setTextFormat(Qt::RichText);
+ sign_verify_text_label->setTextInteractionFlags(Qt::TextBrowserInteraction);
+ sign_verify_text_label->setOpenExternalLinks(true);
+ sign_verify_text_label->setWordWrap(true);
auto* layout = new QVBoxLayout();
- layout->addWidget(keygenLabel);
- layout->addWidget(encrDecyTextLabel);
- layout->addWidget(signVerifyTextLabel);
+ layout->addWidget(keygen_label);
+ layout->addWidget(encr_decy_text_label);
+ layout->addWidget(sign_verify_text_label);
setLayout(layout);
next_page_ = Wizard::Page_Conclusion;
}
@@ -186,33 +175,33 @@ void ChoosePage::slot_jump_page(const QString& page) {
}
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(
+ setTitle(tr("Create a keypair..."));
+ setSubTitle(tr("...for decrypting and signing messages"));
+ auto* top_label = 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):"));
+ top_label->setWordWrap(true);
+ auto* link_label = new QLabel(
"<a href="
"docu_keygen.html#content"
">" +
- QString(_("Offline tutorial")) + "</a>");
+ tr("Offline tutorial") + "</a>");
- auto* createKeyButtonBox = new QWidget(this);
- auto* createKeyButtonBoxLayout = new QHBoxLayout(createKeyButtonBox);
- auto* createKeyButton = new QPushButton(_("Create New Key"));
- createKeyButtonBoxLayout->addWidget(createKeyButton);
- createKeyButtonBoxLayout->addStretch(1);
+ auto* create_key_button_box = new QWidget(this);
+ auto* create_key_button_box_layout = new QHBoxLayout(create_key_button_box);
+ auto* create_key_button = new QPushButton(tr("Create New Key"));
+ create_key_button_box_layout->addWidget(create_key_button);
+ create_key_button_box_layout->addStretch(1);
auto* layout = new QVBoxLayout();
- layout->addWidget(topLabel);
- layout->addWidget(linkLabel);
- layout->addWidget(createKeyButtonBox);
- connect(createKeyButton, &QPushButton::clicked, this,
+ layout->addWidget(top_label);
+ layout->addWidget(link_label);
+ layout->addWidget(create_key_button_box);
+ connect(create_key_button, &QPushButton::clicked, this,
&KeyGenPage::slot_generate_key_dialog);
setLayout(layout);
@@ -226,17 +215,17 @@ void KeyGenPage::slot_generate_key_dialog() {
}
ConclusionPage::ConclusionPage(QWidget* parent) : QWizardPage(parent) {
- setTitle(_("Ready."));
- setSubTitle(_("Have fun with GpgFrontend!"));
+ setTitle(tr("Ready."));
+ setSubTitle(tr("Have fun with GpgFrontend!"));
auto* bottomLabel = new QLabel(
- QString(_("You are ready to use GpgFrontend now.<br><br>")) +
+ tr("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. Anytime you encounter "
- "problems, please try to find help from the documentation") +
+ tr("The Online Document") + "</a>" +
+ tr(" will get you started with GpgFrontend. Anytime you encounter "
+ "problems, please try to find help from the documentation") +
"<br>");
bottomLabel->setTextFormat(Qt::RichText);
@@ -244,10 +233,10 @@ ConclusionPage::ConclusionPage(QWidget* parent) : QWizardPage(parent) {
bottomLabel->setOpenExternalLinks(true);
bottomLabel->setWordWrap(true);
- open_help_check_box_ = new QCheckBox(_("Open offline help."));
+ open_help_check_box_ = new QCheckBox(tr("Open offline help."));
open_help_check_box_->setChecked(true);
- dont_show_wizard_checkbox_ = new QCheckBox(_("Dont show the wizard again."));
+ dont_show_wizard_checkbox_ = new QCheckBox(tr("Dont show the wizard again."));
dont_show_wizard_checkbox_->setChecked(true);
registerField("showWizard", dont_show_wizard_checkbox_);
diff --git a/src/ui/dialog/Wizard.h b/src/ui/dialog/Wizard.h
index 879dc5d9..fbc33d5e 100644
--- a/src/ui/dialog/Wizard.h
+++ b/src/ui/dialog/Wizard.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,14 +20,13 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef WIZARD_H
-#define WIZARD_H
+#pragma once
#include "core/GpgConstants.h"
#include "main_window/KeyMgmt.h"
@@ -185,5 +184,3 @@ class ConclusionPage : public QWizardPage {
};
} // namespace GpgFrontend::UI
-
-#endif
diff --git a/src/ui/dialog/details/SignatureDetailsDialog.cpp b/src/ui/dialog/details/SignatureDetailsDialog.cpp
index a3ad03b3..baf8bd4b 100644
--- a/src/ui/dialog/details/SignatureDetailsDialog.cpp
+++ b/src/ui/dialog/details/SignatureDetailsDialog.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
diff --git a/src/ui/dialog/details/SignatureDetailsDialog.h b/src/ui/dialog/details/SignatureDetailsDialog.h
index 7b01d054..405c11dd 100644
--- a/src/ui/dialog/details/SignatureDetailsDialog.h
+++ b/src/ui/dialog/details/SignatureDetailsDialog.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,14 +20,13 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_SIGNATUREDETAILSDIALOG_H
-#define GPGFRONTEND_SIGNATUREDETAILSDIALOG_H
+#pragma once
#include "ui/GpgFrontendUI.h"
@@ -35,5 +34,3 @@ class SignatureDetailsDialog : public QDialog {
Q_OBJECT
public:
};
-
-#endif // GPGFRONTEND_SIGNATUREDETAILSDIALOG_H
diff --git a/src/ui/dialog/details/VerifyDetailsDialog.cpp b/src/ui/dialog/details/VerifyDetailsDialog.cpp
index 307d404a..cea34607 100644
--- a/src/ui/dialog/details/VerifyDetailsDialog.cpp
+++ b/src/ui/dialog/details/VerifyDetailsDialog.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,14 +28,14 @@
#include "VerifyDetailsDialog.h"
-#include <boost/format.hpp>
+#include "core/GpgModel.h"
namespace GpgFrontend::UI {
VerifyDetailsDialog::VerifyDetailsDialog(QWidget* parent, GpgError error,
GpgVerifyResult result)
- : QDialog(parent), m_result_(std::move(result)), error_(error) {
- this->setWindowTitle(_("Signatures Details"));
+ : QDialog(parent), m_result_(result), error_(error) {
+ this->setWindowTitle(tr("Signatures Details"));
main_layout_ = new QHBoxLayout();
this->setLayout(main_layout_);
@@ -47,7 +47,7 @@ VerifyDetailsDialog::VerifyDetailsDialog(QWidget* parent, GpgError error,
void VerifyDetailsDialog::slot_refresh() {
m_vbox_ = new QWidget();
- auto* mVboxLayout = new QVBoxLayout(m_vbox_);
+ auto* m_vbox_layout = new QVBoxLayout(m_vbox_);
main_layout_->addWidget(m_vbox_);
// Button Box for close button
@@ -55,47 +55,38 @@ void VerifyDetailsDialog::slot_refresh() {
connect(button_box_, &QDialogButtonBox::rejected, this,
&VerifyDetailsDialog::close);
- auto sign = m_result_->signatures;
+ auto signatures = m_result_.GetSignature();
- if (sign == nullptr) {
- mVboxLayout->addWidget(new QLabel(_("No valid input found")));
- mVboxLayout->addWidget(button_box_);
+ if (signatures.empty()) {
+ m_vbox_layout->addWidget(new QLabel(tr("No valid input found")));
+ m_vbox_layout->addWidget(button_box_);
return;
}
// Get timestamp of signature of current text
- QDateTime timestamp;
-#ifdef GPGFRONTEND_GUI_QT6
- timestamp.setSecsSinceEpoch(sign->timestamp);
-#else
- timestamp.setTime_t(sign->timestamp);
-#endif
+ QDateTime timestamp = signatures[0].GetCreateTime();
// 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")));
+ if (gpg_err_code(signatures[0].GetStatus()) == GPG_ERR_BAD_SIGNATURE) {
+ m_vbox_layout->addWidget(new QLabel(tr("Error Validating signature")));
} else if (input_signature_ != 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()));
+ const auto info =
+ tr("File was signed on %1").arg(QLocale::system().toString(timestamp)) +
+ "<br/>" + tr("It Contains") + ": " + "<br/><br/>";
+ m_vbox_layout->addWidget(new QLabel(info));
} 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()));
+ const auto info =
+ tr("Signed on %1").arg(QLocale::system().toString(timestamp)) +
+ "<br/>" + tr("It Contains") + ": " + "<br/><br/>";
+ m_vbox_layout->addWidget(new QLabel(info));
}
// Add information box for every single key
- while (sign) {
- GpgSignature signature(sign);
- auto* sign_box = new VerifyKeyDetailBox(signature, this);
- sign = sign->next;
- mVboxLayout->addWidget(sign_box);
+ for (const auto& signature : signatures) {
+ auto* detail_box = new VerifyKeyDetailBox(signature, this);
+ m_vbox_layout->addWidget(detail_box);
}
- mVboxLayout->addWidget(button_box_);
+ m_vbox_layout->addWidget(button_box_);
}
} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/dialog/details/VerifyDetailsDialog.h b/src/ui/dialog/details/VerifyDetailsDialog.h
index 5bc09884..7b684e07 100644
--- a/src/ui/dialog/details/VerifyDetailsDialog.h
+++ b/src/ui/dialog/details/VerifyDetailsDialog.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,15 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef __VERIFYDETAILSDIALOG_H__
-#define __VERIFYDETAILSDIALOG_H__
+#pragma once
+#include "core/function/result_analyse/GpgResultAnalyse.h"
+#include "core/model/GpgVerifyResult.h"
#include "ui/GpgFrontendUI.h"
#include "ui/widgets/PlainTextEditorPage.h"
#include "ui/widgets/VerifyKeyDetailBox.h"
@@ -70,5 +71,3 @@ class VerifyDetailsDialog : public QDialog {
};
} // namespace GpgFrontend::UI
-
-#endif // __VERIFYDETAILSDIALOG_H__
diff --git a/src/ui/dialog/gnupg/GnuPGControllerDialog.cpp b/src/ui/dialog/gnupg/GnuPGControllerDialog.cpp
index 9214a4fd..fbf018ca 100644
--- a/src/ui/dialog/gnupg/GnuPGControllerDialog.cpp
+++ b/src/ui/dialog/gnupg/GnuPGControllerDialog.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,8 +28,10 @@
#include "GnuPGControllerDialog.h"
-#include "SignalStation.h"
+#include "core/GpgModel.h"
#include "core/function/GlobalSettingStation.h"
+#include "core/module/ModuleManager.h"
+#include "ui/UISignalStation.h"
#include "ui/dialog/GeneralDialog.h"
#include "ui_GnuPGControllerDialog.h"
@@ -37,34 +39,34 @@ namespace GpgFrontend::UI {
GnuPGControllerDialog::GnuPGControllerDialog(QWidget* parent)
: GeneralDialog("GnuPGControllerDialog", parent),
- ui_(std::make_shared<Ui_GnuPGControllerDialog>()) {
+ ui_(GpgFrontend::SecureCreateSharedObject<Ui_GnuPGControllerDialog>()) {
ui_->setupUi(this);
- ui_->generalBox->setTitle(_("General"));
- ui_->keyDatabaseGroupBox->setTitle(_("Key Database"));
- ui_->advanceGroupBox->setTitle(_("Advanced"));
+ ui_->generalBox->setTitle(tr("General"));
+ ui_->keyDatabaseGroupBox->setTitle(tr("Key Database"));
+ ui_->advanceGroupBox->setTitle(tr("Advanced"));
- ui_->asciiModeCheckBox->setText(_("No ASCII Mode"));
+ ui_->asciiModeCheckBox->setText(tr("No ASCII Mode"));
ui_->usePinentryAsPasswordInputDialogCheckBox->setText(
- _("Use Pinentry as Password Input Dialog"));
- ui_->useCustomGnuPGInstallPathCheckBox->setText(_("Use Custom GnuPG"));
- ui_->useCustomGnuPGInstallPathButton->setText(_("Select GnuPG Path"));
+ tr("Use Pinentry as Password Input Dialog"));
+ ui_->useCustomGnuPGInstallPathCheckBox->setText(tr("Use Custom GnuPG"));
+ ui_->useCustomGnuPGInstallPathButton->setText(tr("Select GnuPG Path"));
ui_->keyDatabseUseCustomCheckBox->setText(
- _("Use Custom GnuPG Key Database Path"));
+ tr("Use Custom GnuPG Key Database Path"));
ui_->customKeyDatabasePathSelectButton->setText(
- _("Select Key Database Path"));
+ tr("Select Key Database Path"));
// tips
ui_->customGnuPGPathTipsLabel->setText(
- _("Tips: please select a directroy where \"gpgconf\" is located in."));
+ tr("Tips: please select a directroy where \"gpgconf\" is located in."));
ui_->restartTipsLabel->setText(
- _("Tips: notice that modify any of these settings will cause an "
- "Application restart."));
+ tr("Tips: notice that modify any of these settings will cause an "
+ "Application restart."));
// announce main window
connect(this, &GnuPGControllerDialog::SignalRestartNeeded,
- SignalStation::GetInstance(),
- &SignalStation::SignalRestartApplication);
+ UISignalStation::GetInstance(),
+ &UISignalStation::SignalRestartApplication);
connect(ui_->keyDatabseUseCustomCheckBox, &QCheckBox::stateChanged, this,
[=](int state) {
@@ -90,32 +92,27 @@ GnuPGControllerDialog::GnuPGControllerDialog(QWidget* parent)
[=]() {
QString selected_custom_key_database_path =
QFileDialog::getExistingDirectory(
- this, _("Open Directory"), {},
+ this, tr("Open Directory"), {},
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
- SPDLOG_DEBUG("key databse path selected: {}",
- selected_custom_key_database_path.toStdString());
+ GF_UI_LOG_DEBUG("key databse path selected: {}",
+ selected_custom_key_database_path);
if (!check_custom_gnupg_key_database_path(
- selected_custom_key_database_path.toStdString())) {
+ selected_custom_key_database_path)) {
return;
}
- auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
- auto& general = settings["general"];
+ auto settings = GlobalSettingStation::GetInstance().GetSettings();
// update settings
- if (!general.exists("custom_key_database_path"))
- general.add("custom_key_database_path",
- libconfig::Setting::TypeString) =
- selected_custom_key_database_path.toStdString();
- else {
- general["custom_key_database_path"] =
- selected_custom_key_database_path.toStdString();
+ if (!settings.contains("basic/custom_key_database_path")) {
+ settings.setValue("basic/custom_key_database_path",
+ selected_custom_key_database_path);
}
// announce the restart
- this->slot_set_restart_needed(DEEP_RESTART_CODE);
+ this->slot_set_restart_needed(kDeepRestartCode);
// update ui
this->slot_update_custom_key_database_path_label(
@@ -126,33 +123,25 @@ GnuPGControllerDialog::GnuPGControllerDialog(QWidget* parent)
ui_->useCustomGnuPGInstallPathButton, &QPushButton::clicked, this, [=]() {
QString selected_custom_gnupg_install_path =
QFileDialog::getExistingDirectory(
- this, _("Open Directory"), {},
+ this, tr("Open Directory"), {},
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
- SPDLOG_DEBUG("gnupg install path selected: {}",
- selected_custom_gnupg_install_path.toStdString());
+ GF_UI_LOG_DEBUG("gnupg install path selected: {}",
+ selected_custom_gnupg_install_path);
// notify the user and precheck
- if (!check_custom_gnupg_path(
- selected_custom_gnupg_install_path.toStdString())) {
+ if (!check_custom_gnupg_path(selected_custom_gnupg_install_path)) {
return;
}
- auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
- auto& general = settings["general"];
-
- // update settings
- if (!general.exists("custom_gnupg_install_path"))
- general.add("custom_gnupg_install_path",
- libconfig::Setting::TypeString) =
- selected_custom_gnupg_install_path.toStdString();
- else {
- general["custom_gnupg_install_path"] =
- selected_custom_gnupg_install_path.toStdString();
+ auto settings = GlobalSettingStation::GetInstance().GetSettings();
+ if (!settings.contains("basic/custom_gnupg_install_path")) {
+ settings.setValue("basic/custom_gnupg_install_path",
+ selected_custom_gnupg_install_path);
}
// announce the restart
- this->slot_set_restart_needed(DEEP_RESTART_CODE);
+ this->slot_set_restart_needed(kDeepRestartCode);
// update ui
this->slot_update_custom_gnupg_install_path_label(
@@ -162,7 +151,7 @@ GnuPGControllerDialog::GnuPGControllerDialog(QWidget* parent)
connect(ui_->usePinentryAsPasswordInputDialogCheckBox,
&QCheckBox::stateChanged, this, [=](int state) {
// announce the restart
- this->slot_set_restart_needed(DEEP_RESTART_CODE);
+ this->slot_set_restart_needed(kDeepRestartCode);
});
#ifndef MACOS
@@ -180,20 +169,16 @@ GnuPGControllerDialog::GnuPGControllerDialog(QWidget* parent)
connect(this, &QDialog::finished, this, &GnuPGControllerDialog::deleteLater);
#endif
- setWindowTitle(_("GnuPG Controller"));
+ setWindowTitle(tr("GnuPG Controller"));
set_settings();
}
void GnuPGControllerDialog::SlotAccept() {
apply_settings();
- SPDLOG_DEBUG("gnupg controller apply done");
-
- // write settings to filesystem
- GlobalSettingStation::GetInstance().SyncSettings();
-
- SPDLOG_DEBUG("restart needed: {}", get_restart_needed());
- if (get_restart_needed()) {
+ GF_UI_LOG_DEBUG("gnupg controller apply done");
+ GF_UI_LOG_DEBUG("restart needed: {}", get_restart_needed());
+ if (get_restart_needed() != 0) {
emit SignalRestartNeeded(get_restart_needed());
}
close();
@@ -202,30 +187,34 @@ void GnuPGControllerDialog::SlotAccept() {
void GnuPGControllerDialog::slot_update_custom_key_database_path_label(
int state) {
// announce the restart
- this->slot_set_restart_needed(DEEP_RESTART_CODE);
+ this->slot_set_restart_needed(kDeepRestartCode);
+
+ const auto database_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.database_path", QString{});
+ GF_UI_LOG_DEBUG("got gpgme.ctx.database_path from rt: {}", database_path);
if (state != Qt::CheckState::Checked) {
- ui_->currentKeyDatabasePathLabel->setText(QString::fromStdString(
- GpgContext::GetInstance().GetInfo(false).DatabasePath));
+ ui_->currentKeyDatabasePathLabel->setText(database_path);
// hide label (not necessary to show the default path)
this->ui_->currentKeyDatabasePathLabel->setHidden(true);
} else {
// read from settings file
- std::string custom_key_database_path =
- GlobalSettingStation::GetInstance().LookupSettings(
- "general.custom_key_database_path", std::string{});
+ QString custom_key_database_path =
+ GlobalSettingStation::GetInstance()
+ .GetSettings()
+ .value("basic/custom_key_database_path")
+ .toString();
- SPDLOG_DEBUG("selected_custom_key_database_path from settings: {}",
- custom_key_database_path);
+ GF_UI_LOG_DEBUG("selected_custom_key_database_path from settings: {}",
+ custom_key_database_path);
// notify the user
check_custom_gnupg_key_database_path(custom_key_database_path);
// set label value
- if (!custom_key_database_path.empty()) {
- ui_->currentKeyDatabasePathLabel->setText(
- QString::fromStdString(custom_key_database_path));
+ if (!custom_key_database_path.isEmpty()) {
+ ui_->currentKeyDatabasePathLabel->setText(custom_key_database_path);
this->ui_->currentKeyDatabasePathLabel->setHidden(false);
} else {
this->ui_->currentKeyDatabasePathLabel->setHidden(true);
@@ -236,30 +225,36 @@ void GnuPGControllerDialog::slot_update_custom_key_database_path_label(
void GnuPGControllerDialog::slot_update_custom_gnupg_install_path_label(
int state) {
// announce the restart
- this->slot_set_restart_needed(DEEP_RESTART_CODE);
+ this->slot_set_restart_needed(kDeepRestartCode);
+
+ const auto home_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ "gnupg.home_path", QString{});
+ GF_UI_LOG_DEBUG("got gnupg home path from rt: {}", home_path);
if (state != Qt::CheckState::Checked) {
- ui_->currentCustomGnuPGInstallPathLabel->setText(QString::fromStdString(
- GpgContext::GetInstance().GetInfo(false).GnuPGHomePath));
+ ui_->currentCustomGnuPGInstallPathLabel->setText(home_path);
// hide label (not necessary to show the default path)
this->ui_->currentCustomGnuPGInstallPathLabel->setHidden(true);
} else {
// read from settings file
- std::string custom_gnupg_install_path =
- GlobalSettingStation::GetInstance().LookupSettings(
- "general.custom_gnupg_install_path", std::string{});
+ QString custom_gnupg_install_path =
+ GlobalSettingStation::GetInstance()
+ .GetSettings()
+ .value("basic/custom_gnupg_install_path")
+ .toString();
- SPDLOG_DEBUG("custom_gnupg_install_path from settings: {}",
- custom_gnupg_install_path);
+ GF_UI_LOG_DEBUG("custom_gnupg_install_path from settings: {}",
+ custom_gnupg_install_path);
// notify the user
check_custom_gnupg_path(custom_gnupg_install_path);
// set label value
- if (!custom_gnupg_install_path.empty()) {
+ if (!custom_gnupg_install_path.isEmpty()) {
ui_->currentCustomGnuPGInstallPathLabel->setText(
- QString::fromStdString(custom_gnupg_install_path));
+ custom_gnupg_install_path);
this->ui_->currentCustomGnuPGInstallPathLabel->setHidden(false);
} else {
this->ui_->currentCustomGnuPGInstallPathLabel->setHidden(true);
@@ -268,47 +263,39 @@ void GnuPGControllerDialog::slot_update_custom_gnupg_install_path_label(
}
void GnuPGControllerDialog::set_settings() {
- auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
-
- try {
- bool non_ascii_when_export =
- settings.lookup("general.non_ascii_when_export");
- SPDLOG_DEBUG("non_ascii_when_export: {}", non_ascii_when_export);
- if (non_ascii_when_export)
- ui_->asciiModeCheckBox->setCheckState(Qt::Checked);
- } catch (...) {
- SPDLOG_ERROR("setting operation error: non_ascii_when_export");
- }
-
- try {
- bool use_custom_key_database_path =
- settings.lookup("general.use_custom_key_database_path");
- if (use_custom_key_database_path)
- ui_->keyDatabseUseCustomCheckBox->setCheckState(Qt::Checked);
- } catch (...) {
- SPDLOG_ERROR("setting operation error: use_custom_key_database_path");
+ auto& settings_station = GlobalSettingStation::GetInstance();
+
+ bool non_ascii_when_export = settings_station.GetSettings()
+ .value("basic/non_ascii_when_export", true)
+ .toBool();
+ GF_UI_LOG_DEBUG("non_ascii_when_export: {}", non_ascii_when_export);
+ if (non_ascii_when_export) ui_->asciiModeCheckBox->setCheckState(Qt::Checked);
+
+ bool const use_custom_key_database_path =
+ settings_station.GetSettings()
+ .value("basic/use_custom_key_database_path", false)
+ .toBool();
+ if (use_custom_key_database_path) {
+ ui_->keyDatabseUseCustomCheckBox->setCheckState(Qt::Checked);
}
this->slot_update_custom_key_database_path_label(
ui_->keyDatabseUseCustomCheckBox->checkState());
- try {
- bool use_custom_gnupg_install_path =
- settings.lookup("general.use_custom_gnupg_install_path");
- if (use_custom_gnupg_install_path)
- ui_->useCustomGnuPGInstallPathCheckBox->setCheckState(Qt::Checked);
- } catch (...) {
- SPDLOG_ERROR("setting operation error: use_custom_gnupg_install_path");
+ bool const use_custom_gnupg_install_path =
+ settings_station.GetSettings()
+ .value("basic/use_custom_gnupg_install_path", false)
+ .toBool();
+ if (use_custom_gnupg_install_path) {
+ ui_->useCustomGnuPGInstallPathCheckBox->setCheckState(Qt::Checked);
}
- try {
- bool use_pinentry_as_password_input_dialog =
- settings.lookup("general.use_pinentry_as_password_input_dialog");
- if (use_pinentry_as_password_input_dialog)
- ui_->usePinentryAsPasswordInputDialogCheckBox->setCheckState(Qt::Checked);
- } catch (...) {
- SPDLOG_ERROR(
- "setting operation error: use_pinentry_as_password_input_dialog");
+ bool const use_pinentry_as_password_input_dialog =
+ settings_station.GetSettings()
+ .value("basic/use_pinentry_as_password_input_dialog", false)
+ .toBool();
+ if (use_pinentry_as_password_input_dialog) {
+ ui_->usePinentryAsPasswordInputDialogCheckBox->setCheckState(Qt::Checked);
}
this->slot_update_custom_gnupg_install_path_label(
@@ -318,48 +305,17 @@ void GnuPGControllerDialog::set_settings() {
}
void GnuPGControllerDialog::apply_settings() {
- auto& settings =
- GpgFrontend::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("non_ascii_when_export"))
- general.add("non_ascii_when_export", libconfig::Setting::TypeBoolean) =
- ui_->asciiModeCheckBox->isChecked();
- else {
- general["non_ascii_when_export"] = ui_->asciiModeCheckBox->isChecked();
- }
-
- if (!general.exists("use_custom_key_database_path"))
- general.add("use_custom_key_database_path",
- libconfig::Setting::TypeBoolean) =
- ui_->keyDatabseUseCustomCheckBox->isChecked();
- else {
- general["use_custom_key_database_path"] =
- ui_->keyDatabseUseCustomCheckBox->isChecked();
- }
-
- if (!general.exists("use_custom_gnupg_install_path"))
- general.add("use_custom_gnupg_install_path",
- libconfig::Setting::TypeBoolean) =
- ui_->useCustomGnuPGInstallPathCheckBox->isChecked();
- else {
- general["use_custom_gnupg_install_path"] =
- ui_->useCustomGnuPGInstallPathCheckBox->isChecked();
- }
-
- if (!general.exists("use_pinentry_as_password_input_dialog"))
- general.add("use_pinentry_as_password_input_dialog",
- libconfig::Setting::TypeBoolean) =
- ui_->usePinentryAsPasswordInputDialogCheckBox->isChecked();
- else {
- general["use_pinentry_as_password_input_dialog"] =
- ui_->usePinentryAsPasswordInputDialogCheckBox->isChecked();
- }
+ auto settings =
+ GpgFrontend::GlobalSettingStation::GetInstance().GetSettings();
+
+ settings.setValue("basic/non_ascii_when_export",
+ ui_->asciiModeCheckBox->isChecked());
+ settings.setValue("basic/use_custom_key_database_path",
+ ui_->keyDatabseUseCustomCheckBox->isChecked());
+ settings.setValue("basic/use_custom_gnupg_install_path",
+ ui_->useCustomGnuPGInstallPathCheckBox->isChecked());
+ settings.setValue("basic/use_pinentry_as_password_input_dialog",
+ ui_->usePinentryAsPasswordInputDialogCheckBox->isChecked());
}
int GnuPGControllerDialog::get_restart_needed() const {
@@ -370,60 +326,56 @@ void GnuPGControllerDialog::slot_set_restart_needed(int mode) {
this->restart_needed_ = mode;
}
-bool GnuPGControllerDialog::check_custom_gnupg_path(std::string path) {
- QString path_qstr = QString::fromStdString(path);
-
- if (path_qstr.isEmpty()) {
- QMessageBox::critical(this, _("Illegal GnuPG Path"),
- _("Target GnuPG Path is empty."));
+bool GnuPGControllerDialog::check_custom_gnupg_path(QString path) {
+ if (path.isEmpty()) {
+ QMessageBox::critical(this, tr("Illegal GnuPG Path"),
+ tr("Target GnuPG Path is empty."));
return false;
}
- QFileInfo dir_info(path_qstr);
+ QFileInfo dir_info(path);
if (!dir_info.exists() || !dir_info.isReadable() || !dir_info.isDir()) {
QMessageBox::critical(
- this, _("Illegal GnuPG Path"),
- _("Target GnuPG Path is not an exists readable directory."));
+ this, tr("Illegal GnuPG Path"),
+ tr("Target GnuPG Path is not an exists readable directory."));
return false;
}
- QDir dir(path_qstr);
+ QDir dir(path);
if (!dir.isAbsolute()) {
- QMessageBox::critical(this, _("Illegal GnuPG Path"),
- _("Target GnuPG Path is not an absolute path."));
+ QMessageBox::critical(this, tr("Illegal GnuPG Path"),
+ tr("Target GnuPG Path is not an absolute path."));
}
#ifdef WINDOWS
- QFileInfo gpgconf_info(path_qstr + "/gpgconf.exe");
+ QFileInfo gpgconf_info(path + "/gpgconf.exe");
#else
- QFileInfo gpgconf_info(path_qstr + "/gpgconf");
+ QFileInfo gpgconf_info(path + "/gpgconf");
#endif
if (!gpgconf_info.exists() || !gpgconf_info.isExecutable() ||
!gpgconf_info.isFile()) {
QMessageBox::critical(
- this, _("Illegal GnuPG Path"),
- _("Target GnuPG Path contains no \"gpgconf\" executable."));
+ this, tr("Illegal GnuPG Path"),
+ tr("Target GnuPG Path contains no \"gpgconf\" executable."));
return false;
}
return true;
}
-bool GnuPGControllerDialog::check_custom_gnupg_key_database_path(
- std::string path) {
- QString selected_custom_key_database_path = QString::fromStdString(path);
-
- if (selected_custom_key_database_path.isEmpty()) {
- QMessageBox::critical(this, _("Illegal GnuPG Key Database Path"),
- _("Target GnuPG Key Database Path is empty."));
+auto GnuPGControllerDialog::check_custom_gnupg_key_database_path(QString path)
+ -> bool {
+ if (path.isEmpty()) {
+ QMessageBox::critical(this, tr("Illegal GnuPG Key Database Path"),
+ tr("Target GnuPG Key Database Path is empty."));
return false;
}
- QFileInfo dir_info(selected_custom_key_database_path);
+ QFileInfo dir_info(path);
if (!dir_info.exists() || !dir_info.isReadable() || !dir_info.isDir()) {
- QMessageBox::critical(this, _("Illegal GnuPG Key Database Path"),
- _("Target GnuPG Key Database Path is not an "
- "exists readable directory."));
+ QMessageBox::critical(this, tr("Illegal GnuPG Key Database Path"),
+ tr("Target GnuPG Key Database Path is not an "
+ "exists readable directory."));
return false;
}
diff --git a/src/ui/dialog/gnupg/GnuPGControllerDialog.h b/src/ui/dialog/gnupg/GnuPGControllerDialog.h
index 9d53cf46..201801dc 100644
--- a/src/ui/dialog/gnupg/GnuPGControllerDialog.h
+++ b/src/ui/dialog/gnupg/GnuPGControllerDialog.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,17 +20,14 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GNUPGCONTROLLERDIALOGLOG_H
-#define GPGFRONTEND_GNUPGCONTROLLERDIALOGLOG_H
+#pragma once
-#include <string>
-#include "ui/GpgFrontendUI.h"
#include "ui/dialog/GeneralDialog.h"
class Ui_GnuPGControllerDialog;
@@ -94,16 +91,34 @@ class GnuPGControllerDialog : public GeneralDialog {
* @return true
* @return false
*/
- int get_restart_needed() const;
+ [[nodiscard]] auto get_restart_needed() const -> int;
+ /**
+ * @brief Set the settings object
+ *
+ */
void set_settings();
+ /**
+ * @brief
+ *
+ */
void apply_settings();
- bool check_custom_gnupg_path(std::string);
+ /**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+ auto check_custom_gnupg_path(QString) -> bool;
- bool check_custom_gnupg_key_database_path(std::string);
+ /**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+ auto check_custom_gnupg_key_database_path(QString) -> bool;
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_GNUPGCONTROLLERDIALOGLOG_H
diff --git a/src/ui/dialog/help/AboutDialog.cpp b/src/ui/dialog/help/AboutDialog.cpp
index 111a77af..e4a189a3 100644
--- a/src/ui/dialog/help/AboutDialog.cpp
+++ b/src/ui/dialog/help/AboutDialog.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -30,17 +30,18 @@
#include <openssl/opensslv.h>
+#include <any>
+
#include "GpgFrontendBuildInfo.h"
#include "core/function/GlobalSettingStation.h"
-#include "core/thread/TaskRunnerGetter.h"
+#include "core/module/ModuleManager.h"
#include "ui/dialog/help/GnupgTab.h"
-#include "ui/thread/VersionCheckTask.h"
namespace GpgFrontend::UI {
AboutDialog::AboutDialog(int defaultIndex, QWidget* parent)
: GeneralDialog(typeid(AboutDialog).name(), parent) {
- this->setWindowTitle(QString(_("About")) + " " + qApp->applicationName());
+ this->setWindowTitle(tr("About") + " " + qApp->applicationName());
auto* tab_widget = new QTabWidget;
auto* info_tab = new InfoTab();
@@ -48,70 +49,68 @@ AboutDialog::AboutDialog(int defaultIndex, QWidget* parent)
auto* translators_tab = new TranslatorsTab();
update_tab_ = new UpdateTab();
- tab_widget->addTab(info_tab, _("About GpgFrontend"));
- tab_widget->addTab(gnupg_tab, _("GnuPG"));
- tab_widget->addTab(translators_tab, _("Translators"));
- tab_widget->addTab(update_tab_, _("Update"));
+ tab_widget->addTab(info_tab, tr("About GpgFrontend"));
+ tab_widget->addTab(gnupg_tab, tr("GnuPG"));
+ tab_widget->addTab(translators_tab, tr("Translators"));
+ tab_widget->addTab(update_tab_, tr("Update"));
connect(tab_widget, &QTabWidget::currentChanged, this,
- [&](int index) { SPDLOG_DEBUG("current index: {}", index); });
+ [&](int index) { GF_UI_LOG_DEBUG("current index: {}", index); });
if (defaultIndex < tab_widget->count() && defaultIndex >= 0) {
tab_widget->setCurrentIndex(defaultIndex);
}
- auto* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok);
- connect(buttonBox, &QDialogButtonBox::accepted, this, &AboutDialog::close);
+ auto* button_box = new QDialogButtonBox(QDialogButtonBox::Ok);
+ connect(button_box, &QDialogButtonBox::accepted, this, &AboutDialog::close);
- auto* mainLayout = new QVBoxLayout;
- mainLayout->addWidget(tab_widget);
- mainLayout->addWidget(buttonBox);
- setLayout(mainLayout);
+ auto* main_layout = new QVBoxLayout;
+ main_layout->addWidget(tab_widget);
+ main_layout->addWidget(button_box);
+ setLayout(main_layout);
this->resize(550, 650);
this->setMinimumWidth(450);
this->show();
}
-void AboutDialog::showEvent(QShowEvent* ev) {
- QDialog::showEvent(ev);
- update_tab_->getLatestVersion();
-}
+void AboutDialog::showEvent(QShowEvent* ev) { QDialog::showEvent(ev); }
InfoTab::InfoTab(QWidget* parent) : QWidget(parent) {
- auto* pixmap = new QPixmap(":gpgfrontend-logo.png");
+ const auto gpgme_version = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.version", QString{"2.0.0"});
+ GF_UI_LOG_DEBUG("got gpgme version from rt: {}", gpgme_version);
+
+ auto* pixmap = new QPixmap(":/icons/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, "
- "and installation-free GnuPG Frontend."
- "It visualizes most of the common operations of GnuPG."
- "GpgFrontend is licensed under the GPLv3") +
+ tr("GpgFrontend is an easy-to-use, compact, cross-platform, "
+ "and installation-free GnuPG Frontend."
+ "It visualizes most of the common operations of GnuPG."
+ "GpgFrontend is licensed under the GPLv3") +
"<br><br>"
"<b>" +
- _("Developer:") + "</b><br>" + "Saturneric" + "<br><br>" +
- _("If you have any questions or suggestions, raise an issue at") +
+ tr("Developer:") + "</b><br>" + "Saturneric" + "<br><br>" +
+ tr("If you have any questions or suggestions, raise an issue at") +
"<br/>"
" <a href=\"https://github.com/saturneric/GpgFrontend\">GitHub</a> " +
- _("or send a mail to my mailing list at") + " <a " +
+ tr("or send a mail to my mailing list at") + " <a " +
"href=\"mailto:[email protected]\">[email protected]</a>." + "<br><br> " +
- _("Built with Qt") + " " + qVersion() + ", " + OPENSSL_VERSION_TEXT +
- " " + _("and") + " " + "GPGME" + " " +
- GpgFrontend::GpgContext::GetInstance()
- .GetInfo(false)
- .GpgMEVersion.c_str() +
- "<br>" + _("Built at") + " " + BUILD_TIMESTAMP + "</center>");
+ tr("Built with Qt") + " " + qVersion() + ", " + OPENSSL_VERSION_TEXT +
+ " " + tr("and") + " " + "GPGME" + " " + gpgme_version + "<br>" +
+ tr("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->setWordWrap(true);
- aboutLabel->setOpenExternalLinks(true);
- layout->addWidget(aboutLabel, 1, 0, 1, -1);
+ auto* pixmap_label = new QLabel();
+ pixmap_label->setPixmap(*pixmap);
+ layout->addWidget(pixmap_label, 0, 0, 1, -1, Qt::AlignCenter);
+ auto* about_label = new QLabel();
+ about_label->setText(*text);
+ about_label->setWordWrap(true);
+ about_label->setOpenExternalLinks(true);
+ layout->addWidget(about_label, 1, 0, 1, -1);
layout->addItem(
new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Fixed), 2, 1,
1, 1);
@@ -120,30 +119,18 @@ InfoTab::InfoTab(QWidget* parent) : QWidget(parent) {
}
TranslatorsTab::TranslatorsTab(QWidget* parent) : QWidget(parent) {
- QFile translators_qfile;
- auto translators_file =
- GlobalSettingStation::GetInstance().GetResourceDir() / "TRANSLATORS";
- translators_qfile.setFileName(translators_file.u8string().c_str());
-#ifdef LINUX
- if (!translators_qfile.exists()) {
- translators_qfile.setFileName("/usr/local/share/GpgFrontend/TRANSLATORS");
- }
-#endif
-
- translators_qfile.open(QIODevice::ReadOnly);
- QByteArray in_buffer = translators_qfile.readAll();
-
- auto* label = new QLabel(in_buffer);
+ QFile translators_file(":/TRANSLATORS");
+ translators_file.open(QIODevice::ReadOnly);
+ auto* label = new QLabel(translators_file.readAll());
auto* main_layout = new QVBoxLayout(this);
main_layout->addWidget(label);
main_layout->addStretch();
- auto notice_label = new QLabel(
- _("If you think there are any problems with the translation, why not "
- "participate in the translation work? If you want to participate, "
- "please "
- "read the document or contact me via email."),
+ auto* notice_label = new QLabel(
+ tr("If you think there are any problems with the translation, why not "
+ "participate in the translation work? If you want to participate, "
+ "please read the document or contact me via email."),
this);
notice_label->setWordWrap(true);
main_layout->addWidget(notice_label);
@@ -152,30 +139,29 @@ TranslatorsTab::TranslatorsTab(QWidget* parent) : QWidget(parent) {
}
UpdateTab::UpdateTab(QWidget* parent) : QWidget(parent) {
- auto* pixmap = new QPixmap(":gpgfrontend-logo.png");
+ auto* pixmap = new QPixmap(":/icons/gpgfrontend-logo.png");
auto* layout = new QGridLayout();
auto* pixmap_label = new QLabel();
pixmap_label->setPixmap(*pixmap);
layout->addWidget(pixmap_label, 0, 0, 1, -1, Qt::AlignCenter);
- current_version_ = "v" + QString::number(VERSION_MAJOR) + "." +
- QString::number(VERSION_MINOR) + "." +
- QString::number(VERSION_PATCH);
+ current_version_ =
+ QString("v") + VERSION_MAJOR + "." + VERSION_MINOR + "." + VERSION_PATCH;
- auto tips_label = new QLabel();
+ auto* tips_label = new QLabel();
tips_label->setText(
"<center>" +
- QString(_("It is recommended that you always check the version "
- "of GpgFrontend and upgrade to the latest version.")) +
+ tr("It is recommended that you always check the version "
+ "of GpgFrontend and upgrade to the latest version.") +
"</center><center>" +
- _("New versions not only represent new features, but "
- "also often represent functional and security fixes.") +
+ tr("New versions not only represent new features, but "
+ "also often represent functional and security fixes.") +
"</center>");
tips_label->setWordWrap(true);
current_version_label_ = new QLabel();
- current_version_label_->setText("<center>" + QString(_("Current Version")) +
- _(": ") + "<b>" + current_version_ +
+ current_version_label_->setText("<center>" + tr("Current Version") +
+ tr(": ") + "<b>" + current_version_ +
"</b></center>");
current_version_label_->setWordWrap(true);
@@ -203,59 +189,95 @@ UpdateTab::UpdateTab(QWidget* parent) : QWidget(parent) {
setLayout(layout);
}
-void UpdateTab::getLatestVersion() {
- this->pb_->setHidden(false);
+void UpdateTab::showEvent(QShowEvent* event) {
+ QWidget::showEvent(event);
+ GF_UI_LOG_DEBUG("loading version loading info from rt");
+
+ auto is_loading_done = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.version-checking",
+ "version.loading_done", false);
+
+ if (!is_loading_done) {
+ Module::ListenRTPublishEvent(
+ this, "com.bktus.gpgfrontend.module.integrated.version-checking",
+ "version.loading_done",
+ [=](Module::Namespace, Module::Key, int, std::any) {
+ GF_UI_LOG_DEBUG(
+ "versionchecking version.loading_done changed, calling slot "
+ "version upgrade");
+ this->slot_show_version_status();
+ });
+ Module::TriggerEvent("CHECK_APPLICATION_VERSION");
+ } else {
+ slot_show_version_status();
+ }
+}
- SPDLOG_DEBUG("try to get latest version");
+void UpdateTab::slot_show_version_status() {
+ GF_UI_LOG_DEBUG("loading version info from rt");
+ this->pb_->setHidden(true);
- auto* version_task = new VersionCheckTask();
+ auto is_loading_done = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.version-checking",
+ "version.loading_done", false);
- connect(version_task, &VersionCheckTask::SignalUpgradeVersion, this,
- &UpdateTab::slot_show_version_status);
+ if (!is_loading_done) {
+ GF_UI_LOG_DEBUG("version info loading havn't been done yet.");
+ return;
+ }
- Thread::TaskRunnerGetter::GetInstance()
- .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Network)
- ->PostTask(version_task);
-}
+ auto is_need_upgrade = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.version-checking",
+ "version.need_upgrade", false);
-void UpdateTab::slot_show_version_status(const SoftwareVersion& version) {
- this->pb_->setHidden(true);
- latest_version_label_->setText(
- "<center><b>" + QString(_("Latest Version From Github")) + ": " +
- version.latest_version.c_str() + "</b></center>");
+ auto is_current_a_withdrawn_version = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.version-checking",
+ "version.current_a_withdrawn_version", false);
+
+ auto is_current_version_released = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.version-checking",
+ "version.current_version_released", false);
+
+ auto latest_version = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.version-checking",
+ "version.latest_version", QString{});
+
+ latest_version_label_->setText("<center><b>" +
+ tr("Latest Version From Github") + ": " +
+ latest_version + "</b></center>");
- if (version.NeedUpgrade()) {
+ if (is_need_upgrade) {
upgrade_label_->setText(
"<center>" +
- QString(_("The current version is less than the latest version on "
- "github.")) +
- "</center><center>" + _("Please click") +
+ tr("The current version is less than the latest version on "
+ "github.") +
+ "</center><center>" + tr("Please click") +
" <a "
"href=\"https://www.gpgfrontend.bktus.com/#/downloads\">" +
- _("Here") + "</a> " + _("to download the latest stable version.") +
+ tr("Here") + "</a> " + tr("to download the latest stable version.") +
"</center>");
upgrade_label_->show();
- } else if (version.VersionWithDrawn()) {
+ } else if (is_current_a_withdrawn_version) {
upgrade_label_->setText(
"<center>" +
- QString(_("This version has serious problems and has been withdrawn. "
- "Please stop using it immediately.")) +
- "</center><center>" + _("Please click") +
+ tr("This version has serious problems and has been withdrawn. "
+ "Please stop using it immediately.") +
+ "</center><center>" + tr("Please click") +
" <a "
"href=\"https://github.com/saturneric/GpgFrontend/releases\">" +
- _("Here") + "</a> " + _("to download the latest stable version.") +
+ tr("Here") + "</a> " + tr("to download the latest stable version.") +
"</center>");
upgrade_label_->show();
- } else if (!version.CurrentVersionReleased()) {
+ } else if (!is_current_version_released) {
upgrade_label_->setText(
"<center>" +
- QString(_("This version has not been released yet, it may be a beta "
- "version. If you are not a tester and care about version "
- "stability, please do not use this version.")) +
- "</center><center>" + _("Please click") +
+ tr("This version has not been released yet, it may be a beta "
+ "version. If you are not a tester and care about version "
+ "stability, please do not use this version.") +
+ "</center><center>" + tr("Please click") +
" <a "
"href=\"https://www.gpgfrontend.bktus.com/#/downloads\">" +
- _("Here") + "</a> " + _("to download the latest stable version.") +
+ tr("Here") + "</a> " + tr("to download the latest stable version.") +
"</center>");
upgrade_label_->show();
}
diff --git a/src/ui/dialog/help/AboutDialog.h b/src/ui/dialog/help/AboutDialog.h
index 6d7ce265..b7871a29 100644
--- a/src/ui/dialog/help/AboutDialog.h
+++ b/src/ui/dialog/help/AboutDialog.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,19 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef __ABOUTDIALOG_H__
-#define __ABOUTDIALOG_H__
+#pragma once
-#include "core/GpgContext.h"
#include "ui/GpgFrontendUI.h"
#include "ui/dialog/GeneralDialog.h"
-#include "ui/struct/SoftwareVersion.h"
namespace GpgFrontend::UI {
@@ -89,11 +86,8 @@ class UpdateTab : public QWidget {
*/
explicit UpdateTab(QWidget* parent = nullptr);
- /**
- * @brief Get the Latest Version object
- *
- */
- void getLatestVersion();
+ protected:
+ void showEvent(QShowEvent* event) override;
private slots:
/**
@@ -101,7 +95,7 @@ class UpdateTab : public QWidget {
*
* @param version
*/
- void slot_show_version_status(const SoftwareVersion& version);
+ void slot_show_version_status();
signals:
/**
@@ -141,5 +135,3 @@ class AboutDialog : public GeneralDialog {
};
} // namespace GpgFrontend::UI
-
-#endif // __ABOUTDIALOG_H__
diff --git a/src/ui/dialog/help/GnupgTab.cpp b/src/ui/dialog/help/GnupgTab.cpp
index 996d4ad9..28f1acfe 100644
--- a/src/ui/dialog/help/GnupgTab.cpp
+++ b/src/ui/dialog/help/GnupgTab.cpp
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2022. Saturneric
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
- * This file is part of GpgFrontend.
+ * 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
@@ -20,9 +20,10 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
+ *
*/
//
@@ -31,21 +32,20 @@
#include "GnupgTab.h"
-#include <shared_mutex>
-
-#include "ui/UserInterfaceUtils.h"
+#include "core/module/ModuleManager.h"
#include "ui_GnuPGInfo.h"
GpgFrontend::UI::GnupgTab::GnupgTab(QWidget* parent)
- : QWidget(parent), ui_(std::make_shared<Ui_GnuPGInfo>()) {
+ : QWidget(parent),
+ ui_(GpgFrontend::SecureCreateSharedObject<Ui_GnuPGInfo>()) {
ui_->setupUi(this);
QStringList components_column_titles;
- components_column_titles << _("Name") << _("Description") << _("Version")
- << _("Checksum") << _("Binary Path");
+ components_column_titles << tr("Name") << tr("Description") << tr("Version")
+ << tr("Checksum") << tr("Binary Path");
- ui_->tabWidget->setTabText(0, _("Components"));
- ui_->tabWidget->setTabText(1, _("Configurations"));
+ ui_->tabWidget->setTabText(0, tr("Components"));
+ ui_->tabWidget->setTabText(1, tr("Configurations"));
ui_->componentDetailsTable->setColumnCount(components_column_titles.length());
ui_->componentDetailsTable->setHorizontalHeaderLabels(
@@ -55,7 +55,9 @@ GpgFrontend::UI::GnupgTab::GnupgTab(QWidget* parent)
QAbstractItemView::SelectRows);
QStringList configurations_column_titles;
- configurations_column_titles << _("Key") << _("Value");
+ configurations_column_titles << tr("Component") << tr("Group") << tr("Key")
+ << tr("Description") << tr("Default Value")
+ << tr("Value");
ui_->configurationDetailsTable->setColumnCount(
configurations_column_titles.length());
@@ -79,34 +81,61 @@ GpgFrontend::UI::GnupgTab::GnupgTab(QWidget* parent)
}
void GpgFrontend::UI::GnupgTab::process_software_info() {
- auto& ctx_info = GpgContext::GetInstance().GetInfo();
+ const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gnupg_version", QString{"2.0.0"});
+ GF_UI_LOG_DEBUG("got gnupg version from rt: {}", gnupg_version);
- ui_->gnupgVersionLabel->setText(QString::fromStdString(
- fmt::format("Version: {}", ctx_info.GnupgVersion)));
+ ui_->gnupgVersionLabel->setText(
+ QString::fromStdString(fmt::format("Version: {}", gnupg_version)));
- ui_->componentDetailsTable->setRowCount(ctx_info.ComponentsInfo.size());
+ auto components = Module::ListRTChildKeys(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ "gnupg.components");
+ GF_UI_LOG_DEBUG("got gnupg components from rt, size: {}", components.size());
- int row = 0;
- for (const auto& info : ctx_info.ComponentsInfo) {
- if (info.second.size() != 4) continue;
+ ui_->componentDetailsTable->setRowCount(components.size());
- auto* tmp0 = new QTableWidgetItem(QString::fromStdString(info.first));
+ int row = 0;
+ for (auto& component : components) {
+ auto component_info_json_bytes = Module::RetrieveRTValueTypedOrDefault(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ QString("gnupg.components.%1").arg(component), QByteArray{});
+ GF_UI_LOG_DEBUG("got gnupg component {} info from rt", component);
+
+ auto component_info_json =
+ QJsonDocument::fromJson(component_info_json_bytes);
+ if (!component_info_json.isObject()) {
+ GF_UI_LOG_WARN("illegal gnupg component info, json: {}",
+ QString(component_info_json_bytes));
+ continue;
+ }
+
+ auto component_info = component_info_json.object();
+ if (!component_info.contains("name")) {
+ GF_UI_LOG_WARN(
+ "illegal gnupg component info. it doesn't have a name, json: {}",
+ QString(component_info_json_bytes));
+ continue;
+ }
+
+ auto* tmp0 = new QTableWidgetItem(component_info["name"].toString());
tmp0->setTextAlignment(Qt::AlignCenter);
ui_->componentDetailsTable->setItem(row, 0, tmp0);
- auto* tmp1 = new QTableWidgetItem(QString::fromStdString(info.second[0]));
+ auto* tmp1 = new QTableWidgetItem(component_info["desc"].toString());
tmp1->setTextAlignment(Qt::AlignCenter);
ui_->componentDetailsTable->setItem(row, 1, tmp1);
- auto* tmp2 = new QTableWidgetItem(QString::fromStdString(info.second[1]));
+ auto* tmp2 = new QTableWidgetItem(component_info["version"].toString());
tmp2->setTextAlignment(Qt::AlignCenter);
ui_->componentDetailsTable->setItem(row, 2, tmp2);
- auto* tmp3 = new QTableWidgetItem(QString::fromStdString(info.second[3]));
+ auto* tmp3 =
+ new QTableWidgetItem(component_info["binary_checksum"].toString());
tmp3->setTextAlignment(Qt::AlignCenter);
ui_->componentDetailsTable->setItem(row, 3, tmp3);
- auto* tmp4 = new QTableWidgetItem(QString::fromStdString(info.second[2]));
+ auto* tmp4 = new QTableWidgetItem(component_info["path"].toString());
tmp4->setTextAlignment(Qt::AlignLeft);
ui_->componentDetailsTable->setItem(row, 4, tmp4);
@@ -115,23 +144,96 @@ void GpgFrontend::UI::GnupgTab::process_software_info() {
ui_->componentDetailsTable->resizeColumnsToContents();
- ui_->configurationDetailsTable->setRowCount(
- ctx_info.ConfigurationsInfo.size());
-
+ // calcualte the total row number of configuration table
row = 0;
- for (const auto& info : ctx_info.ConfigurationsInfo) {
- if (info.second.size() != 1) continue;
-
- auto* tmp0 = new QTableWidgetItem(QString::fromStdString(info.first));
- tmp0->setTextAlignment(Qt::AlignCenter);
- ui_->configurationDetailsTable->setItem(row, 0, tmp0);
-
- auto* tmp1 = new QTableWidgetItem(QString::fromStdString(info.second[0]));
- tmp1->setTextAlignment(Qt::AlignCenter);
- ui_->configurationDetailsTable->setItem(row, 1, tmp1);
-
- row++;
+ for (auto& component : components) {
+ auto options = Module::ListRTChildKeys(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ QString("gnupg.components.%1.options").arg(component));
+ for (auto& option : options) {
+ const auto option_info_json =
+ QJsonDocument::fromJson(Module::RetrieveRTValueTypedOrDefault(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ QString("gnupg.components.%1.options.%2")
+ .arg(component)
+ .arg(option),
+ QByteArray{}));
+
+ if (!option_info_json.isObject()) continue;
+
+ auto option_info = option_info_json.object();
+ if (!option_info.contains("name") || option_info["flags"] == "1") {
+ continue;
+ }
+ row++;
+ }
}
+ ui_->configurationDetailsTable->setRowCount(row);
- ui_->configurationDetailsTable->resizeColumnsToContents();
+ row = 0;
+ QString configuration_group;
+ for (auto& component : components) {
+ auto options = Module::ListRTChildKeys(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ QString("gnupg.components.%1.options").arg(component));
+
+ for (auto& option : options) {
+ auto option_info_json_bytes = Module::RetrieveRTValueTypedOrDefault(
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering",
+ QString("gnupg.components.%1.options.%2").arg(component).arg(option),
+ QByteArray{});
+ GF_UI_LOG_DEBUG("got gnupg component's option {} info from rt, info: {}",
+ component, option_info_json_bytes);
+
+ auto option_info_json = QJsonDocument::fromJson(option_info_json_bytes);
+
+ if (!option_info_json.isObject()) {
+ GF_UI_LOG_WARN("illegal gnupg option info, json: {}",
+ QString(option_info_json_bytes));
+ continue;
+ }
+
+ auto option_info = option_info_json.object();
+ if (!option_info.contains("name")) {
+ GF_UI_LOG_WARN(
+ "illegal gnupg configuation info. it doesn't have a name, json: {}",
+ QString(option_info_json_bytes));
+ continue;
+ }
+
+ if (option_info["flags"] == "1") {
+ configuration_group = option_info["name"].toString();
+ continue;
+ }
+
+ auto* tmp0 = new QTableWidgetItem(component);
+ tmp0->setTextAlignment(Qt::AlignCenter);
+ ui_->configurationDetailsTable->setItem(row, 0, tmp0);
+
+ auto* tmp1 = new QTableWidgetItem(configuration_group);
+ tmp1->setTextAlignment(Qt::AlignCenter);
+ ui_->configurationDetailsTable->setItem(row, 1, tmp1);
+
+ auto* tmp2 = new QTableWidgetItem(option_info["name"].toString());
+ tmp2->setTextAlignment(Qt::AlignCenter);
+ ui_->configurationDetailsTable->setItem(row, 2, tmp2);
+
+ auto* tmp3 = new QTableWidgetItem(option_info["description"].toString());
+
+ tmp3->setTextAlignment(Qt::AlignLeft);
+ ui_->configurationDetailsTable->setItem(row, 3, tmp3);
+
+ auto* tmp4 =
+ new QTableWidgetItem(option_info["default_value"].toString());
+ tmp4->setTextAlignment(Qt::AlignLeft);
+ ui_->configurationDetailsTable->setItem(row, 4, tmp4);
+
+ auto* tmp5 = new QTableWidgetItem(option_info["value"].toString());
+ tmp5->setTextAlignment(Qt::AlignLeft);
+ ui_->configurationDetailsTable->setItem(row, 5, tmp5);
+
+ row++;
+ }
+ }
+ // ui_->configurationDetailsTable->resizeColumnsToContents();
}
diff --git a/src/ui/dialog/help/GnupgTab.h b/src/ui/dialog/help/GnupgTab.h
index 9195dee0..9e6191db 100644
--- a/src/ui/dialog/help/GnupgTab.h
+++ b/src/ui/dialog/help/GnupgTab.h
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2022. Saturneric
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
- * This file is part of GpgFrontend.
+ * 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
@@ -20,19 +20,19 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
+ *
*/
//
// Created by eric on 2022/7/23.
//
-#ifndef GPGFRONTEND_GNUPGTAB_H
-#define GPGFRONTEND_GNUPGTAB_H
+#pragma once
-#include "core/GpgContext.h"
+#include "core/function/gpg/GpgContext.h"
#include "ui/GpgFrontendUI.h"
class Ui_GnuPGInfo;
@@ -53,5 +53,3 @@ class GnupgTab : public QWidget {
void process_software_info();
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_GNUPGTAB_H
diff --git a/src/ui/dialog/import_export/ExportKeyPackageDialog.cpp b/src/ui/dialog/import_export/ExportKeyPackageDialog.cpp
index b58d09c1..7c740063 100644
--- a/src/ui/dialog/import_export/ExportKeyPackageDialog.cpp
+++ b/src/ui/dialog/import_export/ExportKeyPackageDialog.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,31 +28,30 @@
#include "ExportKeyPackageDialog.h"
-#include <boost/format.hpp>
-
+#include "core/GpgModel.h"
#include "core/function/KeyPackageOperator.h"
#include "core/function/gpg/GpgKeyGetter.h"
+#include "ui/UserInterfaceUtils.h"
#include "ui_ExportKeyPackageDialog.h"
GpgFrontend::UI::ExportKeyPackageDialog::ExportKeyPackageDialog(
KeyIdArgsListPtr key_ids, QWidget* parent)
: GeneralDialog(typeid(ExportKeyPackageDialog).name(), parent),
- ui_(std::make_shared<Ui_exportKeyPackageDialog>()),
+ ui_(GpgFrontend::SecureCreateSharedObject<Ui_exportKeyPackageDialog>()),
key_ids_(std::move(key_ids)) {
ui_->setupUi(this);
- ui_->nameValueLabel->setText(
- KeyPackageOperator::GenerateKeyPackageName().c_str());
+ ui_->nameValueLabel->setText(KeyPackageOperator::GenerateKeyPackageName());
connect(ui_->gnerateNameButton, &QPushButton::clicked, this, [=]() {
- ui_->nameValueLabel->setText(
- KeyPackageOperator::GenerateKeyPackageName().c_str());
+ ui_->nameValueLabel->setText(KeyPackageOperator::GenerateKeyPackageName());
});
connect(ui_->setOutputPathButton, &QPushButton::clicked, this, [=]() {
auto file_name = QFileDialog::getSaveFileName(
- this, _("Export Key Package"), ui_->nameValueLabel->text() + ".gfepack",
- QString(_("Key Package")) + " (*.gfepack);;All Files (*)");
+ this, tr("Export Key Package"),
+ ui_->nameValueLabel->text() + ".gfepack",
+ tr("Key Package") + " (*.gfepack);;All Files (*)");
// check path
if (file_name.isEmpty()) return;
@@ -62,18 +61,17 @@ GpgFrontend::UI::ExportKeyPackageDialog::ExportKeyPackageDialog(
connect(ui_->generatePassphraseButton, &QPushButton::clicked, this, [=]() {
auto file_name = QFileDialog::getSaveFileName(
- this, _("Export Key Package Passphrase"),
+ this, tr("Export Key Package Passphrase"),
ui_->nameValueLabel->text() + ".key",
- QString(_("Key File")) + " (*.key);;All Files (*)");
+ tr("Key File") + " (*.key);;All Files (*)");
// check path
if (file_name.isEmpty()) return;
- if (!KeyPackageOperator::GeneratePassphrase(file_name.toStdString(),
- passphrase_)) {
+ if (!KeyPackageOperator::GeneratePassphrase(file_name, passphrase_)) {
QMessageBox::critical(
- this, _("Error"),
- _("An error occurred while generating the passphrase file."));
+ this, tr("Error"),
+ tr("An error occurred while generating the passphrase file."));
return;
}
ui_->passphraseValueLabel->setText(file_name);
@@ -82,71 +80,87 @@ GpgFrontend::UI::ExportKeyPackageDialog::ExportKeyPackageDialog(
connect(ui_->button_box_, &QDialogButtonBox::accepted, this, [=]() {
if (ui_->outputPathLabel->text().isEmpty()) {
QMessageBox::critical(
- this, _("Forbidden"),
- _("Please select an output path before exporting."));
+ this, tr("Forbidden"),
+ tr("Please select an output path before exporting."));
return;
}
if (ui_->passphraseValueLabel->text().isEmpty()) {
QMessageBox::critical(
- this, _("Forbidden"),
- _("Please generate a password to protect your key before exporting, "
- "it is very important. Don't forget to back up your password in a "
- "safe place."));
+ this, tr("Forbidden"),
+ tr("Please generate a password to protect your key before exporting, "
+ "it is very important. Don't forget to back up your password in a "
+ "safe place."));
return;
}
// get suitable key ids
- auto key_id_exported = std::make_unique<KeyIdArgsList>();
auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids_);
- for (const auto& key : *keys) {
- if (ui_->noPublicKeyCheckBox->isChecked() && !key.IsPrivateKey())
- continue;
- key_id_exported->push_back(key.GetId());
+ auto keys_new_end =
+ std::remove_if(keys->begin(), keys->end(), [this](const auto& key) {
+ return ui_->noPublicKeyCheckBox->isChecked() && !key.IsPrivateKey();
+ });
+ keys->erase(keys_new_end, keys->end());
+
+ if (keys->empty()) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("No key is suitable to export."));
+ return;
}
- if (KeyPackageOperator::GenerateKeyPackage(
- ui_->outputPathLabel->text().toStdString(),
- ui_->nameValueLabel->text().toStdString(), key_id_exported,
- passphrase_, ui_->includeSecretKeyCheckBox->isChecked())) {
- QMessageBox::information(
- this, _("Success"),
- QString(
- _("The Key Package has been successfully generated and has been "
- "protected by encryption algorithms(AES-256-ECB). You can "
- "safely transfer your Key Package.")) +
- "<br /><br />" + "<b>" +
- _("But the key file cannot be leaked under any "
- "circumstances. Please delete the Key Package and key file as "
- "soon "
- "as possible after completing the transfer operation.") +
- "</b>");
- accept();
- } else {
- QMessageBox::critical(
- this, _("Error"),
- _("An error occurred while exporting the key package."));
- }
+ CommonUtils::WaitForOpera(
+ this, tr("Generating"), [this, keys](const OperaWaitingHd& op_hd) {
+ KeyPackageOperator::GenerateKeyPackage(
+ ui_->outputPathLabel->text(), ui_->nameValueLabel->text(), *keys,
+ passphrase_, ui_->includeSecretKeyCheckBox->isChecked(),
+ [=](GFError err, const DataObjectPtr&) {
+ // stop waiting
+ op_hd();
+
+ if (err >= 0) {
+ QMessageBox::information(
+ this, tr("Success"),
+ QString(
+ tr("The Key Package has been successfully generated "
+ "and has been protected by encryption "
+ "algorithms(AES-256-ECB). You can safely transfer "
+ "your Key Package.")) +
+ "<br /><br />" + "<b>" +
+ tr("But the key file cannot be leaked under any "
+ "circumstances. Please delete the Key Package and "
+ "key file as soon as possible after completing "
+ "the "
+ "transfer "
+ "operation.") +
+ "</b>");
+ accept();
+ } else {
+ QMessageBox::critical(
+ this, tr("Error"),
+ tr("An error occurred while exporting the key package."));
+ }
+ });
+ });
});
connect(ui_->button_box_, &QDialogButtonBox::rejected, this,
[=]() { this->close(); });
- ui_->nameLabel->setText(_("Key Package Name"));
- ui_->selectOutputPathLabel->setText(_("Output Path"));
- ui_->passphraseLabel->setText(_("Passphrase"));
+ ui_->nameLabel->setText(tr("Key Package Name"));
+ ui_->selectOutputPathLabel->setText(tr("Output Path"));
+ ui_->passphraseLabel->setText(tr("Passphrase"));
ui_->tipsLabel->setText(
- _("Tips: You can use Key Package to safely and conveniently transfer "
- "your public and private keys between devices."));
- ui_->generatePassphraseButton->setText(_("Generate and Save Passphrase"));
- ui_->gnerateNameButton->setText(_("Generate Key Package Name"));
- ui_->setOutputPathButton->setText(_("Select Output Path"));
+ tr("Tips: You can use Key Package to safely and conveniently transfer "
+ "your public and private keys between devices."));
+ ui_->generatePassphraseButton->setText(tr("Generate and Save Passphrase"));
+ ui_->gnerateNameButton->setText(tr("Generate Key Package Name"));
+ ui_->setOutputPathButton->setText(tr("Select Output Path"));
ui_->includeSecretKeyCheckBox->setText(
- _("Include secret key (Think twice before acting)"));
+ tr("Include secret key (Think twice before acting)"));
ui_->noPublicKeyCheckBox->setText(
- _("Exclude keys that do not have a private key"));
+ tr("Exclude keys that do not have a private key"));
setAttribute(Qt::WA_DeleteOnClose);
- setWindowTitle(_("Export As Key Package"));
+ setWindowTitle(tr("Export As Key Package"));
}
diff --git a/src/ui/dialog/import_export/ExportKeyPackageDialog.h b/src/ui/dialog/import_export/ExportKeyPackageDialog.h
index c5f9a2b1..abf7a84c 100644
--- a/src/ui/dialog/import_export/ExportKeyPackageDialog.h
+++ b/src/ui/dialog/import_export/ExportKeyPackageDialog.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,16 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_EXPORTKEYPACKAGEDIALOG_H
-#define GPGFRONTEND_EXPORTKEYPACKAGEDIALOG_H
+#pragma once
#include "GpgFrontendUI.h"
+#include "core/typedef/GpgTypedef.h"
#include "ui/dialog/GeneralDialog.h"
class Ui_exportKeyPackageDialog;
@@ -55,8 +55,6 @@ class ExportKeyPackageDialog : public GeneralDialog {
private:
std::shared_ptr<Ui_exportKeyPackageDialog> ui_; ///<
KeyIdArgsListPtr key_ids_; ///<
- std::string passphrase_; ///<
+ QString passphrase_; ///<
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_EXPORTKEYPACKAGEDIALOG_H
diff --git a/src/ui/dialog/import_export/KeyImportDetailDialog.cpp b/src/ui/dialog/import_export/KeyImportDetailDialog.cpp
index 32ae63fa..720fa883 100644
--- a/src/ui/dialog/import_export/KeyImportDetailDialog.cpp
+++ b/src/ui/dialog/import_export/KeyImportDetailDialog.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,21 +28,19 @@
#include "KeyImportDetailDialog.h"
+#include "core/GpgModel.h"
#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/model/GpgImportInformation.h"
namespace GpgFrontend::UI {
-KeyImportDetailDialog::KeyImportDetailDialog(GpgImportInformation result,
- bool automatic, QWidget* parent)
+KeyImportDetailDialog::KeyImportDetailDialog(
+ std::shared_ptr<GpgImportInformation> result, QWidget* parent)
: GeneralDialog(typeid(KeyImportDetailDialog).name(), parent),
m_result_(std::move(result)) {
// If no key for import found, just show a message
- if (m_result_.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"));
+ if (m_result_->considered == 0) {
+ QMessageBox::information(parent, tr("Key Import Details"),
+ tr("No keys found to import"));
emit finished(0);
this->close();
this->deleteLater();
@@ -57,18 +55,13 @@ KeyImportDetailDialog::KeyImportDetailDialog(GpgImportInformation result,
mv_box->addWidget(button_box_);
this->setLayout(mv_box);
- if (automatic)
- this->setWindowTitle(_("Key Update Details"));
- else
- this->setWindowTitle(_("Key Import Details"));
-
- auto pos = QPoint(100, 100);
- if (parent) pos += parent->pos();
- this->move(pos);
+ this->setWindowTitle(tr("Key Import Details"));
this->setMinimumSize(QSize(600, 300));
this->adjustSize();
+ movePosition2CenterOfParent();
+
this->setModal(true);
this->show();
}
@@ -76,54 +69,53 @@ KeyImportDetailDialog::KeyImportDetailDialog(GpgImportInformation result,
void KeyImportDetailDialog::create_general_info_box() {
// GridBox for general import information
- general_info_box_ = new QGroupBox(_("General key info"));
- auto* generalInfoBoxLayout = new QGridLayout(general_info_box_);
+ general_info_box_ = new QGroupBox(tr("General key info"));
+ auto* general_info_box_layout = new QGridLayout(general_info_box_);
- generalInfoBoxLayout->addWidget(new QLabel(QString(_("Considered")) + ": "),
- 1, 0);
- generalInfoBoxLayout->addWidget(
- new QLabel(QString::number(m_result_.considered)), 1, 1);
+ general_info_box_layout->addWidget(new QLabel(tr("Considered") + ": "), 1, 0);
+ general_info_box_layout->addWidget(
+ new QLabel(QString::number(m_result_->considered)), 1, 1);
int row = 2;
- if (m_result_.unchanged != 0) {
- generalInfoBoxLayout->addWidget(
- new QLabel(QString(_("Public unchanged")) + ": "), row, 0);
- generalInfoBoxLayout->addWidget(
- new QLabel(QString::number(m_result_.unchanged)), row, 1);
+ if (m_result_->unchanged != 0) {
+ general_info_box_layout->addWidget(
+ new QLabel(tr("Public unchanged") + ": "), row, 0);
+ general_info_box_layout->addWidget(
+ new QLabel(QString::number(m_result_->unchanged)), row, 1);
row++;
}
- if (m_result_.imported != 0) {
- generalInfoBoxLayout->addWidget(new QLabel(QString(_("Imported")) + ": "),
- row, 0);
- generalInfoBoxLayout->addWidget(
- new QLabel(QString::number(m_result_.imported)), row, 1);
+ if (m_result_->imported != 0) {
+ general_info_box_layout->addWidget(new QLabel(tr("Imported") + ": "), row,
+ 0);
+ general_info_box_layout->addWidget(
+ new QLabel(QString::number(m_result_->imported)), row, 1);
row++;
}
- if (m_result_.not_imported != 0) {
- generalInfoBoxLayout->addWidget(
- new QLabel(QString(_("Not Imported")) + ": "), row, 0);
- generalInfoBoxLayout->addWidget(
- new QLabel(QString::number(m_result_.not_imported)), row, 1);
+ if (m_result_->not_imported != 0) {
+ general_info_box_layout->addWidget(new QLabel(tr("Not Imported") + ": "),
+ row, 0);
+ general_info_box_layout->addWidget(
+ new QLabel(QString::number(m_result_->not_imported)), row, 1);
row++;
}
- if (m_result_.secret_read != 0) {
- generalInfoBoxLayout->addWidget(
- new QLabel(QString(_("Private Read")) + ": "), row, 0);
- generalInfoBoxLayout->addWidget(
- new QLabel(QString::number(m_result_.secret_read)), row, 1);
+ if (m_result_->secret_read != 0) {
+ general_info_box_layout->addWidget(new QLabel(tr("Private Read") + ": "),
+ row, 0);
+ general_info_box_layout->addWidget(
+ new QLabel(QString::number(m_result_->secret_read)), row, 1);
row++;
}
- if (m_result_.secret_imported != 0) {
- generalInfoBoxLayout->addWidget(
- new QLabel(QString(_("Private Imported")) + ": "), row, 0);
- generalInfoBoxLayout->addWidget(
- new QLabel(QString::number(m_result_.secret_imported)), row, 1);
+ if (m_result_->secret_imported != 0) {
+ general_info_box_layout->addWidget(
+ new QLabel(tr("Private Imported") + ": "), row, 0);
+ general_info_box_layout->addWidget(
+ new QLabel(QString::number(m_result_->secret_imported)), row, 1);
row++;
}
- if (m_result_.secret_unchanged != 0) {
- generalInfoBoxLayout->addWidget(
- new QLabel(QString(_("Private Unchanged")) + ": "), row, 0);
- generalInfoBoxLayout->addWidget(
- new QLabel(QString::number(m_result_.secret_unchanged)), row, 1);
+ if (m_result_->secret_unchanged != 0) {
+ general_info_box_layout->addWidget(
+ new QLabel(tr("Private Unchanged") + ": "), row, 0);
+ general_info_box_layout->addWidget(
+ new QLabel(QString::number(m_result_->secret_unchanged)), row, 1);
}
}
@@ -135,24 +127,22 @@ void KeyImportDetailDialog::create_keys_table() {
// Nothing is selectable
keys_table_->setSelectionMode(QAbstractItemView::NoSelection);
- QStringList headerLabels;
- headerLabels << _("Name") << _("Email") << _("Status") << _("Fingerprint");
+ QStringList header_labels;
+ header_labels << tr("Name") << tr("Email") << tr("Status")
+ << tr("Fingerprint");
keys_table_->verticalHeader()->hide();
- keys_table_->setHorizontalHeaderLabels(headerLabels);
+ keys_table_->setHorizontalHeaderLabels(header_labels);
int row = 0;
- for (const auto& imp_key : m_result_.importedKeys) {
+ for (const auto& imp_key : m_result_->imported_keys) {
keys_table_->setRowCount(row + 1);
- GpgKey key = GpgKeyGetter::GetInstance().GetKey(imp_key.fpr);
+ auto key = GpgKeyGetter::GetInstance().GetKey(imp_key.fpr);
if (!key.IsGood()) continue;
- keys_table_->setItem(
- row, 0, new QTableWidgetItem(QString::fromStdString(key.GetName())));
- keys_table_->setItem(
- row, 1, new QTableWidgetItem(QString::fromStdString(key.GetEmail())));
+ keys_table_->setItem(row, 0, new QTableWidgetItem(key.GetName()));
+ keys_table_->setItem(row, 1, new QTableWidgetItem(key.GetEmail()));
keys_table_->setItem(
row, 2, new QTableWidgetItem(get_status_string(imp_key.import_status)));
- keys_table_->setItem(
- row, 3, new QTableWidgetItem(QString::fromStdString(imp_key.fpr)));
+ keys_table_->setItem(row, 3, new QTableWidgetItem(imp_key.fpr));
row++;
}
keys_table_->horizontalHeader()->setSectionResizeMode(
@@ -165,27 +155,27 @@ QString KeyImportDetailDialog::get_status_string(int key_status) {
QString status_string;
// keystatus is greater than 15, if key is private
if (key_status > 15) {
- status_string.append(_("Private"));
+ status_string.append(tr("Private"));
key_status = key_status - 16;
} else {
- status_string.append(_("Public"));
+ status_string.append(tr("Public"));
}
if (key_status == 0) {
- status_string.append(", " + QString(_("Unchanged")));
+ status_string.append(", " + tr("Unchanged"));
} else {
if (key_status == 1) {
- status_string.append(", " + QString(_("New Key")));
+ status_string.append(", " + tr("New Key"));
} else {
if (key_status > 7) {
- status_string.append(", " + QString(_("New Subkey")));
+ status_string.append(", " + tr("New Subkey"));
return status_string;
}
if (key_status > 3) {
- status_string.append(", " + QString(_("New Signature")));
+ status_string.append(", " + tr("New Signature"));
return status_string;
}
if (key_status > 1) {
- status_string.append(", " + QString(_("New UID")));
+ status_string.append(", " + tr("New UID"));
return status_string;
}
}
diff --git a/src/ui/dialog/import_export/KeyImportDetailDialog.h b/src/ui/dialog/import_export/KeyImportDetailDialog.h
index 06f44e94..db355570 100644
--- a/src/ui/dialog/import_export/KeyImportDetailDialog.h
+++ b/src/ui/dialog/import_export/KeyImportDetailDialog.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,20 +20,21 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef __KEYIMPORTDETAILSDIALOG_H__
-#define __KEYIMPORTDETAILSDIALOG_H__
+#pragma once
-#include "core/GpgContext.h"
#include "core/function/gpg/GpgKeyImportExporter.h"
-#include "ui/GpgFrontendUI.h"
#include "ui/dialog/GeneralDialog.h"
+namespace GpgFrontend {
+class GpgImportInformation;
+}
+
namespace GpgFrontend::UI {
/**
@@ -51,8 +52,8 @@ class KeyImportDetailDialog : public GeneralDialog {
* @param automatic
* @param parent
*/
- KeyImportDetailDialog(GpgImportInformation result, bool automatic,
- QWidget* parent = nullptr);
+ explicit KeyImportDetailDialog(std::shared_ptr<GpgImportInformation> result,
+ QWidget* parent = nullptr);
private:
/**
@@ -85,8 +86,7 @@ class KeyImportDetailDialog : public GeneralDialog {
QGroupBox* general_info_box_{}; ///<
QGroupBox* key_info_box_{}; ///<
QDialogButtonBox* button_box_{}; ///<
- GpgImportInformation m_result_; ///<
+
+ std::shared_ptr<GpgImportInformation> m_result_; ///<
};
} // namespace GpgFrontend::UI
-
-#endif // __KEYIMPORTDETAILSDIALOG_H__
diff --git a/src/ui/dialog/import_export/KeyServerImportDialog.cpp b/src/ui/dialog/import_export/KeyServerImportDialog.cpp
index cf4fbe55..49438c44 100644
--- a/src/ui/dialog/import_export/KeyServerImportDialog.cpp
+++ b/src/ui/dialog/import_export/KeyServerImportDialog.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -29,169 +29,115 @@
#include "KeyServerImportDialog.h"
#include <QRegExp>
-#include <string>
-#include <utility>
+#include "core/GpgModel.h"
#include "core/function/GlobalSettingStation.h"
#include "core/function/gpg/GpgKeyImportExporter.h"
-#include "thread/KeyServerImportTask.h"
-#include "ui/SignalStation.h"
+#include "ui/UISignalStation.h"
#include "ui/struct/SettingsObject.h"
+#include "ui/struct/settings/KeyServerSO.h"
+#include "ui/thread/KeyServerImportTask.h"
#include "ui/thread/KeyServerSearchTask.h"
namespace GpgFrontend::UI {
-KeyServerImportDialog::KeyServerImportDialog(bool automatic, QWidget* parent)
- : GeneralDialog("key_server_import_dialog", parent),
- m_automatic_(automatic) {
- // Layout for messagebox
- auto* message_layout = new QHBoxLayout();
-
- bool forbid_all_gnupg_connection =
- GlobalSettingStation::GetInstance().LookupSettings(
- "network.forbid_all_gnupg_connection", false);
-
+KeyServerImportDialog::KeyServerImportDialog(QWidget* parent)
+ : GeneralDialog("key_server_import_dialog", parent) {
+ auto forbid_all_gnupg_connection =
+ GlobalSettingStation::GetInstance()
+ .GetSettings()
+ .value("network/forbid_all_gnupg_connection", false)
+ .toBool();
if (forbid_all_gnupg_connection) {
QMessageBox::critical(this, "Forbidden", "GnuPG is in offline mode now.");
this->close();
this->deleteLater();
}
- if (automatic) {
- setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint);
- } else {
- // Buttons
-
- close_button_ = new QPushButton(_("Close"));
- connect(close_button_, &QPushButton::clicked, this,
- &KeyServerImportDialog::close);
- import_button_ = new QPushButton(_("Import ALL"));
- connect(import_button_, &QPushButton::clicked, this,
- &KeyServerImportDialog::slot_import);
- import_button_->setDisabled(true);
- search_button_ = new QPushButton(_("Search"));
- connect(search_button_, &QPushButton::clicked, this,
- &KeyServerImportDialog::slot_search);
-
- // Line edits for search string
- search_label_ = new QLabel(QString(_("Search String")) + _(": "));
- search_line_edit_ = new QLineEdit();
-
- // combobox for keyserver list
- key_server_label_ = new QLabel(QString(_("Key Server")) + _(": "));
- key_server_combo_box_ = create_comboBox();
-
- // table containing the keys found
- create_keys_table();
- message_ = new QLabel();
- message_->setFixedHeight(24);
- icon_ = new QLabel();
- icon_->setFixedHeight(24);
-
- message_layout->addWidget(icon_);
- message_layout->addWidget(message_);
- message_layout->addStretch();
- }
+ // Buttons
+ close_button_ = new QPushButton(tr("Close"));
+ connect(close_button_, &QPushButton::clicked, this,
+ &KeyServerImportDialog::close);
+ import_button_ = new QPushButton(tr("Import ALL"));
+ connect(import_button_, &QPushButton::clicked, this,
+ &KeyServerImportDialog::slot_import);
+ import_button_->setDisabled(true);
+ search_button_ = new QPushButton(tr("Search"));
+ connect(search_button_, &QPushButton::clicked, this,
+ &KeyServerImportDialog::slot_search);
+
+ // Line edits for search string
+ search_label_ = new QLabel(tr("Search String") + tr(": "));
+ search_line_edit_ = new QLineEdit();
+
+ // combobox for keyserver list
+ key_server_label_ = new QLabel(tr("Key Server") + tr(": "));
+ key_server_combo_box_ = create_combo_box();
+
+ // table containing the keys found
+ create_keys_table();
+ message_ = new QLabel();
+ message_->setFixedHeight(24);
+ icon_ = new QLabel();
+ icon_->setFixedHeight(24);
+
+ // Layout for messagebox
+ message_layout_ = new QHBoxLayout();
+ message_layout_->addWidget(icon_);
+ message_layout_->addWidget(message_);
+ message_layout_->addStretch();
// Network Waiting
waiting_bar_ = new QProgressBar();
waiting_bar_->setVisible(false);
waiting_bar_->setRange(0, 0);
waiting_bar_->setFixedWidth(200);
- message_layout->addWidget(waiting_bar_);
-
- auto* mainLayout = new QGridLayout;
-
- // 自动化调用界面布局
- if (automatic) {
- mainLayout->addLayout(message_layout, 0, 0, 1, 3);
- } else {
- mainLayout->addWidget(search_label_, 1, 0);
- mainLayout->addWidget(search_line_edit_, 1, 1);
- mainLayout->addWidget(search_button_, 1, 2);
- mainLayout->addWidget(key_server_label_, 2, 0);
- mainLayout->addWidget(key_server_combo_box_, 2, 1);
- mainLayout->addWidget(keys_table_, 3, 0, 1, 3);
- mainLayout->addLayout(message_layout, 4, 0, 1, 3);
-
- // Layout for import and close button
- auto* buttonsLayout = new QHBoxLayout;
- buttonsLayout->addStretch();
- buttonsLayout->addWidget(import_button_);
- buttonsLayout->addWidget(close_button_);
- 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);
- }
+ auto* main_layout = new QGridLayout();
+
+ main_layout->addWidget(search_label_, 1, 0);
+ main_layout->addWidget(search_line_edit_, 1, 1);
+ main_layout->addWidget(search_button_, 1, 2);
+ main_layout->addWidget(key_server_label_, 2, 0);
+ main_layout->addWidget(key_server_combo_box_, 2, 1);
+ main_layout->addWidget(keys_table_, 3, 0, 1, 3);
+ main_layout->addWidget(waiting_bar_, 4, 0, 1, 3);
+ main_layout->addLayout(message_layout_, 5, 0, 1, 3);
+
+ // Layout for import and close button
+ auto* buttons_layout = new QHBoxLayout();
+ buttons_layout->addStretch();
+ buttons_layout->addWidget(import_button_);
+ buttons_layout->addWidget(close_button_);
+ main_layout->addLayout(buttons_layout, 6, 0, 1, 3);
+
+ this->setLayout(main_layout);
+ this->setWindowTitle(tr("Import Keys from Keyserver"));
this->setModal(true);
- connect(this, &KeyServerImportDialog::SignalKeyImported,
- SignalStation::GetInstance(),
- &SignalStation::SignalKeyDatabaseRefresh);
-}
-
-KeyServerImportDialog::KeyServerImportDialog(QWidget* parent)
- : GeneralDialog("key_server_import_dialog", parent), m_automatic_(true) {
- setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint);
-
- // Network Waiting
- waiting_bar_ = new QProgressBar();
- waiting_bar_->setVisible(false);
- waiting_bar_->setRange(0, 0);
- waiting_bar_->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
- waiting_bar_->setTextVisible(false);
-
- // Layout for messagebox
- auto* layout = new QHBoxLayout();
- layout->setContentsMargins(0, 0, 0, 0);
- layout->setSpacing(0);
- layout->addWidget(waiting_bar_);
-
- key_server_combo_box_ = create_comboBox();
+ movePosition2CenterOfParent();
- this->setLayout(layout);
- this->setWindowTitle(_("Update Keys from Keyserver"));
- this->setFixedSize(240, 42);
- this->setModal(true);
+ connect(this, &KeyServerImportDialog::SignalKeyImported,
+ UISignalStation::GetInstance(),
+ &UISignalStation::SignalKeyDatabaseRefresh);
}
-QComboBox* KeyServerImportDialog::create_comboBox() {
- auto* comboBox = new QComboBox;
- comboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+auto KeyServerImportDialog::create_combo_box() -> QComboBox* {
+ auto* combo_box = new QComboBox;
+ combo_box->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
try {
- SettingsObject key_server_json("key_server");
-
- const auto key_server_list =
- key_server_json.Check("server_list", nlohmann::json::array());
-
+ KeyServerSO key_server(SettingsObject("general_settings_state"));
+ const auto& key_server_list = key_server.server_list;
for (const auto& key_server : key_server_list) {
- const auto key_server_str = key_server.get<std::string>();
- comboBox->addItem(key_server_str.c_str());
+ combo_box->addItem(key_server);
}
-
- int default_key_server_index = key_server_json.Check("default_server", 0);
- if (default_key_server_index >= key_server_list.size()) {
- throw std::runtime_error("default_server index out of range");
- }
- std::string default_key_server =
- key_server_list[default_key_server_index].get<std::string>();
-
- comboBox->setCurrentText(default_key_server.c_str());
+ combo_box->setCurrentText(key_server.GetTargetServer());
} catch (...) {
- SPDLOG_ERROR("setting operation error", "server_list", "default_server");
+ GF_UI_LOG_ERROR("setting operation error", "server_list", "default_server");
}
- return comboBox;
+ return combo_box;
}
void KeyServerImportDialog::create_keys_table() {
@@ -206,7 +152,7 @@ void KeyServerImportDialog::create_keys_table() {
keys_table_->setSelectionMode(QAbstractItemView::SingleSelection);
QStringList labels;
- labels << _("UID") << _("Creation date") << _("KeyID") << _("Tag");
+ labels << tr("UID") << tr("Creation date") << tr("KeyID") << tr("Tag");
keys_table_->horizontalHeader()->setSectionResizeMode(
0, QHeaderView::ResizeToContents);
keys_table_->setHorizontalHeaderLabels(labels);
@@ -217,27 +163,24 @@ void KeyServerImportDialog::create_keys_table() {
}
void KeyServerImportDialog::set_message(const QString& text, bool error) {
- if (m_automatic_) return;
-
message_->setText(text);
if (error) {
- icon_->setPixmap(
- QPixmap(":error.png").scaled(QSize(24, 24), Qt::KeepAspectRatio));
+ icon_->setPixmap(QPixmap(":/icons/error.png")
+ .scaled(QSize(24, 24), Qt::KeepAspectRatio));
} else {
icon_->setPixmap(
- QPixmap(":info.png").scaled(QSize(24, 24), Qt::KeepAspectRatio));
+ QPixmap(":/icons/info.png").scaled(QSize(24, 24), Qt::KeepAspectRatio));
}
}
void KeyServerImportDialog::slot_search() {
if (search_line_edit_->text().isEmpty()) {
- set_message("<h4>" + QString(_("Text is empty.")) + "</h4>", false);
+ set_message("<h4>" + tr("Text is empty.") + "</h4>", false);
return;
}
- auto* task = new KeyServerSearchTask(
- key_server_combo_box_->currentText().toStdString(),
- search_line_edit_->text().toStdString());
+ auto* task = new KeyServerSearchTask(key_server_combo_box_->currentText(),
+ search_line_edit_->text());
connect(task, &KeyServerSearchTask::SignalKeyServerSearchResult, this,
&KeyServerImportDialog::slot_search_finished);
@@ -267,7 +210,7 @@ void KeyServerImportDialog::slot_search() {
void KeyServerImportDialog::slot_search_finished(
QNetworkReply::NetworkError error, QByteArray buffer) {
- SPDLOG_DEBUG("search result {} {}", error, buffer.size());
+ GF_UI_LOG_DEBUG("search result {} {}", error, buffer.size());
keys_table_->clearContents();
keys_table_->setRowCount(0);
@@ -275,20 +218,20 @@ void KeyServerImportDialog::slot_search_finished(
auto stream = QTextStream(buffer);
if (error != QNetworkReply::NoError) {
- SPDLOG_DEBUG("error from reply: {}", error);
+ GF_UI_LOG_DEBUG("error from reply: {}", error);
switch (error) {
case QNetworkReply::ContentNotFoundError:
- set_message(_("Not Key Found"), true);
+ set_message(tr("Not Key Found"), true);
break;
case QNetworkReply::TimeoutError:
- set_message(_("Timeout"), true);
+ set_message(tr("Timeout"), true);
break;
case QNetworkReply::HostNotFoundError:
- set_message(_("Key Server Not Found"), true);
+ set_message(tr("Key Server Not Found"), true);
break;
default:
- set_message(_("Connection Error"), true);
+ set_message(tr("Connection Error"), true);
}
return;
}
@@ -297,36 +240,32 @@ void KeyServerImportDialog::slot_search_finished(
auto text = stream.readLine(1024);
if (text.contains("Too many responses")) {
- set_message(
- "<h4>" + QString(_("Too many responses from keyserver!")) + "</h4>",
- true);
+ set_message("<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 = search_line_edit_->text();
if (rx.exactMatch(query)) {
- set_message(
- "<h4>" +
- QString(_("No keys found, input may be kexId, retrying search "
- "with 0x.")) +
- "</h4>",
- true);
+ set_message("<h4>" +
+ tr("No keys found, input may be kexId, retrying search "
+ "with 0x.") +
+ "</h4>",
+ true);
search_line_edit_->setText(query.prepend("0x"));
this->slot_search();
return;
- } else {
- set_message(
- "<h4>" + QString(_("No keys found containing the search string!")) +
- "</h4>",
- true);
- return;
}
+ set_message(
+ "<h4>" + tr("No keys found containing the search string!") + "</h4>",
+ true);
+ return;
+
} else if (text.contains("Insufficiently specific words")) {
- set_message("<h4>" +
- QString(_("Insufficiently specific search string!")) +
- "</h4>",
- true);
+ set_message(
+ "<h4>" + tr("Insufficiently specific search string!") + "</h4>",
+ true);
return;
} else {
set_message(text, true);
@@ -359,12 +298,10 @@ void KeyServerImportDialog::slot_search_finished(
new QTableWidgetItem(QString("expired")));
}
if (flags.contains("r")) {
- keys_table_->setItem(row, 3,
- new QTableWidgetItem(QString(_("revoked"))));
+ keys_table_->setItem(row, 3, new QTableWidgetItem(tr("revoked")));
}
if (flags.contains("d")) {
- keys_table_->setItem(row, 3,
- new QTableWidgetItem(QString(_("disabled"))));
+ keys_table_->setItem(row, 3, new QTableWidgetItem(tr("disabled")));
}
}
@@ -377,14 +314,9 @@ void KeyServerImportDialog::slot_search_finished(
uid->setText(line2[1]);
keys_table_->setItem(row, 0, uid);
}
-#ifdef GPGFRONTEND_GUI_QT6
auto* creation_date =
new QTableWidgetItem(QDateTime::fromSecsSinceEpoch(line[4].toInt())
.toString("dd. MMM. yyyy"));
-#else
- auto* creation_date = new QTableWidgetItem(
- QDateTime::fromTime_t(line[4].toInt()).toString("dd. MMM. yyyy"));
-#endif
keys_table_->setItem(row, 1, creation_date);
auto* keyid = new QTableWidgetItem(line[1]);
keys_table_->setItem(row, 2, keyid);
@@ -414,8 +346,7 @@ void KeyServerImportDialog::slot_search_finished(
}
set_message(
QString("<h4>") +
- QString(_("%1 keys found. Double click a key to import it."))
- .arg(row) +
+ tr("%1 keys found. Double click a key to import it.").arg(row) +
"</h4>",
false);
}
@@ -425,142 +356,74 @@ void KeyServerImportDialog::slot_search_finished(
}
void KeyServerImportDialog::slot_import() {
- std::vector<std::string> key_ids;
+ std::vector<QString> key_ids;
const int row_count = keys_table_->rowCount();
for (int i = 0; i < row_count; ++i) {
if (keys_table_->item(i, 2)->isSelected()) {
QString keyid = keys_table_->item(i, 2)->text();
- key_ids.push_back(keyid.toStdString());
+ key_ids.push_back(keyid);
}
}
- if (!key_ids.empty())
- SlotImport(key_ids, key_server_combo_box_->currentText().toStdString());
+ if (!key_ids.empty()) {
+ SlotImport(key_ids, key_server_combo_box_->currentText());
+ }
}
void KeyServerImportDialog::SlotImport(const KeyIdArgsListPtr& keys) {
// keyserver host url
- std::string target_keyserver;
+ QString target_keyserver;
if (key_server_combo_box_ != nullptr) {
- target_keyserver = key_server_combo_box_->currentText().toStdString();
+ target_keyserver = key_server_combo_box_->currentText();
}
- if (target_keyserver.empty()) {
- try {
- SettingsObject key_server_json("key_server");
- const auto key_server_list =
- key_server_json.Check("server_list", nlohmann::json::array());
-
- int default_key_server_index = key_server_json.Check("default_server", 0);
- if (default_key_server_index >= key_server_list.size()) {
- throw std::runtime_error("default_server index out of range");
- }
- std::string default_key_server =
- key_server_list[default_key_server_index].get<std::string>();
-
- target_keyserver = default_key_server;
- } catch (...) {
- SPDLOG_ERROR("setting operation error", "server_list", "default_server");
- QMessageBox::critical(
- nullptr, _("Default Keyserver Not Found"),
- _("Cannot read default keyserver from your settings, "
- "please set a default keyserver first"));
- return;
- }
+ if (target_keyserver.isEmpty()) {
+ KeyServerSO key_server(SettingsObject("general_settings_state"));
+ target_keyserver = key_server.GetTargetServer();
}
- std::vector<std::string> key_ids;
+ std::vector<QString> key_ids;
for (const auto& key_id : *keys) {
key_ids.push_back(key_id);
}
SlotImport(key_ids, target_keyserver);
}
-void KeyServerImportDialog::SlotImport(std::vector<std::string> key_ids,
- std::string keyserver_url) {
- auto* task = new KeyServerImportTask(keyserver_url, key_ids);
+void KeyServerImportDialog::SlotImport(std::vector<QString> key_ids,
+ QString keyserver_url) {
+ auto* task =
+ new KeyServerImportTask(std::move(keyserver_url), std::move(key_ids));
connect(task, &KeyServerImportTask::SignalKeyServerImportResult, this,
&KeyServerImportDialog::slot_import_finished);
+ set_loading(true);
Thread::TaskRunnerGetter::GetInstance()
.GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Network)
->PostTask(task);
}
void KeyServerImportDialog::slot_import_finished(
- QNetworkReply::NetworkError error, QByteArray buffer) {
- if (error != QNetworkReply::NoError) {
- SPDLOG_ERROR("Error From Reply", buffer.toStdString());
- if (!m_automatic_) {
- switch (error) {
- case QNetworkReply::ContentNotFoundError:
- set_message(_("Key Not Found"), true);
- break;
- case QNetworkReply::TimeoutError:
- set_message(_("Timeout"), true);
- break;
- case QNetworkReply::HostNotFoundError:
- set_message(_("Key Server Not Found"), true);
- break;
- default:
- set_message(_("Connection Error"), true);
- }
- } else {
- switch (error) {
- case QNetworkReply::ContentNotFoundError:
- QMessageBox::critical(nullptr, _("Key Not Found"),
- QString(_("key not found in the Keyserver")));
- 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"));
- }
- }
- if (m_automatic_) {
- setWindowFlags(Qt::Window | Qt::WindowTitleHint |
- Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint);
- }
- return;
- }
+ bool success, QString err_msg, QByteArray buffer,
+ std::shared_ptr<GpgImportInformation> info) {
+ set_loading(false);
- this->import_keys(
- std::make_unique<ByteArray>(buffer.constData(), buffer.length()));
-
- if (!m_automatic_) {
- set_message(QString("<h4>") + _("Key Imported") + "</h4>", false);
+ if (!success) {
+ GF_UI_LOG_ERROR("Error From Reply", buffer.toStdString());
+ set_message(err_msg, true);
+ return;
}
-}
-void KeyServerImportDialog::import_keys(ByteArrayPtr in_data) {
- GpgImportInformation result =
- GpgKeyImportExporter::GetInstance().ImportKey(std::move(in_data));
+ set_message(tr("Key Imported"), false);
// refresh the key database
emit SignalKeyImported();
- QWidget* _parent = qobject_cast<QWidget*>(parent());
- if (m_automatic_) {
- auto dialog = new KeyImportDetailDialog(result, true, _parent);
- dialog->show();
- this->accept();
- } else {
- auto dialog = new KeyImportDetailDialog(result, false, this);
- dialog->exec();
- }
+ // show details
+ (new KeyImportDetailDialog(std::move(info), this))->exec();
}
void KeyServerImportDialog::set_loading(bool status) {
waiting_bar_->setVisible(status);
- if (!m_automatic_) {
- icon_->setVisible(!status);
- message_->setVisible(!status);
- }
+ if (status) set_message(tr("Processing ..."), false);
}
} // namespace GpgFrontend::UI
diff --git a/src/ui/dialog/import_export/KeyServerImportDialog.h b/src/ui/dialog/import_export/KeyServerImportDialog.h
index fd912bdd..6a7ddfdd 100644
--- a/src/ui/dialog/import_export/KeyServerImportDialog.h
+++ b/src/ui/dialog/import_export/KeyServerImportDialog.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,22 +20,19 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef __KEY_SERVER_IMPORT_DIALOG_H__
-#define __KEY_SERVER_IMPORT_DIALOG_H__
+#pragma once
-#include <string>
+#include <QtNetwork>
#include "KeyImportDetailDialog.h"
-#include "core/GpgContext.h"
-#include "ui/GpgFrontendUI.h"
+#include "core/typedef/CoreTypedef.h"
#include "ui/dialog/GeneralDialog.h"
-#include "ui/widgets/KeyList.h"
namespace GpgFrontend::UI {
@@ -53,13 +50,6 @@ class KeyServerImportDialog : public GeneralDialog {
* @param automatic
* @param parent
*/
- KeyServerImportDialog(bool automatic, QWidget* parent);
-
- /**
- * @brief Construct a new Key Server Import Dialog object
- *
- * @param parent
- */
explicit KeyServerImportDialog(QWidget* parent);
public slots:
@@ -77,8 +67,7 @@ class KeyServerImportDialog : public GeneralDialog {
* @param keyIds
* @param keyserverUrl
*/
- void SlotImport(std::vector<std::string> key_ids_list,
- std::string keyserver_url);
+ void SlotImport(std::vector<QString> key_ids_list, QString keyserver_url);
signals:
@@ -108,8 +97,8 @@ class KeyServerImportDialog : public GeneralDialog {
*
* @param keyid
*/
- void slot_import_finished(QNetworkReply::NetworkError error,
- QByteArray buffer);
+ void slot_import_finished(bool success, QString err_msg, QByteArray buffer,
+ std::shared_ptr<GpgImportInformation> info);
/**
* @brief
@@ -160,9 +149,9 @@ class KeyServerImportDialog : public GeneralDialog {
*
* @return QComboBox*
*/
- QComboBox* create_comboBox();
+ QComboBox* create_combo_box();
- bool m_automatic_ = false; ///<
+ QHBoxLayout* message_layout_; ///<
QLineEdit* search_line_edit_{}; ///<
QComboBox* key_server_combo_box_{}; ///<
@@ -178,5 +167,3 @@ class KeyServerImportDialog : public GeneralDialog {
};
} // namespace GpgFrontend::UI
-
-#endif // __KEY_SERVER_IMPORT_DIALOG_H__
diff --git a/src/ui/dialog/import_export/KeyUploadDialog.cpp b/src/ui/dialog/import_export/KeyUploadDialog.cpp
index 5e05da2d..903b2e14 100644
--- a/src/ui/dialog/import_export/KeyUploadDialog.cpp
+++ b/src/ui/dialog/import_export/KeyUploadDialog.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,12 +28,15 @@
#include "KeyUploadDialog.h"
-#include <algorithm>
+#include <QtNetwork>
-#include "core/function/GlobalSettingStation.h"
+#include "core/GpgModel.h"
#include "core/function/gpg/GpgKeyGetter.h"
#include "core/function/gpg/GpgKeyImportExporter.h"
+#include "core/utils/GpgUtils.h"
+#include "ui/UserInterfaceUtils.h"
#include "ui/struct/SettingsObject.h"
+#include "ui/struct/settings/KeyServerSO.h"
namespace GpgFrontend::UI {
@@ -53,77 +56,72 @@ KeyUploadDialog::KeyUploadDialog(const KeyIdArgsListPtr& keys_ids,
this->setLayout(layout);
this->setModal(true);
- this->setWindowTitle(_("Uploading Public Key"));
+ this->setWindowTitle(tr("Uploading Public Key"));
this->setFixedSize(240, 42);
- this->setPosCenterOfScreen();
+ this->movePosition2CenterOfParent();
+ this->setAttribute(Qt::WA_DeleteOnClose);
}
void KeyUploadDialog::SlotUpload() {
- auto out_data = std::make_unique<ByteArray>();
- GpgKeyImportExporter::GetInstance().ExportKeys(*m_keys_, out_data);
- slot_upload_key_to_server(*out_data);
-
- // Done
- this->hide();
- this->close();
+ GpgKeyImportExporter::GetInstance().ExportKeys(
+ *m_keys_, false, true, false, false,
+ [=](GpgError err, const DataObjectPtr& data_obj) {
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ CommonUtils::RaiseMessageBox(this, err);
+ return;
+ }
+
+ if (CheckGpgError(err) == GPG_ERR_USER_1 || data_obj == nullptr ||
+ !data_obj->Check<GFBuffer>()) {
+ GF_CORE_LOG_ERROR("data object checking failed");
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unknown error occurred"));
+ // Done
+ this->hide();
+ this->close();
+ return;
+ }
+
+ auto gf_buffer = ExtractParams<GFBuffer>(data_obj, 0);
+ slot_upload_key_to_server(gf_buffer);
+
+ // Done
+ this->hide();
+ this->close();
+ });
}
void KeyUploadDialog::slot_upload_key_to_server(
- const GpgFrontend::ByteArray& keys_data) {
- std::string target_keyserver;
-
- try {
- SettingsObject key_server_json("key_server");
-
- const auto key_server_list =
- key_server_json.Check("server_list", nlohmann::json::array());
-
- int default_key_server_index = key_server_json.Check("default_server", 0);
- if (default_key_server_index >= key_server_list.size()) {
- throw std::runtime_error("default_server index out of range");
- }
-
- target_keyserver =
- key_server_list[default_key_server_index].get<std::string>();
+ const GpgFrontend::GFBuffer& keys_data) {
+ KeyServerSO key_server(SettingsObject("general_settings_state"));
+ auto target_keyserver = key_server.GetTargetServer();
- SPDLOG_DEBUG("set target key server to default key server: {}",
- target_keyserver);
-
- } catch (...) {
- SPDLOG_ERROR(_("Cannot read default_keyserver From Settings"));
- QMessageBox::critical(nullptr, _("Default Keyserver Not Found"),
- _("Cannot read default keyserver from your settings, "
- "please set a default keyserver first"));
- return;
- }
-
- QUrl req_url(QString::fromStdString(target_keyserver + "/pks/add"));
- auto qnam = new QNetworkAccessManager(this);
+ QUrl req_url(target_keyserver + "/pks/add");
+ auto* qnam = new QNetworkAccessManager(this);
// Building Post Data
- QByteArray postData;
+ QByteArray post_data;
- auto data = std::string(keys_data);
+ auto data = keys_data.ConvertToQByteArray();
- 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, " ", "+");
+ data.replace("\n", "%0A");
+ data.replace("\r", "%0D");
+ data.replace("(", "%28");
+ data.replace(")", "%29");
+ data.replace("/", "%2F");
+ data.replace(":", "%3A");
+ data.replace("+", "%2B");
+ data.replace("=", "%3D");
+ data.replace(" ", "+");
QNetworkRequest request(req_url);
request.setHeader(QNetworkRequest::ContentTypeHeader,
"application/x-www-form-urlencoded");
- postData.append("keytext").append("=").append(
- QString::fromStdString(data).toUtf8());
+ post_data.append("keytext").append("=").append(data);
// Send Post Data
- QNetworkReply* reply = qnam->post(request, postData);
+ QNetworkReply* reply = qnam->post(request, post_data);
connect(reply, &QNetworkReply::finished, this,
&KeyUploadDialog::slot_upload_finished);
@@ -136,34 +134,33 @@ void KeyUploadDialog::slot_upload_key_to_server(
void KeyUploadDialog::slot_upload_finished() {
auto* reply = qobject_cast<QNetworkReply*>(sender());
+ this->close();
QByteArray response = reply->readAll();
- SPDLOG_DEBUG("response: {}", response.toStdString());
+ GF_UI_LOG_DEBUG("response: {}", response.toStdString());
auto error = reply->error();
if (error != QNetworkReply::NoError) {
- SPDLOG_DEBUG("error from reply: {}", reply->errorString().toStdString());
+ GF_UI_LOG_DEBUG("error from reply: {}", reply->errorString().toStdString());
QString message;
switch (error) {
case QNetworkReply::ContentNotFoundError:
- message = _("Key Not Found");
+ message = tr("Key Not Found");
break;
case QNetworkReply::TimeoutError:
- message = _("Timeout");
+ message = tr("Timeout");
break;
case QNetworkReply::HostNotFoundError:
- message = _("Key Server Not Found");
+ message = tr("Key Server Not Found");
break;
default:
- message = _("Connection Error");
+ message = tr("Connection Error");
}
- QMessageBox::critical(this, "Upload Failed", message);
+ QMessageBox::critical(this->parentWidget(), tr("Upload Failed"), message);
return;
- } else {
- QMessageBox::information(this, _("Upload Success"),
- _("Upload Public Key Successfully"));
- SPDLOG_DEBUG("success while contacting keyserver!");
}
- reply->deleteLater();
+
+ QMessageBox::information(this->parentWidget(), tr("Upload Success"),
+ tr("Upload Public Key Successfully"));
}
} // namespace GpgFrontend::UI
diff --git a/src/ui/dialog/import_export/KeyUploadDialog.h b/src/ui/dialog/import_export/KeyUploadDialog.h
index d621f33a..042989e5 100644
--- a/src/ui/dialog/import_export/KeyUploadDialog.h
+++ b/src/ui/dialog/import_export/KeyUploadDialog.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,16 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_KEYUPLOADWIDGET_H
-#define GPGFRONTEND_KEYUPLOADWIDGET_H
+#pragma once
-#include "core/GpgContext.h"
+#include "core/model/GFBuffer.h"
+#include "core/typedef/GpgTypedef.h"
#include "ui/GpgFrontendUI.h"
#include "ui/dialog/GeneralDialog.h"
@@ -65,7 +65,7 @@ class KeyUploadDialog : public GeneralDialog {
*
* @param keys_data
*/
- void slot_upload_key_to_server(const GpgFrontend::ByteArray& keys_data);
+ void slot_upload_key_to_server(const GFBuffer&);
/**
* @brief
@@ -79,5 +79,3 @@ class KeyUploadDialog : public GeneralDialog {
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_KEYUPLOADWIDGET_H
diff --git a/src/ui/dialog/key_generate/KeygenDialog.cpp b/src/ui/dialog/key_generate/KeygenDialog.cpp
index 02e0d1c8..0f6c19d8 100644
--- a/src/ui/dialog/key_generate/KeygenDialog.cpp
+++ b/src/ui/dialog/key_generate/KeygenDialog.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,13 +28,15 @@
#include "KeygenDialog.h"
-#include <qobject.h>
-
-#include "core/common/CoreCommonUtil.h"
+#include "core/GpgModel.h"
#include "core/function/GlobalSettingStation.h"
#include "core/function/gpg/GpgKeyOpera.h"
-#include "dialog/WaitingDialog.h"
-#include "ui/SignalStation.h"
+#include "core/model/DataObject.h"
+#include "core/typedef/GpgTypedef.h"
+#include "core/utils/CacheUtils.h"
+#include "core/utils/GpgUtils.h"
+#include "ui/UISignalStation.h"
+#include "ui/UserInterfaceUtils.h"
namespace GpgFrontend::UI {
@@ -43,64 +45,62 @@ KeyGenDialog::KeyGenDialog(QWidget* parent)
button_box_ =
new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
- bool longer_expiration_date =
- GlobalSettingStation::GetInstance().LookupSettings(
- "general.longer_expiration_date", false);
-
- bool use_pinentry_as_password_input_dialog =
- GlobalSettingStation::GetInstance().LookupSettings(
- "general.use_pinentry_as_password_input_dialog", false);
-
- use_pinentry_ = use_pinentry_as_password_input_dialog;
+ bool const longer_expiration_date =
+ GlobalSettingStation::GetInstance()
+ .GetSettings()
+ .value("basic/longer_expiration_date", false)
+ .toBool();
max_date_time_ = longer_expiration_date
? QDateTime::currentDateTime().toLocalTime().addYears(30)
: QDateTime::currentDateTime().toLocalTime().addYears(2);
- this->setWindowTitle(_("Generate Key"));
- this->setModal(true);
-
- connect(this, &KeyGenDialog::SignalKeyGenerated, SignalStation::GetInstance(),
- &SignalStation::SignalKeyDatabaseRefresh);
+ connect(this, &KeyGenDialog::SignalKeyGenerated,
+ UISignalStation::GetInstance(),
+ &UISignalStation::SignalKeyDatabaseRefresh);
generate_key_dialog();
+
+ this->setWindowTitle(tr("Generate Key"));
+ this->setAttribute(Qt::WA_DeleteOnClose);
+ this->setModal(true);
}
void KeyGenDialog::generate_key_dialog() {
key_usage_group_box_ = create_key_usage_group_box();
- auto* groupGrid = new QGridLayout(this);
- groupGrid->addWidget(create_basic_info_group_box(), 0, 0);
- groupGrid->addWidget(key_usage_group_box_, 1, 0);
+ auto* group_grid = new QGridLayout(this);
+ group_grid->addWidget(create_basic_info_group_box(), 0, 0);
+ group_grid->addWidget(key_usage_group_box_, 1, 0);
- auto* nameList = new QWidget(this);
- nameList->setLayout(groupGrid);
+ auto* name_list = new QWidget(this);
+ name_list->setLayout(group_grid);
auto* vbox2 = new QVBoxLayout();
- vbox2->addWidget(nameList);
+ vbox2->addWidget(name_list);
vbox2->addWidget(error_label_);
vbox2->addWidget(button_box_);
this->setLayout(vbox2);
set_signal_slot();
-
refresh_widgets_state();
}
void KeyGenDialog::slot_key_gen_accept() {
- std::stringstream error_stream;
+ QString buffer;
+ QTextStream error_stream(&buffer);
/**
* check for errors in keygen dialog input
*/
if ((name_edit_->text()).size() < 5) {
- error_stream << " " << _("Name must contain at least five characters.")
- << std::endl;
+ error_stream << " " << tr("Name must contain at least five characters.")
+ << '\n';
}
if (email_edit_->text().isEmpty() ||
!check_email_address(email_edit_->text())) {
- error_stream << " " << _("Please give a email address.") << std::endl;
+ error_stream << " " << tr("Please give a email address.") << '\n';
}
/**
@@ -108,81 +108,71 @@ void KeyGenDialog::slot_key_gen_accept() {
* in the future)
*/
if (date_edit_->dateTime() > max_date_time_) {
- error_stream << " " << _("Expiration time too long.") << std::endl;
- }
-
- if (!use_pinentry_ && passphrase_edit_->isEnabled() &&
- passphrase_edit_->text().size() == 0) {
- error_stream << " " << _("Password is empty.") << std::endl;
+ error_stream << " " << tr("Expiration time too long.") << '\n';
}
- auto err_string = error_stream.str();
-
- if (err_string.empty()) {
+ auto err_string = error_stream.readAll();
+ if (err_string.isEmpty()) {
/**
* create the string for key generation
*/
- gen_key_info_->SetName(name_edit_->text().toStdString());
- gen_key_info_->SetEmail(email_edit_->text().toStdString());
- gen_key_info_->SetComment(comment_edit_->text().toStdString());
+ gen_key_info_->SetName(name_edit_->text());
+ gen_key_info_->SetEmail(email_edit_->text());
+ gen_key_info_->SetComment(comment_edit_->text());
gen_key_info_->SetKeyLength(key_size_spin_box_->value());
- if (expire_check_box_->checkState()) {
- gen_key_info_->SetNonExpired(true);
- } else {
-#ifdef GPGFRONTEND_GUI_QT6
- gen_key_info_->SetExpireTime(boost::posix_time::from_time_t(
- date_edit_->dateTime().toSecsSinceEpoch()));
-#else
- gen_key_info_->SetExpireTime(
- boost::posix_time::from_time_t(date_edit_->dateTime().toTime_t()));
-#endif
- }
-
- if (!use_pinentry_ && !gen_key_info_->IsNoPassPhrase()) {
- CoreCommonUtil::GetInstance()->SetTempCacheValue(
- "__key_passphrase", this->passphrase_edit_->text().toStdString());
+ if (no_pass_phrase_check_box_->checkState() != 0U) {
+ gen_key_info_->SetNonPassPhrase(true);
+ if (gen_subkey_info_ != nullptr) {
+ gen_subkey_info_->SetNonPassPhrase(true);
+ }
}
- GpgGenKeyResult result;
- gpgme_error_t error = false;
- auto thread = QThread::create([&]() {
- error = GpgKeyOpera::GetInstance().GenerateKey(gen_key_info_, result);
- });
- thread->start();
-
- auto* dialog = new WaitingDialog(_("Generating"), this);
- dialog->show();
-
- while (thread->isRunning()) {
- QCoreApplication::processEvents();
+ if (expire_check_box_->checkState() != 0U) {
+ gen_key_info_->SetNonExpired(true);
+ if (gen_subkey_info_ != nullptr) gen_subkey_info_->SetNonExpired(true);
+ } else {
+ gen_key_info_->SetExpireTime(date_edit_->dateTime());
+ if (gen_subkey_info_ != nullptr) {
+ gen_subkey_info_->SetExpireTime(date_edit_->dateTime());
+ }
}
- dialog->close();
-
- if (!use_pinentry_ && !gen_key_info_->IsNoPassPhrase()) {
- CoreCommonUtil::GetInstance()->ResetTempCacheValue("__key_passphrase");
+ if (!GlobalSettingStation::GetInstance()
+ .GetSettings()
+ .value("basic/use_pinentry_as_password_input_dialog", false)
+ .toBool() &&
+ !no_pass_phrase_check_box_->isChecked()) {
+ SetCacheValue("PinentryContext", "NEW_PASSPHRASE");
}
- SPDLOG_DEBUG("generate done");
-
- if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) {
- auto* msg_box = new QMessageBox(qobject_cast<QWidget*>(this->parent()));
- 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(true);
- msg_box->open();
-
- SPDLOG_DEBUG("generate success");
-
- emit SignalKeyGenerated();
- this->close();
- } else {
- QMessageBox::critical(this, _("Failure"), _("Key generation failed."));
- }
+ CommonUtils::WaitForOpera(
+ this, tr("Generating"),
+ [this, gen_key_info = this->gen_key_info_](const OperaWaitingHd& hd) {
+ GpgKeyOpera::GetInstance().GenerateKeyWithSubkey(
+ gen_key_info, gen_subkey_info_,
+ [this, hd](GpgError err, const DataObjectPtr&) {
+ // stop showing waiting dialog
+ hd();
+
+ if (CheckGpgError(err) == GPG_ERR_USER_1) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unknown error occurred"));
+ return;
+ }
+
+ CommonUtils::RaiseMessageBox(this->parentWidget() != nullptr
+ ? this->parentWidget()
+ : this,
+ err);
+ if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
+ emit SignalKeyGenerated();
+ }
+ });
+ });
+
+ this->done(0);
} else {
/**
@@ -192,36 +182,30 @@ void KeyGenDialog::slot_key_gen_accept() {
QPalette error = error_label_->palette();
error.setColor(QPalette::Window, "#ff8080");
error_label_->setPalette(error);
- error_label_->setText(err_string.c_str());
+ error_label_->setText(err_string);
this->show();
}
}
-void KeyGenDialog::slot_expire_box_changed() {
- if (expire_check_box_->checkState()) {
- date_edit_->setEnabled(false);
- } else {
- date_edit_->setEnabled(true);
- }
-}
+void KeyGenDialog::slot_expire_box_changed() {}
QGroupBox* KeyGenDialog::create_key_usage_group_box() {
- auto* groupBox = new QGroupBox(this);
+ auto* group_box = new QGroupBox(this);
auto* grid = new QGridLayout(this);
- groupBox->setTitle(_("Key Usage"));
+ group_box->setTitle(tr("Key Usage"));
- auto* encrypt = new QCheckBox(_("Encryption"), groupBox);
+ auto* encrypt = new QCheckBox(tr("Encryption"), group_box);
encrypt->setTristate(false);
- auto* sign = new QCheckBox(_("Signing"), groupBox);
+ auto* sign = new QCheckBox(tr("Signing"), group_box);
sign->setTristate(false);
- auto* cert = new QCheckBox(_("Certification"), groupBox);
+ auto* cert = new QCheckBox(tr("Certification"), group_box);
cert->setTristate(false);
- auto* auth = new QCheckBox(_("Authentication"), groupBox);
+ auto* auth = new QCheckBox(tr("Authentication"), group_box);
auth->setTristate(false);
key_usage_check_boxes_.push_back(encrypt);
@@ -234,9 +218,9 @@ QGroupBox* KeyGenDialog::create_key_usage_group_box() {
grid->addWidget(cert, 1, 0);
grid->addWidget(auth, 1, 1);
- groupBox->setLayout(grid);
+ group_box->setLayout(grid);
- return groupBox;
+ return group_box;
}
void KeyGenDialog::slot_encryption_box_changed(int state) {
@@ -272,64 +256,100 @@ void KeyGenDialog::slot_authentication_box_changed(int state) {
}
void KeyGenDialog::slot_activated_key_type(int index) {
- SPDLOG_DEBUG("key type index changed: {}", index);
+ GF_UI_LOG_DEBUG("key type index changed: {}", index);
// check
- assert(gen_key_info_->GetSupportedKeyAlgo().size() > index);
- gen_key_info_->SetAlgo(gen_key_info_->GetSupportedKeyAlgo()[index]);
+ assert(gen_key_info_->GetSupportedKeyAlgo().size() >
+ static_cast<size_t>(index));
+
+ const auto [name, key_algo, subkey_algo] =
+ gen_key_info_->GetSupportedKeyAlgo()[index];
+ GF_UI_LOG_DEBUG("target key algo changed, name: {}, key: {}, subkey: {}",
+ name, key_algo, subkey_algo);
+
+ assert(!key_algo.isEmpty());
+ gen_key_info_->SetAlgo(key_algo);
+
+ if (!subkey_algo.isEmpty()) {
+ if (gen_subkey_info_ == nullptr) {
+ gen_subkey_info_ = SecureCreateSharedObject<GenKeyInfo>(true);
+ }
+ gen_subkey_info_->SetAlgo(subkey_algo);
+ } else {
+ gen_subkey_info_ = nullptr;
+ }
+
refresh_widgets_state();
}
void KeyGenDialog::refresh_widgets_state() {
- if (gen_key_info_->IsAllowEncryption())
+ if (gen_key_info_->IsAllowEncryption()) {
key_usage_check_boxes_[0]->setCheckState(Qt::CheckState::Checked);
- else
+ } else {
key_usage_check_boxes_[0]->setCheckState(Qt::CheckState::Unchecked);
+ }
- if (gen_key_info_->IsAllowChangeEncryption())
+ if (gen_key_info_->IsAllowChangeEncryption()) {
key_usage_check_boxes_[0]->setDisabled(false);
- else
+ } else {
key_usage_check_boxes_[0]->setDisabled(true);
+ }
- if (gen_key_info_->IsAllowSigning())
+ if (gen_key_info_->IsAllowSigning()) {
key_usage_check_boxes_[1]->setCheckState(Qt::CheckState::Checked);
- else
+ } else {
key_usage_check_boxes_[1]->setCheckState(Qt::CheckState::Unchecked);
+ }
- if (gen_key_info_->IsAllowChangeSigning())
+ if (gen_key_info_->IsAllowChangeSigning()) {
key_usage_check_boxes_[1]->setDisabled(false);
- else
+ } else {
key_usage_check_boxes_[1]->setDisabled(true);
+ }
- if (gen_key_info_->IsAllowCertification())
+ if (gen_key_info_->IsAllowCertification()) {
key_usage_check_boxes_[2]->setCheckState(Qt::CheckState::Checked);
- else
+ } else {
key_usage_check_boxes_[2]->setCheckState(Qt::CheckState::Unchecked);
+ }
- if (gen_key_info_->IsAllowChangeCertification())
+ if (gen_key_info_->IsAllowChangeCertification()) {
key_usage_check_boxes_[2]->setDisabled(false);
- else
+ } else {
key_usage_check_boxes_[2]->setDisabled(true);
+ }
- if (gen_key_info_->IsAllowAuthentication())
+ if (gen_key_info_->IsAllowAuthentication()) {
key_usage_check_boxes_[3]->setCheckState(Qt::CheckState::Checked);
- else
+ } else {
key_usage_check_boxes_[3]->setCheckState(Qt::CheckState::Unchecked);
+ }
- if (gen_key_info_->IsAllowChangeAuthentication())
+ if (gen_key_info_->IsAllowChangeAuthentication()) {
key_usage_check_boxes_[3]->setDisabled(false);
- else
+ } else {
key_usage_check_boxes_[3]->setDisabled(true);
+ }
- if (gen_key_info_->IsAllowNoPassPhrase())
+ if (gen_key_info_->IsAllowNoPassPhrase()) {
no_pass_phrase_check_box_->setDisabled(false);
- else
+ } else {
no_pass_phrase_check_box_->setDisabled(true);
+ }
- key_size_spin_box_->setRange(gen_key_info_->GetSuggestMinKeySize(),
- gen_key_info_->GetSuggestMaxKeySize());
- key_size_spin_box_->setValue(gen_key_info_->GetKeyLength());
- key_size_spin_box_->setSingleStep(gen_key_info_->GetSizeChangeStep());
+ if (gen_key_info_->GetSuggestMinKeySize() == -1 ||
+ gen_key_info_->GetSuggestMaxKeySize() == -1) {
+ key_size_spin_box_->setDisabled(true);
+ key_size_spin_box_->setRange(0, 0);
+ key_size_spin_box_->setValue(0);
+ key_size_spin_box_->setSingleStep(0);
+ } else {
+ key_size_spin_box_->setDisabled(false);
+ key_size_spin_box_->setRange(gen_key_info_->GetSuggestMinKeySize(),
+ gen_key_info_->GetSuggestMaxKeySize());
+ key_size_spin_box_->setValue(gen_key_info_->GetKeyLength());
+ key_size_spin_box_->setSingleStep(gen_key_info_->GetSizeChangeStep());
+ }
}
void KeyGenDialog::set_signal_slot() {
@@ -338,8 +358,9 @@ void KeyGenDialog::set_signal_slot() {
connect(button_box_, &QDialogButtonBox::rejected, this,
&KeyGenDialog::reject);
- connect(expire_check_box_, &QCheckBox::stateChanged, this,
- &KeyGenDialog::slot_expire_box_changed);
+ connect(expire_check_box_, &QCheckBox::stateChanged, this, [this]() {
+ date_edit_->setDisabled(expire_check_box_->checkState() != 0U);
+ });
connect(key_usage_check_boxes_[0], &QCheckBox::stateChanged, this,
&KeyGenDialog::slot_encryption_box_changed);
@@ -356,7 +377,9 @@ void KeyGenDialog::set_signal_slot() {
connect(no_pass_phrase_check_box_, &QCheckBox::stateChanged, this,
[this](int state) -> void {
gen_key_info_->SetNonPassPhrase(state != 0);
- passphrase_edit_->setDisabled(state != 0);
+ if (gen_subkey_info_ != nullptr) {
+ gen_subkey_info_->SetNonPassPhrase(state != 0);
+ }
});
}
@@ -371,10 +394,9 @@ QGroupBox* KeyGenDialog::create_basic_info_group_box() {
comment_edit_ = new QLineEdit(this);
key_size_spin_box_ = new QSpinBox(this);
key_type_combo_box_ = new QComboBox(this);
- passphrase_edit_ = new QLineEdit(this);
- for (auto& algo : GenKeyInfo::GetSupportedKeyAlgo()) {
- key_type_combo_box_->addItem(QString::fromStdString(algo.first));
+ for (const auto& algo : GenKeyInfo::GetSupportedKeyAlgo()) {
+ key_type_combo_box_->addItem(std::get<0>(algo));
}
if (!GenKeyInfo::GetSupportedKeyAlgo().empty()) {
key_type_combo_box_->setCurrentIndex(0);
@@ -391,24 +413,19 @@ QGroupBox* KeyGenDialog::create_basic_info_group_box() {
expire_check_box_ = new QCheckBox(this);
expire_check_box_->setCheckState(Qt::Unchecked);
- passphrase_edit_->setEchoMode(QLineEdit::Password);
- passphrase_edit_->setHidden(use_pinentry_);
-
no_pass_phrase_check_box_ = new QCheckBox(this);
no_pass_phrase_check_box_->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);
- if (!use_pinentry_)
- vbox1->addWidget(new QLabel(QString(_("Password")) + ": "), 6, 0);
- vbox1->addWidget(new QLabel(QString(_("Non Pass Phrase"))), 6, 3);
+ 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(name_edit_, 0, 1, 1, 3);
vbox1->addWidget(email_edit_, 1, 1, 1, 3);
@@ -417,14 +434,13 @@ QGroupBox* KeyGenDialog::create_basic_info_group_box() {
vbox1->addWidget(expire_check_box_, 3, 2);
vbox1->addWidget(key_size_spin_box_, 4, 1);
vbox1->addWidget(key_type_combo_box_, 5, 1);
- if (!use_pinentry_) vbox1->addWidget(passphrase_edit_, 6, 1);
- vbox1->addWidget(no_pass_phrase_check_box_, 6, 2);
+ vbox1->addWidget(no_pass_phrase_check_box_, 6, 1);
- auto basicInfoGroupBox = new QGroupBox();
- basicInfoGroupBox->setLayout(vbox1);
- basicInfoGroupBox->setTitle(_("Basic Information"));
+ auto* basic_info_group_box = new QGroupBox();
+ basic_info_group_box->setLayout(vbox1);
+ basic_info_group_box->setTitle(tr("Basic Information"));
- return basicInfoGroupBox;
+ return basic_info_group_box;
}
} // namespace GpgFrontend::UI
diff --git a/src/ui/dialog/key_generate/KeygenDialog.h b/src/ui/dialog/key_generate/KeygenDialog.h
index 31b5f9c7..ceab3d46 100644
--- a/src/ui/dialog/key_generate/KeygenDialog.h
+++ b/src/ui/dialog/key_generate/KeygenDialog.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,16 +19,19 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef __KEYGENDIALOG_H__
-#define __KEYGENDIALOG_H__
+#pragma once
+
+#include <memory>
-#include "core/GpgContext.h"
-#include "core/GpgGenKeyInfo.h"
+#include "core/model/GpgGenKeyInfo.h"
+#include "core/utils/MemoryUtils.h"
#include "ui/GpgFrontendUI.h"
#include "ui/dialog/GeneralDialog.h"
@@ -86,24 +89,25 @@ class KeyGenDialog : public GeneralDialog {
*/
QStringList error_messages_; ///< List of errors occurring when checking
///< entries of line edits
- std::unique_ptr<GenKeyInfo> gen_key_info_ =
- std::make_unique<GenKeyInfo>(); ///<
- QDialogButtonBox* button_box_; ///< Box for standard buttons
- QLabel* error_label_{}; ///< Label containing error message
- QLineEdit* name_edit_{}; ///< Line edit for the keys name
- QLineEdit* email_edit_{}; ///< Line edit for the keys email
- QLineEdit* comment_edit_{}; ///< Line edit for the keys comment
- QLineEdit* passphrase_edit_{}; ///<
- QSpinBox* key_size_spin_box_{}; ///< Spinbox for the keys size (in bit)
- QComboBox* key_type_combo_box_{}; ///< Combobox for Key type
- QDateTimeEdit* date_edit_{}; ///< Date edit for expiration date
- QCheckBox* expire_check_box_{}; ///< Checkbox, if key should expire
+
+ std::shared_ptr<GenKeyInfo> gen_key_info_ =
+ SecureCreateSharedObject<GenKeyInfo>(); ///<
+ std::shared_ptr<GenKeyInfo> gen_subkey_info_ = nullptr; ///<
+
+ QDialogButtonBox* button_box_; ///< Box for standard buttons
+ QLabel* error_label_{}; ///< Label containing error message
+ QLineEdit* name_edit_{}; ///< Line edit for the keys name
+ QLineEdit* email_edit_{}; ///< Line edit for the keys email
+ QLineEdit* comment_edit_{}; ///< Line edit for the keys comment
+ QSpinBox* key_size_spin_box_{}; ///< Spinbox for the keys size (in bit)
+ QComboBox* key_type_combo_box_{}; ///< Combobox for Key type
+ QDateTimeEdit* date_edit_{}; ///< Date edit for expiration date
+ QCheckBox* expire_check_box_{}; ///< Checkbox, if key should expire
QCheckBox* no_pass_phrase_check_box_{};
QGroupBox* key_usage_group_box_{}; ///< Group of Widgets detecting the usage
///< of the Key
QDateTime max_date_time_; ///<
std::vector<QCheckBox*> key_usage_check_boxes_; ///< ENCR, SIGN, CERT, AUTH
- bool use_pinentry_ = false;
/**
* @brief
@@ -182,5 +186,3 @@ class KeyGenDialog : public GeneralDialog {
};
} // namespace GpgFrontend::UI
-
-#endif // __KEYGENDIALOG_H__
diff --git a/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp b/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp
index abf17c67..eecf2a1d 100644
--- a/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp
+++ b/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,21 +19,25 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "SubkeyGenerateDialog.h"
#include <cassert>
+#include <cstddef>
-#include "core/common/CoreCommonUtil.h"
#include "core/function/GlobalSettingStation.h"
#include "core/function/gpg/GpgKeyGetter.h"
#include "core/function/gpg/GpgKeyOpera.h"
-#include "ui/SignalStation.h"
-#include "ui/dialog/WaitingDialog.h"
+#include "core/utils/CacheUtils.h"
+#include "core/utils/GpgUtils.h"
+#include "ui/UISignalStation.h"
+#include "ui/UserInterfaceUtils.h"
namespace GpgFrontend::UI {
@@ -41,14 +45,10 @@ SubkeyGenerateDialog::SubkeyGenerateDialog(const KeyId& key_id, QWidget* parent)
: GeneralDialog(typeid(SubkeyGenerateDialog).name(), parent),
key_(GpgKeyGetter::GetInstance().GetKey(key_id)) {
bool longer_expiration_date =
- GlobalSettingStation::GetInstance().LookupSettings(
- "general.longer_expiration_date", false);
-
- bool use_pinentry_as_password_input_dialog =
- GlobalSettingStation::GetInstance().LookupSettings(
- "general.use_pinentry_as_password_input_dialog", false);
-
- use_pinentry_ = use_pinentry_as_password_input_dialog;
+ GlobalSettingStation::GetInstance()
+ .GetSettings()
+ .value("basic/longer_expiration_date", false)
+ .toBool();
max_date_time_ = longer_expiration_date
? QDateTime::currentDateTime().toLocalTime().addYears(30)
@@ -63,9 +63,10 @@ SubkeyGenerateDialog::SubkeyGenerateDialog(const KeyId& key_id, QWidget* parent)
group_grid->addWidget(create_basic_info_group_box(), 0, 0);
group_grid->addWidget(key_usage_group_box_, 1, 0);
- auto* tipps_label = new QLabel(
- QString(_("Tipps: if the key pair has a passphrase, the subkey's "
- "passphrase must be equal to it.")));
+ auto* tipps_label =
+ new QLabel(tr("Tipps: if the key pair has a passphrase, the subkey's "
+ "passphrase must be equal to it."));
+ tipps_label->setWordWrap(true);
group_grid->addWidget(tipps_label);
auto* name_list = new QWidget(this);
@@ -76,34 +77,31 @@ SubkeyGenerateDialog::SubkeyGenerateDialog(const KeyId& key_id, QWidget* parent)
vbox2->addWidget(error_label_);
vbox2->addWidget(button_box_);
- this->setWindowTitle(_("Generate New Subkey"));
+ this->setWindowTitle(tr("Generate New Subkey"));
this->setLayout(vbox2);
+ this->setAttribute(Qt::WA_DeleteOnClose);
this->setModal(true);
- connect(this, &SubkeyGenerateDialog::SignalSubKeyGenerated,
- SignalStation::GetInstance(),
- &SignalStation::SignalKeyDatabaseRefresh);
-
set_signal_slot();
refresh_widgets_state();
}
QGroupBox* SubkeyGenerateDialog::create_key_usage_group_box() {
- auto* groupBox = new QGroupBox(this);
+ auto* group_box = new QGroupBox(this);
auto* grid = new QGridLayout(this);
- groupBox->setTitle(_("Key Usage"));
+ group_box->setTitle(tr("Key Usage"));
- auto* encrypt = new QCheckBox(_("Encryption"), groupBox);
+ auto* encrypt = new QCheckBox(tr("Encryption"), group_box);
encrypt->setTristate(false);
- auto* sign = new QCheckBox(_("Signing"), groupBox);
+ auto* sign = new QCheckBox(tr("Signing"), group_box);
sign->setTristate(false);
- auto* cert = new QCheckBox(_("Certification"), groupBox);
+ auto* cert = new QCheckBox(tr("Certification"), group_box);
cert->setTristate(false);
- auto* auth = new QCheckBox(_("Authentication"), groupBox);
+ auto* auth = new QCheckBox(tr("Authentication"), group_box);
auth->setTristate(false);
key_usage_check_boxes_.push_back(encrypt);
@@ -116,9 +114,9 @@ QGroupBox* SubkeyGenerateDialog::create_key_usage_group_box() {
grid->addWidget(cert, 1, 0);
grid->addWidget(auth, 1, 1);
- groupBox->setLayout(grid);
+ group_box->setLayout(grid);
- return groupBox;
+ return group_box;
}
QGroupBox* SubkeyGenerateDialog::create_basic_info_group_box() {
@@ -126,10 +124,9 @@ QGroupBox* SubkeyGenerateDialog::create_basic_info_group_box() {
key_size_spin_box_ = new QSpinBox(this);
key_type_combo_box_ = new QComboBox(this);
no_pass_phrase_check_box_ = new QCheckBox(this);
- passphrase_edit_ = new QLineEdit(this);
- for (auto& algo : GenKeyInfo::GetSupportedSubkeyAlgo()) {
- key_type_combo_box_->addItem(QString::fromStdString(algo.first));
+ for (const auto& algo : GenKeyInfo::GetSupportedSubkeyAlgo()) {
+ key_type_combo_box_->addItem(std::get<0>(algo));
}
if (!GenKeyInfo::GetSupportedSubkeyAlgo().empty()) {
key_type_combo_box_->setCurrentIndex(0);
@@ -146,31 +143,25 @@ QGroupBox* SubkeyGenerateDialog::create_basic_info_group_box() {
expire_check_box_ = new QCheckBox(this);
expire_check_box_->setCheckState(Qt::Unchecked);
- passphrase_edit_->setEchoMode(QLineEdit::Password);
- passphrase_edit_->setHidden(use_pinentry_);
-
auto* vbox1 = new QGridLayout;
- vbox1->addWidget(new QLabel(QString(_("Key Type")) + ": "), 0, 0);
- vbox1->addWidget(new QLabel(QString(_("KeySize (in Bit)")) + ": "), 1, 0);
- vbox1->addWidget(new QLabel(QString(_("Expiration Date")) + ": "), 2, 0);
- vbox1->addWidget(new QLabel(QString(_("Never Expire"))), 2, 3);
- if (!use_pinentry_)
- vbox1->addWidget(new QLabel(QString(_("Password")) + ": "), 3, 0);
- vbox1->addWidget(new QLabel(QString(_("Non Pass Phrase"))), 3, 3);
+ vbox1->addWidget(new QLabel(tr("Key Type") + ": "), 0, 0);
+ vbox1->addWidget(new QLabel(tr("KeySize (in Bit)") + ": "), 1, 0);
+ vbox1->addWidget(new QLabel(tr("Expiration Date") + ": "), 2, 0);
+ vbox1->addWidget(new QLabel(tr("Never Expire")), 2, 3);
+ vbox1->addWidget(new QLabel(tr("Non Pass Phrase")), 3, 0);
vbox1->addWidget(key_type_combo_box_, 0, 1);
vbox1->addWidget(key_size_spin_box_, 1, 1);
vbox1->addWidget(date_edit_, 2, 1);
vbox1->addWidget(expire_check_box_, 2, 2);
- if (!use_pinentry_) vbox1->addWidget(passphrase_edit_, 3, 1);
- vbox1->addWidget(no_pass_phrase_check_box_, 3, 2);
+ vbox1->addWidget(no_pass_phrase_check_box_, 3, 1);
- auto basicInfoGroupBox = new QGroupBox();
- basicInfoGroupBox->setLayout(vbox1);
- basicInfoGroupBox->setTitle(_("Basic Information"));
+ auto* basic_info_group_box = new QGroupBox();
+ basic_info_group_box->setLayout(vbox1);
+ basic_info_group_box->setTitle(tr("Basic Information"));
- return basicInfoGroupBox;
+ return basic_info_group_box;
}
void SubkeyGenerateDialog::set_signal_slot() {
@@ -197,12 +188,11 @@ void SubkeyGenerateDialog::set_signal_slot() {
connect(no_pass_phrase_check_box_, &QCheckBox::stateChanged, this,
[this](int state) -> void {
gen_key_info_->SetNonPassPhrase(state != 0);
- passphrase_edit_->setDisabled(state != 0);
});
}
void SubkeyGenerateDialog::slot_expire_box_changed() {
- if (expire_check_box_->checkState()) {
+ if (expire_check_box_->checkState() != 0U) {
date_edit_->setEnabled(false);
} else {
date_edit_->setEnabled(true);
@@ -210,124 +200,116 @@ void SubkeyGenerateDialog::slot_expire_box_changed() {
}
void SubkeyGenerateDialog::refresh_widgets_state() {
- if (gen_key_info_->IsAllowEncryption())
+ if (gen_key_info_->IsAllowEncryption()) {
key_usage_check_boxes_[0]->setCheckState(Qt::CheckState::Checked);
- else
+ } else {
key_usage_check_boxes_[0]->setCheckState(Qt::CheckState::Unchecked);
+ }
- if (gen_key_info_->IsAllowChangeEncryption())
+ if (gen_key_info_->IsAllowChangeEncryption()) {
key_usage_check_boxes_[0]->setDisabled(false);
- else
+ } else {
key_usage_check_boxes_[0]->setDisabled(true);
+ }
- if (gen_key_info_->IsAllowSigning())
+ if (gen_key_info_->IsAllowSigning()) {
key_usage_check_boxes_[1]->setCheckState(Qt::CheckState::Checked);
- else
+ } else {
key_usage_check_boxes_[1]->setCheckState(Qt::CheckState::Unchecked);
+ }
- if (gen_key_info_->IsAllowChangeSigning())
+ if (gen_key_info_->IsAllowChangeSigning()) {
key_usage_check_boxes_[1]->setDisabled(false);
- else
+ } else {
key_usage_check_boxes_[1]->setDisabled(true);
+ }
- if (gen_key_info_->IsAllowCertification())
+ if (gen_key_info_->IsAllowCertification()) {
key_usage_check_boxes_[2]->setCheckState(Qt::CheckState::Checked);
- else
+ } else {
key_usage_check_boxes_[2]->setCheckState(Qt::CheckState::Unchecked);
+ }
- if (gen_key_info_->IsAllowChangeCertification())
+ if (gen_key_info_->IsAllowChangeCertification()) {
key_usage_check_boxes_[2]->setDisabled(false);
- else
+ } else {
key_usage_check_boxes_[2]->setDisabled(true);
+ }
- if (gen_key_info_->IsAllowAuthentication())
+ if (gen_key_info_->IsAllowAuthentication()) {
key_usage_check_boxes_[3]->setCheckState(Qt::CheckState::Checked);
- else
+ } else {
key_usage_check_boxes_[3]->setCheckState(Qt::CheckState::Unchecked);
+ }
- if (gen_key_info_->IsAllowChangeAuthentication())
+ if (gen_key_info_->IsAllowChangeAuthentication()) {
key_usage_check_boxes_[3]->setDisabled(false);
- else
+ } else {
key_usage_check_boxes_[3]->setDisabled(true);
+ }
- key_size_spin_box_->setRange(gen_key_info_->GetSuggestMinKeySize(),
- gen_key_info_->GetSuggestMaxKeySize());
- key_size_spin_box_->setValue(gen_key_info_->GetKeyLength());
- key_size_spin_box_->setSingleStep(gen_key_info_->GetSizeChangeStep());
+ if (gen_key_info_->GetSuggestMinKeySize() == -1 ||
+ gen_key_info_->GetSuggestMaxKeySize() == -1) {
+ key_size_spin_box_->setDisabled(true);
+ key_size_spin_box_->setRange(0, 0);
+ key_size_spin_box_->setValue(0);
+ key_size_spin_box_->setSingleStep(0);
+ } else {
+ key_size_spin_box_->setDisabled(false);
+ key_size_spin_box_->setRange(gen_key_info_->GetSuggestMinKeySize(),
+ gen_key_info_->GetSuggestMaxKeySize());
+ key_size_spin_box_->setValue(gen_key_info_->GetKeyLength());
+ key_size_spin_box_->setSingleStep(gen_key_info_->GetSizeChangeStep());
+ }
}
void SubkeyGenerateDialog::slot_key_gen_accept() {
- std::stringstream err_stream;
+ QString buffer;
+ QTextStream err_stream(&buffer);
/**
* primary keys should have a reasonable expiration date (no more than 2 years
* in the future)
*/
if (date_edit_->dateTime() > QDateTime::currentDateTime().addYears(2)) {
- err_stream << " " << _("Expiration time no more than 2 years.") << " ";
+ err_stream << " " << tr("Expiration time no more than 2 years.") << " ";
}
- if (!use_pinentry_ && passphrase_edit_->isEnabled() &&
- passphrase_edit_->text().size() == 0) {
- err_stream << " " << _("Password is empty.") << std::endl;
- }
-
- auto err_string = err_stream.str();
+ auto err_string = err_stream.readAll();
- if (err_string.empty()) {
+ if (err_string.isEmpty()) {
gen_key_info_->SetKeyLength(key_size_spin_box_->value());
- if (expire_check_box_->checkState()) {
+ if (expire_check_box_->checkState() != 0U) {
gen_key_info_->SetNonExpired(true);
} else {
-#ifdef GPGFRONTEND_GUI_QT6
- gen_key_info_->SetExpireTime(boost::posix_time::from_time_t(
- date_edit_->dateTime().toSecsSinceEpoch()));
-#else
- gen_key_info_->SetExpireTime(
- boost::posix_time::from_time_t(date_edit_->dateTime().toTime_t()));
-#endif
- }
-
- if (!use_pinentry_ && !gen_key_info_->IsNoPassPhrase()) {
- CoreCommonUtil::GetInstance()->SetTempCacheValue(
- "__key_passphrase", this->passphrase_edit_->text().toStdString());
+ gen_key_info_->SetExpireTime(date_edit_->dateTime());
}
- GpgError error;
- // TODO: remove plain qt thread usage
- auto thread = QThread::create([&]() {
- SPDLOG_DEBUG("thread started");
- error = GpgKeyOpera::GetInstance().GenerateSubkey(key_, gen_key_info_);
- });
- thread->start();
-
- auto* waiting_dialog = new WaitingDialog(_("Generating"), this);
- waiting_dialog->show();
-
- while (thread->isRunning()) {
- QCoreApplication::processEvents();
- }
- waiting_dialog->close();
-
- if (!use_pinentry_ && !gen_key_info_->IsNoPassPhrase()) {
- CoreCommonUtil::GetInstance()->ResetTempCacheValue("__key_passphrase");
- }
-
- if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR) {
- auto* msg_box = new QMessageBox(qobject_cast<QWidget*>(this->parent()));
- 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(true);
- msg_box->open();
-
- emit SignalSubKeyGenerated();
- this->close();
- } else {
- QMessageBox::critical(this, _("Failure"), _("Failed to generate key."));
- }
+ CommonUtils::WaitForOpera(
+ this, tr("Generating"),
+ [this, key = this->key_,
+ gen_key_info = this->gen_key_info_](const OperaWaitingHd& hd) {
+ GpgKeyOpera::GetInstance().GenerateSubkey(
+ key, gen_key_info,
+ [this, hd](GpgError err, const DataObjectPtr&) {
+ // stop showing waiting dialog
+ hd();
+
+ if (CheckGpgError(err) == GPG_ERR_USER_1) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unknown error occurred"));
+ return;
+ }
+
+ CommonUtils::RaiseMessageBox(this, err);
+ if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
+ emit UISignalStation::GetInstance()
+ ->SignalKeyDatabaseRefresh();
+ }
+ });
+ });
+ this->done(0);
} else {
/**
@@ -337,7 +319,7 @@ void SubkeyGenerateDialog::slot_key_gen_accept() {
QPalette error = error_label_->palette();
error.setColor(QPalette::Window, "#ff8080");
error_label_->setPalette(error);
- error_label_->setText(err_string.c_str());
+ error_label_->setText(err_string);
this->show();
}
@@ -376,11 +358,13 @@ void SubkeyGenerateDialog::slot_authentication_box_changed(int state) {
}
void SubkeyGenerateDialog::slot_activated_key_type(int index) {
- SPDLOG_DEBUG("key type index changed: {}", index);
+ GF_UI_LOG_DEBUG("key type index changed: {}", index);
// check
- assert(gen_key_info_->GetSupportedSubkeyAlgo().size() > index);
- gen_key_info_->SetAlgo(gen_key_info_->GetSupportedSubkeyAlgo()[index]);
+ assert(gen_key_info_->GetSupportedSubkeyAlgo().size() >
+ static_cast<size_t>(index));
+ gen_key_info_->SetAlgo(
+ std::get<2>(gen_key_info_->GetSupportedSubkeyAlgo()[index]));
refresh_widgets_state();
}
diff --git a/src/ui/dialog/key_generate/SubkeyGenerateDialog.h b/src/ui/dialog/key_generate/SubkeyGenerateDialog.h
index 2b88bd61..be39669c 100644
--- a/src/ui/dialog/key_generate/SubkeyGenerateDialog.h
+++ b/src/ui/dialog/key_generate/SubkeyGenerateDialog.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,16 +19,22 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_SUBKEYGENERATEDIALOG_H
-#define GPGFRONTEND_SUBKEYGENERATEDIALOG_H
+#pragma once
+
+#include <memory>
-#include "core/GpgContext.h"
-#include "core/GpgGenKeyInfo.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/model/GpgGenKeyInfo.h"
+#include "core/model/GpgKey.h"
+#include "core/typedef/GpgTypedef.h"
+#include "core/utils/MemoryUtils.h"
#include "ui/GpgFrontendUI.h"
#include "ui/dialog/GeneralDialog.h"
@@ -49,18 +55,11 @@ class SubkeyGenerateDialog : public GeneralDialog {
*/
explicit SubkeyGenerateDialog(const KeyId& key_id, QWidget* parent);
- signals:
- /**
- * @brief
- *
- */
- void SignalSubKeyGenerated();
-
private:
GpgKey key_; ///<
- std::unique_ptr<GenKeyInfo> gen_key_info_ =
- std::make_unique<GenKeyInfo>(true); ///<
+ std::shared_ptr<GenKeyInfo> gen_key_info_ =
+ SecureCreateSharedObject<GenKeyInfo>(true); ///<
QGroupBox* key_usage_group_box_{};
QDialogButtonBox* button_box_; ///< Box for standard buttons
@@ -70,11 +69,9 @@ class SubkeyGenerateDialog : public GeneralDialog {
QDateTimeEdit* date_edit_{}; ///< Date edit for expiration date
QCheckBox* expire_check_box_{}; ///< Checkbox, if key should expire
QCheckBox* no_pass_phrase_check_box_{}; ///< Checkbox, if key should expire
- QLineEdit* passphrase_edit_{};
std::vector<QCheckBox*> key_usage_check_boxes_; ///< ENCR, SIGN, CERT, AUTH
QDateTime max_date_time_; ///<
- bool use_pinentry_ = false;
/**
* @brief Create a key usage group box object
@@ -151,5 +148,3 @@ class SubkeyGenerateDialog : public GeneralDialog {
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_SUBKEYGENERATEDIALOG_H
diff --git a/src/ui/dialog/keypair_details/KeyDetailsDialog.cpp b/src/ui/dialog/keypair_details/KeyDetailsDialog.cpp
index 9ac60a73..6908592b 100644
--- a/src/ui/dialog/keypair_details/KeyDetailsDialog.cpp
+++ b/src/ui/dialog/keypair_details/KeyDetailsDialog.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,32 +28,33 @@
#include "KeyDetailsDialog.h"
-#include "KeyPairDetailTab.h"
-#include "KeyPairOperaTab.h"
-#include "KeyPairSubkeyTab.h"
-#include "KeyPairUIDTab.h"
+#include "core/GpgModel.h"
+#include "ui/dialog/keypair_details/KeyPairDetailTab.h"
+#include "ui/dialog/keypair_details/KeyPairOperaTab.h"
+#include "ui/dialog/keypair_details/KeyPairSubkeyTab.h"
+#include "ui/dialog/keypair_details/KeyPairUIDTab.h"
namespace GpgFrontend::UI {
KeyDetailsDialog::KeyDetailsDialog(const GpgKey& key, QWidget* parent)
: GeneralDialog(typeid(KeyDetailsDialog).name(), parent) {
tab_widget_ = new QTabWidget();
tab_widget_->addTab(new KeyPairDetailTab(key.GetId(), tab_widget_),
- _("KeyPair"));
- tab_widget_->addTab(new KeyPairUIDTab(key.GetId(), tab_widget_), _("UIDs"));
+ tr("KeyPair"));
+ tab_widget_->addTab(new KeyPairUIDTab(key.GetId(), tab_widget_), tr("UIDs"));
tab_widget_->addTab(new KeyPairSubkeyTab(key.GetId(), tab_widget_),
- _("Subkeys"));
+ tr("Subkeys"));
tab_widget_->addTab(new KeyPairOperaTab(key.GetId(), tab_widget_),
- _("Operations"));
+ tr("Operations"));
- auto* mainLayout = new QVBoxLayout;
- mainLayout->addWidget(tab_widget_);
+ auto* main_layout = new QVBoxLayout;
+ main_layout->addWidget(tab_widget_);
#ifdef MACOS
setAttribute(Qt::WA_LayoutUsesWidgetRect);
#endif
this->setAttribute(Qt::WA_DeleteOnClose, true);
- this->setLayout(mainLayout);
- this->setWindowTitle(_("Key Details"));
+ this->setLayout(main_layout);
+ this->setWindowTitle(tr("Key Details"));
this->setModal(true);
this->show();
diff --git a/src/ui/dialog/keypair_details/KeyDetailsDialog.h b/src/ui/dialog/keypair_details/KeyDetailsDialog.h
index 1ddcda00..1c72ce98 100644
--- a/src/ui/dialog/keypair_details/KeyDetailsDialog.h
+++ b/src/ui/dialog/keypair_details/KeyDetailsDialog.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,16 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef __KEYDETAILSDIALOG_H__
-#define __KEYDETAILSDIALOG_H__
+#pragma once
-#include "core/GpgContext.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/typedef/GpgTypedef.h"
#include "ui/GpgFrontendUI.h"
#include "ui/dialog/GeneralDialog.h"
@@ -45,5 +45,3 @@ class KeyDetailsDialog : public GeneralDialog {
QTabWidget* tab_widget_{};
};
} // namespace GpgFrontend::UI
-
-#endif // __KEYDETAILSDIALOG_H__
diff --git a/src/ui/dialog/keypair_details/KeyNewUIDDialog.cpp b/src/ui/dialog/keypair_details/KeyNewUIDDialog.cpp
index 18dd1967..cd3c0f29 100644
--- a/src/ui/dialog/keypair_details/KeyNewUIDDialog.cpp
+++ b/src/ui/dialog/keypair_details/KeyNewUIDDialog.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,16 +19,19 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "KeyNewUIDDialog.h"
+#include "core/GpgModel.h"
#include "core/function/gpg/GpgKeyGetter.h"
#include "core/function/gpg/GpgUIDOperator.h"
-#include "ui/SignalStation.h"
+#include "ui/UISignalStation.h"
namespace GpgFrontend::UI {
KeyNewUIDDialog::KeyNewUIDDialog(const KeyId& key_id, QWidget* parent)
@@ -44,9 +47,9 @@ KeyNewUIDDialog::KeyNewUIDDialog(const KeyId& key_id, QWidget* parent)
error_label_ = 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(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);
@@ -54,7 +57,7 @@ KeyNewUIDDialog::KeyNewUIDDialog(const KeyId& key_id, QWidget* parent)
gridLayout->addWidget(create_button_, 3, 0, 1, 2);
gridLayout->addWidget(
- new QLabel(_("Notice: The New UID Created will be set as Primary.")), 4,
+ new QLabel(tr("Notice: The New UID Created will be set as Primary.")), 4,
0, 1, 2);
gridLayout->addWidget(error_label_, 5, 0, 1, 2);
@@ -62,37 +65,38 @@ KeyNewUIDDialog::KeyNewUIDDialog(const KeyId& key_id, QWidget* parent)
&KeyNewUIDDialog::slot_create_new_uid);
this->setLayout(gridLayout);
- this->setWindowTitle(_("Create New UID"));
+ this->setWindowTitle(tr("Create New UID"));
this->setAttribute(Qt::WA_DeleteOnClose, true);
this->setModal(true);
connect(this, &KeyNewUIDDialog::SignalUIDCreated,
- SignalStation::GetInstance(),
- &SignalStation::SignalKeyDatabaseRefresh);
+ UISignalStation::GetInstance(),
+ &UISignalStation::SignalKeyDatabaseRefresh);
}
void KeyNewUIDDialog::slot_create_new_uid() {
- std::stringstream error_stream;
+ QString buffer;
+ QTextStream error_stream(&buffer);
/**
* check for errors in keygen dialog input
*/
if ((name_->text()).size() < 5) {
- error_stream << " " << _("Name must contain at least five characters.")
- << std::endl;
+ error_stream << " " << tr("Name must contain at least five characters.")
+ << Qt::endl;
}
if (email_->text().isEmpty() || !check_email_address(email_->text())) {
- error_stream << " " << _("Please give a email address.") << std::endl;
+ error_stream << " " << tr("Please give a email address.") << Qt::endl;
}
- auto error_string = error_stream.str();
- if (error_string.empty()) {
+ auto error_string = error_stream.readAll();
+ if (error_string.isEmpty()) {
if (GpgUIDOperator::GetInstance().AddUID(
- m_key_, name_->text().toStdString(), comment_->text().toStdString(),
- email_->text().toStdString())) {
+ m_key_, name_->text(), comment_->text(), email_->text())) {
emit finished(1);
emit SignalUIDCreated();
- } else
+ } else {
emit finished(-1);
+ }
} else {
/**
@@ -102,7 +106,7 @@ void KeyNewUIDDialog::slot_create_new_uid() {
QPalette error = error_label_->palette();
error.setColor(QPalette::Window, "#ff8080");
error_label_->setPalette(error);
- error_label_->setText(error_string.c_str());
+ error_label_->setText(error_string);
this->show();
}
diff --git a/src/ui/dialog/keypair_details/KeyNewUIDDialog.h b/src/ui/dialog/keypair_details/KeyNewUIDDialog.h
index 291b59c4..ab1bb5e1 100644
--- a/src/ui/dialog/keypair_details/KeyNewUIDDialog.h
+++ b/src/ui/dialog/keypair_details/KeyNewUIDDialog.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,15 +19,18 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_KEYNEWUIDDIALOG_H
-#define GPGFRONTEND_KEYNEWUIDDIALOG_H
+#pragma once
-#include "core/GpgContext.h"
+#include "core/function/gpg/GpgContext.h"
+#include "core/model/GpgKey.h"
+#include "core/typedef/GpgTypedef.h"
#include "ui/GpgFrontendUI.h"
#include "ui/dialog/GeneralDialog.h"
@@ -84,5 +87,3 @@ class KeyNewUIDDialog : public GeneralDialog {
bool check_email_address(const QString& str);
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_KEYNEWUIDDIALOG_H
diff --git a/src/ui/dialog/keypair_details/KeyPairDetailTab.cpp b/src/ui/dialog/keypair_details/KeyPairDetailTab.cpp
index 578e3279..a91b5fd4 100644
--- a/src/ui/dialog/keypair_details/KeyPairDetailTab.cpp
+++ b/src/ui/dialog/keypair_details/KeyPairDetailTab.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,29 +19,28 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "KeyPairDetailTab.h"
+#include "core/GpgModel.h"
#include "core/function/gpg/GpgKeyGetter.h"
-#include "core/function/gpg/GpgKeyImportExporter.h"
#include "core/model/GpgKey.h"
-#include "dialog/WaitingDialog.h"
-#include "ui/SignalStation.h"
+#include "core/utils/CommonUtils.h"
+#include "ui/UISignalStation.h"
namespace GpgFrontend::UI {
-KeyPairDetailTab::KeyPairDetailTab(const std::string& key_id, QWidget* parent)
+KeyPairDetailTab::KeyPairDetailTab(const QString& key_id, QWidget* parent)
: QWidget(parent), key_(GpgKeyGetter::GetInstance().GetKey(key_id)) {
- SPDLOG_DEBUG(key_.GetEmail(), key_.IsPrivateKey(), key_.IsHasMasterKey(),
- key_.GetSubKeys()->front().IsPrivateKey());
-
- owner_box_ = new QGroupBox(_("Owner"));
- key_box_ = new QGroupBox(_("Primary Key"));
- fingerprint_box_ = new QGroupBox(_("Fingerprint"));
- additional_uid_box_ = new QGroupBox(_("Additional UIDs"));
+ owner_box_ = new QGroupBox(tr("Owner"));
+ key_box_ = new QGroupBox(tr("Primary Key"));
+ fingerprint_box_ = new QGroupBox(tr("Fingerprint"));
+ additional_uid_box_ = new QGroupBox(tr("Additional UIDs"));
name_var_label_ = new QLabel();
name_var_label_->setTextInteractionFlags(Qt::TextSelectableByMouse);
@@ -65,56 +64,52 @@ KeyPairDetailTab::KeyPairDetailTab(const std::string& key_id, QWidget* parent)
primary_key_exist_var_label_ = new QLabel();
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(name_var_label_, 0, 1);
- vboxOD->addWidget(email_var_label_, 1, 1);
- vboxOD->addWidget(comment_var_label_, 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(_("Owner Trust Level")) + ": "), 5, 0);
- vboxKD->addWidget(new QLabel(QString(_("Create Date (Local Time)")) + ": "),
- 6, 0);
- vboxKD->addWidget(new QLabel(QString(_("Expires on (Local Time)")) + ": "), 7,
- 0);
- vboxKD->addWidget(new QLabel(QString(_("Last Update (Local Time)")) + ": "),
- 8, 0);
- vboxKD->addWidget(new QLabel(QString(_("Primary Key Existence")) + ": "), 9,
- 0);
+ auto* vbox_kd = new QGridLayout();
+ auto* vbox_od = new QGridLayout();
+
+ vbox_od->addWidget(new QLabel(tr("Name") + ": "), 0, 0);
+ vbox_od->addWidget(new QLabel(tr("Email Address") + ": "), 1, 0);
+ vbox_od->addWidget(new QLabel(tr("Comment") + ": "), 2, 0);
+ vbox_od->addWidget(name_var_label_, 0, 1);
+ vbox_od->addWidget(email_var_label_, 1, 1);
+ vbox_od->addWidget(comment_var_label_, 2, 1);
+
+ vbox_kd->addWidget(new QLabel(tr("Key ID") + ": "), 0, 0);
+ vbox_kd->addWidget(new QLabel(tr("Algorithm") + ": "), 1, 0);
+ vbox_kd->addWidget(new QLabel(tr("Key Size") + ": "), 2, 0);
+ vbox_kd->addWidget(new QLabel(tr("Nominal Usage") + ": "), 3, 0);
+ vbox_kd->addWidget(new QLabel(tr("Actual Usage") + ": "), 4, 0);
+ vbox_kd->addWidget(new QLabel(tr("Owner Trust Level") + ": "), 5, 0);
+ vbox_kd->addWidget(new QLabel(tr("Create Date (Local Time)") + ": "), 6, 0);
+ vbox_kd->addWidget(new QLabel(tr("Expires on (Local Time)") + ": "), 7, 0);
+ vbox_kd->addWidget(new QLabel(tr("Last Update (Local Time)") + ": "), 8, 0);
+ vbox_kd->addWidget(new QLabel(tr("Primary Key Existence") + ": "), 9, 0);
key_id_var_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
- vboxKD->addWidget(key_id_var_label, 0, 1, 1, 1);
- vboxKD->addWidget(algorithm_var_label_, 1, 1, 1, 2);
- vboxKD->addWidget(key_size_var_label_, 2, 1, 1, 2);
- vboxKD->addWidget(usage_var_label_, 3, 1, 1, 2);
- vboxKD->addWidget(actual_usage_var_label_, 4, 1, 1, 2);
- vboxKD->addWidget(owner_trust_var_label_, 5, 1, 1, 2);
- vboxKD->addWidget(created_var_label_, 6, 1, 1, 2);
- vboxKD->addWidget(expire_var_label_, 7, 1, 1, 2);
- vboxKD->addWidget(last_update_var_label_, 8, 1, 1, 2);
- vboxKD->addWidget(primary_key_exist_var_label_, 9, 1, 1, 2);
-
- auto* copyKeyIdButton = new QPushButton(_("Copy"));
- copyKeyIdButton->setFlat(true);
- copyKeyIdButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
- vboxKD->addWidget(copyKeyIdButton, 0, 2);
- connect(copyKeyIdButton, &QPushButton::clicked, this, [=]() {
+ vbox_kd->addWidget(key_id_var_label, 0, 1, 1, 1);
+ vbox_kd->addWidget(algorithm_var_label_, 1, 1, 1, 2);
+ vbox_kd->addWidget(key_size_var_label_, 2, 1, 1, 2);
+ vbox_kd->addWidget(usage_var_label_, 3, 1, 1, 2);
+ vbox_kd->addWidget(actual_usage_var_label_, 4, 1, 1, 2);
+ vbox_kd->addWidget(owner_trust_var_label_, 5, 1, 1, 2);
+ vbox_kd->addWidget(created_var_label_, 6, 1, 1, 2);
+ vbox_kd->addWidget(expire_var_label_, 7, 1, 1, 2);
+ vbox_kd->addWidget(last_update_var_label_, 8, 1, 1, 2);
+ vbox_kd->addWidget(primary_key_exist_var_label_, 9, 1, 1, 2);
+
+ auto* copy_key_id_button = new QPushButton(tr("Copy"));
+ copy_key_id_button->setFlat(true);
+ copy_key_id_button->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
+ vbox_kd->addWidget(copy_key_id_button, 0, 2);
+ connect(copy_key_id_button, &QPushButton::clicked, this, [=]() {
QString fpr = key_id_var_label->text().trimmed();
QClipboard* cb = QApplication::clipboard();
cb->setText(fpr);
});
- owner_box_->setLayout(vboxOD);
+ owner_box_->setLayout(vbox_od);
mvbox->addWidget(owner_box_);
- key_box_->setLayout(vboxKD);
+ key_box_->setLayout(vbox_kd);
mvbox->addWidget(key_box_);
fingerprint_var_label_ = new QLabel();
@@ -122,26 +117,26 @@ KeyPairDetailTab::KeyPairDetailTab(const std::string& key_id, QWidget* parent)
fingerprint_var_label_->setTextInteractionFlags(Qt::TextSelectableByMouse);
fingerprint_var_label_->setStyleSheet("margin-left: 0; margin-right: 5;");
fingerprint_var_label_->setAlignment(Qt::AlignCenter);
- auto* hboxFP = new QHBoxLayout();
+ auto* hbox_fp = new QHBoxLayout();
- hboxFP->addStretch();
- hboxFP->addWidget(fingerprint_var_label_);
+ hbox_fp->addStretch();
+ hbox_fp->addWidget(fingerprint_var_label_);
- auto* copyFingerprintButton = new QPushButton(_("Copy"));
- copyFingerprintButton->setFlat(true);
- copyFingerprintButton->setToolTip(_("copy fingerprint to clipboard"));
- connect(copyFingerprintButton, &QPushButton::clicked, this,
+ auto* copy_fingerprint_button = new QPushButton(tr("Copy"));
+ copy_fingerprint_button->setFlat(true);
+ copy_fingerprint_button->setToolTip(tr("copy fingerprint to clipboard"));
+ connect(copy_fingerprint_button, &QPushButton::clicked, this,
&KeyPairDetailTab::slot_copy_fingerprint);
- hboxFP->addWidget(copyFingerprintButton);
- hboxFP->addStretch();
+ hbox_fp->addWidget(copy_fingerprint_button);
+ hbox_fp->addStretch();
- fingerprint_box_->setLayout(hboxFP);
+ fingerprint_box_->setLayout(hbox_fp);
mvbox->addWidget(fingerprint_box_);
mvbox->addStretch();
auto* expBox = new QHBoxLayout();
- QPixmap pixmap(":warning.png");
+ QPixmap pixmap(":/icons/warning.png");
exp_label_ = new QLabel();
icon_label_ = new QLabel();
@@ -156,8 +151,8 @@ KeyPairDetailTab::KeyPairDetailTab(const std::string& key_id, QWidget* parent)
mvbox->setContentsMargins(0, 0, 0, 0);
// when key database updated
- connect(SignalStation::GetInstance(),
- &SignalStation::SignalKeyDatabaseRefreshDone, this,
+ connect(UISignalStation::GetInstance(),
+ &UISignalStation::SignalKeyDatabaseRefreshDone, this,
&KeyPairDetailTab::slot_refresh_key);
slot_refresh_key_info();
@@ -175,7 +170,7 @@ void KeyPairDetailTab::slot_copy_fingerprint() {
void KeyPairDetailTab::slot_refresh_key_info() {
// Show the situation that primary key not exists.
primary_key_exist_var_label_->setText(
- key_.IsHasMasterKey() ? _("Exists") : _("Not Exists"));
+ key_.IsHasMasterKey() ? tr("Exists") : tr("Not Exists"));
if (!key_.IsHasMasterKey()) {
auto palette_expired = primary_key_exist_var_label_->palette();
palette_expired.setColor(primary_key_exist_var_label_->foregroundRole(),
@@ -189,89 +184,81 @@ void KeyPairDetailTab::slot_refresh_key_info() {
}
if (key_.IsExpired()) {
- auto paletteExpired = expire_var_label_->palette();
- paletteExpired.setColor(expire_var_label_->foregroundRole(), Qt::red);
- expire_var_label_->setPalette(paletteExpired);
+ auto palette_expired = expire_var_label_->palette();
+ palette_expired.setColor(expire_var_label_->foregroundRole(), Qt::red);
+ expire_var_label_->setPalette(palette_expired);
} else {
- auto paletteValid = expire_var_label_->palette();
- paletteValid.setColor(expire_var_label_->foregroundRole(), Qt::darkGreen);
- expire_var_label_->setPalette(paletteValid);
+ auto palette_valid = expire_var_label_->palette();
+ palette_valid.setColor(expire_var_label_->foregroundRole(), Qt::darkGreen);
+ expire_var_label_->setPalette(palette_valid);
}
- name_var_label_->setText(QString::fromStdString(key_.GetName()));
- email_var_label_->setText(QString::fromStdString(key_.GetEmail()));
+ name_var_label_->setText(key_.GetName());
+ email_var_label_->setText(key_.GetEmail());
- comment_var_label_->setText(QString::fromStdString(key_.GetComment()));
- key_id_var_label->setText(QString::fromStdString(key_.GetId()));
+ comment_var_label_->setText(key_.GetComment());
+ key_id_var_label->setText(key_.GetId());
- std::stringstream usage_steam;
+ QString buffer;
+ QTextStream usage_steam(&buffer);
- if (key_.IsHasCertificationCapability())
- usage_steam << _("Certificate") << " ";
- if (key_.IsHasEncryptionCapability()) usage_steam << _("Encrypt") << " ";
- if (key_.IsHasSigningCapability()) usage_steam << _("Sign") << " ";
- if (key_.IsHasAuthenticationCapability()) usage_steam << _("Auth") << " ";
+ if (key_.IsHasCertificationCapability()) {
+ usage_steam << tr("Certificate") << " ";
+ }
+ if (key_.IsHasEncryptionCapability()) usage_steam << tr("Encrypt") << " ";
+ if (key_.IsHasSigningCapability()) usage_steam << tr("Sign") << " ";
+ if (key_.IsHasAuthenticationCapability()) usage_steam << tr("Auth") << " ";
- usage_var_label_->setText(usage_steam.str().c_str());
+ usage_var_label_->setText(usage_steam.readAll());
- std::stringstream actual_usage_steam;
+ QString buffer_2;
+ QTextStream actual_usage_steam(&buffer_2);
- if (key_.IsHasActualCertificationCapability())
- actual_usage_steam << _("Certificate") << " ";
- if (key_.IsHasActualEncryptionCapability())
- actual_usage_steam << _("Encrypt") << " ";
- if (key_.IsHasActualSigningCapability())
- actual_usage_steam << _("Sign") << " ";
- if (key_.IsHasActualAuthenticationCapability())
- actual_usage_steam << _("Auth") << " ";
+ if (key_.IsHasActualCertificationCapability()) {
+ actual_usage_steam << tr("Certificate") << " ";
+ }
+ if (key_.IsHasActualEncryptionCapability()) {
+ actual_usage_steam << tr("Encrypt") << " ";
+ }
+ if (key_.IsHasActualSigningCapability()) {
+ actual_usage_steam << tr("Sign") << " ";
+ }
+ if (key_.IsHasActualAuthenticationCapability()) {
+ actual_usage_steam << tr("Auth") << " ";
+ }
- actual_usage_var_label_->setText(
- QString::fromStdString(actual_usage_steam.str()));
- owner_trust_var_label_->setText(QString::fromStdString(key_.GetOwnerTrust()));
+ actual_usage_var_label_->setText(actual_usage_steam.readAll());
+ owner_trust_var_label_->setText(key_.GetOwnerTrust());
- std::string key_size_val, key_expire_val, key_create_time_val, key_algo_val,
- key_last_update_val;
+ QString key_size_val;
+ QString key_expire_val;
+ QString key_create_time_val;
+ QString key_algo_val;
+ QString key_last_update_val;
- key_size_val = std::to_string(key_.GetPrimaryKeyLength());
+ key_size_val = QString::number(key_.GetPrimaryKeyLength());
- if (to_time_t(boost::posix_time::ptime(key_.GetExpireTime())) == 0) {
- expire_var_label_->setText(_("Never Expire"));
+ if (key_.GetExpireTime().toSecsSinceEpoch() == 0) {
+ expire_var_label_->setText(tr("Never Expire"));
} else {
-#ifdef GPGFRONTEND_GUI_QT6
- expire_var_label_->setText(QLocale::system().toString(
- QDateTime::fromSecsSinceEpoch(to_time_t(key_.GetExpireTime()))));
-#else
- expire_var_label_->setText(QLocale::system().toString(
- QDateTime::fromTime_t(to_time_t(key_.GetExpireTime()))));
-#endif
+ expire_var_label_->setText(
+ QLocale::system().toString((key_.GetExpireTime())));
}
key_algo_val = key_.GetPublicKeyAlgo();
-#ifdef GPGFRONTEND_GUI_QT6
- created_var_label_->setText(QLocale::system().toString(
- QDateTime::fromSecsSinceEpoch(to_time_t(key_.GetCreateTime()))));
-#else
- created_var_label_->setText(QLocale::system().toString(
- QDateTime::fromTime_t(to_time_t(key_.GetCreateTime()))));
-#endif
+ created_var_label_->setText(QLocale::system().toString(key_.GetCreateTime()));
- if (to_time_t(boost::posix_time::ptime(key_.GetLastUpdateTime())) == 0) {
- last_update_var_label_->setText(_("No Data"));
+ if (key_.GetLastUpdateTime().toSecsSinceEpoch() == 0) {
+ last_update_var_label_->setText(tr("No Data"));
} else {
-#ifdef GPGFRONTEND_GUI_QT6
- last_update_var_label_->setText(QLocale::system().toString(
- QDateTime::fromSecsSinceEpoch(to_time_t(key_.GetLastUpdateTime()))));
-#else
- last_update_var_label_->setText(QLocale::system().toString(
- QDateTime::fromTime_t(to_time_t(key_.GetLastUpdateTime()))));
-#endif
+ last_update_var_label_->setText(
+ QLocale::system().toString(key_.GetLastUpdateTime()));
}
- key_size_var_label_->setText(key_size_val.c_str());
- algorithm_var_label_->setText(key_algo_val.c_str());
- fingerprint_var_label_->setText(
- beautify_fingerprint(key_.GetFingerprint()).c_str());
+ key_size_var_label_->setText(key_size_val);
+ algorithm_var_label_->setText(key_algo_val);
+ fingerprint_var_label_->setText(BeautifyFingerprint(key_.GetFingerprint()));
icon_label_->hide();
exp_label_->hide();
@@ -279,12 +266,12 @@ void KeyPairDetailTab::slot_refresh_key_info() {
if (key_.IsExpired()) {
icon_label_->show();
exp_label_->show();
- exp_label_->setText(_("Warning: The primary key has expired."));
+ exp_label_->setText(tr("Warning: The primary key has expired."));
}
if (key_.IsRevoked()) {
icon_label_->show();
exp_label_->show();
- exp_label_->setText(_("Warning: The primary key has been revoked."));
+ exp_label_->setText(tr("Warning: The primary key has been revoked."));
}
}
diff --git a/src/ui/dialog/keypair_details/KeyPairDetailTab.h b/src/ui/dialog/keypair_details/KeyPairDetailTab.h
index efa3269c..b12f108c 100644
--- a/src/ui/dialog/keypair_details/KeyPairDetailTab.h
+++ b/src/ui/dialog/keypair_details/KeyPairDetailTab.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,16 +19,17 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_KEYPAIRDETAILTAB_H
-#define GPGFRONTEND_KEYPAIRDETAILTAB_H
+#pragma once
#include "KeySetExpireDateDialog.h"
-#include "core/GpgContext.h"
+#include "core/function/gpg/GpgContext.h"
#include "ui/GpgFrontendUI.h"
#include "ui/dialog/import_export/KeyServerImportDialog.h"
#include "ui/dialog/import_export/KeyUploadDialog.h"
@@ -91,10 +92,7 @@ class KeyPairDetailTab : public QWidget {
* @param key_id
* @param parent
*/
- explicit KeyPairDetailTab(const std::string& key_id,
- QWidget* parent = nullptr);
+ explicit KeyPairDetailTab(const QString& key_id, QWidget* parent = nullptr);
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_KEYPAIRDETAILTAB_H
diff --git a/src/ui/dialog/keypair_details/KeyPairOperaTab.cpp b/src/ui/dialog/keypair_details/KeyPairOperaTab.cpp
index c5d0670a..5b0f4642 100644
--- a/src/ui/dialog/keypair_details/KeyPairOperaTab.cpp
+++ b/src/ui/dialog/keypair_details/KeyPairOperaTab.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,8 +19,10 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
@@ -29,43 +31,46 @@
#include "KeySetExpireDateDialog.h"
#include "core/function/GlobalSettingStation.h"
#include "core/function/gpg/GpgKeyImportExporter.h"
-#include "core/function/gpg/GpgKeyManager.h"
#include "core/function/gpg/GpgKeyOpera.h"
-#include "ui/SignalStation.h"
+#include "core/typedef/GpgTypedef.h"
+#include "core/utils/GpgUtils.h"
+#include "core/utils/IOUtils.h"
+#include "ui/UISignalStation.h"
#include "ui/UserInterfaceUtils.h"
#include "ui/dialog/import_export/KeyUploadDialog.h"
+#include "ui/function/SetOwnerTrustLevel.h"
namespace GpgFrontend::UI {
-KeyPairOperaTab::KeyPairOperaTab(const std::string& key_id, QWidget* parent)
+KeyPairOperaTab::KeyPairOperaTab(const QString& key_id, QWidget* parent)
: QWidget(parent), m_key_(GpgKeyGetter::GetInstance().GetKey(key_id)) {
// Set Menu
CreateOperaMenu();
- auto m_vbox = new QVBoxLayout(this);
+ auto* m_vbox = new QVBoxLayout(this);
- auto* opera_key_box = new QGroupBox(_("General Operations"));
+ auto* opera_key_box = new QGroupBox(tr("General Operations"));
auto* vbox_p_k = new QVBoxLayout();
- auto export_h_box_layout = new QHBoxLayout();
+ auto* export_h_box_layout = new QHBoxLayout();
vbox_p_k->addLayout(export_h_box_layout);
- auto* export_public_button = new QPushButton(_("Export Public Key"));
+ auto* export_public_button = new QPushButton(tr("Export Public Key"));
export_h_box_layout->addWidget(export_public_button);
connect(export_public_button, &QPushButton::clicked, this,
&KeyPairOperaTab::slot_export_public_key);
if (m_key_.IsPrivateKey()) {
- auto* export_private_button = new QPushButton(_("Export Private Key"));
+ auto* export_private_button = new QPushButton(tr("Export Private Key"));
export_private_button->setStyleSheet("text-align:center;");
export_private_button->setMenu(secret_key_export_opera_menu_);
export_h_box_layout->addWidget(export_private_button);
if (m_key_.IsHasMasterKey()) {
auto* edit_expires_button =
- new QPushButton(_("Modify Expiration Datetime (Primary Key)"));
+ new QPushButton(tr("Modify Expiration Datetime (Primary Key)"));
connect(edit_expires_button, &QPushButton::clicked, this,
&KeyPairOperaTab::slot_modify_edit_datetime);
- auto* edit_password_button = new QPushButton(_("Modify Password"));
+ auto* edit_password_button = new QPushButton(tr("Modify Password"));
connect(edit_password_button, &QPushButton::clicked, this,
&KeyPairOperaTab::slot_modify_password);
@@ -74,21 +79,17 @@ KeyPairOperaTab::KeyPairOperaTab(const std::string& key_id, QWidget* parent)
}
}
- auto advance_h_box_layout = new QHBoxLayout();
+ auto* advance_h_box_layout = new QHBoxLayout();
+
+ auto settings =
+ GpgFrontend::GlobalSettingStation::GetInstance().GetSettings();
- // get settings
- auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
// read settings
- bool forbid_all_gnupg_connection = false;
- try {
- forbid_all_gnupg_connection =
- settings.lookup("network.forbid_all_gnupg_connection");
- } catch (...) {
- SPDLOG_ERROR("setting operation error: forbid_all_gnupg_connection");
- }
+ bool forbid_all_gnupg_connection =
+ settings.value("network/forbid_all_gnupg_connection").toBool();
auto* key_server_opera_button =
- new QPushButton(_("Key Server Operation (Pubkey)"));
+ new QPushButton(tr("Key Server Operation (Pubkey)"));
key_server_opera_button->setStyleSheet("text-align:center;");
key_server_opera_button->setMenu(key_server_opera_menu_);
key_server_opera_button->setDisabled(forbid_all_gnupg_connection);
@@ -96,18 +97,18 @@ KeyPairOperaTab::KeyPairOperaTab(const std::string& key_id, QWidget* parent)
if (m_key_.IsPrivateKey() && m_key_.IsHasMasterKey()) {
auto* revoke_cert_gen_button =
- new QPushButton(_("Generate Revoke Certificate"));
+ new QPushButton(tr("Generate Revoke Certificate"));
connect(revoke_cert_gen_button, &QPushButton::clicked, this,
&KeyPairOperaTab::slot_gen_revoke_cert);
advance_h_box_layout->addWidget(revoke_cert_gen_button);
}
- auto* modify_tofu_button = new QPushButton(_("Modify TOFU Policy"));
+ auto* modify_tofu_button = new QPushButton(tr("Modify TOFU Policy"));
connect(modify_tofu_button, &QPushButton::clicked, this,
&KeyPairOperaTab::slot_modify_tofu_policy);
auto* set_owner_trust_level_button =
- new QPushButton(_("Set Owner Trust Level"));
+ new QPushButton(tr("Set Owner Trust Level"));
connect(set_owner_trust_level_button, &QPushButton::clicked, this,
&KeyPairOperaTab::slot_set_owner_trust_level);
@@ -123,53 +124,56 @@ KeyPairOperaTab::KeyPairOperaTab(const std::string& key_id, QWidget* parent)
// set up signal
connect(this, &KeyPairOperaTab::SignalKeyDatabaseRefresh,
- SignalStation::GetInstance(),
- &SignalStation::SignalKeyDatabaseRefresh);
+ UISignalStation::GetInstance(),
+ &UISignalStation::SignalKeyDatabaseRefresh);
}
void KeyPairOperaTab::CreateOperaMenu() {
key_server_opera_menu_ = new QMenu(this);
- auto* uploadKeyPair = new QAction(_("Upload Key Pair to Key Server"), this);
- connect(uploadKeyPair, &QAction::triggered, this,
+ auto* upload_key_pair =
+ new QAction(tr("Upload Key Pair to Key Server"), this);
+ connect(upload_key_pair, &QAction::triggered, this,
&KeyPairOperaTab::slot_upload_key_to_server);
- if (!(m_key_.IsPrivateKey() && m_key_.IsHasMasterKey()))
- uploadKeyPair->setDisabled(true);
+ if (!(m_key_.IsPrivateKey() && m_key_.IsHasMasterKey())) {
+ upload_key_pair->setDisabled(true);
+ }
- auto* updateKeyPair = new QAction(_("Sync Key Pair From Key Server"), this);
- connect(updateKeyPair, &QAction::triggered, this,
+ auto* update_key_pair =
+ new QAction(tr("Sync Key Pair From Key Server"), this);
+ connect(update_key_pair, &QAction::triggered, this,
&KeyPairOperaTab::slot_update_key_from_server);
// when a key has primary key, it should always upload to keyserver.
if (m_key_.IsHasMasterKey()) {
- updateKeyPair->setDisabled(true);
+ update_key_pair->setDisabled(true);
}
- key_server_opera_menu_->addAction(uploadKeyPair);
- key_server_opera_menu_->addAction(updateKeyPair);
+ key_server_opera_menu_->addAction(upload_key_pair);
+ key_server_opera_menu_->addAction(update_key_pair);
secret_key_export_opera_menu_ = new QMenu(this);
- auto* exportFullSecretKey = new QAction(_("Export Full Secret Key"), this);
- connect(exportFullSecretKey, &QAction::triggered, this,
+ auto* export_full_secret_key =
+ new QAction(tr("Export Full Secret Key"), this);
+ connect(export_full_secret_key, &QAction::triggered, this,
&KeyPairOperaTab::slot_export_private_key);
- if (!m_key_.IsPrivateKey()) exportFullSecretKey->setDisabled(true);
+ if (!m_key_.IsPrivateKey()) export_full_secret_key->setDisabled(true);
- auto* exportShortestSecretKey =
- new QAction(_("Export Shortest Secret Key"), this);
- connect(exportShortestSecretKey, &QAction::triggered, this,
+ auto* export_shortest_secret_key =
+ new QAction(tr("Export Shortest Secret Key"), this);
+ connect(export_shortest_secret_key, &QAction::triggered, this,
&KeyPairOperaTab::slot_export_short_private_key);
- secret_key_export_opera_menu_->addAction(exportFullSecretKey);
- secret_key_export_opera_menu_->addAction(exportShortestSecretKey);
+ secret_key_export_opera_menu_->addAction(export_full_secret_key);
+ secret_key_export_opera_menu_->addAction(export_shortest_secret_key);
}
void KeyPairOperaTab::slot_export_public_key() {
- ByteArrayPtr keyArray = nullptr;
-
- if (!GpgKeyImportExporter::GetInstance().ExportKey(m_key_, keyArray)) {
- QMessageBox::critical(this, _("Error"),
- _("An error occurred during the export operation."));
+ auto [err, gf_buffer] =
+ GpgKeyImportExporter::GetInstance().ExportKey(m_key_, false, true, false);
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ CommonUtils::RaiseMessageBox(this, err);
return;
}
@@ -183,18 +187,15 @@ void KeyPairOperaTab::slot_export_public_key() {
#endif
std::replace(file_string.begin(), file_string.end(), ' ', '_');
- auto file_name =
- QFileDialog::getSaveFileName(
- this, _("Export Key To File"), QString::fromStdString(file_string),
- QString(_("Key Files")) + " (*.asc *.txt);;All Files (*)")
- .toStdString();
+ auto file_name = QFileDialog::getSaveFileName(
+ this, tr("Export Key To File"), file_string,
+ tr("Key Files") + " (*.asc *.txt);;All Files (*)");
- if (file_name.empty()) return;
+ if (file_name.isEmpty()) return;
- if (!write_buffer_to_file(file_name, *keyArray)) {
- QMessageBox::critical(
- this, _("Export Error"),
- QString(_("Couldn't open %1 for writing")).arg(file_name.c_str()));
+ if (!WriteFileGFBuffer(file_name, gf_buffer)) {
+ QMessageBox::critical(this, tr("Export Error"),
+ tr("Couldn't open %1 for writing").arg(file_name));
return;
}
}
@@ -202,26 +203,23 @@ void KeyPairOperaTab::slot_export_public_key() {
void KeyPairOperaTab::slot_export_short_private_key() {
// Show a information box with explanation about private key
int ret = QMessageBox::information(
- this, _("Exporting short 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 in a Minimum "
- "Size?") +
+ this, tr("Exporting short 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 in a Minimum "
+ "Size?") +
"<br />" +
- _("For OpenPGP keys it removes all signatures except for the latest "
- "self-signatures."),
+ tr("For OpenPGP keys it removes all signatures except for the latest "
+ "self-signatures."),
QMessageBox::Cancel | QMessageBox::Ok);
// export key, if ok was clicked
if (ret == QMessageBox::Ok) {
- ByteArrayPtr keyArray = nullptr;
-
- if (!GpgKeyImportExporter::GetInstance().ExportSecretKeyShortest(
- m_key_, keyArray)) {
- QMessageBox::critical(
- this, _("Error"),
- _("An error occurred during the export operation."));
+ auto [err, gf_buffer] =
+ GpgKeyImportExporter::GetInstance().ExportKey(m_key_, true, true, true);
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ CommonUtils::RaiseMessageBox(this, err);
return;
}
@@ -235,18 +233,15 @@ void KeyPairOperaTab::slot_export_short_private_key() {
#endif
std::replace(file_string.begin(), file_string.end(), ' ', '_');
- auto file_name =
- QFileDialog::getSaveFileName(
- this, _("Export Key To File"), QString::fromStdString(file_string),
- QString(_("Key Files")) + " (*.asc *.txt);;All Files (*)")
- .toStdString();
+ auto file_name = QFileDialog::getSaveFileName(
+ this, tr("Export Key To File"), file_string,
+ tr("Key Files") + " (*.asc *.txt);;All Files (*)");
- if (file_name.empty()) return;
+ if (file_name.isEmpty()) return;
- if (!write_buffer_to_file(file_name, *keyArray)) {
- QMessageBox::critical(
- this, _("Export Error"),
- QString(_("Couldn't open %1 for writing")).arg(file_name.c_str()));
+ if (!WriteFileGFBuffer(file_name, gf_buffer)) {
+ QMessageBox::critical(this, tr("Export Error"),
+ tr("Couldn't open %1 for writing").arg(file_name));
return;
}
}
@@ -255,22 +250,19 @@ void KeyPairOperaTab::slot_export_short_private_key() {
void KeyPairOperaTab::slot_export_private_key() {
// 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?"),
+ 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) {
- ByteArrayPtr keyArray = nullptr;
-
- if (!GpgKeyImportExporter::GetInstance().ExportSecretKey(m_key_,
- keyArray)) {
- QMessageBox::critical(
- this, _("Error"),
- _("An error occurred during the export operation."));
+ auto [err, gf_buffer] = GpgKeyImportExporter::GetInstance().ExportKey(
+ m_key_, true, true, false);
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ CommonUtils::RaiseMessageBox(this, err);
return;
}
@@ -284,25 +276,22 @@ void KeyPairOperaTab::slot_export_private_key() {
#endif
std::replace(file_string.begin(), file_string.end(), ' ', '_');
- auto file_name =
- QFileDialog::getSaveFileName(
- this, _("Export Key To File"), QString::fromStdString(file_string),
- QString(_("Key Files")) + " (*.asc *.txt);;All Files (*)")
- .toStdString();
+ auto file_name = QFileDialog::getSaveFileName(
+ this, tr("Export Key To File"), file_string,
+ tr("Key Files") + " (*.asc *.txt);;All Files (*)");
- if (file_name.empty()) return;
+ if (file_name.isEmpty()) return;
- if (!write_buffer_to_file(file_name, *keyArray)) {
- QMessageBox::critical(
- this, _("Export Error"),
- QString(_("Couldn't open %1 for writing")).arg(file_name.c_str()));
+ if (!WriteFileGFBuffer(file_name, gf_buffer)) {
+ QMessageBox::critical(this, tr("Export Error"),
+ tr("Couldn't open %1 for writing").arg(file_name));
return;
}
}
}
void KeyPairOperaTab::slot_modify_edit_datetime() {
- auto dialog = new KeySetExpireDateDialog(m_key_.GetId(), this);
+ auto* dialog = new KeySetExpireDateDialog(m_key_.GetId(), this);
dialog->show();
}
@@ -323,106 +312,71 @@ void KeyPairOperaTab::slot_update_key_from_server() {
}
void KeyPairOperaTab::slot_gen_revoke_cert() {
- auto literal = QString("%1 (*.rev)").arg(_("Revocation Certificates"));
+ auto literal = QString("%1 (*.rev)").arg(tr("Revocation Certificates"));
QString m_output_file_name;
- QFileDialog dialog(this, "Generate revocation certificate", QString(),
+#ifndef WINDOWS
+ auto file_string = m_key_.GetName() + "<" + m_key_.GetEmail() + ">(" +
+ m_key_.GetId() + ").rev";
+#else
+ auto file_string = m_key_.GetName() + "[" + m_key_.GetEmail() + "](" +
+ m_key_.GetId() + ").rev";
+#endif
+
+ QFileDialog dialog(this, tr("Generate revocation certificate"), file_string,
literal);
dialog.setDefaultSuffix(".rev");
dialog.setAcceptMode(QFileDialog::AcceptSave);
- if (dialog.exec()) m_output_file_name = dialog.selectedFiles().front();
+ if (dialog.exec() != 0) m_output_file_name = dialog.selectedFiles().front();
if (!m_output_file_name.isEmpty()) {
- GpgKeyOpera::GetInstance().GenerateRevokeCert(
- m_key_, m_output_file_name.toStdString());
+ GpgKeyOpera::GetInstance().GenerateRevokeCert(m_key_, m_output_file_name);
}
}
void KeyPairOperaTab::slot_modify_password() {
- auto err = GpgKeyOpera::GetInstance().ModifyPassword(m_key_);
- if (check_gpg_error_2_err_code(err) != GPG_ERR_NO_ERROR) {
- QMessageBox::critical(this, _("Not Successful"),
- QString(_("Modify password not successfully.")));
- }
+ GpgKeyOpera::GetInstance().ModifyPassword(
+ m_key_, [this](GpgError err, const DataObjectPtr&) {
+ CommonUtils::RaiseMessageBox(this, err);
+ });
}
void KeyPairOperaTab::slot_modify_tofu_policy() {
QStringList items;
- items << _("Policy Auto") << _("Policy Good") << _("Policy Bad")
- << _("Policy Ask") << _("Policy Unknown");
+ items << tr("Policy Auto") << tr("Policy Good") << tr("Policy Bad")
+ << tr("Policy Ask") << tr("Policy Unknown");
bool ok;
QString item = QInputDialog::getItem(
- this, _("Modify TOFU Policy(Default is Auto)"),
- _("Policy for the Key Pair:"), items, 0, false, &ok);
+ this, tr("Modify TOFU Policy(Default is Auto)"),
+ tr("Policy for the Key Pair:"), items, 0, false, &ok);
if (ok && !item.isEmpty()) {
- SPDLOG_DEBUG("selected policy: {}", item.toStdString());
+ GF_UI_LOG_DEBUG("selected policy: {}", item.toStdString());
gpgme_tofu_policy_t tofu_policy = GPGME_TOFU_POLICY_AUTO;
- if (item == _("Policy Auto")) {
+ if (item == tr("Policy Auto")) {
tofu_policy = GPGME_TOFU_POLICY_AUTO;
- } else if (item == _("Policy Good")) {
+ } else if (item == tr("Policy Good")) {
tofu_policy = GPGME_TOFU_POLICY_GOOD;
- } else if (item == _("Policy Bad")) {
+ } else if (item == tr("Policy Bad")) {
tofu_policy = GPGME_TOFU_POLICY_BAD;
- } else if (item == _("Policy Ask")) {
+ } else if (item == tr("Policy Ask")) {
tofu_policy = GPGME_TOFU_POLICY_ASK;
- } else if (item == _("Policy Unknown")) {
+ } else if (item == tr("Policy Unknown")) {
tofu_policy = GPGME_TOFU_POLICY_UNKNOWN;
}
auto err = GpgKeyOpera::GetInstance().ModifyTOFUPolicy(m_key_, tofu_policy);
- if (check_gpg_error_2_err_code(err) != GPG_ERR_NO_ERROR) {
- QMessageBox::critical(this, _("Not Successful"),
- QString(_("Modify TOFU policy not successfully.")));
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ QMessageBox::critical(this, tr("Not Successful"),
+ tr("Modify TOFU policy not successfully."));
}
}
}
void KeyPairOperaTab::slot_set_owner_trust_level() {
- QStringList items;
-
- items << _("Unknown") << _("Undefined") << _("Never") << _("Marginal")
- << _("Full") << _("Ultimate");
- bool ok;
- QString item = QInputDialog::getItem(this, _("Modify Owner Trust Level"),
- _("Trust for the Key Pair:"), items,
- m_key_.GetOwnerTrustLevel(), false, &ok);
-
- if (ok && !item.isEmpty()) {
- SPDLOG_DEBUG("selected policy: {}", item.toStdString());
- int trust_level = 0; // Unknown Level
- if (item == _("Ultimate")) {
- trust_level = 5;
- } else if (item == _("Full")) {
- trust_level = 4;
- } else if (item == _("Marginal")) {
- trust_level = 3;
- } else if (item == _("Never")) {
- trust_level = 2;
- } else if (item == _("Undefined")) {
- trust_level = 1;
- }
-
- if (trust_level == 0) {
- QMessageBox::warning(
- this, _("Warning"),
- QString(_("Owner Trust Level cannot set to Unknown level, automately "
- "changing it into Undefined level.")));
- trust_level = 1;
- }
-
- bool status =
- GpgKeyManager::GetInstance().SetOwnerTrustLevel(m_key_, trust_level);
- if (!status) {
- QMessageBox::critical(this, _("Failed"),
- QString(_("Modify Owner Trust Level failed.")));
- } else {
- QMessageBox::information(this, _("Success"),
- QString(_("Set Owner Trust Level successful.")));
- // update key database and refresh ui
- emit SignalKeyDatabaseRefresh();
- }
- }
+ auto* function = new SetOwnerTrustLevel(this);
+ function->Exec(m_key_.GetId());
+ function->deleteLater();
}
} // namespace GpgFrontend::UI
diff --git a/src/ui/dialog/keypair_details/KeyPairOperaTab.h b/src/ui/dialog/keypair_details/KeyPairOperaTab.h
index 0c4a7916..100d4a69 100644
--- a/src/ui/dialog/keypair_details/KeyPairOperaTab.h
+++ b/src/ui/dialog/keypair_details/KeyPairOperaTab.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,15 +19,17 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_KEYPAIROPERATAB_H
-#define GPGFRONTEND_KEYPAIROPERATAB_H
+#pragma once
#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/model/GpgKey.h"
#include "ui/GpgFrontendUI.h"
namespace GpgFrontend::UI {
@@ -40,7 +42,7 @@ class KeyPairOperaTab : public QWidget {
* @param key_id
* @param parent
*/
- KeyPairOperaTab(const std::string& key_id, QWidget* parent);
+ KeyPairOperaTab(const QString& key_id, QWidget* parent);
/**
* @brief Create a Opera Menu object
@@ -122,5 +124,3 @@ class KeyPairOperaTab : public QWidget {
QMenu* secret_key_export_opera_menu_{}; ///<
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_KEYPAIROPERATAB_H
diff --git a/src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp b/src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp
index 9c243a39..3f973fae 100644
--- a/src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp
+++ b/src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,57 +28,52 @@
#include "KeyPairSubkeyTab.h"
+#include "core/GpgModel.h"
#include "core/function/gpg/GpgKeyGetter.h"
-#include "ui/SignalStation.h"
+#include "core/utils/CommonUtils.h"
+#include "ui/UISignalStation.h"
namespace GpgFrontend::UI {
-KeyPairSubkeyTab::KeyPairSubkeyTab(const std::string& key_id, QWidget* parent)
+KeyPairSubkeyTab::KeyPairSubkeyTab(const QString& key_id, QWidget* parent)
: QWidget(parent), key_(GpgKeyGetter::GetInstance().GetKey(key_id)) {
- SPDLOG_DEBUG(key_.GetEmail(), key_.IsPrivateKey(), key_.IsHasMasterKey(),
- key_.GetSubKeys()->front().IsPrivateKey());
-
create_subkey_list();
create_subkey_opera_menu();
- list_box_ = new QGroupBox(_("Subkey List"));
- detail_box_ = new QGroupBox(_("Detail of Selected Subkey"));
+ list_box_ = new QGroupBox(tr("Subkey List"));
+ detail_box_ = new QGroupBox(tr("Detail of Selected Subkey"));
- auto uidButtonsLayout = new QGridLayout();
+ auto* uid_buttons_layout = new QGridLayout();
- auto addSubkeyButton = new QPushButton(_("Generate A New Subkey"));
+ auto* add_subkey_button = new QPushButton(tr("Generate A New Subkey"));
if (!key_.IsPrivateKey() || !key_.IsHasMasterKey()) {
- addSubkeyButton->setDisabled(true);
- setHidden(addSubkeyButton);
+ add_subkey_button->setDisabled(true);
+ setHidden(add_subkey_button);
}
- uidButtonsLayout->addWidget(addSubkeyButton, 0, 1);
-
- auto* baseLayout = new QVBoxLayout();
-
- auto subkeyListLayout = new QGridLayout();
- subkeyListLayout->addWidget(subkey_list_, 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 (Local Time)")) + ": "), 4, 0);
- subkeyDetailLayout->addWidget(
- new QLabel(QString(_("Create Date (Local Time)")) + ": "), 5, 0);
- subkeyDetailLayout->addWidget(new QLabel(QString(_("Existence")) + ": "), 6,
- 0);
- subkeyDetailLayout->addWidget(
- new QLabel(QString(_("Key in Smart Card")) + ": "), 7, 0);
- subkeyDetailLayout->addWidget(new QLabel(QString(_("Fingerprint")) + ": "), 8,
- 0);
+ uid_buttons_layout->addWidget(add_subkey_button, 0, 1);
+
+ auto* base_layout = new QVBoxLayout();
+
+ auto* subkey_list_layout = new QGridLayout();
+ subkey_list_layout->addWidget(subkey_list_, 0, 0);
+ subkey_list_layout->addLayout(uid_buttons_layout, 1, 0);
+ subkey_list_layout->setContentsMargins(0, 10, 0, 0);
+
+ auto* subkey_detail_layout = new QGridLayout();
+
+ subkey_detail_layout->addWidget(new QLabel(tr("Key ID") + ": "), 0, 0);
+ subkey_detail_layout->addWidget(new QLabel(tr("Algorithm") + ": "), 1, 0);
+ subkey_detail_layout->addWidget(new QLabel(tr("Key Size") + ": "), 2, 0);
+ subkey_detail_layout->addWidget(new QLabel(tr("Usage") + ": "), 3, 0);
+ subkey_detail_layout->addWidget(
+ new QLabel(tr("Expires On (Local Time)") + ": "), 4, 0);
+ subkey_detail_layout->addWidget(
+ new QLabel(tr("Create Date (Local Time)") + ": "), 5, 0);
+ subkey_detail_layout->addWidget(new QLabel(tr("Existence") + ": "), 6, 0);
+ subkey_detail_layout->addWidget(new QLabel(tr("Key in Smart Card") + ": "), 7,
+ 0);
+ subkey_detail_layout->addWidget(new QLabel(tr("Fingerprint") + ": "), 8, 0);
key_id_var_label_ = new QLabel(this);
key_size_var_label_ = new QLabel(this);
@@ -90,49 +85,49 @@ KeyPairSubkeyTab::KeyPairSubkeyTab(const std::string& key_id, QWidget* parent)
fingerprint_var_label_ = new QLabel(this);
card_key_label_ = new QLabel(this);
- subkeyDetailLayout->addWidget(key_id_var_label_, 0, 1, 1, 1);
- subkeyDetailLayout->addWidget(key_size_var_label_, 2, 1, 1, 2);
- subkeyDetailLayout->addWidget(expire_var_label_, 4, 1, 1, 2);
- subkeyDetailLayout->addWidget(algorithm_var_label_, 1, 1, 1, 2);
- subkeyDetailLayout->addWidget(created_var_label_, 5, 1, 1, 2);
- subkeyDetailLayout->addWidget(usage_var_label_, 3, 1, 1, 2);
- subkeyDetailLayout->addWidget(master_key_exist_var_label_, 6, 1, 1, 2);
- subkeyDetailLayout->addWidget(card_key_label_, 7, 1, 1, 2);
- subkeyDetailLayout->addWidget(fingerprint_var_label_, 8, 1, 1, 2);
-
- auto* copyKeyIdButton = new QPushButton(_("Copy"));
- copyKeyIdButton->setFlat(true);
- subkeyDetailLayout->addWidget(copyKeyIdButton, 0, 2);
- connect(copyKeyIdButton, &QPushButton::clicked, this, [=]() {
+ subkey_detail_layout->addWidget(key_id_var_label_, 0, 1, 1, 1);
+ subkey_detail_layout->addWidget(key_size_var_label_, 2, 1, 1, 2);
+ subkey_detail_layout->addWidget(expire_var_label_, 4, 1, 1, 2);
+ subkey_detail_layout->addWidget(algorithm_var_label_, 1, 1, 1, 2);
+ subkey_detail_layout->addWidget(created_var_label_, 5, 1, 1, 2);
+ subkey_detail_layout->addWidget(usage_var_label_, 3, 1, 1, 2);
+ subkey_detail_layout->addWidget(master_key_exist_var_label_, 6, 1, 1, 2);
+ subkey_detail_layout->addWidget(card_key_label_, 7, 1, 1, 2);
+ subkey_detail_layout->addWidget(fingerprint_var_label_, 8, 1, 1, 2);
+
+ auto* copy_key_id_button = new QPushButton(tr("Copy"));
+ copy_key_id_button->setFlat(true);
+ subkey_detail_layout->addWidget(copy_key_id_button, 0, 2);
+ connect(copy_key_id_button, &QPushButton::clicked, this, [=]() {
QString fpr = key_id_var_label_->text().trimmed();
QClipboard* cb = QApplication::clipboard();
cb->setText(fpr);
});
- list_box_->setLayout(subkeyListLayout);
+ list_box_->setLayout(subkey_list_layout);
list_box_->setContentsMargins(0, 12, 0, 0);
- detail_box_->setLayout(subkeyDetailLayout);
+ detail_box_->setLayout(subkey_detail_layout);
- baseLayout->addWidget(list_box_);
- baseLayout->addWidget(detail_box_);
- baseLayout->addStretch();
+ base_layout->addWidget(list_box_);
+ base_layout->addWidget(detail_box_);
+ base_layout->addStretch();
- connect(addSubkeyButton, &QPushButton::clicked, this,
+ connect(add_subkey_button, &QPushButton::clicked, this,
&KeyPairSubkeyTab::slot_add_subkey);
connect(subkey_list_, &QTableWidget::itemSelectionChanged, this,
&KeyPairSubkeyTab::slot_refresh_subkey_detail);
// key database refresh signal
- connect(SignalStation::GetInstance(),
- &SignalStation::SignalKeyDatabaseRefreshDone, this,
+ connect(UISignalStation::GetInstance(),
+ &UISignalStation::SignalKeyDatabaseRefreshDone, this,
&KeyPairSubkeyTab::slot_refresh_key_info);
- connect(SignalStation::GetInstance(),
- &SignalStation::SignalKeyDatabaseRefreshDone, this,
+ connect(UISignalStation::GetInstance(),
+ &UISignalStation::SignalKeyDatabaseRefreshDone, this,
&KeyPairSubkeyTab::slot_refresh_subkey_list);
- baseLayout->setContentsMargins(0, 0, 0, 0);
+ base_layout->setContentsMargins(0, 0, 0, 0);
- setLayout(baseLayout);
+ setLayout(base_layout);
setAttribute(Qt::WA_DeleteOnClose, true);
slot_refresh_subkey_list();
@@ -157,8 +152,8 @@ void KeyPairSubkeyTab::create_subkey_list() {
subkey_list_->setAlternatingRowColors(true);
QStringList labels;
- labels << _("Subkey ID") << _("Key Size") << _("Algo")
- << _("Create Date (UTC)") << _("Expire Date (UTC)");
+ labels << tr("Subkey ID") << tr("Key Size") << tr("Algo") << tr("Create Date")
+ << tr("Expire Date");
subkey_list_->setHorizontalHeaderLabels(labels);
subkey_list_->horizontalHeader()->setStretchLastSection(false);
@@ -176,13 +171,13 @@ void KeyPairSubkeyTab::slot_refresh_subkey_list() {
this->buffered_subkeys_.push_back(std::move(sub_key));
}
- SPDLOG_DEBUG("buffered_subkeys_ refreshed size",
- this->buffered_subkeys_.size());
+ GF_UI_LOG_DEBUG("buffered_subkeys_ refreshed size",
+ this->buffered_subkeys_.size());
subkey_list_->setRowCount(buffered_subkeys_.size());
for (const auto& subkeys : buffered_subkeys_) {
- auto* tmp0 = new QTableWidgetItem(QString::fromStdString(subkeys.GetID()));
+ auto* tmp0 = new QTableWidgetItem(subkeys.GetID());
tmp0->setTextAlignment(Qt::AlignCenter);
subkey_list_->setItem(row, 0, tmp0);
@@ -190,21 +185,18 @@ void KeyPairSubkeyTab::slot_refresh_subkey_list() {
tmp1->setTextAlignment(Qt::AlignCenter);
subkey_list_->setItem(row, 1, tmp1);
- auto* tmp2 =
- new QTableWidgetItem(QString::fromStdString(subkeys.GetPubkeyAlgo()));
+ auto* tmp2 = new QTableWidgetItem(subkeys.GetPubkeyAlgo());
tmp2->setTextAlignment(Qt::AlignCenter);
subkey_list_->setItem(row, 2, tmp2);
- auto* tmp3 = new QTableWidgetItem(
- QString::fromStdString(to_iso_string(subkeys.GetCreateTime())));
+ auto* tmp3 = new QTableWidgetItem(subkeys.GetCreateTime().toString());
tmp3->setTextAlignment(Qt::AlignCenter);
subkey_list_->setItem(row, 3, tmp3);
- auto* tmp4 = new QTableWidgetItem(
- boost::posix_time::to_time_t(
- boost::posix_time::ptime(subkeys.GetExpireTime())) == 0
- ? _("Never Expire")
- : QString::fromStdString(to_iso_string(subkeys.GetExpireTime())));
+ auto* tmp4 =
+ new QTableWidgetItem(subkeys.GetExpireTime().toSecsSinceEpoch() == 0
+ ? tr("Never Expire")
+ : subkeys.GetExpireTime().toString());
tmp4->setTextAlignment(Qt::AlignCenter);
subkey_list_->setItem(row, 4, tmp4);
@@ -214,12 +206,12 @@ void KeyPairSubkeyTab::slot_refresh_subkey_list() {
}
}
- SPDLOG_DEBUG("subkey_list_ item {} refreshed", row);
+ GF_UI_LOG_DEBUG("subkey_list_ item {} refreshed", row);
row++;
}
- SPDLOG_DEBUG("subkey_list_ refreshed");
+ GF_UI_LOG_DEBUG("subkey_list_ refreshed");
if (subkey_list_->rowCount() > 0) {
subkey_list_->selectRow(0);
@@ -227,67 +219,55 @@ void KeyPairSubkeyTab::slot_refresh_subkey_list() {
}
void KeyPairSubkeyTab::slot_add_subkey() {
- auto dialog = new SubkeyGenerateDialog(key_.GetId(), this);
+ auto* dialog = new SubkeyGenerateDialog(key_.GetId(), this);
dialog->show();
}
void KeyPairSubkeyTab::slot_refresh_subkey_detail() {
- auto& subkey = get_selected_subkey();
+ const auto& subkey = get_selected_subkey();
- key_id_var_label_->setText(QString::fromStdString(subkey.GetID()));
+ key_id_var_label_->setText(subkey.GetID());
key_size_var_label_->setText(QString::number(subkey.GetKeyLength()));
- time_t subkey_time_t = boost::posix_time::to_time_t(
- boost::posix_time::ptime(subkey.GetExpireTime()));
+ time_t subkey_time_t = subkey.GetExpireTime().toSecsSinceEpoch();
-#ifdef GPGFRONTEND_GUI_QT6
- expire_var_label_->setText(
- subkey_time_t == 0
- ? _("Never Expires")
- : QLocale::system().toString(QDateTime::fromSecsSinceEpoch(
- to_time_t(subkey.GetExpireTime()))));
-#else
expire_var_label_->setText(
- subkey_time_t == 0 ? _("Never Expires")
- : QLocale::system().toString(QDateTime::fromTime_t(
- to_time_t(subkey.GetExpireTime()))));
-#endif
+ subkey_time_t == 0 ? tr("Never Expires")
+ : QLocale::system().toString(subkey.GetExpireTime()));
+
if (subkey_time_t != 0 &&
- subkey.GetExpireTime() < boost::posix_time::second_clock::local_time()) {
- auto paletteExpired = expire_var_label_->palette();
- paletteExpired.setColor(expire_var_label_->foregroundRole(), Qt::red);
- expire_var_label_->setPalette(paletteExpired);
+ subkey.GetExpireTime() < QDateTime::currentDateTime()) {
+ auto palette_expired = expire_var_label_->palette();
+ palette_expired.setColor(expire_var_label_->foregroundRole(), Qt::red);
+ expire_var_label_->setPalette(palette_expired);
} else {
- auto paletteValid = expire_var_label_->palette();
- paletteValid.setColor(expire_var_label_->foregroundRole(), Qt::darkGreen);
- expire_var_label_->setPalette(paletteValid);
+ auto palette_valid = expire_var_label_->palette();
+ palette_valid.setColor(expire_var_label_->foregroundRole(), Qt::darkGreen);
+ expire_var_label_->setPalette(palette_valid);
}
- algorithm_var_label_->setText(QString::fromStdString(subkey.GetPubkeyAlgo()));
-#ifdef GPGFRONTEND_GUI_QT6
- created_var_label_->setText(QLocale::system().toString(
- QDateTime::fromSecsSinceEpoch(to_time_t(subkey.GetCreateTime()))));
-#else
- created_var_label_->setText(QLocale::system().toString(
- QDateTime::fromTime_t(to_time_t(subkey.GetCreateTime()))));
-#endif
+ algorithm_var_label_->setText(subkey.GetPubkeyAlgo());
+ created_var_label_->setText(
+ QLocale::system().toString(subkey.GetCreateTime()));
- std::stringstream usage_steam;
+ QString buffer;
+ QTextStream usage_steam(&buffer);
- if (subkey.IsHasCertificationCapability())
- usage_steam << _("Certificate") << " ";
- if (subkey.IsHasEncryptionCapability()) usage_steam << _("Encrypt") << " ";
- if (subkey.IsHasSigningCapability()) usage_steam << _("Sign") << " ";
- if (subkey.IsHasAuthenticationCapability()) usage_steam << _("Auth") << " ";
+ if (subkey.IsHasCertificationCapability()) {
+ usage_steam << tr("Certificate") << " ";
+ }
+ if (subkey.IsHasEncryptionCapability()) usage_steam << tr("Encrypt") << " ";
+ if (subkey.IsHasSigningCapability()) usage_steam << tr("Sign") << " ";
+ if (subkey.IsHasAuthenticationCapability()) usage_steam << tr("Auth") << " ";
- usage_var_label_->setText(usage_steam.str().c_str());
+ usage_var_label_->setText(usage_steam.readAll());
// Show the situation that secret key not exists.
- master_key_exist_var_label_->setText(subkey.IsSecretKey() ? _("Exists")
- : _("Not Exists"));
+ master_key_exist_var_label_->setText(subkey.IsSecretKey() ? tr("Exists")
+ : tr("Not Exists"));
// Show the situation if key in a smart card.
- card_key_label_->setText(subkey.IsCardKey() ? _("Yes") : _("No"));
+ card_key_label_->setText(subkey.IsCardKey() ? tr("Yes") : tr("No"));
if (!subkey.IsSecretKey()) {
auto palette_expired = master_key_exist_var_label_->palette();
@@ -311,23 +291,22 @@ void KeyPairSubkeyTab::slot_refresh_subkey_detail() {
card_key_label_->setPalette(palette_valid);
}
- fingerprint_var_label_->setText(
- QString::fromStdString(beautify_fingerprint(subkey.GetFingerprint())));
+ fingerprint_var_label_->setText(BeautifyFingerprint(subkey.GetFingerprint()));
}
void KeyPairSubkeyTab::create_subkey_opera_menu() {
subkey_opera_menu_ = new QMenu(this);
- auto* editSubkeyAct = new QAction(_("Edit Expire Date"));
- connect(editSubkeyAct, &QAction::triggered, this,
+ auto* edit_subkey_act = new QAction(tr("Edit Expire Date"));
+ connect(edit_subkey_act, &QAction::triggered, this,
&KeyPairSubkeyTab::slot_edit_subkey);
- subkey_opera_menu_->addAction(editSubkeyAct);
+ subkey_opera_menu_->addAction(edit_subkey_act);
}
void KeyPairSubkeyTab::slot_edit_subkey() {
- SPDLOG_DEBUG("fpr {}", get_selected_subkey().GetFingerprint());
+ GF_UI_LOG_DEBUG("fpr {}", get_selected_subkey().GetFingerprint());
- auto dialog = new KeySetExpireDateDialog(
+ auto* dialog = new KeySetExpireDateDialog(
key_.GetId(), get_selected_subkey().GetFingerprint(), this);
dialog->show();
}
@@ -340,7 +319,7 @@ void KeyPairSubkeyTab::contextMenuEvent(QContextMenuEvent* event) {
}
}
-const GpgSubKey& KeyPairSubkeyTab::get_selected_subkey() {
+auto KeyPairSubkeyTab::get_selected_subkey() -> const GpgSubKey& {
int row = 0;
for (int i = 0; i < subkey_list_->rowCount(); i++) {
diff --git a/src/ui/dialog/keypair_details/KeyPairSubkeyTab.h b/src/ui/dialog/keypair_details/KeyPairSubkeyTab.h
index a93ebca5..c179c3e9 100644
--- a/src/ui/dialog/keypair_details/KeyPairSubkeyTab.h
+++ b/src/ui/dialog/keypair_details/KeyPairSubkeyTab.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,17 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_KEYPAIRSUBKEYTAB_H
-#define GPGFRONTEND_KEYPAIRSUBKEYTAB_H
+#pragma once
#include "KeySetExpireDateDialog.h"
-#include "core/GpgContext.h"
+#include "core/function/gpg/GpgContext.h"
#include "ui/GpgFrontendUI.h"
#include "ui/dialog/key_generate/SubkeyGenerateDialog.h"
@@ -46,7 +45,7 @@ class KeyPairSubkeyTab : public QWidget {
* @param key
* @param parent
*/
- KeyPairSubkeyTab(const std::string& key, QWidget* parent);
+ KeyPairSubkeyTab(const QString& key, QWidget* parent);
private:
/**
@@ -135,5 +134,3 @@ class KeyPairSubkeyTab : public QWidget {
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_KEYPAIRSUBKEYTAB_H
diff --git a/src/ui/dialog/keypair_details/KeyPairUIDTab.cpp b/src/ui/dialog/keypair_details/KeyPairUIDTab.cpp
index d55e44d8..fe2f5f02 100644
--- a/src/ui/dialog/keypair_details/KeyPairUIDTab.cpp
+++ b/src/ui/dialog/keypair_details/KeyPairUIDTab.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,22 +19,25 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "KeyPairUIDTab.h"
+#include "core/GpgModel.h"
#include "core/function/gpg/GpgKeyGetter.h"
#include "core/function/gpg/GpgKeyManager.h"
#include "core/function/gpg/GpgUIDOperator.h"
-#include "ui/SignalStation.h"
+#include "ui/UISignalStation.h"
#include "ui/widgets/TOFUInfoPage.h"
namespace GpgFrontend::UI {
-KeyPairUIDTab::KeyPairUIDTab(const std::string& key_id, QWidget* parent)
+KeyPairUIDTab::KeyPairUIDTab(const QString& key_id, QWidget* parent)
: QWidget(parent), m_key_(GpgKeyGetter::GetInstance().GetKey(key_id)) {
create_uid_list();
create_sign_list();
@@ -42,58 +45,58 @@ KeyPairUIDTab::KeyPairUIDTab(const std::string& key_id, QWidget* parent)
create_uid_popup_menu();
create_sign_popup_menu();
- auto uidButtonsLayout = new QGridLayout();
+ auto* uid_buttons_layout = new QGridLayout();
- auto addUIDButton = new QPushButton(_("New UID"));
- auto manageUIDButton = new QPushButton(_("UID Management"));
+ auto* add_uid_button = new QPushButton(tr("New UID"));
+ auto* manage_uid_button = new QPushButton(tr("UID Management"));
if (m_key_.IsHasMasterKey()) {
- manageUIDButton->setMenu(manage_selected_uid_menu_);
+ manage_uid_button->setMenu(manage_selected_uid_menu_);
} else {
- manageUIDButton->setDisabled(true);
+ manage_uid_button->setDisabled(true);
}
- uidButtonsLayout->addWidget(addUIDButton, 0, 1);
- uidButtonsLayout->addWidget(manageUIDButton, 0, 2);
+ uid_buttons_layout->addWidget(add_uid_button, 0, 1);
+ uid_buttons_layout->addWidget(manage_uid_button, 0, 2);
- auto grid_layout = new QGridLayout();
+ auto* grid_layout = new QGridLayout();
grid_layout->addWidget(uid_list_, 0, 0);
- grid_layout->addLayout(uidButtonsLayout, 1, 0);
+ grid_layout->addLayout(uid_buttons_layout, 1, 0);
grid_layout->setContentsMargins(0, 10, 0, 0);
- auto uid_group_box = new QGroupBox();
+ auto* uid_group_box = new QGroupBox();
uid_group_box->setLayout(grid_layout);
- uid_group_box->setTitle(_("UIDs"));
+ uid_group_box->setTitle(tr("UIDs"));
- auto tofu_group_box = new QGroupBox();
- auto tofu_vbox_layout = new QVBoxLayout();
+ auto* tofu_group_box = new QGroupBox();
+ auto* tofu_vbox_layout = new QVBoxLayout();
tofu_group_box->setLayout(tofu_vbox_layout);
- tofu_group_box->setTitle(_("TOFU"));
+ tofu_group_box->setTitle(tr("TOFU"));
#if !defined(RELEASE)
tofu_tabs_ = new QTabWidget(this);
tofu_vbox_layout->addWidget(tofu_tabs_);
#endif
- auto sign_grid_layout = new QGridLayout();
+ auto* sign_grid_layout = new QGridLayout();
sign_grid_layout->addWidget(sig_list_, 0, 0);
sign_grid_layout->setContentsMargins(0, 10, 0, 0);
- auto sign_group_box = new QGroupBox();
+ auto* sign_group_box = new QGroupBox();
sign_group_box->setLayout(sign_grid_layout);
- sign_group_box->setTitle(_("Signature of Selected UID"));
+ sign_group_box->setTitle(tr("Signature of Selected UID"));
- auto vboxLayout = new QVBoxLayout();
- vboxLayout->addWidget(uid_group_box);
+ auto* vbox_layout = new QVBoxLayout();
+ vbox_layout->addWidget(uid_group_box);
#if !defined(RELEASE)
// Function needed testing
- vboxLayout->addWidget(tofu_group_box);
+ vbox_layout->addWidget(tofu_group_box);
#endif
- vboxLayout->addWidget(sign_group_box);
+ vbox_layout->addWidget(sign_group_box);
- vboxLayout->setContentsMargins(0, 0, 0, 0);
+ vbox_layout->setContentsMargins(0, 0, 0, 0);
- connect(addUIDButton, &QPushButton::clicked, this,
+ connect(add_uid_button, &QPushButton::clicked, this,
&KeyPairUIDTab::slot_add_uid);
connect(uid_list_, &QTableWidget::itemSelectionChanged, this,
&KeyPairUIDTab::slot_refresh_tofu_info);
@@ -101,15 +104,15 @@ KeyPairUIDTab::KeyPairUIDTab(const std::string& key_id, QWidget* parent)
&KeyPairUIDTab::slot_refresh_sig_list);
// Key Database Refresh
- connect(SignalStation::GetInstance(),
- &SignalStation::SignalKeyDatabaseRefreshDone, this,
+ connect(UISignalStation::GetInstance(),
+ &UISignalStation::SignalKeyDatabaseRefreshDone, this,
&KeyPairUIDTab::slot_refresh_key);
connect(this, &KeyPairUIDTab::SignalUpdateUIDInfo,
- SignalStation::GetInstance(),
- &SignalStation::SignalKeyDatabaseRefresh);
+ UISignalStation::GetInstance(),
+ &UISignalStation::SignalKeyDatabaseRefresh);
- setLayout(vboxLayout);
+ setLayout(vbox_layout);
setAttribute(Qt::WA_DeleteOnClose, true);
slot_refresh_uid_list();
@@ -134,7 +137,7 @@ void KeyPairUIDTab::create_uid_list() {
uid_list_->setAlternatingRowColors(true);
QStringList labels;
- labels << _("Select") << _("Name") << _("Email") << _("Comment");
+ labels << tr("Select") << tr("Name") << tr("Email") << tr("Comment");
uid_list_->setHorizontalHeaderLabels(labels);
uid_list_->horizontalHeader()->setStretchLastSection(true);
}
@@ -157,8 +160,8 @@ void KeyPairUIDTab::create_sign_list() {
sig_list_->setAlternatingRowColors(true);
QStringList labels;
- labels << _("Key ID") << _("Name") << _("Email") << _("Create Date (UTC)")
- << _("Expired Date (UTC)");
+ labels << tr("Key ID") << tr("Name") << tr("Email") << tr("Create Date")
+ << tr("Expired Date");
sig_list_->setHorizontalHeaderLabels(labels);
sig_list_->horizontalHeader()->setStretchLastSection(false);
}
@@ -181,13 +184,13 @@ void KeyPairUIDTab::slot_refresh_uid_list() {
uid_list_->setRowCount(buffered_uids_.size());
for (const auto& uid : buffered_uids_) {
- auto* tmp0 = new QTableWidgetItem(QString::fromStdString(uid.GetUID()));
+ auto* tmp0 = new QTableWidgetItem(uid.GetName());
uid_list_->setItem(row, 1, tmp0);
- auto* tmp1 = new QTableWidgetItem(QString::fromStdString(uid.GetUID()));
+ auto* tmp1 = new QTableWidgetItem(uid.GetEmail());
uid_list_->setItem(row, 2, tmp1);
- auto* tmp2 = new QTableWidgetItem(QString::fromStdString(uid.GetUID()));
+ auto* tmp2 = new QTableWidgetItem(uid.GetComment());
uid_list_->setItem(row, 3, tmp2);
auto* tmp3 = new QTableWidgetItem(QString::number(row));
@@ -217,15 +220,15 @@ void KeyPairUIDTab::slot_refresh_uid_list() {
void KeyPairUIDTab::slot_refresh_tofu_info() {
if (this->tofu_tabs_ == nullptr) return;
- int uidRow = 0;
+ int uid_row = 0;
tofu_tabs_->clear();
for (const auto& uid : buffered_uids_) {
// Only Show Selected UID Signatures
- if (!uid_list_->item(uidRow++, 0)->isSelected()) {
+ if (!uid_list_->item(uid_row++, 0)->isSelected()) {
continue;
}
auto tofu_infos = uid.GetTofuInfos();
- SPDLOG_DEBUG("tofu info size: {}", tofu_infos->size());
+ GF_UI_LOG_DEBUG("tofu info size: {}", tofu_infos->size());
if (tofu_infos->empty()) {
tofu_tabs_->hide();
} else {
@@ -234,16 +237,17 @@ void KeyPairUIDTab::slot_refresh_tofu_info() {
int index = 1;
for (const auto& tofu_info : *tofu_infos) {
tofu_tabs_->addTab(new TOFUInfoPage(tofu_info, this),
- QString(_("TOFU %1")).arg(index++));
+ tr("TOFU %1").arg(index++));
}
}
}
void KeyPairUIDTab::slot_refresh_sig_list() {
- int uidRow = 0, sigRow = 0;
+ int uid_row = 0;
+ int sig_row = 0;
for (const auto& uid : buffered_uids_) {
// Only Show Selected UID Signatures
- if (!uid_list_->item(uidRow++, 0)->isSelected()) {
+ if (!uid_list_->item(uid_row++, 0)->isSelected()) {
continue;
}
@@ -259,52 +263,34 @@ void KeyPairUIDTab::slot_refresh_sig_list() {
sig_list_->setRowCount(buffered_signatures_.size());
for (const auto& sig : buffered_signatures_) {
- auto* tmp0 = new QTableWidgetItem(QString::fromStdString(sig.GetKeyID()));
- sig_list_->setItem(sigRow, 0, tmp0);
+ auto* tmp0 = new QTableWidgetItem(sig.GetKeyID());
+ sig_list_->setItem(sig_row, 0, tmp0);
if (gpgme_err_code(sig.GetStatus()) == GPG_ERR_NO_PUBKEY) {
auto* tmp2 = new QTableWidgetItem("<Unknown>");
- sig_list_->setItem(sigRow, 1, tmp2);
+ sig_list_->setItem(sig_row, 1, tmp2);
auto* tmp3 = new QTableWidgetItem("<Unknown>");
- sig_list_->setItem(sigRow, 2, tmp3);
+ sig_list_->setItem(sig_row, 2, tmp3);
} else {
- auto* tmp2 =
- new QTableWidgetItem(QString::fromStdString(sig.GetName()));
- sig_list_->setItem(sigRow, 1, tmp2);
+ auto* tmp2 = new QTableWidgetItem(sig.GetName());
+ sig_list_->setItem(sig_row, 1, tmp2);
- auto* tmp3 =
- new QTableWidgetItem(QString::fromStdString(sig.GetEmail()));
- sig_list_->setItem(sigRow, 2, tmp3);
+ auto* tmp3 = new QTableWidgetItem(sig.GetEmail());
+ sig_list_->setItem(sig_row, 2, tmp3);
}
-#ifdef GPGFRONTEND_GUI_QT6
- auto* tmp4 = new QTableWidgetItem(QLocale::system().toString(
- QDateTime::fromSecsSinceEpoch(to_time_t(sig.GetCreateTime()))));
-#else
- auto* tmp4 = new QTableWidgetItem(QLocale::system().toString(
- QDateTime::fromTime_t(to_time_t(sig.GetCreateTime()))));
-#endif
- sig_list_->setItem(sigRow, 3, tmp4);
+ auto* tmp4 =
+ new QTableWidgetItem(QLocale::system().toString(sig.GetCreateTime()));
+ sig_list_->setItem(sig_row, 3, tmp4);
-#ifdef GPGFRONTEND_GUI_QT6
- auto* tmp5 = new QTableWidgetItem(
- boost::posix_time::to_time_t(
- boost::posix_time::ptime(sig.GetExpireTime())) == 0
- ? _("Never Expires")
- : QLocale::system().toString(QDateTime::fromSecsSinceEpoch(
- to_time_t(sig.GetExpireTime()))));
-#else
auto* tmp5 = new QTableWidgetItem(
- boost::posix_time::to_time_t(
- boost::posix_time::ptime(sig.GetExpireTime())) == 0
- ? _("Never Expires")
- : QLocale::system().toString(
- QDateTime::fromTime_t(to_time_t(sig.GetExpireTime()))));
-#endif
+ sig.GetExpireTime().toSecsSinceEpoch() == 0
+ ? tr("Never Expires")
+ : QLocale::system().toString(sig.GetExpireTime()));
tmp5->setTextAlignment(Qt::AlignCenter);
- sig_list_->setItem(sigRow, 4, tmp5);
+ sig_list_->setItem(sig_row, 4, tmp5);
- sigRow++;
+ sig_row++;
}
break;
@@ -316,21 +302,22 @@ void KeyPairUIDTab::slot_add_sign() {
if (selected_uids->empty()) {
QMessageBox::information(
- nullptr, _("Invalid Operation"),
- _("Please select one or more UIDs before doing this operation."));
+ nullptr, tr("Invalid Operation"),
+ tr("Please select one or more UIDs before doing this operation."));
return;
}
- auto keySignDialog =
+ auto* key_sign_dialog =
new KeyUIDSignDialog(m_key_, std::move(selected_uids), this);
- keySignDialog->show();
+ key_sign_dialog->show();
}
-UIDArgsListPtr KeyPairUIDTab::get_uid_checked() {
+auto KeyPairUIDTab::get_uid_checked() -> UIDArgsListPtr {
auto selected_uids = std::make_unique<UIDArgsList>();
for (int i = 0; i < uid_list_->rowCount(); i++) {
- if (uid_list_->item(i, 0)->checkState() == Qt::Checked)
+ if (uid_list_->item(i, 0)->checkState() == Qt::Checked) {
selected_uids->push_back(buffered_uids_[i].GetUID());
+ }
}
return selected_uids;
}
@@ -338,33 +325,34 @@ UIDArgsListPtr KeyPairUIDTab::get_uid_checked() {
void KeyPairUIDTab::create_manage_uid_menu() {
manage_selected_uid_menu_ = new QMenu(this);
- auto* signUIDAct = new QAction(_("Sign Selected UID(s)"), this);
- connect(signUIDAct, &QAction::triggered, this, &KeyPairUIDTab::slot_add_sign);
- auto* delUIDAct = new QAction(_("Delete Selected UID(s)"), this);
- connect(delUIDAct, &QAction::triggered, this, &KeyPairUIDTab::slot_del_uid);
+ auto* sign_uid_act = new QAction(tr("Sign Selected UID(s)"), this);
+ connect(sign_uid_act, &QAction::triggered, this,
+ &KeyPairUIDTab::slot_add_sign);
+ auto* del_uid_act = new QAction(tr("Delete Selected UID(s)"), this);
+ connect(del_uid_act, &QAction::triggered, this, &KeyPairUIDTab::slot_del_uid);
if (m_key_.IsHasMasterKey()) {
- manage_selected_uid_menu_->addAction(signUIDAct);
- manage_selected_uid_menu_->addAction(delUIDAct);
+ manage_selected_uid_menu_->addAction(sign_uid_act);
+ manage_selected_uid_menu_->addAction(del_uid_act);
}
}
void KeyPairUIDTab::slot_add_uid() {
- auto keyNewUIDDialog = new KeyNewUIDDialog(m_key_.GetId(), this);
- connect(keyNewUIDDialog, &KeyNewUIDDialog::finished, this,
+ auto* key_new_uid_dialog = new KeyNewUIDDialog(m_key_.GetId(), this);
+ connect(key_new_uid_dialog, &KeyNewUIDDialog::finished, this,
&KeyPairUIDTab::slot_add_uid_result);
- connect(keyNewUIDDialog, &KeyNewUIDDialog::finished, keyNewUIDDialog,
+ connect(key_new_uid_dialog, &KeyNewUIDDialog::finished, key_new_uid_dialog,
&KeyPairUIDTab::deleteLater);
- keyNewUIDDialog->show();
+ key_new_uid_dialog->show();
}
void KeyPairUIDTab::slot_add_uid_result(int result) {
if (result == 1) {
- QMessageBox::information(nullptr, _("Successful Operation"),
- _("Successfully added a new UID."));
+ QMessageBox::information(nullptr, tr("Successful Operation"),
+ tr("Successfully added a new UID."));
} else if (result == -1) {
- QMessageBox::critical(nullptr, _("Operation Failed"),
- _("An error occurred during the operation."));
+ QMessageBox::critical(nullptr, tr("Operation Failed"),
+ tr("An error occurred during the operation."));
}
}
@@ -373,34 +361,33 @@ void KeyPairUIDTab::slot_del_uid() {
if (selected_uids->empty()) {
QMessageBox::information(
- nullptr, _("Invalid Operation"),
- _("Please select one or more UIDs before doing this operation."));
+ nullptr, tr("Invalid Operation"),
+ tr("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(uid);
keynames.append("<br/>");
}
int ret = QMessageBox::warning(
- this, _("Deleting UIDs"),
+ this, tr("Deleting UIDs"),
"<b>" +
QString(
- _("Are you sure that you want to delete the following UIDs?")) +
+ tr("Are you sure that you want to delete the following UIDs?")) +
"</b><br/><br/>" + keynames + +"<br/>" +
- _("The action can not be undone."),
+ tr("The action can not be undone."),
QMessageBox::No | QMessageBox::Yes);
if (ret == QMessageBox::Yes) {
for (const auto& uid : *selected_uids) {
- SPDLOG_DEBUG("uid: {}", uid);
+ GF_UI_LOG_DEBUG("uid: {}", uid);
if (!GpgUIDOperator::GetInstance().RevUID(m_key_, uid)) {
QMessageBox::critical(
- nullptr, _("Operation Failed"),
- QString(_("An error occurred during the delete %1 operation."))
- .arg(uid.c_str()));
+ nullptr, tr("Operation Failed"),
+ tr("An error occurred during the delete %1 operation.").arg(uid));
}
}
emit SignalUpdateUIDInfo();
@@ -411,37 +398,37 @@ void KeyPairUIDTab::slot_set_primary_uid() {
auto selected_uids = get_uid_selected();
if (selected_uids->empty()) {
- auto emptyUIDMsg = new QMessageBox();
- emptyUIDMsg->setText("Please select one UID before doing this operation.");
- emptyUIDMsg->exec();
+ auto* empty_uid_msg = new QMessageBox();
+ empty_uid_msg->setText(
+ "Please select one UID before doing this operation.");
+ empty_uid_msg->exec();
return;
}
QString keynames;
- keynames.append(QString::fromStdString(selected_uids->front()));
+ keynames.append(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?")) +
+ this, tr("Set Primary UID"),
+ "<b>" + tr("Are you sure that you want to set the Primary UID to?") +
"</b><br/><br/>" + keynames + +"<br/>" +
- _("The action can not be undone."),
+ tr("The action can not be undone."),
QMessageBox::No | QMessageBox::Yes);
if (ret == QMessageBox::Yes) {
if (!GpgUIDOperator::GetInstance().SetPrimaryUID(m_key_,
selected_uids->front())) {
- QMessageBox::critical(nullptr, _("Operation Failed"),
- _("An error occurred during the operation."));
+ QMessageBox::critical(nullptr, tr("Operation Failed"),
+ tr("An error occurred during the operation."));
} else {
emit SignalUpdateUIDInfo();
}
}
}
-UIDArgsListPtr KeyPairUIDTab::get_uid_selected() {
+auto KeyPairUIDTab::get_uid_selected() -> UIDArgsListPtr {
auto uids = std::make_unique<UIDArgsList>();
for (int i = 0; i < uid_list_->rowCount(); i++) {
if (uid_list_->item(i, 0)->isSelected()) {
@@ -451,7 +438,7 @@ UIDArgsListPtr KeyPairUIDTab::get_uid_selected() {
return uids;
}
-SignIdArgsListPtr KeyPairUIDTab::get_sign_selected() {
+auto KeyPairUIDTab::get_sign_selected() -> SignIdArgsListPtr {
auto signatures = std::make_unique<SignIdArgsList>();
for (int i = 0; i < sig_list_->rowCount(); i++) {
if (sig_list_->item(i, 0)->isSelected()) {
@@ -465,20 +452,20 @@ SignIdArgsListPtr KeyPairUIDTab::get_sign_selected() {
void KeyPairUIDTab::create_uid_popup_menu() {
uid_popup_menu_ = new QMenu(this);
- auto* serPrimaryUIDAct = new QAction(_("Set As Primary"), this);
- connect(serPrimaryUIDAct, &QAction::triggered, this,
+ auto* ser_primary_uid_act = new QAction(tr("Set As Primary"), this);
+ connect(ser_primary_uid_act, &QAction::triggered, this,
&KeyPairUIDTab::slot_set_primary_uid);
- auto* signUIDAct = new QAction(_("Sign UID"), this);
- connect(signUIDAct, &QAction::triggered, this,
+ auto* sign_uid_act = new QAction(tr("Sign UID"), this);
+ connect(sign_uid_act, &QAction::triggered, this,
&KeyPairUIDTab::slot_add_sign_single);
- auto* delUIDAct = new QAction(_("Delete UID"), this);
- connect(delUIDAct, &QAction::triggered, this,
+ auto* del_uid_act = new QAction(tr("Delete UID"), this);
+ connect(del_uid_act, &QAction::triggered, this,
&KeyPairUIDTab::slot_del_uid_single);
if (m_key_.IsHasMasterKey()) {
- uid_popup_menu_->addAction(serPrimaryUIDAct);
- uid_popup_menu_->addAction(signUIDAct);
- uid_popup_menu_->addAction(delUIDAct);
+ uid_popup_menu_->addAction(ser_primary_uid_act);
+ uid_popup_menu_->addAction(sign_uid_act);
+ uid_popup_menu_->addAction(del_uid_act);
}
}
@@ -494,43 +481,43 @@ void KeyPairUIDTab::slot_add_sign_single() {
if (selected_uids->empty()) {
QMessageBox::information(
- nullptr, _("Invalid Operation"),
- _("Please select one UID before doing this operation."));
+ nullptr, tr("Invalid Operation"),
+ tr("Please select one UID before doing this operation."));
return;
}
- auto keySignDialog =
+ auto* key_sign_dialog =
new KeyUIDSignDialog(m_key_, std::move(selected_uids), this);
- keySignDialog->show();
+ key_sign_dialog->show();
}
void KeyPairUIDTab::slot_del_uid_single() {
auto selected_uids = get_uid_selected();
if (selected_uids->empty()) {
QMessageBox::information(
- nullptr, _("Invalid Operation"),
- _("Please select one UID before doing this operation."));
+ nullptr, tr("Invalid Operation"),
+ tr("Please select one UID before doing this operation."));
return;
}
QString keynames;
- keynames.append(QString::fromStdString(selected_uids->front()));
+ keynames.append(selected_uids->front());
keynames.append("<br/>");
int ret = QMessageBox::warning(
- this, _("Deleting UID"),
+ this, tr("Deleting UID"),
"<b>" +
QString(
- _("Are you sure that you want to delete the following uid?")) +
+ tr("Are you sure that you want to delete the following uid?")) +
"</b><br/><br/>" + keynames + +"<br/>" +
- _("The action can not be undone."),
+ tr("The action can not be undone."),
QMessageBox::No | QMessageBox::Yes);
if (ret == QMessageBox::Yes) {
if (!GpgUIDOperator::GetInstance().RevUID(m_key_, selected_uids->front())) {
- QMessageBox::critical(nullptr, _("Operation Failed"),
- _("An error occurred during the operation."));
+ QMessageBox::critical(nullptr, tr("Operation Failed"),
+ tr("An error occurred during the operation."));
} else {
emit SignalUpdateUIDInfo();
}
@@ -540,18 +527,19 @@ void KeyPairUIDTab::slot_del_uid_single() {
void KeyPairUIDTab::create_sign_popup_menu() {
sign_popup_menu_ = new QMenu(this);
- auto* delSignAct = new QAction(_("Delete(Revoke) Key Signature"), this);
- connect(delSignAct, &QAction::triggered, this, &KeyPairUIDTab::slot_del_sign);
+ auto* del_sign_act = new QAction(tr("Delete(Revoke) Key Signature"), this);
+ connect(del_sign_act, &QAction::triggered, this,
+ &KeyPairUIDTab::slot_del_sign);
- sign_popup_menu_->addAction(delSignAct);
+ sign_popup_menu_->addAction(del_sign_act);
}
void KeyPairUIDTab::slot_del_sign() {
auto selected_signs = get_sign_selected();
if (selected_signs->empty()) {
QMessageBox::information(
- nullptr, _("Invalid Operation"),
- _("Please select one Key Signature before doing this operation."));
+ nullptr, tr("Invalid Operation"),
+ tr("Please select one Key Signature before doing this operation."));
return;
}
@@ -559,30 +547,29 @@ void KeyPairUIDTab::slot_del_sign() {
.GetKey(selected_signs->front().first)
.IsGood()) {
QMessageBox::critical(
- nullptr, _("Invalid Operation"),
- _("To delete the signature, you need to have its corresponding public "
- "key in the local database."));
+ 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(QString::fromStdString(selected_signs->front().second));
+ keynames.append(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);
+ 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 (!GpgKeyManager::GetInstance().RevSign(m_key_, selected_signs)) {
- QMessageBox::critical(nullptr, _("Operation Failed"),
- _("An error occurred during the operation."));
+ QMessageBox::critical(nullptr, tr("Operation Failed"),
+ tr("An error occurred during the operation."));
}
}
}
diff --git a/src/ui/dialog/keypair_details/KeyPairUIDTab.h b/src/ui/dialog/keypair_details/KeyPairUIDTab.h
index fae8f9f2..3655511d 100644
--- a/src/ui/dialog/keypair_details/KeyPairUIDTab.h
+++ b/src/ui/dialog/keypair_details/KeyPairUIDTab.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,18 +20,17 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_KEYPAIRUIDTAB_H
-#define GPGFRONTEND_KEYPAIRUIDTAB_H
+#pragma once
#include "KeyNewUIDDialog.h"
#include "KeyUIDSignDialog.h"
-#include "core/GpgContext.h"
+#include "core/function/gpg/GpgContext.h"
#include "ui/GpgFrontendUI.h"
namespace GpgFrontend::UI {
@@ -46,7 +45,7 @@ class KeyPairUIDTab : public QWidget {
* @param key_id
* @param parent
*/
- KeyPairUIDTab(const std::string& key_id, QWidget* parent);
+ KeyPairUIDTab(const QString& key_id, QWidget* parent);
signals:
@@ -203,5 +202,3 @@ class KeyPairUIDTab : public QWidget {
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_KEYPAIRUIDTAB_H
diff --git a/src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp b/src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp
index 89d2ce74..22d1db2a 100644
--- a/src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp
+++ b/src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,12 +28,11 @@
#include "KeySetExpireDateDialog.h"
-#include <utility>
-
#include "core/function/GlobalSettingStation.h"
#include "core/function/gpg/GpgKeyGetter.h"
#include "core/function/gpg/GpgKeyOpera.h"
-#include "ui/SignalStation.h"
+#include "core/utils/GpgUtils.h"
+#include "ui/UISignalStation.h"
#include "ui_ModifiedExpirationDateTime.h"
namespace GpgFrontend::UI {
@@ -41,49 +40,46 @@ namespace GpgFrontend::UI {
KeySetExpireDateDialog::KeySetExpireDateDialog(const KeyId& key_id,
QWidget* parent)
: GeneralDialog(typeid(KeySetExpireDateDialog).name(), parent),
- ui_(std::make_shared<Ui_ModifiedExpirationDateTime>()),
+ ui_(GpgFrontend::SecureCreateSharedObject<
+ Ui_ModifiedExpirationDateTime>()),
m_key_(GpgKeyGetter::GetInstance().GetKey(key_id)) {
init();
}
KeySetExpireDateDialog::KeySetExpireDateDialog(const KeyId& key_id,
- std::string subkey_fpr,
+ QString subkey_fpr,
QWidget* parent)
: GeneralDialog(typeid(KeySetExpireDateDialog).name(), parent),
- ui_(std::make_shared<Ui_ModifiedExpirationDateTime>()),
+ ui_(GpgFrontend::SecureCreateSharedObject<
+ Ui_ModifiedExpirationDateTime>()),
m_key_(GpgKeyGetter::GetInstance().GetKey(key_id)),
m_subkey_(std::move(subkey_fpr)) {
init();
}
void KeySetExpireDateDialog::slot_confirm() {
- SPDLOG_DEBUG("called: {} {}", ui_->dateEdit->date().toString().toStdString(),
- ui_->timeEdit->time().toString().toStdString());
+ GF_UI_LOG_DEBUG("called: {} {}",
+ ui_->dateEdit->date().toString().toStdString(),
+ ui_->timeEdit->time().toString().toStdString());
auto datetime = QDateTime(ui_->dateEdit->date(), ui_->timeEdit->time());
- std::unique_ptr<boost::posix_time::ptime> expires = nullptr;
+ std::unique_ptr<QDateTime> expires = nullptr;
if (ui_->noExpirationCheckBox->checkState() == Qt::Unchecked) {
-#ifdef GPGFRONTEND_GUI_QT6
- expires = std::make_unique<boost::posix_time::ptime>(
- boost::posix_time::from_time_t(
- datetime.toLocalTime().toSecsSinceEpoch()));
-#else
- expires = std::make_unique<boost::posix_time::ptime>(
- boost::posix_time::from_time_t(datetime.toLocalTime().toTime_t()));
-#endif
- SPDLOG_DEBUG("keyid: {}", m_key_.GetId(), m_subkey_,
- to_iso_string(*expires));
+ expires = std::make_unique<QDateTime>(datetime.toLocalTime());
+
+ GF_UI_LOG_DEBUG("keyid: {}", m_key_.GetId(), m_subkey_,
+ expires->toSecsSinceEpoch());
} else {
- SPDLOG_DEBUG("keyid: {}", m_key_.GetId(), m_subkey_, "Non Expired");
+ GF_UI_LOG_DEBUG("keyid: {}", m_key_.GetId(), m_subkey_, "Non Expired");
}
auto err = GpgKeyOpera::GetInstance().SetExpire(m_key_, m_subkey_, expires);
- if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) {
+ if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
auto* msg_box = new QMessageBox(qobject_cast<QWidget*>(this->parent()));
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->setWindowTitle(tr("Success"));
+ msg_box->setText(tr("The expire date of the key pair has been updated."));
msg_box->setModal(true);
msg_box->open();
@@ -92,24 +88,19 @@ void KeySetExpireDateDialog::slot_confirm() {
this->close();
} else {
QMessageBox::critical(
- this, _("Failure"),
- _("Failed to update the expire date of the key pair."));
+ this, tr("Failure"),
+ tr("Failed to update the expire date of the key pair."));
}
}
void KeySetExpireDateDialog::init() {
ui_->setupUi(this);
- auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
+ auto settings =
+ GpgFrontend::GlobalSettingStation::GetInstance().GetSettings();
- bool longer_expiration_date = false;
- try {
- longer_expiration_date = settings.lookup("general.longer_expiration_date");
- SPDLOG_DEBUG("longer_expiration_date: {}", longer_expiration_date);
-
- } catch (...) {
- SPDLOG_ERROR("setting operation error: longer_expiration_date");
- }
+ bool longer_expiration_date = longer_expiration_date =
+ settings.value("basic/longer_expiration_date").toBool();
auto max_date_time =
longer_expiration_date
@@ -122,13 +113,8 @@ void KeySetExpireDateDialog::init() {
ui_->dateEdit->setMinimumDateTime(min_date_time);
// set default date time to expire date time
-#ifdef GPGFRONTEND_GUI_QT6
- auto current_expire_time =
- QDateTime::fromSecsSinceEpoch(to_time_t(m_key_.GetExpireTime()));
-#else
- auto current_expire_time =
- QDateTime::fromTime_t(to_time_t(m_key_.GetExpireTime()));
-#endif
+ auto current_expire_time = m_key_.GetExpireTime();
+
ui_->dateEdit->setDateTime(current_expire_time);
ui_->timeEdit->setDateTime(current_expire_time);
@@ -137,16 +123,25 @@ void KeySetExpireDateDialog::init() {
connect(ui_->button_box_, &QDialogButtonBox::accepted, this,
&KeySetExpireDateDialog::slot_confirm);
connect(this, &KeySetExpireDateDialog::SignalKeyExpireDateUpdated,
- SignalStation::GetInstance(),
- &SignalStation::SignalKeyDatabaseRefresh);
-
- ui_->titleLabel->setText(_("Modified Expiration Date (Local Time)"));
- ui_->label->setText(
- _("Tips: For the sake of security, the key is valid for up to two years. "
- "If you are an expert user, please unlock it for a longer time in the "
- "settings."));
- ui_->noExpirationCheckBox->setText(_("No Expiration"));
- this->setWindowTitle(_("Modified Expiration Date"));
+ UISignalStation::GetInstance(),
+ &UISignalStation::SignalKeyDatabaseRefresh);
+
+ if (m_key_.GetExpireTime().toSecsSinceEpoch() == 0) {
+ ui_->noExpirationCheckBox->setCheckState(Qt::Checked);
+ } else {
+ ui_->dateEdit->setDateTime(m_key_.GetExpireTime());
+ ui_->timeEdit->setDateTime(m_key_.GetExpireTime());
+ }
+
+ ui_->titleLabel->setText(tr("Modified Expiration Date (Local Time)"));
+ ui_->label->setText(tr(
+ "Tips: For the sake of security, the key is valid for up to two years. "
+ "If you are an expert user, please unlock it for a longer time in the "
+ "settings."));
+ ui_->noExpirationCheckBox->setText(tr("No Expiration"));
+ this->setWindowTitle(tr("Modified Expiration Date"));
+ this->setAttribute(Qt::WA_DeleteOnClose);
+ this->setModal(true);
}
void KeySetExpireDateDialog::slot_non_expired_checked(int state) {
diff --git a/src/ui/dialog/keypair_details/KeySetExpireDateDialog.h b/src/ui/dialog/keypair_details/KeySetExpireDateDialog.h
index 3cd6cd01..633840ac 100644
--- a/src/ui/dialog/keypair_details/KeySetExpireDateDialog.h
+++ b/src/ui/dialog/keypair_details/KeySetExpireDateDialog.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,18 +20,17 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_KEYSETEXPIREDATEDIALOG_H
-#define GPGFRONTEND_KEYSETEXPIREDATEDIALOG_H
+#pragma once
-#include "core/GpgContext.h"
+#include "core/function/gpg/GpgContext.h"
#include "core/model/GpgKey.h"
-#include "core/model/GpgSubKey.h"
+#include "core/typedef/GpgTypedef.h"
#include "ui/GpgFrontendUI.h"
#include "ui/dialog/GeneralDialog.h"
@@ -58,7 +57,7 @@ class KeySetExpireDateDialog : public GeneralDialog {
* @param subkey_fpr
* @param parent
*/
- explicit KeySetExpireDateDialog(const KeyId& key_id, std::string subkey_fpr,
+ explicit KeySetExpireDateDialog(const KeyId& key_id, QString subkey_fpr,
QWidget* parent = nullptr);
signals:
@@ -95,5 +94,3 @@ class KeySetExpireDateDialog : public GeneralDialog {
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_KEYSETEXPIREDATEDIALOG_H
diff --git a/src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp b/src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp
index 12da3284..ba12f232 100644
--- a/src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp
+++ b/src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,16 +19,19 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "KeyUIDSignDialog.h"
+#include "core/GpgModel.h"
#include "core/function/gpg/GpgKeyGetter.h"
#include "core/function/gpg/GpgKeyManager.h"
-#include "ui/SignalStation.h"
+#include "ui/UISignalStation.h"
namespace GpgFrontend::UI {
@@ -40,15 +43,12 @@ KeyUIDSignDialog::KeyUIDSignDialog(const GpgKey& key, UIDArgsListPtr uid,
const auto key_id = m_key_.GetId();
m_key_list_ = new KeyList(KeyMenuAbility::NONE, this);
m_key_list_->AddListGroupTab(
- _("Signers"), "signers", KeyListRow::ONLY_SECRET_KEY,
+ tr("Signers"), "signers", KeyListRow::ONLY_SECRET_KEY,
KeyListColumn::NAME | KeyListColumn::EmailAddress,
[key_id](const GpgKey& key, const KeyTable&) -> bool {
- if (key.IsDisabled() || !key.IsHasCertificationCapability() ||
- !key.IsHasMasterKey() || key.IsExpired() || key.IsRevoked() ||
- key_id == key.GetId())
- return false;
- else
- return true;
+ return !(key.IsDisabled() || !key.IsHasCertificationCapability() ||
+ !key.IsHasMasterKey() || key.IsExpired() || key.IsRevoked() ||
+ key_id == key.GetId());
});
m_key_list_->SlotRefresh();
@@ -83,7 +83,7 @@ KeyUIDSignDialog::KeyUIDSignDialog(const GpgKey& key, UIDArgsListPtr uid,
layout->addWidget(m_key_list_, 0, 0);
layout->addWidget(sign_key_button_, 2, 0, Qt::AlignRight);
- timeLayout->addWidget(new QLabel(_("Expire Date")), 0, 0);
+ timeLayout->addWidget(new QLabel(tr("Expire Date")), 0, 0);
timeLayout->addWidget(expires_edit_, 0, 1);
timeLayout->addWidget(non_expire_check_, 0, 2);
layout->addLayout(timeLayout, 1, 0);
@@ -93,14 +93,14 @@ KeyUIDSignDialog::KeyUIDSignDialog(const GpgKey& key, UIDArgsListPtr uid,
this->setLayout(layout);
this->setModal(true);
- this->setWindowTitle(_("Sign For Key's UID(s)"));
+ this->setWindowTitle(tr("Sign For Key's UID(s)"));
this->adjustSize();
setAttribute(Qt::WA_DeleteOnClose, true);
connect(this, &KeyUIDSignDialog::SignalKeyUIDSignUpdate,
- SignalStation::GetInstance(),
- &SignalStation::SignalKeyDatabaseRefresh);
+ UISignalStation::GetInstance(),
+ &UISignalStation::SignalKeyDatabaseRefresh);
}
void KeyUIDSignDialog::slot_sign_key(bool clicked) {
@@ -108,29 +108,23 @@ void KeyUIDSignDialog::slot_sign_key(bool clicked) {
auto key_ids = m_key_list_->GetChecked();
auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
- SPDLOG_DEBUG("key info got");
-#ifdef GPGFRONTEND_GUI_QT6
- auto expires =
- std::make_unique<boost::posix_time::ptime>(boost::posix_time::from_time_t(
- expires_edit_->dateTime().toSecsSinceEpoch()));
-#else
- auto expires = std::make_unique<boost::posix_time::ptime>(
- boost::posix_time::from_time_t(expires_edit_->dateTime().toTime_t()));
-#endif
-
- SPDLOG_DEBUG("sign start");
+ GF_UI_LOG_DEBUG("key info got");
+ auto expires = std::make_unique<QDateTime>(expires_edit_->dateTime());
+
+ GF_UI_LOG_DEBUG("sign start");
for (const auto& uid : *m_uids_) {
- SPDLOG_DEBUG("sign uid: {}", uid);
+ GF_UI_LOG_DEBUG("sign uid: {}", uid);
// Sign For mKey
if (!GpgKeyManager::GetInstance().SignKey(m_key_, *keys, uid, expires)) {
QMessageBox::critical(
- nullptr, _("Unsuccessful Operation"),
- QString(_("Signature operation failed for UID %1")).arg(uid.c_str()));
+ nullptr, tr("Unsuccessful Operation"),
+ tr("Signature operation failed for UID %1").arg(uid));
}
}
- QMessageBox::information(nullptr, _("Operation Complete"),
- _("The signature operation of the UID is complete"));
+ QMessageBox::information(
+ nullptr, tr("Operation Complete"),
+ tr("The signature operation of the UID is complete"));
this->close();
emit SignalKeyUIDSignUpdate();
}
diff --git a/src/ui/dialog/keypair_details/KeyUIDSignDialog.h b/src/ui/dialog/keypair_details/KeyUIDSignDialog.h
index bfaff6d2..35d722ad 100644
--- a/src/ui/dialog/keypair_details/KeyUIDSignDialog.h
+++ b/src/ui/dialog/keypair_details/KeyUIDSignDialog.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,15 +19,16 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_KEYUIDSIGNDIALOG_H
-#define GPGFRONTEND_KEYUIDSIGNDIALOG_H
+#pragma once
-#include "core/GpgContext.h"
+#include "core/function/gpg/GpgContext.h"
#include "ui/GpgFrontendUI.h"
#include "ui/dialog/GeneralDialog.h"
#include "ui/widgets/KeyList.h"
@@ -74,5 +75,3 @@ class KeyUIDSignDialog : public GeneralDialog {
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_KEYUIDSIGNDIALOG_H
diff --git a/src/ui/dialog/settings/SettingsAdvanced.cpp b/src/ui/dialog/settings/SettingsAdvanced.cpp
deleted file mode 100644
index 9a02f473..00000000
--- a/src/ui/dialog/settings/SettingsAdvanced.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#include "SettingsAdvanced.h"
-
-#include "core/function/GlobalSettingStation.h"
-
-namespace GpgFrontend::UI {
-
-AdvancedTab::AdvancedTab(QWidget* parent) : QWidget(parent) {
- auto* stegano_box = new QGroupBox(_("Show Steganography Options"));
- auto* stegano_box_layout = new QHBoxLayout();
- stegano_check_box_ = new QCheckBox(_("Show Steganography Options."), this);
- stegano_box_layout->addWidget(stegano_check_box_);
- stegano_box->setLayout(stegano_box_layout);
-
- auto* pubkey_exchange_box = new QGroupBox(_("Pubkey Exchange"));
- auto* pubkey_exchange_box_layout = new QHBoxLayout();
- auto_pubkey_exchange_check_box_ =
- new QCheckBox(_("Auto Pubkey Exchange"), this);
- pubkey_exchange_box_layout->addWidget(auto_pubkey_exchange_check_box_);
- pubkey_exchange_box->setLayout(pubkey_exchange_box_layout);
-
- auto* main_layout = new QVBoxLayout;
- main_layout->addWidget(stegano_box);
- main_layout->addWidget(pubkey_exchange_box);
- SetSettings();
- main_layout->addStretch(1);
- setLayout(main_layout);
-}
-
-void AdvancedTab::SetSettings() {
- int stegano_checked = GlobalSettingStation::GetInstance().LookupSettings(
- "advanced.stegano_checked", false);
- if (stegano_checked) stegano_check_box_->setCheckState(Qt::Checked);
-
- int auto_pubkey_exchange_checked =
- GlobalSettingStation::GetInstance().LookupSettings(
- "advanced.auto_pubkey_exchange_checked", false);
- if (auto_pubkey_exchange_checked)
- auto_pubkey_exchange_check_box_->setCheckState(Qt::Checked);
-}
-
-void AdvancedTab::ApplySettings() {
- auto& settings =
- GpgFrontend::GlobalSettingStation::GetInstance().GetUISettings();
-
- if (!settings.exists("advanced") ||
- settings.lookup("advanced").getType() != libconfig::Setting::TypeGroup)
- settings.add("advanced", libconfig::Setting::TypeGroup);
-
- auto& advanced = settings["advanced"];
-
- if (!advanced.exists("stegano_checked"))
- advanced.add("stegano_checked", libconfig::Setting::TypeBoolean) =
- stegano_check_box_->isChecked();
- else {
- advanced["stegano_checked"] = stegano_check_box_->isChecked();
- }
-
- if (!advanced.exists("auto_pubkey_exchange_checked"))
- advanced.add("auto_pubkey_exchange_checked",
- libconfig::Setting::TypeBoolean) =
- auto_pubkey_exchange_check_box_->isChecked();
- else {
- advanced["auto_pubkey_exchange_checked"] =
- auto_pubkey_exchange_check_box_->isChecked();
- }
-}
-
-} // namespace GpgFrontend::UI
diff --git a/src/ui/dialog/settings/SettingsAppearance.cpp b/src/ui/dialog/settings/SettingsAppearance.cpp
index b5fbc6a3..d4f97c4c 100644
--- a/src/ui/dialog/settings/SettingsAppearance.cpp
+++ b/src/ui/dialog/settings/SettingsAppearance.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,36 +28,37 @@
#include "SettingsAppearance.h"
-#include "core/function/GlobalSettingStation.h"
+#include "core/utils/MemoryUtils.h"
#include "ui/struct/SettingsObject.h"
+#include "ui/struct/settings/AppearanceSO.h"
#include "ui_AppearanceSettings.h"
namespace GpgFrontend::UI {
AppearanceTab::AppearanceTab(QWidget* parent)
- : QWidget(parent), ui_(std::make_shared<Ui_AppearanceSettings>()) {
+ : QWidget(parent), ui_(SecureCreateSharedObject<Ui_AppearanceSettings>()) {
ui_->setupUi(this);
- ui_->iconSizeBox->setTitle(_("Icon Size"));
- ui_->smallRadioButton->setText(_("small"));
- ui_->mediumRadioButton->setText(_("medium"));
- ui_->largeRadioButton->setText(_("large"));
+ ui_->iconSizeBox->setTitle(tr("Icon Size"));
+ ui_->smallRadioButton->setText(tr("small"));
+ ui_->mediumRadioButton->setText(tr("medium"));
+ ui_->largeRadioButton->setText(tr("large"));
- ui_->iconStyleBox->setTitle(_("Icon Style"));
- ui_->justTextRadioButton->setText(_("just text"));
- ui_->justIconRadioButton->setText(_("just icons"));
- ui_->textAndIconsRadioButton->setText(_("text and icons"));
+ ui_->iconStyleBox->setTitle(tr("Icon Style"));
+ ui_->justTextRadioButton->setText(tr("just text"));
+ ui_->justIconRadioButton->setText(tr("just icons"));
+ ui_->textAndIconsRadioButton->setText(tr("text and icons"));
- ui_->windowStateBox->setTitle(_("Window State"));
+ ui_->windowStateBox->setTitle(tr("Window State"));
ui_->windowStateCheckBox->setText(
- _("Save window size and position on exit."));
+ tr("Save window size and position on exit."));
- ui_->textEditorBox->setTitle(_("Text Editor"));
- ui_->fontSizeTextEditorLabel->setText(_("Font Size in Text Editor"));
+ ui_->textEditorBox->setTitle(tr("Text Editor"));
+ ui_->fontSizeTextEditorLabel->setText(tr("Font Size in Text Editor"));
- ui_->informationBoardBox->setTitle(_("Information Board"));
+ ui_->informationBoardBox->setTitle(tr("Information Board"));
ui_->fontSizeInformationBoardLabel->setText(
- _("Font Size in Information Board"));
+ tr("Font Size in Information Board"));
icon_size_group_ = new QButtonGroup(this);
icon_size_group_->addButton(ui_->smallRadioButton, 1);
@@ -73,12 +74,10 @@ AppearanceTab::AppearanceTab(QWidget* parent)
}
void AppearanceTab::SetSettings() {
- SettingsObject general_settings_state("general_settings_state");
-
- int width = general_settings_state.Check("icon_size").Check("width", 24),
- height = general_settings_state.Check("icon_size").Check("height", 24);
+ AppearanceSO appearance(SettingsObject("general_settings_state"));
- auto icon_size = QSize(width, height);
+ auto icon_size =
+ QSize(appearance.tool_bar_icon_width, appearance.tool_bar_icon_height);
switch (icon_size.width()) {
case 12:
@@ -90,14 +89,12 @@ void AppearanceTab::SetSettings() {
case 32:
ui_->largeRadioButton->setChecked(true);
break;
+ default:
+ ui_->smallRadioButton->setChecked(true);
+ break;
}
- // icon_style
- int s_icon_style =
- general_settings_state.Check("icon_style", Qt::ToolButtonTextUnderIcon);
- auto icon_style = static_cast<Qt::ToolButtonStyle>(s_icon_style);
-
- switch (icon_style) {
+ switch (appearance.tool_bar_button_style) {
case Qt::ToolButtonTextOnly:
ui_->justTextRadioButton->setChecked(true);
break;
@@ -111,24 +108,26 @@ void AppearanceTab::SetSettings() {
break;
}
- bool window_save = general_settings_state.Check("window_save", true);
- if (window_save) ui_->windowStateCheckBox->setCheckState(Qt::Checked);
+ if (appearance.save_window_state) {
+ ui_->windowStateCheckBox->setCheckState(Qt::Checked);
+ }
- auto info_board_info_font_size =
- general_settings_state.Check("info_board").Check("font_size", 10);
- if (info_board_info_font_size < 9 || info_board_info_font_size > 18)
+ auto info_board_info_font_size = appearance.info_board_font_size;
+ if (info_board_info_font_size < 9 || info_board_info_font_size > 18) {
info_board_info_font_size = 10;
+ }
ui_->fontSizeInformationBoardSpinBox->setValue(info_board_info_font_size);
- auto text_editor_info_font_size =
- general_settings_state.Check("text_editor").Check("font_size", 10);
- if (text_editor_info_font_size < 9 || text_editor_info_font_size > 18)
+ auto text_editor_info_font_size = appearance.text_editor_font_size;
+ if (text_editor_info_font_size < 9 || text_editor_info_font_size > 18) {
text_editor_info_font_size = 10;
+ }
ui_->fontSizeTextEditorLabelSpinBox->setValue(text_editor_info_font_size);
}
void AppearanceTab::ApplySettings() {
SettingsObject general_settings_state("general_settings_state");
+ AppearanceSO appearance(general_settings_state);
int icon_size = 24;
switch (icon_size_group_->checkedId()) {
@@ -143,8 +142,8 @@ void AppearanceTab::ApplySettings() {
break;
}
- general_settings_state["icon_size"]["width"] = icon_size;
- general_settings_state["icon_size"]["height"] = icon_size;
+ appearance.tool_bar_icon_height = icon_size;
+ appearance.tool_bar_icon_width = icon_size;
auto icon_style = Qt::ToolButtonTextUnderIcon;
switch (icon_style_group_->checkedId()) {
@@ -157,17 +156,19 @@ void AppearanceTab::ApplySettings() {
case 3:
icon_style = Qt::ToolButtonTextUnderIcon;
break;
+ default:
+ icon_style = Qt::ToolButtonTextOnly;
+ break;
}
+ appearance.tool_bar_button_style = icon_style;
- general_settings_state["icon_style"] = icon_style;
-
- general_settings_state["window_save"] = ui_->windowStateCheckBox->isChecked();
-
- general_settings_state["info_board"]["font_size"] =
+ appearance.save_window_state = ui_->windowStateCheckBox->isChecked();
+ appearance.info_board_font_size =
ui_->fontSizeInformationBoardSpinBox->value();
-
- general_settings_state["text_editor"]["font_size"] =
+ appearance.text_editor_font_size =
ui_->fontSizeTextEditorLabelSpinBox->value();
+
+ general_settings_state.Store(appearance.ToJson());
}
} // namespace GpgFrontend::UI
diff --git a/src/ui/dialog/settings/SettingsAppearance.h b/src/ui/dialog/settings/SettingsAppearance.h
index 8a38c666..6d426934 100644
--- a/src/ui/dialog/settings/SettingsAppearance.h
+++ b/src/ui/dialog/settings/SettingsAppearance.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,14 +20,13 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_SETTINGSAPPEARANCE_H
-#define GPGFRONTEND_SETTINGSAPPEARANCE_H
+#pragma once
#include "ui/GpgFrontendUI.h"
@@ -61,7 +60,7 @@ class AppearanceTab : public QWidget {
private:
std::shared_ptr<Ui_AppearanceSettings> ui_; ///<
- QButtonGroup* icon_style_group_; ///<
+ QButtonGroup* icon_style_group_; ///<
QButtonGroup* icon_size_group_;
signals:
@@ -75,5 +74,3 @@ class AppearanceTab : public QWidget {
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_SETTINGSAPPEARANCE_H
diff --git a/src/ui/dialog/settings/SettingsDialog.cpp b/src/ui/dialog/settings/SettingsDialog.cpp
index d484207a..a1ac1885 100644
--- a/src/ui/dialog/settings/SettingsDialog.cpp
+++ b/src/ui/dialog/settings/SettingsDialog.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,13 +28,13 @@
#include "SettingsDialog.h"
-#include "SettingsAdvanced.h"
-#include "SettingsAppearance.h"
-#include "SettingsGeneral.h"
-#include "SettingsKeyServer.h"
-#include "SettingsNetwork.h"
#include "core/GpgConstants.h"
+#include "core/GpgModel.h"
#include "core/function/GlobalSettingStation.h"
+#include "ui/dialog/settings/SettingsAppearance.h"
+#include "ui/dialog/settings/SettingsGeneral.h"
+#include "ui/dialog/settings/SettingsKeyServer.h"
+#include "ui/dialog/settings/SettingsNetwork.h"
#include "ui/main_window/MainWindow.h"
namespace GpgFrontend::UI {
@@ -47,14 +47,14 @@ SettingsDialog::SettingsDialog(QWidget* parent)
key_server_tab_ = new KeyserverTab();
network_tab_ = new NetworkTab();
- auto* mainLayout = new QVBoxLayout;
- mainLayout->addWidget(tab_widget_);
- mainLayout->stretch(0);
+ auto* main_layout = new QVBoxLayout();
+ main_layout->addWidget(tab_widget_);
+ main_layout->stretch(0);
- tab_widget_->addTab(general_tab_, _("General"));
- tab_widget_->addTab(appearance_tab_, _("Appearance"));
- tab_widget_->addTab(key_server_tab_, _("Key Server"));
- tab_widget_->addTab(network_tab_, _("Network"));
+ tab_widget_->addTab(general_tab_, tr("General"));
+ tab_widget_->addTab(appearance_tab_, tr("Appearance"));
+ tab_widget_->addTab(key_server_tab_, tr("Key Server"));
+ tab_widget_->addTab(network_tab_, tr("Network"));
#ifndef MACOS
button_box_ =
@@ -65,14 +65,14 @@ SettingsDialog::SettingsDialog(QWidget* parent)
&SettingsDialog::reject);
mainLayout->addWidget(button_box_);
mainLayout->stretch(0);
- setWindowTitle(_("Settings"));
+ setWindowTitle(tr("Settings"));
#else
connect(this, &QDialog::finished, this, &SettingsDialog::SlotAccept);
connect(this, &QDialog::finished, this, &SettingsDialog::deleteLater);
- setWindowTitle(_("Preference"));
+ setWindowTitle(tr("Preference"));
#endif
- setLayout(mainLayout);
+ setLayout(main_layout);
// slots for handling the restart needed member
this->slot_set_restart_needed(0);
@@ -80,16 +80,17 @@ SettingsDialog::SettingsDialog(QWidget* parent)
// restart ui
connect(general_tab_, &GeneralTab::SignalRestartNeeded, this,
[=](bool needed) {
- if (needed && restart_needed_ < RESTART_CODE) {
- this->restart_needed_ = RESTART_CODE;
+ if (needed && restart_needed_ < kRestartCode) {
+ this->restart_needed_ = kRestartCode;
}
});
// restart core and ui
connect(general_tab_, &GeneralTab::SignalDeepRestartNeeded, this,
[=](bool needed) {
- if (needed && restart_needed_ < DEEP_RESTART_CODE)
- this->restart_needed_ = DEEP_RESTART_CODE;
+ if (needed && restart_needed_ < kDeepRestartCode) {
+ this->restart_needed_ = kDeepRestartCode;
+ }
});
// announce main window
@@ -101,7 +102,9 @@ SettingsDialog::SettingsDialog(QWidget* parent)
this->show();
}
-int SettingsDialog::get_restart_needed() const { return this->restart_needed_; }
+auto SettingsDialog::get_restart_needed() const -> int {
+ return this->restart_needed_;
+}
void SettingsDialog::slot_set_restart_needed(int mode) {
this->restart_needed_ = mode;
@@ -113,44 +116,31 @@ void SettingsDialog::SlotAccept() {
key_server_tab_->ApplySettings();
network_tab_->ApplySettings();
- SPDLOG_DEBUG("apply done");
-
- // write settings to filesystem
- GlobalSettingStation::GetInstance().SyncSettings();
-
- SPDLOG_DEBUG("restart needed: {}", get_restart_needed());
- if (get_restart_needed()) {
+ GF_UI_LOG_DEBUG("restart needed: {}", get_restart_needed());
+ if (get_restart_needed() != 0) {
emit SignalRestartNeeded(get_restart_needed());
}
close();
}
-QHash<QString, QString> SettingsDialog::ListLanguages() {
+auto SettingsDialog::ListLanguages() -> QHash<QString, QString> {
QHash<QString, QString> languages;
+ languages.insert(QString(), tr("System Default"));
- languages.insert(QString(), _("System Default"));
-
- auto locale_path = GlobalSettingStation::GetInstance().GetLocaleDir();
+ QStringList filenames = QDir(QLatin1String(":/i18n")).entryList();
+ for (const auto& file : filenames) {
+ GF_UI_LOG_DEBUG("get locale from locale directory: {}", file.toStdString());
- auto locale_dir = QDir(QString::fromStdString(locale_path.string()));
- QStringList file_names = locale_dir.entryList(QStringList("*"));
+ auto start = file.indexOf('.') + 1;
+ auto end = file.lastIndexOf('.');
+ if (start < 0 || end < 0 || start >= end) continue;
- for (int i = 0; i < file_names.size(); ++i) {
- QString locale = file_names[i];
- SPDLOG_DEBUG("locale: {}", locale.toStdString());
- if (locale == "." || locale == "..") continue;
+ auto locale = file.mid(start, end - start);
+ QLocale const q_locale(locale);
+ if (q_locale.nativeTerritoryName().isEmpty()) continue;
- // 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);
+ languages.insert(q_locale.name(), language);
}
return languages;
}
diff --git a/src/ui/dialog/settings/SettingsDialog.h b/src/ui/dialog/settings/SettingsDialog.h
index d28013f4..e59cd611 100644
--- a/src/ui/dialog/settings/SettingsDialog.h
+++ b/src/ui/dialog/settings/SettingsDialog.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,14 +20,13 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef __SETTINGSDIALOG_H__
-#define __SETTINGSDIALOG_H__
+#pragma once
#include "ui/GpgFrontendUI.h"
#include "ui/dialog/GeneralDialog.h"
@@ -108,5 +107,3 @@ class SettingsDialog : public GeneralDialog {
};
} // namespace GpgFrontend::UI
-
-#endif // __SETTINGSDIALOG_H__
diff --git a/src/ui/dialog/settings/SettingsGeneral.cpp b/src/ui/dialog/settings/SettingsGeneral.cpp
index be5190dd..44c66e10 100644
--- a/src/ui/dialog/settings/SettingsGeneral.cpp
+++ b/src/ui/dialog/settings/SettingsGeneral.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,224 +28,126 @@
#include "SettingsGeneral.h"
-#include "core/GpgContext.h"
-
-#ifdef MULTI_LANG_SUPPORT
#include "SettingsDialog.h"
-#endif
-
+#include "core/GpgModel.h"
#include "core/function/GlobalSettingStation.h"
#include "ui_GeneralSettings.h"
namespace GpgFrontend::UI {
GeneralTab::GeneralTab(QWidget* parent)
- : QWidget(parent), ui_(std::make_shared<Ui_GeneralSettings>()) {
+ : QWidget(parent),
+ ui_(GpgFrontend::SecureCreateSharedObject<Ui_GeneralSettings>()) {
ui_->setupUi(this);
- ui_->cacheBox->setTitle(_("Cache"));
- ui_->saveCheckedKeysCheckBox->setText(
- _("Save checked private keys on exit and restore them on next start."));
+ ui_->cacheBox->setTitle(tr("Cache"));
ui_->clearGpgPasswordCacheCheckBox->setText(
- _("Clear gpg password cache when closing GpgFrontend."));
+ tr("Clear gpg password cache when closing GpgFrontend."));
ui_->restoreTextEditorPageCheckBox->setText(
- _("Automatically restore unsaved Text Editor pages after an application "
- "crash."));
+ tr("Automatically restore unsaved Text Editor pages after an application "
+ "crash."));
- ui_->importConfirmationBox->setTitle(_("Operation"));
+ ui_->importConfirmationBox->setTitle(tr("Operation"));
ui_->longerKeyExpirationDateCheckBox->setText(
- _("Enable to use longer key expiration date."));
+ tr("Enable to use longer key expiration date."));
ui_->importConfirmationCheckBox->setText(
- _("Import files dropped on the Key List without confirmation."));
+ tr("Import files dropped on the Key List without confirmation."));
- ui_->langBox->setTitle(_("Language"));
+ ui_->langBox->setTitle(tr("Language"));
ui_->langNoteLabel->setText(
- "<b>" + QString(_("NOTE")) + _(": ") + "</b>" +
- _("GpgFrontend will restart automatically if you change the language!"));
-
- ui_->dataBox->setTitle(_("Data"));
- ui_->clearAllLogFilesButton->setText(QString::fromStdString(
- (boost::format(_("Clear All Log (Total Size: %s)")) %
- GlobalSettingStation::GetInstance().GetLogFilesSize())
- .str()));
- ui_->clearAllDataObjectsButton->setText(QString::fromStdString(
- (boost::format(_("Clear All Data Objects (Total Size: %s)")) %
- GlobalSettingStation::GetInstance().GetDataObjectsFilesSize())
- .str()));
-
-#ifdef MULTI_LANG_SUPPORT
+ "<b>" + tr("NOTE") + tr(": ") + "</b>" +
+ tr("GpgFrontend will restart automatically if you change the language!"));
+
+ ui_->dataBox->setTitle(tr("Data"));
+ ui_->clearAllLogFilesButton->setText(
+ tr("Clear All Log (Total Size: %1)")
+ .arg(GlobalSettingStation::GetInstance().GetLogFilesSize()));
+ ui_->clearAllDataObjectsButton->setText(
+ tr("Clear All Data Objects (Total Size: %1)")
+ .arg(GlobalSettingStation::GetInstance().GetDataObjectsFilesSize()));
+
lang_ = SettingsDialog::ListLanguages();
for (const auto& l : lang_) {
ui_->langSelectBox->addItem(l);
}
connect(ui_->langSelectBox, qOverload<int>(&QComboBox::currentIndexChanged),
this, &GeneralTab::slot_language_changed);
-#endif
connect(ui_->clearAllLogFilesButton, &QPushButton::clicked, this, [=]() {
GlobalSettingStation::GetInstance().ClearAllLogFiles();
- ui_->clearAllLogFilesButton->setText(QString::fromStdString(
- (boost::format(_("Clear All Log (Total Size: %s)")) %
- GlobalSettingStation::GetInstance().GetLogFilesSize())
- .str()));
+ ui_->clearAllLogFilesButton->setText(
+ tr("Clear All Log (Total Size: %1)")
+ .arg(GlobalSettingStation::GetInstance().GetLogFilesSize()));
});
connect(ui_->clearAllDataObjectsButton, &QPushButton::clicked, this, [=]() {
QMessageBox::StandardButton reply;
reply = QMessageBox::question(
- this, _("Confirm"),
- _("Are you sure you want to clear all data objects?\nThis will result "
- "in "
- "loss of all cached form positions, statuses, key servers, etc."),
+ this, tr("Confirm"),
+ tr("Are you sure you want to clear all data objects?\nThis will result "
+ "in loss of all cached form positions, statuses, key servers, etc."),
QMessageBox::Yes | QMessageBox::No);
if (reply == QMessageBox::Yes) {
GlobalSettingStation::GetInstance().ClearAllDataObjects();
- ui_->clearAllDataObjectsButton->setText(QString::fromStdString(
- (boost::format(_("Clear All Data Objects (Total Size: %s)")) %
- GlobalSettingStation::GetInstance().GetDataObjectsFilesSize())
- .str()));
+ ui_->clearAllDataObjectsButton->setText(
+ tr("Clear All Data Objects (Total Size: %1)")
+ .arg(GlobalSettingStation::GetInstance()
+ .GetDataObjectsFilesSize()));
}
});
SetSettings();
}
-/**********************************
- * Read the settings from config
- * and set the buttons and checkboxes
- * appropriately
- **********************************/
void GeneralTab::SetSettings() {
- auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
-
- try {
- bool save_key_checked = settings.lookup("general.save_key_checked");
- if (save_key_checked)
- ui_->saveCheckedKeysCheckBox->setCheckState(Qt::Checked);
- } catch (...) {
- SPDLOG_ERROR("setting operation error: save_key_checked");
- }
-
- try {
- bool clear_gpg_password_cache =
- settings.lookup("general.clear_gpg_password_cache");
- if (clear_gpg_password_cache)
- ui_->clearGpgPasswordCacheCheckBox->setCheckState(Qt::Checked);
- } catch (...) {
- SPDLOG_ERROR("setting operation error: clear_gpg_password_cache");
- }
-
- try {
- bool restore_text_editor_page =
- settings.lookup("general.restore_text_editor_page");
- if (restore_text_editor_page)
- ui_->restoreTextEditorPageCheckBox->setCheckState(Qt::Checked);
- } catch (...) {
- SPDLOG_ERROR("setting operation error: restore_text_editor_page");
- }
-
- try {
- bool longer_expiration_date =
- settings.lookup("general.longer_expiration_date");
- SPDLOG_DEBUG("longer_expiration_date: {}", longer_expiration_date);
- if (longer_expiration_date)
- ui_->longerKeyExpirationDateCheckBox->setCheckState(Qt::Checked);
- } catch (...) {
- SPDLOG_ERROR("setting operation error: longer_expiration_date");
- }
-
-#ifdef MULTI_LANG_SUPPORT
- try {
- std::string lang_key = settings.lookup("general.lang");
- QString lang_value = lang_.value(lang_key.c_str());
- SPDLOG_DEBUG("lang settings current: {}", lang_value.toStdString());
- if (!lang_.empty()) {
- ui_->langSelectBox->setCurrentIndex(
- ui_->langSelectBox->findText(lang_value));
- } else {
- ui_->langSelectBox->setCurrentIndex(0);
- }
- } catch (...) {
- SPDLOG_ERROR("setting operation error: lang");
- }
-#endif
-
- try {
- bool confirm_import_keys = settings.lookup("general.confirm_import_keys");
- SPDLOG_DEBUG("confirm_import_keys: {}", confirm_import_keys);
- if (confirm_import_keys)
- ui_->importConfirmationCheckBox->setCheckState(Qt::Checked);
- } catch (...) {
- SPDLOG_ERROR("setting operation error: confirm_import_keys");
+ auto settings = GlobalSettingStation::GetInstance().GetSettings();
+
+ bool clear_gpg_password_cache =
+ settings.value("basic/clear_gpg_password_cache", true).toBool();
+ ui_->clearGpgPasswordCacheCheckBox->setCheckState(
+ clear_gpg_password_cache ? Qt::Checked : Qt::Unchecked);
+
+ bool restore_text_editor_page =
+ settings.value("basic/restore_text_editor_page", true).toBool();
+ ui_->restoreTextEditorPageCheckBox->setCheckState(
+ restore_text_editor_page ? Qt::Checked : Qt::Unchecked);
+
+ bool longer_expiration_date =
+ settings.value("basic/longer_expiration_date", false).toBool();
+ ui_->longerKeyExpirationDateCheckBox->setCheckState(
+ longer_expiration_date ? Qt::Checked : Qt::Unchecked);
+
+ bool confirm_import_keys =
+ settings.value("basic/confirm_import_keys", false).toBool();
+ ui_->importConfirmationCheckBox->setCheckState(
+ confirm_import_keys ? Qt::Checked : Qt::Unchecked);
+
+ QString lang_key = settings.value("basic/lang").toString();
+ QString lang_value = lang_.value(lang_key);
+ GF_UI_LOG_DEBUG("lang settings current: {}", lang_value.toStdString());
+ if (!lang_.empty()) {
+ ui_->langSelectBox->setCurrentIndex(
+ ui_->langSelectBox->findText(lang_value));
+ } else {
+ ui_->langSelectBox->setCurrentIndex(0);
}
}
-/***********************************
- * get the values of the buttons and
- * write them to settings-file
- *************************************/
void GeneralTab::ApplySettings() {
- auto& settings =
- GpgFrontend::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("longer_expiration_date"))
- general.add("longer_expiration_date", libconfig::Setting::TypeBoolean) =
- ui_->longerKeyExpirationDateCheckBox->isChecked();
- else {
- general["longer_expiration_date"] =
- ui_->longerKeyExpirationDateCheckBox->isChecked();
- }
-
- if (!general.exists("save_key_checked"))
- general.add("save_key_checked", libconfig::Setting::TypeBoolean) =
- ui_->saveCheckedKeysCheckBox->isChecked();
- else {
- general["save_key_checked"] = ui_->saveCheckedKeysCheckBox->isChecked();
- }
-
- if (!general.exists("clear_gpg_password_cache"))
- general.add("clear_gpg_password_cache", libconfig::Setting::TypeBoolean) =
- ui_->clearGpgPasswordCacheCheckBox->isChecked();
- else {
- general["clear_gpg_password_cache"] =
- ui_->saveCheckedKeysCheckBox->isChecked();
- }
-
- if (!general.exists("restore_text_editor_page"))
- general.add("restore_text_editor_page", libconfig::Setting::TypeBoolean) =
- ui_->restoreTextEditorPageCheckBox->isChecked();
- else {
- general["restore_text_editor_page"] =
- ui_->restoreTextEditorPageCheckBox->isChecked();
- }
-
-#ifdef MULTI_LANG_SUPPORT
- if (!general.exists("lang"))
- general.add("lang", libconfig::Setting::TypeBoolean) =
- lang_.key(ui_->langSelectBox->currentText()).toStdString();
- else {
- general["lang"] =
- lang_.key(ui_->langSelectBox->currentText()).toStdString();
- }
-#endif
-
- if (!general.exists("confirm_import_keys"))
- general.add("confirm_import_keys", libconfig::Setting::TypeBoolean) =
- ui_->importConfirmationCheckBox->isChecked();
- else {
- general["confirm_import_keys"] =
- ui_->importConfirmationCheckBox->isChecked();
- }
+ auto settings =
+ GpgFrontend::GlobalSettingStation::GetInstance().GetSettings();
+
+ settings.setValue("basic/longer_expiration_date",
+ ui_->longerKeyExpirationDateCheckBox->isChecked());
+ settings.setValue("basic/clear_gpg_password_cache",
+ ui_->clearGpgPasswordCacheCheckBox->isChecked());
+ settings.setValue("basic/restore_text_editor_page",
+ ui_->restoreTextEditorPageCheckBox->isChecked());
+ settings.setValue("basic/confirm_import_keys",
+ ui_->importConfirmationCheckBox->isChecked());
+ settings.setValue("basic/lang", lang_.key(ui_->langSelectBox->currentText()));
}
-#ifdef MULTI_LANG_SUPPORT
void GeneralTab::slot_language_changed() { emit SignalRestartNeeded(true); }
-#endif
} // namespace GpgFrontend::UI
diff --git a/src/ui/dialog/settings/SettingsGeneral.h b/src/ui/dialog/settings/SettingsGeneral.h
index be145b1f..284843d4 100644
--- a/src/ui/dialog/settings/SettingsGeneral.h
+++ b/src/ui/dialog/settings/SettingsGeneral.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,14 +20,13 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_SETTINGSGENERAL_H
-#define GPGFRONTEND_SETTINGSGENERAL_H
+#pragma once
#include "ui/GpgFrontendUI.h"
@@ -81,25 +80,16 @@ class GeneralTab : public QWidget {
private:
std::shared_ptr<Ui_GeneralSettings> ui_; ///<
-
-#ifdef MULTI_LANG_SUPPORT
- QHash<QString, QString> lang_; ///<
-#endif
-
- std::vector<std::string> key_ids_list_; ///<
-
- KeyList* m_key_list_{}; ///<
+ QHash<QString, QString> lang_; ///<
+ std::vector<QString> key_ids_list_; ///<
+ KeyList* m_key_list_{}; ///<
private slots:
-#ifdef MULTI_LANG_SUPPORT
/**
* @brief
*
*/
void slot_language_changed();
-#endif
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_SETTINGSGENERAL_H
diff --git a/src/ui/dialog/settings/SettingsKeyServer.cpp b/src/ui/dialog/settings/SettingsKeyServer.cpp
index 83bd2c80..5613ed45 100644
--- a/src/ui/dialog/settings/SettingsKeyServer.cpp
+++ b/src/ui/dialog/settings/SettingsKeyServer.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,17 +28,21 @@
#include "SettingsKeyServer.h"
+#include <cstddef>
+
#include "core/function/GlobalSettingStation.h"
#include "core/thread/Task.h"
#include "core/thread/TaskRunnerGetter.h"
#include "ui/struct/SettingsObject.h"
+#include "ui/struct/settings/KeyServerSO.h"
#include "ui/thread/ListedKeyServerTestTask.h"
#include "ui_KeyServerSettings.h"
namespace GpgFrontend::UI {
KeyserverTab::KeyserverTab(QWidget* parent)
- : QWidget(parent), ui_(std::make_shared<Ui_KeyServerSettings>()) {
+ : QWidget(parent),
+ ui_(GpgFrontend::SecureCreateSharedObject<Ui_KeyServerSettings>()) {
ui_->setupUi(this);
ui_->keyServerListTable->setSizeAdjustPolicy(
QAbstractScrollArea::AdjustToContents);
@@ -48,25 +52,25 @@ KeyserverTab::KeyserverTab(QWidget* parent)
connect(ui_->testKeyServerButton, &QPushButton::clicked, this,
&KeyserverTab::slot_test_listed_key_server);
- ui_->keyServerListGroupBox->setTitle(_("Keyserver List"));
- ui_->operationsGroupBox->setTitle(_("Operations"));
+ ui_->keyServerListGroupBox->setTitle(tr("Keyserver List"));
+ ui_->operationsGroupBox->setTitle(tr("Operations"));
- ui_->keyServerListTable->horizontalHeaderItem(0)->setText(_("Default"));
+ ui_->keyServerListTable->horizontalHeaderItem(0)->setText(tr("Default"));
ui_->keyServerListTable->horizontalHeaderItem(1)->setText(
- _("Keyserver Address"));
- ui_->keyServerListTable->horizontalHeaderItem(2)->setText(_("Security"));
- ui_->keyServerListTable->horizontalHeaderItem(3)->setText(_("Available"));
+ tr("Keyserver Address"));
+ ui_->keyServerListTable->horizontalHeaderItem(2)->setText(tr("Security"));
+ ui_->keyServerListTable->horizontalHeaderItem(3)->setText(tr("Available"));
- ui_->addKeyServerPushButton->setText(_("Add"));
- ui_->testKeyServerButton->setText(_("Test Listed Keyserver"));
+ ui_->addKeyServerPushButton->setText(tr("Add"));
+ ui_->testKeyServerButton->setText(tr("Test Listed Keyserver"));
ui_->tipsLabel->setText(
- _("Tips: Please Double-click table item to edit it."));
- ui_->actionDelete_Selected_Key_Server->setText(_("Delete Selected"));
+ tr("Tips: Please Double-click table item to edit it."));
+ ui_->actionDelete_Selected_Key_Server->setText(tr("Delete Selected"));
ui_->actionDelete_Selected_Key_Server->setToolTip(
- _("Delete Selected Key Server"));
- ui_->actionSet_As_Default->setText(_("Set As Default"));
- ui_->actionSet_As_Default->setToolTip(_("Set As Default"));
+ tr("Delete Selected Key Server"));
+ ui_->actionSet_As_Default->setText(tr("Set As Default"));
+ ui_->actionSet_As_Default->setToolTip(tr("Set As Default"));
popup_menu_ = new QMenu(this);
popup_menu_->addAction(ui_->actionSet_As_Default);
@@ -74,7 +78,7 @@ KeyserverTab::KeyserverTab(QWidget* parent)
connect(ui_->keyServerListTable, &QTableWidget::itemChanged,
[=](QTableWidgetItem* item) {
- SPDLOG_DEBUG("item edited: {}", item->column());
+ GF_UI_LOG_DEBUG("item edited: {}", item->column());
if (item->column() != 1) return;
const auto row_size = ui_->keyServerListTable->rowCount();
// Update Actions
@@ -115,30 +119,18 @@ KeyserverTab::KeyserverTab(QWidget* parent)
}
void KeyserverTab::SetSettings() {
- try {
- SettingsObject key_server_json("key_server");
-
- const auto key_server_list =
- key_server_json.Check("server_list", nlohmann::json::array());
+ KeyServerSO key_server(SettingsObject("key_server"));
- for (const auto& key_server : key_server_list) {
- const auto key_server_str = key_server.get<std::string>();
- this->key_server_str_list_.append(key_server_str.c_str());
- }
+ if (key_server.server_list.empty()) key_server.ResetDefaultServerList();
+ for (const auto& key_server : key_server.server_list) {
+ this->key_server_str_list_.append(key_server);
+ }
- int default_key_server_index = key_server_json.Check("default_server", 0);
- if (default_key_server_index >= key_server_list.size()) {
- throw std::runtime_error("default_server index out of range");
- }
- std::string default_key_server =
- key_server_list[default_key_server_index].get<std::string>();
-
- if (!key_server_str_list_.contains(default_key_server.c_str()))
- key_server_str_list_.append(default_key_server.c_str());
- default_key_server_ = QString::fromStdString(default_key_server);
- } catch (const std::exception& e) {
- SPDLOG_ERROR("Error reading key-server settings: ", e.what());
+ const auto default_key_server = key_server.GetTargetServer();
+ if (!key_server_str_list_.contains(default_key_server)) {
+ key_server_str_list_.append(default_key_server);
}
+ default_key_server_ = default_key_server;
}
void KeyserverTab::slot_add_key_server() {
@@ -148,47 +140,47 @@ void KeyserverTab::slot_add_key_server() {
;
} else if (target_url.startsWith("http://")) {
QMessageBox::warning(
- this, _("Insecure keyserver address"),
- _("For security reasons, using HTTP as the communication protocol "
- "with "
- "the key server is not recommended. It is recommended to use "
- "HTTPS."));
+ this, tr("Insecure keyserver address"),
+ tr("For security reasons, using HTTP as the communication protocol "
+ "with "
+ "the key server is not recommended. It is recommended to use "
+ "HTTPS."));
}
key_server_str_list_.append(ui_->addKeyServerEdit->text());
} else {
auto ret = QMessageBox::warning(
- this, _("Warning"),
- _("You may not use HTTPS or HTTP as the protocol for communicating "
- "with the key server, which may not be wrong. But please check the "
- "address you entered again to make sure it is correct. Are you "
- "sure "
- "that want to add it into the keyserver list?"),
+ this, tr("Warning"),
+ tr("You may not use HTTPS or HTTP as the protocol for communicating "
+ "with the key server, which may not be wrong. But please check the "
+ "address you entered again to make sure it is correct. Are you "
+ "sure "
+ "that want to add it into the keyserver list?"),
QMessageBox::Ok | QMessageBox::Cancel);
- if (ret == QMessageBox::Cancel)
- return;
- else
- key_server_str_list_.append(ui_->addKeyServerEdit->text());
+ if (ret == QMessageBox::Cancel) return;
+ key_server_str_list_.append(ui_->addKeyServerEdit->text());
}
slot_refresh_table();
}
void KeyserverTab::ApplySettings() {
SettingsObject key_server_json("key_server");
- key_server_json["server_list"] = nlohmann::json::array();
- auto& key_server_list = key_server_json["server_list"];
+ KeyServerSO key_server;
+ auto& key_server_list = key_server.server_list;
const auto list_size = key_server_str_list_.size();
for (int i = 0; i < list_size; i++) {
const auto key_server = key_server_str_list_[i];
- if (default_key_server_ == key_server)
+ if (default_key_server_ == key_server) {
key_server_json["default_server"] = i;
- key_server_list.insert(key_server_list.end(), key_server.toStdString());
+ }
+ key_server_list << key_server;
}
+ key_server_json.Store(key_server.ToJson());
}
void KeyserverTab::slot_refresh_table() {
- SPDLOG_INFO("start refreshing key server table");
+ GF_UI_LOG_INFO("start refreshing key server table");
ui_->keyServerListTable->blockSignals(true);
ui_->keyServerListTable->setRowCount(key_server_str_list_.size());
@@ -205,13 +197,13 @@ void KeyserverTab::slot_refresh_table() {
tmp2->setTextAlignment(Qt::AlignCenter);
ui_->keyServerListTable->setItem(index, 1, tmp2);
- auto* tmp3 = new QTableWidgetItem(server.startsWith("https") ? _("true")
- : _("false"));
+ auto* tmp3 = new QTableWidgetItem(server.startsWith("https") ? tr("true")
+ : tr("false"));
tmp3->setTextAlignment(Qt::AlignCenter);
ui_->keyServerListTable->setItem(index, 2, tmp3);
tmp3->setFlags(tmp3->flags() ^ Qt::ItemIsEditable);
- auto* tmp4 = new QTableWidgetItem(_("unknown"));
+ auto* tmp4 = new QTableWidgetItem(tr("unknown"));
tmp4->setTextAlignment(Qt::AlignCenter);
ui_->keyServerListTable->setItem(index, 3, tmp4);
tmp4->setFlags(tmp3->flags() ^ Qt::ItemIsEditable);
@@ -225,7 +217,7 @@ void KeyserverTab::slot_refresh_table() {
}
void KeyserverTab::slot_test_listed_key_server() {
- auto timeout = QInputDialog::getInt(this, _("Set TCP Timeout"),
+ auto timeout = QInputDialog::getInt(this, tr("Set TCP Timeout"),
tr("timeout(ms): "), 2500, 200, 16000);
QStringList urls;
@@ -243,17 +235,17 @@ void KeyserverTab::slot_test_listed_key_server() {
this,
[=](std::vector<ListedKeyServerTestTask::KeyServerTestResultType>
result) {
- const auto row_size = ui_->keyServerListTable->rowCount();
+ const size_t row_size = ui_->keyServerListTable->rowCount();
if (result.size() != row_size) return;
ui_->keyServerListTable->blockSignals(true);
- for (int i = 0; i < row_size; i++) {
+ for (size_t i = 0; i < row_size; i++) {
const auto status = result[i];
- auto status_iem = ui_->keyServerListTable->item(i, 3);
- if (status == ListedKeyServerTestTask::kTestResultType_Success) {
- status_iem->setText(_("Reachable"));
+ auto* status_iem = ui_->keyServerListTable->item(i, 3);
+ if (status == ListedKeyServerTestTask::kTEST_RESULT_TYPE_SUCCESS) {
+ status_iem->setText(tr("Reachable"));
status_iem->setForeground(QBrush(QColor::fromRgb(0, 255, 0)));
} else {
- status_iem->setText(_("Not Reachable"));
+ status_iem->setText(tr("Not Reachable"));
status_iem->setForeground(QBrush(QColor::fromRgb(255, 0, 0)));
}
}
@@ -264,11 +256,11 @@ void KeyserverTab::slot_test_listed_key_server() {
auto* waiting_dialog = new QProgressDialog(this);
waiting_dialog->setMaximum(0);
waiting_dialog->setMinimum(0);
- auto waiting_dialog_label =
- new QLabel(QString(_("Test Key Server Connection...")) + "<br /><br />" +
- _("This test only tests the network connectivity of the key "
- "server. Passing the test does not mean that the key server "
- "is functionally available."));
+ auto* waiting_dialog_label = new QLabel(
+ tr("Test Key Server Connection...") + "<br /><br />" +
+ tr("This test only tests the network connectivity of the key "
+ "server. Passing the test does not mean that the key server "
+ "is functionally available."));
waiting_dialog_label->setWordWrap(true);
waiting_dialog->setLabel(waiting_dialog_label);
waiting_dialog->resize(420, 120);
diff --git a/src/ui/dialog/settings/SettingsKeyServer.h b/src/ui/dialog/settings/SettingsKeyServer.h
index f983e69b..ae5a3181 100644
--- a/src/ui/dialog/settings/SettingsKeyServer.h
+++ b/src/ui/dialog/settings/SettingsKeyServer.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,14 +20,13 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_SETTINGSKEYSERVER_H
-#define GPGFRONTEND_SETTINGSKEYSERVER_H
+#pragma once
#include "ui/GpgFrontendUI.h"
@@ -107,5 +106,3 @@ class KeyserverTab : public QWidget {
void contextMenuEvent(QContextMenuEvent* event) override;
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_SETTINGSKEYSERVER_H
diff --git a/src/ui/dialog/settings/SettingsNetwork.cpp b/src/ui/dialog/settings/SettingsNetwork.cpp
index 0713856d..c7e1e9f6 100644
--- a/src/ui/dialog/settings/SettingsNetwork.cpp
+++ b/src/ui/dialog/settings/SettingsNetwork.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -33,7 +33,8 @@
#include "ui_NetworkSettings.h"
GpgFrontend::UI::NetworkTab::NetworkTab(QWidget *parent)
- : QWidget(parent), ui_(std::make_shared<Ui_NetworkSettings>()) {
+ : QWidget(parent),
+ ui_(GpgFrontend::SecureCreateSharedObject<Ui_NetworkSettings>()) {
ui_->setupUi(this);
connect(ui_->enableProxyCheckBox, &QCheckBox::stateChanged, this,
@@ -67,207 +68,97 @@ GpgFrontend::UI::NetworkTab::NetworkTab(QWidget *parent)
connect(ui_->checkProxyConnectionButton, &QPushButton::clicked, this,
&NetworkTab::slot_test_proxy_connection_result);
- ui_->proxyGroupBox->setTitle(_("Proxy"));
- ui_->capabilityGroupBox->setTitle(_("Network Ability"));
- ui_->operationsGroupBox->setTitle(_("Operations"));
+ ui_->proxyGroupBox->setTitle(tr("Proxy"));
+ ui_->capabilityGroupBox->setTitle(tr("Network Ability"));
+ ui_->operationsGroupBox->setTitle(tr("Operations"));
- ui_->enableProxyCheckBox->setText(_("Enable Proxy"));
- ui_->proxyServerPortLabel->setText(_("Port"));
+ ui_->enableProxyCheckBox->setText(tr("Enable Proxy"));
+ ui_->proxyServerPortLabel->setText(tr("Port"));
- ui_->proxyServerAddressLabel->setText(_("Host Address"));
- ui_->proxyServerPortLabel->setText(_("Port"));
- ui_->proxyTypeLabel->setText(_("Proxy Type"));
- ui_->usernameLabel->setText(_("Username"));
- ui_->passwordLabel->setText(_("Password"));
+ ui_->proxyServerAddressLabel->setText(tr("Host Address"));
+ ui_->proxyServerPortLabel->setText(tr("Port"));
+ ui_->proxyTypeLabel->setText(tr("Proxy Type"));
+ ui_->usernameLabel->setText(tr("Username"));
+ ui_->passwordLabel->setText(tr("Password"));
ui_->checkProxyConnectionButton->setText(
- _("Apply Proxy Settings and Check Proxy Connection"));
+ tr("Apply Proxy Settings and Check Proxy Connection"));
ui_->forbidALLGnuPGNetworkConnectionCheckBox->setText(
- _("Forbid all GnuPG network connection."));
+ tr("Forbid all GnuPG network connection."));
ui_->prohibitUpdateCheck->setText(
- _("Prohibit checking for version updates when the program starts."));
+ tr("Prohibit checking for version updates when the program starts."));
ui_->autoImportMissingKeyCheckBox->setText(
- _("Automatically import a missing key for signature verification."));
+ tr("Automatically import a missing key for signature verification."));
ui_->networkAbilityTipsLabel->setText(
- _("Tips: These Option Changes take effect only after the "
- "application restart."));
+ tr("Tips: These Option Changes take effect only after the "
+ "application restart."));
SetSettings();
}
void GpgFrontend::UI::NetworkTab::SetSettings() {
- auto &settings = GlobalSettingStation::GetInstance().GetUISettings();
+ auto settings = GlobalSettingStation::GetInstance().GetSettings();
- try {
- std::string proxy_host = settings.lookup("proxy.proxy_host");
- ui_->proxyServerAddressEdit->setText(proxy_host.c_str());
- } catch (...) {
- SPDLOG_ERROR("setting operation error: proxy_host");
- }
+ QString proxy_host = settings.value("proxy/proxy_host").toString();
+ ui_->proxyServerAddressEdit->setText(proxy_host);
+ QString username = settings.value("proxy/username").toString();
+ ui_->usernameEdit->setText(username);
+ QString password = settings.value("proxy/password").toString();
+ ui_->passwordEdit->setText(password);
- try {
- std::string std_username = settings.lookup("proxy.username");
- ui_->usernameEdit->setText(std_username.c_str());
- } catch (...) {
- SPDLOG_ERROR("setting operation error: username");
- }
+ int port = settings.value("proxy/port", 0).toInt();
+ ui_->portSpin->setValue(port);
- try {
- std::string std_password = settings.lookup("proxy.password");
- ui_->passwordEdit->setText(std_password.c_str());
- } catch (...) {
- SPDLOG_ERROR("setting operation error: password");
- }
+ ui_->proxyTypeComboBox->setCurrentText("HTTP");
- try {
- int port = settings.lookup("proxy.port");
- ui_->portSpin->setValue(port);
- } catch (...) {
- SPDLOG_ERROR("setting operation error: port");
- }
+ QString proxy_type = settings.value("proxy/proxy_type").toString();
+ ui_->proxyTypeComboBox->setCurrentText(proxy_type);
- ui_->proxyTypeComboBox->setCurrentText("HTTP");
- try {
- std::string proxy_type = settings.lookup("proxy.proxy_type");
- ui_->proxyTypeComboBox->setCurrentText(proxy_type.c_str());
- } catch (...) {
- SPDLOG_ERROR("setting operation error: proxy_type");
- }
switch_ui_proxy_type(ui_->proxyTypeComboBox->currentText());
ui_->enableProxyCheckBox->setCheckState(Qt::Unchecked);
- try {
- bool proxy_enable = settings.lookup("proxy.enable");
- if (proxy_enable)
- ui_->enableProxyCheckBox->setCheckState(Qt::Checked);
- else
- ui_->enableProxyCheckBox->setCheckState(Qt::Unchecked);
- } catch (...) {
- SPDLOG_ERROR("setting operation error: proxy_enable");
- }
- ui_->forbidALLGnuPGNetworkConnectionCheckBox->setCheckState(Qt::Unchecked);
- try {
- bool forbid_all_gnupg_connection =
- settings.lookup("network.forbid_all_gnupg_connection");
- if (forbid_all_gnupg_connection)
- ui_->forbidALLGnuPGNetworkConnectionCheckBox->setCheckState(Qt::Checked);
- else
- ui_->forbidALLGnuPGNetworkConnectionCheckBox->setCheckState(
- Qt::Unchecked);
- } catch (...) {
- SPDLOG_ERROR("setting operation error: forbid_all_gnupg_connection");
- }
+ bool proxy_enable = settings.value("proxy/enable", false).toBool();
+ ui_->enableProxyCheckBox->setCheckState(proxy_enable ? Qt::Checked
+ : Qt::Unchecked);
- ui_->prohibitUpdateCheck->setCheckState(Qt::Unchecked);
- try {
- bool prohibit_update_checking =
- settings.lookup("network.prohibit_update_checking");
- if (prohibit_update_checking)
- ui_->prohibitUpdateCheck->setCheckState(Qt::Checked);
- else
- ui_->prohibitUpdateCheck->setCheckState(Qt::Unchecked);
- } catch (...) {
- SPDLOG_ERROR("setting operation error: prohibit_update_checking");
- }
+ bool forbid_all_gnupg_connection =
+ settings.value("network/forbid_all_gnupg_connection").toBool();
+ ui_->forbidALLGnuPGNetworkConnectionCheckBox->setCheckState(
+ forbid_all_gnupg_connection ? Qt::Checked : Qt::Unchecked);
- ui_->autoImportMissingKeyCheckBox->setCheckState(Qt::Unchecked);
- try {
- bool auto_import_missing_key =
- settings.lookup("network.auto_import_missing_key");
- if (auto_import_missing_key)
- ui_->autoImportMissingKeyCheckBox->setCheckState(Qt::Checked);
- else
- ui_->autoImportMissingKeyCheckBox->setCheckState(Qt::Unchecked);
- } catch (...) {
- SPDLOG_ERROR("setting operation error: auto_import_missing_key");
- }
+ bool prohibit_update_checking =
+ settings.value("network/prohibit_update_checking").toBool();
+ ui_->prohibitUpdateCheck->setCheckState(
+ prohibit_update_checking ? Qt::Checked : Qt::Unchecked);
+
+ bool auto_import_missing_key =
+ settings.value("network/auto_import_missing_key", true).toBool();
+ ui_->autoImportMissingKeyCheckBox->setCheckState(
+ auto_import_missing_key ? Qt::Checked : Qt::Unchecked);
switch_ui_enabled(ui_->enableProxyCheckBox->isChecked());
switch_ui_proxy_type(ui_->proxyTypeComboBox->currentText());
}
void GpgFrontend::UI::NetworkTab::ApplySettings() {
- auto &settings =
- GpgFrontend::GlobalSettingStation::GetInstance().GetUISettings();
-
- if (!settings.exists("proxy") ||
- settings.lookup("proxy").getType() != libconfig::Setting::TypeGroup)
- settings.add("proxy", libconfig::Setting::TypeGroup);
-
- auto &proxy = settings["proxy"];
-
- if (!proxy.exists("proxy_host"))
- proxy.add("proxy_host", libconfig::Setting::TypeString) =
- ui_->proxyServerAddressEdit->text().toStdString();
- else {
- proxy["proxy_host"] = ui_->proxyServerAddressEdit->text().toStdString();
- }
-
- if (!proxy.exists("username"))
- proxy.add("username", libconfig::Setting::TypeString) =
- ui_->usernameEdit->text().toStdString();
- else {
- proxy["username"] = ui_->usernameEdit->text().toStdString();
- }
-
- if (!proxy.exists("password"))
- proxy.add("password", libconfig::Setting::TypeString) =
- ui_->passwordEdit->text().toStdString();
- else {
- proxy["password"] = ui_->passwordEdit->text().toStdString();
- }
-
- if (!proxy.exists("port"))
- proxy.add("port", libconfig::Setting::TypeInt) = ui_->portSpin->value();
- else {
- proxy["port"] = ui_->portSpin->value();
- }
-
- if (!proxy.exists("proxy_type"))
- proxy.add("proxy_type", libconfig::Setting::TypeString) =
- ui_->proxyTypeComboBox->currentText().toStdString();
- else {
- proxy["proxy_type"] = ui_->proxyTypeComboBox->currentText().toStdString();
- }
-
- if (!proxy.exists("enable"))
- proxy.add("enable", libconfig::Setting::TypeBoolean) =
- ui_->enableProxyCheckBox->isChecked();
- else {
- proxy["enable"] = ui_->enableProxyCheckBox->isChecked();
- }
-
- if (!settings.exists("network") ||
- settings.lookup("network").getType() != libconfig::Setting::TypeGroup)
- settings.add("network", libconfig::Setting::TypeGroup);
-
- auto &network = settings["network"];
-
- if (!network.exists("forbid_all_gnupg_connection"))
- network.add("forbid_all_gnupg_connection",
- libconfig::Setting::TypeBoolean) =
- ui_->forbidALLGnuPGNetworkConnectionCheckBox->isChecked();
- else {
- network["forbid_all_gnupg_connection"] =
- ui_->forbidALLGnuPGNetworkConnectionCheckBox->isChecked();
- }
-
- if (!network.exists("prohibit_update_checking"))
- network.add("prohibit_update_checking", libconfig::Setting::TypeBoolean) =
- ui_->prohibitUpdateCheck->isChecked();
- else {
- network["prohibit_update_checking"] = ui_->prohibitUpdateCheck->isChecked();
- }
-
- if (!network.exists("auto_import_missing_key"))
- network.add("auto_import_missing_key", libconfig::Setting::TypeBoolean) =
- ui_->autoImportMissingKeyCheckBox->isChecked();
- else {
- network["auto_import_missing_key"] =
- ui_->autoImportMissingKeyCheckBox->isChecked();
- }
+ auto settings =
+ GpgFrontend::GlobalSettingStation::GetInstance().GetSettings();
+
+ settings.setValue("proxy/proxy_host", ui_->proxyServerAddressEdit->text());
+ settings.setValue("proxy/username", ui_->usernameEdit->text());
+ settings.setValue("proxy/password", ui_->passwordEdit->text());
+ settings.setValue("proxy/port", ui_->portSpin->value());
+ settings.setValue("proxy/proxy_type", ui_->proxyTypeComboBox->currentText());
+ settings.setValue("proxy/enable", ui_->enableProxyCheckBox->isChecked());
+
+ settings.setValue("network/forbid_all_gnupg_connection",
+ ui_->forbidALLGnuPGNetworkConnectionCheckBox->isChecked());
+ settings.setValue("network/prohibit_update_checking",
+ ui_->prohibitUpdateCheck->isChecked());
+ settings.setValue("network/auto_import_missing_key",
+ ui_->autoImportMissingKeyCheckBox->isChecked());
apply_proxy_settings();
}
@@ -276,7 +167,7 @@ void GpgFrontend::UI::NetworkTab::slot_test_proxy_connection_result() {
apply_proxy_settings();
bool ok;
- auto url = QInputDialog::getText(this, _("Test Server Url Accessibility"),
+ auto url = QInputDialog::getText(this, tr("Test Server Url Accessibility"),
tr("Server Url"), QLineEdit::Normal,
"https://", &ok);
if (ok && !url.isEmpty()) {
@@ -286,14 +177,15 @@ void GpgFrontend::UI::NetworkTab::slot_test_proxy_connection_result() {
SignalProxyConnectionTestResult,
this, [=](const QString &result) {
if (result == "Reachable") {
- QMessageBox::information(this, _("Success"),
- _("Successfully connect to the target "
- "server through the proxy server."));
+ QMessageBox::information(
+ this, tr("Success"),
+ tr("Successfully connect to the target "
+ "server through the proxy server."));
} else {
QMessageBox::critical(
- this, _("Failed"),
- _("Unable to connect to the target server through the "
- "proxy server. Proxy settings may be invalid."));
+ this, tr("Failed"),
+ tr("Unable to connect to the target server through the "
+ "proxy server. Proxy settings may be invalid."));
}
});
@@ -302,9 +194,10 @@ void GpgFrontend::UI::NetworkTab::slot_test_proxy_connection_result() {
waiting_dialog->setMaximum(0);
waiting_dialog->setMinimum(0);
auto waiting_dialog_label = new QLabel(
- QString(_("Test Proxy Server Connection...")) + "<br /><br />" +
- _("Is using your proxy settings to access the url. Note that this test "
- "operation will apply your proxy settings to the entire software."));
+ tr("Test Proxy Server Connection...") + "<br /><br />" +
+ tr("Is using your proxy settings to access the url. Note that this "
+ "test "
+ "operation will apply your proxy settings to the entire software."));
waiting_dialog_label->setWordWrap(true);
waiting_dialog->setLabel(waiting_dialog_label);
waiting_dialog->resize(420, 120);
diff --git a/src/ui/dialog/settings/SettingsNetwork.h b/src/ui/dialog/settings/SettingsNetwork.h
index d4c0d00d..4335dff7 100644
--- a/src/ui/dialog/settings/SettingsNetwork.h
+++ b/src/ui/dialog/settings/SettingsNetwork.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,14 +20,15 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_SETTINGSNETWORK_H
-#define GPGFRONTEND_SETTINGSNETWORK_H
+#pragma once
+
+#include <QtNetwork>
#include "ui/GpgFrontendUI.h"
@@ -90,5 +91,3 @@ class NetworkTab : public QWidget {
void switch_ui_proxy_type(const QString& type_text);
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_SETTINGSNETWORK_H
diff --git a/src/ui/function/GenerateRevokeCertification.cpp b/src/ui/function/GenerateRevokeCertification.cpp
new file mode 100644
index 00000000..b1089d45
--- /dev/null
+++ b/src/ui/function/GenerateRevokeCertification.cpp
@@ -0,0 +1,89 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "GenerateRevokeCertification.h"
+
+#include "core/function/gpg/GpgCommandExecutor.h"
+#include "core/model/GpgKey.h"
+#include "core/module/ModuleManager.h"
+
+namespace GpgFrontend::UI {
+
+GenerateRevokeCertification::GenerateRevokeCertification(QWidget* parent)
+ : QWidget(parent) {}
+
+auto GenerateRevokeCertification::Exec(const GpgKey& key,
+ const QString& output_path) -> int {
+ const auto app_path = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.app_path", QString{});
+ // get all components
+ GpgCommandExecutor::ExecuteSync(
+ {app_path,
+ {"--command-fd", "0", "--status-fd", "1", "--no-tty", "-o",
+ std::move(output_path), "--gen-revoke", key.GetFingerprint()},
+ [=](int exit_code, const QString& p_out, const QString& p_err) {
+ if (exit_code != 0) {
+ GF_UI_LOG_ERROR(
+ "gnupg gen revoke execute error, process stderr: {}, process "
+ "stdout: {}",
+ p_err, p_out);
+ } else {
+ GF_UI_LOG_DEBUG(
+ "gnupg gen revoke exit_code: {}, process stdout size: {}",
+ exit_code, p_out.size());
+ }
+ },
+ nullptr,
+ [](QProcess* proc) -> void {
+ // Code From Gpg4Win
+ while (proc->canReadLine()) {
+ const QString line = QString::fromUtf8(proc->readLine()).trimmed();
+ GF_UI_LOG_DEBUG("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");
+ }
+ }
+ }});
+ return 0;
+}
+
+} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/SignalStation.cpp b/src/ui/function/GenerateRevokeCertification.h
index c1f1238f..edc0161b 100644
--- a/src/ui/SignalStation.cpp
+++ b/src/ui/function/GenerateRevokeCertification.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,25 +20,25 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#include "SignalStation.h"
+#pragma once
-#include "UserInterfaceUtils.h"
+#include "core/GpgModel.h"
+#include "ui/GpgFrontendUI.h"
namespace GpgFrontend::UI {
-std::unique_ptr<SignalStation> SignalStation::_instance = nullptr;
+class GenerateRevokeCertification : public QWidget {
+ Q_OBJECT
+ public:
+ explicit GenerateRevokeCertification(QWidget* parent);
-SignalStation* SignalStation::GetInstance() {
- if (_instance == nullptr) {
- _instance = std::make_unique<SignalStation>();
- }
- return _instance.get();
-}
+ auto Exec(const GpgKey& key, const QString& output_path) -> int;
+};
} // namespace GpgFrontend::UI
diff --git a/src/ui/function/RaisePinentry.cpp b/src/ui/function/RaisePinentry.cpp
new file mode 100644
index 00000000..64e10c48
--- /dev/null
+++ b/src/ui/function/RaisePinentry.cpp
@@ -0,0 +1,122 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "RaisePinentry.h"
+
+#include "core/function/CoreSignalStation.h"
+#include "core/model/GpgPassphraseContext.h"
+#include "core/utils/CacheUtils.h"
+#include "pinentry/pinentrydialog.h"
+
+namespace GpgFrontend::UI {
+
+auto FindTopMostWindow(QWidget* fallback) -> QWidget* {
+ QList<QWidget*> top_widgets = QApplication::topLevelWidgets();
+ foreach (QWidget* widget, top_widgets) {
+ if (widget->isActiveWindow()) {
+ GF_UI_LOG_TRACE("find a topmost widget, address: {}",
+ static_cast<void*>(widget));
+ return widget;
+ }
+ }
+ return fallback;
+}
+
+RaisePinentry::RaisePinentry(QWidget* parent,
+ QSharedPointer<GpgPassphraseContext> context)
+ : QWidget(parent), context_(std::move(context)) {}
+
+auto RaisePinentry::Exec() -> int {
+ GF_UI_LOG_DEBUG(
+ "setting pinetry's arguments, context uids: {}, passphrase info: {}, "
+ "prev_was_bad: {}",
+ context_->GetUidsInfo().toStdString(),
+ context_->GetPassphraseInfo().toStdString(), context_->IsPreWasBad());
+
+ bool ask_for_new = context_->IsAskForNew() &&
+ context_->GetPassphraseInfo().isEmpty() &&
+ context_->GetUidsInfo().isEmpty();
+
+ auto* pinentry =
+ new PinEntryDialog(FindTopMostWindow(this), 0, 15, true, ask_for_new,
+ ask_for_new ? tr("Repeat PIN:") : QString(),
+ tr("Show passphrase"), tr("Hide passphrase"));
+
+ if (context_->IsPreWasBad()) {
+ pinentry->setError(tr("Given PIN was wrong. Please retry."));
+ }
+
+ pinentry->setPrompt(tr("PIN:"));
+
+ if (!context_->GetUidsInfo().isEmpty()) {
+ pinentry->setDescription(QString("Please provide PIN of Key:\n%1\n")
+ .arg(context_->GetUidsInfo()));
+ }
+
+ struct pinentry pinentry_info;
+ pinentry->setPinentryInfo(pinentry_info);
+
+ pinentry->setRepeatErrorText(tr("Passphrases do not match"));
+ pinentry->setGenpinLabel(QString(""));
+ pinentry->setGenpinTT(QString(""));
+ pinentry->setCapsLockHint(tr("Caps Lock is on"));
+ pinentry->setFormattedPassphrase({false, QString()});
+ pinentry->setConstraintsOptions({false, QString(), QString(), QString()});
+
+ pinentry->setWindowTitle(tr("Buddled Pinentry"));
+
+ /* If we reuse the same dialog window. */
+ pinentry->setPin(QString());
+ pinentry->setOkText(tr("Confirm"));
+ pinentry->setCancelText(tr("Cancel"));
+
+ GF_UI_LOG_DEBUG("buddled pinentry is ready to start...");
+ connect(pinentry, &PinEntryDialog::finished, this,
+ [pinentry, this](int result) {
+ bool ret = result != 0;
+ GF_UI_LOG_DEBUG("buddled pinentry finished, ret: {}", ret);
+
+ if (!ret) {
+ emit CoreSignalStation::GetInstance()
+ ->SignalUserInputPassphraseCallback({});
+ return -1;
+ }
+
+ auto pin = pinentry->pin().toUtf8();
+
+ context_->SetPassphrase(pin);
+ emit CoreSignalStation::GetInstance()
+ ->SignalUserInputPassphraseCallback(context_);
+ return 0;
+ });
+ connect(pinentry, &PinEntryDialog::finished, this, &QWidget::deleteLater);
+
+ pinentry->open();
+ return 0;
+}
+} // namespace GpgFrontend::UI
diff --git a/src/ui/dialog/settings/SettingsAdvanced.h b/src/ui/function/RaisePinentry.h
index c1a3d5a6..40175dfd 100644
--- a/src/ui/dialog/settings/SettingsAdvanced.h
+++ b/src/ui/function/RaisePinentry.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,36 +20,41 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_SETTINGSADVANCED_H
-#define GPGFRONTEND_SETTINGSADVANCED_H
+#pragma once
#include "ui/GpgFrontendUI.h"
+namespace GpgFrontend {
+class GpgPassphraseContext;
+}
+
namespace GpgFrontend::UI {
-class AdvancedTab : public QWidget {
- Q_OBJECT
+class RaisePinentry : public QWidget {
+ Q_OBJECT
public:
- explicit AdvancedTab(QWidget* parent = nullptr);
-
- void SetSettings();
-
- void ApplySettings();
+ /**
+ * @brief Construct a new Raise Pinentry object
+ *
+ * @param parent
+ */
+ explicit RaisePinentry(QWidget *parent, QSharedPointer<GpgPassphraseContext>);
+
+ /**
+ * @brief
+ *
+ * @return int
+ */
+ auto Exec() -> int;
private:
- QCheckBox* stegano_check_box_;
- QCheckBox* auto_pubkey_exchange_check_box_;
-
- signals:
-
- void SignalRestartNeeded(bool needed);
+ QSharedPointer<GpgPassphraseContext> context_;
};
-} // namespace GpgFrontend::UI
-#endif // GPGFRONTEND_SETTINGSADVANCED_H
+} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/function/SetOwnerTrustLevel.cpp b/src/ui/function/SetOwnerTrustLevel.cpp
new file mode 100644
index 00000000..360abfce
--- /dev/null
+++ b/src/ui/function/SetOwnerTrustLevel.cpp
@@ -0,0 +1,96 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "SetOwnerTrustLevel.h"
+
+#include "core/GpgModel.h"
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/function/gpg/GpgKeyManager.h"
+#include "ui/UISignalStation.h"
+
+namespace GpgFrontend::UI {
+
+SetOwnerTrustLevel::SetOwnerTrustLevel(QWidget* parent) : QWidget(parent) {}
+
+auto SetOwnerTrustLevel::Exec(const QString& key_id) -> bool {
+ if (key_id.isEmpty()) {
+ return false;
+ }
+
+ auto key = GpgKeyGetter::GetInstance().GetKey(key_id);
+
+ QStringList items;
+
+ items << tr("Unknown") << tr("Undefined") << tr("Never") << tr("Marginal")
+ << tr("Full") << tr("Ultimate");
+ bool ok;
+ QString item = QInputDialog::getItem(this, tr("Modify Owner Trust Level"),
+ tr("Trust for the Key Pair:"), items,
+ key.GetOwnerTrustLevel(), false, &ok);
+
+ if (ok && !item.isEmpty()) {
+ GF_UI_LOG_DEBUG("selected owner trust policy: {}", item.toStdString());
+ int trust_level = 0; // Unknown Level
+ if (item == tr("Ultimate")) {
+ trust_level = 5;
+ } else if (item == tr("Full")) {
+ trust_level = 4;
+ } else if (item == tr("Marginal")) {
+ trust_level = 3;
+ } else if (item == tr("Never")) {
+ trust_level = 2;
+ } else if (item == tr("Undefined")) {
+ trust_level = 1;
+ }
+
+ if (trust_level == 0) {
+ QMessageBox::warning(
+ this, tr("Warning"),
+ QString(
+ tr("Owner Trust Level cannot set to Unknown level, automately "
+ "changing it into Undefined level.")));
+ trust_level = 1;
+ }
+
+ bool status =
+ GpgKeyManager::GetInstance().SetOwnerTrustLevel(key, trust_level);
+ if (!status) {
+ QMessageBox::critical(this, tr("Failed"),
+ tr("Modify Owner Trust Level failed."));
+ return false;
+ }
+
+ // update key database and refresh ui
+ emit UISignalStation::GetInstance()->SignalKeyDatabaseRefresh();
+ return true;
+ }
+
+ return false;
+}
+
+} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/function/SetOwnerTrustLevel.h b/src/ui/function/SetOwnerTrustLevel.h
new file mode 100644
index 00000000..e33f787b
--- /dev/null
+++ b/src/ui/function/SetOwnerTrustLevel.h
@@ -0,0 +1,55 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+#include "GpgFrontendUI.h"
+
+namespace GpgFrontend::UI {
+
+class SetOwnerTrustLevel : public QWidget {
+ Q_OBJECT
+ public:
+ /**
+ * @brief Set the Owner Trust Level object
+ *
+ * @param parent
+ */
+ explicit SetOwnerTrustLevel(QWidget* parent);
+
+ /**
+ * @brief
+ *
+ * @param key_id
+ * @return true
+ * @return false
+ */
+ auto Exec(const QString& key_id) -> bool;
+};
+
+} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/main_window/GeneralMainWindow.cpp b/src/ui/main_window/GeneralMainWindow.cpp
index 0acedec6..2eb9f2a4 100644
--- a/src/ui/main_window/GeneralMainWindow.cpp
+++ b/src/ui/main_window/GeneralMainWindow.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,20 +28,25 @@
#include "GeneralMainWindow.h"
-#include <utility>
-
#include "ui/struct/SettingsObject.h"
+#include "ui/struct/settings/AppearanceSO.h"
+#include "ui/struct/settings/WindowStateSO.h"
+
+namespace GpgFrontend::UI {
-GpgFrontend::UI::GeneralMainWindow::GeneralMainWindow(std::string name,
+class GeneralWindowState {};
+
+GpgFrontend::UI::GeneralMainWindow::GeneralMainWindow(QString name,
QWidget *parent)
- : name_(std::move(name)), QMainWindow(parent) {
+ : QMainWindow(parent), name_(std::move(name)) {
slot_restore_settings();
}
GpgFrontend::UI::GeneralMainWindow::~GeneralMainWindow() = default;
void GpgFrontend::UI::GeneralMainWindow::closeEvent(QCloseEvent *event) {
- SPDLOG_DEBUG("main window close event caught, event type: {}", event->type());
+ GF_UI_LOG_DEBUG("main window close event caught, event type: {}",
+ event->type());
slot_save_settings();
QMainWindow::closeEvent(event);
@@ -49,34 +54,23 @@ void GpgFrontend::UI::GeneralMainWindow::closeEvent(QCloseEvent *event) {
void GpgFrontend::UI::GeneralMainWindow::slot_restore_settings() noexcept {
try {
- SettingsObject general_windows_state(name_ + "_state");
+ WindowStateSO window_state(SettingsObject(name_ + "_state"));
- std::string window_state = general_windows_state.Check(
- "window_state", saveState().toBase64().toStdString());
- SPDLOG_DEBUG("restore main window state: {}", window_state);
+ GF_UI_LOG_DEBUG("restore main window state: {}",
+ window_state.window_state_data);
// state sets pos & size of dock-widgets
this->restoreState(
- QByteArray::fromBase64(QByteArray::fromStdString(window_state)));
-
- bool window_save = general_windows_state.Check("window_save", true);
-
- // Restore window size & location
- if (window_save) {
- int x = general_windows_state.Check("window_pos").Check("x", 100),
- y = general_windows_state.Check("window_pos").Check("y", 100);
-
- pos_ = {x, y};
-
- int width =
- general_windows_state.Check("window_size").Check("width", 800),
- height =
- general_windows_state.Check("window_size").Check("height", 450);
+ QByteArray::fromBase64(window_state.window_state_data.toUtf8()));
- size_ = {width, height};
+ // restore window size & location
+ if (window_state.window_save) {
+ pos_ = {window_state.x, window_state.y};
+ size_ = {window_state.width, window_state.height};
if (this->parent() != nullptr) {
- SPDLOG_DEBUG("parent address: {}", static_cast<void *>(this->parent()));
+ GF_UI_LOG_DEBUG("parent address: {}",
+ static_cast<void *>(this->parent()));
QPoint parent_pos = {0, 0};
QSize parent_size = {0, 0};
@@ -93,10 +87,11 @@ void GpgFrontend::UI::GeneralMainWindow::slot_restore_settings() noexcept {
parent_size = parent_window->size();
}
- SPDLOG_DEBUG("parent pos x: {} y: {}", parent_pos.x(), parent_pos.y());
+ GF_UI_LOG_DEBUG("parent pos x: {} y: {}", parent_pos.x(),
+ parent_pos.y());
- SPDLOG_DEBUG("parent size width: {} height: {}", parent_size.width(),
- parent_size.height());
+ GF_UI_LOG_DEBUG("parent size width: {} height: {}", parent_size.width(),
+ parent_size.height());
if (parent_pos != QPoint{0, 0}) {
QPoint parent_center{parent_pos.x() + parent_size.width() / 2,
@@ -112,59 +107,42 @@ void GpgFrontend::UI::GeneralMainWindow::slot_restore_settings() noexcept {
}
// appearance
- SettingsObject general_settings_state("general_settings_state");
+ AppearanceSO appearance(SettingsObject("general_settings_state"));
- int width = general_settings_state.Check("icon_size").Check("width", 24),
- height = general_settings_state.Check("icon_size").Check("height", 24);
- SPDLOG_DEBUG("icon size: {} {}", width, height);
-
- icon_size_ = {width, height};
- font_size_ = general_settings_state.Check("font_size", 10);
+ icon_size_ = {appearance.tool_bar_icon_width,
+ appearance.tool_bar_icon_height};
+ font_size_ = appearance.info_board_font_size;
this->setIconSize(icon_size_);
-
- // icon_style
- int s_icon_style =
- general_settings_state.Check("icon_style", Qt::ToolButtonTextUnderIcon);
- this->setToolButtonStyle(static_cast<Qt::ToolButtonStyle>(s_icon_style));
+ this->setToolButtonStyle(appearance.tool_bar_button_style);
icon_style_ = toolButtonStyle();
} catch (...) {
- SPDLOG_ERROR(name_, "error");
+ GF_UI_LOG_ERROR("gernal main window: {}, caught exception", name_);
}
}
void GpgFrontend::UI::GeneralMainWindow::slot_save_settings() noexcept {
try {
- SPDLOG_DEBUG("save main window state, name: {}", name_);
+ GF_UI_LOG_DEBUG("save main window state, name: {}", name_);
SettingsObject general_windows_state(name_ + "_state");
- // window position and size
- general_windows_state["window_state"] =
- saveState().toBase64().toStdString();
- general_windows_state["window_pos"]["x"] = pos().x();
- general_windows_state["window_pos"]["y"] = pos().y();
-
- // update size of current dialog
+ // update geo of current dialog
size_ = this->size();
+ pos_ = this->pos();
- general_windows_state["window_size"]["width"] = size_.width();
- general_windows_state["window_size"]["height"] = size_.height();
- general_windows_state["window_save"] = true;
-
- SettingsObject general_settings_state("general_settings_state");
-
- // icon size
- general_settings_state["icon_size"]["width"] = icon_size_.width();
- general_settings_state["icon_size"]["height"] = icon_size_.height();
-
- // font size
- general_settings_state["font_size"] = font_size_;
-
- // tool button style
- general_settings_state["icon_style"] = this->toolButtonStyle();
+ WindowStateSO window_state;
+ window_state.x = pos_.x();
+ window_state.y = pos_.y();
+ window_state.width = size_.width();
+ window_state.height = size_.height();
+ window_state.window_save = true;
+ window_state.window_state_data = this->saveState().toBase64();
+ general_windows_state.Store(window_state.Json());
} catch (...) {
- SPDLOG_ERROR(name_, "error");
+ GF_UI_LOG_ERROR("gernal main window: {}, caught exception", name_);
}
}
+
+} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/main_window/GeneralMainWindow.h b/src/ui/main_window/GeneralMainWindow.h
index 8995883a..e1ff31bb 100644
--- a/src/ui/main_window/GeneralMainWindow.h
+++ b/src/ui/main_window/GeneralMainWindow.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,14 +20,13 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_GENERALMAINWINDOW_H
-#define GPGFRONTEND_GENERALMAINWINDOW_H
+#pragma once
#include "ui/GpgFrontendUI.h"
@@ -42,7 +41,7 @@ class GeneralMainWindow : public QMainWindow {
*
* @param name
*/
- explicit GeneralMainWindow(std::string name, QWidget* parent = nullptr);
+ explicit GeneralMainWindow(QString name, QWidget* parent = nullptr);
/**
*
@@ -72,10 +71,8 @@ class GeneralMainWindow : public QMainWindow {
void slot_save_settings() noexcept;
private:
- std::string name_; ///<
- QPoint pos_; ///<
- QSize size_; ///<
+ QString name_; ///<
+ QPoint pos_; ///<
+ QSize size_; ///<
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_GENERALMAINWINDOW_H
diff --git a/src/ui/main_window/KeyMgmt.cpp b/src/ui/main_window/KeyMgmt.cpp
index 47b0dcb0..3f22265e 100644
--- a/src/ui/main_window/KeyMgmt.cpp
+++ b/src/ui/main_window/KeyMgmt.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,14 +28,16 @@
#include "KeyMgmt.h"
-#include <utility>
-
#include "core/function/GlobalSettingStation.h"
#include "core/function/KeyPackageOperator.h"
#include "core/function/gpg/GpgKeyGetter.h"
#include "core/function/gpg/GpgKeyImportExporter.h"
#include "core/function/gpg/GpgKeyOpera.h"
-#include "ui/SignalStation.h"
+#include "core/model/GpgImportInformation.h"
+#include "core/utils/GpgUtils.h"
+#include "core/utils/IOUtils.h"
+#include "function/SetOwnerTrustLevel.h"
+#include "ui/UISignalStation.h"
#include "ui/UserInterfaceUtils.h"
#include "ui/dialog/import_export/ExportKeyPackageDialog.h"
#include "ui/dialog/key_generate/SubkeyGenerateDialog.h"
@@ -48,10 +50,12 @@ KeyMgmt::KeyMgmt(QWidget* parent)
/* the list of Keys available*/
key_list_ = new KeyList(KeyMenuAbility::ALL, this);
- key_list_->AddListGroupTab(_("All"), "all", KeyListRow::SECRET_OR_PUBLIC_KEY);
+ key_list_->AddListGroupTab(tr("All"), "all",
+ KeyListRow::SECRET_OR_PUBLIC_KEY);
key_list_->AddListGroupTab(
- _("Only Public Key"), "only_public_key", KeyListRow::SECRET_OR_PUBLIC_KEY,
+ tr("Only Public Key"), "only_public_key",
+ KeyListRow::SECRET_OR_PUBLIC_KEY,
KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
KeyListColumn::Usage | KeyListColumn::Validity,
[](const GpgKey& key, const KeyTable&) -> bool {
@@ -60,7 +64,8 @@ KeyMgmt::KeyMgmt(QWidget* parent)
});
key_list_->AddListGroupTab(
- _("Has Private Key"), "has_private_key", KeyListRow::SECRET_OR_PUBLIC_KEY,
+ tr("Has Private Key"), "has_private_key",
+ KeyListRow::SECRET_OR_PUBLIC_KEY,
KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
KeyListColumn::Usage | KeyListColumn::Validity,
[](const GpgKey& key, const KeyTable&) -> bool {
@@ -69,7 +74,7 @@ KeyMgmt::KeyMgmt(QWidget* parent)
});
key_list_->AddListGroupTab(
- _("No Primary Key"), "no_primary_key", KeyListRow::SECRET_OR_PUBLIC_KEY,
+ tr("No Primary Key"), "no_primary_key", KeyListRow::SECRET_OR_PUBLIC_KEY,
KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
KeyListColumn::Usage | KeyListColumn::Validity,
[](const GpgKey& key, const KeyTable&) -> bool {
@@ -78,7 +83,7 @@ KeyMgmt::KeyMgmt(QWidget* parent)
});
key_list_->AddListGroupTab(
- _("Revoked"), "revoked", KeyListRow::SECRET_OR_PUBLIC_KEY,
+ tr("Revoked"), "revoked", KeyListRow::SECRET_OR_PUBLIC_KEY,
KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
KeyListColumn::Usage | KeyListColumn::Validity,
[](const GpgKey& key, const KeyTable&) -> bool {
@@ -86,7 +91,7 @@ KeyMgmt::KeyMgmt(QWidget* parent)
});
key_list_->AddListGroupTab(
- _("Expired"), "expired", KeyListRow::SECRET_OR_PUBLIC_KEY,
+ tr("Expired"), "expired", KeyListRow::SECRET_OR_PUBLIC_KEY,
KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
KeyListColumn::Usage | KeyListColumn::Validity,
[](const GpgKey& key, const KeyTable&) -> bool {
@@ -94,9 +99,10 @@ KeyMgmt::KeyMgmt(QWidget* parent)
});
setCentralWidget(key_list_);
- key_list_->SetDoubleClickedAction([this](const GpgKey& key, QWidget* parent) {
- new KeyDetailsDialog(key, this);
- });
+ key_list_->SetDoubleClickedAction(
+ [this](const GpgKey& key, QWidget* /*parent*/) {
+ new KeyDetailsDialog(key, this);
+ });
key_list_->SlotRefresh();
@@ -110,168 +116,195 @@ KeyMgmt::KeyMgmt(QWidget* parent)
this->statusBar()->show();
- setWindowTitle(_("KeyPair Management"));
+ setWindowTitle(tr("KeyPair Management"));
+ setMinimumSize(QSize(600, 400));
key_list_->AddMenuAction(generate_subkey_act_);
key_list_->AddMenuAction(delete_selected_keys_act_);
key_list_->AddSeparator();
+ key_list_->AddMenuAction(set_owner_trust_of_key_act_);
+ key_list_->AddSeparator();
key_list_->AddMenuAction(show_key_details_act_);
- connect(this, &KeyMgmt::SignalKeyStatusUpdated, SignalStation::GetInstance(),
- &SignalStation::SignalKeyDatabaseRefresh);
- connect(SignalStation::GetInstance(), &SignalStation::SignalRefreshStatusBar,
- this, [=](const QString& message, int timeout) {
+ connect(this, &KeyMgmt::SignalKeyStatusUpdated,
+ UISignalStation::GetInstance(),
+ &UISignalStation::SignalKeyDatabaseRefresh);
+ connect(UISignalStation::GetInstance(),
+ &UISignalStation::SignalRefreshStatusBar, this,
+ [=](const QString& message, int timeout) {
statusBar()->showMessage(message, timeout);
});
}
void KeyMgmt::create_actions() {
- open_key_file_act_ = new QAction(_("Open"), this);
- open_key_file_act_->setShortcut(QKeySequence(_("Ctrl+O")));
- open_key_file_act_->setToolTip(_("Open Key File"));
+ open_key_file_act_ = new QAction(tr("Open"), this);
+ open_key_file_act_->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_O));
+ open_key_file_act_->setToolTip(tr("Open Key File"));
connect(open_key_file_act_, &QAction::triggered, this,
[&]() { CommonUtils::GetInstance()->SlotImportKeyFromFile(this); });
- close_act_ = new QAction(_("Close"), this);
- close_act_->setShortcut(QKeySequence(_("Ctrl+Q")));
- close_act_->setIcon(QIcon(":exit.png"));
- close_act_->setToolTip(_("Close"));
+ close_act_ = new QAction(tr("Close"), this);
+ close_act_->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q));
+ close_act_->setIcon(QIcon(":/icons/exit.png"));
+ close_act_->setToolTip(tr("Close"));
connect(close_act_, &QAction::triggered, this, &KeyMgmt::close);
- generate_key_pair_act_ = new QAction(_("New Keypair"), this);
- generate_key_pair_act_->setShortcut(QKeySequence(_("Ctrl+N")));
- generate_key_pair_act_->setIcon(QIcon(":key_generate.png"));
- generate_key_pair_act_->setToolTip(_("Generate KeyPair"));
+ generate_key_pair_act_ = new QAction(tr("New Keypair"), this);
+ generate_key_pair_act_->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_N));
+ generate_key_pair_act_->setIcon(QIcon(":/icons/key_generate.png"));
+ generate_key_pair_act_->setToolTip(tr("Generate KeyPair"));
connect(generate_key_pair_act_, &QAction::triggered, this,
&KeyMgmt::SlotGenerateKeyDialog);
- generate_subkey_act_ = new QAction(_("New Subkey"), this);
- generate_subkey_act_->setShortcut(QKeySequence(_("Ctrl+Shift+N")));
- generate_subkey_act_->setIcon(QIcon(":key_generate.png"));
- generate_subkey_act_->setToolTip(_("Generate Subkey For Selected KeyPair"));
+ generate_subkey_act_ = new QAction(tr("New Subkey"), this);
+ generate_subkey_act_->setShortcut(
+ QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_N));
+ generate_subkey_act_->setIcon(QIcon(":/icons/key_generate.png"));
+ generate_subkey_act_->setToolTip(tr("Generate Subkey For Selected KeyPair"));
connect(generate_subkey_act_, &QAction::triggered, this,
&KeyMgmt::SlotGenerateSubKey);
- import_key_from_file_act_ = new QAction(_("File"), this);
- import_key_from_file_act_->setIcon(QIcon(":import_key_from_file.png"));
- import_key_from_file_act_->setToolTip(_("Import New Key From File"));
+ import_key_from_file_act_ = new QAction(tr("File"), this);
+ import_key_from_file_act_->setIcon(QIcon(":/icons/import_key_from_file.png"));
+ import_key_from_file_act_->setToolTip(tr("Import New Key From File"));
connect(import_key_from_file_act_, &QAction::triggered, this,
[&]() { CommonUtils::GetInstance()->SlotImportKeyFromFile(this); });
- import_key_from_clipboard_act_ = new QAction(_("Clipboard"), this);
+ import_key_from_clipboard_act_ = new QAction(tr("Clipboard"), this);
import_key_from_clipboard_act_->setIcon(
- QIcon(":import_key_from_clipboard.png"));
+ QIcon(":/icons/import_key_from_clipboard.png"));
import_key_from_clipboard_act_->setToolTip(
- _("Import New Key From Clipboard"));
+ tr("Import New Key From Clipboard"));
connect(import_key_from_clipboard_act_, &QAction::triggered, this, [&]() {
CommonUtils::GetInstance()->SlotImportKeyFromClipboard(this);
});
- bool forbid_all_gnupg_connection =
- GlobalSettingStation::GetInstance().LookupSettings(
- "network.forbid_all_gnupg_connection", false);
+ bool const forbid_all_gnupg_connection =
+ GlobalSettingStation::GetInstance()
+ .GetSettings()
+ .value("network/forbid_all_gnupg_connection", false)
+ .toBool();
- import_key_from_key_server_act_ = new QAction(_("Keyserver"), this);
+ import_key_from_key_server_act_ = new QAction(tr("Keyserver"), this);
import_key_from_key_server_act_->setIcon(
- QIcon(":import_key_from_server.png"));
+ QIcon(":/icons/import_key_from_server.png"));
import_key_from_key_server_act_->setToolTip(
- _("Import New Key From Keyserver"));
+ tr("Import New Key From Keyserver"));
import_key_from_key_server_act_->setDisabled(forbid_all_gnupg_connection);
- connect(import_key_from_key_server_act_, &QAction::triggered, this, [&]() {
+ connect(import_key_from_key_server_act_, &QAction::triggered, this, [this]() {
CommonUtils::GetInstance()->SlotImportKeyFromKeyServer(this);
});
- import_keys_from_key_package_act_ = new QAction(_("Key Package"), this);
- import_keys_from_key_package_act_->setIcon(QIcon(":key_package.png"));
+ import_keys_from_key_package_act_ = new QAction(tr("Key Package"), this);
+ import_keys_from_key_package_act_->setIcon(QIcon(":/icons/key_package.png"));
import_keys_from_key_package_act_->setToolTip(
- _("Import Key(s) From a Key Package"));
+ tr("Import Key(s) From a Key Package"));
connect(import_keys_from_key_package_act_, &QAction::triggered, this,
&KeyMgmt::SlotImportKeyPackage);
- export_key_to_clipboard_act_ = new QAction(_("Export To Clipboard"), this);
- export_key_to_clipboard_act_->setIcon(QIcon(":export_key_to_clipboard.png"));
+ export_key_to_clipboard_act_ = new QAction(tr("Export To Clipboard"), this);
+ export_key_to_clipboard_act_->setIcon(
+ QIcon(":/icons/export_key_to_clipboard.png"));
export_key_to_clipboard_act_->setToolTip(
- _("Export Selected Key(s) To Clipboard"));
+ tr("Export Checked Key(s) To Clipboard"));
connect(export_key_to_clipboard_act_, &QAction::triggered, this,
&KeyMgmt::SlotExportKeyToClipboard);
- export_key_to_file_act_ = new QAction(_("Export To Key Package"), this);
- export_key_to_file_act_->setIcon(QIcon(":key_package.png"));
+ export_key_to_file_act_ = new QAction(tr("Export As Key Package"), this);
+ export_key_to_file_act_->setIcon(QIcon(":/icons/key_package.png"));
export_key_to_file_act_->setToolTip(
- _("Export Checked Key(s) To a Key Package"));
+ tr("Export Checked Key(s) To a Key Package"));
connect(export_key_to_file_act_, &QAction::triggered, this,
&KeyMgmt::SlotExportKeyToKeyPackage);
- export_key_as_open_ssh_format_ = new QAction(_("Export As OpenSSH"), this);
- export_key_as_open_ssh_format_->setIcon(QIcon(":ssh-key.png"));
+ export_key_as_open_ssh_format_ = new QAction(tr("Export As OpenSSH"), this);
+ export_key_as_open_ssh_format_->setIcon(QIcon(":/icons/ssh-key.png"));
export_key_as_open_ssh_format_->setToolTip(
- _("Export Selected Key(s) As OpenSSH Format to File"));
+ tr("Export Checked Key As OpenSSH Format to File"));
connect(export_key_as_open_ssh_format_, &QAction::triggered, this,
&KeyMgmt::SlotExportAsOpenSSHFormat);
- delete_selected_keys_act_ = new QAction(_("Delete Selected Key(s)"), this);
- delete_selected_keys_act_->setToolTip(_("Delete the Selected keys"));
+ delete_selected_keys_act_ = new QAction(tr("Delete Selected Key(s)"), this);
+ delete_selected_keys_act_->setToolTip(tr("Delete the Selected keys"));
connect(delete_selected_keys_act_, &QAction::triggered, this,
&KeyMgmt::SlotDeleteSelectedKeys);
- delete_checked_keys_act_ = new QAction(_("Delete Checked Key(s)"), this);
- delete_checked_keys_act_->setToolTip(_("Delete the Checked keys"));
- delete_checked_keys_act_->setIcon(QIcon(":button_delete.png"));
+ delete_checked_keys_act_ = new QAction(tr("Delete Checked Key(s)"), this);
+ delete_checked_keys_act_->setToolTip(tr("Delete the Checked keys"));
+ delete_checked_keys_act_->setIcon(QIcon(":/icons/button_delete.png"));
connect(delete_checked_keys_act_, &QAction::triggered, this,
&KeyMgmt::SlotDeleteCheckedKeys);
- show_key_details_act_ = new QAction(_("Show Key Details"), this);
- show_key_details_act_->setToolTip(_("Show Details for this Key"));
+ show_key_details_act_ = new QAction(tr("Show Key Details"), this);
+ show_key_details_act_->setToolTip(tr("Show Details for this Key"));
connect(show_key_details_act_, &QAction::triggered, this,
&KeyMgmt::SlotShowKeyDetails);
+
+ set_owner_trust_of_key_act_ = new QAction(tr("Set Owner Trust Level"), this);
+ set_owner_trust_of_key_act_->setToolTip(tr("Set Owner Trust Level"));
+ set_owner_trust_of_key_act_->setData(QVariant("set_owner_trust_level"));
+ connect(set_owner_trust_of_key_act_, &QAction::triggered, this, [this]() {
+ auto keys_selected = key_list_->GetSelected();
+ if (keys_selected->empty()) return;
+
+ auto* function = new SetOwnerTrustLevel(this);
+ function->Exec(keys_selected->front());
+ function->deleteLater();
+ });
}
void KeyMgmt::create_menus() {
- file_menu_ = menuBar()->addMenu(_("File"));
+ file_menu_ = menuBar()->addMenu(tr("File"));
file_menu_->addAction(open_key_file_act_);
file_menu_->addAction(close_act_);
- key_menu_ = menuBar()->addMenu(_("Key"));
- generate_key_menu_ = key_menu_->addMenu(_("Generate Key"));
+ key_menu_ = menuBar()->addMenu(tr("Key"));
+ generate_key_menu_ = key_menu_->addMenu(tr("Generate Key"));
generate_key_menu_->addAction(generate_key_pair_act_);
generate_key_menu_->addAction(generate_subkey_act_);
- import_key_menu_ = key_menu_->addMenu(_("Import Key"));
+ import_key_menu_ = key_menu_->addMenu(tr("Import Key"));
import_key_menu_->addAction(import_key_from_file_act_);
import_key_menu_->addAction(import_key_from_clipboard_act_);
import_key_menu_->addAction(import_key_from_key_server_act_);
import_key_menu_->addAction(import_keys_from_key_package_act_);
- key_menu_->addAction(export_key_to_file_act_);
- key_menu_->addAction(export_key_to_clipboard_act_);
- key_menu_->addAction(export_key_as_open_ssh_format_);
+ export_key_menu_ = key_menu_->addMenu(tr("Export Key"));
+ export_key_menu_->addAction(export_key_to_file_act_);
+ export_key_menu_->addAction(export_key_to_clipboard_act_);
+ export_key_menu_->addAction(export_key_as_open_ssh_format_);
key_menu_->addSeparator();
key_menu_->addAction(delete_checked_keys_act_);
}
void KeyMgmt::create_tool_bars() {
- QToolBar* key_tool_bar = addToolBar(_("Key"));
+ QToolBar* key_tool_bar = addToolBar(tr("Key"));
key_tool_bar->setObjectName("keytoolbar");
// genrate key pair
key_tool_bar->addAction(generate_key_pair_act_);
+ key_tool_bar->addSeparator();
// add button with popup menu for import
- auto* tool_button = new QToolButton(this);
- tool_button->setMenu(import_key_menu_);
- tool_button->setPopupMode(QToolButton::InstantPopup);
- tool_button->setIcon(QIcon(":key_import.png"));
- tool_button->setToolTip(_("Import key"));
- tool_button->setText(_("Import Key"));
- tool_button->setToolButtonStyle(icon_style_);
- key_tool_bar->addWidget(tool_button);
+ auto* import_tool_button = new QToolButton(this);
+ import_tool_button->setMenu(import_key_menu_);
+ import_tool_button->setPopupMode(QToolButton::InstantPopup);
+ import_tool_button->setIcon(QIcon(":/icons/key_import.png"));
+ import_tool_button->setToolTip(tr("Import key"));
+ import_tool_button->setText(tr("Import Key"));
+ import_tool_button->setToolButtonStyle(icon_style_);
+ key_tool_bar->addWidget(import_tool_button);
+
+ auto* export_tool_button = new QToolButton(this);
+ export_tool_button->setMenu(export_key_menu_);
+ export_tool_button->setPopupMode(QToolButton::InstantPopup);
+ export_tool_button->setIcon(QIcon(":/icons/key_export.png"));
+ export_tool_button->setToolTip(tr("Export key"));
+ export_tool_button->setText(tr("Export Key"));
+ export_tool_button->setToolButtonStyle(icon_style_);
+ key_tool_bar->addWidget(export_tool_button);
- key_tool_bar->addSeparator();
key_tool_bar->addAction(delete_checked_keys_act_);
- key_tool_bar->addSeparator();
- key_tool_bar->addAction(export_key_to_file_act_);
- key_tool_bar->addAction(export_key_to_clipboard_act_);
- key_tool_bar->addAction(export_key_as_open_ssh_format_);
}
void KeyMgmt::SlotDeleteSelectedKeys() {
@@ -293,19 +326,17 @@ void KeyMgmt::delete_keys_with_warning(KeyIdArgsListPtr uidList) {
for (const auto& key_id : *uidList) {
auto key = GpgKeyGetter::GetInstance().GetKey(key_id);
if (!key.IsGood()) continue;
- keynames.append(QString::fromStdString(key.GetName()));
+ keynames.append(key.GetName());
keynames.append("<i> &lt;");
- keynames.append(QString::fromStdString(key.GetEmail()));
+ keynames.append(key.GetEmail());
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?")) +
+ int const 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/>" +
- _("The action can not be undone."),
+ tr("The action can not be undone."),
QMessageBox::No | QMessageBox::Yes);
if (ret == QMessageBox::Yes) {
@@ -321,7 +352,7 @@ void KeyMgmt::SlotShowKeyDetails() {
auto key = GpgKeyGetter::GetInstance().GetKey(keys_selected->front());
if (!key.IsGood()) {
- QMessageBox::critical(this, _("Error"), _("Key Not Found."));
+ QMessageBox::critical(this, tr("Error"), tr("Key Not Found."));
return;
}
@@ -332,133 +363,193 @@ void KeyMgmt::SlotExportKeyToKeyPackage() {
auto keys_checked = key_list_->GetChecked();
if (keys_checked->empty()) {
QMessageBox::critical(
- this, _("Forbidden"),
- _("Please check some keys before doing this operation."));
+ this, tr("Forbidden"),
+ tr("Please check some keys before doing this operation."));
return;
}
- auto dialog = new ExportKeyPackageDialog(std::move(keys_checked), this);
+ auto* dialog = new ExportKeyPackageDialog(std::move(keys_checked), this);
dialog->exec();
- emit SignalStatusBarChanged(QString(_("key(s) exported")));
+ emit SignalStatusBarChanged(tr("key(s) exported"));
}
void KeyMgmt::SlotExportKeyToClipboard() {
auto keys_checked = key_list_->GetChecked();
if (keys_checked->empty()) {
QMessageBox::critical(
- this, _("Forbidden"),
- _("Please check some keys before doing this operation."));
+ this, tr("Forbidden"),
+ tr("Please check some keys before doing this operation."));
return;
}
- ByteArrayPtr key_export_data = nullptr;
- if (!GpgKeyImportExporter::GetInstance().ExportKeys(keys_checked,
- key_export_data)) {
- return;
+ if (keys_checked->size() == 1) {
+ auto key = GpgKeyGetter::GetInstance().GetKey(keys_checked->front());
+ auto [err, gf_buffer] =
+ GpgKeyImportExporter::GetInstance().ExportKey(key, false, true, false);
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ CommonUtils::RaiseMessageBox(this, err);
+ return;
+ }
+ QApplication::clipboard()->setText(gf_buffer.ConvertToQByteArray());
+ } else {
+ auto keys = GpgKeyGetter::GetInstance().GetKeys(keys_checked);
+ CommonUtils::WaitForOpera(
+ this, tr("Exporting"), [=](const OperaWaitingHd& op_hd) {
+ GpgKeyImportExporter::GetInstance().ExportKeys(
+ *keys, false, true, false, false,
+ [=](GpgError err, const DataObjectPtr& data_obj) {
+ // stop waiting
+ op_hd();
+
+ if (CheckGpgError(err) == GPG_ERR_USER_1) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unknown error occurred"));
+ return;
+ }
+
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ CommonUtils::RaiseMessageBox(this, err);
+ return;
+ }
+
+ if (data_obj == nullptr || !data_obj->Check<GFBuffer>()) {
+ GF_CORE_LOG_ERROR("data object checking failed");
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unknown error occurred"));
+ return;
+ }
+
+ auto gf_buffer = ExtractParams<GFBuffer>(data_obj, 0);
+ QApplication::clipboard()->setText(
+ gf_buffer.ConvertToQByteArray());
+ });
+ });
}
- QApplication::clipboard()->setText(QString::fromStdString(*key_export_data));
}
void KeyMgmt::SlotGenerateKeyDialog() {
- auto* keyGenDialog = new KeyGenDialog(this);
- keyGenDialog->show();
+ (new KeyGenDialog(this))->exec();
+ this->raise();
}
void KeyMgmt::SlotGenerateSubKey() {
auto keys_selected = key_list_->GetSelected();
if (keys_selected->empty()) {
QMessageBox::information(
- this, _("Invalid Operation"),
- _("Please select one KeyPair before doing this operation."));
+ this, tr("Invalid Operation"),
+ tr("Please select one KeyPair before doing this operation."));
return;
}
const auto key = GpgKeyGetter::GetInstance().GetKey(keys_selected->front());
if (!key.IsGood()) {
- QMessageBox::critical(this, _("Error"), _("Key Not Found."));
+ QMessageBox::critical(this, tr("Error"), tr("Key Not Found."));
return;
}
if (!key.IsPrivateKey()) {
- QMessageBox::critical(this, _("Invalid Operation"),
- _("If a key pair does not have a private key then "
- "it will not be able to generate sub-keys."));
+ QMessageBox::critical(this, 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(key.GetId(), this);
- dialog->show();
+ (new SubkeyGenerateDialog(key.GetId(), this))->exec();
+ this->raise();
}
void KeyMgmt::SlotExportAsOpenSSHFormat() {
- ByteArrayPtr key_export_data = nullptr;
auto keys_checked = key_list_->GetChecked();
-
if (keys_checked->empty()) {
QMessageBox::critical(
- this, _("Forbidden"),
- _("Please select a key before performing this operation. If you select "
- "multiple keys, only the first key will be exported."));
- return;
- }
-
- auto key = GpgKeyGetter::GetInstance().GetKey(keys_checked->front());
- if (!GpgKeyImportExporter::GetInstance().ExportKeyOpenSSH(key,
- key_export_data)) {
- QMessageBox::critical(this, _("Error"), _("An error occur in exporting."));
- return;
- }
-
- if (key_export_data->empty()) {
- QMessageBox::critical(
- this, _("Error"),
- _("This key may not be able to export as OpenSSH format. Please check "
- "the key-size of the subkey(s) used to sign."));
+ this, tr("Forbidden"),
+ tr("Please check a key before performing this operation."));
return;
}
- key = GpgKeyGetter::GetInstance().GetKey(keys_checked->front());
- if (!key.IsGood()) {
- QMessageBox::critical(this, _("Error"), _("Key Not Found."));
+ if (keys_checked->size() > 1) {
+ QMessageBox::critical(this, tr("Forbidden"),
+ tr("This operation accepts just a single key."));
return;
}
- QString fileString = QString::fromStdString(
- key.GetName() + " " + key.GetEmail() + "(" + key.GetId() + ").pub");
- QString file_name = QFileDialog::getSaveFileName(
- this, _("Export OpenSSH Key To File"), fileString,
- QString(_("OpenSSH Public Key Files")) + " (*.pub);;All Files (*)");
-
- if (!file_name.isEmpty()) {
- write_buffer_to_file(file_name.toStdString(), *key_export_data);
- emit SignalStatusBarChanged(QString(_("key(s) exported")));
- }
+ auto keys = GpgKeyGetter::GetInstance().GetKeys(keys_checked);
+ CommonUtils::WaitForOpera(
+ this, tr("Exporting"), [this, keys](const OperaWaitingHd& op_hd) {
+ GpgKeyImportExporter::GetInstance().ExportKeys(
+ *keys, false, true, false, true,
+ [=](GpgError err, const DataObjectPtr& data_obj) {
+ // stop waiting
+ op_hd();
+
+ if (CheckGpgError(err) == GPG_ERR_USER_1) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unknown error occurred"));
+ return;
+ }
+
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ CommonUtils::RaiseMessageBox(this, err);
+ return;
+ }
+
+ if (data_obj == nullptr || !data_obj->Check<GFBuffer>()) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unknown error occurred"));
+ return;
+ }
+
+ auto gf_buffer = ExtractParams<GFBuffer>(data_obj, 0);
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ CommonUtils::RaiseMessageBox(this, err);
+ return;
+ }
+
+ if (gf_buffer.Empty()) {
+ QMessageBox::critical(
+ this, tr("Error"),
+ tr("This key may not be able to export as OpenSSH format. "
+ "Please check the key-size of the subkey(s) used to "
+ "sign."));
+ return;
+ }
+
+ QString const file_name = QFileDialog::getSaveFileName(
+ this, tr("Export OpenSSH Key To File"), "authorized_keys",
+ tr("OpenSSH Public Key Files") + "All Files (*)");
+
+ if (!file_name.isEmpty()) {
+ WriteFileGFBuffer(file_name, gf_buffer);
+ emit SignalStatusBarChanged(tr("key(s) exported"));
+ }
+ });
+ });
}
void KeyMgmt::SlotImportKeyPackage() {
- SPDLOG_INFO("Importing key package...");
+ GF_UI_LOG_INFO("Importing key package...");
auto key_package_file_name = QFileDialog::getOpenFileName(
- this, _("Import Key Package"), {},
- QString(_("Key Package")) + " (*.gfepack);;All Files (*)");
+ this, tr("Import Key Package"), {},
+ tr("Key Package") + " (*.gfepack);;All Files (*)");
auto key_file_name = QFileDialog::getOpenFileName(
- this, _("Import Key Package Passphrase File"), {},
- QString(_("Key Package Passphrase File")) + " (*.key);;All Files (*)");
+ this, tr("Import Key Package Passphrase File"), {},
+ tr("Key Package Passphrase File") + " (*.key);;All Files (*)");
if (key_package_file_name.isEmpty() || key_file_name.isEmpty()) return;
- GpgImportInformation info;
+ GF_UI_LOG_INFO("importing key package: {}", key_package_file_name);
- SPDLOG_INFO("importing key package: {}", key_package_file_name.toStdString());
+ const auto [success, info] = KeyPackageOperator::ImportKeyPackage(
+ key_package_file_name, key_file_name);
- if (KeyPackageOperator::ImportKeyPackage(key_package_file_name.toStdString(),
- key_file_name.toStdString(), info)) {
- emit SignalStatusBarChanged(QString(_("key(s) imported")));
+ if (success) {
+ emit SignalStatusBarChanged(tr("key(s) imported"));
emit SignalKeyStatusUpdated();
- auto dialog = new KeyImportDetailDialog(info, false, this);
+ auto* dialog = new KeyImportDetailDialog(info, this);
dialog->exec();
} else {
- QMessageBox::critical(this, _("Error"),
- _("An error occur in importing key package."));
+ QMessageBox::critical(this, tr("Error"),
+ tr("An error occur in importing key package."));
}
}
diff --git a/src/ui/main_window/KeyMgmt.h b/src/ui/main_window/KeyMgmt.h
index 2073113a..696ce733 100644
--- a/src/ui/main_window/KeyMgmt.h
+++ b/src/ui/main_window/KeyMgmt.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,14 +20,13 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef __KEYMGMT_H__
-#define __KEYMGMT_H__
+#pragma once
#include "ui/GpgFrontendUI.h"
#include "ui/dialog/import_export/KeyImportDetailDialog.h"
@@ -150,11 +149,13 @@ class KeyMgmt : public GeneralMainWindow {
*/
void delete_keys_with_warning(GpgFrontend::KeyIdArgsListPtr uidList);
- KeyList* key_list_; ///<
- QMenu* file_menu_{}; ///<
- QMenu* key_menu_{}; ///<
- QMenu* generate_key_menu_{}; ///<
- QMenu* import_key_menu_{}; ///<
+ KeyList* key_list_; ///<
+ QMenu* file_menu_{}; ///<
+ QMenu* key_menu_{}; ///<
+ QMenu* generate_key_menu_{}; ///<
+ QMenu* import_key_menu_{}; ///<
+ QMenu* export_key_menu_{}; /// <
+
QAction* open_key_file_act_{}; ///<
QAction* export_key_to_file_act_{}; ///<
QAction* export_key_as_open_ssh_format_{}; ///<
@@ -170,9 +171,8 @@ class KeyMgmt : public GeneralMainWindow {
QAction* import_keys_from_key_package_act_{}; ///<
QAction* close_act_{}; ///<
QAction* show_key_details_act_{}; ///<
- KeyServerImportDialog* import_dialog_{}; ///<
+ QAction* set_owner_trust_of_key_act_{};
+ KeyServerImportDialog* import_dialog_{}; ///<
};
} // namespace GpgFrontend::UI
-
-#endif // __KEYMGMT_H__
diff --git a/src/ui/main_window/MainWindow.cpp b/src/ui/main_window/MainWindow.cpp
index b07ad309..f0a2be29 100644
--- a/src/ui/main_window/MainWindow.cpp
+++ b/src/ui/main_window/MainWindow.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,24 +28,27 @@
#include "MainWindow.h"
-#include "core/GpgConstants.h"
+#include "core/GpgModel.h"
#include "core/function/CacheManager.h"
+#include "core/function/CoreSignalStation.h"
#include "core/function/GlobalSettingStation.h"
#include "core/function/gpg/GpgAdvancedOperator.h"
-#include "main_window/GeneralMainWindow.h"
-#include "nlohmann/json_fwd.hpp"
-#include "spdlog/spdlog.h"
-#include "ui/SignalStation.h"
-#include "ui/UserInterfaceUtils.h"
+#include "core/module/ModuleManager.h"
+#include "ui/UISignalStation.h"
+#include "ui/main_window/GeneralMainWindow.h"
#include "ui/struct/SettingsObject.h"
-#include "ui/thread/VersionCheckTask.h"
-#include "widgets/KeyList.h"
+#include "ui/struct/settings/KeyServerSO.h"
+#include "ui/widgets/KeyList.h"
namespace GpgFrontend::UI {
MainWindow::MainWindow() : GeneralMainWindow("main_window") {
this->setMinimumSize(1200, 700);
this->setWindowTitle(qApp->applicationName());
+
+ connect(CoreSignalStation::GetInstance(),
+ &CoreSignalStation::SignalNeedUserInputPassphrase, this,
+ &MainWindow::SlotRaisePinentry);
}
void MainWindow::Init() noexcept {
@@ -84,19 +87,19 @@ void MainWindow::Init() noexcept {
this->menuBar()->show();
connect(this, &MainWindow::SignalRestartApplication,
- SignalStation::GetInstance(),
- &SignalStation::SignalRestartApplication);
+ UISignalStation::GetInstance(),
+ &UISignalStation::SignalRestartApplication);
- connect(this, &MainWindow::SignalUIRefresh, SignalStation::GetInstance(),
- &SignalStation::SignalUIRefresh);
+ connect(this, &MainWindow::SignalUIRefresh, UISignalStation::GetInstance(),
+ &UISignalStation::SignalUIRefresh);
connect(this, &MainWindow::SignalKeyDatabaseRefresh,
- SignalStation::GetInstance(),
- &SignalStation::SignalKeyDatabaseRefresh);
+ UISignalStation::GetInstance(),
+ &UISignalStation::SignalKeyDatabaseRefresh);
connect(edit_->tab_widget_, &QTabWidget::currentChanged, this,
&MainWindow::slot_disable_tab_actions);
- connect(SignalStation::GetInstance(),
- &SignalStation::SignalRefreshStatusBar, this,
+ connect(UISignalStation::GetInstance(),
+ &UISignalStation::SignalRefreshStatusBar, this,
[=](const QString &message, int timeout) {
statusBar()->showMessage(message, timeout);
});
@@ -120,163 +123,101 @@ void MainWindow::Init() noexcept {
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);
-
- SPDLOG_DEBUG("wizard show_wizard: {}", show_wizard);
-
- if (show_wizard) {
- slot_start_wizard();
- }
-
- emit SignalLoaded();
-
- // if not prohibit update checking
- if (!prohibit_update_checking_) {
- auto *version_task = new VersionCheckTask();
-
- connect(version_task, &VersionCheckTask::SignalUpgradeVersion, this,
- &MainWindow::slot_version_upgrade);
-
- Thread::TaskRunnerGetter::GetInstance()
- .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Network)
- ->PostTask(version_task);
- }
-
// before application exit
connect(qApp, &QCoreApplication::aboutToQuit, this, []() {
- SPDLOG_DEBUG("about to quit process started");
-
- if (GlobalSettingStation::GetInstance().LookupSettings(
- "general.clear_gpg_password_cache", false)) {
- if (GpgFrontend::GpgAdvancedOperator::GetInstance()
- .ClearGpgPasswordCache()) {
- SPDLOG_DEBUG("clear gpg password cache done");
- } else {
- SPDLOG_ERROR("clear gpg password cache error");
- }
+ GF_UI_LOG_DEBUG("about to quit process started");
+
+ if (GlobalSettingStation::GetInstance()
+ .GetSettings()
+ .value("basic/clear_gpg_password_cache", false)
+ .toBool()) {
+ GpgFrontend::GpgAdvancedOperator::ClearGpgPasswordCache(
+ [](int, DataObjectPtr) {
+
+ });
}
});
+ Module::ListenRTPublishEvent(
+ this, "com.bktus.gpgfrontend.module.integrated.version-checking",
+ "version.loading_done",
+ [=](Module::Namespace, Module::Key, int, std::any) {
+ GF_UI_LOG_DEBUG(
+ "versionchecking version.loading_done changed, calling slot "
+ "version upgrade");
+ this->slot_version_upgrade_nofity();
+ });
+
+ // loading process is done
+ emit SignalLoaded();
+ Module::TriggerEvent("APPLICATION_LOADED");
+
// recover unsaved page from cache if it exists
recover_editor_unsaved_pages_from_cache();
+ // check if need to open wizard window
+ auto settings = GlobalSettingStation::GetInstance().GetSettings();
+ bool show_wizard = settings.value("wizard/show_wizard", true).toBool();
+ if (show_wizard) slot_start_wizard();
+
} catch (...) {
- SPDLOG_ERROR(_("Critical error occur while loading GpgFrontend."));
- QMessageBox::critical(nullptr, _("Loading Failed"),
- _("Critical error occur while loading GpgFrontend."));
+ GF_UI_LOG_ERROR(tr("Critical error occur while loading GpgFrontend."));
+ QMessageBox::critical(
+ nullptr, tr("Loading Failed"),
+ tr("Critical error occur while loading GpgFrontend."));
QCoreApplication::quit();
exit(0);
}
}
void MainWindow::restore_settings() {
- try {
- SPDLOG_DEBUG("restore settings key_server");
-
- SettingsObject key_server_json("key_server");
- if (!key_server_json.contains("server_list") ||
- key_server_json["server_list"].empty()) {
- key_server_json["server_list"] = {"https://keyserver.ubuntu.com",
- "https://keys.openpgp.org"};
- }
- if (!key_server_json.contains("default_server")) {
- key_server_json["default_server"] = 0;
- }
-
- 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("save_key_checked")) {
- general.add("save_key_checked", libconfig::Setting::TypeBoolean) = true;
- }
+ GF_UI_LOG_DEBUG("restore settings for main windows");
- if (!general.exists("non_ascii_when_export")) {
- general.add("non_ascii_when_export", libconfig::Setting::TypeBoolean) =
- true;
- }
+ KeyServerSO key_server(SettingsObject("key_server"));
+ if (key_server.server_list.empty()) key_server.ResetDefaultServerList();
+ if (key_server.default_server < 0) key_server.default_server = 0;
- bool save_key_checked = true;
- general.lookupValue("save_key_checked", save_key_checked);
-
- // set appearance
- import_button_->setToolButtonStyle(icon_style_);
-
- try {
- SPDLOG_DEBUG("restore settings default_key_checked");
-
- // Checked Keys
- SettingsObject default_key_checked("default_key_checked");
- if (save_key_checked) {
- auto key_ids_ptr = std::make_unique<KeyIdArgsList>();
- for (auto &it : default_key_checked) {
- std::string key_id = it;
- SPDLOG_DEBUG("get checked key id: {}", key_id);
- key_ids_ptr->push_back(key_id);
- }
- m_key_list_->SetChecked(std::move(key_ids_ptr));
- }
- } catch (...) {
- SPDLOG_ERROR("restore default_key_checked failed");
- }
+ auto settings = GlobalSettingStation::GetInstance().GetSettings();
+ if (!settings.contains("basic/non_ascii_when_export")) {
+ settings.setValue("basic/non_ascii_when_export", true);
+ }
- prohibit_update_checking_ = false;
- try {
- prohibit_update_checking_ =
- settings.lookup("network.prohibit_update_checking");
- } catch (...) {
- SPDLOG_ERROR("setting operation error: prohibit_update_checking");
- }
+ // set appearance
+ import_button_->setToolButtonStyle(icon_style_);
- } catch (...) {
- SPDLOG_ERROR("cannot resolve settings");
- }
+ prohibit_update_checking_ =
+ settings.value("network/prohibit_update_check").toBool();
- GlobalSettingStation::GetInstance().SyncSettings();
- SPDLOG_DEBUG("settings restored");
+ GF_UI_LOG_DEBUG("settings restored");
}
void MainWindow::recover_editor_unsaved_pages_from_cache() {
- auto unsaved_page_array =
- CacheManager::GetInstance().LoadCache("editor_unsaved_pages");
+ auto json_data =
+ CacheManager::GetInstance().LoadDurableCache("editor_unsaved_pages");
- if (!unsaved_page_array.is_array() || unsaved_page_array.empty()) {
+ if (json_data.isEmpty() || !json_data.isArray()) {
return;
}
- SPDLOG_DEBUG("plan ot recover unsaved page from cache, page array: {}",
- unsaved_page_array.dump());
+ GF_UI_LOG_DEBUG("plan ot recover unsaved page from cache, page array: {}",
+ json_data.toJson());
bool first = true;
- for (auto &unsaved_page_json : unsaved_page_array) {
+ QJsonArray unsaved_page_array = json_data.array();
+ for (const auto &value_ref : unsaved_page_array) {
+ if (!value_ref.isObject()) continue;
+ auto unsaved_page_json = value_ref.toObject();
+
if (!unsaved_page_json.contains("title") ||
!unsaved_page_json.contains("content")) {
continue;
}
- std::string title = unsaved_page_json["title"];
- std::string content = unsaved_page_json["content"];
- SPDLOG_DEBUG(
+ QString title = unsaved_page_json["title"].toString();
+ QString content = unsaved_page_json["content"].toString();
+
+ GF_UI_LOG_DEBUG(
"recovering unsaved page from cache, page title: {}, content size",
title, content.size());
@@ -289,27 +230,6 @@ void MainWindow::recover_editor_unsaved_pages_from_cache() {
}
}
-void MainWindow::save_settings() {
- bool save_key_checked = GlobalSettingStation::GetInstance().LookupSettings(
- "general.save_key_checked", false);
-
- // keyid-list of private checked keys
- if (save_key_checked) {
- auto key_ids_need_to_store = m_key_list_->GetChecked();
-
- SettingsObject default_key_checked("default_key_checked");
- default_key_checked.clear();
-
- for (const auto &key_id : *key_ids_need_to_store)
- default_key_checked.push_back(key_id);
- } else {
- auto &settings = GlobalSettingStation::GetInstance().GetUISettings();
- settings["general"].remove("save_key_checked");
- }
-
- GlobalSettingStation::GetInstance().SyncSettings();
-}
-
void MainWindow::close_attachment_dock() {
if (!attachment_dock_created_) {
return;
@@ -325,7 +245,6 @@ void MainWindow::closeEvent(QCloseEvent *event) {
* modified documents in any tab
*/
if (edit_->MaybeSaveAnyTab()) {
- save_settings();
event->accept();
} else {
event->ignore();
@@ -333,8 +252,8 @@ void MainWindow::closeEvent(QCloseEvent *event) {
if (event->isAccepted()) {
// clear cache of unsaved page
- CacheManager::GetInstance().SaveCache("editor_unsaved_pages",
- nlohmann::json::array(), true);
+ CacheManager::GetInstance().SaveDurableCache(
+ "editor_unsaved_pages", QJsonDocument(QJsonArray()), true);
// clear password from memory
// GpgContext::GetInstance().clearPasswordCache();
diff --git a/src/ui/main_window/MainWindow.h b/src/ui/main_window/MainWindow.h
index 42f9daf3..66b61d68 100644
--- a/src/ui/main_window/MainWindow.h
+++ b/src/ui/main_window/MainWindow.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,31 +20,22 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef __GPGWIN_H__
-#define __GPGWIN_H__
-
-#include "KeyMgmt.h"
-#include "core/GpgConstants.h"
-#include "core/function/result_analyse/GpgDecryptResultAnalyse.h"
-#include "core/function/result_analyse/GpgEncryptResultAnalyse.h"
-#include "core/function/result_analyse/GpgSignResultAnalyse.h"
-#include "ui/GpgFrontendUI.h"
-#include "ui/dialog/WaitingDialog.h"
-#include "ui/dialog/Wizard.h"
-#include "ui/dialog/help/AboutDialog.h"
-#include "ui/dialog/import_export/KeyUploadDialog.h"
-#include "ui/dialog/settings/SettingsDialog.h"
+#pragma once
+
#include "ui/main_window/GeneralMainWindow.h"
-#include "ui/widgets/FindWidget.h"
#include "ui/widgets/InfoBoardWidget.h"
#include "ui/widgets/TextEdit.h"
+namespace GpgFrontend {
+class GpgPassphraseContext;
+}
+
namespace GpgFrontend::UI {
/**
* @brief
@@ -127,82 +118,130 @@ class MainWindow : public GeneralMainWindow {
/**
* @details Open a new tab for path
*/
- void SlotOpenFile(QString& path);
+ void SlotOpenFile(const QString& path);
/**
- * @details Open dialog for encrypting file.
+ * @details encrypt the text of currently active textedit-page
+ * with the currently checked keys
*/
- void SlotFileEncrypt();
+ void SlotEncrypt();
/**
- * @details Open dialog for decrypting file.
+ * @details encrypt and sign the text of currently active textedit-page
+ * with the currently checked keys
*/
- void SlotFileDecrypt();
+ void SlotEncryptSign();
/**
- * @details Open dialog for signing file.
+ * @details Show a passphrase dialog and decrypt the text of currently active
+ * tab.
*/
- void SlotFileSign();
+ void SlotDecrypt();
/**
- * @details Open dialog for verifying file.
+ * @details Sign the text of currently active tab with the checked private
+ * keys
*/
- void SlotFileVerify();
+ void SlotSign();
/**
- * @details Open dialog for signing file.
+ * @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 SlotFileEncryptSign();
+ void SlotVerify();
/**
- * @details Open dialog for verifying file.
+ * @details decrypt and verify the text of currently active textedit-page
+ * with the currently checked keys
*/
- void SlotFileDecryptVerify();
+ void SlotDecryptVerify();
/**
- * @details get value of member restartNeeded to needed.
- * @param needed true, if application has to be restarted
+ * @details Open dialog for encrypting file.
*/
- void SlotSetRestartNeeded(int);
+ void SlotFileEncrypt(const QString&);
- private slots:
+ /**
+ * @brief
+ *
+ */
+ void SlotDirectoryEncrypt(const QString&);
/**
- * @details encrypt the text of currently active textedit-page
- * with the currently checked keys
+ * @brief
+ *
+ * @param path
*/
- void slot_encrypt();
+ void SlotFileDecrypt(const QString& path);
/**
- * @details encrypt and sign the text of currently active textedit-page
- * with the currently checked keys
+ * @brief
+ *
+ * @param path
*/
- void slot_encrypt_sign();
+ void SlotArchiveDecrypt(const QString& path);
/**
- * @details Show a passphrase dialog and decrypt the text of currently active
- * tab.
+ * @brief
+ *
+ * @param path
*/
- void slot_decrypt();
+ void SlotFileSign(const QString& path);
/**
- * @details Sign the text of currently active tab with the checked private
- * keys
+ * @brief
+ *
+ * @param path
*/
- void slot_sign();
+ void SlotFileVerify(const QString& path);
/**
- * @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.
+ * @brief
+ *
+ * @param path
*/
- void slot_verify();
+ void SlotFileEncryptSign(const QString& path);
/**
- * @details decrypt and verify the text of currently active textedit-page
- * with the currently checked keys
+ * @brief
+ *
+ * @param path
+ */
+ void SlotDirectoryEncryptSign(const QString& path);
+
+ /**
+ * @brief
+ *
+ * @param path
+ */
+ void SlotFileDecryptVerify(const QString& path);
+
+ /**
+ * @brief
+ *
+ * @param path
+ */
+ void SlotArchiveDecryptVerify(const QString& path);
+
+ /**
+ * @details get value of member restartNeeded to needed.
+ * @param needed true, if application has to be restarted
+ */
+ void SlotSetRestartNeeded(int);
+
+ /**
+ * @details Open a new tab for path
+ */
+ void SlotRaisePinentry(QSharedPointer<GpgPassphraseContext>);
+
+ private slots:
+
+ /**
+ * @brief
+ *
*/
- void slot_decrypt_verify();
+ void slot_refresh_current_file_view();
/**
* @details Show the details of the first of the first of selected keys
@@ -315,7 +354,7 @@ class MainWindow : public GeneralMainWindow {
/**
* @details called when need to upgrade.
*/
- void slot_version_upgrade(const SoftwareVersion& version);
+ void slot_version_upgrade_nofity();
/**
* @details
@@ -380,11 +419,6 @@ class MainWindow : public GeneralMainWindow {
void recover_editor_unsaved_pages_from_cache();
/**
- * @details Save settings to ini-file.
- */
- void save_settings();
-
- /**
* @brief return true, if restart is needed
*/
[[nodiscard]] int get_restart_needed() const;
@@ -490,5 +524,3 @@ class MainWindow : public GeneralMainWindow {
};
} // namespace GpgFrontend::UI
-
-#endif // __GPGWIN_H__
diff --git a/src/ui/main_window/MainWindowFileSlotFunction.cpp b/src/ui/main_window/MainWindowFileSlotFunction.cpp
index 6fe8062b..76fd4a9d 100644
--- a/src/ui/main_window/MainWindowFileSlotFunction.cpp
+++ b/src/ui/main_window/MainWindowFileSlotFunction.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,526 +20,618 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "MainWindow.h"
-#include "core/function/ArchiveFileOperator.h"
#include "core/function/GlobalSettingStation.h"
#include "core/function/gpg/GpgFileOpera.h"
#include "core/function/gpg/GpgKeyGetter.h"
-#include "core/thread/Task.h"
-#include "dialog/SignersPicker.h"
+#include "core/function/result_analyse/GpgDecryptResultAnalyse.h"
+#include "core/function/result_analyse/GpgEncryptResultAnalyse.h"
+#include "core/function/result_analyse/GpgSignResultAnalyse.h"
+#include "core/function/result_analyse/GpgVerifyResultAnalyse.h"
+#include "core/utils/GpgUtils.h"
+#include "core/utils/IOUtils.h"
#include "ui/UserInterfaceUtils.h"
+#include "ui/dialog/SignersPicker.h"
namespace GpgFrontend::UI {
-bool path_pre_check(QWidget* parent, const QString& path) {
- QFileInfo file_info(path);
- QFileInfo path_info(file_info.absolutePath());
- if (!path_info.exists()) {
- QMessageBox::critical(parent, _("Error"),
- QString(_("The path %1 does not exist.")).arg(path));
- 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;
-}
-
-/**
- * @brief convert directory into tarball
- *
- * @param parent parent widget
- * @param path the directory to be converted
- * @return
- */
-bool process_tarball_into_directory(QWidget* parent,
- std::filesystem::path& path) {
- SPDLOG_DEBUG("converting directory into tarball: {}", path.u8string());
- auto selected_dir_path = std::filesystem::path(path);
-
- if (selected_dir_path.extension() != ".tar") {
- QMessageBox::critical(parent, _("Error"), _("The file is not a tarball."));
- return false;
- }
-
- try {
- auto base_path = selected_dir_path.parent_path();
-
- auto target_path = selected_dir_path;
- target_path.replace_extension(".tar");
-
- SPDLOG_DEBUG("base path: {} target archive path: {]", base_path.u8string(),
- target_path.u8string());
-
- bool if_error = false;
- process_operation(parent, _("Extracting Tarball"),
- [&](Thread::Task::DataObjectPtr) -> int {
- try {
- GpgFrontend::ArchiveFileOperator::ExtractArchive(
- target_path, base_path);
- } catch (const std::runtime_error& e) {
- if_error = true;
- }
- return 0;
- });
-
- if (if_error || !exists(target_path)) {
- throw std::runtime_error("Decompress Failed");
- }
- path = target_path.u8string().c_str();
- } catch (...) {
- SPDLOG_ERROR("decompress error");
- return false;
+void MainWindow::SlotFileEncrypt(const QString& path) {
+ auto check_result = TargetFilePreCheck(path, true);
+ if (!std::get<0>(check_result)) {
+ QMessageBox::critical(
+ this, tr("Error"),
+ tr("Cannot read from file: %1").arg(QFileInfo(path).fileName()));
+ return;
}
- return true;
-}
-/**
- * @brief convert tarball into directory
- *
- * @param parent parent widget
- * @param path the tarball to be converted
- */
-bool process_directory_into_tarball(QWidget* parent, QString& path) {
-#ifdef WINDOWS
- std::filesystem::path selected_dir_path = path.toStdU16String();
-#else
- std::filesystem::path selected_dir_path = path.toStdString();
-#endif
-
- try {
- auto base_path = selected_dir_path.parent_path();
- auto target_path = selected_dir_path;
- selected_dir_path.replace_extension("");
-
- SPDLOG_DEBUG("base path: {} target archive path: {} selected_dir_path: {}",
- base_path.u8string(), target_path.u8string(),
- selected_dir_path.u8string());
-
- bool if_error = false;
- process_operation(parent, _("Making Tarball"),
- [&](Thread::Task::DataObjectPtr) -> int {
- try {
- GpgFrontend::ArchiveFileOperator::CreateArchive(
- base_path, target_path, 0, {selected_dir_path});
- } catch (const std::runtime_error& e) {
- if_error = true;
- }
- return 0;
- });
-
- if (if_error || !exists(target_path)) {
- throw std::runtime_error("Compress Failed");
- }
- path = target_path.u8string().c_str();
- } catch (...) {
- SPDLOG_ERROR("compress error");
- return false;
- }
- return true;
-}
+ bool const non_ascii_when_export =
+ GlobalSettingStation::GetInstance()
+ .GetSettings()
+ .value("basic/non_ascii_when_export", true)
+ .toBool();
+ auto out_path =
+ SetExtensionOfOutputFile(path, kENCRYPT, !non_ascii_when_export);
-void MainWindow::SlotFileEncrypt() {
- auto fileTreeView = edit_->SlotCurPageFileTreeView();
- auto path = fileTreeView->GetSelected();
+ if (QFile::exists(out_path)) {
+ auto out_file_name = tr("The target file %1 already exists, "
+ "do you need to overwrite it?")
+ .arg(out_path);
+ auto ret = QMessageBox::warning(this, tr("Warning"), out_file_name,
+ QMessageBox::Ok | QMessageBox::Cancel);
- if (!path_pre_check(this, path)) {
- SPDLOG_ERROR("path pre check failed");
+ if (ret == QMessageBox::Cancel) return;
+ }
+
+ check_result = TargetFilePreCheck(out_path, false);
+ if (!std::get<0>(check_result)) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Cannot write to file: %1").arg(out_path));
return;
}
// check selected keys
auto key_ids = m_key_list_->GetChecked();
- GpgEncrResult result = nullptr;
- GpgError error;
- bool if_error = false;
+ if (key_ids->empty()) {
+ // Symmetric Encrypt
+ auto ret = QMessageBox::information(
+ this, tr("Symmetric Encryption"),
+ tr("No Key Selected. Do you want to encrypt with a "
+ "symmetric cipher using a passphrase?"),
+ QMessageBox::Ok | QMessageBox::Cancel);
+ if (ret == QMessageBox::Cancel) return;
+
+ CommonUtils::WaitForOpera(
+ this, tr("Symmetrically Encrypting"), [=](const OperaWaitingHd& op_hd) {
+ GpgFileOpera::GetInstance().EncryptFileSymmetric(
+ path, !non_ascii_when_export, out_path,
+ [=](GpgError err, const DataObjectPtr& data_obj) {
+ // stop waiting
+ op_hd();
+
+ if (CheckGpgError(err) == GPG_ERR_USER_1 ||
+ data_obj == nullptr ||
+ !data_obj->Check<GpgEncryptResult>()) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unknown error occurred"));
+ return;
+ }
+
+ auto result = ExtractParams<GpgEncryptResult>(data_obj, 0);
+ auto result_analyse = GpgEncryptResultAnalyse(err, result);
+ result_analyse.Analyse();
+
+ process_result_analyse(edit_, info_board_, result_analyse);
+ this->slot_refresh_current_file_view();
+ });
+ });
+
+ return;
+ }
- bool non_ascii_when_export =
- GlobalSettingStation::GetInstance().LookupSettings(
- "general.non_ascii_when_export", true);
+ auto p_keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
- // get file info
- QFileInfo file_info(path);
+ // check key abilities
+ for (const auto& key : *p_keys) {
+ bool const key_can_encrypt = key.IsHasActualEncryptionCapability();
- if (file_info.isDir()) {
- path = path + (file_info.isDir() ? ".tar" : "");
+ if (!key_can_encrypt) {
+ QMessageBox::critical(
+ nullptr, tr("Invalid KeyPair"),
+ tr("The selected keypair cannot be used for encryption.") +
+ "<br/><br/>" + tr("For example the Following Key:") + " <br/>" +
+ key.GetUIDs()->front().GetUID());
+ return;
+ }
}
- auto _channel = GPGFRONTEND_DEFAULT_CHANNEL;
- auto _extension = ".asc";
- if (non_ascii_when_export || file_info.isDir()) {
- _channel = GPGFRONTEND_NON_ASCII_CHANNEL;
- _extension = ".gpg";
+ CommonUtils::WaitForOpera(
+ this, tr("Encrypting"), [=](const OperaWaitingHd& op_hd) {
+ GpgFileOpera::GetInstance().EncryptFile(
+ {p_keys->begin(), p_keys->end()}, path, !non_ascii_when_export,
+ out_path, [=](GpgError err, const DataObjectPtr& data_obj) {
+ // stop waiting
+ op_hd();
+
+ if (CheckGpgError(err) == GPG_ERR_USER_1 || data_obj == nullptr ||
+ !data_obj->Check<GpgEncryptResult>()) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unknown error occurred"));
+ return;
+ }
+
+ auto result = ExtractParams<GpgEncryptResult>(data_obj, 0);
+ auto result_analyse = GpgEncryptResultAnalyse(err, result);
+ result_analyse.Analyse();
+
+ process_result_analyse(edit_, info_board_, result_analyse);
+ this->slot_refresh_current_file_view();
+ });
+ });
+}
+
+void MainWindow::SlotDirectoryEncrypt(const QString& path) {
+ auto check_result = TargetFilePreCheck(path, true);
+ if (!std::get<0>(check_result)) {
+ QMessageBox::critical(
+ this, tr("Error"),
+ tr("Cannot read from file: %1").arg(QFileInfo(path).fileName()));
+ return;
}
- auto out_path = path + _extension;
+ bool const non_ascii_when_export =
+ GlobalSettingStation::GetInstance()
+ .GetSettings()
+ .value("basic/non_ascii_when_export", true)
+ .toBool();
+ auto out_path = SetExtensionOfOutputFileForArchive(path, kENCRYPT,
+ !non_ascii_when_export);
if (QFile::exists(out_path)) {
-#ifdef WINDOWS
- std::filesystem::path _out_path = out_path.toStdU16String();
-#else
- std::filesystem::path _out_path = out_path.toStdString();
-#endif
- auto out_file_name = boost::format(_("The target file %1% already exists, "
- "do you need to overwrite it?")) %
- _out_path.filename();
- auto ret =
- QMessageBox::warning(this, _("Warning"), out_file_name.str().c_str(),
- QMessageBox::Ok | QMessageBox::Cancel);
+ auto out_file_name = tr("The target file %1 already exists, "
+ "do you need to overwrite it?")
+ .arg(out_path);
+ auto ret = QMessageBox::warning(this, tr("Warning"), out_file_name,
+ QMessageBox::Ok | QMessageBox::Cancel);
if (ret == QMessageBox::Cancel) return;
}
- if (file_info.isDir()) {
- // stop if the process making tarball failed
- if (!process_directory_into_tarball(this, path)) {
- QMessageBox::critical(this, _("Error"),
- _("Unable to convert the folder into tarball."));
- return;
- }
+ check_result = TargetFilePreCheck(out_path, false);
+ if (!std::get<0>(check_result)) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Cannot write to file: %1").arg(out_path));
+ return;
}
+ // check selected keys
+ auto key_ids = m_key_list_->GetChecked();
+ // symmetric encrypt
if (key_ids->empty()) {
- // Symmetric Encrypt
auto ret = QMessageBox::information(
- this, _("Symmetric Encryption"),
- _("No Key Selected. Do you want to encrypt with a "
- "symmetric cipher using a passphrase?"),
+ this, tr("Symmetric Encryption"),
+ tr("No Key Selected. Do you want to encrypt with a "
+ "symmetric cipher using a passphrase?"),
QMessageBox::Ok | QMessageBox::Cancel);
-
if (ret == QMessageBox::Cancel) return;
- process_operation(
- this, _("Symmetrically Encrypting"),
- [&](Thread::Task::DataObjectPtr) -> int {
- try {
- error = GpgFrontend::GpgFileOpera::EncryptFileSymmetric(
- path.toStdString(), out_path.toStdString(), result, _channel);
- } catch (const std::runtime_error& e) {
- if_error = true;
- }
- return 0;
+ CommonUtils::WaitForOpera(
+ this, tr("Archiving & Symmetrically Encrypting"),
+ [=](const OperaWaitingHd& op_hd) {
+ GpgFileOpera::GetInstance().EncryptDerectorySymmetric(
+ path, !non_ascii_when_export, out_path,
+ [=](GpgError err, const DataObjectPtr& data_obj) {
+ // stop waiting
+ op_hd();
+
+ if (data_obj == nullptr ||
+ !data_obj->Check<GpgEncryptResult>()) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unknown error occurred"));
+ return;
+ }
+
+ auto result = ExtractParams<GpgEncryptResult>(data_obj, 0);
+ auto result_analyse = GpgEncryptResultAnalyse(err, result);
+ result_analyse.Analyse();
+
+ process_result_analyse(edit_, info_board_, result_analyse);
+ this->slot_refresh_current_file_view();
+ });
});
- } else {
- auto p_keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
-
- // check key abilities
- for (const auto& key : *p_keys) {
- bool key_can_encrypt = key.IsHasActualEncryptionCapability();
-
- 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.GetUIDs()->front().GetUID()));
- return;
- }
- }
- process_operation(this, _("Encrypting"),
- [&](Thread::Task::DataObjectPtr) -> int {
- try {
- error = GpgFileOpera::EncryptFile(
- std::move(p_keys), path.toStdString(),
- out_path.toStdString(), result, _channel);
- } catch (const std::runtime_error& e) {
- if_error = true;
- }
- return 0;
- });
- }
-
- // remove xxx.tar and only left xxx.tar.gpg
- if (file_info.isDir()) {
- auto selected_dir_path = std::filesystem::path(path.toStdString());
- auto target_path = selected_dir_path.replace_extension(".tar");
- if (exists(target_path)) {
- std::filesystem::remove(target_path);
+ return;
+ }
+
+ auto p_keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
+
+ // check key abilities
+ for (const auto& key : *p_keys) {
+ bool const key_can_encrypt = key.IsHasActualEncryptionCapability();
+
+ if (!key_can_encrypt) {
+ QMessageBox::critical(
+ nullptr, tr("Invalid KeyPair"),
+ tr("The selected keypair cannot be used for encryption.") +
+ "<br/><br/>" + tr("For example the Following Key:") + " <br/>" +
+ key.GetUIDs()->front().GetUID());
+ return;
}
}
- if (!if_error) {
- auto resultAnalyse = GpgEncryptResultAnalyse(error, std::move(result));
- resultAnalyse.Analyse();
- process_result_analyse(edit_, info_board_, resultAnalyse);
- fileTreeView->update();
- } else {
- QMessageBox::critical(this, _("Error"),
- _("An error occurred during operation."));
+ CommonUtils::WaitForOpera(
+ this, tr("Archiving & Encrypting"), [=](const OperaWaitingHd& op_hd) {
+ GpgFileOpera::GetInstance().EncryptDirectory(
+ {p_keys->begin(), p_keys->end()}, path, !non_ascii_when_export,
+ out_path, [=](GpgError err, const DataObjectPtr& data_obj) {
+ // stop waiting
+ op_hd();
+
+ if (CheckGpgError(err) == GPG_ERR_USER_1 || data_obj == nullptr ||
+ !data_obj->Check<GpgEncryptResult>()) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unknown error occurred"));
+ return;
+ }
+
+ auto result = ExtractParams<GpgEncryptResult>(data_obj, 0);
+ auto result_analyse = GpgEncryptResultAnalyse(err, result);
+ result_analyse.Analyse();
+
+ process_result_analyse(edit_, info_board_, result_analyse);
+ this->slot_refresh_current_file_view();
+ });
+ });
+}
+
+void MainWindow::SlotFileDecrypt(const QString& path) {
+ auto check_result = TargetFilePreCheck(path, true);
+ if (!std::get<0>(check_result)) {
+ QMessageBox::critical(
+ this, tr("Error"),
+ tr("Cannot read from file: %1").arg(QFileInfo(path).fileName()));
return;
}
-}
-void MainWindow::SlotFileDecrypt() {
- auto fileTreeView = edit_->SlotCurPageFileTreeView();
- auto path = fileTreeView->GetSelected();
+ auto out_path = SetExtensionOfOutputFile(path, kDECRYPT, true);
+ if (QFileInfo(out_path).exists()) {
+ auto ret = QMessageBox::warning(
+ this, tr("Warning"),
+ tr("The target file already exists, do you need to overwrite it?"),
+ QMessageBox::Ok | QMessageBox::Cancel);
- if (!path_pre_check(this, path)) return;
+ if (ret == QMessageBox::Cancel) return;
+ }
+
+ check_result = TargetFilePreCheck(out_path, false);
+ if (!std::get<0>(check_result)) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Cannot write to file: %1").arg(out_path));
+ return;
+ }
-#ifdef WINDOWS
- std::filesystem::path out_path = path.toStdU16String();
-#else
- std::filesystem::path out_path = path.toStdString();
-#endif
+ CommonUtils::WaitForOpera(
+ this, tr("Decrypting"), [=](const OperaWaitingHd& op_hd) {
+ GpgFileOpera::GetInstance().DecryptFile(
+ path, out_path, [=](GpgError err, const DataObjectPtr& data_obj) {
+ // stop waiting
+ op_hd();
- if (out_path.extension() == ".asc" || out_path.extension() == ".gpg") {
- out_path = out_path.parent_path() / out_path.stem();
- } else {
- out_path += ".out";
+ if (CheckGpgError(err) == GPG_ERR_USER_1 || data_obj == nullptr ||
+ !data_obj->Check<GpgDecryptResult>()) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unknown error occurred"));
+ return;
+ }
+
+ auto result = ExtractParams<GpgDecryptResult>(data_obj, 0);
+ auto result_analyse = GpgDecryptResultAnalyse(err, result);
+ result_analyse.Analyse();
+
+ process_result_analyse(edit_, info_board_, result_analyse);
+ this->slot_refresh_current_file_view();
+ });
+ });
+}
+
+void MainWindow::SlotArchiveDecrypt(const QString& path) {
+ auto check_result = TargetFilePreCheck(path, true);
+ if (!std::get<0>(check_result)) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Cannot read from file: %1").arg(path));
+ return;
}
- if (exists(out_path)) {
+ auto out_path = SetExtensionOfOutputFileForArchive(path, kDECRYPT, true);
+ if (QFileInfo(out_path).exists()) {
auto ret = QMessageBox::warning(
- this, _("Warning"),
- _("The target file already exists, do you need to overwrite it?"),
+ this, tr("Warning"),
+ tr("The target file already exists, do you need to overwrite it?"),
QMessageBox::Ok | QMessageBox::Cancel);
if (ret == QMessageBox::Cancel) return;
}
- GpgDecrResult result = nullptr;
- gpgme_error_t error;
- bool if_error = false;
- process_operation(this, _("Decrypting"),
- [&](Thread::Task::DataObjectPtr) -> int {
- try {
- error = GpgFileOpera::DecryptFile(
- path.toStdString(), out_path.u8string(), result);
- } catch (const std::runtime_error& e) {
- if_error = true;
- }
- return 0;
- });
-
- if (!if_error) {
- auto resultAnalyse = GpgDecryptResultAnalyse(error, std::move(result));
- resultAnalyse.Analyse();
- process_result_analyse(edit_, info_board_, resultAnalyse);
-
- fileTreeView->update();
- } else {
- QMessageBox::critical(this, _("Error"),
- _("An error occurred during operation."));
+ check_result = TargetFilePreCheck(out_path, false);
+ if (!std::get<0>(check_result)) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Cannot write to file: %1").arg(out_path));
return;
}
- // extract the tarball
- if (out_path.extension() == ".tar" && exists(out_path)) {
- bool ret = QMessageBox::information(
- this, _("Decrypting"),
- _("Do you want to extract and delete the decrypted tarball?"),
- QMessageBox::Ok | QMessageBox::Cancel);
- if (ret) {
- if (process_tarball_into_directory(this, out_path)) {
- QMessageBox::information(this, _("Decrypting"),
- _("Extracting tarball succeeded."));
- // remove tarball
- std::filesystem::remove(out_path);
- } else {
- QMessageBox::critical(this, _("Decrypting"),
- _("Extracting tarball failed."));
- }
- }
- }
-}
+ CommonUtils::WaitForOpera(
+ this, tr("Decrypting & Extrating"), [=](const OperaWaitingHd& op_hd) {
+ GpgFileOpera::GetInstance().DecryptArchive(
+ path, out_path, [=](GpgError err, const DataObjectPtr& data_obj) {
+ // stop waiting
+ op_hd();
-void MainWindow::SlotFileSign() {
- auto fileTreeView = edit_->SlotCurPageFileTreeView();
- auto path = fileTreeView->GetSelected();
+ if (CheckGpgError(err) == GPG_ERR_USER_1 || data_obj == nullptr ||
+ !data_obj->Check<GpgDecryptResult>()) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unknown error occurred"));
+ return;
+ }
- if (!path_pre_check(this, path)) return;
+ auto result = ExtractParams<GpgDecryptResult>(data_obj, 0);
+ auto result_analyse = GpgDecryptResultAnalyse(err, result);
+ result_analyse.Analyse();
+
+ process_result_analyse(edit_, info_board_, result_analyse);
+ this->slot_refresh_current_file_view();
+ });
+ });
+}
+
+void MainWindow::SlotFileSign(const QString& path) {
+ auto check_result = TargetFilePreCheck(path, true);
+ if (!std::get<0>(check_result)) {
+ QMessageBox::critical(
+ this, tr("Error"),
+ tr("Cannot read from file: %1").arg(QFileInfo(path).fileName()));
+ return;
+ }
auto key_ids = m_key_list_->GetChecked();
auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
if (keys->empty()) {
QMessageBox::critical(
- this, _("No Key Checked"),
- _("Please check the key in the key toolbox on the right."));
+ this, tr("No Key Checked"),
+ tr("Please check the key in the key toolbox on the right."));
return;
}
for (const auto& key : *keys) {
if (!key.IsHasActualSigningCapability()) {
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.GetUIDs()->front().GetUID()));
+ this, tr("Invalid Operation"),
+ tr("The selected key contains a key that does not actually "
+ "have a sign usage.") +
+ "<br/><br/>" + tr("for example the Following Key:") + " <br/>" +
+ key.GetUIDs()->front().GetUID());
return;
}
}
- bool non_ascii_when_export =
- GlobalSettingStation::GetInstance().LookupSettings(
- "general.non_ascii_when_export", true);
-
- auto _channel = GPGFRONTEND_DEFAULT_CHANNEL;
- auto _extension = ".asc";
- if (non_ascii_when_export) {
- _channel = GPGFRONTEND_NON_ASCII_CHANNEL;
- _extension = ".sig";
- }
-
-#ifdef WINDOWS
- std::filesystem::path in_path = path.toStdU16String();
-#else
- std::filesystem::path in_path = path.toStdString();
-#endif
+ bool const non_ascii_when_export =
+ GlobalSettingStation::GetInstance()
+ .GetSettings()
+ .value("basic/non_ascii_when_export", true)
+ .toBool();
+ auto sig_file_path =
+ SetExtensionOfOutputFile(path, kSIGN, !non_ascii_when_export);
- auto sig_file_path = in_path;
- sig_file_path += _extension;
- if (exists(sig_file_path)) {
- auto ret = QMessageBox::warning(
- this, _("Warning"),
- QString(_("The signature file \"%1\" exists, "
- "do you need to overwrite it?"))
- .arg(sig_file_path.filename().u8string().c_str()),
- QMessageBox::Ok | QMessageBox::Cancel);
+ if (QFileInfo(sig_file_path).exists()) {
+ auto ret = QMessageBox::warning(this, tr("Warning"),
+ tr("The signature file \"%1\" exists, "
+ "do you need to overwrite it?")
+ .arg(sig_file_path),
+ QMessageBox::Ok | QMessageBox::Cancel);
if (ret == QMessageBox::Cancel) return;
}
- GpgSignResult result = nullptr;
- gpgme_error_t error;
- bool if_error = false;
-
- process_operation(
- this, _("Signing"), [&](Thread::Task::DataObjectPtr) -> int {
- try {
- error = GpgFileOpera::SignFile(std::move(keys), in_path.u8string(),
- sig_file_path.u8string(), result,
- _channel);
- } catch (const std::runtime_error& e) {
- if_error = true;
- }
- return 0;
+ CommonUtils::WaitForOpera(
+ this, tr("Signing"), [=](const OperaWaitingHd& op_hd) {
+ GpgFileOpera::GetInstance().SignFile(
+ {keys->begin(), keys->end()}, path, !non_ascii_when_export,
+ sig_file_path, [=](GpgError err, const DataObjectPtr& data_obj) {
+ // stop waiting
+ op_hd();
+
+ if (CheckGpgError(err) == GPG_ERR_USER_1 || data_obj == nullptr ||
+ !data_obj->Check<GpgSignResult>()) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unknown error occurred"));
+ return;
+ }
+
+ auto result = ExtractParams<GpgSignResult>(data_obj, 0);
+ auto result_analyse = GpgSignResultAnalyse(err, result);
+ result_analyse.Analyse();
+
+ process_result_analyse(edit_, info_board_, result_analyse);
+ this->slot_refresh_current_file_view();
+ });
});
+}
- if (!if_error) {
- auto resultAnalyse = GpgSignResultAnalyse(error, std::move(result));
- resultAnalyse.Analyse();
- process_result_analyse(edit_, info_board_, resultAnalyse);
+void MainWindow::SlotFileVerify(const QString& path) {
+ auto check_result = TargetFilePreCheck(path, true);
+ if (!std::get<0>(check_result)) {
+ QMessageBox::critical(
+ this, tr("Error"),
+ tr("Cannot read from file: %1").arg(QFileInfo(path).fileName()));
+ return;
+ }
- fileTreeView->update();
+ auto file_info = QFileInfo(path);
+ QString sign_file_path = path;
+ QString data_file_path;
+ bool const prossible_singleton_target =
+ file_info.suffix() == "gpg" || file_info.suffix() == "pgp";
+ if (prossible_singleton_target) {
+ swap(data_file_path, sign_file_path);
} else {
- QMessageBox::critical(this, _("Error"),
- _("An error occurred during operation."));
- return;
+ data_file_path = file_info.path() + "/" + file_info.baseName();
}
- fileTreeView->update();
-}
+ auto data_file_info = QFileInfo(data_file_path);
+ if (!prossible_singleton_target && !data_file_info.exists()) {
+ bool ok;
+ QString const text = QInputDialog::getText(
+ this, tr("File to be Verified"),
+ tr("Please provide An ABSOLUTE Path \n"
+ "If Data And Signature is COMBINED within a single file, "
+ "KEEP THIS EMPTY: "),
+ QLineEdit::Normal, data_file_path, &ok);
-void MainWindow::SlotFileVerify() {
- auto fileTreeView = edit_->SlotCurPageFileTreeView();
- auto path = fileTreeView->GetSelected();
+ if (!ok) return;
-#ifdef WINDOWS
- std::filesystem::path in_path = path.toStdU16String();
-#else
- std::filesystem::path in_path = path.toStdString();
-#endif
+ data_file_path = text.isEmpty() ? path : text;
+ }
- std::filesystem::path sign_file_path = in_path, data_file_path;
+ if (!data_file_info.isFile() ||
+ (!sign_file_path.isEmpty() && !QFileInfo(sign_file_path).isFile())) {
+ QMessageBox::critical(
+ this, tr("Error"),
+ tr("Please select the appropriate origin file or signature file. "
+ "Ensure that both are in this directory."));
+ return;
+ }
- bool non_ascii_when_export =
- GlobalSettingStation::GetInstance().LookupSettings(
- "general.non_ascii_when_export", true);
+ GF_UI_LOG_DEBUG("verification data file path: {}", data_file_path);
+ GF_UI_LOG_DEBUG("verification signature file path: {}", sign_file_path);
+
+ CommonUtils::WaitForOpera(
+ this, tr("Verifying"), [=](const OperaWaitingHd& op_hd) {
+ GpgFileOpera::GetInstance().VerifyFile(
+ data_file_path, sign_file_path,
+ [=](GpgError err, const DataObjectPtr& data_obj) {
+ // stop waiting
+ op_hd();
+
+ if (CheckGpgError(err) == GPG_ERR_USER_1 || data_obj == nullptr ||
+ !data_obj->Check<GpgVerifyResult>()) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unknown error occurred"));
+ return;
+ }
+
+ auto result = ExtractParams<GpgVerifyResult>(data_obj, 0);
+ auto result_analyse = GpgVerifyResultAnalyse(err, result);
+ result_analyse.Analyse();
+
+ process_result_analyse(edit_, info_board_, result_analyse);
+ if (result_analyse.GetStatus() == -2) {
+ import_unknown_key_from_keyserver(this, result_analyse);
+ }
+ if (result_analyse.GetStatus() >= 0) {
+ show_verify_details(this, info_board_, err, result);
+ }
+
+ this->slot_refresh_current_file_view();
+ });
+ });
+}
- auto _channel = GPGFRONTEND_DEFAULT_CHANNEL;
- if (non_ascii_when_export) {
- _channel = GPGFRONTEND_NON_ASCII_CHANNEL;
+void MainWindow::SlotFileEncryptSign(const QString& path) {
+ auto check_result = TargetFilePreCheck(path, true);
+ if (!std::get<0>(check_result)) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Cannot read from file: %1").arg(path));
+ return;
}
- if (in_path.extension() == ".gpg") {
- swap(data_file_path, sign_file_path);
- } else if (in_path.extension() == ".sig" || in_path.extension() == ".asc") {
- data_file_path = sign_file_path.parent_path() / sign_file_path.stem();
+ // check selected keys
+ auto key_ids = m_key_list_->GetChecked();
+ auto p_keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
+
+ if (p_keys->empty()) {
+ QMessageBox::critical(
+ this, tr("No Key Checked"),
+ tr("Please check the key in the key toolbox on the right."));
+ return;
}
- SPDLOG_DEBUG("sign_file_path: {} {}", sign_file_path.u8string(),
- sign_file_path.extension().u8string());
+ // check key abilities
+ for (const auto& key : *p_keys) {
+ bool const key_can_encrypt = key.IsHasActualEncryptionCapability();
- if (in_path.extension() != ".gpg") {
- bool ok;
- QString text = QInputDialog::getText(
- this, _("Origin file to verify"), _("Filepath"), QLineEdit::Normal,
- data_file_path.u8string().c_str(), &ok);
- if (ok && !text.isEmpty()) {
- data_file_path = text.toStdString();
- } else {
+ if (!key_can_encrypt) {
+ QMessageBox::critical(
+ nullptr, tr("Invalid KeyPair"),
+ tr("The selected keypair cannot be used for encryption.") +
+ "<br/><br/>" + tr("For example the Following Key:") + " <br/>" +
+ key.GetUIDs()->front().GetUID());
return;
}
}
- if (!is_regular_file(data_file_path) ||
- (!sign_file_path.empty() && !is_regular_file(sign_file_path))) {
- QMessageBox::critical(
- this, _("Error"),
- _("Please select the appropriate origin file or signature file. "
- "Ensure that both are in this directory."));
+ bool const non_ascii_when_export =
+ GlobalSettingStation::GetInstance()
+ .GetSettings()
+ .value("basic/non_ascii_when_export", true)
+ .toBool();
+ auto out_path =
+ SetExtensionOfOutputFile(path, kENCRYPT_SIGN, !non_ascii_when_export);
+
+ check_result = TargetFilePreCheck(out_path, false);
+ if (!std::get<0>(check_result)) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Cannot write to file: %1").arg(out_path));
return;
}
- SPDLOG_DEBUG("data path: {}", data_file_path.u8string());
- SPDLOG_DEBUG("sign path: {}", sign_file_path.u8string());
-
- GpgVerifyResult result = nullptr;
- gpgme_error_t error;
- bool if_error = false;
- process_operation(
- this, _("Verifying"), [&](Thread::Task::DataObjectPtr) -> int {
- try {
- error = GpgFileOpera::VerifyFile(data_file_path.u8string(),
- sign_file_path.u8string(), result,
- _channel);
- } catch (const std::runtime_error& e) {
- if_error = true;
- }
- return 0;
- });
+ if (QFile::exists(out_path)) {
+ auto ret = QMessageBox::warning(
+ this, tr("Warning"),
+ tr("The target file already exists, do you need to overwrite it?"),
+ QMessageBox::Ok | QMessageBox::Cancel);
- if (!if_error) {
- auto result_analyse = GpgVerifyResultAnalyse(error, result);
- result_analyse.Analyse();
- process_result_analyse(edit_, info_board_, result_analyse);
+ if (ret == QMessageBox::Cancel) return;
+ }
- if (result_analyse.GetStatus() == -2)
- import_unknown_key_from_keyserver(this, result_analyse);
+ auto* signers_picker = new SignersPicker(this);
+ QEventLoop loop;
+ connect(signers_picker, &SignersPicker::finished, &loop, &QEventLoop::quit);
+ loop.exec();
- if (result_analyse.GetStatus() >= 0)
- show_verify_details(this, info_board_, error, result);
+ // return when canceled
+ if (!signers_picker->GetStatus()) return;
- fileTreeView->update();
- } else {
- QMessageBox::critical(this, _("Error"),
- _("An error occurred during operation."));
- return;
- }
-}
+ auto signer_key_ids = signers_picker->GetCheckedSigners();
+ auto p_signer_keys = GpgKeyGetter::GetInstance().GetKeys(signer_key_ids);
-void MainWindow::SlotFileEncryptSign() {
- auto fileTreeView = edit_->SlotCurPageFileTreeView();
- auto path = fileTreeView->GetSelected();
+ CommonUtils::WaitForOpera(
+ this, tr("Encrypting and Signing"), [=](const OperaWaitingHd& op_hd) {
+ GpgFileOpera::GetInstance().EncryptSignFile(
+ {p_keys->begin(), p_keys->end()},
+ {p_signer_keys->begin(), p_signer_keys->end()}, path,
+ !non_ascii_when_export, out_path,
+ [=](GpgError err, const DataObjectPtr& data_obj) {
+ // stop waiting
+ op_hd();
+
+ if (CheckGpgError(err) == GPG_ERR_USER_1 || data_obj == nullptr ||
+ !data_obj->Check<GpgEncryptResult, GpgSignResult>()) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unknown error occurred"));
+ return;
+ }
+ auto encrypt_result =
+ ExtractParams<GpgEncryptResult>(data_obj, 0);
+ auto sign_result = ExtractParams<GpgSignResult>(data_obj, 1);
+
+ auto encrypt_result_analyse =
+ GpgEncryptResultAnalyse(err, encrypt_result);
+ encrypt_result_analyse.Analyse();
+
+ auto sign_result_analyse = GpgSignResultAnalyse(err, sign_result);
+ sign_result_analyse.Analyse();
+
+ process_result_analyse(edit_, info_board_, encrypt_result_analyse,
+ sign_result_analyse);
+
+ this->slot_refresh_current_file_view();
+ });
+ });
+}
- if (!path_pre_check(this, path)) return;
+void MainWindow::SlotDirectoryEncryptSign(const QString& path) {
+ auto check_result = TargetFilePreCheck(path, true);
+ if (!std::get<0>(check_result)) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Cannot read from file: %1").arg(path));
+ return;
+ }
// check selected keys
auto key_ids = m_key_list_->GetChecked();
@@ -547,205 +639,228 @@ void MainWindow::SlotFileEncryptSign() {
if (p_keys->empty()) {
QMessageBox::critical(
- this, _("No Key Checked"),
- _("Please check the key in the key toolbox on the right."));
+ this, tr("No Key Checked"),
+ tr("Please check the key in the key toolbox on the right."));
return;
}
// check key abilities
for (const auto& key : *p_keys) {
- bool key_can_encrypt = key.IsHasActualEncryptionCapability();
+ bool const key_can_encrypt = key.IsHasActualEncryptionCapability();
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.GetUIDs()->front().GetUID()));
+ nullptr, tr("Invalid KeyPair"),
+ tr("The selected keypair cannot be used for encryption.") +
+ "<br/><br/>" + tr("For example the Following Key:") + " <br/>" +
+ key.GetUIDs()->front().GetUID());
return;
}
}
- bool non_ascii_when_export =
- GlobalSettingStation::GetInstance().LookupSettings(
- "general.non_ascii_when_export", true);
-
- // get file info
- QFileInfo file_info(path);
-
- if (file_info.isDir()) {
- path = path + (file_info.isDir() ? ".tar" : "");
- }
+ bool const non_ascii_when_export =
+ GlobalSettingStation::GetInstance()
+ .GetSettings()
+ .value("basic/non_ascii_when_export", true)
+ .toBool();
+ auto out_path = SetExtensionOfOutputFileForArchive(path, kENCRYPT_SIGN,
+ !non_ascii_when_export);
- auto _channel = GPGFRONTEND_DEFAULT_CHANNEL;
- auto _extension = ".asc";
- if (non_ascii_when_export || file_info.isDir()) {
- _channel = GPGFRONTEND_NON_ASCII_CHANNEL;
- _extension = ".gpg";
+ check_result = TargetFilePreCheck(out_path, false);
+ if (!std::get<0>(check_result)) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Cannot write to file: %1").arg(out_path));
+ return;
}
- auto out_path = path + _extension;
-
if (QFile::exists(out_path)) {
auto ret = QMessageBox::warning(
- this, _("Warning"),
- _("The target file already exists, do you need to overwrite it?"),
+ this, tr("Warning"),
+ tr("The target file already exists, do you need to overwrite it?"),
QMessageBox::Ok | QMessageBox::Cancel);
if (ret == QMessageBox::Cancel) return;
}
- auto signersPicker = new SignersPicker(this);
+ auto* signers_picker = new SignersPicker(this);
QEventLoop loop;
- connect(signersPicker, &SignersPicker::finished, &loop, &QEventLoop::quit);
+ connect(signers_picker, &SignersPicker::finished, &loop, &QEventLoop::quit);
loop.exec();
// return when canceled
- if (!signersPicker->GetStatus()) return;
+ if (!signers_picker->GetStatus()) return;
- auto signer_key_ids = signersPicker->GetCheckedSigners();
+ auto signer_key_ids = signers_picker->GetCheckedSigners();
auto p_signer_keys = GpgKeyGetter::GetInstance().GetKeys(signer_key_ids);
- // convert directory into tarball
- if (file_info.isDir()) {
- // stop if the process making tarball failed
- if (!process_directory_into_tarball(this, path)) {
- QMessageBox::critical(this, _("Error"),
- _("Unable to convert the folder into tarball."));
- return;
- }
- }
-
- GpgEncrResult encr_result = nullptr;
- GpgSignResult sign_result = nullptr;
-
- gpgme_error_t error;
- bool if_error = false;
-
- process_operation(this, _("Encrypting and Signing"),
- [&](Thread::Task::DataObjectPtr) -> int {
- try {
- error = GpgFileOpera::EncryptSignFile(
- std::move(p_keys), std::move(p_signer_keys),
- path.toStdString(), out_path.toStdString(),
- encr_result, sign_result, _channel);
- } catch (const std::runtime_error& e) {
- if_error = true;
- }
- return 0;
- });
+ CommonUtils::WaitForOpera(
+ this, tr("Archiving & Encrypting & Signing"),
+ [=](const OperaWaitingHd& op_hd) {
+ GpgFileOpera::GetInstance().EncryptSignDirectory(
+ {p_keys->begin(), p_keys->end()},
+ {p_signer_keys->begin(), p_signer_keys->end()}, path,
+ !non_ascii_when_export, out_path,
+ [=](GpgError err, const DataObjectPtr& data_obj) {
+ // stop waiting
+ op_hd();
+
+ if (CheckGpgError(err) == GPG_ERR_USER_1 || data_obj == nullptr ||
+ !data_obj->Check<GpgEncryptResult, GpgSignResult>()) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unknown error occurred"));
+ return;
+ }
+ auto encrypt_result =
+ ExtractParams<GpgEncryptResult>(data_obj, 0);
+ auto sign_result = ExtractParams<GpgSignResult>(data_obj, 1);
+
+ auto encrypt_result_analyse =
+ GpgEncryptResultAnalyse(err, encrypt_result);
+ encrypt_result_analyse.Analyse();
+
+ auto sign_result_analyse = GpgSignResultAnalyse(err, sign_result);
+ sign_result_analyse.Analyse();
+
+ process_result_analyse(edit_, info_board_, encrypt_result_analyse,
+ sign_result_analyse);
+
+ this->slot_refresh_current_file_view();
+ });
+ });
+}
- if (!if_error) {
- auto encrypt_result =
- GpgEncryptResultAnalyse(error, std::move(encr_result));
- auto sign_res = GpgSignResultAnalyse(error, std::move(sign_result));
- encrypt_result.Analyse();
- sign_res.Analyse();
- process_result_analyse(edit_, info_board_, encrypt_result, sign_res);
+void MainWindow::SlotFileDecryptVerify(const QString& path) {
+ auto check_result = TargetFilePreCheck(path, true);
+ if (!std::get<0>(check_result)) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Cannot read from file: %1").arg(path));
+ return;
+ }
- fileTreeView->update();
+ auto out_path = SetExtensionOfOutputFile(path, kDECRYPT_VERIFY, true);
- } else {
- QMessageBox::critical(this, _("Error"),
- _("An error occurred during operation."));
+ check_result = TargetFilePreCheck(out_path, false);
+ if (!std::get<0>(check_result)) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Cannot write to file: %1").arg(out_path));
return;
}
- // remove xxx.tar and only left xxx.tar.gpg
- if (file_info.isDir()) {
- auto selected_dir_path = std::filesystem::path(path.toStdString());
- auto target_path = selected_dir_path.replace_extension(".tar");
- if (exists(target_path)) {
- std::filesystem::remove(target_path);
- }
+ if (QFile::exists(out_path)) {
+ auto ret = QMessageBox::warning(this, tr("Warning"),
+ tr("The output file %1 already exists, do "
+ "you need to overwrite it?")
+ .arg(out_path),
+ QMessageBox::Ok | QMessageBox::Cancel);
+
+ if (ret == QMessageBox::Cancel) return;
}
-}
-void MainWindow::SlotFileDecryptVerify() {
- auto fileTreeView = edit_->SlotCurPageFileTreeView();
- auto path = fileTreeView->GetSelected();
+ CommonUtils::WaitForOpera(
+ this, tr("Decrypting and Verifying"), [=](const OperaWaitingHd& op_hd) {
+ GpgFileOpera::GetInstance().DecryptVerifyFile(
+ path, out_path, [=](GpgError err, const DataObjectPtr& data_obj) {
+ // stop waiting
+ op_hd();
+
+ if (CheckGpgError(err) == GPG_ERR_USER_1 || data_obj == nullptr ||
+ !data_obj->Check<GpgDecryptResult, GpgVerifyResult>()) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unknown error occurred"));
+ return;
+ }
+ auto decrypt_result =
+ ExtractParams<GpgDecryptResult>(data_obj, 0);
+ auto verify_result = ExtractParams<GpgVerifyResult>(data_obj, 1);
+
+ auto decrypt_result_analyse =
+ GpgDecryptResultAnalyse(err, decrypt_result);
+ decrypt_result_analyse.Analyse();
+
+ auto verify_result_analyse =
+ GpgVerifyResultAnalyse(err, verify_result);
+ verify_result_analyse.Analyse();
+
+ process_result_analyse(edit_, info_board_, decrypt_result_analyse,
+ verify_result_analyse);
+ if (verify_result_analyse.GetStatus() == -2) {
+ import_unknown_key_from_keyserver(this, verify_result_analyse);
+ }
+ if (verify_result_analyse.GetStatus() >= 0) {
+ show_verify_details(this, info_board_, err, verify_result);
+ }
+
+ this->slot_refresh_current_file_view();
+ });
+ });
+}
- if (!path_pre_check(this, path)) return;
+void MainWindow::SlotArchiveDecryptVerify(const QString& path) {
+ auto check_result = TargetFilePreCheck(path, true);
+ if (!std::get<0>(check_result)) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Cannot read from file: %1").arg(path));
+ return;
+ }
-#ifdef WINDOWS
- std::filesystem::path in_path = path.toStdU16String();
-#else
- std::filesystem::path in_path = path.toStdString();
-#endif
+ auto out_path =
+ SetExtensionOfOutputFileForArchive(path, kDECRYPT_VERIFY, true);
- std::filesystem::path out_path = in_path;
- if (in_path.extension() == ".asc" || in_path.extension() == ".gpg") {
- out_path = in_path.parent_path() / out_path.stem();
- } else {
- out_path += ".out";
+ check_result = TargetFilePreCheck(out_path, false);
+ if (!std::get<0>(check_result)) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Cannot write to file: %1").arg(out_path));
+ return;
}
- SPDLOG_DEBUG("out path: {}", out_path.u8string());
- if (QFile::exists(out_path.u8string().c_str())) {
- auto ret =
- QMessageBox::warning(this, _("Warning"),
- QString(_("The output file %1 already exists, do "
- "you need to overwrite it?"))
- .arg(out_path.filename().u8string().c_str()),
- QMessageBox::Ok | QMessageBox::Cancel);
+ if (QFile::exists(out_path)) {
+ auto ret = QMessageBox::warning(this, tr("Warning"),
+ tr("The output file %1 already exists, do "
+ "you need to overwrite it?")
+ .arg(out_path),
+ QMessageBox::Ok | QMessageBox::Cancel);
if (ret == QMessageBox::Cancel) return;
}
- GpgDecrResult d_result = nullptr;
- GpgVerifyResult v_result = nullptr;
- gpgme_error_t error;
- bool if_error = false;
- process_operation(this, _("Decrypting and Verifying"),
- [&](Thread::Task::DataObjectPtr) -> int {
- try {
- error = GpgFileOpera::DecryptVerifyFile(
- path.toStdString(), out_path.u8string(), d_result,
- v_result);
- } catch (const std::runtime_error& e) {
- if_error = true;
- }
- return 0;
- });
-
- if (!if_error) {
- auto decrypt_res = GpgDecryptResultAnalyse(error, std::move(d_result));
- auto verify_res = GpgVerifyResultAnalyse(error, v_result);
- decrypt_res.Analyse();
- verify_res.Analyse();
- process_result_analyse(edit_, info_board_, decrypt_res, verify_res);
-
- if (verify_res.GetStatus() == -2)
- import_unknown_key_from_keyserver(this, verify_res);
-
- if (verify_res.GetStatus() >= 0)
- show_verify_details(this, info_board_, error, v_result);
-
- fileTreeView->update();
- } else {
- QMessageBox::critical(this, _("Error"),
- _("An error occurred during operation."));
- return;
- }
-
- // extract the tarball
- if (out_path.extension() == ".tar" && exists(out_path)) {
- bool ret = QMessageBox::information(
- this, _("Decrypting"),
- _("Do you want to extract and delete the decrypted tarball?"),
- QMessageBox::Ok | QMessageBox::Cancel);
- if (ret) {
- if (process_tarball_into_directory(this, out_path)) {
- QMessageBox::information(this, _("Decrypting"),
- _("Extracting tarball succeeded."));
- // remove tarball
- std::filesystem::remove(out_path);
- } else {
- QMessageBox::critical(this, _("Decrypting"),
- _("Extracting tarball failed."));
- }
- }
- }
+ CommonUtils::WaitForOpera(
+ this, tr("Decrypting & Verifying & Extracting"),
+ [=](const OperaWaitingHd& op_hd) {
+ GpgFileOpera::GetInstance().DecryptVerifyArchive(
+ path, out_path, [=](GpgError err, const DataObjectPtr& data_obj) {
+ // stop waiting
+ op_hd();
+
+ if (CheckGpgError(err) == GPG_ERR_USER_1 || data_obj == nullptr ||
+ !data_obj->Check<GpgDecryptResult, GpgVerifyResult>()) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unknown error occurred"));
+ return;
+ }
+ auto decrypt_result =
+ ExtractParams<GpgDecryptResult>(data_obj, 0);
+ auto verify_result = ExtractParams<GpgVerifyResult>(data_obj, 1);
+
+ auto decrypt_result_analyse =
+ GpgDecryptResultAnalyse(err, decrypt_result);
+ decrypt_result_analyse.Analyse();
+
+ auto verify_result_analyse =
+ GpgVerifyResultAnalyse(err, verify_result);
+ verify_result_analyse.Analyse();
+
+ process_result_analyse(edit_, info_board_, decrypt_result_analyse,
+ verify_result_analyse);
+ if (verify_result_analyse.GetStatus() == -2) {
+ import_unknown_key_from_keyserver(this, verify_result_analyse);
+ }
+ if (verify_result_analyse.GetStatus() >= 0) {
+ show_verify_details(this, info_board_, err, verify_result);
+ }
+
+ this->slot_refresh_current_file_view();
+ });
+ });
}
} // namespace GpgFrontend::UI
diff --git a/src/ui/main_window/MainWindowGpgOperaFunction.cpp b/src/ui/main_window/MainWindowGpgOperaFunction.cpp
new file mode 100644
index 00000000..ea9540bb
--- /dev/null
+++ b/src/ui/main_window/MainWindowGpgOperaFunction.cpp
@@ -0,0 +1,396 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "MainWindow.h"
+#include "core/function/gpg/GpgBasicOperator.h"
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/function/result_analyse/GpgDecryptResultAnalyse.h"
+#include "core/function/result_analyse/GpgEncryptResultAnalyse.h"
+#include "core/function/result_analyse/GpgSignResultAnalyse.h"
+#include "core/function/result_analyse/GpgVerifyResultAnalyse.h"
+#include "core/model/DataObject.h"
+#include "core/model/GpgEncryptResult.h"
+#include "core/utils/GpgUtils.h"
+#include "ui/UserInterfaceUtils.h"
+#include "ui/dialog/SignersPicker.h"
+
+namespace GpgFrontend::UI {
+
+void MainWindow::SlotEncrypt() {
+ if (edit_->SlotCurPageTextEdit() == nullptr) return;
+
+ auto key_ids = m_key_list_->GetChecked();
+
+ if (key_ids->empty()) {
+ // Symmetric Encrypt
+ auto ret = QMessageBox::information(
+ this, tr("Symmetric Encryption"),
+ tr("No Key Checked. Do you want to encrypt with a "
+ "symmetric cipher using a passphrase?"),
+ QMessageBox::Ok | QMessageBox::Cancel);
+
+ if (ret == QMessageBox::Cancel) return;
+
+ auto buffer = GFBuffer(edit_->CurTextPage()->GetTextPage()->toPlainText());
+ CommonUtils::WaitForOpera(
+ this, tr("Symmetrically Encrypting"),
+ [this, buffer](const OperaWaitingHd& op_hd) {
+ GpgFrontend::GpgBasicOperator::GetInstance().EncryptSymmetric(
+ buffer, true,
+ [this, op_hd](GpgError err, const DataObjectPtr& data_obj) {
+ // stop waiting
+ op_hd();
+
+ if (CheckGpgError(err) == GPG_ERR_USER_1 ||
+ data_obj == nullptr ||
+ !data_obj->Check<GpgEncryptResult, GFBuffer>()) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unknown error occurred"));
+ return;
+ }
+
+ auto result = ExtractParams<GpgEncryptResult>(data_obj, 0);
+ auto buffer = ExtractParams<GFBuffer>(data_obj, 1);
+
+ auto result_analyse = GpgEncryptResultAnalyse(err, result);
+ result_analyse.Analyse();
+ process_result_analyse(edit_, info_board_, result_analyse);
+
+ if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
+ edit_->SlotFillTextEditWithText(buffer.ConvertToQByteArray());
+ }
+ info_board_->ResetOptionActionsMenu();
+ });
+ });
+
+ return;
+ }
+
+ auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
+ for (const auto& key : *keys) {
+ if (!key.IsHasActualEncryptionCapability()) {
+ QMessageBox::information(
+ this, tr("Invalid Operation"),
+ tr("The selected key contains a key that does not actually have a "
+ "encrypt usage.") +
+ "<br/><br/>" + tr("For example the Following Key:") + " <br/>" +
+ key.GetUIDs()->front().GetUID());
+ return;
+ }
+ }
+
+ auto buffer = GFBuffer(edit_->CurTextPage()->GetTextPage()->toPlainText());
+ CommonUtils::WaitForOpera(
+ this, tr("Encrypting"),
+ [this, keys, buffer](const OperaWaitingHd& op_hd) {
+ GpgFrontend::GpgBasicOperator::GetInstance().Encrypt(
+ {keys->begin(), keys->end()}, buffer, true,
+ [this, op_hd](GpgError err, const DataObjectPtr& data_obj) {
+ // stop waiting
+ op_hd();
+
+ if (data_obj == nullptr ||
+ !data_obj->Check<GpgEncryptResult, GFBuffer>()) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unknown error occurred"));
+ return;
+ }
+
+ auto result = ExtractParams<GpgEncryptResult>(data_obj, 0);
+ auto buffer = ExtractParams<GFBuffer>(data_obj, 1);
+
+ auto result_analyse = GpgEncryptResultAnalyse(err, result);
+ result_analyse.Analyse();
+ process_result_analyse(edit_, info_board_, result_analyse);
+
+ if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
+ edit_->SlotFillTextEditWithText(buffer.ConvertToQByteArray());
+ }
+ info_board_->ResetOptionActionsMenu();
+ });
+ });
+}
+
+void MainWindow::SlotSign() {
+ if (edit_->SlotCurPageTextEdit() == nullptr) return;
+
+ auto key_ids = m_key_list_->GetPrivateChecked();
+ if (key_ids->empty()) {
+ QMessageBox::critical(
+ this, tr("No Key Checked"),
+ tr("Please check the key in the key toolbox on the right."));
+ return;
+ }
+
+ auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
+ for (const auto& key : *keys) {
+ if (!key.IsHasActualSigningCapability()) {
+ QMessageBox::information(
+ this, tr("Invalid Operation"),
+ tr("The selected key contains a key that does not actually have a "
+ "signature usage.") +
+ "<br/><br/>" + tr("For example the Following Key:") + "<br/>" +
+ key.GetUIDs()->front().GetUID());
+ return;
+ }
+ }
+
+ // set input buffer
+ auto buffer = GFBuffer(edit_->CurTextPage()->GetTextPage()->toPlainText());
+ CommonUtils::WaitForOpera(
+ this, tr("Signing"), [this, keys, buffer](const OperaWaitingHd& hd) {
+ GpgFrontend::GpgBasicOperator::GetInstance().Sign(
+ {keys->begin(), keys->end()}, buffer, GPGME_SIG_MODE_CLEAR, true,
+ [this, hd](GpgError err, const DataObjectPtr& data_obj) {
+ // stop waiting
+ hd();
+
+ if (CheckGpgError(err) == GPG_ERR_USER_1 || data_obj == nullptr ||
+ !data_obj->Check<GpgSignResult, GFBuffer>()) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unknown error occurred"));
+ return;
+ }
+ auto sign_result = ExtractParams<GpgSignResult>(data_obj, 0);
+ auto sign_out_buffer = ExtractParams<GFBuffer>(data_obj, 1);
+ auto result_analyse = GpgSignResultAnalyse(err, sign_result);
+ result_analyse.Analyse();
+ process_result_analyse(edit_, info_board_, result_analyse);
+
+ if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
+ edit_->SlotFillTextEditWithText(
+ sign_out_buffer.ConvertToQByteArray());
+ }
+ });
+ });
+}
+
+void MainWindow::SlotDecrypt() {
+ if (edit_->SlotCurPageTextEdit() == nullptr) return;
+
+ // data to transfer into task
+ auto buffer = GFBuffer(edit_->CurTextPage()->GetTextPage()->toPlainText());
+
+ CommonUtils::WaitForOpera(
+ this, tr("Decrypting"), [this, buffer](const OperaWaitingHd& hd) {
+ GpgFrontend::GpgBasicOperator::GetInstance().Decrypt(
+ buffer, [this, hd](GpgError err, const DataObjectPtr& data_obj) {
+ // stop waiting
+ hd();
+
+ if (CheckGpgError(err) == GPG_ERR_USER_1 || data_obj == nullptr ||
+ !data_obj->Check<GpgDecryptResult, GFBuffer>()) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unknown error occurred"));
+ return;
+ }
+ auto decrypt_result =
+ ExtractParams<GpgDecryptResult>(data_obj, 0);
+ auto out_buffer = ExtractParams<GFBuffer>(data_obj, 1);
+ auto result_analyse =
+ GpgDecryptResultAnalyse(err, decrypt_result);
+ result_analyse.Analyse();
+ process_result_analyse(edit_, info_board_, result_analyse);
+
+ if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
+ edit_->SlotFillTextEditWithText(
+ out_buffer.ConvertToQByteArray());
+ }
+ });
+ });
+}
+
+void MainWindow::SlotVerify() {
+ if (edit_->SlotCurPageTextEdit() == nullptr) return;
+
+ // set input buffer
+ auto buffer = GFBuffer(edit_->CurTextPage()->GetTextPage()->toPlainText());
+
+ CommonUtils::WaitForOpera(
+ this, tr("Verifying"), [this, buffer](const OperaWaitingHd& hd) {
+ GpgFrontend::GpgBasicOperator::GetInstance().Verify(
+ buffer, GFBuffer(),
+ [this, hd](GpgError err, const DataObjectPtr& data_obj) {
+ // stop waiting
+ hd();
+
+ if (CheckGpgError(err) == GPG_ERR_USER_1 || data_obj == nullptr ||
+ !data_obj->Check<GpgVerifyResult>()) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unknown error occurred"));
+ return;
+ }
+ auto verify_result = ExtractParams<GpgVerifyResult>(data_obj, 0);
+
+ // analyse result
+ auto result_analyse = GpgVerifyResultAnalyse(err, verify_result);
+ result_analyse.Analyse();
+ process_result_analyse(edit_, info_board_, result_analyse);
+ });
+ });
+}
+
+void MainWindow::SlotEncryptSign() {
+ if (edit_->SlotCurPageTextEdit() == nullptr) return;
+
+ auto key_ids = m_key_list_->GetChecked();
+
+ if (key_ids->empty()) {
+ QMessageBox::critical(
+ this, tr("No Key Checked"),
+ tr("Please check some key in the key toolbox on the right."));
+ return;
+ }
+
+ auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
+
+ for (const auto& key : *keys) {
+ bool key_can_encrypt = key.IsHasActualEncryptionCapability();
+
+ if (!key_can_encrypt) {
+ QMessageBox::critical(
+ this, tr("Invalid KeyPair"),
+ tr("The selected keypair cannot be used for encryption.") +
+ "<br/><br/>" + tr("For example the Following Key:") + " <br/>" +
+ key.GetUIDs()->front().GetUID());
+ return;
+ }
+ }
+
+ auto* signers_picker = new SignersPicker(this);
+ QEventLoop loop;
+ connect(signers_picker, &SignersPicker::finished, &loop, &QEventLoop::quit);
+ loop.exec();
+
+ // return when canceled
+ if (!signers_picker->GetStatus()) return;
+
+ auto signer_key_ids = signers_picker->GetCheckedSigners();
+ auto signer_keys = GpgKeyGetter::GetInstance().GetKeys(signer_key_ids);
+
+ for (const auto& key : *keys) {
+ GF_UI_LOG_DEBUG("keys {}", key.GetEmail());
+ }
+
+ for (const auto& signer : *signer_keys) {
+ GF_UI_LOG_DEBUG("signers {}", signer.GetEmail());
+ }
+
+ // data to transfer into task
+ auto buffer = GFBuffer(edit_->CurTextPage()->GetTextPage()->toPlainText());
+
+ CommonUtils::WaitForOpera(
+ this, tr("Encrypting and Signing"),
+ [this, keys, signer_keys, buffer](const OperaWaitingHd& hd) {
+ GpgFrontend::GpgBasicOperator::GetInstance().EncryptSign(
+ {keys->begin(), keys->end()},
+ {signer_keys->begin(), signer_keys->end()}, buffer, true,
+ [this, hd](GpgError err, const DataObjectPtr& data_obj) {
+ // stop waiting
+ hd();
+
+ if (CheckGpgError(err) == GPG_ERR_USER_1 || data_obj == nullptr ||
+ !data_obj
+ ->Check<GpgEncryptResult, GpgSignResult, GFBuffer>()) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unknown error occurred"));
+ return;
+ }
+ auto encrypt_result =
+ ExtractParams<GpgEncryptResult>(data_obj, 0);
+ auto sign_result = ExtractParams<GpgSignResult>(data_obj, 1);
+ auto out_buffer = ExtractParams<GFBuffer>(data_obj, 2);
+
+ // analyse result
+ auto encrypt_result_analyse =
+ GpgEncryptResultAnalyse(err, encrypt_result);
+ encrypt_result_analyse.Analyse();
+
+ auto sign_result_analyse = GpgSignResultAnalyse(err, sign_result);
+ sign_result_analyse.Analyse();
+
+ // show analyse result
+ process_result_analyse(edit_, info_board_, encrypt_result_analyse,
+ sign_result_analyse);
+
+ if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
+ edit_->SlotFillTextEditWithText(
+ out_buffer.ConvertToQByteArray());
+ }
+ });
+ });
+}
+
+void MainWindow::SlotDecryptVerify() {
+ if (edit_->SlotCurPageTextEdit() == nullptr) return;
+
+ // data to transfer into task
+ auto buffer = GFBuffer(edit_->CurTextPage()->GetTextPage()->toPlainText());
+
+ CommonUtils::WaitForOpera(
+ this, tr("Decrypting and Verifying"),
+ [this, buffer](const OperaWaitingHd& hd) {
+ GpgFrontend::GpgBasicOperator::GetInstance().DecryptVerify(
+ buffer, [this, hd](GpgError err, const DataObjectPtr& data_obj) {
+ // stop waiting
+ hd();
+
+ if (CheckGpgError(err) == GPG_ERR_USER_1 || data_obj == nullptr ||
+ !data_obj
+ ->Check<GpgDecryptResult, GpgVerifyResult, GFBuffer>()) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unknown error occurred"));
+ return;
+ }
+ auto decrypt_result =
+ ExtractParams<GpgDecryptResult>(data_obj, 0);
+ auto verify_result = ExtractParams<GpgVerifyResult>(data_obj, 1);
+ auto out_buffer = ExtractParams<GFBuffer>(data_obj, 2);
+
+ // analyse result
+ auto decrypt_result_analyse =
+ GpgDecryptResultAnalyse(err, decrypt_result);
+ decrypt_result_analyse.Analyse();
+
+ auto verify_result_analyse =
+ GpgVerifyResultAnalyse(err, verify_result);
+ verify_result_analyse.Analyse();
+
+ // show analyse result
+ process_result_analyse(edit_, info_board_, decrypt_result_analyse,
+ verify_result_analyse);
+
+ if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
+ edit_->SlotFillTextEditWithText(
+ out_buffer.ConvertToQByteArray());
+ }
+ });
+ });
+}
+
+} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/main_window/MainWindowSlotFunction.cpp b/src/ui/main_window/MainWindowSlotFunction.cpp
index 1adf2d4e..fe9aa0df 100644
--- a/src/ui/main_window/MainWindowSlotFunction.cpp
+++ b/src/ui/main_window/MainWindowSlotFunction.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,577 +20,28 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#include <boost/date_time/posix_time/posix_time.hpp>
-#include <boost/date_time/posix_time/posix_time_io.hpp>
-#include <memory>
-#include <string>
-#include <utility>
-
#include "MainWindow.h"
-#include "core/GpgConstants.h"
-#include "core/GpgContext.h"
#include "core/GpgModel.h"
-#include "core/function/gpg/GpgBasicOperator.h"
#include "core/function/gpg/GpgKeyGetter.h"
#include "core/function/gpg/GpgKeyImportExporter.h"
-#include "core/function/gpg/GpgKeyManager.h"
-#include "dialog/SignersPicker.h"
-#include "spdlog/spdlog.h"
+#include "core/module/ModuleManager.h"
+#include "core/typedef/GpgTypedef.h"
+#include "core/utils/CommonUtils.h"
+#include "core/utils/GpgUtils.h"
#include "ui/UserInterfaceUtils.h"
#include "ui/dialog/help/AboutDialog.h"
+#include "ui/dialog/import_export/KeyUploadDialog.h"
+#include "ui/dialog/keypair_details/KeyDetailsDialog.h"
+#include "ui/function/SetOwnerTrustLevel.h"
+#include "ui/widgets/FindWidget.h"
namespace GpgFrontend::UI {
-/**
- * Encrypt Entry(Text & File)
- */
-void MainWindow::slot_encrypt() {
- if (edit_->TabCount() == 0 || edit_->SlotCurPageTextEdit() == nullptr) {
- if (edit_->SlotCurPageFileTreeView() != nullptr) this->SlotFileEncrypt();
- return;
- }
-
- auto key_ids = m_key_list_->GetChecked();
-
- // data to transfer into task
- auto data_object = std::make_shared<Thread::Task::DataObject>();
-
- // set input buffer
- auto buffer =
- edit_->CurTextPage()->GetTextPage()->toPlainText().toStdString();
- data_object->AppendObject(std::move(buffer));
-
- // the callback function
- auto result_callback = [this](int rtn,
- Thread::Task::DataObjectPtr data_object) {
- if (!rtn) {
- if (data_object->GetObjectSize() != 3)
- throw std::runtime_error("Invalid data object size");
- auto error = data_object->PopObject<GpgError>();
- auto result = data_object->PopObject<GpgEncrResult>();
- auto tmp = data_object->PopObject<std::unique_ptr<ByteArray>>();
-
- auto resultAnalyse = GpgEncryptResultAnalyse(error, std::move(result));
- resultAnalyse.Analyse();
- process_result_analyse(edit_, info_board_, resultAnalyse);
-
- if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR)
- edit_->SlotFillTextEditWithText(QString::fromStdString(*tmp));
- info_board_->ResetOptionActionsMenu();
- } else {
- QMessageBox::critical(this, _("Error"),
- _("An error occurred during operation."));
- return;
- }
- };
-
- Thread::Task::TaskRunnable encrypt_runner = nullptr;
-
- std::string encrypt_type = "";
-
- if (key_ids->empty()) {
- // Symmetric Encrypt
- auto ret = QMessageBox::information(
- this, _("Symmetric Encryption"),
- _("No Key Checked. Do you want to encrypt with a "
- "symmetric cipher using a passphrase?"),
- QMessageBox::Ok | QMessageBox::Cancel);
-
- if (ret == QMessageBox::Cancel) return;
-
- encrypt_type = _("Symmetrically Encrypting");
- encrypt_runner = [](Thread::Task::DataObjectPtr data_object) -> int {
- if (data_object == nullptr || data_object->GetObjectSize() != 1)
- throw std::runtime_error("Invalid data object size");
- auto buffer = data_object->PopObject<std::string>();
- try {
- GpgEncrResult result = nullptr;
- auto tmp = std::make_unique<ByteArray>();
- GpgError error =
- GpgFrontend::GpgBasicOperator::GetInstance().EncryptSymmetric(
- buffer, tmp, result);
- data_object->AppendObject(std::move(tmp));
- data_object->AppendObject(std::move(result));
- data_object->AppendObject(std::move(error));
- } catch (const std::runtime_error& e) {
- return -1;
- }
- return 0;
- };
-
- } else {
- auto& key_getter = GpgFrontend::GpgKeyGetter::GetInstance();
- auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
- for (const auto& key : *keys) {
- if (!key.IsHasActualEncryptionCapability()) {
- 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.GetUIDs()->front().GetUID()));
- return;
- }
- }
-
- // push the keys into data object
- data_object->AppendObject(std::move(keys));
-
- // Asymmetric Encrypt
- encrypt_type = _("Encrypting");
- encrypt_runner = [](Thread::Task::DataObjectPtr data_object) -> int {
- // check the size of the data object
- if (data_object == nullptr || data_object->GetObjectSize() != 2)
- throw std::runtime_error("Invalid data object size");
-
- auto keys = data_object->PopObject<KeyListPtr>();
- auto buffer = data_object->PopObject<std::string>();
- try {
- GpgEncrResult result = nullptr;
- auto tmp = std::make_unique<ByteArray>();
- GpgError error = GpgFrontend::GpgBasicOperator::GetInstance().Encrypt(
- std::move(keys), buffer, tmp, result);
-
- data_object->AppendObject(std::move(tmp));
- data_object->AppendObject(std::move(result));
- data_object->AppendObject(std::move(error));
- } catch (const std::runtime_error& e) {
- return -1;
- }
- return 0;
- };
- }
- // Do the task
- process_operation(this, _("Encrypting"), std::move(encrypt_runner),
- std::move(result_callback), data_object);
-}
-
-void MainWindow::slot_sign() {
- if (edit_->TabCount() == 0 || edit_->SlotCurPageTextEdit() == nullptr) {
- if (edit_->SlotCurPageFileTreeView() != nullptr) this->SlotFileSign();
- return;
- }
-
- auto key_ids = m_key_list_->GetPrivateChecked();
-
- if (key_ids->empty()) {
- QMessageBox::critical(
- this, _("No Key Checked"),
- _("Please check the key in the key toolbox on the right."));
- return;
- }
-
- auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
- for (const auto& key : *keys) {
- if (!key.IsHasActualSigningCapability()) {
- 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.GetUIDs()->front().GetUID().c_str());
- return;
- }
- }
-
- // data to transfer into task
- auto data_object = std::make_shared<Thread::Task::DataObject>();
-
- // set input buffer
- auto buffer =
- edit_->CurTextPage()->GetTextPage()->toPlainText().toStdString();
- data_object->AppendObject(std::move(buffer));
-
- // push the keys into data object
- data_object->AppendObject(std::move(keys));
-
- auto sign_ruunner = [](Thread::Task::DataObjectPtr data_object) -> int {
- // check the size of the data object
- if (data_object == nullptr || data_object->GetObjectSize() != 2)
- throw std::runtime_error("Invalid data object size");
-
- auto keys = data_object->PopObject<KeyListPtr>();
- auto buffer = data_object->PopObject<std::string>();
- try {
- GpgSignResult result = nullptr;
- auto tmp = std::make_unique<ByteArray>();
- GpgError error = GpgFrontend::GpgBasicOperator::GetInstance().Sign(
- std::move(keys), buffer, tmp, GPGME_SIG_MODE_CLEAR, result);
- data_object->AppendObject(std::move(tmp));
- data_object->AppendObject(std::move(result));
- data_object->AppendObject(std::move(error));
- } catch (const std::runtime_error& e) {
- return -1;
- }
- return 0;
- };
-
- auto result_callback = [this](int rtn,
- Thread::Task::DataObjectPtr data_object) {
- if (!rtn) {
- if (data_object == nullptr || data_object->GetObjectSize() != 3)
- throw std::runtime_error("Invalid data object size");
- auto error = data_object->PopObject<GpgError>();
- auto result = data_object->PopObject<GpgSignResult>();
- auto tmp = data_object->PopObject<std::unique_ptr<ByteArray>>();
- auto resultAnalyse = GpgSignResultAnalyse(error, std::move(result));
- resultAnalyse.Analyse();
- process_result_analyse(edit_, info_board_, 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;
- }
- };
-
- process_operation(this, _("Signing"), std::move(sign_ruunner),
- std::move(result_callback), data_object);
-}
-
-void MainWindow::slot_decrypt() {
- if (edit_->TabCount() == 0 || edit_->SlotCurPageTextEdit() == nullptr) {
- if (edit_->SlotCurPageFileTreeView() != nullptr) this->SlotFileDecrypt();
- return;
- }
-
- QByteArray text = edit_->CurTextPage()->GetTextPage()->toPlainText().toUtf8();
-
- if (text.trimmed().startsWith(GpgConstants::GPG_FRONTEND_SHORT_CRYPTO_HEAD)) {
- QMessageBox::critical(
- this, _("Notice"),
- _("Short Crypto Text only supports Decrypt & Verify."));
- return;
- }
-
- // data to transfer into task
- auto data_object = std::make_shared<Thread::Task::DataObject>();
-
- // set input buffer
- auto buffer =
- edit_->CurTextPage()->GetTextPage()->toPlainText().toStdString();
- data_object->AppendObject(std::move(buffer));
-
- auto decrypt_runner = [](Thread::Task::DataObjectPtr data_object) -> int {
- // check the size of the data object
- if (data_object == nullptr || data_object->GetObjectSize() != 1)
- throw std::runtime_error("Invalid data object size");
-
- auto buffer = data_object->PopObject<std::string>();
- try {
- GpgDecrResult result = nullptr;
- auto decrypted = std::make_unique<ByteArray>();
- GpgError error = GpgFrontend::GpgBasicOperator::GetInstance().Decrypt(
- buffer, decrypted, result);
- data_object->AppendObject(std::move(decrypted));
- data_object->AppendObject(std::move(result));
- data_object->AppendObject(std::move(error));
- } catch (const std::runtime_error& e) {
- return -1;
- }
- return 0;
- };
-
- auto result_callback = [this](int rtn,
- Thread::Task::DataObjectPtr data_object) {
- if (!rtn) {
- if (data_object == nullptr || data_object->GetObjectSize() != 3)
- throw std::runtime_error("Invalid data object size");
- auto error = data_object->PopObject<GpgError>();
- auto result = data_object->PopObject<GpgDecrResult>();
- auto decrypted = data_object->PopObject<std::unique_ptr<ByteArray>>();
- auto resultAnalyse = GpgDecryptResultAnalyse(error, std::move(result));
- resultAnalyse.Analyse();
- process_result_analyse(edit_, info_board_, 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;
- }
- };
-
- process_operation(this, _("Decrypting"), std::move(decrypt_runner),
- std::move(result_callback), data_object);
-}
-
-void MainWindow::slot_verify() {
- if (edit_->TabCount() == 0 || edit_->SlotCurPageTextEdit() == nullptr) {
- if (edit_->SlotCurPageFileTreeView() != nullptr) this->SlotFileVerify();
- return;
- }
-
- // data to transfer into task
- auto data_object = std::make_shared<Thread::Task::DataObject>();
-
- // set input buffer
- auto buffer =
- edit_->CurTextPage()->GetTextPage()->toPlainText().toStdString();
- data_object->AppendObject(std::move(buffer));
-
- auto verify_runner = [](Thread::Task::DataObjectPtr data_object) -> int {
- // check the size of the data object
- if (data_object == nullptr || data_object->GetObjectSize() != 1)
- throw std::runtime_error("Invalid data object size");
-
- auto buffer = data_object->PopObject<std::string>();
-
- SPDLOG_DEBUG("verify buffer size: {}", buffer.size());
-
- try {
- GpgVerifyResult verify_result = nullptr;
- auto sig_buffer = std::unique_ptr<ByteArray>(nullptr);
- GpgError error = GpgFrontend::GpgBasicOperator::GetInstance().Verify(
- buffer, sig_buffer, verify_result);
-
- data_object->AppendObject(std::move(verify_result));
- data_object->AppendObject(std::move(error));
- } catch (const std::runtime_error& e) {
- return -1;
- }
- return 0;
- };
-
- auto result_callback = [this](int rtn,
- Thread::Task::DataObjectPtr data_object) {
- if (!rtn) {
- if (data_object == nullptr || data_object->GetObjectSize() != 2)
- throw std::runtime_error("Invalid data object size");
- auto error = data_object->PopObject<GpgError>();
- auto verify_result = data_object->PopObject<GpgVerifyResult>();
-
- auto result_analyse = GpgVerifyResultAnalyse(error, verify_result);
- result_analyse.Analyse();
- process_result_analyse(edit_, info_board_, result_analyse);
-
- if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR) {
- if (result_analyse.GetStatus() == -2)
- import_unknown_key_from_keyserver(this, result_analyse);
-
- if (result_analyse.GetStatus() >= 0)
- show_verify_details(this, info_board_, error, verify_result);
- }
- } else {
- QMessageBox::critical(this, _("Error"),
- _("An error occurred during operation."));
- return;
- }
- };
-
- process_operation(this, _("Verifying"), verify_runner, result_callback,
- data_object);
-}
-
-void MainWindow::slot_encrypt_sign() {
- if (edit_->TabCount() == 0 || edit_->SlotCurPageTextEdit() == nullptr) {
- if (edit_->SlotCurPageFileTreeView() != nullptr)
- this->SlotFileEncryptSign();
- return;
- }
-
- auto key_ids = m_key_list_->GetChecked();
-
- if (key_ids->empty()) {
- QMessageBox::critical(
- this, _("No Key Checked"),
- _("Please check some key in the key toolbox on the right."));
- return;
- }
-
- auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
-
- for (const auto& key : *keys) {
- bool key_can_encrypt = key.IsHasActualEncryptionCapability();
-
- if (!key_can_encrypt) {
- QMessageBox::critical(
- this, _("Invalid KeyPair"),
- QString(_("The selected keypair cannot be used for encryption.")) +
- "<br/><br/>" + _("For example the Following Key:") + " <br/>" +
- QString::fromStdString(key.GetUIDs()->front().GetUID()));
- return;
- }
- }
-
- auto signersPicker = new SignersPicker(this);
- QEventLoop loop;
- connect(signersPicker, &SignersPicker::finished, &loop, &QEventLoop::quit);
- loop.exec();
-
- // return when canceled
- if (!signersPicker->GetStatus()) return;
-
- auto signer_key_ids = signersPicker->GetCheckedSigners();
- auto signer_keys = GpgKeyGetter::GetInstance().GetKeys(signer_key_ids);
-
- for (const auto& key : *keys) {
- SPDLOG_DEBUG("keys {}", key.GetEmail());
- }
-
- for (const auto& signer : *signer_keys) {
- SPDLOG_DEBUG("signers {}", signer.GetEmail());
- }
-
- // data to transfer into task
- auto data_object = std::make_shared<Thread::Task::DataObject>();
-
- // set input buffer
- auto buffer =
- edit_->CurTextPage()->GetTextPage()->toPlainText().toStdString();
- data_object->AppendObject(std::move(buffer));
- // push the keys into data object
- data_object->AppendObject(std::move(keys));
- data_object->AppendObject(std::move(signer_keys));
-
- auto encrypt_sign_runner =
- [](Thread::Task::DataObjectPtr data_object) -> int {
- // check the size of the data object
- if (data_object == nullptr || data_object->GetObjectSize() != 3)
- throw std::runtime_error("Invalid data object size");
-
- auto signer_keys = data_object->PopObject<KeyListPtr>();
- auto keys = data_object->PopObject<KeyListPtr>();
- auto buffer = data_object->PopObject<std::string>();
- try {
- GpgEncrResult encr_result = nullptr;
- GpgSignResult sign_result = nullptr;
- auto tmp = std::make_unique<ByteArray>();
- GpgError error = GpgFrontend::GpgBasicOperator::GetInstance().EncryptSign(
- std::move(keys), std::move(signer_keys), buffer, tmp, encr_result,
- sign_result);
-
- data_object->AppendObject(std::move(tmp));
- data_object->AppendObject(std::move(sign_result));
- data_object->AppendObject(std::move(encr_result));
- data_object->AppendObject(std::move(error));
-
- } catch (const std::runtime_error& e) {
- return -1;
- }
- return 0;
- };
-
- auto result_callback = [this](int rtn,
- Thread::Task::DataObjectPtr data_object) {
- if (!rtn) {
- if (data_object == nullptr || data_object->GetObjectSize() != 4)
- throw std::runtime_error("Invalid data object size");
- auto error = data_object->PopObject<GpgError>();
- auto encrypt_result = data_object->PopObject<GpgEncrResult>();
- auto sign_result = data_object->PopObject<GpgSignResult>();
- auto tmp = data_object->PopObject<std::unique_ptr<ByteArray>>();
-
- auto encrypt_result_analyse =
- GpgEncryptResultAnalyse(error, std::move(encrypt_result));
- auto sign_result_analyse =
- GpgSignResultAnalyse(error, std::move(sign_result));
- encrypt_result_analyse.Analyse();
- sign_result_analyse.Analyse();
- process_result_analyse(edit_, info_board_, encrypt_result_analyse,
- sign_result_analyse);
- if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR)
- edit_->SlotFillTextEditWithText(QString::fromStdString(*tmp));
-
- info_board_->ResetOptionActionsMenu();
- } else {
- QMessageBox::critical(this, _("Error"),
- _("An error occurred during operation."));
- return;
- }
- };
-
- process_operation(this, _("Encrypting and Signing"), encrypt_sign_runner,
- result_callback, data_object);
-}
-
-void MainWindow::slot_decrypt_verify() {
- if (edit_->TabCount() == 0 || edit_->SlotCurPageTextEdit() == nullptr) {
- if (edit_->SlotCurPageFileTreeView() != nullptr)
- this->SlotFileDecryptVerify();
- return;
- }
-
- // data to transfer into task
- auto data_object = std::make_shared<Thread::Task::DataObject>();
-
- // set input buffer
- auto buffer =
- edit_->CurTextPage()->GetTextPage()->toPlainText().toStdString();
- data_object->AppendObject(std::move(buffer));
-
- auto decrypt_verify_runner =
- [](Thread::Task::DataObjectPtr data_object) -> int {
- // check the size of the data object
- if (data_object == nullptr || data_object->GetObjectSize() != 1)
- throw std::runtime_error("Invalid data object size");
-
- auto buffer = data_object->PopObject<std::string>();
- try {
- GpgDecrResult decrypt_result = nullptr;
- GpgVerifyResult verify_result = nullptr;
- auto decrypted_buffer = std::make_unique<ByteArray>();
- GpgError error = GpgBasicOperator::GetInstance().DecryptVerify(
- buffer, decrypted_buffer, decrypt_result, verify_result);
-
- data_object->AppendObject(std::move(decrypted_buffer));
- data_object->AppendObject(std::move(verify_result));
- data_object->AppendObject(std::move(decrypt_result));
- data_object->AppendObject(std::move(error));
- } catch (const std::runtime_error& e) {
- SPDLOG_ERROR(e.what());
- return -1;
- }
- return 0;
- };
-
- auto result_callback = [this](int rtn,
- Thread::Task::DataObjectPtr data_object) {
- if (!rtn) {
- if (data_object == nullptr || data_object->GetObjectSize() != 4)
- throw std::runtime_error("Invalid data object size");
-
- auto error = data_object->PopObject<GpgError>();
- auto decrypt_result = data_object->PopObject<GpgDecrResult>();
- auto verify_result = data_object->PopObject<GpgVerifyResult>();
- auto decrypted = data_object->PopObject<std::unique_ptr<ByteArray>>();
-
- auto decrypt_result_analyse =
- GpgDecryptResultAnalyse(error, std::move(decrypt_result));
- auto verify_result_analyse = GpgVerifyResultAnalyse(error, verify_result);
- decrypt_result_analyse.Analyse();
- verify_result_analyse.Analyse();
- process_result_analyse(edit_, info_board_, decrypt_result_analyse,
- verify_result_analyse);
- if (check_gpg_error_2_err_code(error) == GPG_ERR_NO_ERROR)
- edit_->SlotFillTextEditWithText(QString::fromStdString(*decrypted));
-
- if (verify_result_analyse.GetStatus() == -2)
- import_unknown_key_from_keyserver(this, verify_result_analyse);
-
- if (verify_result_analyse.GetStatus() >= 0)
- show_verify_details(this, info_board_, error, verify_result);
-
- } else {
- QMessageBox::critical(this, _("Error"),
- _("An error occurred during operation."));
- return;
- }
- };
-
- process_operation(this, _("Decrypting and Verifying"), decrypt_verify_runner,
- result_callback, data_object);
-}
void MainWindow::slot_find() {
if (edit_->TabCount() == 0 || edit_->CurTextPage() == nullptr) {
@@ -608,76 +59,68 @@ void MainWindow::slot_find() {
* Append the selected (not checked!) Key(s) To Textedit
*/
void MainWindow::slot_append_selected_keys() {
- if (edit_->TabCount() == 0 || edit_->SlotCurPageTextEdit() == nullptr) {
- return;
- }
-
- auto exported = std::make_unique<ByteArray>();
auto key_ids = m_key_list_->GetSelected();
if (key_ids->empty()) {
- SPDLOG_ERROR("no key is selected");
+ GF_UI_LOG_ERROR("no key is selected to export");
return;
}
- if (!GpgKeyImportExporter::GetInstance().ExportKeys(key_ids, exported)) {
- QMessageBox::critical(this, _("Error"), _("Key Export Operation Failed."));
+ auto key = GpgKeyGetter::GetInstance().GetKey(key_ids->front());
+ if (!key.IsGood()) {
+ GF_UI_LOG_ERROR("selected key for exporting is invalid, key id: {}",
+ key_ids->front());
return;
}
- edit_->CurTextPage()->GetTextPage()->appendPlainText(
- QString::fromStdString(*exported));
-}
-void MainWindow::slot_append_keys_create_datetime() {
- if (edit_->TabCount() == 0 || edit_->SlotCurPageTextEdit() == nullptr) {
+ auto [err, gf_buffer] =
+ GpgKeyImportExporter::GetInstance().ExportKey(key, false, true, false);
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ CommonUtils::RaiseMessageBox(this, err);
return;
}
+ edit_->SlotAppendText2CurTextPage(gf_buffer.ConvertToQByteArray());
+}
+
+void MainWindow::slot_append_keys_create_datetime() {
auto key_ids = m_key_list_->GetSelected();
if (key_ids->empty()) {
- SPDLOG_ERROR("no key is selected");
+ GF_UI_LOG_ERROR("no key is selected");
return;
}
auto key = GpgKeyGetter::GetInstance().GetKey(key_ids->front());
if (!key.IsGood()) {
- QMessageBox::critical(this, _("Error"), _("Key Not Found."));
+ QMessageBox::critical(this, tr("Error"), tr("Key Not Found."));
return;
}
- auto create_datetime_format_str =
- boost::posix_time::to_iso_extended_string(key.GetCreateTime()) +
- " (UTC) " + "\n";
-
- edit_->CurTextPage()->GetTextPage()->appendPlainText(
- QString::fromStdString(create_datetime_format_str));
+ auto create_datetime_format_str_local =
+ QLocale::system().toString(key.GetCreateTime()) + tr(" (Local Time) ") +
+ "\n";
+ edit_->SlotAppendText2CurTextPage(create_datetime_format_str_local);
}
void MainWindow::slot_append_keys_expire_datetime() {
- if (edit_->TabCount() == 0 || edit_->SlotCurPageTextEdit() == nullptr) {
- return;
- }
-
auto key_ids = m_key_list_->GetSelected();
if (key_ids->empty()) {
- SPDLOG_ERROR("no key is selected");
+ GF_UI_LOG_ERROR("no key is selected");
return;
}
auto key = GpgKeyGetter::GetInstance().GetKey(key_ids->front());
if (!key.IsGood()) {
- QMessageBox::critical(this, _("Error"), _("Key Not Found."));
+ QMessageBox::critical(this, tr("Error"), tr("Key Not Found."));
return;
}
auto create_datetime_format_str =
- boost::posix_time::to_iso_extended_string(key.GetCreateTime()) +
- " (UTC) " + "\n";
+ key.GetCreateTime().toString() + " (UTC) " + "\n";
- edit_->CurTextPage()->GetTextPage()->appendPlainText(
- QString::fromStdString(create_datetime_format_str));
+ edit_->SlotAppendText2CurTextPage(create_datetime_format_str);
}
void MainWindow::slot_append_keys_fingerprint() {
@@ -686,15 +129,14 @@ void MainWindow::slot_append_keys_fingerprint() {
auto key = GpgKeyGetter::GetInstance().GetKey(key_ids->front());
if (!key.IsGood()) {
- QMessageBox::critical(this, _("Error"), _("Key Not Found."));
+ QMessageBox::critical(this, tr("Error"), tr("Key Not Found."));
return;
}
auto fingerprint_format_str =
- beautify_fingerprint(key.GetFingerprint()) + "\n";
+ BeautifyFingerprint(key.GetFingerprint()) + "\n";
- edit_->CurTextPage()->GetTextPage()->appendPlainText(
- QString::fromStdString(fingerprint_format_str));
+ edit_->SlotAppendText2CurTextPage(fingerprint_format_str);
}
void MainWindow::slot_copy_mail_address_to_clipboard() {
@@ -703,11 +145,11 @@ void MainWindow::slot_copy_mail_address_to_clipboard() {
auto key = GpgKeyGetter::GetInstance().GetKey(key_ids->front());
if (!key.IsGood()) {
- QMessageBox::critical(this, _("Error"), _("Key Not Found."));
+ QMessageBox::critical(this, tr("Error"), tr("Key Not Found."));
return;
}
QClipboard* cb = QApplication::clipboard();
- cb->setText(QString::fromStdString(key.GetEmail()));
+ cb->setText(key.GetEmail());
}
void MainWindow::slot_copy_default_uid_to_clipboard() {
@@ -716,11 +158,11 @@ void MainWindow::slot_copy_default_uid_to_clipboard() {
auto key = GpgKeyGetter::GetInstance().GetKey(key_ids->front());
if (!key.IsGood()) {
- QMessageBox::critical(this, _("Error"), _("Key Not Found."));
+ QMessageBox::critical(this, tr("Error"), tr("Key Not Found."));
return;
}
QClipboard* cb = QApplication::clipboard();
- cb->setText(QString::fromStdString(key.GetUIDs()->front().GetUID()));
+ cb->setText(key.GetUIDs()->front().GetUID());
}
void MainWindow::slot_copy_key_id_to_clipboard() {
@@ -729,11 +171,11 @@ void MainWindow::slot_copy_key_id_to_clipboard() {
auto key = GpgKeyGetter::GetInstance().GetKey(key_ids->front());
if (!key.IsGood()) {
- QMessageBox::critical(this, _("Error"), _("Key Not Found."));
+ QMessageBox::critical(this, tr("Error"), tr("Key Not Found."));
return;
}
QClipboard* cb = QApplication::clipboard();
- cb->setText(QString::fromStdString(key.GetId()));
+ cb->setText(key.GetId());
}
void MainWindow::slot_show_key_details() {
@@ -744,7 +186,7 @@ void MainWindow::slot_show_key_details() {
if (key.IsGood()) {
new KeyDetailsDialog(key, this);
} else {
- QMessageBox::critical(this, _("Error"), _("Key Not Found."));
+ QMessageBox::critical(this, tr("Error"), tr("Key Not Found."));
}
}
@@ -781,50 +223,9 @@ void MainWindow::slot_set_owner_trust_level_of_key() {
auto key_ids = m_key_list_->GetSelected();
if (key_ids->empty()) return;
- auto key = GpgKeyGetter::GetInstance().GetKey(key_ids->front());
-
- QStringList items;
-
- items << _("Unknown") << _("Undefined") << _("Never") << _("Marginal")
- << _("Full") << _("Ultimate");
- bool ok;
- QString item = QInputDialog::getItem(this, _("Modify Owner Trust Level"),
- _("Trust for the Key Pair:"), items,
- key.GetOwnerTrustLevel(), false, &ok);
-
- if (ok && !item.isEmpty()) {
- SPDLOG_DEBUG("selected policy: {}", item.toStdString());
- int trust_level = 0; // Unknown Level
- if (item == _("Ultimate")) {
- trust_level = 5;
- } else if (item == _("Full")) {
- trust_level = 4;
- } else if (item == _("Marginal")) {
- trust_level = 3;
- } else if (item == _("Never")) {
- trust_level = 2;
- } else if (item == _("Undefined")) {
- trust_level = 1;
- }
-
- if (trust_level == 0) {
- QMessageBox::warning(
- this, _("Warning"),
- QString(_("Owner Trust Level cannot set to Unknown level, automately "
- "changing it into Undefined level.")));
- trust_level = 1;
- }
-
- bool status =
- GpgKeyManager::GetInstance().SetOwnerTrustLevel(key, trust_level);
- if (!status) {
- QMessageBox::critical(this, _("Failed"),
- QString(_("Modify Owner Trust Level failed.")));
- } else {
- // update key database and refresh ui
- emit SignalKeyDatabaseRefresh();
- }
- }
+ auto* function = new SetOwnerTrustLevel(this);
+ function->Exec(key_ids->front());
+ function->deleteLater();
}
void MainWindow::upload_key_to_server() {
@@ -834,50 +235,97 @@ void MainWindow::upload_key_to_server() {
dialog->SlotUpload();
}
-void MainWindow::SlotOpenFile(QString& path) { edit_->SlotOpenFile(path); }
+void MainWindow::SlotOpenFile(const QString& path) {
+ QFileInfo const info(path);
+ if (!info.isFile() || !info.isReadable()) {
+ QMessageBox::critical(
+ this, tr("Error"),
+ tr("Cannot open this file. Please make sure that this "
+ "is a regular file and it's readable."));
+ return;
+ }
-void MainWindow::slot_version_upgrade(const SoftwareVersion& version) {
- if (!version.InfoValid()) {
- SPDLOG_ERROR("invalid version info");
+ if (info.size() > static_cast<qint64>(1024 * 1024)) {
+ QMessageBox::critical(
+ this, tr("Error"),
+ tr("Cannot open this file. The file is TOO LARGE (>1MB) for "
+ "GpgFrontend Text Editor."));
return;
}
- SPDLOG_DEBUG(
- "version info, need upgrade: {}, with drawn: {}, current version "
- "released: {}",
- version.NeedUpgrade(), version.VersionWithDrawn(),
- version.CurrentVersionReleased());
+ edit_->SlotOpenFile(path);
+}
+
+void MainWindow::slot_version_upgrade_nofity() {
+ GF_UI_LOG_DEBUG(
+ "slot version upgrade notify called, checking version info from rt...");
+ auto is_loading_done = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.version-checking",
+ "version.loading_done", false);
+
+ GF_UI_LOG_DEBUG("checking version info from rt, is loading done state: {}",
+ is_loading_done);
+ if (!is_loading_done) {
+ GF_UI_LOG_ERROR("invalid version info from rt, loading hasn't done yet");
+ return;
+ }
+
+ auto is_need_upgrade = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.version-checking",
+ "version.need_upgrade", false);
+
+ auto is_current_a_withdrawn_version = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.version-checking",
+ "version.current_a_withdrawn_version", false);
+
+ auto is_current_version_released = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.version-checking",
+ "version.current_version_released", false);
- if (version.NeedUpgrade()) {
+ auto latest_version = Module::RetrieveRTValueTypedOrDefault<>(
+ "com.bktus.gpgfrontend.module.integrated.version-checking",
+ "version.latest_version", QString{});
+
+ GF_UI_LOG_DEBUG(
+ "got version info from rt, need upgrade: {}, with drawn: {}, "
+ "current version released: {}",
+ is_need_upgrade, is_current_a_withdrawn_version,
+ is_current_version_released);
+
+ if (is_need_upgrade) {
statusBar()->showMessage(
- QString(_("GpgFrontend Upgradeable (New Version: %1)."))
- .arg(version.latest_version.c_str()),
+ tr("GpgFrontend Upgradeable (New Version: %1).").arg(latest_version),
30000);
- auto update_button = new QPushButton("Update GpgFrontend", this);
+ auto* update_button = new QPushButton("Update GpgFrontend", this);
connect(update_button, &QPushButton::clicked, [=]() {
auto* about_dialog = new AboutDialog(2, this);
about_dialog->show();
});
statusBar()->addPermanentWidget(update_button, 0);
- } else if (version.VersionWithDrawn()) {
+ } else if (is_current_a_withdrawn_version) {
QMessageBox::warning(
- this, _("Withdrawn Version"),
- QString(
- _("This version(%1) may have been withdrawn by the developer due "
- "to serious problems. Please stop using this version "
- "immediately and use the latest stable version."))
- .arg(version.current_version.c_str()) +
+ this, tr("Withdrawn Version"),
+
+ tr("This version(%1) may have been withdrawn by the developer due "
+ "to serious problems. Please stop using this version "
+ "immediately and use the latest stable version.")
+ .arg(latest_version) +
"<br/>" +
- QString(_("You can download the latest stable version(%1) on "
- "Github Releases "
- "Page.<br/>"))
- .arg(version.latest_version.c_str()));
- } else if (!version.CurrentVersionReleased()) {
+ tr("You can download the latest stable version(%1) on "
+ "Github Releases Page.<br/>")
+ .arg(latest_version));
+ } else if (!is_current_version_released) {
statusBar()->showMessage(
- QString(_("This maybe a BETA Version (Latest Stable Version: %1)."))
- .arg(version.latest_version.c_str()),
+ tr("This maybe a BETA Version (Latest Stable Version: %1).")
+ .arg(latest_version),
30000);
}
}
+void MainWindow::slot_refresh_current_file_view() {
+ if (edit_->CurFilePage() != nullptr) {
+ edit_->CurFilePage()->update();
+ }
+}
+
} // namespace GpgFrontend::UI
diff --git a/src/ui/main_window/MainWindowSlotUI.cpp b/src/ui/main_window/MainWindowSlotUI.cpp
index 0b7f4c64..1b39b606 100644
--- a/src/ui/main_window/MainWindowSlotUI.cpp
+++ b/src/ui/main_window/MainWindowSlotUI.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,9 +28,13 @@
#include "MainWindow.h"
#include "core/GpgConstants.h"
-#include "core/function/GlobalSettingStation.h"
+#include "core/model/GpgPassphraseContext.h"
#include "ui/UserInterfaceUtils.h"
+#include "ui/dialog/Wizard.h"
+#include "ui/function/RaisePinentry.h"
+#include "ui/main_window/KeyMgmt.h"
#include "ui/struct/SettingsObject.h"
+#include "ui/struct/settings/AppearanceSO.h"
namespace GpgFrontend::UI {
@@ -47,11 +51,12 @@ void MainWindow::slot_start_wizard() {
void MainWindow::slot_import_key_from_edit() {
if (edit_->TabCount() == 0 || edit_->SlotCurPageTextEdit() == nullptr) return;
CommonUtils::GetInstance()->SlotImportKeys(
- this, edit_->CurTextPage()->GetTextPage()->toPlainText().toStdString());
+ this, edit_->CurTextPage()->GetTextPage()->toPlainText());
}
void MainWindow::slot_open_key_management() {
auto* dialog = new KeyMgmt(this);
+ dialog->setWindowModality(Qt::ApplicationModal);
dialog->show();
dialog->raise();
}
@@ -61,10 +66,7 @@ void MainWindow::slot_open_file_tab() { edit_->SlotNewFileTab(); }
void MainWindow::slot_disable_tab_actions(int number) {
bool disable;
- if (number == -1)
- disable = true;
- else
- disable = false;
+ disable = number == -1;
if (edit_->CurFilePage() != nullptr) {
disable = true;
@@ -93,7 +95,6 @@ void MainWindow::slot_disable_tab_actions(int number) {
zoom_in_act_->setDisabled(disable);
clean_double_line_breaks_act_->setDisabled(disable);
quote_act_->setDisabled(disable);
- append_selected_keys_act_->setDisabled(disable);
import_key_from_edit_act_->setDisabled(disable);
cut_pgp_header_act_->setDisabled(disable);
@@ -101,32 +102,26 @@ void MainWindow::slot_disable_tab_actions(int number) {
}
void MainWindow::slot_open_settings_dialog() {
- auto dialog = new SettingsDialog(this);
+ auto* dialog = new SettingsDialog(this);
connect(dialog, &SettingsDialog::finished, this, [&]() -> void {
- SettingsObject general_settings_state("general_settings_state");
-
- int width = general_settings_state.Check("icon_size").Check("width", 24),
- height = general_settings_state.Check("icon_size").Check("height", 24);
- SPDLOG_DEBUG("icon_size: {} {}", width, height);
-
- general_settings_state.Check("info_font_size", 10);
+ AppearanceSO appearance(SettingsObject("general_settings_state"));
+ GF_UI_LOG_DEBUG("tool bar icon_size: {}, {}",
+ appearance.tool_bar_icon_width,
+ appearance.tool_bar_icon_height);
- // icon_style
- int s_icon_style =
- general_settings_state.Check("icon_style", Qt::ToolButtonTextUnderIcon);
- auto icon_style = static_cast<Qt::ToolButtonStyle>(s_icon_style);
- this->setToolButtonStyle(icon_style);
- import_button_->setToolButtonStyle(icon_style);
+ this->setToolButtonStyle(appearance.tool_bar_button_style);
+ import_button_->setToolButtonStyle(appearance.tool_bar_button_style);
// icons ize
- this->setIconSize(QSize(width, height));
- import_button_->setIconSize(QSize(width, height));
+ this->setIconSize(
+ QSize(appearance.tool_bar_icon_width, appearance.tool_bar_icon_height));
+ import_button_->setIconSize(
+ QSize(appearance.tool_bar_icon_width, appearance.tool_bar_icon_height));
// restart mainwindow if necessary
- if (get_restart_needed()) {
+ if (get_restart_needed() != 0) {
if (edit_->MaybeSaveAnyTab()) {
- save_settings();
emit SignalRestartApplication(get_restart_needed());
}
}
@@ -151,8 +146,8 @@ void MainWindow::slot_add_pgp_header() {
QString content =
edit_->CurTextPage()->GetTextPage()->toPlainText().trimmed();
- content.prepend("\n\n").prepend(GpgConstants::PGP_CRYPT_BEGIN);
- content.append("\n").append(GpgConstants::PGP_CRYPT_END);
+ content.prepend("\n\n").prepend(PGP_CRYPT_BEGIN);
+ content.append("\n").append(PGP_CRYPT_END);
edit_->SlotFillTextEditWithText(content);
}
@@ -163,8 +158,8 @@ void MainWindow::slot_cut_pgp_header() {
}
QString content = edit_->CurTextPage()->GetTextPage()->toPlainText();
- int start = content.indexOf(GpgConstants::PGP_CRYPT_BEGIN);
- int end = content.indexOf(GpgConstants::PGP_CRYPT_END);
+ int start = content.indexOf(PGP_CRYPT_BEGIN);
+ int end = content.indexOf(PGP_CRYPT_END);
if (start < 0 || end < 0) {
return;
@@ -175,14 +170,14 @@ void MainWindow::slot_cut_pgp_header() {
content.remove(start, headEnd - start);
// remove tail
- end = content.indexOf(GpgConstants::PGP_CRYPT_END);
- content.remove(end, QString(GpgConstants::PGP_CRYPT_END).size());
+ end = content.indexOf(PGP_CRYPT_END);
+ content.remove(end, QString(PGP_CRYPT_END).size());
edit_->SlotFillTextEditWithText(content.trimmed());
}
void MainWindow::SlotSetRestartNeeded(int mode) {
- SPDLOG_DEBUG("restart mode: {}", mode);
+ GF_UI_LOG_DEBUG("restart mode: {}", mode);
this->restart_needed_ = mode;
}
@@ -190,7 +185,7 @@ int MainWindow::get_restart_needed() const { return this->restart_needed_; }
void MainWindow::SetCryptoMenuStatus(
MainWindow::CryptoMenu::OperationType type) {
- SPDLOG_DEBUG("type: {}", type);
+ GF_UI_LOG_DEBUG("type: {}", type);
// refresh status to disable all
verify_act_->setDisabled(true);
@@ -221,4 +216,10 @@ void MainWindow::SetCryptoMenuStatus(
}
}
+void MainWindow::SlotRaisePinentry(
+ QSharedPointer<GpgPassphraseContext> context) {
+ auto* function = new RaisePinentry(this, context);
+ function->Exec();
+}
+
} // namespace GpgFrontend::UI
diff --git a/src/ui/main_window/MainWindowUI.cpp b/src/ui/main_window/MainWindowUI.cpp
index d1a3cb68..662c673f 100644
--- a/src/ui/main_window/MainWindowUI.cpp
+++ b/src/ui/main_window/MainWindowUI.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,151 +20,149 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
+#include <any>
+
#include "MainWindow.h"
#include "core/function/GlobalSettingStation.h"
#include "core/function/gpg/GpgAdvancedOperator.h"
-#include "dialog/gnupg/GnuPGControllerDialog.h"
+#include "core/module/ModuleManager.h"
+#include "core/utils/IOUtils.h"
#include "ui/UserInterfaceUtils.h"
+#include "ui/dialog/gnupg/GnuPGControllerDialog.h"
+#include "ui/dialog/help/AboutDialog.h"
namespace GpgFrontend::UI {
void MainWindow::create_actions() {
/* Main Menu
*/
- new_tab_act_ = new QAction(_("New"), this);
- new_tab_act_->setIcon(QIcon(":misc_doc.png"));
- QList<QKeySequence> newTabActShortcutList;
-#ifdef GPGFRONTEND_GUI_QT6
- newTabActShortcutList.append(QKeySequence(Qt::CTRL | Qt::Key_N));
- newTabActShortcutList.append(QKeySequence(Qt::CTRL | Qt::Key_T));
-#else
-#endif
- new_tab_act_->setShortcuts(newTabActShortcutList);
- new_tab_act_->setToolTip(_("Open a new file"));
+ new_tab_act_ = new QAction(tr("New"), this);
+ new_tab_act_->setIcon(QIcon(":/icons/misc_doc.png"));
+ QList<QKeySequence> new_tab_act_shortcut_list;
+ new_tab_act_shortcut_list.append(QKeySequence(Qt::CTRL | Qt::Key_N));
+ new_tab_act_shortcut_list.append(QKeySequence(Qt::CTRL | Qt::Key_T));
+ new_tab_act_->setShortcuts(new_tab_act_shortcut_list);
+ new_tab_act_->setToolTip(tr("Open a new file"));
connect(new_tab_act_, &QAction::triggered, edit_, &TextEdit::SlotNewTab);
- open_act_ = new QAction(_("Open..."), this);
- open_act_->setIcon(QIcon(":fileopen.png"));
+ open_act_ = new QAction(tr("Open..."), this);
+ open_act_->setIcon(QIcon(":/icons/fileopen.png"));
open_act_->setShortcut(QKeySequence::Open);
- open_act_->setToolTip(_("Open an existing file"));
+ open_act_->setToolTip(tr("Open an existing file"));
connect(open_act_, &QAction::triggered, edit_, &TextEdit::SlotOpen);
- browser_act_ = new QAction(_("File Browser"), this);
- browser_act_->setIcon(QIcon(":file-browser.png"));
-#ifdef GPGFRONTEND_GUI_QT6
+ browser_act_ = new QAction(tr("File Browser"), this);
+ browser_act_->setIcon(QIcon(":/icons/file-browser.png"));
browser_act_->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_B));
-#else
- browser_act_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_B));
-#endif
- browser_act_->setToolTip(_("Open a file browser"));
+ browser_act_->setToolTip(tr("Open a file browser"));
connect(browser_act_, &QAction::triggered, this,
&MainWindow::slot_open_file_tab);
- save_act_ = new QAction(_("Save File"), this);
- save_act_->setIcon(QIcon(":filesave.png"));
+ save_act_ = new QAction(tr("Save File"), this);
+ save_act_->setIcon(QIcon(":/icons/filesave.png"));
save_act_->setShortcut(QKeySequence::Save);
- save_act_->setToolTip(_("Save the current File"));
+ save_act_->setToolTip(tr("Save the current File"));
connect(save_act_, &QAction::triggered, edit_, &TextEdit::SlotSave);
- save_as_act_ = new QAction(QString(_("Save As")) + "...", this);
- save_as_act_->setIcon(QIcon(":filesaveas.png"));
+ save_as_act_ = new QAction(tr("Save As") + "...", this);
+ save_as_act_->setIcon(QIcon(":/icons/filesaveas.png"));
save_as_act_->setShortcut(QKeySequence::SaveAs);
- save_as_act_->setToolTip(_("Save the current File as..."));
+ save_as_act_->setToolTip(tr("Save the current File as..."));
connect(save_as_act_, &QAction::triggered, edit_, &TextEdit::SlotSaveAs);
- print_act_ = new QAction(_("Print"), this);
- print_act_->setIcon(QIcon(":fileprint.png"));
+ print_act_ = new QAction(tr("Print"), this);
+ print_act_->setIcon(QIcon(":/icons/fileprint.png"));
print_act_->setShortcut(QKeySequence::Print);
- print_act_->setToolTip(_("Print Document"));
+ print_act_->setToolTip(tr("Print Document"));
connect(print_act_, &QAction::triggered, edit_, &TextEdit::SlotPrint);
- close_tab_act_ = new QAction(_("Close"), this);
+ close_tab_act_ = new QAction(tr("Close"), this);
close_tab_act_->setShortcut(QKeySequence::Close);
- close_tab_act_->setToolTip(_("Close file"));
+ close_tab_act_->setToolTip(tr("Close file"));
connect(close_tab_act_, &QAction::triggered, edit_, &TextEdit::SlotCloseTab);
- quit_act_ = new QAction(_("Quit"), this);
+ quit_act_ = new QAction(tr("Quit"), this);
quit_act_->setShortcut(QKeySequence::Quit);
- quit_act_->setIcon(QIcon(":exit.png"));
- quit_act_->setToolTip(_("Quit Program"));
+ quit_act_->setIcon(QIcon(":/icons/exit.png"));
+ quit_act_->setToolTip(tr("Quit Program"));
connect(quit_act_, &QAction::triggered, this, &MainWindow::close);
/* Edit Menu
*/
- undo_act_ = new QAction(_("Undo"), this);
+ undo_act_ = new QAction(tr("Undo"), this);
undo_act_->setShortcut(QKeySequence::Undo);
- undo_act_->setToolTip(_("Undo Last Edit Action"));
+ undo_act_->setToolTip(tr("Undo Last Edit Action"));
connect(undo_act_, &QAction::triggered, edit_, &TextEdit::SlotUndo);
- redo_act_ = new QAction(_("Redo"), this);
+ redo_act_ = new QAction(tr("Redo"), this);
redo_act_->setShortcut(QKeySequence::Redo);
- redo_act_->setToolTip(_("Redo Last Edit Action"));
+ redo_act_->setToolTip(tr("Redo Last Edit Action"));
connect(redo_act_, &QAction::triggered, edit_, &TextEdit::SlotRedo);
- zoom_in_act_ = new QAction(_("Zoom In"), this);
+ zoom_in_act_ = new QAction(tr("Zoom In"), this);
zoom_in_act_->setShortcut(QKeySequence::ZoomIn);
connect(zoom_in_act_, &QAction::triggered, edit_, &TextEdit::SlotZoomIn);
- zoom_out_act_ = new QAction(_("Zoom Out"), this);
+ zoom_out_act_ = new QAction(tr("Zoom Out"), this);
zoom_out_act_->setShortcut(QKeySequence::ZoomOut);
connect(zoom_out_act_, &QAction::triggered, edit_, &TextEdit::SlotZoomOut);
- paste_act_ = new QAction(_("Paste"), this);
- paste_act_->setIcon(QIcon(":button_paste.png"));
+ paste_act_ = new QAction(tr("Paste"), this);
+ paste_act_->setIcon(QIcon(":/icons/button_paste.png"));
paste_act_->setShortcut(QKeySequence::Paste);
- paste_act_->setToolTip(_("Paste Text From Clipboard"));
+ paste_act_->setToolTip(tr("Paste Text From Clipboard"));
connect(paste_act_, &QAction::triggered, edit_, &TextEdit::SlotPaste);
- cut_act_ = new QAction(_("Cut"), this);
- cut_act_->setIcon(QIcon(":button_cut.png"));
+ cut_act_ = new QAction(tr("Cut"), this);
+ cut_act_->setIcon(QIcon(":/icons/button_cut.png"));
cut_act_->setShortcut(QKeySequence::Cut);
cut_act_->setToolTip(
- _("Cut the current selection's contents to the "
- "clipboard"));
+ tr("Cut the current selection's contents to the "
+ "clipboard"));
connect(cut_act_, &QAction::triggered, edit_, &TextEdit::SlotCut);
- copy_act_ = new QAction(_("Copy"), this);
- copy_act_->setIcon(QIcon(":button_copy.png"));
+ copy_act_ = new QAction(tr("Copy"), this);
+ copy_act_->setIcon(QIcon(":/icons/button_copy.png"));
copy_act_->setShortcut(QKeySequence::Copy);
copy_act_->setToolTip(
- _("Copy the current selection's contents to the "
- "clipboard"));
+ tr("Copy the current selection's contents to the "
+ "clipboard"));
connect(copy_act_, &QAction::triggered, edit_, &TextEdit::SlotCopy);
- quote_act_ = new QAction(_("Quote"), this);
- quote_act_->setIcon(QIcon(":quote.png"));
- quote_act_->setToolTip(_("Quote whole text"));
+ quote_act_ = new QAction(tr("Quote"), this);
+ quote_act_->setIcon(QIcon(":/icons/quote.png"));
+ quote_act_->setToolTip(tr("Quote whole text"));
connect(quote_act_, &QAction::triggered, edit_, &TextEdit::SlotQuote);
- select_all_act_ = new QAction(_("Select All"), this);
- select_all_act_->setIcon(QIcon(":edit.png"));
+ select_all_act_ = new QAction(tr("Select All"), this);
+ select_all_act_->setIcon(QIcon(":/icons/edit.png"));
select_all_act_->setShortcut(QKeySequence::SelectAll);
- select_all_act_->setToolTip(_("Select the whole text"));
+ select_all_act_->setToolTip(tr("Select the whole text"));
connect(select_all_act_, &QAction::triggered, edit_,
&TextEdit::SlotSelectAll);
- find_act_ = new QAction(_("Find"), this);
+ find_act_ = new QAction(tr("Find"), this);
find_act_->setShortcut(QKeySequence::Find);
- find_act_->setToolTip(_("Find a word"));
+ find_act_->setToolTip(tr("Find a word"));
connect(find_act_, &QAction::triggered, this, &MainWindow::slot_find);
- clean_double_line_breaks_act_ = new QAction(_("Remove spacing"), this);
+ clean_double_line_breaks_act_ = new QAction(tr("Remove spacing"), this);
clean_double_line_breaks_act_->setIcon(
- QIcon(":format-line-spacing-triple.png"));
+ QIcon(":/icons/format-line-spacing-triple.png"));
// cleanDoubleLineBreaksAct->setShortcut(QKeySequence::SelectAll);
clean_double_line_breaks_act_->setToolTip(
- _("Remove double linebreaks, e.g. in pasted text from Web Mailer"));
+ tr("Remove double linebreaks, e.g. in pasted text from Web Mailer"));
connect(clean_double_line_breaks_act_, &QAction::triggered, this,
&MainWindow::slot_clean_double_line_breaks);
- open_settings_act_ = new QAction(_("Settings"), this);
- open_settings_act_->setToolTip(_("Open settings dialog"));
+ open_settings_act_ = new QAction(tr("Settings"), this);
+ open_settings_act_->setToolTip(tr("Open settings dialog"));
open_settings_act_->setMenuRole(QAction::PreferencesRole);
open_settings_act_->setShortcut(QKeySequence::Preferences);
connect(open_settings_act_, &QAction::triggered, this,
@@ -172,269 +170,345 @@ void MainWindow::create_actions() {
/* Crypt Menu
*/
- encrypt_act_ = new QAction(_("Encrypt"), this);
- encrypt_act_->setIcon(QIcon(":encrypted.png"));
-#ifdef GPGFRONTEND_GUI_QT6
+ encrypt_act_ = new QAction(tr("Encrypt"), this);
+ encrypt_act_->setIcon(QIcon(":/icons/encrypted.png"));
encrypt_act_->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_E));
-#else
-#endif
- encrypt_act_->setToolTip(_("Encrypt Message"));
- connect(encrypt_act_, &QAction::triggered, this, &MainWindow::slot_encrypt);
-
- encrypt_sign_act_ = new QAction(_("Encrypt Sign"), this);
- encrypt_sign_act_->setIcon(QIcon(":encrypted_signed.png"));
-#ifdef GPGFRONTEND_GUI_QT6
+
+ encrypt_act_->setToolTip(tr("Encrypt Message"));
+ connect(encrypt_act_, &QAction::triggered, this, [this]() {
+ if (edit_->SlotCurPageFileTreeView() != nullptr) {
+ const auto* file_tree_view = edit_->SlotCurPageFileTreeView();
+ const auto path = file_tree_view->GetSelected();
+
+ const auto file_info = QFileInfo(path);
+ if (file_info.isFile()) {
+ this->SlotFileEncrypt(path);
+ } else if (file_info.isDir()) {
+ this->SlotDirectoryEncrypt(path);
+ }
+ }
+ if (edit_->SlotCurPageTextEdit() != nullptr) {
+ this->SlotEncrypt();
+ }
+ });
+
+ encrypt_sign_act_ = new QAction(tr("Encrypt Sign"), this);
+ encrypt_sign_act_->setIcon(QIcon(":/icons/encrypted_signed.png"));
encrypt_sign_act_->setShortcut(
QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_E));
-#else
- encrypt_act_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_E));
-#endif
- encrypt_sign_act_->setToolTip(_("Encrypt and Sign Message"));
- connect(encrypt_sign_act_, &QAction::triggered, this,
- &MainWindow::slot_encrypt_sign);
-
- decrypt_act_ = new QAction(_("Decrypt"), this);
- decrypt_act_->setIcon(QIcon(":decrypted.png"));
-#ifdef GPGFRONTEND_GUI_QT6
+
+ encrypt_sign_act_->setToolTip(tr("Encrypt and Sign Message"));
+ connect(encrypt_sign_act_, &QAction::triggered, this, [this]() {
+ if (edit_->SlotCurPageFileTreeView() != nullptr) {
+ const auto* file_tree_view = edit_->SlotCurPageFileTreeView();
+ const auto path = file_tree_view->GetSelected();
+
+ const auto file_info = QFileInfo(path);
+ if (file_info.isFile()) {
+ this->SlotFileEncryptSign(path);
+ } else if (file_info.isDir()) {
+ this->SlotDirectoryEncryptSign(path);
+ }
+ }
+ if (edit_->SlotCurPageTextEdit() != nullptr) {
+ this->SlotEncryptSign();
+ }
+ });
+
+ decrypt_act_ = new QAction(tr("Decrypt"), this);
+ decrypt_act_->setIcon(QIcon(":/icons/decrypted.png"));
decrypt_act_->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_D));
-#else
- encrypt_act_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_E));
-#endif
- decrypt_act_->setToolTip(_("Decrypt Message"));
- connect(decrypt_act_, &QAction::triggered, this, &MainWindow::slot_decrypt);
-
- decrypt_verify_act_ = new QAction(_("Decrypt Verify"), this);
- decrypt_verify_act_->setIcon(QIcon(":decrypted_verified.png"));
-#ifdef GPGFRONTEND_GUI_QT6
+ decrypt_act_->setToolTip(tr("Decrypt Message"));
+ connect(decrypt_act_, &QAction::triggered, this, [this]() {
+ if (edit_->SlotCurPageFileTreeView() != nullptr) {
+ const auto* file_tree_view = edit_->SlotCurPageFileTreeView();
+ const auto path = file_tree_view->GetSelected();
+
+ const auto file_info = QFileInfo(path);
+ if (file_info.isFile()) {
+ const QString extension = file_info.completeSuffix();
+
+ if (extension == "tar.gpg" || extension == "tar.asc") {
+ this->SlotArchiveDecrypt(path);
+ } else {
+ this->SlotFileDecrypt(path);
+ }
+ }
+ }
+ if (edit_->SlotCurPageTextEdit() != nullptr) {
+ this->SlotDecrypt();
+ }
+ });
+
+ decrypt_verify_act_ = new QAction(tr("Decrypt Verify"), this);
+ decrypt_verify_act_->setIcon(QIcon(":/icons/decrypted_verified.png"));
decrypt_verify_act_->setShortcut(
QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_D));
-#else
- encrypt_act_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_E));
-#endif
- decrypt_verify_act_->setToolTip(_("Decrypt and Verify Message"));
- connect(decrypt_verify_act_, &QAction::triggered, this,
- &MainWindow::slot_decrypt_verify);
-
- sign_act_ = new QAction(_("Sign"), this);
- sign_act_->setIcon(QIcon(":signature.png"));
-#ifdef GPGFRONTEND_GUI_QT6
+ decrypt_verify_act_->setToolTip(tr("Decrypt and Verify Message"));
+ connect(decrypt_verify_act_, &QAction::triggered, this, [this]() {
+ if (edit_->SlotCurPageFileTreeView() != nullptr) {
+ const auto* file_tree_view = edit_->SlotCurPageFileTreeView();
+ const auto path = file_tree_view->GetSelected();
+
+ const auto file_info = QFileInfo(path);
+ if (file_info.isFile()) {
+ const QString extension = file_info.completeSuffix();
+
+ if (extension == ".tar.gpg" || extension == ".tar.asc") {
+ this->SlotArchiveDecryptVerify(path);
+ } else {
+ this->SlotFileDecryptVerify(path);
+ }
+ }
+ }
+ if (edit_->SlotCurPageTextEdit() != nullptr) {
+ this->SlotDecryptVerify();
+ }
+ });
+
+ sign_act_ = new QAction(tr("Sign"), this);
+ sign_act_->setIcon(QIcon(":/icons/signature.png"));
sign_act_->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_I));
-#else
- encrypt_act_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_E));
-#endif
- sign_act_->setToolTip(_("Sign Message"));
- connect(sign_act_, &QAction::triggered, this, &MainWindow::slot_sign);
-
- verify_act_ = new QAction(_("Verify"), this);
- verify_act_->setIcon(QIcon(":verify.png"));
-#ifdef GPGFRONTEND_GUI_QT6
+ sign_act_->setToolTip(tr("Sign Message"));
+ connect(sign_act_, &QAction::triggered, this, [this]() {
+ if (edit_->SlotCurPageFileTreeView() != nullptr) {
+ const auto* file_tree_view = edit_->SlotCurPageFileTreeView();
+ const auto path = file_tree_view->GetSelected();
+
+ const auto file_info = QFileInfo(path);
+ if (file_info.isFile()) this->SlotFileSign(path);
+ }
+ if (edit_->SlotCurPageTextEdit() != nullptr) this->SlotSign();
+ });
+
+ verify_act_ = new QAction(tr("Verify"), this);
+ verify_act_->setIcon(QIcon(":/icons/verify.png"));
verify_act_->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_V));
-#else
- encrypt_act_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_E));
-#endif
- verify_act_->setToolTip(_("Verify Message"));
- connect(verify_act_, &QAction::triggered, this, &MainWindow::slot_verify);
+ verify_act_->setToolTip(tr("Verify Message"));
+ connect(verify_act_, &QAction::triggered, this, [this]() {
+ if (edit_->SlotCurPageFileTreeView() != nullptr) {
+ const auto* file_tree_view = edit_->SlotCurPageFileTreeView();
+ const auto path = file_tree_view->GetSelected();
+
+ const auto file_info = QFileInfo(path);
+ if (file_info.isFile()) this->SlotFileVerify(path);
+ }
+ if (edit_->SlotCurPageTextEdit() != nullptr) this->SlotVerify();
+ });
/* Key Menu
*/
- import_key_from_file_act_ = new QAction(_("File"), this);
- import_key_from_file_act_->setIcon(QIcon(":import_key_from_file.png"));
- import_key_from_file_act_->setToolTip(_("Import New Key From File"));
+ import_key_from_file_act_ = new QAction(tr("File"), this);
+ import_key_from_file_act_->setIcon(QIcon(":/icons/import_key_from_file.png"));
+ import_key_from_file_act_->setToolTip(tr("Import New Key From File"));
connect(import_key_from_file_act_, &QAction::triggered, this,
[&]() { CommonUtils::GetInstance()->SlotImportKeyFromFile(this); });
- import_key_from_clipboard_act_ = new QAction(_("Clipboard"), this);
+ import_key_from_clipboard_act_ = new QAction(tr("Clipboard"), this);
import_key_from_clipboard_act_->setIcon(
- QIcon(":import_key_from_clipboard.png"));
+ QIcon(":/icons/import_key_from_clipboard.png"));
import_key_from_clipboard_act_->setToolTip(
- _("Import New Key From Clipboard"));
+ tr("Import New Key From Clipboard"));
connect(import_key_from_clipboard_act_, &QAction::triggered, this, [&]() {
CommonUtils::GetInstance()->SlotImportKeyFromClipboard(this);
});
bool forbid_all_gnupg_connection =
- GlobalSettingStation::GetInstance().LookupSettings(
- "network.forbid_all_gnupg_connection", false);
+ GlobalSettingStation::GetInstance()
+ .GetSettings()
+ .value("network/forbid_all_gnupg_connection", false)
+ .toBool();
- import_key_from_key_server_act_ = new QAction(_("Keyserver"), this);
+ import_key_from_key_server_act_ = new QAction(tr("Keyserver"), this);
import_key_from_key_server_act_->setIcon(
- QIcon(":import_key_from_server.png"));
+ QIcon(":/icons/import_key_from_server.png"));
import_key_from_key_server_act_->setToolTip(
- _("Import New Key From Keyserver"));
+ tr("Import New Key From Keyserver"));
import_key_from_key_server_act_->setDisabled(forbid_all_gnupg_connection);
connect(import_key_from_key_server_act_, &QAction::triggered, this, [&]() {
CommonUtils::GetInstance()->SlotImportKeyFromKeyServer(this);
});
- import_key_from_edit_act_ = new QAction(_("Editor"), this);
- import_key_from_edit_act_->setIcon(QIcon(":txt.png"));
- import_key_from_edit_act_->setToolTip(_("Import New Key From Editor"));
+ import_key_from_edit_act_ = new QAction(tr("Editor"), this);
+ import_key_from_edit_act_->setIcon(QIcon(":/icons/txt.png"));
+ import_key_from_edit_act_->setToolTip(tr("Import New Key From Editor"));
connect(import_key_from_edit_act_, &QAction::triggered, this,
&MainWindow::slot_import_key_from_edit);
- open_key_management_act_ = new QAction(_("Manage Keys"), this);
- open_key_management_act_->setIcon(QIcon(":keymgmt.png"));
- open_key_management_act_->setToolTip(_("Open Key Management"));
+ open_key_management_act_ = new QAction(tr("Manage Keys"), this);
+ open_key_management_act_->setIcon(QIcon(":/icons/keymgmt.png"));
+ open_key_management_act_->setToolTip(tr("Open Key Management"));
connect(open_key_management_act_, &QAction::triggered, this,
&MainWindow::slot_open_key_management);
- clean_gpg_password_cache_act_ = new QAction(_("Clear Password Cache"), this);
- clean_gpg_password_cache_act_->setIcon(QIcon(":configure.png"));
- clean_gpg_password_cache_act_->setToolTip(_("Clear Password Cache of GnuPG"));
+ clean_gpg_password_cache_act_ = new QAction(tr("Clear Password Cache"), this);
+ clean_gpg_password_cache_act_->setIcon(QIcon(":/icons/configure.png"));
+ clean_gpg_password_cache_act_->setToolTip(
+ tr("Clear Password Cache of GnuPG"));
connect(clean_gpg_password_cache_act_, &QAction::triggered, this, [=]() {
- if (GpgFrontend::GpgAdvancedOperator::GetInstance()
- .ClearGpgPasswordCache()) {
- QMessageBox::information(this, _("Successful Operation"),
- _("Clear password cache successfully"));
- } else {
- QMessageBox::critical(this, _("Failed Operation"),
- _("Failed to clear password cache of GnuPG"));
- }
+ GpgFrontend::GpgAdvancedOperator::ClearGpgPasswordCache([=](int err,
+ DataObjectPtr) {
+ if (err >= 0) {
+ QMessageBox::information(this, tr("Successful Operation"),
+ tr("Clear password cache successfully"));
+ } else {
+ QMessageBox::critical(this, tr("Failed Operation"),
+ tr("Failed to clear password cache of GnuPG"));
+ }
+ });
});
- reload_components_act_ = new QAction(_("Reload All Components"), this);
- reload_components_act_->setIcon(QIcon(":configure.png"));
- reload_components_act_->setToolTip(_("Reload All GnuPG's Components"));
+ reload_components_act_ = new QAction(tr("Reload All Components"), this);
+ reload_components_act_->setIcon(QIcon(":/icons/configure.png"));
+ reload_components_act_->setToolTip(tr("Reload All GnuPG's Components"));
connect(reload_components_act_, &QAction::triggered, this, [=]() {
- if (GpgFrontend::GpgAdvancedOperator::GetInstance().ReloadGpgComponents()) {
- QMessageBox::information(
- this, _("Successful Operation"),
- _("Reload all the GnuPG's components successfully"));
- } else {
- QMessageBox::critical(
- this, _("Failed Operation"),
- _("Failed to reload all or one of the GnuPG's component(s)"));
- }
+ GpgFrontend::GpgAdvancedOperator::ReloadGpgComponents(
+ [=](int err, DataObjectPtr) {
+ if (err >= 0) {
+ QMessageBox::information(
+ this, tr("Successful Operation"),
+ tr("Reload all the GnuPG's components successfully"));
+ } else {
+ QMessageBox::critical(
+ this, tr("Failed Operation"),
+ tr("Failed to reload all or one of the GnuPG's component(s)"));
+ }
+ });
});
- restart_components_act_ = new QAction(_("Restart All Components"), this);
- restart_components_act_->setIcon(QIcon(":configure.png"));
- restart_components_act_->setToolTip(_("Restart All GnuPG's Components"));
+ restart_components_act_ = new QAction(tr("Restart All Components"), this);
+ restart_components_act_->setIcon(QIcon(":/icons/configure.png"));
+ restart_components_act_->setToolTip(tr("Restart All GnuPG's Components"));
connect(restart_components_act_, &QAction::triggered, this, [=]() {
- if (GpgFrontend::GpgAdvancedOperator::GetInstance()
- .RestartGpgComponents()) {
- QMessageBox::information(
- this, _("Successful Operation"),
- _("Restart all the GnuPG's components successfully"));
- } else {
- QMessageBox::critical(
- this, _("Failed Operation"),
- _("Failed to restart all or one of the GnuPG's component(s)"));
- }
+ GpgFrontend::GpgAdvancedOperator::RestartGpgComponents();
+ Module::ListenRTPublishEvent(
+ this, "core", "gpg_advanced_operator.restart_gpg_components",
+ [=](Module::Namespace, Module::Key, int, std::any value) {
+ bool success_state = std::any_cast<bool>(value);
+ if (success_state) {
+ QMessageBox::information(
+ this, tr("Successful Operation"),
+ tr("Restart all the GnuPG's components successfully"));
+ } else {
+ QMessageBox::critical(
+ this, tr("Failed Operation"),
+ tr("Failed to restart all or one of the GnuPG's component(s)"));
+ }
+ });
});
- gnupg_controller_open_act_ = new QAction(_("Open GnuPG Controller"), this);
- gnupg_controller_open_act_->setIcon(QIcon(":configure.png"));
- gnupg_controller_open_act_->setToolTip(_("Open GnuPG Controller Dialog"));
+ gnupg_controller_open_act_ = new QAction(tr("Open GnuPG Controller"), this);
+ gnupg_controller_open_act_->setIcon(QIcon(":/icons/configure.png"));
+ gnupg_controller_open_act_->setToolTip(tr("Open GnuPG Controller Dialog"));
connect(gnupg_controller_open_act_, &QAction::triggered, this,
[this]() { (new GnuPGControllerDialog(this))->exec(); });
/*
* About Menu
*/
- about_act_ = new QAction(_("About"), this);
- about_act_->setIcon(QIcon(":help.png"));
- about_act_->setToolTip(_("Show the application's About box"));
+ about_act_ = new QAction(tr("About"), this);
+ about_act_->setIcon(QIcon(":/icons/help.png"));
+ about_act_->setToolTip(tr("Show the application's About box"));
about_act_->setMenuRole(QAction::AboutRole);
connect(about_act_, &QAction::triggered, this,
[=]() { new AboutDialog(0, this); });
- gnupg_act_ = new QAction(_("GnuPG"), this);
- gnupg_act_->setIcon(QIcon(":help.png"));
- gnupg_act_->setToolTip(_("Information about Gnupg"));
+ gnupg_act_ = new QAction(tr("GnuPG"), this);
+ gnupg_act_->setIcon(QIcon(":/icons/help.png"));
+ gnupg_act_->setToolTip(tr("Information about Gnupg"));
connect(gnupg_act_, &QAction::triggered, this,
[=]() { new AboutDialog(1, this); });
- translate_act_ = new QAction(_("Translate"), this);
- translate_act_->setIcon(QIcon(":help.png"));
- translate_act_->setToolTip(_("Information about translation"));
+ translate_act_ = new QAction(tr("Translate"), this);
+ translate_act_->setIcon(QIcon(":/icons/help.png"));
+ translate_act_->setToolTip(tr("Information about translation"));
connect(translate_act_, &QAction::triggered, this,
[=]() { new AboutDialog(2, this); });
/*
* Check Update Menu
*/
- check_update_act_ = new QAction(_("Check for Updates"), this);
- check_update_act_->setIcon(QIcon(":help.png"));
- check_update_act_->setToolTip(_("Check for updates"));
+ check_update_act_ = new QAction(tr("Check for Updates"), this);
+ check_update_act_->setIcon(QIcon(":/icons/help.png"));
+ check_update_act_->setToolTip(tr("Check for updates"));
connect(check_update_act_, &QAction::triggered, this,
[=]() { new AboutDialog(3, this); });
- start_wizard_act_ = new QAction(_("Open Wizard"), this);
- start_wizard_act_->setToolTip(_("Open the wizard"));
+ start_wizard_act_ = new QAction(tr("Open Wizard"), this);
+ start_wizard_act_->setToolTip(tr("Open the wizard"));
connect(start_wizard_act_, &QAction::triggered, this,
&MainWindow::slot_start_wizard);
append_selected_keys_act_ =
- new QAction(_("Append Public Key to Editor"), this);
+ new QAction(tr("Append Public Key to Editor"), this);
append_selected_keys_act_->setToolTip(
- _("Append selected Keypair's Public Key to Editor"));
+ tr("Append selected Keypair's Public Key to Editor"));
connect(append_selected_keys_act_, &QAction::triggered, this,
&MainWindow::slot_append_selected_keys);
append_key_create_date_to_editor_act_ =
- new QAction(_("Append Create DateTime to Editor"), this);
+ new QAction(tr("Append Create DateTime to Editor"), this);
append_key_create_date_to_editor_act_->setToolTip(
- _("Append selected Key's creation date and time to Editor"));
+ tr("Append selected Key's creation date and time to Editor"));
connect(append_key_create_date_to_editor_act_, &QAction::triggered, this,
&MainWindow::slot_append_keys_create_datetime);
append_key_expire_date_to_editor_act_ =
- new QAction(_("Append Expire DateTime to Editor"), this);
+ new QAction(tr("Append Expire DateTime to Editor"), this);
append_key_expire_date_to_editor_act_->setToolTip(
- _("Append selected Key's expiration date and time to Editor"));
+ tr("Append selected Key's expiration date and time to Editor"));
connect(append_key_expire_date_to_editor_act_, &QAction::triggered, this,
&MainWindow::slot_append_keys_expire_datetime);
append_key_fingerprint_to_editor_act_ =
- new QAction(_("Append Fingerprint to Editor"), this);
+ new QAction(tr("Append Fingerprint to Editor"), this);
append_key_expire_date_to_editor_act_->setToolTip(
- _("Append selected Key's Fingerprint to Editor"));
+ tr("Append selected Key's Fingerprint to Editor"));
connect(append_key_fingerprint_to_editor_act_, &QAction::triggered, this,
&MainWindow::slot_append_keys_fingerprint);
- copy_mail_address_to_clipboard_act_ = new QAction(_("Copy Email"), this);
+ copy_mail_address_to_clipboard_act_ = new QAction(tr("Copy Email"), this);
copy_mail_address_to_clipboard_act_->setToolTip(
- _("Copy selected Keypair's to clipboard"));
+ tr("Copy selected Keypair's to clipboard"));
connect(copy_mail_address_to_clipboard_act_, &QAction::triggered, this,
&MainWindow::slot_copy_mail_address_to_clipboard);
copy_key_default_uid_to_clipboard_act_ =
- new QAction(_("Copy Default UID"), this);
+ new QAction(tr("Copy Default UID"), this);
copy_key_default_uid_to_clipboard_act_->setToolTip(
- _("Copy selected Keypair's default UID to clipboard"));
+ tr("Copy selected Keypair's default UID to clipboard"));
connect(copy_key_default_uid_to_clipboard_act_, &QAction::triggered, this,
&MainWindow::slot_copy_default_uid_to_clipboard);
- copy_key_id_to_clipboard_act_ = new QAction(_("Copy Key ID"), this);
+ copy_key_id_to_clipboard_act_ = new QAction(tr("Copy Key ID"), this);
copy_key_id_to_clipboard_act_->setToolTip(
- _("Copy selected Keypair's ID to clipboard"));
+ tr("Copy selected Keypair's ID to clipboard"));
connect(copy_key_id_to_clipboard_act_, &QAction::triggered, this,
&MainWindow::slot_copy_key_id_to_clipboard);
- show_key_details_act_ = new QAction(_("Show Key Details"), this);
- show_key_details_act_->setToolTip(_("Show Details for this Key"));
+ show_key_details_act_ = new QAction(tr("Show Key Details"), this);
+ show_key_details_act_->setToolTip(tr("Show Details for this Key"));
connect(show_key_details_act_, &QAction::triggered, this,
&MainWindow::slot_show_key_details);
- add_key_2_favourtie_act_ = new QAction(_("Add To Favourite"), this);
- add_key_2_favourtie_act_->setToolTip(_("Add this key to Favourite Table"));
+ add_key_2_favourtie_act_ = new QAction(tr("Add To Favourite"), this);
+ add_key_2_favourtie_act_->setToolTip(tr("Add this key to Favourite Table"));
add_key_2_favourtie_act_->setData(QVariant("add_key_2_favourite_action"));
connect(add_key_2_favourtie_act_, &QAction::triggered, this,
&MainWindow::slot_add_key_2_favourite);
remove_key_from_favourtie_act_ =
- new QAction(_("Remove From Favourite"), this);
+ new QAction(tr("Remove From Favourite"), this);
remove_key_from_favourtie_act_->setToolTip(
- _("Remove this key from Favourite Table"));
+ tr("Remove this key from Favourite Table"));
remove_key_from_favourtie_act_->setData(
QVariant("remove_key_from_favourtie_action"));
connect(remove_key_from_favourtie_act_, &QAction::triggered, this,
&MainWindow::slot_remove_key_from_favourite);
- set_owner_trust_of_key_act_ = new QAction(_("Set Owner Trust Level"), this);
- set_owner_trust_of_key_act_->setToolTip(_("Set Owner Trust Level"));
+ set_owner_trust_of_key_act_ = new QAction(tr("Set Owner Trust Level"), this);
+ set_owner_trust_of_key_act_->setToolTip(tr("Set Owner Trust Level"));
set_owner_trust_of_key_act_->setData(QVariant("set_owner_trust_level"));
connect(set_owner_trust_of_key_act_, &QAction::triggered, this,
&MainWindow::slot_set_owner_trust_level_of_key);
@@ -453,17 +527,17 @@ void MainWindow::create_actions() {
&TextEdit::SlotSwitchTabDown);
this->addAction(switch_tab_down_act_);
- cut_pgp_header_act_ = new QAction(_("Remove PGP Header"), this);
+ cut_pgp_header_act_ = new QAction(tr("Remove PGP Header"), this);
connect(cut_pgp_header_act_, &QAction::triggered, this,
&MainWindow::slot_cut_pgp_header);
- add_pgp_header_act_ = new QAction(_("Add PGP Header"), this);
+ add_pgp_header_act_ = new QAction(tr("Add PGP Header"), this);
connect(add_pgp_header_act_, &QAction::triggered, this,
&MainWindow::slot_add_pgp_header);
}
void MainWindow::create_menus() {
- file_menu_ = menuBar()->addMenu(_("File"));
+ file_menu_ = menuBar()->addMenu(tr("File"));
file_menu_->addAction(new_tab_act_);
file_menu_->addAction(browser_act_);
file_menu_->addAction(open_act_);
@@ -476,7 +550,7 @@ void MainWindow::create_menus() {
file_menu_->addAction(close_tab_act_);
file_menu_->addAction(quit_act_);
- edit_menu_ = menuBar()->addMenu(_("Edit"));
+ edit_menu_ = menuBar()->addMenu(tr("Edit"));
edit_menu_->addAction(undo_act_);
edit_menu_->addAction(redo_act_);
edit_menu_->addSeparator();
@@ -494,7 +568,7 @@ void MainWindow::create_menus() {
edit_menu_->addSeparator();
edit_menu_->addAction(open_settings_act_);
- crypt_menu_ = menuBar()->addMenu(_("Crypt"));
+ crypt_menu_ = menuBar()->addMenu(tr("Crypt"));
crypt_menu_->addAction(encrypt_act_);
crypt_menu_->addAction(encrypt_sign_act_);
crypt_menu_->addAction(decrypt_act_);
@@ -504,16 +578,16 @@ void MainWindow::create_menus() {
crypt_menu_->addAction(verify_act_);
crypt_menu_->addSeparator();
- key_menu_ = menuBar()->addMenu(_("Keys"));
- import_key_menu_ = key_menu_->addMenu(_("Import Key"));
- import_key_menu_->setIcon(QIcon(":key_import.png"));
+ key_menu_ = menuBar()->addMenu(tr("Keys"));
+ import_key_menu_ = key_menu_->addMenu(tr("Import Key"));
+ import_key_menu_->setIcon(QIcon(":/icons/key_import.png"));
import_key_menu_->addAction(import_key_from_file_act_);
import_key_menu_->addAction(import_key_from_edit_act_);
import_key_menu_->addAction(import_key_from_clipboard_act_);
import_key_menu_->addAction(import_key_from_key_server_act_);
key_menu_->addAction(open_key_management_act_);
- gpg_menu_ = menuBar()->addMenu(_("GnuPG"));
+ gpg_menu_ = menuBar()->addMenu(tr("GnuPG"));
gpg_menu_->addAction(clean_gpg_password_cache_act_);
gpg_menu_->addSeparator();
gpg_menu_->addAction(reload_components_act_);
@@ -521,13 +595,13 @@ void MainWindow::create_menus() {
gpg_menu_->addSeparator();
gpg_menu_->addAction(gnupg_controller_open_act_);
- steganography_menu_ = menuBar()->addMenu(_("Steganography"));
+ steganography_menu_ = menuBar()->addMenu(tr("Steganography"));
steganography_menu_->addAction(cut_pgp_header_act_);
steganography_menu_->addAction(add_pgp_header_act_);
- view_menu_ = menuBar()->addMenu(_("View"));
+ view_menu_ = menuBar()->addMenu(tr("View"));
- help_menu_ = menuBar()->addMenu(_("Help"));
+ help_menu_ = menuBar()->addMenu(tr("Help"));
help_menu_->addAction(start_wizard_act_);
help_menu_->addSeparator();
help_menu_->addAction(check_update_act_);
@@ -537,15 +611,14 @@ void MainWindow::create_menus() {
}
void MainWindow::create_tool_bars() {
- file_tool_bar_ = addToolBar(_("File"));
+ file_tool_bar_ = addToolBar(tr("File"));
file_tool_bar_->setObjectName("fileToolBar");
file_tool_bar_->addAction(new_tab_act_);
file_tool_bar_->addAction(open_act_);
- file_tool_bar_->addAction(save_act_);
file_tool_bar_->addAction(browser_act_);
view_menu_->addAction(file_tool_bar_->toggleViewAction());
- crypt_tool_bar_ = addToolBar(_("Operations"));
+ crypt_tool_bar_ = addToolBar(tr("Operations"));
crypt_tool_bar_->setObjectName("cryptToolBar");
crypt_tool_bar_->addAction(encrypt_act_);
crypt_tool_bar_->addAction(encrypt_sign_act_);
@@ -555,12 +628,12 @@ void MainWindow::create_tool_bars() {
crypt_tool_bar_->addAction(verify_act_);
view_menu_->addAction(crypt_tool_bar_->toggleViewAction());
- key_tool_bar_ = addToolBar(_("Key"));
+ key_tool_bar_ = addToolBar(tr("Key"));
key_tool_bar_->setObjectName("keyToolBar");
key_tool_bar_->addAction(open_key_management_act_);
view_menu_->addAction(key_tool_bar_->toggleViewAction());
- edit_tool_bar_ = addToolBar(_("Edit"));
+ edit_tool_bar_ = addToolBar(tr("Edit"));
edit_tool_bar_->setObjectName("editToolBar");
edit_tool_bar_->addAction(copy_act_);
edit_tool_bar_->addAction(paste_act_);
@@ -568,7 +641,7 @@ void MainWindow::create_tool_bars() {
edit_tool_bar_->hide();
view_menu_->addAction(edit_tool_bar_->toggleViewAction());
- special_edit_tool_bar_ = addToolBar(_("Special Edit"));
+ special_edit_tool_bar_ = addToolBar(tr("Special Edit"));
special_edit_tool_bar_->setObjectName("specialEditToolBar");
special_edit_tool_bar_->addAction(quote_act_);
special_edit_tool_bar_->addAction(clean_double_line_breaks_act_);
@@ -579,32 +652,32 @@ void MainWindow::create_tool_bars() {
import_button_ = new QToolButton();
import_button_->setMenu(import_key_menu_);
import_button_->setPopupMode(QToolButton::InstantPopup);
- import_button_->setIcon(QIcon(":key_import.png"));
- import_button_->setToolTip(_("Import key from..."));
- import_button_->setText(_("Import key"));
+ import_button_->setIcon(QIcon(":/icons/key_import.png"));
+ import_button_->setToolTip(tr("Import key from..."));
+ import_button_->setText(tr("Import key"));
key_tool_bar_->addWidget(import_button_);
}
void MainWindow::create_status_bar() {
- auto* statusBarBox = new QWidget();
- auto* statusBarBoxLayout = new QHBoxLayout();
+ auto* status_bar_box = new QWidget();
+ auto* status_bar_box_layout = new QHBoxLayout();
// QPixmap* pixmap;
// icon which should be shown if there are files in attachments-folder
- // pixmap = new QPixmap(":statusbar_icon.png");
+ // pixmap = new QPixmap(":/icons/statusbar_icon.png");
// statusBarIcon = new QLabel();
// statusBar()->addWidget(statusBarIcon);
//
// statusBarIcon->setPixmap(*pixmap);
// statusBar()->insertPermanentWidget(0, statusBarIcon, 0);
- statusBar()->showMessage(_("Ready"), 2000);
- statusBarBox->setLayout(statusBarBoxLayout);
+ statusBar()->showMessage(tr("Ready"), 2000);
+ status_bar_box->setLayout(status_bar_box_layout);
}
void MainWindow::create_dock_windows() {
/* KeyList-Dock window
*/
- key_list_dock_ = new QDockWidget(_("Key ToolBox"), this);
+ key_list_dock_ = new QDockWidget(tr("Key ToolBox"), this);
key_list_dock_->setObjectName("EncryptDock");
key_list_dock_->setAllowedAreas(Qt::LeftDockWidgetArea |
Qt::RightDockWidgetArea);
@@ -612,7 +685,7 @@ void MainWindow::create_dock_windows() {
addDockWidget(Qt::RightDockWidgetArea, key_list_dock_);
m_key_list_->AddListGroupTab(
- _("Default"), "default", KeyListRow::SECRET_OR_PUBLIC_KEY,
+ tr("Default"), "default", KeyListRow::SECRET_OR_PUBLIC_KEY,
KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
KeyListColumn::Usage | KeyListColumn::Validity,
[](const GpgKey& key, const KeyTable&) -> bool {
@@ -620,7 +693,7 @@ void MainWindow::create_dock_windows() {
});
m_key_list_->AddListGroupTab(
- _("Favourite"), "favourite", KeyListRow::SECRET_OR_PUBLIC_KEY,
+ tr("Favourite"), "favourite", KeyListRow::SECRET_OR_PUBLIC_KEY,
KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
KeyListColumn::Usage | KeyListColumn::Validity,
[](const GpgKey& key, const KeyTable&) -> bool {
@@ -628,7 +701,8 @@ void MainWindow::create_dock_windows() {
});
m_key_list_->AddListGroupTab(
- _("Only Public Key"), "only_public_key", KeyListRow::SECRET_OR_PUBLIC_KEY,
+ tr("Only Public Key"), "only_public_key",
+ KeyListRow::SECRET_OR_PUBLIC_KEY,
KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
KeyListColumn::Usage | KeyListColumn::Validity,
[](const GpgKey& key, const KeyTable&) -> bool {
@@ -637,7 +711,8 @@ void MainWindow::create_dock_windows() {
});
m_key_list_->AddListGroupTab(
- _("Has Private Key"), "has_private_key", KeyListRow::SECRET_OR_PUBLIC_KEY,
+ tr("Has Private Key"), "has_private_key",
+ KeyListRow::SECRET_OR_PUBLIC_KEY,
KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
KeyListColumn::Usage | KeyListColumn::Validity,
[](const GpgKey& key, const KeyTable&) -> bool {
@@ -650,7 +725,7 @@ void MainWindow::create_dock_windows() {
key_list_dock_->setWidget(m_key_list_);
view_menu_->addAction(key_list_dock_->toggleViewAction());
- info_board_dock_ = new QDockWidget(_("Information Board"), this);
+ info_board_dock_ = new QDockWidget(tr("Information Board"), this);
info_board_dock_->setObjectName("Information Board");
info_board_dock_->setAllowedAreas(Qt::BottomDockWidgetArea);
addDockWidget(Qt::BottomDockWidgetArea, info_board_dock_);
diff --git a/src/ui/struct/CacheObject.cpp b/src/ui/struct/CacheObject.cpp
new file mode 100644
index 00000000..bd3b9818
--- /dev/null
+++ b/src/ui/struct/CacheObject.cpp
@@ -0,0 +1,45 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "CacheObject.h"
+
+#include "core/function/CacheManager.h"
+
+namespace GpgFrontend::UI {
+
+CacheObject::CacheObject(QString cache_name)
+ : cache_name_(std::move(cache_name)) {
+ this->QJsonDocument::operator=(
+ CacheManager::GetInstance().LoadDurableCache(cache_name_));
+}
+
+CacheObject::~CacheObject() {
+ CacheManager::GetInstance().SaveDurableCache(cache_name_, *this);
+}
+
+} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/struct/CacheObject.h b/src/ui/struct/CacheObject.h
new file mode 100644
index 00000000..ae8aa056
--- /dev/null
+++ b/src/ui/struct/CacheObject.h
@@ -0,0 +1,52 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+namespace GpgFrontend::UI {
+
+class CacheObject : public QJsonDocument {
+ public:
+ /**
+ * @brief Construct a new Cache Object object
+ *
+ * @param cache_name
+ */
+ explicit CacheObject(QString cache_name);
+
+ /**
+ * @brief Destroy the Cache Object object
+ *
+ */
+ ~CacheObject();
+
+ private:
+ QString cache_name_; ///<
+};
+
+} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/struct/SettingsObject.cpp b/src/ui/struct/SettingsObject.cpp
index d5230089..cc5e85bf 100644
--- a/src/ui/struct/SettingsObject.cpp
+++ b/src/ui/struct/SettingsObject.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,77 +28,42 @@
#include "SettingsObject.h"
-nlohmann::json& GpgFrontend::UI::SettingsObject::Check(
- const std::string& key, const nlohmann::json& default_value) {
- // check if the self null
- if (this->nlohmann::json::is_null()) {
- SPDLOG_DEBUG("settings object is null, creating new one");
- this->nlohmann::json::operator=(nlohmann::json::object());
- }
-
- try {
- if (!this->nlohmann::json::contains(key) ||
- this->nlohmann::json::at(key).is_null() ||
- this->nlohmann::json::at(key).type_name() !=
- default_value.type_name()) {
- SPDLOG_DEBUG("added missing key: {}", key);
- if (default_value.is_null()) {
- SPDLOG_WARN("default value is null, using empty object");
- this->nlohmann::json::operator[](key) = nlohmann::json::object();
- } else {
- this->nlohmann::json::operator[](key) = default_value;
- }
- }
- return this->nlohmann::json::at(key);
- } catch (nlohmann::json::exception& e) {
- SPDLOG_ERROR(e.what());
- throw e;
- }
-}
-
-GpgFrontend::UI::SettingsObject GpgFrontend::UI::SettingsObject::Check(
- const std::string& key) {
- // check if the self null
- if (this->nlohmann::json::is_null()) {
- SPDLOG_DEBUG("settings object is null, creating new one");
- this->nlohmann::json::operator=(nlohmann::json::object());
- }
+#include "core/function/DataObjectOperator.h"
- if (!nlohmann::json::contains(key) ||
- this->nlohmann::json::at(key).is_null() ||
- this->nlohmann::json::at(key).type() != nlohmann::json::value_t::object) {
- SPDLOG_DEBUG("added missing key: {}", key);
- this->nlohmann::json::operator[](key) = nlohmann::json::object();
- }
- return SettingsObject{nlohmann::json::operator[](key), false};
-}
+namespace GpgFrontend::UI {
-GpgFrontend::UI::SettingsObject::SettingsObject(std::string settings_name)
+SettingsObject::SettingsObject(QString settings_name)
: settings_name_(std::move(settings_name)) {
try {
- SPDLOG_DEBUG("loading settings from: {}", this->settings_name_);
- auto _json_optional =
- GpgFrontend::DataObjectOperator::GetInstance().GetDataObject(
- settings_name_);
+ GF_UI_LOG_DEBUG("loading settings from: {}", this->settings_name_);
+ auto json_optional =
+ DataObjectOperator::GetInstance().GetDataObject(settings_name_);
- if (_json_optional.has_value()) {
- SPDLOG_DEBUG("settings object: {} loaded.", settings_name_);
- nlohmann::json::operator=(_json_optional.value());
+ if (json_optional.has_value() && json_optional->isObject()) {
+ GF_UI_LOG_DEBUG("settings object: {} loaded.", settings_name_);
+ QJsonObject::operator=(json_optional.value().object());
} else {
- SPDLOG_DEBUG("settings object: {} not found.", settings_name_);
- nlohmann::json::operator=({});
+ GF_UI_LOG_DEBUG("settings object: {} not found.", settings_name_);
+ QJsonObject::operator=({});
}
} catch (std::exception& e) {
- SPDLOG_ERROR(e.what());
+ GF_UI_LOG_ERROR("load setting object error: {}", e.what());
}
}
-GpgFrontend::UI::SettingsObject::SettingsObject(nlohmann::json _sub_json, bool)
- : nlohmann::json(std::move(_sub_json)), settings_name_({}) {}
+SettingsObject::SettingsObject(QJsonObject sub_json)
+ : QJsonObject(std::move(sub_json)) {}
-GpgFrontend::UI::SettingsObject::~SettingsObject() {
- if (!settings_name_.empty())
- GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(settings_name_,
- *this);
-} \ No newline at end of file
+SettingsObject::~SettingsObject() {
+ if (!settings_name_.isEmpty()) {
+ DataObjectOperator::GetInstance().SaveDataObj(settings_name_,
+ QJsonDocument(*this));
+ }
+}
+
+void SettingsObject::Store(const QJsonObject& json) {
+ auto* parent = (static_cast<QJsonObject*>(this));
+ *parent = json;
+}
+} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/struct/SettingsObject.h b/src/ui/struct/SettingsObject.h
index d1e85be5..a9e5819f 100644
--- a/src/ui/struct/SettingsObject.h
+++ b/src/ui/struct/SettingsObject.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,41 +20,36 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_SETTINGSOBJECT_H
-#define GPGFRONTEND_SETTINGSOBJECT_H
-
-#include <utility>
-
-#include "core/function/DataObjectOperator.h"
+#pragma once
namespace GpgFrontend::UI {
/**
* @brief The SettingsObject class
- * This class is used to store settings for the application securely.
+ * This class is used to store data for the application securely.
*
*/
-class SettingsObject : public nlohmann::json {
+class SettingsObject : public QJsonObject {
public:
/**
* @brief Construct a new Settings Object object
*
* @param settings_name The name of the settings object
*/
- explicit SettingsObject(std::string settings_name);
+ explicit SettingsObject(QString settings_name);
/**
* @brief Construct a new Settings Object object
*
* @param _sub_json
*/
- explicit SettingsObject(nlohmann::json _sub_json, bool);
+ explicit SettingsObject(QJsonObject sub_json);
/**
* @brief Destroy the Settings Object object
@@ -65,24 +60,10 @@ class SettingsObject : public nlohmann::json {
/**
* @brief
*
- * @param key
- * @param default_value
- * @return nlohmann::json&
- */
- nlohmann::json& Check(const std::string& key,
- const nlohmann::json& default_value);
-
- /**
- * @brief
- *
- * @param key
- * @return SettingsObject
*/
- SettingsObject Check(const std::string& key);
+ void Store(const QJsonObject&);
private:
- std::string settings_name_; ///<
+ QString settings_name_; ///<
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_SETTINGSOBJECT_H
diff --git a/src/ui/struct/SoftwareVersion.cpp b/src/ui/struct/SoftwareVersion.cpp
deleted file mode 100644
index 6a60cb02..00000000
--- a/src/ui/struct/SoftwareVersion.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#include "SoftwareVersion.h"
-
-int GpgFrontend::UI::SoftwareVersion::version_compare(const std::string& a,
- const std::string& b) {
- auto temp_a = a, temp_b = b;
-
- if (!temp_a.empty() && temp_a.front() == 'v') {
- temp_a = temp_a.erase(0, 1);
- SPDLOG_DEBUG("real version a: {}", temp_a);
- }
-
- if (!temp_b.empty() && temp_b.front() == 'v') {
- temp_b.erase(0, 1);
- SPDLOG_DEBUG("real version b: {}", temp_b);
- }
-
- // First, split the string.
- std::vector<std::string> va, vb;
- boost::split(va, temp_a, boost::is_any_of("."));
- boost::split(vb, temp_b, boost::is_any_of("."));
-
- // Compare the numbers step by step, but only as deep as the version
- // with the least elements allows.
- const int depth =
- std::min(static_cast<int>(va.size()), static_cast<int>(vb.size()));
- int ia = 0, ib = 0;
- for (int i = 0; i < depth; ++i) {
- try {
- ia = boost::lexical_cast<int>(va[i]);
- ib = boost::lexical_cast<int>(vb[i]);
- } catch (boost::bad_lexical_cast& ignored) {
- break;
- }
- if (ia != ib) break;
- }
-
- // Return the required number.
- if (ia > ib)
- return 1;
- else if (ia < ib)
- return -1;
- else {
- // In case of equal versions, assumes that the version
- // with the most elements is the highest version.
- if (va.size() > vb.size())
- return 1;
- else if (va.size() < vb.size())
- return -1;
- }
-
- // Everything is equal, return 0.
- return 0;
-}
-
-bool GpgFrontend::UI::SoftwareVersion::NeedUpgrade() const {
- SPDLOG_DEBUG("compair version current {} latest {}, result {}",
- current_version, latest_version,
- version_compare(current_version, latest_version));
-
- SPDLOG_DEBUG("load done: {}, pre-release: {}, draft: {}", load_info_done,
- latest_prerelease, latest_draft);
- return load_info_done && !latest_prerelease && !latest_draft &&
- version_compare(current_version, latest_version) < 0;
-}
-
-bool GpgFrontend::UI::SoftwareVersion::VersionWithDrawn() const {
- return load_info_done && !current_version_found && current_prerelease &&
- !current_draft;
-}
-
-bool GpgFrontend::UI::SoftwareVersion::CurrentVersionReleased() const {
- return load_info_done && current_version_found;
-} \ No newline at end of file
diff --git a/src/ui/struct/settings/AppearanceSO.h b/src/ui/struct/settings/AppearanceSO.h
new file mode 100644
index 00000000..25262f22
--- /dev/null
+++ b/src/ui/struct/settings/AppearanceSO.h
@@ -0,0 +1,77 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+namespace GpgFrontend::UI {
+
+struct AppearanceSO {
+ int text_editor_font_size = 12;
+ int info_board_font_size = 12;
+ int tool_bar_icon_width = 24;
+ int tool_bar_icon_height = 24;
+ Qt::ToolButtonStyle tool_bar_button_style = Qt::ToolButtonTextUnderIcon;
+
+ bool save_window_state;
+
+ explicit AppearanceSO(const QJsonObject& j) {
+ if (const auto v = j["text_editor_font_size"]; v.isDouble()) {
+ text_editor_font_size = v.toInt();
+ }
+ if (const auto v = j["info_board_font_size"]; v.isDouble()) {
+ info_board_font_size = v.toInt();
+ }
+ if (const auto v = j["tool_bar_icon_width"]; v.isDouble()) {
+ tool_bar_icon_width = v.toInt();
+ }
+ if (const auto v = j["tool_bar_icon_height"]; v.isDouble()) {
+ tool_bar_icon_height = v.toInt();
+ }
+ if (const auto v = j["tool_bar_button_style"]; v.isDouble()) {
+ tool_bar_button_style = static_cast<Qt::ToolButtonStyle>(v.toInt());
+ }
+
+ if (const auto v = j["save_window_state"]; v.isBool()) {
+ save_window_state = v.toBool();
+ }
+ }
+
+ [[nodiscard]] auto ToJson() const -> QJsonObject {
+ QJsonObject j;
+ j["text_editor_font_size"] = text_editor_font_size;
+ j["info_board_font_size"] = info_board_font_size;
+ j["tool_bar_icon_width"] = tool_bar_icon_width;
+ j["tool_bar_icon_height"] = tool_bar_icon_height;
+ j["tool_bar_button_style"] = tool_bar_button_style;
+
+ j["save_window_state"] = save_window_state;
+ return j;
+ }
+};
+
+} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/struct/settings/KeyServerSO.h b/src/ui/struct/settings/KeyServerSO.h
new file mode 100644
index 00000000..3c9320d2
--- /dev/null
+++ b/src/ui/struct/settings/KeyServerSO.h
@@ -0,0 +1,79 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+namespace GpgFrontend::UI {
+
+struct KeyServerSO {
+ int default_server = 0;
+ QStringList server_list;
+
+ KeyServerSO() = default;
+
+ explicit KeyServerSO(const QJsonObject& j) {
+ if (const auto v = j["default_server"]; v.isDouble()) {
+ default_server = v.toInt();
+ }
+
+ if (const auto v = j["server_list"]; v.isArray()) {
+ const QJsonArray j_array = v.toArray();
+ server_list.reserve(j_array.size());
+ for (const auto& server : j_array) {
+ server_list.append(server.toString());
+ }
+ }
+
+ if (server_list.empty()) ResetDefaultServerList();
+ }
+
+ auto ToJson() -> QJsonObject {
+ QJsonObject j;
+ j["default_server"] = default_server;
+ auto j_array = QJsonArray();
+
+ for (const auto& s : server_list) {
+ j_array.push_back(s);
+ }
+ j["server_list"] = j_array;
+ return j;
+ }
+
+ auto GetTargetServer() -> QString {
+ if (server_list.empty()) this->ResetDefaultServerList();
+ if (default_server >= server_list.size()) default_server = 0;
+ return server_list[default_server];
+ }
+
+ void ResetDefaultServerList() {
+ server_list << "https://keyserver.ubuntu.com"
+ << "https://keys.openpgp.org";
+ }
+};
+
+} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/struct/settings/WindowStateSO.h b/src/ui/struct/settings/WindowStateSO.h
new file mode 100644
index 00000000..3fa56f3c
--- /dev/null
+++ b/src/ui/struct/settings/WindowStateSO.h
@@ -0,0 +1,65 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+namespace GpgFrontend::UI {
+
+struct WindowStateSO {
+ bool window_save = false;
+ QString window_state_data;
+ int x = 100;
+ int y = 100;
+ int width = 400;
+ int height = 200;
+
+ WindowStateSO() = default;
+
+ explicit WindowStateSO(const QJsonObject &j) {
+ if (const auto v = j["window_save"]; v.isBool()) window_save = v.toBool();
+ if (const auto v = j["window_state_data"]; v.isString()) {
+ window_state_data = v.toString();
+ }
+ if (const auto v = j["x"]; v.isDouble()) x = v.toInt();
+ if (const auto v = j["y"]; v.isDouble()) y = v.toInt();
+ if (const auto v = j["width"]; v.isDouble()) width = v.toInt();
+ if (const auto v = j["height"]; v.isDouble()) height = v.toInt();
+ }
+
+ [[nodiscard]] auto Json() const -> QJsonObject {
+ QJsonObject j;
+ j["window_save"] = window_save;
+ j["window_state_data"] = window_state_data;
+ j["x"] = x;
+ j["y"] = y;
+ j["width"] = width;
+ j["height"] = height;
+ return j;
+ }
+};
+} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/thread/KeyServerImportTask.cpp b/src/ui/thread/KeyServerImportTask.cpp
index fc6a868c..63cabbcd 100644
--- a/src/ui/thread/KeyServerImportTask.cpp
+++ b/src/ui/thread/KeyServerImportTask.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,47 +19,76 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "ui/thread/KeyServerImportTask.h"
-#include <vector>
+#include "core/function/gpg/GpgKeyImportExporter.h"
+#include "ui/struct/SettingsObject.h"
+#include "ui/struct/settings/KeyServerSO.h"
GpgFrontend::UI::KeyServerImportTask::KeyServerImportTask(
- std::string keyserver_url, std::vector<std::string> keyids)
+ QString keyserver_url, std::vector<QString> keyids)
: Task("key_server_import_task"),
keyserver_url_(std::move(keyserver_url)),
keyids_(std::move(keyids)),
- manager_(new QNetworkAccessManager(this)) {}
+ manager_(new QNetworkAccessManager(this)) {
+ HoldOnLifeCycle(true);
-void GpgFrontend::UI::KeyServerImportTask::run() {
- SetFinishAfterRun(false);
+ if (keyserver_url_.isEmpty()) {
+ KeyServerSO key_server(SettingsObject("general_settings_state"));
+ keyserver_url_ = key_server.GetTargetServer();
+ GF_UI_LOG_DEBUG("key server import task sets key server url: {}",
+ keyserver_url_);
+ }
+}
- QUrl keyserver_url = QUrl(keyserver_url_.c_str());
+auto GpgFrontend::UI::KeyServerImportTask::Run() -> int {
+ QUrl const keyserver_url = QUrl(keyserver_url_);
for (const auto& key_id : keyids_) {
- QUrl req_url(keyserver_url.scheme() + "://" + keyserver_url.host() +
- "/pks/lookup?op=get&search=0x" + key_id.c_str() +
- "&options=mr");
+ QUrl const req_url(keyserver_url.scheme() + "://" + keyserver_url.host() +
+ "/pks/lookup?op=get&search=0x" + key_id + "&options=mr");
reply_ = manager_->get(QNetworkRequest(req_url));
-
connect(reply_, &QNetworkReply::finished, this,
&KeyServerImportTask::dealing_reply_from_server);
}
+ return 0;
}
void GpgFrontend::UI::KeyServerImportTask::dealing_reply_from_server() {
- QByteArray buffer;
- QNetworkReply::NetworkError network_reply = reply_->error();
- if (network_reply == QNetworkReply::NoError) {
- buffer = reply_->readAll();
+ auto const network_reply = reply_->error();
+ auto buffer = reply_->readAll();
+
+ if (network_reply != QNetworkReply::NoError) {
+ GF_UI_LOG_ERROR("key import error, message from key server reply: ",
+ buffer);
+ QString err_msg;
+ switch (network_reply) {
+ case QNetworkReply::ContentNotFoundError:
+ err_msg = tr("Key not found in the Keyserver.");
+ break;
+ case QNetworkReply::TimeoutError:
+ err_msg = tr("Network connection timeout.");
+ break;
+ case QNetworkReply::HostNotFoundError:
+ err_msg = tr("Cannot resolve the address of target key server.");
+ break;
+ default:
+ err_msg = tr("General connection error occurred.");
+ }
+ emit SignalKeyServerImportResult(false, err_msg, buffer, nullptr);
}
- emit SignalKeyServerImportResult(network_reply, buffer);
- if (result_count_++ == keyids_.size() - 1) {
- emit SignalTaskRunnableEnd(0);
+ auto info = GpgKeyImportExporter::GetInstance().ImportKey(GFBuffer(buffer));
+ emit SignalKeyServerImportResult(true, tr("Success"), buffer, info);
+
+ if (static_cast<size_t>(result_count_++) == keyids_.size() - 1) {
+ emit SignalTaskShouldEnd(0);
}
} \ No newline at end of file
diff --git a/src/ui/thread/KeyServerImportTask.h b/src/ui/thread/KeyServerImportTask.h
index 7d3b66c6..8797916c 100644
--- a/src/ui/thread/KeyServerImportTask.h
+++ b/src/ui/thread/KeyServerImportTask.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,17 +19,26 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_KEYSERVERIMPORTTASK_H
-#define GPGFRONTEND_KEYSERVERIMPORTTASK_H
+#pragma once
+
+#include <qnetworkaccessmanager.h>
+#include <qnetworkreply.h>
+
+#include "core/thread/Task.h"
-#include "GpgFrontendUI.h"
+namespace GpgFrontend {
+class GpgImportInformation;
+}
namespace GpgFrontend::UI {
+
class KeyServerImportTask : public Thread::Task {
Q_OBJECT
public:
@@ -39,25 +48,23 @@ class KeyServerImportTask : public Thread::Task {
* @param keyserver_url
* @param search_string
*/
- KeyServerImportTask(std::string keyserver_url,
- std::vector<std::string> keyid);
-
- signals:
+ KeyServerImportTask(QString keyserver_url, std::vector<QString> keyid);
/**
* @brief
*
- * @param result
*/
- void SignalKeyServerImportResult(QNetworkReply::NetworkError reply,
- QByteArray buffer);
+ auto Run() -> int override;
+
+ signals:
- protected:
/**
* @brief
*
+ * @param result
*/
- void run() override;
+ void SignalKeyServerImportResult(bool, QString, QByteArray,
+ std::shared_ptr<GpgImportInformation>);
private slots:
@@ -68,13 +75,11 @@ class KeyServerImportTask : public Thread::Task {
void dealing_reply_from_server();
private:
- std::string keyserver_url_; ///<
- std::vector<std::string> keyids_; ///<
+ QString keyserver_url_; ///<
+ std::vector<QString> keyids_; ///<
int result_count_ = 0;
QNetworkAccessManager *manager_; ///<
QNetworkReply *reply_; ///<
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_KEYSERVERIMPORTTASK_H \ No newline at end of file
diff --git a/src/ui/thread/KeyServerSearchTask.cpp b/src/ui/thread/KeyServerSearchTask.cpp
index 863a4ca3..2f05b774 100644
--- a/src/ui/thread/KeyServerSearchTask.cpp
+++ b/src/ui/thread/KeyServerSearchTask.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,34 +19,34 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "ui/thread/KeyServerSearchTask.h"
-#include <utility>
-
-GpgFrontend::UI::KeyServerSearchTask::KeyServerSearchTask(
- std::string keyserver_url, std::string search_string)
+GpgFrontend::UI::KeyServerSearchTask::KeyServerSearchTask(QString keyserver_url,
+ QString search_string)
: Task("key_server_search_task"),
keyserver_url_(std::move(keyserver_url)),
search_string_(std::move(search_string)),
- manager_(new QNetworkAccessManager(this)) {}
-
-void GpgFrontend::UI::KeyServerSearchTask::run() {
- SetFinishAfterRun(false);
+ manager_(new QNetworkAccessManager(this)) {
+ HoldOnLifeCycle(true);
+}
- QUrl url_from_remote =
- QString::fromStdString(keyserver_url_) +
- "/pks/lookup?search=" + QString::fromStdString(search_string_) +
- "&op=index&options=mr";
+auto GpgFrontend::UI::KeyServerSearchTask::Run() -> int {
+ QUrl url_from_remote = keyserver_url_ +
+ "/pks/lookup?search=" + search_string_ +
+ "&op=index&options=mr";
reply_ = manager_->get(QNetworkRequest(url_from_remote));
-
connect(reply_, &QNetworkReply::finished, this,
&KeyServerSearchTask::dealing_reply_from_server);
+
+ return 0;
}
void GpgFrontend::UI::KeyServerSearchTask::dealing_reply_from_server() {
@@ -56,5 +56,5 @@ void GpgFrontend::UI::KeyServerSearchTask::dealing_reply_from_server() {
buffer = reply_->readAll();
}
emit SignalKeyServerSearchResult(network_reply, buffer);
- emit SignalTaskRunnableEnd(0);
+ emit SignalTaskShouldEnd(0);
}
diff --git a/src/ui/thread/KeyServerSearchTask.h b/src/ui/thread/KeyServerSearchTask.h
index 3333e949..cdce944d 100644
--- a/src/ui/thread/KeyServerSearchTask.h
+++ b/src/ui/thread/KeyServerSearchTask.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,18 +19,22 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_KEYSERVERSEARCHTASK_H
-#define GPGFRONTEND_KEYSERVERSEARCHTASK_H
+#pragma once
+
+#include <qnetworkaccessmanager.h>
+#include <qnetworkreply.h>
#include "GpgFrontendUI.h"
+#include "core/thread/ThreadingModel.h"
namespace GpgFrontend::UI {
-
class KeyServerSearchTask : public Thread::Task {
Q_OBJECT
public:
@@ -40,37 +44,34 @@ class KeyServerSearchTask : public Thread::Task {
* @param keyserver_url
* @param search_string
*/
- KeyServerSearchTask(std::string keyserver_url, std::string search_string);
-
- signals:
+ KeyServerSearchTask(QString keyserver_url, QString search_string);
/**
* @brief
*
- * @param result
*/
- void SignalKeyServerSearchResult(QNetworkReply::NetworkError reply,
- QByteArray buffer);
+ auto Run() -> int override;
+
+ signals:
- protected:
/**
* @brief
*
+ * @param result
*/
- void run() override;
+ void SignalKeyServerSearchResult(QNetworkReply::NetworkError reply,
+ QByteArray buffer);
private slots:
void dealing_reply_from_server();
private:
- std::string keyserver_url_; ///<
- std::string search_string_; ///<
+ QString keyserver_url_; ///<
+ QString search_string_; ///<
QNetworkAccessManager *manager_; ///<
QNetworkReply *reply_; ///<
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_KEYSERVERSEARCHTASK_H \ No newline at end of file
diff --git a/src/ui/thread/ListedKeyServerTestTask.cpp b/src/ui/thread/ListedKeyServerTestTask.cpp
index 914cd3d6..4ab7ba5f 100644
--- a/src/ui/thread/ListedKeyServerTestTask.cpp
+++ b/src/ui/thread/ListedKeyServerTestTask.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,46 +19,48 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "ListedKeyServerTestTask.h"
+#include <QtNetwork>
#include <vector>
GpgFrontend::UI::ListedKeyServerTestTask::ListedKeyServerTestTask(
- const QStringList& urls, int timeout, QWidget* parent)
+ QStringList urls, int timeout, QWidget* /*parent*/)
: Task("listed_key_server_test_task"),
- urls_(urls),
- timeout_(timeout),
+ urls_(std::move(urls)),
+ result_(urls_.size(), kTEST_RESULT_TYPE_ERROR),
network_manager_(new QNetworkAccessManager(this)),
- result_(urls_.size(), kTestResultType_Error) {
+ timeout_(timeout) {
+ HoldOnLifeCycle(true);
qRegisterMetaType<std::vector<KeyServerTestResultType>>(
"std::vector<KeyServerTestResultType>");
}
-void GpgFrontend::UI::ListedKeyServerTestTask::run() {
- SetFinishAfterRun(false);
-
+auto GpgFrontend::UI::ListedKeyServerTestTask::Run() -> int {
size_t index = 0;
for (const auto& url : urls_) {
auto key_url = QUrl{url};
- SPDLOG_DEBUG("key server request: {}", key_url.host().toStdString());
+ GF_UI_LOG_DEBUG("key server request: {}", key_url.host().toStdString());
auto* network_reply = network_manager_->get(QNetworkRequest{key_url});
auto* timer = new QTimer(this);
connect(network_reply, &QNetworkReply::finished, this,
[this, index, network_reply]() {
- SPDLOG_DEBUG("key server domain reply: {}",
- urls_[index].toStdString());
+ GF_UI_LOG_DEBUG("key server domain reply: {}",
+ urls_[index].toStdString());
this->slot_process_network_reply(index, network_reply);
});
connect(timer, &QTimer::timeout, this, [this, index, network_reply]() {
- SPDLOG_DEBUG("timeout for key server: {}", urls_[index].toStdString());
+ GF_UI_LOG_DEBUG("timeout for key server: {}", urls_[index].toStdString());
if (network_reply->isRunning()) {
network_reply->abort();
this->slot_process_network_reply(index, network_reply);
@@ -66,24 +68,26 @@ void GpgFrontend::UI::ListedKeyServerTestTask::run() {
});
timer->start(timeout_);
-
index++;
}
+
+ return 0;
}
void GpgFrontend::UI::ListedKeyServerTestTask::slot_process_network_reply(
int index, QNetworkReply* reply) {
if (!reply->isRunning() && reply->error() == QNetworkReply::NoError) {
- result_[index] = kTestResultType_Success;
+ result_[index] = kTEST_RESULT_TYPE_SUCCESS;
} else {
- if (!reply->isFinished())
- result_[index] = kTestResultType_Timeout;
- else
- result_[index] = kTestResultType_Error;
+ if (!reply->isFinished()) {
+ result_[index] = kTEST_RESULT_TYPE_TIMEOUT;
+ } else {
+ result_[index] = kTEST_RESULT_TYPE_ERROR;
+ }
}
if (++result_count_ == urls_.size()) {
emit SignalKeyServerListTestResult(result_);
- emit SignalTaskRunnableEnd(0);
+ emit SignalTaskShouldEnd(0);
}
}
diff --git a/src/ui/thread/ListedKeyServerTestTask.h b/src/ui/thread/ListedKeyServerTestTask.h
index aa1bac5e..fdd036d4 100644
--- a/src/ui/thread/ListedKeyServerTestTask.h
+++ b/src/ui/thread/ListedKeyServerTestTask.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,15 +19,21 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_LISTEDKEYSERVERTESTTHREAD_H
-#define GPGFRONTEND_LISTEDKEYSERVERTESTTHREAD_H
+#pragma once
#include "GpgFrontendUI.h"
+#include "core/thread/ThreadingModel.h"
+
+class QNetworkAccessManager;
+class QNetworkReply;
+
namespace GpgFrontend::UI {
/**
@@ -38,29 +44,28 @@ class ListedKeyServerTestTask : public Thread::Task {
Q_OBJECT
public:
enum KeyServerTestResultType {
- kTestResultType_Success,
- kTestResultType_Timeout,
- kTestResultType_Error,
+ kTEST_RESULT_TYPE_SUCCESS,
+ kTEST_RESULT_TYPE_TIMEOUT,
+ kTEST_RESULT_TYPE_ERROR,
};
- explicit ListedKeyServerTestTask(const QStringList& urls, int timeout,
+ explicit ListedKeyServerTestTask(QStringList urls, int timeout,
QWidget* parent = nullptr);
- signals:
/**
* @brief
*
- * @param result
*/
- void SignalKeyServerListTestResult(
- std::vector<KeyServerTestResultType> result);
+ auto Run() -> int override;
- protected:
+ signals:
/**
* @brief
*
+ * @param result
*/
- void run() override;
+ void SignalKeyServerListTestResult(
+ std::vector<KeyServerTestResultType> result);
private:
QStringList urls_; ///<
@@ -81,5 +86,3 @@ class ListedKeyServerTestTask : public Thread::Task {
} // namespace GpgFrontend::UI
class TestListedKeyServerThread {};
-
-#endif // GPGFRONTEND_LISTEDKEYSERVERTESTTHREAD_H
diff --git a/src/ui/thread/ProxyConnectionTestTask.cpp b/src/ui/thread/ProxyConnectionTestTask.cpp
index c7d623d7..6b0993fe 100644
--- a/src/ui/thread/ProxyConnectionTestTask.cpp
+++ b/src/ui/thread/ProxyConnectionTestTask.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,35 +19,39 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "ProxyConnectionTestTask.h"
+#include <QtNetwork>
+
GpgFrontend::UI::ProxyConnectionTestTask::ProxyConnectionTestTask(QString url,
int timeout)
: Task("proxy_connection_test_task"),
url_(std::move(url)),
timeout_(timeout),
- network_manager_(new QNetworkAccessManager(this)) {}
-
-void GpgFrontend::UI::ProxyConnectionTestTask::run() {
- SetFinishAfterRun(false);
+ network_manager_(new QNetworkAccessManager(this)) {
+ HoldOnLifeCycle(true);
+}
+auto GpgFrontend::UI::ProxyConnectionTestTask::Run() -> int {
auto* network_reply = network_manager_->get(QNetworkRequest{url_});
auto* timer = new QTimer(this);
connect(network_reply, &QNetworkReply::finished, this,
[this, network_reply]() {
- SPDLOG_DEBUG("key server domain reply: {} received",
- url_.toStdString());
+ GF_UI_LOG_DEBUG("key server domain reply: {} received",
+ url_.toStdString());
this->slot_process_network_reply(network_reply);
});
connect(timer, &QTimer::timeout, this, [this, network_reply]() {
- SPDLOG_DEBUG("timeout for key server: {}", url_.toStdString());
+ GF_UI_LOG_DEBUG("timeout for key server: {}", url_.toStdString());
if (network_reply->isRunning()) {
network_reply->abort();
this->slot_process_network_reply(network_reply);
@@ -55,13 +59,14 @@ void GpgFrontend::UI::ProxyConnectionTestTask::run() {
});
timer->start(timeout_);
+ return 0;
}
void GpgFrontend::UI::ProxyConnectionTestTask::slot_process_network_reply(
QNetworkReply* reply) {
auto buffer = reply->readAll();
- SPDLOG_DEBUG("key server domain reply: {}, buffer size: {}",
- url_.toStdString(), buffer.size());
+ GF_UI_LOG_DEBUG("key server domain reply: {}, buffer size: {}",
+ url_.toStdString(), buffer.size());
if (reply->error() == QNetworkReply::NoError && !buffer.isEmpty()) {
result_ = "Reachable";
@@ -70,5 +75,5 @@ void GpgFrontend::UI::ProxyConnectionTestTask::slot_process_network_reply(
}
emit SignalProxyConnectionTestResult(result_);
- emit SignalTaskRunnableEnd(0);
+ emit SignalTaskShouldEnd(0);
}
diff --git a/src/ui/thread/ProxyConnectionTestTask.h b/src/ui/thread/ProxyConnectionTestTask.h
index 38e78ae4..c15f45bc 100644
--- a/src/ui/thread/ProxyConnectionTestTask.h
+++ b/src/ui/thread/ProxyConnectionTestTask.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,19 +19,20 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_PROXYCONNECTIONTESTTHREAD_H
-#define GPGFRONTEND_PROXYCONNECTIONTESTTHREAD_H
-
-class ProxyConnectionTestThread {};
-
-#include <utility>
+#pragma once
#include "GpgFrontendUI.h"
+#include "core/thread/ThreadingModel.h"
+
+class QNetworkAccessManager;
+class QNetworkReply;
namespace GpgFrontend::UI {
@@ -51,6 +52,12 @@ class ProxyConnectionTestTask : public Thread::Task {
*/
explicit ProxyConnectionTestTask(QString url, int timeout);
+ /**
+ * @brief
+ *
+ */
+ auto Run() -> int override;
+
signals:
/**
* @brief
@@ -59,14 +66,13 @@ class ProxyConnectionTestTask : public Thread::Task {
*/
void SignalProxyConnectionTestResult(const QString& result);
- protected:
+ private slots:
+
/**
* @brief
*
+ * @param reply
*/
- void run() override;
-
- private slots:
void slot_process_network_reply(QNetworkReply* reply);
private:
@@ -77,5 +83,3 @@ class ProxyConnectionTestTask : public Thread::Task {
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_PROXYCONNECTIONTESTTHREAD_H
diff --git a/src/ui/thread/VersionCheckTask.cpp b/src/ui/thread/VersionCheckTask.cpp
deleted file mode 100644
index e9490e1c..00000000
--- a/src/ui/thread/VersionCheckTask.cpp
+++ /dev/null
@@ -1,178 +0,0 @@
-/**
- * Copyright (C) 2021 Saturneric
- *
- * This file is part of GpgFrontend.
- *
- * GpgFrontend is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GpgFrontend is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
- *
- * The initial version of the source code is inherited from
- * the gpg4usb project, which is under GPL-3.0-or-later.
- *
- * All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#include "VersionCheckTask.h"
-
-#include <QMetaType>
-#include <memory>
-
-#include "GpgFrontendBuildInfo.h"
-
-namespace GpgFrontend::UI {
-
-VersionCheckTask::VersionCheckTask()
- : Task("version_check_task"),
- network_manager_(new QNetworkAccessManager(this)),
- current_version_(std::string("v") + std::to_string(VERSION_MAJOR) + "." +
- std::to_string(VERSION_MINOR) + "." +
- std::to_string(VERSION_PATCH)) {
- qRegisterMetaType<SoftwareVersion>("SoftwareVersion");
- version_.current_version = current_version_;
-}
-
-void VersionCheckTask::Run() {
- SetFinishAfterRun(false);
-
- try {
- using namespace nlohmann;
- SPDLOG_DEBUG("current version: {}", current_version_);
- std::string latest_version_url =
- "https://api.github.com/repos/saturneric/gpgfrontend/releases/latest";
-
- QNetworkRequest latest_request;
- latest_request.setUrl(QUrl(latest_version_url.c_str()));
- latest_reply_ = network_manager_->get(latest_request);
- connect(latest_reply_, &QNetworkReply::finished, this,
- &VersionCheckTask::slot_parse_latest_version_info);
-
- // loading done
- version_.load_info_done = true;
-
- } catch (...) {
- SPDLOG_ERROR("unknown error occurred");
- emit SignalTaskRunnableEnd(-1);
- }
-}
-
-void VersionCheckTask::slot_parse_latest_version_info() {
- version_.current_version = current_version_;
-
- try {
- if (latest_reply_ == nullptr ||
- latest_reply_->error() != QNetworkReply::NoError) {
- SPDLOG_ERROR("latest version request error");
- version_.latest_version = current_version_;
- } else {
- latest_reply_bytes_ = latest_reply_->readAll();
-
- auto latest_reply_json =
- nlohmann::json::parse(latest_reply_bytes_.toStdString());
-
- std::string latest_version = latest_reply_json["tag_name"];
-
- SPDLOG_INFO("latest version from Github: {}", latest_version);
-
- QRegularExpression re(R"(^[vV](\d+\.)?(\d+\.)?(\*|\d+))");
- auto version_match = re.match(latest_version.c_str());
- if (version_match.hasMatch()) {
- latest_version = version_match.captured(0).toStdString();
- SPDLOG_DEBUG("latest version matched: {}", latest_version);
- } else {
- latest_version = current_version_;
- SPDLOG_WARN("latest version unknown");
- }
-
- bool prerelease = latest_reply_json["prerelease"],
- draft = latest_reply_json["draft"];
- std::string publish_date = latest_reply_json["published_at"];
- std::string release_note = latest_reply_json["body"];
- version_.latest_version = latest_version;
- version_.latest_prerelease = prerelease;
- version_.latest_draft = draft;
- version_.publish_date = publish_date;
- version_.release_note = release_note;
- }
- } catch (...) {
- SPDLOG_ERROR("unknown error occurred");
- version_.load_info_done = false;
- }
-
- if (latest_reply_ != nullptr) {
- latest_reply_->deleteLater();
- }
-
- try {
- std::string current_version_url =
- "https://api.github.com/repos/saturneric/gpgfrontend/releases/tags/" +
- current_version_;
-
- QNetworkRequest current_request;
- current_request.setUrl(QUrl(current_version_url.c_str()));
- current_reply_ = network_manager_->get(current_request);
-
- connect(current_reply_, &QNetworkReply::finished, this,
- &VersionCheckTask::slot_parse_current_version_info);
- } catch (...) {
- SPDLOG_ERROR("current version request create error");
- emit SignalTaskRunnableEnd(-1);
- }
-}
-
-void VersionCheckTask::slot_parse_current_version_info() {
- try {
- if (current_reply_ == nullptr ||
- current_reply_->error() != QNetworkReply::NoError) {
- if (current_reply_ != nullptr) {
- SPDLOG_ERROR("current version request network error: {}",
- current_reply_->errorString().toStdString());
- } else {
- SPDLOG_ERROR(
- "current version request network error, null reply object");
- }
-
- version_.current_version_found = false;
- version_.load_info_done = false;
- } else {
- version_.current_version_found = true;
- current_reply_bytes_ = current_reply_->readAll();
- SPDLOG_DEBUG("current version: {}", current_reply_bytes_.size());
- auto current_reply_json =
- nlohmann::json::parse(current_reply_bytes_.toStdString());
- bool current_prerelease = current_reply_json["prerelease"],
- current_draft = current_reply_json["draft"];
- version_.latest_prerelease = current_prerelease;
- version_.latest_draft = current_draft;
- version_.load_info_done = true;
- }
- } catch (...) {
- SPDLOG_ERROR("unknown error occurred");
- version_.load_info_done = false;
- }
-
- SPDLOG_DEBUG("current version parse done: {}",
- version_.current_version_found);
-
- if (current_reply_ != nullptr) {
- current_reply_->deleteLater();
- }
-
- emit SignalUpgradeVersion(version_);
- emit SignalTaskRunnableEnd(0);
-}
-
-} // namespace GpgFrontend::UI
diff --git a/src/ui/widgets/FilePage.cpp b/src/ui/widgets/FilePage.cpp
index b5243da0..27f4205f 100644
--- a/src/ui/widgets/FilePage.cpp
+++ b/src/ui/widgets/FilePage.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,40 +28,29 @@
#include "ui/widgets/FilePage.h"
-#include <string>
-
-#include "core/function/ArchiveFileOperator.h"
-#include "core/function/gpg/GpgFileOpera.h"
-#include "ui/SignalStation.h"
+#include "core/GpgModel.h"
+#include "ui/UISignalStation.h"
#include "ui/main_window/MainWindow.h"
#include "ui_FilePage.h"
namespace GpgFrontend::UI {
-FilePage::FilePage(QWidget* parent)
- : QWidget(parent), ui_(std::make_shared<Ui_FilePage>()) {
+FilePage::FilePage(QWidget* parent, const QString& target_path)
+ : QWidget(parent),
+ ui_(GpgFrontend::SecureCreateSharedObject<Ui_FilePage>()),
+ file_tree_view_(new FileTreeView(this, target_path)) {
ui_->setupUi(this);
+ ui_->trewViewLayout->addWidget(file_tree_view_);
- first_parent_ = parent;
-
- dir_model_ = new QFileSystemModel();
- dir_model_->setRootPath(QDir::currentPath());
- dir_model_->setFilter(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);
-
- ui_->fileTreeView->setModel(dir_model_);
- ui_->fileTreeView->setColumnWidth(0, 320);
- ui_->fileTreeView->sortByColumn(0, Qt::AscendingOrder);
- m_path_ = std::filesystem::path(dir_model_->rootPath().toStdString());
-
- create_popup_menu();
-
- connect(ui_->upPathButton, &QPushButton::clicked, this,
- &FilePage::slot_up_level);
+ connect(ui_->upPathButton, &QPushButton::clicked, file_tree_view_,
+ &FileTreeView::SlotUpLevel);
connect(ui_->refreshButton, &QPushButton::clicked, this,
&FilePage::SlotGoPath);
- ui_->optionsButton->setMenu(option_popup_menu_);
+ connect(this->ui_->newDirButton, &QPushButton::clicked, file_tree_view_,
+ &FileTreeView::SlotMkdir);
- ui_->pathEdit->setText(dir_model_->rootPath());
+ ui_->pathEdit->setText(
+ QString::fromStdString(file_tree_view_->GetCurrentPath().u8string()));
path_edit_completer_ = new QCompleter(this);
path_complete_model_ = new QStringListModel();
@@ -71,12 +60,19 @@ FilePage::FilePage(QWidget* parent)
QCompleter::UnfilteredPopupCompletion);
ui_->pathEdit->setCompleter(path_edit_completer_);
- connect(ui_->fileTreeView, &QTreeView::clicked, this,
- &FilePage::slot_file_tree_view_item_clicked);
- connect(ui_->fileTreeView, &QTreeView::doubleClicked, this,
- &FilePage::slot_file_tree_view_item_double_clicked);
- connect(ui_->fileTreeView, &QTreeView::customContextMenuRequested, this,
- &FilePage::onCustomContextMenu);
+ option_popup_menu_ = new QMenu(this);
+ auto* show_hidden_act = new QAction(tr("Show Hidden File"), this);
+ show_hidden_act->setCheckable(true);
+ connect(show_hidden_act, &QAction::triggered, file_tree_view_,
+ &FileTreeView::SlotShowHiddenFile);
+ option_popup_menu_->addAction(show_hidden_act);
+
+ auto* show_system_act = new QAction(tr("Show System File"), this);
+ show_system_act->setCheckable(true);
+ connect(show_system_act, &QAction::triggered, file_tree_view_,
+ &FileTreeView::SlotShowSystemFile);
+ option_popup_menu_->addAction(show_system_act);
+ ui_->optionsButton->setMenu(option_popup_menu_);
connect(ui_->pathEdit, &QLineEdit::textChanged, [=]() {
auto path = ui_->pathEdit->text();
@@ -94,387 +90,84 @@ FilePage::FilePage(QWidget* parent)
}
});
- connect(this, &FilePage::SignalRefreshInfoBoard, SignalStation::GetInstance(),
- &SignalStation::SignalRefreshInfoBoard);
-}
-
-void FilePage::slot_file_tree_view_item_clicked(const QModelIndex& index) {
-#ifdef WINDOWS
- selected_path_ = std::filesystem::path(
- dir_model_->fileInfo(index).absoluteFilePath().toStdU16String());
-#else
- selected_path_ = std::filesystem::path(
- dir_model_->fileInfo(index).absoluteFilePath().toStdString());
-#endif
-
- m_path_ = selected_path_;
- SPDLOG_DEBUG("selected path: {}", selected_path_.u8string());
-
- selected_path_ = std::filesystem::path(selected_path_);
- MainWindow::CryptoMenu::OperationType operation_type =
- MainWindow::CryptoMenu::None;
-
- if (index.isValid()) {
- QFileInfo info(QString::fromStdString(selected_path_.u8string()));
-
- if ((info.isDir() || info.isFile()) &&
- (info.suffix() != "gpg" && info.suffix() != "pgp" &&
- info.suffix() != "sig" && info.suffix() != "asc")) {
- operation_type |= MainWindow::CryptoMenu::Encrypt;
- }
-
- if ((info.isDir() || info.isFile()) &&
- (info.suffix() != "gpg" && info.suffix() != "pgp" &&
- info.suffix() != "sig" && info.suffix() != "asc")) {
- operation_type |= MainWindow::CryptoMenu::EncryptAndSign;
- }
-
- if (info.isFile() && (info.suffix() == "gpg" || info.suffix() == "pgp" ||
- info.suffix() == "asc")) {
- operation_type |= MainWindow::CryptoMenu::Decrypt;
- operation_type |= MainWindow::CryptoMenu::DecryptAndVerify;
- }
-
- if (info.isFile() && (info.suffix() != "gpg" && info.suffix() != "pgp" &&
- info.suffix() != "sig" && info.suffix() != "asc")) {
- operation_type |= MainWindow::CryptoMenu::Sign;
- }
-
- if (info.isFile() && (info.suffix() == "sig" || info.suffix() == "gpg" ||
- info.suffix() == "pgp" || info.suffix() == "asc")) {
- operation_type |= MainWindow::CryptoMenu::Verify;
- }
- }
-
- auto main_window = qobject_cast<MainWindow*>(first_parent_);
- if (main_window != nullptr) main_window->SetCryptoMenuStatus(operation_type);
-}
-
-void FilePage::slot_up_level() {
- QModelIndex currentRoot = ui_->fileTreeView->rootIndex();
-#ifdef WINDOWS
- auto str_path =
- dir_model_->fileInfo(currentRoot).absoluteFilePath().toStdU16String();
-#else
- auto str_path = dir_model_->fileInfo(currentRoot)
- .absoluteFilePath()
- .toUtf8()
- .toStdString();
-#endif
- std::filesystem::path path_obj(str_path);
-
- m_path_ = path_obj;
- SPDLOG_DEBUG("get path: {}", m_path_.u8string());
- if (m_path_.has_parent_path() && !m_path_.parent_path().empty()) {
- m_path_ = m_path_.parent_path();
- SPDLOG_DEBUG("parent path: {}", m_path_.u8string());
- ui_->pathEdit->setText(m_path_.u8string().c_str());
- this->SlotGoPath();
- }
-}
-
-void FilePage::slot_file_tree_view_item_double_clicked(
- const QModelIndex& index) {
- QFileInfo file_info(dir_model_->fileInfo(index).absoluteFilePath());
- if (file_info.isFile()) {
- slot_open_item();
- } else {
- ui_->pathEdit->setText(file_info.filePath());
- SlotGoPath();
+ connect(this, &FilePage::SignalRefreshInfoBoard,
+ UISignalStation::GetInstance(),
+ &UISignalStation::SignalRefreshInfoBoard);
+ connect(file_tree_view_, &FileTreeView::SignalPathChanged, this,
+ [this](const QString& path) { this->ui_->pathEdit->setText(path); });
+ connect(file_tree_view_, &FileTreeView::SignalPathChanged, this,
+ &FilePage::SignalPathChanged);
+
+ auto* main_window = qobject_cast<MainWindow*>(this->parent());
+ if (main_window != nullptr) {
+ connect(file_tree_view_, &FileTreeView::SignalOpenFile, main_window,
+ &MainWindow::SlotOpenFile);
+
+ connect(file_tree_view_, &FileTreeView::SignalSelectedChanged, this,
+ [main_window](const QString& selected_path) {
+ MainWindow::CryptoMenu::OperationType operation_type =
+ MainWindow::CryptoMenu::None;
+
+ // abort...
+ if (selected_path.isEmpty()) return;
+
+ QFileInfo const info(selected_path);
+
+ if ((info.isDir() || info.isFile()) &&
+ (info.suffix() != "gpg" && info.suffix() != "pgp" &&
+ info.suffix() != "sig" && info.suffix() != "asc")) {
+ operation_type |= MainWindow::CryptoMenu::Encrypt;
+ }
+
+ if ((info.isDir() || info.isFile()) &&
+ (info.suffix() != "gpg" && info.suffix() != "pgp" &&
+ info.suffix() != "sig" && info.suffix() != "asc")) {
+ operation_type |= MainWindow::CryptoMenu::EncryptAndSign;
+ }
+
+ if (info.isFile() &&
+ (info.suffix() == "gpg" || info.suffix() == "pgp" ||
+ info.suffix() == "asc")) {
+ operation_type |= MainWindow::CryptoMenu::Decrypt;
+ operation_type |= MainWindow::CryptoMenu::DecryptAndVerify;
+ }
+
+ if (info.isFile() &&
+ (info.suffix() != "gpg" && info.suffix() != "pgp" &&
+ info.suffix() != "sig" && info.suffix() != "asc")) {
+ operation_type |= MainWindow::CryptoMenu::Sign;
+ }
+
+ if (info.isFile() &&
+ (info.suffix() == "sig" || info.suffix() == "gpg" ||
+ info.suffix() == "pgp" || info.suffix() == "asc")) {
+ operation_type |= MainWindow::CryptoMenu::Verify;
+ }
+
+ main_window->SetCryptoMenuStatus(operation_type);
+ });
}
}
-QString FilePage::GetSelected() const {
- return QString::fromStdString(selected_path_.u8string());
+auto FilePage::GetSelected() const -> QString {
+ return QString::fromStdString(file_tree_view_->GetSelectedPath().string());
}
void FilePage::SlotGoPath() {
#ifdef WINDOWS
- std::filesystem::path path_edit_obj(ui_->pathEdit->text().toStdU16String());
+ std::filesystem::path target_path(ui_->pathEdit->text().toStdU16String());
#else
- std::filesystem::path path_edit_obj(ui_->pathEdit->text().toStdString());
+ std::filesystem::path target_path(ui_->pathEdit->text().toStdString());
#endif
-
- m_path_ = m_path_ != path_edit_obj ? path_edit_obj : m_path_;
- auto fileInfo = QFileInfo(m_path_.string().c_str());
- if (fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) {
-#ifdef WINDOWS
- m_path_ = std::filesystem::path(fileInfo.filePath().toStdU16String());
-#else
- m_path_ = std::filesystem::path(fileInfo.filePath().toStdString());
-#endif
-
- SPDLOG_DEBUG("set path: {}", m_path_.u8string());
- ui_->fileTreeView->setRootIndex(dir_model_->index(fileInfo.filePath()));
- dir_model_->setRootPath(fileInfo.filePath());
- for (int i = 1; i < dir_model_->columnCount(); ++i) {
- ui_->fileTreeView->resizeColumnToContents(i);
- }
- ui_->pathEdit->setText(QString::fromStdString(m_path_.u8string()));
- } else {
- QMessageBox::critical(
- this, _("Error"),
- _("The path is not exists, unprivileged or unreachable."));
- }
- emit SignalPathChanged(QString::fromStdString(m_path_.u8string()));
-}
-
-void FilePage::create_popup_menu() {
- popup_menu_ = new QMenu();
-
- ui_->actionOpenFile->setText(_("Open"));
- connect(ui_->actionOpenFile, &QAction::triggered, this,
- &FilePage::slot_open_item);
- ui_->actionRenameFile->setText(_("Rename"));
- connect(ui_->actionRenameFile, &QAction::triggered, this,
- &FilePage::slot_rename_item);
- ui_->actionDeleteFile->setText(_("Delete"));
- connect(ui_->actionDeleteFile, &QAction::triggered, this,
- &FilePage::slot_delete_item);
-
- ui_->actionCalculateHash->setText(_("Calculate Hash"));
- connect(ui_->actionCalculateHash, &QAction::triggered, this,
- &FilePage::slot_calculate_hash);
-
- ui_->actionMakeDirectory->setText(_("Directory"));
- connect(ui_->actionMakeDirectory, &QAction::triggered, this,
- &FilePage::slot_mkdir);
-
- ui_->actionCreateEmptyFile->setText(_("File"));
- connect(ui_->actionCreateEmptyFile, &QAction::triggered, this,
- &FilePage::slot_create_empty_file);
-
- ui_->actionCompressFiles->setText(_("Compress..."));
- ui_->actionCompressFiles->setVisible(false);
- connect(ui_->actionCompressFiles, &QAction::triggered, this,
- &FilePage::slot_compress_files);
-
- ui_->actionOpenWithSystemDefaultApplication->setText(
- _("Open with Default System Application"));
- connect(ui_->actionOpenWithSystemDefaultApplication, &QAction::triggered,
- this, &FilePage::slot_open_item_by_system_application);
-
- auto new_item_action_menu = new QMenu(this);
- new_item_action_menu->setTitle(_("New"));
- new_item_action_menu->addAction(ui_->actionCreateEmptyFile);
- new_item_action_menu->addAction(ui_->actionMakeDirectory);
-
- popup_menu_->addAction(ui_->actionOpenFile);
- popup_menu_->addAction(ui_->actionOpenWithSystemDefaultApplication);
-
- popup_menu_->addSeparator();
- popup_menu_->addMenu(new_item_action_menu);
- popup_menu_->addSeparator();
-
- popup_menu_->addAction(ui_->actionRenameFile);
- popup_menu_->addAction(ui_->actionDeleteFile);
- popup_menu_->addAction(ui_->actionCompressFiles);
- popup_menu_->addAction(ui_->actionCalculateHash);
-
- option_popup_menu_ = new QMenu();
-
- auto showHiddenAct = new QAction(_("Show Hidden File"), this);
- showHiddenAct->setCheckable(true);
- connect(showHiddenAct, &QAction::triggered, this, [&](bool checked) {
- SPDLOG_DEBUG("set hidden: {}", checked);
- if (checked)
- dir_model_->setFilter(dir_model_->filter() | QDir::Hidden);
- else
- dir_model_->setFilter(dir_model_->filter() & ~QDir::Hidden);
- dir_model_->setRootPath(m_path_.u8string().c_str());
- });
- option_popup_menu_->addAction(showHiddenAct);
-
- auto showSystemAct = new QAction(_("Show System File"), this);
- showSystemAct->setCheckable(true);
- connect(showSystemAct, &QAction::triggered, this, [&](bool checked) {
- SPDLOG_DEBUG("set hidden: {}", checked);
- if (checked)
- dir_model_->setFilter(dir_model_->filter() | QDir::System);
- else
- dir_model_->setFilter(dir_model_->filter() & ~QDir::System);
- dir_model_->setRootPath(m_path_.u8string().c_str());
- });
- option_popup_menu_->addAction(showSystemAct);
-}
-
-void FilePage::onCustomContextMenu(const QPoint& point) {
- QModelIndex index = ui_->fileTreeView->indexAt(point);
- SPDLOG_DEBUG("right click: {}", selected_path_.u8string());
-
-#ifdef WINDOWS
- auto index_dir_str =
- dir_model_->fileInfo(index).absoluteFilePath().toStdU16String();
-#else
- auto index_dir_str =
- dir_model_->fileInfo(index).absoluteFilePath().toStdString();
-#endif
-
- selected_path_ = std::filesystem::path(index_dir_str);
-
- // update crypt menu
- slot_file_tree_view_item_clicked(index);
-
- if (index.isValid()) {
- ui_->actionOpenFile->setEnabled(true);
- ui_->actionRenameFile->setEnabled(true);
- ui_->actionDeleteFile->setEnabled(true);
-
- QFileInfo info(QString::fromStdString(selected_path_.u8string()));
- ui_->actionCalculateHash->setEnabled(info.isFile() && info.isReadable());
- } else {
- ui_->actionOpenFile->setEnabled(false);
- ui_->actionRenameFile->setEnabled(false);
- ui_->actionDeleteFile->setEnabled(false);
-
- ui_->actionCalculateHash->setEnabled(false);
- }
- popup_menu_->exec(ui_->fileTreeView->viewport()->mapToGlobal(point));
-}
-
-void FilePage::slot_open_item() {
- QFileInfo info(QString::fromStdString(selected_path_.u8string()));
- if (info.isDir()) {
- if (info.isReadable() && info.isExecutable()) {
- const auto file_path = info.filePath().toUtf8().toStdString();
- SPDLOG_DEBUG("set path: {}", file_path);
- ui_->pathEdit->setText(info.filePath().toUtf8());
- SlotGoPath();
- } else {
- QMessageBox::critical(this, _("Error"),
- _("The directory is unprivileged or unreachable."));
- }
- } else {
- if (info.isReadable()) {
- // handle normal text or binary file
- auto main_window = qobject_cast<MainWindow*>(first_parent_);
- auto qt_open_path = QString::fromStdString(selected_path_.u8string());
- SPDLOG_DEBUG("open item: {}", qt_open_path.toStdString());
- if (main_window != nullptr) main_window->SlotOpenFile(qt_open_path);
- } else {
- QMessageBox::critical(this, _("Error"),
- _("The file is unprivileged or unreachable."));
- }
- }
-}
-
-void FilePage::slot_open_item_by_system_application() {
- QFileInfo info(QString::fromStdString(selected_path_.u8string()));
- auto q_selected_path = QString::fromStdString(selected_path_.u8string());
- if (info.isDir()) {
- const auto file_path = info.filePath().toUtf8().toStdString();
- QDesktopServices::openUrl(QUrl::fromLocalFile(q_selected_path));
-
- } else {
- QDesktopServices::openUrl(QUrl::fromLocalFile(q_selected_path));
- }
-}
-
-void FilePage::slot_rename_item() {
- auto new_name_path = selected_path_, old_name_path = selected_path_;
- auto old_name = old_name_path.filename();
- new_name_path = new_name_path.remove_filename();
-
- bool ok;
- auto text = QInputDialog::getText(
- this, _("Rename"), _("New Filename"), QLineEdit::Normal,
- QString::fromStdString(old_name.u8string()), &ok);
- if (ok && !text.isEmpty()) {
- try {
-#ifdef WINDOWS
- new_name_path /= text.toStdU16String();
-#else
- new_name_path /= text.toStdString();
-#endif
- SPDLOG_DEBUG("new name path: {}", new_name_path.u8string());
- std::filesystem::rename(old_name_path, new_name_path);
- // refresh
- this->SlotGoPath();
- } catch (...) {
- SPDLOG_ERROR("rename error: {}", new_name_path.u8string());
- QMessageBox::critical(this, _("Error"),
- _("Unable to rename the file or folder."));
- }
- }
-}
-
-void FilePage::slot_delete_item() {
- QModelIndex index = ui_->fileTreeView->currentIndex();
- QVariant data = ui_->fileTreeView->model()->data(index);
-
- auto ret = QMessageBox::warning(this, _("Warning"),
- _("Are you sure you want to delete it?"),
- QMessageBox::Ok | QMessageBox::Cancel);
-
- if (ret == QMessageBox::Cancel) return;
-
- SPDLOG_DEBUG("delete item: {}", data.toString().toStdString());
-
- if (!dir_model_->remove(index)) {
- QMessageBox::critical(this, _("Error"),
- _("Unable to delete the file or folder."));
- }
-}
-
-void FilePage::slot_calculate_hash() {
- auto info_str = FileOperator::CalculateHash(selected_path_);
- emit SignalRefreshInfoBoard(info_str.c_str(), InfoBoardStatus::INFO_ERROR_OK);
-}
-
-void FilePage::slot_mkdir() {
- auto index = ui_->fileTreeView->rootIndex();
-
- QString new_dir_name;
- bool ok;
- new_dir_name =
- QInputDialog::getText(this, _("Make New Directory"), _("Directory Name"),
- QLineEdit::Normal, new_dir_name, &ok);
- if (ok && !new_dir_name.isEmpty()) {
- dir_model_->mkdir(index, new_dir_name);
- }
-}
-
-void FilePage::slot_create_empty_file() {
-#ifdef WINDOWS
- auto root_path_str = dir_model_->rootPath().toStdU16String();
-#else
- auto root_path_str = dir_model_->rootPath().toStdString();
-#endif
- std::filesystem::path root_path(root_path_str);
-
- QString new_file_name;
- bool ok;
- new_file_name = QInputDialog::getText(this, _("Create Empty File"),
- _("Filename (you can given extension)"),
- QLineEdit::Normal, new_file_name, &ok);
- if (ok && !new_file_name.isEmpty()) {
-#ifdef WINDOWS
- auto file_path = root_path / new_file_name.toStdU16String();
-#else
- auto file_path = root_path / new_file_name.toStdString();
-#endif
- QFile new_file(file_path.u8string().c_str());
- if (!new_file.open(QIODevice::WriteOnly | QIODevice::NewOnly)) {
- QMessageBox::critical(this, _("Error"), _("Unable to create the file."));
- }
- new_file.close();
- }
+ file_tree_view_->SlotGoPath(target_path);
}
void FilePage::keyPressEvent(QKeyEvent* event) {
- SPDLOG_DEBUG("key press: {}", event->key());
+ GF_UI_LOG_DEBUG("file page notices key press by user: {}", event->key());
if (ui_->pathEdit->hasFocus() &&
(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)) {
SlotGoPath();
- } else if (ui_->fileTreeView->currentIndex().isValid()) {
- if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)
- slot_open_item();
- else if (event->key() == Qt::Key_Delete ||
- event->key() == Qt::Key_Backspace)
- slot_delete_item();
}
}
-void FilePage::slot_compress_files() {}
-
} // namespace GpgFrontend::UI
diff --git a/src/ui/widgets/FilePage.h b/src/ui/widgets/FilePage.h
index 74548b13..da5370a2 100644
--- a/src/ui/widgets/FilePage.h
+++ b/src/ui/widgets/FilePage.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,16 +20,16 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_FILEPAGE_H
-#define GPGFRONTEND_FILEPAGE_H
+#pragma once
#include "ui/GpgFrontendUI.h"
+#include "ui/widgets/FileTreeView.h"
#include "ui/widgets/InfoBoardWidget.h"
class Ui_FilePage;
@@ -48,14 +48,14 @@ class FilePage : public QWidget {
*
* @param parent
*/
- explicit FilePage(QWidget* parent = nullptr);
+ explicit FilePage(QWidget* parent, const QString&);
/**
* @brief Get the Selected object
*
* @return QString
*/
- [[nodiscard]] QString GetSelected() const;
+ [[nodiscard]] auto GetSelected() const -> QString;
public slots:
/**
@@ -82,76 +82,6 @@ class FilePage : public QWidget {
void SignalRefreshInfoBoard(const QString& text,
InfoBoardStatus verify_label_status);
- private slots:
-
- /**
- * @brief
- *
- * @param index
- */
- void slot_file_tree_view_item_clicked(const QModelIndex& index);
-
- /**
- * @brief
- *
- * @param index
- */
- void slot_file_tree_view_item_double_clicked(const QModelIndex& index);
-
- /**
- * @brief
- *
- */
- void slot_up_level();
-
- /**
- * @brief
- *
- */
- void slot_open_item();
-
- /**
- * @brief
- *
- */
- void slot_open_item_by_system_application();
-
- /**
- * @brief
- *
- */
- void slot_rename_item();
-
- /**
- * @brief
- *
- */
- void slot_delete_item();
-
- /**
- * @brief
- *
- */
- void slot_calculate_hash();
-
- /**
- * @brief
- *
- */
- void slot_mkdir();
-
- /**
- * @brief
- *
- */
- void slot_create_empty_file();
-
- /**
- * @brief compress directory into gpg-zip
- *
- */
- void slot_compress_files();
-
protected:
/**
* @brief
@@ -160,34 +90,15 @@ class FilePage : public QWidget {
*/
void keyPressEvent(QKeyEvent* event) override;
- /**
- * @brief
- *
- * @param point
- */
- void onCustomContextMenu(const QPoint& point);
-
private:
- /**
- * @brief Create a popup menu object
- *
- */
- void create_popup_menu();
-
std::shared_ptr<Ui_FilePage> ui_; ///<
- QFileSystemModel* dir_model_; ///<
QCompleter* path_edit_completer_; ///<
QStringListModel* path_complete_model_; ///<
- std::filesystem::path m_path_; ///<
- std::filesystem::path selected_path_; ///<
-
QMenu* popup_menu_{}; ///<
QMenu* option_popup_menu_{}; ///<
- QWidget* first_parent_{}; ///<
+ FileTreeView* file_tree_view_;
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_FILEPAGE_H
diff --git a/src/ui/widgets/FileTreeView.cpp b/src/ui/widgets/FileTreeView.cpp
new file mode 100644
index 00000000..f3556dc9
--- /dev/null
+++ b/src/ui/widgets/FileTreeView.cpp
@@ -0,0 +1,403 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "FileTreeView.h"
+
+#include "core/utils/IOUtils.h"
+#include "ui/UISignalStation.h"
+
+namespace GpgFrontend::UI {
+
+FileTreeView::FileTreeView(QWidget* parent, const QString& target_path)
+ : QTreeView(parent) {
+ dir_model_ = new QFileSystemModel();
+ dir_model_->setRootPath(target_path.isEmpty() ? QDir::currentPath()
+ : target_path);
+ dir_model_->setFilter(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);
+
+ this->setModel(dir_model_);
+ this->setColumnWidth(0, 320);
+ this->sortByColumn(0, Qt::AscendingOrder);
+ current_path_ = std::filesystem::path(dir_model_->rootPath().toStdString());
+
+ slot_create_popup_menu();
+ this->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(this, &QWidget::customContextMenuRequested, this,
+ &FileTreeView::slot_show_custom_context_menu);
+ connect(this, &QTreeView::doubleClicked, this,
+ &FileTreeView::slot_file_tree_view_item_double_clicked);
+}
+
+void FileTreeView::selectionChanged(const QItemSelection& selected,
+ const QItemSelection& deselected) {
+ QTreeView::selectionChanged(selected, deselected);
+
+ if (!selected.indexes().empty()) {
+ selected_path_ = dir_model_->fileInfo(selected.indexes().first())
+ .filesystemAbsoluteFilePath();
+ GF_UI_LOG_DEBUG("file tree view selected target path: {}",
+ selected_path_.u8string());
+ emit SignalSelectedChanged(QString::fromStdString(selected_path_));
+ } else {
+ selected_path_ = std::filesystem::path{};
+ }
+}
+
+void FileTreeView::SlotGoPath(const std::filesystem::path& target_path) {
+ auto file_info = QFileInfo(target_path);
+ if (file_info.isDir() && file_info.isReadable() && file_info.isExecutable()) {
+ current_path_ = file_info.filesystemAbsoluteFilePath();
+ GF_UI_LOG_DEBUG("file tree view set target path: {}",
+ current_path_.u8string());
+ this->setRootIndex(dir_model_->index(file_info.filePath()));
+ dir_model_->setRootPath(file_info.filePath());
+ for (int i = 1; i < dir_model_->columnCount(); ++i) {
+ this->resizeColumnToContents(i);
+ }
+ } else {
+ QMessageBox::critical(
+ this, tr("Error"),
+ tr("The path is not exists, unprivileged or unreachable."));
+ }
+ emit SignalPathChanged(QString::fromStdString(current_path_.u8string()));
+}
+
+void FileTreeView::slot_file_tree_view_item_double_clicked(
+ const QModelIndex& index) {
+ QFileInfo const file_info(dir_model_->fileInfo(index).absoluteFilePath());
+ if (file_info.isFile()) {
+ if (file_info.isReadable()) {
+ emit SignalOpenFile(file_info.absoluteFilePath());
+ } else {
+ QMessageBox::critical(this, tr("Error"),
+ tr("The file is unprivileged or unreachable."));
+ }
+ } else {
+ SlotGoPath(file_info.filesystemAbsoluteFilePath());
+ }
+}
+
+void FileTreeView::SlotUpLevel() {
+ QModelIndex const current_root = this->rootIndex();
+
+ auto target_path =
+ dir_model_->fileInfo(current_root).filesystemAbsoluteFilePath();
+ if (target_path.has_parent_path() && !target_path.parent_path().empty()) {
+ target_path = target_path.parent_path();
+ GF_UI_LOG_DEBUG("file tree view go parent path: {}",
+ target_path.u8string());
+ this->SlotGoPath(target_path);
+ }
+ current_path_ = target_path;
+}
+
+auto FileTreeView::GetCurrentPath() -> std::filesystem::path {
+ return current_path_;
+}
+
+void FileTreeView::SlotShowSystemFile(bool on) {
+ auto filters = on ? dir_model_->filter() | QDir::System
+ : dir_model_->filter() & ~QDir::System;
+ dir_model_->setFilter(filters);
+ dir_model_->setRootPath(QString::fromStdString(current_path_.u8string()));
+}
+
+void FileTreeView::SlotShowHiddenFile(bool on) {
+ auto filters = on ? dir_model_->filter() | QDir::Hidden
+ : dir_model_->filter() & ~QDir::Hidden;
+ dir_model_->setFilter(filters);
+ dir_model_->setRootPath(QString::fromStdString(current_path_.u8string()));
+}
+
+auto FileTreeView::GetPathByClickPoint(const QPoint& point)
+ -> std::filesystem::path {
+ auto const index = this->indexAt(point);
+
+ if (!index.isValid()) {
+ return {};
+ }
+
+ auto index_path = dir_model_->fileInfo(index).filesystemAbsoluteFilePath();
+ GF_UI_LOG_DEBUG("file tree view right click on: {}", index_path.string());
+ return index_path;
+}
+
+auto FileTreeView::GetSelectedPath() -> std::filesystem::path {
+ return selected_path_;
+}
+
+auto FileTreeView::SlotDeleteSelectedItem() -> void {
+ QModelIndex const index = this->currentIndex();
+ QVariant const data = this->model()->data(index);
+
+ auto ret = QMessageBox::warning(this, tr("Warning"),
+ tr("Are you sure you want to delete it?"),
+ QMessageBox::Ok | QMessageBox::Cancel);
+
+ if (ret == QMessageBox::Cancel) return;
+
+ GF_UI_LOG_DEBUG("delete item: {}", data.toString().toStdString());
+
+ if (!dir_model_->remove(index)) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unable to delete the file or folder."));
+ }
+}
+
+void FileTreeView::SlotMkdir() {
+ auto index = this->rootIndex();
+
+ QString new_dir_name;
+ bool ok;
+ new_dir_name = QInputDialog::getText(this, tr("Make New Directory"),
+ tr("Directory Name"), QLineEdit::Normal,
+ new_dir_name, &ok);
+ if (ok && !new_dir_name.isEmpty()) {
+ dir_model_->mkdir(index, new_dir_name);
+ }
+}
+
+void FileTreeView::SlotMkdirBelowAtSelectedItem() {
+ auto index = this->currentIndex();
+
+ QString new_dir_name;
+ bool ok;
+ new_dir_name = QInputDialog::getText(this, tr("Make New Directory"),
+ tr("Directory Name"), QLineEdit::Normal,
+ new_dir_name, &ok);
+ if (ok && !new_dir_name.isEmpty()) {
+ dir_model_->mkdir(index, new_dir_name);
+ }
+}
+
+void FileTreeView::SlotTouch() {
+#ifdef WINDOWS
+ auto root_path_str = dir_model_->rootPath().toStdU16String();
+#else
+ auto root_path_str = dir_model_->rootPath().toStdString();
+#endif
+ std::filesystem::path root_path(root_path_str);
+
+ QString new_file_name;
+ bool ok;
+ new_file_name = QInputDialog::getText(
+ this, tr("Create Empty File"), tr("Filename (you can given extension)"),
+ QLineEdit::Normal, new_file_name, &ok);
+ if (ok && !new_file_name.isEmpty()) {
+#ifdef WINDOWS
+ auto file_path = root_path / new_file_name.toStdU16String();
+#else
+ auto file_path = root_path / new_file_name.toStdString();
+#endif
+ QFile new_file(file_path.u8string().c_str());
+ if (!new_file.open(QIODevice::WriteOnly | QIODevice::NewOnly)) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unable to create the file."));
+ }
+ new_file.close();
+ }
+}
+
+void FileTreeView::SlotTouchBelowAtSelectedItem() {
+ std::filesystem::path root_path(selected_path_);
+
+ QString new_file_name;
+ bool ok;
+ new_file_name = QInputDialog::getText(
+ this, tr("Create Empty File"), tr("Filename (you can given extension)"),
+ QLineEdit::Normal, new_file_name, &ok);
+ if (ok && !new_file_name.isEmpty()) {
+#ifdef WINDOWS
+ auto file_path = root_path / new_file_name.toStdU16String();
+#else
+ auto file_path = root_path / new_file_name.toStdString();
+#endif
+ QFile new_file(file_path.u8string().c_str());
+ if (!new_file.open(QIODevice::WriteOnly | QIODevice::NewOnly)) {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unable to create the file."));
+ }
+ new_file.close();
+ }
+}
+
+void FileTreeView::keyPressEvent(QKeyEvent* event) {
+ QTreeView::keyPressEvent(event);
+
+ if (this->currentIndex().isValid()) {
+ if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
+ slot_file_tree_view_item_double_clicked(this->currentIndex());
+ } else if (event->key() == Qt::Key_Delete ||
+ event->key() == Qt::Key_Backspace) {
+ SlotDeleteSelectedItem();
+ }
+ }
+}
+
+void FileTreeView::SlotOpenSelectedItemBySystemApplication() {
+ QFileInfo const info(QString::fromStdString(selected_path_.u8string()));
+ auto q_selected_path = QString::fromStdString(selected_path_.u8string());
+ if (info.isDir()) {
+ const auto file_path = info.filePath().toUtf8().toStdString();
+ QDesktopServices::openUrl(QUrl::fromLocalFile(q_selected_path));
+
+ } else {
+ QDesktopServices::openUrl(QUrl::fromLocalFile(q_selected_path));
+ }
+}
+
+void FileTreeView::SlotRenameSelectedItem() {
+ bool ok;
+ auto text = QInputDialog::getText(
+ this, tr("Rename"), tr("New Filename"), QLineEdit::Normal,
+ QString::fromStdString(selected_path_.filename().u8string()), &ok);
+ if (ok && !text.isEmpty()) {
+ try {
+#ifdef WINDOWS
+ auto new_name_path = selected_path_.parent_path() / text.toStdU16String();
+#else
+ auto new_name_path = selected_path_.parent_path() / text.toStdString();
+#endif
+ GF_UI_LOG_DEBUG("new name path: {}", new_name_path.u8string());
+ std::filesystem::rename(selected_path_, new_name_path);
+
+ // refresh
+ SlotGoPath(current_path_);
+ } catch (...) {
+ GF_UI_LOG_ERROR("file tree view rename error: {}",
+ selected_path_.u8string());
+ QMessageBox::critical(this, tr("Error"),
+ tr("Unable to rename the file or folder."));
+ }
+ }
+}
+
+auto FileTreeView::GetMousePointGlobal(const QPoint& point) -> QPoint {
+ return this->viewport()->mapToGlobal(point);
+}
+
+void FileTreeView::slot_create_popup_menu() {
+ popup_menu_ = new QMenu();
+
+ action_open_file_ = new QAction(this);
+ action_open_file_->setText(tr("Open"));
+ connect(action_open_file_, &QAction::triggered, this, [this](bool) {
+ emit SignalOpenFile(QString::fromStdString(GetSelectedPath()));
+ });
+
+ action_rename_file_ = new QAction(this);
+ action_rename_file_->setText(tr("Rename"));
+ connect(action_rename_file_, &QAction::triggered, this,
+ &FileTreeView::SlotRenameSelectedItem);
+
+ action_delete_file_ = new QAction(this);
+ action_delete_file_->setText(tr("Delete"));
+ connect(action_delete_file_, &QAction::triggered, this,
+ &FileTreeView::SlotDeleteSelectedItem);
+
+ action_calculate_hash_ = new QAction(this);
+ action_calculate_hash_->setText(tr("Calculate Hash"));
+ connect(action_calculate_hash_, &QAction::triggered, this,
+ &FileTreeView::slot_calculate_hash);
+
+ action_make_directory_ = new QAction(this);
+ action_make_directory_->setText(tr("Directory"));
+ connect(action_make_directory_, &QAction::triggered, this,
+ &FileTreeView::SlotMkdirBelowAtSelectedItem);
+
+ action_create_empty_file_ = new QAction(this);
+ action_create_empty_file_->setText(tr("File"));
+ connect(action_create_empty_file_, &QAction::triggered, this,
+ &FileTreeView::SlotTouchBelowAtSelectedItem);
+
+ action_compress_files_ = new QAction(this);
+ action_compress_files_->setText(tr("Compress..."));
+ action_compress_files_->setVisible(false);
+ connect(action_compress_files_, &QAction::triggered, this,
+ &FileTreeView::slot_compress_files);
+
+ auto* action_open_with_system_default_application = new QAction(this);
+ action_open_with_system_default_application->setText(
+ tr("Open with Default System Application"));
+ connect(action_open_with_system_default_application, &QAction::triggered,
+ this, &FileTreeView::SlotOpenSelectedItemBySystemApplication);
+
+ auto* new_item_action_menu = new QMenu(this);
+ new_item_action_menu->setTitle(tr("New"));
+ new_item_action_menu->addAction(action_create_empty_file_);
+ new_item_action_menu->addAction(action_make_directory_);
+
+ popup_menu_->addAction(action_open_file_);
+ popup_menu_->addAction(action_open_with_system_default_application);
+
+ popup_menu_->addSeparator();
+ popup_menu_->addMenu(new_item_action_menu);
+ popup_menu_->addSeparator();
+
+ popup_menu_->addAction(action_rename_file_);
+ popup_menu_->addAction(action_delete_file_);
+ popup_menu_->addAction(action_compress_files_);
+ popup_menu_->addAction(action_calculate_hash_);
+}
+
+void FileTreeView::slot_show_custom_context_menu(const QPoint& point) {
+ auto target_path = this->GetPathByClickPoint(point);
+
+ if (!target_path.empty()) {
+ action_open_file_->setEnabled(true);
+ action_rename_file_->setEnabled(true);
+ action_delete_file_->setEnabled(true);
+
+ QFileInfo const info(QString::fromStdString(this->GetSelectedPath()));
+ action_calculate_hash_->setEnabled(info.isFile() && info.isReadable());
+
+ } else {
+ action_open_file_->setEnabled(false);
+ action_rename_file_->setEnabled(false);
+ action_delete_file_->setEnabled(false);
+
+ action_calculate_hash_->setEnabled(false);
+ }
+ popup_menu_->exec(this->GetMousePointGlobal(point));
+}
+
+void FileTreeView::slot_calculate_hash() {
+ emit UISignalStation::GetInstance()->SignalRefreshInfoBoard(
+ CalculateHash(this->GetSelectedPath().c_str()),
+ InfoBoardStatus::INFO_ERROR_OK);
+}
+
+void FileTreeView::slot_compress_files() {}
+
+void FileTreeView::paintEvent(QPaintEvent* event) {
+ QTreeView::paintEvent(event);
+ for (int i = 1; i < dir_model_->columnCount(); ++i) {
+ this->resizeColumnToContents(i);
+ }
+}
+} // namespace GpgFrontend::UI
diff --git a/src/ui/widgets/FileTreeView.h b/src/ui/widgets/FileTreeView.h
new file mode 100644
index 00000000..5d013ae4
--- /dev/null
+++ b/src/ui/widgets/FileTreeView.h
@@ -0,0 +1,229 @@
+/**
+ * Copyright (C) 2021 Saturneric <[email protected]>
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#pragma once
+
+namespace GpgFrontend::UI {
+
+class FileTreeView : public QTreeView {
+ Q_OBJECT
+ public:
+ explicit FileTreeView(QWidget* parent, const QString& target_path);
+
+ /**
+ * @brief Get the Current Path object
+ *
+ * @return std::filesystem::path
+ */
+ auto GetCurrentPath() -> std::filesystem::path;
+
+ /**
+ * @brief Get the Selected Path object
+ *
+ * @return std::filesystem::path
+ */
+ auto GetSelectedPath() -> std::filesystem::path;
+
+ /**
+ * @brief Get the Path By Click Point object
+ *
+ * @param point
+ * @return std::filesystem::path
+ */
+ auto GetPathByClickPoint(const QPoint& point) -> std::filesystem::path;
+
+ /**
+ * @brief Get the Mouse Point Global object
+ *
+ * @param point
+ * @return QPoint
+ */
+ auto GetMousePointGlobal(const QPoint& point) -> QPoint;
+
+ protected:
+ /**
+ * @brief
+ *
+ * @param selected
+ * @param deselected
+ */
+ void selectionChanged(const QItemSelection& selected,
+ const QItemSelection& deselected) override;
+
+ /**
+ * @brief
+ *
+ * @param event
+ */
+ void keyPressEvent(QKeyEvent* event) override;
+
+ /**
+ * @brief
+ *
+ */
+ void paintEvent(QPaintEvent* event) override;
+
+ signals:
+
+ /**
+ * @brief
+ *
+ * @param path
+ */
+ void SignalPathChanged(const QString&);
+
+ /**
+ * @brief
+ *
+ */
+ void SignalSelectedChanged(const QString&);
+
+ /**
+ * @brief
+ *
+ */
+ void SignalOpenFile(const QString&);
+
+ public slots:
+
+ /**
+ * @brief
+ *
+ */
+ void SlotGoPath(const std::filesystem::path&);
+
+ /**
+ * @brief
+ *
+ */
+ void SlotUpLevel();
+
+ /**
+ * @brief
+ *
+ */
+ void SlotShowSystemFile(bool);
+
+ /**
+ * @brief
+ *
+ * @param on
+ */
+ void SlotShowHiddenFile(bool);
+
+ /**
+ * @brief
+ *
+ */
+ auto SlotDeleteSelectedItem() -> void;
+
+ /**
+ * @brief
+ *
+ */
+ void SlotMkdir();
+
+ /**
+ * @brief
+ *
+ */
+ void SlotMkdirBelowAtSelectedItem();
+
+ /**
+ * @brief
+ *
+ */
+ void SlotTouch();
+
+ /**
+ * @brief
+ *
+ */
+ void SlotTouchBelowAtSelectedItem();
+
+ /**
+ * @brief
+ *
+ */
+ void SlotRenameSelectedItem();
+
+ /**
+ * @brief
+ *
+ */
+ void SlotOpenSelectedItemBySystemApplication();
+
+ private slots:
+
+ /**
+ * @brief
+ *
+ * @param index
+ */
+ void slot_file_tree_view_item_double_clicked(const QModelIndex& index);
+
+ /**
+ * @brief
+ *
+ */
+ void slot_calculate_hash();
+
+ /**
+ * @brief compress directory into gpg-zip
+ *
+ */
+ void slot_compress_files();
+
+ /**
+ * @brief
+ *
+ * @param point
+ */
+ void slot_show_custom_context_menu(const QPoint& point);
+
+ /**
+ * @brief Create a popup menu object
+ *
+ */
+ void slot_create_popup_menu();
+
+ private:
+ QFileSystemModel* dir_model_; ///<
+ std::filesystem::path current_path_; ///<
+ std::filesystem::path selected_path_; ///<
+
+ QMenu* popup_menu_;
+ QAction* action_open_file_;
+ QAction* action_rename_file_;
+ QAction* action_delete_file_;
+ QAction* action_calculate_hash_;
+ QAction* action_create_empty_file_;
+ QAction* action_make_directory_;
+ QAction* action_compress_files_;
+};
+} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/widgets/FindWidget.cpp b/src/ui/widgets/FindWidget.cpp
index 598d8004..7cc569e4 100644
--- a/src/ui/widgets/FindWidget.cpp
+++ b/src/ui/widgets/FindWidget.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -33,28 +33,31 @@ namespace GpgFrontend::UI {
FindWidget::FindWidget(QWidget* parent, PlainTextEditorPage* edit)
: QWidget(parent), m_text_page_(edit) {
find_edit_ = new QLineEdit(this);
- auto* closeButton = new QPushButton(
+ auto* close_button = 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(find_edit_, 2);
- notificationWidgetLayout->addWidget(nextButton);
- notificationWidgetLayout->addWidget(previousButton);
- notificationWidgetLayout->addWidget(closeButton);
-
- this->setLayout(notificationWidgetLayout);
+ auto* next_button =
+ new QPushButton(QIcon(":/icons/button_next.png"), QString());
+ auto* previous_button =
+ new QPushButton(QIcon(":/icons/button_previous.png"), "");
+
+ auto* notification_widget_layout = new QHBoxLayout(this);
+ notification_widget_layout->setContentsMargins(10, 0, 0, 0);
+ notification_widget_layout->addWidget(new QLabel(tr("Find") + ": "));
+ notification_widget_layout->addWidget(find_edit_, 2);
+ notification_widget_layout->addWidget(next_button);
+ notification_widget_layout->addWidget(previous_button);
+ notification_widget_layout->addWidget(close_button);
+
+ this->setLayout(notification_widget_layout);
connect(find_edit_, &QLineEdit::textEdited, this, &FindWidget::slot_find);
connect(find_edit_, &QLineEdit::returnPressed, this,
&FindWidget::slot_find_next);
- connect(nextButton, &QPushButton::clicked, this, &FindWidget::slot_find_next);
- connect(previousButton, &QPushButton::clicked, this,
+ connect(next_button, &QPushButton::clicked, this,
+ &FindWidget::slot_find_next);
+ connect(previous_button, &QPushButton::clicked, this,
&FindWidget::slot_find_previous);
- connect(closeButton, &QPushButton::clicked, this, &FindWidget::slot_close);
+ connect(close_button, &QPushButton::clicked, this, &FindWidget::slot_close);
// The timer is necessary for setting the focus
QTimer::singleShot(0, find_edit_, SLOT(setFocus()));
@@ -63,17 +66,17 @@ FindWidget::FindWidget(QWidget* parent, PlainTextEditorPage* edit)
void FindWidget::set_background() {
// auto cursor = m_text_page_->GetTextPage()->textCursor();
// if match is found set background of QLineEdit to white, otherwise to red
- QPalette bgPalette(find_edit_->palette());
+ QPalette bg_palette(find_edit_->palette());
if (!find_edit_->text().isEmpty() && m_text_page_->GetTextPage()
->document()
->find(find_edit_->text())
.position() < 0) {
- bgPalette.setColor(QPalette::Base, "#ececba");
+ bg_palette.setColor(QPalette::Base, "#ececba");
} else {
- bgPalette.setColor(QPalette::Base, Qt::white);
+ bg_palette.setColor(QPalette::Base, Qt::white);
}
- find_edit_->setPalette(bgPalette);
+ find_edit_->setPalette(bg_palette);
}
void FindWidget::slot_find_next() {
diff --git a/src/ui/widgets/FindWidget.h b/src/ui/widgets/FindWidget.h
index dfe50f9c..a32a877c 100644
--- a/src/ui/widgets/FindWidget.h
+++ b/src/ui/widgets/FindWidget.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,14 +20,13 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef FINDWIDGET_H
-#define FINDWIDGET_H
+#pragma once
#include "ui/GpgFrontendUI.h"
#include "ui/widgets/PlainTextEditorPage.h"
@@ -95,5 +94,3 @@ class FindWidget : public QWidget {
};
} // namespace GpgFrontend::UI
-
-#endif // FINDWIDGET_H
diff --git a/src/ui/widgets/HelpPage.cpp b/src/ui/widgets/HelpPage.cpp
index b116df30..dc82d279 100644
--- a/src/ui/widgets/HelpPage.cpp
+++ b/src/ui/widgets/HelpPage.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,8 +28,6 @@
#include "ui/widgets/HelpPage.h"
-#include <utility>
-
namespace GpgFrontend::UI {
HelpPage::HelpPage(const QString& path, QWidget* parent) : QWidget(parent) {
diff --git a/src/ui/widgets/HelpPage.h b/src/ui/widgets/HelpPage.h
index 0b0db5ea..3ab2cbf6 100644
--- a/src/ui/widgets/HelpPage.h
+++ b/src/ui/widgets/HelpPage.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,14 +20,13 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef HELPPAGE_H
-#define HELPPAGE_H
+#pragma once
#include "ui/GpgFrontendUI.h"
@@ -70,5 +69,3 @@ class HelpPage : public QWidget {
};
} // namespace GpgFrontend::UI
-
-#endif // HELPPAGE_H
diff --git a/src/ui/widgets/InfoBoardWidget.cpp b/src/ui/widgets/InfoBoardWidget.cpp
index 98b07089..fdec1e50 100644
--- a/src/ui/widgets/InfoBoardWidget.cpp
+++ b/src/ui/widgets/InfoBoardWidget.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,31 +28,34 @@
#include "ui/widgets/InfoBoardWidget.h"
-#include "core/function/GlobalSettingStation.h"
-#include "ui/SignalStation.h"
+#include "core/GpgModel.h"
+#include "ui/UISignalStation.h"
#include "ui/struct/SettingsObject.h"
+#include "ui/struct/settings/AppearanceSO.h"
#include "ui_InfoBoard.h"
namespace GpgFrontend::UI {
InfoBoardWidget::InfoBoardWidget(QWidget* parent)
- : QWidget(parent), ui_(std::make_shared<Ui_InfoBoard>()) {
+ : QWidget(parent),
+ ui_(GpgFrontend::SecureCreateSharedObject<Ui_InfoBoard>()) {
ui_->setupUi(this);
ui_->actionButtonLayout->addStretch();
- ui_->copyButton->setText(_("Copy"));
- ui_->saveButton->setText(_("Save File"));
- ui_->clearButton->setText(_("Clear"));
+ ui_->copyToolButton->setToolTip(tr("Copy"));
+ ui_->saveToolButton->setToolTip(tr("Save File"));
+ ui_->clearToolButton->setToolTip(tr("Clear"));
- connect(ui_->copyButton, &QPushButton::clicked, this,
+ connect(ui_->copyToolButton, &QToolButton::clicked, this,
&InfoBoardWidget::slot_copy);
- connect(ui_->saveButton, &QPushButton::clicked, this,
+ connect(ui_->saveToolButton, &QToolButton::clicked, this,
&InfoBoardWidget::slot_save);
- connect(ui_->clearButton, &QPushButton::clicked, this,
+ connect(ui_->clearToolButton, &QToolButton::clicked, this,
&InfoBoardWidget::SlotReset);
- connect(SignalStation::GetInstance(), &SignalStation::SignalRefreshInfoBoard,
- this, &InfoBoardWidget::SlotRefresh);
+ connect(UISignalStation::GetInstance(),
+ &UISignalStation::SignalRefreshInfoBoard, this,
+ &InfoBoardWidget::SlotRefresh);
}
void InfoBoardWidget::SetInfoBoard(const QString& text,
@@ -79,12 +82,10 @@ void InfoBoardWidget::SetInfoBoard(const QString& text,
status.setColor(QPalette::Text, color);
ui_->infoBoard->setPalette(status);
- SettingsObject general_settings_state("general_settings_state");
+ AppearanceSO appearance(SettingsObject("general_settings_state"));
// info board font size
- auto info_font_size =
- general_settings_state.Check("text_editor").Check("font_size", 10);
- ui_->infoBoard->setFont(QFont("Times", info_font_size));
+ ui_->infoBoard->setFont(QFont("Times", appearance.info_board_font_size));
}
void InfoBoardWidget::SlotRefresh(const QString& text, InfoBoardStatus status) {
@@ -94,9 +95,10 @@ void InfoBoardWidget::SlotRefresh(const QString& text, InfoBoardStatus status) {
}
void InfoBoardWidget::AssociateTextEdit(QTextEdit* edit) {
- if (m_text_page_ != nullptr)
+ if (m_text_page_ != nullptr) {
disconnect(m_text_page_, &QTextEdit::textChanged, this,
&InfoBoardWidget::SlotReset);
+ }
this->m_text_page_ = edit;
connect(edit, &QTextEdit::textChanged, this, &InfoBoardWidget::SlotReset);
}
@@ -113,15 +115,15 @@ void InfoBoardWidget::AssociateTabWidget(QTabWidget* tab) {
void InfoBoardWidget::AddOptionalAction(const QString& name,
const std::function<void()>& action) {
- SPDLOG_DEBUG("add option: {}", name.toStdString());
- auto actionButton = new QPushButton(name);
- auto layout = new QHBoxLayout();
+ GF_UI_LOG_DEBUG("add option: {}", name.toStdString());
+ auto* action_button = new QPushButton(name);
+ auto* layout = new QHBoxLayout();
layout->setContentsMargins(5, 0, 5, 0);
ui_->infoBoard->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
// set margin from surroundings
- layout->addWidget(actionButton);
+ layout->addWidget(action_button);
ui_->actionButtonLayout->addLayout(layout);
- connect(actionButton, &QPushButton::clicked, this, [=]() { action(); });
+ connect(action_button, &QPushButton::clicked, this, [=]() { action(); });
}
/**
@@ -146,10 +148,11 @@ void InfoBoardWidget::delete_widgets_in_layout(QLayout* layout,
QLayoutItem* item;
while ((item = layout->layout()->takeAt(start_index)) != nullptr) {
layout->removeItem(item);
- if (item->layout() != nullptr)
+ if (item->layout() != nullptr) {
delete_widgets_in_layout(item->layout());
- else if (item->widget() != nullptr)
+ } else if (item->widget() != nullptr) {
delete item->widget();
+ }
delete item;
}
}
@@ -161,8 +164,8 @@ void InfoBoardWidget::slot_copy() {
void InfoBoardWidget::slot_save() {
auto file_path = QFileDialog::getSaveFileName(
- this, _("Save Information Board's Content"), {}, tr("Text (*.txt)"));
- SPDLOG_DEBUG("file path: {}", file_path.toStdString());
+ this, tr("Save Information Board's Content"), {}, tr("Text (*.txt)"));
+ GF_UI_LOG_DEBUG("file path: {}", file_path.toStdString());
if (file_path.isEmpty()) return;
QFile file(file_path);
@@ -170,8 +173,8 @@ void InfoBoardWidget::slot_save() {
file.write(ui_->infoBoard->toPlainText().toUtf8());
} else {
QMessageBox::critical(
- this, _("Error"),
- _("The file path is not exists, unprivileged or unreachable."));
+ this, tr("Error"),
+ tr("The file path is not exists, unprivileged or unreachable."));
}
file.close();
}
diff --git a/src/ui/widgets/InfoBoardWidget.h b/src/ui/widgets/InfoBoardWidget.h
index 47740456..183a386c 100644
--- a/src/ui/widgets/InfoBoardWidget.h
+++ b/src/ui/widgets/InfoBoardWidget.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,14 +20,13 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef __VERIFYNOTIFICATION_H__
-#define __VERIFYNOTIFICATION_H__
+#pragma once
#include "PlainTextEditorPage.h"
#include "core/function/result_analyse/GpgVerifyResultAnalyse.h"
@@ -144,5 +143,3 @@ class InfoBoardWidget : public QWidget {
};
} // 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 ce3c1c3d..a3eb85ea 100644
--- a/src/ui/widgets/KeyList.cpp
+++ b/src/ui/widgets/KeyList.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,24 +28,21 @@
#include "ui/widgets/KeyList.h"
-#include <boost/format.hpp>
+#include <cstddef>
#include <mutex>
-#include <utility>
#include "core/GpgCoreInit.h"
#include "core/function/GlobalSettingStation.h"
#include "core/function/gpg/GpgKeyGetter.h"
-#include "spdlog/spdlog.h"
-#include "ui/SignalStation.h"
+#include "ui/UISignalStation.h"
#include "ui/UserInterfaceUtils.h"
#include "ui_KeyList.h"
-#include "widgets/TextEdit.h"
namespace GpgFrontend::UI {
KeyList::KeyList(KeyMenuAbility::AbilityType menu_ability, QWidget* parent)
: QWidget(parent),
- ui_(std::make_shared<Ui_KeyList>()),
+ ui_(GpgFrontend::SecureCreateSharedObject<Ui_KeyList>()),
menu_ability_(menu_ability) {
init();
}
@@ -53,7 +50,7 @@ KeyList::KeyList(KeyMenuAbility::AbilityType menu_ability, QWidget* parent)
void KeyList::init() {
ui_->setupUi(this);
- ui_->menuWidget->setHidden(!menu_ability_);
+ ui_->menuWidget->setHidden(menu_ability_ == 0U);
ui_->refreshKeyListButton->setHidden(~menu_ability_ &
KeyMenuAbility::REFRESH);
ui_->syncButton->setHidden(~menu_ability_ & KeyMenuAbility::SYNC_PUBLIC_KEY);
@@ -64,20 +61,22 @@ void KeyList::init() {
popup_menu_ = new QMenu(this);
bool forbid_all_gnupg_connection =
- GlobalSettingStation::GetInstance().LookupSettings(
- "network.forbid_all_gnupg_connection", false);
+ GlobalSettingStation::GetInstance()
+ .GetSettings()
+ .value("network/forbid_all_gnupg_connection", false)
+ .toBool();
// forbidden networks connections
if (forbid_all_gnupg_connection) ui_->syncButton->setDisabled(true);
// register key database refresh signal
- connect(this, &KeyList::SignalRefreshDatabase, SignalStation::GetInstance(),
- &SignalStation::SignalKeyDatabaseRefresh);
- connect(SignalStation::GetInstance(),
- &SignalStation::SignalKeyDatabaseRefreshDone, this,
+ connect(this, &KeyList::SignalRefreshDatabase, UISignalStation::GetInstance(),
+ &UISignalStation::SignalKeyDatabaseRefresh);
+ connect(UISignalStation::GetInstance(),
+ &UISignalStation::SignalKeyDatabaseRefreshDone, this,
&KeyList::SlotRefresh);
- connect(SignalStation::GetInstance(), &SignalStation::SignalUIRefresh, this,
- &KeyList::SlotRefreshUI);
+ connect(UISignalStation::GetInstance(), &UISignalStation::SignalUIRefresh,
+ this, &KeyList::SlotRefreshUI);
// register key database sync signal for refresh button
connect(ui_->refreshKeyListButton, &QPushButton::clicked, this,
@@ -91,33 +90,34 @@ void KeyList::init() {
&KeyList::slot_sync_with_key_server);
connect(ui_->searchBarEdit, &QLineEdit::textChanged, this,
&KeyList::filter_by_keyword);
- connect(this, &KeyList::SignalRefreshStatusBar, SignalStation::GetInstance(),
- &SignalStation::SignalRefreshStatusBar);
+ connect(this, &KeyList::SignalRefreshStatusBar,
+ UISignalStation::GetInstance(),
+ &UISignalStation::SignalRefreshStatusBar);
setAcceptDrops(true);
- ui_->refreshKeyListButton->setText(_("Refresh"));
+ ui_->refreshKeyListButton->setText(tr("Refresh"));
ui_->refreshKeyListButton->setToolTip(
- _("Refresh the key list to synchronize changes."));
- ui_->syncButton->setText(_("Sync Public Key"));
+ tr("Refresh the key list to synchronize changes."));
+ ui_->syncButton->setText(tr("Sync Public Key"));
ui_->syncButton->setToolTip(
- _("Sync public key with your default keyserver."));
- ui_->uncheckButton->setText(_("Uncheck ALL"));
+ tr("Sync public key with your default keyserver."));
+ ui_->uncheckButton->setText(tr("Uncheck ALL"));
ui_->uncheckButton->setToolTip(
- _("Cancel all checked items in the current tab at once."));
- ui_->checkALLButton->setText(_("Check ALL"));
+ tr("Cancel all checked items in the current tab at once."));
+ ui_->checkALLButton->setText(tr("Check ALL"));
ui_->checkALLButton->setToolTip(
- _("Check all items in the current tab at once"));
- ui_->searchBarEdit->setPlaceholderText(_("Search for keys..."));
+ tr("Check all items in the current tab at once"));
+ ui_->searchBarEdit->setPlaceholderText(tr("Search for keys..."));
}
void KeyList::AddListGroupTab(const QString& name, const QString& id,
KeyListRow::KeyType selectType,
KeyListColumn::InfoType infoType,
const KeyTable::KeyTableFilter filter) {
- SPDLOG_DEBUG("add tab: {}", name.toStdString());
+ GF_UI_LOG_DEBUG("add tab: {}", name.toStdString());
- auto key_list = new QTableWidget(this);
+ auto* key_list = new QTableWidget(this);
if (m_key_list_ == nullptr) {
m_key_list_ = key_list;
}
@@ -144,28 +144,28 @@ void KeyList::AddListGroupTab(const QString& name, const QString& id,
key_list->setAlternatingRowColors(true);
// Hidden Column For Purpose
- if (!(infoType & KeyListColumn::TYPE)) {
+ if ((infoType & KeyListColumn::TYPE) == 0U) {
key_list->setColumnHidden(1, true);
}
- if (!(infoType & KeyListColumn::NAME)) {
+ if ((infoType & KeyListColumn::NAME) == 0U) {
key_list->setColumnHidden(2, true);
}
- if (!(infoType & KeyListColumn::EmailAddress)) {
+ if ((infoType & KeyListColumn::EmailAddress) == 0U) {
key_list->setColumnHidden(3, true);
}
- if (!(infoType & KeyListColumn::Usage)) {
+ if ((infoType & KeyListColumn::Usage) == 0U) {
key_list->setColumnHidden(4, true);
}
- if (!(infoType & KeyListColumn::Validity)) {
+ if ((infoType & KeyListColumn::Validity) == 0U) {
key_list->setColumnHidden(5, true);
}
- if (!(infoType & KeyListColumn::FingerPrint)) {
+ if ((infoType & KeyListColumn::FingerPrint) == 0U) {
key_list->setColumnHidden(6, true);
}
QStringList labels;
- labels << _("Select") << _("Type") << _("Name") << _("Email Address")
- << _("Usage") << _("Trust") << _("Finger Print");
+ labels << tr("Select") << tr("Type") << tr("Name") << tr("Email Address")
+ << tr("Usage") << tr("Trust") << tr("Finger Print");
key_list->setHorizontalHeaderLabels(labels);
key_list->horizontalHeader()->setStretchLastSection(false);
@@ -175,18 +175,18 @@ void KeyList::AddListGroupTab(const QString& name, const QString& id,
}
void KeyList::SlotRefresh() {
- SPDLOG_DEBUG("refresh, address: {}", static_cast<void*>(this));
+ GF_UI_LOG_DEBUG("refresh, address: {}", static_cast<void*>(this));
ui_->refreshKeyListButton->setDisabled(true);
ui_->syncButton->setDisabled(true);
- emit SignalRefreshStatusBar(_("Refreshing Key List..."), 3000);
+ emit SignalRefreshStatusBar(tr("Refreshing Key List..."), 3000);
this->buffered_keys_list_ = GpgKeyGetter::GetInstance().FetchKey();
this->slot_refresh_ui();
}
void KeyList::SlotRefreshUI() {
- SPDLOG_DEBUG("refresh, address: {}", static_cast<void*>(this));
+ GF_UI_LOG_DEBUG("refresh, address: {}", static_cast<void*>(this));
this->slot_refresh_ui();
}
@@ -201,7 +201,7 @@ KeyIdArgsListPtr KeyList::GetChecked(const KeyTable& key_table) {
}
KeyIdArgsListPtr KeyList::GetChecked() {
- auto key_list =
+ auto* key_list =
qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget());
const auto& buffered_keys =
m_key_tables_[ui_->keyGroupTab->currentIndex()].buffered_keys_;
@@ -215,13 +215,13 @@ KeyIdArgsListPtr KeyList::GetChecked() {
}
KeyIdArgsListPtr KeyList::GetAllPrivateKeys() {
- auto key_list =
+ auto* key_list =
qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget());
const auto& buffered_keys =
m_key_tables_[ui_->keyGroupTab->currentIndex()].buffered_keys_;
auto ret = std::make_unique<KeyIdArgsList>();
for (int i = 0; i < key_list->rowCount(); i++) {
- if (key_list->item(i, 1) && buffered_keys[i].IsPrivateKey()) {
+ if ((key_list->item(i, 1) != nullptr) && buffered_keys[i].IsPrivateKey()) {
ret->push_back(buffered_keys[i].GetId());
}
}
@@ -232,14 +232,14 @@ KeyIdArgsListPtr KeyList::GetPrivateChecked() {
auto ret = std::make_unique<KeyIdArgsList>();
if (ui_->keyGroupTab->size().isEmpty()) return ret;
- auto key_list =
+ auto* key_list =
qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget());
const auto& buffered_keys =
m_key_tables_[ui_->keyGroupTab->currentIndex()].buffered_keys_;
for (int i = 0; i < key_list->rowCount(); i++) {
if ((key_list->item(i, 0)->checkState() == Qt::Checked) &&
- (key_list->item(i, 1))) {
+ ((key_list->item(i, 1)) != nullptr)) {
ret->push_back(buffered_keys[i].GetId());
}
}
@@ -259,7 +259,7 @@ void KeyList::SetChecked(const KeyIdArgsListPtr& keyIds,
}
void KeyList::SetChecked(KeyIdArgsListPtr key_ids) {
- auto key_list =
+ auto* key_list =
qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget());
if (key_list == nullptr) return;
if (!m_key_tables_.empty()) {
@@ -276,13 +276,13 @@ KeyIdArgsListPtr KeyList::GetSelected() {
auto ret = std::make_unique<KeyIdArgsList>();
if (ui_->keyGroupTab->size().isEmpty()) return ret;
- auto key_list =
+ auto* key_list =
qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget());
const auto& buffered_keys =
m_key_tables_[ui_->keyGroupTab->currentIndex()].buffered_keys_;
for (int i = 0; i < key_list->rowCount(); i++) {
- if (key_list->item(i, 0)->isSelected() == 1) {
+ if (key_list->item(i, 0)->isSelected()) {
ret->push_back(buffered_keys[i].GetId());
}
}
@@ -294,7 +294,7 @@ KeyIdArgsListPtr KeyList::GetSelected() {
m_key_list_ = qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget());
for (int i = 0; i < m_key_list_->rowCount(); i++) {
- if (m_key_list_->item(i, 1)) {
+ if (m_key_list_->item(i, 1) != nullptr) {
return true;
}
}
@@ -314,8 +314,8 @@ void KeyList::contextMenuEvent(QContextMenuEvent* event) {
QString current_tab_widget_obj_name =
ui_->keyGroupTab->widget(ui_->keyGroupTab->currentIndex())->objectName();
- SPDLOG_DEBUG("current tab widget object name: {}",
- current_tab_widget_obj_name.toStdString());
+ GF_UI_LOG_DEBUG("current tab widget object name: {}",
+ current_tab_widget_obj_name.toStdString());
if (current_tab_widget_obj_name == "favourite") {
QList<QAction*> actions = popup_menu_->actions();
for (QAction* action : actions) {
@@ -348,31 +348,30 @@ void KeyList::AddMenuAction(QAction* act) { popup_menu_->addAction(act); }
void KeyList::dropEvent(QDropEvent* event) {
auto* dialog = new QDialog();
- dialog->setWindowTitle(_("Import Keys"));
+ dialog->setWindowTitle(tr("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");
+ label = new QLabel(tr("You've dropped something on the table.") + "\n " +
+ tr("GpgFrontend will now try to import key(s).") + "\n");
// "always import keys"-CheckBox
- auto* checkBox = new QCheckBox(_("Always import without bothering."));
+ auto* check_box = new QCheckBox(tr("Always import without bothering."));
- bool confirm_import_keys = GlobalSettingStation::GetInstance().LookupSettings(
- "general.confirm_import_keys", true);
- if (confirm_import_keys) checkBox->setCheckState(Qt::Checked);
+ bool confirm_import_keys = GlobalSettingStation::GetInstance()
+ .GetSettings()
+ .value("basic/confirm_import_keys", true)
+ .toBool();
+ if (confirm_import_keys) check_box->setCheckState(Qt::Checked);
// Buttons for ok and cancel
- auto* buttonBox =
+ auto* button_box =
new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
- connect(buttonBox, &QDialogButtonBox::accepted, dialog, &QDialog::accept);
- connect(buttonBox, &QDialogButtonBox::rejected, dialog, &QDialog::reject);
+ connect(button_box, &QDialogButtonBox::accepted, dialog, &QDialog::accept);
+ connect(button_box, &QDialogButtonBox::rejected, dialog, &QDialog::reject);
auto* vbox = new QVBoxLayout();
vbox->addWidget(label);
- vbox->addWidget(checkBox);
- vbox->addWidget(buttonBox);
+ vbox->addWidget(check_box);
+ vbox->addWidget(button_box);
dialog->setLayout(vbox);
@@ -380,19 +379,8 @@ void KeyList::dropEvent(QDropEvent* event) {
dialog->exec();
if (dialog->result() == QDialog::Rejected) return;
- 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("confirm_import_keys"))
- general.add("confirm_import_keys", libconfig::Setting::TypeBoolean) =
- checkBox->isChecked();
- else {
- general["confirm_import_keys"] = checkBox->isChecked();
- }
- GlobalSettingStation::GetInstance().SyncSettings();
+ auto settings = GlobalSettingStation::GetInstance().GetSettings();
+ settings.setValue("basic/confirm_import_keys", check_box->isChecked());
}
if (event->mimeData()->hasUrls()) {
@@ -400,15 +388,15 @@ void KeyList::dropEvent(QDropEvent* event) {
QFile file;
file.setFileName(tmp.toLocalFile());
if (!file.open(QIODevice::ReadOnly)) {
- SPDLOG_ERROR("couldn't open file: {}", tmp.toString().toStdString());
+ GF_UI_LOG_ERROR("couldn't open file: {}", tmp.toString().toStdString());
}
- QByteArray inBuffer = file.readAll();
- this->import_keys(inBuffer);
+ QByteArray in_buffer = file.readAll();
+ this->import_keys(in_buffer);
file.close();
}
} else {
- QByteArray inBuffer(event->mimeData()->text().toUtf8());
- this->import_keys(inBuffer);
+ QByteArray in_buffer(event->mimeData()->text().toUtf8());
+ this->import_keys(in_buffer);
}
}
@@ -416,20 +404,10 @@ 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) {
- spdlog::debug("marked: ", id.toStdString());
- }
-}
-
-void KeyList::import_keys(const QByteArray& inBuffer) {
- auto std_buffer = std::make_unique<ByteArray>(inBuffer.toStdString());
- GpgImportInformation result =
- GpgKeyImportExporter::GetInstance().ImportKey(std::move(std_buffer));
- new KeyImportDetailDialog(result, false, this);
+void KeyList::import_keys(const QByteArray& in_buffer) {
+ auto result =
+ GpgKeyImportExporter::GetInstance().ImportKey(GFBuffer(in_buffer));
+ (new KeyImportDetailDialog(result, this))->exec();
}
void KeyList::slot_double_clicked(const QModelIndex& index) {
@@ -448,13 +426,13 @@ void KeyList::SetDoubleClickedAction(
this->m_action_ = std::move(action);
}
-std::string KeyList::GetSelectedKey() {
+QString KeyList::GetSelectedKey() {
if (ui_->keyGroupTab->size().isEmpty()) return {};
const auto& buffered_keys =
m_key_tables_[ui_->keyGroupTab->currentIndex()].buffered_keys_;
for (int i = 0; i < m_key_list_->rowCount(); i++) {
- if (m_key_list_->item(i, 0)->isSelected() == 1) {
+ if (m_key_list_->item(i, 0)->isSelected()) {
return buffered_keys[i].GetId();
}
}
@@ -462,7 +440,7 @@ std::string KeyList::GetSelectedKey() {
}
void KeyList::slot_refresh_ui() {
- SPDLOG_DEBUG("refresh: {}", static_cast<void*>(buffered_keys_list_.get()));
+ GF_UI_LOG_DEBUG("refresh: {}", static_cast<void*>(buffered_keys_list_.get()));
if (buffered_keys_list_ != nullptr) {
std::lock_guard<std::mutex> guard(buffered_key_list_mutex_);
@@ -471,7 +449,7 @@ void KeyList::slot_refresh_ui() {
GpgKeyGetter::GetInstance().GetKeysCopy(buffered_keys_list_));
}
}
- emit SignalRefreshStatusBar(_("Key List Refreshed."), 1000);
+ emit SignalRefreshStatusBar(tr("Key List Refreshed."), 1000);
ui_->refreshKeyListButton->setDisabled(false);
ui_->syncButton->setDisabled(false);
}
@@ -481,8 +459,9 @@ void KeyList::slot_sync_with_key_server() {
{
std::lock_guard<std::mutex> guard(buffered_key_list_mutex_);
for (const auto& key : *buffered_keys_list_) {
- if (!(key.IsPrivateKey() && key.IsHasMasterKey()))
+ if (!(key.IsPrivateKey() && key.IsHasMasterKey())) {
key_ids.push_back(key.GetId());
+ }
}
}
@@ -491,23 +470,25 @@ void KeyList::slot_sync_with_key_server() {
ui_->refreshKeyListButton->setDisabled(true);
ui_->syncButton->setDisabled(true);
- emit SignalRefreshStatusBar(_("Syncing Key List..."), 3000);
+ emit SignalRefreshStatusBar(tr("Syncing Key List..."), 3000);
CommonUtils::SlotImportKeyFromKeyServer(
- key_ids, [=](const std::string& key_id, const std::string& status,
+ key_ids, [=](const QString& key_id, const QString& status,
size_t current_index, size_t all_index) {
- SPDLOG_DEBUG("import key: {} {} {} {}", key_id, status, current_index,
- all_index);
+ GF_UI_LOG_DEBUG("import key: {} {} {} {}", key_id, status,
+ current_index, all_index);
auto key = GpgKeyGetter::GetInstance().GetKey(key_id);
- boost::format status_str = boost::format(_("Sync [%1%/%2%] %3% %4%")) %
- current_index % all_index %
- key.GetUIDs()->front().GetUID() % status;
- emit SignalRefreshStatusBar(status_str.str().c_str(), 1500);
+ auto status_str = tr("Sync [%1/%2] %3 %4")
+ .arg(current_index)
+ .arg(all_index)
+ .arg(key.GetUIDs()->front().GetUID())
+ .arg(status);
+ emit SignalRefreshStatusBar(status_str, 1500);
if (current_index == all_index) {
ui_->syncButton->setDisabled(false);
ui_->refreshKeyListButton->setDisabled(false);
- emit SignalRefreshStatusBar(_("Key List Sync Done."), 3000);
+ emit SignalRefreshStatusBar(tr("Key List Sync Done."), 3000);
emit this->SignalRefreshDatabase();
}
});
@@ -517,10 +498,10 @@ void KeyList::filter_by_keyword() {
auto keyword = ui_->searchBarEdit->text();
keyword = keyword.trimmed();
- SPDLOG_DEBUG("get new keyword of search bar: {}", keyword.toStdString());
+ GF_UI_LOG_DEBUG("get new keyword of search bar: {}", keyword);
for (auto& table : m_key_tables_) {
// refresh arguments
- table.SetFilterKeyword(keyword.toLower().toStdString());
+ table.SetFilterKeyword(keyword.toLower());
table.SetMenuAbility(menu_ability_);
}
// refresh ui
@@ -528,7 +509,7 @@ void KeyList::filter_by_keyword() {
}
void KeyList::uncheck_all() {
- auto key_list =
+ auto* key_list =
qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget());
if (key_list == nullptr) return;
if (!m_key_tables_.empty()) {
@@ -542,7 +523,7 @@ void KeyList::uncheck_all() {
}
void KeyList::check_all() {
- auto key_list =
+ auto* key_list =
qobject_cast<QTableWidget*>(ui_->keyGroupTab->currentWidget());
if (key_list == nullptr) return;
if (!m_key_tables_.empty()) {
@@ -556,10 +537,11 @@ void KeyList::check_all() {
}
KeyIdArgsListPtr& KeyTable::GetChecked() {
- if (checked_key_ids_ == nullptr)
+ if (checked_key_ids_ == nullptr) {
checked_key_ids_ = std::make_unique<KeyIdArgsList>();
+ }
auto& ret = checked_key_ids_;
- for (int i = 0; i < buffered_keys_.size(); i++) {
+ for (size_t i = 0; i < buffered_keys_.size(); i++) {
auto key_id = buffered_keys_[i].GetId();
if (key_list_->item(i, 0)->checkState() == Qt::Checked &&
std::find(ret->begin(), ret->end(), key_id) == ret->end()) {
@@ -582,32 +564,24 @@ void KeyTable::Refresh(KeyLinkListPtr m_keys) {
// Optimization for copy
KeyLinkListPtr keys = nullptr;
- if (m_keys == nullptr)
+ if (m_keys == nullptr) {
keys = GpgKeyGetter::GetInstance().FetchKey();
- else
+ } else {
keys = std::move(m_keys);
+ }
auto it = keys->begin();
int row_count = 0;
while (it != keys->end()) {
// filter by search bar's keyword
- if (ability_ & KeyMenuAbility::SEARCH_BAR && !keyword_.empty()) {
- auto name = it->GetName();
- std::transform(name.begin(), name.end(), name.begin(),
- [](unsigned char c) { return std::tolower(c); });
-
- auto email = it->GetEmail();
- std::transform(email.begin(), email.end(), email.begin(),
- [](unsigned char c) { return std::tolower(c); });
-
- auto comment = it->GetComment();
- std::transform(comment.begin(), comment.end(), comment.begin(),
- [](unsigned char c) { return std::tolower(c); });
-
- if (name.find(keyword_) == std::string::npos &&
- email.find(keyword_) == std::string::npos &&
- comment.find(keyword_) == std::string::npos) {
+ if (ability_ & KeyMenuAbility::SEARCH_BAR && !keyword_.isEmpty()) {
+ auto name = it->GetName().toLower();
+ auto email = it->GetEmail().toLower();
+ auto comment = it->GetComment().toLower();
+
+ if (!name.contains(keyword_) && !email.contains(keyword_) &&
+ !comment.contains(keyword_)) {
it = keys->erase(it);
continue;
}
@@ -662,9 +636,9 @@ void KeyTable::Refresh(KeyLinkListPtr m_keys) {
auto* tmp1 = new QTableWidgetItem(type_str);
key_list_->setItem(row_index, 1, tmp1);
- auto* tmp2 = new QTableWidgetItem(QString::fromStdString(it->GetName()));
+ auto* tmp2 = new QTableWidgetItem(it->GetName());
key_list_->setItem(row_index, 2, tmp2);
- auto* tmp3 = new QTableWidgetItem(QString::fromStdString(it->GetEmail()));
+ auto* tmp3 = new QTableWidgetItem(it->GetEmail());
key_list_->setItem(row_index, 3, tmp3);
QString usage;
@@ -679,13 +653,11 @@ void KeyTable::Refresh(KeyLinkListPtr m_keys) {
temp_usage->setTextAlignment(Qt::AlignCenter);
key_list_->setItem(row_index, 4, temp_usage);
- auto* temp_validity =
- new QTableWidgetItem(QString::fromStdString(it->GetOwnerTrust()));
+ auto* temp_validity = new QTableWidgetItem(it->GetOwnerTrust());
temp_validity->setTextAlignment(Qt::AlignCenter);
key_list_->setItem(row_index, 5, temp_validity);
- auto* temp_fpr =
- new QTableWidgetItem(QString::fromStdString(it->GetFingerprint()));
+ auto* temp_fpr = new QTableWidgetItem(it->GetFingerprint());
temp_fpr->setTextAlignment(Qt::AlignCenter);
key_list_->setItem(row_index, 6, temp_fpr);
@@ -735,7 +707,7 @@ void KeyTable::SetMenuAbility(KeyMenuAbility::AbilityType ability) {
this->ability_ = ability;
}
-void KeyTable::SetFilterKeyword(std::string keyword) {
- this->keyword_ = keyword;
+void KeyTable::SetFilterKeyword(QString keyword) {
+ this->keyword_ = std::move(keyword);
}
} // namespace GpgFrontend::UI
diff --git a/src/ui/widgets/KeyList.h b/src/ui/widgets/KeyList.h
index eb346740..f709aa9e 100644
--- a/src/ui/widgets/KeyList.h
+++ b/src/ui/widgets/KeyList.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,20 +20,15 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef __KEYLIST_H__
-#define __KEYLIST_H__
+#pragma once
-#include <string>
-#include <utility>
-
-#include "core/GpgContext.h"
-#include "ui/dialog/import_export/KeyImportDetailDialog.h"
+#include "core/GpgModel.h"
class Ui_KeyList;
@@ -96,7 +91,7 @@ struct KeyTable {
KeyTableFilter filter_; ///<
KeyIdArgsListPtr checked_key_ids_; ///<
KeyMenuAbility::AbilityType ability_; ///<
- std::string keyword_; ///<
+ QString keyword_; ///<
/**
* @brief Construct a new Key Table object
@@ -160,7 +155,7 @@ struct KeyTable {
* @brief
*
*/
- void SetFilterKeyword(std::string keyword);
+ void SetFilterKeyword(QString keyword);
};
/**
@@ -279,16 +274,9 @@ class KeyList : public QWidget {
/**
* @brief Get the Selected Key object
*
- * @return std::string
- */
- std::string GetSelectedKey();
-
- /**
- * @brief
- *
- * @param keyIds
+ * @return QString
*/
- [[maybe_unused]] static void MarkKeys(QStringList* keyIds);
+ QString GetSelectedKey();
/**
* @brief
@@ -414,5 +402,3 @@ class KeyList : public QWidget {
};
} // namespace GpgFrontend::UI
-
-#endif // __KEYLIST_H__
diff --git a/src/ui/widgets/PlainTextEditorPage.cpp b/src/ui/widgets/PlainTextEditorPage.cpp
index c9a65a4c..7d951006 100644
--- a/src/ui/widgets/PlainTextEditorPage.cpp
+++ b/src/ui/widgets/PlainTextEditorPage.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,56 +19,49 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "PlainTextEditorPage.h"
-#include <boost/format.hpp>
-#include <string>
-#include <utility>
-
-#include "core/function/CharsetOperator.h"
#include "core/thread/FileReadTask.h"
-#include "core/thread/Task.h"
#include "core/thread/TaskRunnerGetter.h"
#include "ui/struct/SettingsObject.h"
+#include "ui/struct/settings/AppearanceSO.h"
#include "ui_PlainTextEditor.h"
namespace GpgFrontend::UI {
PlainTextEditorPage::PlainTextEditorPage(QString file_path, QWidget *parent)
: QWidget(parent),
- ui_(std::make_shared<Ui_PlainTextEditor>()),
+ ui_(GpgFrontend::SecureCreateSharedObject<Ui_PlainTextEditor>()),
full_file_path_(std::move(file_path)) {
ui_->setupUi(this);
ui_->textPage->setFocus();
ui_->loadingLabel->setHidden(true);
- // Front in same width
- SettingsObject general_settings_state("general_settings_state");
-
// font size
- auto editor_font_size =
- general_settings_state.Check("text_editor").Check("font_size", 10);
- ui_->textPage->setFont(QFont("Courier", editor_font_size));
+ AppearanceSO appearance(SettingsObject("general_settings_state"));
+ ui_->textPage->setFont(QFont("Courier", appearance.text_editor_font_size));
this->setAttribute(Qt::WA_DeleteOnClose);
- this->ui_->characterLabel->setText(_("0 character"));
- this->ui_->lfLabel->setText(_("lf"));
- this->ui_->encodingLabel->setText(_("utf-8"));
+ this->ui_->characterLabel->setText(tr("0 character"));
+ this->ui_->lfLabel->setHidden(true);
+ this->ui_->encodingLabel->setText("Unicode");
connect(ui_->textPage, &QPlainTextEdit::textChanged, this, [=]() {
// if file is loading
if (!read_done_) return;
auto text = ui_->textPage->document()->toPlainText();
- auto str = boost::format(_("%1% character(s)")) % text.size();
- this->ui_->characterLabel->setText(str.str().c_str());
+ auto str = tr("%1 character(s)").arg(text.size());
+ this->ui_->characterLabel->setText(str);
});
if (full_file_path_.isEmpty()) {
@@ -76,7 +69,7 @@ PlainTextEditorPage::PlainTextEditorPage(QString file_path, QWidget *parent)
ui_->loadingLabel->setHidden(true);
} else {
read_done_ = false;
- ui_->loadingLabel->setText(_("Loading..."));
+ ui_->loadingLabel->setText(tr("Loading..."));
ui_->loadingLabel->setHidden(false);
}
}
@@ -87,24 +80,11 @@ const QString &PlainTextEditorPage::GetFilePath() const {
QPlainTextEdit *PlainTextEditorPage::GetTextPage() { return ui_->textPage; }
-bool PlainTextEditorPage::WillCharsetChange() const {
- // detect if the line-ending will change
- if (is_crlf_) return true;
-
- // detect if the charset of the file will change
- if (charset_name_ != "UTF-8" && charset_name_ != "ISO-8859-1")
- return true;
- else
- return false;
-}
-
void PlainTextEditorPage::NotifyFileSaved() {
this->is_crlf_ = false;
- this->charset_confidence_ = 100;
- this->charset_name_ = "UTF-8";
- this->ui_->lfLabel->setText(_("lf"));
- this->ui_->encodingLabel->setText(_("UTF-8"));
+ this->ui_->lfLabel->setText(tr("lf"));
+ this->ui_->encodingLabel->setText(tr("UTF-8"));
}
void PlainTextEditorPage::SetFilePath(const QString &filePath) {
@@ -130,10 +110,9 @@ void PlainTextEditorPage::slot_format_gpg_header() {
QString content = ui_->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);
+ int start = content.indexOf(GpgFrontend::PGP_SIGNED_BEGIN);
+ int startSig = content.indexOf(GpgFrontend::PGP_SIGNATURE_BEGIN);
+ int endSig = content.indexOf(GpgFrontend::PGP_SIGNATURE_END);
if (start < 0 || startSig < 0 || endSig < 0 || sign_marked_) {
return;
@@ -168,12 +147,12 @@ void PlainTextEditorPage::ReadFile() {
ui_->loadingLabel->setHidden(false);
ui_->textPage->document()->blockSignals(true);
- auto text_page = this->GetTextPage();
+ auto *text_page = this->GetTextPage();
text_page->setReadOnly(true);
- const auto target_path = this->full_file_path_.toStdString();
+ const auto target_path = this->full_file_path_;
- auto *task_runner =
+ auto task_runner =
GpgFrontend::Thread::TaskRunnerGetter::GetInstance().GetTaskRunner();
auto *read_task = new FileReadTask(target_path);
@@ -182,13 +161,12 @@ void PlainTextEditorPage::ReadFile() {
connect(this, &PlainTextEditorPage::SignalUIBytesDisplayed, read_task,
&FileReadTask::SignalFileBytesReadNext, Qt::QueuedConnection);
- connect(read_task, &FileReadTask::SignalTaskRunnableEnd, this,
- []() { SPDLOG_DEBUG("read thread closed"); });
+ connect(read_task, &FileReadTask::SignalTaskShouldEnd, this,
+ []() { GF_UI_LOG_DEBUG("read thread closed"); });
connect(this, &PlainTextEditorPage::close, read_task,
- [=]() { read_task->SignalTaskRunnableEnd(0); });
+ [=]() { read_task->SignalTaskShouldEnd(0); });
connect(read_task, &FileReadTask::SignalFileBytesReadEnd, this, [=]() {
// set the UI
- if (!binary_mode_) text_page->setReadOnly(false);
this->read_done_ = true;
this->ui_->textPage->setEnabled(true);
text_page->document()->setModified(false);
@@ -200,104 +178,27 @@ void PlainTextEditorPage::ReadFile() {
task_runner->PostTask(read_task);
}
-std::string binary_to_string(const std::string &source) {
- static char syms[] = "0123456789ABCDEF";
- std::stringstream ss;
- for (unsigned char c : source)
- ss << syms[((c >> 4) & 0xf)] << syms[c & 0xf] << " ";
- return ss.str();
+auto BinaryToString(const QByteArray &source) -> QString {
+ static const char kSyms[] = "0123456789ABCDEF";
+ QString buffer;
+ QTextStream ss(&buffer);
+ for (auto c : source) ss << kSyms[((c >> 4) & 0xf)] << kSyms[c & 0xf] << " ";
+ return buffer;
}
void PlainTextEditorPage::slot_insert_text(QByteArray bytes_data) {
- std::string data = bytes_data.toStdString();
- SPDLOG_DEBUG("data size: {}", data.size());
- read_bytes_ += data.size();
- // If binary format is detected, the entire file is converted to binary
- // format for display.
- bool if_last_binary_mode = binary_mode_;
- if (!binary_mode_ && !read_done_) {
- detect_encoding(data);
- }
+ GF_UI_LOG_TRACE("inserting data read to editor, data size: {}",
+ bytes_data.size());
+ read_bytes_ += bytes_data.size();
- if (binary_mode_) {
- // change formery displayed text to binary format
- if (if_last_binary_mode != binary_mode_) {
- auto text_buffer =
- ui_->textPage->document()->toRawText().toLocal8Bit().toStdString();
- ui_->textPage->clear();
- this->GetTextPage()->insertPlainText(
- binary_to_string(text_buffer).c_str());
- this->ui_->lfLabel->setText("None");
- }
+ // insert the text to the text page
+ this->GetTextPage()->insertPlainText(bytes_data);
- // insert new data
- this->GetTextPage()->insertPlainText(binary_to_string(data).c_str());
+ auto text = this->GetTextPage()->toPlainText();
+ auto str = tr("%1 character(s)").arg(text.size());
+ this->ui_->characterLabel->setText(str);
- // update the size of the file
- auto str = boost::format(_("%1% byte(s)")) % read_bytes_;
- this->ui_->characterLabel->setText(str.str().c_str());
- } else {
- // detect crlf/lf line ending
- detect_cr_lf(data);
-
- // when reding from a text file
- // try convert the any of thetext to utf8
- std::string utf8_data;
- if (!read_done_ && charset_confidence_ > 25) {
- CharsetOperator::Convert2Utf8(data, utf8_data, charset_name_);
- } else {
- // when editing a text file, do nothing.
- utf8_data = data;
- }
-
- // insert the text to the text page
- this->GetTextPage()->insertPlainText(utf8_data.c_str());
-
- auto text = this->GetTextPage()->toPlainText();
- auto str = boost::format(_("%1% character(s)")) % text.size();
- this->ui_->characterLabel->setText(str.str().c_str());
- }
QTimer::singleShot(25, this, &PlainTextEditorPage::SignalUIBytesDisplayed);
}
-void PlainTextEditorPage::detect_encoding(const std::string &data) {
- // skip the binary data to avoid the false detection of the encoding
- if (binary_mode_) return;
-
- // detect the encoding
- auto charset = CharsetOperator::Detect(data);
- this->charset_name_ = std::get<0>(charset).c_str();
- this->language_name_ = std::get<1>(charset).c_str();
- this->charset_confidence_ = std::get<2>(charset);
-
- // probably there is no need to detect the encoding again
- if (this->charset_confidence_ < 10) {
- binary_mode_ = true;
- }
-
- if (binary_mode_) {
- // hide the line ending label, when the file is binary
- this->ui_->lfLabel->setHidden(true);
- this->ui_->encodingLabel->setText(_("binary"));
- } else {
- ui_->encodingLabel->setText(this->charset_name_.c_str());
- }
-}
-
-void PlainTextEditorPage::detect_cr_lf(const std::string &data) {
- if (binary_mode_) {
- return;
- }
-
- // if contain crlf, set the label to crlf
- if (is_crlf_) return;
-
- if (data.find("\r\n") != std::string::npos) {
- this->ui_->lfLabel->setText("crlf");
- is_crlf_ = true;
- } else {
- this->ui_->lfLabel->setText("lf");
- }
-}
-
} // namespace GpgFrontend::UI
diff --git a/src/ui/widgets/PlainTextEditorPage.h b/src/ui/widgets/PlainTextEditorPage.h
index ffa31762..4981b24c 100644
--- a/src/ui/widgets/PlainTextEditorPage.h
+++ b/src/ui/widgets/PlainTextEditorPage.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,19 +20,13 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef __EDITORPAGE_H__
-#define __EDITORPAGE_H__
-
-#include <string>
-
-#include "core/GpgConstants.h"
-#include "ui/GpgFrontendUI.h"
+#pragma once
class Ui_PlainTextEditor;
@@ -101,12 +95,6 @@ class PlainTextEditorPage : public QWidget {
[[nodiscard]] bool ReadDone() const { return this->read_done_; }
/**
- * @brief detect if the charset of the file will change
- *
- */
- bool WillCharsetChange() const;
-
- /**
* @brief notify the user that the file has been saved.
*
*/
@@ -124,27 +112,9 @@ class PlainTextEditorPage : public QWidget {
std::shared_ptr<Ui_PlainTextEditor> ui_; ///<
QString full_file_path_; ///< The path to the file handled in the tab
bool sign_marked_{}; ///< true, if the signed header is marked, false if not
- bool read_done_ = false; ///<
- bool binary_mode_ = false; ///<
- size_t read_bytes_ = 0; ///<
- std::string charset_name_; ///<
- std::string language_name_; ///<
- int32_t charset_confidence_{}; ///<
- bool is_crlf_ = false; ///<
-
- /**
- * @brief
- *
- * @param data
- */
- void detect_encoding(const std::string& data);
-
- /**
- * @brief
- *
- * @param data
- */
- void detect_cr_lf(const std::string& data);
+ bool read_done_ = false; ///<
+ size_t read_bytes_ = 0; ///<
+ bool is_crlf_ = false; ///<
private slots:
@@ -162,5 +132,3 @@ class PlainTextEditorPage : public QWidget {
};
} // namespace GpgFrontend::UI
-
-#endif // __EDITORPAGE_H__
diff --git a/src/ui/widgets/TOFUInfoPage.cpp b/src/ui/widgets/TOFUInfoPage.cpp
index 709a66e1..39cf8921 100644
--- a/src/ui/widgets/TOFUInfoPage.cpp
+++ b/src/ui/widgets/TOFUInfoPage.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,27 +19,28 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "TOFUInfoPage.h"
GpgFrontend::UI::TOFUInfoPage::TOFUInfoPage(
- const GpgFrontend::GpgTOFUInfo &tofu_info, QWidget *parent)
+ const GpgFrontend::GpgTOFUInfo & /*tofu_info*/, QWidget *parent)
: QWidget(parent) {
auto grid_layout = new QGridLayout();
- grid_layout->addWidget(new QLabel(QString(_("Key ID")) + ": "), 0, 0);
- grid_layout->addWidget(new QLabel(QString(_("Algorithm")) + ": "), 1, 0);
- grid_layout->addWidget(new QLabel(QString(_("Key Size")) + ": "), 2, 0);
- grid_layout->addWidget(new QLabel(QString(_("Nominal Usage")) + ": "), 3, 0);
- grid_layout->addWidget(new QLabel(QString(_("Actual Usage")) + ": "), 4, 0);
- grid_layout->addWidget(new QLabel(QString(_("Expires on")) + ": "), 5, 0);
- grid_layout->addWidget(new QLabel(QString(_("Last Update")) + ": "), 6, 0);
- grid_layout->addWidget(new QLabel(QString(_("Secret Key Existence")) + ": "),
- 7, 0);
+ grid_layout->addWidget(new QLabel(tr("Key ID") + ": "), 0, 0);
+ grid_layout->addWidget(new QLabel(tr("Algorithm") + ": "), 1, 0);
+ grid_layout->addWidget(new QLabel(tr("Key Size") + ": "), 2, 0);
+ grid_layout->addWidget(new QLabel(tr("Nominal Usage") + ": "), 3, 0);
+ grid_layout->addWidget(new QLabel(tr("Actual Usage") + ": "), 4, 0);
+ grid_layout->addWidget(new QLabel(tr("Expires on") + ": "), 5, 0);
+ grid_layout->addWidget(new QLabel(tr("Last Update") + ": "), 6, 0);
+ grid_layout->addWidget(new QLabel(tr("Secret Key Existence") + ": "), 7, 0);
setLayout(grid_layout);
}
diff --git a/src/ui/widgets/TOFUInfoPage.h b/src/ui/widgets/TOFUInfoPage.h
index 445b1567..4bd9b89a 100644
--- a/src/ui/widgets/TOFUInfoPage.h
+++ b/src/ui/widgets/TOFUInfoPage.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -19,15 +19,16 @@
* The initial version of the source code is inherited from
* the gpg4usb project, which is under GPL-3.0-or-later.
*
- * The source code version of this software was modified and released
- * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021.
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric <[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef GPGFRONTEND_TOFUINFOPAGE_H
-#define GPGFRONTEND_TOFUINFOPAGE_H
+#pragma once
-#include "core/GpgModel.h"
+#include "core/typedef/GpgTypedef.h"
#include "ui/GpgFrontendUI.h"
namespace GpgFrontend::UI {
@@ -49,5 +50,3 @@ class TOFUInfoPage : public QWidget {
QWidget *parent = nullptr);
};
} // namespace GpgFrontend::UI
-
-#endif // GPGFRONTEND_TOFUINFOPAGE_H
diff --git a/src/ui/widgets/TextEdit.cpp b/src/ui/widgets/TextEdit.cpp
index 7af4d5f8..59890465 100644
--- a/src/ui/widgets/TextEdit.cpp
+++ b/src/ui/widgets/TextEdit.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,15 +28,14 @@
#include "ui/widgets/TextEdit.h"
-#include <boost/format.hpp>
-#include <string>
+#include <QtPrintSupport>
#include <tuple>
#include <vector>
+#include "core/GpgModel.h"
#include "core/function/CacheManager.h"
#include "core/function/GlobalSettingStation.h"
-#include "nlohmann/json_fwd.hpp"
-#include "spdlog/spdlog.h"
+#include "ui/struct/CacheObject.h"
namespace GpgFrontend::UI {
@@ -60,11 +59,11 @@ TextEdit::TextEdit(QWidget* parent) : QWidget(parent) {
}
void TextEdit::SlotNewTab() {
- QString header = _("untitled") + QString::number(++count_page_) + ".txt";
+ QString header = tr("untitled") + QString::number(++count_page_) + ".txt";
auto* page = new PlainTextEditorPage();
auto index = tab_widget_->addTab(page, header);
- tab_widget_->setTabIcon(index, QIcon(":file.png"));
+ tab_widget_->setTabIcon(index, QIcon(":/icons/file.png"));
tab_widget_->setCurrentIndex(tab_widget_->count() - 1);
page->GetTextPage()->setFocus();
connect(page->GetTextPage()->document(), &QTextDocument::modificationChanged,
@@ -73,21 +72,20 @@ void TextEdit::SlotNewTab() {
this, &TextEdit::slot_save_status_to_cache_for_revovery);
}
-void TextEdit::SlotNewTabWithContent(std::string title,
- const std::string& content) {
- QString header = _("untitled") + QString::number(++count_page_) + ".txt";
- if (!title.empty()) {
+void TextEdit::SlotNewTabWithContent(QString title, const QString& content) {
+ QString header = tr("untitled") + QString::number(++count_page_) + ".txt";
+ if (!title.isEmpty()) {
// modify title
- if (!title.empty() && title[0] == '*') {
- title.erase(0, 1);
+ if (!title.isEmpty() && title[0] == '*') {
+ title.remove(0, 1);
}
// set title
- header = QString::fromStdString(title);
+ header = title;
}
auto* page = new PlainTextEditorPage();
auto index = tab_widget_->addTab(page, header);
- tab_widget_->setTabIcon(index, QIcon(":file.png"));
+ tab_widget_->setTabIcon(index, QIcon(":/icons/file.png"));
tab_widget_->setCurrentIndex(tab_widget_->count() - 1);
page->GetTextPage()->setFocus();
connect(page->GetTextPage()->document(), &QTextDocument::modificationChanged,
@@ -96,8 +94,7 @@ void TextEdit::SlotNewTabWithContent(std::string title,
this, &TextEdit::slot_save_status_to_cache_for_revovery);
// set content with modified status
- page->GetTextPage()->document()->setPlainText(
- QString::fromStdString(content));
+ page->GetTextPage()->document()->setPlainText(content);
}
void TextEdit::slotNewHelpTab(const QString& title, const QString& path) const {
@@ -106,10 +103,15 @@ void TextEdit::slotNewHelpTab(const QString& title, const QString& path) const {
tab_widget_->setCurrentIndex(tab_widget_->count() - 1);
}
-void TextEdit::SlotNewFileTab() const {
- auto* page = new FilePage(qobject_cast<QWidget*>(parent()));
+void TextEdit::SlotNewFileTab() {
+ auto const target_dir = QFileDialog::getExistingDirectory(
+ this, tr("Open Directory"), QDir::home().path(),
+ QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
+ if (target_dir.isEmpty()) return;
+
+ auto* page = new FilePage(qobject_cast<QWidget*>(parent()), target_dir);
auto index = tab_widget_->addTab(page, QString());
- tab_widget_->setTabIcon(index, QIcon(":file-browser.png"));
+ tab_widget_->setTabIcon(index, QIcon(":/icons/file-browser.png"));
tab_widget_->setCurrentIndex(tab_widget_->count() - 1);
connect(page, &FilePage::SignalPathChanged, this,
&TextEdit::slot_file_page_path_changed);
@@ -118,7 +120,8 @@ void TextEdit::SlotNewFileTab() const {
void TextEdit::SlotOpenFile(const QString& path) {
QFile file(path);
- SPDLOG_DEBUG("path: {}", path.toStdString());
+ GF_UI_LOG_DEBUG("main window editor is opening file at path: {}",
+ path.toStdString());
auto result = file.open(QIODevice::ReadOnly | QIODevice::Text);
if (result) {
auto* page = new PlainTextEditorPage(path);
@@ -131,17 +134,15 @@ void TextEdit::SlotOpenFile(const QString& path) {
QApplication::setOverrideCursor(Qt::WaitCursor);
auto index = tab_widget_->addTab(page, stripped_name(path));
- tab_widget_->setTabIcon(index, QIcon(":file.png"));
+ tab_widget_->setTabIcon(index, QIcon(":/icons/file.png"));
tab_widget_->setCurrentIndex(tab_widget_->count() - 1);
QApplication::restoreOverrideCursor();
page->GetTextPage()->setFocus();
page->ReadFile();
} else {
- QMessageBox::warning(this, _("Warning"),
- (boost::format(_("Cannot read file %1%:\n%2%.")) %
- path.toStdString() % file.errorString().toStdString())
- .str()
- .c_str());
+ QMessageBox::warning(
+ this, tr("Warning"),
+ tr("Cannot read file %1:\n%2.").arg(path).arg(file.errorString()));
}
file.close();
@@ -149,7 +150,7 @@ void TextEdit::SlotOpenFile(const QString& path) {
void TextEdit::SlotOpen() {
QStringList file_names =
- QFileDialog::getOpenFileNames(this, _("Open file"), QDir::currentPath());
+ QFileDialog::getOpenFileNames(this, tr("Open file"), QDir::currentPath());
for (const auto& file_name : file_names) {
if (!file_name.isEmpty()) {
SlotOpenFile(file_name);
@@ -162,14 +163,14 @@ void TextEdit::SlotSave() {
return;
}
- QString fileName = SlotCurPageTextEdit()->GetFilePath();
+ QString file_name = SlotCurPageTextEdit()->GetFilePath();
- if (fileName.isEmpty()) {
+ if (file_name.isEmpty()) {
// QString docname = tabWidget->tabText(tabWidget->currentIndex());
// docname.remove(0,2);
SlotSaveAs();
} else {
- save_file(fileName);
+ save_file(file_name);
}
}
@@ -181,54 +182,31 @@ bool TextEdit::save_file(const QString& fileName) {
PlainTextEditorPage* page = SlotCurPageTextEdit();
if (page == nullptr) return false;
- if (page->WillCharsetChange()) {
- auto result = QMessageBox::warning(
- this, _("Save"),
- QString("<p>") +
- _("After saving, the encoding of the current file will be "
- "converted to UTF-8 and the line endings will be changed to "
- "LF. ") +
- "</p>" + "<p>" +
- _("If this is not the result you expect, please use \"save "
- "as\".") +
- "</p>",
- QMessageBox::Save | QMessageBox::Cancel, QMessageBox::Cancel);
-
- if (result == QMessageBox::Cancel) {
- return false;
- }
- }
-
QFile file(fileName);
-
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
- QTextStream outputStream(&file);
+ QTextStream output_stream(&file);
QApplication::setOverrideCursor(Qt::WaitCursor);
- outputStream << page->GetTextPage()->toPlainText();
+ output_stream << page->GetTextPage()->toPlainText();
QApplication::restoreOverrideCursor();
QTextDocument* document = page->GetTextPage()->document();
document->setModified(false);
- int curIndex = tab_widget_->currentIndex();
- tab_widget_->setTabText(curIndex, stripped_name(fileName));
+ int cur_index = tab_widget_->currentIndex();
+ tab_widget_->setTabText(cur_index, stripped_name(fileName));
page->SetFilePath(fileName);
page->NotifyFileSaved();
file.close();
return true;
- } else {
- QMessageBox::warning(
- this, _("Warning"),
- (boost::format(_("Cannot read file %1%:\n%2%.")) %
- fileName.toStdString() % file.errorString().toStdString())
- .str()
- .c_str());
- return false;
}
+ QMessageBox::warning(
+ this, tr("Warning"),
+ tr("Cannot read file %1:\n%2.").arg(fileName).arg(file.errorString()));
+ return false;
}
-bool TextEdit::SlotSaveAs() {
+auto TextEdit::SlotSaveAs() -> bool {
if (tab_widget_->count() == 0 || SlotCurPageTextEdit() == nullptr) {
return true;
}
@@ -241,8 +219,7 @@ bool TextEdit::SlotSaveAs() {
path = tab_widget_->tabText(tab_widget_->currentIndex()).remove(0, 2);
}
- QString fileName = QFileDialog::getSaveFileName(this, _("Save file"), path);
- return save_file(fileName);
+ return save_file(QFileDialog::getSaveFileName(this, tr("Save file"), path));
}
void TextEdit::SlotCloseTab() {
@@ -303,13 +280,13 @@ bool TextEdit::maybe_save_current_tab(bool askToSave) {
const QString& file_path = page->GetFilePath();
if (askToSave) {
result = QMessageBox::warning(
- this, _("Unsaved document"),
- QString(_("The document \"%1\" has been modified. Do you want to "
- "save your changes?"))
+ this, tr("Unsaved document"),
+ tr("The document \"%1\" has been modified. Do you want to "
+ "save your changes?")
.arg(doc_name) +
- "<br/><b>" + _("Note:") + "</b>" +
- _("If you don't save these files, all changes are "
- "lost.") +
+ "<br/><b>" + tr("Note:") + "</b>" +
+ tr("If you don't save these files, all changes are "
+ "lost.") +
"<br/>",
QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
}
@@ -318,20 +295,16 @@ bool TextEdit::maybe_save_current_tab(bool askToSave) {
// QString docname = tabWidget->tabText(tabWidget->currentIndex());
// docname.remove(0,2);
return SlotSaveAs();
- } else {
- return save_file(file_path);
}
- } else if (result == QMessageBox::Discard) {
- return true;
- } else {
- return false;
+ return save_file(file_path);
}
+ return result == QMessageBox::Discard;
}
page->deleteLater();
return true;
}
-bool TextEdit::MaybeSaveAnyTab() {
+auto TextEdit::MaybeSaveAnyTab() -> bool {
// get a list of all unsaved documents and their tabids
QHash<int, QString> unsaved_docs = this->UnsavedDocuments();
@@ -346,8 +319,8 @@ bool TextEdit::MaybeSaveAnyTab() {
* and show normal unsaved doc dialog
*/
if (unsaved_docs.size() == 1) {
- int modifiedTab = unsaved_docs.keys().at(0);
- tab_widget_->setCurrentIndex(modifiedTab);
+ int modified_tab = unsaved_docs.keys().at(0);
+ tab_widget_->setCurrentIndex(modified_tab);
return maybe_save_current_tab(true);
}
@@ -355,32 +328,29 @@ bool TextEdit::MaybeSaveAnyTab() {
* more than one unsaved documents
*/
if (unsaved_docs.size() > 1) {
- QHashIterator<int, QString> i(unsaved_docs);
+ QHashIterator<int, QString> const i(unsaved_docs);
QuitDialog* dialog;
- dialog = new QuitDialog(this, unsaved_docs);
- int result = dialog->exec();
+ dialog = new QuitDialog(
+ this->parentWidget() != nullptr ? this->parentWidget() : this,
+ unsaved_docs);
+ int const result = dialog->exec();
// if result is QDialog::Rejected, discard or cancel was clicked
if (result == QDialog::Rejected) {
// return true, if discard is clicked, so app can be closed
- if (dialog->IsDiscarded()) {
- return true;
- } else {
- return false;
- }
- } else {
- bool all_saved = true;
- QList<int> tabIdsToSave = dialog->GetTabIdsToSave();
-
- for (const auto& tabId : tabIdsToSave) {
- tab_widget_->setCurrentIndex(tabId);
- if (!maybe_save_current_tab(false)) {
- all_saved = false;
- }
+ return dialog->IsDiscarded();
+ }
+
+ bool all_saved = true;
+ QList<int> const tab_ids_to_save = dialog->GetTabIdsToSave();
+ for (const auto& tab_id : tab_ids_to_save) {
+ tab_widget_->setCurrentIndex(tab_id);
+ if (!maybe_save_current_tab(false)) {
+ all_saved = false;
}
- return all_saved;
}
+ return all_saved;
}
// code should never reach this statement
return false;
@@ -390,26 +360,30 @@ PlainTextEditorPage* TextEdit::CurTextPage() const {
return qobject_cast<PlainTextEditorPage*>(tab_widget_->currentWidget());
}
+void TextEdit::SlotAppendText2CurTextPage(const QString& text) {
+ if (CurTextPage() == nullptr) SlotNewTab();
+ CurTextPage()->GetTextPage()->appendPlainText(text);
+}
+
FilePage* TextEdit::CurFilePage() const {
- auto* curFilePage = qobject_cast<FilePage*>(tab_widget_->currentWidget());
- if (curFilePage != nullptr) {
- return curFilePage;
- } else {
- return nullptr;
+ auto* cur_file_page = qobject_cast<FilePage*>(tab_widget_->currentWidget());
+ if (cur_file_page != nullptr) {
+ return cur_file_page;
}
+ return nullptr;
}
int TextEdit::TabCount() const { return tab_widget_->count(); }
PlainTextEditorPage* TextEdit::SlotCurPageTextEdit() const {
- auto* curPage =
+ auto* cur_page =
qobject_cast<PlainTextEditorPage*>(tab_widget_->currentWidget());
- return curPage;
+ return cur_page;
}
FilePage* TextEdit::SlotCurPageFileTreeView() const {
- auto* curPage = qobject_cast<FilePage*>(tab_widget_->currentWidget());
- return curPage;
+ auto* cur_page = qobject_cast<FilePage*>(tab_widget_->currentWidget());
+ return cur_page;
}
void TextEdit::SlotQuote() const {
@@ -446,11 +420,8 @@ void TextEdit::LoadFile(const QString& fileName) {
QFile file(fileName);
if (!file.open(QFile::ReadOnly | QFile::Text)) {
QMessageBox::warning(
- this, _("Warning"),
- (boost::format(_("Cannot read file %1%:\n%2%.")) %
- fileName.toStdString() % file.errorString().toStdString())
- .str()
- .c_str());
+ this, tr("Warning"),
+ tr("Cannot read file %1:\n%2.").arg(fileName).arg(file.errorString()));
return;
}
QTextStream in(&file);
@@ -460,7 +431,7 @@ void TextEdit::LoadFile(const QString& fileName) {
SlotCurPageTextEdit()->SetFilePath(fileName);
tab_widget_->setTabText(tab_widget_->currentIndex(), stripped_name(fileName));
file.close();
- // statusBar()->showMessage(_("File loaded"), 2000);
+ // statusBar()->showMessage(tr("File loaded"), 2000);
}
QString TextEdit::stripped_name(const QString& full_file_name) {
@@ -483,9 +454,13 @@ void TextEdit::SlotPrint() {
if (dlg->exec() != QDialog::Accepted) {
return;
}
- document->print(&printer);
+ if (document != nullptr) {
+ document->print(&printer);
+ } else {
+ QMessageBox::warning(this, tr("Warning"), tr("No document to print"));
+ }
- // statusBar()->showMessage(_("Ready"), 2000);
+ // statusBar()->showMessage(tr("Ready"), 2000);
#endif
}
@@ -528,22 +503,22 @@ 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> unsaved_docs; // this list could be used to implement
+ // gedit like "unsaved changed"-dialog
for (int i = 0; i < tab_widget_->count(); i++) {
auto* ep = qobject_cast<PlainTextEditorPage*>(tab_widget_->widget(i));
if (ep != nullptr && ep->ReadDone() &&
ep->GetTextPage()->document()->isModified()) {
QString doc_name = tab_widget_->tabText(i);
- SPDLOG_DEBUG("unsaved: {}", doc_name.toStdString());
+ GF_UI_LOG_DEBUG("unsaved: {}", doc_name.toStdString());
// remove * before name of modified doc
doc_name.remove(0, 2);
- unsavedDocs.insert(i, doc_name);
+ unsaved_docs.insert(i, doc_name);
}
}
- return unsavedDocs;
+ return unsaved_docs;
}
void TextEdit::SlotCut() const {
@@ -617,42 +592,38 @@ void TextEdit::SlotSelectAll() const {
void TextEdit::slot_file_page_path_changed(const QString& path) const {
int index = tab_widget_->currentIndex();
- QString mPath;
- QFileInfo fileInfo(path);
- QString tPath = fileInfo.absoluteFilePath();
+ QString m_path;
+ QFileInfo file_info(path);
+ QString t_path = file_info.absoluteFilePath();
if (path.size() > 18) {
- mPath = tPath.mid(tPath.size() - 18, 18).prepend("...");
+ m_path = t_path.mid(t_path.size() - 18, 18).prepend("...");
} else {
- mPath = tPath;
+ m_path = t_path;
}
- tab_widget_->setTabText(index, mPath);
+ tab_widget_->setTabText(index, m_path);
}
void TextEdit::slot_save_status_to_cache_for_revovery() {
if (this->text_page_data_modified_count_++ % 8 != 0) return;
- auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
- bool restore_text_editor_page = false;
- try {
- restore_text_editor_page =
- settings.lookup("general.restore_text_editor_page");
- } catch (...) {
- SPDLOG_ERROR("setting operation error: restore_text_editor_page");
- }
+ auto settings =
+ GpgFrontend::GlobalSettingStation::GetInstance().GetSettings();
+ bool restore_text_editor_page =
+ settings.value("basic/restore_text_editor_page", false).toBool();
if (!restore_text_editor_page) {
- SPDLOG_DEBUG("restore_text_editor_page is false, ignoring...");
+ GF_UI_LOG_DEBUG("restore_text_editor_page is false, ignoring...");
return;
}
int tab_count = tab_widget_->count();
- SPDLOG_DEBUG(
+ GF_UI_LOG_DEBUG(
"restore_text_editor_page is true, pan to save pages, current tabs "
"count: "
"{}",
tab_count);
- std::vector<std::tuple<int, std::string, std::string>> unsaved_pages;
+ std::vector<std::tuple<int, QString, QString>> unsaved_pages;
for (int i = 0; i < tab_count; i++) {
auto* target_page =
@@ -664,31 +635,31 @@ void TextEdit::slot_save_status_to_cache_for_revovery() {
}
auto* document = target_page->GetTextPage()->document();
- auto tab_title = tab_widget_->tabText(i).toStdString();
+ auto tab_title = tab_widget_->tabText(i);
if (!target_page->ReadDone() || !target_page->isEnabled() ||
!document->isModified()) {
continue;
}
- auto raw_text = document->toRawText().toStdString();
- SPDLOG_DEBUG("unsaved page index: {}, tab title: {} tab content: {}", i,
- tab_title, raw_text.size());
- unsaved_pages.push_back({i, tab_title, raw_text});
+ auto raw_text = document->toRawText();
+ GF_UI_LOG_DEBUG("unsaved page index: {}, tab title: {}", i, tab_title);
+ unsaved_pages.emplace_back(i, tab_title, raw_text);
}
- nlohmann::json unsaved_page_array = nlohmann::json::array();
+ CacheObject cache("editor_unsaved_pages");
+ QJsonArray unsaved_page_array;
for (const auto& page : unsaved_pages) {
- nlohmann::json page_json;
- page_json["index"] = std::get<0>(page);
- page_json["title"] = std::get<1>(page);
- page_json["content"] = std::get<2>(page);
+ const auto [index, title, content] = page;
+
+ QJsonObject page_json;
+ page_json["index"] = index;
+ page_json["title"] = title;
+ page_json["content"] = content;
unsaved_page_array.push_back(page_json);
}
- SPDLOG_DEBUG("unsaved page json array: {}", unsaved_page_array.dump());
- CacheManager::GetInstance().SaveCache("editor_unsaved_pages",
- unsaved_page_array);
+ cache.setArray(unsaved_page_array);
}
} // namespace GpgFrontend::UI
diff --git a/src/ui/widgets/TextEdit.h b/src/ui/widgets/TextEdit.h
index f69bda4c..cba1c6e4 100644
--- a/src/ui/widgets/TextEdit.h
+++ b/src/ui/widgets/TextEdit.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,14 +20,13 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef __TEXTEDIT_H__
-#define __TEXTEDIT_H__
+#pragma once
#include "ui/dialog/QuitDialog.h"
#include "ui/widgets/FilePage.h"
@@ -154,7 +153,7 @@ class TextEdit : public QWidget {
* @details
*
*/
- void SlotNewTabWithContent(std::string title, const std::string& content);
+ void SlotNewTabWithContent(QString title, const QString& content);
/**
* @details Adds a new tab with opening file by path
@@ -172,7 +171,7 @@ class TextEdit : public QWidget {
/**
* New File Tab to do file operation
*/
- void SlotNewFileTab() const;
+ void SlotNewFileTab();
/**
* @details put a * in front of current tabs title, if current textedit is
@@ -283,6 +282,13 @@ class TextEdit : public QWidget {
*/
void SlotSelectAll() const;
+ /**
+ * @brief
+ *
+ * @param text
+ */
+ void SlotAppendText2CurTextPage(const QString& text);
+
protected:
/**
* @brief Saves the content of currentTab to the file filename
@@ -293,5 +299,3 @@ class TextEdit : public QWidget {
};
} // namespace GpgFrontend::UI
-
-#endif // __TEXTEDIT_H__
diff --git a/src/ui/widgets/VerifyKeyDetailBox.cpp b/src/ui/widgets/VerifyKeyDetailBox.cpp
index 192b09f3..c2dd74d3 100644
--- a/src/ui/widgets/VerifyKeyDetailBox.cpp
+++ b/src/ui/widgets/VerifyKeyDetailBox.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,7 +20,7 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
@@ -28,8 +28,10 @@
#include "ui/widgets/VerifyKeyDetailBox.h"
+#include "core/GpgModel.h"
#include "core/function/GlobalSettingStation.h"
#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/utils/CommonUtils.h"
namespace GpgFrontend::UI {
@@ -43,21 +45,23 @@ VerifyKeyDetailBox::VerifyKeyDetailBox(const GpgSignature& signature,
this->setTitle("A Error Signature");
bool forbid_all_gnupg_connection =
- GlobalSettingStation::GetInstance().LookupSettings(
- "network.forbid_all_gnupg_connection", false);
+ GlobalSettingStation::GetInstance()
+ .GetSettings()
+ .value("network/forbid_all_gnupg_connection", false)
+ .toBool();
- auto* import_button = new QPushButton(_("Import from keyserver"));
+ auto* import_button = new QPushButton(tr("Import from keyserver"));
import_button->setDisabled(forbid_all_gnupg_connection);
connect(import_button, &QPushButton::clicked, this,
&VerifyKeyDetailBox::slot_import_form_key_server);
- this->setTitle(QString(_("Key not present with id 0x")) + fpr_.c_str());
+ this->setTitle(tr("Key not present with id 0x") + fpr_);
- auto grid = new QGridLayout();
+ auto* grid = new QGridLayout();
- 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(tr("Status") + tr(":")), 0, 0);
+ // grid->addWidget(new QLabel(tr("Fingerprint:")), 1, 0);
+ grid->addWidget(new QLabel(tr("Key not present in key list")), 0, 1);
// grid->addWidget(new QLabel(signature->fpr), 1, 1);
grid->addWidget(import_button, 2, 0, 2, 1);
@@ -65,96 +69,91 @@ VerifyKeyDetailBox::VerifyKeyDetailBox(const GpgSignature& signature,
break;
}
case GPG_ERR_NO_ERROR: {
- this->setTitle(QString(_("A Signature")) + ":");
- auto gird = create_key_info_grid(signature);
+ this->setTitle(tr("A Signature") + ":");
+ auto* gird = create_key_info_grid(signature);
if (gird != nullptr) {
vbox->addLayout(gird);
} else {
- vbox->addWidget(new QLabel(_("Key Information is NOT Available")));
- if (!signature.GetFingerprint().empty()) {
- vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " +
- signature.GetFingerprint().c_str()));
+ vbox->addWidget(new QLabel(tr("Key Information is NOT Available")));
+ if (!signature.GetFingerprint().isEmpty()) {
+ vbox->addWidget(new QLabel(tr("Fingerprint") + ": " +
+ signature.GetFingerprint()));
}
}
break;
}
case GPG_ERR_CERT_REVOKED: {
this->setTitle("An Error Signature");
- vbox->addWidget(
- new QLabel(QString(_("Status")) + ":" + _("Cert Revoked")));
- auto gird = create_key_info_grid(signature);
+ vbox->addWidget(new QLabel(tr("Status") + ":" + tr("Cert Revoked")));
+ auto* gird = create_key_info_grid(signature);
if (gird != nullptr) {
vbox->addLayout(gird);
} else {
- vbox->addWidget(new QLabel(_("Key Information is NOT Available")));
- if (!signature.GetFingerprint().empty()) {
- vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " +
- signature.GetFingerprint().c_str()));
+ vbox->addWidget(new QLabel(tr("Key Information is NOT Available")));
+ if (!signature.GetFingerprint().isEmpty()) {
+ vbox->addWidget(new QLabel(tr("Fingerprint") + ": " +
+ signature.GetFingerprint()));
}
}
break;
}
case GPG_ERR_SIG_EXPIRED: {
this->setTitle("An Error Signature");
- vbox->addWidget(
- new QLabel(QString(_("Status")) + ":" + _("Signature Expired")));
- auto gird = create_key_info_grid(signature);
+ vbox->addWidget(new QLabel(tr("Status") + ":" + tr("Signature Expired")));
+ auto* gird = create_key_info_grid(signature);
if (gird != nullptr) {
vbox->addLayout(gird);
} else {
- vbox->addWidget(new QLabel(_("Key Information is NOT Available")));
- if (!signature.GetFingerprint().empty()) {
- vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " +
- signature.GetFingerprint().c_str()));
+ vbox->addWidget(new QLabel(tr("Key Information is NOT Available")));
+ if (!signature.GetFingerprint().isEmpty()) {
+ vbox->addWidget(new QLabel(tr("Fingerprint") + ": " +
+ signature.GetFingerprint()));
}
}
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 = create_key_info_grid(signature);
+ vbox->addWidget(new QLabel(tr("Status") + ":" + tr("Key Expired")));
+ vbox->addWidget(new QLabel(tr("Status") + ":" + tr("Key Expired")));
+ auto* gird = create_key_info_grid(signature);
if (gird != nullptr) {
vbox->addLayout(gird);
} else {
- vbox->addWidget(new QLabel(_("Key Information is NOT Available")));
- if (!signature.GetFingerprint().empty()) {
- vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " +
- signature.GetFingerprint().c_str()));
+ vbox->addWidget(new QLabel(tr("Key Information is NOT Available")));
+ if (!signature.GetFingerprint().isEmpty()) {
+ vbox->addWidget(new QLabel(tr("Fingerprint") + ": " +
+ signature.GetFingerprint()));
}
}
break;
}
case GPG_ERR_GENERAL: {
this->setTitle("An Error Signature");
- vbox->addWidget(
- new QLabel(QString(_("Status")) + ":" + _("General Error")));
- auto gird = create_key_info_grid(signature);
+ vbox->addWidget(new QLabel(tr("Status") + ":" + tr("General Error")));
+ auto* gird = create_key_info_grid(signature);
if (gird != nullptr) {
vbox->addLayout(gird);
} else {
- vbox->addWidget(new QLabel(_("Key Information is NOT Available")));
- if (!signature.GetFingerprint().empty()) {
- vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " +
- signature.GetFingerprint().c_str()));
+ vbox->addWidget(new QLabel(tr("Key Information is NOT Available")));
+ if (!signature.GetFingerprint().isEmpty()) {
+ vbox->addWidget(new QLabel(tr("Fingerprint") + ": " +
+ signature.GetFingerprint()));
}
}
break;
}
default: {
this->setTitle("An Error Signature");
- this->setTitle(QString(_("Status")) + ":" + _("Unknown Error "));
- auto gird = create_key_info_grid(signature);
+ this->setTitle(tr("Status") + ":" + tr("Unknown Error "));
+ auto* gird = create_key_info_grid(signature);
if (gird != nullptr) {
vbox->addLayout(gird);
} else {
- vbox->addWidget(new QLabel(_("Key Information is NOT Available")));
- if (!signature.GetFingerprint().empty()) {
- vbox->addWidget(new QLabel(QString(_("Fingerprint")) + ": " +
- signature.GetFingerprint().c_str()));
+ vbox->addWidget(new QLabel(tr("Key Information is NOT Available")));
+ if (!signature.GetFingerprint().isEmpty()) {
+ vbox->addWidget(new QLabel(tr("Fingerprint") + ": " +
+ signature.GetFingerprint()));
}
}
break;
@@ -164,59 +163,60 @@ VerifyKeyDetailBox::VerifyKeyDetailBox(const GpgSignature& signature,
}
void VerifyKeyDetailBox::slot_import_form_key_server() {
- auto* importDialog = new KeyServerImportDialog(false, this);
+ auto* import_dialog = new KeyServerImportDialog(this);
auto key_ids = std::make_unique<KeyIdArgsList>();
key_ids->push_back(fpr_);
- importDialog->SlotImport(key_ids);
+ import_dialog->SlotImport(key_ids);
}
-QGridLayout* VerifyKeyDetailBox::create_key_info_grid(
- const GpgSignature& signature) {
- auto grid = new QGridLayout();
- GpgKey key = GpgKeyGetter::GetInstance().GetKey(fpr_);
+auto VerifyKeyDetailBox::create_key_info_grid(const GpgSignature& signature)
+ -> QGridLayout* {
+ auto* grid = new QGridLayout();
+ auto key = GpgKeyGetter::GetInstance().GetKey(fpr_);
if (!key.IsGood()) 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.GetName())), 0, 1);
- grid->addWidget(new QLabel(QString::fromStdString(key.GetEmail())), 1, 1);
- grid->addWidget(new QLabel(beautify_fingerprint(fpr_).c_str()), 2, 1);
-
- if (signature.GetSummary() & GPGME_SIGSUM_VALID) {
- grid->addWidget(new QLabel(_("Fully Valid")), 3, 1);
+ 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.GetName()), 0, 1);
+ grid->addWidget(new QLabel(key.GetEmail()), 1, 1);
+ grid->addWidget(new QLabel(BeautifyFingerprint(fpr_)), 2, 1);
+
+ if ((signature.GetSummary() & GPGME_SIGSUM_VALID) != 0U) {
+ grid->addWidget(new QLabel(tr("Fully Valid")), 3, 1);
} else {
- grid->addWidget(new QLabel(_("NOT Fully Valid")), 3, 1);
+ grid->addWidget(new QLabel(tr("NOT Fully Valid")), 3, 1);
}
- std::stringstream text_stream;
+ QString buffer;
+ QTextStream text_stream(&buffer);
- if (signature.GetSummary() & GPGME_SIGSUM_GREEN) {
- text_stream << _("Good") << " ";
+ if ((signature.GetSummary() & GPGME_SIGSUM_GREEN) != 0U) {
+ text_stream << tr("Good") << " ";
}
- if (signature.GetSummary() & GPGME_SIGSUM_RED) {
- text_stream << _("Bad") << " ";
+ if ((signature.GetSummary() & GPGME_SIGSUM_RED) != 0U) {
+ text_stream << tr("Bad") << " ";
}
- if (signature.GetSummary() & GPGME_SIGSUM_SIG_EXPIRED) {
- text_stream << _("Expired") << " ";
+ if ((signature.GetSummary() & GPGME_SIGSUM_SIG_EXPIRED) != 0U) {
+ text_stream << tr("Expired") << " ";
}
- if (signature.GetSummary() & GPGME_SIGSUM_KEY_MISSING) {
- text_stream << _("Missing Key") << " ";
+ if ((signature.GetSummary() & GPGME_SIGSUM_KEY_MISSING) != 0U) {
+ text_stream << tr("Missing Key") << " ";
}
- if (signature.GetSummary() & GPGME_SIGSUM_KEY_REVOKED) {
- text_stream << _("Revoked Key") << " ";
+ if ((signature.GetSummary() & GPGME_SIGSUM_KEY_REVOKED) != 0U) {
+ text_stream << tr("Revoked Key") << " ";
}
- if (signature.GetSummary() & GPGME_SIGSUM_KEY_EXPIRED) {
- text_stream << _("Expired Key") << " ";
+ if ((signature.GetSummary() & GPGME_SIGSUM_KEY_EXPIRED) != 0U) {
+ text_stream << tr("Expired Key") << " ";
}
- if (signature.GetSummary() & GPGME_SIGSUM_CRL_MISSING) {
- text_stream << _("Missing CRL") << " ";
+ if ((signature.GetSummary() & GPGME_SIGSUM_CRL_MISSING) != 0U) {
+ text_stream << tr("Missing CRL") << " ";
}
- grid->addWidget(new QLabel(text_stream.str().c_str()), 4, 1);
+ grid->addWidget(new QLabel(text_stream.readAll()), 4, 1);
return grid;
}
diff --git a/src/ui/widgets/VerifyKeyDetailBox.h b/src/ui/widgets/VerifyKeyDetailBox.h
index 6ed9fd52..4885fdda 100644
--- a/src/ui/widgets/VerifyKeyDetailBox.h
+++ b/src/ui/widgets/VerifyKeyDetailBox.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Saturneric
+ * Copyright (C) 2021 Saturneric <[email protected]>
*
* This file is part of GpgFrontend.
*
@@ -20,14 +20,13 @@
* the gpg4usb project, which is under GPL-3.0-or-later.
*
* All the source code of GpgFrontend was modified and released by
- * Saturneric<[email protected]> starting on May 12, 2021.
+ * Saturneric <[email protected]> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
-#ifndef __VERIFYKEYDETAILBOX_H__
-#define __VERIFYKEYDETAILBOX_H__
+#pragma once
#include "ui/dialog/import_export/KeyServerImportDialog.h"
#include "ui/widgets/KeyList.h"
@@ -65,9 +64,7 @@ class VerifyKeyDetailBox : public QGroupBox {
*/
QGridLayout* create_key_info_grid(const GpgSignature& signature);
- std::string fpr_; ///< fingerprint of the key
+ QString fpr_; ///< fingerprint of the key
};
} // namespace GpgFrontend::UI
-
-#endif // __VERIFYKEYDETAILBOX_H__