diff --git a/doc/img/hide.xcf b/doc/img/hide.xcf
new file mode 100644
index 000000000..022857dd4
Binary files /dev/null and b/doc/img/hide.xcf differ
diff --git a/plugins/feature/afc/afcgui.h b/plugins/feature/afc/afcgui.h
index 1b376f9a0..83c73a537 100644
--- a/plugins/feature/afc/afcgui.h
+++ b/plugins/feature/afc/afcgui.h
@@ -43,6 +43,10 @@ public:
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
+ virtual void setWorkspaceIndex(int index) { m_settings.m_workspaceIndex = index; }
+ virtual int getWorkspaceIndex() const { return m_settings.m_workspaceIndex; }
+ virtual void setGeometryBytes(const QByteArray& blob) { m_settings.m_geometryBytes = blob; }
+ virtual QByteArray getGeometryBytes() const { return m_settings.m_geometryBytes; }
private:
Ui::AFCGUI* ui;
diff --git a/plugins/feature/afc/afcsettings.cpp b/plugins/feature/afc/afcsettings.cpp
index 7eec426c9..d8dc8eed5 100644
--- a/plugins/feature/afc/afcsettings.cpp
+++ b/plugins/feature/afc/afcsettings.cpp
@@ -44,6 +44,7 @@ void AFCSettings::resetToDefaults()
m_reverseAPIPort = 8888;
m_reverseAPIFeatureSetIndex = 0;
m_reverseAPIFeatureIndex = 0;
+ m_workspaceIndex = 0;
}
QByteArray AFCSettings::serialize() const
@@ -69,6 +70,9 @@ QByteArray AFCSettings::serialize() const
s.writeBlob(15, m_rollupState->serialize());
}
+ s.writeS32(16, m_workspaceIndex);
+ s.writeBlob(17, m_geometryBytes);
+
return s.final();
}
@@ -118,6 +122,9 @@ bool AFCSettings::deserialize(const QByteArray& data)
m_rollupState->deserialize(bytetmp);
}
+ d.readS32(16, &m_workspaceIndex, 0);
+ d.readBlob(17, &m_geometryBytes);
+
return true;
}
else
diff --git a/plugins/feature/afc/afcsettings.h b/plugins/feature/afc/afcsettings.h
index 115cdfebf..fb3d750a4 100644
--- a/plugins/feature/afc/afcsettings.h
+++ b/plugins/feature/afc/afcsettings.h
@@ -40,6 +40,8 @@ struct AFCSettings
uint16_t m_reverseAPIFeatureSetIndex;
uint16_t m_reverseAPIFeatureIndex;
Serializable *m_rollupState;
+ int m_workspaceIndex;
+ QByteArray m_geometryBytes;
AFCSettings();
void resetToDefaults();
diff --git a/plugins/feature/ais/aisgui.h b/plugins/feature/ais/aisgui.h
index a1e43584a..7bc3651a6 100644
--- a/plugins/feature/ais/aisgui.h
+++ b/plugins/feature/ais/aisgui.h
@@ -57,6 +57,10 @@ public:
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
+ virtual void setWorkspaceIndex(int index) { m_settings.m_workspaceIndex = index; }
+ virtual int getWorkspaceIndex() const { return m_settings.m_workspaceIndex; }
+ virtual void setGeometryBytes(const QByteArray& blob) { m_settings.m_geometryBytes = blob; }
+ virtual QByteArray getGeometryBytes() const { return m_settings.m_geometryBytes; }
private:
Ui::AISGUI* ui;
diff --git a/plugins/feature/ais/aissettings.cpp b/plugins/feature/ais/aissettings.cpp
index 7d902d105..bdc7145f9 100644
--- a/plugins/feature/ais/aissettings.cpp
+++ b/plugins/feature/ais/aissettings.cpp
@@ -47,6 +47,7 @@ void AISSettings::resetToDefaults()
m_reverseAPIPort = 8888;
m_reverseAPIFeatureSetIndex = 0;
m_reverseAPIFeatureIndex = 0;
+ m_workspaceIndex = 0;
for (int i = 0; i < AIS_VESSEL_COLUMNS; i++)
{
@@ -71,6 +72,9 @@ QByteArray AISSettings::serialize() const
s.writeBlob(27, m_rollupState->serialize());
}
+ s.writeS32(27, m_workspaceIndex);
+ s.writeBlob(28, m_geometryBytes);
+
for (int i = 0; i < AIS_VESSEL_COLUMNS; i++) {
s.writeS32(300 + i, m_vesselColumnIndexes[i]);
}
@@ -122,6 +126,9 @@ bool AISSettings::deserialize(const QByteArray& data)
m_rollupState->deserialize(bytetmp);
}
+ d.readS32(27, &m_workspaceIndex, 0);
+ d.readBlob(28, &m_geometryBytes);
+
for (int i = 0; i < AIS_VESSEL_COLUMNS; i++) {
d.readS32(300 + i, &m_vesselColumnIndexes[i], i);
}
diff --git a/plugins/feature/ais/aissettings.h b/plugins/feature/ais/aissettings.h
index d29fe3f84..2cf555800 100644
--- a/plugins/feature/ais/aissettings.h
+++ b/plugins/feature/ais/aissettings.h
@@ -39,6 +39,8 @@ struct AISSettings
uint16_t m_reverseAPIFeatureSetIndex;
uint16_t m_reverseAPIFeatureIndex;
Serializable *m_rollupState;
+ int m_workspaceIndex;
+ QByteArray m_geometryBytes;
int m_vesselColumnIndexes[AIS_VESSEL_COLUMNS];
int m_vesselColumnSizes[AIS_VESSEL_COLUMNS];
diff --git a/plugins/feature/antennatools/antennatoolsgui.h b/plugins/feature/antennatools/antennatoolsgui.h
index c21c8654b..95823f9a3 100644
--- a/plugins/feature/antennatools/antennatoolsgui.h
+++ b/plugins/feature/antennatools/antennatoolsgui.h
@@ -46,6 +46,10 @@ public:
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
+ virtual void setWorkspaceIndex(int index) { m_settings.m_workspaceIndex = index; }
+ virtual int getWorkspaceIndex() const { return m_settings.m_workspaceIndex; }
+ virtual void setGeometryBytes(const QByteArray& blob) { m_settings.m_geometryBytes = blob; }
+ virtual QByteArray getGeometryBytes() const { return m_settings.m_geometryBytes; }
private:
Ui::AntennaToolsGUI* ui;
diff --git a/plugins/feature/antennatools/antennatoolssettings.cpp b/plugins/feature/antennatools/antennatoolssettings.cpp
index 2dd559bbe..2dce3f633 100644
--- a/plugins/feature/antennatools/antennatoolssettings.cpp
+++ b/plugins/feature/antennatools/antennatoolssettings.cpp
@@ -49,6 +49,7 @@ void AntennaToolsSettings::resetToDefaults()
m_reverseAPIPort = 8888;
m_reverseAPIFeatureSetIndex = 0;
m_reverseAPIFeatureIndex = 0;
+ m_workspaceIndex = 0;
}
QByteArray AntennaToolsSettings::serialize() const
@@ -78,6 +79,9 @@ QByteArray AntennaToolsSettings::serialize() const
s.writeBlob(19, m_rollupState->serialize());
}
+ s.writeS32(20, m_workspaceIndex);
+ s.writeBlob(21, m_geometryBytes);
+
return s.final();
}
@@ -131,6 +135,9 @@ bool AntennaToolsSettings::deserialize(const QByteArray& data)
m_rollupState->deserialize(bytetmp);
}
+ d.readS32(20, &m_workspaceIndex, 0);
+ d.readBlob(21, &m_geometryBytes);
+
return true;
}
else
diff --git a/plugins/feature/antennatools/antennatoolssettings.h b/plugins/feature/antennatools/antennatoolssettings.h
index 704f17501..3302cdfd4 100644
--- a/plugins/feature/antennatools/antennatoolssettings.h
+++ b/plugins/feature/antennatools/antennatoolssettings.h
@@ -51,6 +51,8 @@ struct AntennaToolsSettings
uint16_t m_reverseAPIFeatureSetIndex;
uint16_t m_reverseAPIFeatureIndex;
Serializable *m_rollupState;
+ int m_workspaceIndex;
+ QByteArray m_geometryBytes;
AntennaToolsSettings();
void resetToDefaults();
diff --git a/plugins/feature/aprs/aprsgui.h b/plugins/feature/aprs/aprsgui.h
index 412387164..f1a89d1e5 100644
--- a/plugins/feature/aprs/aprsgui.h
+++ b/plugins/feature/aprs/aprsgui.h
@@ -105,6 +105,10 @@ public:
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
+ virtual void setWorkspaceIndex(int index) { m_settings.m_workspaceIndex = index; }
+ virtual int getWorkspaceIndex() const { return m_settings.m_workspaceIndex; }
+ virtual void setGeometryBytes(const QByteArray& blob) { m_settings.m_geometryBytes = blob; }
+ virtual QByteArray getGeometryBytes() const { return m_settings.m_geometryBytes; }
protected:
void resizeEvent(QResizeEvent* size);
diff --git a/plugins/feature/aprs/aprssettings.cpp b/plugins/feature/aprs/aprssettings.cpp
index 5e843f04b..b9b2036af 100644
--- a/plugins/feature/aprs/aprssettings.cpp
+++ b/plugins/feature/aprs/aprssettings.cpp
@@ -77,6 +77,7 @@ void APRSSettings::resetToDefaults()
m_reverseAPIPort = 8888;
m_reverseAPIFeatureSetIndex = 0;
m_reverseAPIFeatureIndex = 0;
+ m_workspaceIndex = 0;
for (int i = 0; i < APRS_PACKETS_TABLE_COLUMNS; i++)
{
@@ -143,6 +144,9 @@ QByteArray APRSSettings::serialize() const
s.writeBlob(20, m_rollupState->serialize());
}
+ s.writeS32(21, m_workspaceIndex);
+ s.writeBlob(22, m_geometryBytes);
+
for (int i = 0; i < APRS_PACKETS_TABLE_COLUMNS; i++)
s.writeS32(100 + i, m_packetsTableColumnIndexes[i]);
for (int i = 0; i < APRS_PACKETS_TABLE_COLUMNS; i++)
@@ -222,6 +226,9 @@ bool APRSSettings::deserialize(const QByteArray& data)
m_rollupState->deserialize(bytetmp);
}
+ d.readS32(21, &m_workspaceIndex, 0);
+ d.readBlob(22, &m_geometryBytes);
+
for (int i = 0; i < APRS_PACKETS_TABLE_COLUMNS; i++)
d.readS32(100 + i, &m_packetsTableColumnIndexes[i], i);
for (int i = 0; i < APRS_PACKETS_TABLE_COLUMNS; i++)
diff --git a/plugins/feature/aprs/aprssettings.h b/plugins/feature/aprs/aprssettings.h
index 509bdd160..99c58894f 100644
--- a/plugins/feature/aprs/aprssettings.h
+++ b/plugins/feature/aprs/aprssettings.h
@@ -77,6 +77,8 @@ struct APRSSettings
uint16_t m_reverseAPIFeatureSetIndex;
uint16_t m_reverseAPIFeatureIndex;
Serializable *m_rollupState;
+ int m_workspaceIndex;
+ QByteArray m_geometryBytes;
int m_packetsTableColumnIndexes[APRS_PACKETS_TABLE_COLUMNS];//!< How the columns are ordered in the table
int m_packetsTableColumnSizes[APRS_PACKETS_TABLE_COLUMNS]; //!< Size of the columns in the table
diff --git a/plugins/feature/demodanalyzer/demodanalyzergui.h b/plugins/feature/demodanalyzer/demodanalyzergui.h
index b11100ecf..e26fddd60 100644
--- a/plugins/feature/demodanalyzer/demodanalyzergui.h
+++ b/plugins/feature/demodanalyzer/demodanalyzergui.h
@@ -49,6 +49,10 @@ public:
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
+ virtual void setWorkspaceIndex(int index) { m_settings.m_workspaceIndex = index; }
+ virtual int getWorkspaceIndex() const { return m_settings.m_workspaceIndex; }
+ virtual void setGeometryBytes(const QByteArray& blob) { m_settings.m_geometryBytes = blob; }
+ virtual QByteArray getGeometryBytes() const { return m_settings.m_geometryBytes; }
private:
Ui::DemodAnalyzerGUI* ui;
diff --git a/plugins/feature/demodanalyzer/demodanalyzersettings.cpp b/plugins/feature/demodanalyzer/demodanalyzersettings.cpp
index 12419b2cc..d261e5417 100644
--- a/plugins/feature/demodanalyzer/demodanalyzersettings.cpp
+++ b/plugins/feature/demodanalyzer/demodanalyzersettings.cpp
@@ -76,6 +76,7 @@ void DemodAnalyzerSettings::resetToDefaults()
m_reverseAPIPort = 8888;
m_reverseAPIFeatureSetIndex = 0;
m_reverseAPIFeatureIndex = 0;
+ m_workspaceIndex = 0;
}
QByteArray DemodAnalyzerSettings::serialize() const
@@ -103,6 +104,9 @@ QByteArray DemodAnalyzerSettings::serialize() const
s.writeBlob(12, m_rollupState->serialize());
}
+ s.writeS32(13, m_workspaceIndex);
+ s.writeBlob(14, m_geometryBytes);
+
return s.final();
}
@@ -158,6 +162,9 @@ bool DemodAnalyzerSettings::deserialize(const QByteArray& data)
m_rollupState->deserialize(bytetmp);
}
+ d.readS32(13, &m_workspaceIndex, 0);
+ d.readBlob(14, &m_geometryBytes);
+
return true;
}
else
diff --git a/plugins/feature/demodanalyzer/demodanalyzersettings.h b/plugins/feature/demodanalyzer/demodanalyzersettings.h
index c4ba8516a..d3670d181 100644
--- a/plugins/feature/demodanalyzer/demodanalyzersettings.h
+++ b/plugins/feature/demodanalyzer/demodanalyzersettings.h
@@ -52,6 +52,8 @@ struct DemodAnalyzerSettings
Serializable *m_spectrumGUI;
Serializable *m_scopeGUI;
Serializable *m_rollupState;
+ int m_workspaceIndex;
+ QByteArray m_geometryBytes;
DemodAnalyzerSettings();
void resetToDefaults();
diff --git a/plugins/feature/gs232controller/gs232controllergui.h b/plugins/feature/gs232controller/gs232controllergui.h
index 1fbd42d03..887d5d783 100644
--- a/plugins/feature/gs232controller/gs232controllergui.h
+++ b/plugins/feature/gs232controller/gs232controllergui.h
@@ -45,6 +45,10 @@ public:
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
+ virtual void setWorkspaceIndex(int index) { m_settings.m_workspaceIndex = index; }
+ virtual int getWorkspaceIndex() const { return m_settings.m_workspaceIndex; }
+ virtual void setGeometryBytes(const QByteArray& blob) { m_settings.m_geometryBytes = blob; }
+ virtual QByteArray getGeometryBytes() const { return m_settings.m_geometryBytes; }
private:
Ui::GS232ControllerGUI* ui;
diff --git a/plugins/feature/gs232controller/gs232controllersettings.cpp b/plugins/feature/gs232controller/gs232controllersettings.cpp
index 0e9f3d756..fd9a34278 100644
--- a/plugins/feature/gs232controller/gs232controllersettings.cpp
+++ b/plugins/feature/gs232controller/gs232controllersettings.cpp
@@ -69,6 +69,7 @@ void GS232ControllerSettings::resetToDefaults()
m_connection = SERIAL;
m_host = "127.0.0.1";
m_port = 4533;
+ m_workspaceIndex = 0;
}
QByteArray GS232ControllerSettings::serialize() const
@@ -104,6 +105,9 @@ QByteArray GS232ControllerSettings::serialize() const
s.writeBlob(26, m_rollupState->serialize());
}
+ s.writeS32(27, m_workspaceIndex);
+ s.writeBlob(28, m_geometryBytes);
+
return s.final();
}
@@ -163,6 +167,9 @@ bool GS232ControllerSettings::deserialize(const QByteArray& data)
m_rollupState->deserialize(bytetmp);
}
+ d.readS32(27, &m_workspaceIndex, 0);
+ d.readBlob(28, &m_geometryBytes);
+
return true;
}
else
diff --git a/plugins/feature/gs232controller/gs232controllersettings.h b/plugins/feature/gs232controller/gs232controllersettings.h
index f922022f8..3db11f2ce 100644
--- a/plugins/feature/gs232controller/gs232controllersettings.h
+++ b/plugins/feature/gs232controller/gs232controllersettings.h
@@ -68,6 +68,8 @@ struct GS232ControllerSettings
uint16_t m_reverseAPIPort;
uint16_t m_reverseAPIFeatureSetIndex;
uint16_t m_reverseAPIFeatureIndex;
+ int m_workspaceIndex;
+ QByteArray m_geometryBytes;
GS232ControllerSettings();
void resetToDefaults();
diff --git a/plugins/feature/jogdialcontroller/jogdialcontrollergui.h b/plugins/feature/jogdialcontroller/jogdialcontrollergui.h
index d7d27633c..932b5592d 100644
--- a/plugins/feature/jogdialcontroller/jogdialcontrollergui.h
+++ b/plugins/feature/jogdialcontroller/jogdialcontrollergui.h
@@ -47,6 +47,10 @@ public:
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
+ virtual void setWorkspaceIndex(int index) { m_settings.m_workspaceIndex = index; }
+ virtual int getWorkspaceIndex() const { return m_settings.m_workspaceIndex; }
+ virtual void setGeometryBytes(const QByteArray& blob) { m_settings.m_geometryBytes = blob; }
+ virtual QByteArray getGeometryBytes() const { return m_settings.m_geometryBytes; }
protected:
void focusInEvent(QFocusEvent* e);
diff --git a/plugins/feature/jogdialcontroller/jogdialcontrollersettings.cpp b/plugins/feature/jogdialcontroller/jogdialcontrollersettings.cpp
index 8893cbe5e..01900a482 100644
--- a/plugins/feature/jogdialcontroller/jogdialcontrollersettings.cpp
+++ b/plugins/feature/jogdialcontroller/jogdialcontrollersettings.cpp
@@ -71,6 +71,7 @@ void JogdialControllerSettings::resetToDefaults()
m_reverseAPIPort = 8888;
m_reverseAPIFeatureSetIndex = 0;
m_reverseAPIFeatureIndex = 0;
+ m_workspaceIndex = 0;
}
QByteArray JogdialControllerSettings::serialize() const
@@ -89,6 +90,9 @@ QByteArray JogdialControllerSettings::serialize() const
s.writeBlob(12, m_rollupState->serialize());
}
+ s.writeS32(13, m_workspaceIndex);
+ s.writeBlob(14, m_geometryBytes);
+
return s.final();
}
@@ -131,6 +135,9 @@ bool JogdialControllerSettings::deserialize(const QByteArray& data)
m_rollupState->deserialize(bytetmp);
}
+ d.readS32(13, &m_workspaceIndex, 0);
+ d.readBlob(14, &m_geometryBytes);
+
return true;
}
else
diff --git a/plugins/feature/jogdialcontroller/jogdialcontrollersettings.h b/plugins/feature/jogdialcontroller/jogdialcontrollersettings.h
index 5d1b82773..fecb052a4 100644
--- a/plugins/feature/jogdialcontroller/jogdialcontrollersettings.h
+++ b/plugins/feature/jogdialcontroller/jogdialcontrollersettings.h
@@ -52,6 +52,8 @@ struct JogdialControllerSettings
uint16_t m_reverseAPIFeatureSetIndex;
uint16_t m_reverseAPIFeatureIndex;
Serializable *m_rollupState;
+ int m_workspaceIndex;
+ QByteArray m_geometryBytes;
JogdialControllerSettings();
void resetToDefaults();
diff --git a/plugins/feature/map/mapgui.h b/plugins/feature/map/mapgui.h
index 16ad02a19..774810f8d 100644
--- a/plugins/feature/map/mapgui.h
+++ b/plugins/feature/map/mapgui.h
@@ -72,6 +72,10 @@ public:
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
+ virtual void setWorkspaceIndex(int index) { m_settings.m_workspaceIndex = index; }
+ virtual int getWorkspaceIndex() const { return m_settings.m_workspaceIndex; }
+ virtual void setGeometryBytes(const QByteArray& blob) { m_settings.m_geometryBytes = blob; }
+ virtual QByteArray getGeometryBytes() const { return m_settings.m_geometryBytes; }
AzEl *getAzEl() { return &m_azEl; }
Map *getMap() { return m_map; }
QQuickItem *getMapItem();
diff --git a/plugins/feature/map/mapsettings.cpp b/plugins/feature/map/mapsettings.cpp
index 732e58502..8df0b3501 100644
--- a/plugins/feature/map/mapsettings.cpp
+++ b/plugins/feature/map/mapsettings.cpp
@@ -106,6 +106,7 @@ void MapSettings::resetToDefaults()
m_eciCamera = false;
m_modelDir = HttpDownloadManager::downloadDir() + "/3d";
m_antiAliasing = "None";
+ m_workspaceIndex = 0;
}
QByteArray MapSettings::serialize() const
@@ -144,6 +145,8 @@ QByteArray MapSettings::serialize() const
s.writeBool(30, m_eciCamera);
s.writeString(31, m_cesiumIonAPIKey);
s.writeString(32, m_antiAliasing);
+ s.writeS32(33, m_workspaceIndex);
+ s.writeBlob(34, m_geometryBytes);
return s.final();
}
@@ -210,6 +213,8 @@ bool MapSettings::deserialize(const QByteArray& data)
d.readBool(30, &m_eciCamera, false);
d.readString(31, &m_cesiumIonAPIKey, "");
d.readString(32, &m_antiAliasing, "None");
+ d.readS32(33, &m_workspaceIndex, 0);
+ d.readBlob(34, &m_geometryBytes);
return true;
}
diff --git a/plugins/feature/map/mapsettings.h b/plugins/feature/map/mapsettings.h
index e190f770a..7ce04b65f 100644
--- a/plugins/feature/map/mapsettings.h
+++ b/plugins/feature/map/mapsettings.h
@@ -90,6 +90,8 @@ struct MapSettings
Serializable *m_rollupState;
bool m_map2DEnabled;
QString m_mapType; // "Street Map", "Satellite Map", etc.. as selected in combobox
+ int m_workspaceIndex;
+ QByteArray m_geometryBytes;
// 3D Map settings
bool m_map3DEnabled;
diff --git a/plugins/feature/pertester/pertestergui.h b/plugins/feature/pertester/pertestergui.h
index b5fe9b0fa..2306bf792 100644
--- a/plugins/feature/pertester/pertestergui.h
+++ b/plugins/feature/pertester/pertestergui.h
@@ -45,6 +45,10 @@ public:
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
+ virtual void setWorkspaceIndex(int index) { m_settings.m_workspaceIndex = index; }
+ virtual int getWorkspaceIndex() const { return m_settings.m_workspaceIndex; }
+ virtual void setGeometryBytes(const QByteArray& blob) { m_settings.m_geometryBytes = blob; }
+ virtual QByteArray getGeometryBytes() const { return m_settings.m_geometryBytes; }
private:
Ui::PERTesterGUI* ui;
diff --git a/plugins/feature/pertester/pertestersettings.cpp b/plugins/feature/pertester/pertestersettings.cpp
index 7499902d4..0121b1d8d 100644
--- a/plugins/feature/pertester/pertestersettings.cpp
+++ b/plugins/feature/pertester/pertestersettings.cpp
@@ -50,6 +50,7 @@ void PERTesterSettings::resetToDefaults()
m_reverseAPIPort = 8888;
m_reverseAPIFeatureSetIndex = 0;
m_reverseAPIFeatureIndex = 0;
+ m_workspaceIndex = 0;
}
QByteArray PERTesterSettings::serialize() const
@@ -78,6 +79,8 @@ QByteArray PERTesterSettings::serialize() const
s.writeBlob(27, m_rollupState->serialize());
}
+ s.writeS32(28, m_workspaceIndex);
+
return s.final();
}
@@ -146,6 +149,9 @@ bool PERTesterSettings::deserialize(const QByteArray& data)
m_rollupState->deserialize(bytetmp);
}
+ d.readS32(28, &m_workspaceIndex, 0);
+ d.readBlob(29, &m_geometryBytes);
+
return true;
}
else
diff --git a/plugins/feature/pertester/pertestersettings.h b/plugins/feature/pertester/pertestersettings.h
index ea2cfcc83..119aebbcd 100644
--- a/plugins/feature/pertester/pertestersettings.h
+++ b/plugins/feature/pertester/pertestersettings.h
@@ -48,6 +48,8 @@ struct PERTesterSettings
uint16_t m_reverseAPIFeatureSetIndex;
uint16_t m_reverseAPIFeatureIndex;
Serializable *m_rollupState;
+ int m_workspaceIndex;
+ QByteArray m_geometryBytes;
PERTesterSettings();
void resetToDefaults();
diff --git a/plugins/feature/radiosonde/radiosondegui.h b/plugins/feature/radiosonde/radiosondegui.h
index 18202ab61..1bd135232 100644
--- a/plugins/feature/radiosonde/radiosondegui.h
+++ b/plugins/feature/radiosonde/radiosondegui.h
@@ -74,6 +74,10 @@ public:
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
+ virtual void setWorkspaceIndex(int index) { m_settings.m_workspaceIndex = index; }
+ virtual int getWorkspaceIndex() const { return m_settings.m_workspaceIndex; }
+ virtual void setGeometryBytes(const QByteArray& blob) { m_settings.m_geometryBytes = blob; }
+ virtual QByteArray getGeometryBytes() const { return m_settings.m_geometryBytes; }
private:
Ui::RadiosondeGUI* ui;
diff --git a/plugins/feature/radiosonde/radiosondesettings.cpp b/plugins/feature/radiosonde/radiosondesettings.cpp
index 565d44877..2e2f016b6 100644
--- a/plugins/feature/radiosonde/radiosondesettings.cpp
+++ b/plugins/feature/radiosonde/radiosondesettings.cpp
@@ -76,6 +76,8 @@ QByteArray RadiosondeSettings::serialize() const
s.writeS32(10, (int)m_y1);
s.writeS32(11, (int)m_y2);
+ s.writeS32(12, m_workspaceIndex);
+ s.writeBlob(13, m_geometryBytes);
for (int i = 0; i < RADIOSONDES_COLUMNS; i++) {
s.writeS32(300 + i, m_radiosondesColumnIndexes[i]);
@@ -130,6 +132,8 @@ bool RadiosondeSettings::deserialize(const QByteArray& data)
d.readS32(10, (int *)&m_y1, (int)ALTITUDE);
d.readS32(11, (int *)&m_y2, (int)TEMPERATURE);
+ d.readS32(12, &m_workspaceIndex, 0);
+ d.readBlob(13, &m_geometryBytes);
for (int i = 0; i < RADIOSONDES_COLUMNS; i++) {
d.readS32(300 + i, &m_radiosondesColumnIndexes[i], i);
diff --git a/plugins/feature/radiosonde/radiosondesettings.h b/plugins/feature/radiosonde/radiosondesettings.h
index 4c199c731..878b39bfc 100644
--- a/plugins/feature/radiosonde/radiosondesettings.h
+++ b/plugins/feature/radiosonde/radiosondesettings.h
@@ -39,6 +39,8 @@ struct RadiosondeSettings
uint16_t m_reverseAPIFeatureSetIndex;
uint16_t m_reverseAPIFeatureIndex;
Serializable *m_rollupState;
+ int m_workspaceIndex;
+ QByteArray m_geometryBytes;
enum ChartData {
NONE,
diff --git a/plugins/feature/rigctlserver/rigctlservergui.h b/plugins/feature/rigctlserver/rigctlservergui.h
index 679b61dd6..51f429a09 100644
--- a/plugins/feature/rigctlserver/rigctlservergui.h
+++ b/plugins/feature/rigctlserver/rigctlservergui.h
@@ -45,6 +45,10 @@ public:
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
+ virtual void setWorkspaceIndex(int index) { m_settings.m_workspaceIndex = index; }
+ virtual int getWorkspaceIndex() const { return m_settings.m_workspaceIndex; }
+ virtual void setGeometryBytes(const QByteArray& blob) { m_settings.m_geometryBytes = blob; }
+ virtual QByteArray getGeometryBytes() const { return m_settings.m_geometryBytes; }
private:
Ui::RigCtlServerGUI* ui;
diff --git a/plugins/feature/rigctlserver/rigctlserversettings.cpp b/plugins/feature/rigctlserver/rigctlserversettings.cpp
index a875dc5d1..ad00529cb 100644
--- a/plugins/feature/rigctlserver/rigctlserversettings.cpp
+++ b/plugins/feature/rigctlserver/rigctlserversettings.cpp
@@ -44,6 +44,7 @@ void RigCtlServerSettings::resetToDefaults()
m_reverseAPIPort = 8888;
m_reverseAPIFeatureSetIndex = 0;
m_reverseAPIFeatureIndex = 0;
+ m_workspaceIndex = 0;
}
QByteArray RigCtlServerSettings::serialize() const
@@ -66,6 +67,9 @@ QByteArray RigCtlServerSettings::serialize() const
s.writeBlob(12, m_rollupState->serialize());
}
+ s.writeS32(13, m_workspaceIndex);
+ s.writeBlob(14, m_geometryBytes);
+
return s.final();
}
@@ -119,6 +123,9 @@ bool RigCtlServerSettings::deserialize(const QByteArray& data)
m_rollupState->deserialize(bytetmp);
}
+ d.readS32(13, &m_workspaceIndex, 0);
+ d.readBlob(14, &m_geometryBytes);
+
return true;
}
else
diff --git a/plugins/feature/rigctlserver/rigctlserversettings.h b/plugins/feature/rigctlserver/rigctlserversettings.h
index 70bdabf65..b76562b38 100644
--- a/plugins/feature/rigctlserver/rigctlserversettings.h
+++ b/plugins/feature/rigctlserver/rigctlserversettings.h
@@ -60,6 +60,8 @@ struct RigCtlServerSettings
uint16_t m_reverseAPIFeatureSetIndex;
uint16_t m_reverseAPIFeatureIndex;
Serializable *m_rollupState;
+ int m_workspaceIndex;
+ QByteArray m_geometryBytes;
RigCtlServerSettings();
void resetToDefaults();
diff --git a/plugins/feature/satellitetracker/satellitetrackergui.h b/plugins/feature/satellitetracker/satellitetrackergui.h
index 2d192f48b..143d81bd6 100644
--- a/plugins/feature/satellitetracker/satellitetrackergui.h
+++ b/plugins/feature/satellitetracker/satellitetrackergui.h
@@ -52,6 +52,10 @@ public:
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
+ virtual void setWorkspaceIndex(int index) { m_settings.m_workspaceIndex = index; }
+ virtual int getWorkspaceIndex() const { return m_settings.m_workspaceIndex; }
+ virtual void setGeometryBytes(const QByteArray& blob) { m_settings.m_geometryBytes = blob; }
+ virtual QByteArray getGeometryBytes() const { return m_settings.m_geometryBytes; }
private:
Ui::SatelliteTrackerGUI* ui;
diff --git a/plugins/feature/satellitetracker/satellitetrackersettings.cpp b/plugins/feature/satellitetracker/satellitetrackersettings.cpp
index 1d7eaa9ad..9afab8bd5 100644
--- a/plugins/feature/satellitetracker/satellitetrackersettings.cpp
+++ b/plugins/feature/satellitetracker/satellitetrackersettings.cpp
@@ -78,6 +78,8 @@ void SatelliteTrackerSettings::resetToDefaults()
m_dateTimeSelect = NOW;
m_mapFeature = "";
m_fileInputDevice = "";
+ m_workspaceIndex = 0;
+
for (int i = 0; i < SAT_COL_COLUMNS; i++)
{
m_columnIndexes[i] = i;
@@ -134,6 +136,8 @@ QByteArray SatelliteTrackerSettings::serialize() const
s.writeS32(42, (int)m_dateTimeSelect);
s.writeString(43, m_mapFeature);
s.writeString(44, m_fileInputDevice);
+ s.writeS32(45, m_workspaceIndex);
+ s.writeBlob(46, m_geometryBytes);
for (int i = 0; i < SAT_COL_COLUMNS; i++) {
s.writeS32(100 + i, m_columnIndexes[i]);
@@ -225,6 +229,8 @@ bool SatelliteTrackerSettings::deserialize(const QByteArray& data)
d.readS32(42, (int *)&m_dateTimeSelect, (int)NOW);
d.readString(43, &m_mapFeature, "");
d.readString(44, &m_fileInputDevice, "");
+ d.readS32(45, &m_workspaceIndex, 0);
+ d.readBlob(46, &m_geometryBytes);
for (int i = 0; i < SAT_COL_COLUMNS; i++) {
d.readS32(100 + i, &m_columnIndexes[i], i);
diff --git a/plugins/feature/satellitetracker/satellitetrackersettings.h b/plugins/feature/satellitetracker/satellitetrackersettings.h
index 238d1f5c7..34495e41b 100644
--- a/plugins/feature/satellitetracker/satellitetrackersettings.h
+++ b/plugins/feature/satellitetracker/satellitetrackersettings.h
@@ -94,6 +94,8 @@ struct SatelliteTrackerSettings
uint16_t m_reverseAPIFeatureSetIndex;
uint16_t m_reverseAPIFeatureIndex;
Serializable *m_rollupState;
+ int m_workspaceIndex;
+ QByteArray m_geometryBytes;
SatelliteTrackerSettings();
void resetToDefaults();
diff --git a/plugins/feature/simpleptt/simplepttgui.h b/plugins/feature/simpleptt/simplepttgui.h
index 3062bde6a..bee5244d8 100644
--- a/plugins/feature/simpleptt/simplepttgui.h
+++ b/plugins/feature/simpleptt/simplepttgui.h
@@ -44,6 +44,10 @@ public:
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
+ virtual void setWorkspaceIndex(int index) { m_settings.m_workspaceIndex = index; }
+ virtual int getWorkspaceIndex() const { return m_settings.m_workspaceIndex; }
+ virtual void setGeometryBytes(const QByteArray& blob) { m_settings.m_geometryBytes = blob; }
+ virtual QByteArray getGeometryBytes() const { return m_settings.m_geometryBytes; }
private:
Ui::SimplePTTGUI* ui;
diff --git a/plugins/feature/simpleptt/simplepttsettings.cpp b/plugins/feature/simpleptt/simplepttsettings.cpp
index 1029d312f..efbafdbd8 100644
--- a/plugins/feature/simpleptt/simplepttsettings.cpp
+++ b/plugins/feature/simpleptt/simplepttsettings.cpp
@@ -47,6 +47,7 @@ void SimplePTTSettings::resetToDefaults()
m_reverseAPIPort = 8888;
m_reverseAPIFeatureSetIndex = 0;
m_reverseAPIFeatureIndex = 0;
+ m_workspaceIndex = 0;
}
QByteArray SimplePTTSettings::serialize() const
@@ -74,6 +75,8 @@ QByteArray SimplePTTSettings::serialize() const
s.writeBool(15, m_vox);
s.writeBool(16, m_voxEnable);
s.writeS32(17, m_voxHold);
+ s.writeS32(18, m_workspaceIndex);
+ s.writeBlob(19, m_geometryBytes);
return s.final();
}
@@ -125,7 +128,9 @@ bool SimplePTTSettings::deserialize(const QByteArray& data)
d.readS32(14, &m_voxLevel, -20);
d.readBool(15, &m_vox, false);
d.readBool(16, &m_voxEnable, false);
- d.readS32(16, &m_voxHold, 500);
+ d.readS32(17, &m_voxHold, 500);
+ d.readS32(18, &m_workspaceIndex, 0);
+ d.readBlob(19, &m_geometryBytes);
return true;
}
diff --git a/plugins/feature/simpleptt/simplepttsettings.h b/plugins/feature/simpleptt/simplepttsettings.h
index 00a12a77c..39c9a2fdb 100644
--- a/plugins/feature/simpleptt/simplepttsettings.h
+++ b/plugins/feature/simpleptt/simplepttsettings.h
@@ -42,6 +42,8 @@ struct SimplePTTSettings
uint16_t m_reverseAPIFeatureSetIndex;
uint16_t m_reverseAPIFeatureIndex;
Serializable *m_rollupState;
+ int m_workspaceIndex;
+ QByteArray m_geometryBytes;
SimplePTTSettings();
void resetToDefaults();
diff --git a/plugins/feature/startracker/startrackergui.h b/plugins/feature/startracker/startrackergui.h
index 2d41484da..802cfae69 100644
--- a/plugins/feature/startracker/startrackergui.h
+++ b/plugins/feature/startracker/startrackergui.h
@@ -66,6 +66,10 @@ public:
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
+ virtual void setWorkspaceIndex(int index) { m_settings.m_workspaceIndex = index; }
+ virtual int getWorkspaceIndex() const { return m_settings.m_workspaceIndex; }
+ virtual void setGeometryBytes(const QByteArray& blob) { m_settings.m_geometryBytes = blob; }
+ virtual QByteArray getGeometryBytes() const { return m_settings.m_geometryBytes; }
private:
Ui::StarTrackerGUI* ui;
diff --git a/plugins/feature/startracker/startrackersettings.cpp b/plugins/feature/startracker/startrackersettings.cpp
index f15aad679..b83e3d802 100644
--- a/plugins/feature/startracker/startrackersettings.cpp
+++ b/plugins/feature/startracker/startrackersettings.cpp
@@ -82,6 +82,7 @@ void StarTrackerSettings::resetToDefaults()
m_weatherUpdatePeriod = 60;
m_drawSunOnSkyTempChart = true;
m_drawMoonOnSkyTempChart = true;
+ m_workspaceIndex = 0;
}
QByteArray StarTrackerSettings::serialize() const
@@ -136,6 +137,9 @@ QByteArray StarTrackerSettings::serialize() const
s.writeBlob(44, m_rollupState->serialize());
}
+ s.writeS32(45, m_workspaceIndex);
+ s.writeBlob(46, m_geometryBytes);
+
return s.final();
}
@@ -221,6 +225,9 @@ bool StarTrackerSettings::deserialize(const QByteArray& data)
m_rollupState->deserialize(bytetmp);
}
+ d.readS32(45, &m_workspaceIndex, 0);
+ d.readBlob(46, &m_geometryBytes);
+
return true;
}
else
diff --git a/plugins/feature/startracker/startrackersettings.h b/plugins/feature/startracker/startrackersettings.h
index 9232eea9c..eec6f2627 100644
--- a/plugins/feature/startracker/startrackersettings.h
+++ b/plugins/feature/startracker/startrackersettings.h
@@ -72,6 +72,8 @@ struct StarTrackerSettings
bool m_drawSunOnSkyTempChart;
bool m_drawMoonOnSkyTempChart;
Serializable *m_rollupState;
+ int m_workspaceIndex;
+ QByteArray m_geometryBytes;
StarTrackerSettings();
void resetToDefaults();
diff --git a/plugins/feature/vorlocalizer/vorlocalizergui.h b/plugins/feature/vorlocalizer/vorlocalizergui.h
index b2d1f34f0..0f498a930 100644
--- a/plugins/feature/vorlocalizer/vorlocalizergui.h
+++ b/plugins/feature/vorlocalizer/vorlocalizergui.h
@@ -214,6 +214,10 @@ public:
bool deserialize(const QByteArray& data);
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
void selectVOR(VORGUI *vorGUI, bool selected);
+ virtual void setWorkspaceIndex(int index) { m_settings.m_workspaceIndex = index; }
+ virtual int getWorkspaceIndex() const { return m_settings.m_workspaceIndex; }
+ virtual void setGeometryBytes(const QByteArray& blob) { m_settings.m_geometryBytes = blob; }
+ virtual QByteArray getGeometryBytes() const { return m_settings.m_geometryBytes; }
private:
friend class VORGUI;
diff --git a/plugins/feature/vorlocalizer/vorlocalizersettings.cpp b/plugins/feature/vorlocalizer/vorlocalizersettings.cpp
index 760a450d4..a6e4da6c7 100644
--- a/plugins/feature/vorlocalizer/vorlocalizersettings.cpp
+++ b/plugins/feature/vorlocalizer/vorlocalizersettings.cpp
@@ -41,7 +41,7 @@ void VORLocalizerSettings::resetToDefaults()
m_reverseAPIPort = 8888;
m_reverseAPIFeatureSetIndex = 0;
m_reverseAPIFeatureIndex = 0;
-
+ m_workspaceIndex = 0;
for (int i = 0; i < VORDEMOD_COLUMNS; i++)
{
@@ -69,6 +69,9 @@ QByteArray VORLocalizerSettings::serialize() const
s.writeBlob(19, m_rollupState->serialize());
}
+ s.writeS32(20, m_workspaceIndex);
+ s.writeBlob(21, m_geometryBytes);
+
for (int i = 0; i < VORDEMOD_COLUMNS; i++) {
s.writeS32(100 + i, m_columnIndexes[i]);
}
@@ -123,6 +126,9 @@ bool VORLocalizerSettings::deserialize(const QByteArray& data)
m_rollupState->deserialize(bytetmp);
}
+ d.readS32(20, &m_workspaceIndex, 0);
+ d.readBlob(21, &m_geometryBytes);
+
for (int i = 0; i < VORDEMOD_COLUMNS; i++) {
d.readS32(100 + i, &m_columnIndexes[i], i);
}
diff --git a/plugins/feature/vorlocalizer/vorlocalizersettings.h b/plugins/feature/vorlocalizer/vorlocalizersettings.h
index 410c96331..c34a0f790 100644
--- a/plugins/feature/vorlocalizer/vorlocalizersettings.h
+++ b/plugins/feature/vorlocalizer/vorlocalizersettings.h
@@ -74,7 +74,8 @@ struct VORLocalizerSettings
uint16_t m_reverseAPIFeatureSetIndex;
uint16_t m_reverseAPIFeatureIndex;
Serializable *m_rollupState;
-
+ int m_workspaceIndex;
+ QByteArray m_geometryBytes;
static const int VORDEMOD_COLUMNS = 11;
static const int VOR_COL_NAME = 0;
diff --git a/sdrbase/CMakeLists.txt b/sdrbase/CMakeLists.txt
index 899bd7bdc..c8be0d4b8 100644
--- a/sdrbase/CMakeLists.txt
+++ b/sdrbase/CMakeLists.txt
@@ -176,6 +176,7 @@ set(sdrbase_SOURCES
pipes/objectpipe.cpp
pipes/objectpipesregistrations.cpp
+ settings/configuration.cpp
settings/featuresetpreset.cpp
settings/preferences.cpp
settings/preset.cpp
@@ -389,6 +390,7 @@ set(sdrbase_HEADERS
plugin/pluginapi.h
plugin/pluginmanager.h
+ settings/configuration.h
settings/featuresetpreset.h
settings/preferences.h
settings/preset.h
diff --git a/sdrbase/pipes/messagepipeslegacy.cpp b/sdrbase/pipes/messagepipeslegacy.cpp
deleted file mode 100644
index 6d9355bba..000000000
--- a/sdrbase/pipes/messagepipeslegacy.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 2020 Edouard Griffiths, F4EXB //
-// //
-// This program is free software; you can redistribute it and/or modify //
-// it under the terms of the GNU General Public License as published by //
-// the Free Software Foundation as version 3 of the License, or //
-// (at your option) any later version. //
-// //
-// This program is distributed in the hope that it will be useful, //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
-// GNU General Public License V3 for more details. //
-// //
-// You should have received a copy of the GNU General Public License //
-// along with this program. If not, see . //
-///////////////////////////////////////////////////////////////////////////////////
-
-#include
-
-#include "util/messagequeue.h"
-
-#include "messagepipeslegacygcworker.h"
-#include "messagepipeslegacy.h"
-#include "pipeendpoint.h"
-
-MessagePipesLegacy::MessagePipesLegacy()
-{
- m_gcWorker = new MessagePipesLegacyGCWorker();
- m_gcWorker->setC2FRegistrations(
- m_registrations.getMutex(),
- m_registrations.getElements(),
- m_registrations.getConsumers()
- );
- m_gcWorker->moveToThread(&m_gcThread);
- startGC();
-}
-
-MessagePipesLegacy::~MessagePipesLegacy()
-{
- if (m_gcWorker->isRunning()) {
- stopGC();
- }
-}
-
-MessageQueue *MessagePipesLegacy::registerChannelToFeature(const PipeEndPoint *source, PipeEndPoint *dest, const QString& type)
-{
- qDebug("MessagePipesLegacy::registerChannelToFeature: %p %p %s", source, dest, qPrintable(type));
- return m_registrations.registerProducerToConsumer(source, dest, type);
-}
-
-MessageQueue *MessagePipesLegacy::unregisterChannelToFeature(const PipeEndPoint *source, PipeEndPoint *dest, const QString& type)
-{
- qDebug("MessagePipesLegacy::unregisterChannelToFeature: %p %p %s", source, dest, qPrintable(type));
- MessageQueue *messageQueue = m_registrations.unregisterProducerToConsumer(source, dest, type);
- m_gcWorker->addMessageQueueToDelete(messageQueue);
- return messageQueue;
-}
-
-QList* MessagePipesLegacy::getMessageQueues(const PipeEndPoint *source, const QString& type)
-{
- //qDebug("MessagePipesLegacy::getMessageQueues: %p %s", source, qPrintable(type));
- return m_registrations.getElements(source, type);
-}
-
-void MessagePipesLegacy::startGC()
-{
- qDebug("MessagePipesLegacy::startGC");
- m_gcWorker->startWork();
- m_gcThread.start();
-}
-
-void MessagePipesLegacy::stopGC()
-{
- qDebug("MessagePipesLegacy::stopGC");
- m_gcWorker->stopWork();
- m_gcThread.quit();
- m_gcThread.wait();
-}
diff --git a/sdrbase/pipes/messagepipeslegacy.h b/sdrbase/pipes/messagepipeslegacy.h
deleted file mode 100644
index 562e582a8..000000000
--- a/sdrbase/pipes/messagepipeslegacy.h
+++ /dev/null
@@ -1,59 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 2020 Edouard Griffiths, F4EXB //
-// //
-// This program is free software; you can redistribute it and/or modify //
-// it under the terms of the GNU General Public License as published by //
-// the Free Software Foundation as version 3 of the License, or //
-// (at your option) any later version. //
-// //
-// This program is distributed in the hope that it will be useful, //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
-// GNU General Public License V3 for more details. //
-// //
-// You should have received a copy of the GNU General Public License //
-// along with this program. If not, see . //
-///////////////////////////////////////////////////////////////////////////////////
-
-#ifndef SDRBASE_PIPES_MESSAGEPIPESLEGACY_H_
-#define SDRBASE_PIPES_MESSAGEPIPESLEGACY_H_
-
-#include
-#include
-#include
-#include
-#include
-
-#include "export.h"
-
-#include "messagepipeslegacycommon.h"
-#include "elementpipesregistrations.h"
-
-class PipeEndPoint;
-class MessagePipesLegacyGCWorker;
-class MessageQueue;
-
-class SDRBASE_API MessagePipesLegacy : public QObject
-{
- Q_OBJECT
-public:
- MessagePipesLegacy();
- MessagePipesLegacy(const MessagePipesLegacy&) = delete;
- MessagePipesLegacy& operator=(const MessagePipesLegacy&) = delete;
- ~MessagePipesLegacy();
-
- // FIXME: Names of these functions should probably change, as we now support channel or feature at either end
- MessageQueue *registerChannelToFeature(const PipeEndPoint *source, PipeEndPoint *dest, const QString& type);
- MessageQueue *unregisterChannelToFeature(const PipeEndPoint *source, PipeEndPoint *dest, const QString& type);
- QList* getMessageQueues(const PipeEndPoint *source, const QString& type);
-
-private:
- ElementPipesRegistrations m_registrations;
- QThread m_gcThread; //!< Garbage collector thread
- MessagePipesLegacyGCWorker *m_gcWorker; //!< Garbage collector
-
- void startGC(); //!< Start garbage collector
- void stopGC(); //!< Stop garbage collector
-};
-
-#endif // SDRBASE_PIPES_MESSAGEPIPESLEGACY_H_
diff --git a/sdrbase/settings/configuration.cpp b/sdrbase/settings/configuration.cpp
new file mode 100644
index 000000000..91210fa91
--- /dev/null
+++ b/sdrbase/settings/configuration.cpp
@@ -0,0 +1,102 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2022 Edouard Griffiths, F4EXB. //
+// //
+// Swagger server adapter interface //
+// //
+// This program is free software; you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation as version 3 of the License, or //
+// (at your option) any later version. //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#include "util/simpleserializer.h"
+#include "configuration.h"
+
+Configuration::Configuration()
+{
+ resetToDefaults();
+}
+
+Configuration::~Configuration()
+{ }
+
+void Configuration::resetToDefaults()
+{
+ m_group = "default";
+ m_description = "no name";
+ m_workspaceGeometries.clear();
+}
+
+QByteArray Configuration::serialize() const
+{
+ SimpleSerializer s(1);
+
+ s.writeString(1, m_group);
+ s.writeString(2, m_description);
+ QByteArray b = m_featureSetPreset.serialize();
+ s.writeBlob(3, b);
+
+ s.writeS32(100, m_workspaceGeometries.size());
+
+ for(int i = 0; i < m_workspaceGeometries.size(); i++) {
+ s.writeBlob(101 + i, m_workspaceGeometries[i]);
+ }
+
+ return s.final();
+}
+
+bool Configuration::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");
+
+ QByteArray b;
+ d.readBlob(3, &b);
+ m_featureSetPreset.deserialize(b);
+
+ int nbWorkspaces;
+ d.readS32(100, &nbWorkspaces, 0);
+
+ for(int i = 0; i < nbWorkspaces; i++)
+ {
+ m_workspaceGeometries.push_back(QByteArray());
+ d.readBlob(101 + i, &m_workspaceGeometries.back());
+ }
+
+ return true;
+ }
+ else
+ {
+ resetToDefaults();
+ return false;
+ }
+}
+
+int Configuration::getNumberOfWorkspaces() const
+{
+ return m_workspaceGeometries.size();
+}
+
+void Configuration::clearData()
+{
+ m_featureSetPreset.clearFeatures();
+ m_workspaceGeometries.clear();
+}
diff --git a/sdrbase/settings/configuration.h b/sdrbase/settings/configuration.h
new file mode 100644
index 000000000..cbdbc37ed
--- /dev/null
+++ b/sdrbase/settings/configuration.h
@@ -0,0 +1,78 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2022 Edouard Griffiths, F4EXB. //
+// //
+// Swagger server adapter interface //
+// //
+// This program is free software; you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation as version 3 of the License, or //
+// (at your option) any later version. //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDE_CONFIGURATION_H
+#define INCLUDE_CONFIGURATION_H
+
+#include
+#include
+#include
+#include
+
+#include "featuresetpreset.h"
+#include "export.h"
+
+class SDRBASE_API WorkspaceConfiguration {
+public:
+};
+
+class SDRBASE_API Configuration {
+public:
+ Configuration();
+ ~Configuration();
+ 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; }
+
+ int getNumberOfWorkspaces() const;
+ FeatureSetPreset& getFeatureSetPreset() { return m_featureSetPreset; }
+ const FeatureSetPreset& getFeatureSetPreset() const { return m_featureSetPreset; }
+ QList& getWorkspaceGeometries() { return m_workspaceGeometries; }
+ const QList& getWorkspaceGeometries() const { return m_workspaceGeometries; }
+ void clearData();
+
+ static bool configCompare(const Configuration *p1, Configuration *p2)
+ {
+ if (p1->m_group != p2->m_group)
+ {
+ return p1->m_group < p2->m_group;
+ }
+ else
+ {
+ return p1->m_description < p2->m_description;
+ }
+ }
+
+private:
+ QString m_group;
+ QString m_description;
+ QList m_workspaceGeometries;
+ FeatureSetPreset m_featureSetPreset;
+};
+
+Q_DECLARE_METATYPE(const Configuration*)
+Q_DECLARE_METATYPE(Configuration*)
+
+#endif // INCLUDE_CONFIGURATION_H
diff --git a/sdrbase/settings/mainsettings.cpp b/sdrbase/settings/mainsettings.cpp
index 51d6ad8d9..560b7ecd1 100644
--- a/sdrbase/settings/mainsettings.cpp
+++ b/sdrbase/settings/mainsettings.cpp
@@ -52,8 +52,9 @@ void MainSettings::load()
QSettings s;
m_preferences.deserialize(qUncompress(QByteArray::fromBase64(s.value("preferences").toByteArray())));
- m_workingPreset.deserialize(qUncompress(QByteArray::fromBase64(s.value("current").toByteArray())));
- m_workingFeatureSetPreset.deserialize(qUncompress(QByteArray::fromBase64(s.value("current-featureset").toByteArray())));
+ // m_workingPreset.deserialize(qUncompress(QByteArray::fromBase64(s.value("current").toByteArray())));
+ // m_workingFeatureSetPreset.deserialize(qUncompress(QByteArray::fromBase64(s.value("current-featureset").toByteArray())));
+ m_workingConfiguration.deserialize(qUncompress(QByteArray::fromBase64(s.value("current-configuration").toByteArray())));
if (m_audioDeviceManager) {
m_audioDeviceManager->deserialize(qUncompress(QByteArray::fromBase64(s.value("audio").toByteArray())));
@@ -113,6 +114,22 @@ void MainSettings::load()
delete featureSetPreset;
}
+ s.endGroup();
+ }
+ else if (groups[i].startsWith("configuration"))
+ {
+ s.beginGroup(groups[i]);
+ Configuration* configuration = new Configuration;
+
+ if (configuration->deserialize(qUncompress(QByteArray::fromBase64(s.value("data").toByteArray()))))
+ {
+ m_configurations.append(configuration);
+ }
+ else
+ {
+ delete configuration;
+ }
+
s.endGroup();
}
}
@@ -126,8 +143,9 @@ void MainSettings::save() const
QSettings s;
s.setValue("preferences", qCompress(m_preferences.serialize()).toBase64());
- s.setValue("current", qCompress(m_workingPreset.serialize()).toBase64());
- s.setValue("current-featureset", qCompress(m_workingFeatureSetPreset.serialize()).toBase64());
+ // s.setValue("current", qCompress(m_workingPreset.serialize()).toBase64());
+ // s.setValue("current-featureset", qCompress(m_workingFeatureSetPreset.serialize()).toBase64());
+ s.setValue("current-configuration", qCompress(m_workingConfiguration.serialize()).toBase64());
if (m_audioDeviceManager) {
s.setValue("audio", qCompress(m_audioDeviceManager->serialize()).toBase64());
@@ -171,6 +189,14 @@ void MainSettings::save() const
s.endGroup();
}
+ for (int i = 0; i < m_configurations.count(); ++i)
+ {
+ QString group = QString("configuration-%1").arg(i + 1);
+ s.beginGroup(group);
+ s.setValue("data", qCompress(m_configurations[i]->serialize()).toBase64());
+ s.endGroup();
+ }
+
s.setValue("hwDeviceUserArgs", qCompress(m_hardwareDeviceUserArgs.serialize()).toBase64());
s.setValue("limeRFEUSBCalib", qCompress(m_limeRFEUSBCalib.serialize()).toBase64());
}
@@ -181,6 +207,7 @@ void MainSettings::initialize()
clearCommands();
clearPresets();
clearFeatureSetPresets();
+ clearConfigurations();
}
void MainSettings::resetToDefaults()
@@ -188,6 +215,7 @@ void MainSettings::resetToDefaults()
m_preferences.resetToDefaults();
m_workingPreset.resetToDefaults();
m_workingFeatureSetPreset.resetToDefaults();
+ m_workingConfiguration.resetToDefaults();
}
// DeviceSet presets
@@ -395,7 +423,7 @@ void MainSettings::renameFeatureSetPresetGroup(const QString& oldGroupName, cons
for (int i = 0; i < nbPresets; i++)
{
- if (getPreset(i)->getGroup() == oldGroupName)
+ if (getFeatureSetPreset(i)->getGroup() == oldGroupName)
{
FeatureSetPreset *preset_mod = const_cast(getFeatureSetPreset(i));
preset_mod->setGroup(newGroupName);
@@ -427,3 +455,83 @@ void MainSettings::clearFeatureSetPresets()
m_featureSetPresets.clear();
}
+
+// Configurations
+
+Configuration* MainSettings::newConfiguration(const QString& group, const QString& description)
+{
+ Configuration* configuration = new Configuration();
+ configuration->setGroup(group);
+ configuration->setDescription(description);
+ m_configurations.append(configuration);
+ return configuration;
+}
+
+void MainSettings::addConfiguration(Configuration *configuration)
+{
+ m_configurations.append(configuration);
+}
+
+void MainSettings::deleteConfiguration(const Configuration *configuration)
+{
+ m_configurations.removeAll((Configuration*) configuration);
+ delete (Configuration*) configuration;
+}
+
+const Configuration* MainSettings::getConfiguration(const QString& groupName, const QString& description) const
+{
+ int nbConfigurations = getConfigurationCount();
+
+ for (int i = 0; i < nbConfigurations; i++)
+ {
+ if ((getConfiguration(i)->getGroup() == groupName) &&
+ (getConfiguration(i)->getDescription() == description))
+ {
+ return getConfiguration(i);
+ }
+ }
+
+ return nullptr;
+}
+
+void MainSettings::sortConfigurations()
+{
+ std::sort(m_configurations.begin(), m_configurations.end(), Configuration::configCompare);
+}
+
+void MainSettings::renameConfigurationGroup(const QString& oldGroupName, const QString& newGroupName)
+{
+ int nbConfigurations = getConfigurationCount();
+
+ for (int i = 0; i < nbConfigurations; i++)
+ {
+ if (getConfiguration(i)->getGroup() == oldGroupName)
+ {
+ Configuration *configuration_mod = const_cast(getConfiguration(i));
+ configuration_mod->setGroup(newGroupName);
+ }
+ }
+}
+
+void MainSettings::deleteConfigurationGroup(const QString& groupName)
+{
+ Configurations::iterator it = m_configurations.begin();
+
+ while (it != m_configurations.end())
+ {
+ if ((*it)->getGroup() == groupName) {
+ it = m_configurations.erase(it);
+ } else {
+ ++it;
+ }
+ }
+}
+
+void MainSettings::clearConfigurations()
+{
+ foreach (Configuration *configuration, m_configurations) {
+ delete configuration;
+ }
+
+ m_configurations.clear();
+}
diff --git a/sdrbase/settings/mainsettings.h b/sdrbase/settings/mainsettings.h
index aa67fbe6a..cf9a7fa85 100644
--- a/sdrbase/settings/mainsettings.h
+++ b/sdrbase/settings/mainsettings.h
@@ -8,6 +8,7 @@
#include "preferences.h"
#include "preset.h"
#include "featuresetpreset.h"
+#include "configuration.h"
#include "export.h"
#include "plugin/pluginmanager.h"
@@ -70,6 +71,20 @@ public:
FeatureSetPreset* getWorkingFeatureSetPreset() { return &m_workingFeatureSetPreset; }
QList *getFeatureSetPresets() { return &m_featureSetPresets; }
+ Configuration* newConfiguration(const QString& group, const QString& description);
+ void addConfiguration(Configuration *configuration);
+ void deleteConfiguration(const Configuration *configuration);
+ int getConfigurationCount() const { return m_configurations.size(); }
+ const Configuration* getConfiguration(int index) const { return m_configurations[index]; }
+ const Configuration* getConfiguration(const QString& groupName, const QString& description) const;
+ void sortConfigurations();
+ void renameConfigurationGroup(const QString& oldGroupName, const QString& newGroupName);
+ void deleteConfigurationGroup(const QString& groupName);
+ void clearConfigurations();
+ const Configuration& getWorkingConfigurationConst() const { return m_workingConfiguration; }
+ Configuration* getWorkingConfiguration() { return &m_workingConfiguration; }
+ QList *getConfigurations() { return &m_configurations; }
+
const QString& getSourceDevice() const { return m_preferences.getSourceDevice(); }
void setSourceDevice(const QString& value)
{
@@ -174,13 +189,16 @@ protected:
Preferences m_preferences;
AudioDeviceManager *m_audioDeviceManager;
Preset m_workingPreset;
- FeatureSetPreset m_workingFeatureSetPreset;
typedef QList Presets;
Presets m_presets;
typedef QList Commands;
Commands m_commands;
+ FeatureSetPreset m_workingFeatureSetPreset;
typedef QList FeatureSetPresets;
FeatureSetPresets m_featureSetPresets;
+ Configuration m_workingConfiguration;
+ typedef QList Configurations;
+ Configurations m_configurations;
DeviceUserArgs m_hardwareDeviceUserArgs;
LimeRFEUSBCalib m_limeRFEUSBCalib;
AMBEEngine *m_ambeEngine;
diff --git a/sdrgui/CMakeLists.txt b/sdrgui/CMakeLists.txt
index 3a58139d0..4ed80997d 100644
--- a/sdrgui/CMakeLists.txt
+++ b/sdrgui/CMakeLists.txt
@@ -23,6 +23,7 @@ set(sdrgui_SOURCES
gui/commanditem.cpp
gui/commandsdialog.cpp
gui/commandoutputdialog.cpp
+ gui/configurationsdialog.cpp
gui/crightclickenabler.cpp
gui/customtextedit.cpp
gui/cwkeyergui.cpp
@@ -120,6 +121,7 @@ set(sdrgui_HEADERS
gui/commanditem.h
gui/commandsdialog.h
gui/commandoutputdialog.h
+ gui/configurationsdialog.h
gui/crightclickenabler.h
gui/customtextedit.h
gui/cwkeyergui.h
@@ -212,6 +214,7 @@ set(sdrgui_FORMS
gui/channeladddialog.ui
gui/commandsdialog.ui
gui/commandoutputdialog.ui
+ gui/configurationsdialog.ui
gui/cwkeyergui.ui
gui/devicestreamselectiondialog.ui
gui/deviceuserargsdialog.ui
diff --git a/sdrgui/feature/featuregui.cpp b/sdrgui/feature/featuregui.cpp
index 18128e2c1..05e5f8d02 100644
--- a/sdrgui/feature/featuregui.cpp
+++ b/sdrgui/feature/featuregui.cpp
@@ -33,7 +33,6 @@
FeatureGUI::FeatureGUI(QWidget *parent) :
QMdiSubWindow(parent),
m_featureIndex(0),
- m_workspaceIndex(0),
m_contextMenuType(ContextMenuNone),
m_drag(false)
{
@@ -81,7 +80,7 @@ FeatureGUI::FeatureGUI(QWidget *parent) :
m_closeButton->setToolTip("Close feature");
m_statusLabel = new QLabel();
- m_statusLabel->setText("OK"); // for future use
+ // m_statusLabel->setText("OK"); // for future use
m_statusLabel->setFixedHeight(20);
m_statusLabel->setToolTip("Feature status");
@@ -111,6 +110,7 @@ FeatureGUI::FeatureGUI(QWidget *parent) :
m_bottomLayout->addWidget(m_statusLabel);
m_sizeGripBottomRight = new QSizeGrip(this);
m_sizeGripBottomRight->setStyleSheet("QSizeGrip { background-color: rgb(128, 128, 128); width: 10px; height: 10px; }");
+ m_bottomLayout->addStretch(1);
m_bottomLayout->addWidget(m_sizeGripBottomRight, 0, Qt::AlignBottom | Qt::AlignRight);
m_layouts->addLayout(m_topLayout);
diff --git a/sdrgui/feature/featuregui.h b/sdrgui/feature/featuregui.h
index c51691acb..ce185df40 100644
--- a/sdrgui/feature/featuregui.h
+++ b/sdrgui/feature/featuregui.h
@@ -49,6 +49,11 @@ public:
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;
+ virtual void setGeometryBytes(const QByteArray& blob) = 0;
+ virtual QByteArray getGeometryBytes() const = 0;
virtual MessageQueue* getInputMessageQueue() = 0;
@@ -56,8 +61,7 @@ public:
void setTitleColor(const QColor&) {} // not implemented for a feature
void setTitle(const QString& title);
void setIndex(int index);
- void setWorkspaceIndex(int index) { m_workspaceIndex = index; }
- int getWorkspaceIndex() const { return m_workspaceIndex; }
+ int getIndex() const { return m_featureIndex; }
protected:
void closeEvent(QCloseEvent *event);
@@ -66,7 +70,6 @@ protected:
void resetContextMenuType() { m_contextMenuType = ContextMenuNone; }
int m_featureIndex;
- int m_workspaceIndex;
QString m_helpURL;
RollupContents m_rollupContents;
ContextMenuType m_contextMenuType;
diff --git a/sdrgui/feature/featureuiset.cpp b/sdrgui/feature/featureuiset.cpp
index 621d811c1..e09d2d0fb 100644
--- a/sdrgui/feature/featureuiset.cpp
+++ b/sdrgui/feature/featureuiset.cpp
@@ -112,6 +112,24 @@ Feature *FeatureUISet::getFeatureAt(int featureIndex)
}
}
+const FeatureGUI *FeatureUISet::getFeatureGuiAt(int featureIndex) const
+{
+ if ((featureIndex >= 0) && (featureIndex < m_featureInstanceRegistrations.count())) {
+ return m_featureInstanceRegistrations.at(featureIndex).m_gui;
+ } else{
+ return nullptr;
+ }
+}
+
+FeatureGUI *FeatureUISet::getFeatureGuiAt(int featureIndex)
+{
+ if ((featureIndex >= 0) && (featureIndex < m_featureInstanceRegistrations.count())) {
+ return m_featureInstanceRegistrations.at(featureIndex).m_gui;
+ } else{
+ return nullptr;
+ }
+}
+
void FeatureUISet::loadFeatureSetSettings(
const FeatureSetPreset *preset,
PluginAPI *pluginAPI,
@@ -147,6 +165,7 @@ void FeatureUISet::loadFeatureSetSettings(
{
const FeatureSetPreset::FeatureConfig& featureConfig = preset->getFeatureConfig(i);
FeatureGUI *featureGUI = nullptr;
+ Feature *feature = nullptr;
// create feature instance
@@ -158,14 +177,9 @@ void FeatureUISet::loadFeatureSetSettings(
qPrintable((*featureRegistrations)[i].m_featureIdURI),
qPrintable(featureConfig.m_featureIdURI)
);
- Feature *feature =
- (*featureRegistrations)[i].m_plugin->createFeature(apiAdapter);
- featureGUI =
- (*featureRegistrations)[i].m_plugin->createFeatureGUI(this, feature);
+ feature = (*featureRegistrations)[i].m_plugin->createFeature(apiAdapter);
+ featureGUI = (*featureRegistrations)[i].m_plugin->createFeatureGUI(this, feature);
registerFeatureInstance(featureGUI, feature);
- featureGUI->setIndex(feature->getIndexInFeatureSet());
- featureGUI->setWorkspaceIndex(workspace->getIndex());
- workspace->addToMdiArea((QMdiSubWindow*) featureGUI);
break;
}
}
@@ -173,9 +187,63 @@ void FeatureUISet::loadFeatureSetSettings(
if (featureGUI)
{
qDebug("FeatureUISet::loadFeatureSetSettings: deserializing feature [%s]",
- qPrintable(featureConfig.m_featureIdURI)
- );
+ qPrintable(featureConfig.m_featureIdURI));
featureGUI->deserialize(featureConfig.m_config);
+
+ if (workspace) // restore in current workspace
+ {
+ featureGUI->setIndex(feature->getIndexInFeatureSet());
+ featureGUI->setWorkspaceIndex(workspace->getIndex());
+ workspace->addToMdiArea((QMdiSubWindow*) featureGUI);
+ }
+ }
+ }
+}
+
+void FeatureUISet::loadFeatureSetSettings(
+ const FeatureSetPreset* preset,
+ PluginAPI *pluginAPI,
+ WebAPIAdapterInterface *apiAdapter,
+ QList& workspaces
+)
+{
+ // This method loads from scratch - load from configuration
+ qDebug("FeatureUISet::loadFeatureSetSettings: %d feature(s) in preset", preset->getFeatureCount());
+
+ // Available feature plugins
+ PluginAPI::FeatureRegistrations *featureRegistrations = pluginAPI->getFeatureRegistrations();
+
+ for (int i = 0; i < preset->getFeatureCount(); i++)
+ {
+ const FeatureSetPreset::FeatureConfig& featureConfig = preset->getFeatureConfig(i);
+ FeatureGUI *featureGUI = nullptr;
+ Feature *feature = nullptr;
+
+ // create feature instance
+
+ for(int i = 0; i < featureRegistrations->count(); i++)
+ {
+ if (FeatureUtils::compareFeatureURIs((*featureRegistrations)[i].m_featureIdURI, featureConfig.m_featureIdURI))
+ {
+ qDebug("FeatureUISet::loadFeatureSetSettings: creating new feature [%s] from config [%s]",
+ qPrintable((*featureRegistrations)[i].m_featureIdURI),
+ qPrintable(featureConfig.m_featureIdURI)
+ );
+ feature = (*featureRegistrations)[i].m_plugin->createFeature(apiAdapter);
+ featureGUI = (*featureRegistrations)[i].m_plugin->createFeatureGUI(this, feature);
+ registerFeatureInstance(featureGUI, feature);
+ break;
+ }
+ }
+
+ if (featureGUI)
+ {
+ qDebug("FeatureUISet::loadFeatureSetSettings: deserializing feature [%s]",
+ qPrintable(featureConfig.m_featureIdURI));
+ featureGUI->deserialize(featureConfig.m_config);
+ featureGUI->setIndex(feature->getIndexInFeatureSet());
+ workspaces[featureGUI->getWorkspaceIndex()]->addToMdiArea((QMdiSubWindow*) featureGUI);
+ featureGUI->restoreGeometry(featureGUI->getGeometryBytes());
}
}
}
@@ -187,6 +255,8 @@ void FeatureUISet::saveFeatureSetSettings(FeatureSetPreset *preset)
qDebug("FeatureUISet::saveFeatureSetSettings: saving feature [%s]",
qPrintable(m_featureInstanceRegistrations.at(i).m_feature->getURI())
);
+ FeatureGUI *featureGUI = m_featureInstanceRegistrations.at(i).m_gui;
+ featureGUI->setGeometryBytes(featureGUI->saveGeometry());
preset->addFeature(
m_featureInstanceRegistrations.at(i).m_feature->getURI(),
m_featureInstanceRegistrations.at(i).m_gui->serialize()
diff --git a/sdrgui/feature/featureuiset.h b/sdrgui/feature/featureuiset.h
index b82ff1e82..372a3cb3e 100644
--- a/sdrgui/feature/featureuiset.h
+++ b/sdrgui/feature/featureuiset.h
@@ -46,13 +46,22 @@ public:
void deleteFeature(int featureIndex);
const Feature *getFeatureAt(int featureIndex) const;
Feature *getFeatureAt(int featureIndex);
+ const FeatureGUI *getFeatureGuiAt(int featureIndex) const;
+ FeatureGUI *getFeatureGuiAt(int featureIndex);
void loadFeatureSetSettings(
const FeatureSetPreset* preset,
PluginAPI *pluginAPI,
WebAPIAdapterInterface *apiAdapter,
Workspace *workspace
);
+ void loadFeatureSetSettings(
+ const FeatureSetPreset* preset,
+ PluginAPI *pluginAPI,
+ WebAPIAdapterInterface *apiAdapter,
+ QList& workspaces
+ );
void saveFeatureSetSettings(FeatureSetPreset* preset);
+ void freeFeatures();
private:
struct FeatureInstanceRegistration
@@ -79,7 +88,6 @@ private:
int m_featureTabIndex;
FeatureSet *m_featureSet;
- void freeFeatures();
private slots:
void handleClosingFeatureGUI(FeatureGUI *featureGUI);
diff --git a/sdrgui/gui/commandsdialog.cpp b/sdrgui/gui/commandsdialog.cpp
index 6efab2cb5..faae90c80 100644
--- a/sdrgui/gui/commandsdialog.cpp
+++ b/sdrgui/gui/commandsdialog.cpp
@@ -50,10 +50,9 @@ void CommandsDialog::populateTree()
{
MainCore::instance()->m_settings.sortCommands();
ui->commandTree->clear();
- QTreeWidgetItem *treeItem;
for (int i = 0; i < MainCore::instance()->m_settings.getCommandCount(); ++i) {
- treeItem = addCommandToTree(MainCore::instance()->m_settings.getCommand(i));
+ addCommandToTree(MainCore::instance()->m_settings.getCommand(i));
}
}
@@ -222,11 +221,6 @@ void CommandsDialog::on_commandOutput_clicked()
}
}
-void CommandsDialog::on_commandsSave_clicked()
-{
- MainCore::instance()->m_settings.save();
-}
-
void CommandsDialog::on_commandDelete_clicked()
{
QTreeWidgetItem* item = ui->commandTree->currentItem();
diff --git a/sdrgui/gui/commandsdialog.h b/sdrgui/gui/commandsdialog.h
index 508bf97e4..30655b701 100644
--- a/sdrgui/gui/commandsdialog.h
+++ b/sdrgui/gui/commandsdialog.h
@@ -60,7 +60,6 @@ private slots:
void on_commandEdit_clicked();
void on_commandRun_clicked();
void on_commandOutput_clicked();
- void on_commandsSave_clicked();
void on_commandDelete_clicked();
void on_commandKeyboardConnect_toggled(bool checked);
};
diff --git a/sdrgui/gui/commandsdialog.ui b/sdrgui/gui/commandsdialog.ui
index 10e606ee3..91dc4183f 100644
--- a/sdrgui/gui/commandsdialog.ui
+++ b/sdrgui/gui/commandsdialog.ui
@@ -123,20 +123,6 @@
- -
-
-
- Save commands in settings
-
-
-
-
-
-
- :/save.png:/save.png
-
-
-
-
@@ -179,6 +165,9 @@
-
+
+ false
+
Toggle keyboard to command connection
diff --git a/sdrgui/gui/configurationsdialog.cpp b/sdrgui/gui/configurationsdialog.cpp
new file mode 100644
index 000000000..eb9266ded
--- /dev/null
+++ b/sdrgui/gui/configurationsdialog.cpp
@@ -0,0 +1,403 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2022 F4EXB //
+// written by Edouard Griffiths //
+// //
+// This program is free software; you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation as version 3 of the License, or //
+// (at your option) any later version. //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#include
+#include
+
+#include "gui/addpresetdialog.h"
+#include "configurationsdialog.h"
+#include "ui_configurationsdialog.h"
+
+#include "settings/configuration.h"
+
+ConfigurationsDialog::ConfigurationsDialog(QWidget* parent) :
+ QDialog(parent),
+ ui(new Ui::ConfigurationsDialog)
+{
+ ui->setupUi(this);
+}
+
+ConfigurationsDialog::~ConfigurationsDialog()
+{
+ delete ui;
+}
+
+void ConfigurationsDialog::populateTree()
+{
+ if (!m_configurations) {
+ return;
+ }
+
+ QList::const_iterator it = m_configurations->begin();
+ int middleIndex = m_configurations->size() / 2;
+ QTreeWidgetItem *treeItem;
+ ui->configurationsTree->clear();
+
+ for (int i = 0; it != m_configurations->end(); ++it, i++)
+ {
+ treeItem = addConfigurationToTree(*it);
+
+ if (i == middleIndex) {
+ ui->configurationsTree->setCurrentItem(treeItem);
+ }
+ }
+
+ updateConfigurationControls();
+}
+
+QTreeWidgetItem* ConfigurationsDialog::addConfigurationToTree(const Configuration* configuration)
+{
+ QTreeWidgetItem* group = nullptr;
+
+ for (int i = 0; i < ui->configurationsTree->topLevelItemCount(); i++)
+ {
+ if (ui->configurationsTree->topLevelItem(i)->text(0) == configuration->getGroup())
+ {
+ group = ui->configurationsTree->topLevelItem(i);
+ break;
+ }
+ }
+
+ if (!group)
+ {
+ QStringList sl;
+ sl.append(configuration->getGroup());
+ group = new QTreeWidgetItem(ui->configurationsTree, sl, PGroup);
+ group->setFirstColumnSpanned(true);
+ group->setExpanded(true);
+ ui->configurationsTree->sortByColumn(0, Qt::AscendingOrder);
+ }
+
+ QStringList sl;
+ sl.append(configuration->getDescription());
+ QTreeWidgetItem* item = new QTreeWidgetItem(group, sl, PItem); // description column
+ item->setTextAlignment(0, Qt::AlignLeft);
+ item->setData(0, Qt::UserRole, QVariant::fromValue(configuration));
+
+ updateConfigurationControls();
+ return item;
+}
+
+void ConfigurationsDialog::updateConfigurationControls()
+{
+ ui->configurationsTree->resizeColumnToContents(0);
+
+ if (ui->configurationsTree->currentItem())
+ {
+ ui->configurationDelete->setEnabled(true);
+ ui->configurationLoad->setEnabled(true);
+ }
+ else
+ {
+ ui->configurationDelete->setEnabled(false);
+ ui->configurationLoad->setEnabled(false);
+ }
+}
+
+void ConfigurationsDialog::on_configurationSave_clicked()
+{
+ QStringList groups;
+ QString group;
+ QString description = "";
+
+ for (int i = 0; i < ui->configurationsTree->topLevelItemCount(); i++) {
+ groups.append(ui->configurationsTree->topLevelItem(i)->text(0));
+ }
+
+ QTreeWidgetItem* item = ui->configurationsTree->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)
+ {
+ Configuration* configuration = newConfiguration(dlg.group(), dlg.description());
+ emit saveConfiguration(configuration);
+ ui->configurationsTree->setCurrentItem(addConfigurationToTree(configuration));
+ }
+
+ sortConfigurations();
+}
+
+void ConfigurationsDialog::on_configurationUpdate_clicked()
+{
+ QTreeWidgetItem* item = ui->configurationsTree->currentItem();
+ const Configuration* changedConfiguration = nullptr;
+
+ if (item)
+ {
+ if( item->type() == PItem)
+ {
+ const Configuration* configuration = qvariant_cast(item->data(0, Qt::UserRole));
+
+ if (configuration)
+ {
+ Configuration* configuration_mod = const_cast(configuration);
+ emit saveConfiguration(configuration_mod);
+ changedConfiguration = configuration;
+ }
+ }
+ }
+
+ sortConfigurations();
+ ui->configurationsTree->clear();
+
+ for (int i = 0; i < m_configurations->size(); ++i)
+ {
+ QTreeWidgetItem *item_x = addConfigurationToTree(m_configurations->at(i));
+ const Configuration* configuration_x = qvariant_cast(item_x->data(0, Qt::UserRole));
+
+ if (changedConfiguration && (configuration_x == changedConfiguration)) { // set cursor on changed configuration
+ ui->configurationsTree->setCurrentItem(item_x);
+ }
+ }
+}
+
+void ConfigurationsDialog::on_configurationEdit_clicked()
+{
+ QTreeWidgetItem* item = ui->configurationsTree->currentItem();
+ QStringList groups;
+ bool change = false;
+ const Configuration *changedConfiguration = nullptr;
+ QString newGroupName;
+
+ for (int i = 0; i < ui->configurationsTree->topLevelItemCount(); i++) {
+ groups.append(ui->configurationsTree->topLevelItem(i)->text(0));
+ }
+
+ if (item)
+ {
+ if (item->type() == PItem)
+ {
+ const Configuration* configuration = qvariant_cast(item->data(0, Qt::UserRole));
+ AddPresetDialog dlg(groups, configuration->getGroup(), this);
+ dlg.setDescription(configuration->getDescription());
+
+ if (dlg.exec() == QDialog::Accepted)
+ {
+ Configuration* configuration_mod = const_cast(configuration);
+ configuration_mod->setGroup(dlg.group());
+ configuration_mod->setDescription(dlg.description());
+ change = true;
+ changedConfiguration = configuration;
+ }
+ }
+ else if (item->type() == PGroup)
+ {
+ AddPresetDialog dlg(groups, item->text(0), this);
+ dlg.showGroupOnly();
+ dlg.setDialogTitle("Edit configuration group");
+
+ if (dlg.exec() == QDialog::Accepted)
+ {
+ renameConfigurationGroup(item->text(0), dlg.group());
+ newGroupName = dlg.group();
+ change = true;
+ }
+ }
+ }
+
+ if (change)
+ {
+ sortConfigurations();
+ ui->configurationsTree->clear();
+
+ for (int i = 0; i < m_configurations->size(); ++i)
+ {
+ QTreeWidgetItem *item_x = addConfigurationToTree(m_configurations->at(i));
+ const Configuration* configuration_x = qvariant_cast(item_x->data(0, Qt::UserRole));
+
+ if (changedConfiguration && (configuration_x == changedConfiguration)) { // set cursor on changed configuration
+ ui->configurationsTree->setCurrentItem(item_x);
+ }
+ }
+
+ if (!changedConfiguration) // on group name change set cursor on the group that has been changed
+ {
+ for(int i = 0; i < ui->configurationsTree->topLevelItemCount(); i++)
+ {
+ QTreeWidgetItem* item = ui->configurationsTree->topLevelItem(i);
+
+ if (item->text(0) == newGroupName) {
+ ui->configurationsTree->setCurrentItem(item);
+ }
+ }
+ }
+ }
+}
+
+void ConfigurationsDialog::on_configurationDelete_clicked()
+{
+ QTreeWidgetItem* item = ui->configurationsTree->currentItem();
+
+ if (item == 0)
+ {
+ updateConfigurationControls();
+ return;
+ }
+ else
+ {
+ if (item->type() == PItem)
+ {
+ const Configuration* configuration = qvariant_cast(item->data(0, Qt::UserRole));
+
+ if (configuration)
+ {
+ if (
+ QMessageBox::question(
+ this,
+ tr("Delete Configuration"),
+ tr("Do you want to delete configuration '%1'?").arg(configuration->getDescription()),
+ QMessageBox::No | QMessageBox::Yes,
+ QMessageBox::No
+ ) == QMessageBox::Yes
+ )
+ {
+ delete item;
+ deleteConfiguration(configuration);
+ }
+ }
+ }
+ else if (item->type() == PGroup)
+ {
+ if (
+ QMessageBox::question(
+ this,
+ tr("Delete configuration group"),
+ tr("Do you want to delete configuration group '%1'?").arg(item->text(0)),
+ QMessageBox::No | QMessageBox::Yes,
+ QMessageBox::No
+ ) == QMessageBox::Yes
+ )
+ {
+ deleteConfigurationGroup(item->text(0));
+
+ ui->configurationsTree->clear();
+
+ for (int i = 0; i < m_configurations->size(); ++i) {
+ addConfigurationToTree(m_configurations->at(i));
+ }
+ }
+ }
+ }
+}
+
+void ConfigurationsDialog::on_configurationLoad_clicked()
+{
+ qDebug() << "ConfigurationsDialog::on_configurationLoad_clicked";
+
+ QTreeWidgetItem* item = ui->configurationsTree->currentItem();
+
+ if (!item)
+ {
+ qDebug("ConfigurationsDialog::on_configurationLoad_clicked: item null");
+ updateConfigurationControls();
+ return;
+ }
+
+ const Configuration* configuration = qvariant_cast(item->data(0, Qt::UserRole));
+
+ if (!configuration)
+ {
+ qDebug("ConfigurationsDialog::on_configurationLoad_clicked: configuration null");
+ return;
+ }
+
+ emit loadConfiguration(configuration);
+}
+
+void ConfigurationsDialog::on_configurationTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
+{
+ (void) current;
+ (void) previous;
+ updateConfigurationControls();
+}
+
+void ConfigurationsDialog::on_configurationTree_itemActivated(QTreeWidgetItem *item, int column)
+{
+ (void) item;
+ (void) column;
+ on_configurationLoad_clicked();
+}
+
+Configuration* ConfigurationsDialog::newConfiguration(const QString& group, const QString& description)
+{
+ Configuration* configuration = new Configuration();
+ configuration->setGroup(group);
+ configuration->setDescription(description);
+ addConfiguration(configuration);
+ return configuration;
+}
+
+void ConfigurationsDialog::addConfiguration(Configuration *configuration)
+{
+ m_configurations->append(configuration);
+}
+
+void ConfigurationsDialog::sortConfigurations()
+{
+ std::sort(m_configurations->begin(), m_configurations->end(), Configuration::configCompare);
+}
+
+void ConfigurationsDialog::renameConfigurationGroup(const QString& oldGroupName, const QString& newGroupName)
+{
+ for (int i = 0; i < m_configurations->size(); i++)
+ {
+ if (m_configurations->at(i)->getGroup() == oldGroupName)
+ {
+ Configuration *configuration_mod = const_cast(m_configurations->at(i));
+ configuration_mod->setGroup(newGroupName);
+ }
+ }
+}
+
+void ConfigurationsDialog::deleteConfiguration(const Configuration* configuration)
+{
+ m_configurations->removeAll((Configuration*) configuration);
+ delete (Configuration*) configuration;
+}
+
+void ConfigurationsDialog::deleteConfigurationGroup(const QString& groupName)
+{
+ QList::iterator it = m_configurations->begin();
+
+ while (it != m_configurations->end())
+ {
+ if ((*it)->getGroup() == groupName) {
+ it = m_configurations->erase(it);
+ } else {
+ ++it;
+ }
+ }
+}
diff --git a/sdrgui/gui/configurationsdialog.h b/sdrgui/gui/configurationsdialog.h
new file mode 100644
index 000000000..12489e533
--- /dev/null
+++ b/sdrgui/gui/configurationsdialog.h
@@ -0,0 +1,78 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2022 F4EXB //
+// written by Edouard Griffiths //
+// //
+// This program is free software; you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation as version 3 of the License, or //
+// (at your option) any later version. //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef SDRGUI_GUI_CONFIGURATIONSDIALOG_H_
+#define SDRGUI_GUI_CONFIGURATIONSDIALOG_H_
+
+#include
+#include
+#include
+
+#include "export.h"
+
+class Configuration;
+class FeatureUISet;
+class WebAPIAdapterInterface;
+class PluginAPI;
+class Workspace;
+
+namespace Ui {
+ class ConfigurationsDialog;
+}
+
+class SDRGUI_API ConfigurationsDialog : public QDialog {
+ Q_OBJECT
+public:
+ explicit ConfigurationsDialog(QWidget* parent = nullptr);
+ ~ConfigurationsDialog();
+ void setConfigurations(QList* configurations) { m_configurations = configurations; }
+ void populateTree();
+
+private:
+ enum {
+ PGroup,
+ PItem
+ };
+
+ Ui::ConfigurationsDialog* ui;
+ QList *m_configurations;
+
+ QTreeWidgetItem* addConfigurationToTree(const Configuration* configuration);
+ void updateConfigurationControls();
+ Configuration* newConfiguration(const QString& group, const QString& description);
+ void addConfiguration(Configuration *configuration);
+ void sortConfigurations();
+ void renameConfigurationGroup(const QString& oldGroupName, const QString& newGroupName);
+ void deleteConfiguration(const Configuration* configuration);
+ void deleteConfigurationGroup(const QString& groupName);
+
+private slots:
+ void on_configurationSave_clicked();
+ void on_configurationUpdate_clicked();
+ void on_configurationEdit_clicked();
+ void on_configurationDelete_clicked();
+ void on_configurationLoad_clicked();
+ void on_configurationTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
+ void on_configurationTree_itemActivated(QTreeWidgetItem *item, int column);
+
+signals:
+ void saveConfiguration(Configuration*);
+ void loadConfiguration(const Configuration*);
+};
+
+#endif // SDRGUI_GUI_CONFIGURATIONSDIALOG_H_
diff --git a/sdrgui/gui/configurationsdialog.ui b/sdrgui/gui/configurationsdialog.ui
new file mode 100644
index 000000000..d7938bdcc
--- /dev/null
+++ b/sdrgui/gui/configurationsdialog.ui
@@ -0,0 +1,244 @@
+
+
+ ConfigurationsDialog
+
+
+
+ 0
+ 0
+ 392
+ 414
+
+
+
+
+ Liberation Sans
+ 9
+
+
+
+ Configurations
+
+
+
+
+ 40
+ 380
+ 341
+ 32
+
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Close
+
+
+
+
+
+ 0
+ 10
+ 392
+ 310
+
+
+
+
-
+
+
+ List of configurations
+
+
+ 5
+
+
+ true
+
+
+ 1
+
+
+ 5
+
+
+
+ Description
+
+
+
+
+
+
+
+
+
+ 0
+ 330
+ 392
+ 34
+
+
+
+ -
+
+
+ Save current workspaces configuration as new configuration
+
+
+ ...
+
+
+
+ :/create.png:/create.png
+
+
+
+ 16
+ 16
+
+
+
+
+ -
+
+
+ Update selected configuration with current workspaces configuration
+
+
+ ...
+
+
+
+ :/recycle.png:/recycle.png
+
+
+
+ 16
+ 16
+
+
+
+
+ -
+
+
+ Edit configuration details
+
+
+
+
+
+
+ :/edit.png:/edit.png
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Delete selected configuration
+
+
+ ...
+
+
+
+ :/bin.png:/bin.png
+
+
+
+ 16
+ 16
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Load selected configuration
+
+
+ ...
+
+
+
+ :/load.png:/load.png
+
+
+
+ 16
+ 16
+
+
+
+
+
+
+
+
+
+
+
+
+ buttonBox
+ accepted()
+ ConfigurationsDialog
+ accept()
+
+
+ 248
+ 254
+
+
+ 157
+ 274
+
+
+
+
+ buttonBox
+ rejected()
+ ConfigurationsDialog
+ reject()
+
+
+ 316
+ 260
+
+
+ 286
+ 274
+
+
+
+
+
diff --git a/sdrgui/gui/featurepresetsdialog.cpp b/sdrgui/gui/featurepresetsdialog.cpp
index 9d842ac07..6458a43e1 100644
--- a/sdrgui/gui/featurepresetsdialog.cpp
+++ b/sdrgui/gui/featurepresetsdialog.cpp
@@ -21,8 +21,10 @@
#include "gui/addpresetdialog.h"
#include "feature/featureuiset.h"
-#include "featurepresetsdialog.h"
#include "settings/featuresetpreset.h"
+#include "maincore.h"
+
+#include "featurepresetsdialog.h"
#include "ui_featurepresetsdialog.h"
FeaturePresetsDialog::FeaturePresetsDialog(QWidget* parent) :
@@ -31,7 +33,8 @@ FeaturePresetsDialog::FeaturePresetsDialog(QWidget* parent) :
m_featureSetPresets(nullptr),
m_featureUISet(nullptr),
m_pluginAPI(nullptr),
- m_apiAdapter(nullptr)
+ m_apiAdapter(nullptr),
+ m_presetLoaded(false)
{
ui->setupUi(this);
}
@@ -188,10 +191,6 @@ void FeaturePresetsDialog::on_presetUpdate_clicked()
}
}
-void FeaturePresetsDialog::on_settingsSave_clicked()
-{
-}
-
void FeaturePresetsDialog::on_presetEdit_clicked()
{
QTreeWidgetItem* item = ui->presetsTree->currentItem();
@@ -376,6 +375,7 @@ void FeaturePresetsDialog::loadPresetSettings(const FeatureSetPreset* preset)
qPrintable(preset->getDescription()));
m_featureUISet->loadFeatureSetSettings(preset, m_pluginAPI, m_apiAdapter, m_workspace);
+ m_presetLoaded = true;
}
void FeaturePresetsDialog::sortFeatureSetPresets()
diff --git a/sdrgui/gui/featurepresetsdialog.h b/sdrgui/gui/featurepresetsdialog.h
index 7785be0f2..1addbf404 100644
--- a/sdrgui/gui/featurepresetsdialog.h
+++ b/sdrgui/gui/featurepresetsdialog.h
@@ -46,6 +46,7 @@ public:
void setWebAPIAdapter(WebAPIAdapterInterface *apiAdapter) { m_apiAdapter = apiAdapter; }
void setWorkspace(Workspace *workspace) { m_workspace = workspace; }
void populateTree();
+ bool wasPresetLoaded() const { return m_presetLoaded; }
private:
enum {
@@ -59,6 +60,7 @@ private:
PluginAPI *m_pluginAPI;
WebAPIAdapterInterface *m_apiAdapter;
Workspace *m_workspace;
+ bool m_presetLoaded;
QTreeWidgetItem* addPresetToTree(const FeatureSetPreset* preset);
void updatePresetControls();
@@ -74,7 +76,6 @@ private:
private slots:
void on_presetSave_clicked();
void on_presetUpdate_clicked();
- void on_settingsSave_clicked();
void on_presetEdit_clicked();
void on_presetDelete_clicked();
void on_presetLoad_clicked();
diff --git a/sdrgui/gui/featurepresetsdialog.ui b/sdrgui/gui/featurepresetsdialog.ui
index 55de482eb..1ee9c22f2 100644
--- a/sdrgui/gui/featurepresetsdialog.ui
+++ b/sdrgui/gui/featurepresetsdialog.ui
@@ -118,26 +118,6 @@
- -
-
-
- Save the current settings (inc. presets)
-
-
- ...
-
-
-
- :/save.png:/save.png
-
-
-
- 16
- 16
-
-
-
-
-
diff --git a/sdrgui/gui/workspace.cpp b/sdrgui/gui/workspace.cpp
index 3509a6810..fc7eed526 100644
--- a/sdrgui/gui/workspace.cpp
+++ b/sdrgui/gui/workspace.cpp
@@ -37,6 +37,7 @@ Workspace::Workspace(int index, QWidget *parent, Qt::WindowFlags flags) :
setWidget(m_mdi);
setWindowTitle(tr("W%1").arg(m_index));
+ setObjectName(tr("W%1").arg(m_index));
m_titleBar = new QWidget();
m_titleBarLayout = new QHBoxLayout();
@@ -105,7 +106,7 @@ Workspace::Workspace(int index, QWidget *parent, Qt::WindowFlags flags) :
m_normalButton->setFixedSize(20, 20);
m_closeButton = new QPushButton();
- QIcon closeIcon(":/cross.png");
+ QIcon closeIcon(":/hide.png");
m_closeButton->setIcon(closeIcon);
m_closeButton->setToolTip("Hide workspace");
m_closeButton->setFixedSize(20, 20);
@@ -269,3 +270,18 @@ void Workspace::removeFromMdiArea(QMdiSubWindow *sub)
{
m_mdi->removeSubWindow(sub);
}
+
+int Workspace::getNumberOfSubWindows() const
+{
+ return m_mdi->subWindowList().size();
+}
+
+QByteArray Workspace::saveMdiGeometry()
+{
+ return qCompress(m_mdi->saveGeometry());
+}
+
+void Workspace::restoreMdiGeometry(const QByteArray& blob)
+{
+ m_mdi->restoreGeometry(qUncompress(blob));
+}
diff --git a/sdrgui/gui/workspace.h b/sdrgui/gui/workspace.h
index 56b307fad..3944ddfad 100644
--- a/sdrgui/gui/workspace.h
+++ b/sdrgui/gui/workspace.h
@@ -44,6 +44,9 @@ public:
void addAvailableFeatures(const QStringList& featureNames) { m_featureAddDialog.addFeatureNames(featureNames); }
void addToMdiArea(QMdiSubWindow *sub);
void removeFromMdiArea(QMdiSubWindow *sub);
+ int getNumberOfSubWindows() const;
+ QByteArray saveMdiGeometry();
+ void restoreMdiGeometry(const QByteArray& blob);
private:
int m_index;
diff --git a/sdrgui/mainwindow.cpp b/sdrgui/mainwindow.cpp
index a98ae3a54..65a464ee5 100644
--- a/sdrgui/mainwindow.cpp
+++ b/sdrgui/mainwindow.cpp
@@ -66,6 +66,7 @@
#include "gui/workspace.h"
#include "gui/featurepresetsdialog.h"
#include "gui/commandsdialog.h"
+#include "gui/configurationsdialog.h"
#include "dsp/dspengine.h"
#include "dsp/spectrumvis.h"
#include "dsp/dspcommands.h"
@@ -263,6 +264,7 @@ MainWindow::MainWindow(qtwebapp::LoggerWithFile *logger, const MainParser& parse
// loadPresetSettings(m_mainCore->m_settings.getWorkingPreset(), 0);
m_apiAdapter = new WebAPIAdapter();
// loadFeatureSetPresetSettings(m_mainCore->m_settings.getWorkingFeatureSetPreset(), 0);
+ loadConfiguration(m_mainCore->m_settings.getWorkingConfiguration());
splash->showStatusMessage("update preset controls...", Qt::white);
qDebug() << "MainWindow::MainWindow: update preset controls...";
@@ -324,6 +326,7 @@ MainWindow::MainWindow(qtwebapp::LoggerWithFile *logger, const MainParser& parse
MainWindow::~MainWindow()
{
+ m_mainCore->m_settings.save();
m_apiServer->stop();
delete m_apiServer;
delete m_requestMapper;
@@ -773,8 +776,8 @@ void MainWindow::loadSettings()
m_mainCore->m_settings.load();
m_mainCore->m_settings.sortPresets();
- int middleIndex = m_mainCore->m_settings.getPresetCount() / 2;
- QTreeWidgetItem *treeItem;
+ // int middleIndex = m_mainCore->m_settings.getPresetCount() / 2;
+ // QTreeWidgetItem *treeItem;
// for (int i = 0; i < m_mainCore->m_settings.getPresetCount(); ++i)
// {
@@ -787,10 +790,10 @@ void MainWindow::loadSettings()
m_mainCore->m_settings.sortCommands();
- for (int i = 0; i < m_mainCore->m_settings.getCommandCount(); ++i)
- {
- treeItem = addCommandToTree(m_mainCore->m_settings.getCommand(i));
- }
+ // for (int i = 0; i < m_mainCore->m_settings.getCommandCount(); ++i)
+ // {
+ // treeItem = addCommandToTree(m_mainCore->m_settings.getCommand(i));
+ // }
m_mainCore->setLoggingOptions();
}
@@ -894,8 +897,64 @@ void MainWindow::saveFeatureSetPresetSettings(FeatureSetPreset* preset, int feat
featureUI->saveFeatureSetSettings(preset);
}
-void MainWindow::saveCommandSettings()
+void MainWindow::loadConfiguration(const Configuration *configuration)
{
+ qDebug("MainWindow::loadConfiguration: configuration [%s | %s] %d workspaces",
+ qPrintable(configuration->getGroup()),
+ qPrintable(configuration->getDescription()),
+ configuration->getNumberOfWorkspaces()
+ );
+
+ // Wipe out everything first
+
+ // Features
+ m_featureUIs[0]->freeFeatures();
+ // Workspaces
+ for (const auto& workspace : m_workspaces) {
+ delete workspace;
+ }
+ m_workspaces.clear();
+
+ // Reconstruct
+
+ // Workspaces
+ for (int i = 0; i < configuration->getNumberOfWorkspaces(); i++) {
+ addWorkspace();
+ }
+ // Features
+ m_featureUIs[0]->loadFeatureSetSettings(&configuration->getFeatureSetPreset(), m_pluginManager->getPluginAPI(), m_apiAdapter, m_workspaces);
+
+ for (int i = 0; i < m_featureUIs[0]->getNumberOfFeatures(); i++)
+ {
+ FeatureGUI *gui = m_featureUIs[0]->getFeatureGuiAt(i);
+ QObject::connect(
+ gui,
+ &FeatureGUI::moveToWorkspace,
+ this,
+ [=](int wsIndexDest){ this->featureMove(gui, wsIndexDest); }
+ );
+ }
+
+ // Lastly restore workspaces geometry
+ for (int i = 0; i < configuration->getNumberOfWorkspaces(); i++) {
+ m_workspaces[i]->restoreGeometry(configuration->getWorkspaceGeometries()[i]);
+ }
+}
+
+void MainWindow::saveConfiguration(Configuration *configuration)
+{
+ qDebug("MainWindow::saveConfiguration: configuration [%s | %s] %d workspaces",
+ qPrintable(configuration->getGroup()),
+ qPrintable(configuration->getDescription()),
+ m_workspaces.size()
+ );
+
+ configuration->clearData();
+ m_featureUIs[0]->saveFeatureSetSettings(&configuration->getFeatureSetPreset());
+
+ for (const auto& workspace : m_workspaces) {
+ configuration->getWorkspaceGeometries().push_back(workspace->saveGeometry());
+ }
}
QString MainWindow::openGLVersion()
@@ -950,8 +1009,14 @@ void MainWindow::createMenuBar()
QAction *viewAllWorkspacesAction = workspacesMenu->addAction("View all");
viewAllWorkspacesAction->setToolTip("View all workspaces");
QObject::connect(viewAllWorkspacesAction, &QAction::triggered, this, &MainWindow::viewAllWorkspaces);
+ QAction *removeEmptyWorkspacesAction = workspacesMenu->addAction("Remove empty");
+ removeEmptyWorkspacesAction->setToolTip("Remove empty workspaces");
+ QObject::connect(removeEmptyWorkspacesAction, &QAction::triggered, this, &MainWindow::removeEmptyWorkspaces);
QMenu *preferencesMenu = menuBar->addMenu("Preferences");
+ QAction *configurationsAction = preferencesMenu->addAction("Configurations");
+ configurationsAction->setToolTip("Manage configurations");
+ QObject::connect(configurationsAction, &QAction::triggered, this, &MainWindow::on_action_Configurations_triggered);
QAction *audioAction = preferencesMenu->addAction("Audio");
audioAction->setToolTip("Audio preferences");
QObject::connect(audioAction, &QAction::triggered, this, &MainWindow::on_action_Audio_triggered);
@@ -977,6 +1042,9 @@ void MainWindow::createMenuBar()
QAction *commandsAction = preferencesMenu->addAction("Commands");
commandsAction->setToolTip("External commands dialog");
QObject::connect(commandsAction, &QAction::triggered, this, &MainWindow::on_action_commands_triggered);
+ QAction *saveAllAction = preferencesMenu->addAction("Save all");
+ saveAllAction->setToolTip("Save all current settings");
+ QObject::connect(saveAllAction, &QAction::triggered, this, &MainWindow::on_action_saveAll_triggered);
QMenu *helpMenu = menuBar->addMenu("Help");
QAction *quickStartAction = helpMenu->addAction("Quick start");
@@ -1021,7 +1089,8 @@ void MainWindow::closeEvent(QCloseEvent *closeEvent)
// savePresetSettings(m_mainCore->m_settings.getWorkingPreset(), 0);
// saveFeatureSetPresetSettings(m_mainCore->m_settings.getWorkingFeatureSetPreset(), 0);
- // m_mainCore->m_settings.save();
+ saveConfiguration(m_mainCore->m_settings.getWorkingConfiguration());
+ m_mainCore->m_settings.save();
// while (m_deviceUIs.size() > 0)
// {
@@ -1128,6 +1197,7 @@ void MainWindow::applySettings()
{
// loadPresetSettings(m_mainCore->m_settings.getWorkingPreset(), 0);
// loadFeatureSetPresetSettings(m_mainCore->m_settings.getWorkingFeatureSetPreset(), 0);
+ loadConfiguration(m_mainCore->m_settings.getWorkingConfiguration());
m_mainCore->m_settings.sortPresets();
int middleIndex = m_mainCore->m_settings.getPresetCount() / 2;
@@ -1420,6 +1490,24 @@ void MainWindow::viewAllWorkspaces()
}
}
+void MainWindow::removeEmptyWorkspaces()
+{
+ QList::iterator it = m_workspaces.begin();
+
+ while (it != m_workspaces.end())
+ {
+ if ((*it)->getNumberOfSubWindows() == 0)
+ {
+ removeDockWidget(*it);
+ it = m_workspaces.erase(it);
+ }
+ else
+ {
+ ++it;
+ }
+ }
+}
+
void MainWindow::on_action_View_Fullscreen_toggled(bool checked)
{
if(checked) {
@@ -1674,11 +1762,13 @@ void MainWindow::on_presetImport_clicked()
// }
}
-void MainWindow::on_settingsSave_clicked()
+void MainWindow::on_action_saveAll_triggered()
{
// savePresetSettings(m_mainCore->m_settings.getWorkingPreset(), ui->tabInputsView->currentIndex());
// saveFeatureSetPresetSettings(m_mainCore->m_settings.getWorkingFeatureSetPreset(), ui->tabFeatures->currentIndex());
+ saveConfiguration(m_mainCore->m_settings.getWorkingConfiguration());
m_mainCore->m_settings.save();
+ QMessageBox::information(this, tr("Done"), tr("All curent settings saved"));
}
void MainWindow::on_presetLoad_clicked()
@@ -1777,6 +1867,26 @@ void MainWindow::on_action_Loaded_Plugins_triggered()
pluginsDialog.exec();
}
+void MainWindow::on_action_Configurations_triggered()
+{
+ ConfigurationsDialog dialog(this);
+ dialog.setConfigurations(m_mainCore->m_settings.getConfigurations());
+ dialog.populateTree();
+ QObject::connect(
+ &dialog,
+ &ConfigurationsDialog::saveConfiguration,
+ this,
+ &MainWindow::saveConfiguration
+ );
+ QObject::connect(
+ &dialog,
+ &ConfigurationsDialog::loadConfiguration,
+ this,
+ &MainWindow::loadConfiguration
+ );
+ dialog.exec();
+}
+
void MainWindow::on_action_Audio_triggered()
{
AudioDialogX audioDialog(m_dspEngine->getAudioDeviceManager(), this);
@@ -2329,6 +2439,20 @@ void MainWindow::openFeaturePresetsDialog(QPoint p, Workspace *workspace)
dialog.populateTree();
dialog.move(p);
dialog.exec();
+
+ if (dialog.wasPresetLoaded())
+ {
+ for (int i = 0; i < m_featureUIs[0]->getNumberOfFeatures(); i++)
+ {
+ FeatureGUI *gui = m_featureUIs[0]->getFeatureGuiAt(i);
+ QObject::connect(
+ gui,
+ &FeatureGUI::moveToWorkspace,
+ this,
+ [=](int wsIndexDest){ this->featureMove(gui, wsIndexDest); }
+ );
+ }
+ }
}
void MainWindow::deleteFeature(int featureSetIndex, int featureIndex)
diff --git a/sdrgui/mainwindow.h b/sdrgui/mainwindow.h
index 13f077016..0481bc8e0 100644
--- a/sdrgui/mainwindow.h
+++ b/sdrgui/mainwindow.h
@@ -128,7 +128,6 @@ private:
void savePresetSettings(Preset* preset, int tabIndex);
void loadFeatureSetPresetSettings(const FeatureSetPreset* preset, int featureSetIndex, Workspace *workspace);
void saveFeatureSetPresetSettings(FeatureSetPreset* preset, int featureSetIndex);
- void saveCommandSettings();
QString openGLVersion();
void createMenuBar();
@@ -162,6 +161,9 @@ private slots:
void updateStatus();
void addWorkspace();
void viewAllWorkspaces();
+ void removeEmptyWorkspaces();
+ void loadConfiguration(const Configuration *configuration);
+ void saveConfiguration(Configuration *configuration);
void on_action_View_Fullscreen_toggled(bool checked);
void on_presetSave_clicked();
@@ -169,11 +171,12 @@ private slots:
void on_presetEdit_clicked();
void on_presetExport_clicked();
void on_presetImport_clicked();
- void on_settingsSave_clicked();
+ void on_action_saveAll_triggered();
void on_presetLoad_clicked();
void on_presetDelete_clicked();
void on_presetTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
void on_presetTree_itemActivated(QTreeWidgetItem *item, int column);
+ void on_action_Configurations_triggered();
void on_action_Audio_triggered();
void on_action_Logging_triggered();
void on_action_FFT_triggered();
diff --git a/sdrgui/resources/hide.png b/sdrgui/resources/hide.png
new file mode 100644
index 000000000..d92ceae15
Binary files /dev/null and b/sdrgui/resources/hide.png differ
diff --git a/sdrgui/resources/res.qrc b/sdrgui/resources/res.qrc
index 73b00a400..bb851fc62 100644
--- a/sdrgui/resources/res.qrc
+++ b/sdrgui/resources/res.qrc
@@ -129,6 +129,7 @@
help.png
shrink.png
exit.png
+ hide.png
LiberationMono-Regular.ttf
LiberationSans-Regular.ttf