BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
viewmodelbase.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/viewmodel/mvvm/viewmodel/viewmodelbase.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 
17 #include <stdexcept>
18 
19 using namespace ModelView;
20 
22  ViewModelBase* model{nullptr};
23  std::unique_ptr<ViewItem> root;
25 
27  {
28  return model->indexFromItem(item).isValid() || item == model->rootItem();
29  }
30 };
31 
33  : QAbstractItemModel(parent), p_impl(std::make_unique<ViewModelBaseImpl>(this))
34 {
35  beginResetModel();
36  setRootViewItem(std::make_unique<RootViewItem>(nullptr));
37  endResetModel();
38 }
39 
41 
42 QModelIndex ViewModelBase::index(int row, int column, const QModelIndex& parent) const
43 {
44  auto parent_item = itemFromIndex(parent) ? itemFromIndex(parent) : rootItem();
45  const bool is_valid_row = row >= 0 && row < rowCount(parent);
46  const bool is_valid_column = column >= 0 && column < columnCount(parent);
47  return is_valid_row && is_valid_column
48  ? createIndex(row, column, parent_item->child(row, column))
49  : QModelIndex();
50 }
51 
52 QModelIndex ViewModelBase::parent(const QModelIndex& child) const
53 {
54  if (auto child_item = itemFromIndex(child); child_item) {
55  auto parent_item = child_item->parent();
56  return parent_item == rootItem()
57  ? QModelIndex()
58  : createIndex(parent_item->row(), parent_item->column(), parent_item);
59  }
60 
61  return QModelIndex();
62 }
63 
64 int ViewModelBase::rowCount(const QModelIndex& parent) const
65 {
66  auto parent_item = itemFromIndex(parent);
67  return parent_item ? parent_item->rowCount() : rootItem()->rowCount();
68 }
69 
70 int ViewModelBase::columnCount(const QModelIndex& parent) const
71 {
72  auto parent_item = itemFromIndex(parent);
73  return parent_item ? parent_item->columnCount() : rootItem()->columnCount();
74 }
75 
76 QVariant ViewModelBase::data(const QModelIndex& index, int role) const
77 {
78  if (!rootItem())
79  return QVariant();
80 
81  auto item = itemFromIndex(index);
82  return item ? item->data(role) : QVariant();
83 }
84 
85 bool ViewModelBase::setData(const QModelIndex& index, const QVariant& value, int role)
86 {
87  if (!index.isValid())
88  return false;
89 
90  if (auto item = itemFromIndex(index); item) {
91  bool result = item->setData(value, role);
92  if (result)
93  dataChanged(index, index, QVector<int>() << role);
94  return result;
95  }
96 
97  return false;
98 }
99 
100 //! Returns a pointer to invisible root item.
101 
103 {
104  return p_impl->root.get();
105 }
106 
107 //! Returns a pointer to the RefViewItem associated with the given index.
108 //! If index is invalid, returns nullptr.
109 
110 ViewItem* ViewModelBase::itemFromIndex(const QModelIndex& index) const
111 {
112  return index.isValid() ? static_cast<ViewItem*>(index.internalPointer()) : nullptr;
113 }
114 
115 //! Returns the QModelIndex associated with the given item.
116 
117 QModelIndex ViewModelBase::indexFromItem(const ViewItem* item) const
118 {
119  return item && item->parent()
120  ? createIndex(item->row(), item->column(), const_cast<ViewItem*>(item))
121  : QModelIndex();
122 }
123 
124 void ViewModelBase::removeRow(ViewItem* parent, int row)
125 {
126  if (!p_impl->item_belongs_to_model(parent))
127  throw std::runtime_error(
128  "Error in ViewModelBase: attempt to use parent from another model");
129 
130  beginRemoveRows(indexFromItem(parent), row, row);
131  parent->removeRow(row);
132  endRemoveRows();
133 }
134 
136 {
137  if (!p_impl->item_belongs_to_model(parent))
138  throw std::runtime_error(
139  "Error in ViewModelBase: attempt to use parent from another model");
140 
141  if (!parent->rowCount())
142  return;
143 
144  beginRemoveRows(indexFromItem(parent), 0, parent->rowCount() - 1);
145  parent->clear();
146  endRemoveRows();
147 }
148 
149 //! Insert a row of items at index 'row' to given parent.
150 
151 void ViewModelBase::insertRow(ViewItem* parent, int row,
152  std::vector<std::unique_ptr<ViewItem>> items)
153 {
154  if (!p_impl->item_belongs_to_model(parent))
155  throw std::runtime_error(
156  "Error in ViewModelBase: attempt to use parent from another model");
157 
158  beginInsertRows(indexFromItem(parent), row, row);
159  parent->insertRow(row, std::move(items));
160  endInsertRows();
161 }
162 
163 //! Appends row of items to given parent.
164 
165 void ViewModelBase::appendRow(ViewItem* parent, std::vector<std::unique_ptr<ViewItem>> items)
166 {
167  insertRow(parent, parent->rowCount(), std::move(items));
168 }
169 
170 //! Returns the item flags for the given index.
171 
172 Qt::ItemFlags ViewModelBase::flags(const QModelIndex& index) const
173 {
174  Qt::ItemFlags result = QAbstractItemModel::flags(index);
175  if (auto item = itemFromIndex(index); item)
176  result |= item->flags();
177  return result;
178 }
179 
180 //! Sets new root item. Previous item will be deleted, model will be reset.
181 
182 void ViewModelBase::setRootViewItem(std::unique_ptr<ViewItem> root_item)
183 {
184  p_impl->root = std::move(root_item);
185 }
Represents the view of SessionItem's data in a single cell of ViewModel.
Definition: viewitem.h:29
int columnCount() const
Returns the number of child item columns that the item has.
Definition: viewitem.cpp:120
int row() const
Returns the row where the item is located in its parent's child table, or -1 if the item has no paren...
Definition: viewitem.cpp:181
int rowCount() const
Returns the number of child item rows that the item has.
Definition: viewitem.cpp:113
int column() const
Returns the column where the item is located in its parent's child table, or -1 if the item has no pa...
Definition: viewitem.cpp:190
ViewItem * parent() const
Definition: viewitem.cpp:158
Base class for all view models to show content of SessionModel in Qt views.
Definition: viewmodelbase.h:31
void removeRow(ViewItem *parent, int row)
void appendRow(ViewItem *parent, std::vector< std::unique_ptr< ViewItem >> items)
Appends row of items to given parent.
ViewItem * rootItem() const
Returns a pointer to invisible root item.
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
int rowCount(const QModelIndex &parent=QModelIndex()) const override
Qt::ItemFlags flags(const QModelIndex &index) const override
Returns the item flags for the given index.
void clearRows(ViewItem *parent)
ViewModelBase(QObject *parent=nullptr)
bool setData(const QModelIndex &index, const QVariant &value, int role) override
std::unique_ptr< ViewModelBaseImpl > p_impl
Definition: viewmodelbase.h:69
QModelIndex indexFromItem(const ViewItem *item) const
Returns the QModelIndex associated with the given item.
void insertRow(ViewItem *parent, int row, std::vector< std::unique_ptr< ViewItem >> items)
Insert a row of items at index 'row' to given parent.
QModelIndex parent(const QModelIndex &child) const override
void setRootViewItem(std::unique_ptr< ViewItem > root_item)
Sets new root item. Previous item will be deleted, model will be reset.
int columnCount(const QModelIndex &parent=QModelIndex()) const override
ViewItem * itemFromIndex(const QModelIndex &index) const
Returns a pointer to the RefViewItem associated with the given index.
materialitems.h Collection of materials to populate MaterialModel.
Definition: filesystem.h:81
Defines class CLASS?
Defines class CLASS?