BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
jsonvariantconverter.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // qt-mvvm: Model-view-view-model framework for large GUI applications
4 //
5 //! @file mvvm/model/mvvm/serialization/jsonvariantconverter.cpp
6 //! @brief Implements class CLASS?
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2020
11 //! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
21 #include "mvvm/utils/reallimits.h"
22 #include <QJsonArray>
23 #include <QJsonObject>
24 #include <stdexcept>
25 
26 using namespace ModelView;
27 
28 namespace {
29 
30 const QString variantTypeKey = "type";
31 const QString variantValueKey = "value";
32 const QString comboValuesKey = "values";
33 const QString comboSelectionKey = "selections";
34 const QString extPropertyTextKey = "text";
35 const QString extPropertyColorKey = "color";
36 const QString extPropertyIdKey = "identifier";
37 const QString realLimitsTextKey = "text";
38 const QString realLimitsMinKey = "min";
39 const QString realLimitsMaxKey = "max";
40 
41 QStringList expected_variant_keys();
42 
43 QJsonObject from_invalid(const Variant& variant);
44 Variant to_invalid(const QJsonObject& object);
45 
46 QJsonObject from_bool(const Variant& variant);
47 Variant to_bool(const QJsonObject& object);
48 
49 QJsonObject from_int(const Variant& variant);
50 Variant to_int(const QJsonObject& object);
51 
52 QJsonObject from_string(const Variant& variant);
53 Variant to_string(const QJsonObject& object);
54 
55 QJsonObject from_double(const Variant& variant);
56 Variant to_double(const QJsonObject& object);
57 
58 QJsonObject from_vector_double(const Variant& variant);
59 Variant to_vector_double(const QJsonObject& object);
60 
61 QJsonObject from_comboproperty(const Variant& variant);
62 Variant to_comboproperty(const QJsonObject& object);
63 
64 QJsonObject from_qcolor(const Variant& variant);
65 Variant to_qcolor(const QJsonObject& object);
66 
67 QJsonObject from_extproperty(const Variant& variant);
68 Variant to_extproperty(const QJsonObject& object);
69 
70 QJsonObject from_reallimits(const Variant& variant);
71 Variant to_reallimits(const QJsonObject& object);
72 
73 } // namespace
74 
76 {
77  m_converters[Constants::invalid_type_name] = {from_invalid, to_invalid};
78  m_converters[Constants::bool_type_name] = {from_bool, to_bool};
79  m_converters[Constants::int_type_name] = {from_int, to_int};
80  m_converters[Constants::string_type_name] = {from_string, to_string};
81  m_converters[Constants::double_type_name] = {from_double, to_double};
82  m_converters[Constants::vector_double_type_name] = {from_vector_double, to_vector_double};
83  m_converters[Constants::comboproperty_type_name] = {from_comboproperty, to_comboproperty};
84  m_converters[Constants::qcolor_type_name] = {from_qcolor, to_qcolor};
85  m_converters[Constants::extproperty_type_name] = {from_extproperty, to_extproperty};
86  m_converters[Constants::reallimits_type_name] = {from_reallimits, to_reallimits};
87 }
88 
89 QJsonObject JsonVariantConverter::get_json(const Variant& variant)
90 {
91  const std::string type_name = Utils::VariantName(variant);
92 
93  if (m_converters.find(type_name) == m_converters.end())
94  throw std::runtime_error("json::get_json() -> Error. Unknown variant type '" + type_name
95  + "'.");
96 
97  return m_converters[type_name].variant_to_json(variant);
98 }
99 
100 Variant JsonVariantConverter::get_variant(const QJsonObject& object)
101 {
102  if (!isVariant(object))
103  throw std::runtime_error("json::get_variant() -> Error. Invalid json object");
104 
105  const auto type_name = object[variantTypeKey].toString().toStdString();
106  if (m_converters.find(type_name) == m_converters.end())
107  throw std::runtime_error("json::get_variant() -> Error. Unknown variant type '" + type_name
108  + "' in json object.");
109 
110  return m_converters[type_name].json_to_variant(object);
111 }
112 
113 //! Returns true if given json object represents variant.
114 
115 bool JsonVariantConverter::isVariant(const QJsonObject& object) const
116 {
117  static const QStringList expected = expected_variant_keys();
118  return object.keys() == expected;
119 }
120 
121 namespace {
122 
123 QStringList expected_variant_keys()
124 {
125  QStringList result = QStringList() << variantTypeKey << variantValueKey;
126  std::sort(result.begin(), result.end());
127  return result;
128 }
129 
130 QJsonObject from_invalid(const Variant& variant)
131 {
132  (void)variant;
133  QJsonObject result;
134  result[variantTypeKey] = QString::fromStdString(Constants::invalid_type_name);
135  result[variantValueKey] = QJsonValue();
136  return result;
137 }
138 
139 Variant to_invalid(const QJsonObject& object)
140 {
141  (void)object;
142  return Variant();
143 }
144 
145 QJsonObject from_bool(const Variant& variant)
146 {
147  QJsonObject result;
148  result[variantTypeKey] = QString::fromStdString(Constants::bool_type_name);
149  result[variantValueKey] = variant.value<bool>();
150  return result;
151 }
152 
153 Variant to_bool(const QJsonObject& object)
154 {
155  return object[variantValueKey].toVariant();
156 }
157 
158 QJsonObject from_int(const Variant& variant)
159 {
160  QJsonObject result;
161  result[variantTypeKey] = QString::fromStdString(Constants::int_type_name);
162  result[variantValueKey] = variant.value<int>();
163  return result;
164 }
165 
166 Variant to_int(const QJsonObject& object)
167 {
168  // deliberately recreating variant, otherwise it is changing type to Qariant::Double
169  return Variant::fromValue(object[variantValueKey].toVariant().value<int>());
170 }
171 
172 QJsonObject from_string(const Variant& variant)
173 {
174  QJsonObject result;
175  result[variantTypeKey] = QString::fromStdString(Constants::string_type_name);
176  result[variantValueKey] = QString::fromStdString(variant.value<std::string>());
177  return result;
178 }
179 
180 Variant to_string(const QJsonObject& object)
181 {
182  std::string value = object[variantValueKey].toString().toStdString();
183  return Variant::fromValue(value);
184 }
185 
186 QJsonObject from_double(const Variant& variant)
187 {
188  QJsonObject result;
189  result[variantTypeKey] = QString::fromStdString(Constants::double_type_name);
190  result[variantValueKey] = variant.value<double>();
191  return result;
192 }
193 
194 Variant to_double(const QJsonObject& object)
195 {
196  // deliberately recreating variant, otherwise it is changing type to qlonglong for
197  // numbers like 43.0
198  return object[variantValueKey].toVariant().value<double>();
199 }
200 
201 // --- std::vector<double> ------
202 
203 QJsonObject from_vector_double(const Variant& variant)
204 {
205  QJsonObject result;
206  result[variantTypeKey] = QString::fromStdString(Constants::vector_double_type_name);
207  QJsonArray array;
208  auto data = variant.value<std::vector<double>>();
209  std::copy(data.begin(), data.end(), std::back_inserter(array));
210  result[variantValueKey] = array;
211  return result;
212 }
213 
214 Variant to_vector_double(const QJsonObject& object)
215 {
216  std::vector<double> vec;
217  for (auto x : object[variantValueKey].toArray())
218  vec.push_back(x.toDouble());
219  return Variant::fromValue(vec);
220 }
221 
222 // --- ComboProperty ------
223 
224 QJsonObject from_comboproperty(const Variant& variant)
225 {
226  QJsonObject result;
227  result[variantTypeKey] = QString::fromStdString(Constants::comboproperty_type_name);
228  auto combo = variant.value<ComboProperty>();
229  QJsonObject json_data;
230  json_data[comboValuesKey] = QString::fromStdString(combo.stringOfValues());
231  json_data[comboSelectionKey] = QString::fromStdString(combo.stringOfSelections());
232  result[variantValueKey] = json_data;
233  return result;
234 }
235 
236 Variant to_comboproperty(const QJsonObject& object)
237 {
238  ComboProperty combo;
239  QJsonObject json_data = object[variantValueKey].toObject();
240  combo.setStringOfValues(json_data[comboValuesKey].toString().toStdString());
241  combo.setStringOfSelections(json_data[comboSelectionKey].toString().toStdString());
242  return Variant::fromValue(combo);
243 }
244 
245 // --- QColor ------
246 
247 QJsonObject from_qcolor(const Variant& variant)
248 {
249  QJsonObject result;
250  result[variantTypeKey] = QString::fromStdString(Constants::qcolor_type_name);
251  auto color = variant.value<QColor>();
252  result[variantValueKey] = color.name(QColor::HexArgb);
253  return result;
254 }
255 
256 Variant to_qcolor(const QJsonObject& object)
257 {
258  return Variant::fromValue(QColor(object[variantValueKey].toString()));
259 }
260 
261 // --- ExternalProperty ------
262 
263 QJsonObject from_extproperty(const Variant& variant)
264 {
265  QJsonObject result;
266  result[variantTypeKey] = QString::fromStdString(Constants::extproperty_type_name);
267  auto extprop = variant.value<ExternalProperty>();
268  QJsonObject json_data;
269  json_data[extPropertyTextKey] = QString::fromStdString(extprop.text());
270  json_data[extPropertyColorKey] = extprop.color().name(QColor::HexArgb);
271  json_data[extPropertyIdKey] = QString::fromStdString(extprop.identifier());
272  result[variantValueKey] = json_data;
273  return result;
274 }
275 
276 Variant to_extproperty(const QJsonObject& object)
277 {
278  QJsonObject json_data = object[variantValueKey].toObject();
279  const std::string text = json_data[extPropertyTextKey].toString().toStdString();
280  const std::string color = json_data[extPropertyColorKey].toString().toStdString();
281  const std::string id = json_data[extPropertyIdKey].toString().toStdString();
282 
283  return Variant::fromValue(ExternalProperty(text, QColor(QString::fromStdString(color)), id));
284 }
285 
286 // --- RealLimits ------
287 
288 QJsonObject from_reallimits(const Variant& variant)
289 {
290  QJsonObject result;
291  result[variantTypeKey] = QString::fromStdString(Constants::reallimits_type_name);
292  auto limits = variant.value<RealLimits>();
293  QJsonObject json_data;
294 
295  json_data[realLimitsTextKey] = QString::fromStdString(JsonUtils::ToString(limits));
296  json_data[realLimitsMinKey] = limits.lowerLimit();
297  json_data[realLimitsMaxKey] = limits.upperLimit();
298 
299  result[variantValueKey] = json_data;
300  return result;
301 }
302 
303 Variant to_reallimits(const QJsonObject& object)
304 {
305  QJsonObject json_data = object[variantValueKey].toObject();
306  const std::string text = json_data[realLimitsTextKey].toString().toStdString();
307  const double min = json_data[realLimitsMinKey].toDouble();
308  const double max = json_data[realLimitsMaxKey].toDouble();
309 
310  return Variant::fromValue(JsonUtils::CreateLimits(text, min, max));
311 }
312 
313 } // namespace
Custom property to define list of string values with multiple selections.
Definition: comboproperty.h:27
void setStringOfSelections(const std::string &values)
Sets selected indices from string.
void setStringOfValues(const std::string &values)
Sets values from the string containing delimeter ';'.
Property to carry text, color and identifier.
QJsonObject get_json(const Variant &variant) override
std::map< std::string, Converters > m_converters
bool isVariant(const QJsonObject &object) const
Returns true if given json object represents variant.
Variant get_variant(const QJsonObject &object) override
Limits for double.
Definition: reallimits.h:25
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
const std::string string_type_name
const std::string bool_type_name
const std::string reallimits_type_name
const std::string comboproperty_type_name
const std::string double_type_name
const std::string extproperty_type_name
const std::string vector_double_type_name
const std::string invalid_type_name
const std::string qcolor_type_name
const std::string int_type_name
MVVM_MODEL_EXPORT RealLimits CreateLimits(const std::string &text, double min=0.0, double max=0.0)
Definition: jsonutils.cpp:60
MVVM_MODEL_EXPORT std::string ToString(const RealLimits &limits)
Returns string representation of RealLimits.
Definition: jsonutils.cpp:42
MVVM_MODEL_EXPORT std::string VariantName(const Variant &variant)
Returns name of variant.
materialitems.h Collection of materials to populate MaterialModel.
std::string toString(PyObject *obj)
Converts PyObject into string, if possible, or throws exception.
Definition: PyUtils.cpp:24
Defines class CLASS?
QVariant Variant
Definition: variant.h:23
Defines class CLASS?