From 600a5683c1a8e679b7b63a00d5b1211b5b9771c7 Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Wed, 16 Apr 2008 23:29:31 +0000 Subject: [PATCH] Merging r732:766 from trunk to branches/0.3. --- build/buildconf.pri | 1 + src/client/buffermodel.cpp | 19 +-- src/client/buffermodel.h | 8 +- src/client/mappedselectionmodel.cpp | 103 ++++++--------- src/client/mappedselectionmodel.h | 22 ---- src/client/networkmodel.cpp | 6 +- src/client/networkmodel.h | 2 +- src/client/selectionmodelsynchronizer.cpp | 145 +++++++++++++++------- src/client/selectionmodelsynchronizer.h | 36 ++++-- src/core/coresession.cpp | 33 +++-- src/core/networkconnection.cpp | 29 ++++- src/core/networkconnection.h | 11 ++ src/core/sqlitestorage.cpp | 4 +- src/core/userinputhandler.cpp | 1 - src/qtui/chatline-old.cpp | 7 +- src/qtui/chatline-old.h | 2 + src/uisupport/abstractbuffercontainer.cpp | 19 ++- src/uisupport/bufferviewfilter.cpp | 10 +- version.inc | 4 +- 19 files changed, 267 insertions(+), 195 deletions(-) diff --git a/build/buildconf.pri b/build/buildconf.pri index ebc939e5..11297db4 100644 --- a/build/buildconf.pri +++ b/build/buildconf.pri @@ -13,4 +13,5 @@ win32:static { mac:Tiger { QMAKE_MAC_SDK=/Developer/SDKs/MacOSX10.4u.sdk + CONFIG += x86 ppc } 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/networkmodel.cpp b/src/client/networkmodel.cpp index 9a16ac17..bec3edf1 100644 --- a/src/client/networkmodel.cpp +++ b/src/client/networkmodel.cpp @@ -41,7 +41,8 @@ BufferItem::BufferItem(BufferInfo bufferInfo, AbstractTreeItem *parent) : PropertyMapItem(QStringList() << "bufferName" << "topic" << "nickCount", parent), _bufferInfo(bufferInfo), _bufferName(bufferInfo.bufferName()), - _activity(Buffer::NoActivity) + _activity(Buffer::NoActivity), + _ircChannel(0) { Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled; if(bufferType() == BufferInfo::QueryBuffer) @@ -144,6 +145,9 @@ void BufferItem::attachIrcChannel(IrcChannel *ircChannel) { } void BufferItem::ircChannelDestroyed() { + Q_CHECK_PTR(_ircChannel); + disconnect(_ircChannel, 0, this, 0); + _ircChannel = 0; emit dataChanged(); removeAllChilds(); } diff --git a/src/client/networkmodel.h b/src/client/networkmodel.h index dc010dd8..634c402e 100644 --- a/src/client/networkmodel.h +++ b/src/client/networkmodel.h @@ -100,7 +100,7 @@ private: QString _bufferName; Buffer::ActivityLevel _activity; - QPointer _ircChannel; + IrcChannel *_ircChannel; }; 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/core/coresession.cpp b/src/core/coresession.cpp index d7b9cb19..b5768542 100644 --- a/src/core/coresession.cpp +++ b/src/core/coresession.cpp @@ -396,19 +396,25 @@ void CoreSession::createNetwork(const NetworkInfo &info_) { if(!info.networkId.isValid()) Core::createNetwork(user(), info); - Q_ASSERT(info.networkId.isValid()); + if(!info.networkId.isValid()) { + qWarning() << qPrintable(tr("CoreSession::createNetwork(): Got invalid networkId from Core when trying to create network %1!").arg(info.networkName)); + return; + } id = info.networkId.toInt(); - Q_ASSERT(!_networks.contains(id)); - - Network *net = new Network(id, this); - connect(net, SIGNAL(connectRequested(NetworkId)), this, SLOT(connectToNetwork(NetworkId))); - connect(net, SIGNAL(disconnectRequested(NetworkId)), this, SLOT(disconnectFromNetwork(NetworkId))); - net->setNetworkInfo(info); - net->setProxy(signalProxy()); - _networks[id] = net; - signalProxy()->synchronize(net); - emit networkCreated(id); + if(!_networks.contains(id)) { + Network *net = new Network(id, this); + connect(net, SIGNAL(connectRequested(NetworkId)), this, SLOT(connectToNetwork(NetworkId))); + connect(net, SIGNAL(disconnectRequested(NetworkId)), this, SLOT(disconnectFromNetwork(NetworkId))); + net->setNetworkInfo(info); + net->setProxy(signalProxy()); + _networks[id] = net; + signalProxy()->synchronize(net); + emit networkCreated(id); + } else { + qWarning() << qPrintable(tr("CoreSession::createNetwork(): Trying to create a network that already exists, updating instead!")); + updateNetwork(info); + } } void CoreSession::updateNetwork(const NetworkInfo &info) { @@ -462,7 +468,10 @@ void CoreSession::removeBufferRequested(BufferId bufferId) { if(bufferInfo.type() == BufferInfo::ChannelBuffer) { Network *net = network(bufferInfo.networkId()); - Q_ASSERT(net); + if(!net) { + qWarning() << "CoreSession::removeBufferRequested(): Received BufferInfo with unknown networkId!"; + return; + } IrcChannel *chan = net->ircChannel(bufferInfo.bufferName()); if(chan) { qWarning() << "CoreSession::removeBufferRequested(): Unable to remove Buffer for joined Channel:" << bufferInfo.bufferName(); diff --git a/src/core/networkconnection.cpp b/src/core/networkconnection.cpp index 35d44ad9..15b081cc 100644 --- a/src/core/networkconnection.cpp +++ b/src/core/networkconnection.cpp @@ -61,6 +61,14 @@ NetworkConnection::NetworkConnection(Network *network, CoreSession *session) : Q _autoWhoCycleTimer.setInterval(_autoWhoInterval * 1000); _autoWhoCycleTimer.setSingleShot(false); + // TokenBucket to avaid sending too much at once + _messagesPerSecond = 1; + _burstSize = 5; + _tokenBucket = 5; // init with a full bucket + + _tokenBucketTimer.start(_messagesPerSecond * 1000); + _tokenBucketTimer.setSingleShot(false); + QHash channels = coreSession()->persistentChannels(networkId()); foreach(QString chan, channels.keys()) { _channelKeys[chan.toLower()] = channels[chan]; @@ -69,6 +77,7 @@ NetworkConnection::NetworkConnection(Network *network, CoreSession *session) : Q connect(&_autoReconnectTimer, SIGNAL(timeout()), this, SLOT(doAutoReconnect())); connect(&_autoWhoTimer, SIGNAL(timeout()), this, SLOT(sendAutoWho())); connect(&_autoWhoCycleTimer, SIGNAL(timeout()), this, SLOT(startAutoWhoCycle())); + connect(&_tokenBucketTimer, SIGNAL(timeout()), this, SLOT(fillBucketAndProcessQueue())); connect(network, SIGNAL(currentServerSet(const QString &)), this, SLOT(networkInitialized(const QString &))); connect(network, SIGNAL(useAutoReconnectSet(bool)), this, SLOT(autoReconnectSettingsChanged())); @@ -380,9 +389,27 @@ void NetworkConnection::userInput(BufferInfo buf, QString msg) { } void NetworkConnection::putRawLine(QByteArray s) { + if(_tokenBucket > 0) { + writeToSocket(s); + } else { + _msgQueue.append(s); + } +} + +void NetworkConnection::writeToSocket(QByteArray s) { s += "\r\n"; socket.write(s); - if(Global::SPUTDEV) qDebug() << "SENT:" << s; + _tokenBucket--; +} + +void NetworkConnection::fillBucketAndProcessQueue() { + if(_tokenBucket < _burstSize) { + _tokenBucket++; + } + + while(_msgQueue.size() > 0 && _tokenBucket > 0) { + writeToSocket(_msgQueue.takeFirst()); + } } void NetworkConnection::putCmd(const QString &cmd, const QVariantList ¶ms, const QByteArray &prefix) { diff --git a/src/core/networkconnection.h b/src/core/networkconnection.h index 5f593137..959eb740 100644 --- a/src/core/networkconnection.h +++ b/src/core/networkconnection.h @@ -147,6 +147,8 @@ private slots: void sslErrors(const QList &errors); #endif + void fillBucketAndProcessQueue(); + private: #ifndef QT_NO_OPENSSL QSslSocket socket; @@ -180,6 +182,15 @@ private: int _autoWhoDelay; QTimer _autoWhoTimer, _autoWhoCycleTimer; + QTimer _tokenBucketTimer; + int _messagesPerSecond; // token refill speed + int _burstSize; // size of the token bucket + int _tokenBucket; // the virtual bucket that holds the tokens + QList _msgQueue; + + void writeToSocket(QByteArray s); + + class ParseError : public Exception { public: diff --git a/src/core/sqlitestorage.cpp b/src/core/sqlitestorage.cpp index ea19ca96..8cd4d5b0 100644 --- a/src/core/sqlitestorage.cpp +++ b/src/core/sqlitestorage.cpp @@ -188,7 +188,9 @@ NetworkId SqliteStorage::createNetwork(UserId user, const NetworkInfo &info) { if(!networkId.isValid()) { watchQuery(&query); } else { - updateNetwork(user, info); + NetworkInfo newNetworkInfo = info; + newNetworkInfo.networkId = networkId; + updateNetwork(user, newNetworkInfo); } return networkId; } diff --git a/src/core/userinputhandler.cpp b/src/core/userinputhandler.cpp index 618bc8da..0ef5aba0 100644 --- a/src/core/userinputhandler.cpp +++ b/src/core/userinputhandler.cpp @@ -92,7 +92,6 @@ void UserInputHandler::handleBan(const BufferInfo &bufferInfo, const QString &ms } QString banMsg = QString("MODE %1 +b %2").arg(banChannel).arg(banUser); - qDebug() << banMsg; emit putRawLine(serverEncode(banMsg)); } diff --git a/src/qtui/chatline-old.cpp b/src/qtui/chatline-old.cpp index c1cd7d2f..2df6bbb4 100644 --- a/src/qtui/chatline-old.cpp +++ b/src/qtui/chatline-old.cpp @@ -36,6 +36,9 @@ ChatLineOld::ChatLineOld(Message m) { selectionMode = None; isHighlight = false; formatMsg(msg); + + QtUiSettings s("QtUi/Colors"); + _highlightColor = s.value("highlightColor", QVariant(QColor("lightcoral"))).value(); } ChatLineOld::~ChatLineOld() { @@ -318,10 +321,8 @@ void ChatLineOld::draw(QPainter *p, const QPointF &pos) { p->drawRect(QRectF(pos, QSizeF(tsWidth + QtUi::style()->sepTsSender() + senderWidth + QtUi::style()->sepSenderText() + textWidth, height()))); } else { if(isHighlight) { - QtUiSettings s("QtUi/Colors"); - QColor highlightColor = s.value("highlightColor", QVariant(QColor("lightcoral"))).value(); p->setPen(Qt::NoPen); - p->setBrush(highlightColor /*pal.brush(QPalette::AlternateBase) */); + p->setBrush(_highlightColor /*pal.brush(QPalette::AlternateBase) */); p->drawRect(QRectF(pos, QSizeF(tsWidth + QtUi::style()->sepTsSender() + senderWidth + QtUi::style()->sepSenderText() + textWidth, height()))); } if(selectionMode == Partial) { diff --git a/src/qtui/chatline-old.h b/src/qtui/chatline-old.h index 8d286b07..f4877a96 100644 --- a/src/qtui/chatline-old.h +++ b/src/qtui/chatline-old.h @@ -106,6 +106,8 @@ class ChatLineOld : public QObject, public AbstractUiMsg { void precomputeLine(); QList calcFormatRanges(const UiStyle::StyledText &); QList calcFormatRanges(const UiStyle::StyledText &, const QTextLayout::FormatRange &additional); + + QColor _highlightColor; }; #endif diff --git a/src/uisupport/abstractbuffercontainer.cpp b/src/uisupport/abstractbuffercontainer.cpp index 14440271..fd2b9da9 100644 --- a/src/uisupport/abstractbuffercontainer.cpp +++ b/src/uisupport/abstractbuffercontainer.cpp @@ -78,19 +78,18 @@ void AbstractBufferContainer::currentChanged(const QModelIndex ¤t, const Q } void AbstractBufferContainer::setCurrentBuffer(BufferId bufferId) { - if(!bufferId.isValid()) { - showChatView(0); - return; - } - AbstractChatView *chatView = 0; - Buffer *buf = Client::buffer(bufferId); - if(!buf) { - qWarning() << "AbstractBufferContainer::setBuffer(BufferId): Can't show unknown Buffer:" << bufferId; - return; - } Buffer *prevBuffer = Client::buffer(currentBuffer()); if(prevBuffer) prevBuffer->setVisible(false); + + Buffer *buf; + if(!bufferId.isValid() || !(buf = Client::buffer(bufferId))) { + if(bufferId.isValid()) + qWarning() << "AbstractBufferContainer::setBuffer(BufferId): Can't show unknown Buffer:" << bufferId; + _currentBuffer = 0; + showChatView(0); + return; + } if(_chatViews.contains(bufferId)) { chatView = _chatViews[bufferId]; } else { diff --git a/src/uisupport/bufferviewfilter.cpp b/src/uisupport/bufferviewfilter.cpp index a14ab031..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(); @@ -148,6 +147,9 @@ bool BufferViewFilter::filterAcceptBuffer(const QModelIndex &source_bufferIndex) if(!_config) return true; + if(config()->networkId().isValid() && config()->networkId() != sourceModel()->data(source_bufferIndex, NetworkModel::NetworkIdRole).value()) + return false; + if(!(_config->allowedBufferTypes() & (BufferInfo::Type)source_bufferIndex.data(NetworkModel::BufferTypeRole).toInt())) return false; @@ -206,7 +208,7 @@ bool BufferViewFilter::bufferLessThan(const QModelIndex &source_left, const QMod if(config()) { return config()->bufferList().indexOf(leftBufferId) < config()->bufferList().indexOf(rightBufferId); } else - return leftBufferId < rightBufferId; + return bufferIdLessThan(leftBufferId, rightBufferId); } bool BufferViewFilter::networkLessThan(const QModelIndex &source_left, const QModelIndex &source_right) const { @@ -279,6 +281,6 @@ bool bufferIdLessThan(const BufferId &left, const BufferId &right) { if(leftType != rightType) return leftType < rightType; else - return Client::networkModel()->data(leftIndex, Qt::DisplayRole).toString() < Client::networkModel()->data(rightIndex, Qt::DisplayRole).toString(); + return QString::compare(Client::networkModel()->data(leftIndex, Qt::DisplayRole).toString(), Client::networkModel()->data(rightIndex, Qt::DisplayRole).toString(), Qt::CaseInsensitive) < 0; } diff --git a/version.inc b/version.inc index 7f81fdb0..03281a3d 100644 --- a/version.inc +++ b/version.inc @@ -4,8 +4,8 @@ { using namespace Global; quasselVersion = "0.2.0-beta1-pre"; - quasselDate = "2008-04-14"; - quasselBuild = 745; + quasselDate = "2008-04-16"; + quasselBuild = 756; //! Minimum client build number the core needs clientBuildNeeded = 731; -- 2.20.1