From f7da5c52a6c08076f4040689970566ea05369b90 Mon Sep 17 00:00:00 2001
From: Julien STAUB
Date: Sat, 8 Aug 2026 08:12:59 +0200
Subject: [PATCH 01/20] WIP single source of truth for QSettings
---
DFTFringe.pro | 11 +++----
DFTFringe_Dale.pro | 5 ++++
DFTFringe_QT5.pro | 11 +++----
settingsfacade.cpp | 37 ++++++++++++++++++++++++
settingsfacade.h | 41 ++++++++++++++++++++++++++
settingsstores.cpp | 60 +++++++++++++++++++++++++++++++++++++++
settingsstores.h | 52 +++++++++++++++++++++++++++++++++
settingsstores_fields.inc | 47 ++++++++++++++++++++++++++++++
usercolormapdlg.cpp | 2 +-
9 files changed, 255 insertions(+), 11 deletions(-)
create mode 100644 settingsfacade.cpp
create mode 100644 settingsfacade.h
create mode 100644 settingsstores.cpp
create mode 100644 settingsstores.h
create mode 100644 settingsstores_fields.inc
diff --git a/DFTFringe.pro b/DFTFringe.pro
index e94e9cab..d781a12c 100644
--- a/DFTFringe.pro
+++ b/DFTFringe.pro
@@ -265,6 +265,8 @@ SOURCES += SingleApplication/singleapplication.cpp \
zernikepolar.cpp \
zernikeprocess.cpp \
zernikes.cpp \
+ settingsfacade.cpp \
+ settingsstores.cpp \
zernikesmoothingdlg.cpp
HEADERS += bezier/bezier.h \
@@ -356,6 +358,8 @@ HEADERS += bezier/bezier.h \
settingsGeneral2.h \
settingsigram.h \
settingsigramimportconfig.h \
+ settingsfacade.h \
+ settingsstores.h \
settingsprofile.h \
showaliasdlg.h \
showallcontoursdlg.h \
@@ -550,8 +554,5 @@ DISTFILES += buildingDFTFringe64.txt \
COPYING.LESSER.txt \
COPYING.txt \
README.md \
- RevisionHistory.html
-
-
-
-
+ RevisionHistory.html \
+ settingsstores_fields.inc
diff --git a/DFTFringe_Dale.pro b/DFTFringe_Dale.pro
index 76fd813f..36b6e654 100644
--- a/DFTFringe_Dale.pro
+++ b/DFTFringe_Dale.pro
@@ -141,6 +141,8 @@ SOURCES += main.cpp \
outlinedialog.cpp \
psitiltoptions.cpp \
contourrulerparams.cpp \
+ settingsfacade.cpp \
+ settingsstores.cpp \
zernikesmoothingdlg.cpp \
zernike/zapm.cpp \
SingleApplication/singleapplication.cpp \
@@ -262,6 +264,8 @@ HEADERS += mainwindow.h \
outlinedialog.h \
psitiltoptions.h \
contourrulerparams.h \
+ settingsfacade.h \
+ settingsstores.h \
zernikesmoothingdlg.h \
bezier/bezier.h \
zernike/zapm_interface.h \
@@ -498,6 +502,7 @@ DISTFILES += \
COPYING.txt \
RevisionHistory.html \
README.md \
+ settingsstores_fields.inc
TRANSLATIONS = dftfringe_fr.ts
diff --git a/DFTFringe_QT5.pro b/DFTFringe_QT5.pro
index 65573323..58d60aac 100644
--- a/DFTFringe_QT5.pro
+++ b/DFTFringe_QT5.pro
@@ -264,6 +264,8 @@ SOURCES += SingleApplication/singleapplication.cpp \
zernikepolar.cpp \
zernikeprocess.cpp \
zernikes.cpp \
+ settingsfacade.cpp \
+ settingsstores.cpp \
zernikesmoothingdlg.cpp
HEADERS += bezier/bezier.h \
@@ -355,6 +357,8 @@ HEADERS += bezier/bezier.h \
settingsGeneral2.h \
settingsigram.h \
settingsigramimportconfig.h \
+ settingsfacade.h \
+ settingsstores.h \
settingsprofile.h \
showaliasdlg.h \
showallcontoursdlg.h \
@@ -549,8 +553,5 @@ DISTFILES += buildingDFTFringe64.txt \
COPYING.LESSER.txt \
COPYING.txt \
README.md \
- RevisionHistory.html
-
-
-
-
+ RevisionHistory.html \
+ settingsstores_fields.inc
diff --git a/settingsfacade.cpp b/settingsfacade.cpp
new file mode 100644
index 00000000..e765494a
--- /dev/null
+++ b/settingsfacade.cpp
@@ -0,0 +1,37 @@
+#include "settingsfacade.h"
+
+SettingsFacade &SettingsFacade::instance()
+{
+ static SettingsFacade facade;
+ return facade;
+}
+
+MirrorSettingsStore &SettingsFacade::mirrorStore()
+{
+ return m_mirrorStore;
+}
+
+const MirrorSettingsStore &SettingsFacade::mirrorStore() const
+{
+ return m_mirrorStore;
+}
+
+GeneralProcessingSettingsStore &SettingsFacade::generalProcessingStore()
+{
+ return m_generalProcessingStore;
+}
+
+const GeneralProcessingSettingsStore &SettingsFacade::generalProcessingStore() const
+{
+ return m_generalProcessingStore;
+}
+
+ContourSettingsStore &SettingsFacade::contourStore()
+{
+ return m_contourStore;
+}
+
+const ContourSettingsStore &SettingsFacade::contourStore() const
+{
+ return m_contourStore;
+}
diff --git a/settingsfacade.h b/settingsfacade.h
new file mode 100644
index 00000000..07a028ef
--- /dev/null
+++ b/settingsfacade.h
@@ -0,0 +1,41 @@
+#ifndef SETTINGSFACADE_H
+#define SETTINGSFACADE_H
+
+#include "settingsstores.h"
+
+/**
+ * @brief Thin entry point that delegates to domain-specific settings stores.
+ *
+ * This class intentionally stays small; domain behavior belongs in internal
+ * stores such as MirrorSettingsStore or ContourSettingsStore.
+ */
+class SettingsFacade
+{
+public:
+ /** @brief Returns process-wide facade instance. */
+ static SettingsFacade &instance();
+
+ /** @brief Accessor for mirror settings persistence. */
+ MirrorSettingsStore &mirrorStore();
+ /** @brief Const accessor for mirror settings persistence. */
+ const MirrorSettingsStore &mirrorStore() const;
+
+ /** @brief Accessor for general processing settings persistence. */
+ GeneralProcessingSettingsStore &generalProcessingStore();
+ /** @brief Const accessor for general processing settings persistence. */
+ const GeneralProcessingSettingsStore &generalProcessingStore() const;
+
+ /** @brief Accessor for contour settings persistence. */
+ ContourSettingsStore &contourStore();
+ /** @brief Const accessor for contour settings persistence. */
+ const ContourSettingsStore &contourStore() const;
+
+private:
+ SettingsFacade() = default;
+
+ MirrorSettingsStore m_mirrorStore;
+ GeneralProcessingSettingsStore m_generalProcessingStore;
+ ContourSettingsStore m_contourStore;
+};
+
+#endif // SETTINGSFACADE_H
diff --git a/settingsstores.cpp b/settingsstores.cpp
new file mode 100644
index 00000000..c088cf2c
--- /dev/null
+++ b/settingsstores.cpp
@@ -0,0 +1,60 @@
+#include "settingsstores.h"
+
+#include
+
+#define SETTINGS_STORE_LOAD_FIELD_FROM_QSETTINGS(type, name, defaultValue, key, converter) \
+ value.name = s.value(key, defaultValue).converter();
+
+#define SETTINGS_STORE_SAVE_FIELD_TO_QSETTINGS(type, name, defaultValue, key, converter) \
+ s.setValue(key, value.name);
+
+MirrorSettings MirrorSettingsStore::load() const
+{
+ QSettings s;
+
+ MirrorSettings value{};
+ SETTINGS_STORE_FOR_EACH_MIRROR_FIELD(SETTINGS_STORE_LOAD_FIELD_FROM_QSETTINGS)
+
+ return value;
+}
+
+void MirrorSettingsStore::save(const MirrorSettings &value) const
+{
+ QSettings s;
+ SETTINGS_STORE_FOR_EACH_MIRROR_FIELD(SETTINGS_STORE_SAVE_FIELD_TO_QSETTINGS)
+}
+
+GeneralProcessingSettings GeneralProcessingSettingsStore::load() const
+{
+ QSettings s;
+
+ GeneralProcessingSettings value{};
+ SETTINGS_STORE_FOR_EACH_GENERAL_FIELD(SETTINGS_STORE_LOAD_FIELD_FROM_QSETTINGS)
+
+ return value;
+}
+
+void GeneralProcessingSettingsStore::save(const GeneralProcessingSettings &value) const
+{
+ QSettings s;
+ SETTINGS_STORE_FOR_EACH_GENERAL_FIELD(SETTINGS_STORE_SAVE_FIELD_TO_QSETTINGS)
+}
+
+ContourSettings ContourSettingsStore::load() const
+{
+ QSettings s;
+
+ ContourSettings value{};
+ SETTINGS_STORE_FOR_EACH_CONTOUR_FIELD(SETTINGS_STORE_LOAD_FIELD_FROM_QSETTINGS)
+
+ return value;
+}
+
+void ContourSettingsStore::save(const ContourSettings &value) const
+{
+ QSettings s;
+ SETTINGS_STORE_FOR_EACH_CONTOUR_FIELD(SETTINGS_STORE_SAVE_FIELD_TO_QSETTINGS)
+}
+
+#undef SETTINGS_STORE_LOAD_FIELD_FROM_QSETTINGS
+#undef SETTINGS_STORE_SAVE_FIELD_TO_QSETTINGS
diff --git a/settingsstores.h b/settingsstores.h
new file mode 100644
index 00000000..1bbb6834
--- /dev/null
+++ b/settingsstores.h
@@ -0,0 +1,52 @@
+#ifndef SETTINGSSTORES_H
+#define SETTINGSSTORES_H
+
+#include
+
+class QSettings;
+
+#include "settingsstores_fields.inc"
+
+#define SETTINGS_STORE_DECLARE_STRUCT_FIELD(type, name, defaultValue, key, converter) type name = defaultValue;
+
+
+struct MirrorSettings {
+ SETTINGS_STORE_FOR_EACH_MIRROR_FIELD(SETTINGS_STORE_DECLARE_STRUCT_FIELD)
+};
+
+class MirrorSettingsStore {
+public:
+
+ MirrorSettings load() const;
+ void save(const MirrorSettings &value) const;
+};
+
+
+
+struct GeneralProcessingSettings {
+ SETTINGS_STORE_FOR_EACH_GENERAL_FIELD(SETTINGS_STORE_DECLARE_STRUCT_FIELD)
+};
+
+class GeneralProcessingSettingsStore {
+public:
+
+ GeneralProcessingSettings load() const;
+ void save(const GeneralProcessingSettings &value) const;
+};
+
+
+
+struct ContourSettings {
+ SETTINGS_STORE_FOR_EACH_CONTOUR_FIELD(SETTINGS_STORE_DECLARE_STRUCT_FIELD)
+};
+
+class ContourSettingsStore {
+public:
+
+ ContourSettings load() const;
+ void save(const ContourSettings &value) const;
+};
+
+#undef SETTINGS_STORE_DECLARE_STRUCT_FIELD
+
+#endif // SETTINGSSTORES_H
diff --git a/settingsstores_fields.inc b/settingsstores_fields.inc
new file mode 100644
index 00000000..d34146e2
--- /dev/null
+++ b/settingsstores_fields.inc
@@ -0,0 +1,47 @@
+// Shared settings schema list.
+// Entry format for callbacks:
+// FIELD(type, memberName, defaultValue, key, converter)
+
+#define SETTINGS_STORE_FOR_EACH_MIRROR_FIELD(FIELD) \
+ FIELD(QString, mirrorName, QStringLiteral("default"), "config mirror name", toString) \
+ FIELD(bool, doNull, true, "config doNull", toBool) \
+ FIELD(double, diameter, 200.0, "config diameter", toDouble) \
+ FIELD(double, roc, 2000.0, "config roc", toDouble) \
+ FIELD(double, obstruction, 0.0, "config obstruction", toDouble) \
+ FIELD(double, cc, -1.0, "config cc", toDouble) \
+ FIELD(double, lambda, 640.0, "config lambda", toDouble) \
+ FIELD(double, fringeSpacing, 1.0, "config fringe spacing", toDouble) \
+ FIELD(bool, flipH, false, "flipH", toBool) \
+ FIELD(bool, useAnnulus, false, "md use annulus", toBool) \
+ FIELD(double, annulusPercent, 0.0, "md annulus percent", toDouble) \
+ FIELD(bool, annulusToObstruction, false, "md Annulus to obs", toBool) \
+ FIELD(int, outlineShape, 0, "outlineShape", toInt) \
+ FIELD(double, ellipseMinorAxis, 50.0, "ellipseMinorAxis", toDouble) \
+ FIELD(bool, apertureReductionEnabled, false, "configAperatureReductionChecked", toBool) \
+ FIELD(double, apertureReduction, 0.0, "config aperatureReduction", toDouble) \
+ FIELD(QString, projectPath, QString(), "projectPath", toString) \
+ FIELD(QString, mirrorConfigFile, QString(), "mirrorConfigFile", toString)
+
+#define SETTINGS_STORE_FOR_EACH_GENERAL_FIELD(FIELD) \
+ FIELD(bool, useMakeStarTest, false, "useMakeStarTest", toBool) \
+ FIELD(int, wavefrontDownSizeValue, 650, "wavefrontDownSizeValue", toInt) \
+ FIELD(bool, wavefrontShouldDownsize, false, "wavefrontShouldDownsize", toBool) \
+ FIELD(double, outputLambda, 550.0, "outputLambda", toDouble) \
+ FIELD(bool, applyOffsets, false, "applyOffsets", toBool) \
+ FIELD(int, astigDistGraphWidth, 0, "AstigDistGraphWidth", toInt) \
+ FIELD(bool, gaussianBlurEnabled, true, "GBlur", toBool) \
+ FIELD(int, gaussianBlurValue, 20, "GBValue", toInt) \
+ FIELD(bool, gaussianRadiusConverted, false, "gaussianRadiusConverted", toBool) \
+ FIELD(int, lowMemoryThreshold, 0, "lowMemoryThreshold", toInt) \
+ FIELD(bool, deletePrevWave, false, "deletePrevWave", toBool)
+
+#define SETTINGS_STORE_FOR_EACH_CONTOUR_FIELD(FIELD) \
+ FIELD(double, contourRange, 0.100, "contourRange", toDouble) \
+ FIELD(bool, contourShowFill, true, "contourShowFill", toBool) \
+ FIELD(bool, contourShowLines, true, "contourShowLines", toBool) \
+ FIELD(bool, contourShowRuler, false, "contourShowRuler", toBool) \
+ FIELD(int, colorMapType, 0, "colorMapType", toInt) \
+ FIELD(int, colorMapIndex, 1, "colorMap ndx", toInt) \
+ FIELD(QString, contourLineColor, QStringLiteral("grey"), "ContourLineColor", toString) \
+ FIELD(QString, contourRulerColor, QStringLiteral("grey"), "ContourRulerColor", toString) \
+ FIELD(double, contourRulerRadialDeg, 0.0, "contourRulerRadialDeg", toDouble)
diff --git a/usercolormapdlg.cpp b/usercolormapdlg.cpp
index ed627550..3a2f8672 100644
--- a/usercolormapdlg.cpp
+++ b/usercolormapdlg.cpp
@@ -283,7 +283,7 @@ void userColorMapDlg::on_pb10_clicked()
ui->pb10->setStyleSheet(s);
ui->pb10->update();
QSettings set;
- set.setValue("userColorStopColor09",c.name());
+ set.setValue("userColorStopColor10",c.name());
setColorMap();
emit colorMapChanged(5);
}
From ed905ba04d6cfd5bfe6f00a5d88a88ce13cce006 Mon Sep 17 00:00:00 2001
From: Julien STAUB
Date: Sat, 8 Aug 2026 09:45:44 +0200
Subject: [PATCH 02/20] force facade usage with friend class
---
settingsfacade.h | 11 +++--------
settingsstores.h | 15 ++++++++++++---
2 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/settingsfacade.h b/settingsfacade.h
index 07a028ef..e1f54cd7 100644
--- a/settingsfacade.h
+++ b/settingsfacade.h
@@ -12,27 +12,22 @@
class SettingsFacade
{
public:
- /** @brief Returns process-wide facade instance. */
+
static SettingsFacade &instance();
- /** @brief Accessor for mirror settings persistence. */
MirrorSettingsStore &mirrorStore();
- /** @brief Const accessor for mirror settings persistence. */
const MirrorSettingsStore &mirrorStore() const;
- /** @brief Accessor for general processing settings persistence. */
GeneralProcessingSettingsStore &generalProcessingStore();
- /** @brief Const accessor for general processing settings persistence. */
const GeneralProcessingSettingsStore &generalProcessingStore() const;
- /** @brief Accessor for contour settings persistence. */
ContourSettingsStore &contourStore();
- /** @brief Const accessor for contour settings persistence. */
const ContourSettingsStore &contourStore() const;
private:
- SettingsFacade() = default;
+ SettingsFacade() = default; // Enforce singleton
+ // Only facade owns these
MirrorSettingsStore m_mirrorStore;
GeneralProcessingSettingsStore m_generalProcessingStore;
ContourSettingsStore m_contourStore;
diff --git a/settingsstores.h b/settingsstores.h
index 1bbb6834..bb167bb0 100644
--- a/settingsstores.h
+++ b/settingsstores.h
@@ -15,8 +15,11 @@ struct MirrorSettings {
};
class MirrorSettingsStore {
-public:
+private:
+ friend class SettingsFacade; // Only facade can construct
+ MirrorSettingsStore() = default;
+public:
MirrorSettings load() const;
void save(const MirrorSettings &value) const;
};
@@ -28,8 +31,11 @@ struct GeneralProcessingSettings {
};
class GeneralProcessingSettingsStore {
+private:
+ friend class SettingsFacade;
+ GeneralProcessingSettingsStore() = default;
+
public:
-
GeneralProcessingSettings load() const;
void save(const GeneralProcessingSettings &value) const;
};
@@ -41,8 +47,11 @@ struct ContourSettings {
};
class ContourSettingsStore {
+private:
+ friend class SettingsFacade;
+ ContourSettingsStore() = default;
+
public:
-
ContourSettings load() const;
void save(const ContourSettings &value) const;
};
From 681c56d3462517b9a5c0a5afcf082fe33af307bc Mon Sep 17 00:00:00 2001
From: Julien STAUB
Date: Sat, 8 Aug 2026 10:21:49 +0200
Subject: [PATCH 03/20] use draft mirror config to fix cancel button
---
mirrordlg.cpp | 99 +++++++++++++++++++++++++++++++++++++++------------
mirrordlg.h | 15 ++++++++
2 files changed, 91 insertions(+), 23 deletions(-)
diff --git a/mirrordlg.cpp b/mirrordlg.cpp
index 95403981..d9260bdd 100644
--- a/mirrordlg.cpp
+++ b/mirrordlg.cpp
@@ -19,6 +19,7 @@
#include "ui_mirrordlg.h"
#include "spdlog/spdlog.h"
#include
+#include
#include
#include
#include
@@ -134,6 +135,59 @@ mirrorDlg::~mirrorDlg()
spdlog::get("logger")->trace("mirrorDlg::~mirrorDlg");
delete ui;
}
+
+void mirrorDlg::loadDraftFromSettings()
+{
+ // Load mirror settings from persistent storage via facade into working draft.
+ // This ensures every dialog open/show starts with the last-saved state.
+ m_draft = SettingsFacade::instance().mirrorStore().load();
+
+ // Sync public member variables with draft for backward compatibility.
+ m_name = m_draft.mirrorName;
+ diameter = m_draft.diameter;
+ roc = m_draft.roc;
+ obs = m_draft.obstruction;
+ cc = m_draft.cc;
+ lambda = m_draft.lambda;
+ fringeSpacing = m_draft.fringeSpacing;
+ fliph = m_draft.flipH;
+ doNull = m_draft.doNull;
+ m_useAnnular = m_draft.useAnnulus;
+ m_annularObsPercent = m_draft.annulusPercent;
+ m_connectAnnulusToObs = m_draft.annulusToObstruction;
+ m_outlineShape = (outlineShape)m_draft.outlineShape;
+ m_verticalAxis = m_draft.ellipseMinorAxis;
+ aperatureReduction = m_draft.apertureReduction;
+ m_aperatureReductionEnabled = m_draft.apertureReductionEnabled;
+ m_projectPath = m_draft.projectPath;
+}
+
+void mirrorDlg::showEvent(QShowEvent *event)
+{
+ // Reload draft from persistent settings before dialog becomes visible.
+ // This ensures Cancel always reverts to the last-saved state.
+ loadDraftFromSettings();
+
+ // Sync UI with reloaded draft values
+ ui->name->setText(m_draft.mirrorName);
+ ui->diameter->setText(QString("%1").arg(diameter, 6, 'f', 2));
+ ui->roc->setText(QString("%1").arg(roc, 6, 'f', 2));
+ ui->obs->setText(QString("%1").arg(obs, 6, 'f', 2));
+ ui->lambda->setText(QString("%1").arg(lambda, 6, 'f', 1));
+ ui->cc->setText(QString("%1").arg(cc, 6, 'f', 2));
+ ui->flipH->setChecked(m_draft.flipH);
+ ui->nullCB->setChecked(m_draft.doNull);
+ ui->fringeSpacingEdit->setText(QString("%1").arg(fringeSpacing, 6, 'f', 3));
+ ui->ellipseShape->setChecked(m_outlineShape == ELLIPSE);
+ ui->minorAxisEdit->setText(QString::number(m_verticalAxis));
+ ui->ReducApp->setChecked(m_aperatureReductionEnabled);
+ ui->reduceValue->setValue(aperatureReduction);
+ ui->useAnnulus->setChecked(m_useAnnular);
+ ui->annulusPercent->setValue(m_annularObsPercent * 100);
+
+ QDialog::showEvent(event);
+}
+
bool mirrorDlg::shouldFlipH(){
return ui->flipH->isChecked();
}
@@ -617,7 +671,6 @@ void mirrorDlg::on_unitsCB_clicked(bool checked)
void mirrorDlg::on_buttonBox_accepted()
{
- QSettings settings;
setclearAp();
updateZ8();
@@ -627,32 +680,32 @@ void mirrorDlg::on_buttonBox_accepted()
updateAutoInvertStatus();
}
- settings.setValue("config mirror name", ui->name->text());
- settings.setValue("config roc", roc);
- settings.setValue("config lambda",lambda);
- settings.setValue("config diameter",diameter);
- settings.setValue("config obstruction", obs);
- settings.setValue("config cc", cc);
- settings.setValue("flipH", ui->flipH->isChecked());
- settings.setValue("md Annulus to obs", m_useAnnular);
-
- settings.setValue("outlineShape", m_outlineShape);
- fringeSpacing = ui->fringeSpacingEdit->text().toDouble();
- settings.setValue("config fringe spacing", fringeSpacing);
- //settings.setValue("config unitsMM", mm);
- settings.setValue("config doNull",doNull);
- settings.setValue("outlineShape",(int)m_outlineShape);
- settings.setValue("ellipseMinorAxis",m_verticalAxis);
- settings.setValue("configAperatureReductionChecked", m_aperatureReductionEnabled);
- settings.setValue("config aperatureReduction", aperatureReduction);
- settings.setValue("md annulus percent", m_annularObsPercent);
- settings.setValue("md use annulus", m_useAnnular);
- if (m_obsChanged)
+ // Update draft with current UI values
+ m_draft.mirrorName = ui->name->text();
+ m_draft.diameter = diameter;
+ m_draft.roc = roc;
+ m_draft.obstruction = obs;
+ m_draft.cc = cc;
+ m_draft.lambda = lambda;
+ m_draft.fringeSpacing = ui->fringeSpacingEdit->text().toDouble();
+ m_draft.flipH = ui->flipH->isChecked();
+ m_draft.doNull = doNull;
+ m_draft.useAnnulus = m_useAnnular;
+ m_draft.annulusPercent = m_annularObsPercent;
+ m_draft.annulusToObstruction = m_connectAnnulusToObs;
+ m_draft.outlineShape = (int)m_outlineShape;
+ m_draft.ellipseMinorAxis = m_verticalAxis;
+ m_draft.apertureReductionEnabled = m_aperatureReductionEnabled;
+ m_draft.apertureReduction = aperatureReduction;
+ m_draft.projectPath = m_projectPath;
+
+ // Persist draft to QSettings via facade (single atomic save)
+ SettingsFacade::instance().mirrorStore().save(m_draft);
+ if (m_obsChanged)
emit obstructionChanged();
emit recomputeZerns();
if (m_aperatureReductionValueChanged){
-
QMessageBox::warning(0, tr("Aperature Reduction value was changed."),
tr("Aperature Reduction was changed.\n"
"The wave front will not be correct until it is recomputed from the interferogram."));
diff --git a/mirrordlg.h b/mirrordlg.h
index a810e1e8..64130d11 100644
--- a/mirrordlg.h
+++ b/mirrordlg.h
@@ -21,6 +21,7 @@
#include
#include
#include "autoinvertdlg.h"
+#include "settingsfacade.h"
namespace Ui {
class mirrorDlg;
@@ -133,15 +134,29 @@ private slots:
void recomputeZerns();
void aperatureChanged();
+protected:
+ /** @brief Reload draft settings before dialog becomes visible.
+ * Ensures Cancel always reverts to the last-saved state (issue #121). */
+ void showEvent(QShowEvent *event) override;
+
private:
explicit mirrorDlg(QWidget *parent = 0);
void setclearAp();
+
+ /** @brief Load draft from persistent settings before dialog is shown.
+ * Ensures Cancel always reverts to the last saved state. */
+ void loadDraftFromSettings();
Ui::mirrorDlg *ui;
bool m_aperatureReductionValueChanged;
QTimer spacingChangeTimer;
void saveJson(const QString &fileName);
void enableAnnular(bool enable);
+
+ /** @brief Working copy of mirror settings during dialog edit.
+ * All UI modifications update this draft. On OK, it persists via facade.
+ * On Cancel, it's discarded, leaving member variables unchanged. */
+ MirrorSettings m_draft;
};
#endif // MIRRORDLG_H
From 004ff48830055ebe0ad733aa85e865eeb7ef6ef7 Mon Sep 17 00:00:00 2001
From: Julien STAUB
Date: Sat, 8 Aug 2026 10:28:59 +0200
Subject: [PATCH 04/20] all mirror configs are accessed though settingsStore.
No more qsettings duplication
---
mirrordlg.cpp | 102 ++++++++++++--------------------------------------
1 file changed, 24 insertions(+), 78 deletions(-)
diff --git a/mirrordlg.cpp b/mirrordlg.cpp
index d9260bdd..bd7684b5 100644
--- a/mirrordlg.cpp
+++ b/mirrordlg.cpp
@@ -46,88 +46,29 @@ mirrorDlg::mirrorDlg(QWidget *parent) :
m_useAnnular = false;
m_connectAnnulusToObs = false;
ui->setupUi(this);
- QSettings settings;
- m_name = settings.value("config mirror name", "default").toString();
- ui->name->setText(m_name);
- doNull = settings.value("config doNull", true).toBool();
- m_useAnnular = settings.value("md use annulus", false).toBool();
- ui->useAnnulus->setChecked(m_useAnnular);
- enableAnnular(m_useAnnular);
- ui->annulusPercent->setValue(settings.value("md annulus percent",0.).toDouble() * 100 );
-
- ui->nullCB->setChecked(doNull);
- diameter = settings.value("config diameter", 200.).toDouble();
- aperatureReduction = settings.value("config aperatureReduction", 0.).toDouble();
- m_aperatureReductionEnabled = settings.value("configAperatureReductionChecked",false).toBool();
-
- roc = settings.value("config roc", 2000.).toDouble();
- FNumber = roc/(2. * diameter);
+
+ // Initialize defaults only; loadDraftFromSettings() called in showEvent() populates UI
+ FNumber = 0.0;
ui->FNumber->blockSignals(true);
ui->roc->blockSignals(true);
ui->lambda->blockSignals(true);
ui->cc->blockSignals(true);
ui->unitsCB->blockSignals(true);
ui->fringeSpacingEdit->blockSignals(true);
-
- if (!doNull){
- ui->roc->hide();
- ui->rocLab->hide();
- ui->FNumber->hide();
- ui->fnumberLab->hide();
- }
- else
- { ui->roc->show();
- ui->rocLab->show();
- ui->fnumberLab->show();
- ui->FNumber->show();
- ui->roc->setText(QString("%1").arg(roc, 6, 'f', 2));
- ui->FNumber->setText(QString("%1").arg(FNumber, 6, 'f', 2));
- }
- lambda = settings.value("config lambda", 640).toDouble();
-
- ui->lambda->setText(QString("%1").arg(lambda, 6 ,'f' ,1));
-
- obs = settings.value("config obstruction", 0.).toDouble();
-
- cc = settings.value("config cc", -1.).toDouble();
-
- ui->cc->setText(QString("%1").arg(cc, 6, 'f', 2));
-
- ui->ReducApp->setChecked( m_aperatureReductionEnabled);
- if ( m_aperatureReductionEnabled)
- ui->reduceValue->setEnabled(true);
-
- ui->reduceValue->setValue(aperatureReduction);
-
-
+ ui->minorAxisEdit->blockSignals(true);
+
ui->unitsCB->setChecked(mm);
-
- ui->FNumber->blockSignals(false);
- ui->flipH->setChecked((settings.value( "flipH", false).toBool()));
- m_projectPath = settings.value("projectPath", "").toString();
- fringeSpacing = settings.value("config fringe spacing", 1.).toDouble();
-
- ui->fringeSpacingEdit->setText(QString("%1").arg(fringeSpacing, 6, 'f', 3));
- ui->fringeSpacingEdit->blockSignals(false);
- m_outlineShape = (outlineShape)settings.value("outlineShape", CIRCLE).toInt();
- ui->minorAxisEdit->setText(QString::number(settings.value("ellipseMinorAxis", 50.).toDouble()));
connect(&spacingChangeTimer, &QTimer::timeout, this, &mirrorDlg::spacingChangeTimeout);
- if (m_verticalAxis == 0)
- m_verticalAxis = diameter;
- ui->ellipseShape->setChecked(m_outlineShape == ELLIPSE);
- ui->minorAxisEdit->setText(QString().number(m_verticalAxis));
- ui->diameter->setText(QString("%1").arg(diameter, 6, 'f', 2));
- ui->obs->setText(QString("%1").arg(obs, 6, 'f', 2));
+
ui->FNumber->blockSignals(false);
ui->roc->blockSignals(false);
ui->lambda->blockSignals(false);
ui->cc->blockSignals(false);
ui->unitsCB->blockSignals(false);
ui->fringeSpacingEdit->blockSignals(false);
- ui->ClearAp->setVisible( m_aperatureReductionEnabled);
- ui->clearApLabel->setVisible( m_aperatureReductionEnabled);
+ ui->minorAxisEdit->blockSignals(false);
+
m_aperatureReductionValueChanged = false;
- setclearAp();
}
mirrorDlg::~mirrorDlg()
@@ -238,8 +179,7 @@ void mirrorDlg::saveJson(const QString &fileName){
}
void mirrorDlg:: on_saveBtn_clicked()
{
- QSettings settings;
- QString path = settings.value("mirrorConfigFile").toString();
+ QString path = m_draft.mirrorConfigFile;
QString extensionTypes("config file (*.json)");
QString fileName = QFileDialog::getSaveFileName(this,
tr("Save config file"), path,
@@ -256,9 +196,11 @@ void mirrorDlg:: on_saveBtn_clicked()
}
saveJson(fileName);
QFileInfo info(fileName);
- settings.setValue("mirrorConfigFile", fileName);
- settings.setValue("projectPath", info.absolutePath());
- m_projectPath = info.absolutePath();
+
+ // Update draft with new file path, then persist via facade
+ m_draft.mirrorConfigFile = fileName;
+ m_draft.projectPath = info.absolutePath();
+ m_projectPath = m_draft.projectPath;
}
void mirrorDlg::loadFile(QString & fileName){
@@ -267,13 +209,16 @@ void mirrorDlg::loadFile(QString & fileName){
ui->ellipseShape->setChecked(false);
m_outlineShape = CIRCLE;
QFileInfo info(fileName);
+
+ // Only persist non-mirror-settings to QSettings (lastPath)
QSettings settings;
-
settings.setValue("lastPath", info.absolutePath());
+
emit newPath(info.absolutePath());
- m_projectPath = info.absolutePath();
- settings.setValue("mirrorConfigFile",fileName);
- settings.setValue("lastPath", info.absolutePath());
+
+ // Update draft with new file path and project path via facade
+ m_draft.projectPath = info.absolutePath();
+ m_draft.mirrorConfigFile = fileName;
if (fileName.endsWith(".json")){
@@ -661,8 +606,9 @@ void mirrorDlg::on_unitsCB_clicked(bool checked)
ui->annularDiameter->blockSignals(true);
ui->annularDiameter->setValue(diameter * m_annularObsPercent * ((mm)? 1.: 1./25.4));
ui->annularDiameter->blockSignals(false);
- QSettings set;
- aperatureReduction = set.value("config aperatureReduction",0.).toDouble();
+
+ // Get aperatureReduction from draft (already loaded from persistent storage)
+ aperatureReduction = m_draft.apertureReduction;
ui->reduceValue->setValue(aperatureReduction * ((mm) ? 1. : 1./25.4));
ui->reduceValue->blockSignals(false);
From 5bbac225aaaa85f3191422dc5db8729d3d7cfee2 Mon Sep 17 00:00:00 2001
From: Julien STAUB
Date: Sat, 8 Aug 2026 10:43:21 +0200
Subject: [PATCH 05/20] separate some conveniance path from mirror settings
---
astigstatsdlg.cpp | 4 ++--
igramarea.cpp | 4 +++-
igramintensity.cpp | 4 ++--
mainwindow.cpp | 4 +++-
percentcorrectiondlg.cpp | 14 ++++++++------
settingsfacade.cpp | 10 ++++++++++
settingsfacade.h | 6 ++++++
settingsstores.cpp | 16 ++++++++++++++++
settingsstores.h | 16 ++++++++++++++++
settingsstores_fields.inc | 7 +++++--
standastigwizard.cpp | 6 ++++--
statsview.cpp | 10 ++++------
surfacemanager.cpp | 3 ++-
unwraperrorsview.cpp | 3 ++-
14 files changed, 83 insertions(+), 24 deletions(-)
diff --git a/astigstatsdlg.cpp b/astigstatsdlg.cpp
index 9992af56..1301e2f9 100644
--- a/astigstatsdlg.cpp
+++ b/astigstatsdlg.cpp
@@ -1,5 +1,6 @@
#include "astigstatsdlg.h"
#include "ui_astigstatsdlg.h"
+#include "settingsfacade.h"
#include "circleutils.h"
#include "circle.h"
#include
@@ -489,8 +490,7 @@ void astigStatsDlg::showItem(const QVariant &item, bool on, int /*ndx*/){
void astigStatsDlg::on_zernikePB_pressed()
{
- QSettings set;
- QString path = set.value("mirrorConfigFile").toString();
+ QString path = SettingsFacade::instance().appStore().load().mirrorConfigFile;
QFile fn(path);
QFileInfo info(fn.fileName());
QString dd = info.dir().absolutePath();
diff --git a/igramarea.cpp b/igramarea.cpp
index 9f05a970..a58cf5d6 100644
--- a/igramarea.cpp
+++ b/igramarea.cpp
@@ -22,6 +22,7 @@
#endif
#include "IgramArea.h"
+#include "settingsfacade.h"
#include "Circleoutline.h"
#include
#include
@@ -2481,7 +2482,8 @@ void IgramArea::save(){
mimeTypeFilters.append(mimeTypeName);
mimeTypeFilters.sort();
QSettings settings;
- QString lastPath = settings.value("projectPath",".").toString();
+ QString lastPath = SettingsFacade::instance().appStore().load().projectPath;
+ if (lastPath.isEmpty()) lastPath = ".";
QString filters = QStringList(mimeTypeFilters.mid(1,6)).join(" ");
diff --git a/igramintensity.cpp b/igramintensity.cpp
index c074fc0b..055a1898 100644
--- a/igramintensity.cpp
+++ b/igramintensity.cpp
@@ -17,6 +17,7 @@
****************************************************************************/
#include "igramintensity.h"
#include "ui_igramintensity.h"
+#include "settingsfacade.h"
#include
#include
#include
@@ -58,8 +59,7 @@ void igramIntensity::on_showGreen_clicked(bool checked)
void igramIntensity::on_pushButton_clicked()
{
- QSettings set;
- QString path = set.value("mirrorConfigFile").toString();
+ QString path = SettingsFacade::instance().appStore().load().mirrorConfigFile;
QFile fn(path);
QFileInfo info(fn.fileName());
QString dd = info.dir().absolutePath();
diff --git a/mainwindow.cpp b/mainwindow.cpp
index fcac91b9..363b13f2 100644
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -18,6 +18,7 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "spdlog/spdlog.h"
+#include "settingsfacade.h"
#include
#include
#include
@@ -1996,7 +1997,8 @@ void MainWindow::on_actionSave_curent_profile_triggered()
if (m_profilePlot->m_wf == 0)
return;
QSettings settings;
- QString lastPath = settings.value("projectPath",".").toString();
+ QString lastPath = SettingsFacade::instance().appStore().load().projectPath;
+ if (lastPath.isEmpty()) lastPath = ".";
QString fName = QFileDialog::getSaveFileName(0,
tr("Save Profile"), lastPath + "//profile.txt");
if (fName.isEmpty())
diff --git a/percentcorrectiondlg.cpp b/percentcorrectiondlg.cpp
index 20816d84..8ace9092 100644
--- a/percentcorrectiondlg.cpp
+++ b/percentcorrectiondlg.cpp
@@ -1,5 +1,6 @@
#include "percentcorrectiondlg.h"
#include "ui_percentcorrectiondlg.h"
+#include "settingsfacade.h"
#include "qwt_plot_grid.h"
#include "qwt_scale_div.h"
#include "qwt_plot_barchart.h"
@@ -715,9 +716,7 @@ void percentCorrectionDlg::on_help_clicked()
void percentCorrectionDlg::on_loadZones_clicked()
{
-
- QSettings set;
- QString path = set.value("projectPath").toString();
+ QString path = SettingsFacade::instance().appStore().load().projectPath;
QString extensionTypes(tr( "zone file (*.zones)"));
QString fileName = QFileDialog::getOpenFileName(0,
tr("Read zone file"), path,
@@ -754,8 +753,7 @@ void percentCorrectionDlg::on_loadZones_clicked()
void percentCorrectionDlg::on_saveZones_clicked()
{
- QSettings set;
- QString path = set.value("projectPath").toString();
+ QString path = SettingsFacade::instance().appStore().load().projectPath;
QString extensionTypes(tr( "zone file (*.zones)"));
QString fileName = QFileDialog::getSaveFileName(0,
tr("Save zone file"), path,
@@ -774,7 +772,11 @@ void percentCorrectionDlg::on_saveZones_clicked()
out << jsonString;
file.close();
- set.setValue("projectPath", QFileInfo(fileName).absolutePath());
+
+ // Update and persist application settings via facade
+ ApplicationSettings appSettings = SettingsFacade::instance().appStore().load();
+ appSettings.projectPath = QFileInfo(fileName).absolutePath();
+ SettingsFacade::instance().appStore().save(appSettings);
}
diff --git a/settingsfacade.cpp b/settingsfacade.cpp
index e765494a..f3b887d1 100644
--- a/settingsfacade.cpp
+++ b/settingsfacade.cpp
@@ -35,3 +35,13 @@ const ContourSettingsStore &SettingsFacade::contourStore() const
{
return m_contourStore;
}
+
+ApplicationSettingsStore &SettingsFacade::appStore()
+{
+ return m_appStore;
+}
+
+const ApplicationSettingsStore &SettingsFacade::appStore() const
+{
+ return m_appStore;
+}
diff --git a/settingsfacade.h b/settingsfacade.h
index e1f54cd7..f9ae4085 100644
--- a/settingsfacade.h
+++ b/settingsfacade.h
@@ -24,6 +24,11 @@ class SettingsFacade
ContourSettingsStore &contourStore();
const ContourSettingsStore &contourStore() const;
+ /** @brief Accessor for application-wide path settings (project path, file paths, etc.). */
+ ApplicationSettingsStore &appStore();
+ /** @brief Const accessor for application-wide path settings. */
+ const ApplicationSettingsStore &appStore() const;
+
private:
SettingsFacade() = default; // Enforce singleton
@@ -31,6 +36,7 @@ class SettingsFacade
MirrorSettingsStore m_mirrorStore;
GeneralProcessingSettingsStore m_generalProcessingStore;
ContourSettingsStore m_contourStore;
+ ApplicationSettingsStore m_appStore;
};
#endif // SETTINGSFACADE_H
diff --git a/settingsstores.cpp b/settingsstores.cpp
index c088cf2c..1829cd91 100644
--- a/settingsstores.cpp
+++ b/settingsstores.cpp
@@ -56,5 +56,21 @@ void ContourSettingsStore::save(const ContourSettings &value) const
SETTINGS_STORE_FOR_EACH_CONTOUR_FIELD(SETTINGS_STORE_SAVE_FIELD_TO_QSETTINGS)
}
+ApplicationSettings ApplicationSettingsStore::load() const
+{
+ QSettings s;
+
+ ApplicationSettings value{};
+ SETTINGS_STORE_FOR_EACH_APPLICATION_FIELD(SETTINGS_STORE_LOAD_FIELD_FROM_QSETTINGS)
+
+ return value;
+}
+
+void ApplicationSettingsStore::save(const ApplicationSettings &value) const
+{
+ QSettings s;
+ SETTINGS_STORE_FOR_EACH_APPLICATION_FIELD(SETTINGS_STORE_SAVE_FIELD_TO_QSETTINGS)
+}
+
#undef SETTINGS_STORE_LOAD_FIELD_FROM_QSETTINGS
#undef SETTINGS_STORE_SAVE_FIELD_TO_QSETTINGS
diff --git a/settingsstores.h b/settingsstores.h
index bb167bb0..12c26b88 100644
--- a/settingsstores.h
+++ b/settingsstores.h
@@ -56,6 +56,22 @@ class ContourSettingsStore {
void save(const ContourSettings &value) const;
};
+
+
+struct ApplicationSettings {
+ SETTINGS_STORE_FOR_EACH_APPLICATION_FIELD(SETTINGS_STORE_DECLARE_STRUCT_FIELD)
+};
+
+class ApplicationSettingsStore {
+private:
+ friend class SettingsFacade;
+ ApplicationSettingsStore() = default;
+
+public:
+ ApplicationSettings load() const;
+ void save(const ApplicationSettings &value) const;
+};
+
#undef SETTINGS_STORE_DECLARE_STRUCT_FIELD
#endif // SETTINGSSTORES_H
diff --git a/settingsstores_fields.inc b/settingsstores_fields.inc
index d34146e2..70a84ca8 100644
--- a/settingsstores_fields.inc
+++ b/settingsstores_fields.inc
@@ -18,9 +18,12 @@
FIELD(int, outlineShape, 0, "outlineShape", toInt) \
FIELD(double, ellipseMinorAxis, 50.0, "ellipseMinorAxis", toDouble) \
FIELD(bool, apertureReductionEnabled, false, "configAperatureReductionChecked", toBool) \
- FIELD(double, apertureReduction, 0.0, "config aperatureReduction", toDouble) \
+ FIELD(double, apertureReduction, 0.0, "config aperatureReduction", toDouble)
+
+#define SETTINGS_STORE_FOR_EACH_APPLICATION_FIELD(FIELD) \
FIELD(QString, projectPath, QString(), "projectPath", toString) \
- FIELD(QString, mirrorConfigFile, QString(), "mirrorConfigFile", toString)
+ FIELD(QString, mirrorConfigFile, QString(), "mirrorConfigFile", toString) \
+ FIELD(QString, lastPath, QString(), "lastPath", toString)
#define SETTINGS_STORE_FOR_EACH_GENERAL_FIELD(FIELD) \
FIELD(bool, useMakeStarTest, false, "useMakeStarTest", toBool) \
diff --git a/standastigwizard.cpp b/standastigwizard.cpp
index 4f7b9489..e3395b6b 100644
--- a/standastigwizard.cpp
+++ b/standastigwizard.cpp
@@ -17,6 +17,7 @@
****************************************************************************/
#include "standastigwizard.h"
#include "ui_standastigwizard.h"
+#include "settingsfacade.h"
#include "spdlog/spdlog.h"
#include
#include
@@ -133,7 +134,8 @@ makeAverages::makeAverages(QWidget *parent)
}
void define_input::pdfNamesPressed(){
QSettings set;
- QString standReportPath = set.value("stand report path", mirrorDlg::get_Instance()->getProjectPath()).toString();
+ QString standReportPath = SettingsFacade::instance().appStore().load().projectPath;
+ if (standReportPath.isEmpty()) standReportPath = mirrorDlg::get_Instance()->getProjectPath();
QString fileName = QFileDialog::getSaveFileName((QWidget* )0, "Export PDF", standReportPath + "/stand.pdf" ,
"*.pdf");
if (fileName.isEmpty())
@@ -227,7 +229,7 @@ define_input::define_input(QWidget *parent)
connect(runpb, &QAbstractButton::pressed, this, &define_input::compute);
QSettings settings;
- QString lastPath = settings.value("projectPath","").toString();
+ QString lastPath = SettingsFacade::instance().appStore().load().projectPath;
basePath = new QLineEdit(settings.value("rotation base path",lastPath).toString());
basePath->setToolTip("Directory were rotation files are stored.");
QPushButton *browsePath = new QPushButton("...");
diff --git a/statsview.cpp b/statsview.cpp
index bc19e68a..81b8707a 100644
--- a/statsview.cpp
+++ b/statsview.cpp
@@ -1,5 +1,6 @@
#include "statsview.h"
#include "ui_statsview.h"
+#include "settingsfacade.h"
#include
#include "wftstats.h"
#include "surfacemanager.h"
@@ -173,8 +174,7 @@ void statsView::on_checkBox_2_toggled(bool checked)
void statsView::on_saveImg_clicked()
{
- QSettings settings;
- QString path = settings.value("projectPath").toString();
+ QString path = SettingsFacade::instance().appStore().load().projectPath;
QFile fn(path);
QString csvName = path + "/stats.pdf";
QString name = QFileInfo(csvName).absoluteFilePath() + "/stats.png";
@@ -226,8 +226,7 @@ QString statsView::title(const QString &dir){
void statsView::on_SaveCSV_clicked()
{
- QSettings settings;
- QString path = settings.value("projectPath").toString();
+ QString path = SettingsFacade::instance().appStore().load().projectPath;
QFile fn(path);
QFileInfo info(fn.fileName());
QString csvName = path + "/stats.csv";
@@ -293,8 +292,7 @@ void statsView::on_SaveCSV_clicked()
void statsView::on_savePdf_clicked()
{
- QSettings settings;
- QString path = settings.value("projectPath").toString();
+ QString path = SettingsFacade::instance().appStore().load().projectPath;
QFile fn(path);
QFileInfo info(fn.fileName());
QString csvName = path + "/stats.pdf";
diff --git a/surfacemanager.cpp b/surfacemanager.cpp
index 228f2e35..74922ba0 100644
--- a/surfacemanager.cpp
+++ b/surfacemanager.cpp
@@ -17,6 +17,7 @@
****************************************************************************/
#include "surfacemanager.h"
#include "spdlog/spdlog.h"
+#include "settingsfacade.h"
#include
#include
#include
@@ -3404,7 +3405,7 @@ bool QPointFLessThan(QPointF p1, QPointF p2){
void SurfaceManager::tiltAnalysis(){
QSettings set;
- QString path = set.value("mirrorConfigFile").toString();
+ QString path = SettingsFacade::instance().appStore().load().mirrorConfigFile;
QFile fn(path);
QFileInfo info(fn.fileName());
QString dd = info.dir().absolutePath();
diff --git a/unwraperrorsview.cpp b/unwraperrorsview.cpp
index 2eea6f8b..908dd266 100644
--- a/unwraperrorsview.cpp
+++ b/unwraperrorsview.cpp
@@ -1,5 +1,6 @@
#include "unwraperrorsview.h"
#include "ui_unwraperrorsview.h"
+#include "settingsfacade.h"
#include
#include
#include
@@ -71,7 +72,7 @@ unwrapErrorsView::~unwrapErrorsView()
void unwrapErrorsView::on_save_clicked()
{
QSettings set;
- QString path = set.value("mirrorConfigFile").toString();
+ QString path = SettingsFacade::instance().appStore().load().mirrorConfigFile;
QFile fn(path);
QFileInfo info(fn.fileName());
QString dd = info.dir().absolutePath();
From abcc92794d83a7e21c0b9b43259ee8c7767cb0eb Mon Sep 17 00:00:00 2001
From: Julien STAUB
Date: Sat, 8 Aug 2026 11:07:55 +0200
Subject: [PATCH 06/20] all access to public members done through accesor. TODO
remove members
---
averagewavefrontfilesdlg.cpp | 2 +-
dftarea.cpp | 4 +--
foucaultview.cpp | 24 ++++++-------
igramarea.cpp | 2 +-
mainwindow.cpp | 8 ++---
metricsdisplay.cpp | 4 +--
mirrordlg.cpp | 4 +--
mirrordlg.h | 6 ++++
nullvariationdlg.cpp | 8 ++---
percentcorrectiondlg.cpp | 4 +--
profileplot.cpp | 6 ++--
reportdlg.cpp | 2 +-
simigramdlg.cpp | 6 ++--
simulationsview.cpp | 6 ++--
standastigwizard.cpp | 2 +-
statsview.cpp | 8 ++---
surfacemanager.cpp | 70 ++++++++++++++++++------------------
wftstats.cpp | 14 ++++----
zernikeprocess.cpp | 40 ++++++++++-----------
19 files changed, 113 insertions(+), 107 deletions(-)
diff --git a/averagewavefrontfilesdlg.cpp b/averagewavefrontfilesdlg.cpp
index 7fc615f0..4b7b6f5d 100644
--- a/averagewavefrontfilesdlg.cpp
+++ b/averagewavefrontfilesdlg.cpp
@@ -66,7 +66,7 @@ void averageWaveFrontFilesDlg::on_process_clicked()
sm->generateSurfacefromWavefront(wf);
cv::Scalar mean,std;
cv::meanStdDev(wf->workData,mean,std,wf->workMask);
- double stdVal = std.val[0]* md->lambda/outputLambda;
+ double stdVal = std.val[0]* md->currentSettings().lambda/outputLambda;
if (stdVal > filterRMS){
QFileInfo info(name);
QString item = QString("%1 RMS:%2").arg(info.baseName()).arg(stdVal, 0, 'f');
diff --git a/dftarea.cpp b/dftarea.cpp
index fa7d9962..34b68b33 100644
--- a/dftarea.cpp
+++ b/dftarea.cpp
@@ -1032,8 +1032,8 @@ void DFTArea::makeSurface(){
mirrorDlg *md = mirrorDlg::get_Instance();
- if (md->fringeSpacing != 1.){
- result *= md->fringeSpacing;
+ if (md->currentSettings().fringeSpacing != 1.){
+ result *= md->currentSettings().fringeSpacing;
}
if (md->isEllipse()) {
diff --git a/foucaultview.cpp b/foucaultview.cpp
index 93c8f3c9..8529394a 100644
--- a/foucaultview.cpp
+++ b/foucaultview.cpp
@@ -203,7 +203,7 @@ void foucaultView::drawGridOverlay(QImage &img) {
int maxPixelRadius = w / 2;
mirrorDlg *md = mirrorDlg::get_Instance();
- double mirrorRadiusMM = md->diameter / 2.0;
+ double mirrorRadiusMM = md->currentSettings().diameter / 2.0;
// 3. Determine physics-to-pixel scale
double stepSizeMM = 0;
@@ -298,8 +298,8 @@ void foucaultView::setSurface(wavefront *wf){
double offset = set.value("foucault roc offset", 0.).toDouble();
m_wf = wf;
mirrorDlg *md = mirrorDlg::get_Instance();
- double rad = md->diameter/2.;
- double FL = md->roc/2.;
+ double rad = md->currentSettings().diameter/2.;
+ double FL = md->currentSettings().roc/2.;
double mul = (ui->useMM->isChecked()) ? 1. : 1/25.4;
m_sag = mul * (rad * rad) /( 4 * FL);
m_sag = round(100 * m_sag)/100.;
@@ -362,9 +362,9 @@ QImage foucaultView::generateOpticalTestImage(OpticalTestType type, wavefront* w
double coc_offset_mm = s.rocOffset * unitMultiplyer;
// Physics geometry
- double r2 = (md->diameter / 2.0) * (md->diameter / 2.0);
- double b = md->roc + coc_offset_mm;
- double pv = (sqrt(r2 + (md->roc * md->roc)) - (sqrt(r2 + b * b) - coc_offset_mm)) / (md->lambda * 1.E-6);
+ double r2 = (md->currentSettings().diameter / 2.0) * (md->currentSettings().diameter / 2.0);
+ double b = md->currentSettings().roc + coc_offset_mm;
+ double pv = (sqrt(r2 + (md->currentSettings().roc * md->currentSettings().roc)) - (sqrt(r2 + b * b) - coc_offset_mm)) / (md->currentSettings().lambda * 1.E-6);
double z3 = pv / moving_constant;
double effectiveZ3 = (type == OpticalTestType::Ronchi) ? (s.ronchiX * z3) : z3;
@@ -377,20 +377,20 @@ QImage foucaultView::generateOpticalTestImage(OpticalTestType type, wavefront* w
SimulationsView *sv = SimulationsView::getInstance(0);
sv->setSurface(wf);
- bool oldDoNull = md->doNull;
+ bool oldDoNull = md->currentSettings().doNull;
if (bAutoCollimate == false)
- md->doNull = false; // this is normal foucault/ronchi so we *don't* subtract the null (autcoCollimate ronchi or foucault mode will typically subtract the null)
+ md->m_draft.doNull = false; // this is normal foucault/ronchi so we *don't* subtract the null (autcoCollimate ronchi or foucault mode will typically subtract the null)
cv::Mat surf_fft = sv->computeStarTest(s.heightMultiply * sv->nulledSurface(effectiveZ3), size, actualPad, true);
wf->InputZerns = originalZerns; // Restore state immediately
- md->doNull = oldDoNull;
+ md->m_draft.doNull = oldDoNull;
// 3. Mask Generation
cv::Mat mask = cv::Mat::zeros(size, size, CV_64FC1);
cv::Mat sourceSlit = cv::Mat::zeros(size, size, CV_64FC1);
int hx = (size - 1) / 2 + s.lateralOffset;
- double pixwidth = s.outputLambda * 1.E-6 * (0.5 * md->roc / md->diameter) * 2. / (25.4 * actualPad);
+ double pixwidth = s.outputLambda * 1.E-6 * (0.5 * md->currentSettings().roc / md->currentSettings().diameter) * 2. / (25.4 * actualPad);
if (type == OpticalTestType::Ronchi) {
double lpi_val = s.lpi * (s.useMM ? 25.4 : 1.0);
@@ -954,8 +954,8 @@ void foucaultView::on_RonchiX_valueChanged(double arg1)
void foucaultView::on_pushButton_clicked()
{
mirrorDlg *md = mirrorDlg::get_Instance();
- double rad = md->diameter/2.;
- double FL = md->roc/2.;
+ double rad = md->currentSettings().diameter/2.;
+ double FL = md->currentSettings().roc/2.;
double mul = (ui->useMM->isChecked()) ? 1. : 1/25.4;
m_sag = mul * (rad * rad) /( 4 * FL);
m_sag = round(100 * m_sag)/100.;
diff --git a/igramarea.cpp b/igramarea.cpp
index a58cf5d6..871eea48 100644
--- a/igramarea.cpp
+++ b/igramarea.cpp
@@ -883,7 +883,7 @@ void IgramArea::useAnnulusforCenterOutine(){
if (m_current_boundry == CenterOutline) {
mirrorDlg *md = mirrorDlg::get_Instance();
- double rad = m_outside.m_radius * md->m_annularObsPercent;
+ double rad = m_outside.m_radius * md->currentSettings().annulusPercent;
double cx = m_outside.m_center.x();
double cy = m_outside.m_center.y();
diff --git a/mainwindow.cpp b/mainwindow.cpp
index 363b13f2..a597f97b 100644
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -592,16 +592,16 @@ void MainWindow::updateMetrics(wavefront& wf){
metrics->setZernTitle(ztitle);
double z8 = zernTablemodel->values[8];
double BestSC;
- if (m_mirrorDlg->doNull && wf.useSANull){
+ if (m_mirrorDlg->currentSettings().doNull && wf.useSANull){
BestSC = z8/m_mirrorDlg->z8;
}
else {
- BestSC = m_mirrorDlg->cc +z8/m_mirrorDlg->z8;
+ BestSC = m_mirrorDlg->currentSettings().cc +z8/m_mirrorDlg->z8;
}
metrics->setOutputLambda(outputLambda);
- metrics->setWavePerFringe(m_mirrorDlg->fringeSpacing, m_mirrorDlg->lambda);
- if (m_mirrorDlg->doNull)
+ metrics->setWavePerFringe(m_mirrorDlg->currentSettings().fringeSpacing, m_mirrorDlg->currentSettings().lambda);
+ if (m_mirrorDlg->currentSettings().doNull)
metrics->mCC->setText(QString("%1").arg(BestSC, 6 ,'f', 3));
else {
metrics->mCC->setText("NA");
diff --git a/metricsdisplay.cpp b/metricsdisplay.cpp
index 772b3fcf..493c57c2 100644
--- a/metricsdisplay.cpp
+++ b/metricsdisplay.cpp
@@ -58,8 +58,8 @@ void metricsDisplay::setWavePerFringe(double val, double lambda){
ui->wavesPerFringe->setText(QString("Waves Per Fringe: %1").arg(val, 2, 'f', 1));
ui->lambda->setText(QString("Igram laser wavelength: %1 nm").arg(lambda, 6, 'f', 2));
mirrorDlg *md = mirrorDlg::get_Instance();
- QString donull = (md->doNull) ? (QString("SANull: %1").arg(md->z8 * md->cc, 6, 'f', 4)) : "";
- ui->desiredConicLb->setText(QString("Desired Conic: %1 ").arg( md->cc, 6, 'f', 2) + donull);
+ QString donull = (md->currentSettings().doNull) ? (QString("SANull: %1").arg(md->currentSettings().z8 * md->currentSettings().cc, 6, 'f', 4)) : "";
+ ui->desiredConicLb->setText(QString("Desired Conic: %1 ").arg( md->currentSettings().cc, 6, 'f', 2) + donull);
if (md->isEllipse()){
ui->desiredConicLb->setText("");
ui->zernTitle->setText("Zernike Values not computed for Flats");
diff --git a/mirrordlg.cpp b/mirrordlg.cpp
index bd7684b5..620bef09 100644
--- a/mirrordlg.cpp
+++ b/mirrordlg.cpp
@@ -137,7 +137,7 @@ double mirrorDlg::getMinorAxis(){
}
bool mirrorDlg::isEllipse(){
- return m_outlineShape == ELLIPSE;
+ return m_draft.outlineShape == ELLIPSE;
}
void mirrorDlg::saveJson(const QString &fileName){
QJsonObject jDoc, jMirror,jIgram, jEllipse, jAnnulus;
@@ -449,7 +449,7 @@ void mirrorDlg::on_ReadBtn_clicked()
loadFile(fileName);
}
QString mirrorDlg::getProjectPath(){
- return m_projectPath;
+ return m_draft.projectPath;
}
void mirrorDlg::on_diameter_textChanged(const QString &arg1) {
diff --git a/mirrordlg.h b/mirrordlg.h
index 64130d11..16fd8fca 100644
--- a/mirrordlg.h
+++ b/mirrordlg.h
@@ -74,6 +74,12 @@ class mirrorDlg : public QDialog
void setMinorAxis(double val);
bool m_aperatureReductionEnabled;
void setObsPercent(double obs);
+
+ /** @brief Access current mirror settings (read-only snapshot).
+ * Returns the draft which is the canonical storage for all mirror config.
+ * All member variables are kept in sync with this for backward compatibility. */
+ const MirrorSettings& currentSettings() const { return m_draft; }
+
private slots:
void on_ReadBtn_clicked();
diff --git a/nullvariationdlg.cpp b/nullvariationdlg.cpp
index a0612b0f..da231276 100644
--- a/nullvariationdlg.cpp
+++ b/nullvariationdlg.cpp
@@ -26,8 +26,8 @@ nullVariationDlg::nullVariationDlg(QWidget *parent) :
ui->roc->blockSignals(true);
ui->diameter->blockSignals(true);
- ui->diameter->setText(QString::number(md->diameter));
- ui->roc->setText(QString::number(md->roc));
+ ui->diameter->setText(QString::number(md->currentSettings().diameter));
+ ui->roc->setText(QString::number(md->currentSettings().roc));
ui->roc->blockSignals(false);
ui->diameter->blockSignals(false);
@@ -151,7 +151,7 @@ void nullVariationDlg::calculate()
double roc = ui->roc->text().toDouble() * mul;
mirrorDlg *md = mirrorDlg::get_Instance();
- double lambda = md->lambda;
+ double lambda = md->currentSettings().lambda;
double center = 1.5 * pow(diam,4) * 1000000. /(384. * lambda * pow(roc,3));
//qDebug() << center/1.5;
@@ -190,7 +190,7 @@ void nullVariationDlg::on_ComputeSim_clicked()
double roc = ui->roc->text().toDouble() * mul;
mirrorDlg *md = mirrorDlg::get_Instance();
- double lambda = md->lambda;
+ double lambda = md->currentSettings().lambda;
double center = 1.5 * pow(diam,4) * 1000000. /(384. * lambda * pow(roc,3));
std::default_random_engine generator(time(0));
std::default_random_engine g2(time(0) + 1000);
diff --git a/percentcorrectiondlg.cpp b/percentcorrectiondlg.cpp
index 8ace9092..898b6247 100644
--- a/percentcorrectiondlg.cpp
+++ b/percentcorrectiondlg.cpp
@@ -354,7 +354,7 @@ QPolygonF percentCorrectionDlg::makePercentages(surfaceData *surf){
ActualZoneKnife << 0.0;
mirrorDlg *md = mirrorDlg::get_Instance();
- double nullval = md->z8 * md->cc; // null value was computed at the igram wavevlength
+ double nullval = md->currentSettings().z8 * md->currentSettings().cc; // null value was computed at the igram wavevlength
nullval *= m_lambda_nm/m_outputLambda; // only data from the profile needs the null but it's data is at the output wavelength;
// process each zone center
@@ -400,7 +400,7 @@ QPolygonF percentCorrectionDlg::makePercentages(surfaceData *surf){
void percentCorrectionDlg::plotProfile(){
mirrorDlg *md = mirrorDlg::get_Instance();
- double nullval = md->z8 * md->cc;
+ double nullval = md->currentSettings().z8 * md->currentSettings().cc;
for (int i = 0; i < surfs.length(); ++ i) {
QwtPlotCurve *Curve = new QwtPlotCurve();
diff --git a/profileplot.cpp b/profileplot.cpp
index 87096ce8..2073a854 100644
--- a/profileplot.cpp
+++ b/profileplot.cpp
@@ -526,7 +526,7 @@ void ProfilePlot::make_correction_graph(){
QColor penColor = Settings2::m_profile->getColor(i);
// give the plot routine new zernike values for each curve.
mirrorDlg *md = mirrorDlg::get_Instance();
- surfs << new surfaceData( md->lambda, penColor, theZerns ,name);
+ surfs << new surfaceData( md->currentSettings().lambda, penColor, theZerns ,name);
}
QPolygonF avg = createAverageProfile(1., wfs->at(list[0]),true);
@@ -1170,11 +1170,11 @@ void ProfilePlot::CreateWaveFrontFromAverage(){
//create a matrix from the avgRadius profile.
mirrorDlg *md = mirrorDlg::get_Instance();
// first add the null back into it.
- if (md->doNull){
+ if (md->currentSettings().doNull){
for (unsigned int i = 0; i < avgRadius.size(); ++i) {
double R2 = (double(i))/(avgRadius.size() -1);
R2 *= R2;
- avgRadius[i] += md->z8 * md->cc * (1. + R2 * (-6 + 6. * R2));;
+ avgRadius[i] += md->currentSettings().z8 * md->currentSettings().cc * (1. + R2 * (-6 + 6. * R2));;
}
}
cv::Mat result = createInterpolatedCircularSurface(avgRadius);
diff --git a/reportdlg.cpp b/reportdlg.cpp
index ad5fda56..cd76deab 100644
--- a/reportdlg.cpp
+++ b/reportdlg.cpp
@@ -9,7 +9,7 @@ ReportDlg::ReportDlg(QPrinter *p, QWidget *parent) :
ui(new Ui::ReportDlg)
{
ui->setupUi(this);
- ui->title->setText( mirrorDlg::get_Instance()->m_name);
+ ui->title->setText(mirrorDlg::get_Instance()->currentSettings().mirrorName);
QSettings set;
contourWidth = set.value("ReprotContourWidth", 1.).toDouble();
ui->contourWidth->setValue(contourWidth);
diff --git a/simigramdlg.cpp b/simigramdlg.cpp
index ac3567e2..d128754a 100644
--- a/simigramdlg.cpp
+++ b/simigramdlg.cpp
@@ -186,7 +186,7 @@ simIgramDlg::simIgramDlg(QWidget *parent) :
zernikes[2] = ytilt;
size = s.value("simSize", 601).toDouble();
ui->sizeSB->setValue(size);
- if (mirrorDlg::get_Instance()->cc == 0.){
+ if (mirrorDlg::get_Instance()->currentSettings().cc == 0.){
ui->correctionPb->setChecked(false);
}
@@ -325,8 +325,8 @@ void simIgramDlg::on_editArbitrary_clicked()
{
UserDrawnProfileDlg * dlg = UserDrawnProfileDlg::get_instance();
mirrorDlg* md = mirrorDlg::get_Instance();
- if (md->diameter>0)
- dlg->setDiameter(md->diameter);
+ if (md->currentSettings().diameter>0)
+ dlg->setDiameter(md->currentSettings().diameter);
dlg->setModal(true);
dlg->exec();
if (dlg->bOkPressed == false)
diff --git a/simulationsview.cpp b/simulationsview.cpp
index 12fff464..ee49e826 100644
--- a/simulationsview.cpp
+++ b/simulationsview.cpp
@@ -117,7 +117,7 @@ void SimulationsView::initMTFPlot(){
grid->enableXMin(true);
grid->setPen( Qt::gray, 0.0, Qt::DotLine );
grid->attach( ui->MTF);
- m_arcSecScaleDraw = new arcSecScaleDraw(mirrorDlg::get_Instance()->diameter);
+ m_arcSecScaleDraw = new arcSecScaleDraw(mirrorDlg::get_Instance()->currentSettings().diameter);
ui->MTF->setAxisScaleDraw(ui->MTF->xBottom, m_arcSecScaleDraw);
QwtPlotLegendItem *customLegend = new QwtPlotLegendItem();
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
@@ -221,7 +221,7 @@ cv::Mat SimulationsView::nulledSurface(double defocus){
CropGaussianBlur(nulled_surface, nulled_surface, blurRad, m_wf->m_outside, m_wf->m_inside);
}
- nulled_surface *= M2PI * md->lambda/outputLambda;
+ nulled_surface *= M2PI * md->currentSettings().lambda/outputLambda;
return nulled_surface;
}
@@ -663,7 +663,7 @@ void SimulationsView::on_MakePB_clicked()
// remove obstructions
cv::Mat noObstruction = savedMask.clone();
mirrorDlg *md = mirrorDlg::get_Instance();
- double r = md->obs * (2. * m_wf->m_outside.m_radius)/md->diameter;
+ double r = md->currentSettings().obstruction * (2. * m_wf->m_outside.m_radius)/md->currentSettings().diameter;
if (r > 0){
circle(noObstruction,Point(noObstruction.cols/2,noObstruction.cols/2),r, Scalar(255),-1);
diff --git a/standastigwizard.cpp b/standastigwizard.cpp
index e3395b6b..874ef690 100644
--- a/standastigwizard.cpp
+++ b/standastigwizard.cpp
@@ -192,7 +192,7 @@ define_input::define_input(QWidget *parent)
browsePb = new QPushButton("Add average Wavefront file to List");
QString pdfNameStr = set.value("stand pdf file", "stand.pdf").toString();
connect(browsePb, &QAbstractButton::pressed, this, &define_input::browse);
- AstigReportTitle = mirrorDlg::get_Instance()->m_name;
+ AstigReportTitle = mirrorDlg::get_Instance()->currentSettings().mirrorName;
AstigReportPdfName = mirrorDlg::get_Instance()->getProjectPath() + "/" + pdfNameStr;
title = new QLineEdit(AstigReportTitle);
pdfName = new QPushButton(AstigReportPdfName);
diff --git a/statsview.cpp b/statsview.cpp
index 81b8707a..cf161d32 100644
--- a/statsview.cpp
+++ b/statsview.cpp
@@ -269,9 +269,9 @@ void statsView::on_SaveCSV_clicked()
double v = wf->InputZerns[ndx];
// apply software Null if needed
- if (ndx == 8 and md->doNull)
- v -= md->z8 * md->cc;
- double Sigma = computeRMS(ndx,v) * md->lambda/outputLambda;
+ if (ndx == 8 and md->currentSettings().doNull)
+ v -= md->currentSettings().z8 * md->currentSettings().cc;
+ double Sigma = computeRMS(ndx,v) * md->currentSettings().lambda/outputLambda;
if (ndx == 8) {
spherical << QPointF(row,Sigma);
@@ -279,7 +279,7 @@ void statsView::on_SaveCSV_clicked()
sphericaRunningAvg << QPointF(row,sperAvg/(i+1));
}
- mZerns.at(row,ndx) = Sigma * md->lambda/outputLambda;
+ mZerns.at(row,ndx) = Sigma * md->currentSettings().lambda/outputLambda;
}
diff --git a/surfacemanager.cpp b/surfacemanager.cpp
index 74922ba0..6c4fd68c 100644
--- a/surfacemanager.cpp
+++ b/surfacemanager.cpp
@@ -396,7 +396,7 @@ void SurfaceManager::generateSurfacefromWavefront(wavefront * wf){
QGuiApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
autoInvertDlg dlg_ai;
dlg_ai.setMainLabel("Your wavefront may be inverted. What do you want to do?");
- dlg_ai.enableConic(md->cc != 0);
+ dlg_ai.enableConic(md->currentSettings().cc != 0);
dlg_ai.exec();
QGuiApplication::restoreOverrideCursor();
md->updateAutoInvertStatus();
@@ -404,7 +404,7 @@ void SurfaceManager::generateSurfacefromWavefront(wavefront * wf){
bool reverse = false;
if (m_inverseMode == invCONIC)
{
- if (md->cc != 0.0 && md->cc * wf->InputZerns[8] < 0.)
+ if (md->currentSettings().cc != 0.0 && md->currentSettings().cc * wf->InputZerns[8] < 0.)
reverse = true;
} else if (m_inverseMode == invINSIDE)
{
@@ -500,8 +500,8 @@ cv::Mat SurfaceManager::computeWaveFrontFromZernikes(int wx, int wy, std::vector
}
else {
if (en[z]){
- if (z == 8 && md->doNull)
- S1 += md->z8 * zpolar.zernike(z);
+ if (z == 8 && md->currentSettings().doNull)
+ S1 += md->currentSettings().z8 * zpolar.zernike(z);
S1 += zerns[z] * zpolar.zernike(z);
}
@@ -800,7 +800,7 @@ void SurfaceManager::useDemoWaveFront(){
if (rho <= 1.)
{
- double S1 = md->z8 * -.9 * zpolar.zernike(8) + .02* zpolar.zernike(9);
+ double S1 = md->currentSettings().z8 * -.9 * zpolar.zernike(8) + .02* zpolar.zernike(9);
result.at(j,i) = S1;
}
@@ -856,7 +856,7 @@ void SurfaceManager::surfaceSmoothGBValue(double value){
m_gbValue = value;
mirrorDlg *md = mirrorDlg::get_Instance();
- m_surfaceTools->setBlurText(QString("%1 mm").arg( .01 * value * md->diameter, 6, 'f', 2));
+ m_surfaceTools->setBlurText(QString("%1 mm").arg( .01 * value * md->currentSettings().diameter, 6, 'f', 2));
if (m_wavefronts.size() == 0)
return;
@@ -878,7 +878,7 @@ void SurfaceManager::surfaceSmoothGBEnabled(bool b){
rad = m_wavefronts[m_currentNdx]->m_outside.m_radius-1;
mirrorDlg *md = ((MainWindow*)parent())->m_mirrorDlg;
- double mmPerPixel = md->diameter/(2 * rad);
+ double mmPerPixel = md->currentSettings().diameter/(2 * rad);
m_surfaceTools->setBlurText(QString("%1 mm").arg(m_gbValue* mmPerPixel, 6, 'f', 2));
if (m_wavefronts.size() == 0)
return;
@@ -890,16 +890,16 @@ void SurfaceManager::computeMetrics(wavefront *wf){
mirrorDlg *md = mirrorDlg::get_Instance();
cv::Scalar mean,std;
cv::meanStdDev(wf->workData,mean,std,wf->workMask);
- wf->mean = mean.val[0] * md->lambda/outputLambda;
- wf->std = std.val[0]* md->lambda/outputLambda;
+ wf->mean = mean.val[0] * md->currentSettings().lambda/outputLambda;
+ wf->std = std.val[0]* md->currentSettings().lambda/outputLambda;
double mmin;
double mmax;
minMaxIdx(wf->workData, &mmin,&mmax);
- wf->min = mmin * md->lambda/outputLambda;
- wf->max = mmax * md->lambda/outputLambda;
+ wf->min = mmin * md->currentSettings().lambda/outputLambda;
+ wf->max = mmax * md->currentSettings().lambda/outputLambda;
((MainWindow*)(parent()))->zernTablemodel->setValues(wf->InputZerns, !wf->useSANull);
@@ -1118,9 +1118,9 @@ void SurfaceManager::createSurfaceFromPhaseMap(cv::Mat phase, CircleOutline outs
wf->m_inside = center;
wf->data = phase;
mirrorDlg *md = mirrorDlg::get_Instance();
- wf->diameter = md->diameter;
- wf->lambda = md->lambda;
- wf->roc = md->roc;
+ wf->diameter = md->currentSettings().diameter;
+ wf->lambda = md->currentSettings().lambda;
+ wf->roc = md->currentSettings().roc;
wf->dirtyZerns = true;
wf->wasSmoothed = false;
wf->regions = polyArea;
@@ -1137,9 +1137,9 @@ void SurfaceManager::createSurfaceFromPhaseMap(cv::Mat phase, CircleOutline outs
wavefront * SurfaceManager::readWaveFront(const QString &fileName){
mirrorDlg *md = mirrorDlg::get_Instance();
double xm,ym,radm;
- double roc = md->roc,
- lambda = md->lambda,
- diam = md->diameter;
+ double roc = md->currentSettings().roc,
+ lambda = md->currentSettings().lambda,
+ diam = md->currentSettings().diameter;
double xo, yo, rado;
wavefront *wf = new wavefront();
@@ -1326,11 +1326,11 @@ wavefront * SurfaceManager::readWaveFront(const QString &fileName){
wf->m_inside = CircleOutline(QPointF(xo,yo), rado);
- if (lambda != md->lambda){
+ if (lambda != md->currentSettings().lambda){
if (lambdResp == ASK){
QString message("The interferogram wavelength (");
message += QString("%1").arg( lambda, 6, 'f', 3) +
- ") Of the wavefront does not match the config value of " + QString("%1\n").arg(md->lambda, 6, 'f', 3) +
+ ") Of the wavefront does not match the config value of " + QString("%1\n").arg(md->currentSettings().lambda, 6, 'f', 3) +
"Do you want to make the config match?";
@@ -1352,11 +1352,11 @@ wavefront * SurfaceManager::readWaveFront(const QString &fileName){
}
}
- if (roundl(diam * 10) != roundl(md->diameter* 10))
+ if (roundl(diam * 10) != roundl(md->currentSettings().diameter* 10))
{
QString message("The mirror diameter (");
message += QString("%1").arg(diam, 6, 'f', 3) +
- ") Of the wavefront does not match the config value of " + QString("%1\n").arg(md->diameter, 6, 'f', 3) +
+ ") Of the wavefront does not match the config value of " + QString("%1\n").arg(md->currentSettings().diameter, 6, 'f', 3) +
"Do you want to make the config match?";
if (diamResp == ASK){
int resp = QMessageBox(QMessageBox::Information,"config", message,QMessageBox::Yes|QMessageBox::No |
@@ -1375,16 +1375,16 @@ wavefront * SurfaceManager::readWaveFront(const QString &fileName){
emit diameterChanged(diam);
}
else {
- diam = md->diameter;
+ diam = md->currentSettings().diameter;
}
}
- if (roundl(roc * 10.) != roundl(md->roc * 10.))
+ if (roundl(roc * 10.) != roundl(md->currentSettings().roc * 10.))
{
QString message("The mirror roc (");
message += QString("%1").arg(roc, 6, 'f', 3) +
- ") Of the wavefront does not match the config value of " + QString("%1\n").arg(md->roc, 6, 'f', 3) +
+ ") Of the wavefront does not match the config value of " + QString("%1\n").arg(md->currentSettings().roc, 6, 'f', 3) +
"Do you want to make the config match?";
//qDebug() << message;
if (rocResp == ASK){
@@ -1404,7 +1404,7 @@ wavefront * SurfaceManager::readWaveFront(const QString &fileName){
emit rocChanged(roc);
}
else {
- roc = md->roc;
+ roc = md->currentSettings().roc;
}
}
@@ -3009,9 +3009,9 @@ void SurfaceManager::report(){
+ QDate::currentDate().toString() +
" " +QTime::currentTime().toString()+"
DFTFringe Version:"+APP_VERSION+"");
- QString Diameter = (md->isEllipse()) ? " Horizontal Axis: " : " Diameter: " +QString().number(md->diameter,'f',1) ;
- QString ROC = (md->isEllipse()) ? "Vertical Axis: " + QString().number(md->m_verticalAxis) : "ROC: " + QString().number(md->roc,'f',1);
- QString FNumber = (md->isEllipse()) ? "" : "Fnumber: " + QString().number(md->FNumber,'f',1);
+ QString Diameter = (md->isEllipse()) ? " Horizontal Axis: " : " Diameter: " +QString().number(md->currentSettings().diameter,'f',1) ;
+ QString ROC = (md->isEllipse()) ? "Vertical Axis: " + QString().number(md->currentSettings().ellipseMinorAxis) : "ROC: " + QString().number(md->currentSettings().roc,'f',1);
+ QString FNumber = (md->isEllipse()) ? "" : "Fnumber: " + QString().number(md->currentSettings().roc/(2.0*md->currentSettings().diameter),'f',1);
QString BFC = (md->isEllipse()) ? " Flat" : "Best Fit CC: " +metrics->mCC->text();
QString html = ""
"
| " + Diameter + " mm | " + ROC + " mm | "
@@ -3019,9 +3019,9 @@ void SurfaceManager::report(){
"
| RMS: " + QString().number(wf->std,'f',3) +
QString(" waves at %1 nm | Strehl: ").arg(outputLambda, 6, 'f', 1) + metrics->mStrehl->text() +
" | " + BFC + " |
"
- "| " + ((md->isEllipse()) ? "":"Desired Conic: " + QString::number(md->cc)) + " | " +
- ((md->doNull) ? QString("SANull: %1").arg(md->z8 * md->cc, 6, 'f', 4) : "No software Null") + " | "
- "Waves per fringe: " + QString::number(md->fringeSpacing) + " Interferogram Wave length: "+ QString::number(md->lambda) + "nm |
"
+ "| " + ((md->isEllipse()) ? "":"Desired Conic: " + QString::number(md->currentSettings().cc)) + " | " +
+ ((md->currentSettings().doNull) ? QString("SANull: %1").arg(md->currentSettings().z8 * md->currentSettings().cc, 6, 'f', 4) : "No software Null") + " | "
+ "Waves per fringe: " + QString::number(md->currentSettings().fringeSpacing) + " Interferogram Wave length: "+ QString::number(md->currentSettings().lambda) + "nm |
"
"
";
// zerenike values
@@ -3029,8 +3029,8 @@ void SurfaceManager::report(){
if (!md->isEllipse()){
zerns = "
"
"" +
- ((!md->m_useAnnular) ? QString("Zernike Values at interferogram wavelength") :
- QString("Annular Zernike Values %1\% center hole").arg(100 * md->m_annularObsPercent, 6,'f',2))+
+ ((!md->currentSettings().useAnnulus) ? QString("Zernike Values at interferogram wavelength") :
+ QString("Annular Zernike Values %1\% center hole").arg(100 * md->currentSettings().annulusPercent, 6,'f',2))+
" |
"
"";
zerns.append("| Term | | ");
@@ -3042,8 +3042,8 @@ void SurfaceManager::report(){
val = m_surfaceTools->m_defocus;
enabled = true;
}
- if ( i == 8 && md->doNull){
- val -= md->z8 * md->cc;
+ if ( i == 8 && md->currentSettings().doNull){
+ val -= md->currentSettings().z8 * md->currentSettings().cc;
}
diff --git a/wftstats.cpp b/wftstats.cpp
index 3b4c876e..e728860d 100644
--- a/wftstats.cpp
+++ b/wftstats.cpp
@@ -139,10 +139,10 @@ void wftStats::computeZernStats( int ndx){
for (int i = 0; i < c.rows; ++i){
int row = (i + ndx) % c.rows;
- double v = computeRMS(ndx,c.at(row)) * outputLambda/md->lambda;
+ double v = computeRMS(ndx,c.at(row)) * outputLambda/md->currentSettings().lambda;
if (isPair){
cv::Mat c2 = m_Zerns.col(zern+1);
- double v2 = computeRMS(ndx,c2.at(row)) * outputLambda/md->lambda;
+ double v2 = computeRMS(ndx,c2.at(row)) * outputLambda/md->currentSettings().lambda;
double s = sqrt(v * v + v2 * v2);
v = s;
zname += " ";
@@ -214,9 +214,9 @@ void wftStats::computeWftStats( QVector wavefronts, int ndx){
double v = wf->InputZerns[ndx];
// apply software Null if needed
- if (ndx == 8 and md->doNull)
- v -= md->z8 * md->cc;
- double Sigma = computeRMS(ndx,v) * outputLambda/md->lambda;
+ if (ndx == 8 and md->currentSettings().doNull)
+ v -= md->currentSettings().z8 * md->currentSettings().cc;
+ double Sigma = computeRMS(ndx,v) * outputLambda/md->currentSettings().lambda;
if (ndx == 8) {
spherical << QPointF(row,Sigma);
@@ -294,9 +294,9 @@ void wftStats::computeWftRunningAvg( QVector wavefronts, int ndx){
cv::Mat avg = sum/(j+1);
cv::Scalar mean,std;
cv::meanStdDev(resized,mean,std,mask);
- double stdi = std.val[0]* md->lambda/outputLambda;
+ double stdi = std.val[0]* md->currentSettings().lambda/outputLambda;
cv::meanStdDev(avg,mean,std,mask);
- avgPoints << QPointF(j,std.val[0] * md->lambda/outputLambda);
+ avgPoints << QPointF(j,std.val[0] * md->currentSettings().lambda/outputLambda);
wftPoints << QPointF(j,stdi);
trueNdx << i;
}
diff --git a/zernikeprocess.cpp b/zernikeprocess.cpp
index d6ea4a52..e8bf66a6 100644
--- a/zernikeprocess.cpp
+++ b/zernikeprocess.cpp
@@ -381,7 +381,7 @@ void zernikeProcess::unwrap_to_zernikes(wavefront &wf, int zterms){
// if annular zernikes needed then do this instead of all the other stuff below this.
mirrorDlg *md = mirrorDlg::get_Instance();
- if (md->m_useAnnular) {
+ if (md->currentSettings().useAnnulus) {
initGrid(wf, 12);
ZernFitWavefront(wf);
@@ -491,12 +491,12 @@ cv::Mat zernikeProcess::null_unwrapped(wavefront&wf, std::vector zerns,
cv::Mat unwrapped = wf.data.clone();
- double scz8 = md->z8 * md->cc;
+ double scz8 = md->currentSettings().z8 * md->currentSettings().cc;
mirrorDlg *md = mirrorDlg::get_Instance();
- if (!md->doNull || !wf.useSANull){
+ if (!md->currentSettings().doNull || !wf.useSANull){
scz8 = 0.;
}
double midx = wf.m_outside.m_center.rx();
@@ -524,7 +524,7 @@ cv::Mat zernikeProcess::null_unwrapped(wavefront&wf, std::vector zerns,
// make a list of points on the surface containing their rho and theta values as well as their
// row column indexes in the matix that contanis the wave front.
// annular wave fronts already have this made elsewhere.
- if (!md->m_useAnnular){
+ if (!md->currentSettings().useAnnulus){
m_rhoTheta = rhotheta(nx ,wf.m_outside.m_radius, midx,midy, &wf);
if (m_lastusedAnnulus)
m_needsInit=true;
@@ -541,7 +541,7 @@ cv::Mat zernikeProcess::null_unwrapped(wavefront&wf, std::vector zerns,
rho = m_rhoTheta.row(0)(i);
theta = m_rhoTheta.row(1)(i);
- if (!md->m_useAnnular){
+ if (!md->currentSettings().useAnnulus){
zpolar = new zernikePolar(rho,theta, Z_TERMS);
}
@@ -550,8 +550,8 @@ cv::Mat zernikeProcess::null_unwrapped(wavefront&wf, std::vector zerns,
if (last_term > 7)
{
- if (md->doNull && enables[8]){
- if (!md->m_useAnnular)
+ if (md->currentSettings().doNull && enables[8]){
+ if (!md->currentSettings().useAnnulus)
nz -= scz8 * zpolar->zernike(8);
else {
nz -= scz8 * m_zerns(i, 8);
@@ -562,7 +562,7 @@ cv::Mat zernikeProcess::null_unwrapped(wavefront&wf, std::vector zerns,
for (int z = start_term; z < Z_TERMS; ++z)
{
if ((z == 3) && doDefocus){
- if (!md->m_useAnnular) {
+ if (!md->currentSettings().useAnnulus) {
nz += defocus * zpolar->zernike(z);
nz -= zerns[z] * zpolar->zernike(z);
}
@@ -572,7 +572,7 @@ cv::Mat zernikeProcess::null_unwrapped(wavefront&wf, std::vector zerns,
}
}
else if (!enables[z]){
- if (!md->m_useAnnular) {
+ if (!md->currentSettings().useAnnulus) {
nz -= zerns[z] * zpolar->zernike(z);
}
else {
@@ -581,7 +581,7 @@ cv::Mat zernikeProcess::null_unwrapped(wavefront&wf, std::vector zerns,
}
}
- if (!md->m_useAnnular){
+ if (!md->currentSettings().useAnnulus){
delete zpolar;
}
@@ -597,7 +597,7 @@ void zernikeProcess::fillVoid(wavefront &wf){
double ux,uy;
double rho,theta;
mirrorDlg *md = mirrorDlg::get_Instance();
- bool useannular = md->m_useAnnular;
+ bool useannular = md->currentSettings().useAnnulus;
if (wf.regions.size() > 0){
int x = wf.regions[0][0].x;
@@ -667,7 +667,7 @@ void zernikeProcess::fillVoid(wavefront &wf){
arma::rowvec r(rhov),t(thetav);
// now that we have the points in rho and theta get the zernike terms at each of those points
- arma::mat zerns = zapm( r.as_col(), t.as_col(), md->m_annularObsPercent, 12);
+ arma::mat zerns = zapm( r.as_col(), t.as_col(), md->currentSettings().annulusPercent, 12);
// compute the surface at each point by using the zernike poly at each point.
for (arma::uword i = 0; i < r.size(); ++i){
double S1 = 0.0;
@@ -748,7 +748,7 @@ void zernikeProcess::fillVoid(wavefront &wf){
arma::rowvec r(rhov),t(thetav);
// now that we have the points in rho and theta get the zernike terms at each of those points
- arma::mat zerns = zapm( r.as_col(), t.as_col(), md->m_annularObsPercent, 12);
+ arma::mat zerns = zapm( r.as_col(), t.as_col(), md->currentSettings().annulusPercent, 12);
// compute the surface at each point by using the zernike poly at each point.
for (arma::uword i = 0; i < r.size(); ++i){
double S1 = 0.0;
@@ -875,7 +875,7 @@ cv::Mat zernikeProcess::makeSurfaceFromZerns(int border, bool doColor){
mirrorDlg *md = mirrorDlg::get_Instance();
double r,g,b;
- spectral_color(r,g,b, md->lambda);
+ spectral_color(r,g,b, md->currentSettings().lambda);
if (doColor) {
result = cv::Vec4f(0.,125. * .5 * g, 125 * r, 125. * b);
}
@@ -914,9 +914,9 @@ cv::Mat zernikeProcess::makeSurfaceFromZerns(int border, bool doColor){
for (unsigned int z = 0; z < m_zerns.n_cols; ++z){
double val = dlg.zernikes[z];
if (z == 8){
- val = (dlg.doCorrection && md->doNull) ? md->cc * md->z8 * val * .01 : val;
+ val = (dlg.doCorrection && md->currentSettings().doNull) ? md->currentSettings().cc * md->currentSettings().z8 * val * .01 : val;
}
- S1 += val * m_zerns(i,z)/((doColor) ? md->fringeSpacing: 1.);
+ S1 += val * m_zerns(i,z)/((doColor) ? md->currentSettings().fringeSpacing: 1.);
int x = m_col[i];
int y = m_row[i];
@@ -948,8 +948,8 @@ arma::mat zernikeProcess::rhotheta( int width, double radius, double cx, double
bool useMask = false;
double centerR = 0.0;
mirrorDlg *md = mirrorDlg::get_Instance();
- if (md->m_useAnnular){
- centerR = md->m_annularObsPercent;
+ if (md->currentSettings().useAnnulus){
+ centerR = md->currentSettings().annulusPercent;
}
if (wf != 0){
useMask = true;
@@ -1079,8 +1079,8 @@ void zernikeProcess::initGrid(int width, double radius, double cx, double cy, in
double obsPercent = 0.;
bool shouldUseAnnulus = false;
mirrorDlg *md = mirrorDlg::get_Instance();
- if (md->m_useAnnular){
- obsPercent = md->m_annularObsPercent;
+ if (md->currentSettings().useAnnulus){
+ obsPercent = md->currentSettings().annulusPercent;
shouldUseAnnulus = true;
}
From 13e191e14a1c95ddae375a50789dbd55bb09631b Mon Sep 17 00:00:00 2001
From: Julien STAUB
Date: Sat, 8 Aug 2026 11:11:39 +0200
Subject: [PATCH 07/20] fix build
---
foucaultview.cpp | 11 ++++-------
metricsdisplay.cpp | 2 +-
mirrordlg.cpp | 31 +++++++++++++++++++------------
percentcorrectiondlg.cpp | 6 ++++--
profileplot.cpp | 2 +-
simulationsview.cpp | 6 ++++--
simulationsview.h | 2 +-
statsview.cpp | 2 +-
surfacemanager.cpp | 8 ++++----
wftstats.cpp | 2 +-
zernikeprocess.cpp | 10 +++++-----
zernikeprocess.h | 2 +-
12 files changed, 46 insertions(+), 38 deletions(-)
diff --git a/foucaultview.cpp b/foucaultview.cpp
index 8529394a..4e2d7641 100644
--- a/foucaultview.cpp
+++ b/foucaultview.cpp
@@ -377,14 +377,11 @@ QImage foucaultView::generateOpticalTestImage(OpticalTestType type, wavefront* w
SimulationsView *sv = SimulationsView::getInstance(0);
sv->setSurface(wf);
- bool oldDoNull = md->currentSettings().doNull;
- if (bAutoCollimate == false)
- md->m_draft.doNull = false; // this is normal foucault/ronchi so we *don't* subtract the null (autcoCollimate ronchi or foucault mode will typically subtract the null)
+ // For normal Foucault/Ronchi mode (not autocollimation), disable null correction
+ // Autocollimation mode applies null if configured; normal mode does not
+ bool applyNull = bAutoCollimate && md->currentSettings().doNull;
- cv::Mat surf_fft = sv->computeStarTest(s.heightMultiply * sv->nulledSurface(effectiveZ3), size, actualPad, true);
-
- wf->InputZerns = originalZerns; // Restore state immediately
- md->m_draft.doNull = oldDoNull;
+ cv::Mat surf_fft = sv->computeStarTest(s.heightMultiply * sv->nulledSurface(effectiveZ3, applyNull), size, actualPad, true);
// 3. Mask Generation
cv::Mat mask = cv::Mat::zeros(size, size, CV_64FC1);
diff --git a/metricsdisplay.cpp b/metricsdisplay.cpp
index 493c57c2..178d8fb7 100644
--- a/metricsdisplay.cpp
+++ b/metricsdisplay.cpp
@@ -58,7 +58,7 @@ void metricsDisplay::setWavePerFringe(double val, double lambda){
ui->wavesPerFringe->setText(QString("Waves Per Fringe: %1").arg(val, 2, 'f', 1));
ui->lambda->setText(QString("Igram laser wavelength: %1 nm").arg(lambda, 6, 'f', 2));
mirrorDlg *md = mirrorDlg::get_Instance();
- QString donull = (md->currentSettings().doNull) ? (QString("SANull: %1").arg(md->currentSettings().z8 * md->currentSettings().cc, 6, 'f', 4)) : "";
+ QString donull = (md->currentSettings().doNull) ? (QString("SANull: %1").arg(md->z8 * md->currentSettings().cc, 6, 'f', 4)) : "";
ui->desiredConicLb->setText(QString("Desired Conic: %1 ").arg( md->currentSettings().cc, 6, 'f', 2) + donull);
if (md->isEllipse()){
ui->desiredConicLb->setText("");
diff --git a/mirrordlg.cpp b/mirrordlg.cpp
index 620bef09..9f8cd585 100644
--- a/mirrordlg.cpp
+++ b/mirrordlg.cpp
@@ -100,7 +100,10 @@ void mirrorDlg::loadDraftFromSettings()
m_verticalAxis = m_draft.ellipseMinorAxis;
aperatureReduction = m_draft.apertureReduction;
m_aperatureReductionEnabled = m_draft.apertureReductionEnabled;
- m_projectPath = m_draft.projectPath;
+
+ // Load application-level settings separately (projectPath, mirrorConfigFile, lastPath)
+ ApplicationSettings appSettings = SettingsFacade::instance().appStore().load();
+ m_projectPath = appSettings.projectPath;
}
void mirrorDlg::showEvent(QShowEvent *event)
@@ -179,7 +182,7 @@ void mirrorDlg::saveJson(const QString &fileName){
}
void mirrorDlg:: on_saveBtn_clicked()
{
- QString path = m_draft.mirrorConfigFile;
+ QString path = m_projectPath; // Use current project path for file dialog default
QString extensionTypes("config file (*.json)");
QString fileName = QFileDialog::getSaveFileName(this,
tr("Save config file"), path,
@@ -197,10 +200,12 @@ void mirrorDlg:: on_saveBtn_clicked()
saveJson(fileName);
QFileInfo info(fileName);
- // Update draft with new file path, then persist via facade
- m_draft.mirrorConfigFile = fileName;
- m_draft.projectPath = info.absolutePath();
- m_projectPath = m_draft.projectPath;
+ // Update application settings with new file path
+ ApplicationSettings appSettings = SettingsFacade::instance().appStore().load();
+ appSettings.mirrorConfigFile = fileName;
+ appSettings.projectPath = info.absolutePath();
+ SettingsFacade::instance().appStore().save(appSettings);
+ m_projectPath = appSettings.projectPath;
}
void mirrorDlg::loadFile(QString & fileName){
@@ -210,15 +215,18 @@ void mirrorDlg::loadFile(QString & fileName){
m_outlineShape = CIRCLE;
QFileInfo info(fileName);
- // Only persist non-mirror-settings to QSettings (lastPath)
+ // Persist UI convenience path to QSettings
QSettings settings;
settings.setValue("lastPath", info.absolutePath());
emit newPath(info.absolutePath());
- // Update draft with new file path and project path via facade
- m_draft.projectPath = info.absolutePath();
- m_draft.mirrorConfigFile = fileName;
+ // Update application settings with new file path and mirror config file via facade
+ ApplicationSettings appSettings = SettingsFacade::instance().appStore().load();
+ appSettings.projectPath = info.absolutePath();
+ appSettings.mirrorConfigFile = fileName;
+ SettingsFacade::instance().appStore().save(appSettings);
+ m_projectPath = appSettings.projectPath;
if (fileName.endsWith(".json")){
@@ -449,7 +457,7 @@ void mirrorDlg::on_ReadBtn_clicked()
loadFile(fileName);
}
QString mirrorDlg::getProjectPath(){
- return m_draft.projectPath;
+ return m_projectPath; // Already synced from application settings in loadDraftFromSettings()
}
void mirrorDlg::on_diameter_textChanged(const QString &arg1) {
@@ -643,7 +651,6 @@ void mirrorDlg::on_buttonBox_accepted()
m_draft.ellipseMinorAxis = m_verticalAxis;
m_draft.apertureReductionEnabled = m_aperatureReductionEnabled;
m_draft.apertureReduction = aperatureReduction;
- m_draft.projectPath = m_projectPath;
// Persist draft to QSettings via facade (single atomic save)
SettingsFacade::instance().mirrorStore().save(m_draft);
diff --git a/percentcorrectiondlg.cpp b/percentcorrectiondlg.cpp
index 898b6247..4ae01bbf 100644
--- a/percentcorrectiondlg.cpp
+++ b/percentcorrectiondlg.cpp
@@ -98,6 +98,7 @@ void percentCorrectionDlg::saveSettings(){
* fixme figure that out.
*/
QList percentCorrectionDlg::generateZoneCenters(double radius, int number_of_zones, bool makeNew){
+ QSettings set;
QList zoneCenters;
if (!makeNew) { // read last used zones
@@ -354,7 +355,7 @@ QPolygonF percentCorrectionDlg::makePercentages(surfaceData *surf){
ActualZoneKnife << 0.0;
mirrorDlg *md = mirrorDlg::get_Instance();
- double nullval = md->currentSettings().z8 * md->currentSettings().cc; // null value was computed at the igram wavevlength
+ double nullval = md->z8 * md->currentSettings().cc; // null value was computed at the igram wavevlength
nullval *= m_lambda_nm/m_outputLambda; // only data from the profile needs the null but it's data is at the output wavelength;
// process each zone center
@@ -400,7 +401,7 @@ QPolygonF percentCorrectionDlg::makePercentages(surfaceData *surf){
void percentCorrectionDlg::plotProfile(){
mirrorDlg *md = mirrorDlg::get_Instance();
- double nullval = md->currentSettings().z8 * md->currentSettings().cc;
+ double nullval = md->z8 * md->currentSettings().cc;
for (int i = 0; i < surfs.length(); ++ i) {
QwtPlotCurve *Curve = new QwtPlotCurve();
@@ -753,6 +754,7 @@ void percentCorrectionDlg::on_loadZones_clicked()
void percentCorrectionDlg::on_saveZones_clicked()
{
+ QSettings set;
QString path = SettingsFacade::instance().appStore().load().projectPath;
QString extensionTypes(tr( "zone file (*.zones)"));
QString fileName = QFileDialog::getSaveFileName(0,
diff --git a/profileplot.cpp b/profileplot.cpp
index 2073a854..38a3582d 100644
--- a/profileplot.cpp
+++ b/profileplot.cpp
@@ -1174,7 +1174,7 @@ void ProfilePlot::CreateWaveFrontFromAverage(){
for (unsigned int i = 0; i < avgRadius.size(); ++i) {
double R2 = (double(i))/(avgRadius.size() -1);
R2 *= R2;
- avgRadius[i] += md->currentSettings().z8 * md->currentSettings().cc * (1. + R2 * (-6 + 6. * R2));;
+ avgRadius[i] += md->z8 * md->currentSettings().cc * (1. + R2 * (-6 + 6. * R2));;
}
}
cv::Mat result = createInterpolatedCircularSurface(avgRadius);
diff --git a/simulationsview.cpp b/simulationsview.cpp
index ee49e826..71a4a36a 100644
--- a/simulationsview.cpp
+++ b/simulationsview.cpp
@@ -191,7 +191,7 @@ SimulationsView *SimulationsView::getInstance(QWidget *parent){
-cv::Mat SimulationsView::nulledSurface(double defocus){
+cv::Mat SimulationsView::nulledSurface(double defocus, bool applyNull){
cv::Mat out;
mirrorDlg *md = mirrorDlg::get_Instance();
@@ -210,7 +210,9 @@ cv::Mat SimulationsView::nulledSurface(double defocus){
// save the user selected defocus enable to be restored after this.
bool saved_defocus_enable = zernEnables[3];
zernEnables[3] = false;
- cv::Mat nulled_surface = zp.null_unwrapped( *(m_Instance->m_wf), newZerns, zernEnables);
+
+ // Pass the applyNull flag to control whether null correction is applied
+ cv::Mat nulled_surface = zp.null_unwrapped( *(m_Instance->m_wf), newZerns, zernEnables, 0, Z_TERMS, applyNull);
zernEnables[3] = saved_defocus_enable;
if (GB_enabled){
diff --git a/simulationsview.h b/simulationsview.h
index 59a68808..9c107a75 100644
--- a/simulationsview.h
+++ b/simulationsview.h
@@ -51,7 +51,7 @@ class SimulationsView : public QWidget
void compute();
bool needs_drawing;
bool needs_drawing_3D;
- cv::Mat nulledSurface(double defocus);
+ cv::Mat nulledSurface(double defocus, bool applyNull = true);
cv::Mat m_PSF;
private:
bool alias;
diff --git a/statsview.cpp b/statsview.cpp
index cf161d32..c7008c94 100644
--- a/statsview.cpp
+++ b/statsview.cpp
@@ -270,7 +270,7 @@ void statsView::on_SaveCSV_clicked()
// apply software Null if needed
if (ndx == 8 and md->currentSettings().doNull)
- v -= md->currentSettings().z8 * md->currentSettings().cc;
+ v -= md->z8 * md->currentSettings().cc;
double Sigma = computeRMS(ndx,v) * md->currentSettings().lambda/outputLambda;
if (ndx == 8) {
diff --git a/surfacemanager.cpp b/surfacemanager.cpp
index 6c4fd68c..f2963e58 100644
--- a/surfacemanager.cpp
+++ b/surfacemanager.cpp
@@ -501,7 +501,7 @@ cv::Mat SurfaceManager::computeWaveFrontFromZernikes(int wx, int wy, std::vector
else {
if (en[z]){
if (z == 8 && md->currentSettings().doNull)
- S1 += md->currentSettings().z8 * zpolar.zernike(z);
+ S1 += md->z8 * zpolar.zernike(z);
S1 += zerns[z] * zpolar.zernike(z);
}
@@ -800,7 +800,7 @@ void SurfaceManager::useDemoWaveFront(){
if (rho <= 1.)
{
- double S1 = md->currentSettings().z8 * -.9 * zpolar.zernike(8) + .02* zpolar.zernike(9);
+ double S1 = md->z8 * -.9 * zpolar.zernike(8) + .02* zpolar.zernike(9);
result.at(j,i) = S1;
}
@@ -3020,7 +3020,7 @@ void SurfaceManager::report(){
QString(" waves at %1 nmStrehl: ").arg(outputLambda, 6, 'f', 1) + metrics->mStrehl->text() +
" | " + BFC + " | "
"| " + ((md->isEllipse()) ? "":"Desired Conic: " + QString::number(md->currentSettings().cc)) + " | " +
- ((md->currentSettings().doNull) ? QString("SANull: %1").arg(md->currentSettings().z8 * md->currentSettings().cc, 6, 'f', 4) : "No software Null") + " | "
+ ((md->currentSettings().doNull) ? QString("SANull: %1").arg(md->z8 * md->currentSettings().cc, 6, 'f', 4) : "No software Null") + ""
"Waves per fringe: " + QString::number(md->currentSettings().fringeSpacing) + " Interferogram Wave length: "+ QString::number(md->currentSettings().lambda) + "nm | "
" ";
@@ -3043,7 +3043,7 @@ void SurfaceManager::report(){
enabled = true;
}
if ( i == 8 && md->currentSettings().doNull){
- val -= md->currentSettings().z8 * md->currentSettings().cc;
+ val -= md->z8 * md->currentSettings().cc;
}
diff --git a/wftstats.cpp b/wftstats.cpp
index e728860d..4b37fefd 100644
--- a/wftstats.cpp
+++ b/wftstats.cpp
@@ -215,7 +215,7 @@ void wftStats::computeWftStats( QVector wavefronts, int ndx){
// apply software Null if needed
if (ndx == 8 and md->currentSettings().doNull)
- v -= md->currentSettings().z8 * md->currentSettings().cc;
+ v -= md->z8 * md->currentSettings().cc;
double Sigma = computeRMS(ndx,v) * outputLambda/md->currentSettings().lambda;
if (ndx == 8) {
diff --git a/zernikeprocess.cpp b/zernikeprocess.cpp
index e8bf66a6..d2394420 100644
--- a/zernikeprocess.cpp
+++ b/zernikeprocess.cpp
@@ -484,19 +484,19 @@ void zernikeProcess::unwrap_to_zernikes(wavefront &wf, int zterms){
}
cv::Mat zernikeProcess::null_unwrapped(wavefront&wf, std::vector zerns, std::vector enables,
- int start_term, int last_term)
+ int start_term, int last_term, bool applyNull)
{
int nx = wf.data.cols;
cv::Mat unwrapped = wf.data.clone();
- double scz8 = md->currentSettings().z8 * md->currentSettings().cc;
-
mirrorDlg *md = mirrorDlg::get_Instance();
+
+ double scz8 = md->z8 * md->currentSettings().cc;
- if (!md->currentSettings().doNull || !wf.useSANull){
+ if (!applyNull || !md->currentSettings().doNull || !wf.useSANull){
scz8 = 0.;
}
double midx = wf.m_outside.m_center.rx();
@@ -914,7 +914,7 @@ cv::Mat zernikeProcess::makeSurfaceFromZerns(int border, bool doColor){
for (unsigned int z = 0; z < m_zerns.n_cols; ++z){
double val = dlg.zernikes[z];
if (z == 8){
- val = (dlg.doCorrection && md->currentSettings().doNull) ? md->currentSettings().cc * md->currentSettings().z8 * val * .01 : val;
+ val = (dlg.doCorrection && md->currentSettings().doNull) ? md->currentSettings().cc * md->z8 * val * .01 : val;
}
S1 += val * m_zerns(i,z)/((doColor) ? md->currentSettings().fringeSpacing: 1.);
diff --git a/zernikeprocess.h b/zernikeprocess.h
index f01d570f..f7fd3183 100644
--- a/zernikeprocess.h
+++ b/zernikeprocess.h
@@ -55,7 +55,7 @@ class zernikeProcess : public QObject
explicit zernikeProcess(QObject *parent = 0);
static zernikeProcess *get_Instance();
void unwrap_to_zernikes(wavefront &wf, int zterms = Z_TERMS);
- cv::Mat null_unwrapped(wavefront&wf, std::vector zerns, std::vector enables,int start_term =0, int last_term = Z_TERMS);
+ cv::Mat null_unwrapped(wavefront&wf, std::vector zerns, std::vector enables, int start_term = 0, int last_term = Z_TERMS, bool applyNull = true);
std::vector ZernFitWavefront( wavefront &wf);
void initGrid(wavefront &wf, int maxOrder);
void initGrid(int width, double radius, double cx, double cy, int maxOrder, double inside = 0);
From 419d4ec2370c96cbdb4319c082cb2b32e06b0712 Mon Sep 17 00:00:00 2001
From: Julien STAUB
Date: Sat, 8 Aug 2026 14:18:20 +0200
Subject: [PATCH 08/20] ensure programmatically mirror dialog is only one to be
able to modify mirror settings
---
bathastigdlg.cpp | 6 ++---
dftarea.cpp | 16 ++++++------
igramarea.cpp | 20 +++++++--------
mainwindow.cpp | 4 +--
mirrordlg.cpp | 14 ++++++++++-
mirrordlg.h | 53 ++++++++++++++++++++++++----------------
percentcorrectiondlg.cpp | 8 +++---
profileplot.cpp | 8 +++---
settingsfacade.cpp | 5 ++++
settingsfacade.h | 14 +++++++++++
settingsstores.h | 5 ++--
surfacemanager.cpp | 18 ++++++++------
zernikedlg.cpp | 4 +--
13 files changed, 110 insertions(+), 65 deletions(-)
diff --git a/bathastigdlg.cpp b/bathastigdlg.cpp
index c8aaba0e..d5162f5b 100644
--- a/bathastigdlg.cpp
+++ b/bathastigdlg.cpp
@@ -8,9 +8,9 @@ bathAstigDlg::bathAstigDlg(QWidget *parent) :
{
ui->setupUi(this);
mirrorDlg &md = *mirrorDlg::get_Instance();
- ui->diamSb->setValue(md.diameter);
- ui->rocsb->setValue(md.roc);
- ui->lambdaSb->setValue(md.lambda);
+ ui->diamSb->setValue(md.currentSettings().diameter);
+ ui->rocsb->setValue(md.currentSettings().roc);
+ ui->lambdaSb->setValue(md.currentSettings().lambda);
ui->sepSb->setValue(5.);
compute();
}
diff --git a/dftarea.cpp b/dftarea.cpp
index 34b68b33..831c0465 100644
--- a/dftarea.cpp
+++ b/dftarea.cpp
@@ -40,7 +40,7 @@ cv::Mat makeMask(const CircleOutline &outside, const CircleOutline ¢er, con
double rady = radm;
mirrorDlg &md = *mirrorDlg::get_Instance();
if (md.isEllipse())
- rady = radm * md.m_verticalAxis/md.diameter;
+ rady = radm * md.currentSettings().ellipseMinorAxis/md.currentSettings().diameter;
double rado = center.m_radius;
double cx = outside.m_center.x();
double cy = outside.m_center.y();
@@ -151,14 +151,14 @@ DFTArea::DFTArea(QWidget *mparent, IgramArea *ip, DFTTools * tools, vortexDebug
grid->attach(test);
QPolygonF points;
mirrorDlg &md = *mirrorDlg::get_Instance();
- double roc = md.roc;
- double diam = md.diameter;
+ double roc = md.currentSettings().roc;
+ double diam = md.currentSettings().diameter;
double r3 = roc * roc * roc;
double d4 = diam * diam * diam * diam;
for (double i = 0; i < .03; i += .0001){
- double z1 = -i * 384. * r3 * md.lambda * 1.E-6/(d4);
+ double z1 = -i * 384. * r3 * md.currentSettings().lambda * 1.E-6/(d4);
points << QPointF( -i, z1 );
@@ -251,9 +251,9 @@ cv::Mat DFTArea::grayComplexMatfromImage(QImage &img){
double centerY = igramArea->m_outside.m_center.y();
mirrorDlg &md = *mirrorDlg::get_Instance();
- double pixelsPermm =(igramArea->m_outside.m_radius/(md.diameter/2.));
- double reduction = md.aperatureReduction * pixelsPermm;
- if (md.m_aperatureReductionEnabled == false)
+ double pixelsPermm =(igramArea->m_outside.m_radius/(md.currentSettings().diameter/2.));
+ double reduction = md.currentSettings().apertureReduction * pixelsPermm;
+ if (md.currentSettings().apertureReductionEnabled == false)
reduction = 0;
double rad = igramArea->m_outside.m_radius - reduction;
@@ -262,7 +262,7 @@ cv::Mat DFTArea::grayComplexMatfromImage(QImage &img){
double rady = rad;
if (md.isEllipse()){
- rady = rady * md.m_verticalAxis/ md.diameter;
+ rady = rady * md.currentSettings().ellipseMinorAxis / md.currentSettings().diameter;
}
double left = centerX - rad;
diff --git a/igramarea.cpp b/igramarea.cpp
index 871eea48..b7b7cc68 100644
--- a/igramarea.cpp
+++ b/igramarea.cpp
@@ -151,9 +151,9 @@ IgramArea::IgramArea(QWidget *parent, void *mw)
void IgramArea::computeEdgeRadius(){
// compute mask inner edge in pixels
mirrorDlg &md = *mirrorDlg::get_Instance();
- double pixelsPermm =(m_outside.m_radius/(md.diameter/2.));
- m_edgeMaskWidth = md.aperatureReduction * pixelsPermm;
- if (md.m_aperatureReductionEnabled == false)
+ double pixelsPermm =(m_outside.m_radius/(md.currentSettings().diameter/2.));
+ m_edgeMaskWidth = md.currentSettings().apertureReduction * pixelsPermm;
+ if (md.currentSettings().apertureReductionEnabled == false)
m_edgeMaskWidth = 0;
}
@@ -1545,7 +1545,7 @@ void IgramArea::mouseMoveEvent(QMouseEvent *event)
int majorRad = fabs((m_OutterP2.x() - m_OutterP1.x()))/2.;
double e = (double)minorRad/majorRad;
mirrorDlg &md = *mirrorDlg::get_Instance();
- md.m_verticalAxis = md.diameter * e;
+ md.setVerticalAxis(md.currentSettings().diameter * e);
drawBoundary();
return;
}
@@ -1624,8 +1624,8 @@ void IgramArea::mouseReleaseEvent(QMouseEvent *event)
setCursor(Qt::ArrowCursor);
if (event->button() == Qt::LeftButton && verticalTracking) {
mirrorDlg &md = *mirrorDlg::get_Instance();
- double e = md.m_verticalAxis/ md.diameter;
- md.setMinorAxis( e * md.diameter);
+ double e = md.currentSettings().ellipseMinorAxis / md.currentSettings().diameter;
+ md.setMinorAxis( e * md.currentSettings().diameter);
}
@@ -1705,7 +1705,7 @@ void IgramArea::drawBoundary()
mirrorDlg &md = *mirrorDlg::get_Instance();
if ((md.isEllipse())){
- s2 = md.m_verticalAxis/ md.diameter;
+ s2 = md.currentSettings().ellipseMinorAxis / md.currentSettings().diameter;
}
if (m_searching_outside){
QColor c(Qt::cyan);
@@ -1719,7 +1719,7 @@ void IgramArea::drawBoundary()
painter.setBrush(Qt::NoBrush);
}
outside.draw(painter,1.,s2);
- if ( md.m_aperatureReductionEnabled && md.m_clearAperature != md.diameter){
+ if ( md.currentSettings().apertureReductionEnabled && md.currentSettings().apertureReduction != md.currentSettings().diameter){
painter.setPen(QPen(edgePenColor, edgePenWidth, Qt::DotLine));
computeEdgeRadius();
painter.drawEllipse(outside.m_center,
@@ -1927,7 +1927,7 @@ void IgramArea::paintEvent(QPaintEvent *event)
mirrorDlg &md = *mirrorDlg::get_Instance();
double e = 1.;
if (md.isEllipse()){
- e = md.m_verticalAxis/md.diameter;
+ e = md.currentSettings().ellipseMinorAxis / md.currentSettings().diameter;
}
@@ -2022,7 +2022,7 @@ void IgramArea::crop() {
mirrorDlg &md = *mirrorDlg::get_Instance();
if (md.isEllipse()){
- double e = md.m_verticalAxis/md.diameter;
+ double e = md.currentSettings().ellipseMinorAxis/md.currentSettings().diameter;
rady = radx * e;
top = fmax(0,cy - rady);
bottom = igramColor.height() - (rady + cy);
diff --git a/mainwindow.cpp b/mainwindow.cpp
index a597f97b..372c83d0 100644
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -586,8 +586,8 @@ void MainWindow::updateMetrics(wavefront& wf){
double Strehl = pow(e, -st);
metrics->mStrehl->setText(QString("%1").arg(Strehl, 6, 'f', 3));
QString ztitle("Zernike Values");
- if (m_mirrorDlg->m_useAnnular){
- ztitle = QString("Annular Zernike values %1% center hole").arg(100 * m_mirrorDlg->m_annularObsPercent, 6, 'f',1);
+ if (m_mirrorDlg->currentSettings().useAnnulus){
+ ztitle = QString("Annular Zernike values %1% center hole").arg(100 * m_mirrorDlg->currentSettings().annulusPercent, 6, 'f',1);
}
metrics->setZernTitle(ztitle);
double z8 = zernTablemodel->values[8];
diff --git a/mirrordlg.cpp b/mirrordlg.cpp
index 9f8cd585..2a14cd90 100644
--- a/mirrordlg.cpp
+++ b/mirrordlg.cpp
@@ -653,7 +653,8 @@ void mirrorDlg::on_buttonBox_accepted()
m_draft.apertureReduction = aperatureReduction;
// Persist draft to QSettings via facade (single atomic save)
- SettingsFacade::instance().mirrorStore().save(m_draft);
+ // Note: Only mirrordlg can call this (via friend declaration) - enforces single source of truth
+ SettingsFacade::instance().saveMirrorSettings(m_draft);
if (m_obsChanged)
emit obstructionChanged();
@@ -708,6 +709,17 @@ void mirrorDlg::setMinorAxis(double val){
//on_minorAxisEdit_textChanged( QString::number(val));
}
+void mirrorDlg::setVerticalAxis(double val){
+ m_verticalAxis = val;
+ m_draft.ellipseMinorAxis = val;
+}
+
+void mirrorDlg::setOutlineShape(outlineShape shape){
+ m_outlineShape = shape;
+ m_draft.outlineShape = (int)shape;
+ ui->ellipseShape->setChecked(shape == ELLIPSE);
+}
+
void mirrorDlg::on_ellipseShape_clicked(bool checked)
{
if (checked) m_outlineShape = ELLIPSE;
diff --git a/mirrordlg.h b/mirrordlg.h
index 16fd8fca..4fc1efa3 100644
--- a/mirrordlg.h
+++ b/mirrordlg.h
@@ -37,49 +37,60 @@ class mirrorDlg : public QDialog
mirrorDlg(const mirrorDlg&) = delete;
mirrorDlg& operator=(const mirrorDlg&) = delete;
+ // File and configuration operations
void loadFile(QString & fileName);
void updateZ8();
void updateAutoInvertStatus();
- QString m_name;
+ // Computed/derived values (read-only, not from settings)
bool mm;
- double diameter;
- double roc;
double FNumber;
- double obs; // obstruction
- double cc;
- bool doNull;
double z8;
- double lambda;
- double fringeSpacing;
- bool flipv;
- bool fliph;
- bool m_useAnnular;
- bool m_connectAnnulusToObs;
- double m_annularObsPercent; // a value from 0 to 1 (not 0 to 100)
- double m_clearAperature;
- double aperatureReduction;
static QString m_projectPath;
+
+ // State flags
+ bool m_obsChanged;
+ bool m_majorHorizontal;
+
+ // Methods for configuration access/modification
void on_roc_Changed(const double newVal);
void on_diameter_Changed(const double diam);
bool shouldFlipH();
static QString getProjectPath();
- bool m_obsChanged;
void newLambda(const QString &v);
double getMinorAxis();
- bool m_majorHorizontal;
- double m_verticalAxis;
- outlineShape m_outlineShape;
bool isEllipse();
void setMinorAxis(double val);
- bool m_aperatureReductionEnabled;
+ void setVerticalAxis(double val);
+ void setOutlineShape(outlineShape shape);
void setObsPercent(double obs);
/** @brief Access current mirror settings (read-only snapshot).
* Returns the draft which is the canonical storage for all mirror config.
- * All member variables are kept in sync with this for backward compatibility. */
+ * All internal member variables are kept in sync with this. */
const MirrorSettings& currentSettings() const { return m_draft; }
+private:
+ // Configuration members (access via currentSettings() or setters)
+ QString m_name;
+ double diameter;
+ double roc;
+ double obs; // obstruction
+ double cc;
+ bool doNull;
+ double lambda;
+ double fringeSpacing;
+ bool flipv;
+ bool fliph;
+ bool m_useAnnular;
+ bool m_connectAnnulusToObs;
+ double m_annularObsPercent; // a value from 0 to 1 (not 0 to 100)
+ double m_clearAperature;
+ double aperatureReduction;
+ bool m_aperatureReductionEnabled;
+ double m_verticalAxis;
+ outlineShape m_outlineShape;
+
private slots:
void on_ReadBtn_clicked();
diff --git a/percentcorrectiondlg.cpp b/percentcorrectiondlg.cpp
index 4ae01bbf..fa205094 100644
--- a/percentcorrectiondlg.cpp
+++ b/percentcorrectiondlg.cpp
@@ -31,7 +31,7 @@ percentCorrectionDlg::percentCorrectionDlg( QWidget *parent) :
mirrorDlg &md = *mirrorDlg::get_Instance();
- m_radius = md.m_clearAperature/2.;
+ m_radius = md.currentSettings().apertureReduction/2.;
QSettings set;
ui->minvalue->blockSignals(true);
ui->maxvalue->blockSignals(true);
@@ -639,12 +639,12 @@ void percentCorrectionDlg::setData( QVector< surfaceData *> data) {
mirrorDlg &md = *mirrorDlg::get_Instance();
- m_roc = md.roc;
- m_lambda_nm = md.lambda;
+ m_roc = md.currentSettings().roc;
+ m_lambda_nm = md.currentSettings().lambda;
QSettings set;
m_outputLambda = set.value("outputLambda").toDouble();
- m_radius = md.m_clearAperature/2.;
+ m_radius = md.currentSettings().apertureReduction/2.;
surfs = data;
ui->percentTable->setRowCount(data.length());
diff --git a/profileplot.cpp b/profileplot.cpp
index 38a3582d..853ffe5c 100644
--- a/profileplot.cpp
+++ b/profileplot.cpp
@@ -427,8 +427,8 @@ QPolygonF ProfilePlot::createProfile(double units, const wavefront *wf, bool all
// 1. Setup constants
double steps = 1.0 / wf->m_outside.m_radius;
double offset = allowOffset ? y_offset : 0.0;
- double radius = md.m_clearAperature / 2.0;
- double obs_radius = md.obs / 2.0;
+ double radius = md.currentSettings().apertureReduction / 2.0;
+ double obs_radius = md.currentSettings().obstruction / 2.0;
if (m_displayInches) {
obs_radius /= 25.4;
@@ -443,12 +443,12 @@ QPolygonF ProfilePlot::createProfile(double units, const wavefront *wf, bool all
if (m_displayPercent) {
radx = 100.0 * radx / radius;
- obs_radius = 100.0 * (md.obs / 2.0) / radius;
+ obs_radius = 100.0 * (md.currentSettings().obstruction / 2.0) / radius;
}
double e = 1.0;
if (md.isEllipse()) {
- e = md.m_verticalAxis / md.diameter;
+ e = md.currentSettings().ellipseMinorAxis / md.currentSettings().diameter;
}
// Calculate matrix coordinates
diff --git a/settingsfacade.cpp b/settingsfacade.cpp
index f3b887d1..5a65fcac 100644
--- a/settingsfacade.cpp
+++ b/settingsfacade.cpp
@@ -45,3 +45,8 @@ const ApplicationSettingsStore &SettingsFacade::appStore() const
{
return m_appStore;
}
+
+void SettingsFacade::saveMirrorSettings(const MirrorSettings &settings)
+{
+ m_mirrorStore.save(settings);
+}
diff --git a/settingsfacade.h b/settingsfacade.h
index f9ae4085..15e9693b 100644
--- a/settingsfacade.h
+++ b/settingsfacade.h
@@ -3,14 +3,21 @@
#include "settingsstores.h"
+// Forward declaration for friend access
+class mirrorDlg;
+
/**
* @brief Thin entry point that delegates to domain-specific settings stores.
*
* This class intentionally stays small; domain behavior belongs in internal
* stores such as MirrorSettingsStore or ContourSettingsStore.
+ *
+ * Access control: saveMirrorSettings() is restricted to mirrordlg (via friend)
+ * to ensure mirror configuration is saved only from the dialog's OK button.
*/
class SettingsFacade
{
+ friend class mirrorDlg; // Only mirrordlg can call saveMirrorSettings()
public:
static SettingsFacade &instance();
@@ -30,6 +37,13 @@ class SettingsFacade
const ApplicationSettingsStore &appStore() const;
private:
+ friend class mirrorDlg; // Allow mirrordlg to call restricted save
+
+ /** @brief Restricted save for mirror settings (mirrordlg only via friend).
+ * Ensures single source of truth: only the mirror dialog's OK button can persist changes.
+ * Nobody will be able to save mirror settings directly elsewhere in the code. */
+ void saveMirrorSettings(const MirrorSettings &settings);
+
SettingsFacade() = default; // Enforce singleton
// Only facade owns these
diff --git a/settingsstores.h b/settingsstores.h
index 12c26b88..bf719cc7 100644
--- a/settingsstores.h
+++ b/settingsstores.h
@@ -16,12 +16,13 @@ struct MirrorSettings {
class MirrorSettingsStore {
private:
- friend class SettingsFacade; // Only facade can construct
+ friend class SettingsFacade; // Only facade can construct and call save()
MirrorSettingsStore() = default;
+ void save(const MirrorSettings &value) const;
+
public:
MirrorSettings load() const;
- void save(const MirrorSettings &value) const;
};
diff --git a/surfacemanager.cpp b/surfacemanager.cpp
index f2963e58..bb4f06fc 100644
--- a/surfacemanager.cpp
+++ b/surfacemanager.cpp
@@ -647,7 +647,7 @@ void SurfaceManager::makeMask(wavefront *wf, bool useInsideCircle){
mirrorDlg &md = *mirrorDlg::get_Instance();
double rx = radm;
double rx2 = rx * rx;
- double ry = rx * md.m_verticalAxis/md.diameter;
+ double ry = rx * md.currentSettings().ellipseMinorAxis / md.currentSettings().diameter;
double ry2 = ry * ry;
if (!mirrorDlg::get_Instance()->isEllipse()){
uchar v = 0xff;
@@ -718,7 +718,7 @@ void SurfaceManager::makeMask(wavefront *wf, bool useInsideCircle){
// add central obstruction (not to be confused with a hole in the mirror - this comes from mirror configuration)
- double r = md.obs * (2. * radm)/md.diameter;
+ double r = md.currentSettings().obstruction * (2. * radm)/md.currentSettings().diameter;
r/= 2.;
if (r > 0){
@@ -941,9 +941,9 @@ void SurfaceManager::computeZerns()
mirrorDlg &md = *mirrorDlg::get_Instance();
foreach(int ndx , doThese){
wavefront &wf = *m_wavefronts[ndx];
- wf.diameter = md.diameter;
- wf.roc = md.roc;
- wf.lambda = md.lambda;
+ wf.diameter = md.currentSettings().diameter;
+ wf.roc = md.currentSettings().roc;
+ wf.lambda = md.currentSettings().lambda;
}
m_waveFrontTimer->start(500);
@@ -997,7 +997,7 @@ void SurfaceManager::writeWavefront(const QString &fname, wavefront *wf, bool sa
}
mirrorDlg &md = *mirrorDlg::get_Instance();
if (md.isEllipse()){
- file << "ellipse_vertical_axis " << md.m_verticalAxis;
+ file << "ellipse_vertical_axis " << md.currentSettings().ellipseMinorAxis;
}
}
@@ -1305,8 +1305,10 @@ wavefront * SurfaceManager::readWaveFront(const QString &fileName){
continue;
}
if (l.startsWith("ellipse_vertical_axis")){
- md->m_outlineShape = ELLIPSE;
- iss >> dummy >> md->m_verticalAxis;
+ md->setOutlineShape(ELLIPSE);
+ double vertAxis;
+ iss >> dummy >> vertAxis;
+ md->setVerticalAxis(vertAxis);
}
if (l.startsWith("Do Not use null") || l.startsWith("nulled") ){
wf->useSANull = false;
diff --git a/zernikedlg.cpp b/zernikedlg.cpp
index b95416b4..78acb1d1 100644
--- a/zernikedlg.cpp
+++ b/zernikedlg.cpp
@@ -119,8 +119,8 @@ QVariant ZernTableModel::data(const QModelIndex &index, int role) const
}
mirrorDlg &md = *mirrorDlg::get_Instance();
- if (index.row() == 8 && md.doNull && !m_nulled){
- double val = values[8] - md.z8 * md.cc;
+ if (index.row() == 8 && md.currentSettings().doNull && !m_nulled){
+ double val = values[8] - md.z8 * md.currentSettings().cc;
return QString("%1 %2").arg(val, 6, 'f', 3).arg( computeRMS(8, val), 6, 'f', 3);
}
From 6629b254a9a7e1b622a4b3b491fa86ad0b7a2305 Mon Sep 17 00:00:00 2001
From: Julien STAUB
Date: Sat, 8 Aug 2026 15:28:31 +0200
Subject: [PATCH 09/20] fix the draft/current settings way of working
---
mirrordlg.cpp | 348 ++++++++++++++++++++++----------------------------
mirrordlg.h | 43 ++-----
2 files changed, 170 insertions(+), 221 deletions(-)
diff --git a/mirrordlg.cpp b/mirrordlg.cpp
index 2a14cd90..a613906d 100644
--- a/mirrordlg.cpp
+++ b/mirrordlg.cpp
@@ -43,11 +43,9 @@ mirrorDlg::mirrorDlg(QWidget *parent) :
QDialog(parent),
mm(true),m_obsChanged(false),ui(new Ui::mirrorDlg)
{
- m_useAnnular = false;
- m_connectAnnulusToObs = false;
ui->setupUi(this);
- // Initialize defaults only; loadDraftFromSettings() called in showEvent() populates UI
+ // Initialize defaults only; loadDraftFromSettings() populates m_current and m_draft
FNumber = 0.0;
ui->FNumber->blockSignals(true);
ui->roc->blockSignals(true);
@@ -69,6 +67,9 @@ mirrorDlg::mirrorDlg(QWidget *parent) :
ui->minorAxisEdit->blockSignals(false);
m_aperatureReductionValueChanged = false;
+
+ // Initialize settings from persistent storage (in case dialog used without showEvent)
+ loadDraftFromSettings();
}
mirrorDlg::~mirrorDlg()
@@ -79,27 +80,11 @@ mirrorDlg::~mirrorDlg()
void mirrorDlg::loadDraftFromSettings()
{
- // Load mirror settings from persistent storage via facade into working draft.
- // This ensures every dialog open/show starts with the last-saved state.
- m_draft = SettingsFacade::instance().mirrorStore().load();
-
- // Sync public member variables with draft for backward compatibility.
- m_name = m_draft.mirrorName;
- diameter = m_draft.diameter;
- roc = m_draft.roc;
- obs = m_draft.obstruction;
- cc = m_draft.cc;
- lambda = m_draft.lambda;
- fringeSpacing = m_draft.fringeSpacing;
- fliph = m_draft.flipH;
- doNull = m_draft.doNull;
- m_useAnnular = m_draft.useAnnulus;
- m_annularObsPercent = m_draft.annulusPercent;
- m_connectAnnulusToObs = m_draft.annulusToObstruction;
- m_outlineShape = (outlineShape)m_draft.outlineShape;
- m_verticalAxis = m_draft.ellipseMinorAxis;
- aperatureReduction = m_draft.apertureReduction;
- m_aperatureReductionEnabled = m_draft.apertureReductionEnabled;
+ // Load mirror settings from persistent storage via facade into BOTH copies.
+ // m_current: persistent copy (source of truth for external code)
+ // m_draft: working copy for dialog edits (discarded on Cancel)
+ m_current = SettingsFacade::instance().mirrorStore().load();
+ m_draft = m_current;
// Load application-level settings separately (projectPath, mirrorConfigFile, lastPath)
ApplicationSettings appSettings = SettingsFacade::instance().appStore().load();
@@ -112,22 +97,22 @@ void mirrorDlg::showEvent(QShowEvent *event)
// This ensures Cancel always reverts to the last-saved state.
loadDraftFromSettings();
- // Sync UI with reloaded draft values
+ // Sync UI with reloaded draft (working copy) values
ui->name->setText(m_draft.mirrorName);
- ui->diameter->setText(QString("%1").arg(diameter, 6, 'f', 2));
- ui->roc->setText(QString("%1").arg(roc, 6, 'f', 2));
- ui->obs->setText(QString("%1").arg(obs, 6, 'f', 2));
- ui->lambda->setText(QString("%1").arg(lambda, 6, 'f', 1));
- ui->cc->setText(QString("%1").arg(cc, 6, 'f', 2));
+ ui->diameter->setText(QString("%1").arg(m_draft.diameter, 6, 'f', 2));
+ ui->roc->setText(QString("%1").arg(m_draft.roc, 6, 'f', 2));
+ ui->obs->setText(QString("%1").arg(m_draft.obstruction, 6, 'f', 2));
+ ui->lambda->setText(QString("%1").arg(m_draft.lambda, 6, 'f', 1));
+ ui->cc->setText(QString("%1").arg(m_draft.cc, 6, 'f', 2));
ui->flipH->setChecked(m_draft.flipH);
ui->nullCB->setChecked(m_draft.doNull);
- ui->fringeSpacingEdit->setText(QString("%1").arg(fringeSpacing, 6, 'f', 3));
- ui->ellipseShape->setChecked(m_outlineShape == ELLIPSE);
- ui->minorAxisEdit->setText(QString::number(m_verticalAxis));
- ui->ReducApp->setChecked(m_aperatureReductionEnabled);
- ui->reduceValue->setValue(aperatureReduction);
- ui->useAnnulus->setChecked(m_useAnnular);
- ui->annulusPercent->setValue(m_annularObsPercent * 100);
+ ui->fringeSpacingEdit->setText(QString("%1").arg(m_draft.fringeSpacing, 6, 'f', 3));
+ ui->ellipseShape->setChecked((outlineShape)m_draft.outlineShape == ELLIPSE);
+ ui->minorAxisEdit->setText(QString::number(m_draft.ellipseMinorAxis));
+ ui->ReducApp->setChecked(m_draft.apertureReductionEnabled);
+ ui->reduceValue->setValue(m_draft.apertureReduction);
+ ui->useAnnulus->setChecked(m_draft.useAnnulus);
+ ui->annulusPercent->setValue(m_draft.annulusPercent * 100);
QDialog::showEvent(event);
}
@@ -140,30 +125,29 @@ double mirrorDlg::getMinorAxis(){
}
bool mirrorDlg::isEllipse(){
- return m_draft.outlineShape == ELLIPSE;
+ return (outlineShape)m_draft.outlineShape == ELLIPSE;
}
void mirrorDlg::saveJson(const QString &fileName){
QJsonObject jDoc, jMirror,jIgram, jEllipse, jAnnulus;
- jDoc["name"] = m_name;
+ jDoc["name"] = m_draft.mirrorName;
jDoc["show units in mm"] = mm;
- jDoc["useNull"] = doNull;
- jIgram["wavelength"] = lambda;
- jIgram["fringe spacing"] = fringeSpacing;
- jMirror["diameter"] = diameter;
- jMirror["obs diameter"] = obs;
- jMirror["roc"] = roc;
- jMirror["desired conic"] = cc;
- jMirror["edgeMaskon"] = m_aperatureReductionEnabled;
- jMirror["edge mask value"] = aperatureReduction;
- jIgram["wavelength"] = lambda;
+ jDoc["useNull"] = m_draft.doNull;
+ jIgram["wavelength"] = m_draft.lambda;
+ jIgram["fringe spacing"] = m_draft.fringeSpacing;
+ jMirror["diameter"] = m_draft.diameter;
+ jMirror["obs diameter"] = m_draft.obstruction;
+ jMirror["roc"] = m_draft.roc;
+ jMirror["desired conic"] = m_draft.cc;
+ jMirror["edgeMaskon"] = m_draft.apertureReductionEnabled;
+ jMirror["edge mask value"] = m_draft.apertureReduction;
+ jIgram["wavelength"] = m_draft.lambda;
jIgram["null value"] = z8;
- jIgram["flip horizontal"] = fliph;
- jIgram["flip vert"] = flipv;
- jIgram["fringe spacing"] = fringeSpacing;
- jEllipse["is ellipse"] = m_outlineShape;
- jEllipse["ellipse vert axis"] = m_verticalAxis;
- jAnnulus["use annular Zernike values"] = m_useAnnular;
- jAnnulus["obs percentage"] = m_annularObsPercent;
+ jIgram["flip horizontal"] = m_draft.flipH;
+ jIgram["fringe spacing"] = m_draft.fringeSpacing;
+ jEllipse["is ellipse"] = m_draft.outlineShape;
+ jEllipse["ellipse vert axis"] = m_draft.ellipseMinorAxis;
+ jAnnulus["use annular Zernike values"] = m_draft.useAnnulus;
+ jAnnulus["obs percentage"] = m_draft.annulusPercent;
jDoc["mirror"] = jMirror;
jDoc["igram"] = jIgram;
jDoc["ellipse"] = jEllipse;
@@ -212,7 +196,7 @@ void mirrorDlg::loadFile(QString & fileName){
// clear ellipse in case this is an old config that does not have it.
ui->ellipseShape->setChecked(false);
- m_outlineShape = CIRCLE;
+ m_draft.outlineShape = (int)CIRCLE;
QFileInfo info(fileName);
// Persist UI convenience path to QSettings
@@ -247,56 +231,55 @@ void mirrorDlg::loadFile(QString & fileName){
// set diameter early - before setting roc and annulus percentage
QJsonObject mirror = loadDoc["mirror"].toObject();
- diameter = QJsonValue(mirror["diameter"]).toDouble();
+ m_draft.diameter = QJsonValue(mirror["diameter"]).toDouble();
ui->diameter->blockSignals(true);
- ui->diameter->setText(QString("%1").arg(diameter, 6, 'f', 2));
+ ui->diameter->setText(QString("%1").arg(m_draft.diameter, 6, 'f', 2));
ui->diameter->blockSignals(false);
ui->nullCB->setChecked( QJsonValue(loadDoc["useNull"]).toBool());
- obs = QJsonValue(mirror["obs diameter"]).toDouble();
- roc = QJsonValue(mirror["roc"]).toDouble();
- cc = QJsonValue(mirror["desired conic"]).toDouble();
- m_aperatureReductionEnabled = QJsonValue(mirror["edgeMaskon"]).toBool();
- aperatureReduction=QJsonValue( mirror["edge mask value"]).toDouble();
+ m_draft.obstruction = QJsonValue(mirror["obs diameter"]).toDouble();
+ m_draft.roc = QJsonValue(mirror["roc"]).toDouble();
+ m_draft.cc = QJsonValue(mirror["desired conic"]).toDouble();
+ m_draft.apertureReductionEnabled = QJsonValue(mirror["edgeMaskon"]).toBool();
+ m_draft.apertureReduction = QJsonValue( mirror["edge mask value"]).toDouble();
QJsonObject Igram = loadDoc["igram"].toObject();
- lambda = QJsonValue(Igram["wavelength"]).toDouble();
+ m_draft.lambda = QJsonValue(Igram["wavelength"]).toDouble();
z8 = QJsonValue(Igram["null value"]).toDouble();
- fliph = QJsonValue(Igram["flip horizontal"]).toBool();
- flipv = QJsonValue(Igram["flip vert"]).toBool();
- fringeSpacing = QJsonValue(Igram["fringe spacing"]).toDouble();
+ m_draft.flipH = QJsonValue(Igram["flip horizontal"]).toBool();
+ m_draft.fringeSpacing = QJsonValue(Igram["fringe spacing"]).toDouble();
QJsonObject Ellipse = loadDoc["ellipse"].toObject();
- m_outlineShape = (outlineShape)QJsonValue(Ellipse["is ellipse"]).toInt();
- m_verticalAxis = QJsonValue(Ellipse["ellipse vert axis"]).toDouble();
+ m_draft.outlineShape = QJsonValue(Ellipse["is ellipse"]).toInt();
+ m_draft.ellipseMinorAxis = QJsonValue(Ellipse["ellipse vert axis"]).toDouble();
QJsonObject Annulus = loadDoc["Annulus"].toObject();
- m_useAnnular = QJsonValue(Annulus["use annular Zernike values"]).toBool();
- m_annularObsPercent = QJsonValue(Annulus["obs percentage"]).toDouble();
- ui->useAnnulus->setChecked(m_useAnnular);
- ui->annulusPercent->setValue(m_annularObsPercent * 100);
- on_annulusPercent_valueChanged(m_annularObsPercent * 100);
- enableAnnular(m_useAnnular);
+ m_draft.useAnnulus = QJsonValue(Annulus["use annular Zernike values"]).toBool();
+ m_draft.annulusPercent = QJsonValue(Annulus["obs percentage"]).toDouble();
+ ui->useAnnulus->setChecked(m_draft.useAnnulus);
+ ui->annulusPercent->setValue(m_draft.annulusPercent * 100);
+ on_annulusPercent_valueChanged(m_draft.annulusPercent * 100);
+ enableAnnular(m_draft.useAnnulus);
ui->fringeSpacingEdit->blockSignals(true);
- ui->fringeSpacingEdit->setText(QString("%1").arg(fringeSpacing, 3, 'f', 1));
+ ui->fringeSpacingEdit->setText(QString("%1").arg(m_draft.fringeSpacing, 3, 'f', 1));
ui->fringeSpacingEdit->blockSignals(false);
- ui->obs->setText(QString().number(obs));
+ ui->obs->setText(QString().number(m_draft.obstruction));
ui->roc->blockSignals(true);
- ui->roc->setText(QString("%1").arg(roc, 6, 'f', 2));
+ ui->roc->setText(QString("%1").arg(m_draft.roc, 6, 'f', 2));
ui->roc->blockSignals(false);
- ui->cc->setText(QString().number(cc));
+ ui->cc->setText(QString().number(m_draft.cc));
ui->z8->setText(QString().number(z8));
- ui->ellipseShape->setChecked(m_outlineShape == ELLIPSE);
+ ui->ellipseShape->setChecked((outlineShape)m_draft.outlineShape == ELLIPSE);
- ui->minorAxisEdit->setText(QString::number(m_verticalAxis));
+ ui->minorAxisEdit->setText(QString::number(m_draft.ellipseMinorAxis));
- FNumber = roc/(2. * diameter);
+ FNumber = m_draft.roc/(2. * m_draft.diameter);
ui->FNumber->blockSignals(true);
ui->FNumber->setText(QString("%1").arg(FNumber, 6, 'f', 2));
ui->FNumber->blockSignals(false);
@@ -344,29 +327,29 @@ void mirrorDlg::loadFile(QString & fileName){
}
ui->name->setText(name);
- m_name = name;
+ m_draft.mirrorName = name;
// donull
file.read(buf,4);
bool *bp = (bool *)buf;
ui->nullCB->setChecked(*bp);
- doNull = *bp;
+ m_draft.doNull = *bp;
//fringe Spacing
file.read(buf,8);
double *dp = (double*)buf;
- fringeSpacing = *dp;
+ m_draft.fringeSpacing = *dp;
ui->fringeSpacingEdit->blockSignals(true);
ui->fringeSpacingEdit->setText(QString("%1").arg(*dp, 3, 'f', 1));
ui->fringeSpacingEdit->blockSignals(false);
//read diameter
file.read(buf,8);
- diameter = *dp;
+ m_draft.diameter = *dp;
//Lambda
file.read(buf,8);
- lambda = *dp;
+ m_draft.lambda = *dp;
ui->lambda->setText(QString().number(*dp));
//Units mm
@@ -376,11 +359,11 @@ void mirrorDlg::loadFile(QString & fileName){
//obsruction
file.read(buf,4 * 9);
- obs = *(dp++);
- ui->obs->setText(QString().number(obs));
+ m_draft.obstruction = *(dp++);
+ ui->obs->setText(QString().number(m_draft.obstruction));
//ROC
- roc = *(dp++);
+ m_draft.roc = *(dp++);
//Diameter
if (!mm){
@@ -388,15 +371,15 @@ void mirrorDlg::loadFile(QString & fileName){
//roc *= 25.4;
}
ui->diameter->blockSignals(true);
- ui->diameter->setText(QString("%1").arg(diameter, 6, 'f', 2));
+ ui->diameter->setText(QString("%1").arg(m_draft.diameter, 6, 'f', 2));
ui->diameter->blockSignals(false);
ui->roc->blockSignals(true);
- ui->roc->setText(QString("%1").arg(roc, 6, 'f', 2));
+ ui->roc->setText(QString("%1").arg(m_draft.roc, 6, 'f', 2));
ui->roc->blockSignals(false);
//conic
- cc = *(dp++);
- ui->cc->setText(QString().number(cc));
+ m_draft.cc = *(dp++);
+ ui->cc->setText(QString().number(m_draft.cc));
//z8
z8 = *(dp++);
@@ -414,27 +397,27 @@ void mirrorDlg::loadFile(QString & fileName){
//flips
if (!file.eof()){
file.read(buf,4); // 1234 read right here
- fliph = *(bool*)buf;
+ m_draft.flipH = *(bool*)buf;
file.read(buf,4);
- flipv = *(bool*)buf;
+ // Skip vertical flip - not stored in MirrorSettings struct and not used
}
// ellipse
if (file.tellg() > 0){
// read outlineShape
file.read(buf,4);
- m_outlineShape = *(outlineShape*)buf;
- ui->ellipseShape->setChecked(m_outlineShape == ELLIPSE);
+ m_draft.outlineShape = (int)*(outlineShape*)buf;
+ ui->ellipseShape->setChecked((outlineShape)m_draft.outlineShape == ELLIPSE);
}
// vertical axis
if (file.tellg() > 0){
file.read(buf,8);
- m_verticalAxis = *(double*)buf;
- ui->minorAxisEdit->setText(QString::number(m_verticalAxis));
+ m_draft.ellipseMinorAxis = *(double*)buf;
+ ui->minorAxisEdit->setText(QString::number(m_draft.ellipseMinorAxis));
}
- FNumber = roc/(2. * diameter);
+ FNumber = m_draft.roc/(2. * m_draft.diameter);
ui->FNumber->blockSignals(true);
ui->FNumber->setText(QString("%1").arg(FNumber, 6, 'f', 2));
ui->FNumber->blockSignals(false);
@@ -463,19 +446,19 @@ QString mirrorDlg::getProjectPath(){
void mirrorDlg::on_diameter_textChanged(const QString &arg1) {
double diam = arg1.toDouble() * ((mm) ? 1.: 25.4);
- if (m_outlineShape == ELLIPSE){
- double e = m_verticalAxis/diameter;
- m_verticalAxis = e * diam;
- ui->minorAxisEdit->setText(QString().number(m_verticalAxis));
+ if ((outlineShape)m_draft.outlineShape == ELLIPSE){
+ double e = m_draft.ellipseMinorAxis/m_draft.diameter;
+ m_draft.ellipseMinorAxis = e * diam;
+ ui->minorAxisEdit->setText(QString().number(m_draft.ellipseMinorAxis));
}
- diameter = diam;
- FNumber = roc/(2. * diameter);
+ m_draft.diameter = diam;
+ FNumber = m_draft.roc/(2. * m_draft.diameter);
ui->FNumber->blockSignals(true);
ui->FNumber->setText(QString("%1").arg(FNumber, 6, 'f', 2));
ui->FNumber->blockSignals(false);
updateZ8();
- if (m_useAnnular){
- on_annulusPercent_valueChanged(m_annularObsPercent * 100);
+ if (m_draft.useAnnulus){
+ on_annulusPercent_valueChanged(m_draft.annulusPercent * 100);
}
}
@@ -483,17 +466,17 @@ void mirrorDlg::on_diameter_textChanged(const QString &arg1) {
//Used when the just loading wavfront is different
void mirrorDlg::on_diameter_Changed(const double diam)
{
- if (m_outlineShape == ELLIPSE){
- double e = m_verticalAxis/diameter;
- m_verticalAxis = e * diam;
- ui->minorAxisEdit->setText(QString().number(m_verticalAxis));
+ if ((outlineShape)m_draft.outlineShape == ELLIPSE){
+ double e = m_draft.ellipseMinorAxis/m_draft.diameter;
+ m_draft.ellipseMinorAxis = e * diam;
+ ui->minorAxisEdit->setText(QString().number(m_draft.ellipseMinorAxis));
}
- diameter = diam ;
- FNumber = roc/(2. * diameter);
+ m_draft.diameter = diam ;
+ FNumber = m_draft.roc/(2. * m_draft.diameter);
ui->FNumber->blockSignals(true);
const QSignalBlocker blocker(ui->diameter);
ui->FNumber->setText(QString("%1").arg(FNumber *( (mm) ? 1.: 25.4), 6, 'f', 2));
- ui->diameter->setText(QString("%1").arg(diameter * ((mm) ? 1.: 25.4), 6, 'f', 2));
+ ui->diameter->setText(QString("%1").arg(m_draft.diameter * ((mm) ? 1.: 25.4), 6, 'f', 2));
ui->FNumber->blockSignals(false);
ui->diameter->blockSignals(false);
@@ -504,8 +487,8 @@ void mirrorDlg::on_diameter_Changed(const double diam)
void mirrorDlg::on_roc_textChanged(const QString &arg1)
{
- roc = arg1.toDouble() * ((mm) ? 1: 25.4);
- FNumber = roc /(2. * diameter);
+ m_draft.roc = arg1.toDouble() * ((mm) ? 1: 25.4);
+ FNumber = m_draft.roc /(2. * m_draft.diameter);
ui->FNumber->blockSignals(true);
ui->FNumber->setText(QString("%1").arg(FNumber, 6, 'f', 2));
ui->FNumber->blockSignals(false);
@@ -515,33 +498,33 @@ void mirrorDlg::on_roc_textChanged(const QString &arg1)
/* used when the just loading wavefront is different */
void mirrorDlg::on_roc_Changed(const double newVal)
{
- roc = newVal;
+ m_draft.roc = newVal;
- FNumber = roc /(2. * diameter);
+ FNumber = m_draft.roc /(2. * m_draft.diameter);
ui->FNumber->blockSignals(true);
ui->FNumber->setText(QString("%1").arg(FNumber * ((mm) ? 1.: 25.4), 6, 'f', 2));
ui->FNumber->blockSignals(false);
ui->roc->blockSignals(true);
- ui->roc->setText(QString("%1").arg(roc * ((mm) ? 1.: 25.4), 6, 'f', 2));
+ ui->roc->setText(QString("%1").arg(m_draft.roc * ((mm) ? 1.: 25.4), 6, 'f', 2));
ui->roc->blockSignals(false);
updateZ8();
}
void mirrorDlg::updateZ8(){
//Z = d^6 / (16 * R^5)
- double aperature = (ui->ReducApp->isChecked()) ? diameter- aperatureReduction*2. : diameter;
+ double aperature = (ui->ReducApp->isChecked()) ? m_draft.diameter - m_draft.apertureReduction*2. : m_draft.diameter;
z8 = (pow(aperature,4) * 1000000.) /
- (384. * pow(roc, 3) * lambda);
+ (384. * pow(m_draft.roc, 3) * m_draft.lambda);
- if (m_useAnnular){
- double f = (1 - (m_annularObsPercent * m_annularObsPercent));
+ if (m_draft.useAnnulus){
+ double f = (1 - (m_draft.annulusPercent * m_draft.annulusPercent));
f *= f;
z8 *= f;
}
ui->z8->blockSignals(true);
- ui->z8->setText(QString().number(z8 * cc));
+ ui->z8->setText(QString().number(z8 * m_draft.cc));
ui->z8->blockSignals(false);
}
@@ -550,18 +533,18 @@ void mirrorDlg::on_FNumber_textChanged(const QString &arg1)
{
FNumber = arg1.toDouble();
- roc = FNumber *(2 * diameter);
+ m_draft.roc = FNumber *(2 * m_draft.diameter);
ui->roc->blockSignals(true);
- ui->roc->setText(QString().number(roc * ((mm) ? 1.: 1./25.4)));
+ ui->roc->setText(QString().number(m_draft.roc * ((mm) ? 1.: 1./25.4)));
ui->roc->blockSignals(false);
updateZ8();
}
void mirrorDlg::on_obs_textChanged(const QString &arg1)
{
- if (arg1.toDouble() != obs)
+ if (arg1.toDouble() != m_draft.obstruction)
m_obsChanged = true;
- obs = ((mm) ? 1: 25.4) * arg1.toDouble();
+ m_draft.obstruction = ((mm) ? 1: 25.4) * arg1.toDouble();
}
void mirrorDlg::newLambda(const QString &v){
@@ -570,16 +553,16 @@ void mirrorDlg::newLambda(const QString &v){
void mirrorDlg::on_lambda_textChanged(const QString &arg1)
{
- lambda = arg1.toDouble();
+ m_draft.lambda = arg1.toDouble();
updateZ8();
}
void mirrorDlg::on_nullCB_clicked(bool checked)
{
- doNull = checked;
+ m_draft.doNull = checked;
ui->FNumber->blockSignals(true);
ui->roc->blockSignals(true);
- if (!doNull){
+ if (!m_draft.doNull){
ui->FNumber->hide();
ui->fnumberLab->hide();
@@ -603,24 +586,22 @@ void mirrorDlg::on_unitsCB_clicked(bool checked)
ui->roc->blockSignals(true);
ui->diameter->blockSignals(true);
- ui->diameter->setText(QString("%1").arg(diameter/div, 6, 'f', 2));
- ui->roc->setText(QString().number(roc/div));
- ui->obs->setText(QString().number(obs/div));
+ ui->diameter->setText(QString("%1").arg(m_draft.diameter/div, 6, 'f', 2));
+ ui->roc->setText(QString().number(m_draft.roc/div));
+ ui->obs->setText(QString().number(m_draft.obstruction/div));
ui->diameter->blockSignals(false);
ui->roc->blockSignals(false);
ui->minorAxisEdit->blockSignals(true);
- ui->minorAxisEdit->setText(QString("%1").arg(m_verticalAxis/div, 6, 'f', 2));
+ ui->minorAxisEdit->setText(QString("%1").arg(m_draft.ellipseMinorAxis/div, 6, 'f', 2));
ui->reduceValue->blockSignals(true);
ui->annularDiameter->blockSignals(true);
- ui->annularDiameter->setValue(diameter * m_annularObsPercent * ((mm)? 1.: 1./25.4));
+ ui->annularDiameter->setValue(m_draft.diameter * m_draft.annulusPercent * ((mm)? 1.: 1./25.4));
ui->annularDiameter->blockSignals(false);
- // Get aperatureReduction from draft (already loaded from persistent storage)
- aperatureReduction = m_draft.apertureReduction;
-
- ui->reduceValue->setValue(aperatureReduction * ((mm) ? 1. : 1./25.4));
+ // Get apertureReduction from draft (already loaded from persistent storage)
+ ui->reduceValue->setValue(m_draft.apertureReduction * ((mm) ? 1. : 1./25.4));
ui->reduceValue->blockSignals(false);
- ui->ClearAp->setText(QString("%1 ").arg(m_clearAperature * ((mm) ? 1: 1./25.4), 6, 'f', 2));
+ ui->ClearAp->setText(QString("%1 ").arg(m_draft.apertureReduction * ((mm) ? 1: 1./25.4), 6, 'f', 2));
}
void mirrorDlg::on_buttonBox_accepted()
@@ -629,32 +610,17 @@ void mirrorDlg::on_buttonBox_accepted()
updateZ8();
SurfaceManager * sm = SurfaceManager::get_instance();
- if (sm->m_inverseMode == invCONIC && cc==0) {
+ if (sm->m_inverseMode == invCONIC && m_draft.cc == 0) {
sm->m_inverseMode = invNOTSET; // don't allow inverse mode to be conic if conic constant is zero
updateAutoInvertStatus();
}
- // Update draft with current UI values
- m_draft.mirrorName = ui->name->text();
- m_draft.diameter = diameter;
- m_draft.roc = roc;
- m_draft.obstruction = obs;
- m_draft.cc = cc;
- m_draft.lambda = lambda;
- m_draft.fringeSpacing = ui->fringeSpacingEdit->text().toDouble();
- m_draft.flipH = ui->flipH->isChecked();
- m_draft.doNull = doNull;
- m_draft.useAnnulus = m_useAnnular;
- m_draft.annulusPercent = m_annularObsPercent;
- m_draft.annulusToObstruction = m_connectAnnulusToObs;
- m_draft.outlineShape = (int)m_outlineShape;
- m_draft.ellipseMinorAxis = m_verticalAxis;
- m_draft.apertureReductionEnabled = m_aperatureReductionEnabled;
- m_draft.apertureReduction = aperatureReduction;
+ // Commit draft edits to persistent copy
+ m_current = m_draft;
- // Persist draft to QSettings via facade (single atomic save)
+ // Persist persistent copy to QSettings via facade (single atomic save)
// Note: Only mirrordlg can call this (via friend declaration) - enforces single source of truth
- SettingsFacade::instance().saveMirrorSettings(m_draft);
+ SettingsFacade::instance().saveMirrorSettings(m_current);
if (m_obsChanged)
emit obstructionChanged();
@@ -670,18 +636,18 @@ void mirrorDlg::on_buttonBox_accepted()
void mirrorDlg::on_cc_textChanged(const QString &arg1)
{
- cc = arg1.toDouble();
+ m_draft.cc = arg1.toDouble();
updateZ8();
}
void mirrorDlg::spacingChangeTimeout(){
spacingChangeTimer.stop();
double v = ui->fringeSpacingEdit->text().toDouble();
- if ( v != fringeSpacing){
+ if ( v != m_draft.fringeSpacing){
QMessageBox::information(0,"Fringe Spacing Changed", "This change will only be used when Interferograms are analyzed. "
"It will not be applied to any existing wavefronts already loaded.");
}
- fringeSpacing = v;
+ m_draft.fringeSpacing = v;
}
@@ -692,7 +658,7 @@ void mirrorDlg::on_fringeSpacingEdit_textChanged(const QString & /*text*/)
void mirrorDlg::on_name_editingFinished()
{
- m_name = ui->name->text();
+ m_draft.mirrorName = ui->name->text();
}
@@ -700,34 +666,32 @@ void mirrorDlg::on_name_editingFinished()
void mirrorDlg::on_minorAxisEdit_textChanged(const QString &arg1)
{
- m_verticalAxis = arg1.toDouble();
+ m_draft.ellipseMinorAxis = arg1.toDouble();
}
void mirrorDlg::setMinorAxis(double val){
- m_verticalAxis = val;
+ m_draft.ellipseMinorAxis = val;
ui->minorAxisEdit->setText(QString::number(val));
//on_minorAxisEdit_textChanged( QString::number(val));
}
void mirrorDlg::setVerticalAxis(double val){
- m_verticalAxis = val;
m_draft.ellipseMinorAxis = val;
}
void mirrorDlg::setOutlineShape(outlineShape shape){
- m_outlineShape = shape;
m_draft.outlineShape = (int)shape;
ui->ellipseShape->setChecked(shape == ELLIPSE);
}
void mirrorDlg::on_ellipseShape_clicked(bool checked)
{
- if (checked) m_outlineShape = ELLIPSE;
- else m_outlineShape = CIRCLE;
+ if (checked) m_draft.outlineShape = (int)ELLIPSE;
+ else m_draft.outlineShape = (int)CIRCLE;
- if (m_verticalAxis == 0){
- m_verticalAxis = diameter;
- ui->minorAxisEdit->setText(QString().number(m_verticalAxis));
+ if (m_draft.ellipseMinorAxis == 0){
+ m_draft.ellipseMinorAxis = m_draft.diameter;
+ ui->minorAxisEdit->setText(QString().number(m_draft.ellipseMinorAxis));
}
}
@@ -740,21 +704,21 @@ void mirrorDlg::on_buttonBox_helpRequested()
void mirrorDlg::setclearAp(){
- m_clearAperature = (diameter - aperatureReduction * 2) ;
- if (m_aperatureReductionEnabled == false)
- m_clearAperature = diameter;
- ui->ClearAp->setText(QString("%1 ").arg(m_clearAperature * ((mm) ? 1: 1./25.4), 6, 'f', 2));
+ double clearAperature = (m_draft.diameter - m_draft.apertureReduction * 2) ;
+ if (m_draft.apertureReductionEnabled == false)
+ clearAperature = m_draft.diameter;
+ ui->ClearAp->setText(QString("%1 ").arg(clearAperature * ((mm) ? 1: 1./25.4), 6, 'f', 2));
}
void mirrorDlg::on_ReducApp_clicked(bool checked)
{
- m_aperatureReductionEnabled = checked;
+ m_draft.apertureReductionEnabled = checked;
ui->reduceValue->setEnabled(checked);
ui->ClearAp->setVisible(checked);
ui->clearApLabel->setVisible(checked);
updateZ8();
- ui->reduceValue->setValue(aperatureReduction);
+ ui->reduceValue->setValue(m_draft.apertureReduction);
m_aperatureReductionValueChanged = true;
setclearAp();
emit aperatureChanged();
@@ -763,7 +727,7 @@ void mirrorDlg::on_ReducApp_clicked(bool checked)
void mirrorDlg::on_reduceValue_valueChanged(double arg1)
{
- aperatureReduction = ((mm) ? 1: 25.4) * arg1;
+ m_draft.apertureReduction = ((mm) ? 1: 25.4) * arg1;
updateZ8();
setclearAp();
@@ -774,12 +738,12 @@ void mirrorDlg::on_reduceValue_valueChanged(double arg1)
void mirrorDlg::on_annulusPercent_valueChanged(double arg1)
{
ui->annularDiameter->blockSignals(true);
- m_annularObsPercent = .01 * arg1;
- ui->annularDiameter->setValue( m_annularObsPercent * diameter * ( (mm) ? 1.: 1./25.4));
+ m_draft.annulusPercent = .01 * arg1;
+ ui->annularDiameter->setValue( m_draft.annulusPercent * m_draft.diameter * ( (mm) ? 1.: 1./25.4));
ui->annularDiameter->blockSignals(false);
- if (m_connectAnnulusToObs){
- ui->obs->setText(QString::number(m_annularObsPercent * diameter * ((mm)? 1.: 1./25.4)));
+ if (m_draft.annulusToObstruction){
+ ui->obs->setText(QString::number(m_draft.annulusPercent * m_draft.diameter * ((mm)? 1.: 1./25.4)));
}
updateZ8();
}
@@ -805,7 +769,7 @@ void mirrorDlg::enableAnnular(bool enable){
void mirrorDlg::on_useAnnulus_clicked(bool checked)
{
- m_useAnnular = checked;
+ m_draft.useAnnulus = checked;
enableAnnular(checked);
updateZ8();
@@ -823,8 +787,8 @@ void mirrorDlg::on_annulusHelp_clicked()
void mirrorDlg::on_annularDiameter_valueChanged(double arg1)
{
- m_annularObsPercent = arg1/diameter;
- ui->annulusPercent->setValue(m_annularObsPercent * 100);
+ m_draft.annulusPercent = arg1/m_draft.diameter;
+ ui->annulusPercent->setValue(m_draft.annulusPercent * 100);
updateZ8();
}
@@ -859,7 +823,7 @@ void mirrorDlg::on_btnChangeAutoInvert_clicked()
{
autoInvertDlg dlg;
dlg.setMainLabel("How should DFTFringe choose to auto invert?");
- dlg.enableConic(cc != 0);
+ dlg.enableConic(m_draft.cc != 0);
dlg.exec();
updateAutoInvertStatus();
}
diff --git a/mirrordlg.h b/mirrordlg.h
index 4fc1efa3..ca0ad9c3 100644
--- a/mirrordlg.h
+++ b/mirrordlg.h
@@ -32,6 +32,8 @@ class mirrorDlg : public QDialog
Q_OBJECT
public:
+ //TODO if we get rid of the singleton design, settings are read from settingsFacade instead here
+ // check if it makes sense
static mirrorDlg *get_Instance();
~mirrorDlg();
mirrorDlg(const mirrorDlg&) = delete;
@@ -65,31 +67,17 @@ class mirrorDlg : public QDialog
void setOutlineShape(outlineShape shape);
void setObsPercent(double obs);
- /** @brief Access current mirror settings (read-only snapshot).
- * Returns the draft which is the canonical storage for all mirror config.
- * All internal member variables are kept in sync with this. */
- const MirrorSettings& currentSettings() const { return m_draft; }
+ /** @brief Access current mirror settings.
+ * Returns the persistent copy - the last saved state.
+ * External code reads this as source of truth. */
+ const MirrorSettings& currentSettings() const { return m_current; }
private:
- // Configuration members (access via currentSettings() or setters)
- QString m_name;
- double diameter;
- double roc;
- double obs; // obstruction
- double cc;
- bool doNull;
- double lambda;
- double fringeSpacing;
- bool flipv;
- bool fliph;
- bool m_useAnnular;
- bool m_connectAnnulusToObs;
- double m_annularObsPercent; // a value from 0 to 1 (not 0 to 100)
- double m_clearAperature;
- double aperatureReduction;
- bool m_aperatureReductionEnabled;
- double m_verticalAxis;
- outlineShape m_outlineShape;
+ // Persistent mirror configuration copy (source of truth for external code)
+ MirrorSettings m_current;
+
+ // Working copy for dialog edits (discarded on Cancel, committed to m_current on OK)
+ MirrorSettings m_draft;
private slots:
void on_ReadBtn_clicked();
@@ -141,6 +129,8 @@ private slots:
void on_btnChangeAutoInvert_clicked();
signals:
+ // TODO some of these are not used.
+ // also notify shoud probably only happen when OK is clicked, not on every change.
void diameterChanged(double);
void rocChanged(double);
void lambdaChanged(double);
@@ -152,8 +142,7 @@ private slots:
void aperatureChanged();
protected:
- /** @brief Reload draft settings before dialog becomes visible.
- * Ensures Cancel always reverts to the last-saved state (issue #121). */
+ /** @brief Reload settings before dialog becomes visible. */
void showEvent(QShowEvent *event) override;
private:
@@ -170,10 +159,6 @@ private slots:
void saveJson(const QString &fileName);
void enableAnnular(bool enable);
- /** @brief Working copy of mirror settings during dialog edit.
- * All UI modifications update this draft. On OK, it persists via facade.
- * On Cancel, it's discarded, leaving member variables unchanged. */
- MirrorSettings m_draft;
};
#endif // MIRRORDLG_H
From 7813be5579c9c0da0443cca3d817910e143b6c42 Mon Sep 17 00:00:00 2001
From: Julien STAUB
Date: Sat, 8 Aug 2026 16:10:40 +0200
Subject: [PATCH 10/20] fix some compile errors and make more things private
---
defocusdlg.cpp | 2 +-
mainwindow.cpp | 4 +--
metricsdisplay.cpp | 2 +-
mirrordlg.cpp | 3 --
mirrordlg.h | 62 +++++++++++++++++++++++-----------------
percentcorrectiondlg.cpp | 4 +--
profileplot.cpp | 4 +--
statsview.cpp | 2 +-
surfacemanager.cpp | 8 +++---
wftstats.cpp | 2 +-
zernikedlg.cpp | 2 +-
zernikeprocess.cpp | 4 +--
12 files changed, 52 insertions(+), 47 deletions(-)
diff --git a/defocusdlg.cpp b/defocusdlg.cpp
index 0bbd223c..11c35d03 100644
--- a/defocusdlg.cpp
+++ b/defocusdlg.cpp
@@ -86,7 +86,7 @@ void defocusDlg::on_defocusSlider_valueChanged(int value)
ui->defocusVal->setValue(val);
ui->defocusVal->blockSignals(false);
- double f = mirrorDlg::get_Instance()->FNumber;
+ double f = mirrorDlg::get_Instance()->getFNumber();
double mm = f * f * 8. * value * .00055; //mmeters
m_defocusInmm = mm;
qDebug() << "defocus offset" << mm;
diff --git a/mainwindow.cpp b/mainwindow.cpp
index 372c83d0..3b69a282 100644
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -593,10 +593,10 @@ void MainWindow::updateMetrics(wavefront& wf){
double z8 = zernTablemodel->values[8];
double BestSC;
if (m_mirrorDlg->currentSettings().doNull && wf.useSANull){
- BestSC = z8/m_mirrorDlg->z8;
+ BestSC = z8/m_mirrorDlg->getZ8();
}
else {
- BestSC = m_mirrorDlg->currentSettings().cc +z8/m_mirrorDlg->z8;
+ BestSC = m_mirrorDlg->currentSettings().cc +z8/m_mirrorDlg->getZ8();
}
metrics->setOutputLambda(outputLambda);
diff --git a/metricsdisplay.cpp b/metricsdisplay.cpp
index 178d8fb7..0f70bd73 100644
--- a/metricsdisplay.cpp
+++ b/metricsdisplay.cpp
@@ -58,7 +58,7 @@ void metricsDisplay::setWavePerFringe(double val, double lambda){
ui->wavesPerFringe->setText(QString("Waves Per Fringe: %1").arg(val, 2, 'f', 1));
ui->lambda->setText(QString("Igram laser wavelength: %1 nm").arg(lambda, 6, 'f', 2));
mirrorDlg *md = mirrorDlg::get_Instance();
- QString donull = (md->currentSettings().doNull) ? (QString("SANull: %1").arg(md->z8 * md->currentSettings().cc, 6, 'f', 4)) : "";
+ QString donull = (md->currentSettings().doNull) ? (QString("SANull: %1").arg(md->getZ8() * md->currentSettings().cc, 6, 'f', 4)) : "";
ui->desiredConicLb->setText(QString("Desired Conic: %1 ").arg( md->currentSettings().cc, 6, 'f', 2) + donull);
if (md->isEllipse()){
ui->desiredConicLb->setText("");
diff --git a/mirrordlg.cpp b/mirrordlg.cpp
index a613906d..ad36e877 100644
--- a/mirrordlg.cpp
+++ b/mirrordlg.cpp
@@ -792,9 +792,6 @@ void mirrorDlg::on_annularDiameter_valueChanged(double arg1)
updateZ8();
}
-void mirrorDlg::setObsPercent(double obs){
- ui->annulusPercent->setValue(obs);
-}
void mirrorDlg::updateAutoInvertStatus()
{
diff --git a/mirrordlg.h b/mirrordlg.h
index ca0ad9c3..ee8720e1 100644
--- a/mirrordlg.h
+++ b/mirrordlg.h
@@ -32,40 +32,32 @@ class mirrorDlg : public QDialog
Q_OBJECT
public:
- //TODO if we get rid of the singleton design, settings are read from settingsFacade instead here
+ // TODO if we get rid of the singleton design, settings could be read from settingsFacade instead here
// check if it makes sense
static mirrorDlg *get_Instance();
~mirrorDlg();
mirrorDlg(const mirrorDlg&) = delete;
mirrorDlg& operator=(const mirrorDlg&) = delete;
- // File and configuration operations
- void loadFile(QString & fileName);
- void updateZ8();
+ // TODO this group must be investigatedto validate they are OK
+ // we cannot change settings/configuration from both outside and inside the dialog. We need to have a single source of truth for settings/configuration.
void updateAutoInvertStatus();
-
- // Computed/derived values (read-only, not from settings)
- bool mm;
- double FNumber;
- double z8;
- static QString m_projectPath;
-
- // State flags
- bool m_obsChanged;
- bool m_majorHorizontal;
-
- // Methods for configuration access/modification
+ void newLambda(const QString &v);
+ void setMinorAxis(double val);
+ void setVerticalAxis(double val);
+ void setOutlineShape(outlineShape shape);
void on_roc_Changed(const double newVal);
void on_diameter_Changed(const double diam);
- bool shouldFlipH();
+
+
+ // Computed/derived value accessors (read-only)
+ double getFNumber() const { return FNumber; }
+ double getZ8() const { return z8; }
static QString getProjectPath();
- void newLambda(const QString &v);
double getMinorAxis();
bool isEllipse();
- void setMinorAxis(double val);
- void setVerticalAxis(double val);
- void setOutlineShape(outlineShape shape);
- void setObsPercent(double obs);
+ bool shouldFlipH();
+
/** @brief Access current mirror settings.
* Returns the persistent copy - the last saved state.
@@ -73,11 +65,7 @@ class mirrorDlg : public QDialog
const MirrorSettings& currentSettings() const { return m_current; }
private:
- // Persistent mirror configuration copy (source of truth for external code)
- MirrorSettings m_current;
-
- // Working copy for dialog edits (discarded on Cancel, committed to m_current on OK)
- MirrorSettings m_draft;
+
private slots:
void on_ReadBtn_clicked();
@@ -154,10 +142,30 @@ private slots:
void loadDraftFromSettings();
Ui::mirrorDlg *ui;
+
+ // State flags
bool m_aperatureReductionValueChanged;
+ bool m_obsChanged;
+
QTimer spacingChangeTimer;
+
+ // Persistent mirror configuration copy (source of truth for external code)
+ MirrorSettings m_current;
+
+ // Working copy for dialog edits (discarded on Cancel, committed to m_current on OK)
+ MirrorSettings m_draft;
+
+ // Computed/derived values (read-only, not from settings)
+ //TODO actually mm is not saved in settings. should probably be saved as it's a user preference. I need to check what happens when user enters values in mm or inch and reopens DFTFringe
+ bool mm; // Unit display flag: true = mm, false = other units
+ double FNumber; // Computed f-number (focal length / diameter)
+ double z8; // Z8 Zernike coefficient or null reference value
+ static QString m_projectPath; // Current project directory path
+
void saveJson(const QString &fileName);
void enableAnnular(bool enable);
+ void updateZ8();
+ void loadFile(QString & fileName);
};
diff --git a/percentcorrectiondlg.cpp b/percentcorrectiondlg.cpp
index fa205094..31da9def 100644
--- a/percentcorrectiondlg.cpp
+++ b/percentcorrectiondlg.cpp
@@ -355,7 +355,7 @@ QPolygonF percentCorrectionDlg::makePercentages(surfaceData *surf){
ActualZoneKnife << 0.0;
mirrorDlg *md = mirrorDlg::get_Instance();
- double nullval = md->z8 * md->currentSettings().cc; // null value was computed at the igram wavevlength
+ double nullval = md->getZ8() * md->currentSettings().cc; // null value was computed at the igram wavevlength
nullval *= m_lambda_nm/m_outputLambda; // only data from the profile needs the null but it's data is at the output wavelength;
// process each zone center
@@ -401,7 +401,7 @@ QPolygonF percentCorrectionDlg::makePercentages(surfaceData *surf){
void percentCorrectionDlg::plotProfile(){
mirrorDlg *md = mirrorDlg::get_Instance();
- double nullval = md->z8 * md->currentSettings().cc;
+ double nullval = md->getZ8() * md->currentSettings().cc;
for (int i = 0; i < surfs.length(); ++ i) {
QwtPlotCurve *Curve = new QwtPlotCurve();
diff --git a/profileplot.cpp b/profileplot.cpp
index 853ffe5c..d5ea053d 100644
--- a/profileplot.cpp
+++ b/profileplot.cpp
@@ -406,7 +406,7 @@ QPolygonF ProfilePlot::createAverageProfile(double /*umnits*/, wavefront * /*wf*
// double rho = avg[i].x() / md.diameter/2.;
// double rho2 = rho * rho;
// double y = avg[i].y();
-// y += md.z8 * md.cc * (1. + rho2 * (-6 + 6. * rho2));
+// y += md.getZ8() * md.cc * (1. + rho2 * (-6 + 6. * rho2));
// avg2 << QPointF(avg[i].x(),y);
// }
// avg = avg2;
@@ -1174,7 +1174,7 @@ void ProfilePlot::CreateWaveFrontFromAverage(){
for (unsigned int i = 0; i < avgRadius.size(); ++i) {
double R2 = (double(i))/(avgRadius.size() -1);
R2 *= R2;
- avgRadius[i] += md->z8 * md->currentSettings().cc * (1. + R2 * (-6 + 6. * R2));;
+ avgRadius[i] += md->getZ8() * md->currentSettings().cc * (1. + R2 * (-6 + 6. * R2));;
}
}
cv::Mat result = createInterpolatedCircularSurface(avgRadius);
diff --git a/statsview.cpp b/statsview.cpp
index c7008c94..830d036d 100644
--- a/statsview.cpp
+++ b/statsview.cpp
@@ -270,7 +270,7 @@ void statsView::on_SaveCSV_clicked()
// apply software Null if needed
if (ndx == 8 and md->currentSettings().doNull)
- v -= md->z8 * md->currentSettings().cc;
+ v -= md->getZ8() * md->currentSettings().cc;
double Sigma = computeRMS(ndx,v) * md->currentSettings().lambda/outputLambda;
if (ndx == 8) {
diff --git a/surfacemanager.cpp b/surfacemanager.cpp
index bb4f06fc..058e8958 100644
--- a/surfacemanager.cpp
+++ b/surfacemanager.cpp
@@ -501,7 +501,7 @@ cv::Mat SurfaceManager::computeWaveFrontFromZernikes(int wx, int wy, std::vector
else {
if (en[z]){
if (z == 8 && md->currentSettings().doNull)
- S1 += md->z8 * zpolar.zernike(z);
+ S1 += md->getZ8() * zpolar.zernike(z);
S1 += zerns[z] * zpolar.zernike(z);
}
@@ -800,7 +800,7 @@ void SurfaceManager::useDemoWaveFront(){
if (rho <= 1.)
{
- double S1 = md->z8 * -.9 * zpolar.zernike(8) + .02* zpolar.zernike(9);
+ double S1 = md->getZ8() * -.9 * zpolar.zernike(8) + .02* zpolar.zernike(9);
result.at(j,i) = S1;
}
@@ -3022,7 +3022,7 @@ void SurfaceManager::report(){
QString(" waves at %1 nm | Strehl: ").arg(outputLambda, 6, 'f', 1) + metrics->mStrehl->text() +
" | " + BFC + " |
"
"| " + ((md->isEllipse()) ? "":"Desired Conic: " + QString::number(md->currentSettings().cc)) + " | " +
- ((md->currentSettings().doNull) ? QString("SANull: %1").arg(md->z8 * md->currentSettings().cc, 6, 'f', 4) : "No software Null") + " | "
+ ((md->currentSettings().doNull) ? QString("SANull: %1").arg(md->getZ8() * md->currentSettings().cc, 6, 'f', 4) : "No software Null") + ""
"Waves per fringe: " + QString::number(md->currentSettings().fringeSpacing) + " Interferogram Wave length: "+ QString::number(md->currentSettings().lambda) + "nm |
"
"
";
@@ -3045,7 +3045,7 @@ void SurfaceManager::report(){
enabled = true;
}
if ( i == 8 && md->currentSettings().doNull){
- val -= md->z8 * md->currentSettings().cc;
+ val -= md->getZ8() * md->currentSettings().cc;
}
diff --git a/wftstats.cpp b/wftstats.cpp
index 4b37fefd..f1106625 100644
--- a/wftstats.cpp
+++ b/wftstats.cpp
@@ -215,7 +215,7 @@ void wftStats::computeWftStats( QVector wavefronts, int ndx){
// apply software Null if needed
if (ndx == 8 and md->currentSettings().doNull)
- v -= md->z8 * md->currentSettings().cc;
+ v -= md->getZ8() * md->currentSettings().cc;
double Sigma = computeRMS(ndx,v) * outputLambda/md->currentSettings().lambda;
if (ndx == 8) {
diff --git a/zernikedlg.cpp b/zernikedlg.cpp
index 78acb1d1..4533089d 100644
--- a/zernikedlg.cpp
+++ b/zernikedlg.cpp
@@ -120,7 +120,7 @@ QVariant ZernTableModel::data(const QModelIndex &index, int role) const
mirrorDlg &md = *mirrorDlg::get_Instance();
if (index.row() == 8 && md.currentSettings().doNull && !m_nulled){
- double val = values[8] - md.z8 * md.currentSettings().cc;
+ double val = values[8] - md.getZ8() * md.currentSettings().cc;
return QString("%1 %2").arg(val, 6, 'f', 3).arg( computeRMS(8, val), 6, 'f', 3);
}
diff --git a/zernikeprocess.cpp b/zernikeprocess.cpp
index d2394420..49a7535a 100644
--- a/zernikeprocess.cpp
+++ b/zernikeprocess.cpp
@@ -493,7 +493,7 @@ cv::Mat zernikeProcess::null_unwrapped(wavefront&wf, std::vector zerns,
mirrorDlg *md = mirrorDlg::get_Instance();
- double scz8 = md->z8 * md->currentSettings().cc;
+ double scz8 = md->getZ8() * md->currentSettings().cc;
if (!applyNull || !md->currentSettings().doNull || !wf.useSANull){
@@ -914,7 +914,7 @@ cv::Mat zernikeProcess::makeSurfaceFromZerns(int border, bool doColor){
for (unsigned int z = 0; z < m_zerns.n_cols; ++z){
double val = dlg.zernikes[z];
if (z == 8){
- val = (dlg.doCorrection && md->currentSettings().doNull) ? md->currentSettings().cc * md->z8 * val * .01 : val;
+ val = (dlg.doCorrection && md->currentSettings().doNull) ? md->currentSettings().cc * md->getZ8() * val * .01 : val;
}
S1 += val * m_zerns(i,z)/((doColor) ? md->currentSettings().fringeSpacing: 1.);
From 31ca070a1860f3e40ff6e65ef7e1fe0cf801dde5 Mon Sep 17 00:00:00 2001
From: Julien STAUB
Date: Sun, 9 Aug 2026 08:22:07 +0200
Subject: [PATCH 11/20] delete unused signals
---
mirrordlg.h | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/mirrordlg.h b/mirrordlg.h
index ee8720e1..53b30605 100644
--- a/mirrordlg.h
+++ b/mirrordlg.h
@@ -117,13 +117,7 @@ private slots:
void on_btnChangeAutoInvert_clicked();
signals:
- // TODO some of these are not used.
- // also notify shoud probably only happen when OK is clicked, not on every change.
- void diameterChanged(double);
- void rocChanged(double);
- void lambdaChanged(double);
- void saNullChanged(double);
- void CCChanged(double);
+ // TODO notify shoud probably only happen when OK is clicked, not on every change.
void obstructionChanged();
void newPath(QString);
void recomputeZerns();
From 59c65af8cec1a379f739833a9b61259098bff216 Mon Sep 17 00:00:00 2001
From: Julien STAUB
Date: Sun, 9 Aug 2026 08:26:29 +0200
Subject: [PATCH 12/20] fix compile warning
---
mirrordlg.cpp | 4 +++-
mirrordlg.h | 2 +-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/mirrordlg.cpp b/mirrordlg.cpp
index ad36e877..8b3f2c54 100644
--- a/mirrordlg.cpp
+++ b/mirrordlg.cpp
@@ -41,7 +41,9 @@ mirrorDlg *mirrorDlg::get_Instance(){
mirrorDlg::mirrorDlg(QWidget *parent) :
QDialog(parent),
- mm(true),m_obsChanged(false),ui(new Ui::mirrorDlg)
+ ui(new Ui::mirrorDlg),
+ m_obsChanged(false),
+ mm(true)
{
ui->setupUi(this);
diff --git a/mirrordlg.h b/mirrordlg.h
index 53b30605..5afcad1b 100644
--- a/mirrordlg.h
+++ b/mirrordlg.h
@@ -39,7 +39,7 @@ class mirrorDlg : public QDialog
mirrorDlg(const mirrorDlg&) = delete;
mirrorDlg& operator=(const mirrorDlg&) = delete;
- // TODO this group must be investigatedto validate they are OK
+ // TODO this group must be investigated to validate they are OK
// we cannot change settings/configuration from both outside and inside the dialog. We need to have a single source of truth for settings/configuration.
void updateAutoInvertStatus();
void newLambda(const QString &v);
From 805252fd877b9d6ddf46510ad8af0fef793d0731 Mon Sep 17 00:00:00 2001
From: Julien STAUB
Date: Sun, 9 Aug 2026 08:33:15 +0200
Subject: [PATCH 13/20] remove duplicate operation
---
mainwindow.cpp | 7 +------
mainwindow.h | 1 -
mirrordlg.cpp | 4 +---
mirrordlg.h | 1 -
4 files changed, 2 insertions(+), 11 deletions(-)
diff --git a/mainwindow.cpp b/mainwindow.cpp
index 3b69a282..1edb341f 100644
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -274,7 +274,6 @@ MainWindow::MainWindow(QWidget *parent) :
}
connect(m_surfaceManager, &SurfaceManager::rocChanged,this, &MainWindow::rocChanged);
- connect(m_mirrorDlg, &mirrorDlg::newPath,this, &MainWindow::newMirrorDlgPath);
progBar = new QProgressBar(this);
status1 = new QLabel();
@@ -845,11 +844,7 @@ void MainWindow::on_showIntensity_clicked(bool checked)
else
m_intensityPlot->close();
}
-void MainWindow::newMirrorDlgPath(const QString &path){
- QFileInfo info(path);
- QSettings settings;
- settings.setValue("lastPath",info.path());
-}
+
//make a simulated wavefront based on zernike values
#define TSIZE 200
void MainWindow::on_actionWavefront_triggered()
diff --git a/mainwindow.h b/mainwindow.h
index 1f03c955..c9b5f684 100644
--- a/mainwindow.h
+++ b/mainwindow.h
@@ -120,7 +120,6 @@ private slots:
void on_shiftDown_clicked();
void on_shiftRight_clicked();
void selectDftTab();
- void newMirrorDlgPath(const QString &path);
void on_actionRead_WaveFront_triggered();
void on_actionPreferences_triggered();
diff --git a/mirrordlg.cpp b/mirrordlg.cpp
index 8b3f2c54..c2c5bd49 100644
--- a/mirrordlg.cpp
+++ b/mirrordlg.cpp
@@ -204,9 +204,7 @@ void mirrorDlg::loadFile(QString & fileName){
// Persist UI convenience path to QSettings
QSettings settings;
settings.setValue("lastPath", info.absolutePath());
-
- emit newPath(info.absolutePath());
-
+
// Update application settings with new file path and mirror config file via facade
ApplicationSettings appSettings = SettingsFacade::instance().appStore().load();
appSettings.projectPath = info.absolutePath();
diff --git a/mirrordlg.h b/mirrordlg.h
index 5afcad1b..742b34f5 100644
--- a/mirrordlg.h
+++ b/mirrordlg.h
@@ -119,7 +119,6 @@ private slots:
signals:
// TODO notify shoud probably only happen when OK is clicked, not on every change.
void obstructionChanged();
- void newPath(QString);
void recomputeZerns();
void aperatureChanged();
From 42a20fcc4498e1031e718d79802700623360273d Mon Sep 17 00:00:00 2001
From: Julien STAUB
Date: Sun, 9 Aug 2026 13:23:49 +0200
Subject: [PATCH 14/20] simplify mirrordlg settings adoption from wft
---
mainwindow.cpp | 11 -------
mainwindow.h | 2 --
mirrordlg.cpp | 74 ++++++++++++++++++++++------------------------
mirrordlg.h | 26 ++++++++++------
surfacemanager.cpp | 13 ++++++--
surfacemanager.h | 2 --
6 files changed, 62 insertions(+), 66 deletions(-)
diff --git a/mainwindow.cpp b/mainwindow.cpp
index 1edb341f..50339b1d 100644
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -194,7 +194,6 @@ MainWindow::MainWindow(QWidget *parent) :
m_ogl->m_surface, metrics);
connect(m_contourView, &contourView::showAllContours, m_surfaceManager, &SurfaceManager::showAllContours);
connect(m_dftArea, &DFTArea::newWavefront, m_surfaceManager, &SurfaceManager::createSurfaceFromPhaseMap);
- connect(m_surfaceManager, &SurfaceManager::diameterChanged,this,&MainWindow::diameterChanged);
connect(m_surfaceManager, &SurfaceManager::showTab, ui->tabWidget, &QTabWidget::setCurrentIndex);
connect(m_surfTools, &surfaceAnalysisTools::updateSelected, m_surfaceManager, &SurfaceManager::backGroundUpdate);
ui->tabWidget->addTab(review, "Results");
@@ -273,7 +272,6 @@ MainWindow::MainWindow(QWidget *parent) :
zernEnables[i] = false;
}
- connect(m_surfaceManager, &SurfaceManager::rocChanged,this, &MainWindow::rocChanged);
progBar = new QProgressBar(this);
status1 = new QLabel();
@@ -778,15 +776,6 @@ void MainWindow::showMessage(const QString &msg, int id){
}
-void MainWindow::diameterChanged(double v){
- m_mirrorDlg->on_diameter_Changed(v);
-}
-void MainWindow::rocChanged(double v){
- m_mirrorDlg->on_roc_Changed(v);
-}
-
-
-
void MainWindow::on_SelectOutSideOutline_clicked(bool checked)
{
m_igramArea->SideOutLineActive( checked);
diff --git a/mainwindow.h b/mainwindow.h
index c9b5f684..80e95758 100644
--- a/mainwindow.h
+++ b/mainwindow.h
@@ -84,8 +84,6 @@ class MainWindow : public QMainWindow
public slots:
void enableShiftButtons(bool enable);
void showMessage(const QString&, int id);
- void diameterChanged(double);
- void rocChanged(double);
void batchProcess(QStringList fileList);
void batchMakeSurfaceReady();
void batchConnections(bool flag);
diff --git a/mirrordlg.cpp b/mirrordlg.cpp
index c2c5bd49..ae71c5bc 100644
--- a/mirrordlg.cpp
+++ b/mirrordlg.cpp
@@ -428,6 +428,41 @@ void mirrorDlg::loadFile(QString & fileName){
}
}
}
+
+void mirrorDlg::adoptWavefrontSettings(double diameter, double roc, double lambda)
+{
+ if ((outlineShape)m_draft.outlineShape == ELLIPSE && m_draft.diameter != 0.0) {
+ const double e = m_draft.ellipseMinorAxis / m_draft.diameter;
+ m_draft.ellipseMinorAxis = e * diameter;
+ }
+
+ m_draft.diameter = diameter;
+ m_draft.roc = roc;
+ m_draft.lambda = lambda;
+
+ FNumber = m_draft.roc / (2. * m_draft.diameter);
+
+ {
+ const QSignalBlocker blockDiameter(ui->diameter);
+ const QSignalBlocker blockRoc(ui->roc);
+ const QSignalBlocker blockLambda(ui->lambda);
+ const QSignalBlocker blockMinor(ui->minorAxisEdit);
+ const QSignalBlocker blockFNumber(ui->FNumber);
+
+ ui->diameter->setText(QString("%1").arg(m_draft.diameter * ((mm) ? 1. : 1./25.4), 6, 'f', 2));
+ ui->roc->setText(QString("%1").arg(m_draft.roc * ((mm) ? 1. : 1./25.4), 6, 'f', 2));
+ ui->lambda->setText(QString("%1").arg(m_draft.lambda, 6, 'f', 1));
+ ui->minorAxisEdit->setText(QString::number(m_draft.ellipseMinorAxis));
+ ui->FNumber->setText(QString("%1").arg(FNumber, 6, 'f', 2));
+ }
+
+ setclearAp();
+ updateZ8();
+
+ m_current = m_draft;
+ SettingsFacade::instance().saveMirrorSettings(m_current);
+}
+
void mirrorDlg::on_ReadBtn_clicked()
{
QSettings settings;
@@ -463,28 +498,6 @@ void mirrorDlg::on_diameter_textChanged(const QString &arg1) {
}
-//Used when the just loading wavfront is different
-void mirrorDlg::on_diameter_Changed(const double diam)
-{
- if ((outlineShape)m_draft.outlineShape == ELLIPSE){
- double e = m_draft.ellipseMinorAxis/m_draft.diameter;
- m_draft.ellipseMinorAxis = e * diam;
- ui->minorAxisEdit->setText(QString().number(m_draft.ellipseMinorAxis));
- }
- m_draft.diameter = diam ;
- FNumber = m_draft.roc/(2. * m_draft.diameter);
- ui->FNumber->blockSignals(true);
- const QSignalBlocker blocker(ui->diameter);
- ui->FNumber->setText(QString("%1").arg(FNumber *( (mm) ? 1.: 25.4), 6, 'f', 2));
- ui->diameter->setText(QString("%1").arg(m_draft.diameter * ((mm) ? 1.: 25.4), 6, 'f', 2));
- ui->FNumber->blockSignals(false);
- ui->diameter->blockSignals(false);
-
- setclearAp();
- updateZ8();
-
-}
-
void mirrorDlg::on_roc_textChanged(const QString &arg1)
{
m_draft.roc = arg1.toDouble() * ((mm) ? 1: 25.4);
@@ -495,20 +508,6 @@ void mirrorDlg::on_roc_textChanged(const QString &arg1)
updateZ8();
}
-/* used when the just loading wavefront is different */
-void mirrorDlg::on_roc_Changed(const double newVal)
-{
- m_draft.roc = newVal;
-
- FNumber = m_draft.roc /(2. * m_draft.diameter);
- ui->FNumber->blockSignals(true);
- ui->FNumber->setText(QString("%1").arg(FNumber * ((mm) ? 1.: 25.4), 6, 'f', 2));
- ui->FNumber->blockSignals(false);
- ui->roc->blockSignals(true);
- ui->roc->setText(QString("%1").arg(m_draft.roc * ((mm) ? 1.: 25.4), 6, 'f', 2));
- ui->roc->blockSignals(false);
- updateZ8();
-}
void mirrorDlg::updateZ8(){
//Z = d^6 / (16 * R^5)
@@ -547,9 +546,6 @@ void mirrorDlg::on_obs_textChanged(const QString &arg1)
m_draft.obstruction = ((mm) ? 1: 25.4) * arg1.toDouble();
}
-void mirrorDlg::newLambda(const QString &v){
- ui->lambda->setText(v);
-}
void mirrorDlg::on_lambda_textChanged(const QString &arg1)
{
diff --git a/mirrordlg.h b/mirrordlg.h
index 742b34f5..8efb835d 100644
--- a/mirrordlg.h
+++ b/mirrordlg.h
@@ -39,16 +39,24 @@ class mirrorDlg : public QDialog
mirrorDlg(const mirrorDlg&) = delete;
mirrorDlg& operator=(const mirrorDlg&) = delete;
- // TODO this group must be investigated to validate they are OK
- // we cannot change settings/configuration from both outside and inside the dialog. We need to have a single source of truth for settings/configuration.
- void updateAutoInvertStatus();
- void newLambda(const QString &v);
- void setMinorAxis(double val);
+ void updateAutoInvertStatus(); //This one makes sense. Not saved
+
+ // ---- file loading ----
+ //TODO This one not OK. Edits m_draft.ellipseMinorAxis and wont get saved.
+ // need to investigate why external code needs to change the minor axis. If it is a user preference, it should be saved in settings. If it is a computed value, it should be computed from other values and not set directly.
+ void setMinorAxis(double val);
+ //TODO even worse, same thing but it doesn't update UI text
+ // on call from a file load but the other ?
void setVerticalAxis(double val);
+ // TODO not OK. Edits m_draft.outlineShape and wont get saved
+ // from file load
void setOutlineShape(outlineShape shape);
- void on_roc_Changed(const double newVal);
- void on_diameter_Changed(const double diam);
+
+ // Apply loaded wavefront settings to both runtime and persisted mirror settings.
+ // Intended for a single call after wavefront load mismatch decisions are finalized.
+ void adoptWavefrontSettings(double diameter, double roc, double lambda);
+
// Computed/derived value accessors (read-only)
double getFNumber() const { return FNumber; }
@@ -117,10 +125,9 @@ private slots:
void on_btnChangeAutoInvert_clicked();
signals:
- // TODO notify shoud probably only happen when OK is clicked, not on every change.
void obstructionChanged();
void recomputeZerns();
- void aperatureChanged();
+ void aperatureChanged(); // TODO this one only : notify shoud probably only happen when OK is clicked, not on every change.
protected:
/** @brief Reload settings before dialog becomes visible. */
@@ -143,6 +150,7 @@ private slots:
QTimer spacingChangeTimer;
// Persistent mirror configuration copy (source of truth for external code)
+ //TODO check if all UI settings are actually saved in settings
MirrorSettings m_current;
// Working copy for dialog edits (discarded on Cancel, committed to m_current on OK)
diff --git a/surfacemanager.cpp b/surfacemanager.cpp
index 058e8958..804172ab 100644
--- a/surfacemanager.cpp
+++ b/surfacemanager.cpp
@@ -1327,6 +1327,8 @@ wavefront * SurfaceManager::readWaveFront(const QString &fileName){
}
wf->m_inside = CircleOutline(QPointF(xo,yo), rado);
+ bool shouldAdoptWavefrontSettings = false;
+
if (lambda != md->currentSettings().lambda){
if (lambdResp == ASK){
@@ -1350,7 +1352,7 @@ wavefront * SurfaceManager::readWaveFront(const QString &fileName){
}
if ( lambdResp == YES || messageResult == QMessageBox::Yes){
- md->newLambda(QString::number(lambda));
+ shouldAdoptWavefrontSettings = true;
}
}
@@ -1374,7 +1376,7 @@ wavefront * SurfaceManager::readWaveFront(const QString &fileName){
}
}
if (diamResp == YES || messageResult == QMessageBox::Yes){
- emit diameterChanged(diam);
+ shouldAdoptWavefrontSettings = true;
}
else {
diam = md->currentSettings().diameter;
@@ -1403,13 +1405,18 @@ wavefront * SurfaceManager::readWaveFront(const QString &fileName){
}
}
if (rocResp == YES || messageResult == QMessageBox::Yes){
- emit rocChanged(roc);
+ shouldAdoptWavefrontSettings = true;
}
else {
roc = md->currentSettings().roc;
}
}
+
+ if (shouldAdoptWavefrontSettings) {
+ md->adoptWavefrontSettings(diam, roc, lambda);
+ }
+
wf->diameter = diam;
wf->roc = roc;
wf->lambda = lambda;
diff --git a/surfacemanager.h b/surfacemanager.h
index 39587023..a726fe8a 100644
--- a/surfacemanager.h
+++ b/surfacemanager.h
@@ -147,8 +147,6 @@ class SurfaceManager : public QObject
void deleteWavefront(int);
void rotateTheseSig(int, QList);
void progress(int);
- void diameterChanged(double);
- void rocChanged(double);
void nameChanged(const QString &, const QString &);
void showTab(int);
void enableControls(bool);
From 3381113f0f64a38827f3596f8d10a3b0800baad5 Mon Sep 17 00:00:00 2001
From: Julien STAUB
Date: Sun, 9 Aug 2026 14:40:58 +0200
Subject: [PATCH 15/20] comment settings things that are not yet used
---
settingsfacade.cpp | 43 +++++++++++++------------
settingsfacade.h | 21 ++++++------
settingsstores.cpp | 65 ++++++++++++++++++-------------------
settingsstores.h | 67 +++++++++++++++++++--------------------
settingsstores_fields.inc | 5 +--
5 files changed, 102 insertions(+), 99 deletions(-)
diff --git a/settingsfacade.cpp b/settingsfacade.cpp
index 5a65fcac..52617eb6 100644
--- a/settingsfacade.cpp
+++ b/settingsfacade.cpp
@@ -16,24 +16,9 @@ const MirrorSettingsStore &SettingsFacade::mirrorStore() const
return m_mirrorStore;
}
-GeneralProcessingSettingsStore &SettingsFacade::generalProcessingStore()
-{
- return m_generalProcessingStore;
-}
-
-const GeneralProcessingSettingsStore &SettingsFacade::generalProcessingStore() const
-{
- return m_generalProcessingStore;
-}
-
-ContourSettingsStore &SettingsFacade::contourStore()
-{
- return m_contourStore;
-}
-
-const ContourSettingsStore &SettingsFacade::contourStore() const
+void SettingsFacade::saveMirrorSettings(const MirrorSettings &settings)
{
- return m_contourStore;
+ m_mirrorStore.save(settings);
}
ApplicationSettingsStore &SettingsFacade::appStore()
@@ -46,7 +31,23 @@ const ApplicationSettingsStore &SettingsFacade::appStore() const
return m_appStore;
}
-void SettingsFacade::saveMirrorSettings(const MirrorSettings &settings)
-{
- m_mirrorStore.save(settings);
-}
+// examples for future PRs
+//GeneralProcessingSettingsStore &SettingsFacade::generalProcessingStore()
+//{
+// return m_generalProcessingStore;
+//}
+//
+//const GeneralProcessingSettingsStore &SettingsFacade::generalProcessingStore() const
+//{
+// return m_generalProcessingStore;
+//}
+//
+//ContourSettingsStore &SettingsFacade::contourStore()
+//{
+// return m_contourStore;
+//}
+//
+//const ContourSettingsStore &SettingsFacade::contourStore() const
+//{
+// return m_contourStore;
+//}
diff --git a/settingsfacade.h b/settingsfacade.h
index 15e9693b..83ecd7b1 100644
--- a/settingsfacade.h
+++ b/settingsfacade.h
@@ -25,17 +25,17 @@ class SettingsFacade
MirrorSettingsStore &mirrorStore();
const MirrorSettingsStore &mirrorStore() const;
- GeneralProcessingSettingsStore &generalProcessingStore();
- const GeneralProcessingSettingsStore &generalProcessingStore() const;
-
- ContourSettingsStore &contourStore();
- const ContourSettingsStore &contourStore() const;
-
- /** @brief Accessor for application-wide path settings (project path, file paths, etc.). */
ApplicationSettingsStore &appStore();
- /** @brief Const accessor for application-wide path settings. */
const ApplicationSettingsStore &appStore() const;
+ // examples for future PRs
+ //GeneralProcessingSettingsStore &generalProcessingStore();
+ //const GeneralProcessingSettingsStore &generalProcessingStore() const;
+//
+ //ContourSettingsStore &contourStore();
+ //const ContourSettingsStore &contourStore() const;
+
+
private:
friend class mirrorDlg; // Allow mirrordlg to call restricted save
@@ -48,9 +48,10 @@ class SettingsFacade
// Only facade owns these
MirrorSettingsStore m_mirrorStore;
- GeneralProcessingSettingsStore m_generalProcessingStore;
- ContourSettingsStore m_contourStore;
ApplicationSettingsStore m_appStore;
+ // examples for future PRs
+ //GeneralProcessingSettingsStore m_generalProcessingStore;
+ //ContourSettingsStore m_contourStore;
};
#endif // SETTINGSFACADE_H
diff --git a/settingsstores.cpp b/settingsstores.cpp
index 1829cd91..d2c2c6d5 100644
--- a/settingsstores.cpp
+++ b/settingsstores.cpp
@@ -24,38 +24,6 @@ void MirrorSettingsStore::save(const MirrorSettings &value) const
SETTINGS_STORE_FOR_EACH_MIRROR_FIELD(SETTINGS_STORE_SAVE_FIELD_TO_QSETTINGS)
}
-GeneralProcessingSettings GeneralProcessingSettingsStore::load() const
-{
- QSettings s;
-
- GeneralProcessingSettings value{};
- SETTINGS_STORE_FOR_EACH_GENERAL_FIELD(SETTINGS_STORE_LOAD_FIELD_FROM_QSETTINGS)
-
- return value;
-}
-
-void GeneralProcessingSettingsStore::save(const GeneralProcessingSettings &value) const
-{
- QSettings s;
- SETTINGS_STORE_FOR_EACH_GENERAL_FIELD(SETTINGS_STORE_SAVE_FIELD_TO_QSETTINGS)
-}
-
-ContourSettings ContourSettingsStore::load() const
-{
- QSettings s;
-
- ContourSettings value{};
- SETTINGS_STORE_FOR_EACH_CONTOUR_FIELD(SETTINGS_STORE_LOAD_FIELD_FROM_QSETTINGS)
-
- return value;
-}
-
-void ContourSettingsStore::save(const ContourSettings &value) const
-{
- QSettings s;
- SETTINGS_STORE_FOR_EACH_CONTOUR_FIELD(SETTINGS_STORE_SAVE_FIELD_TO_QSETTINGS)
-}
-
ApplicationSettings ApplicationSettingsStore::load() const
{
QSettings s;
@@ -72,5 +40,38 @@ void ApplicationSettingsStore::save(const ApplicationSettings &value) const
SETTINGS_STORE_FOR_EACH_APPLICATION_FIELD(SETTINGS_STORE_SAVE_FIELD_TO_QSETTINGS)
}
+// examples for future PRs
+//GeneralProcessingSettings GeneralProcessingSettingsStore::load() const
+//{
+// QSettings s;
+//
+// GeneralProcessingSettings value{};
+// SETTINGS_STORE_FOR_EACH_GENERAL_FIELD(SETTINGS_STORE_LOAD_FIELD_FROM_QSETTINGS)
+//
+// return value;
+//}
+//
+//void GeneralProcessingSettingsStore::save(const GeneralProcessingSettings &value) const
+//{
+// QSettings s;
+// SETTINGS_STORE_FOR_EACH_GENERAL_FIELD(SETTINGS_STORE_SAVE_FIELD_TO_QSETTINGS)
+//}
+//
+//ContourSettings ContourSettingsStore::load() const
+//{
+// QSettings s;
+//
+// ContourSettings value{};
+// SETTINGS_STORE_FOR_EACH_CONTOUR_FIELD(SETTINGS_STORE_LOAD_FIELD_FROM_QSETTINGS)
+//
+// return value;
+//}
+//
+//void ContourSettingsStore::save(const ContourSettings &value) const
+//{
+// QSettings s;
+// SETTINGS_STORE_FOR_EACH_CONTOUR_FIELD(SETTINGS_STORE_SAVE_FIELD_TO_QSETTINGS)
+//}
+
#undef SETTINGS_STORE_LOAD_FIELD_FROM_QSETTINGS
#undef SETTINGS_STORE_SAVE_FIELD_TO_QSETTINGS
diff --git a/settingsstores.h b/settingsstores.h
index bf719cc7..ba1a54ea 100644
--- a/settingsstores.h
+++ b/settingsstores.h
@@ -25,40 +25,6 @@ class MirrorSettingsStore {
MirrorSettings load() const;
};
-
-
-struct GeneralProcessingSettings {
- SETTINGS_STORE_FOR_EACH_GENERAL_FIELD(SETTINGS_STORE_DECLARE_STRUCT_FIELD)
-};
-
-class GeneralProcessingSettingsStore {
-private:
- friend class SettingsFacade;
- GeneralProcessingSettingsStore() = default;
-
-public:
- GeneralProcessingSettings load() const;
- void save(const GeneralProcessingSettings &value) const;
-};
-
-
-
-struct ContourSettings {
- SETTINGS_STORE_FOR_EACH_CONTOUR_FIELD(SETTINGS_STORE_DECLARE_STRUCT_FIELD)
-};
-
-class ContourSettingsStore {
-private:
- friend class SettingsFacade;
- ContourSettingsStore() = default;
-
-public:
- ContourSettings load() const;
- void save(const ContourSettings &value) const;
-};
-
-
-
struct ApplicationSettings {
SETTINGS_STORE_FOR_EACH_APPLICATION_FIELD(SETTINGS_STORE_DECLARE_STRUCT_FIELD)
};
@@ -73,6 +39,39 @@ class ApplicationSettingsStore {
void save(const ApplicationSettings &value) const;
};
+// examples for future PRs
+//struct GeneralProcessingSettings {
+// SETTINGS_STORE_FOR_EACH_GENERAL_FIELD(SETTINGS_STORE_DECLARE_STRUCT_FIELD)
+//};
+//
+//class GeneralProcessingSettingsStore {
+//private:
+// friend class SettingsFacade;
+// GeneralProcessingSettingsStore() = default;
+//
+//public:
+// GeneralProcessingSettings load() const;
+// void save(const GeneralProcessingSettings &value) const;
+//};
+//
+//
+//
+//struct ContourSettings {
+// SETTINGS_STORE_FOR_EACH_CONTOUR_FIELD(SETTINGS_STORE_DECLARE_STRUCT_FIELD)
+//};
+//
+//class ContourSettingsStore {
+//private:
+// friend class SettingsFacade;
+// ContourSettingsStore() = default;
+//
+//public:
+// ContourSettings load() const;
+// void save(const ContourSettings &value) const;
+//};
+
+
+
#undef SETTINGS_STORE_DECLARE_STRUCT_FIELD
#endif // SETTINGSSTORES_H
diff --git a/settingsstores_fields.inc b/settingsstores_fields.inc
index 70a84ca8..19c86fe5 100644
--- a/settingsstores_fields.inc
+++ b/settingsstores_fields.inc
@@ -25,7 +25,8 @@
FIELD(QString, mirrorConfigFile, QString(), "mirrorConfigFile", toString) \
FIELD(QString, lastPath, QString(), "lastPath", toString)
-#define SETTINGS_STORE_FOR_EACH_GENERAL_FIELD(FIELD) \
+// examples for futur PRs
+/*#define SETTINGS_STORE_FOR_EACH_GENERAL_FIELD(FIELD) \
FIELD(bool, useMakeStarTest, false, "useMakeStarTest", toBool) \
FIELD(int, wavefrontDownSizeValue, 650, "wavefrontDownSizeValue", toInt) \
FIELD(bool, wavefrontShouldDownsize, false, "wavefrontShouldDownsize", toBool) \
@@ -47,4 +48,4 @@
FIELD(int, colorMapIndex, 1, "colorMap ndx", toInt) \
FIELD(QString, contourLineColor, QStringLiteral("grey"), "ContourLineColor", toString) \
FIELD(QString, contourRulerColor, QStringLiteral("grey"), "ContourRulerColor", toString) \
- FIELD(double, contourRulerRadialDeg, 0.0, "contourRulerRadialDeg", toDouble)
+ FIELD(double, contourRulerRadialDeg, 0.0, "contourRulerRadialDeg", toDouble)*/
From 423fb06e67d21e75d68bbb6d46c9059113b3964c Mon Sep 17 00:00:00 2001
From: Julien STAUB
Date: Sun, 9 Aug 2026 14:41:45 +0200
Subject: [PATCH 16/20] apertureChanged is emit only on accept
---
mirrordlg.cpp | 5 ++---
mirrordlg.h | 8 ++++----
2 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/mirrordlg.cpp b/mirrordlg.cpp
index ae71c5bc..6adb085d 100644
--- a/mirrordlg.cpp
+++ b/mirrordlg.cpp
@@ -619,9 +619,10 @@ void mirrorDlg::on_buttonBox_accepted()
SettingsFacade::instance().saveMirrorSettings(m_current);
if (m_obsChanged)
- emit obstructionChanged();
+ emit obstructionChanged();
emit recomputeZerns();
if (m_aperatureReductionValueChanged){
+ emit aperatureChanged();
QMessageBox::warning(0, tr("Aperature Reduction value was changed."),
tr("Aperature Reduction was changed.\n"
"The wave front will not be correct until it is recomputed from the interferogram."));
@@ -717,7 +718,6 @@ void mirrorDlg::on_ReducApp_clicked(bool checked)
ui->reduceValue->setValue(m_draft.apertureReduction);
m_aperatureReductionValueChanged = true;
setclearAp();
- emit aperatureChanged();
}
@@ -728,7 +728,6 @@ void mirrorDlg::on_reduceValue_valueChanged(double arg1)
setclearAp();
m_aperatureReductionValueChanged = true;
- emit aperatureChanged();
}
void mirrorDlg::on_annulusPercent_valueChanged(double arg1)
diff --git a/mirrordlg.h b/mirrordlg.h
index 8efb835d..059e1f11 100644
--- a/mirrordlg.h
+++ b/mirrordlg.h
@@ -125,9 +125,10 @@ private slots:
void on_btnChangeAutoInvert_clicked();
signals:
+ // Emitted only after OK/accept when committed settings are saved.
void obstructionChanged();
void recomputeZerns();
- void aperatureChanged(); // TODO this one only : notify shoud probably only happen when OK is clicked, not on every change.
+ void aperatureChanged();
protected:
/** @brief Reload settings before dialog becomes visible. */
@@ -149,15 +150,14 @@ private slots:
QTimer spacingChangeTimer;
- // Persistent mirror configuration copy (source of truth for external code)
- //TODO check if all UI settings are actually saved in settings
+ // Persistent mirror configuration copy (source of truth)
MirrorSettings m_current;
// Working copy for dialog edits (discarded on Cancel, committed to m_current on OK)
MirrorSettings m_draft;
// Computed/derived values (read-only, not from settings)
- //TODO actually mm is not saved in settings. should probably be saved as it's a user preference. I need to check what happens when user enters values in mm or inch and reopens DFTFringe
+ //TODO actually mm is not saved in settings. should probably be saved as it's a user preference
bool mm; // Unit display flag: true = mm, false = other units
double FNumber; // Computed f-number (focal length / diameter)
double z8; // Z8 Zernike coefficient or null reference value
From 1af46664891bee4adca94a7c702528f5236a865b Mon Sep 17 00:00:00 2001
From: Julien STAUB
Date: Sun, 9 Aug 2026 15:07:44 +0200
Subject: [PATCH 17/20] deduplicate function
---
igramarea.cpp | 2 +-
mirrordlg.cpp | 4 ----
mirrordlg.h | 3 ---
surfacemanager.cpp | 2 +-
4 files changed, 2 insertions(+), 9 deletions(-)
diff --git a/igramarea.cpp b/igramarea.cpp
index b7b7cc68..19d5ae51 100644
--- a/igramarea.cpp
+++ b/igramarea.cpp
@@ -1545,7 +1545,7 @@ void IgramArea::mouseMoveEvent(QMouseEvent *event)
int majorRad = fabs((m_OutterP2.x() - m_OutterP1.x()))/2.;
double e = (double)minorRad/majorRad;
mirrorDlg &md = *mirrorDlg::get_Instance();
- md.setVerticalAxis(md.currentSettings().diameter * e);
+ md.setMinorAxis(md.currentSettings().diameter * e);
drawBoundary();
return;
}
diff --git a/mirrordlg.cpp b/mirrordlg.cpp
index 6adb085d..4987aba5 100644
--- a/mirrordlg.cpp
+++ b/mirrordlg.cpp
@@ -672,10 +672,6 @@ void mirrorDlg::setMinorAxis(double val){
//on_minorAxisEdit_textChanged( QString::number(val));
}
-void mirrorDlg::setVerticalAxis(double val){
- m_draft.ellipseMinorAxis = val;
-}
-
void mirrorDlg::setOutlineShape(outlineShape shape){
m_draft.outlineShape = (int)shape;
ui->ellipseShape->setChecked(shape == ELLIPSE);
diff --git a/mirrordlg.h b/mirrordlg.h
index 059e1f11..6edbe88c 100644
--- a/mirrordlg.h
+++ b/mirrordlg.h
@@ -45,9 +45,6 @@ class mirrorDlg : public QDialog
//TODO This one not OK. Edits m_draft.ellipseMinorAxis and wont get saved.
// need to investigate why external code needs to change the minor axis. If it is a user preference, it should be saved in settings. If it is a computed value, it should be computed from other values and not set directly.
void setMinorAxis(double val);
- //TODO even worse, same thing but it doesn't update UI text
- // on call from a file load but the other ?
- void setVerticalAxis(double val);
// TODO not OK. Edits m_draft.outlineShape and wont get saved
// from file load
void setOutlineShape(outlineShape shape);
diff --git a/surfacemanager.cpp b/surfacemanager.cpp
index 804172ab..bd832323 100644
--- a/surfacemanager.cpp
+++ b/surfacemanager.cpp
@@ -1308,7 +1308,7 @@ wavefront * SurfaceManager::readWaveFront(const QString &fileName){
md->setOutlineShape(ELLIPSE);
double vertAxis;
iss >> dummy >> vertAxis;
- md->setVerticalAxis(vertAxis);
+ md->setMinorAxis(vertAxis);
}
if (l.startsWith("Do Not use null") || l.startsWith("nulled") ){
wf->useSANull = false;
From ef52e3341c99d84938b0bbbbde13d352f0912c0c Mon Sep 17 00:00:00 2001
From: Julien STAUB
Date: Tue, 11 Aug 2026 14:23:17 +0200
Subject: [PATCH 18/20] some comment cleanup
---
mirrordlg.h | 12 ++++++------
surfacemanager.cpp | 2 +-
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/mirrordlg.h b/mirrordlg.h
index 6edbe88c..927bbfee 100644
--- a/mirrordlg.h
+++ b/mirrordlg.h
@@ -32,8 +32,7 @@ class mirrorDlg : public QDialog
Q_OBJECT
public:
- // TODO if we get rid of the singleton design, settings could be read from settingsFacade instead here
- // check if it makes sense
+ // TODO we could get rid of singleton if every file accessed settings though SettingsFacade instead of mirrorDlg::get_Instance()->currentSettings()
static mirrorDlg *get_Instance();
~mirrorDlg();
mirrorDlg(const mirrorDlg&) = delete;
@@ -42,11 +41,12 @@ class mirrorDlg : public QDialog
void updateAutoInvertStatus(); //This one makes sense. Not saved
// ---- file loading ----
- //TODO This one not OK. Edits m_draft.ellipseMinorAxis and wont get saved.
- // need to investigate why external code needs to change the minor axis. If it is a user preference, it should be saved in settings. If it is a computed value, it should be computed from other values and not set directly.
+ //TODO This is still not 100% clean
+ // One call from loading file shoulb be integgrated to adoptWavefrontSettings
+ // other calls are outline helpers. Need to be clarified
void setMinorAxis(double val);
- // TODO not OK. Edits m_draft.outlineShape and wont get saved
- // from file load
+ // TODO to be fixed with #358.
+ // saving shape shall be asked as it is for ROC, lambda and diameter and be saved using adoptWavefrontSettings
void setOutlineShape(outlineShape shape);
diff --git a/surfacemanager.cpp b/surfacemanager.cpp
index 4c54baeb..490463e7 100644
--- a/surfacemanager.cpp
+++ b/surfacemanager.cpp
@@ -906,7 +906,7 @@ void SurfaceManager::syncGaussianStateForWavefront(wavefront *wf){
m_surfaceTools->setGaussianControls(wf->gbEnabled, wf->gbValue);
mirrorDlg *md = mirrorDlg::get_Instance();
- m_surfaceTools->setBlurText(QString("%1 mm").arg(.01 * wf->gbValue * md->diameter, 6, 'f', 2));
+ m_surfaceTools->setBlurText(QString("%1 mm").arg(.01 * wf->gbValue * md->currentSettings().diameter, 6, 'f', 2));
}
void SurfaceManager::computeMetrics(wavefront *wf){
From 1cfb6773134719cd1d85aeec0975deb8f74fc5ab Mon Sep 17 00:00:00 2001
From: Julien STAUB
Date: Wed, 12 Aug 2026 07:35:49 +0200
Subject: [PATCH 19/20] fix warning. Square is expected downstream. This is
just leftover code
---
dftarea.cpp | 7 -------
1 file changed, 7 deletions(-)
diff --git a/dftarea.cpp b/dftarea.cpp
index 831c0465..f08b2270 100644
--- a/dftarea.cpp
+++ b/dftarea.cpp
@@ -258,13 +258,6 @@ cv::Mat DFTArea::grayComplexMatfromImage(QImage &img){
double rad = igramArea->m_outside.m_radius - reduction;
-
- double rady = rad;
-
- if (md.isEllipse()){
- rady = rady * md.currentSettings().ellipseMinorAxis / md.currentSettings().diameter;
- }
-
double left = centerX - rad;
double top = centerY - rad;
std::vector bgr_planes;
From 836023817e8193118874f49af89eae9fc26528ba Mon Sep 17 00:00:00 2001
From: Julien STAUB
Date: Wed, 12 Aug 2026 10:25:53 +0200
Subject: [PATCH 20/20] fix some earlier wrong replacements leading to broken
profileplot
---
igramarea.cpp | 2 +-
mirrordlg.cpp | 10 +++++++++-
mirrordlg.h | 1 +
percentcorrectiondlg.cpp | 4 ++--
profileplot.cpp | 2 +-
5 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/igramarea.cpp b/igramarea.cpp
index 1530426e..1257f200 100644
--- a/igramarea.cpp
+++ b/igramarea.cpp
@@ -1719,7 +1719,7 @@ void IgramArea::drawBoundary()
painter.setBrush(Qt::NoBrush);
}
outside.draw(painter,1.,s2);
- if ( md.currentSettings().apertureReductionEnabled && md.currentSettings().apertureReduction != md.currentSettings().diameter){
+ if ( md.currentSettings().apertureReductionEnabled && md.getClearAperture() != md.currentSettings().diameter){
painter.setPen(QPen(edgePenColor, edgePenWidth, Qt::DotLine));
computeEdgeRadius();
painter.drawEllipse(outside.m_center,
diff --git a/mirrordlg.cpp b/mirrordlg.cpp
index 4987aba5..ebb7598c 100644
--- a/mirrordlg.cpp
+++ b/mirrordlg.cpp
@@ -597,7 +597,7 @@ void mirrorDlg::on_unitsCB_clicked(bool checked)
// Get apertureReduction from draft (already loaded from persistent storage)
ui->reduceValue->setValue(m_draft.apertureReduction * ((mm) ? 1. : 1./25.4));
ui->reduceValue->blockSignals(false);
- ui->ClearAp->setText(QString("%1 ").arg(m_draft.apertureReduction * ((mm) ? 1: 1./25.4), 6, 'f', 2));
+ setclearAp();
}
void mirrorDlg::on_buttonBox_accepted()
@@ -703,6 +703,14 @@ void mirrorDlg::setclearAp(){
ui->ClearAp->setText(QString("%1 ").arg(clearAperature * ((mm) ? 1: 1./25.4), 6, 'f', 2));
}
+double mirrorDlg::getClearAperture() const {
+ double clearAperature = (m_current.diameter - m_current.apertureReduction * 2) ;
+ if (m_current.apertureReductionEnabled == false){
+ clearAperature = m_current.diameter;
+ }
+ return clearAperature;
+}
+
void mirrorDlg::on_ReducApp_clicked(bool checked)
{
m_draft.apertureReductionEnabled = checked;
diff --git a/mirrordlg.h b/mirrordlg.h
index 927bbfee..9422360a 100644
--- a/mirrordlg.h
+++ b/mirrordlg.h
@@ -60,6 +60,7 @@ class mirrorDlg : public QDialog
double getZ8() const { return z8; }
static QString getProjectPath();
double getMinorAxis();
+ double getClearAperture() const;
bool isEllipse();
bool shouldFlipH();
diff --git a/percentcorrectiondlg.cpp b/percentcorrectiondlg.cpp
index 31da9def..6d044c35 100644
--- a/percentcorrectiondlg.cpp
+++ b/percentcorrectiondlg.cpp
@@ -31,7 +31,7 @@ percentCorrectionDlg::percentCorrectionDlg( QWidget *parent) :
mirrorDlg &md = *mirrorDlg::get_Instance();
- m_radius = md.currentSettings().apertureReduction/2.;
+ m_radius = md.getClearAperture()/2.;
QSettings set;
ui->minvalue->blockSignals(true);
ui->maxvalue->blockSignals(true);
@@ -644,7 +644,7 @@ void percentCorrectionDlg::setData( QVector< surfaceData *> data) {
QSettings set;
m_outputLambda = set.value("outputLambda").toDouble();
- m_radius = md.currentSettings().apertureReduction/2.;
+ m_radius = md.getClearAperture()/2.;
surfs = data;
ui->percentTable->setRowCount(data.length());
diff --git a/profileplot.cpp b/profileplot.cpp
index afd3d8a5..2d3c84ff 100644
--- a/profileplot.cpp
+++ b/profileplot.cpp
@@ -427,7 +427,7 @@ QPolygonF ProfilePlot::createProfile(double units, const wavefront *wf, bool all
// 1. Setup constants
double steps = 1.0 / wf->m_outside.m_radius;
double offset = allowOffset ? y_offset : 0.0;
- double radius = md.currentSettings().apertureReduction / 2.0;
+ double radius = md.getClearAperture() / 2.0;
double obs_radius = md.currentSettings().obstruction / 2.0;
if (m_displayInches) {