merging branches/fu-debug with trunk :)
authorMarcus Eggenberger <egs@quassel-irc.org>
Wed, 16 Apr 2008 20:59:59 +0000 (20:59 +0000)
committerMarcus Eggenberger <egs@quassel-irc.org>
Wed, 16 Apr 2008 20:59:59 +0000 (20:59 +0000)
src/client/buffermodel.cpp
src/client/buffermodel.h
src/client/mappedselectionmodel.cpp
src/client/mappedselectionmodel.h
src/client/selectionmodelsynchronizer.cpp
src/client/selectionmodelsynchronizer.h
src/uisupport/bufferviewfilter.cpp

index 52d6d54..3dfdc6d 100644 (file)
 
 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 << ")";
 }
index 0be559a..3126f73 100644 (file)
@@ -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<QItemSelectionModel *>(&_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
index 99b1e4f..84cd9fe 100644 (file)
 #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 &current, 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);
 }
 
index a59ea25..9641658 100644 (file)
@@ -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 &current, const QModelIndex &previous);
-  void _selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
-  
-signals:
-  void mappedCurrentChanged(const QModelIndex &current);
-  void mappedSelectionChanged(const QItemSelection &selected);
-
-private:
-  bool _isProxyModel;
-
 };
 
 #endif
index 169fddc..d533ea4 100644 (file)
 
 #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 &current) {
-  emit setCurrentIndex(current, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
+void SelectionModelSynchronizer::mappedCurrentChanged(const QModelIndex &current, 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 &current, 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);
 }
index 5cda9cc..2e153b6 100644 (file)
 #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 &current, QItemSelectionModel::SelectionFlags command);
+  void select(const QItemSelection &selected, QItemSelectionModel::SelectionFlags command);
 
 private slots:
-  void _mappedCurrentChanged(const QModelIndex &current);
-  void _mappedSelectionChanged(const QItemSelection &selected);
+  void mappedCurrentChanged(const QModelIndex &current, 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 &current, 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
index 1245579..fa29358 100644 (file)
@@ -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();