From 89c07686d193fe31e1b3ea45735b3f5a0d1e6cfb Mon Sep 17 00:00:00 2001 From: Marcus Eggenberger Date: Thu, 6 Mar 2008 12:43:59 +0000 Subject: [PATCH] fixed slow buffer switches --- src/client/treemodel.cpp | 4 +- src/qtui/bufferwidget.cpp | 14 ++++-- src/qtui/mainwin.cpp | 6 ++- src/qtui/nicklistwidget.cpp | 79 ++++++++++++++++++++++++++++---- src/qtui/nicklistwidget.h | 31 ++++++++++--- src/uisupport/bufferview.cpp | 2 + src/uisupport/nickview.cpp | 34 ++++++++++---- src/uisupport/nickview.h | 39 +++++++++------- src/uisupport/nickviewfilter.cpp | 17 ++++++- src/uisupport/nickviewfilter.h | 9 +++- version.inc | 4 +- 11 files changed, 187 insertions(+), 52 deletions(-) diff --git a/src/client/treemodel.cpp b/src/client/treemodel.cpp index d66cc3a9..ace9d3d7 100644 --- a/src/client/treemodel.cpp +++ b/src/client/treemodel.cpp @@ -528,7 +528,7 @@ void TreeModel::clear() { } void TreeModel::debug_rowsAboutToBeInserted(const QModelIndex &parent, int start, int end) { - // qDebug() << "debug_rowsAboutToBeInserted" << parent << parent.internalPointer() << parent.data().toString() << rowCount(parent) << start << end; + qDebug() << "debug_rowsAboutToBeInserted" << parent << parent.internalPointer() << parent.data().toString() << rowCount(parent) << start << end; } void TreeModel::debug_rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) { @@ -566,5 +566,5 @@ void TreeModel::debug_rowsInserted(const QModelIndex &parent, int start, int end } void TreeModel::debug_rowsRemoved(const QModelIndex &parent, int start, int end) { - // qDebug() << "debug_rowsRemoved" << parent << parent.internalPointer() << parent.data().toString() << rowCount(parent) << start << end; + qDebug() << "debug_rowsRemoved" << parent << parent.internalPointer() << parent.data().toString() << rowCount(parent) << start << end; } diff --git a/src/qtui/bufferwidget.cpp b/src/qtui/bufferwidget.cpp index 8831a28e..e408e714 100644 --- a/src/qtui/bufferwidget.cpp +++ b/src/qtui/bufferwidget.cpp @@ -48,8 +48,11 @@ void BufferWidget::setModel(BufferModel *bufferModel) { disconnect(_bufferModel, 0, this, 0); } _bufferModel = bufferModel; - connect(bufferModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)), - this, SLOT(rowsAboutToBeRemoved(QModelIndex, int, int))); + + if(bufferModel) { + connect(bufferModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)), + this, SLOT(rowsAboutToBeRemoved(QModelIndex, int, int))); + } } void BufferWidget::setSelectionModel(QItemSelectionModel *selectionModel) { @@ -57,8 +60,11 @@ void BufferWidget::setSelectionModel(QItemSelectionModel *selectionModel) { disconnect(_selectionModel, 0, this, 0); } _selectionModel = selectionModel; - connect(selectionModel, SIGNAL(currentChanged(QModelIndex, QModelIndex)), - this, SLOT(currentChanged(QModelIndex, QModelIndex))); + + if(selectionModel) { + connect(selectionModel, SIGNAL(currentChanged(QModelIndex, QModelIndex)), + this, SLOT(currentChanged(QModelIndex, QModelIndex))); + } } void BufferWidget::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) { diff --git a/src/qtui/mainwin.cpp b/src/qtui/mainwin.cpp index d700b642..1f168b69 100644 --- a/src/qtui/mainwin.cpp +++ b/src/qtui/mainwin.cpp @@ -111,7 +111,7 @@ void MainWin::init() { disconnectedFromCore(); // Disable menus and stuff showCoreConnectionDlg(true); // autoconnect if appropriate - // attach the BufferWidget to the PropertyMapper + // attach the BufferWidget to the BufferModel and the default selection ui.bufferWidget->setModel(Client::bufferModel()); ui.bufferWidget->setSelectionModel(Client::bufferModel()->standardSelectionModel()); @@ -208,6 +208,10 @@ void MainWin::setupNickWidget() { ui.menuViews->addAction(nickDock->toggleViewAction()); + // attach the NickListWidget to the BufferModel and the default selection + nickListWidget->setModel(Client::bufferModel()); + nickListWidget->setSelectionModel(Client::bufferModel()->standardSelectionModel()); + Client::bufferModel()->mapProperty(0, NetworkModel::BufferIdRole, nickListWidget, "currentBuffer"); } diff --git a/src/qtui/nicklistwidget.cpp b/src/qtui/nicklistwidget.cpp index 82191722..cb941618 100644 --- a/src/qtui/nicklistwidget.cpp +++ b/src/qtui/nicklistwidget.cpp @@ -28,16 +28,62 @@ NickListWidget::NickListWidget(QWidget *parent) : QWidget(parent), - _currentBuffer(0) + _bufferModel(0), + _selectionModel(0) { ui.setupUi(this); } +void NickListWidget::setModel(BufferModel *bufferModel) { + if(_bufferModel) { + disconnect(_bufferModel, 0, this, 0); + } + + _bufferModel = bufferModel; + + if(bufferModel) { + connect(bufferModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)), + this, SLOT(rowsAboutToBeRemoved(QModelIndex, int, int))); + } +} + +void NickListWidget::setSelectionModel(QItemSelectionModel *selectionModel) { + if(_selectionModel) { + disconnect(_selectionModel, 0, this, 0); + } + + _selectionModel = selectionModel; + + if(selectionModel) { + connect(selectionModel, SIGNAL(currentChanged(QModelIndex, QModelIndex)), + this, SLOT(currentChanged(QModelIndex, QModelIndex))); + } +} + -BufferId NickListWidget::currentBuffer() const { - return _currentBuffer; +void NickListWidget::reset() { + NickView *nickView; + QHash::iterator iter = nickViews.begin(); + while(iter != nickViews.end()) { + nickView = *iter; + iter = nickViews.erase(iter); + ui.stackedWidget->removeWidget(nickView); + nickView->deleteLater(); + } +} + + +void NickListWidget::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) { + Q_UNUSED(previous); + QVariant variant; + + variant = current.data(NetworkModel::BufferIdRole); + if(!variant.isValid()) + return; + setCurrentBuffer(variant.value()); } + void NickListWidget::setCurrentBuffer(BufferId bufferId) { QModelIndex bufferIdx = Client::networkModel()->bufferIndex(bufferId); @@ -50,21 +96,36 @@ void NickListWidget::setCurrentBuffer(BufferId bufferId) { ui.stackedWidget->setCurrentWidget(nickViews.value(bufferId)); } else { NickView *view = new NickView(this); - NickViewFilter *filter = new NickViewFilter(Client::networkModel()); + NickViewFilter *filter = new NickViewFilter(bufferId, Client::networkModel()); + filter->setObjectName("Buffer " + QString::number(bufferId.toInt())); view->setModel(filter); view->setRootIndex(filter->mapFromSource(bufferIdx)); + view->expandAll(); nickViews[bufferId] = view; ui.stackedWidget->addWidget(view); ui.stackedWidget->setCurrentWidget(view); } } -void NickListWidget::reset() { - foreach(NickView *view, nickViews.values()) { - ui.stackedWidget->removeWidget(view); - view->deleteLater(); + +void NickListWidget::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) { + Q_ASSERT(model()); + if(!parent.isValid()) { + // ok this means that whole networks are about to be removed + // we can't determine which buffers are affect, so we hope that all nets are removed + // this is the most common case (for example disconnecting from the core or terminating the clint) + reset(); + } else { + // check if there are explicitly buffers removed + for(int i = start; i <= end; i++) { + QVariant variant = parent.child(i,0).data(NetworkModel::BufferIdRole); + if(!variant.isValid()) + continue; + + BufferId bufferId = qVariantValue(variant); + removeBuffer(bufferId); + } } - nickViews.clear(); } void NickListWidget::removeBuffer(BufferId bufferId) { diff --git a/src/qtui/nicklistwidget.h b/src/qtui/nicklistwidget.h index a004f2a2..3db7e083 100644 --- a/src/qtui/nicklistwidget.h +++ b/src/qtui/nicklistwidget.h @@ -26,33 +26,52 @@ #include +#include +#include + +#include "buffermodel.h" + class Buffer; class NickView; class NickListWidget : public QWidget { Q_OBJECT - Q_PROPERTY(BufferId currentBuffer READ currentBuffer WRITE setCurrentBuffer); // FIXME BufferId - public: NickListWidget(QWidget *parent = 0); + inline BufferModel *model() { return _bufferModel; } + void setModel(BufferModel *bufferModel); + + inline QItemSelectionModel *selectionModel() const { return _selectionModel; } + void setSelectionModel(QItemSelectionModel *selectionModel); + public slots: - BufferId currentBuffer() const; - void setCurrentBuffer(BufferId bufferId); void reset(); protected: virtual QSize sizeHint() const; +protected slots: +// virtual void closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint); +// virtual void commitData(QWidget *editor); + virtual void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); +// virtual void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); +// virtual void editorDestroyed(QObject *editor); + virtual void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end); +// virtual void rowsInserted(const QModelIndex &parent, int start, int end); +// virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected); + private slots: void removeBuffer(BufferId bufferId); + void setCurrentBuffer(BufferId bufferId); private: Ui::NickListWidget ui; QHash nickViews; - BufferId _currentBuffer; - + + QPointer _bufferModel; + QPointer _selectionModel; }; #endif diff --git a/src/uisupport/bufferview.cpp b/src/uisupport/bufferview.cpp index 8c26056b..6bc01d87 100644 --- a/src/uisupport/bufferview.cpp +++ b/src/uisupport/bufferview.cpp @@ -287,6 +287,8 @@ void BufferView::wheelEvent(QWheelEvent* event) { QSize BufferView::sizeHint() const { + return QSize(120, 50); + if(!model()) return QTreeView::sizeHint(); diff --git a/src/uisupport/nickview.cpp b/src/uisupport/nickview.cpp index 7e30cb7c..78cb709b 100644 --- a/src/uisupport/nickview.cpp +++ b/src/uisupport/nickview.cpp @@ -30,7 +30,8 @@ NickView::NickView(QWidget *parent) - : QTreeView(parent) + : QTreeView(parent), + _sizeHint(QTreeView::sizeHint()) { setIndentation(10); setAnimated(true); @@ -41,7 +42,7 @@ NickView::NickView(QWidget *parent) setContextMenuPolicy(Qt::CustomContextMenu); connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), - this, SLOT(showContextMenu(const QPoint&))); + this, SLOT(showContextMenu(const QPoint&))); connect(this, SIGNAL(activated( const QModelIndex& )), this, SLOT(startQuery( const QModelIndex& ))); } @@ -57,6 +58,7 @@ void NickView::init() { setColumnHidden(i, true); expandAll(); + updateSizeHint(); } void NickView::setModel(QAbstractItemModel *model) { @@ -64,9 +66,21 @@ void NickView::setModel(QAbstractItemModel *model) { init(); } -void NickView::rowsInserted(const QModelIndex &index, int start, int end) { - QTreeView::rowsInserted(index, start, end); - expandAll(); // FIXME We need to do this more intelligently. Maybe a pimped TreeView? +void NickView::rowsInserted(const QModelIndex &parent, int start, int end) { + QTreeView::rowsInserted(parent, start, end); + if(model()->data(parent, NetworkModel::ItemTypeRole) == NetworkModel::UserCategoryItemType && !isExpanded(parent)) + expand(parent); + updateSizeHint(); +} + +void NickView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) { + QTreeView::rowsAboutToBeRemoved(parent, start, end); + updateSizeHint(); +} + +void NickView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) { + QTreeView::dataChanged(topLeft, bottomRight); + updateSizeHint(); } QString NickView::nickFromModelIndex(const QModelIndex & index) { @@ -143,9 +157,9 @@ void NickView::executeCommand(const BufferInfo & bufferInfo, const QString & com Client::instance()->userInput(bufferInfo, command); } -QSize NickView::sizeHint() const { +void NickView::updateSizeHint() { if(!model()) - return QTreeView::sizeHint(); + return; int columnSize = 0; for(int i = 0; i < model()->columnCount(); i++) { @@ -153,5 +167,9 @@ QSize NickView::sizeHint() const { columnSize += sizeHintForColumn(i); } - return QSize(columnSize, 50); + _sizeHint = QSize(columnSize, 50); +} + +QSize NickView::sizeHint() const { + return _sizeHint; } diff --git a/src/uisupport/nickview.h b/src/uisupport/nickview.h index 18a2bd65..cb263c44 100644 --- a/src/uisupport/nickview.h +++ b/src/uisupport/nickview.h @@ -35,25 +35,30 @@ class QSortFilterProxyModel; class NickView : public QTreeView { Q_OBJECT - public: - NickView(QWidget *parent = 0); - virtual ~NickView(); +public: + NickView(QWidget *parent = 0); + virtual ~NickView(); - protected: - virtual void rowsInserted(const QModelIndex &, int, int); - virtual QSize sizeHint() const; - - public slots: - void setModel(QAbstractItemModel *model); - void init(); - void showContextMenu(const QPoint & pos); - void startQuery(const QModelIndex & modelIndex); - - private: - BufferInfo bufferInfoFromModelIndex(const QModelIndex & index); - QString nickFromModelIndex(const QModelIndex & index); - void executeCommand(const BufferInfo & bufferInfo, const QString & command); +protected: + virtual void rowsInserted(const QModelIndex &parent, int start, int end); + virtual void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); + virtual void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end); + virtual QSize sizeHint() const; +public slots: + void setModel(QAbstractItemModel *model); + void init(); + void showContextMenu(const QPoint & pos); + void startQuery(const QModelIndex & modelIndex); + +private: + QSize _sizeHint; + + void updateSizeHint(); + BufferInfo bufferInfoFromModelIndex(const QModelIndex & index); + QString nickFromModelIndex(const QModelIndex & index); + void executeCommand(const BufferInfo & bufferInfo, const QString & command); + }; diff --git a/src/uisupport/nickviewfilter.cpp b/src/uisupport/nickviewfilter.cpp index 993bac08..7a6e704b 100644 --- a/src/uisupport/nickviewfilter.cpp +++ b/src/uisupport/nickviewfilter.cpp @@ -29,8 +29,9 @@ /****************************************************************************************** * NickViewFilter ******************************************************************************************/ -NickViewFilter::NickViewFilter(NetworkModel *parent) - : QSortFilterProxyModel(parent) +NickViewFilter::NickViewFilter(const BufferId &bufferId, NetworkModel *parent) + : QSortFilterProxyModel(parent), + _bufferId(bufferId) { setSourceModel(parent); setDynamicSortFilter(true); @@ -42,6 +43,12 @@ QVariant NickViewFilter::data(const QModelIndex &index, int role) const { return foreground(index); else return QSortFilterProxyModel::data(index, role); +// else { +// QVariant d = +// if(role == 0) +// qDebug() << index << role << d; +// return d; +// } } QVariant NickViewFilter::foreground(const QModelIndex &index) const { @@ -57,3 +64,9 @@ QVariant NickViewFilter::foreground(const QModelIndex &index) const { // FIXME:: make colors configurable; // FIXME: use the style interface instead of qsettings } + + +bool NickViewFilter::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { + QModelIndex source_child = source_parent.child(source_row, 0); + return (sourceModel()->data(source_child, NetworkModel::BufferIdRole).value() == _bufferId); +} diff --git a/src/uisupport/nickviewfilter.h b/src/uisupport/nickviewfilter.h index 47da2948..38b7ca3a 100644 --- a/src/uisupport/nickviewfilter.h +++ b/src/uisupport/nickviewfilter.h @@ -22,6 +22,7 @@ #define NICKVIEWFILTER_H #include +#include "types.h" class NetworkModel; @@ -31,9 +32,15 @@ class NickViewFilter : public QSortFilterProxyModel { Q_OBJECT public: - NickViewFilter(NetworkModel *parent = 0); + NickViewFilter(const BufferId &bufferId, NetworkModel *parent = 0); QVariant data(const QModelIndex &index, int role) const; QVariant foreground(const QModelIndex &index) const; + +protected: + virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; + +private: + BufferId _bufferId; }; #endif diff --git a/version.inc b/version.inc index f7051ff3..ab351aef 100644 --- a/version.inc +++ b/version.inc @@ -4,8 +4,8 @@ { using namespace Global; quasselVersion = "0.2.0-alpha3-pre"; - quasselDate = "2008-03-03"; - quasselBuild = 615; + quasselDate = "2008-03-06"; + quasselBuild = 616; //! Minimum client build number the core needs clientBuildNeeded = 613; -- 2.20.1