BornAgain  1.19.79
Simulate and fit neutron and x-ray scattering at grazing incidence
AbstractDataLoaderResultModel.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/Support/IO/AbstractDataLoaderResultModel.cpp
6 //! @brief Implements class AbstractDataLoaderResultModel
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2021
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
16 #include <QColor>
17 #include <QIcon>
18 #include <QVariant>
19 
20 namespace {
21 
22 struct Palette {
23  static QColor backgroundColorFileContent;
24  static QColor backgroundColorRawContent;
25  static QColor backgroundColorProcessedContent;
26  static QColor backgroundColorErrors;
27  static QColor skippedLineTextColor;
28 };
29 
30 QColor Palette::backgroundColorFileContent(239, 237, 248);
31 QColor Palette::backgroundColorRawContent(247, 240, 210);
32 QColor Palette::backgroundColorProcessedContent(191, 232, 242);
33 QColor Palette::backgroundColorErrors(247, 140, 146);
34 QColor Palette::skippedLineTextColor(Qt::lightGray);
35 
36 } // namespace
37 
39 {
40  m_warningIcon = QIcon(":/images/warning_16x16.png");
41 }
42 
43 int AbstractDataLoaderResultModel::columnCount(const QModelIndex& parent /*= QModelIndex()*/) const
44 {
45  if (parent.isValid())
46  return 0;
47 
50 
51  int cols = 0;
52  for (ColumnType type : colTypes)
53  cols += columnCount(type);
54 
55  return cols;
56 }
57 
58 int AbstractDataLoaderResultModel::rowCount(const QModelIndex& parent) const
59 {
60  return parent.isValid() ? 0 : rowCount();
61 }
62 
63 QVariant AbstractDataLoaderResultModel::data(const QModelIndex& index,
64  int role /*= Qt::DisplayRole*/) const
65 {
66  if (!index.isValid())
67  return QVariant();
68 
69  const auto colType = columnType(index);
70 
71  if (role == Qt::BackgroundRole) {
72  switch (colType) {
73  case ColumnType::line:
75  return Palette::backgroundColorFileContent;
76  case ColumnType::raw:
77  return rowIsSkipped(index) ? QVariant() : Palette::backgroundColorRawContent;
79  return rowIsSkipped(index) || rowHasError(index)
80  ? QVariant()
81  : Palette::backgroundColorProcessedContent;
82  case ColumnType::error:
83  return rowIsSkipped(index) || !rowHasError(index) ? QVariant()
84  : Palette::backgroundColorErrors;
85  default:
86  return QVariant();
87  }
88  }
89 
90  if (role == Qt::ForegroundRole) {
91  if (colType == ColumnType::fileContent && rowIsSkipped(index))
92  return Palette::skippedLineTextColor;
93  return QVariant();
94  }
95 
96  if (role == Qt::DisplayRole) {
97  switch (colType) {
98  case ColumnType::line:
99  return QString::number(index.row() + 1);
100 
102  QString lineContent =
103  cellText(colType, index.row(), index.column() - firstSectionOfColumnType(colType));
104  lineContent.replace("\t", " --> ");
105  return lineContent;
106  }
107 
108  case ColumnType::raw:
109  case ColumnType::error: {
110  if (!rowIsSkipped(index))
111  return cellText(colType, index.row(),
112  index.column() - firstSectionOfColumnType(colType));
113  } break;
114 
115  case ColumnType::processed: {
116  if (!rowIsSkipped(index) && !rowHasError(index))
117  return cellText(colType, index.row(),
118  index.column() - firstSectionOfColumnType(colType));
119  } break;
120  default:
121  break;
122  }
123 
124  return QVariant();
125  }
126 
127  if (role == Qt::DecorationRole && (colType == ColumnType::line || colType == ColumnType::error)
128  && rowHasError(index))
129  return m_warningIcon;
130 
131  if (role == Qt::TextAlignmentRole && colType == ColumnType::line)
132  return QVariant(Qt::AlignRight | Qt::AlignVCenter);
133 
134  if (role == Qt::ToolTipRole && colType == ColumnType::line && rowHasError(index))
135  return cellText(ColumnType::error, index.row(), 0);
136 
137  return QVariant();
138 }
139 
140 QVariant AbstractDataLoaderResultModel::headerData(int section, Qt::Orientation orientation,
141  int role) const
142 {
143  if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
144  switch (columnType(section)) {
145  case ColumnType::line:
146  return "Line";
148  return "File content (text)";
149  case ColumnType::raw:
150  return QString("Column %1 raw")
151  .arg(section - firstSectionOfColumnType(ColumnType::raw) + 1);
153  return headerTextOfCalculatedColumn(section
155  case ColumnType::error:
156  return "Parser warnings";
157  default:
158  return QVariant();
159  }
160  }
161 
162  return QAbstractTableModel::headerData(section, orientation, role);
163 }
164 
166 {
167  QVector<int> sections;
168  for (int section = firstSectionOfColumnType(type); section <= lastSectionOfColumnType(type);
169  section++)
170  if (section >= 0)
171  sections << section;
172 
173  return sections;
174 }
175 
178 {
181 
182  for (ColumnType type : colTypes) {
183  const int firstSection = firstSectionOfColumnType(type);
184  if (firstSection < 0)
185  continue;
186 
187  if (section >= firstSection && section <= lastSectionOfColumnType(type))
188  return type;
189  }
190 
191  return ColumnType::none;
192 }
193 
195 AbstractDataLoaderResultModel::columnType(const QModelIndex& index) const
196 {
197  return columnType(index.column());
198 }
199 
201 {
202  const int lineColumnCount = columnCount(ColumnType::line);
203  const int fileContentColumnCount = columnCount(ColumnType::fileContent);
204 
205  if (type == ColumnType::line)
206  return lineColumnCount > 0 ? 0 : -1;
207 
208  if (type == ColumnType::fileContent)
209  return columnCount(ColumnType::fileContent) > 0 ? lineColumnCount : -1;
210 
211  if (type == ColumnType::raw) {
212  const bool hasRawContent = columnCount(ColumnType::raw) > 0;
213  return hasRawContent ? lineColumnCount + fileContentColumnCount : -1;
214  }
215 
216  if (type == ColumnType::processed) {
217  const bool hasProcessedContent = columnCount(ColumnType::processed) > 0;
218  return hasProcessedContent
219  ? (lineColumnCount + fileContentColumnCount + columnCount(ColumnType::raw))
220  : -1;
221  }
222 
223  if (type == ColumnType::error) {
224  const bool hasParsingErrors = columnCount(ColumnType::error) > 0;
225  return hasParsingErrors
226  ? (lineColumnCount + fileContentColumnCount + columnCount(ColumnType::raw)
228  : -1;
229  }
230 
231  return -1;
232 }
233 
235 {
236  const int firstSection = firstSectionOfColumnType(type);
237  if (firstSection == -1)
238  return -1;
239 
240  return firstSection + columnCount(type) - 1;
241 }
242 
243 bool AbstractDataLoaderResultModel::rowIsSkipped(const QModelIndex& index) const
244 {
245  return rowIsSkipped(index.row());
246 }
247 
248 bool AbstractDataLoaderResultModel::rowHasError(const QModelIndex& index) const
249 {
250  return rowHasError(index.row());
251 }
Defines class AbstractDataLoaderResultModel.
virtual QString headerTextOfCalculatedColumn(int column) const =0
Return the table header text for the given column. For convenience, column starts at 0 for first calc...
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
int firstSectionOfColumnType(ColumnType type) const
Calculates the first real header view section of the given column type. Returns -1 if the column type...
QVector< int > sectionsOfColumnType(ColumnType type) const
The table header sections which belong to the given column type. Empty if this column type is not pre...
virtual bool rowIsSkipped(const QModelIndex &index) const
Returns whether the row given in the index is a skipped row. Only override this for performance reaso...
int columnCount(const QModelIndex &parent=QModelIndex()) const override
virtual QString cellText(ColumnType type, int row, int column) const =0
The text of the given cell. For convenience, column starts at 0 for the given column type,...
virtual bool rowHasError(const QModelIndex &index) const
Returns whether the row given in the index contains errors. Only override this for performance reason...
ColumnType columnType(const QModelIndex &index) const
Calculates the column type of the given index.
virtual int rowCount() const =0
The row count of the result table.
int lastSectionOfColumnType(ColumnType type) const
Calculates the last real header view section of the given column type. Returns -1 if the column type ...
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override