24 #include <QtCore/QAbstractItemModel>
25 #include <QtCore/QWeakPointer>
26 #include <QtGui/QAbstractProxyModel>
27 #include <QtGui/QItemSelectionModel>
31 class KModelIndexProxyMapperPrivate
34 : q_ptr(qq), m_leftModel(leftModel), m_rightModel(rightModel)
39 void createProxyChain();
42 bool assertSelectionValid(
const QItemSelection &selection)
const {
43 foreach(
const QItemSelectionRange &range, selection) {
44 if (!range.isValid()) {
45 kDebug() << selection << m_leftModel << m_rightModel << m_proxyChainDown << m_proxyChainUp;
47 Q_ASSERT(range.isValid());
99 void KModelIndexProxyMapperPrivate::createProxyChain()
101 QWeakPointer<const QAbstractItemModel> targetModel = m_rightModel;
106 if (m_leftModel == targetModel)
110 QWeakPointer<const QAbstractProxyModel> selectionTargetProxyModel = qobject_cast<
const QAbstractProxyModel*>(targetModel.data());
111 while( selectionTargetProxyModel )
113 proxyChainDown.prepend( selectionTargetProxyModel );
115 selectionTargetProxyModel = qobject_cast<
const QAbstractProxyModel*>(selectionTargetProxyModel.data()->sourceModel());
117 if (selectionTargetProxyModel.data() == m_leftModel.data())
119 m_proxyChainDown = proxyChainDown;
124 QWeakPointer<const QAbstractItemModel> sourceModel = m_leftModel;
125 QWeakPointer<const QAbstractProxyModel> sourceProxyModel = qobject_cast<
const QAbstractProxyModel*>(sourceModel.data());
127 while(sourceProxyModel)
129 m_proxyChainUp.append(sourceProxyModel);
131 sourceProxyModel = qobject_cast<
const QAbstractProxyModel*>(sourceProxyModel.data()->sourceModel());
133 const int targetIndex = proxyChainDown.indexOf(sourceProxyModel);
135 if (targetIndex != -1)
137 m_proxyChainDown = proxyChainDown.mid(targetIndex + 1, proxyChainDown.size());
141 m_proxyChainDown = proxyChainDown;
142 Q_ASSERT(assertValid());
145 bool KModelIndexProxyMapperPrivate::assertValid()
147 if ( m_proxyChainDown.isEmpty())
149 Q_ASSERT( !m_proxyChainUp.isEmpty() );
150 Q_ASSERT( m_proxyChainUp.last().data()->sourceModel() == m_rightModel.data() );
152 else if ( m_proxyChainUp.isEmpty())
154 Q_ASSERT( !m_proxyChainDown.isEmpty() );
155 Q_ASSERT( m_proxyChainDown.first().data()->sourceModel() == m_leftModel.data() );
157 Q_ASSERT( m_proxyChainDown.first().data()->sourceModel() == m_proxyChainUp.last().data()->sourceModel() );
163 :
QObject(parent), d_ptr( new KModelIndexProxyMapperPrivate(leftModel, rightModel, this) )
176 if (selection.isEmpty())
177 return QModelIndex();
179 return selection.indexes().first();
185 if (selection.isEmpty())
186 return QModelIndex();
188 return selection.indexes().first();
195 #if QT_VERSION < 0x040702
196 #define RANGE_FIX_HACK
199 #ifdef RANGE_FIX_HACK
202 QItemSelection result;
203 Q_FOREACH(
const QItemSelectionRange &range, selection)
205 if (!range.isValid())
217 if (selection.isEmpty())
218 return QItemSelection();
220 if (selection.first().model() != d->m_leftModel.data())
221 kDebug() <<
"FAIL" << selection.first().model() << d->m_leftModel.data() << d->m_rightModel.data();
222 Q_ASSERT(selection.first().model() == d->m_leftModel.data());
224 QItemSelection seekSelection = selection;
225 Q_ASSERT(d->assertSelectionValid(seekSelection));
226 QListIterator<QWeakPointer<const QAbstractProxyModel> > iUp(d->m_proxyChainUp);
228 while (iUp.hasNext())
230 const QWeakPointer<const QAbstractProxyModel> proxy = iUp.next();
232 return QItemSelection();
233 seekSelection = proxy.data()->mapSelectionToSource(seekSelection);
235 #ifdef RANGE_FIX_HACK
238 Q_ASSERT(d->assertSelectionValid(seekSelection));
241 QListIterator<QWeakPointer<const QAbstractProxyModel> > iDown(d->m_proxyChainDown);
243 while (iDown.hasNext())
245 const QWeakPointer<const QAbstractProxyModel> proxy = iDown.next();
247 return QItemSelection();
248 seekSelection = proxy.data()->mapSelectionFromSource(seekSelection);
250 #ifdef RANGE_FIX_HACK
253 Q_ASSERT(d->assertSelectionValid(seekSelection));
256 Q_ASSERT( ( !seekSelection.isEmpty() && seekSelection.first().model() == d->m_rightModel.data() ) ||
true );
257 return seekSelection;
264 if (selection.isEmpty())
265 return QItemSelection();
267 if (selection.first().model() != d->m_rightModel.data())
268 kDebug() <<
"FAIL" << selection.first().model() << d->m_leftModel.data() << d->m_rightModel.data();
269 Q_ASSERT(selection.first().model() == d->m_rightModel.data());
271 QItemSelection seekSelection = selection;
272 Q_ASSERT(d->assertSelectionValid(seekSelection));
273 QListIterator<QWeakPointer<const QAbstractProxyModel> > iDown(d->m_proxyChainDown);
276 while (iDown.hasPrevious())
278 const QWeakPointer<const QAbstractProxyModel> proxy = iDown.previous();
280 return QItemSelection();
281 seekSelection = proxy.data()->mapSelectionToSource(seekSelection);
283 #ifdef RANGE_FIX_HACK
286 Q_ASSERT(d->assertSelectionValid(seekSelection));
289 QListIterator<QWeakPointer<const QAbstractProxyModel> > iUp(d->m_proxyChainUp);
292 while (iUp.hasPrevious())
294 const QWeakPointer<const QAbstractProxyModel> proxy = iUp.previous();
296 return QItemSelection();
297 seekSelection = proxy.data()->mapSelectionFromSource(seekSelection);
299 #ifdef RANGE_FIX_HACK
302 Q_ASSERT(d->assertSelectionValid(seekSelection));
305 Q_ASSERT( ( !seekSelection.isEmpty() && seekSelection.first().model() == d->m_leftModel.data() ) ||
true );
306 return seekSelection;
309 #include "kmodelindexproxymapper.moc"