Save/open preferences
This commit is contained in:
parent
5d8efd4336
commit
fa481e2062
@ -25,7 +25,7 @@ Calkit::Calkit()
|
|||||||
{
|
{
|
||||||
|
|
||||||
// set default values
|
// set default values
|
||||||
for(auto e : json_descr) {
|
for(auto e : descr) {
|
||||||
e.var.setValue(e.def);
|
e.var.setValue(e.def);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -40,24 +40,7 @@ void Calkit::toFile(QString filename)
|
|||||||
|
|
||||||
TransformPathsToRelative(filename);
|
TransformPathsToRelative(filename);
|
||||||
|
|
||||||
json j;
|
json j = Savable::createJSON(descr);
|
||||||
for(auto e : json_descr) {
|
|
||||||
auto list = e.name.split("/");
|
|
||||||
auto *json_entry = &j;
|
|
||||||
while(list.size() > 0) {
|
|
||||||
json_entry = &(*json_entry)[list.takeFirst().toStdString()];
|
|
||||||
}
|
|
||||||
// json library does not now about QVariant, handle used cases
|
|
||||||
auto val = e.var.value();
|
|
||||||
switch(static_cast<QMetaType::Type>(val.type())) {
|
|
||||||
case QMetaType::Double: *json_entry = val.toDouble(); break;
|
|
||||||
case QMetaType::Int: *json_entry = val.toInt(); break;
|
|
||||||
case QMetaType::Bool: *json_entry = val.toBool(); break;
|
|
||||||
case QMetaType::QString: *json_entry = val.toString().toStdString(); break;
|
|
||||||
default:
|
|
||||||
throw runtime_error("Unimplemented metatype");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ofstream file;
|
ofstream file;
|
||||||
file.open(filename.toStdString());
|
file.open(filename.toStdString());
|
||||||
file << setw(4) << j << endl;
|
file << setw(4) << j << endl;
|
||||||
@ -90,58 +73,19 @@ Calkit Calkit::fromFile(QString filename)
|
|||||||
throw runtime_error("JSON parsing error: " + string(e.what()));
|
throw runtime_error("JSON parsing error: " + string(e.what()));
|
||||||
}
|
}
|
||||||
if(j.contains("SOLT")) {
|
if(j.contains("SOLT")) {
|
||||||
// older file versions specify Z0 for resistance. If resistance entry is missing,
|
// older file versions specify Z0 for resistance. Set resistance to Nan to detect missing values later
|
||||||
// set it to Z0 later
|
c.SOLT.load_m.resistance = std::numeric_limits<double>::quiet_NaN();
|
||||||
bool loadResistanceMissing_m = false;
|
c.SOLT.load_f.resistance = std::numeric_limits<double>::quiet_NaN();
|
||||||
bool loadResistanceMissing_f = false;
|
|
||||||
|
|
||||||
qDebug() << "JSON format detected";
|
qDebug() << "JSON format detected";
|
||||||
// calkit file uses json format, parse
|
// calkit file uses json format, parse
|
||||||
for(auto e : c.json_descr) {
|
Savable::parseJSON(j, c.descr);
|
||||||
auto list = e.name.split("/");
|
// adjust Z0/resistance in case of older calkit file version with missing resistance entries
|
||||||
auto *json_entry = &j;
|
if(isnan(c.SOLT.load_f.resistance)) {
|
||||||
bool entry_exists = true;
|
|
||||||
while(list.size() > 0) {
|
|
||||||
auto key = list.takeFirst().toStdString();
|
|
||||||
if((*json_entry).contains(key)) {
|
|
||||||
json_entry = &(*json_entry)[key];
|
|
||||||
} else {
|
|
||||||
entry_exists = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!entry_exists) {
|
|
||||||
// missing entry in json file, nothing to do (default values already set in constructor)
|
|
||||||
qWarning() << "Entry" << e.name << "not present in file, assuming default value";
|
|
||||||
if(e.name == "SOLT/Load/Param/Resistance") {
|
|
||||||
loadResistanceMissing_m = true;
|
|
||||||
} else if(e.name == "SOLT/Load/Param/Resistance_Female") {
|
|
||||||
loadResistanceMissing_f = true;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// json library does not now about QVariant, handle used cases
|
|
||||||
auto val = e.var.value();
|
|
||||||
switch(static_cast<QMetaType::Type>(val.type())) {
|
|
||||||
case QMetaType::Double: e.var.setValue((*json_entry).get<double>()); break;
|
|
||||||
case QMetaType::Int: e.var.setValue((*json_entry).get<int>()); break;
|
|
||||||
case QMetaType::Bool: e.var.setValue((*json_entry).get<bool>()); break;
|
|
||||||
case QMetaType::QString: {
|
|
||||||
auto s = QString::fromStdString((*json_entry).get<string>());
|
|
||||||
e.var.setValue(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw runtime_error("Unimplemented metatype");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// adjust Z0/resistance in case of older calkit file version
|
|
||||||
if(loadResistanceMissing_f) {
|
|
||||||
c.SOLT.load_f.resistance = c.SOLT.load_f.Z0;
|
c.SOLT.load_f.resistance = c.SOLT.load_f.Z0;
|
||||||
c.SOLT.load_f.Z0 = 50.0;
|
c.SOLT.load_f.Z0 = 50.0;
|
||||||
}
|
}
|
||||||
if(loadResistanceMissing_m) {
|
if(isnan(c.SOLT.load_m.resistance)) {
|
||||||
c.SOLT.load_m.resistance = c.SOLT.load_m.Z0;
|
c.SOLT.load_m.resistance = c.SOLT.load_m.Z0;
|
||||||
c.SOLT.load_m.Z0 = 50.0;
|
c.SOLT.load_m.Z0 = 50.0;
|
||||||
}
|
}
|
||||||
|
@ -105,90 +105,85 @@ private:
|
|||||||
Touchstone *ts_through;
|
Touchstone *ts_through;
|
||||||
bool ts_cached;
|
bool ts_cached;
|
||||||
|
|
||||||
using JSONDescription = struct _jsondescr {
|
const std::vector<Savable::SettingDescription> descr = {{
|
||||||
QPointerVariant var;
|
|
||||||
QString name;
|
|
||||||
QVariant def;
|
|
||||||
};
|
|
||||||
const std::array<JSONDescription, 73> json_descr = {{
|
|
||||||
{&manufacturer, "Manufacturer", ""},
|
{&manufacturer, "Manufacturer", ""},
|
||||||
{&serialnumber, "Serialnumber", ""},
|
{&serialnumber, "Serialnumber", ""},
|
||||||
{&description, "Description", ""},
|
{&description, "Description", ""},
|
||||||
|
|
||||||
{&SOLT.open_m.Z0, "SOLT/Open/Param/Z0", 50.0},
|
{&SOLT.open_m.Z0, "SOLT.Open.Param.Z0", 50.0},
|
||||||
{&SOLT.open_m.delay, "SOLT/Open/Param/Delay", 0.0},
|
{&SOLT.open_m.delay, "SOLT.Open.Param.Delay", 0.0},
|
||||||
{&SOLT.open_m.loss, "SOLT/Open/Param/Loss", 0.0},
|
{&SOLT.open_m.loss, "SOLT.Open.Param.Loss", 0.0},
|
||||||
{&SOLT.open_m.C0, "SOLT/Open/Param/C0", 0.0},
|
{&SOLT.open_m.C0, "SOLT.Open.Param.C0", 0.0},
|
||||||
{&SOLT.open_m.C1, "SOLT/Open/Param/C1", 0.0},
|
{&SOLT.open_m.C1, "SOLT.Open.Param.C1", 0.0},
|
||||||
{&SOLT.open_m.C2, "SOLT/Open/Param/C2", 0.0},
|
{&SOLT.open_m.C2, "SOLT.Open.Param.C2", 0.0},
|
||||||
{&SOLT.open_m.C3, "SOLT/Open/Param/C3", 0.0},
|
{&SOLT.open_m.C3, "SOLT.Open.Param.C3", 0.0},
|
||||||
{&SOLT.open_m.useMeasurements, "SOLT/Open/Measurements/Use", false},
|
{&SOLT.open_m.useMeasurements, "SOLT.Open.Measurements.Use", false},
|
||||||
{&SOLT.open_m.file, "SOLT/Open/Measurements/File", ""},
|
{&SOLT.open_m.file, "SOLT.Open.Measurements.File", ""},
|
||||||
{&SOLT.open_m.Sparam, "SOLT/Open/Measurements/Port", 0},
|
{&SOLT.open_m.Sparam, "SOLT.Open.Measurements.Port", 0},
|
||||||
{&SOLT.open_f.Z0, "SOLT/Open/Param/Z0_Female", 50.0},
|
{&SOLT.open_f.Z0, "SOLT.Open.Param.Z0_Female", 50.0},
|
||||||
{&SOLT.open_f.delay, "SOLT/Open/Param/Delay_Female", 0.0},
|
{&SOLT.open_f.delay, "SOLT.Open.Param.Delay_Female", 0.0},
|
||||||
{&SOLT.open_f.loss, "SOLT/Open/Param/Loss_Female", 0.0},
|
{&SOLT.open_f.loss, "SOLT.Open.Param.Loss_Female", 0.0},
|
||||||
{&SOLT.open_f.C0, "SOLT/Open/Param/C0_Female", 0.0},
|
{&SOLT.open_f.C0, "SOLT.Open.Param.C0_Female", 0.0},
|
||||||
{&SOLT.open_f.C1, "SOLT/Open/Param/C1_Female", 0.0},
|
{&SOLT.open_f.C1, "SOLT.Open.Param.C1_Female", 0.0},
|
||||||
{&SOLT.open_f.C2, "SOLT/Open/Param/C2_Female", 0.0},
|
{&SOLT.open_f.C2, "SOLT.Open.Param.C2_Female", 0.0},
|
||||||
{&SOLT.open_f.C3, "SOLT/Open/Param/C3_Female", 0.0},
|
{&SOLT.open_f.C3, "SOLT.Open.Param.C3_Female", 0.0},
|
||||||
{&SOLT.open_f.useMeasurements, "SOLT/Open/Measurements/Use_Female", false},
|
{&SOLT.open_f.useMeasurements, "SOLT.Open.Measurements.Use_Female", false},
|
||||||
{&SOLT.open_f.file, "SOLT/Open/Measurements/File_Female", ""},
|
{&SOLT.open_f.file, "SOLT.Open.Measurements.File_Female", ""},
|
||||||
{&SOLT.open_f.Sparam, "SOLT/Open/Measurements/Port_Female", 0},
|
{&SOLT.open_f.Sparam, "SOLT.Open.Measurements.Port_Female", 0},
|
||||||
|
|
||||||
{&SOLT.short_m.Z0, "SOLT/Short/Param/Z0", 50.0},
|
{&SOLT.short_m.Z0, "SOLT.Short.Param.Z0", 50.0},
|
||||||
{&SOLT.short_m.delay, "SOLT/Short/Param/Delay", 0.0},
|
{&SOLT.short_m.delay, "SOLT.Short.Param.Delay", 0.0},
|
||||||
{&SOLT.short_m.loss, "SOLT/Short/Param/Loss", 0.0},
|
{&SOLT.short_m.loss, "SOLT.Short.Param.Loss", 0.0},
|
||||||
{&SOLT.short_m.L0, "SOLT/Short/Param/L0", 0.0},
|
{&SOLT.short_m.L0, "SOLT.Short.Param.L0", 0.0},
|
||||||
{&SOLT.short_m.L1, "SOLT/Short/Param/L1", 0.0},
|
{&SOLT.short_m.L1, "SOLT.Short.Param.L1", 0.0},
|
||||||
{&SOLT.short_m.L2, "SOLT/Short/Param/L2", 0.0},
|
{&SOLT.short_m.L2, "SOLT.Short.Param.L2", 0.0},
|
||||||
{&SOLT.short_m.L3, "SOLT/Short/Param/L3", 0.0},
|
{&SOLT.short_m.L3, "SOLT.Short.Param.L3", 0.0},
|
||||||
{&SOLT.short_m.useMeasurements, "SOLT/Short/Measurements/Use", false},
|
{&SOLT.short_m.useMeasurements, "SOLT.Short.Measurements.Use", false},
|
||||||
{&SOLT.short_m.file, "SOLT/Short/Measurements/File", ""},
|
{&SOLT.short_m.file, "SOLT.Short.Measurements.File", ""},
|
||||||
{&SOLT.short_m.Sparam, "SOLT/Short/Measurements/Port", 0},
|
{&SOLT.short_m.Sparam, "SOLT.Short.Measurements.Port", 0},
|
||||||
{&SOLT.short_f.Z0, "SOLT/Short/Param/Z0_Female", 50.0},
|
{&SOLT.short_f.Z0, "SOLT.Short.Param.Z0_Female", 50.0},
|
||||||
{&SOLT.short_f.delay, "SOLT/Short/Param/Delay_Female", 0.0},
|
{&SOLT.short_f.delay, "SOLT.Short.Param.Delay_Female", 0.0},
|
||||||
{&SOLT.short_f.loss, "SOLT/Short/Param/Loss_Female", 0.0},
|
{&SOLT.short_f.loss, "SOLT.Short.Param.Loss_Female", 0.0},
|
||||||
{&SOLT.short_f.L0, "SOLT/Short/Param/L0_Female", 0.0},
|
{&SOLT.short_f.L0, "SOLT.Short.Param.L0_Female", 0.0},
|
||||||
{&SOLT.short_f.L1, "SOLT/Short/Param/L1_Female", 0.0},
|
{&SOLT.short_f.L1, "SOLT.Short.Param.L1_Female", 0.0},
|
||||||
{&SOLT.short_f.L2, "SOLT/Short/Param/L2_Female", 0.0},
|
{&SOLT.short_f.L2, "SOLT.Short.Param.L2_Female", 0.0},
|
||||||
{&SOLT.short_f.L3, "SOLT/Short/Param/L3_Female", 0.0},
|
{&SOLT.short_f.L3, "SOLT.Short.Param.L3_Female", 0.0},
|
||||||
{&SOLT.short_f.useMeasurements, "SOLT/Short/Measurements/Use_Female", false},
|
{&SOLT.short_f.useMeasurements, "SOLT.Short.Measurements.Use_Female", false},
|
||||||
{&SOLT.short_f.file, "SOLT/Short/Measurements/File_Female", ""},
|
{&SOLT.short_f.file, "SOLT.Short.Measurements.File_Female", ""},
|
||||||
{&SOLT.short_f.Sparam, "SOLT/Short/Measurements/Port_Female", 0},
|
{&SOLT.short_f.Sparam, "SOLT.Short.Measurements.Port_Female", 0},
|
||||||
|
|
||||||
{&SOLT.load_m.resistance, "SOLT/Load/Param/Resistance", 50.0},
|
{&SOLT.load_m.resistance, "SOLT.Load.Param.Resistance", 50.0},
|
||||||
{&SOLT.load_m.Z0, "SOLT/Load/Param/Z0", 50.0},
|
{&SOLT.load_m.Z0, "SOLT.Load.Param.Z0", 50.0},
|
||||||
{&SOLT.load_m.delay, "SOLT/Load/Param/Delay", 0.0},
|
{&SOLT.load_m.delay, "SOLT.Load.Param.Delay", 0.0},
|
||||||
{&SOLT.load_m.Cparallel, "SOLT/Load/Param/C", 0.0},
|
{&SOLT.load_m.Cparallel, "SOLT.Load.Param.C", 0.0},
|
||||||
{&SOLT.load_m.Lseries, "SOLT/Load/Param/L", 0.0},
|
{&SOLT.load_m.Lseries, "SOLT.Load.Param.L", 0.0},
|
||||||
{&SOLT.load_m.useMeasurements, "SOLT/Load/Measurements/Use", false},
|
{&SOLT.load_m.useMeasurements, "SOLT.Load.Measurements.Use", false},
|
||||||
{&SOLT.load_m.file, "SOLT/Load/Measurements/File", ""},
|
{&SOLT.load_m.file, "SOLT.Load.Measurements.File", ""},
|
||||||
{&SOLT.load_m.Sparam, "SOLT/Load/Measurements/Port", 0},
|
{&SOLT.load_m.Sparam, "SOLT.Load.Measurements.Port", 0},
|
||||||
{&SOLT.load_f.resistance, "SOLT/Load/Param/Resistance_Female", 50.0},
|
{&SOLT.load_f.resistance, "SOLT.Load.Param.Resistance_Female", 50.0},
|
||||||
{&SOLT.load_f.Z0, "SOLT/Load/Param/Z0_Female", 50.0},
|
{&SOLT.load_f.Z0, "SOLT.Load.Param.Z0_Female", 50.0},
|
||||||
{&SOLT.load_f.delay, "SOLT/Load/Param/Delay_Female", 0.0},
|
{&SOLT.load_f.delay, "SOLT.Load.Param.Delay_Female", 0.0},
|
||||||
{&SOLT.load_f.Cparallel, "SOLT/Load/Param/C_Female", 0.0},
|
{&SOLT.load_f.Cparallel, "SOLT.Load.Param.C_Female", 0.0},
|
||||||
{&SOLT.load_f.Lseries, "SOLT/Load/Param/L_Female", 0.0},
|
{&SOLT.load_f.Lseries, "SOLT.Load.Param.L_Female", 0.0},
|
||||||
{&SOLT.load_f.useMeasurements, "SOLT/Load/Measurements/Use_Female", false},
|
{&SOLT.load_f.useMeasurements, "SOLT.Load.Measurements.Use_Female", false},
|
||||||
{&SOLT.load_f.file, "SOLT/Load/Measurements/File_Female", ""},
|
{&SOLT.load_f.file, "SOLT.Load.Measurements.File_Female", ""},
|
||||||
{&SOLT.load_f.Sparam, "SOLT/Load/Measurements/Port_Female", 0},
|
{&SOLT.load_f.Sparam, "SOLT.Load.Measurements.Port_Female", 0},
|
||||||
|
|
||||||
{&SOLT.Through.Z0, "SOLT/Through/Param/Z0", 50.0},
|
{&SOLT.Through.Z0, "SOLT.Through.Param.Z0", 50.0},
|
||||||
{&SOLT.Through.delay, "SOLT/Through/Param/Delay", 0.0},
|
{&SOLT.Through.delay, "SOLT.Through.Param.Delay", 0.0},
|
||||||
{&SOLT.Through.loss, "SOLT/Through/Param/Loss", 0.0},
|
{&SOLT.Through.loss, "SOLT.Through.Param.Loss", 0.0},
|
||||||
{&SOLT.Through.useMeasurements, "SOLT/Through/Measurements/Use", false},
|
{&SOLT.Through.useMeasurements, "SOLT.Through.Measurements.Use", false},
|
||||||
{&SOLT.Through.file, "SOLT/Through/Measurements/File", ""},
|
{&SOLT.Through.file, "SOLT.Through.Measurements.File", ""},
|
||||||
{&SOLT.Through.Sparam1, "SOLT/Through/Measurements/Port1", 0},
|
{&SOLT.Through.Sparam1, "SOLT.Through.Measurements.Port1", 0},
|
||||||
{&SOLT.Through.Sparam2, "SOLT/Through/Measurements/Port2", 1},
|
{&SOLT.Through.Sparam2, "SOLT.Through.Measurements.Port2", 1},
|
||||||
|
|
||||||
{&SOLT.separate_male_female, "SOLT/SeparateMaleFemale", false},
|
{&SOLT.separate_male_female, "SOLT.SeparateMaleFemale", false},
|
||||||
|
|
||||||
{&TRL.Through.Z0, "TRL/Through/Z0", 50.0},
|
{&TRL.Through.Z0, "TRL.Through.Z0", 50.0},
|
||||||
{&TRL.Reflection.isShort, "TRL/Reflect/isShort", false},
|
{&TRL.Reflection.isShort, "TRL.Reflect.isShort", false},
|
||||||
{&TRL.Line.delay, "TRL/Line/Delay", 74.0},
|
{&TRL.Line.delay, "TRL.Line.Delay", 74.0},
|
||||||
{&TRL.Line.minFreq, "TRL/Line/minFreq", 751000000.0},
|
{&TRL.Line.minFreq, "TRL.Line.minFreq", 751000000.0},
|
||||||
{&TRL.Line.maxFreq, "TRL/Line/maxFreq", 6000000000.0},
|
{&TRL.Line.maxFreq, "TRL.Line.maxFreq", 6000000000.0},
|
||||||
|
|
||||||
{&startDialogWithSOLT, "StartDialogWithSOLT", true}
|
{&startDialogWithSOLT, "StartDialogWithSOLT", true}
|
||||||
}};
|
}};
|
||||||
|
@ -6,8 +6,12 @@
|
|||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <map>
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QFileDialog>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -128,55 +132,34 @@ PreferencesDialog::PreferencesDialog(Preferences *pref, QWidget *parent) :
|
|||||||
});
|
});
|
||||||
connect(ui->buttonBox->button(QDialogButtonBox::Ok), &QPushButton::clicked, [=](){
|
connect(ui->buttonBox->button(QDialogButtonBox::Ok), &QPushButton::clicked, [=](){
|
||||||
// apply GUI state to settings
|
// apply GUI state to settings
|
||||||
p->Startup.ConnectToFirstDevice = ui->StartupAutoconnect->isChecked();
|
updateFromGUI();
|
||||||
p->Startup.RememberSweepSettings = ui->StartupSweepLastUsed->isChecked();
|
|
||||||
p->Startup.DefaultSweep.type = ui->StartupSweepType->currentText();
|
|
||||||
p->Startup.DefaultSweep.f_start = ui->StartupSweepStart->value();
|
|
||||||
p->Startup.DefaultSweep.f_stop = ui->StartupSweepStop->value();
|
|
||||||
p->Startup.DefaultSweep.f_excitation = ui->StartupSweepLevel->value();
|
|
||||||
p->Startup.DefaultSweep.dbm_start = ui->StartupSweepPowerStart->value();
|
|
||||||
p->Startup.DefaultSweep.dbm_stop = ui->StartupSweepPowerStop->value();
|
|
||||||
p->Startup.DefaultSweep.dbm_freq = ui->StartupSweepPowerFrequency->value();
|
|
||||||
p->Startup.DefaultSweep.bandwidth = ui->StartupSweepBandwidth->value();
|
|
||||||
p->Startup.DefaultSweep.points = ui->StartupSweepPoints->value();
|
|
||||||
p->Startup.DefaultSweep.averaging = ui->StartupSweepAveraging->value();
|
|
||||||
p->Startup.Generator.frequency = ui->StartupGeneratorFrequency->value();
|
|
||||||
p->Startup.Generator.level = ui->StartupGeneratorLevel->value();
|
|
||||||
p->Startup.SA.start = ui->StartupSAStart->value();
|
|
||||||
p->Startup.SA.stop = ui->StartupSAStop->value();
|
|
||||||
p->Startup.SA.RBW = ui->StartupSARBW->value();
|
|
||||||
p->Startup.SA.window = ui->StartupSAWindow->currentIndex();
|
|
||||||
p->Startup.SA.detector = ui->StartupSADetector->currentIndex();
|
|
||||||
p->Startup.SA.signalID = ui->StartupSASignalID->isChecked();
|
|
||||||
|
|
||||||
p->Acquisition.alwaysExciteBothPorts = ui->AcquisitionAlwaysExciteBoth->isChecked();
|
|
||||||
p->Acquisition.suppressPeaks = ui->AcquisitionSuppressPeaks->isChecked();
|
|
||||||
p->Acquisition.adjustPowerLevel = ui->AcquisitionAdjustPowerLevel->isChecked();
|
|
||||||
p->Acquisition.harmonicMixing = ui->AcquisitionUseHarmonic->isChecked();
|
|
||||||
p->Acquisition.useDFTinSAmode = ui->AcquisitionUseDFT->isChecked();
|
|
||||||
p->Acquisition.RBWLimitForDFT = ui->AcquisitionDFTlimitRBW->value();
|
|
||||||
p->Acquisition.useMedianAveraging = ui->AcquisitionAveragingMode->currentIndex() == 1;
|
|
||||||
p->Acquisition.IF1 = ui->AcquisitionIF1->value();
|
|
||||||
p->Acquisition.ADCprescaler = ui->AcquisitionADCpresc->value();
|
|
||||||
p->Acquisition.DFTPhaseInc = ui->AcquisitionADCphaseInc->value();
|
|
||||||
|
|
||||||
p->Graphs.showUnits = ui->GraphsShowUnit->isChecked();
|
|
||||||
p->Graphs.Color.background = ui->GraphsColorBackground->getColor();
|
|
||||||
p->Graphs.Color.axis = ui->GraphsColorAxis->getColor();
|
|
||||||
p->Graphs.Color.Ticks.Background.enabled = ui->GraphsColorTicksBackgroundEnabled->isChecked();
|
|
||||||
p->Graphs.Color.Ticks.Background.background = ui->GraphsColorTicksBackground->getColor();
|
|
||||||
p->Graphs.Color.Ticks.divisions = ui->GraphsColorTicksDivisions->getColor();
|
|
||||||
p->Graphs.domainChangeBehavior = (GraphDomainChangeBehavior) ui->GraphsDomainChangeBehavior->currentIndex();
|
|
||||||
p->Graphs.lineWidth = ui->GraphsLineWidth->value();
|
|
||||||
|
|
||||||
p->Marker.defaultBehavior.showDataOnGraphs = ui->MarkerShowMarkerData->isChecked();
|
|
||||||
p->Marker.defaultBehavior.showAllData = ui->MarkerShowAllMarkerData->isChecked();
|
|
||||||
p->Marker.interpolatePoints = ui->MarkerInterpolate->currentIndex() == 1;
|
|
||||||
|
|
||||||
p->SCPIServer.enabled = ui->SCPIServerEnabled->isChecked();
|
|
||||||
p->SCPIServer.port = ui->SCPIServerPort->value();
|
|
||||||
accept();
|
accept();
|
||||||
});
|
});
|
||||||
|
connect(ui->buttonBox->button(QDialogButtonBox::Save), &QPushButton::clicked, [=](){
|
||||||
|
auto filename = QFileDialog::getSaveFileName(this, "Save preferences", "", "LibreVNA preferences files (*.vnapref)", nullptr, QFileDialog::DontUseNativeDialog);
|
||||||
|
if(filename.length() > 0) {
|
||||||
|
if(!filename.toLower().endsWith(".vnapref")) {
|
||||||
|
filename.append(".vnapref");
|
||||||
|
}
|
||||||
|
ofstream file;
|
||||||
|
file.open(filename.toStdString());
|
||||||
|
updateFromGUI();
|
||||||
|
file << setw(1) << p->toJSON();
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(ui->buttonBox->button(QDialogButtonBox::Open), &QPushButton::clicked, [=](){
|
||||||
|
auto filename = QFileDialog::getOpenFileName(this, "Load preferences", "", "LibreVNA preferences files (*.vnapref)", nullptr, QFileDialog::DontUseNativeDialog);
|
||||||
|
if(filename.length() > 0) {
|
||||||
|
ifstream file;
|
||||||
|
file.open(filename.toStdString());
|
||||||
|
nlohmann::json j;
|
||||||
|
file >> j;
|
||||||
|
file.close();
|
||||||
|
p->fromJSON(j);
|
||||||
|
setInitialGUIState();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
setInitialGUIState();
|
setInitialGUIState();
|
||||||
updateADCRate();
|
updateADCRate();
|
||||||
@ -259,6 +242,57 @@ void PreferencesDialog::setInitialGUIState()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PreferencesDialog::updateFromGUI()
|
||||||
|
{
|
||||||
|
p->Startup.ConnectToFirstDevice = ui->StartupAutoconnect->isChecked();
|
||||||
|
p->Startup.RememberSweepSettings = ui->StartupSweepLastUsed->isChecked();
|
||||||
|
p->Startup.DefaultSweep.type = ui->StartupSweepType->currentText();
|
||||||
|
p->Startup.DefaultSweep.f_start = ui->StartupSweepStart->value();
|
||||||
|
p->Startup.DefaultSweep.f_stop = ui->StartupSweepStop->value();
|
||||||
|
p->Startup.DefaultSweep.f_excitation = ui->StartupSweepLevel->value();
|
||||||
|
p->Startup.DefaultSweep.dbm_start = ui->StartupSweepPowerStart->value();
|
||||||
|
p->Startup.DefaultSweep.dbm_stop = ui->StartupSweepPowerStop->value();
|
||||||
|
p->Startup.DefaultSweep.dbm_freq = ui->StartupSweepPowerFrequency->value();
|
||||||
|
p->Startup.DefaultSweep.bandwidth = ui->StartupSweepBandwidth->value();
|
||||||
|
p->Startup.DefaultSweep.points = ui->StartupSweepPoints->value();
|
||||||
|
p->Startup.DefaultSweep.averaging = ui->StartupSweepAveraging->value();
|
||||||
|
p->Startup.Generator.frequency = ui->StartupGeneratorFrequency->value();
|
||||||
|
p->Startup.Generator.level = ui->StartupGeneratorLevel->value();
|
||||||
|
p->Startup.SA.start = ui->StartupSAStart->value();
|
||||||
|
p->Startup.SA.stop = ui->StartupSAStop->value();
|
||||||
|
p->Startup.SA.RBW = ui->StartupSARBW->value();
|
||||||
|
p->Startup.SA.window = ui->StartupSAWindow->currentIndex();
|
||||||
|
p->Startup.SA.detector = ui->StartupSADetector->currentIndex();
|
||||||
|
p->Startup.SA.signalID = ui->StartupSASignalID->isChecked();
|
||||||
|
|
||||||
|
p->Acquisition.alwaysExciteBothPorts = ui->AcquisitionAlwaysExciteBoth->isChecked();
|
||||||
|
p->Acquisition.suppressPeaks = ui->AcquisitionSuppressPeaks->isChecked();
|
||||||
|
p->Acquisition.adjustPowerLevel = ui->AcquisitionAdjustPowerLevel->isChecked();
|
||||||
|
p->Acquisition.harmonicMixing = ui->AcquisitionUseHarmonic->isChecked();
|
||||||
|
p->Acquisition.useDFTinSAmode = ui->AcquisitionUseDFT->isChecked();
|
||||||
|
p->Acquisition.RBWLimitForDFT = ui->AcquisitionDFTlimitRBW->value();
|
||||||
|
p->Acquisition.useMedianAveraging = ui->AcquisitionAveragingMode->currentIndex() == 1;
|
||||||
|
p->Acquisition.IF1 = ui->AcquisitionIF1->value();
|
||||||
|
p->Acquisition.ADCprescaler = ui->AcquisitionADCpresc->value();
|
||||||
|
p->Acquisition.DFTPhaseInc = ui->AcquisitionADCphaseInc->value();
|
||||||
|
|
||||||
|
p->Graphs.showUnits = ui->GraphsShowUnit->isChecked();
|
||||||
|
p->Graphs.Color.background = ui->GraphsColorBackground->getColor();
|
||||||
|
p->Graphs.Color.axis = ui->GraphsColorAxis->getColor();
|
||||||
|
p->Graphs.Color.Ticks.Background.enabled = ui->GraphsColorTicksBackgroundEnabled->isChecked();
|
||||||
|
p->Graphs.Color.Ticks.Background.background = ui->GraphsColorTicksBackground->getColor();
|
||||||
|
p->Graphs.Color.Ticks.divisions = ui->GraphsColorTicksDivisions->getColor();
|
||||||
|
p->Graphs.domainChangeBehavior = (GraphDomainChangeBehavior) ui->GraphsDomainChangeBehavior->currentIndex();
|
||||||
|
p->Graphs.lineWidth = ui->GraphsLineWidth->value();
|
||||||
|
|
||||||
|
p->Marker.defaultBehavior.showDataOnGraphs = ui->MarkerShowMarkerData->isChecked();
|
||||||
|
p->Marker.defaultBehavior.showAllData = ui->MarkerShowAllMarkerData->isChecked();
|
||||||
|
p->Marker.interpolatePoints = ui->MarkerInterpolate->currentIndex() == 1;
|
||||||
|
|
||||||
|
p->SCPIServer.enabled = ui->SCPIServerEnabled->isChecked();
|
||||||
|
p->SCPIServer.port = ui->SCPIServerPort->value();
|
||||||
|
}
|
||||||
|
|
||||||
void Preferences::load()
|
void Preferences::load()
|
||||||
{
|
{
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
@ -296,3 +330,13 @@ void Preferences::setDefault()
|
|||||||
d.var.setValue(d.def);
|
d.var.setValue(d.def);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Preferences::fromJSON(nlohmann::json j)
|
||||||
|
{
|
||||||
|
parseJSON(j, descr);
|
||||||
|
}
|
||||||
|
|
||||||
|
nlohmann::json Preferences::toJSON()
|
||||||
|
{
|
||||||
|
return createJSON(descr);
|
||||||
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define PREFERENCESDIALOG_H
|
#define PREFERENCESDIALOG_H
|
||||||
|
|
||||||
#include "Util/qpointervariant.h"
|
#include "Util/qpointervariant.h"
|
||||||
|
#include "savable.h"
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
@ -16,7 +17,7 @@ enum GraphDomainChangeBehavior {
|
|||||||
Q_DECLARE_METATYPE(GraphDomainChangeBehavior);
|
Q_DECLARE_METATYPE(GraphDomainChangeBehavior);
|
||||||
|
|
||||||
|
|
||||||
class Preferences {
|
class Preferences : public Savable {
|
||||||
public:
|
public:
|
||||||
static Preferences& getInstance() {
|
static Preferences& getInstance() {
|
||||||
return instance;
|
return instance;
|
||||||
@ -104,16 +105,16 @@ public:
|
|||||||
} SCPIServer;
|
} SCPIServer;
|
||||||
|
|
||||||
bool TCPoverride; // in case of manual port specification via command line
|
bool TCPoverride; // in case of manual port specification via command line
|
||||||
|
|
||||||
|
void fromJSON(nlohmann::json j) override;
|
||||||
|
nlohmann::json toJSON() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Preferences() :
|
Preferences() :
|
||||||
TCPoverride(false) {};
|
TCPoverride(false) {};
|
||||||
static Preferences instance;
|
static Preferences instance;
|
||||||
using SettingDescription = struct {
|
|
||||||
QPointerVariant var;
|
const std::vector<Savable::SettingDescription> descr = {{
|
||||||
QString name;
|
|
||||||
QVariant def;
|
|
||||||
};
|
|
||||||
const std::array<SettingDescription, 45> descr = {{
|
|
||||||
{&Startup.ConnectToFirstDevice, "Startup.ConnectToFirstDevice", true},
|
{&Startup.ConnectToFirstDevice, "Startup.ConnectToFirstDevice", true},
|
||||||
{&Startup.RememberSweepSettings, "Startup.RememberSweepSettings", false},
|
{&Startup.RememberSweepSettings, "Startup.RememberSweepSettings", false},
|
||||||
{&Startup.DefaultSweep.type, "Startup.DefaultSweep.type", "Frequency"},
|
{&Startup.DefaultSweep.type, "Startup.DefaultSweep.type", "Frequency"},
|
||||||
@ -176,6 +177,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void setInitialGUIState();
|
void setInitialGUIState();
|
||||||
|
void updateFromGUI();
|
||||||
Ui::PreferencesDialog *ui;
|
Ui::PreferencesDialog *ui;
|
||||||
Preferences *p;
|
Preferences *p;
|
||||||
};
|
};
|
||||||
|
@ -1144,7 +1144,7 @@
|
|||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="standardButtons">
|
<property name="standardButtons">
|
||||||
<set>QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
|
<set>QDialogButtonBox::Ok|QDialogButtonBox::Open|QDialogButtonBox::RestoreDefaults|QDialogButtonBox::Save</set>
|
||||||
</property>
|
</property>
|
||||||
<property name="centerButtons">
|
<property name="centerButtons">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
|
@ -2,11 +2,87 @@
|
|||||||
#define SAVABLE_H
|
#define SAVABLE_H
|
||||||
|
|
||||||
#include "json.hpp"
|
#include "json.hpp"
|
||||||
|
#include "Util/qpointervariant.h"
|
||||||
|
|
||||||
|
#include <QVariant>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QColor>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
class Savable {
|
class Savable {
|
||||||
public:
|
public:
|
||||||
virtual nlohmann::json toJSON() = 0;
|
virtual nlohmann::json toJSON() = 0;
|
||||||
virtual void fromJSON(nlohmann::json j) = 0;
|
virtual void fromJSON(nlohmann::json j) = 0;
|
||||||
|
|
||||||
|
using SettingDescription = struct {
|
||||||
|
QPointerVariant var;
|
||||||
|
QString name;
|
||||||
|
QVariant def;
|
||||||
|
};
|
||||||
|
static void parseJSON(nlohmann::json j, std::vector<SettingDescription> descr) {
|
||||||
|
for(auto e : descr) {
|
||||||
|
auto list = e.name.split(".");
|
||||||
|
auto *json_entry = &j;
|
||||||
|
bool entry_exists = true;
|
||||||
|
while(list.size() > 0) {
|
||||||
|
auto key = list.takeFirst().toStdString();
|
||||||
|
if((*json_entry).contains(key)) {
|
||||||
|
json_entry = &(*json_entry)[key];
|
||||||
|
} else {
|
||||||
|
entry_exists = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!entry_exists) {
|
||||||
|
// missing entry in json file, nothing to do (default values already set in constructor)
|
||||||
|
qWarning() << "Entry" << e.name << "not present in file";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// json library does not now about QVariant, handle used cases
|
||||||
|
auto val = e.var.value();
|
||||||
|
switch(static_cast<QMetaType::Type>(val.type())) {
|
||||||
|
case QMetaType::Double: e.var.setValue((*json_entry).get<double>()); break;
|
||||||
|
case QMetaType::Int: e.var.setValue((*json_entry).get<int>()); break;
|
||||||
|
case QMetaType::Bool: e.var.setValue((*json_entry).get<bool>()); break;
|
||||||
|
case QMetaType::QString: {
|
||||||
|
auto s = QString::fromStdString((*json_entry).get<std::string>());
|
||||||
|
e.var.setValue(s);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case QMetaType::QColor: {
|
||||||
|
auto s = QString::fromStdString((*json_entry).get<std::string>());
|
||||||
|
e.var.setValue(QColor(s));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("Unimplemented metatype:"+std::string(val.typeName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static nlohmann::json createJSON(std::vector<SettingDescription> descr) {
|
||||||
|
nlohmann::json j;
|
||||||
|
for(auto e : descr) {
|
||||||
|
auto list = e.name.split(".");
|
||||||
|
auto *json_entry = &j;
|
||||||
|
while(list.size() > 0) {
|
||||||
|
json_entry = &(*json_entry)[list.takeFirst().toStdString()];
|
||||||
|
}
|
||||||
|
// json library does not now about QVariant, handle used cases
|
||||||
|
auto val = e.var.value();
|
||||||
|
switch(static_cast<QMetaType::Type>(val.type())) {
|
||||||
|
case QMetaType::Double: *json_entry = val.toDouble(); break;
|
||||||
|
case QMetaType::Int: *json_entry = val.toInt(); break;
|
||||||
|
case QMetaType::Bool: *json_entry = val.toBool(); break;
|
||||||
|
case QMetaType::QString: *json_entry = val.toString().toStdString(); break;
|
||||||
|
case QMetaType::QColor: *json_entry = val.value<QColor>().name().toStdString(); break;
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("Unimplemented metatype:"+std::string(val.typeName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return j;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SAVABLE_H
|
#endif // SAVABLE_H
|
||||||
|
Loading…
Reference in New Issue
Block a user