From 4ab683fa7d947e89007313c995b8e3de134a14c1 Mon Sep 17 00:00:00 2001 From: f4exb Date: Sat, 3 Oct 2020 23:55:24 +0200 Subject: [PATCH] Feature plugins: use specialized FeatureGUI superclass. Handle GUI lifecycle in DeviceUISet --- .../feature/rigctlserver/rigctlservergui.cpp | 3 +- .../feature/rigctlserver/rigctlservergui.h | 5 +- .../rigctlserver/rigctlserverplugin.cpp | 4 +- .../feature/rigctlserver/rigctlserverplugin.h | 4 +- plugins/feature/simpleptt/simplepttgui.cpp | 3 +- plugins/feature/simpleptt/simplepttgui.h | 5 +- plugins/feature/simpleptt/simplepttplugin.cpp | 4 +- plugins/feature/simpleptt/simplepttplugin.h | 4 +- sdrbase/plugin/plugininterface.h | 3 +- sdrgui/CMakeLists.txt | 2 + sdrgui/feature/featuregui.cpp | 27 ++++++++++ sdrgui/feature/featuregui.h | 49 +++++++++++++++++++ sdrgui/feature/featureuiset.cpp | 25 ++++++++-- sdrgui/feature/featureuiset.h | 17 ++++--- sdrgui/mainwindow.cpp | 2 +- 15 files changed, 128 insertions(+), 29 deletions(-) create mode 100644 sdrgui/feature/featuregui.cpp create mode 100644 sdrgui/feature/featuregui.h diff --git a/plugins/feature/rigctlserver/rigctlservergui.cpp b/plugins/feature/rigctlserver/rigctlservergui.cpp index f81ae6227..b7bf9cf3e 100644 --- a/plugins/feature/rigctlserver/rigctlservergui.cpp +++ b/plugins/feature/rigctlserver/rigctlservergui.cpp @@ -116,7 +116,7 @@ void RigCtlServerGUI::onWidgetRolled(QWidget* widget, bool rollDown) } RigCtlServerGUI::RigCtlServerGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent) : - RollupWidget(parent), + FeatureGUI(parent), ui(new Ui::RigCtlServerGUI), m_pluginAPI(pluginAPI), m_featureUISet(featureUISet), @@ -145,7 +145,6 @@ RigCtlServerGUI::RigCtlServerGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISe RigCtlServerGUI::~RigCtlServerGUI() { - m_featureUISet->removeFeatureInstance(this); delete m_rigCtlServer; // When the GUI closes it has to delete the demodulator because it can be done with (x) delete ui; } diff --git a/plugins/feature/rigctlserver/rigctlservergui.h b/plugins/feature/rigctlserver/rigctlservergui.h index 738357a70..889a553fa 100644 --- a/plugins/feature/rigctlserver/rigctlservergui.h +++ b/plugins/feature/rigctlserver/rigctlservergui.h @@ -21,8 +21,7 @@ #include -#include "plugin/plugininstancegui.h" -#include "gui/rollupwidget.h" +#include "feature/featuregui.h" #include "util/messagequeue.h" #include "rigctlserversettings.h" @@ -34,7 +33,7 @@ namespace Ui { class RigCtlServerGUI; } -class RigCtlServerGUI : public RollupWidget, public PluginInstanceGUI { +class RigCtlServerGUI : public FeatureGUI { Q_OBJECT public: static RigCtlServerGUI* create(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature); diff --git a/plugins/feature/rigctlserver/rigctlserverplugin.cpp b/plugins/feature/rigctlserver/rigctlserverplugin.cpp index 339d82f12..8d9b406c1 100644 --- a/plugins/feature/rigctlserver/rigctlserverplugin.cpp +++ b/plugins/feature/rigctlserver/rigctlserverplugin.cpp @@ -57,14 +57,14 @@ void RigCtlServerPlugin::initPlugin(PluginAPI* pluginAPI) } #ifdef SERVER_MODE -PluginInstanceGUI* RigCtlServerPlugin::createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const +FeatureGUI* RigCtlServerPlugin::createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const { (void) featureUISet; (void) feature; return nullptr; } #else -PluginInstanceGUI* RigCtlServerPlugin::createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const +FeatureGUI* RigCtlServerPlugin::createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const { return RigCtlServerGUI::create(m_pluginAPI, featureUISet, feature); } diff --git a/plugins/feature/rigctlserver/rigctlserverplugin.h b/plugins/feature/rigctlserver/rigctlserverplugin.h index 455eb38da..d48131f84 100644 --- a/plugins/feature/rigctlserver/rigctlserverplugin.h +++ b/plugins/feature/rigctlserver/rigctlserverplugin.h @@ -22,6 +22,8 @@ #include #include "plugin/plugininterface.h" +class PluginInstanceGUI; +class FeatureGUI; class WebAPIAdapterInterface; class RigCtlServerPlugin : public QObject, PluginInterface { @@ -35,7 +37,7 @@ public: const PluginDescriptor& getPluginDescriptor() const; void initPlugin(PluginAPI* pluginAPI); - virtual PluginInstanceGUI* createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const; + virtual FeatureGUI* createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const; virtual Feature* createFeature(WebAPIAdapterInterface *webAPIAdapterInterface) const; virtual FeatureWebAPIAdapter* createFeatureWebAPIAdapter() const; diff --git a/plugins/feature/simpleptt/simplepttgui.cpp b/plugins/feature/simpleptt/simplepttgui.cpp index 434024cf8..6048dd26d 100644 --- a/plugins/feature/simpleptt/simplepttgui.cpp +++ b/plugins/feature/simpleptt/simplepttgui.cpp @@ -123,7 +123,7 @@ void SimplePTTGUI::onWidgetRolled(QWidget* widget, bool rollDown) } SimplePTTGUI::SimplePTTGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent) : - RollupWidget(parent), + FeatureGUI(parent), ui(new Ui::SimplePTTGUI), m_pluginAPI(pluginAPI), m_featureUISet(featureUISet), @@ -160,7 +160,6 @@ SimplePTTGUI::SimplePTTGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Fea SimplePTTGUI::~SimplePTTGUI() { - m_featureUISet->removeFeatureInstance(this); delete m_simplePTT; // When the GUI closes it has to delete the demodulator because it can be done with (x) delete ui; } diff --git a/plugins/feature/simpleptt/simplepttgui.h b/plugins/feature/simpleptt/simplepttgui.h index 5c5ad1a9f..539073eb4 100644 --- a/plugins/feature/simpleptt/simplepttgui.h +++ b/plugins/feature/simpleptt/simplepttgui.h @@ -20,8 +20,7 @@ #include -#include "plugin/plugininstancegui.h" -#include "gui/rollupwidget.h" +#include "feature/featuregui.h" #include "util/messagequeue.h" #include "simplepttsettings.h" @@ -33,7 +32,7 @@ namespace Ui { class SimplePTTGUI; } -class SimplePTTGUI : public RollupWidget, public PluginInstanceGUI { +class SimplePTTGUI : public FeatureGUI { Q_OBJECT public: static SimplePTTGUI* create(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature); diff --git a/plugins/feature/simpleptt/simplepttplugin.cpp b/plugins/feature/simpleptt/simplepttplugin.cpp index 454d3f328..906419e5b 100644 --- a/plugins/feature/simpleptt/simplepttplugin.cpp +++ b/plugins/feature/simpleptt/simplepttplugin.cpp @@ -56,14 +56,14 @@ void SimplePTTPlugin::initPlugin(PluginAPI* pluginAPI) } #ifdef SERVER_MODE -PluginInstanceGUI* SimplePTTPlugin::createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const +FeatureGUI* SimplePTTPlugin::createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const { (void) featureUISet; (void) feature; return nullptr; } #else -PluginInstanceGUI* SimplePTTPlugin::createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const +FeatureGUI* SimplePTTPlugin::createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const { return SimplePTTGUI::create(m_pluginAPI, featureUISet, feature); } diff --git a/plugins/feature/simpleptt/simplepttplugin.h b/plugins/feature/simpleptt/simplepttplugin.h index 330f65d2a..2e1f1274c 100644 --- a/plugins/feature/simpleptt/simplepttplugin.h +++ b/plugins/feature/simpleptt/simplepttplugin.h @@ -21,6 +21,8 @@ #include #include "plugin/plugininterface.h" +class PluginInstanceGUI; +class FeatureGUI; class WebAPIAdapterInterface; class SimplePTTPlugin : public QObject, PluginInterface { @@ -34,7 +36,7 @@ public: const PluginDescriptor& getPluginDescriptor() const; void initPlugin(PluginAPI* pluginAPI); - virtual PluginInstanceGUI* createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const; + virtual FeatureGUI* createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const; virtual Feature* createFeature(WebAPIAdapterInterface *webAPIAdapterInterface) const; virtual FeatureWebAPIAdapter* createFeatureWebAPIAdapter() const; diff --git a/sdrbase/plugin/plugininterface.h b/sdrbase/plugin/plugininterface.h index 45e6b9c1d..05d2f67d3 100644 --- a/sdrbase/plugin/plugininterface.h +++ b/sdrbase/plugin/plugininterface.h @@ -36,6 +36,7 @@ class ChannelWebAPIAdapter; class DeviceWebAPIAdapter; class FeatureWebAPIAdapter; class Feature; +class FeatureGUI; class SDRBASE_API PluginInterface { public: @@ -331,7 +332,7 @@ public: // Features - virtual PluginInstanceGUI* createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const + virtual FeatureGUI* createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const { return nullptr; } diff --git a/sdrgui/CMakeLists.txt b/sdrgui/CMakeLists.txt index 0509081b6..86d15d51f 100644 --- a/sdrgui/CMakeLists.txt +++ b/sdrgui/CMakeLists.txt @@ -69,6 +69,7 @@ set(sdrgui_SOURCES device/deviceuiset.cpp + feature/featuregui.cpp feature/featureuiset.cpp soapygui/discreterangegui.cpp @@ -152,6 +153,7 @@ set(sdrgui_HEADERS device/deviceuiset.h + feature/featuregui.h feature/featureuiset.h plugin/plugininstancegui.h diff --git a/sdrgui/feature/featuregui.cpp b/sdrgui/feature/featuregui.cpp new file mode 100644 index 000000000..df0790251 --- /dev/null +++ b/sdrgui/feature/featuregui.cpp @@ -0,0 +1,27 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2020 Edouard Griffiths, F4EXB // +// // +// 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 as version 3 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 V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include + +#include "featuregui.h" + +void FeatureGUI::closeEvent(QCloseEvent *event) +{ + qDebug("FeatureGUI::closeEvent"); + emit closing(); + event->accept(); +} diff --git a/sdrgui/feature/featuregui.h b/sdrgui/feature/featuregui.h new file mode 100644 index 000000000..8c0fee0b1 --- /dev/null +++ b/sdrgui/feature/featuregui.h @@ -0,0 +1,49 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2020 Edouard Griffiths, F4EXB // +// // +// 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 as version 3 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 V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef SDRGUI_FEATURE_FEATUREGUI_H_ +#define SDRGUI_FEATURE_FEATUREGUI_H_ + +#include "gui/rollupwidget.h" + +class QCloseEvent; +class MessageQueue; + +class FeatureGUI : public RollupWidget +{ + Q_OBJECT +public: + FeatureGUI(QWidget *parent = nullptr) : + RollupWidget(parent) + { } + virtual ~FeatureGUI() { } + virtual void destroy() = 0; + + virtual void resetToDefaults() = 0; + virtual QByteArray serialize() const = 0; + virtual bool deserialize(const QByteArray& data) = 0; + + virtual MessageQueue* getInputMessageQueue() = 0; + +protected: + void closeEvent(QCloseEvent *event); + +signals: + void closing(); +}; + +#endif // SDRGUI_FEATURE_FEATUREGUI_H_ diff --git a/sdrgui/feature/featureuiset.cpp b/sdrgui/feature/featureuiset.cpp index 5d27c1acd..7d10d887a 100644 --- a/sdrgui/feature/featureuiset.cpp +++ b/sdrgui/feature/featureuiset.cpp @@ -21,6 +21,7 @@ #include "settings/featuresetpreset.h" #include "feature/featureutils.h" #include "feature/feature.h" +#include "feature/featuregui.h" #include "featureuiset.h" @@ -40,16 +41,23 @@ void FeatureUISet::addRollupWidget(QWidget *widget) m_featureWindow->addRollupWidget(widget); } -void FeatureUISet::registerFeatureInstance(const QString& featureURI, PluginInstanceGUI* pluginGUI, Feature *feature) +void FeatureUISet::registerFeatureInstance(const QString& featureURI, FeatureGUI* featureGUI, Feature *feature) { - m_featureInstanceRegistrations.append(FeatureInstanceRegistration(featureURI, pluginGUI, feature)); + m_featureInstanceRegistrations.append(FeatureInstanceRegistration(featureURI, featureGUI, feature)); + QObject::connect( + featureGUI, + &FeatureGUI::closing, + this, + [=](){ this->handleClosingFeatureGUI(featureGUI); }, + Qt::QueuedConnection + ); } -void FeatureUISet::removeFeatureInstance(PluginInstanceGUI* pluginGUI) +void FeatureUISet::removeFeatureInstance(FeatureGUI* featureGUI) { for (FeatureInstanceRegistrations::iterator it = m_featureInstanceRegistrations.begin(); it != m_featureInstanceRegistrations.end(); ++it) { - if (it->m_gui == pluginGUI) + if (it->m_gui == featureGUI) { m_featureInstanceRegistrations.erase(it); break; @@ -140,7 +148,7 @@ void FeatureUISet::loadFeatureSetSettings(const FeatureSetPreset *preset, Plugin qPrintable(featureConfig.m_featureIdURI)); Feature *feature = (*featureRegistrations)[i].m_plugin->createFeature(apiAdapter); - PluginInstanceGUI *featureGUI = + FeatureGUI *featureGUI = (*featureRegistrations)[i].m_plugin->createFeatureGUI(this, feature); registerFeatureInstance(feature->getURI(), featureGUI, feature); break; @@ -165,3 +173,10 @@ void FeatureUISet::saveFeatureSetSettings(FeatureSetPreset *preset) preset->addFeature(m_featureInstanceRegistrations[i].m_featureURI, m_featureInstanceRegistrations[i].m_gui->serialize()); } } + + +void FeatureUISet::handleClosingFeatureGUI(FeatureGUI *featureGUI) +{ + qDebug("FeatureUISet::handleClosingFeatureGUI"); + removeFeatureInstance(featureGUI); +} diff --git a/sdrgui/feature/featureuiset.h b/sdrgui/feature/featureuiset.h index 1b7ea7ba6..52c70c085 100644 --- a/sdrgui/feature/featureuiset.h +++ b/sdrgui/feature/featureuiset.h @@ -18,6 +18,7 @@ #ifndef SDRGUI_FEATURE_FEATUREUISET_H_ #define SDRGUI_FEATURE_FEATUREUISET_H_ +#include #include #include @@ -25,22 +26,23 @@ class QWidget; class FeatureWindow; -class PluginInstanceGUI; +class FeatureGUI; class PluginAPI; class Feature; class FeatureSetPreset; class WebAPIAdapterInterface; -class SDRGUI_API FeatureUISet +class SDRGUI_API FeatureUISet : public QObject { + Q_OBJECT public: FeatureUISet(int tabIndex); ~FeatureUISet(); void addRollupWidget(QWidget *widget); //!< Add feature rollup widget to feature window int getNumberOfFeatures() const { return m_featureInstanceRegistrations.size(); } - void registerFeatureInstance(const QString& featureURI, PluginInstanceGUI* pluginGUI, Feature *feature); - void removeFeatureInstance(PluginInstanceGUI* pluginGUI); + void registerFeatureInstance(const QString& featureURI, FeatureGUI* featureGUI, Feature *feature); + void removeFeatureInstance(FeatureGUI* featureGUI); void freeFeatures(); void deleteFeature(int featureIndex); const Feature *getFeatureAt(int featureIndex) const; @@ -54,7 +56,7 @@ private: struct FeatureInstanceRegistration { QString m_featureURI; - PluginInstanceGUI* m_gui; + FeatureGUI* m_gui; Feature* m_feature; FeatureInstanceRegistration() : @@ -63,7 +65,7 @@ private: m_feature(nullptr) { } - FeatureInstanceRegistration(const QString& featureURI, PluginInstanceGUI* pluginGUI, Feature *feature) : + FeatureInstanceRegistration(const QString& featureURI, FeatureGUI* pluginGUI, Feature *feature) : m_featureURI(featureURI), m_gui(pluginGUI), m_feature(feature) @@ -76,6 +78,9 @@ private: FeatureInstanceRegistrations m_featureInstanceRegistrations; int m_featureTabIndex; + +private slots: + void handleClosingFeatureGUI(FeatureGUI *featureGUI); }; #endif // SDRGUI_FEATURE_FEATUREUISET_H_ diff --git a/sdrgui/mainwindow.cpp b/sdrgui/mainwindow.cpp index 00d034cb6..210cb4128 100644 --- a/sdrgui/mainwindow.cpp +++ b/sdrgui/mainwindow.cpp @@ -1978,7 +1978,7 @@ void MainWindow::featureAddClicked(int featureIndex) PluginAPI::FeatureRegistrations *featureRegistrations = m_pluginManager->getFeatureRegistrations(); // Available feature plugins PluginInterface *pluginInterface = (*featureRegistrations)[featureIndex].m_plugin; Feature *feature = pluginInterface->createFeature(m_apiAdapter); - PluginInstanceGUI *gui = pluginInterface->createFeatureGUI(featureUISet, feature); + FeatureGUI *gui = pluginInterface->createFeatureGUI(featureUISet, feature); featureUISet->registerFeatureInstance(feature->getURI(), gui, feature); } }