From e190d576540cf5dfb2e63d33a69662083f3db210 Mon Sep 17 00:00:00 2001 From: Marcus Eggenberger Date: Wed, 16 Apr 2008 20:59:59 +0000 Subject: [PATCH] merging branches/fu-debug with trunk :) --- src/client/buffermodel.cpp | 19 +-- src/client/buffermodel.h | 8 +- src/client/mappedselectionmodel.cpp | 103 ++++++--------- src/client/mappedselectionmodel.h | 22 ---- src/client/selectionmodelsynchronizer.cpp | 145 +++++++++++++++------- src/client/selectionmodelsynchronizer.h | 36 ++++-- src/uisupport/bufferviewfilter.cpp | 3 +- 7 files changed, 175 insertions(+), 161 deletions(-) diff --git a/src/client/buffermodel.cpp b/src/client/buffermodel.cpp index 52d6d54c..3dfdc6da 100644 --- a/src/client/buffermodel.cpp +++ b/src/client/buffermodel.cpp @@ -27,14 +27,9 @@ 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 { @@ -65,6 +60,14 @@ QModelIndex BufferModel::currentIndex() { } 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 << ")"; } diff --git a/src/client/buffermodel.h b/src/client/buffermodel.h index 0be559aa..3126f737 100644 --- a/src/client/buffermodel.h +++ b/src/client/buffermodel.h @@ -36,12 +36,11 @@ class BufferModel : public QSortFilterProxyModel { 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(&_standardSelectionModel); } + inline QItemSelectionModel *standardSelectionModel() const { return _selectionModelSynchronizer.selectionModel(); } void synchronizeSelectionModel(MappedSelectionModel *selectionModel); void synchronizeView(QAbstractItemView *view); @@ -49,9 +48,12 @@ public: 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 diff --git a/src/client/mappedselectionmodel.cpp b/src/client/mappedselectionmodel.cpp index 99b1e4fd..84cd9fe0 100644 --- a/src/client/mappedselectionmodel.cpp +++ b/src/client/mappedselectionmodel.cpp @@ -23,89 +23,60 @@ #include #include #include +#include #include 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(model()); } QModelIndex MappedSelectionModel::mapFromSource(const QModelIndex &sourceIndex) { - if(isProxyModel()) - return proxyModel()->mapFromSource(sourceIndex); - else - return sourceIndex; + QModelIndex proxyIndex = sourceIndex; + QLinkedList proxies; + const QAbstractItemModel *baseModel = model(); + const QAbstractProxyModel *proxyModel = 0; + while((proxyModel = qobject_cast(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 proxies; + const QAbstractItemModel *baseModel = model(); + const QAbstractProxyModel *proxyModel = 0; + while((proxyModel = qobject_cast(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); } diff --git a/src/client/mappedselectionmodel.h b/src/client/mappedselectionmodel.h index a59ea253..9641658a 100644 --- a/src/client/mappedselectionmodel.h +++ b/src/client/mappedselectionmodel.h @@ -33,35 +33,13 @@ class MappedSelectionModel : public QItemSelectionModel { 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 diff --git a/src/client/selectionmodelsynchronizer.cpp b/src/client/selectionmodelsynchronizer.cpp index 169fddcd..d533ea4a 100644 --- a/src/client/selectionmodelsynchronizer.cpp +++ b/src/client/selectionmodelsynchronizer.cpp @@ -23,78 +23,129 @@ #include #include "mappedselectionmodel.h" +#include #include 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(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(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(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(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(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(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(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); } diff --git a/src/client/selectionmodelsynchronizer.h b/src/client/selectionmodelsynchronizer.h index 5cda9cce..2e153b65 100644 --- a/src/client/selectionmodelsynchronizer.h +++ b/src/client/selectionmodelsynchronizer.h @@ -25,34 +25,44 @@ #include 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(&_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 diff --git a/src/uisupport/bufferviewfilter.cpp b/src/uisupport/bufferviewfilter.cpp index 1245579b..fa293581 100644 --- a/src/uisupport/bufferviewfilter.cpp +++ b/src/uisupport/bufferviewfilter.cpp @@ -39,7 +39,6 @@ BufferViewFilter::BufferViewFilter(QAbstractItemModel *model, BufferViewConfig * setSourceModel(model); connect(model, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(source_rowsInserted(const QModelIndex &, int, int))); - // setSortCaseSensitivity(Qt::CaseInsensitive); setDynamicSortFilter(true); } @@ -116,7 +115,7 @@ bool BufferViewFilter::dropMimeData(const QMimeData *data, Qt::DropAction action } void BufferViewFilter::addBuffer(const BufferId &bufferId) { - if(config()->bufferList().contains(bufferId)) + if(!config() || config()->bufferList().contains(bufferId)) return; int pos = config()->bufferList().count(); -- 2.20.1