Client::bufferModel()->selectionModelSynchronizer()->addSelectionModel(mappedSelectionModel)
(maybe I'll make this a bit easier... ;))
#include <QColor> // FIXME Dependency on QtGui!
#include "buffertreemodel.h"
+#include "selectionmodelsynchronizer.h"
#include "bufferinfo.h"
#include "client.h"
* BufferTreeModel
*****************************************/
BufferTreeModel::BufferTreeModel(QObject *parent)
- : TreeModel(BufferTreeModel::defaultHeader(), parent)
+ : TreeModel(BufferTreeModel::defaultHeader(), parent),
+ _selectionModelSynchronizer(new SelectionModelSynchronizer(this))
{
- Client::signalProxy()->attachSignal(this, SIGNAL(fakeUserInput(BufferInfo, QString)), SIGNAL(sendInput(BufferInfo, QString)));
+ connect(_selectionModelSynchronizer, SIGNAL(setCurrentIndex(QModelIndex, QItemSelectionModel::SelectionFlags)),
+ this, SLOT(setCurrentIndex(QModelIndex, QItemSelectionModel::SelectionFlags)));
}
QList<QVariant >BufferTreeModel::defaultHeader() {
}
// This Slot indicates that the user has selected a different buffer in the gui
-void BufferTreeModel::changeCurrent(const QModelIndex ¤t, const QModelIndex &/*previous*/) {
- if(isBufferIndex(current)) {
- currentBuffer = getBufferByIndex(current);
+void BufferTreeModel::setCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) {
+ Q_UNUSED(command)
+ if(isBufferIndex(index)) {
+ currentBuffer = getBufferByIndex(index);
bufferActivity(Buffer::NoActivity, currentBuffer);
emit bufferSelected(currentBuffer);
- emit selectionChanged(current);
+ emit selectionChanged(index);
}
}
void BufferTreeModel::selectBuffer(Buffer *buffer) {
QModelIndex index = getOrCreateBufferItemIndex(buffer);
- //emit selectionChanged(index);
- changeCurrent(index, QModelIndex());
+ // SUPER UGLY!
+ setCurrentIndex(index, 0);
}
#include <QtCore>
#include "treemodel.h"
-class BufferInfo;
#include "buffer.h"
+#include <QItemSelectionModel>
+
+class BufferInfo;
+class SelectionModelSynchronizer;
+
+
/*****************************************
* Fancy Buffer Items
*****************************************/
BufferTreeModel(QObject *parent = 0);
static QList<QVariant> defaultHeader();
-
+
+ inline SelectionModelSynchronizer *selectionModelSynchronizer() { return _selectionModelSynchronizer; }
+
public slots:
- void bufferUpdated(Buffer *);
- void changeCurrent(const QModelIndex &, const QModelIndex &);
+ void bufferUpdated(Buffer *);
+ void setCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags command);
void selectBuffer(Buffer *buffer);
void bufferActivity(Buffer::ActivityLevel, Buffer *buffer);
signals:
void bufferSelected(Buffer *);
void invalidateFilter();
- void fakeUserInput(BufferInfo, QString);
void selectionChanged(const QModelIndex &);
private:
QStringList mimeTypes() const;
QMimeData *mimeData(const QModelIndexList &) const;
bool dropMimeData(const QMimeData *, Qt::DropAction, int, int, const QModelIndex &);
-
+
+ SelectionModelSynchronizer *_selectionModelSynchronizer;
Buffer *currentBuffer;
};
DEPMOD = common contrib/qxt
QT_MOD = core network gui # gui is needed just for QColor... FIXME!
-SRCS += buffer.cpp buffertreemodel.cpp client.cpp clientsettings.cpp treemodel.cpp
-HDRS += buffer.h buffertreemodel.h client.h clientsettings.h quasselui.h treemodel.h
+SRCS += buffer.cpp buffertreemodel.cpp client.cpp clientsettings.cpp treemodel.cpp mappedselectionmodel.cpp selectionmodelsynchronizer.cpp
+HDRS += buffer.h buffertreemodel.h client.h clientsettings.h quasselui.h treemodel.h mappedselectionmodel.h selectionmodelsynchronizer.h
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2005-07 by The Quassel Team *
+ * 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) any later version. *
+ * *
+ * 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 <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;
+}
+
+QItemSelection MappedSelectionModel::mapFromSource(const QItemSelection &sourceSelection) {
+ if(isProxyModel()) {
+ QItemSelection mappedSelection;
+ foreach(QItemSelectionRange range, sourceSelection) {
+ QModelIndex topleft = mapFromSource(range.topLeft());
+ QModelIndex bottomright = mapFromSource(range.bottomRight());
+ if(topleft.isValid() && bottomright.isValid())
+ mappedSelection << QItemSelectionRange(topleft, bottomright);
+ else
+ Q_ASSERT(!topleft.isValid() && !bottomright.isValid());
+ }
+ return mappedSelection;
+ } else {
+ return sourceSelection;
+ }
+}
+
+QModelIndex MappedSelectionModel::mapToSource(const QModelIndex &proxyIndex) {
+ if(isProxyModel())
+ return proxyModel()->mapToSource(proxyIndex);
+ else
+ return proxyIndex;
+}
+
+QItemSelection MappedSelectionModel::mapToSource(const QItemSelection &proxySelection) {
+ if(isProxyModel()) {
+ QItemSelection mappedSelection;
+ foreach(QItemSelectionRange range, proxySelection) {
+ mappedSelection << QItemSelectionRange(mapToSource(range.topLeft()), mapToSource(range.bottomRight()));
+ }
+ return mappedSelection;
+ } else {
+ return proxySelection;
+ }
+}
+
+void MappedSelectionModel::mappedSelect(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) {
+ QModelIndex mappedIndex = mapFromSource(index);
+ if(!isSelected(mappedIndex))
+ select(mappedIndex, command);
+}
+
+void MappedSelectionModel::mappedSelect(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) {
+ QItemSelection mappedSelection = mapFromSource(selection);
+ if(mappedSelection != QItemSelectionModel::selection())
+ select(mappedSelection, command);
+}
+
+void MappedSelectionModel::mappedSetCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) {
+ QModelIndex mappedIndex = mapFromSource(index);
+ if(mappedIndex == currentIndex())
+ return;
+
+ if(mappedIndex.isValid())
+ setCurrentIndex(mappedIndex, command);
+ else if(hasSelection())
+ setCurrentIndex(currentIndex(), QItemSelectionModel::Clear);
+}
+
+
+void MappedSelectionModel::_currentChanged(const QModelIndex ¤t, const QModelIndex &previous) {
+ Q_UNUSED(previous)
+ emit mappedCurrentChanged(mapToSource(current));
+}
+
+void MappedSelectionModel::_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) {
+ Q_UNUSED(selected)
+ Q_UNUSED(deselected)
+ emit mappedSelectionChanged(mapToSource(QItemSelectionModel::selection()));
+}
+
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2005-07 by The Quassel Team *
+ * 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) any later version. *
+ * *
+ * 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);
+ virtual ~MappedSelectionModel();
+
+ inline bool isProxyModel() const { return _isProxyModel; }
+
+ const QAbstractItemModel *baseModel() const;
+ const QAbstractProxyModel *proxyModel() const;
+
+ QModelIndex mapFromSource(const QModelIndex &sourceIndex);
+ QItemSelection mapFromSource(const QItemSelection &sourceSelection);
+
+ QModelIndex mapToSource(const QModelIndex &proxyIndex);
+ QItemSelection mapToSource(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
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2005-07 by The Quassel Team *
+ * 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) any later version. *
+ * *
+ * 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 "selectionmodelsynchronizer.h"
+
+
+#include <QAbstractItemModel>
+#include "mappedselectionmodel.h"
+
+#include <QDebug>
+
+SelectionModelSynchronizer::SelectionModelSynchronizer(QAbstractItemModel *parent)
+ : QObject(parent),
+ _model(parent)
+{
+}
+
+SelectionModelSynchronizer::~SelectionModelSynchronizer() {
+}
+
+void SelectionModelSynchronizer::addSelectionModel(MappedSelectionModel *selectionmodel) {
+ if(selectionmodel->baseModel() != model()) {
+ 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)));
+
+}
+
+void SelectionModelSynchronizer::removeSelectionModel(MappedSelectionModel *model) {
+ disconnect(model, 0, this, 0);
+ disconnect(this, 0, model, 0);
+}
+
+void SelectionModelSynchronizer::_mappedCurrentChanged(const QModelIndex ¤t) {
+ emit setCurrentIndex(current, QItemSelectionModel::ClearAndSelect);
+}
+
+void SelectionModelSynchronizer::_mappedSelectionChanged(const QItemSelection &selected) {
+ emit select(selected, QItemSelectionModel::ClearAndSelect);
+}
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2005-07 by The Quassel Team *
+ * 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) any later version. *
+ * *
+ * 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 _SELECTIONMODELSYNCHRONIZER_H_
+#define _SELECTIONMODELSYNCHRONIZER_H_
+
+#include <QObject>
+#include <QItemSelectionModel>
+
+class QAbstractItemModel;
+class MappedSelectionModel;
+
+class SelectionModelSynchronizer : public QObject {
+ Q_OBJECT
+
+public:
+ SelectionModelSynchronizer(QAbstractItemModel *parent = 0);
+ virtual ~SelectionModelSynchronizer();
+
+ void addSelectionModel(MappedSelectionModel *model);
+ void removeSelectionModel(MappedSelectionModel *model);
+
+ inline QAbstractItemModel *model() { return _model; }
+
+private slots:
+ void _mappedCurrentChanged(const QModelIndex ¤t);
+ void _mappedSelectionChanged(const QItemSelection &selected);
+
+signals:
+ void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command);
+ void setCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags command);
+
+private:
+ QAbstractItemModel *_model;
+};
+
+#endif
setSortingEnabled(true);
sortByColumn(0, Qt::AscendingOrder);
- connect(selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
- model(), SLOT(changeCurrent(const QModelIndex &, const QModelIndex &)));
-
- connect(model(), SIGNAL(selectionChanged(const QModelIndex &)),
- this, SLOT(select(const QModelIndex &)));
-
- connect(this, SIGNAL(selectionChanged(const QModelIndex &, QItemSelectionModel::SelectionFlags)),
- selectionModel(), SLOT(select(const QModelIndex &, QItemSelectionModel::SelectionFlags)));
-
connect(this, SIGNAL(activated(QModelIndex)), this, SLOT(joinChannel(QModelIndex)));
}
void BufferView::setModel(QAbstractItemModel *model) {
QTreeView::setModel(model);
init();
-}
-
-void BufferView::select(const QModelIndex ¤t) {
- emit selectionChanged(current, QItemSelectionModel::ClearAndSelect);
+
}
void BufferView::dropEvent(QDropEvent *event) {
void setModel(QAbstractItemModel *model);
void setFilteredModel(QAbstractItemModel *model, BufferViewFilter::Modes mode, QStringList nets);
-public slots:
- void select(const QModelIndex &);
-
signals:
void eventDropped(QDropEvent *);
void removeBuffer(const QModelIndex &);
- void selectionChanged(const QModelIndex &, QItemSelectionModel::SelectionFlags);
private slots:
void dropEvent(QDropEvent *);
networks = nets;
connect(model, SIGNAL(invalidateFilter()), this, SLOT(invalidateMe()));
- connect(model, SIGNAL(selectionChanged(const QModelIndex &)),
- this, SLOT(select(const QModelIndex &)));
-
- connect(this, SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
- model, SLOT(changeCurrent(const QModelIndex &, const QModelIndex &)));
}
void BufferViewFilter::invalidateMe() {
invalidateFilter();
}
-void BufferViewFilter::select(const QModelIndex &index) {
- emit selectionChanged(mapFromSource(index));
-}
-
-void BufferViewFilter::changeCurrent(const QModelIndex ¤t, const QModelIndex &previous) {
- emit currentChanged(mapToSource(current), mapToSource(previous));
-}
-
-void BufferViewFilter::doubleClickReceived(const QModelIndex &clicked) {
- emit doubleClicked(mapToSource(clicked));
-}
-
void BufferViewFilter::dropEvent(QDropEvent *event) {
const QMimeData *data = event->mimeData();
if(!(mode & FullCustom))
public slots:
void invalidateMe();
- void changeCurrent(const QModelIndex &, const QModelIndex &);
- void doubleClickReceived(const QModelIndex &);
- void select(const QModelIndex &);
void dropEvent(QDropEvent *);
void removeBuffer(const QModelIndex &);
-
-signals:
- void currentChanged(const QModelIndex &, const QModelIndex &);
- void doubleClicked(const QModelIndex &);
- void selectionChanged(const QModelIndex &);
-
private:
bool filterAcceptBuffer(const QModelIndex &) const;
bool filterAcceptNetwork(const QModelIndex &) const;
#include "topicwidget.h"
+#include "selectionmodelsynchronizer.h"
+#include "mappedselectionmodel.h"
+
MainWin::MainWin(QtUi *_gui, QWidget *parent) : QMainWindow(parent), gui(_gui) {
ui.setupUi(this);
setWindowTitle("Quassel IRC");
//create the view and initialize it's filter
BufferView *view = new BufferView(dock);
view->setFilteredModel(model, mode, nets);
+
+ MappedSelectionModel *mappedSelectionModel = new MappedSelectionModel(view->model());
+ Client::bufferModel()->selectionModelSynchronizer()->addSelectionModel(mappedSelectionModel);
+ Q_ASSERT(mappedSelectionModel);
+ delete view->selectionModel();
+ view->setSelectionModel(mappedSelectionModel);
+
dock->setWidget(view);
addDockWidget(Qt::LeftDockWidgetArea, dock);