diff --git a/sdrgui/CMakeLists.txt b/sdrgui/CMakeLists.txt
index 884fd3fc4..0770ec523 100644
--- a/sdrgui/CMakeLists.txt
+++ b/sdrgui/CMakeLists.txt
@@ -67,6 +67,7 @@ set(sdrgui_SOURCES
gui/loggingdialog.cpp
gui/logslider.cpp
gui/loglabelslider.cpp
+ gui/mdiutils.cpp
gui/mypositiondialog.cpp
gui/nanosecondsdelegate.cpp
gui/pluginsdialog.cpp
@@ -189,6 +190,7 @@ set(sdrgui_HEADERS
gui/loggingdialog.h
gui/logslider.h
gui/loglabelslider.h
+ gui/mdiutils.h
gui/mypositiondialog.h
gui/nanosecondsdelegate.h
gui/physicalunit.h
diff --git a/sdrgui/device/deviceuiset.cpp b/sdrgui/device/deviceuiset.cpp
index de935007b..9416a5fa0 100644
--- a/sdrgui/device/deviceuiset.cpp
+++ b/sdrgui/device/deviceuiset.cpp
@@ -26,6 +26,7 @@
#include "gui/glspectrumview.h"
#include "gui/glspectrumgui.h"
// #include "gui/channelwindow.h"
+#include "gui/mdiutils.h"
#include "gui/workspace.h"
#include "gui/rollupcontents.h"
#include "device/devicegui.h"
@@ -248,8 +249,8 @@ void DeviceUISet::loadDeviceSetSettings(
qDebug("DeviceUISet::loadDeviceSetSettings: preset: [%s, %s]",
qPrintable(preset->getGroup()), qPrintable(preset->getDescription()));
m_spectrumGUI->deserialize(preset->getSpectrumConfig());
- m_mainSpectrumGUI->restoreGeometry(preset->getSpectrumGeometry());
- m_deviceGUI->restoreGeometry(preset->getDeviceGeometry());
+ MDIUtils::restoreMDIGeometry(m_mainSpectrumGUI, preset->getSpectrumGeometry());
+ MDIUtils::restoreMDIGeometry(m_deviceGUI, preset->getDeviceGeometry());
m_deviceAPI->loadSamplingDeviceSettings(preset);
if (!preset->getShowSpectrum()) {
@@ -271,8 +272,8 @@ void DeviceUISet::saveDeviceSetSettings(Preset* preset) const
qPrintable(preset->getGroup()), qPrintable(preset->getDescription()));
preset->setSpectrumConfig(m_spectrumGUI->serialize());
preset->setSpectrumWorkspaceIndex(m_mainSpectrumGUI->getWorkspaceIndex());
- preset->setSpectrumGeometry(m_mainSpectrumGUI->saveGeometry());
- preset->setDeviceGeometry(m_deviceGUI->saveGeometry());
+ preset->setSpectrumGeometry(MDIUtils::saveMDIGeometry(m_mainSpectrumGUI));
+ preset->setDeviceGeometry(MDIUtils::saveMDIGeometry(m_deviceGUI));
preset->setShowSpectrum(m_spectrumGUI->isVisible());
preset->setSelectedDevice(Preset::SelectedDevice{
m_deviceAPI->getSamplingDeviceId(),
@@ -379,7 +380,7 @@ void DeviceUISet::loadRxChannelSettings(const Preset *preset, PluginAPI *pluginA
rxChannelGUI->hide();
}
- rxChannelGUI->restoreGeometry(rxChannelGUI->getGeometryBytes());
+ MDIUtils::restoreMDIGeometry(rxChannelGUI, rxChannelGUI->getGeometryBytes());
rxChannelGUI->getRollupContents()->arrangeRollups();
rxChannelGUI->setDeviceType(ChannelGUI::DeviceRx);
rxChannelGUI->setDeviceSetIndex(m_deviceSetIndex);
@@ -420,8 +421,7 @@ void DeviceUISet::saveRxChannelSettings(Preset *preset) const
for (int i = 0; i < m_channelInstanceRegistrations.count(); i++)
{
ChannelGUI *channelGUI = m_channelInstanceRegistrations[i].m_gui;
- qDebug("DeviceUISet::saveRxChannelSettings: saving channel [%s]", qPrintable(m_channelInstanceRegistrations[i].m_channelAPI->getURI()));
- channelGUI->setGeometryBytes(channelGUI->saveGeometry());
+ channelGUI->setGeometryBytes(MDIUtils::saveMDIGeometry(channelGUI));
channelGUI->zetHidden(channelGUI->isHidden());
preset->addChannel(m_channelInstanceRegistrations[i].m_channelAPI->getURI(), channelGUI->serialize());
}
@@ -508,7 +508,7 @@ void DeviceUISet::loadTxChannelSettings(const Preset *preset, PluginAPI *pluginA
txChannelGUI->hide();
}
- txChannelGUI->restoreGeometry(txChannelGUI->getGeometryBytes());
+ MDIUtils::restoreMDIGeometry(txChannelGUI, txChannelGUI->getGeometryBytes());
txChannelGUI->getRollupContents()->arrangeRollups();
txChannelGUI->setDeviceType(ChannelGUI::DeviceTx);
txChannelGUI->setDeviceSetIndex(m_deviceSetIndex);
@@ -551,7 +551,7 @@ void DeviceUISet::saveTxChannelSettings(Preset *preset) const
{
ChannelGUI *channelGUI = m_channelInstanceRegistrations[i].m_gui;
qDebug("DeviceUISet::saveTxChannelSettings: saving channel [%s]", qPrintable(m_channelInstanceRegistrations[i].m_channelAPI->getURI()));
- channelGUI->setGeometryBytes(channelGUI->saveGeometry());
+ channelGUI->setGeometryBytes(MDIUtils::saveMDIGeometry(channelGUI));
channelGUI->zetHidden(channelGUI->isHidden());
preset->addChannel(m_channelInstanceRegistrations[i].m_channelAPI->getURI(), channelGUI->serialize());
}
@@ -682,7 +682,7 @@ void DeviceUISet::loadMIMOChannelSettings(const Preset *preset, PluginAPI *plugi
channelGUI->hide();
}
- channelGUI->restoreGeometry(channelGUI->getGeometryBytes());
+ MDIUtils::restoreMDIGeometry(channelGUI, channelGUI->getGeometryBytes());
channelGUI->getRollupContents()->arrangeRollups();
channelGUI->setDeviceType(ChannelGUI::DeviceMIMO);
channelGUI->setDeviceSetIndex(m_deviceSetIndex);
@@ -731,7 +731,7 @@ void DeviceUISet::saveMIMOChannelSettings(Preset *preset) const
{
ChannelGUI *channelGUI = m_channelInstanceRegistrations[i].m_gui;
qDebug("DeviceUISet::saveMIMOChannelSettings: saving channel [%s]", qPrintable(m_channelInstanceRegistrations[i].m_channelAPI->getURI()));
- channelGUI->setGeometryBytes(channelGUI->saveGeometry());
+ channelGUI->setGeometryBytes(MDIUtils::saveMDIGeometry(channelGUI));
channelGUI->zetHidden(channelGUI->isHidden());
preset->addChannel(m_channelInstanceRegistrations[i].m_channelAPI->getURI(), channelGUI->serialize());
}
diff --git a/sdrgui/feature/featureuiset.cpp b/sdrgui/feature/featureuiset.cpp
index e9bb2fc00..5369b6033 100644
--- a/sdrgui/feature/featureuiset.cpp
+++ b/sdrgui/feature/featureuiset.cpp
@@ -15,6 +15,7 @@
// along with this program. If not, see . //
///////////////////////////////////////////////////////////////////////////////////
+#include "gui/mdiutils.h"
#include "gui/workspace.h"
#include "plugin/pluginapi.h"
#include "settings/featuresetpreset.h"
@@ -198,14 +199,14 @@ void FeatureUISet::loadFeatureSetSettings(
if (workspaces && (workspaces->size() > 0) && (originalWorkspaceIndex < workspaces->size())) // restore in original workspace
{
(*workspaces)[originalWorkspaceIndex]->addToMdiArea((QMdiSubWindow*) featureGUI);
- featureGUI->restoreGeometry(featureGUI->getGeometryBytes());
+ MDIUtils::restoreMDIGeometry(featureGUI, featureGUI->getGeometryBytes());
featureGUI->getRollupContents()->arrangeRollups();
}
else if (currentWorkspace) // restore in current workspace
{
featureGUI->setWorkspaceIndex(currentWorkspace->getIndex());
currentWorkspace->addToMdiArea((QMdiSubWindow*) featureGUI);
- featureGUI->restoreGeometry(featureGUI->getGeometryBytes());
+ MDIUtils::restoreMDIGeometry(featureGUI, featureGUI->getGeometryBytes());
featureGUI->getRollupContents()->arrangeRollups();
}
}
@@ -220,7 +221,7 @@ void FeatureUISet::saveFeatureSetSettings(FeatureSetPreset *preset)
qPrintable(m_featureInstanceRegistrations.at(i).m_feature->getURI())
);
FeatureGUI *featureGUI = m_featureInstanceRegistrations.at(i).m_gui;
- featureGUI->setGeometryBytes(featureGUI->saveGeometry());
+ featureGUI->setGeometryBytes(MDIUtils::saveMDIGeometry(featureGUI));
preset->addFeature(
m_featureInstanceRegistrations.at(i).m_feature->getURI(),
m_featureInstanceRegistrations.at(i).m_gui->serialize()
diff --git a/sdrgui/gui/mdiutils.cpp b/sdrgui/gui/mdiutils.cpp
new file mode 100644
index 000000000..46918f2b2
--- /dev/null
+++ b/sdrgui/gui/mdiutils.cpp
@@ -0,0 +1,87 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2023 Jon Beniston, M7RCE //
+// //
+// This program is free software; you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation as version 3 of the License, or //
+// (at your option) any later version. //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#include
+#include
+#include
+
+#include "mdiutils.h"
+
+// QWidget::save/restoreGeometry doesn't work properly for MDI sub-windows
+// so we have this code
+
+QByteArray MDIUtils::saveMDIGeometry(QWidget *widget)
+{
+ QByteArray array;
+ QDataStream stream(&array, QIODevice::WriteOnly);
+ quint16 version = 1;
+ stream << version
+ << widget->x()
+ << widget->y()
+ << widget->width()
+ << widget->height()
+ << widget->isMaximized()
+ << widget->isFullScreen();
+ return array;
+}
+
+bool MDIUtils::restoreMDIGeometry(QWidget *widget, const QByteArray& geometry)
+{
+ if (geometry.size() == 66)
+ {
+ // Older versions of SDRangel used save/restoreGeometry
+ return widget->restoreGeometry(geometry);
+ }
+ else if (geometry.size() < 4)
+ {
+ qDebug() << "MDIUtils::restoreMDIGeometry: geometry is invalid";
+ return false;
+ }
+ else
+ {
+ QDataStream stream(geometry);
+ quint16 version = 0;
+ stream >> version;
+ if (version != 1)
+ {
+ qDebug() << "MDIUtils::restoreMDIGeometry: Unsupported version" << version;
+ return false;
+ }
+
+ // Restore window position
+ qint32 x, y, width, height;
+ stream >> x >> y >> width >> height;
+ widget->move(x, y);
+ widget->resize(width, height);
+
+ // Restore window state
+ // After restoring the geometry for a number of MDI windows, if one was maximized
+ // but not the last to have geometry restored for, we end up with the wrong
+ // window being maximized, so we don't bother trying for now
+ bool maximized, fullscreen;
+ stream >> maximized >> fullscreen;
+ /*if (fullscreen) {
+ widget->showFullScreen();
+ } else if (maximized) {
+ widget->showMaximized();
+ } else {
+ widget->showNormal();
+ }*/
+
+ return true;
+ }
+}
diff --git a/sdrgui/gui/mdiutils.h b/sdrgui/gui/mdiutils.h
new file mode 100644
index 000000000..4a5227702
--- /dev/null
+++ b/sdrgui/gui/mdiutils.h
@@ -0,0 +1,36 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2023 Jon Beniston, M7RCE //
+// //
+// This program is free software; you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation as version 3 of the License, or //
+// (at your option) any later version. //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef SDRGUI_GUI_MDIUTILS_H
+#define SDRGUI_GUI_MDIUTILS_H
+
+#include
+
+#include "export.h"
+
+class QWidget;
+
+class SDRGUI_API MDIUtils {
+
+public:
+
+ static QByteArray saveMDIGeometry(QWidget *widget);
+ static bool restoreMDIGeometry(QWidget *widget, const QByteArray& geometry);
+
+};
+
+#endif // SDRGUI_GUI_MDIUTILS_H
diff --git a/sdrgui/mainwindow.cpp b/sdrgui/mainwindow.cpp
index 37545f84e..8af943245 100644
--- a/sdrgui/mainwindow.cpp
+++ b/sdrgui/mainwindow.cpp
@@ -64,6 +64,7 @@
#include "gui/loggingdialog.h"
#include "gui/deviceuserargsdialog.h"
#include "gui/sdrangelsplash.h"
+#include "gui/mdiutils.h"
#include "gui/mypositiondialog.h"
#include "gui/fftdialog.h"
#include "gui/fftwisdomdialog.h"
@@ -1571,9 +1572,9 @@ void MainWindow::saveConfiguration(Configuration *configuration)
{
deviceSetPresets.push_back(Preset());
deviceUISet->saveDeviceSetSettings(&deviceSetPresets.back());
- deviceSetPresets.back().setSpectrumGeometry(deviceUISet->m_mainSpectrumGUI->saveGeometry());
+ deviceSetPresets.back().setSpectrumGeometry(MDIUtils::saveMDIGeometry(deviceUISet->m_mainSpectrumGUI));
deviceSetPresets.back().setSpectrumWorkspaceIndex(deviceUISet->m_mainSpectrumGUI->getWorkspaceIndex());
- deviceSetPresets.back().setDeviceGeometry(deviceUISet->m_deviceGUI->saveGeometry());
+ deviceSetPresets.back().setDeviceGeometry(MDIUtils::saveMDIGeometry(deviceUISet->m_deviceGUI));
deviceSetPresets.back().setDeviceWorkspaceIndex(deviceUISet->m_deviceGUI->getWorkspaceIndex());
qDebug("MainWindow::saveConfiguration: %s device in workspace %d spectrum in %d",
qPrintable(deviceUISet->m_deviceAPI->getSamplingDeviceId()),