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()),