#include <QAbstractItemView>
#include "client.h"
-#include "mappedselectionmodel.h"
#include "networkmodel.h"
#include "quassel.h"
return false;
}
-void BufferModel::synchronizeSelectionModel(MappedSelectionModel *selectionModel) {
- _selectionModelSynchronizer.addSelectionModel(selectionModel);
-}
-
void BufferModel::synchronizeView(QAbstractItemView *view) {
- MappedSelectionModel *mappedSelectionModel = new MappedSelectionModel(view->model());
- _selectionModelSynchronizer.addSelectionModel(mappedSelectionModel);
- Q_ASSERT(mappedSelectionModel);
- delete view->selectionModel();
- view->setSelectionModel(mappedSelectionModel);
+ _selectionModelSynchronizer.synchronizeSelectionModel(view->selectionModel());
}
void BufferModel::setCurrentIndex(const QModelIndex &newCurrent) {
#include "selectionmodelsynchronizer.h"
class NetworkModel;
-class MappedSelectionModel;
class QAbstractItemView;
class BufferModel : public QSortFilterProxyModel {
inline const SelectionModelSynchronizer *selectionModelSynchronizer() const { return &_selectionModelSynchronizer; }
inline QItemSelectionModel *standardSelectionModel() const { return _selectionModelSynchronizer.selectionModel(); }
- void synchronizeSelectionModel(MappedSelectionModel *selectionModel);
+ inline void synchronizeSelectionModel(QItemSelectionModel *selectionModel) { _selectionModelSynchronizer.synchronizeSelectionModel(selectionModel); }
void synchronizeView(QAbstractItemView *view);
inline QModelIndex currentIndex() { return standardSelectionModel()->currentIndex(); }
+++ /dev/null
-/***************************************************************************
- * Copyright (C) 2005-08 by the Quassel Project *
- * devel@quassel-irc.org *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) version 3. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-
-#include "mappedselectionmodel.h"
-
-#include <QItemSelectionModel>
-#include <QAbstractItemModel>
-#include <QAbstractProxyModel>
-#include <QLinkedList>
-#include <QDebug>
-
-MappedSelectionModel::MappedSelectionModel(QAbstractItemModel *model)
- : QItemSelectionModel(model)
-{
-}
-
-QModelIndex MappedSelectionModel::mapFromSource(const QModelIndex &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(sourceSelection.isEmpty())
- return sourceSelection;
-
- 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;
- }
-
- while(!proxies.isEmpty()) {
- proxyModel = proxies.takeLast();
- proxySelection = proxyModel->mapSelectionFromSource(proxySelection);
- }
- return proxySelection;
-}
-
-void MappedSelectionModel::mappedSetCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) {
- setCurrentIndex(mapFromSource(index), command);
-}
-
-void MappedSelectionModel::mappedSelect(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) {
- select(mapSelectionFromSource(selection), command);
-}
-
+++ /dev/null
-/***************************************************************************
- * Copyright (C) 2005-08 by the Quassel Project *
- * devel@quassel-irc.org *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) version 3. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-
-#ifndef _MAPPEDSELECTIONMODEL_H_
-#define _MAPPEDSELECTIONMODEL_H_
-
-#include <QObject>
-#include <QModelIndex>
-#include <QItemSelection>
-#include <QItemSelectionModel>
-
-class QAbstractProxyModel;
-
-class MappedSelectionModel : public QItemSelectionModel {
- Q_OBJECT
-
-public:
- MappedSelectionModel(QAbstractItemModel *model = 0);
-
- QModelIndex mapFromSource(const QModelIndex &sourceIndex);
- QItemSelection mapSelectionFromSource(const QItemSelection &sourceSelection);
-
-public slots:
- void mappedSelect(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command);
- void mappedSetCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags command);
-};
-
-#endif
#include <QAbstractItemModel>
-#include "mappedselectionmodel.h"
#include <QAbstractProxyModel>
#include <QDebug>
SelectionModelSynchronizer::SelectionModelSynchronizer(QAbstractItemModel *parent)
: QObject(parent),
_model(parent),
- _selectionModel(parent)
+ _selectionModel(parent),
+ _changeCurrentEnabled(true),
+ _changeSelectionEnabled(true)
{
connect(&_selectionModel, SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
this, SLOT(currentChanged(const QModelIndex &, const QModelIndex &)));
return baseModel == model();
}
-void SelectionModelSynchronizer::addSelectionModel(QItemSelectionModel *selectionModel) {
+void SelectionModelSynchronizer::synchronizeSelectionModel(QItemSelectionModel *selectionModel) {
if(!checkBaseModel(selectionModel)) {
qWarning() << "cannot Syncronize SelectionModel" << selectionModel << "which has a different baseModel()";
return;
}
+ if(_selectionModels.contains(selectionModel)) {
+ selectionModel->setCurrentIndex(mapFromSource(currentIndex(), selectionModel), QItemSelectionModel::Current);
+ selectionModel->select(mapSelectionFromSource(currentSelection(), selectionModel), QItemSelectionModel::ClearAndSelect);
+ return;
+ }
+
connect(selectionModel, SIGNAL(currentChanged(QModelIndex, QModelIndex)),
- this, SLOT(mappedCurrentChanged(QModelIndex, QModelIndex)));
+ this, SLOT(syncedCurrentChanged(QModelIndex, QModelIndex)));
connect(selectionModel, SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
- this, SLOT(mappedSelectionChanged(QItemSelection, QItemSelection)));
-
- 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)));
- }
+ this, SLOT(syncedSelectionChanged(QItemSelection, QItemSelection)));
+
+ connect(selectionModel, SIGNAL(destroyed(QObject *)), this, SLOT(selectionModelDestroyed(QObject *)));
+
+ _selectionModels << selectionModel;
}
void SelectionModelSynchronizer::removeSelectionModel(QItemSelectionModel *model) {
disconnect(model, 0, this, 0);
disconnect(this, 0, model, 0);
+ selectionModelDestroyed(model);
}
-void SelectionModelSynchronizer::mappedCurrentChanged(const QModelIndex ¤t, const QModelIndex &previous) {
+void SelectionModelSynchronizer::selectionModelDestroyed(QObject *object) {
+ QItemSelectionModel *model = static_cast<QItemSelectionModel *>(object);
+ QSet<QItemSelectionModel *>::iterator iter = _selectionModels.begin();
+ while(iter != _selectionModels.end()) {
+ if(*iter == model) {
+ iter = _selectionModels.erase(iter);
+ } else {
+ iter++;
+ }
+ }
+}
+
+void SelectionModelSynchronizer::syncedCurrentChanged(const QModelIndex ¤t, const QModelIndex &previous) {
Q_UNUSED(previous);
+
+ if(!_changeCurrentEnabled)
+ return;
+
QItemSelectionModel *selectionModel = qobject_cast<QItemSelectionModel *>(sender());
Q_ASSERT(selectionModel);
QModelIndex newSourceCurrent = mapToSource(current, selectionModel);
setCurrentIndex(newSourceCurrent);
}
-void SelectionModelSynchronizer::mappedSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected) {
+void SelectionModelSynchronizer::syncedSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected) {
Q_UNUSED(selected);
Q_UNUSED(deselected);
+
+ if(!_changeSelectionEnabled)
+ return;
+
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);
+
+ QItemSelection mappedSelection = selectionModel->selection();
+ QItemSelection currentSelectionMapped = mapSelectionFromSource(currentSelection(), selectionModel);
+
+ QItemSelection checkSelection = currentSelectionMapped;
+ checkSelection.merge(mappedSelection, QItemSelectionModel::Deselect);
+ if(checkSelection.isEmpty()) {
+ // that means the new selection contains the current selection (currentSel - newSel = {})
+ checkSelection = mappedSelection;
+ checkSelection.merge(currentSelectionMapped, QItemSelectionModel::Deselect);
+ if(checkSelection.isEmpty()) {
+ // that means the current selection contains the new selection (newSel - currentSel = {})
+ // -> currentSel == newSel
+ return;
+ }
+ }
+ setCurrentSelection(mapSelectionToSource(mappedSelection, selectionModel));
+}
+
+QModelIndex SelectionModelSynchronizer::mapFromSource(const QModelIndex &sourceIndex, const QItemSelectionModel *selectionModel) {
+ Q_ASSERT(selectionModel);
+
+ QModelIndex mappedIndex = sourceIndex;
+
+ // make a list of all involved proxies, wie have to traverse backwards
+ QList<const QAbstractProxyModel *> proxyModels;
+ const QAbstractItemModel *baseModel = selectionModel->model();
+ const QAbstractProxyModel *proxyModel = 0;
+ while((proxyModel = qobject_cast<const QAbstractProxyModel *>(baseModel)) != 0) {
+ if(baseModel == model())
+ break;
+ proxyModels << proxyModel;
+ baseModel = proxyModel->sourceModel();
+ }
+
+ // now traverse it;
+ for(int i = proxyModels.count() - 1; i >= 0; i--) {
+ mappedIndex = proxyModels[i]->mapFromSource(mappedIndex);
+ }
+
+ return mappedIndex;
+}
+
+QItemSelection SelectionModelSynchronizer::mapSelectionFromSource(const QItemSelection &sourceSelection, const QItemSelectionModel *selectionModel) {
+ Q_ASSERT(selectionModel);
+
+ QItemSelection mappedSelection = sourceSelection;
+
+ // make a list of all involved proxies, wie have to traverse backwards
+ QList<const QAbstractProxyModel *> proxyModels;
+ const QAbstractItemModel *baseModel = selectionModel->model();
+ const QAbstractProxyModel *proxyModel = 0;
+ while((proxyModel = qobject_cast<const QAbstractProxyModel *>(baseModel)) != 0) {
+ if(baseModel == model())
+ break;
+ proxyModels << proxyModel;
+ baseModel = proxyModel->sourceModel();
+ }
+
+ // now traverse it;
+ for(int i = proxyModels.count() - 1; i >= 0; i--) {
+ mappedSelection = proxyModels[i]->mapSelectionFromSource(mappedSelection);
+ }
+ return mappedSelection;
}
QModelIndex SelectionModelSynchronizer::mapToSource(const QModelIndex &index, QItemSelectionModel *selectionModel) {
_selectionModel.setCurrentIndex(index, QItemSelectionModel::Current);
}
void SelectionModelSynchronizer::setCurrentSelection(const QItemSelection &selection) {
- _selectionModel.select(selection, QItemSelectionModel::Rows | QItemSelectionModel::ClearAndSelect);
+ _selectionModel.select(selection, QItemSelectionModel::ClearAndSelect);
}
void SelectionModelSynchronizer::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) {
Q_UNUSED(previous);
- emit setCurrentIndex(current, QItemSelectionModel::Current);
+
+ _changeCurrentEnabled = false;
+ QSet<QItemSelectionModel *>::iterator iter = _selectionModels.begin();
+ while(iter != _selectionModels.end()) {
+ (*iter)->setCurrentIndex(mapFromSource(current, (*iter)), QItemSelectionModel::Current);
+ iter++;
+ }
+ _changeCurrentEnabled = true;
}
void SelectionModelSynchronizer::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) {
Q_UNUSED(selected);
Q_UNUSED(deselected);
- emit select(_selectionModel.selection(), QItemSelectionModel::ClearAndSelect);
+
+ _changeSelectionEnabled = false;
+ QSet<QItemSelectionModel *>::iterator iter = _selectionModels.begin();
+ while(iter != _selectionModels.end()) {
+ (*iter)->select(mapSelectionFromSource(currentSelection(), (*iter)), QItemSelectionModel::ClearAndSelect);
+ iter++;
+ }
+ _changeSelectionEnabled = true;
}
public:
SelectionModelSynchronizer(QAbstractItemModel *parent = 0);
- void addSelectionModel(QItemSelectionModel *selectionModel);
+ void synchronizeSelectionModel(QItemSelectionModel *selectionModel);
void removeSelectionModel(QItemSelectionModel *selectionModel);
inline QAbstractItemModel *model() { return _model; }
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, const QModelIndex &previous);
- void mappedSelectionChanged(const QItemSelection &selected, const QItemSelection &previous);
+ void syncedCurrentChanged(const QModelIndex ¤t, const QModelIndex &previous);
+ void syncedSelectionChanged(const QItemSelection &selected, const QItemSelection &previous);
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);
+ void selectionModelDestroyed(QObject *object);
+
private:
QAbstractItemModel *_model;
QItemSelectionModel _selectionModel;
+ bool _changeCurrentEnabled;
+ bool _changeSelectionEnabled;
bool checkBaseModel(QItemSelectionModel *model);
+ QModelIndex mapFromSource(const QModelIndex &sourceIndex, const QItemSelectionModel *selectionModel);
+ QItemSelection mapSelectionFromSource(const QItemSelection &sourceSelection, const QItemSelectionModel *selectionModel);
QModelIndex mapToSource(const QModelIndex &index, QItemSelectionModel *selectionModel);
QItemSelection mapSelectionToSource(const QItemSelection &selection, QItemSelectionModel *selectionModel);
-
+ QSet<QItemSelectionModel *> _selectionModels;
};
#endif
#include "buffersyncer.h"
#include "client.h"
#include "iconloader.h"
-#include "mappedselectionmodel.h"
#include "network.h"
#include "networkmodel.h"
#include "networkmodelactionprovider.h"
collapse(networkIdx);
}
- // update selection to current one
- MappedSelectionModel *mappedSelectionModel = qobject_cast<MappedSelectionModel *>(selectionModel());
- if(!config() || !mappedSelectionModel)
- return;
+ if(config()) {
+ // update selection to current one
+ Client::bufferModel()->synchronizeView(this);
+ }
- mappedSelectionModel->mappedSetCurrentIndex(Client::bufferModel()->standardSelectionModel()->currentIndex(), QItemSelectionModel::Current);
- mappedSelectionModel->mappedSelect(Client::bufferModel()->standardSelectionModel()->selection(), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
+ return;
}
void BufferView::on_collapse(const QModelIndex &index) {
if(!config) {
invalidate();
+ setObjectName("");
return;
}
disconnect(config(), SIGNAL(initDone()), this, SLOT(configInitialized()));
+ setObjectName(config()->bufferViewName());
+
invalidate();
emit configChanged();
}