BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
ComponentProxyModel.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/coregui/Models/ComponentProxyModel.cpp
6 //! @brief Implements class ComponentProxyModel
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 
19 #include <QSet>
20 #include <functional>
21 
23  : QAbstractProxyModel(parent)
24  , m_model(nullptr)
25  // , m_proxyStrategy(new IndentityProxyStrategy)
26  , m_proxyStrategy(new ComponentProxyStrategy)
27 {
28 }
29 
31 {
32  beginResetModel();
33 
34  if (sourceModel()) {
35  disconnect(sourceModel(), &QAbstractItemModel::dataChanged, this,
37  disconnect(sourceModel(), &QAbstractItemModel::rowsInserted, this,
39  disconnect(sourceModel(), &QAbstractItemModel::rowsRemoved, this,
41  }
42 
43  QAbstractProxyModel::setSourceModel(model);
44 
45  if (sourceModel()) {
46  connect(sourceModel(), &QAbstractItemModel::dataChanged, this,
48  connect(sourceModel(), &QAbstractItemModel::rowsInserted, this,
50  connect(sourceModel(), &QAbstractItemModel::rowsRemoved, this,
52  }
53 
54  endResetModel();
55 
56  m_model = model;
57  buildModelMap();
58 }
59 
60 void ComponentProxyModel::setRootIndex(const QModelIndex& sourceRootIndex)
61 {
62  m_proxyStrategy->setRootIndex(sourceRootIndex);
63  buildModelMap();
64 }
65 
67 {
68  m_proxyStrategy.reset(strategy);
69  buildModelMap();
70 }
71 
72 QModelIndex ComponentProxyModel::mapToSource(const QModelIndex& proxyIndex) const
73 {
74  if (!proxyIndex.isValid())
75  return QModelIndex();
76 
77  return m_proxyStrategy->sourceToProxy().key(proxyIndex);
78 }
79 
80 QModelIndex ComponentProxyModel::mapFromSource(const QModelIndex& sourceIndex) const
81 {
82  if (!sourceIndex.isValid())
83  return QModelIndex();
84 
85  return m_proxyStrategy->sourceToProxy().value(sourceIndex);
86 }
87 
88 QModelIndex ComponentProxyModel::index(int row, int column, const QModelIndex& parent) const
89 {
90  QModelIndex sourceParent;
91  if (parent.isValid())
92  sourceParent = mapToSource(parent);
93 
94  QMapIterator<QPersistentModelIndex, QPersistentModelIndex> it(
95  m_proxyStrategy->proxySourceParent());
96  while (it.hasNext()) {
97  it.next();
98  if (it.value() == sourceParent && it.key().row() == row && it.key().column() == column)
99  return it.key();
100  }
101  return QModelIndex();
102 }
103 
104 QModelIndex ComponentProxyModel::parent(const QModelIndex& child) const
105 {
106  QModelIndex sourceParent = m_proxyStrategy->proxySourceParent().value(child);
107  if (sourceParent.isValid())
108  return mapFromSource(sourceParent);
109 
110  return QModelIndex();
111 }
112 
113 int ComponentProxyModel::rowCount(const QModelIndex& parent) const
114 {
115  QModelIndex sourceParent;
116  if (parent.isValid())
117  sourceParent = mapToSource(parent);
118  QMapIterator<QPersistentModelIndex, QPersistentModelIndex> it(
119  m_proxyStrategy->proxySourceParent());
120 
121  QSet<int> rows;
122  while (it.hasNext()) {
123  it.next();
124  if (it.value() == sourceParent)
125  rows.insert(it.key().row());
126  }
127  return rows.size();
128 }
129 
130 int ComponentProxyModel::columnCount(const QModelIndex& parent) const
131 {
132  if (parent.isValid() && parent.column() != 0)
133  return 0;
135 }
136 
137 bool ComponentProxyModel::hasChildren(const QModelIndex& parent) const
138 {
139  QModelIndex source_parent = mapToSource(parent);
140  if (parent.isValid() && !source_parent.isValid())
141  return false;
142 
143  return rowCount(parent) != 0;
144 }
145 
146 void ComponentProxyModel::sourceDataChanged(const QModelIndex& topLeft,
147  const QModelIndex& bottomRight,
148  const QVector<int>& roles)
149 {
150  ASSERT(topLeft.isValid() ? topLeft.model() == sourceModel() : true);
151  ASSERT(bottomRight.isValid() ? bottomRight.model() == sourceModel() : true);
152 
153  if (SessionItem* item = m_model->itemForIndex(topLeft)) {
154  if (item->modelType() == "GroupProperty")
155  updateModelMap();
156  }
157  dataChanged(mapFromSource(topLeft), mapFromSource(bottomRight), roles);
158 }
159 
160 void ComponentProxyModel::sourceRowsInserted(const QModelIndex& parent, int start, int end)
161 {
162  Q_UNUSED(parent);
163  Q_UNUSED(start);
164  Q_UNUSED(end);
165  buildModelMap();
166 }
167 
168 void ComponentProxyModel::sourceRowsRemoved(const QModelIndex& parent, int start, int end)
169 {
170  Q_UNUSED(parent);
171  Q_UNUSED(start);
172  Q_UNUSED(end);
173  buildModelMap();
174 }
175 
176 //! Main method to build the map of persistent indeses.
177 
179 {
180  if (!m_model)
181  return;
182  m_proxyStrategy->buildModelMap(m_model, this);
183  layoutChanged();
184 }
185 
187 {
188  m_proxyStrategy->onDataChanged(m_model, this);
189 }
#define ASSERT(condition)
Definition: Assert.h:31
Defines class ComponentProxyModel.
Defines class ComponentProxyStrategy.
Defines ModelUtils namespace.
Defines class SessionModel.
ComponentProxyModel(QObject *parent=nullptr)
std::unique_ptr< ProxyModelStrategy > m_proxyStrategy
int rowCount(const QModelIndex &parent={}) const
QModelIndex index(int row, int column, const QModelIndex &parent={}) const
void setRootIndex(const QModelIndex &sourceRootIndex)
void setProxyStrategy(ProxyModelStrategy *strategy)
QModelIndex parent(const QModelIndex &child) const
bool hasChildren(const QModelIndex &parent) const
void buildModelMap()
Main method to build the map of persistent indeses.
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const
void sourceRowsRemoved(const QModelIndex &parent, int start, int end)
int columnCount(const QModelIndex &parent={}) const
QModelIndex mapToSource(const QModelIndex &proxyIndex) const
void setSessionModel(SessionModel *model)
void sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector< int > &roles={})
void sourceRowsInserted(const QModelIndex &parent, int start, int end)
Strategy for ComponentProxyModel which hides extra level of GroupProperty.
Base class for proxy strategies in ComponentProxyModel.
SessionItem * itemForIndex(const QModelIndex &index) const