1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-25 01:18:38 -05:00

Add support for plugin presets.

This commit is contained in:
Jon Beniston 2023-08-24 15:51:50 +01:00
parent 028a44ce48
commit 2a24f72590
28 changed files with 1397 additions and 41 deletions

View File

@ -207,6 +207,7 @@ set(sdrbase_SOURCES
settings/configuration.cpp
settings/featuresetpreset.cpp
settings/pluginpreset.cpp
settings/preferences.cpp
settings/preset.cpp
settings/mainsettings.cpp
@ -437,6 +438,7 @@ set(sdrbase_HEADERS
settings/configuration.h
settings/featuresetpreset.h
settings/pluginpreset.h
settings/preferences.h
settings/preset.h
settings/mainsettings.h

View File

@ -25,6 +25,7 @@
#include "dsp/devicesamplemimo.h"
#include "settings/preset.h"
#include "channel/channelapi.h"
#include "util/simpleserializer.h"
#include "deviceapi.h"
@ -467,6 +468,115 @@ ChannelAPI *DeviceAPI::getMIMOChannelAPIAt(int index)
}
}
QList<quint64> DeviceAPI::getCenterFrequency() const
{
QList<quint64> frequencies;
if (m_deviceSourceEngine && m_deviceSourceEngine->getSource())
{
frequencies.append(m_deviceSourceEngine->getSource()->getCenterFrequency());
}
else if (m_deviceSinkEngine && m_deviceSinkEngine->getSink())
{
frequencies.append(m_deviceSinkEngine->getSink()->getCenterFrequency());
}
else if (m_deviceMIMOEngine && m_deviceMIMOEngine->getMIMO())
{
for (int i = 0; i < m_deviceMIMOEngine->getMIMO()->getNbSourceStreams(); i++) {
frequencies.append(m_deviceMIMOEngine->getMIMO()->getSourceCenterFrequency(i));
}
for (int i = 0; i < m_deviceMIMOEngine->getMIMO()->getNbSinkStreams(); i++) {
frequencies.append(m_deviceMIMOEngine->getMIMO()->getSinkCenterFrequency(i));
}
}
return frequencies;
}
void DeviceAPI::setCenterFrequency(QList<quint64> centerFrequency)
{
if (m_deviceSourceEngine && m_deviceSourceEngine->getSource())
{
m_deviceSourceEngine->getSource()->setCenterFrequency(centerFrequency[0]);
}
else if (m_deviceSinkEngine && m_deviceSinkEngine->getSink())
{
m_deviceSinkEngine->getSink()->setCenterFrequency(centerFrequency[0]);
}
else if (m_deviceMIMOEngine && m_deviceMIMOEngine->getMIMO())
{
int idx = 0;
for (int i = 0; i < m_deviceMIMOEngine->getMIMO()->getNbSourceStreams(); i++, idx++) {
m_deviceMIMOEngine->getMIMO()->setSourceCenterFrequency(centerFrequency[idx], i);
}
for (int i = 0; i < m_deviceMIMOEngine->getMIMO()->getNbSinkStreams(); i++) {
m_deviceMIMOEngine->getMIMO()->setSinkCenterFrequency(centerFrequency[idx], i);
}
}
}
// Serialization is only currently used for saving device settings as part of a Device preset
// loadSamplingDeviceSettings/saveSamplingDeviceSettings is used for Device Set presets (which includes channel settings)
QByteArray DeviceAPI::serialize() const
{
SimpleSerializer s(1);
if (m_deviceSourceEngine && m_deviceSourceEngine->getSource()) {
s.writeBlob(1, m_deviceSourceEngine->getSource()->serialize());
}
if (m_deviceSinkEngine && m_deviceSinkEngine->getSink()) {
s.writeBlob(2, m_deviceSinkEngine->getSink()->serialize());
}
if (m_deviceMIMOEngine && m_deviceMIMOEngine->getMIMO()) {
s.writeBlob(3, m_deviceMIMOEngine->getMIMO()->serialize());
}
s.writeList<quint64>(4, getCenterFrequency());
return s.final();
}
bool DeviceAPI::deserialize(const QByteArray& data)
{
SimpleDeserializer d(data);
if (!d.isValid()) {
return false;
}
if (d.getVersion() == 1)
{
QByteArray data;
QList<quint64> centerFrequency;
if (m_deviceSourceEngine && m_deviceSourceEngine->getSource())
{
d.readBlob(1, &data);
if (data.size() > 0) {
m_deviceSourceEngine->getSource()->deserialize(data);
}
}
if (m_deviceSinkEngine && m_deviceSinkEngine->getSink())
{
d.readBlob(2, &data);
if (data.size() > 0) {
m_deviceSinkEngine->getSink()->deserialize(data);
}
}
if (m_deviceMIMOEngine && m_deviceMIMOEngine->getMIMO())
{
d.readBlob(3, &data);
if (data.size() > 0) {
m_deviceMIMOEngine->getMIMO()->deserialize(data);
}
}
d.readList<quint64>(4, &centerFrequency);
setCenterFrequency(centerFrequency);
}
else
{
return false;
}
}
void DeviceAPI::loadSamplingDeviceSettings(const Preset* preset)
{
if (m_deviceSourceEngine && (preset->isSourcePreset()))

View File

@ -22,6 +22,7 @@
#include <QString>
#include <QTimer>
#include "settings/serializableinterface.h"
#include "export.h"
class BasebandSampleSink;
@ -38,7 +39,7 @@ class DSPDeviceSinkEngine;
class DSPDeviceMIMOEngine;
class Preset;
class SDRBASE_API DeviceAPI : public QObject {
class SDRBASE_API DeviceAPI : public QObject, public SerializableInterface {
Q_OBJECT
public:
enum StreamType //!< This is the same enum as in PluginInterface
@ -146,6 +147,13 @@ public:
// void saveSourceSettings(Preset* preset);
// void saveSinkSettings(Preset* preset);
QByteArray serialize() const override;
bool deserialize(const QByteArray& data) override;
// List of one frequency for Single Rx / Tx or one frequency per stream for MIMO
QList<quint64> getCenterFrequency() const;
void setCenterFrequency(QList<quint64> centerFrequency);
DSPDeviceSourceEngine *getDeviceSourceEngine() { return m_deviceSourceEngine; }
DSPDeviceSinkEngine *getDeviceSinkEngine() { return m_deviceSinkEngine; }
DSPDeviceMIMOEngine *getDeviceMIMOEngine() { return m_deviceMIMOEngine; }

View File

@ -848,6 +848,7 @@ public:
qint64 getElapsedNsecs() const { return m_masterElapsedTimer.nsecsElapsed(); } //!< Elapsed nanoseconds since main core construction
qint64 getStartMsecsSinceEpoch() const { return m_startMsecsSinceEpoch; } //!< Epoch timestamp in millisecodns close to elapsed timer start
const MainSettings& getSettings() const { return m_settings; }
MainSettings& getMutableSettings() { return m_settings; }
MessageQueue *getMainMessageQueue() { return m_mainMessageQueue; }
PluginManager *getPluginManager() const { return m_pluginManager; }
std::vector<DeviceSet*>& getDeviceSets() { return m_deviceSets; }

View File

@ -31,6 +31,10 @@ MainSettings::~MainSettings()
{
delete m_featureSetPresets[i];
}
for (int i = 0; i < m_pluginPresets.count(); ++i)
{
delete m_pluginPresets[i];
}
}
QString MainSettings::getFileLocation() const
@ -108,6 +112,22 @@ void MainSettings::load()
delete featureSetPreset;
}
s.endGroup();
}
else if (groups[i].startsWith("pluginpreset"))
{
s.beginGroup(groups[i]);
PluginPreset* pluginPreset = new PluginPreset;
if (pluginPreset->deserialize(qUncompress(QByteArray::fromBase64(s.value("data").toByteArray()))))
{
m_pluginPresets.append(pluginPreset);
}
else
{
delete pluginPreset;
}
s.endGroup();
}
else if (groups[i].startsWith("configuration"))
@ -176,6 +196,14 @@ void MainSettings::save() const
s.endGroup();
}
for (int i = 0; i < m_pluginPresets.count(); ++i)
{
QString group = QString("pluginpreset-%1").arg(i + 1);
s.beginGroup(group);
s.setValue("data", qCompress(m_pluginPresets[i]->serialize()).toBase64());
s.endGroup();
}
for (int i = 0; i < m_configurations.count(); ++i)
{
QString group = QString("configuration-%1").arg(i + 1);
@ -193,6 +221,7 @@ void MainSettings::initialize()
clearCommands();
clearPresets();
clearFeatureSetPresets();
clearPluginPresets();
clearConfigurations();
}
@ -201,6 +230,7 @@ void MainSettings::resetToDefaults()
m_preferences.resetToDefaults();
m_workingPreset.resetToDefaults();
m_workingFeatureSetPreset.resetToDefaults();
m_workingPluginPreset.resetToDefaults();
m_workingConfiguration.resetToDefaults();
}
@ -452,6 +482,86 @@ void MainSettings::clearFeatureSetPresets()
m_featureSetPresets.clear();
}
// FeatureSet presets
PluginPreset* MainSettings::newPluginPreset(const QString& group, const QString& description)
{
PluginPreset* preset = new PluginPreset();
preset->setGroup(group);
preset->setDescription(description);
addPluginPreset(preset);
return preset;
}
void MainSettings::addPluginPreset(PluginPreset *preset)
{
m_pluginPresets.append(preset);
}
void MainSettings::deletePluginPreset(const PluginPreset* preset)
{
m_pluginPresets.removeAll((PluginPreset*) preset);
delete (PluginPreset*) preset;
}
void MainSettings::deletePluginPresetGroup(const QString& groupName)
{
PluginPresets::iterator it = m_pluginPresets.begin();
while (it != m_pluginPresets.end())
{
if ((*it)->getGroup() == groupName) {
it = m_pluginPresets.erase(it);
} else {
++it;
}
}
}
void MainSettings::sortPluginPresets()
{
std::sort(m_pluginPresets.begin(), m_pluginPresets.end(), PluginPreset::presetCompare);
}
void MainSettings::renamePluginPresetGroup(const QString& oldGroupName, const QString& newGroupName)
{
int nbPresets = getPluginPresetCount();
for (int i = 0; i < nbPresets; i++)
{
if (getPluginPreset(i)->getGroup() == oldGroupName)
{
PluginPreset *preset_mod = const_cast<PluginPreset*>(getPluginPreset(i));
preset_mod->setGroup(newGroupName);
}
}
}
const PluginPreset* MainSettings::getPluginPreset(const QString& groupName, const QString& description) const
{
int nbPresets = getPluginPresetCount();
for (int i = 0; i < nbPresets; i++)
{
if ((getPluginPreset(i)->getGroup() == groupName) &&
(getPluginPreset(i)->getDescription() == description))
{
return getPluginPreset(i);
}
}
return nullptr;
}
void MainSettings::clearPluginPresets()
{
foreach (PluginPreset *preset, m_pluginPresets) {
delete preset;
}
m_pluginPresets.clear();
}
// Configurations
Configuration* MainSettings::newConfiguration(const QString& group, const QString& description)

View File

@ -7,6 +7,7 @@
#include "preferences.h"
#include "preset.h"
#include "featuresetpreset.h"
#include "pluginpreset.h"
#include "configuration.h"
#include "export.h"
#include "plugin/pluginmanager.h"
@ -72,6 +73,20 @@ public:
FeatureSetPreset* getWorkingFeatureSetPreset() { return &m_workingFeatureSetPreset; }
QList<FeatureSetPreset*> *getFeatureSetPresets() { return &m_featureSetPresets; }
PluginPreset* newPluginPreset(const QString& group, const QString& description);
void addPluginPreset(PluginPreset *preset);
void deletePluginPreset(const PluginPreset* preset);
int getPluginPresetCount() const { return m_pluginPresets.count(); }
const PluginPreset* getPluginPreset(int index) const { return m_pluginPresets[index]; }
const PluginPreset* getPluginPreset(const QString& groupName, const QString& description) const;
void sortPluginPresets();
void renamePluginPresetGroup(const QString& oldGroupName, const QString& newGroupName);
void deletePluginPresetGroup(const QString& groupName);
void clearPluginPresets();
const PluginPreset& getWorkingPluginPresetConst() const { return m_workingPluginPreset; }
PluginPreset* getWorkingPluginPreset() { return &m_workingPluginPreset; }
QList<PluginPreset*> *getPluginPresets() { return &m_pluginPresets; }
Configuration* newConfiguration(const QString& group, const QString& description);
void addConfiguration(Configuration *configuration);
void deleteConfiguration(const Configuration *configuration);
@ -231,6 +246,9 @@ protected:
FeatureSetPreset m_workingFeatureSetPreset;
typedef QList<FeatureSetPreset*> FeatureSetPresets;
FeatureSetPresets m_featureSetPresets;
PluginPreset m_workingPluginPreset;
typedef QList<PluginPreset*> PluginPresets;
PluginPresets m_pluginPresets;
Configuration m_workingConfiguration;
typedef QList<Configuration*> Configurations;
Configurations m_configurations;

View File

@ -0,0 +1,79 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2020 Edouard Griffiths, F4EXB //
// Copyright (C) 2023 Jon Beniston, M7RCE //
// //
// 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 "util/simpleserializer.h"
#include "pluginpreset.h"
PluginPreset::PluginPreset()
{
resetToDefaults();
}
PluginPreset::PluginPreset(const PluginPreset& other) :
m_group(other.m_group),
m_description(other.m_description),
m_pluginIdURI(other.m_pluginIdURI),
m_config(other.m_config)
{}
void PluginPreset::resetToDefaults()
{
m_group = "default";
m_description = "no name";
m_pluginIdURI = "";
m_config = QByteArray();
}
QByteArray PluginPreset::serialize() const
{
SimpleSerializer s(1);
s.writeString(1, m_group);
s.writeString(2, m_description);
s.writeString(3, m_pluginIdURI);
s.writeBlob(4, m_config);
return s.final();
}
bool PluginPreset::deserialize(const QByteArray& data)
{
SimpleDeserializer d(data);
if (!d.isValid())
{
resetToDefaults();
return false;
}
if (d.getVersion() == 1)
{
d.readString(1, &m_group, "default");
d.readString(2, &m_description, "no name");
d.readString(3, &m_pluginIdURI, "");
d.readBlob(4, &m_config);
return true;
}
else
{
resetToDefaults();
return false;
}
}

View File

@ -0,0 +1,70 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2020 Edouard Griffiths, F4EXB //
// Copyright (C) 2023 Jon Beniston, M7RCE //
// //
// 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 SDRBASE_SETTINGS_PLUGINPRESET_H_
#define SDRBASE_SETTINGS_PLUGINPRESET_H_
#include <QString>
#include <QByteArray>
#include <QMetaType>
#include "export.h"
class SDRBASE_API PluginPreset {
public:
PluginPreset();
PluginPreset(const PluginPreset& other);
void resetToDefaults();
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
void setGroup(const QString& group) { m_group = group; }
const QString& getGroup() const { return m_group; }
void setDescription(const QString& description) { m_description = description; }
const QString& getDescription() const { return m_description; }
void setConfig(const QString& pluginIdURI, const QByteArray& config) { m_pluginIdURI = pluginIdURI; m_config = config; }
const QByteArray& getConfig() const { return m_config; }
const QString& getPluginIdURI() const { return m_pluginIdURI; }
static bool presetCompare(const PluginPreset *p1, PluginPreset *p2)
{
if (p1->m_group != p2->m_group)
{
return p1->m_group < p2->m_group;
}
else
{
return p1->m_description < p2->m_description;
}
}
private:
// group and preset description
QString m_group;
QString m_description;
QString m_pluginIdURI; //!< Plugin type ID in URI form
QByteArray m_config;
};
Q_DECLARE_METATYPE(const PluginPreset*)
Q_DECLARE_METATYPE(PluginPreset*)
#endif // SDRBASE_SETTINGS_PLUGINPRESET_H_

View File

@ -68,6 +68,7 @@ set(sdrgui_SOURCES
gui/mypositiondialog.cpp
gui/nanosecondsdelegate.cpp
gui/pluginsdialog.cpp
gui/pluginpresetsdialog.cpp
gui/presetitem.cpp
gui/profiledialog.cpp
gui/rollupcontents.cpp
@ -188,7 +189,9 @@ set(sdrgui_HEADERS
gui/nanosecondsdelegate.h
gui/physicalunit.h
gui/pluginsdialog.h
gui/pluginpresetsdialog.h
gui/presetitem.h
gui/presets/dialog.h
gui/profiledialog.h
gui/qtcompatibility.h
gui/rollupcontents.h
@ -266,6 +269,7 @@ set(sdrgui_FORMS
gui/glspectrumgui.ui
gui/graphicsdialog.ui
gui/pluginsdialog.ui
gui/pluginpresetsdialog.ui
gui/profiledialog.ui
gui/audiodialog.ui
gui/audioselectdialog.ui

View File

@ -23,6 +23,7 @@
#include "gui/qtcompatibility.h"
#include "gui/framelesswindowresizer.h"
#include "settings/serializableinterface.h"
#include "export.h"
class QCloseEvent;
@ -35,7 +36,7 @@ class QSizeGrip;
class RollupContents;
class ChannelMarker;
class SDRGUI_API ChannelGUI : public QMdiSubWindow
class SDRGUI_API ChannelGUI : public QMdiSubWindow, public SerializableInterface
{
Q_OBJECT
public:
@ -57,8 +58,6 @@ public:
virtual void destroy() = 0;
virtual void resetToDefaults() = 0;
virtual QByteArray serialize() const = 0;
virtual bool deserialize(const QByteArray& data) = 0;
// Data saved in the derived settings
virtual void setWorkspaceIndex(int index)= 0;
virtual int getWorkspaceIndex() const = 0;

View File

@ -28,6 +28,7 @@
#include "gui/channeladddialog.h"
#include "gui/framelesswindowresizer.h"
#include "settings/serializableinterface.h"
#include "export.h"
class QCloseEvent;
@ -39,7 +40,7 @@ class QHBoxLayout;
class QSizeGrip;
class DeviceUISet;
class SDRGUI_API DeviceGUI : public QMdiSubWindow {
class SDRGUI_API DeviceGUI : public QMdiSubWindow, public SerializableInterface {
Q_OBJECT
public:
enum DeviceType
@ -60,8 +61,6 @@ public:
virtual void destroy() = 0;
virtual void resetToDefaults() = 0;
virtual QByteArray serialize() const = 0;
virtual bool deserialize(const QByteArray& data) = 0;
void setWorkspaceIndex(int index);
int getWorkspaceIndex() const { return m_workspaceIndex; }
@ -78,6 +77,7 @@ public:
int getIndex() const { return m_deviceSetIndex; }
void setCurrentDeviceIndex(int index) { m_currentDeviceIndex = index; } //!< index in plugins list
void setChannelNames(const QStringList& channelNames) { m_channelAddDialog.addChannelNames(channelNames); }
DeviceUISet* getDeviceUISet() { return m_deviceUISet; }
protected:
void closeEvent(QCloseEvent *event) override;

View File

@ -38,6 +38,7 @@
#include "channel/channelgui.h"
#include "mainspectrum/mainspectrumgui.h"
#include "settings/preset.h"
#include "util/simpleserializer.h"
#include "mainwindow.h"
#include "deviceuiset.h"
@ -196,6 +197,45 @@ ChannelGUI *DeviceUISet::getChannelGUIAt(int channelIndex)
return m_channelInstanceRegistrations[channelIndex].m_gui;
}
// Serialization is only used for Device and Spectrum settings in a Device preset
// To include channels, use a Device Set preset via loadDeviceSetSettings/saveDeviceSetSettings
QByteArray DeviceUISet::serialize() const
{
SimpleSerializer s(1);
s.writeBlob(1, m_deviceAPI->serialize());
s.writeBlob(2, m_deviceGUI->serialize());
s.writeBlob(3, m_spectrumGUI->serialize());
return s.final();
}
bool DeviceUISet::deserialize(const QByteArray& data)
{
SimpleDeserializer d(data);
if (!d.isValid()) {
return false;
}
if (d.getVersion() == 1)
{
QByteArray data;
d.readBlob(1, &data);
m_deviceAPI->deserialize(data);
d.readBlob(2, &data);
m_deviceGUI->deserialize(data);
d.readBlob(3, &data);
m_spectrumGUI->deserialize(data);
}
else
{
return false;
}
}
void DeviceUISet::loadDeviceSetSettings(
const Preset* preset,
PluginAPI *pluginAPI,

View File

@ -22,6 +22,7 @@
#include <QTimer>
#include <QByteArray>
#include "settings/serializableinterface.h"
#include "export.h"
class SpectrumVis;
@ -48,7 +49,7 @@ namespace SWGSDRangel {
class SWGSuccessResponse;
};
class SDRGUI_API DeviceUISet : public QObject
class SDRGUI_API DeviceUISet : public QObject, public SerializableInterface
{
Q_OBJECT
public:
@ -84,6 +85,9 @@ public:
ChannelAPI *getChannelAt(int channelIndex);
ChannelGUI *getChannelGUIAt(int channelIndex);
QByteArray serialize() const override;
bool deserialize(const QByteArray& data) override;
void loadDeviceSetSettings(
const Preset* preset,
PluginAPI *pluginAPI,

View File

@ -23,6 +23,7 @@
#include "gui/framelesswindowresizer.h"
#include "gui/rollupcontents.h"
#include "settings/serializableinterface.h"
#include "export.h"
class QCloseEvent;
@ -34,7 +35,7 @@ class QHBoxLayout;
class QSizeGrip;
class Feature;
class SDRGUI_API FeatureGUI : public QMdiSubWindow
class SDRGUI_API FeatureGUI : public QMdiSubWindow, public SerializableInterface
{
Q_OBJECT
public:
@ -49,8 +50,6 @@ public:
virtual void destroy() = 0;
virtual void resetToDefaults() = 0;
virtual QByteArray serialize() const = 0;
virtual bool deserialize(const QByteArray& data) = 0;
// Data saved in the derived settings
virtual void setWorkspaceIndex(int index)= 0;
virtual int getWorkspaceIndex() const = 0;

View File

@ -1,6 +1,11 @@
#include <QColorDialog>
#include "dsp/channelmarker.h"
#include "gui/pluginpresetsdialog.h"
#include "gui/dialogpositioner.h"
#include "channel/channelapi.h"
#include "channel/channelgui.h"
#include "maincore.h"
#include "basicchannelsettingsdialog.h"
#include "ui_basicchannelsettingsdialog.h"
@ -154,6 +159,28 @@ void BasicChannelSettingsDialog::on_titleReset_clicked()
ui->title->setText(m_defaultTitle);
}
void BasicChannelSettingsDialog::on_presets_clicked()
{
ChannelGUI *channelGUI = qobject_cast<ChannelGUI *>(parent());
if (!channelGUI)
{
qDebug() << "BasicChannelSettingsDialog::on_presets_clicked: parent not a ChannelGUI";
return;
}
ChannelAPI *channel = MainCore::instance()->getChannel(channelGUI->getDeviceSetIndex(), channelGUI->getIndex());
const QString& id = channel->getURI();
PluginPresetsDialog dialog(id);
dialog.setPresets(MainCore::instance()->getMutableSettings().getPluginPresets());
dialog.setSerializableInterface(channelGUI);
dialog.populateTree();
new DialogPositioner(&dialog, true);
dialog.exec();
if (dialog.wasPresetLoaded()) {
QDialog::reject(); // Settings may have changed, so GUI will be inconsistent. Just close it
}
}
void BasicChannelSettingsDialog::accept()
{
m_channelMarker->blockSignals(true);

View File

@ -43,6 +43,7 @@ private slots:
void on_reverseAPIDeviceIndex_editingFinished();
void on_reverseAPIChannelIndex_editingFinished();
void on_streamIndex_valueChanged(int value);
void on_presets_clicked();
void accept();
private:

View File

@ -301,14 +301,32 @@
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QToolButton" name="presets">
<property name="toolTip">
<string>Open channel presets dialog</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resources/res.qrc">
<normaloff>:/star.png</normaloff>:/star.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>

View File

@ -1,3 +1,10 @@
#include "gui/pluginpresetsdialog.h"
#include "gui/dialogpositioner.h"
#include "device/deviceapi.h"
#include "device/devicegui.h"
#include "device/deviceuiset.h"
#include "maincore.h"
#include "basicdevicesettingsdialog.h"
#include "ui_basicdevicesettingsdialog.h"
@ -81,6 +88,30 @@ void BasicDeviceSettingsDialog::on_reverseAPIDeviceIndex_editingFinished()
}
}
void BasicDeviceSettingsDialog::on_presets_clicked()
{
DeviceGUI *deviceGUI = qobject_cast<DeviceGUI *>(parent());
if (!deviceGUI)
{
qDebug() << "BasicDeviceSettingsDialog::on_presets_clicked: parent not a DeviceGUI";
return;
}
DeviceAPI *device = MainCore::instance()->getDevice(deviceGUI->getIndex());
const QString& id = device->getSamplingDeviceId();
// To include spectrum settings, we need to serialize DeviceUISet rather than just the DeviceGUI
DeviceUISet *deviceUISet = deviceGUI->getDeviceUISet();
PluginPresetsDialog dialog(id);
dialog.setPresets(MainCore::instance()->getMutableSettings().getPluginPresets());
dialog.setSerializableInterface(deviceUISet);
dialog.populateTree();
new DialogPositioner(&dialog, true);
dialog.exec();
if (dialog.wasPresetLoaded()) {
QDialog::reject(); // Settings may have changed, so GUI will be inconsistent. Just close it
}
}
void BasicDeviceSettingsDialog::accept()
{
m_hasChanged = true;

View File

@ -31,6 +31,7 @@ private slots:
void on_reverseAPIAddress_editingFinished();
void on_reverseAPIPort_editingFinished();
void on_reverseAPIDeviceIndex_editingFinished();
void on_presets_clicked();
void accept();
private:

View File

@ -134,18 +134,38 @@
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QToolButton" name="presets">
<property name="toolTip">
<string>Open device presets dialog</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resources/res.qrc">
<normaloff>:/star.png</normaloff>:/star.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<resources>
<include location="../resources/res.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>

View File

@ -1,5 +1,11 @@
#include <QColorDialog>
#include "gui/pluginpresetsdialog.h"
#include "gui/dialogpositioner.h"
#include "feature/feature.h"
#include "feature/featuregui.h"
#include "maincore.h"
#include "basicfeaturesettingsdialog.h"
#include "ui_basicfeaturesettingsdialog.h"
@ -82,6 +88,28 @@ void BasicFeatureSettingsDialog::on_reverseAPIFeatureIndex_editingFinished()
}
}
void BasicFeatureSettingsDialog::on_presets_clicked()
{
FeatureGUI *featureGUI = qobject_cast<FeatureGUI *>(parent());
if (!featureGUI)
{
qDebug() << "BasicFeatureSettingsDialog::on_presets_clicked: parent not a FeatureGUI";
return;
}
Feature *feature = MainCore::instance()->getFeature(0, featureGUI->getIndex());
const QString& id = feature->getURI();
PluginPresetsDialog dialog(id);
dialog.setPresets(MainCore::instance()->getMutableSettings().getPluginPresets());
dialog.setSerializableInterface(featureGUI);
dialog.populateTree();
new DialogPositioner(&dialog, true);
dialog.exec();
if (dialog.wasPresetLoaded()) {
QDialog::reject(); // Settings may have changed, so GUI will be inconsistent. Just close it
}
}
void BasicFeatureSettingsDialog::accept()
{
m_hasChanged = true;

View File

@ -56,6 +56,7 @@ private slots:
void on_reverseAPIPort_editingFinished();
void on_reverseAPIFeatureSetIndex_editingFinished();
void on_reverseAPIFeatureIndex_editingFinished();
void on_presets_clicked();
void accept();
private:

View File

@ -201,14 +201,32 @@
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QToolButton" name="presets">
<property name="toolTip">
<string>Open feature presets dialog</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resources/res.qrc">
<normaloff>:/star.png</normaloff>:/star.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>

View File

@ -0,0 +1,430 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2020 Edouard Griffiths, F4EXB //
// Copyright (C) 2023 Jon Beniston, M7RCE //
// //
// 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 <QMessageBox>
#include <QDebug>
#include "gui/addpresetdialog.h"
#include "settings/serializableinterface.h"
#include "settings/pluginpreset.h"
#include "maincore.h"
#include "pluginpresetsdialog.h"
#include "ui_pluginpresetsdialog.h"
PluginPresetsDialog::PluginPresetsDialog(const QString& pluginId, QWidget* parent) :
QDialog(parent),
ui(new Ui::PluginPresetsDialog),
m_pluginId(pluginId),
m_pluginPresets(nullptr),
m_serializableInterface(nullptr),
m_presetLoaded(false)
{
ui->setupUi(this);
}
PluginPresetsDialog::~PluginPresetsDialog()
{
delete ui;
}
void PluginPresetsDialog::populateTree()
{
if (!m_pluginPresets) {
return;
}
QList<PluginPreset*>::const_iterator it = m_pluginPresets->begin();
int middleIndex = m_pluginPresets->size() / 2;
QTreeWidgetItem *treeItem;
ui->presetsTree->clear();
for (int i = 0; it != m_pluginPresets->end(); ++it, i++)
{
const PluginPreset *preset = *it;
treeItem = addPresetToTree(preset);
if (i == middleIndex) {
ui->presetsTree->setCurrentItem(treeItem);
}
}
updatePresetControls();
}
QTreeWidgetItem* PluginPresetsDialog::addPresetToTree(const PluginPreset* preset)
{
QTreeWidgetItem* group = nullptr;
for (int i = 0; i < ui->presetsTree->topLevelItemCount(); i++)
{
if (ui->presetsTree->topLevelItem(i)->text(0) == preset->getGroup())
{
group = ui->presetsTree->topLevelItem(i);
break;
}
}
if (!group)
{
QStringList sl;
sl.append(preset->getGroup());
group = new QTreeWidgetItem(ui->presetsTree, sl, PGroup);
group->setFirstColumnSpanned(true);
group->setExpanded(true);
ui->presetsTree->sortByColumn(0, Qt::AscendingOrder);
// Only show group when it contains presets for this pluging
if (preset->getPluginIdURI() != m_pluginId) {
group->setHidden(true);
}
}
else
{
if (preset->getPluginIdURI() == m_pluginId) {
group->setHidden(false);
}
}
QStringList sl;
sl.append(preset->getDescription());
QTreeWidgetItem* item = new QTreeWidgetItem(group, sl, PItem); // description column
item->setTextAlignment(0, Qt::AlignLeft);
item->setData(0, Qt::UserRole, QVariant::fromValue(preset));
// Only show presets for this plugin
if (preset->getPluginIdURI() != m_pluginId) {
item->setHidden(true);
}
updatePresetControls();
return item;
}
void PluginPresetsDialog::updatePresetControls()
{
ui->presetsTree->resizeColumnToContents(0);
if (ui->presetsTree->currentItem())
{
ui->presetDelete->setEnabled(true);
ui->presetLoad->setEnabled(true);
}
else
{
ui->presetDelete->setEnabled(false);
ui->presetLoad->setEnabled(false);
}
}
void PluginPresetsDialog::on_presetSave_clicked()
{
QStringList groups;
QString group;
QString description = "";
for (int i = 0; i < ui->presetsTree->topLevelItemCount(); i++) {
groups.append(ui->presetsTree->topLevelItem(i)->text(0));
}
QTreeWidgetItem* item = ui->presetsTree->currentItem();
if (item)
{
if (item->type() == PGroup)
{
group = item->text(0);
}
else if (item->type() == PItem)
{
group = item->parent()->text(0);
description = item->text(0);
}
}
AddPresetDialog dlg(groups, group, this);
if (description.length() > 0) {
dlg.setDescription(description);
}
if (dlg.exec() == QDialog::Accepted)
{
PluginPreset* preset = newPreset(dlg.group(), dlg.description());
savePresetSettings(preset);
ui->presetsTree->setCurrentItem(addPresetToTree(preset));
}
sortPresets();
}
void PluginPresetsDialog::on_presetUpdate_clicked()
{
QTreeWidgetItem* item = ui->presetsTree->currentItem();
const PluginPreset* changedPreset = nullptr;
if (item)
{
if( item->type() == PItem)
{
const PluginPreset* preset = qvariant_cast<const PluginPreset*>(item->data(0, Qt::UserRole));
if (preset)
{
PluginPreset* preset_mod = const_cast<PluginPreset*>(preset);
savePresetSettings(preset_mod);
changedPreset = preset;
}
}
}
sortPresets();
ui->presetsTree->clear();
for (int i = 0; i < m_pluginPresets->size(); ++i)
{
QTreeWidgetItem *item_x = addPresetToTree(m_pluginPresets->at(i));
const PluginPreset* preset_x = qvariant_cast<const PluginPreset*>(item_x->data(0, Qt::UserRole));
if (changedPreset && (preset_x == changedPreset)) { // set cursor on changed preset
ui->presetsTree->setCurrentItem(item_x);
}
}
}
void PluginPresetsDialog::on_presetEdit_clicked()
{
QTreeWidgetItem* item = ui->presetsTree->currentItem();
QStringList groups;
bool change = false;
const PluginPreset *changedPreset = nullptr;
QString newGroupName;
for (int i = 0; i < ui->presetsTree->topLevelItemCount(); i++) {
groups.append(ui->presetsTree->topLevelItem(i)->text(0));
}
if (item)
{
if (item->type() == PItem)
{
const PluginPreset* preset = qvariant_cast<const PluginPreset*>(item->data(0, Qt::UserRole));
AddPresetDialog dlg(groups, preset->getGroup(), this);
dlg.setDescription(preset->getDescription());
if (dlg.exec() == QDialog::Accepted)
{
PluginPreset* preset_mod = const_cast<PluginPreset*>(preset);
preset_mod->setGroup(dlg.group());
preset_mod->setDescription(dlg.description());
change = true;
changedPreset = preset;
}
}
else if (item->type() == PGroup)
{
AddPresetDialog dlg(groups, item->text(0), this);
dlg.showGroupOnly();
dlg.setDialogTitle("Edit preset group");
if (dlg.exec() == QDialog::Accepted)
{
renamePresetGroup(item->text(0), dlg.group());
newGroupName = dlg.group();
change = true;
}
}
}
if (change)
{
sortPresets();
ui->presetsTree->clear();
for (int i = 0; i < m_pluginPresets->size(); ++i)
{
QTreeWidgetItem *item_x = addPresetToTree(m_pluginPresets->at(i));
const PluginPreset* preset_x = qvariant_cast<const PluginPreset*>(item_x->data(0, Qt::UserRole));
if (changedPreset && (preset_x == changedPreset)) { // set cursor on changed preset
ui->presetsTree->setCurrentItem(item_x);
}
}
if (!changedPreset) // on group name change set cursor on the group that has been changed
{
for(int i = 0; i < ui->presetsTree->topLevelItemCount(); i++)
{
QTreeWidgetItem* item = ui->presetsTree->topLevelItem(i);
if (item->text(0) == newGroupName) {
ui->presetsTree->setCurrentItem(item);
}
}
}
}
}
void PluginPresetsDialog::on_presetDelete_clicked()
{
QTreeWidgetItem* item = ui->presetsTree->currentItem();
if (item == 0)
{
updatePresetControls();
return;
}
else
{
if (item->type() == PItem)
{
const PluginPreset* preset = qvariant_cast<const PluginPreset*>(item->data(0, Qt::UserRole));
if (preset)
{
if(QMessageBox::question(this, tr("Delete Preset"), tr("Do you want to delete preset '%1'?").arg(preset->getDescription()), QMessageBox::No | QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) {
delete item;
deletePreset(preset);
}
}
}
else if (item->type() == PGroup)
{
if (QMessageBox::question(this,
tr("Delete preset group"),
tr("Do you want to delete preset group '%1'?")
.arg(item->text(0)), QMessageBox::No | QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
{
deletePresetGroup(item->text(0));
ui->presetsTree->clear();
for (int i = 0; i < m_pluginPresets->size(); ++i) {
addPresetToTree(m_pluginPresets->at(i));
}
}
}
}
}
void PluginPresetsDialog::on_presetLoad_clicked()
{
qDebug() << "PluginPresetsDialog::on_presetLoad_clicked";
QTreeWidgetItem* item = ui->presetsTree->currentItem();
if (!item)
{
qDebug("PluginPresetsDialog::on_presetLoad_clicked: item null");
updatePresetControls();
return;
}
const PluginPreset* preset = qvariant_cast<const PluginPreset*>(item->data(0, Qt::UserRole));
if (!preset)
{
qDebug("PluginPresetsDialog::on_presetLoad_clicked: preset null");
return;
}
loadPresetSettings(preset);
}
void PluginPresetsDialog::on_presetTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
{
(void) current;
(void) previous;
updatePresetControls();
}
void PluginPresetsDialog::on_presetTree_itemActivated(QTreeWidgetItem *item, int column)
{
(void) item;
(void) column;
on_presetLoad_clicked();
}
PluginPreset* PluginPresetsDialog::newPreset(const QString& group, const QString& description)
{
PluginPreset* preset = new PluginPreset();
preset->setGroup(group);
preset->setDescription(description);
addPreset(preset);
return preset;
}
void PluginPresetsDialog::addPreset(PluginPreset *preset)
{
m_pluginPresets->append(preset);
}
void PluginPresetsDialog::savePresetSettings(PluginPreset* preset)
{
qDebug("PluginPresetsDialog::savePresetSettings: preset [%s | %s]",
qPrintable(preset->getGroup()),
qPrintable(preset->getDescription()));
preset->setConfig(m_pluginId, m_serializableInterface->serialize());
}
void PluginPresetsDialog::loadPresetSettings(const PluginPreset* preset)
{
qDebug("PluginPresetsDialog::loadPresetSettings: preset [%s | %s]",
qPrintable(preset->getGroup()),
qPrintable(preset->getDescription()));
m_serializableInterface->deserialize(preset->getConfig());
m_presetLoaded = true;
}
void PluginPresetsDialog::sortPresets()
{
std::sort(m_pluginPresets->begin(), m_pluginPresets->end(), PluginPreset::presetCompare);
}
void PluginPresetsDialog::renamePresetGroup(const QString& oldGroupName, const QString& newGroupName)
{
for (int i = 0; i < m_pluginPresets->size(); i++)
{
if (m_pluginPresets->at(i)->getGroup() == oldGroupName)
{
PluginPreset *preset_mod = const_cast<PluginPreset*>(m_pluginPresets->at(i));
preset_mod->setGroup(newGroupName);
}
}
}
void PluginPresetsDialog::deletePreset(const PluginPreset* preset)
{
m_pluginPresets->removeAll((PluginPreset*) preset);
delete (PluginPreset*) preset;
}
void PluginPresetsDialog::deletePresetGroup(const QString& groupName)
{
QList<PluginPreset*>::iterator it = m_pluginPresets->begin();
while (it != m_pluginPresets->end())
{
if ((*it)->getGroup() == groupName) {
it = m_pluginPresets->erase(it);
} else {
++it;
}
}
}

View File

@ -0,0 +1,81 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2020 Edouard Griffiths, F4EXB //
// Copyright (C) 2023 Jon Beniston, M7RCE //
// //
// 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_GUI_PLUGINPRESETSDIALOG_H_
#define SDRGUI_GUI_PLUGINPRESETSDIALOG_H_
#include <QDialog>
#include <QList>
#include <QTreeWidgetItem>
#include "export.h"
class PluginPreset;
class SerializableInterface;
class WebAPIAdapterInterface;
class PluginAPI;
class Workspace;
namespace Ui {
class PluginPresetsDialog;
}
class SDRGUI_API PluginPresetsDialog : public QDialog {
Q_OBJECT
public:
explicit PluginPresetsDialog(const QString& pluginId, QWidget* parent = nullptr);
~PluginPresetsDialog();
void setPresets(QList<PluginPreset*>* presets) { m_pluginPresets = presets; }
void setSerializableInterface(SerializableInterface *serializableInterface) { m_serializableInterface = serializableInterface; }
void populateTree();
bool wasPresetLoaded() const { return m_presetLoaded; }
private:
enum {
PGroup,
PItem
};
Ui::PluginPresetsDialog* ui;
QString m_pluginId;
QList<PluginPreset*> *m_pluginPresets;
SerializableInterface *m_serializableInterface;
bool m_presetLoaded;
QTreeWidgetItem* addPresetToTree(const PluginPreset* preset);
void updatePresetControls();
PluginPreset* newPreset(const QString& group, const QString& description);
void addPreset(PluginPreset *preset);
void savePresetSettings(PluginPreset* preset);
void loadPresetSettings(const PluginPreset* preset);
void sortPresets();
void renamePresetGroup(const QString& oldGroupName, const QString& newGroupName);
void deletePreset(const PluginPreset* preset);
void deletePresetGroup(const QString& groupName);
private slots:
void on_presetSave_clicked();
void on_presetUpdate_clicked();
void on_presetEdit_clicked();
void on_presetDelete_clicked();
void on_presetLoad_clicked();
void on_presetTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
void on_presetTree_itemActivated(QTreeWidgetItem *item, int column);
};
#endif // SDRGUI_GUI_PLUGINPRESETSDIALOG_H_

View File

@ -0,0 +1,235 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PluginPresetsDialog</class>
<widget class="QDialog" name="PluginPresetsDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>376</width>
<height>399</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>Liberation Sans</family>
<pointsize>9</pointsize>
</font>
</property>
<property name="windowTitle">
<string>Plugin presets</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QWidget" name="widget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTreeWidget" name="presetsTree">
<property name="indentation">
<number>5</number>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<property name="columnCount">
<number>1</number>
</property>
<attribute name="headerMinimumSectionSize">
<number>5</number>
</attribute>
<column>
<property name="text">
<string>Description</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="presetsControl">
<item>
<widget class="QToolButton" name="presetSave">
<property name="toolTip">
<string>Save current settings as new preset</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../resources/res.qrc">
<normaloff>:/create.png</normaloff>:/create.png</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="presetUpdate">
<property name="toolTip">
<string>Update selected preset with current settings</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../resources/res.qrc">
<normaloff>:/recycle.png</normaloff>:/recycle.png</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="presetEdit">
<property name="toolTip">
<string>Edit preset details</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resources/res.qrc">
<normaloff>:/edit.png</normaloff>:/edit.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="presetDelete">
<property name="toolTip">
<string>Delete selected preset</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../resources/res.qrc">
<normaloff>:/bin.png</normaloff>:/bin.png</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="presetLoad">
<property name="toolTip">
<string>Load selected preset</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../resources/res.qrc">
<normaloff>:/load.png</normaloff>:/load.png</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../resources/res.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>PluginPresetsDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>PluginPresetsDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -92,6 +92,7 @@
#include "webapi/webapiserver.h"
#include "webapi/webapiadapter.h"
#include "commands/command.h"
#include "settings/serializableinterface.h"
#ifdef ANDROID
#include "util/android.h"
#endif
@ -403,6 +404,7 @@ void MainWindow::sampleSourceAdd(Workspace *deviceWorkspace, Workspace *spectrum
deviceWorkspace->addToMdiArea(m_deviceUIs.back()->m_deviceGUI);
spectrumWorkspace->addToMdiArea(m_deviceUIs.back()->m_mainSpectrumGUI);
loadDefaultPreset(deviceAPI->getSamplingDeviceId(), m_deviceUIs.back());
emit m_mainCore->deviceSetAdded(deviceSetIndex, deviceAPI);
#ifdef ANDROID
@ -638,6 +640,7 @@ void MainWindow::sampleSinkAdd(Workspace *deviceWorkspace, Workspace *spectrumWo
deviceWorkspace->addToMdiArea(m_deviceUIs.back()->m_deviceGUI);
spectrumWorkspace->addToMdiArea(m_deviceUIs.back()->m_mainSpectrumGUI);
loadDefaultPreset(deviceAPI->getSamplingDeviceId(), m_deviceUIs.back());
emit m_mainCore->deviceSetAdded(deviceSetIndex, deviceAPI);
}
@ -869,6 +872,7 @@ void MainWindow::sampleMIMOAdd(Workspace *deviceWorkspace, Workspace *spectrumWo
deviceWorkspace->addToMdiArea(m_deviceUIs.back()->m_deviceGUI);
spectrumWorkspace->addToMdiArea(m_deviceUIs.back()->m_mainSpectrumGUI);
loadDefaultPreset(deviceAPI->getSamplingDeviceId(), m_deviceUIs.back());
emit m_mainCore->deviceSetAdded(deviceSetIndex, deviceAPI);
}
@ -2777,13 +2781,13 @@ void MainWindow::channelAddClicked(Workspace *workspace, int deviceSetIndex, int
{
DeviceUISet *deviceUI = m_deviceUIs[deviceSetIndex];
ChannelGUI *gui = nullptr;
ChannelAPI *channelAPI;
DeviceAPI *deviceAPI = deviceUI->m_deviceAPI;
if (deviceUI->m_deviceSourceEngine) // source device => Rx channels
{
PluginAPI::ChannelRegistrations *channelRegistrations = m_pluginManager->getRxChannelRegistrations(); // Available channel plugins
PluginInterface *pluginInterface = (*channelRegistrations)[channelPluginIndex].m_plugin;
ChannelAPI *channelAPI;
BasebandSampleSink *rxChannel;
pluginInterface->createRxChannel(deviceUI->m_deviceAPI, &rxChannel, &channelAPI);
gui = pluginInterface->createRxChannelGUI(deviceUI, rxChannel);
@ -2796,7 +2800,6 @@ void MainWindow::channelAddClicked(Workspace *workspace, int deviceSetIndex, int
{
PluginAPI::ChannelRegistrations *channelRegistrations = m_pluginManager->getTxChannelRegistrations(); // Available channel plugins
PluginInterface *pluginInterface = (*channelRegistrations)[channelPluginIndex].m_plugin;
ChannelAPI *channelAPI;
BasebandSampleSource *txChannel;
pluginInterface->createTxChannel(deviceUI->m_deviceAPI, &txChannel, &channelAPI);
gui = pluginInterface->createTxChannelGUI(deviceUI, txChannel);
@ -2817,7 +2820,6 @@ void MainWindow::channelAddClicked(Workspace *workspace, int deviceSetIndex, int
{
PluginAPI::ChannelRegistrations *channelRegistrations = m_pluginManager->getMIMOChannelRegistrations(); // Available channel plugins
PluginInterface *pluginInterface = (*channelRegistrations)[channelPluginIndex].m_plugin;
ChannelAPI *channelAPI;
MIMOChannel *mimoChannel;
pluginInterface->createMIMOChannel(deviceUI->m_deviceAPI, &mimoChannel, &channelAPI);
gui = pluginInterface->createMIMOChannelGUI(deviceUI, mimoChannel);
@ -2829,7 +2831,6 @@ void MainWindow::channelAddClicked(Workspace *workspace, int deviceSetIndex, int
{
PluginAPI::ChannelRegistrations *channelRegistrations = m_pluginManager->getRxChannelRegistrations(); // Available channel plugins
PluginInterface *pluginInterface = (*channelRegistrations)[channelPluginIndex - nbMIMOChannels].m_plugin;
ChannelAPI *channelAPI;
BasebandSampleSink *rxChannel;
pluginInterface->createRxChannel(deviceUI->m_deviceAPI, &rxChannel, &channelAPI);
gui = pluginInterface->createRxChannelGUI(deviceUI, rxChannel);
@ -2841,7 +2842,6 @@ void MainWindow::channelAddClicked(Workspace *workspace, int deviceSetIndex, int
{
PluginAPI::ChannelRegistrations *channelRegistrations = m_pluginManager->getTxChannelRegistrations(); // Available channel plugins
PluginInterface *pluginInterface = (*channelRegistrations)[channelPluginIndex - nbMIMOChannels - nbRxChannels].m_plugin;
ChannelAPI *channelAPI;
BasebandSampleSource *txChannel;
pluginInterface->createTxChannel(deviceUI->m_deviceAPI, &txChannel, &channelAPI);
gui = pluginInterface->createTxChannelGUI(deviceUI, txChannel);
@ -2881,6 +2881,7 @@ void MainWindow::channelAddClicked(Workspace *workspace, int deviceSetIndex, int
qPrintable(gui->getTitle()), workspace->getIndex());
workspace->addToMdiArea((QMdiSubWindow*) gui);
//gui->restoreGeometry(gui->getGeometryBytes());
loadDefaultPreset(channelAPI->getURI(), gui);
}
}
}
@ -2901,6 +2902,7 @@ void MainWindow::featureAddClicked(Workspace *workspace, int featureIndex)
gui->setWorkspaceIndex(workspace->getIndex());
gui->setDisplayedame(pluginInterface->getPluginDescriptor().displayedName);
workspace->addToMdiArea((QMdiSubWindow*) gui);
loadDefaultPreset(feature->getURI(), gui);
QObject::connect(
gui,
@ -3087,6 +3089,23 @@ void MainWindow::deleteFeature(int featureSetIndex, int featureIndex)
}
}
// Look for and load a preset named Defaults/Default for the given plugin id
void MainWindow::loadDefaultPreset(const QString& pluginId, SerializableInterface *serializableInterface)
{
QList<PluginPreset*>* presets = m_mainCore->m_settings.getPluginPresets();
for (const auto preset : *presets)
{
if (preset->getGroup() == "Defaults"
&& preset->getDescription() == "Default"
&& preset->getPluginIdURI() == pluginId)
{
qDebug() << "MainWindow::loadDefaultPreset: Loading " << preset->getGroup() << preset->getDescription() << "for" << pluginId;
serializableInterface->deserialize(preset->getConfig());
}
}
}
void MainWindow::on_action_About_triggered()
{
AboutDialog dlg(m_apiHost.isEmpty() ? "127.0.0.1" : m_apiHost, m_apiPort, m_mainCore->m_settings, this);

View File

@ -60,6 +60,7 @@ class FeatureSetPreset;
class CommandKeyReceiver;
class ConfigurationsDialog;
class ProfileDialog;
class SerializableInterface;
class QMenuBar;
class Workspace;
@ -171,6 +172,7 @@ private:
DeviceUISet *deviceUISet
);
void deleteFeature(int featureSetIndex, int featureIndex);
void loadDefaultPreset(const QString& pluginId, SerializableInterface *serializableInterface);
bool handleMessage(const Message& cmd);