aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorsaturneric <[email protected]>2026-09-23 23:04:17 +0200
committersaturneric <[email protected]>2026-09-23 23:04:17 +0200
commit925809823638085caf5aa47022a2f64e3c21b33b (patch)
treec0db7f485e2d71eb1fa72dadf560f84bc5afc103 /src
parentfeat(modules): enable custom UI capabilities (diff)
downloadmodules-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.txt3
-rw-r--r--src/m_gpg_info/GnuPGInfoGatheringModule.cpp114
-rw-r--r--src/m_gpg_info/GnupgTab.cpp2
-rw-r--r--src/m_gpg_info/module.json5
-rw-r--r--src/m_gpg_info/ui/main.lua13
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",
+}