From f174b6e703599e80bec6ee44b4309873cf074ff0 Mon Sep 17 00:00:00 2001
From: Mikhail Svechnikov <m.svechnikov@fz-juelich.de>
Date: Mon, 23 Jan 2023 19:49:37 +0100
Subject: [PATCH] INSTRUMENT: remember if collapsed

---
 GUI/Model/Descriptor/AxisProperty.cpp         | 11 ++++
 GUI/Model/Descriptor/AxisProperty.h           |  6 +-
 GUI/Model/Device/BeamDistributionItem.cpp     | 13 ++++-
 GUI/Model/Device/BeamDistributionItem.h       |  4 ++
 GUI/Model/Device/BeamItems.cpp                | 22 ++++++++
 GUI/Model/Device/BeamItems.h                  |  8 +++
 GUI/Model/Device/DetectorItems.cpp            | 11 ++++
 GUI/Model/Device/DetectorItems.h              |  4 ++
 GUI/Model/Device/InstrumentItems.cpp          | 55 +++++++++++++++++++
 GUI/Model/Device/InstrumentItems.h            | 22 ++++++++
 GUI/Model/Device/RectangularDetectorItem.cpp  | 22 ++++++++
 GUI/Model/Device/RectangularDetectorItem.h    |  9 +++
 GUI/View/Instrument/AxisPropertyEditor.cpp    |  5 +-
 .../Instrument/DepthprobeInstrumentEditor.cpp |  6 +-
 GUI/View/Instrument/DetectorEditor.cpp        |  5 +-
 GUI/View/Instrument/DistributionEditor.cpp    |  5 +-
 GUI/View/Instrument/EnvironmentEditor.cpp     |  5 +-
 .../Instrument/FootprintCorrectionEditor.cpp  |  5 +-
 GUI/View/Instrument/GISASBeamEditor.cpp       |  5 +-
 .../Instrument/InclinationAnglesEditor.cpp    |  5 +-
 GUI/View/Instrument/InstrumentView.cpp        |  6 +-
 GUI/View/Instrument/OffspecBeamEditor.cpp     |  5 +-
 .../Instrument/PolarizationAnalysisEditor.cpp |  5 +-
 .../Instrument/RectangularDetectorEditor.cpp  | 11 +++-
 .../Instrument/ResolutionFunctionEditor.cpp   |  5 +-
 GUI/View/Instrument/SpecularBeamEditor.cpp    |  5 +-
 GUI/View/Tool/GroupBoxCollapser.cpp           |  6 +-
 GUI/View/Tool/GroupBoxCollapser.h             |  3 +
 28 files changed, 254 insertions(+), 20 deletions(-)

diff --git a/GUI/Model/Descriptor/AxisProperty.cpp b/GUI/Model/Descriptor/AxisProperty.cpp
index 2c5256d4fd9..00528c20db8 100644
--- a/GUI/Model/Descriptor/AxisProperty.cpp
+++ b/GUI/Model/Descriptor/AxisProperty.cpp
@@ -22,6 +22,7 @@ namespace Tag {
 const QString Nbins("Nbins");
 const QString Min("Min");
 const QString Max("Max");
+const QString ExpandGroupbox("ExpandGroupbox");
 
 } // namespace Tag
 } // namespace
@@ -68,6 +69,11 @@ void AxisProperty::writeTo(QXmlStreamWriter* w) const
     w->writeStartElement(Tag::Max);
     m_max.writeTo(w);
     w->writeEndElement();
+
+    // groupbox: is expanded?
+    w->writeStartElement(Tag::ExpandGroupbox);
+    XML::writeAttribute(w, XML::Attrib::value, m_expandGroupBox);
+    w->writeEndElement();
 }
 
 void AxisProperty::readFrom(QXmlStreamReader* r)
@@ -93,6 +99,11 @@ void AxisProperty::readFrom(QXmlStreamReader* r)
             m_max.readFrom(r);
             XML::gotoEndElementOfTag(r, tag);
 
+            // groupbox: is expanded?
+        } else if (tag == Tag::ExpandGroupbox) {
+            XML::readAttribute(r, XML::Attrib::value, &m_expandGroupBox);
+            XML::gotoEndElementOfTag(r, tag);
+
         } else
             r->skipCurrentElement();
     }
diff --git a/GUI/Model/Descriptor/AxisProperty.h b/GUI/Model/Descriptor/AxisProperty.h
index 343b4fa1dfa..697439475b3 100644
--- a/GUI/Model/Descriptor/AxisProperty.h
+++ b/GUI/Model/Descriptor/AxisProperty.h
@@ -57,15 +57,17 @@ public:
     uint nbins() const { return m_nbins; }
     void setNbins(uint v) { m_nbins = v; }
 
+    bool isExpandGroupBox() const { return m_expandGroupBox; }
+    void setExpandGroupBox(bool b) { m_expandGroupBox = b; }
+
     void writeTo(QXmlStreamWriter* w) const;
     void readFrom(QXmlStreamReader* r);
 
 private:
     uint m_nbins = 100;
-
-protected:
     DoubleProperty m_min;
     DoubleProperty m_max;
+    bool m_expandGroupBox = true;
 };
 
 #endif // BORNAGAIN_GUI_MODEL_DESCRIPTOR_AXISPROPERTY_H
diff --git a/GUI/Model/Device/BeamDistributionItem.cpp b/GUI/Model/Device/BeamDistributionItem.cpp
index 92f86185aa2..89bb16f569e 100644
--- a/GUI/Model/Device/BeamDistributionItem.cpp
+++ b/GUI/Model/Device/BeamDistributionItem.cpp
@@ -19,8 +19,9 @@ namespace {
 namespace Tag {
 
 const QString Distribution("Distribution");
+const QString ExpandGroupbox("ExpandGroupbox");
 
-}
+} // namespace Tag
 } // namespace
 
 void BeamDistributionItem::writeTo(QXmlStreamWriter* w) const
@@ -31,6 +32,11 @@ void BeamDistributionItem::writeTo(QXmlStreamWriter* w) const
     w->writeStartElement(Tag::Distribution);
     m_distribution.writeTo(w);
     w->writeEndElement();
+
+    // groupbox: is expanded?
+    w->writeStartElement(Tag::ExpandGroupbox);
+    XML::writeAttribute(w, XML::Attrib::value, m_expandGroupBox);
+    w->writeEndElement();
 }
 
 void BeamDistributionItem::readFrom(QXmlStreamReader* r)
@@ -46,6 +52,11 @@ void BeamDistributionItem::readFrom(QXmlStreamReader* r)
             m_distribution.readFrom(r);
             XML::gotoEndElementOfTag(r, tag);
 
+            // groupbox: is expanded?
+        } else if (tag == Tag::ExpandGroupbox) {
+            XML::readAttribute(r, XML::Attrib::value, &m_expandGroupBox);
+            XML::gotoEndElementOfTag(r, tag);
+
         } else
             r->skipCurrentElement();
     }
diff --git a/GUI/Model/Device/BeamDistributionItem.h b/GUI/Model/Device/BeamDistributionItem.h
index 6b55e9dba8b..5f7e14ce0d8 100644
--- a/GUI/Model/Device/BeamDistributionItem.h
+++ b/GUI/Model/Device/BeamDistributionItem.h
@@ -43,10 +43,14 @@ public:
     DistributionItem* distributionItem() const { return m_distribution.currentItem(); }
     SelectionProperty<DistributionItemCatalog>& distributionSelection() { return m_distribution; }
 
+    bool isExpandGroupBox() const { return m_expandGroupBox; }
+    void setExpandGroupBox(bool b) { m_expandGroupBox = b; }
+
 protected:
     virtual std::unique_ptr<IDistribution1D> createDistribution1D() const;
 
     SelectionProperty<DistributionItemCatalog> m_distribution;
+    bool m_expandGroupBox = true;
 };
 
 template <typename T>
diff --git a/GUI/Model/Device/BeamItems.cpp b/GUI/Model/Device/BeamItems.cpp
index 28d5836e998..5d444eb7eb6 100644
--- a/GUI/Model/Device/BeamItems.cpp
+++ b/GUI/Model/Device/BeamItems.cpp
@@ -32,6 +32,8 @@ const QString AzimuthalAngle("AzimuthalAngle");
 const QString InclinationAngle("InclinationAngle");
 const QString Footprint("Footprint");
 const QString BaseData("BaseData");
+const QString ExpandBeamParametersGroupbox("ExpandBeamParametersGroupbox");
+const QString ExpandFootprintGroupbox("ExpandFootprintGroupbox");
 
 } // namespace Tag
 
@@ -81,6 +83,11 @@ void BeamItem::writeTo(QXmlStreamWriter* w) const
     w->writeStartElement(Tag::InclinationAngle);
     m_inclinationAngleItem->writeTo(w);
     w->writeEndElement();
+
+    // beam parameters groupbox: is expanded?
+    w->writeStartElement(Tag::ExpandBeamParametersGroupbox);
+    XML::writeAttribute(w, XML::Attrib::value, m_expandBeamParameters);
+    w->writeEndElement();
 }
 
 void BeamItem::readFrom(QXmlStreamReader* r)
@@ -114,6 +121,11 @@ void BeamItem::readFrom(QXmlStreamReader* r)
             m_inclinationAngleItem->readFrom(r);
             XML::gotoEndElementOfTag(r, tag);
 
+            // beam parameters groupbox: is expanded?
+        } else if (tag == Tag::ExpandBeamParametersGroupbox) {
+            XML::readAttribute(r, XML::Attrib::value, &m_expandBeamParameters);
+            XML::gotoEndElementOfTag(r, tag);
+
         } else
             r->skipCurrentElement();
     }
@@ -207,6 +219,11 @@ void SpecularBeamItem::writeTo(QXmlStreamWriter* w) const
     w->writeStartElement(Tag::Footprint);
     m_footprint.writeTo(w);
     w->writeEndElement();
+
+    // footprint groupbox: is expanded?
+    w->writeStartElement(Tag::ExpandFootprintGroupbox);
+    XML::writeAttribute(w, XML::Attrib::value, m_expandFootprint);
+    w->writeEndElement();
 }
 
 void SpecularBeamItem::readFrom(QXmlStreamReader* r)
@@ -227,6 +244,11 @@ void SpecularBeamItem::readFrom(QXmlStreamReader* r)
             m_footprint.readFrom(r);
             XML::gotoEndElementOfTag(r, tag);
 
+            // footprint groupbox: is expanded?
+        } else if (tag == Tag::ExpandFootprintGroupbox) {
+            XML::readAttribute(r, XML::Attrib::value, &m_expandFootprint);
+            XML::gotoEndElementOfTag(r, tag);
+
         } else
             r->skipCurrentElement();
     }
diff --git a/GUI/Model/Device/BeamItems.h b/GUI/Model/Device/BeamItems.h
index a8f941b5eed..fbf6cf7cce5 100644
--- a/GUI/Model/Device/BeamItems.h
+++ b/GUI/Model/Device/BeamItems.h
@@ -55,6 +55,9 @@ public:
 
     std::shared_ptr<Beam> createBeam() const;
 
+    bool isExpandBeamParameters() const { return m_expandBeamParameters; }
+    void setExpandBeamParameters(bool b) { m_expandBeamParameters = b; }
+
 protected:
     BeamItem();
 
@@ -68,6 +71,7 @@ protected:
     std::unique_ptr<BeamDistributionItem> m_inclinationAngleItem;
 
     DoubleProperty m_intensity;
+    bool m_expandBeamParameters = true;
 };
 
 class SpecularBeamItem : public BeamItem {
@@ -90,8 +94,12 @@ public:
     void updateToData(const IAxis& axis, QString units);
     void updateWavelength();
 
+    bool isExpandFootprint() const { return m_expandFootprint; }
+    void setExpandFootprint(bool b) { m_expandFootprint = b; }
+
 private:
     SelectionProperty<FootprintItemCatalog> m_footprint;
+    bool m_expandFootprint = true;
 };
 
 class GISASBeamItem : public BeamItem {
diff --git a/GUI/Model/Device/DetectorItems.cpp b/GUI/Model/Device/DetectorItems.cpp
index b82d8fb43b1..608f8bec339 100644
--- a/GUI/Model/Device/DetectorItems.cpp
+++ b/GUI/Model/Device/DetectorItems.cpp
@@ -25,6 +25,7 @@ namespace Tag {
 
 const QString ResolutionFunction("ResolutionFunction");
 const QString MaskModel("MaskModel");
+const QString ExpandGroupbox("ExpandGroupbox");
 
 } // namespace Tag
 } // namespace
@@ -55,6 +56,11 @@ void DetectorItem::writeTo(QXmlStreamWriter* w) const
     w->writeStartElement(Tag::MaskModel);
     m_maskItems.writeTo(w);
     w->writeEndElement();
+
+    // groupbox: is expanded?
+    w->writeStartElement(Tag::ExpandGroupbox);
+    XML::writeAttribute(w, XML::Attrib::value, m_expandResolutionFunc);
+    w->writeEndElement();
 }
 
 void DetectorItem::readFrom(QXmlStreamReader* r)
@@ -75,6 +81,11 @@ void DetectorItem::readFrom(QXmlStreamReader* r)
             m_maskItems.readFrom(r);
             XML::gotoEndElementOfTag(r, tag);
 
+            // groupbox: is expanded?
+        } else if (tag == Tag::ExpandGroupbox) {
+            XML::readAttribute(r, XML::Attrib::value, &m_expandResolutionFunc);
+            XML::gotoEndElementOfTag(r, tag);
+
         } else
             r->skipCurrentElement();
     }
diff --git a/GUI/Model/Device/DetectorItems.h b/GUI/Model/Device/DetectorItems.h
index 8a21eaec417..2839f2cdb78 100644
--- a/GUI/Model/Device/DetectorItems.h
+++ b/GUI/Model/Device/DetectorItems.h
@@ -59,6 +59,9 @@ public:
     //! Scales the values provided by axes (to perform deg->rad conversion on the way to domain).
     virtual double axesToCoreUnitsFactor() const { return 1.0; }
 
+    bool isExpandResolutionFunc() const { return m_expandResolutionFunc; }
+    void setExpandResolutionFunc(bool b) { m_expandResolutionFunc = b; }
+
 protected:
     DetectorItem();
 
@@ -71,6 +74,7 @@ protected:
     // TODO why masks should be here? now 'MaskContainerItem' belongs to 'IntensityDataItem'
     MaskItems m_maskItems; //!< for creation of domain detector; only filled and relevant in jobs
     SelectionProperty<ResolutionFunctionItemCatalog> m_resolutionFunction;
+    bool m_expandResolutionFunc = true;
 };
 
 template <typename T>
diff --git a/GUI/Model/Device/InstrumentItems.cpp b/GUI/Model/Device/InstrumentItems.cpp
index 68b64cd0415..d0ec33b39d0 100644
--- a/GUI/Model/Device/InstrumentItems.cpp
+++ b/GUI/Model/Device/InstrumentItems.cpp
@@ -54,6 +54,11 @@ const QString Detector("Detector");
 const QString ZAxis("ZAxis");
 const QString AlphaAxis("AlphaAxis");
 const QString BaseData("BaseData");
+const QString ExpandInfoGroupbox("ExpandInfoGroupbox");
+const QString ExpandDetectorGroupbox("ExpandDetectorGroupbox");
+const QString ExpandPolarizationGroupbox("ExpandPolarizationGroupbox");
+const QString ExpandEnvironmentGroupbox("ExpandEnvironmentGroupbox");
+const QString ExpandBeamParametersGroupbox("ExpandBeamParametersGroupbox");
 
 } // namespace Tag
 
@@ -178,6 +183,21 @@ void InstrumentItem::writeTo(QXmlStreamWriter* w) const
     w->writeStartElement(Tag::Beam);
     m_beamItem->writeTo(w);
     w->writeEndElement();
+
+    // info groupbox: is expanded?
+    w->writeStartElement(Tag::ExpandInfoGroupbox);
+    XML::writeAttribute(w, XML::Attrib::value, m_expandInfo);
+    w->writeEndElement();
+
+    // polarization groupbox: is expanded?
+    w->writeStartElement(Tag::ExpandPolarizationGroupbox);
+    XML::writeAttribute(w, XML::Attrib::value, m_expandPolarizerAlanyzer);
+    w->writeEndElement();
+
+    // environment groupbox: is expanded?
+    w->writeStartElement(Tag::ExpandEnvironmentGroupbox);
+    XML::writeAttribute(w, XML::Attrib::value, m_expandEnvironment);
+    w->writeEndElement();
 }
 
 void InstrumentItem::readFrom(QXmlStreamReader* r)
@@ -240,6 +260,21 @@ void InstrumentItem::readFrom(QXmlStreamReader* r)
             m_beamItem->readFrom(r);
             XML::gotoEndElementOfTag(r, tag);
 
+            // info groupbox: is expanded?
+        } else if (tag == Tag::ExpandInfoGroupbox) {
+            XML::readAttribute(r, XML::Attrib::value, &m_expandInfo);
+            XML::gotoEndElementOfTag(r, tag);
+
+            // polarization groupbox: is expanded?
+        } else if (tag == Tag::ExpandPolarizationGroupbox) {
+            XML::readAttribute(r, XML::Attrib::value, &m_expandPolarizerAlanyzer);
+            XML::gotoEndElementOfTag(r, tag);
+
+            // environment groupbox: is expanded?
+        } else if (tag == Tag::ExpandEnvironmentGroupbox) {
+            XML::readAttribute(r, XML::Attrib::value, &m_expandEnvironment);
+            XML::gotoEndElementOfTag(r, tag);
+
         } else
             r->skipCurrentElement();
     }
@@ -469,6 +504,11 @@ void Instrument2DItem::writeTo(QXmlStreamWriter* w) const
     w->writeStartElement(Tag::Detector);
     m_detector.writeTo(w);
     w->writeEndElement();
+
+    // detector groupbox: is expanded?
+    w->writeStartElement(Tag::ExpandDetectorGroupbox);
+    XML::writeAttribute(w, XML::Attrib::value, m_expandDetector);
+    w->writeEndElement();
 }
 
 void Instrument2DItem::readFrom(QXmlStreamReader* r)
@@ -489,6 +529,11 @@ void Instrument2DItem::readFrom(QXmlStreamReader* r)
             m_detector.readFrom(r);
             XML::gotoEndElementOfTag(r, tag);
 
+            // detector groupbox: is expanded?
+        } else if (tag == Tag::ExpandDetectorGroupbox) {
+            XML::readAttribute(r, XML::Attrib::value, &m_expandDetector);
+            XML::gotoEndElementOfTag(r, tag);
+
         } else
             r->skipCurrentElement();
     }
@@ -595,6 +640,11 @@ void OffspecInstrumentItem::writeTo(QXmlStreamWriter* w) const
     w->writeStartElement(Tag::AlphaAxis);
     m_alphaAxis.writeTo(w);
     w->writeEndElement();
+
+    // beam parameters groupbox: is expanded?
+    w->writeStartElement(Tag::ExpandBeamParametersGroupbox);
+    XML::writeAttribute(w, XML::Attrib::value, m_expandBeamParameters);
+    w->writeEndElement();
 }
 
 void OffspecInstrumentItem::readFrom(QXmlStreamReader* r)
@@ -615,6 +665,11 @@ void OffspecInstrumentItem::readFrom(QXmlStreamReader* r)
             m_alphaAxis.readFrom(r);
             XML::gotoEndElementOfTag(r, tag);
 
+            // beam parameters groupbox: is expanded?
+        } else if (tag == Tag::ExpandBeamParametersGroupbox) {
+            XML::readAttribute(r, XML::Attrib::value, &m_expandBeamParameters);
+            XML::gotoEndElementOfTag(r, tag);
+
         } else
             r->skipCurrentElement();
     }
diff --git a/GUI/Model/Device/InstrumentItems.h b/GUI/Model/Device/InstrumentItems.h
index 403c7f102b9..8917d96ec1e 100644
--- a/GUI/Model/Device/InstrumentItems.h
+++ b/GUI/Model/Device/InstrumentItems.h
@@ -106,6 +106,15 @@ public:
     const DoubleProperty& analyzerTotalTransmission() const { return m_analyzerTotalTransmission; }
     void setAnalyzerTotalTransmission(double v) { m_analyzerTotalTransmission.setValue(v); }
 
+    bool isExpandInfo() const { return m_expandInfo; }
+    void setExpandInfo(bool b) { m_expandInfo = b; }
+
+    bool isExpandPolarizerAlanyzer() const { return m_expandPolarizerAlanyzer; }
+    void setExpandPolarizerAlanyzer(bool b) { m_expandPolarizerAlanyzer = b; }
+
+    bool isExpandEnvironment() const { return m_expandEnvironment; }
+    void setExpandEnvironment(bool b) { m_expandEnvironment = b; }
+
 protected:
     explicit InstrumentItem(const QString& modelType);
 
@@ -124,6 +133,9 @@ protected:
 
     DoubleProperty m_analyzerEfficiency;
     DoubleProperty m_analyzerTotalTransmission;
+    bool m_expandInfo = true;
+    bool m_expandPolarizerAlanyzer = true;
+    bool m_expandEnvironment = true;
 };
 
 
@@ -166,10 +178,13 @@ public:
     AxisProperty& zAxis() { return m_zAxis; }
     const AxisProperty& zAxis() const { return m_zAxis; }
 
+    bool isExpandParameters() const { return m_expandParameters; }
+    void setExpandParameters(bool b) { m_expandParameters = b; }
 
 protected:
     mutable std::unique_ptr<const ICoordSystem> m_coosys;
     AxisProperty m_zAxis;
+    bool m_expandParameters = true;
 };
 
 
@@ -191,10 +206,14 @@ public:
 
     static bool isDetectorPropertyName(const QString& name);
 
+    bool isExpandDetector() const { return m_expandDetector; }
+    void setExpandDetector(bool b) { m_expandDetector = b; }
+
 protected:
     Instrument2DItem();
 
     SelectionProperty<DetectorItemCatalog> m_detector;
+    bool m_expandDetector = true;
 };
 
 
@@ -226,9 +245,12 @@ public:
     AxisProperty& alphaAxis() { return m_alphaAxis; }
     const AxisProperty& alphaAxis() const { return m_alphaAxis; }
 
+    bool isExpandBeamParameters() const { return m_expandBeamParameters; }
+    void setExpandBeamParameters(bool b) { m_expandBeamParameters = b; }
 
 protected:
     AxisProperty m_alphaAxis;
+    bool m_expandBeamParameters = true;
 };
 
 //  ************************************************************************************************
diff --git a/GUI/Model/Device/RectangularDetectorItem.cpp b/GUI/Model/Device/RectangularDetectorItem.cpp
index a3cbac72af6..98b607e6311 100644
--- a/GUI/Model/Device/RectangularDetectorItem.cpp
+++ b/GUI/Model/Device/RectangularDetectorItem.cpp
@@ -35,6 +35,8 @@ const QString Distance("Distance");
 const QString NormalVector("NormalVector");
 const QString DirectionVector("DirectionVector");
 const QString BaseData("BaseData");
+const QString ExpandXaxisGroupBox("ExpandXaxisGroupBox");
+const QString ExpandYaxisGroupBox("ExpandYaxisGroupBox");
 
 } // namespace Tag
 
@@ -149,6 +151,16 @@ void RectangularDetectorItem::writeTo(QXmlStreamWriter* w) const
     w->writeStartElement(Tag::Distance);
     m_distance.writeTo(w);
     w->writeEndElement();
+
+    // x axis groupbox: is expanded?
+    w->writeStartElement(Tag::ExpandXaxisGroupBox);
+    XML::writeAttribute(w, XML::Attrib::value, m_expandXaxis);
+    w->writeEndElement();
+
+    // y axis groupbox: is expanded?
+    w->writeStartElement(Tag::ExpandYaxisGroupBox);
+    XML::writeAttribute(w, XML::Attrib::value, m_expandYaxis);
+    w->writeEndElement();
 }
 
 void RectangularDetectorItem::readFrom(QXmlStreamReader* r)
@@ -215,6 +227,16 @@ void RectangularDetectorItem::readFrom(QXmlStreamReader* r)
             m_distance.readFrom(r);
             XML::gotoEndElementOfTag(r, tag);
 
+            // x axis groupbox: is expanded?
+        } else if (tag == Tag::ExpandXaxisGroupBox) {
+            XML::readAttribute(r, XML::Attrib::value, &m_expandXaxis);
+            XML::gotoEndElementOfTag(r, tag);
+
+            // y axis groupbox: is expanded?
+        } else if (tag == Tag::ExpandYaxisGroupBox) {
+            XML::readAttribute(r, XML::Attrib::value, &m_expandYaxis);
+            XML::gotoEndElementOfTag(r, tag);
+
         } else
             r->skipCurrentElement();
     }
diff --git a/GUI/Model/Device/RectangularDetectorItem.h b/GUI/Model/Device/RectangularDetectorItem.h
index ff9b9fefce5..9997777c8df 100644
--- a/GUI/Model/Device/RectangularDetectorItem.h
+++ b/GUI/Model/Device/RectangularDetectorItem.h
@@ -66,6 +66,12 @@ public:
     const DoubleProperty& distance() const { return m_distance; }
     void setDistance(double v) { m_distance.setValue(v); }
 
+    bool isExpandXaxis() const { return m_expandXaxis; }
+    void setExpandXaxis(bool b) { m_expandXaxis = b; }
+
+    bool isExpandYaxis() const { return m_expandYaxis; }
+    void setExpandYaxis(bool b) { m_expandYaxis = b; }
+
 private:
     std::unique_ptr<IDetector> createDomainDetector() const override;
     void updateTooltips();
@@ -83,6 +89,9 @@ private:
     DoubleProperty m_u0;
     DoubleProperty m_v0;
     DoubleProperty m_distance;
+
+    bool m_expandXaxis = true;
+    bool m_expandYaxis = true;
 };
 
 #endif // BORNAGAIN_GUI_MODEL_DEVICE_RECTANGULARDETECTORITEM_H
diff --git a/GUI/View/Instrument/AxisPropertyEditor.cpp b/GUI/View/Instrument/AxisPropertyEditor.cpp
index 49f7d63f33d..9641a838f30 100644
--- a/GUI/View/Instrument/AxisPropertyEditor.cpp
+++ b/GUI/View/Instrument/AxisPropertyEditor.cpp
@@ -44,7 +44,10 @@ AxisPropertyEditor::AxisPropertyEditor(QWidget* parent, const QString& groupTitl
     m_minSpinBox = GUI::Util::createDoubleSpinBoxRow(formLayout, axisProperty->min());
     m_maxSpinBox = GUI::Util::createDoubleSpinBoxRow(formLayout, axisProperty->max());
 
-    GroupBoxCollapser::installIntoGroupBox(this);
+    auto* collapser = GroupBoxCollapser::installIntoGroupBox(this);
+    collapser->setExpanded(m_axisProperty->isExpandGroupBox());
+    connect(collapser, &GroupBoxCollapser::toggled, this,
+            [this](bool b) { m_axisProperty->setExpandGroupBox(b); });
 
     connect(m_minSpinBox, qOverload<double>(&DoubleSpinBox::baseValueChanged), [=](double v) {
         if (m_axisProperty->min() != v) {
diff --git a/GUI/View/Instrument/DepthprobeInstrumentEditor.cpp b/GUI/View/Instrument/DepthprobeInstrumentEditor.cpp
index 14a08b126c9..f8496ab9902 100644
--- a/GUI/View/Instrument/DepthprobeInstrumentEditor.cpp
+++ b/GUI/View/Instrument/DepthprobeInstrumentEditor.cpp
@@ -50,7 +50,11 @@ DepthprobeInstrumentEditor::DepthprobeInstrumentEditor(QWidget* parent,
                                                    "Number of points in scan across sample bulk");
     vLayout->addWidget(depthAxisEditor);
 
-    GroupBoxCollapser::installIntoGroupBox(parametersGroupBox);
+    auto* collapser = GroupBoxCollapser::installIntoGroupBox(parametersGroupBox);
+    collapser->setExpanded(instrument->isExpandParameters());
+    connect(collapser, &GroupBoxCollapser::toggled, this,
+            [instrument](bool b) { instrument->setExpandParameters(b); });
+
     layout->addWidget(parametersGroupBox);
 
     auto* polMatricesAnalysisEditor = new PolarizationAnalysisEditor(this, instrument);
diff --git a/GUI/View/Instrument/DetectorEditor.cpp b/GUI/View/Instrument/DetectorEditor.cpp
index e86b16722dd..da2a14f6dc5 100644
--- a/GUI/View/Instrument/DetectorEditor.cpp
+++ b/GUI/View/Instrument/DetectorEditor.cpp
@@ -37,7 +37,10 @@ DetectorEditor::DetectorEditor(QWidget* parent, Instrument2DItem* instrument)
         });
     m_formLayout->addRow("Detector:", detectorTypeCombo);
 
-    GroupBoxCollapser::installIntoGroupBox(this);
+    auto* collapser = GroupBoxCollapser::installIntoGroupBox(this);
+    collapser->setExpanded(instrument->isExpandDetector());
+    connect(collapser, &GroupBoxCollapser::toggled, this,
+            [instrument](bool b) { instrument->setExpandDetector(b); });
 
     createDetectorWidgets();
 }
diff --git a/GUI/View/Instrument/DistributionEditor.cpp b/GUI/View/Instrument/DistributionEditor.cpp
index 17c7c34132f..43f9685794a 100644
--- a/GUI/View/Instrument/DistributionEditor.cpp
+++ b/GUI/View/Instrument/DistributionEditor.cpp
@@ -184,7 +184,10 @@ DistributionEditor::DistributionEditor(const QString& title,
     hLayout->addWidget(m_plot);
     hLayout->addStretch(1);
 
-    GroupBoxCollapser::installIntoGroupBox(this);
+    auto* collapser = GroupBoxCollapser::installIntoGroupBox(this);
+    collapser->setExpanded(item->isExpandGroupBox());
+    connect(collapser, &GroupBoxCollapser::toggled, this,
+            [item](bool b) { item->setExpandGroupBox(b); });
 
     connect(m_selector, &DistributionSelector::distributionChanged, this,
             &DistributionEditor::distributionChanged);
diff --git a/GUI/View/Instrument/EnvironmentEditor.cpp b/GUI/View/Instrument/EnvironmentEditor.cpp
index 7cc3b4650da..ce9a0605be3 100644
--- a/GUI/View/Instrument/EnvironmentEditor.cpp
+++ b/GUI/View/Instrument/EnvironmentEditor.cpp
@@ -36,7 +36,10 @@ EnvironmentEditor::EnvironmentEditor(QWidget* parent, InstrumentItem* instrument
     m_formLayout->addRow("Background type:", backgroundTypeCombo);
 
     createBackgroundWidgets();
-    GroupBoxCollapser::installIntoGroupBox(this);
+    auto* collapser = GroupBoxCollapser::installIntoGroupBox(this);
+    collapser->setExpanded(instrument->isExpandEnvironment());
+    connect(collapser, &GroupBoxCollapser::toggled, this,
+            [instrument](bool b) { instrument->setExpandEnvironment(b); });
 }
 
 void EnvironmentEditor::createBackgroundWidgets()
diff --git a/GUI/View/Instrument/FootprintCorrectionEditor.cpp b/GUI/View/Instrument/FootprintCorrectionEditor.cpp
index 37bd7b272fd..5ecaabe1604 100644
--- a/GUI/View/Instrument/FootprintCorrectionEditor.cpp
+++ b/GUI/View/Instrument/FootprintCorrectionEditor.cpp
@@ -34,7 +34,10 @@ FootprintCorrectionEditor::FootprintCorrectionEditor(QWidget* parent, SpecularBe
     });
     m_formLayout->addRow("Type:", typeCombo);
 
-    GroupBoxCollapser::installIntoGroupBox(this);
+    auto* collapser = GroupBoxCollapser::installIntoGroupBox(this);
+    collapser->setExpanded(item->isExpandFootprint());
+    connect(collapser, &GroupBoxCollapser::toggled, this,
+            [item](bool b) { item->setExpandFootprint(b); });
 
     createFootprintWidgets();
 }
diff --git a/GUI/View/Instrument/GISASBeamEditor.cpp b/GUI/View/Instrument/GISASBeamEditor.cpp
index 677197b6b0f..f57a98dda0e 100644
--- a/GUI/View/Instrument/GISASBeamEditor.cpp
+++ b/GUI/View/Instrument/GISASBeamEditor.cpp
@@ -59,7 +59,10 @@ GISASBeamEditor::GISASBeamEditor(QWidget* parent, BeamItem* item)
 
     intensityEditor->setText(QString::number(item->intensity()));
 
-    GroupBoxCollapser::installIntoGroupBox(this);
+    auto* collapser = GroupBoxCollapser::installIntoGroupBox(this);
+    collapser->setExpanded(item->isExpandBeamParameters());
+    connect(collapser, &GroupBoxCollapser::toggled, this,
+            [item](bool b) { item->setExpandBeamParameters(b); });
 
     connect(wavelengthEditor, &DistributionEditor::distributionChanged, this,
             &GISASBeamEditor::dataChanged);
diff --git a/GUI/View/Instrument/InclinationAnglesEditor.cpp b/GUI/View/Instrument/InclinationAnglesEditor.cpp
index 891009b14f7..41e0f47d987 100644
--- a/GUI/View/Instrument/InclinationAnglesEditor.cpp
+++ b/GUI/View/Instrument/InclinationAnglesEditor.cpp
@@ -63,7 +63,10 @@ InclinationAnglesEditor::InclinationAnglesEditor(QWidget* parent, SpecularBeamIn
     hLayout->setAlignment(m_plot, Qt::AlignTop);
     hLayout->addStretch(1);
 
-    GroupBoxCollapser::installIntoGroupBox(this);
+    auto* collapser = GroupBoxCollapser::installIntoGroupBox(this);
+    collapser->setExpanded(item->isExpandGroupBox());
+    connect(collapser, &GroupBoxCollapser::toggled, this,
+            [item](bool b) { item->setExpandGroupBox(b); });
 
     connect(m_selector, &DistributionSelector::distributionChanged, this,
             &InclinationAnglesEditor::dataChanged);
diff --git a/GUI/View/Instrument/InstrumentView.cpp b/GUI/View/Instrument/InstrumentView.cpp
index 03a38e1ea54..870009b1755 100644
--- a/GUI/View/Instrument/InstrumentView.cpp
+++ b/GUI/View/Instrument/InstrumentView.cpp
@@ -159,7 +159,11 @@ void InstrumentView::createWidgetsForCurrentInstrument()
     connect(descriptionEdit, &QTextEdit::textChanged,
             [=]() { onInstrumentdescriptionEdited(descriptionEdit->toPlainText()); });
 
-    GroupBoxCollapser::installIntoGroupBox(g);
+    auto* collapser = GroupBoxCollapser::installIntoGroupBox(g);
+    collapser->setExpanded(currentInstrument->isExpandInfo());
+    connect(collapser, &GroupBoxCollapser::toggled, this,
+            [currentInstrument](bool b) { currentInstrument->setExpandInfo(b); });
+
 
     if (auto* sp = dynamic_cast<SpecularInstrumentItem*>(currentInstrument)) {
         auto* editor =
diff --git a/GUI/View/Instrument/OffspecBeamEditor.cpp b/GUI/View/Instrument/OffspecBeamEditor.cpp
index 8a16975c802..decec1993b9 100644
--- a/GUI/View/Instrument/OffspecBeamEditor.cpp
+++ b/GUI/View/Instrument/OffspecBeamEditor.cpp
@@ -59,7 +59,10 @@ OffspecBeamEditor::OffspecBeamEditor(QWidget* parent, OffspecInstrumentItem* ite
 
     intensityEditor->setText(QString::number(item->beamItem()->intensity()));
 
-    GroupBoxCollapser::installIntoGroupBox(this);
+    auto* collapser = GroupBoxCollapser::installIntoGroupBox(this);
+    collapser->setExpanded(item->isExpandBeamParameters());
+    connect(collapser, &GroupBoxCollapser::toggled, this,
+            [item](bool b) { item->setExpandBeamParameters(b); });
 
     connect(wavelengthEditor, &DistributionEditor::distributionChanged, this,
             &OffspecBeamEditor::dataChanged);
diff --git a/GUI/View/Instrument/PolarizationAnalysisEditor.cpp b/GUI/View/Instrument/PolarizationAnalysisEditor.cpp
index 2ca285b286f..bb579a131d5 100644
--- a/GUI/View/Instrument/PolarizationAnalysisEditor.cpp
+++ b/GUI/View/Instrument/PolarizationAnalysisEditor.cpp
@@ -53,7 +53,10 @@ PolarizationAnalysisEditor::PolarizationAnalysisEditor(QWidget* parent, Instrume
         emit dataChanged();
     });
 
-    GroupBoxCollapser::installIntoGroupBox(this);
+    auto* collapser = GroupBoxCollapser::installIntoGroupBox(this);
+    collapser->setExpanded(instrument->isExpandPolarizerAlanyzer());
+    connect(collapser, &GroupBoxCollapser::toggled, this,
+            [instrument](bool b) { instrument->setExpandPolarizerAlanyzer(b); });
 }
 
 DoubleSpinBox* PolarizationAnalysisEditor::createSpinBox(DoubleProperty& d)
diff --git a/GUI/View/Instrument/RectangularDetectorEditor.cpp b/GUI/View/Instrument/RectangularDetectorEditor.cpp
index ec7da653667..f1eac77afd8 100644
--- a/GUI/View/Instrument/RectangularDetectorEditor.cpp
+++ b/GUI/View/Instrument/RectangularDetectorEditor.cpp
@@ -61,7 +61,10 @@ RectangularDetectorEditor::RectangularDetectorEditor(QWidget* parent,
                 emit dataChanged();
             });
     grid->addWidget(xAxisGroupBox, 1, 0);
-    GroupBoxCollapser::installIntoGroupBox(xAxisGroupBox);
+    auto* collapserX = GroupBoxCollapser::installIntoGroupBox(xAxisGroupBox);
+    collapserX->setExpanded(detector->isExpandXaxis());
+    connect(collapserX, &GroupBoxCollapser::toggled, this,
+            [detector](bool b) { detector->setExpandXaxis(b); });
 
 
     // -- y-axis controls
@@ -88,7 +91,11 @@ RectangularDetectorEditor::RectangularDetectorEditor(QWidget* parent,
                 emit dataChanged();
             });
     grid->addWidget(yAxisGroupBox, 1, 1);
-    GroupBoxCollapser::installIntoGroupBox(yAxisGroupBox);
+
+    auto* collapserY = GroupBoxCollapser::installIntoGroupBox(yAxisGroupBox);
+    collapserY->setExpanded(detector->isExpandYaxis());
+    connect(collapserY, &GroupBoxCollapser::toggled, this,
+            [detector](bool b) { detector->setExpandYaxis(b); });
 
     // -- resolution function
     auto* resolutionFunctionEditor =
diff --git a/GUI/View/Instrument/ResolutionFunctionEditor.cpp b/GUI/View/Instrument/ResolutionFunctionEditor.cpp
index b2b9946bfde..e50761385cb 100644
--- a/GUI/View/Instrument/ResolutionFunctionEditor.cpp
+++ b/GUI/View/Instrument/ResolutionFunctionEditor.cpp
@@ -38,7 +38,10 @@ ResolutionFunctionEditor::ResolutionFunctionEditor(Unit unit, QWidget* parent, D
         });
     m_formLayout->addRow("Type:", typeCombo);
 
-    GroupBoxCollapser::installIntoGroupBox(this);
+    auto* collapser = GroupBoxCollapser::installIntoGroupBox(this);
+    collapser->setExpanded(item->isExpandResolutionFunc());
+    connect(collapser, &GroupBoxCollapser::toggled, this,
+            [item](bool b) { item->setExpandResolutionFunc(b); });
 
     createResolutionWidgets();
 }
diff --git a/GUI/View/Instrument/SpecularBeamEditor.cpp b/GUI/View/Instrument/SpecularBeamEditor.cpp
index 1329eab0bbf..ca3ca764ce5 100644
--- a/GUI/View/Instrument/SpecularBeamEditor.cpp
+++ b/GUI/View/Instrument/SpecularBeamEditor.cpp
@@ -59,7 +59,10 @@ SpecularBeamEditor::SpecularBeamEditor(QWidget* parent, SpecularBeamItem* item,
 
     intensityLineEdit->setText(QString::number(item->intensity()));
 
-    GroupBoxCollapser::installIntoGroupBox(this);
+    auto* collapser = GroupBoxCollapser::installIntoGroupBox(this);
+    collapser->setExpanded(item->isExpandBeamParameters());
+    connect(collapser, &GroupBoxCollapser::toggled, this,
+            [item](bool b) { item->setExpandBeamParameters(b); });
 
     // order of the next two connections is important! Indicators have to be recalculated first,
     // then updated (recalculation is done in EditController)
diff --git a/GUI/View/Tool/GroupBoxCollapser.cpp b/GUI/View/Tool/GroupBoxCollapser.cpp
index d5a74047f02..f44e72c433c 100644
--- a/GUI/View/Tool/GroupBoxCollapser.cpp
+++ b/GUI/View/Tool/GroupBoxCollapser.cpp
@@ -12,7 +12,7 @@
 //
 //  ************************************************************************************************
 
-#include "GroupBoxCollapser.h"
+#include "GUI/View/Tool/GroupBoxCollapser.h"
 #include "GUI/Application/ApplicationSettings.h"
 #include <QAction>
 #include <QBoxLayout>
@@ -117,7 +117,8 @@ GroupBoxCollapser::GroupBoxCollapser(QGroupBox* groupBox)
     groupBox->setTitle("");
     groupBox->setProperty("collapsible", true); // helps to distinguish GroupBoxes in stylesheets
 
-    connect(m_toggleButton, &QAbstractButton::clicked, this, &GroupBoxCollapser::toggle);
+    connect(m_toggleButton, &QAbstractButton::clicked, this, &GroupBoxCollapser::toggle,
+            Qt::UniqueConnection);
 }
 
 void GroupBoxCollapser::toggle(bool checked)
@@ -128,4 +129,5 @@ void GroupBoxCollapser::toggle(bool checked)
         m_contentArea->show();
     else
         m_contentArea->hide();
+    emit toggled(m_toggleButton->isChecked());
 }
diff --git a/GUI/View/Tool/GroupBoxCollapser.h b/GUI/View/Tool/GroupBoxCollapser.h
index 30f9b111708..769bbaf3d86 100644
--- a/GUI/View/Tool/GroupBoxCollapser.h
+++ b/GUI/View/Tool/GroupBoxCollapser.h
@@ -54,6 +54,9 @@ public:
     //! Expand/collapse the content area
     void setExpanded(bool expanded = true);
 
+signals:
+    void toggled(bool b);
+
 private:
     GroupBoxCollapser(QGroupBox* groupBox);
     void toggle(bool checked);
-- 
GitLab