BufferModel::BufferModel(NetworkModel *parent)
: QSortFilterProxyModel(parent),
- _selectionModelSynchronizer(this),
- _standardSelectionModel(this)
+ _selectionModelSynchronizer(this)
{
setSourceModel(parent);
- _selectionModelSynchronizer.addRegularSelectionModel(standardSelectionModel());
-}
-
-BufferModel::~BufferModel() {
}
bool BufferModel::filterAcceptsRow(int sourceRow, const QModelIndex &parent) const {
}
void BufferModel::setCurrentIndex(const QModelIndex &newCurrent) {
- _standardSelectionModel.setCurrentIndex(newCurrent, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
- _standardSelectionModel.select(newCurrent, QItemSelectionModel::ClearAndSelect);
+ _selectionModelSynchronizer.selectionModel()->setCurrentIndex(newCurrent, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
+ _selectionModelSynchronizer.selectionModel()->select(newCurrent, QItemSelectionModel::Current);
+}
+
+void BufferModel::debug_currentChanged(QModelIndex current, QModelIndex previous) {
+ qDebug() << "New current:" << current << "(previous:" << previous << ")";
+}
+
+void BufferModel::debug_selectionChanged(QItemSelection current , QItemSelection previous) {
+ qDebug() << "new selection:" << current << "(previoius:" << previous << ")";
}
public:
BufferModel(NetworkModel *parent = 0);
- virtual ~BufferModel();
bool filterAcceptsRow(int sourceRow, const QModelIndex &parent) const;
inline const SelectionModelSynchronizer *selectionModelSynchronizer() const { return &_selectionModelSynchronizer; }
- inline QItemSelectionModel *standardSelectionModel() const { return const_cast<QItemSelectionModel *>(&_standardSelectionModel); }
+ inline QItemSelectionModel *standardSelectionModel() const { return _selectionModelSynchronizer.selectionModel(); }
void synchronizeSelectionModel(MappedSelectionModel *selectionModel);
void synchronizeView(QAbstractItemView *view);
QModelIndex currentIndex();
void setCurrentIndex(const QModelIndex &newCurrent);
+private slots:
+ void debug_currentChanged(QModelIndex current, QModelIndex previous);
+ void debug_selectionChanged(QItemSelection current , QItemSelection previous);
+
private:
SelectionModelSynchronizer _selectionModelSynchronizer;
- QItemSelectionModel _standardSelectionModel;
};
#endif // BUFFERMODEL_H
#include <QItemSelectionModel>
#include <QAbstractItemModel>
#include <QAbstractProxyModel>
+#include <QLinkedList>
#include <QDebug>
MappedSelectionModel::MappedSelectionModel(QAbstractItemModel *model)
: QItemSelectionModel(model)
{
- _isProxyModel = (bool)proxyModel();
- connect(this, SIGNAL(currentChanged(QModelIndex, QModelIndex)),
- this, SLOT(_currentChanged(QModelIndex, QModelIndex)));
- connect(this, SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
- this, SLOT(_selectionChanged(QItemSelection, QItemSelection)));
-}
-
-MappedSelectionModel::~MappedSelectionModel() {
-}
-
-const QAbstractItemModel *MappedSelectionModel::baseModel() const {
- if(isProxyModel())
- return proxyModel()->sourceModel();
- else
- return model();
-}
-
-const QAbstractProxyModel *MappedSelectionModel::proxyModel() const {
- return qobject_cast<const QAbstractProxyModel *>(model());
}
QModelIndex MappedSelectionModel::mapFromSource(const QModelIndex &sourceIndex) {
- if(isProxyModel())
- return proxyModel()->mapFromSource(sourceIndex);
- else
- return sourceIndex;
+ QModelIndex proxyIndex = sourceIndex;
+ QLinkedList<const QAbstractProxyModel *> proxies;
+ const QAbstractItemModel *baseModel = model();
+ const QAbstractProxyModel *proxyModel = 0;
+ while((proxyModel = qobject_cast<const QAbstractProxyModel *>(baseModel)) != 0) {
+ proxies.push_back(proxyModel);
+ baseModel = proxyModel->sourceModel();
+ if(baseModel == sourceIndex.model())
+ break;
+ }
+
+ while(!proxies.isEmpty()) {
+ proxyModel = proxies.takeLast();
+ proxyIndex = proxyModel->mapFromSource(proxyIndex);
+ }
+ return proxyIndex;
}
QItemSelection MappedSelectionModel::mapSelectionFromSource(const QItemSelection &sourceSelection) {
- if(isProxyModel())
- return proxyModel()->mapSelectionFromSource(sourceSelection);
- else
+ if(sourceSelection.isEmpty())
return sourceSelection;
-}
-
-QModelIndex MappedSelectionModel::mapToSource(const QModelIndex &proxyIndex) {
- if(isProxyModel())
- return proxyModel()->mapToSource(proxyIndex);
- else
- return proxyIndex;
-}
-QItemSelection MappedSelectionModel::mapSelectionToSource(const QItemSelection &proxySelection) {
- if(isProxyModel())
- return proxyModel()->mapSelectionToSource(proxySelection);
- else
- return proxySelection;
-}
-
-void MappedSelectionModel::mappedSelect(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) {
- QModelIndex mappedIndex = mapFromSource(index);
- if(!isSelected(mappedIndex))
- select(mappedIndex, command);
-}
+ QItemSelection proxySelection = sourceSelection;
+ QLinkedList<const QAbstractProxyModel *> proxies;
+ const QAbstractItemModel *baseModel = model();
+ const QAbstractProxyModel *proxyModel = 0;
+ while((proxyModel = qobject_cast<const QAbstractProxyModel *>(baseModel)) != 0) {
+ proxies.push_back(proxyModel);
+ baseModel = proxyModel->sourceModel();
+ if(baseModel == sourceSelection.first().model())
+ break;
+ }
-void MappedSelectionModel::mappedSelect(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) {
- QItemSelection mappedSelection = mapSelectionFromSource(selection);
- if(mappedSelection != QItemSelectionModel::selection())
- select(mappedSelection, command);
+ while(!proxies.isEmpty()) {
+ proxyModel = proxies.takeLast();
+ proxySelection = proxyModel->mapSelectionFromSource(proxySelection);
+ }
+ return proxySelection;
}
-
+
void MappedSelectionModel::mappedSetCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) {
- QModelIndex mappedIndex = mapFromSource(index);
- if(mappedIndex == currentIndex())
- return;
- setCurrentIndex(mappedIndex, command);
+ setCurrentIndex(mapFromSource(index), command);
}
-
-void MappedSelectionModel::_currentChanged(const QModelIndex ¤t, const QModelIndex &previous) {
- Q_UNUSED(previous)
- if(current.isValid())
- emit mappedCurrentChanged(mapToSource(current));
-}
-
-void MappedSelectionModel::_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) {
- Q_UNUSED(selected)
- Q_UNUSED(deselected)
- emit mappedSelectionChanged(mapSelectionToSource(QItemSelectionModel::selection()));
+void MappedSelectionModel::mappedSelect(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) {
+ select(mapSelectionFromSource(selection), command);
}
public:
MappedSelectionModel(QAbstractItemModel *model = 0);
- virtual ~MappedSelectionModel();
- inline bool isProxyModel() const { return _isProxyModel; }
-
- const QAbstractItemModel *baseModel() const;
- const QAbstractProxyModel *proxyModel() const;
-
QModelIndex mapFromSource(const QModelIndex &sourceIndex);
QItemSelection mapSelectionFromSource(const QItemSelection &sourceSelection);
-
- QModelIndex mapToSource(const QModelIndex &proxyIndex);
- QItemSelection mapSelectionToSource(const QItemSelection &proxySelection);
public slots:
- void mappedSelect(const QModelIndex &index, QItemSelectionModel::SelectionFlags command);
void mappedSelect(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command);
void mappedSetCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags command);
-
-private slots:
- void _currentChanged(const QModelIndex ¤t, const QModelIndex &previous);
- void _selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
-
-signals:
- void mappedCurrentChanged(const QModelIndex ¤t);
- void mappedSelectionChanged(const QItemSelection &selected);
-
-private:
- bool _isProxyModel;
-
};
#endif
#include <QAbstractItemModel>
#include "mappedselectionmodel.h"
+#include <QAbstractProxyModel>
#include <QDebug>
SelectionModelSynchronizer::SelectionModelSynchronizer(QAbstractItemModel *parent)
: QObject(parent),
- _model(parent)
+ _model(parent),
+ _selectionModel(parent)
{
+ connect(&_selectionModel, SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
+ this, SLOT(currentChanged(const QModelIndex &, const QModelIndex &)));
+ connect(&_selectionModel, SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
+ this, SLOT(selectionChanged(const QItemSelection &, const QItemSelection &)));
}
-SelectionModelSynchronizer::~SelectionModelSynchronizer() {
-}
+bool SelectionModelSynchronizer::checkBaseModel(QItemSelectionModel *selectionModel) {
+ if(!selectionModel)
+ return false;
-void SelectionModelSynchronizer::addSelectionModel(MappedSelectionModel *selectionmodel) {
- if(selectionmodel->model() == model()) {
- addRegularSelectionModel(selectionmodel);
- return;
+ const QAbstractItemModel *baseModel = selectionModel->model();
+ const QAbstractProxyModel *proxyModel = 0;
+ while((proxyModel = qobject_cast<const QAbstractProxyModel *>(baseModel)) != 0) {
+ baseModel = proxyModel->sourceModel();
+ if(baseModel == model())
+ break;
}
-
- if(selectionmodel->baseModel() != model()) {
- qWarning() << "cannot Syncronize SelectionModel" << selectionmodel << "which has a different baseModel()";
+ return baseModel == model();
+}
+
+void SelectionModelSynchronizer::addSelectionModel(QItemSelectionModel *selectionModel) {
+ if(!checkBaseModel(selectionModel)) {
+ qWarning() << "cannot Syncronize SelectionModel" << selectionModel << "which has a different baseModel()";
return;
}
- connect(selectionmodel, SIGNAL(mappedCurrentChanged(QModelIndex)),
- this, SLOT(_mappedCurrentChanged(QModelIndex)));
- connect(selectionmodel, SIGNAL(mappedSelectionChanged(QItemSelection)),
- this, SLOT(_mappedSelectionChanged(QItemSelection)));
-
- connect(this, SIGNAL(setCurrentIndex(QModelIndex, QItemSelectionModel::SelectionFlags)),
- selectionmodel, SLOT(mappedSetCurrentIndex(QModelIndex, QItemSelectionModel::SelectionFlags)));
- connect(this, SIGNAL(select(QItemSelection, QItemSelectionModel::SelectionFlags)),
- selectionmodel, SLOT(mappedSelect(QItemSelection, QItemSelectionModel::SelectionFlags)));
-}
+ connect(selectionModel, SIGNAL(currentChanged(QModelIndex, QModelIndex)),
+ this, SLOT(mappedCurrentChanged(QModelIndex, QModelIndex)));
+ connect(selectionModel, SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
+ this, SLOT(mappedSelectionChanged(QItemSelection, QItemSelection)));
-void SelectionModelSynchronizer::addRegularSelectionModel(QItemSelectionModel *selectionmodel) {
- if(selectionmodel->model() != model()) {
- qWarning() << "cannot Syncronize QItemSelectionModel" << selectionmodel << "which has a different model()";
- return;
+ if(qobject_cast<MappedSelectionModel *>(selectionModel)) {
+ connect(this, SIGNAL(setCurrentIndex(QModelIndex, QItemSelectionModel::SelectionFlags)),
+ selectionModel, SLOT(mappedSetCurrentIndex(QModelIndex, QItemSelectionModel::SelectionFlags)));
+ connect(this, SIGNAL(select(QItemSelection, QItemSelectionModel::SelectionFlags)),
+ selectionModel, SLOT(mappedSelect(QItemSelection, QItemSelectionModel::SelectionFlags)));
+ } else {
+ connect(this, SIGNAL(setCurrentIndex(QModelIndex, QItemSelectionModel::SelectionFlags)),
+ selectionModel, SLOT(setCurrentIndex(QModelIndex, QItemSelectionModel::SelectionFlags)));
+ connect(this, SIGNAL(select(QItemSelection, QItemSelectionModel::SelectionFlags)),
+ selectionModel, SLOT(select(QItemSelection, QItemSelectionModel::SelectionFlags)));
}
- connect(selectionmodel, SIGNAL(currentChanged(QModelIndex, QModelIndex)),
- this, SLOT(_regularCurrentChanged(QModelIndex, QModelIndex)));
- connect(selectionmodel, SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
- this, SLOT(_regularSelectionChanged(QItemSelection, QItemSelection)));
-
- connect(this, SIGNAL(setCurrentIndex(QModelIndex, QItemSelectionModel::SelectionFlags)),
- selectionmodel, SLOT(setCurrentIndex(QModelIndex, QItemSelectionModel::SelectionFlags)));
- connect(this, SIGNAL(select(QItemSelection, QItemSelectionModel::SelectionFlags)),
- selectionmodel, SLOT(select(QItemSelection, QItemSelectionModel::SelectionFlags)));
-
}
-void SelectionModelSynchronizer::removeSelectionModel(MappedSelectionModel *model) {
+void SelectionModelSynchronizer::removeSelectionModel(QItemSelectionModel *model) {
disconnect(model, 0, this, 0);
disconnect(this, 0, model, 0);
}
-void SelectionModelSynchronizer::_mappedCurrentChanged(const QModelIndex ¤t) {
- emit setCurrentIndex(current, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
+void SelectionModelSynchronizer::mappedCurrentChanged(const QModelIndex ¤t, const QModelIndex &previous) {
+ Q_UNUSED(previous);
+ QItemSelectionModel *selectionModel = qobject_cast<QItemSelectionModel *>(sender());
+ Q_ASSERT(selectionModel);
+ QModelIndex newSourceCurrent = mapToSource(current, selectionModel);
+ if(newSourceCurrent.isValid() && newSourceCurrent != currentIndex())
+ setCurrentIndex(newSourceCurrent);
+}
+
+void SelectionModelSynchronizer::mappedSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected) {
+ Q_UNUSED(selected);
+ Q_UNUSED(deselected);
+ QItemSelectionModel *selectionModel = qobject_cast<QItemSelectionModel *>(sender());
+ Q_ASSERT(selectionModel);
+ QItemSelection newSourceSelection = mapSelectionToSource(selectionModel->selection(), selectionModel);
+ QItemSelection currentContainsSelection = newSourceSelection;
+ currentContainsSelection.merge(currentSelection(), QItemSelectionModel::Deselect);
+ if(!currentContainsSelection.isEmpty())
+ setCurrentSelection(newSourceSelection);
+}
+
+QModelIndex SelectionModelSynchronizer::mapToSource(const QModelIndex &index, QItemSelectionModel *selectionModel) {
+ Q_ASSERT(selectionModel);
+
+ QModelIndex sourceIndex = index;
+ const QAbstractItemModel *baseModel = selectionModel->model();
+ const QAbstractProxyModel *proxyModel = 0;
+ while((proxyModel = qobject_cast<const QAbstractProxyModel *>(baseModel)) != 0) {
+ sourceIndex = proxyModel->mapToSource(sourceIndex);
+ baseModel = proxyModel->sourceModel();
+ if(baseModel == model())
+ break;
+ }
+ return sourceIndex;
+}
+
+QItemSelection SelectionModelSynchronizer::mapSelectionToSource(const QItemSelection &selection, QItemSelectionModel *selectionModel) {
+ Q_ASSERT(selectionModel);
+
+ QItemSelection sourceSelection = selection;
+ const QAbstractItemModel *baseModel = selectionModel->model();
+ const QAbstractProxyModel *proxyModel = 0;
+ while((proxyModel = qobject_cast<const QAbstractProxyModel *>(baseModel)) != 0) {
+ sourceSelection = proxyModel->mapSelectionToSource(sourceSelection);
+ baseModel = proxyModel->sourceModel();
+ if(baseModel == model())
+ break;
+ }
+ return sourceSelection;
}
-void SelectionModelSynchronizer::_mappedSelectionChanged(const QItemSelection &selected) {
- emit select(selected, QItemSelectionModel::ClearAndSelect);
+void SelectionModelSynchronizer::setCurrentIndex(const QModelIndex &index) {
+ _selectionModel.setCurrentIndex(index, QItemSelectionModel::Current);
+}
+void SelectionModelSynchronizer::setCurrentSelection(const QItemSelection &selection) {
+ _selectionModel.select(selection, QItemSelectionModel::Rows | QItemSelectionModel::ClearAndSelect);
}
-void SelectionModelSynchronizer::_regularCurrentChanged(const QModelIndex &newCurrent, const QModelIndex &oldCurrent) {
- Q_UNUSED(oldCurrent)
- emit setCurrentIndex(newCurrent, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
+void SelectionModelSynchronizer::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) {
+ Q_UNUSED(previous);
+ emit setCurrentIndex(current, QItemSelectionModel::Current);
}
-void SelectionModelSynchronizer::_regularSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected) {
- Q_UNUSED(selected)
- Q_UNUSED(deselected)
- QItemSelectionModel *selectionModel = qobject_cast<QItemSelectionModel *>(sender());
- emit select(selectionModel->selection(), QItemSelectionModel::ClearAndSelect);
+void SelectionModelSynchronizer::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) {
+ Q_UNUSED(selected);
+ Q_UNUSED(deselected);
+ emit select(_selectionModel.selection(), QItemSelectionModel::ClearAndSelect);
}
#include <QItemSelectionModel>
class QAbstractItemModel;
-class MappedSelectionModel;
class SelectionModelSynchronizer : public QObject {
Q_OBJECT
public:
SelectionModelSynchronizer(QAbstractItemModel *parent = 0);
- virtual ~SelectionModelSynchronizer();
- void addSelectionModel(MappedSelectionModel *model);
- void addRegularSelectionModel(QItemSelectionModel *model);
- void removeSelectionModel(MappedSelectionModel *model);
+ void addSelectionModel(QItemSelectionModel *selectionModel);
+ void removeSelectionModel(QItemSelectionModel *selectionModel);
inline QAbstractItemModel *model() { return _model; }
+ inline QItemSelectionModel *selectionModel() const { return const_cast<QItemSelectionModel *>(&_selectionModel); }
+ inline QModelIndex currentIndex() const { return _selectionModel.currentIndex(); }
+ inline QItemSelection currentSelection() const { return _selectionModel.selection(); }
+
+signals:
+ void setCurrentIndex(const QModelIndex ¤t, QItemSelectionModel::SelectionFlags command);
+ void select(const QItemSelection &selected, QItemSelectionModel::SelectionFlags command);
private slots:
- void _mappedCurrentChanged(const QModelIndex ¤t);
- void _mappedSelectionChanged(const QItemSelection &selected);
+ void mappedCurrentChanged(const QModelIndex ¤t, const QModelIndex &previous);
+ void mappedSelectionChanged(const QItemSelection &selected, const QItemSelection &previous);
- void _regularCurrentChanged(const QModelIndex &newCurrent, const QModelIndex &oldCurrent);
- void _regularSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
+ void setCurrentIndex(const QModelIndex &index);
+ void setCurrentSelection(const QItemSelection &selection);
+
+ void currentChanged(const QModelIndex ¤t, const QModelIndex &previous);
+ void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
-signals:
- void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command);
- void setCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags command);
-
private:
QAbstractItemModel *_model;
+ QItemSelectionModel _selectionModel;
+
+ bool checkBaseModel(QItemSelectionModel *model);
+ QModelIndex mapToSource(const QModelIndex &index, QItemSelectionModel *selectionModel);
+ QItemSelection mapSelectionToSource(const QItemSelection &selection, QItemSelectionModel *selectionModel);
+
+
};
#endif
setSourceModel(model);
connect(model, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(source_rowsInserted(const QModelIndex &, int, int)));
- // setSortCaseSensitivity(Qt::CaseInsensitive);
setDynamicSortFilter(true);
}
}
void BufferViewFilter::addBuffer(const BufferId &bufferId) {
- if(config()->bufferList().contains(bufferId))
+ if(!config() || config()->bufferList().contains(bufferId))
return;
int pos = config()->bufferList().count();