KGantt

kganttforwardingproxymodel.cpp
1 /*
2  * SPDX-FileCopyrightText: 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved.
3  *
4  * This file is part of the KGantt library.
5  *
6  * SPDX-License-Identifier: GPL-2.0-or-later
7  */
8 
9 #include "kganttforwardingproxymodel.h"
10 
11 #include <cassert>
12 #include <QStringList>
13 
14 using namespace KGantt;
15 
17 
18 
19 ForwardingProxyModel::ForwardingProxyModel( QObject* parent )
20  : BASE( parent )
21 {
22 }
23 
24 ForwardingProxyModel::~ForwardingProxyModel()
25 {
26 }
27 
28 
29 QModelIndex ForwardingProxyModel::mapFromSource( const QModelIndex & sourceIndex ) const
30 {
31  if ( !sourceIndex.isValid() )
32  return QModelIndex();
33  assert( sourceIndex.model() == sourceModel() );
34 
35  // Create an index that preserves the internal pointer from the source;
36  // this way KDDataConverterProxyModel preserves the structure of the source model
37  return createIndex( sourceIndex.row(), sourceIndex.column(), sourceIndex.internalPointer() );
38 }
39 #ifdef __GNUC__
40 #if __GNUC__ > 3
41 #define ATTRIBUTE __attribute__((__may_alias__))
42 #endif
43 #else
44 #define ATTRIBUTE
45 #endif
46 namespace {
47  // Think this is ugly? Well, it's not from me, it comes from QProxyModel
48  struct ATTRIBUTE KDPrivateModelIndex {
49  int r, c;
50  void *p;
51  const QAbstractItemModel *m;
52  };
53 }
54 
55 
56 QModelIndex ForwardingProxyModel::mapToSource( const QModelIndex & proxyIndex ) const
57 {
58  if ( !proxyIndex.isValid() )
59  return QModelIndex();
60  assert( proxyIndex.model() == this );
61  // So here we need to create a source index which holds that internal pointer.
62  // No way to pass it to sourceModel()->index... so we have to do the ugly way:
63  QModelIndex sourceIndex;
64  KDPrivateModelIndex* hack = reinterpret_cast<KDPrivateModelIndex*>(&sourceIndex);
65  hack->r = proxyIndex.row();
66  hack->c = proxyIndex.column();
67  hack->p = proxyIndex.internalPointer();
68  hack->m = sourceModel();
69  assert( sourceIndex.isValid() );
70  return sourceIndex;
71 }
72 
73 
74 void ForwardingProxyModel::setSourceModel( QAbstractItemModel* model )
75 {
76  if ( sourceModel() ) sourceModel()->disconnect( this );
77  BASE::setSourceModel( model );
78 
79  if (!model) return;
80 
81  connect( model, SIGNAL(modelAboutToBeReset()), this, SLOT(sourceModelAboutToBeReset()) );
82  connect( model, SIGNAL(modelReset()), this, SLOT(sourceModelReset()) );
83  connect( model, SIGNAL(layoutAboutToBeChanged()), this, SLOT(sourceLayoutAboutToBeChanged()) );
84  connect( model, SIGNAL(layoutChanged()), this, SLOT(sourceLayoutChanged()) );
85 
86  connect( model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
87  this, SLOT(sourceDataChanged(QModelIndex,QModelIndex)) );
88 
89 
90  connect( model, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)),
91  this, SLOT(sourceColumnsAboutToBeInserted(QModelIndex,int,int)) );
92  connect( model, SIGNAL(columnsInserted(QModelIndex,int,int)),
93  this, SLOT(sourceColumnsInserted(QModelIndex,int,int)) );
94  connect( model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
95  this, SLOT(sourceColumnsAboutToBeRemoved(QModelIndex,int,int)) );
96  connect( model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
97  this, SLOT(sourceColumnsRemoved(QModelIndex,int,int)) );
98 
99  connect( model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
100  this, SLOT(sourceRowsAboutToBeInserted(QModelIndex,int,int)) );
101  connect( model, SIGNAL(rowsInserted(QModelIndex,int,int)),
102  this, SLOT(sourceRowsInserted(QModelIndex,int,int)) );
103  connect( model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
104  this, SLOT(sourceRowsAboutToBeRemoved(QModelIndex,int,int)) );
105  connect( model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
106  this, SLOT(sourceRowsRemoved(QModelIndex,int,int)) );
107 }
108 
109 
110 void ForwardingProxyModel::sourceModelAboutToBeReset()
111 {
112  // The matching signal is emitted be reset()
113 }
114 
115 
116 void ForwardingProxyModel::sourceModelReset()
117 {
118  //qDebug() << "ForwardingProxyModel::sourceModelReset()";
119  beginResetModel();
120  endResetModel();
121 }
122 
123 
124 
125 void ForwardingProxyModel::sourceLayoutAboutToBeChanged()
126 {
127  //qDebug() << "ForwardingProxyModel::sourceLayoutAboutToBeChanged()";
128  Q_EMIT layoutAboutToBeChanged();
129 }
130 
131 
132 void ForwardingProxyModel::sourceLayoutChanged()
133 {
134  //qDebug() << "ForwardingProxyModel::sourceLayoutChanged()";
135  beginResetModel();
136  endResetModel();
137 }
138 
139 
140 void ForwardingProxyModel::sourceDataChanged( const QModelIndex& from, const QModelIndex& to )
141 {
142  //qDebug() << "ForwardingProxyModel::sourceDataChanged("<<from<<to<<")";
143  Q_EMIT dataChanged( mapFromSource( from ), mapFromSource( to ) );
144 }
145 
146 
147 void ForwardingProxyModel::sourceColumnsAboutToBeInserted( const QModelIndex& parentIdx,
148  int start,
149  int end )
150 {
151  beginInsertColumns( mapFromSource( parentIdx ), start, end );
152 }
153 
154 
155 void ForwardingProxyModel::sourceColumnsInserted( const QModelIndex& parentIdx, int start, int end )
156 {
157  Q_UNUSED( parentIdx );
158  Q_UNUSED( start );
159  Q_UNUSED( end );
160  endInsertColumns();
161 }
162 
163 
164 void ForwardingProxyModel::sourceColumnsAboutToBeRemoved( const QModelIndex& parentIdx,
165  int start,
166  int end )
167 {
168  beginRemoveColumns( mapFromSource( parentIdx ), start, end );
169 }
170 
171 
172 void ForwardingProxyModel::sourceColumnsRemoved( const QModelIndex& parentIdx, int start, int end )
173 {
174  Q_UNUSED( parentIdx );
175  Q_UNUSED( start );
176  Q_UNUSED( end );
177  endRemoveColumns();
178 }
179 
180 
181 void ForwardingProxyModel::sourceRowsAboutToBeInserted( const QModelIndex & parentIdx, int start, int end )
182 {
183  beginInsertRows( mapFromSource( parentIdx ), start, end );
184 }
185 
186 
187 void ForwardingProxyModel::sourceRowsInserted( const QModelIndex& parentIdx, int start, int end )
188 {
189  Q_UNUSED( parentIdx );
190  Q_UNUSED( start );
191  Q_UNUSED( end );
192  endInsertRows();
193 }
194 
195 
196 void ForwardingProxyModel::sourceRowsAboutToBeRemoved( const QModelIndex & parentIdx, int start, int end )
197 {
198  beginRemoveRows( mapFromSource( parentIdx ), start, end );
199 }
200 
201 
202 void ForwardingProxyModel::sourceRowsRemoved( const QModelIndex& parentIdx, int start, int end )
203 {
204  Q_UNUSED( parentIdx );
205  Q_UNUSED( start );
206  Q_UNUSED( end );
207  endRemoveRows();
208 }
209 
210 
211 int ForwardingProxyModel::rowCount( const QModelIndex& idx ) const
212 {
213  return sourceModel()->rowCount( mapToSource( idx ) );
214 }
215 
216 
217 int ForwardingProxyModel::columnCount( const QModelIndex& idx ) const
218 {
219  return sourceModel()->columnCount( mapToSource( idx ) );
220 }
221 
222 
223 QModelIndex ForwardingProxyModel::index( int row, int column, const QModelIndex& parent ) const
224 {
225  return mapFromSource( sourceModel()->index( row, column, mapToSource( parent ) ) );
226 }
227 
228 
229 QModelIndex ForwardingProxyModel::parent( const QModelIndex& idx ) const
230 {
231  return mapFromSource( sourceModel()->parent( mapToSource( idx ) ) );
232 }
233 
234 
235 bool ForwardingProxyModel::setData( const QModelIndex& index, const QVariant& value, int role )
236 {
237  //qDebug() << "ForwardingProxyModel::setData( " << index<<value<< role<<")";
238  return sourceModel()->setData( mapToSource( index ), value, role );
239 }
240 
241 QMimeData *ForwardingProxyModel::mimeData(const QModelIndexList &indexes) const
242 {
243  QModelIndexList source_indexes;
244  for (int i = 0; i < indexes.count(); ++i)
245  source_indexes << mapToSource(indexes.at(i));
246  return sourceModel()->mimeData(source_indexes);
247 }
248 
249 bool ForwardingProxyModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
250 {
251  if ((row == -1) && (column == -1))
252  return sourceModel()->dropMimeData(data, action, -1, -1, mapToSource(parent));
253  int source_destination_row = -1;
254  int source_destination_column = -1;
255  QModelIndex source_parent;
256  if (row == rowCount(parent)) {
257  source_parent = mapToSource(parent);
258  source_destination_row = sourceModel()->rowCount(source_parent);
259  } else {
260  QModelIndex proxy_index = index(row, column, parent);
261  QModelIndex source_index = mapToSource(proxy_index);
262  source_destination_row = source_index.row();
263  source_destination_column = source_index.column();
264  source_parent = source_index.parent();
265  }
266  return sourceModel()->dropMimeData(data, action, source_destination_row, source_destination_column, source_parent);
267 }
268 
269 QStringList ForwardingProxyModel::mimeTypes() const
270 {
271  return sourceModel()->mimeTypes();
272 }
273 
274 Qt::DropActions ForwardingProxyModel::supportedDropActions() const
275 {
276  return sourceModel()->supportedDropActions();
277 }
278 
279 #include "moc_kganttforwardingproxymodel.cpp"
280 
bool isValid() const const
int row() const const
virtual void setSourceModel(QAbstractItemModel *sourceModel)
void * internalPointer() const const
Global namespace.
QModelIndex parent() const const
const QAbstractItemModel * model() const const
int column() const const
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const const
DropAction
Q_EMITQ_EMIT
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sun Dec 5 2021 22:32:42 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.