1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2025-09-03 05:37:50 -04:00

Feature plugins: use specialized FeatureGUI superclass. Handle GUI lifecycle in DeviceUISet

This commit is contained in:
f4exb 2020-10-03 23:55:24 +02:00
parent 1a9f67b55c
commit 4ab683fa7d
15 changed files with 128 additions and 29 deletions

View File

@ -116,7 +116,7 @@ void RigCtlServerGUI::onWidgetRolled(QWidget* widget, bool rollDown)
} }
RigCtlServerGUI::RigCtlServerGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent) : RigCtlServerGUI::RigCtlServerGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent) :
RollupWidget(parent), FeatureGUI(parent),
ui(new Ui::RigCtlServerGUI), ui(new Ui::RigCtlServerGUI),
m_pluginAPI(pluginAPI), m_pluginAPI(pluginAPI),
m_featureUISet(featureUISet), m_featureUISet(featureUISet),
@ -145,7 +145,6 @@ RigCtlServerGUI::RigCtlServerGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISe
RigCtlServerGUI::~RigCtlServerGUI() 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 m_rigCtlServer; // When the GUI closes it has to delete the demodulator because it can be done with (x)
delete ui; delete ui;
} }

View File

@ -21,8 +21,7 @@
#include <QTimer> #include <QTimer>
#include "plugin/plugininstancegui.h" #include "feature/featuregui.h"
#include "gui/rollupwidget.h"
#include "util/messagequeue.h" #include "util/messagequeue.h"
#include "rigctlserversettings.h" #include "rigctlserversettings.h"
@ -34,7 +33,7 @@ namespace Ui {
class RigCtlServerGUI; class RigCtlServerGUI;
} }
class RigCtlServerGUI : public RollupWidget, public PluginInstanceGUI { class RigCtlServerGUI : public FeatureGUI {
Q_OBJECT Q_OBJECT
public: public:
static RigCtlServerGUI* create(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature); static RigCtlServerGUI* create(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature);

View File

@ -57,14 +57,14 @@ void RigCtlServerPlugin::initPlugin(PluginAPI* pluginAPI)
} }
#ifdef SERVER_MODE #ifdef SERVER_MODE
PluginInstanceGUI* RigCtlServerPlugin::createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const FeatureGUI* RigCtlServerPlugin::createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const
{ {
(void) featureUISet; (void) featureUISet;
(void) feature; (void) feature;
return nullptr; return nullptr;
} }
#else #else
PluginInstanceGUI* RigCtlServerPlugin::createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const FeatureGUI* RigCtlServerPlugin::createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const
{ {
return RigCtlServerGUI::create(m_pluginAPI, featureUISet, feature); return RigCtlServerGUI::create(m_pluginAPI, featureUISet, feature);
} }

View File

@ -22,6 +22,8 @@
#include <QObject> #include <QObject>
#include "plugin/plugininterface.h" #include "plugin/plugininterface.h"
class PluginInstanceGUI;
class FeatureGUI;
class WebAPIAdapterInterface; class WebAPIAdapterInterface;
class RigCtlServerPlugin : public QObject, PluginInterface { class RigCtlServerPlugin : public QObject, PluginInterface {
@ -35,7 +37,7 @@ public:
const PluginDescriptor& getPluginDescriptor() const; const PluginDescriptor& getPluginDescriptor() const;
void initPlugin(PluginAPI* pluginAPI); 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 Feature* createFeature(WebAPIAdapterInterface *webAPIAdapterInterface) const;
virtual FeatureWebAPIAdapter* createFeatureWebAPIAdapter() const; virtual FeatureWebAPIAdapter* createFeatureWebAPIAdapter() const;

View File

@ -123,7 +123,7 @@ void SimplePTTGUI::onWidgetRolled(QWidget* widget, bool rollDown)
} }
SimplePTTGUI::SimplePTTGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent) : SimplePTTGUI::SimplePTTGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent) :
RollupWidget(parent), FeatureGUI(parent),
ui(new Ui::SimplePTTGUI), ui(new Ui::SimplePTTGUI),
m_pluginAPI(pluginAPI), m_pluginAPI(pluginAPI),
m_featureUISet(featureUISet), m_featureUISet(featureUISet),
@ -160,7 +160,6 @@ SimplePTTGUI::SimplePTTGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Fea
SimplePTTGUI::~SimplePTTGUI() 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 m_simplePTT; // When the GUI closes it has to delete the demodulator because it can be done with (x)
delete ui; delete ui;
} }

View File

@ -20,8 +20,7 @@
#include <QTimer> #include <QTimer>
#include "plugin/plugininstancegui.h" #include "feature/featuregui.h"
#include "gui/rollupwidget.h"
#include "util/messagequeue.h" #include "util/messagequeue.h"
#include "simplepttsettings.h" #include "simplepttsettings.h"
@ -33,7 +32,7 @@ namespace Ui {
class SimplePTTGUI; class SimplePTTGUI;
} }
class SimplePTTGUI : public RollupWidget, public PluginInstanceGUI { class SimplePTTGUI : public FeatureGUI {
Q_OBJECT Q_OBJECT
public: public:
static SimplePTTGUI* create(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature); static SimplePTTGUI* create(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature);

View File

@ -56,14 +56,14 @@ void SimplePTTPlugin::initPlugin(PluginAPI* pluginAPI)
} }
#ifdef SERVER_MODE #ifdef SERVER_MODE
PluginInstanceGUI* SimplePTTPlugin::createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const FeatureGUI* SimplePTTPlugin::createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const
{ {
(void) featureUISet; (void) featureUISet;
(void) feature; (void) feature;
return nullptr; return nullptr;
} }
#else #else
PluginInstanceGUI* SimplePTTPlugin::createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const FeatureGUI* SimplePTTPlugin::createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const
{ {
return SimplePTTGUI::create(m_pluginAPI, featureUISet, feature); return SimplePTTGUI::create(m_pluginAPI, featureUISet, feature);
} }

View File

@ -21,6 +21,8 @@
#include <QObject> #include <QObject>
#include "plugin/plugininterface.h" #include "plugin/plugininterface.h"
class PluginInstanceGUI;
class FeatureGUI;
class WebAPIAdapterInterface; class WebAPIAdapterInterface;
class SimplePTTPlugin : public QObject, PluginInterface { class SimplePTTPlugin : public QObject, PluginInterface {
@ -34,7 +36,7 @@ public:
const PluginDescriptor& getPluginDescriptor() const; const PluginDescriptor& getPluginDescriptor() const;
void initPlugin(PluginAPI* pluginAPI); 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 Feature* createFeature(WebAPIAdapterInterface *webAPIAdapterInterface) const;
virtual FeatureWebAPIAdapter* createFeatureWebAPIAdapter() const; virtual FeatureWebAPIAdapter* createFeatureWebAPIAdapter() const;

View File

@ -36,6 +36,7 @@ class ChannelWebAPIAdapter;
class DeviceWebAPIAdapter; class DeviceWebAPIAdapter;
class FeatureWebAPIAdapter; class FeatureWebAPIAdapter;
class Feature; class Feature;
class FeatureGUI;
class SDRBASE_API PluginInterface { class SDRBASE_API PluginInterface {
public: public:
@ -331,7 +332,7 @@ public:
// Features // Features
virtual PluginInstanceGUI* createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const virtual FeatureGUI* createFeatureGUI(FeatureUISet *featureUISet, Feature *feature) const
{ {
return nullptr; return nullptr;
} }

View File

@ -69,6 +69,7 @@ set(sdrgui_SOURCES
device/deviceuiset.cpp device/deviceuiset.cpp
feature/featuregui.cpp
feature/featureuiset.cpp feature/featureuiset.cpp
soapygui/discreterangegui.cpp soapygui/discreterangegui.cpp
@ -152,6 +153,7 @@ set(sdrgui_HEADERS
device/deviceuiset.h device/deviceuiset.h
feature/featuregui.h
feature/featureuiset.h feature/featureuiset.h
plugin/plugininstancegui.h plugin/plugininstancegui.h

View File

@ -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 <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <QCloseEvent>
#include "featuregui.h"
void FeatureGUI::closeEvent(QCloseEvent *event)
{
qDebug("FeatureGUI::closeEvent");
emit closing();
event->accept();
}

View File

@ -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 <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#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_

View File

@ -21,6 +21,7 @@
#include "settings/featuresetpreset.h" #include "settings/featuresetpreset.h"
#include "feature/featureutils.h" #include "feature/featureutils.h"
#include "feature/feature.h" #include "feature/feature.h"
#include "feature/featuregui.h"
#include "featureuiset.h" #include "featureuiset.h"
@ -40,16 +41,23 @@ void FeatureUISet::addRollupWidget(QWidget *widget)
m_featureWindow->addRollupWidget(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) 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); m_featureInstanceRegistrations.erase(it);
break; break;
@ -140,7 +148,7 @@ void FeatureUISet::loadFeatureSetSettings(const FeatureSetPreset *preset, Plugin
qPrintable(featureConfig.m_featureIdURI)); qPrintable(featureConfig.m_featureIdURI));
Feature *feature = Feature *feature =
(*featureRegistrations)[i].m_plugin->createFeature(apiAdapter); (*featureRegistrations)[i].m_plugin->createFeature(apiAdapter);
PluginInstanceGUI *featureGUI = FeatureGUI *featureGUI =
(*featureRegistrations)[i].m_plugin->createFeatureGUI(this, feature); (*featureRegistrations)[i].m_plugin->createFeatureGUI(this, feature);
registerFeatureInstance(feature->getURI(), featureGUI, feature); registerFeatureInstance(feature->getURI(), featureGUI, feature);
break; break;
@ -165,3 +173,10 @@ void FeatureUISet::saveFeatureSetSettings(FeatureSetPreset *preset)
preset->addFeature(m_featureInstanceRegistrations[i].m_featureURI, m_featureInstanceRegistrations[i].m_gui->serialize()); preset->addFeature(m_featureInstanceRegistrations[i].m_featureURI, m_featureInstanceRegistrations[i].m_gui->serialize());
} }
} }
void FeatureUISet::handleClosingFeatureGUI(FeatureGUI *featureGUI)
{
qDebug("FeatureUISet::handleClosingFeatureGUI");
removeFeatureInstance(featureGUI);
}

View File

@ -18,6 +18,7 @@
#ifndef SDRGUI_FEATURE_FEATUREUISET_H_ #ifndef SDRGUI_FEATURE_FEATUREUISET_H_
#define SDRGUI_FEATURE_FEATUREUISET_H_ #define SDRGUI_FEATURE_FEATUREUISET_H_
#include <QObject>
#include <QString> #include <QString>
#include <QList> #include <QList>
@ -25,22 +26,23 @@
class QWidget; class QWidget;
class FeatureWindow; class FeatureWindow;
class PluginInstanceGUI; class FeatureGUI;
class PluginAPI; class PluginAPI;
class Feature; class Feature;
class FeatureSetPreset; class FeatureSetPreset;
class WebAPIAdapterInterface; class WebAPIAdapterInterface;
class SDRGUI_API FeatureUISet class SDRGUI_API FeatureUISet : public QObject
{ {
Q_OBJECT
public: public:
FeatureUISet(int tabIndex); FeatureUISet(int tabIndex);
~FeatureUISet(); ~FeatureUISet();
void addRollupWidget(QWidget *widget); //!< Add feature rollup widget to feature window void addRollupWidget(QWidget *widget); //!< Add feature rollup widget to feature window
int getNumberOfFeatures() const { return m_featureInstanceRegistrations.size(); } int getNumberOfFeatures() const { return m_featureInstanceRegistrations.size(); }
void registerFeatureInstance(const QString& featureURI, PluginInstanceGUI* pluginGUI, Feature *feature); void registerFeatureInstance(const QString& featureURI, FeatureGUI* featureGUI, Feature *feature);
void removeFeatureInstance(PluginInstanceGUI* pluginGUI); void removeFeatureInstance(FeatureGUI* featureGUI);
void freeFeatures(); void freeFeatures();
void deleteFeature(int featureIndex); void deleteFeature(int featureIndex);
const Feature *getFeatureAt(int featureIndex) const; const Feature *getFeatureAt(int featureIndex) const;
@ -54,7 +56,7 @@ private:
struct FeatureInstanceRegistration struct FeatureInstanceRegistration
{ {
QString m_featureURI; QString m_featureURI;
PluginInstanceGUI* m_gui; FeatureGUI* m_gui;
Feature* m_feature; Feature* m_feature;
FeatureInstanceRegistration() : FeatureInstanceRegistration() :
@ -63,7 +65,7 @@ private:
m_feature(nullptr) m_feature(nullptr)
{ } { }
FeatureInstanceRegistration(const QString& featureURI, PluginInstanceGUI* pluginGUI, Feature *feature) : FeatureInstanceRegistration(const QString& featureURI, FeatureGUI* pluginGUI, Feature *feature) :
m_featureURI(featureURI), m_featureURI(featureURI),
m_gui(pluginGUI), m_gui(pluginGUI),
m_feature(feature) m_feature(feature)
@ -76,6 +78,9 @@ private:
FeatureInstanceRegistrations m_featureInstanceRegistrations; FeatureInstanceRegistrations m_featureInstanceRegistrations;
int m_featureTabIndex; int m_featureTabIndex;
private slots:
void handleClosingFeatureGUI(FeatureGUI *featureGUI);
}; };
#endif // SDRGUI_FEATURE_FEATUREUISET_H_ #endif // SDRGUI_FEATURE_FEATUREUISET_H_

View File

@ -1978,7 +1978,7 @@ void MainWindow::featureAddClicked(int featureIndex)
PluginAPI::FeatureRegistrations *featureRegistrations = m_pluginManager->getFeatureRegistrations(); // Available feature plugins PluginAPI::FeatureRegistrations *featureRegistrations = m_pluginManager->getFeatureRegistrations(); // Available feature plugins
PluginInterface *pluginInterface = (*featureRegistrations)[featureIndex].m_plugin; PluginInterface *pluginInterface = (*featureRegistrations)[featureIndex].m_plugin;
Feature *feature = pluginInterface->createFeature(m_apiAdapter); Feature *feature = pluginInterface->createFeature(m_apiAdapter);
PluginInstanceGUI *gui = pluginInterface->createFeatureGUI(featureUISet, feature); FeatureGUI *gui = pluginInterface->createFeatureGUI(featureUISet, feature);
featureUISet->registerFeatureInstance(feature->getURI(), gui, feature); featureUISet->registerFeatureInstance(feature->getURI(), gui, feature);
} }
} }