BornAgain  1.19.79
Simulate and fit neutron and x-ray scattering at grazing incidence
DataProperties.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/Model/Data/DataProperties.cpp
6 //! @brief Implements class DataPresentationProperties and its descendants
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2018
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
18 #include "GUI/Model/Job/JobItem.h"
20 #include "GUI/Util/ComboProperty.h"
21 #include "GUI/Util/Error.h"
22 #include "GUI/Util/Path.h"
23 #include <QColor>
24 #include <utility>
25 
26 namespace {
27 
28 // set of simple colors for representation of 1D graphs
29 const std::vector<std::pair<QString, Qt::GlobalColor>> color_queue = {
30  {"Black", Qt::GlobalColor::black}, {"Blue", Qt::GlobalColor::blue},
31  {"Red", Qt::GlobalColor::darkRed}, {"Cyan", Qt::GlobalColor::darkCyan},
32  {"Gray", Qt::GlobalColor::darkGray}, {"Magenta", Qt::GlobalColor::darkMagenta}};
33 
34 // scatters for representation of 1D graphs
35 const QMap<QString, QCPScatterStyle::ScatterShape> scatter_map = {
36  {"None", QCPScatterStyle::ScatterShape::ssNone},
37  {"Disc", QCPScatterStyle::ScatterShape::ssDisc},
38  {"Circle", QCPScatterStyle::ScatterShape::ssCircle},
39  {"Cross", QCPScatterStyle::ScatterShape::ssCross},
40  {"Diamond", QCPScatterStyle::ScatterShape::ssDiamond},
41  {"Star", QCPScatterStyle::ScatterShape::ssStar}};
42 
43 // connection lines for representation of 1D graphs
44 const QMap<QString, QCPGraph::LineStyle> line_map = {
45  {"None", QCPGraph::LineStyle::lsNone},
46  {"Line", QCPGraph::LineStyle::lsLine},
47  {"StepLeft", QCPGraph::LineStyle::lsStepLeft},
48  {"StepRight", QCPGraph::LineStyle::lsStepRight},
49  {"StepCenter", QCPGraph::LineStyle::lsStepCenter},
50  {"Impulse", QCPGraph::LineStyle::lsImpulse}};
51 
52 struct ColorNameComparator {
53  ColorNameComparator(QString value_to_comp)
54  : m_value_to_comp(std::move(value_to_comp))
55  {
56  }
57  bool operator()(const std::pair<QString, Qt::GlobalColor>& value) const
58  {
59  return value.first == m_value_to_comp;
60  }
61 
62  const QString m_value_to_comp;
63 };
64 
65 ComboProperty defaultColorCombo()
66 {
67  ComboProperty result;
68  for (const auto& color : color_queue)
69  result << color.first;
70  result.setValue(color_queue.front().first);
71  return result;
72 }
73 
74 ComboProperty defaultScatterCombo()
75 {
76  ComboProperty result;
77  for (const auto& scatter : scatter_map.keys())
78  result << scatter;
79  result.setValue(scatter_map.keys().first());
80  return result;
81 }
82 
83 ComboProperty defaultLineCombo()
84 {
85  ComboProperty result;
86  for (const auto& line : line_map.keys())
87  result << line;
88  result.setValue(line_map.keys().first());
89  return result;
90 }
91 
92 // TODO cover with unit tests and simplify
93 
94 QModelIndex getIndexFromPath(const SessionModel* model, const QString& path)
95 {
96  if (!model)
97  return {};
98 
99  QStringList parts = path.split("/");
100  SessionItem* t = model->rootItem();
101  for (int i = 0; i < parts.length(); i++) {
102  for (int j = 0; j < t->numberOfChildren(); j++) {
103  if (t->childAt(j)->itemName() == parts[i]) {
104  t = t->childAt(j);
105  break;
106  }
107  }
108  }
109  return t->index();
110 }
111 
112 } // namespace
113 
114 
115 DataProperties::DataProperties(const QString& model_type)
116  : SessionItem(model_type)
117 {
118  addProperty(P_DATALINK, QString());
119 }
120 
122 {
123  const QString& path = GUI::Util::Path::getPathFromIndex(item->index());
124  setItemValue(P_DATALINK, path);
125 }
126 
128 {
129  SessionModel* hosting_model = this->model();
130  const QString& path = getItemValue(P_DATALINK).toString();
131  auto item_index = getIndexFromPath(hosting_model, path);
132  ASSERT(item_index.isValid());
133  auto* item = hosting_model->itemForIndex(item_index);
134  return dynamic_cast<DataItem*>(item);
135 }
136 
138  : DataProperties(M_TYPE)
139 {
140  addProperty(P_COLOR, defaultColorCombo().variant());
141  addProperty(P_SCATTER, defaultScatterCombo().variant());
142  addProperty(P_LINE, defaultLineCombo().variant());
143 }
144 
146 {
147  const QString& color_name = getItemValue(P_COLOR).value<ComboProperty>().getValue();
148  auto iter =
149  std::find_if(color_queue.begin(), color_queue.end(), ColorNameComparator(color_name));
150  ASSERT(iter != color_queue.end());
151  return QColor(iter->second);
152 }
153 
155 {
156  return getItemValue(P_COLOR).value<ComboProperty>().getValue();
157 }
158 
160 {
161  if (!properties)
162  return color_queue.front().first;
163  const auto& current_color = properties->getItemValue(P_COLOR).value<ComboProperty>().getValue();
164  auto iter =
165  std::find_if(color_queue.begin(), color_queue.end(), ColorNameComparator(current_color));
166  if (iter == color_queue.end() || *iter == color_queue.back())
167  return color_queue.front().first;
168  return (++iter)->first;
169 }
170 
171 void Data1DProperties::setColorProperty(const QString& color_name)
172 {
173  auto color_combo = defaultColorCombo();
174  color_combo.setValue(color_name);
175  setItemValue(P_COLOR, color_combo.variant());
176 }
177 
178 QCPScatterStyle::ScatterShape Data1DProperties::scatter()
179 {
180  const QString& scatter_name = getItemValue(P_SCATTER).value<ComboProperty>().getValue();
181  bool contains = scatter_map.contains(scatter_name);
182  ASSERT(contains);
183  return QCPScatterStyle::ScatterShape(scatter_map.value(scatter_name));
184 }
185 
186 QCPGraph::LineStyle Data1DProperties::line()
187 {
188  const QString& line_name = getItemValue(P_LINE).value<ComboProperty>().getValue();
189  bool contains = line_map.contains(line_name);
190  ASSERT(contains);
191  return QCPGraph::LineStyle(line_map.value(line_name));
192 }
193 
194 void Data1DProperties::setScatterProperty(const QString& scatter_name)
195 {
196  auto scatter_combo = defaultScatterCombo();
197  scatter_combo.setValue(scatter_name);
198  setItemValue(P_SCATTER, scatter_combo.variant());
199 }
200 
201 void Data1DProperties::setLineProperty(const QString& line_name)
202 {
203  auto line_combo = defaultLineCombo();
204  line_combo.setValue(line_name);
205  setItemValue(P_LINE, line_combo.variant());
206 }
Defines class ComboProperty.
Declares class DataItem.
Defines class DataProperties and its descendants.
Defines error class.
Defines class InstrumentItem and all its children.
Defines class JobItem.
Defines class Helpers functions.
Defines class SessionModel.
Custom property to define list of string values with multiple selections. Intended for QVariant.
Definition: ComboProperty.h:25
void setValue(const QString &name)
Holds data required for 1D DataItem representation.
void setColorProperty(const QString &color_name)
Returns set up color ComboProperty.
static constexpr auto P_COLOR
static const QString & nextColorName(Data1DProperties *properties)
Returns the name of the color, which follows the color of passes property container....
QColor color()
Creates and returns a color object from color name.
QCPScatterStyle::ScatterShape scatter()
Returns a QCP scatter object from its name.
void setLineProperty(const QString &line_name)
Set up line for qcustomplot.
static constexpr auto P_SCATTER
QString colorName() const
Returns the name of the color.
static constexpr auto P_LINE
QCPGraph::LineStyle line()
Returns a QCP line object from its name.
void setScatterProperty(const QString &scatter_name)
Set up scatter for qcustomplot.
Abstract base class for IntensityDataItem and SpecularDataItem. Owns one simulated data set of type D...
Definition: DataItem.h:34
Implements a link to DataItem. If path name of a DataItem changes, the link becomes invalid....
void setDataItem(DataItem *item)
DataProperties(const QString &model_type)
static constexpr auto P_DATALINK
DataItem * dataItem()
Base class for a GUI data item.
Definition: SessionItem.h:204
QString itemName() const
Get item name, return display name if no name is set.
SessionItem * addProperty(const QString &name, const QVariant &variant)
Add new property item and register new tag. name is the tag name and the display name....
int numberOfChildren() const
Returns total number of children.
Definition: SessionItem.cpp:88
QVariant getItemValue(const QString &tag) const
Directly access value of item under given tag.
void setItemValue(const QString &tag, const QVariant &variant) const
Directly set value of item under given tag.
SessionModel * model() const
Returns model of this item.
Definition: SessionItem.cpp:60
T * item(const QString &tag) const
Definition: SessionItem.h:353
SessionItem * childAt(int row) const
Returns the child at the given row.
QModelIndex index() const
Returns model index of this item.
Definition: SessionItem.cpp:74
Base class for a GUI data collection. A collection is e.g. all real data (RealDataModel)....
Definition: SessionModel.h:42
SessionItem * itemForIndex(const QModelIndex &index) const
SessionItem * rootItem() const
QString getPathFromIndex(const QModelIndex &index)
Definition: Path.cpp:144