diff options
| author | saturneric <[email protected]> | 2026-09-23 23:04:17 +0200 |
|---|---|---|
| committer | saturneric <[email protected]> | 2026-09-23 23:04:17 +0200 |
| commit | 925809823638085caf5aa47022a2f64e3c21b33b (patch) | |
| tree | c0db7f485e2d71eb1fa72dadf560f84bc5afc103 /src | |
| parent | feat(modules): enable custom UI capabilities (diff) | |
| download | modules-925809823638085caf5aa47022a2f64e3c21b33b.tar.gz modules-925809823638085caf5aa47022a2f64e3c21b33b.zip | |
feat(gpg-info): expose GnuPG details through scripted UI
- register a native GnuPG information widget with the host
- add a command for opening the information dialog
- mount the Help menu action through the Lua UI script
- remove legacy menu and dialog event handling
- declare the command and Lua script in module metadata
Diffstat (limited to 'src')
| -rw-r--r-- | src/m_gpg_info/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | src/m_gpg_info/GnuPGInfoGatheringModule.cpp | 114 | ||||
| -rw-r--r-- | src/m_gpg_info/GnupgTab.cpp | 2 | ||||
| -rw-r--r-- | src/m_gpg_info/module.json | 5 | ||||
| -rw-r--r-- | src/m_gpg_info/ui/main.lua | 13 |
5 files changed, 67 insertions, 70 deletions
diff --git a/src/m_gpg_info/CMakeLists.txt b/src/m_gpg_info/CMakeLists.txt index 3967bbb..c89ccfb 100644 --- a/src/m_gpg_info/CMakeLists.txt +++ b/src/m_gpg_info/CMakeLists.txt @@ -27,4 +27,5 @@ # capabilities and translation context -- lives in module.json beside this file. gf_add_module( NAME gpg_info - QT Core Widgets Concurrent) + QT Core Widgets Concurrent + LUA_SCRIPTS ui/main.lua) diff --git a/src/m_gpg_info/GnuPGInfoGatheringModule.cpp b/src/m_gpg_info/GnuPGInfoGatheringModule.cpp index 72998c1..2405910 100644 --- a/src/m_gpg_info/GnuPGInfoGatheringModule.cpp +++ b/src/m_gpg_info/GnuPGInfoGatheringModule.cpp @@ -32,15 +32,11 @@ #include <GFSDKLog.h> // qt -#include <QApplication> #include <QCoreApplication> #include <QCryptographicHash> -#include <QDialog> #include <QDir> #include <QFileInfo> #include <QJsonDocument> -#include <QMainWindow> -#include <QMenu> #include <QString> #include <QVBoxLayout> @@ -49,6 +45,7 @@ #include "GFModule.h" #include "GFModuleIdentity.h" +#include "GFSDKHostCommands.hpp" #include "GnupgTab.h" #include "GpgInfo.h" @@ -67,40 +64,51 @@ extern auto StartStartGatheringGnuPGComponentsInfo( const QString &gpgme_version, const QString &gpgconf_path, const QString &default_home_path) -> int; -extern auto GnupgTabFactory(void *id) -> void *; - using Context = struct { QString gpgme_version; QString gpgconf_path; GpgComponentInfo component_info; }; -auto OnActivate() -> GFResult { - LOG_INFO("gnupg info gathering module registering"); - return GFResult::Ok(); -} - namespace { -auto RaiseUpdateDialog(QWidget *parent) -> QDialog * { - auto *dialog = new QDialog(parent); - dialog->setWindowTitle(QCoreApplication::translate("GTrC", "GnuPG")); - dialog->setModal(true); - dialog->setAttribute(Qt::WA_DeleteOnClose); - auto *layout = new QVBoxLayout(); - auto *update_tab = new GnupgTab(dialog); - layout->addWidget(update_tab); - dialog->setLayout(layout); - dialog->resize(500, 600); - dialog->show(); - return dialog; +/// What GnuPG is installed and how it is configured, in a dialog frame the +/// Host owns. +class GnupgInfoWidget : public QWidget, public gf::ui::DialogWidget { + public: + GnupgInfoWidget() { + auto* layout = new QVBoxLayout(this); + layout->addWidget(new GnupgTab(this)); + } +}; + +/// Help > GnuPG. Its title and whereabouts are the command's and the +/// script's; it only opens the module's own dialog. +struct ShowGnupgInfo { + static constexpr gf::cmd::Meta kMeta{ + GF_MODULE_ID ".show_gnupg_info", GC_TR("GnuPG"), + GC_TR("Information about GnuPG"), "", 0, gf::cmd::kNeedsGuiThread}; + using Args = gf::cmd::Unit; + using Result = gf::cmd::Unit; +}; + +auto DoShowGnupgInfo(const gf::cmd::CommandContext& /*ctx*/, + const gf::cmd::Unit& /*args*/) + -> gf::cmd::Outcome<gf::cmd::Unit> { + Commands().Invoke<gf::cmd::host::ViewOpen>( + {gf::cmd::ViewRef{QStringLiteral(GF_MODULE_ID ".info")}}); + return gf::cmd::Outcome<gf::cmd::Unit>::Success({}); } + } // namespace -auto OnApplicationLoaded(const GFEvent & /*event*/) -> GFEventResult { - // Subscribed but with nothing to do: the module wants the host to consider - // it a listener of this event, and answering is all that is required. - return GFEventResult::Ok(); +auto OnActivate() -> GFResult { + LOG_INFO("gnupg info gathering module registering"); + const bool ok = gf::ui::RegisterNativeWidget<GnupgInfoWidget>( + "info", {GC_TR("GnuPG"), "", "", "", ":/icons/key.png", 500, 600}, + [](const QCborMap& /*args*/) { return new GnupgInfoWidget(); }); + return ok ? GFResult::Ok() + : GFResult::Fail("the GnuPG information widget was not registered"); } auto OnRequestGatheringAllGnuPGInfo(const GFEvent & /*event*/) @@ -113,53 +121,29 @@ auto OnUnload() -> void { LOG_INFO("gnupg info gathering module unregistering"); } -auto OnMainWindowMenuMounted(const GFEvent &event) -> GFEventResult { - QMainWindow *main_window = nullptr; - if (auto r = event.RequireGui("main_window", main_window); !r.ok) return r; - - QMenu *help_menu = nullptr; - if (auto r = event.RequireGui("help_menu", help_menu); !r.ok) return r; - - LOG_DEBUG("adding check update action to help menu"); - - QMetaObject::invokeMethod( - QApplication::instance(), - [&]() -> void { - QWidget *parent = - qobject_cast<QWidget *>(static_cast<QObject *>(main_window)); - auto *action = - new QAction(QCoreApplication::translate("GTrC", "GnuPG"), nullptr); - action->setToolTip( - QCoreApplication::translate("GTrC", "Information about GnuPG")); - action->setIcon(QIcon(":/icons/key.png")); - QObject::connect(action, &QAction::triggered, parent, - [=]() { RaiseUpdateDialog(parent); }); - help_menu->addAction(action); - }, - Qt::BlockingQueuedConnection); - - return GFEventResult::Ok(); -} - -// The module's whole framework surface: which events it handles, what runs at -// each lifecycle point, and one forwarder to the runtime that implements all -// of it. Everything above is business logic. -constexpr GFEventBinding kEvents[] = { - {"APPLICATION_LOADED", &OnApplicationLoaded}, - {"MAINWINDOW_MENU_MOUNTED", &OnMainWindowMenuMounted}, +// The module's whole framework surface: which events it handles, what it +// provides, what runs at each lifecycle point, and one forwarder to the +// runtime that implements all of it. Everything above is business logic. +constexpr std::array<GFEventBinding, 1> kEvents = {{ {"REQUEST_GATHERING_ALL_GNUPG_INFO", &OnRequestGatheringAllGnuPGInfo}, +}}; + +const std::array<gf::cmd::Binding, 1> kCommands = { + gf::cmd::Bind<ShowGnupgInfo, &DoShowGnupgInfo>(), }; -constexpr GFModuleHooks kHooks = { +const GFModuleHooks kHooks = { sizeof(GFModuleHooks), GF_MODULE_ID, GF_MODULE_VERSION, GF_MODULE_TRANSLATION_CONTEXT, &OnActivate, - nullptr, // nothing registered with the host, so nothing to undo + nullptr, // the Host withdraws the command, widget and script itself &OnUnload, - kEvents, - std::size(kEvents), + kEvents.data(), + kEvents.size(), + kCommands.data(), + kCommands.size(), }; extern "C" GF_MODULE_EXPORT auto GFModuleGetApi(uint32_t abi) diff --git a/src/m_gpg_info/GnupgTab.cpp b/src/m_gpg_info/GnupgTab.cpp index 4581480..a340551 100644 --- a/src/m_gpg_info/GnupgTab.cpp +++ b/src/m_gpg_info/GnupgTab.cpp @@ -335,5 +335,3 @@ void GnupgTab::showEvent(QShowEvent* event) { slot_gather_gnupg_info(); } } - -auto GnupgTabFactory(void*) -> void* { return new GnupgTab(); }
\ No newline at end of file diff --git a/src/m_gpg_info/module.json b/src/m_gpg_info/module.json index db9257e..0f3efd4 100644 --- a/src/m_gpg_info/module.json +++ b/src/m_gpg_info/module.json @@ -13,9 +13,10 @@ "ui.custom" ], "events": [ - "APPLICATION_LOADED", - "MAINWINDOW_MENU_MOUNTED", "REQUEST_GATHERING_ALL_GNUPG_INFO" ], + "commands": [ + "com.bktus.gpgfrontend.module.gnupg_info_gathering.show_gnupg_info" + ], "translation_context": "ModuleGnuPGInfoGathering" } diff --git a/src/m_gpg_info/ui/main.lua b/src/m_gpg_info/ui/main.lua new file mode 100644 index 0000000..c5629ed --- /dev/null +++ b/src/m_gpg_info/ui/main.lua @@ -0,0 +1,13 @@ +-- GnuPG information: where it is offered. The dialog is the module's own +-- widget, in a frame the Host owns; the entry's title is the command's. + +local show = commands.get("com.bktus.gpgfrontend.module.gnupg_info_gathering.show_gnupg_info") + +ui.mount { id = "info", anchor = ui.anchor.dialog {}, widget = native.widget("info") } + +ui.action { + id = "help", + anchor = ui.anchor("main.menu.help"), + command = show, + icon = ":/icons/key.png", +} |
