kopia lustrzana https://github.com/f4exb/sdrangel
				
				
				
			Add support for plugin presets.
							rodzic
							
								
									028a44ce48
								
							
						
					
					
						commit
						2a24f72590
					
				| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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, ¢erFrequency);
 | 
			
		||||
        setCenterFrequency(centerFrequency);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DeviceAPI::loadSamplingDeviceSettings(const Preset* preset)
 | 
			
		||||
{
 | 
			
		||||
    if (m_deviceSourceEngine && (preset->isSourcePreset()))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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; }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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; }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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_
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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_
 | 
			
		||||
| 
						 | 
				
			
			@ -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>
 | 
			
		||||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Ładowanie…
	
		Reference in New Issue