Commit cb91fc7a authored by CABEL Tristan's avatar CABEL Tristan

Merge branch 'feature/parameterReader' into 'develop'

Feature/parameter reader

See merge request !20
parents 3626d16a 25b118a0
......@@ -20,6 +20,7 @@
#include "dtkWidgetsMenuBar.h"
#include <dtkCore/dtkCoreParameter>
#include <dtkCore/dtkCoreParameterReader>
#include <dtkFonts/dtkFontAwesome>
......@@ -34,11 +35,10 @@ public:
void parseParameter(dtkWidgetsMenu *, const QJsonObject&);
public:
QJsonArray nature;
QJsonObject definition;
QJsonArray menu;
public:
QHash<QString, dtkCoreParameter *> parameters;
dtkCoreParameters parameters;
};
// ///////////////////////////////////////////////////////////////////
......@@ -46,21 +46,10 @@ public:
void dtkWidgetsParameterMenuBarGeneratorPrivate::parseParameter(dtkWidgetsMenu *menu, const QJsonObject& parameter_object)
{
QString widget_string = parameter_object["widget"].toString();
QString type_string = parameter_object["type"].toString();
QVariantHash map;
map.insert("type", type_string);
dtkCoreParameter *parameter = dtkCoreParameter::create(map);
if (!parameter)
return;
QString parameter_uid = parameter_object["uid"].toString();
parameter->setValue(this->definition[parameter_uid].toObject().toVariantHash());
dtkCoreParameter *parameter = this->parameters[parameter_uid];
menu->addParameter(parameter->label(), parameter, widget_string);
parameters[parameter_uid] = parameter;
}
template<class T>
......@@ -97,47 +86,41 @@ void dtkWidgetsParameterMenuBarGeneratorPrivate::parseGroup(T* menu, const QJson
// dtkWidgetsParameterMenuBarGenerator implementation
// ///////////////////////////////////////////////////////////////////
dtkWidgetsParameterMenuBarGenerator::dtkWidgetsParameterMenuBarGenerator(const QString& nature_file_path, const QString& definition_file_path) : d(new dtkWidgetsParameterMenuBarGeneratorPrivate)
dtkWidgetsParameterMenuBarGenerator::dtkWidgetsParameterMenuBarGenerator(const QString& menu_file_path, const QString& definition_file_path) : d(new dtkWidgetsParameterMenuBarGeneratorPrivate)
{
QFile nature_file(nature_file_path);
QFile definition_file(definition_file_path);
if (nature_file.open(QFile::ReadOnly) && definition_file.open(QFile::ReadOnly)) {
QJsonParseError nature_error;
QJsonDocument nature_document = QJsonDocument::fromJson(nature_file.readAll(), &nature_error);
if(nature_error.error != QJsonParseError::NoError) {
qWarning() << Q_FUNC_INFO << "Error :" << nature_error.errorString() << "parsing" << nature_file_path << "offset :" << nature_error.offset << ".";
return;
}
QFile menu_file(menu_file_path);
QJsonObject nature_object = nature_document.object();
if(!nature_object.contains("contents")) {
qWarning() << Q_FUNC_INFO << "The nature parameters file should contain a first json object with key 'contents'. The file cannot be processed any further.";
return;
}
dtkCoreParameterReader param_reader;
param_reader.setJsonFile(definition_file_path);
if (!param_reader.read()) {
qWarning() << Q_FUNC_INFO << "The file" << definition_file_path << "could not be read.";
return;
}
d->parameters = param_reader.parameters();
QJsonParseError definition_error;
QJsonDocument definition_document = QJsonDocument::fromJson(definition_file.readAll(), &definition_error);
if(definition_error.error != QJsonParseError::NoError) {
qWarning() << Q_FUNC_INFO << "Error :" << definition_error.errorString() << "parsing" << definition_file_path << "offset :" << definition_error.offset << ".";
if (menu_file.open(QFile::ReadOnly)) {
QJsonParseError menu_error;
QJsonDocument menu_document = QJsonDocument::fromJson(menu_file.readAll(), &menu_error);
if(menu_error.error != QJsonParseError::NoError) {
qWarning() << Q_FUNC_INFO << "Error :" << menu_error.errorString() << "parsing" << menu_file_path << "offset :" << menu_error.offset << ".";
return;
}
QJsonObject definition_object = definition_document.object();
if(!definition_object.contains("contents")) {
qWarning() << Q_FUNC_INFO << "The nature parameters file should contain a first json object with key 'contents'. The file cannot be processed any further.";
QJsonObject menu_object = menu_document.object();
if(!menu_object.contains("contents")) {
qWarning() << Q_FUNC_INFO << "The menu parameters file should contain a first json object with key 'contents'. The file cannot be processed any further.";
return;
}
QJsonValue nature_contents = nature_object["contents"];
QJsonValue definition_contents = definition_object["contents"];
if (nature_contents.isArray() && definition_contents.isObject()) {
d->nature = nature_contents.toArray();
d->definition = definition_contents.toObject();
QJsonValue menu_contents = menu_object["contents"];
if (menu_contents.isArray()) {
d->menu = menu_contents.toArray();
} else {
qWarning() << Q_FUNC_INFO << "The first object with key 'contents' must be an array.";
}
} else {
qWarning() << Q_FUNC_INFO << "The file" << nature_file_path << "could not be opened.";
qWarning() << Q_FUNC_INFO << "The file" << menu_file_path << "could not be opened.";
}
}
......@@ -148,7 +131,7 @@ dtkWidgetsParameterMenuBarGenerator::~dtkWidgetsParameterMenuBarGenerator(void)
void dtkWidgetsParameterMenuBarGenerator::populate(dtkWidgetsMenuBar *menubar)
{
for(auto it = d->nature.begin(); it != d->nature.end(); ++it) {
for(auto it = d->menu.begin(); it != d->menu.end(); ++it) {
if(it->isObject()) {
QJsonObject content_object = it->toObject();
if(content_object.contains("group")) {
......@@ -163,7 +146,7 @@ void dtkWidgetsParameterMenuBarGenerator::populate(dtkWidgetsMenuBar *menubar)
}
}
QHash<QString, dtkCoreParameter *> dtkWidgetsParameterMenuBarGenerator::parameters(void) const
dtkCoreParameters dtkWidgetsParameterMenuBarGenerator::parameters(void) const
{
return d->parameters;
}
......
......@@ -16,11 +16,12 @@
#include <dtkWidgetsExport>
#include <dtkCore/dtkCoreParameters>
#include <QtCore>
class dtkWidgetsMenuBar;
class dtkCoreParameter;
class dtkWidgetsParameter;
// ///////////////////////////////////////////////////////////////////
// dtkWidgetsParameterMenuBarGenerator declaration
......@@ -29,14 +30,14 @@ class dtkWidgetsParameter;
class DTKWIDGETS_EXPORT dtkWidgetsParameterMenuBarGenerator
{
public:
dtkWidgetsParameterMenuBarGenerator(const QString&, const QString&);
dtkWidgetsParameterMenuBarGenerator(const QString& menu_file, const QString& definition_file);
~dtkWidgetsParameterMenuBarGenerator(void);
public:
void populate(dtkWidgetsMenuBar *menubar);
public:
QHash<QString, dtkCoreParameter *> parameters(void) const;
dtkCoreParameters parameters(void) const;
protected:
class dtkWidgetsParameterMenuBarGeneratorPrivate *d;
......
......@@ -58,6 +58,7 @@ add_executable(${PROJECT_NAME}
target_link_libraries(${PROJECT_NAME} dtkWidgets)
target_link_libraries(${PROJECT_NAME} dtkCore)
target_link_libraries(${PROJECT_NAME} dtkThemes)
target_link_libraries(${PROJECT_NAME} Qt5::Widgets)
target_link_libraries(${PROJECT_NAME} Qt5::Test)
......
......@@ -17,8 +17,9 @@
#include <dtkWidgetsTest>
#include <dtkWidgets/dtkWidgets>
#include <dtkThemes>
#include <dtkWidgets/dtkWidgets>
#include <dtkWidgets/dtkWidgetsParameterMenuBarGenerator>
// ///////////////////////////////////////////////////////////////////
......@@ -36,20 +37,11 @@ class dtkWidgetsParameterMenuBarGeneratorTestCasePrivate
dtkWidgetsParameterMenuBarGeneratorTestCase::dtkWidgetsParameterMenuBarGeneratorTestCase(void) : d(new dtkWidgetsParameterMenuBarGeneratorTestCasePrivate)
{
qRegisterMetaTypeStreamOperators<dtk::d_bool>("dtk::d_bool");
qRegisterMetaTypeStreamOperators<dtk::d_real>("dtk::d_real");
qRegisterMetaTypeStreamOperators<dtk::d_int>("dtk::d_int");
qRegisterMetaTypeStreamOperators<dtk::d_string>("dtk::d_string");
qRegisterMetaType<dtk::d_real *>();
qRegisterMetaType<dtk::d_bool *>();
qRegisterMetaType<dtk::d_int *>();
qRegisterMetaType<dtk::d_string *>();
dtk::core::registerParameters();
dtk::widgets::setVerboseLoading(true);
dtk::widgets::initialize("");
dtkThemesEngine::instance()->apply();
}
dtkWidgetsParameterMenuBarGeneratorTestCase::~dtkWidgetsParameterMenuBarGeneratorTestCase(void)
......@@ -69,11 +61,19 @@ void dtkWidgetsParameterMenuBarGeneratorTestCase::init(void)
void dtkWidgetsParameterMenuBarGeneratorTestCase::testBasic(void)
{
QString nature_file_path = QFINDTESTDATA("../resources/parameters_nature.json");
QString definition_file_path = QFINDTESTDATA("../resources/parameters_definition.json");
QString nature_file_path = QFINDTESTDATA("../resources/new_menu.json");
QString definition_file_path = QFINDTESTDATA("../resources/new_definition.json");
dtkWidgetsParameterMenuBarGenerator menu_bar_generator(nature_file_path, definition_file_path);
dtkCoreParameters params = menu_bar_generator.parameters();
QCOMPARE(params.count() , 78);
dtkWidgetsMenuBar bar;
menu_bar_generator.populate(&bar);
auto menus = bar.menus();
QCOMPARE(menus.count() , 4);
}
void dtkWidgetsParameterMenuBarGeneratorTestCase::cleanup(void)
......
{
"contents": {
"vbb_1": {
"label": "Browse Video",
"doc": "Load the video used as input in the simulation.",
"filters": [
"mp4 (*.mp4)"
],
"type": "dtk::d_path"
},
"gbb_1": {
"label": "Browse Graph",
"doc": "Load the graph to be used in the simulation.",
"filters": [
"macular (*.mac)"
],
"type": "dtk::d_path"
},
"run": {
"label": "Run Simulation",
"doc": "Run the simulation. After setting the graph",
"value": "false",
"type": "dtk::d_bool"
},
"reset": {
"label": "Reset Simulation",
"doc": "Reset the simulation.",
"value": "false",
"type": "dtk::d_bool"
},
"model": {
"label": "Model",
"doc": "Choose the model.",
"value": "Virtual Retina",
"values": [
"Virtual Retina",
"Prosthesis"
],
"type": "dtk::d_inliststring"
},
"framerate": {
"label": "Frame Rate",
"doc": "Controls how fast the visualization should be updated.",
"value": "10",
"min": "1",
"max": "60",
"type": "dtk::d_int"
},
"dt": {
"label": "Integration timestep",
"doc": "Controls the integration step of the ODE solver (ms).",
"value": "0.005",
"min": "0.",
"decimals": "6",
"type": "dtk::d_real"
},
"save_restore": {
"label": "Save/Restore parameters",
"doc": "Stores the parameters of the cells so they are restored when the application is opened again",
"value": "false",
"type": "dtk::d_bool"
},
"save_frequency": {
"label": "Save frequency",
"doc": "save frequency as a multiple of dt (0 = no save)",
"value": "0",
"min": 0,
"max": 10000,
"type": "dtk::d_int"
},
"vrOn/temporal_step": {
"label": "temporal step",
"doc": "temporal step for vrOn",
"value": 0.005,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOn/input_luminosity_range": {
"label": "input luminosity range",
"doc": "input luminosity range for vrOn",
"value": 255.0,
"min": 0.0,
"max": 1000.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOn/pixels_per_degree": {
"label": "pixels per degree",
"doc": "pixels per degree for vrOn",
"value": 2.0,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOn/sigmaCenter": {
"label": "sigma Center",
"doc": "sigma Center for vrOn",
"value": 0.4,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOn/tauCenter": {
"label": "tau Center",
"doc": "tau Center for vrOn",
"value": 0.01,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOn/nCenter": {
"label": "n Center",
"doc": "n Center for vrOn",
"value": 0.0,
"min": -1.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOn/sigmaSurround": {
"label": "sigma Surround",
"doc": "sigma Surround for vrOn",
"value": 1.2,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOn/tauSurround": {
"label": "tau Surround",
"doc": "tau Surround for vrOn",
"value": 0.01,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOn/wSurround": {
"label": "w Surround",
"doc": "w Surround for vrOn",
"value": 1.0,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOn/leakyHeatEq": {
"label": "leaky Heat Eq",
"doc": "leaky Heat Eq for vrOn",
"value": 0.0,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOn/relative_ampOPL": {
"label": "relative ampOPL",
"doc": "relative ampOPL for vrOn",
"value": 1.0,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOn/FGC_ampFeedback": {
"label": "FGC ampFeedback",
"doc": " for vrOn",
"value": 100.0,
"min": 0.0,
"max": 1000.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOn/FGC_ampInputCurrent": {
"label": "FGC ampInputCurrent",
"doc": "FGC ampInputCurrent for vrOn",
"value": 150.0,
"min": 0.0,
"max": 1000.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOn/FGC_gLeak": {
"label": "FGC gLeak",
"doc": "FGC gLeak for vrOn",
"value": 5.0,
"min": 0.0,
"max": 100.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOn/FGC_sigmaSurround": {
"label": "FGC sigmaSurround",
"doc": "FGC sigmaSurround for vrOn",
"value": 2.5,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOn/FGC_tauSurround": {
"label": "FGC tauSurround",
"doc": "FGC tauSurround for vrOn",
"value": 0.01,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOff/temporal_step": {
"label": "temporal step",
"doc": "temporal step for vrOff",
"value": 0.005,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOff/input_luminosity_range": {
"label": "input luminosity range",
"doc": "input luminosity range for vrOff",
"value": 255.0,
"min": 0.0,
"max": 1000.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOff/pixels_per_degree": {
"label": "pixels per degree",
"doc": "pixels per degree for vrOff",
"value": 2.0,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOff/sigmaCenter": {
"label": "sigma Center",
"doc": "sigma Center for vrOff",
"value": 0.4,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOff/tauCenter": {
"label": "tau Center",
"doc": "tau Center for vrOff",
"value": 0.01,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOff/nCenter": {
"label": "n Center",
"doc": "n Center for vrOff",
"value": 0.0,
"min": -1.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOff/sigmaSurround": {
"label": "sigma Surround",
"doc": "sigma Surround for vrOff",
"value": 1.2,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOff/tauSurround": {
"label": "tau Surround",
"doc": "tau Surround for vrOff",
"value": 0.01,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOff/wSurround": {
"label": "w Surround",
"doc": "w Surround for vrOff",
"value": 1.0,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOff/leakyHeatEq": {
"label": "leaky Heat Eq",
"doc": "leaky Heat Eq for vrOff",
"value": 0.0,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOff/relative_ampOPL": {
"label": "relative ampOPL",
"doc": "relative ampOPL for vrOff",
"value": 1.0,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOff/FGC_ampFeedback": {
"label": "FGC ampFeedback",
"doc": " for vrOff",
"value": 100.0,
"min": 0.0,
"max": 1000.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOff/FGC_ampInputCurrent": {
"label": "FGC ampInputCurrent",
"doc": "FGC ampInputCurrent for vrOff",
"value": 150.0,
"min": 0.0,
"max": 1000.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOff/FGC_gLeak": {
"label": "FGC gLeak",
"doc": "FGC gLeak for vrOff",
"value": 5.0,
"min": 0.0,
"max": 100.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOff/FGC_sigmaSurround": {
"label": "FGC sigmaSurround",
"doc": "FGC sigmaSurround for vrOff",
"value": 2.5,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vrOff/FGC_tauSurround": {
"label": "FGC tauSurround",
"doc": "FGC tauSurround for vrOff",
"value": 0.01,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vRodOn/temporal_step": {
"label": "temporal step",
"doc": "temporal step for vRodOn",
"value": 0.005,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vRodOn/input_luminosity_range": {
"label": "input luminosity range",
"doc": "input luminosity range for vRodOn",
"value": 255.0,
"min": 0.0,
"max": 1000.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vRodOn/pixels_per_degree": {
"label": "pixels per degree",
"doc": "pixels per degree for vRodOn",
"value": 2.0,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vRodOn/sigmaCenter": {
"label": "sigma Center",
"doc": "sigma Center for vRodOn",
"value": 0.4,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vRodOn/tauCenter": {
"label": "tau Center",
"doc": "tau Center for vRodOn",
"value": 0.01,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vRodOn/nCenter": {
"label": "n Center",
"doc": "n Center for vRodOn",
"value": 0.0,
"min": -1.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vRodOn/sigmaSurround": {
"label": "sigma Surround",
"doc": "sigma Surround for vRodOn",
"value": 1.2,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vRodOn/tauSurround": {
"label": "tau Surround",
"doc": "tau Surround for vRodOn",
"value": 0.01,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vRodOn/wSurround": {
"label": "w Surround",
"doc": "w Surround for vRodOn",
"value": 1.0,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vRodOn/leakyHeatEq": {
"label": "leaky Heat Eq",
"doc": "leaky Heat Eq for vRodOn",
"value": 0.0,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vRodOn/relative_ampOPL": {
"label": "relative ampOPL",
"doc": "relative ampOPL for vRodOn",
"value": 1.0,
"min": 0.0,
"max": 10.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vRodOn/FGC_ampFeedback": {
"label": "FGC ampFeedback",
"doc": " for vRodOn",
"value": 100.0,
"min": 0.0,
"max": 1000.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vRodOn/FGC_ampInputCurrent": {
"label": "FGC ampInputCurrent",
"doc": "FGC ampInputCurrent for vRodOn",
"value": 150.0,
"min": 0.0,
"max": 1000.0,
"decimals": 6,
"type": "dtk::d_real"
},
"vRodOn/FGC_gLeak": {
"label": "FGC gLeak",
"doc": "FGC gLeak for vRodOn",
"value": 5.0,